1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Routines for dealing with Device Independent Bitmaps.
5 // Modified by: Jason Quijano 06/06/2001
8 // Copyright: (c) Julian Smart
9 /////////////////////////////////////////////////////////////////////////////
11 // wxReadDIB() - Reads a DIB
12 // WriteDIB() - Writes a global handle in CF_DIB format to a file.
13 // wxPaletteSize() - Calculates the palette size in bytes of given DIB *
14 // DibNumColors() - Determines the number of colors in DIB
15 // DibFromBitmap() - Creates a DIB repr. the DDB passed in.
16 // lread() - Private routine to read more than 64k
17 // lwrite() - Private routine to write more than 64k
18 /////////////////////////////////////////////////////////////////////////////
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
23 #if defined(__BORLANDC__)
28 #include "wx/bitmap.h"
37 #if !defined(__MWERKS__) && !defined(__SALFORDC__)
41 #include "wx/msw/dib.h"
42 #include "wx/filesys.h"
44 #ifdef __GNUWIN32_OLD__
45 #include "wx/msw/gnuwin32/extra.h"
55 // Number of bytes to be read during each read operation.
58 // Header signatutes for various resources
59 #define BFT_ICON 0x4349 // 'IC'
60 #define BFT_BITMAP 0x4d42 // 'BM'
61 #define BFT_CURSOR 0x5450 // 'PT('
63 // macro to determine if resource is a DIB
64 #define ISDIB(bft) ((bft) == BFT_BITMAP)
66 // Macro to align given value to the closest DWORD (unsigned long )
67 #define ALIGNULONG(i) ((i+3)/4*4)
69 // Macro to determine to round off the given value to the closest byte
70 #define WIDTHBYTES(i) ((i+31)/32*4)
72 #define PALVERSION 0x300
73 #define MAXPALETTE 256 // max. # supported palette entries
75 static DWORD PASCAL
lwrite(int fh
, VOID FAR
*pv
, DWORD ul
);
77 static BOOL
WriteDIB (LPTSTR szFile
,HANDLE hdib
);
78 WORD
wxPaletteSize (VOID FAR
* pv
); // This is non-static as some apps use it externally
79 static WORD
DibNumColors (VOID FAR
* pv
);
80 // HANDLE DibFromBitmap (HBITMAP hbm, DWORD biStyle, WORD biBits, HPALETTE hpal);
81 static BOOL PASCAL
MakeBitmapAndPalette(HDC
,HANDLE
,HPALETTE
*,HBITMAP
*);
83 // ----------------------------------------------------------------------------
84 // FUNCTION : WriteDIB(LPSTR szFile,HANDLE hdib)
85 // PURPOSE : Write a global handle in CF_DIB format to a file.
86 // RETURNS : TRUE - if successful. FALSE - otherwise
87 // ----------------------------------------------------------------------------
93 LPBITMAPINFOHEADER lpbi
;
99 fh
= OpenFile(wxConvertWX2MB(szFile
), &of
, OF_CREATE
| OF_READWRITE
);
103 #ifdef __WINDOWS_386__
104 lpbi
= (LPBITMAPINFOHEADER
) MK_FP32(GlobalLock(hdib
));
106 lpbi
= (LPBITMAPINFOHEADER
) GlobalLock(hdib
);
108 // Fill in the fields of the file header
109 hdr
.bfType
= BFT_BITMAP
;
110 hdr
.bfSize
= GlobalSize(hdib
) + sizeof(BITMAPFILEHEADER
);
113 hdr
.bfOffBits
= (DWORD
) sizeof(BITMAPFILEHEADER
) + lpbi
->biSize
+ wxPaletteSize(lpbi
);
115 // Write the file header
116 _lwrite(fh
, (LPSTR
) &hdr
, sizeof(BITMAPFILEHEADER
));
118 //Write the DIB header and the bits
119 lwrite(fh
, (LPSTR
) lpbi
, GlobalSize(hdib
));
126 // ----------------------------------------------------------------------------
127 // FUNCTION : wxPaletteSize(VOID FAR * pv)
128 // PURPOSE : Calculates the palette size in bytes. If the info. block
129 // is of the BITMAPCOREHEADER type, the number of colors is
130 // multiplied by 3 to give the palette size, otherwise the
131 // number of colors is multiplied by 4.
132 // RETURNS : Palette size in number of bytes.
133 // ----------------------------------------------------------------------------
137 LPBITMAPINFOHEADER lpbi
;
140 lpbi
= (LPBITMAPINFOHEADER
) pv
;
141 NumColors
= DibNumColors(lpbi
);
143 if (lpbi
->biSize
== sizeof(BITMAPCOREHEADER
))
144 return (WORD
)(NumColors
* sizeof(RGBTRIPLE
));
146 return (WORD
)(NumColors
* sizeof(RGBQUAD
));
149 // ----------------------------------------------------------------------------
150 // FUNCTION : DibNumColors(VOID FAR * pv)
151 // PURPOSE : Determines the number of colors in the DIB by looking at
152 // the BitCount filed in the info block.
153 // RETURNS : The number of colors in the DIB.
154 // ----------------------------------------------------------------------------
155 static WORD
DibNumColors(
159 BITMAPINFOHEADER
*lpbi
;
160 BITMAPCOREHEADER
*lpbc
;
161 lpbi
= ((BITMAPINFOHEADER
*) pv
);
162 lpbc
= ((BITMAPCOREHEADER
*) pv
);
164 // With the BITMAPINFO format headers, the size of the palette
165 // is in biClrUsed, whereas in the BITMAPCORE - style headers, it
166 // is dependent on the bits per pixel ( = 2 raised to the power of
169 if (lpbi
->biSize
!= sizeof(BITMAPCOREHEADER
)) {
170 if (lpbi
->biClrUsed
!= 0)
171 return (WORD
) lpbi
->biClrUsed
;
172 bits
= lpbi
->biBitCount
;
175 bits
= lpbc
->bcBitCount
;
185 // A 24 bitcount DIB has no color table
190 // ----------------------------------------------------------------------------
191 // FUNCTION : DibFromBitmap()
192 // PURPOSE : Will create a global memory block in DIB format that
193 // represents the Device-dependent bitmap (DDB) passed in.
194 // RETURNS : A handle to the DIB
195 // ----------------------------------------------------------------------------
197 static HANDLE
DibFromBitmap(
205 BITMAPINFOHEADER FAR
*lpbi
;
214 hpal
= GetStockObject(DEFAULT_PALETTE
);
216 GetObject(hbm
, sizeof (bm
), (LPSTR
) &bm
);
219 biBits
= bm
.bmPlanes
* bm
.bmBitsPixel
;
221 bi
.biSize
= sizeof(BITMAPINFOHEADER
);
222 bi
.biWidth
= bm
.bmWidth
;
223 bi
.biHeight
= bm
.bmHeight
;
225 bi
.biBitCount
= biBits
;
226 bi
.biCompression
= biStyle
;
228 bi
.biXPelsPerMeter
= 0;
229 bi
.biYPelsPerMeter
= 0;
231 bi
.biClrImportant
= 0;
233 dwLen
= bi
.biSize
+ wxPaletteSize(&bi
);
235 hdc
= GetDC((HWND
) NULL
);
236 hpal
= SelectPalette(hdc
, hpal
, FALSE
);
239 hdib
= GlobalAlloc(GHND
, dwLen
);
242 SelectPalette(hdc
, hpal
, FALSE
);
243 ReleaseDC(NULL
, hdc
);
247 #ifdef __WINDOWS_386__
248 lpbi
= (BITMAPINFOHEADER FAR
*) MK_FP32(GlobalLock(hdib
));
250 lpbi
= (BITMAPINFOHEADER FAR
*) GlobalLock(hdib
);
255 // call GetDIBits with a NULL lpBits param, so it will calculate the
256 // biSizeImage field for us
257 GetDIBits(hdc
, hbm
, 0, (WORD
) bi
.biHeight
, NULL
, (LPBITMAPINFO
) lpbi
, DIB_RGB_COLORS
);
261 // If the driver did not fill in the biSizeImage field, make one up
262 if (bi
.biSizeImage
== 0) {
263 bi
.biSizeImage
= WIDTHBYTES((DWORD
)bm
.bmWidth
* biBits
) * bm
.bmHeight
;
264 if (biStyle
!= BI_RGB
)
265 bi
.biSizeImage
= (bi
.biSizeImage
* 3) / 2;
268 // realloc the buffer big enough to hold all the bits
269 dwLen
= bi
.biSize
+ wxPaletteSize(&bi
) + bi
.biSizeImage
;
270 if (h
= GlobalReAlloc(hdib
, dwLen
, 0))
275 SelectPalette(hdc
, hpal
, FALSE
);
276 ReleaseDC(NULL
, hdc
);
280 // call GetDIBits with a NON-NULL lpBits param, and actualy get the
283 #ifdef __WINDOWS_386__
284 lpbi
= (BITMAPINFOHEADER FAR
*) MK_FP32(GlobalLock(hdib
));
286 lpbi
= (BITMAPINFOHEADER FAR
*) GlobalLock(hdib
);
293 (LPSTR
) lpbi
+ (WORD
) lpbi
->biSize
+ wxPaletteSize(lpbi
),
294 (LPBITMAPINFO
) lpbi
, DIB_RGB_COLORS
) == 0) {
297 SelectPalette(hdc
, hpal
, FALSE
);
298 ReleaseDC((HWND
) NULL
, hdc
);
304 SelectPalette(hdc
, hpal
, FALSE
);
305 ReleaseDC(NULL
, hdc
);
311 //************* PRIVATE ROUTINES TO WRITE MORE THAN 64K ******************
312 // ----------------------------------------------------------------------------
313 // FUNCTION : lwrite(int fh, VOID FAR *pv, DWORD ul)
314 // PURPOSE : Writes data in steps of 32k till all the data is written.
315 // RETURNS : 0 - If write did not proceed correctly. number of bytes written otherwise.
316 // ----------------------------------------------------------------------------
317 static DWORD PASCAL
lwrite(
323 #if defined(WINNT) || defined(__WIN32__) || defined(__WIN32__) || defined(__WXWINE__)
324 BYTE
*hp
= (BYTE
*) pv
;
326 BYTE huge
*hp
= (BYTE huge
*) pv
;
328 while (ul
> MAXREAD
) {
329 if (_lwrite(fh
, (LPSTR
) hp
, (WORD
) MAXREAD
) != MAXREAD
)
334 if (_lwrite(fh
, (LPSTR
) hp
, (WXUINT
) ul
) != (WXUINT
) ul
)
339 // ----------------------------------------------------------------------------
340 // FUNCTION : ReadDIB(hWnd)
341 // PURPOSE : Reads a DIB from a file, obtains a handle to its
342 // BITMAPINFO struct. and loads the DIB. Once the DIB
343 // is loaded, the function also creates a bitmap and
344 // palette out of the DIB for a device-dependent form.
345 // RETURNS : TRUE - DIB loaded and bitmap/palette created
346 // The DIBINIT structure pointed to by pInfo is
347 // filled with the appropriate handles.
349 // ----------------------------------------------------------------------------
355 LPBITMAPINFOHEADER lpbi
;
361 BOOL bCoreHead
= FALSE
;
364 // JQ: We want to use wxFileSystem here in stead of Openfile so
365 // that we can use other FS types like a zip files.
367 wxFSFile
*file
= fsys
.OpenFile(lpFileName
);
368 wxInputStream
*dibs
= file
->GetStream();
370 wxLogError(_("Can't open file '%s'"), lpFileName
);
374 hDIB
= GlobalAlloc(GHND
, (DWORD
)(sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
)));
378 #ifdef __WINDOWS_386__
379 lpbi
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock(hDIB
));
381 lpbi
= (LPBITMAPINFOHEADER
)GlobalLock(hDIB
);
384 // JQ: read from the wxInputStream dibs instead of fh so
385 // that we can use other FS types like zip files.
386 dibs
->Read((LPSTR
)&bf
,sizeof(bf
));
387 if (sizeof(bf
) != dibs
->LastRead())
390 if (bf
.bfType
!= 0x4d42) // 'BM'
393 // JQ: read from the wxInputStream dibs instead of fh so
394 // that we can use other FS types like zip files.
395 dibs
->Read((LPSTR
)lpbi
,sizeof(BITMAPCOREHEADER
));
396 if (sizeof(BITMAPCOREHEADER
) != dibs
->LastRead())
399 if (lpbi
->biSize
== sizeof(BITMAPCOREHEADER
)){
400 lpbi
->biSize
= sizeof(BITMAPINFOHEADER
);
401 lpbi
->biBitCount
= ((LPBITMAPCOREHEADER
)lpbi
)->bcBitCount
;
402 lpbi
->biPlanes
= ((LPBITMAPCOREHEADER
)lpbi
)->bcPlanes
;
403 lpbi
->biHeight
= ((LPBITMAPCOREHEADER
)lpbi
)->bcHeight
;
404 lpbi
->biWidth
= ((LPBITMAPCOREHEADER
)lpbi
)->bcWidth
;
409 // JQ: Get to the start of the header and read INFOHEADER
410 // using dibs wxInputStream
411 dibs
->SeekI(sizeof(BITMAPFILEHEADER
),wxFromStart
);
412 if (dibs
->LastError() != wxSTREAM_NO_ERROR
)
415 // JQ: read from the wxInputStream dibs instead of fh so
416 // that we can use other FS types like zip files.
417 // Can I do error checking with this?
418 dibs
->Read((LPSTR
)lpbi
,sizeof(BITMAPINFOHEADER
));
419 if (sizeof(BITMAPINFOHEADER
) != dibs
->LastRead())
424 nNumColors
= (WORD
)lpbi
->biClrUsed
;
425 if ( nNumColors
== 0 ) {
426 // no color table for 24-bit, default size otherwise
427 if (lpbi
->biBitCount
!= 24)
428 nNumColors
= 1 << lpbi
->biBitCount
; // standard size table
431 // fill in some default values if they are zero
432 if (lpbi
->biClrUsed
== 0)
433 lpbi
->biClrUsed
= nNumColors
;
435 if (lpbi
->biSizeImage
== 0){
436 lpbi
->biSizeImage
= ((((lpbi
->biWidth
* (DWORD
)lpbi
->biBitCount
) + 31) & ~31) >> 3)
440 // get a proper-sized buffer for header, color table and bits
442 hDIB
= GlobalReAlloc(hDIB
, lpbi
->biSize
+ nNumColors
* sizeof(RGBQUAD
) +
443 lpbi
->biSizeImage
, 0);
445 // can't resize buffer for loading
449 #ifdef __WINDOWS_386__
450 lpbi
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock(hDIB
));
452 lpbi
= (LPBITMAPINFOHEADER
)GlobalLock(hDIB
);
455 // read the color table
457 dibs
->Read((LPSTR
)lpbi
+ lpbi
->biSize
, nNumColors
* sizeof(RGBQUAD
));
461 RGBTRIPLE FAR
*pTriple
;
462 dibs
->Read((LPSTR
)lpbi
+ lpbi
->biSize
, nNumColors
* sizeof(RGBTRIPLE
));
463 pQuad
= (RGBQUAD FAR
*)((LPSTR
)lpbi
+ lpbi
->biSize
);
464 pTriple
= (RGBTRIPLE FAR
*) pQuad
;
465 for (i
= nNumColors
- 1; i
>= 0; i
--){
466 pQuad
[i
].rgbRed
= pTriple
[i
].rgbtRed
;
467 pQuad
[i
].rgbBlue
= pTriple
[i
].rgbtBlue
;
468 pQuad
[i
].rgbGreen
= pTriple
[i
].rgbtGreen
;
469 pQuad
[i
].rgbReserved
= 0;
473 // offset to the bits from start of DIB header
474 offBits
= (WORD
)(lpbi
->biSize
+ nNumColors
* sizeof(RGBQUAD
));
476 if (bf
.bfOffBits
!= 0L)
477 dibs
->SeekI(bf
.bfOffBits
, wxFromStart
);
479 dibs
->Read((LPSTR
)lpbi
+ offBits
,lpbi
->biSizeImage
);
480 if (lpbi
->biSizeImage
== dibs
->LastRead())
484 if (!MakeBitmapAndPalette(hDC
, hDIB
, palette
, bitmap
))
506 // ----------------------------------------------------------------------------
507 // FUNCTION : MakeBitmapAndPalette
508 // PURPOSE : Given a DIB, creates a bitmap and corresponding palette
509 // to be used for a device-dependent representation of
511 // RETURNS : TRUE --> success. phPal and phBitmap are filled with
512 // appropriate handles. Caller is responsible for freeing objects.
513 // FALSE --> unable to create objects. both pointer are not valid
514 // ----------------------------------------------------------------------------
515 static BOOL PASCAL
MakeBitmapAndPalette(
521 LPBITMAPINFOHEADER lpInfo
;
524 HPALETTE hPalette
, hOldPal
;
527 #ifdef __WINDOWS_386__
528 lpInfo
= (LPBITMAPINFOHEADER
) MK_FP32(GlobalLock(hDIB
));
530 lpInfo
= (LPBITMAPINFOHEADER
) GlobalLock(hDIB
);
533 hPalette
= wxMakeDIBPalette(lpInfo
);
536 // Need to realize palette for converting DIB to bitmap.
537 hOldPal
= SelectPalette(hDC
, hPalette
, TRUE
);
540 lpBits
= (LPSTR
)lpInfo
+ (WORD
)lpInfo
->biSize
+
541 (WORD
)lpInfo
->biClrUsed
* sizeof(RGBQUAD
);
542 hBitmap
= CreateDIBitmap(hDC
, lpInfo
, CBM_INIT
, lpBits
,
543 (LPBITMAPINFO
)lpInfo
, DIB_RGB_COLORS
);
545 SelectPalette(hDC
, hOldPal
, TRUE
);
549 DeleteObject(hPalette
);
558 GlobalUnlock (hDIB
); // glt
562 // ----------------------------------------------------------------------------
563 // FUNCTION : wxMakeDIBPalette(lpInfo)
564 // PURPOSE : Given a BITMAPINFOHEADER, create a palette based on
566 // RETURNS : non-zero - handle of a corresponding palette
567 // zero - unable to create palette
568 // ----------------------------------------------------------------------------
569 HPALETTE
wxMakeDIBPalette(
570 LPBITMAPINFOHEADER lpInfo
)
580 // since biClrUsed field was filled during the loading of the DIB,
581 // we know it contains the number of colors in the color table.
582 if (lpInfo
->biClrUsed
)
585 npPal = (NPLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
586 (WORD)lpInfo->biClrUsed * sizeof(PALETTEENTRY));
588 npPal
= (LPLOGPALETTE
)malloc(sizeof(LOGPALETTE
) +
589 (WORD
)lpInfo
->biClrUsed
* sizeof(PALETTEENTRY
));
593 npPal
->palVersion
= 0x300;
594 npPal
->palNumEntries
= (WORD
)lpInfo
->biClrUsed
;
596 // get pointer to the color table
597 lpRGB
= (RGBQUAD FAR
*)((LPSTR
)lpInfo
+ lpInfo
->biSize
);
599 // copy colors from the color table to the LogPalette structure
600 for (i
= 0; (DWORD
)i
< lpInfo
->biClrUsed
; i
++, lpRGB
++)
602 npPal
->palPalEntry
[i
].peRed
= lpRGB
->rgbRed
;
603 npPal
->palPalEntry
[i
].peGreen
= lpRGB
->rgbGreen
;
604 npPal
->palPalEntry
[i
].peBlue
= lpRGB
->rgbBlue
;
605 npPal
->palPalEntry
[i
].peFlags
= 0;
608 hLogPal
= CreatePalette((LPLOGPALETTE
)npPal
);
609 // LocalFree((HANDLE)npPal);
614 // 24-bit DIB with no color table. return default palette. Another
615 // option would be to create a 256 color "rainbow" palette to provide
616 // some good color choices.
618 return((HPALETTE
) GetStockObject(DEFAULT_PALETTE
));
622 // ----------------------------------------------------------------------------
626 // ----------------------------------------------------------------------------
627 bool wxLoadIntoBitmap(
635 bool success
= (wxReadDIB(filename
, &hBitmap
, &hPalette
) != 0);
638 DeleteObject(hPalette
);
646 *pal
= new wxPalette
;
647 (*pal
)->SetHPALETTE((WXHPALETTE
) hPalette
);
650 DeleteObject(hPalette
);
658 GetObject(hBitmap
, sizeof(bm
), (LPSTR
)&bm
);
660 bitmap
->SetHBITMAP((WXHBITMAP
) hBitmap
);
661 bitmap
->SetWidth(bm
.bmWidth
);
662 bitmap
->SetHeight(bm
.bmHeight
);
663 bitmap
->SetDepth(bm
.bmPlanes
* bm
.bmBitsPixel
);
664 #if WXWIN_COMPATIBILITY_2
666 #endif // WXWIN_COMPATIBILITY_2
672 // ----------------------------------------------------------------------------
676 // ----------------------------------------------------------------------------
677 wxBitmap
*wxLoadBitmap(
681 wxBitmap
*bitmap
= new wxBitmap
;
682 if (wxLoadIntoBitmap(filename
, bitmap
, pal
))
691 //---------------------------------------------------------------------
692 // FUNCTION : InitBitmapInfoHeader
693 // PURPOSE : Does a "standard" initialization of a BITMAPINFOHEADER,
694 // given the Width, Height, and Bits per Pixel for the DIB.
696 // By standard, I mean that all the relevant fields are set
697 // to the specified values. biSizeImage is computed, the
698 // biCompression field is set to "no compression," and all
699 // other fields are 0.
701 // Note that DIBs only allow BitsPixel values of 1, 4, 8, or
702 // 24. This routine makes sure that one of these values is
703 // used (whichever is most appropriate for the specified
706 // PARMS : lpBmInfoHdr == Far pointer to a BITMAPINFOHEADER structure
708 // dwWidth == Width of DIB (not in Win 3.0 & 3.1, high
710 // dwHeight == Height of DIB (not in Win 3.0 & 3.1, high
712 // nBPP == Bits per Pixel for the DIB.
714 // History: Date Reason
717 //---------------------------------------------------------------------
718 static void InitBitmapInfoHeader (
719 LPBITMAPINFOHEADER lpBmInfoHdr
,
724 // _fmemset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER));
725 memset (lpBmInfoHdr
, 0, sizeof (BITMAPINFOHEADER
));
727 lpBmInfoHdr
->biSize
= sizeof (BITMAPINFOHEADER
);
728 lpBmInfoHdr
->biWidth
= dwWidth
;
729 lpBmInfoHdr
->biHeight
= dwHeight
;
730 lpBmInfoHdr
->biPlanes
= 1;
745 lpBmInfoHdr
->biBitCount
= nBPP
;
746 lpBmInfoHdr
->biSizeImage
= WIDTHBYTES (dwWidth
* nBPP
) * dwHeight
;
749 // ----------------------------------------------------------------------------
753 // ----------------------------------------------------------------------------
754 LPSTR
wxFindDIBBits (LPSTR lpbi
)
756 return (lpbi
+ *(LPDWORD
)lpbi
+ wxPaletteSize (lpbi
));
759 //---------------------------------------------------------------------
760 // Function: BitmapToDIB
762 // Purpose: Given a device dependent bitmap and a palette, returns
763 // a handle to global memory with a DIB spec in it. The
764 // DIB is rendered using the colors of the palette passed in.
766 // Stolen almost verbatim from ShowDIB.
768 // Parms: hBitmap == Handle to device dependent bitmap compatible
769 // with default screen display device.
770 // hPal == Palette to render the DDB with. If it's NULL,
771 // use the default palette.
773 // History: Date Reason
776 //---------------------------------------------------------------------
777 HANDLE
wxBitmapToDIB (
782 BITMAPINFOHEADER bmInfoHdr
;
783 LPBITMAPINFOHEADER lpbmInfoHdr
;
787 HPALETTE hOldPal
= NULL
;
789 // Do some setup -- make sure the Bitmap passed in is valid,
790 // get info on the bitmap (like its height, width, etc.),
791 // then setup a BITMAPINFOHEADER.
796 if (!GetObject (hBitmap
, sizeof (Bitmap
), (LPSTR
) &Bitmap
))
799 InitBitmapInfoHeader (&bmInfoHdr
,
802 Bitmap
.bmPlanes
* Bitmap
.bmBitsPixel
);
805 // Now allocate memory for the DIB. Then, set the BITMAPINFOHEADER
806 // into this memory, and find out where the bitmap bits go.
808 hDIB
= GlobalAlloc (GHND
, sizeof (BITMAPINFOHEADER
) +
809 wxPaletteSize ((LPSTR
) &bmInfoHdr
) + bmInfoHdr
.biSizeImage
);
814 #ifdef __WINDOWS_386__
815 lpbmInfoHdr
= (LPBITMAPINFOHEADER
) MK_FP32(GlobalLock (hDIB
));
817 lpbmInfoHdr
= (LPBITMAPINFOHEADER
) GlobalLock (hDIB
);
820 *lpbmInfoHdr
= bmInfoHdr
;
821 lpBits
= wxFindDIBBits ((LPSTR
) lpbmInfoHdr
);
823 // Now, we need a DC to hold our bitmap. If the app passed us
824 // a palette, it should be selected into the DC.
825 hMemDC
= GetDC (NULL
);
829 hOldPal
= SelectPalette (hMemDC
, hPal
, FALSE
);
830 RealizePalette (hMemDC
);
833 // We're finally ready to get the DIB. Call the driver and let
834 // it party on our bitmap. It will fill in the color table,
835 // and bitmap bits of our global memory block.
836 if (!GetDIBits (hMemDC
,
841 (LPBITMAPINFO
) lpbmInfoHdr
,
851 // Finally, clean up and return.
853 SelectPalette (hMemDC
, hOldPal
, FALSE
);
855 ReleaseDC (NULL
, hMemDC
);
859 // ----------------------------------------------------------------------------
863 // ----------------------------------------------------------------------------
867 wxPalette
*colourmap
)
869 HPALETTE hPalette
= 0;
871 hPalette
= (HPALETTE
) colourmap
->GetHPALETTE();
873 HANDLE dibHandle
= wxBitmapToDIB((HBITMAP
) bitmap
->GetHBITMAP(), hPalette
);
876 bool success
= (WriteDIB(filename
, dibHandle
) != 0);
877 GlobalFree(dibHandle
);