1 /*******************************************************************************
5 * DESCRIPTION : Routines for dealing with Device Independent Bitmaps. *
9 * ReadDIB() - Reads a DIB *
11 * WriteDIB() - Writes a global handle in CF_DIB format*
14 * PaletteSize() - Calculates the palette size in bytes *
17 * DibNumColors() - Determines the number of colors in DIB *
19 * DibFromBitmap() - Creates a DIB repr. the DDB passed in. *
22 * lread() - Private routine to read more than 64k *
24 * lwrite() - Private routine to write more than 64k *
26 *******************************************************************************/
28 // For compilers that support precompilation, includes "wx.h".
29 #include "wx/wxprec.h"
31 #if defined(__BORLANDC__)
38 #include "wx/bitmap.h"
45 #if !defined(__MWERKS__) && !defined(__SALFORDC__)
49 #include "wx/msw/dib.h"
52 #ifndef wxUSE_NORLANDER_HEADERS
54 #include "wx/msw/gnuwin32/extra.h"
60 /* flags for _lseek */
66 #define MAXREAD 32768 /* Number of bytes to be read during */
67 /* each read operation. */
69 /* Header signatutes for various resources */
70 #define BFT_ICON 0x4349 /* 'IC' */
71 #define BFT_BITMAP 0x4d42 /* 'BM' */
72 #define BFT_CURSOR 0x5450 /* 'PT' */
74 /* macro to determine if resource is a DIB */
75 #define ISDIB(bft) ((bft) == BFT_BITMAP)
77 /* Macro to align given value to the closest DWORD (unsigned long ) */
78 #define ALIGNULONG(i) ((i+3)/4*4)
80 /* Macro to determine to round off the given value to the closest byte */
81 #define WIDTHBYTES(i) ((i+31)/32*4)
83 #define PALVERSION 0x300
84 #define MAXPALETTE 256 /* max. # supported palette entries */
86 DWORD PASCAL
lread(int fh
, VOID FAR
*pv
, DWORD ul
);
87 DWORD PASCAL
lwrite(int fh
, VOID FAR
*pv
, DWORD ul
);
89 BOOL
WriteDIB (LPTSTR szFile
,HANDLE hdib
);
90 WORD
PaletteSize (VOID FAR
* pv
);
91 WORD
DibNumColors (VOID FAR
* pv
);
92 // HANDLE DibFromBitmap (HBITMAP hbm, DWORD biStyle, WORD biBits, HPALETTE hpal);
93 BOOL PASCAL
MakeBitmapAndPalette(HDC
,HANDLE
,HPALETTE
*,HBITMAP
*);
94 HPALETTE
MakeDIBPalette(LPBITMAPINFOHEADER
);
95 BOOL
ReadDIB(LPTSTR lpFileName
, HBITMAP
*bitmap
, HPALETTE
*palette
);
97 /****************************************************************************
99 * FUNCTION : WriteDIB(LPSTR szFile,HANDLE hdib) *
101 * PURPOSE : Write a global handle in CF_DIB format to a file. *
103 * RETURNS : TRUE - if successful. *
104 * FALSE - otherwise *
106 ****************************************************************************/
108 BOOL
WriteDIB(LPTSTR szFile
, HANDLE hdib
)
110 BITMAPFILEHEADER hdr
;
111 LPBITMAPINFOHEADER lpbi
;
118 fh
= OpenFile(wxFNCONV(szFile
), &of
, OF_CREATE
| OF_READWRITE
);
122 #ifdef __WINDOWS_386__
123 lpbi
= (LPBITMAPINFOHEADER
) MK_FP32(GlobalLock(hdib
));
125 lpbi
= (LPBITMAPINFOHEADER
) GlobalLock(hdib
);
127 /* Fill in the fields of the file header */
128 hdr
.bfType
= BFT_BITMAP
;
129 hdr
.bfSize
= GlobalSize(hdib
) + sizeof(BITMAPFILEHEADER
);
132 hdr
.bfOffBits
= (DWORD
) sizeof(BITMAPFILEHEADER
) + lpbi
->biSize
+
135 /* Write the file header */
136 _lwrite(fh
, (LPSTR
) &hdr
, sizeof(BITMAPFILEHEADER
));
138 /* Write the DIB header and the bits */
139 lwrite(fh
, (LPSTR
) lpbi
, GlobalSize(hdib
));
146 /****************************************************************************
148 * FUNCTION : PaletteSize(VOID FAR * pv) *
150 * PURPOSE : Calculates the palette size in bytes. If the info. block *
151 * is of the BITMAPCOREHEADER type, the number of colors is *
152 * multiplied by 3 to give the palette size, otherwise the *
153 * number of colors is multiplied by 4. *
155 * RETURNS : Palette size in number of bytes. *
157 ****************************************************************************/
159 WORD
PaletteSize(VOID FAR
* pv
)
161 LPBITMAPINFOHEADER lpbi
;
164 lpbi
= (LPBITMAPINFOHEADER
) pv
;
165 NumColors
= DibNumColors(lpbi
);
167 if (lpbi
->biSize
== sizeof(BITMAPCOREHEADER
))
168 return NumColors
* sizeof(RGBTRIPLE
);
170 return NumColors
* sizeof(RGBQUAD
);
173 /****************************************************************************
175 * FUNCTION : DibNumColors(VOID FAR * pv) *
177 * PURPOSE : Determines the number of colors in the DIB by looking at *
178 * the BitCount filed in the info block. *
180 * RETURNS : The number of colors in the DIB. *
182 ****************************************************************************/
184 WORD
DibNumColors(VOID FAR
*pv
)
187 BITMAPINFOHEADER
*lpbi
;
188 BITMAPCOREHEADER
*lpbc
;
190 lpbi
= ((BITMAPINFOHEADER
*) pv
);
191 lpbc
= ((BITMAPCOREHEADER
*) pv
);
193 /* With the BITMAPINFO format headers, the size of the palette
194 * is in biClrUsed, whereas in the BITMAPCORE - style headers, it
195 * is dependent on the bits per pixel ( = 2 raised to the power of
198 if (lpbi
->biSize
!= sizeof(BITMAPCOREHEADER
)) {
199 if (lpbi
->biClrUsed
!= 0)
200 return (WORD
) lpbi
->biClrUsed
;
201 bits
= lpbi
->biBitCount
;
204 bits
= lpbc
->bcBitCount
;
214 /* A 24 bitcount DIB has no color table */
219 /****************************************************************************
221 * FUNCTION : DibFromBitmap() *
223 * PURPOSE : Will create a global memory block in DIB format that *
224 * represents the Device-dependent bitmap (DDB) passed in. *
226 * RETURNS : A handle to the DIB *
228 ****************************************************************************/
231 HANDLE
DibFromBitmap(HBITMAP hbm
, DWORD biStyle
, WORD biBits
, HPALETTE hpal
)
235 BITMAPINFOHEADER FAR
*lpbi
;
245 hpal
= GetStockObject(DEFAULT_PALETTE
);
247 GetObject(hbm
, sizeof (bm
), (LPSTR
) &bm
);
250 biBits
= bm
.bmPlanes
* bm
.bmBitsPixel
;
252 bi
.biSize
= sizeof(BITMAPINFOHEADER
);
253 bi
.biWidth
= bm
.bmWidth
;
254 bi
.biHeight
= bm
.bmHeight
;
256 bi
.biBitCount
= biBits
;
257 bi
.biCompression
= biStyle
;
259 bi
.biXPelsPerMeter
= 0;
260 bi
.biYPelsPerMeter
= 0;
262 bi
.biClrImportant
= 0;
264 dwLen
= bi
.biSize
+ PaletteSize(&bi
);
266 hdc
= GetDC((HWND
) NULL
);
267 hpal
= SelectPalette(hdc
, hpal
, FALSE
);
270 hdib
= GlobalAlloc(GHND
, dwLen
);
273 SelectPalette(hdc
, hpal
, FALSE
);
274 ReleaseDC(NULL
, hdc
);
278 #ifdef __WINDOWS_386__
279 lpbi
= (BITMAPINFOHEADER FAR
*) MK_FP32(GlobalLock(hdib
));
281 lpbi
= (BITMAPINFOHEADER FAR
*) GlobalLock(hdib
);
286 /* call GetDIBits with a NULL lpBits param, so it will calculate the
287 * biSizeImage field for us
289 GetDIBits(hdc
, hbm
, 0, (WORD
) bi
.biHeight
,
290 NULL
, (LPBITMAPINFO
) lpbi
, DIB_RGB_COLORS
);
295 /* If the driver did not fill in the biSizeImage field, make one up */
296 if (bi
.biSizeImage
== 0) {
297 bi
.biSizeImage
= WIDTHBYTES((DWORD
)bm
.bmWidth
* biBits
) * bm
.bmHeight
;
299 if (biStyle
!= BI_RGB
)
300 bi
.biSizeImage
= (bi
.biSizeImage
* 3) / 2;
303 /* realloc the buffer big enough to hold all the bits */
304 dwLen
= bi
.biSize
+ PaletteSize(&bi
) + bi
.biSizeImage
;
305 if (h
= GlobalReAlloc(hdib
, dwLen
, 0))
311 SelectPalette(hdc
, hpal
, FALSE
);
312 ReleaseDC(NULL
, hdc
);
316 /* call GetDIBits with a NON-NULL lpBits param, and actualy get the
319 #ifdef __WINDOWS_386__
320 lpbi
= (BITMAPINFOHEADER FAR
*) MK_FP32(GlobalLock(hdib
));
322 lpbi
= (BITMAPINFOHEADER FAR
*) GlobalLock(hdib
);
329 (LPSTR
) lpbi
+ (WORD
) lpbi
->biSize
+ PaletteSize(lpbi
),
330 (LPBITMAPINFO
) lpbi
, DIB_RGB_COLORS
) == 0) {
333 SelectPalette(hdc
, hpal
, FALSE
);
334 ReleaseDC((HWND
) NULL
, hdc
);
341 SelectPalette(hdc
, hpal
, FALSE
);
342 ReleaseDC(NULL
, hdc
);
347 /************* PRIVATE ROUTINES TO READ/WRITE MORE THAN 64K ***************/
348 /****************************************************************************
350 * FUNCTION : lread(int fh, VOID FAR *pv, DWORD ul) *
352 * PURPOSE : Reads data in steps of 32k till all the data has been read.*
354 * RETURNS : 0 - If read did not proceed correctly. *
355 * number of bytes read otherwise. *
357 ****************************************************************************/
359 DWORD PASCAL
lread(int fh
, void far
*pv
, DWORD ul
)
362 #if defined(WINNT) || defined(__WIN32__) || defined(__WIN32__) || defined(__WXWINE__)
363 BYTE
*hp
= (BYTE
*) pv
;
365 BYTE huge
*hp
= (BYTE huge
*) pv
;
367 while (ul
> (DWORD
) MAXREAD
) {
368 if (_lread(fh
, (LPSTR
) hp
, (WORD
) MAXREAD
) != MAXREAD
)
373 if (_lread(fh
, (LPSTR
) hp
, (WORD
) ul
) != (WORD
) ul
)
378 /****************************************************************************
380 * FUNCTION : lwrite(int fh, VOID FAR *pv, DWORD ul) *
382 * PURPOSE : Writes data in steps of 32k till all the data is written. *
384 * RETURNS : 0 - If write did not proceed correctly. *
385 * number of bytes written otherwise. *
387 ****************************************************************************/
389 DWORD PASCAL
lwrite(int fh
, VOID FAR
*pv
, DWORD ul
)
392 #if defined(WINNT) || defined(__WIN32__) || defined(__WIN32__) || defined(__WXWINE__)
393 BYTE
*hp
= (BYTE
*) pv
;
395 BYTE huge
*hp
= (BYTE huge
*) pv
;
397 while (ul
> MAXREAD
) {
398 if (_lwrite(fh
, (LPSTR
) hp
, (WORD
) MAXREAD
) != MAXREAD
)
403 if (_lwrite(fh
, (LPSTR
) hp
, (WORD
) ul
) != (WORD
) ul
)
408 /****************************************************************************
410 * FUNCTION : ReadDIB(hWnd)
412 * PURPOSE : Reads a DIB from a file, obtains a handle to its
413 * BITMAPINFO struct. and loads the DIB. Once the DIB
414 * is loaded, the function also creates a bitmap and
415 * palette out of the DIB for a device-dependent form.
417 * RETURNS : TRUE - DIB loaded and bitmap/palette created
418 * The DIBINIT structure pointed to by pInfo is
419 * filled with the appropriate handles.
422 ****************************************************************************/
423 BOOL
ReadDIB(LPTSTR lpFileName
, HBITMAP
*bitmap
, HPALETTE
*palette
)
426 LPBITMAPINFOHEADER lpbi
;
434 BOOL bCoreHead
= FALSE
;
437 /* Open the file and get a handle to it's BITMAPINFO */
439 fh
= OpenFile (wxFNCONV(lpFileName
), &of
, OF_READ
);
441 wsprintf(str
,_T("Can't open file '%s'"), lpFileName
);
442 MessageBox(NULL
, str
, _T("Error"), MB_ICONSTOP
| MB_OK
);
446 hDIB
= GlobalAlloc(GHND
, (DWORD
)(sizeof(BITMAPINFOHEADER
) +
447 256 * sizeof(RGBQUAD
)));
451 #ifdef __WINDOWS_386__
452 lpbi
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock(hDIB
));
454 lpbi
= (LPBITMAPINFOHEADER
)GlobalLock(hDIB
);
457 /* read the BITMAPFILEHEADER */
458 if (sizeof (bf
) != _lread (fh
, (LPSTR
)&bf
, sizeof (bf
)))
461 if (bf
.bfType
!= 0x4d42) /* 'BM' */
464 if (sizeof(BITMAPCOREHEADER
) != _lread (fh
, (LPSTR
)lpbi
, sizeof(BITMAPCOREHEADER
)))
467 if (lpbi
->biSize
== sizeof(BITMAPCOREHEADER
))
469 lpbi
->biSize
= sizeof(BITMAPINFOHEADER
);
470 lpbi
->biBitCount
= ((LPBITMAPCOREHEADER
)lpbi
)->bcBitCount
;
471 lpbi
->biPlanes
= ((LPBITMAPCOREHEADER
)lpbi
)->bcPlanes
;
472 lpbi
->biHeight
= ((LPBITMAPCOREHEADER
)lpbi
)->bcHeight
;
473 lpbi
->biWidth
= ((LPBITMAPCOREHEADER
)lpbi
)->bcWidth
;
478 // get to the start of the header and read INFOHEADER
479 _llseek(fh
,sizeof(BITMAPFILEHEADER
),SEEK_SET
);
480 if (sizeof(BITMAPINFOHEADER
) != _lread (fh
, (LPSTR
)lpbi
, sizeof(BITMAPINFOHEADER
)))
484 nNumColors
= (WORD
)lpbi
->biClrUsed
;
485 if ( nNumColors
== 0 )
487 /* no color table for 24-bit, default size otherwise */
488 if (lpbi
->biBitCount
!= 24)
489 nNumColors
= 1 << lpbi
->biBitCount
; /* standard size table */
492 /* fill in some default values if they are zero */
493 if (lpbi
->biClrUsed
== 0)
494 lpbi
->biClrUsed
= nNumColors
;
496 if (lpbi
->biSizeImage
== 0)
498 lpbi
->biSizeImage
= ((((lpbi
->biWidth
* (DWORD
)lpbi
->biBitCount
) + 31) & ~31) >> 3)
502 /* get a proper-sized buffer for header, color table and bits */
504 hDIB
= GlobalReAlloc(hDIB
, lpbi
->biSize
+
505 nNumColors
* sizeof(RGBQUAD
) +
506 lpbi
->biSizeImage
, 0);
507 if (!hDIB
) /* can't resize buffer for loading */
510 #ifdef __WINDOWS_386__
511 lpbi
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock(hDIB
));
513 lpbi
= (LPBITMAPINFOHEADER
)GlobalLock(hDIB
);
516 /* read the color table */
518 _lread(fh
, (LPSTR
)(lpbi
) + lpbi
->biSize
, nNumColors
* sizeof(RGBQUAD
));
523 RGBTRIPLE FAR
*pTriple
;
525 _lread(fh
, (LPSTR
)(lpbi
) + lpbi
->biSize
, nNumColors
* sizeof(RGBTRIPLE
));
527 pQuad
= (RGBQUAD FAR
*)((LPSTR
)lpbi
+ lpbi
->biSize
);
528 pTriple
= (RGBTRIPLE FAR
*) pQuad
;
529 for (i
= nNumColors
- 1; i
>= 0; i
--)
531 pQuad
[i
].rgbRed
= pTriple
[i
].rgbtRed
;
532 pQuad
[i
].rgbBlue
= pTriple
[i
].rgbtBlue
;
533 pQuad
[i
].rgbGreen
= pTriple
[i
].rgbtGreen
;
534 pQuad
[i
].rgbReserved
= 0;
538 /* offset to the bits from start of DIB header */
539 offBits
= (WORD
)lpbi
->biSize
+ nNumColors
* sizeof(RGBQUAD
);
541 if (bf
.bfOffBits
!= 0L)
543 _llseek(fh
,bf
.bfOffBits
,SEEK_SET
);
546 if (lpbi
->biSizeImage
== lread(fh
, (LPSTR
)lpbi
+ offBits
, lpbi
->biSizeImage
))
551 if (!MakeBitmapAndPalette(hDC
, hDIB
, palette
,
576 /****************************************************************************
578 * FUNCTION : MakeBitmapAndPalette
580 * PURPOSE : Given a DIB, creates a bitmap and corresponding palette
581 * to be used for a device-dependent representation of
584 * RETURNS : TRUE --> success. phPal and phBitmap are filled with
585 * appropriate handles. Caller is responsible
586 * for freeing objects.
587 * FALSE --> unable to create objects. both pointer are
590 ****************************************************************************/
591 BOOL PASCAL
MakeBitmapAndPalette(HDC hDC
, HANDLE hDIB
,
592 HPALETTE
* phPal
, HBITMAP
* phBitmap
)
594 LPBITMAPINFOHEADER lpInfo
;
597 HPALETTE hPalette
, hOldPal
;
600 #ifdef __WINDOWS_386__
601 lpInfo
= (LPBITMAPINFOHEADER
) MK_FP32(GlobalLock(hDIB
));
603 lpInfo
= (LPBITMAPINFOHEADER
) GlobalLock(hDIB
);
606 hPalette
= MakeDIBPalette(lpInfo
);
609 // Need to realize palette for converting DIB to bitmap.
610 hOldPal
= SelectPalette(hDC
, hPalette
, TRUE
);
613 lpBits
= (LPSTR
)lpInfo
+ (WORD
)lpInfo
->biSize
+
614 (WORD
)lpInfo
->biClrUsed
* sizeof(RGBQUAD
);
615 hBitmap
= CreateDIBitmap(hDC
, lpInfo
, CBM_INIT
, lpBits
,
616 (LPBITMAPINFO
)lpInfo
, DIB_RGB_COLORS
);
618 SelectPalette(hDC
, hOldPal
, TRUE
);
622 DeleteObject(hPalette
);
633 /****************************************************************************
635 * FUNCTION : MakeDIBPalette(lpInfo) *
637 * PURPOSE : Given a BITMAPINFOHEADER, create a palette based on
641 * RETURNS : non-zero - handle of a corresponding palette
642 * zero - unable to create palette
644 ****************************************************************************/
645 HPALETTE
MakeDIBPalette(LPBITMAPINFOHEADER lpInfo
)
655 /* since biClrUsed field was filled during the loading of the DIB,
656 ** we know it contains the number of colors in the color table.
658 if (lpInfo
->biClrUsed
)
661 npPal = (NPLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
662 (WORD)lpInfo->biClrUsed * sizeof(PALETTEENTRY));
664 npPal
= (NPLOGPALETTE
)malloc(sizeof(LOGPALETTE
) +
665 (WORD
)lpInfo
->biClrUsed
* sizeof(PALETTEENTRY
));
669 npPal
->palVersion
= 0x300;
670 npPal
->palNumEntries
= (WORD
)lpInfo
->biClrUsed
;
672 /* get pointer to the color table */
673 lpRGB
= (RGBQUAD FAR
*)((LPSTR
)lpInfo
+ lpInfo
->biSize
);
675 /* copy colors from the color table to the LogPalette structure */
676 for (i
= 0; i
< lpInfo
->biClrUsed
; i
++, lpRGB
++)
678 npPal
->palPalEntry
[i
].peRed
= lpRGB
->rgbRed
;
679 npPal
->palPalEntry
[i
].peGreen
= lpRGB
->rgbGreen
;
680 npPal
->palPalEntry
[i
].peBlue
= lpRGB
->rgbBlue
;
681 npPal
->palPalEntry
[i
].peFlags
= 0;
684 hLogPal
= CreatePalette((LPLOGPALETTE
)npPal
);
685 // LocalFree((HANDLE)npPal);
691 /* 24-bit DIB with no color table. return default palette. Another
692 ** option would be to create a 256 color "rainbow" palette to provide
693 ** some good color choices.
696 return((HPALETTE
) GetStockObject(DEFAULT_PALETTE
));
701 bool wxLoadIntoBitmap(wxChar
*filename
, wxBitmap
*bitmap
, wxPalette
**pal
)
706 bool success
= (ReadDIB(filename
, &hBitmap
, &hPalette
) != 0);
710 DeleteObject(hPalette
);
718 *pal
= new wxPalette
;
719 (*pal
)->SetHPALETTE((WXHPALETTE
) hPalette
);
722 DeleteObject(hPalette
);
730 GetObject(hBitmap
, sizeof(bm
), (LPSTR
)&bm
);
732 bitmap
->SetHBITMAP((WXHBITMAP
) hBitmap
);
733 bitmap
->SetWidth(bm
.bmWidth
);
734 bitmap
->SetHeight(bm
.bmHeight
);
735 bitmap
->SetDepth(bm
.bmPlanes
* bm
.bmBitsPixel
);
742 wxBitmap
*wxLoadBitmap(wxChar
*filename
, wxPalette
**pal
)
744 wxBitmap
*bitmap
= new wxBitmap
;
745 if (wxLoadIntoBitmap(filename
, bitmap
, pal
))
754 //---------------------------------------------------------------------
756 // Function: InitBitmapInfoHeader
758 // Purpose: Does a "standard" initialization of a BITMAPINFOHEADER,
759 // given the Width, Height, and Bits per Pixel for the
762 // By standard, I mean that all the relevant fields are set
763 // to the specified values. biSizeImage is computed, the
764 // biCompression field is set to "no compression," and all
765 // other fields are 0.
767 // Note that DIBs only allow BitsPixel values of 1, 4, 8, or
768 // 24. This routine makes sure that one of these values is
769 // used (whichever is most appropriate for the specified
772 // Parms: lpBmInfoHdr == Far pointer to a BITMAPINFOHEADER structure
774 // dwWidth == Width of DIB (not in Win 3.0 & 3.1, high
776 // dwHeight == Height of DIB (not in Win 3.0 & 3.1, high
778 // nBPP == Bits per Pixel for the DIB.
780 // History: Date Reason
783 //---------------------------------------------------------------------
785 void InitBitmapInfoHeader (LPBITMAPINFOHEADER lpBmInfoHdr
,
790 // _fmemset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER));
791 memset (lpBmInfoHdr
, 0, sizeof (BITMAPINFOHEADER
));
793 lpBmInfoHdr
->biSize
= sizeof (BITMAPINFOHEADER
);
794 lpBmInfoHdr
->biWidth
= dwWidth
;
795 lpBmInfoHdr
->biHeight
= dwHeight
;
796 lpBmInfoHdr
->biPlanes
= 1;
811 lpBmInfoHdr
->biBitCount
= nBPP
;
812 lpBmInfoHdr
->biSizeImage
= WIDTHBYTES (dwWidth
* nBPP
) * dwHeight
;
818 LPSTR
FindDIBBits (LPSTR lpbi
)
820 return (lpbi
+ *(LPDWORD
)lpbi
+ PaletteSize (lpbi
));
823 //---------------------------------------------------------------------
825 // Function: BitmapToDIB
827 // Purpose: Given a device dependent bitmap and a palette, returns
828 // a handle to global memory with a DIB spec in it. The
829 // DIB is rendered using the colors of the palette passed in.
831 // Stolen almost verbatim from ShowDIB.
833 // Parms: hBitmap == Handle to device dependent bitmap compatible
834 // with default screen display device.
835 // hPal == Palette to render the DDB with. If it's NULL,
836 // use the default palette.
838 // History: Date Reason
841 //---------------------------------------------------------------------
843 HANDLE
BitmapToDIB (HBITMAP hBitmap
, HPALETTE hPal
)
846 BITMAPINFOHEADER bmInfoHdr
;
847 LPBITMAPINFOHEADER lpbmInfoHdr
;
851 HPALETTE hOldPal
= NULL
;
853 // Do some setup -- make sure the Bitmap passed in is valid,
854 // get info on the bitmap (like its height, width, etc.),
855 // then setup a BITMAPINFOHEADER.
860 if (!GetObject (hBitmap
, sizeof (Bitmap
), (LPSTR
) &Bitmap
))
863 InitBitmapInfoHeader (&bmInfoHdr
,
866 Bitmap
.bmPlanes
* Bitmap
.bmBitsPixel
);
869 // Now allocate memory for the DIB. Then, set the BITMAPINFOHEADER
870 // into this memory, and find out where the bitmap bits go.
872 hDIB
= GlobalAlloc (GHND
, sizeof (BITMAPINFOHEADER
) +
873 PaletteSize ((LPSTR
) &bmInfoHdr
) + bmInfoHdr
.biSizeImage
);
878 #ifdef __WINDOWS_386__
879 lpbmInfoHdr
= (LPBITMAPINFOHEADER
) MK_FP32(GlobalLock (hDIB
));
881 lpbmInfoHdr
= (LPBITMAPINFOHEADER
) GlobalLock (hDIB
);
884 *lpbmInfoHdr
= bmInfoHdr
;
885 lpBits
= FindDIBBits ((LPSTR
) lpbmInfoHdr
);
888 // Now, we need a DC to hold our bitmap. If the app passed us
889 // a palette, it should be selected into the DC.
891 hMemDC
= GetDC (NULL
);
895 hOldPal
= SelectPalette (hMemDC
, hPal
, FALSE
);
896 RealizePalette (hMemDC
);
901 // We're finally ready to get the DIB. Call the driver and let
902 // it party on our bitmap. It will fill in the color table,
903 // and bitmap bits of our global memory block.
905 if (!GetDIBits (hMemDC
,
910 (LPBITMAPINFO
) lpbmInfoHdr
,
921 // Finally, clean up and return.
924 SelectPalette (hMemDC
, hOldPal
, FALSE
);
926 ReleaseDC (NULL
, hMemDC
);
931 bool wxSaveBitmap(wxChar
*filename
, wxBitmap
*bitmap
, wxPalette
*colourmap
)
933 HPALETTE hPalette
= 0;
935 hPalette
= (HPALETTE
) colourmap
->GetHPALETTE();
937 HANDLE dibHandle
= BitmapToDIB((HBITMAP
) bitmap
->GetHBITMAP(), hPalette
);
940 bool success
= (WriteDIB(filename
, dibHandle
) != 0);
941 GlobalFree(dibHandle
);