1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "bitmap.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
37 #include "wx/palette.h"
38 #include "wx/dcmemory.h"
39 #include "wx/bitmap.h"
43 #include "wx/msw/private.h"
46 #include "wx/msw/dib.h"
49 // ----------------------------------------------------------------------------
51 // ----------------------------------------------------------------------------
53 #if !USE_SHARED_LIBRARIES
54 IMPLEMENT_DYNAMIC_CLASS(wxBitmap
, wxGDIObject
)
55 IMPLEMENT_DYNAMIC_CLASS(wxMask
, wxObject
)
58 // ============================================================================
60 // ============================================================================
62 // ----------------------------------------------------------------------------
64 // ----------------------------------------------------------------------------
66 wxBitmapRefData::wxBitmapRefData()
74 m_selectedInto
= NULL
;
79 wxBitmapRefData::~wxBitmapRefData()
81 wxASSERT_MSG( !m_selectedInto
,
82 wxT("deleting bitmap still selected into wxMemoryDC") );
85 DeleteObject((HBITMAP
) m_hBitmap
);
91 // ----------------------------------------------------------------------------
93 // ----------------------------------------------------------------------------
95 wxList
wxBitmap::sm_handlers
;
97 // this function should be called from all wxBitmap ctors
100 // m_refData = NULL; done in the base class ctor
102 if ( wxTheBitmapList
)
103 wxTheBitmapList
->AddBitmap(this);
106 bool wxBitmap::CopyFromIcon(const wxIcon
& icon
)
113 int width
= icon
.GetWidth(),
114 height
= icon
.GetHeight();
116 HICON hicon
= (HICON
) icon
.GetHICON();
118 // GetIconInfo() doesn't exist under Win16 and I don't know any other way
119 // to create a bitmap from icon there - but using this way we won't have
122 // copy the icon to the bitmap
123 HDC hdcScreen
= ::GetDC((HWND
)NULL
);
124 HDC hdc
= ::CreateCompatibleDC(hdcScreen
);
125 HBITMAP hbitmap
= ::CreateCompatibleBitmap(hdcScreen
, width
, height
);
126 HBITMAP hbmpOld
= (HBITMAP
)::SelectObject(hdc
, hbitmap
);
128 ::DrawIcon(hdc
, 0, 0, hicon
);
130 ::SelectObject(hdc
, hbmpOld
);
132 ::ReleaseDC((HWND
)NULL
, hdcScreen
);
135 if ( !GetIconInfo(hicon
, &iconInfo
) )
137 wxLogLastError("GetIconInfo");
142 HBITMAP hbitmap
= iconInfo
.hbmColor
;
144 wxMask
*mask
= new wxMask
;
145 mask
->SetMaskBitmap((WXHBITMAP
)iconInfo
.hbmMask
);
148 m_refData
= new wxBitmapRefData
;
150 M_BITMAPDATA
->m_width
= width
;
151 M_BITMAPDATA
->m_height
= height
;
152 M_BITMAPDATA
->m_depth
= wxDisplayDepth();
154 M_BITMAPDATA
->m_hBitmap
= (WXHBITMAP
)hbitmap
;
155 M_BITMAPDATA
->m_ok
= TRUE
;
164 wxBitmap::~wxBitmap()
167 wxTheBitmapList
->DeleteObject(this);
170 bool wxBitmap::FreeResource(bool WXUNUSED(force
))
175 wxASSERT_MSG( !M_BITMAPDATA
->m_selectedInto
,
176 wxT("freeing bitmap still selected into wxMemoryDC") );
178 if (M_BITMAPDATA
->m_hBitmap
)
180 DeleteObject((HBITMAP
) M_BITMAPDATA
->m_hBitmap
);
182 M_BITMAPDATA
->m_hBitmap
= 0 ;
185 if (M_BITMAPDATA->m_bitmapPalette)
186 delete M_BITMAPDATA->m_bitmapPalette;
188 M_BITMAPDATA->m_bitmapPalette = NULL ;
195 wxBitmap::wxBitmap(const char bits
[], int the_width
, int the_height
, int no_bits
)
199 m_refData
= new wxBitmapRefData
;
201 M_BITMAPDATA
->m_width
= the_width
;
202 M_BITMAPDATA
->m_height
= the_height
;
203 M_BITMAPDATA
->m_depth
= no_bits
;
204 M_BITMAPDATA
->m_numColors
= 0;
206 M_BITMAPDATA
->m_hBitmap
= (WXHBITMAP
) CreateBitmap(the_width
, the_height
, 1, no_bits
, bits
);
208 if (M_BITMAPDATA
->m_hBitmap
)
209 M_BITMAPDATA
->m_ok
= TRUE
;
211 M_BITMAPDATA
->m_ok
= FALSE
;
213 M_BITMAPDATA
->m_selectedInto
= NULL
;
216 // Create from XPM data
217 wxBitmap::wxBitmap(char **data
, wxControl
*WXUNUSED(anItem
))
221 (void)Create((void *)data
, wxBITMAP_TYPE_XPM_DATA
, 0, 0, 0);
224 wxBitmap::wxBitmap(int w
, int h
, int d
)
228 (void)Create(w
, h
, d
);
231 wxBitmap::wxBitmap(void *data
, long type
, int width
, int height
, int depth
)
235 (void) Create(data
, type
, width
, height
, depth
);
238 wxBitmap::wxBitmap(const wxString
& filename
, long type
)
242 LoadFile(filename
, (int)type
);
245 bool wxBitmap::Create(int w
, int h
, int d
)
249 m_refData
= new wxBitmapRefData
;
251 M_BITMAPDATA
->m_width
= w
;
252 M_BITMAPDATA
->m_height
= h
;
253 M_BITMAPDATA
->m_depth
= d
;
257 M_BITMAPDATA
->m_hBitmap
= (WXHBITMAP
) CreateBitmap(w
, h
, 1, d
, NULL
);
261 HDC dc
= GetDC((HWND
) NULL
);
262 M_BITMAPDATA
->m_hBitmap
= (WXHBITMAP
) CreateCompatibleBitmap(dc
, w
, h
);
263 ReleaseDC((HWND
) NULL
, dc
);
264 M_BITMAPDATA
->m_depth
= wxDisplayDepth();
266 if (M_BITMAPDATA
->m_hBitmap
)
267 M_BITMAPDATA
->m_ok
= TRUE
;
269 M_BITMAPDATA
->m_ok
= FALSE
;
270 return M_BITMAPDATA
->m_ok
;
273 bool wxBitmap::LoadFile(const wxString
& filename
, long type
)
277 m_refData
= new wxBitmapRefData
;
279 wxBitmapHandler
*handler
= FindHandler(type
);
282 if ( handler
== NULL
)
285 if ( handler
== NULL
) {
287 if (!image
.LoadFile( filename
, type
)) return FALSE
;
290 *this = image
.ConvertToBitmap();
296 return handler
->LoadFile(this, filename
, type
, -1, -1);
299 bool wxBitmap::Create(void *data
, long type
, int width
, int height
, int depth
)
303 m_refData
= new wxBitmapRefData
;
305 wxBitmapHandler
*handler
= FindHandler(type
);
307 if ( handler
== NULL
) {
308 wxLogWarning(wxT("no bitmap handler for type %d defined."), type
);
313 return handler
->Create(this, data
, type
, width
, height
, depth
);
316 bool wxBitmap::SaveFile(const wxString
& filename
, int type
, const wxPalette
*palette
)
318 wxBitmapHandler
*handler
= FindHandler(type
);
321 if ( handler
== NULL
)
324 if ( handler
== NULL
) { // try wxImage
325 wxImage
image( *this );
326 if (image
.Ok()) return image
.SaveFile( filename
, type
);
331 return handler
->SaveFile(this, filename
, type
, palette
);
334 void wxBitmap::SetWidth(int w
)
337 m_refData
= new wxBitmapRefData
;
339 M_BITMAPDATA
->m_width
= w
;
342 void wxBitmap::SetHeight(int h
)
345 m_refData
= new wxBitmapRefData
;
347 M_BITMAPDATA
->m_height
= h
;
350 void wxBitmap::SetDepth(int d
)
353 m_refData
= new wxBitmapRefData
;
355 M_BITMAPDATA
->m_depth
= d
;
358 void wxBitmap::SetQuality(int q
)
361 m_refData
= new wxBitmapRefData
;
363 M_BITMAPDATA
->m_quality
= q
;
366 void wxBitmap::SetOk(bool isOk
)
369 m_refData
= new wxBitmapRefData
;
371 M_BITMAPDATA
->m_ok
= isOk
;
374 void wxBitmap::SetPalette(const wxPalette
& palette
)
377 m_refData
= new wxBitmapRefData
;
379 M_BITMAPDATA
->m_bitmapPalette
= palette
;
382 void wxBitmap::SetMask(wxMask
*mask
)
385 m_refData
= new wxBitmapRefData
;
387 M_BITMAPDATA
->m_bitmapMask
= mask
;
390 void wxBitmap::SetHBITMAP(WXHBITMAP bmp
)
393 m_refData
= new wxBitmapRefData
;
395 M_BITMAPDATA
->m_hBitmap
= bmp
;
396 M_BITMAPDATA
->m_ok
= bmp
!= 0;
399 void wxBitmap::AddHandler(wxBitmapHandler
*handler
)
401 sm_handlers
.Append(handler
);
404 void wxBitmap::InsertHandler(wxBitmapHandler
*handler
)
406 sm_handlers
.Insert(handler
);
409 bool wxBitmap::RemoveHandler(const wxString
& name
)
411 wxBitmapHandler
*handler
= FindHandler(name
);
414 sm_handlers
.DeleteObject(handler
);
421 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& name
)
423 wxNode
*node
= sm_handlers
.First();
426 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
427 if ( (handler
->GetName().Cmp(name
) == 0) )
434 wxBitmapHandler
*wxBitmap::FindHandler(const wxString
& extension
, long bitmapType
)
436 wxNode
*node
= sm_handlers
.First();
439 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
440 if ( (handler
->GetExtension().Cmp(extension
) == 0) &&
441 (bitmapType
== -1 || (handler
->GetType() == bitmapType
)) )
448 wxBitmapHandler
*wxBitmap::FindHandler(long bitmapType
)
450 wxNode
*node
= sm_handlers
.First();
453 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
454 if (handler
->GetType() == bitmapType
)
461 // New Create/FreeDIB functions since ones in dibutils.cpp are confusing
462 static long createDIB(long xSize
, long ySize
, long bitsPerPixel
,
463 HPALETTE hPal
, LPBITMAPINFO
* lpDIBHeader
);
464 static long freeDIB(LPBITMAPINFO lpDIBHeader
);
466 // Creates a bitmap that matches the device context, from
467 // an arbitray bitmap. At present, the original bitmap must have an
468 // associated palette. TODO: use a default palette if no palette exists.
469 // Contributed by Frederic Villeneuve <frederic.villeneuve@natinst.com>
470 wxBitmap
wxBitmap::GetBitmapForDC(wxDC
& dc
) const
473 wxBitmap
tmpBitmap(this->GetWidth(), this->GetHeight(), dc
.GetDepth());
474 HPALETTE hPal
= (HPALETTE
) NULL
;
476 void *lpBits
= (void*) NULL
;
479 wxASSERT( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) );
481 tmpBitmap.SetPalette(this->GetPalette());
482 memDC.SelectObject(tmpBitmap);
483 memDC.SetPalette(this->GetPalette());
485 hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
487 if( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) )
489 tmpBitmap
.SetPalette(* this->GetPalette());
490 memDC
.SelectObject(tmpBitmap
);
491 memDC
.SetPalette(* this->GetPalette());
492 hPal
= (HPALETTE
) this->GetPalette()->GetHPALETTE();
496 hPal
= (HPALETTE
) ::GetStockObject(DEFAULT_PALETTE
);
498 palette
.SetHPALETTE( (WXHPALETTE
)hPal
);
499 tmpBitmap
.SetPalette( palette
);
500 memDC
.SelectObject(tmpBitmap
);
501 memDC
.SetPalette( palette
);
504 // set the height negative because in a DIB the order of the lines is reversed
505 createDIB(this->GetWidth(), -this->GetHeight(), this->GetDepth(), hPal
, &lpDib
);
507 lpBits
= malloc(lpDib
->bmiHeader
.biSizeImage
);
509 ::GetBitmapBits((HBITMAP
)GetHBITMAP(), lpDib
->bmiHeader
.biSizeImage
, lpBits
);
511 ::SetDIBitsToDevice((HDC
) memDC
.GetHDC(), 0, 0, this->GetWidth(), this->GetHeight(),
512 0, 0, 0, this->GetHeight(), lpBits
, lpDib
, DIB_RGB_COLORS
);
529 // Construct a mask from a bitmap and a colour indicating
530 // the transparent area
531 wxMask::wxMask(const wxBitmap
& bitmap
, const wxColour
& colour
)
534 Create(bitmap
, colour
);
537 // Construct a mask from a bitmap and a palette index indicating
538 // the transparent area
539 wxMask::wxMask(const wxBitmap
& bitmap
, int paletteIndex
)
542 Create(bitmap
, paletteIndex
);
545 // Construct a mask from a mono bitmap (copies the bitmap).
546 wxMask::wxMask(const wxBitmap
& bitmap
)
555 ::DeleteObject((HBITMAP
) m_maskBitmap
);
558 // Create a mask from a mono bitmap (copies the bitmap).
559 bool wxMask::Create(const wxBitmap
& bitmap
)
563 ::DeleteObject((HBITMAP
) m_maskBitmap
);
566 if (!bitmap
.Ok() || bitmap
.GetDepth() != 1)
570 m_maskBitmap
= (WXHBITMAP
) CreateBitmap(
575 HDC srcDC
= CreateCompatibleDC(0);
576 SelectObject(srcDC
, (HBITMAP
) bitmap
.GetHBITMAP());
577 HDC destDC
= CreateCompatibleDC(0);
578 SelectObject(destDC
, (HBITMAP
) m_maskBitmap
);
579 BitBlt(destDC
, 0, 0, bitmap
.GetWidth(), bitmap
.GetHeight(), srcDC
, 0, 0, SRCCOPY
);
580 SelectObject(srcDC
, 0);
582 SelectObject(destDC
, 0);
587 // Create a mask from a bitmap and a palette index indicating
588 // the transparent area
589 bool wxMask::Create(const wxBitmap
& bitmap
, int paletteIndex
)
593 ::DeleteObject((HBITMAP
) m_maskBitmap
);
596 if (bitmap
.Ok() && bitmap
.GetPalette()->Ok())
598 unsigned char red
, green
, blue
;
599 if (bitmap
.GetPalette()->GetRGB(paletteIndex
, &red
, &green
, &blue
))
601 wxColour
transparentColour(red
, green
, blue
);
602 return Create(bitmap
, transparentColour
);
608 // Create a mask from a bitmap and a colour indicating
609 // the transparent area
610 bool wxMask::Create(const wxBitmap
& bitmap
, const wxColour
& colour
)
614 ::DeleteObject((HBITMAP
) m_maskBitmap
);
622 // scan the bitmap for the transparent colour and set
623 // the corresponding pixels in the mask to BLACK and
625 COLORREF maskColour
= RGB(colour
.Red(), colour
.Green(), colour
.Blue());
626 m_maskBitmap
= (WXHBITMAP
) ::CreateBitmap(
631 HDC srcDC
= ::CreateCompatibleDC(0);
632 ::SelectObject(srcDC
, (HBITMAP
) bitmap
.GetHBITMAP());
633 HDC destDC
= ::CreateCompatibleDC(0);
634 ::SelectObject(destDC
, (HBITMAP
) m_maskBitmap
);
636 // this is not very efficient, but I can't think
637 // of a better way of doing it
638 for (int w
= 0; w
< bitmap
.GetWidth(); w
++)
640 for (int h
= 0; h
< bitmap
.GetHeight(); h
++)
642 COLORREF col
= GetPixel(srcDC
, w
, h
);
643 if (col
== maskColour
)
645 ::SetPixel(destDC
, w
, h
, RGB(0, 0, 0));
649 ::SetPixel(destDC
, w
, h
, RGB(255, 255, 255));
653 ::SelectObject(srcDC
, 0);
655 ::SelectObject(destDC
, 0);
664 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler
, wxObject
)
666 bool wxBitmapHandler::Create(wxBitmap
*WXUNUSED(bitmap
), void *WXUNUSED(data
), long WXUNUSED(type
), int WXUNUSED(width
), int WXUNUSED(height
), int WXUNUSED(depth
))
671 bool wxBitmapHandler::LoadFile(wxBitmap
*WXUNUSED(bitmap
), const wxString
& WXUNUSED(name
), long WXUNUSED(type
),
672 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
677 bool wxBitmapHandler::SaveFile(wxBitmap
*WXUNUSED(bitmap
), const wxString
& WXUNUSED(name
), int WXUNUSED(type
), const wxPalette
*WXUNUSED(palette
))
686 class WXDLLEXPORT wxBMPResourceHandler
: public wxBitmapHandler
688 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler
)
690 inline wxBMPResourceHandler()
692 m_name
= "Windows bitmap resource";
694 m_type
= wxBITMAP_TYPE_BMP_RESOURCE
;
697 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
698 int desiredWidth
, int desiredHeight
);
700 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler
, wxBitmapHandler
)
702 bool wxBMPResourceHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long WXUNUSED(flags
),
703 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
705 // TODO: load colourmap.
706 M_BITMAPHANDLERDATA
->m_hBitmap
= (WXHBITMAP
) ::LoadBitmap(wxGetInstance(), name
);
707 if (M_BITMAPHANDLERDATA
->m_hBitmap
)
709 M_BITMAPHANDLERDATA
->m_ok
= TRUE
;
711 GetObject((HBITMAP
) M_BITMAPHANDLERDATA
->m_hBitmap
, sizeof(BITMAP
), (LPSTR
) &bm
);
712 M_BITMAPHANDLERDATA
->m_width
= bm
.bmWidth
;
713 M_BITMAPHANDLERDATA
->m_height
= bm
.bmHeight
;
714 M_BITMAPHANDLERDATA
->m_depth
= bm
.bmBitsPixel
;
716 if ( bitmap
->IsKindOf(CLASSINFO(wxIcon
)) )
723 // it's probably not found
724 wxLogError(wxT("Can't load bitmap '%s' from resources! Check .rc file."), name
.c_str());
729 class WXDLLEXPORT wxBMPFileHandler
: public wxBitmapHandler
731 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler
)
733 inline wxBMPFileHandler()
735 m_name
= "Windows bitmap file";
737 m_type
= wxBITMAP_TYPE_BMP
;
740 virtual bool LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long flags
,
741 int desiredWidth
, int desiredHeight
);
742 virtual bool SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int type
, const wxPalette
*palette
= NULL
);
744 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler
, wxBitmapHandler
)
746 bool wxBMPFileHandler::LoadFile(wxBitmap
*bitmap
, const wxString
& name
, long WXUNUSED(flags
),
747 int WXUNUSED(desiredWidth
), int WXUNUSED(desiredHeight
))
749 #if wxUSE_IMAGE_LOADING_IN_MSW
750 wxPalette
*palette
= NULL
;
751 bool success
= FALSE
;
753 if (type & wxBITMAP_DISCARD_COLOURMAP)
754 success = wxLoadIntoBitmap(WXSTRINGCAST name, bitmap);
757 success
= (wxLoadIntoBitmap(WXSTRINGCAST name
, bitmap
, &palette
) != 0);
758 if (!success
&& palette
)
765 M_BITMAPHANDLERDATA
->m_bitmapPalette
= *palette
;
774 bool wxBMPFileHandler::SaveFile(wxBitmap
*bitmap
, const wxString
& name
, int WXUNUSED(type
), const wxPalette
*pal
)
776 #if wxUSE_IMAGE_LOADING_IN_MSW
777 wxPalette
*actualPalette
= (wxPalette
*)pal
;
778 if (!actualPalette
&& (!M_BITMAPHANDLERDATA
->m_bitmapPalette
.IsNull()))
779 actualPalette
= & (M_BITMAPHANDLERDATA
->m_bitmapPalette
);
780 return (wxSaveBitmap(WXSTRINGCAST name
, bitmap
, actualPalette
) != 0);
786 void wxBitmap::CleanUpHandlers()
788 wxNode
*node
= sm_handlers
.First();
791 wxBitmapHandler
*handler
= (wxBitmapHandler
*)node
->Data();
792 wxNode
*next
= node
->Next();
799 void wxBitmap::InitStandardHandlers()
801 AddHandler(new wxBMPResourceHandler
);
802 AddHandler(new wxBMPFileHandler
);
804 // Not added by default: include xpmhand.h in your app
805 // and call these in your wxApp::OnInit.
806 // AddHandler(new wxXPMFileHandler);
807 // AddHandler(new wxXPMDataHandler);
809 AddHandler(new wxICOResourceHandler
);
810 AddHandler(new wxICOFileHandler
);
813 static long createDIB(long xSize
, long ySize
, long bitsPerPixel
,
814 HPALETTE hPal
, LPBITMAPINFO
* lpDIBHeader
)
816 unsigned long i
, headerSize
;
817 LPBITMAPINFO lpDIBheader
= NULL
;
818 LPPALETTEENTRY lpPe
= NULL
;
821 // Allocate space for a DIB header
822 headerSize
= (sizeof(BITMAPINFOHEADER
) + (256 * sizeof(PALETTEENTRY
)));
823 lpDIBheader
= (BITMAPINFO
*) malloc(headerSize
);
824 lpPe
= (PALETTEENTRY
*)((BYTE
*)lpDIBheader
+ sizeof(BITMAPINFOHEADER
));
826 GetPaletteEntries(hPal
, 0, 256, lpPe
);
829 memset(lpDIBheader
, 0x00, sizeof(BITMAPINFOHEADER
));
832 // Fill in the static parts of the DIB header
833 lpDIBheader
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
834 lpDIBheader
->bmiHeader
.biWidth
= xSize
;
835 lpDIBheader
->bmiHeader
.biHeight
= ySize
;
836 lpDIBheader
->bmiHeader
.biPlanes
= 1;
838 // this value must be 1, 4, 8 or 24 so PixelDepth can only be
839 lpDIBheader
->bmiHeader
.biBitCount
= (WORD
)(bitsPerPixel
);
840 lpDIBheader
->bmiHeader
.biCompression
= BI_RGB
;
841 lpDIBheader
->bmiHeader
.biSizeImage
= xSize
* abs(ySize
) * bitsPerPixel
>>
843 lpDIBheader
->bmiHeader
.biClrUsed
= 256;
846 // Initialize the DIB palette
847 for (i
= 0; i
< 256; i
++) {
848 lpDIBheader
->bmiColors
[i
].rgbReserved
= lpPe
[i
].peFlags
;
849 lpDIBheader
->bmiColors
[i
].rgbRed
= lpPe
[i
].peRed
;
850 lpDIBheader
->bmiColors
[i
].rgbGreen
= lpPe
[i
].peGreen
;
851 lpDIBheader
->bmiColors
[i
].rgbBlue
= lpPe
[i
].peBlue
;
854 *lpDIBHeader
= lpDIBheader
;
863 static long freeDIB(LPBITMAPINFO lpDIBHeader
)
866 if (lpDIBHeader
!= NULL
) {