1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/msw/dib.h
3 // Purpose:     wxDIB class representing Win32 device independent bitmaps
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     03.03.03 (replaces the old file with the same name)
7 // RCS-ID:      $Id: dib.h 49804 2007-11-10 01:09:42Z VZ $
8 // Copyright:   (c) 1997-2003 wxWidgets team
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef _WX_MSW_DIB_H_
13 #define _WX_MSW_DIB_H_
14 
15 class WXDLLIMPEXP_FWD_CORE wxBitmap;
16 class WXDLLIMPEXP_FWD_CORE wxPalette;
17 
18 #include "wx/msw/private.h"
19 
20 #if wxUSE_WXDIB
21 
22 // ----------------------------------------------------------------------------
23 // wxDIB: represents a DIB section
24 // ----------------------------------------------------------------------------
25 
26 class WXDLLEXPORT wxDIB
27 {
28 public:
29     // ctors and such
30     // --------------
31 
32     // create an uninitialized DIB with the given width, height and depth (only
33     // 24 and 32 bpp DIBs are currently supported)
34     //
35     // after using this ctor, GetData() and GetHandle() may be used if IsOk()
36     // returns true
wxDIB(int width,int height,int depth)37     wxDIB(int width, int height, int depth)
38         { Init(); (void)Create(width, height, depth); }
39 
40     // create a DIB from the DDB
wxDIB(const wxBitmap & bmp)41     wxDIB(const wxBitmap& bmp)
42         { Init(); (void)Create(bmp); }
43 
44     // create a DIB from the Windows DDB
wxDIB(HBITMAP hbmp)45     wxDIB(HBITMAP hbmp)
46         { Init(); (void)Create(hbmp); }
47 
48     // load a DIB from file (any depth is supoprted here unlike above)
49     //
50     // as above, use IsOk() to see if the bitmap was loaded successfully
wxDIB(const wxString & filename)51     wxDIB(const wxString& filename)
52         { Init(); (void)Load(filename); }
53 
54     // same as the corresponding ctors but with return value
55     bool Create(int width, int height, int depth);
56     bool Create(const wxBitmap& bmp);
57     bool Create(HBITMAP hbmp);
58     bool Load(const wxString& filename);
59 
60     // dtor is not virtual, this class is not meant to be used polymorphically
61     ~wxDIB();
62 
63 
64     // operations
65     // ----------
66 
67 #ifndef __WXWINCE__
68     // create a bitmap compatible with the given HDC (or screen by default) and
69     // return its handle, the caller is responsible for freeing it (using
70     // DeleteObject())
71     HBITMAP CreateDDB(HDC hdc = 0) const;
72 #endif // !__WXWINCE__
73 
74     // get the handle from the DIB and reset it, i.e. this object won't destroy
75     // the DIB after this (but the caller should do it)
Detach()76     HBITMAP Detach() { HBITMAP hbmp = m_handle; m_handle = 0; return hbmp; }
77 
78 #if wxUSE_PALETTE
79     // create a palette for this DIB (always a trivial/default one for 24bpp)
80     wxPalette *CreatePalette() const;
81 #endif // wxUSE_PALETTE
82 
83     // save the DIB as a .BMP file to the file with the given name
84     bool Save(const wxString& filename);
85 
86 
87     // accessors
88     // ---------
89 
90     // return true if DIB was successfully created, false otherwise
IsOk()91     bool IsOk() const { return m_handle != 0; }
92 
93     // get the bitmap size
GetSize()94     wxSize GetSize() const { DoGetObject(); return wxSize(m_width, m_height); }
GetWidth()95     int GetWidth() const { DoGetObject(); return m_width; }
GetHeight()96     int GetHeight() const { DoGetObject(); return m_height; }
97 
98     // get the number of bits per pixel, or depth
GetDepth()99     int GetDepth() const { DoGetObject(); return m_depth; }
100 
101     // get the DIB handle
GetHandle()102     HBITMAP GetHandle() const { return m_handle; }
103 
104     // get raw pointer to bitmap bits, you should know what you do if you
105     // decide to use it
GetData()106     unsigned char *GetData() const
107         { DoGetObject(); return (unsigned char *)m_data; }
108 
109 
110     // HBITMAP conversion
111     // ------------------
112 
113     // these functions are only used by wxWidgets internally right now, please
114     // don't use them directly if possible as they're subject to change
115 
116 #ifndef __WXWINCE__
117     // creates a DDB compatible with the given (or screen) DC from either
118     // a plain DIB or a DIB section (in which case the last parameter must be
119     // non NULL)
120     static HBITMAP ConvertToBitmap(const BITMAPINFO *pbi,
121                                    HDC hdc = 0,
122                                    void *bits = NULL);
123 
124     // create a plain DIB (not a DIB section) from a DDB, the caller is
125     // responsable for freeing it using ::GlobalFree()
126     static HGLOBAL ConvertFromBitmap(HBITMAP hbmp);
127 
128     // creates a DIB from the given DDB or calculates the space needed by it:
129     // if pbi is NULL, only the space is calculated, otherwise pbi is supposed
130     // to point at BITMAPINFO of the correct size which is filled by this
131     // function (this overload is needed for wxBitmapDataObject code in
132     // src/msw/ole/dataobj.cpp)
133     static size_t ConvertFromBitmap(BITMAPINFO *pbi, HBITMAP hbmp);
134 #endif // __WXWINCE__
135 
136 
137     // wxImage conversion
138     // ------------------
139 
140 #if wxUSE_IMAGE
141     // create a DIB from the given image, the DIB will be either 24 or 32 (if
142     // the image has alpha channel) bpp
wxDIB(const wxImage & image)143     wxDIB(const wxImage& image) { Init(); (void)Create(image); }
144 
145     // same as the above ctor but with the return code
146     bool Create(const wxImage& image);
147 
148     // create wxImage having the same data as this DIB
149     wxImage ConvertToImage() const;
150 #endif // wxUSE_IMAGE
151 
152 
153     // helper functions
154     // ----------------
155 
156     // return the size of one line in a DIB with given width and depth: the
157     // point here is that as the scan lines need to be DWORD aligned so we may
158     // need to add some padding
GetLineSize(int width,int depth)159     static unsigned long GetLineSize(int width, int depth)
160     {
161         return ((width*depth + 31) & ~31) >> 3;
162     }
163 
164 private:
165     // common part of all ctors
166     void Init();
167 
168     // free resources
169     void Free();
170 
171     // initialize the contents from the provided DDB (Create() must have been
172     // already called)
173     bool CopyFromDDB(HBITMAP hbmp);
174 
175 
176     // the DIB section handle, 0 if invalid
177     HBITMAP m_handle;
178 
179     // NB: we could store only m_handle and not any of the other fields as
180     //     we may always retrieve them from it using ::GetObject(), but we
181     //     decide to still store them for efficiency concerns -- however if we
182     //     don't have them from the very beginning (e.g. DIB constructed from a
183     //     bitmap), we only retrieve them when necessary and so these fields
184     //     should *never* be accessed directly, even from inside wxDIB code
185 
186     // function which must be called before accessing any members and which
187     // gets their values from m_handle, if not done yet
188     void DoGetObject() const;
189 
190     // pointer to DIB bits, may be NULL
191     void *m_data;
192 
193     // size and depth of the image
194     int m_width,
195         m_height,
196         m_depth;
197 
198     // in some cases we could be using a handle which we didn't create and in
199     // this case we shouldn't free it neither -- this flag tell us if this is
200     // the case
201     bool m_ownsHandle;
202 
203     // if true, we have alpha, if false we don't (note that we can still have
204     // m_depth == 32 but the last component is then simply padding and not
205     // alpha)
206     bool m_hasAlpha;
207 
208 
209     // DIBs can't be copied
210     wxDIB(const wxDIB&);
211     wxDIB& operator=(const wxDIB&);
212 };
213 
214 // ----------------------------------------------------------------------------
215 // inline functions implementation
216 // ----------------------------------------------------------------------------
217 
218 inline
Init()219 void wxDIB::Init()
220 {
221     m_handle = 0;
222     m_ownsHandle = true;
223     m_hasAlpha = false;
224 
225     m_data = NULL;
226 
227     m_width =
228     m_height =
229     m_depth = 0;
230 }
231 
232 inline
Free()233 void wxDIB::Free()
234 {
235     if ( m_handle && m_ownsHandle )
236     {
237         if ( !::DeleteObject(m_handle) )
238         {
239             wxLogLastError(wxT("DeleteObject(hDIB)"));
240         }
241 
242         Init();
243     }
244 }
245 
~wxDIB()246 inline wxDIB::~wxDIB()
247 {
248     Free();
249 }
250 
251 #endif
252     // wxUSE_WXDIB
253 
254 #endif // _WX_MSW_DIB_H_
255 
256