2 * $Id: dib.c,v 1.51 2004/06/20 00:45:37 navaraf Exp $
4 * ReactOS W32 Subsystem
5 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 NtGdiSetDIBColorTable(HDC hDC
, UINT StartIndex
, UINT Entries
, CONST RGBQUAD
*Colors
)
29 if (!(dc
= DC_LockDc(hDC
))) return 0;
31 BitmapObj
= BITMAPOBJ_LockBitmap(dc
->w
.hBitmap
);
32 if (BitmapObj
== NULL
)
35 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
39 if (BitmapObj
->dib
== NULL
)
41 BITMAPOBJ_UnlockBitmap(dc
->w
.hBitmap
);
43 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
47 if (BitmapObj
->dib
->dsBmih
.biBitCount
<= 8 &&
48 StartIndex
< (1 << BitmapObj
->dib
->dsBmih
.biBitCount
))
50 if (StartIndex
+ Entries
> (1 << BitmapObj
->dib
->dsBmih
.biBitCount
))
51 Entries
= (1 << BitmapObj
->dib
->dsBmih
.biBitCount
) - StartIndex
;
53 MmCopyFromCaller(BitmapObj
->ColorMap
+ StartIndex
, Colors
, Entries
* sizeof(RGBQUAD
));
55 /* Rebuild the palette. */
56 NtGdiDeleteObject(dc
->w
.hPalette
);
57 dc
->w
.hPalette
= PALETTE_AllocPalette(PAL_INDEXED
,
58 1 << BitmapObj
->dib
->dsBmih
.biBitCount
,
59 (PULONG
)BitmapObj
->ColorMap
, 0, 0, 0);
64 BITMAPOBJ_UnlockBitmap(dc
->w
.hBitmap
);
71 NtGdiGetDIBColorTable(HDC hDC
, UINT StartIndex
, UINT Entries
, RGBQUAD
*Colors
)
76 if (!(dc
= DC_LockDc(hDC
))) return 0;
78 BitmapObj
= BITMAPOBJ_LockBitmap(dc
->w
.hBitmap
);
79 if (BitmapObj
== NULL
)
82 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
86 if (BitmapObj
->dib
== NULL
)
88 BITMAPOBJ_UnlockBitmap(dc
->w
.hBitmap
);
90 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
94 if (BitmapObj
->dib
->dsBmih
.biBitCount
<= 8 &&
95 StartIndex
< (1 << BitmapObj
->dib
->dsBmih
.biBitCount
))
97 if (StartIndex
+ Entries
> (1 << BitmapObj
->dib
->dsBmih
.biBitCount
))
98 Entries
= (1 << BitmapObj
->dib
->dsBmih
.biBitCount
) - StartIndex
;
100 MmCopyToCaller(Colors
, BitmapObj
->ColorMap
+ StartIndex
, Entries
* sizeof(RGBQUAD
));
105 BITMAPOBJ_UnlockBitmap(dc
->w
.hBitmap
);
111 // Converts a DIB to a device-dependent bitmap
119 CONST BITMAPINFO
*bmi
,
123 HBITMAP SourceBitmap
, DestBitmap
;
126 SURFOBJ
*DestSurf
, *SourceSurf
;
134 HPALETTE DDB_Palette
, DIB_Palette
;
135 ULONG DDB_Palette_Type
, DIB_Palette_Type
;
136 const BYTE
*vBits
= (const BYTE
*)Bits
;
137 INT scanDirection
= 1, DIBWidth
;
140 if (!(bitmap
= BITMAPOBJ_LockBitmap(hBitmap
)))
146 //if (ColorUse == DIB_PAL_COLORS)
147 // lpRGB = DIB_MapPaletteColors(hDC, bmi);
149 // lpRGB = &bmi->bmiColors[0];
151 // Create a temporary surface for the destination bitmap
152 DestBitmap
= BitmapToSurf(bitmap
, DC
->GDIDevice
);
154 DestSurf
= (SURFOBJ
*) AccessUserObject( (ULONG
)DestBitmap
);
155 DestGDI
= (PSURFGDI
) AccessInternalObjectFromUserObject( DestSurf
);
157 // Create source surface
158 SourceSize
.cx
= bmi
->bmiHeader
.biWidth
;
159 SourceSize
.cy
= abs(bmi
->bmiHeader
.biHeight
);
161 // Determine width of DIB
162 DIBWidth
= DIB_GetDIBWidthBytes(SourceSize
.cx
, bmi
->bmiHeader
.biBitCount
);
164 // Determine DIB Vertical Orientation
165 if(bmi
->bmiHeader
.biHeight
> 0)
168 vBits
+= DIBWidth
* bmi
->bmiHeader
.biHeight
- DIBWidth
;
171 SourceBitmap
= EngCreateBitmap(SourceSize
,
172 DIBWidth
* scanDirection
,
173 BitmapFormat(bmi
->bmiHeader
.biBitCount
, bmi
->bmiHeader
.biCompression
),
176 SourceSurf
= (SURFOBJ
*)AccessUserObject((ULONG
)SourceBitmap
);
178 // Destination palette obtained from the hDC
179 hDCPalette
= PALETTE_LockPalette(DC
->DevInfo
->hpalDefault
);
180 if (NULL
== hDCPalette
)
182 EngDeleteSurface((HSURF
)SourceBitmap
);
183 EngDeleteSurface((HSURF
)DestBitmap
);
184 BITMAPOBJ_UnlockBitmap(hBitmap
);
185 SetLastWin32Error(ERROR_INVALID_HANDLE
);
188 DDB_Palette_Type
= hDCPalette
->Mode
;
189 DDB_Palette
= DC
->DevInfo
->hpalDefault
;
190 PALETTE_UnlockPalette(DC
->DevInfo
->hpalDefault
);
192 // Source palette obtained from the BITMAPINFO
193 DIB_Palette
= BuildDIBPalette ( (PBITMAPINFO
)bmi
, (PINT
)&DIB_Palette_Type
);
194 if (NULL
== DIB_Palette
)
196 EngDeleteSurface((HSURF
)SourceBitmap
);
197 EngDeleteSurface((HSURF
)DestBitmap
);
198 BITMAPOBJ_UnlockBitmap(hBitmap
);
199 SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES
);
203 // Determine XLATEOBJ for color translation
204 XlateObj
= IntEngCreateXlate(DDB_Palette_Type
, DIB_Palette_Type
, DDB_Palette
, DIB_Palette
);
205 if (NULL
== XlateObj
)
207 PALETTE_FreePalette(DIB_Palette
);
208 EngDeleteSurface((HSURF
)SourceBitmap
);
209 EngDeleteSurface((HSURF
)DestBitmap
);
210 BITMAPOBJ_UnlockBitmap(hBitmap
);
211 SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES
);
219 // Determine destination rectangle
222 DestRect
.right
= SourceSize
.cx
;
223 DestRect
.bottom
= SourceSize
.cy
;
225 copyBitsResult
= EngCopyBits(DestSurf
, SourceSurf
, NULL
, XlateObj
, &DestRect
, &ZeroPoint
);
227 // If it succeeded, return number of scanlines copies
228 if(copyBitsResult
== TRUE
)
230 result
= SourceSize
.cy
- 1;
234 EngDeleteXlate(XlateObj
);
235 PALETTE_FreePalette(DIB_Palette
);
236 EngDeleteSurface((HSURF
)SourceBitmap
);
237 EngDeleteSurface((HSURF
)DestBitmap
);
239 // if (ColorUse == DIB_PAL_COLORS)
240 // WinFree((LPSTR)lpRGB);
242 BITMAPOBJ_UnlockBitmap(hBitmap
);
247 // Converts a DIB to a device-dependent bitmap
255 CONST BITMAPINFO
*bmi
,
264 SetLastWin32Error(ERROR_INVALID_HANDLE
);
268 Ret
= IntSetDIBits(Dc
, hBitmap
, StartScan
, ScanLines
, Bits
, bmi
, ColorUse
);
276 NtGdiSetDIBitsToDevice(
287 CONST BITMAPINFO
*bmi
,
294 // Converts a device-dependent bitmap to a DIB
296 INT STDCALL
NtGdiGetDIBits(HDC hDC
,
301 LPBITMAPINFO UnsafeInfo
,
304 INT STDCALL
NtGdiGetDIBits(
305 HDC hdc
, /* [in] Handle to device context */
306 HBITMAP hbitmap
, /* [in] Handle to bitmap */
307 UINT startscan
, /* [in] First scan line to set in dest bitmap */
308 UINT lines
, /* [in] Number of scan lines to copy */
309 LPVOID bits
, /* [out] Address of array for bitmap bits */
310 BITMAPINFO
* info
, /* [out] Address of structure with bitmap data */
311 UINT coloruse
) /* [in] RGB or palette index */
316 BITMAPCOREHEADER
*Core
;
317 PBITMAPOBJ BitmapObj
;
330 BitmapObj
= BITMAPOBJ_LockBitmap(hBitmap
);
331 if (NULL
== BitmapObj
)
333 SetLastWin32Error(ERROR_INVALID_HANDLE
);
337 RtlZeroMemory(&Info
, sizeof(BITMAPINFO
));
338 Status
= MmCopyFromCaller(&(Info
.bmiHeader
.biSize
),
339 &(UnsafeInfo
->bmiHeader
.biSize
),
341 if (! NT_SUCCESS(Status
))
343 SetLastNtError(Status
);
344 BITMAPOBJ_UnlockBitmap(hBitmap
);
348 /* If the bits are not requested, UnsafeInfo can point to either a
349 BITMAPINFOHEADER or a BITMAPCOREHEADER */
350 if (sizeof(BITMAPINFOHEADER
) != Info
.bmiHeader
.biSize
&&
351 (sizeof(BITMAPCOREHEADER
) != Info
.bmiHeader
.biSize
||
354 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
355 BITMAPOBJ_UnlockBitmap(hBitmap
);
359 Status
= MmCopyFromCaller(&(Info
.bmiHeader
),
360 &(UnsafeInfo
->bmiHeader
),
361 Info
.bmiHeader
.biSize
);
362 if (! NT_SUCCESS(Status
))
364 SetLastNtError(Status
);
365 BITMAPOBJ_UnlockBitmap(hBitmap
);
371 if (sizeof(BITMAPINFOHEADER
) == Info
.bmiHeader
.biSize
)
373 if (0 != Info
.bmiHeader
.biBitCount
)
375 DPRINT("NtGdiGetDIBits(): This operation isn't fully implemented yet.");
379 Info
.bmiHeader
.biWidth
= BitmapObj
->bitmap
.bmWidth
;
380 Info
.bmiHeader
.biHeight
= BitmapObj
->bitmap
.bmHeight
;
381 Info
.bmiHeader
.biPlanes
= BitmapObj
->bitmap
.bmPlanes
;
382 Info
.bmiHeader
.biBitCount
= BitmapObj
->bitmap
.bmBitsPixel
;
383 Info
.bmiHeader
.biCompression
= BI_RGB
;
384 Info
.bmiHeader
.biSizeImage
= BitmapObj
->bitmap
.bmHeight
* BitmapObj
->bitmap
.bmWidthBytes
;
388 Core
= (BITMAPCOREHEADER
*)(&Info
.bmiHeader
);
389 if (0 != Core
->bcBitCount
)
394 Core
->bcWidth
= BitmapObj
->bitmap
.bmWidth
;
395 Core
->bcHeight
= BitmapObj
->bitmap
.bmHeight
;
396 Core
->bcPlanes
= BitmapObj
->bitmap
.bmPlanes
;
397 Core
->bcBitCount
= BitmapObj
->bitmap
.bmBitsPixel
;
400 Status
= MmCopyToCaller(UnsafeInfo
, &Info
, Info
.bmiHeader
.biSize
);
401 if (! NT_SUCCESS(Status
))
403 SetLastNtError(Status
);
404 BITMAPOBJ_UnlockBitmap(hBitmap
);
409 else if (0 == StartScan
&& Info
.bmiHeader
.biHeight
== (LONG
) (StartScan
+ ScanLines
) &&
410 Info
.bmiHeader
.biWidth
== BitmapObj
->bitmap
.bmWidth
&&
411 Info
.bmiHeader
.biHeight
== BitmapObj
->bitmap
.bmHeight
&&
412 Info
.bmiHeader
.biPlanes
== BitmapObj
->bitmap
.bmPlanes
&&
413 Info
.bmiHeader
.biBitCount
== BitmapObj
->bitmap
.bmBitsPixel
&&
414 8 < Info
.bmiHeader
.biBitCount
)
416 Info
.bmiHeader
.biSizeImage
= BitmapObj
->bitmap
.bmHeight
* BitmapObj
->bitmap
.bmWidthBytes
;
417 Status
= MmCopyToCaller(Bits
, BitmapObj
->bitmap
.bmBits
, Info
.bmiHeader
.biSizeImage
);
418 if (! NT_SUCCESS(Status
))
420 SetLastNtError(Status
);
421 BITMAPOBJ_UnlockBitmap(hBitmap
);
424 RtlZeroMemory(&InfoWithBitFields
, sizeof(InfoWithBitFields
));
425 RtlCopyMemory(&(InfoWithBitFields
.Info
), &Info
, sizeof(BITMAPINFO
));
426 if (BI_BITFIELDS
== Info
.bmiHeader
.biCompression
)
428 DCObj
= DC_LockDc(hDC
);
431 SetLastWin32Error(ERROR_INVALID_HANDLE
);
432 BITMAPOBJ_UnlockBitmap(hBitmap
);
435 PalGdi
= PALETTE_LockPalette(DCObj
->w
.hPalette
);
436 BitField
= (DWORD
*) ((char *) &InfoWithBitFields
+ InfoWithBitFields
.Info
.bmiHeader
.biSize
);
437 BitField
[0] = PalGdi
->RedMask
;
438 BitField
[1] = PalGdi
->GreenMask
;
439 BitField
[2] = PalGdi
->BlueMask
;
440 PALETTE_UnlockPalette(DCObj
->w
.hPalette
);
441 InfoSize
= InfoWithBitFields
.Info
.bmiHeader
.biSize
+ 3 * sizeof(DWORD
);
446 InfoSize
= Info
.bmiHeader
.biSize
;
448 Status
= MmCopyToCaller(UnsafeInfo
, &InfoWithBitFields
, InfoSize
);
449 if (! NT_SUCCESS(Status
))
451 SetLastNtError(Status
);
452 BITMAPOBJ_UnlockBitmap(hBitmap
);
461 BITMAPOBJ_UnlockBitmap(hBitmap
);
470 if (!(dc
= DC_LockDc( hdc
))) return 0;
471 if (!(bmp
= BITMAPOBJ_LockBitmap(hbitmap
)))
477 /* Transfer color info */
479 if (info
->bmiHeader
.biBitCount
<= 8 && info
->bmiHeader
.biBitCount
> 0 ) {
481 info
->bmiHeader
.biClrUsed
= 0;
483 /* If the bitmap object already has a dib section at the
484 same color depth then get the color map from it */
485 if (bmp
->dib
&& bmp
->dib
->dsBm
.bmBitsPixel
== info
->bmiHeader
.biBitCount
) {
486 NtGdiGetDIBColorTable(hdc
, 0, 1 << info
->bmiHeader
.biBitCount
, info
->bmiColors
);
489 if(info
->bmiHeader
.biBitCount
>= bmp
->bitmap
.bmBitsPixel
) {
490 /* Generate the color map from the selected palette */
491 PALETTEENTRY
* palEntry
;
493 if (!(palette
= PALETTE_LockPalette(dc
->w
.hPalette
))) {
495 BITMAPOBJ_UnlockBitmap( hbitmap
);
498 palEntry
= palette
->IndexedColors
;
499 for (i
= 0; i
< (1 << bmp
->bitmap
.bmBitsPixel
); i
++, palEntry
++) {
500 if (coloruse
== DIB_RGB_COLORS
) {
501 info
->bmiColors
[i
].rgbRed
= palEntry
->peRed
;
502 info
->bmiColors
[i
].rgbGreen
= palEntry
->peGreen
;
503 info
->bmiColors
[i
].rgbBlue
= palEntry
->peBlue
;
504 info
->bmiColors
[i
].rgbReserved
= 0;
506 else ((WORD
*)info
->bmiColors
)[i
] = (WORD
)i
;
508 PALETTE_UnlockPalette( dc
->w
.hPalette
);
510 switch (info
->bmiHeader
.biBitCount
) {
512 info
->bmiColors
[0].rgbRed
= info
->bmiColors
[0].rgbGreen
=
513 info
->bmiColors
[0].rgbBlue
= 0;
514 info
->bmiColors
[0].rgbReserved
= 0;
515 info
->bmiColors
[1].rgbRed
= info
->bmiColors
[1].rgbGreen
=
516 info
->bmiColors
[1].rgbBlue
= 0xff;
517 info
->bmiColors
[1].rgbReserved
= 0;
521 memcpy(info
->bmiColors
, COLOR_GetSystemPaletteTemplate(), NB_RESERVED_COLORS
* sizeof(PALETTEENTRY
));
529 memcpy(info
->bmiColors
, COLOR_GetSystemPaletteTemplate(),
530 10 * sizeof(RGBQUAD
));
531 memcpy(info
->bmiColors
+ 246, COLOR_GetSystemPaletteTemplate() + 10,
532 10 * sizeof(RGBQUAD
));
533 color
= info
->bmiColors
+ 10;
534 for(r
= 0; r
<= 5; r
++) /* FIXME */
535 for(g
= 0; g
<= 5; g
++)
536 for(b
= 0; b
<= 5; b
++) {
537 color
->rgbRed
= (r
* 0xff) / 5;
538 color
->rgbGreen
= (g
* 0xff) / 5;
539 color
->rgbBlue
= (b
* 0xff) / 5;
540 color
->rgbReserved
= 0;
551 /* If the bitmap object already have a dib section that contains image data, get the bits from it */
552 if(bmp
->dib
&& bmp
->dib
->dsBm
.bmBitsPixel
>= 15 && info
->bmiHeader
.biBitCount
>= 15)
554 /*FIXME: Only RGB dibs supported for now */
555 unsigned int srcwidth
= bmp
->dib
->dsBm
.bmWidth
, srcwidthb
= bmp
->dib
->dsBm
.bmWidthBytes
;
556 int dstwidthb
= DIB_GetDIBWidthBytes( info
->bmiHeader
.biWidth
, info
->bmiHeader
.biBitCount
);
557 LPBYTE dbits
= bits
, sbits
= (LPBYTE
) bmp
->dib
->dsBm
.bmBits
+ (startscan
* srcwidthb
);
560 if ((info
->bmiHeader
.biHeight
< 0) ^ (bmp
->dib
->dsBmih
.biHeight
< 0))
562 dbits
= (LPBYTE
)bits
+ (dstwidthb
* (lines
-1));
563 dstwidthb
= -dstwidthb
;
566 switch( info
->bmiHeader
.biBitCount
) {
569 case 16: /* 16 bpp dstDIB */
571 LPWORD dstbits
= (LPWORD
)dbits
;
572 WORD rmask
= 0x7c00, gmask
= 0x03e0, bmask
= 0x001f;
574 /* FIXME: BI_BITFIELDS not supported yet */
576 switch(bmp
->dib
->dsBm
.bmBitsPixel
) {
578 case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
580 /* FIXME: BI_BITFIELDS not supported yet */
581 for (y
= 0; y
< lines
; y
++, dbits
+=dstwidthb
, sbits
+=srcwidthb
)
582 memcpy(dbits
, sbits
, srcwidthb
);
586 case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
588 LPBYTE srcbits
= sbits
;
590 for( y
= 0; y
< lines
; y
++) {
591 for( x
= 0; x
< srcwidth
; x
++, srcbits
+= 3)
592 *dstbits
++ = ((srcbits
[0] >> 3) & bmask
) |
593 (((WORD
)srcbits
[1] << 2) & gmask
) |
594 (((WORD
)srcbits
[2] << 7) & rmask
);
596 dstbits
= (LPWORD
)(dbits
+=dstwidthb
);
597 srcbits
= (sbits
+= srcwidthb
);
602 case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
604 LPDWORD srcbits
= (LPDWORD
)sbits
;
607 for( y
= 0; y
< lines
; y
++) {
608 for( x
= 0; x
< srcwidth
; x
++ ) {
610 *dstbits
++ = (WORD
)(((val
>> 3) & bmask
) | ((val
>> 6) & gmask
) |
611 ((val
>> 9) & rmask
));
613 dstbits
= (LPWORD
)(dbits
+=dstwidthb
);
614 srcbits
= (LPDWORD
)(sbits
+=srcwidthb
);
619 default: /* ? bit bmp -> 16 bit DIB */
620 DPRINT1("FIXME: 15/16 bit DIB %d bit bitmap\n",
621 bmp
->bitmap
.bmBitsPixel
);
627 case 24: /* 24 bpp dstDIB */
629 LPBYTE dstbits
= dbits
;
631 switch(bmp
->dib
->dsBm
.bmBitsPixel
) {
633 case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
635 LPWORD srcbits
= (LPWORD
)sbits
;
638 /* FIXME: BI_BITFIELDS not supported yet */
639 for( y
= 0; y
< lines
; y
++) {
640 for( x
= 0; x
< srcwidth
; x
++ ) {
642 *dstbits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07));
643 *dstbits
++ = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07));
644 *dstbits
++ = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07));
646 dstbits
= (LPBYTE
)(dbits
+=dstwidthb
);
647 srcbits
= (LPWORD
)(sbits
+=srcwidthb
);
652 case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
654 for (y
= 0; y
< lines
; y
++, dbits
+=dstwidthb
, sbits
+=srcwidthb
)
655 memcpy(dbits
, sbits
, srcwidthb
);
659 case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
661 LPBYTE srcbits
= (LPBYTE
)sbits
;
663 for( y
= 0; y
< lines
; y
++) {
664 for( x
= 0; x
< srcwidth
; x
++, srcbits
++ ) {
665 *dstbits
++ = *srcbits
++;
666 *dstbits
++ = *srcbits
++;
667 *dstbits
++ = *srcbits
++;
669 dstbits
=(LPBYTE
)(dbits
+=dstwidthb
);
670 srcbits
= (LPBYTE
)(sbits
+=srcwidthb
);
675 default: /* ? bit bmp -> 24 bit DIB */
676 DPRINT1("FIXME: 24 bit DIB %d bit bitmap\n",
677 bmp
->bitmap
.bmBitsPixel
);
683 case 32: /* 32 bpp dstDIB */
685 LPDWORD dstbits
= (LPDWORD
)dbits
;
687 /* FIXME: BI_BITFIELDS not supported yet */
689 switch(bmp
->dib
->dsBm
.bmBitsPixel
) {
690 case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
692 LPWORD srcbits
= (LPWORD
)sbits
;
695 /* FIXME: BI_BITFIELDS not supported yet */
696 for( y
= 0; y
< lines
; y
++) {
697 for( x
= 0; x
< srcwidth
; x
++ ) {
698 val
= (DWORD
)*srcbits
++;
699 *dstbits
++ = ((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07) |
700 ((val
<< 6) & 0xf800) | ((val
<< 1) & 0x0700) |
701 ((val
<< 9) & 0xf80000) | ((val
<< 4) & 0x070000);
703 dstbits
=(LPDWORD
)(dbits
+=dstwidthb
);
704 srcbits
=(LPWORD
)(sbits
+=srcwidthb
);
709 case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
711 LPBYTE srcbits
= sbits
;
713 for( y
= 0; y
< lines
; y
++) {
714 for( x
= 0; x
< srcwidth
; x
++, srcbits
+=3 )
715 *dstbits
++ = ((DWORD
)*srcbits
) & 0x00ffffff;
716 dstbits
=(LPDWORD
)(dbits
+=dstwidthb
);
717 srcbits
=(sbits
+=srcwidthb
);
722 case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
724 /* FIXME: BI_BITFIELDS not supported yet */
725 for (y
= 0; y
< lines
; y
++, dbits
+=dstwidthb
, sbits
+=srcwidthb
)
726 memcpy(dbits
, sbits
, srcwidthb
);
730 default: /* ? bit bmp -> 32 bit DIB */
731 DPRINT1("FIXME: 32 bit DIB %d bit bitmap\n",
732 bmp
->bitmap
.bmBitsPixel
);
738 default: /* ? bit DIB */
739 DPRINT1("FIXME: Unsupported DIB depth %d\n", info
->bmiHeader
.biBitCount
);
743 /* Otherwise, get bits from the XImage */
749 else if( info
->bmiHeader
.biSize
>= sizeof(BITMAPINFOHEADER
) )
751 /* fill in struct members */
753 if( info
->bmiHeader
.biBitCount
== 0)
755 info
->bmiHeader
.biWidth
= bmp
->bitmap
.bmWidth
;
756 info
->bmiHeader
.biHeight
= bmp
->bitmap
.bmHeight
;
757 info
->bmiHeader
.biPlanes
= 1;
758 info
->bmiHeader
.biBitCount
= bmp
->bitmap
.bmBitsPixel
;
759 info
->bmiHeader
.biSizeImage
=
760 DIB_GetDIBImageBytes( bmp
->bitmap
.bmWidth
,
761 bmp
->bitmap
.bmHeight
,
762 bmp
->bitmap
.bmBitsPixel
);
763 info
->bmiHeader
.biCompression
= 0;
767 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
768 info
->bmiHeader
.biWidth
,
769 info
->bmiHeader
.biHeight
,
770 info
->bmiHeader
.biBitCount
);
775 BITMAPOBJ_UnlockBitmap( hbitmap
);
781 INT STDCALL
NtGdiStretchDIBits(HDC hDC
,
791 CONST BITMAPINFO
*BitsInfo
,
795 HBITMAP hBitmap
, hOldBitmap
;
798 if (!Bits
|| !BitsInfo
)
800 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
804 hdcMem
= NtGdiCreateCompatableDC(hDC
);
805 hBitmap
= NtGdiCreateCompatibleBitmap(hDC
, BitsInfo
->bmiHeader
.biWidth
,
806 BitsInfo
->bmiHeader
.biHeight
);
807 hOldBitmap
= NtGdiSelectObject(hdcMem
, hBitmap
);
809 if (BitsInfo
->bmiHeader
.biCompression
== BI_RLE4
||
810 BitsInfo
->bmiHeader
.biCompression
== BI_RLE8
)
812 /* copy existing bitmap from destination dc */
813 if (SrcWidth
== DestWidth
&& SrcHeight
== DestHeight
)
814 NtGdiBitBlt(hdcMem
, XSrc
, abs(BitsInfo
->bmiHeader
.biHeight
) - SrcHeight
- YSrc
,
815 SrcWidth
, SrcHeight
, hDC
, XDest
, YDest
, ROP
);
817 NtGdiStretchBlt(hdcMem
, XSrc
, abs(BitsInfo
->bmiHeader
.biHeight
) - SrcHeight
- YSrc
,
818 SrcWidth
, SrcHeight
, hDC
, XDest
, YDest
, DestWidth
, DestHeight
,
822 NtGdiSetDIBits(hdcMem
, hBitmap
, 0, BitsInfo
->bmiHeader
.biHeight
, Bits
,
825 /* Origin for DIBitmap may be bottom left (positive biHeight) or top
826 left (negative biHeight) */
827 if (SrcWidth
== DestWidth
&& SrcHeight
== DestHeight
)
828 NtGdiBitBlt(hDC
, XDest
, YDest
, DestWidth
, DestHeight
,
829 hdcMem
, XSrc
, abs(BitsInfo
->bmiHeader
.biHeight
) - SrcHeight
- YSrc
,
832 NtGdiStretchBlt(hDC
, XDest
, YDest
, DestWidth
, DestHeight
,
833 hdcMem
, XSrc
, abs(BitsInfo
->bmiHeader
.biHeight
) - SrcHeight
- YSrc
,
834 SrcWidth
, SrcHeight
, ROP
);
836 NtGdiSelectObject(hdcMem
, hOldBitmap
);
837 NtGdiDeleteDC(hdcMem
);
838 NtGdiDeleteObject(hBitmap
);
843 LONG STDCALL
NtGdiGetBitmapBits(HBITMAP hBitmap
,
850 bmp
= BITMAPOBJ_LockBitmap (hBitmap
);
856 /* If the bits vector is null, the function should return the read size */
859 return bmp
->bitmap
.bmWidthBytes
* bmp
->bitmap
.bmHeight
;
864 DPRINT ("(%ld): Negative number of bytes passed???\n", Count
);
868 /* Only get entire lines */
869 height
= Count
/ bmp
->bitmap
.bmWidthBytes
;
870 if (height
> bmp
->bitmap
.bmHeight
)
872 height
= bmp
->bitmap
.bmHeight
;
874 Count
= height
* bmp
->bitmap
.bmWidthBytes
;
877 DPRINT("Less then one entire line requested\n");
881 DPRINT("(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
882 hBitmap
, Count
, Bits
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
883 1 << bmp
->bitmap
.bmBitsPixel
, height
);
885 /* FIXME: Call DDI CopyBits here if available */
888 DPRINT("Calling device specific BitmapBits\n");
889 if(bmp
->DDBitmap
->funcs
->pBitmapBits
)
891 ret
= bmp
->DDBitmap
->funcs
->pBitmapBits(hbitmap
, bits
, count
,
896 ERR_(bitmap
)("BitmapBits == NULL??\n");
903 if(!bmp
->bitmap
.bmBits
)
905 DPRINT ("Bitmap is empty\n");
910 memcpy(Bits
, bmp
->bitmap
.bmBits
, Count
);
918 static HBITMAP FASTCALL
919 IntCreateDIBitmap(PDC Dc
, const BITMAPINFOHEADER
*header
,
920 DWORD init
, LPCVOID bits
, const BITMAPINFO
*data
,
930 if (DIB_GetBitmapInfo( header
, &width
, &height
, &bpp
, &compr
) == -1) return 0;
931 if (height
< 0) height
= -height
;
933 // Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
934 // colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.
936 if (bpp
!= 1) fColor
= TRUE
;
937 else if ((coloruse
!= DIB_RGB_COLORS
) ||
938 (init
!= CBM_INIT
) || !data
) fColor
= FALSE
;
941 if (data
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))
943 RGBQUAD
*rgb
= data
->bmiColors
;
944 DWORD col
= RGB( rgb
->rgbRed
, rgb
->rgbGreen
, rgb
->rgbBlue
);
946 // Check if the first color of the colormap is black
947 if ((col
== RGB(0, 0, 0)))
950 col
= RGB( rgb
->rgbRed
, rgb
->rgbGreen
, rgb
->rgbBlue
);
952 // If the second color is white, create a monochrome bitmap
953 fColor
= (col
!= RGB(0xff,0xff,0xff));
957 else if (data
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
959 RGBTRIPLE
*rgb
= ((BITMAPCOREINFO
*)data
)->bmciColors
;
960 DWORD col
= RGB( rgb
->rgbtRed
, rgb
->rgbtGreen
, rgb
->rgbtBlue
);
962 if ((col
== RGB(0,0,0)))
965 col
= RGB( rgb
->rgbtRed
, rgb
->rgbtGreen
, rgb
->rgbtBlue
);
966 fColor
= (col
!= RGB(0xff,0xff,0xff));
972 DPRINT("(%ld): wrong size for data\n", data
->bmiHeader
.biSize
);
977 // Now create the bitmap
980 handle
= IntCreateCompatibleBitmap(Dc
, width
, height
);
984 handle
= NtGdiCreateBitmap( width
, height
, 1, 1, NULL
);
987 if (NULL
!= handle
&& CBM_INIT
== init
)
989 IntSetDIBits(Dc
, handle
, 0, height
, bits
, data
, coloruse
);
995 // The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
996 // The DDB that is created will be whatever bit depth your reference DC is
997 HBITMAP STDCALL
NtGdiCreateDIBitmap(HDC hDc
, const BITMAPINFOHEADER
*Header
,
998 DWORD Init
, LPCVOID Bits
, const BITMAPINFO
*Data
,
1004 Dc
= DC_LockDc(hDc
);
1007 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1011 Bmp
= IntCreateDIBitmap(Dc
, Header
, Init
, Bits
, Data
, ColorUse
);
1018 HBITMAP STDCALL
NtGdiCreateDIBSection(HDC hDC
,
1019 CONST BITMAPINFO
*bmi
,
1025 HBITMAP hbitmap
= 0;
1027 BOOL bDesktopDC
= FALSE
;
1029 // If the reference hdc is null, take the desktop dc
1032 hDC
= NtGdiCreateCompatableDC(0);
1036 if ((dc
= DC_LockDc(hDC
)))
1038 hbitmap
= DIB_CreateDIBSection ( dc
, (BITMAPINFO
*)bmi
, Usage
, Bits
,
1039 hSection
, dwOffset
, 0);
1050 DIB_CreateDIBSection(
1051 PDC dc
, BITMAPINFO
*bmi
, UINT usage
,
1052 LPVOID
*bits
, HANDLE section
,
1053 DWORD offset
, DWORD ovr_pitch
)
1056 BITMAPOBJ
*bmp
= NULL
;
1057 DIBSECTION
*dib
= NULL
;
1059 // Fill BITMAP32 structure with DIB data
1060 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
1066 DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
1067 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
1068 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
1070 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
1072 bm
.bmWidth
= bi
->biWidth
;
1073 bm
.bmHeight
= effHeight
;
1074 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
: (ULONG
) DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
1076 bm
.bmPlanes
= bi
->biPlanes
;
1077 bm
.bmBitsPixel
= bi
->biBitCount
;
1080 // Get storage location for DIB bits. Only use biSizeImage if it's valid and
1081 // we're dealing with a compressed bitmap. Otherwise, use width * height.
1082 totalSize
= bi
->biSizeImage
&& bi
->biCompression
!= BI_RGB
1083 ? bi
->biSizeImage
: (ULONG
) (bm
.bmWidthBytes
* effHeight
);
1086 /* bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS,
1087 0L, offset, totalSize); */
1088 DbgPrint("DIB_CreateDIBSection: Cannot yet handle section DIBs\n");
1089 else if (ovr_pitch
&& offset
)
1090 bm
.bmBits
= (LPVOID
) offset
;
1093 bm
.bmBits
= EngAllocUserMem(totalSize
, 0);
1096 /* bm.bmBits = ExAllocatePool(PagedPool, totalSize); */
1098 if(usage
== DIB_PAL_COLORS
)
1099 memcpy(bmi
->bmiColors
, (UINT
*)DIB_MapPaletteColors(dc
, bmi
), sizeof(UINT
*));
1101 // Allocate Memory for DIB and fill structure
1104 dib
= ExAllocatePoolWithTag(PagedPool
, sizeof(DIBSECTION
), TAG_DIB
);
1105 RtlZeroMemory(dib
, sizeof(DIBSECTION
));
1112 dib
->dsBmih
.biSizeImage
= totalSize
;
1114 /* Set dsBitfields values */
1115 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
1117 dib
->dsBitfields
[0] = dib
->dsBitfields
[1] = dib
->dsBitfields
[2] = 0;
1119 else switch(bi
->biBitCount
)
1122 dib
->dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
1123 dib
->dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
1124 dib
->dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f; break;
1127 dib
->dsBitfields
[0] = 0xff;
1128 dib
->dsBitfields
[1] = 0xff00;
1129 dib
->dsBitfields
[2] = 0xff0000;
1133 dib
->dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff;
1134 dib
->dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0xff00;
1135 dib
->dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0xff0000;
1138 dib
->dshSection
= section
;
1139 dib
->dsOffset
= offset
;
1142 // Create Device Dependent Bitmap and add DIB pointer
1145 res
= IntCreateDIBitmap(dc
, bi
, 0, NULL
, bmi
, usage
);
1150 bmp
= BITMAPOBJ_LockBitmap(res
);
1153 NtGdiDeleteObject(bmp
);
1156 bmp
->dib
= (DIBSECTION
*) dib
;
1157 /* Install user-mode bits instead of kernel-mode bits */
1158 ExFreePool(bmp
->bitmap
.bmBits
);
1159 bmp
->bitmap
.bmBits
= bm
.bmBits
;
1161 /* WINE NOTE: WINE makes use of a colormap, which is a color translation table between the DIB and the X physical
1162 device. Obviously, this is left out of the ReactOS implementation. Instead, we call
1163 NtGdiSetDIBColorTable. */
1164 if(bi
->biBitCount
== 1) { Entries
= 2; } else
1165 if(bi
->biBitCount
== 4) { Entries
= 16; } else
1166 if(bi
->biBitCount
== 8) { Entries
= 256; }
1168 bmp
->ColorMap
= ExAllocatePoolWithTag(PagedPool
, sizeof(RGBQUAD
)*Entries
, TAG_COLORMAP
);
1169 RtlCopyMemory(bmp
->ColorMap
, bmi
->bmiColors
, sizeof(RGBQUAD
)*Entries
);
1172 // Clean up in case of errors
1173 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
)
1175 DPRINT("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n", res
, bmp
, dib
, bm
.bmBits
);
1179 UnmapViewOfFile(bm.bmBits), bm.bmBits = NULL;
1181 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
1184 if (dib
) { ExFreePool(dib
); dib
= NULL
; }
1185 if (bmp
) { bmp
= NULL
; }
1186 if (res
) { BITMAPOBJ_FreeBitmap(res
); res
= 0; }
1191 BITMAPOBJ_UnlockBitmap(res
);
1194 // Return BITMAP handle and storage location
1195 if (NULL
!= bm
.bmBits
&& NULL
!= bits
)
1203 /***********************************************************************
1204 * DIB_GetDIBWidthBytes
1206 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
1207 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
1208 * 11/16/1999 (RJJ) lifted from wine
1210 INT FASTCALL
DIB_GetDIBWidthBytes (INT width
, INT depth
)
1216 case 1: words
= (width
+ 31) >> 5; break;
1217 case 4: words
= (width
+ 7) >> 3; break;
1218 case 8: words
= (width
+ 3) >> 2; break;
1220 case 16: words
= (width
+ 1) >> 1; break;
1221 case 24: words
= (width
* 3 + 3) >> 2; break;
1224 DPRINT("(%d): Unsupported depth\n", depth
);
1232 /***********************************************************************
1233 * DIB_GetDIBImageBytes
1235 * Return the number of bytes used to hold the image in a DIB bitmap.
1236 * 11/16/1999 (RJJ) lifted from wine
1239 INT STDCALL
DIB_GetDIBImageBytes (INT width
, INT height
, INT depth
)
1241 return DIB_GetDIBWidthBytes( width
, depth
) * (height
< 0 ? -height
: height
);
1244 /***********************************************************************
1245 * DIB_BitmapInfoSize
1247 * Return the size of the bitmap info structure including color table.
1248 * 11/16/1999 (RJJ) lifted from wine
1251 INT FASTCALL
DIB_BitmapInfoSize (const BITMAPINFO
* info
, WORD coloruse
)
1255 if (info
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
1257 BITMAPCOREHEADER
*core
= (BITMAPCOREHEADER
*)info
;
1258 colors
= (core
->bcBitCount
<= 8) ? 1 << core
->bcBitCount
: 0;
1259 return sizeof(BITMAPCOREHEADER
) + colors
* ((coloruse
== DIB_RGB_COLORS
) ? sizeof(RGBTRIPLE
) : sizeof(WORD
));
1261 else /* assume BITMAPINFOHEADER */
1263 colors
= info
->bmiHeader
.biClrUsed
;
1264 if (!colors
&& (info
->bmiHeader
.biBitCount
<= 8)) colors
= 1 << info
->bmiHeader
.biBitCount
;
1265 return sizeof(BITMAPINFOHEADER
) + colors
* ((coloruse
== DIB_RGB_COLORS
) ? sizeof(RGBQUAD
) : sizeof(WORD
));
1269 INT STDCALL
DIB_GetBitmapInfo (const BITMAPINFOHEADER
*header
,
1275 if (header
->biSize
== sizeof(BITMAPINFOHEADER
))
1277 *width
= header
->biWidth
;
1278 *height
= header
->biHeight
;
1279 *bpp
= header
->biBitCount
;
1280 *compr
= header
->biCompression
;
1283 if (header
->biSize
== sizeof(BITMAPCOREHEADER
))
1285 BITMAPCOREHEADER
*core
= (BITMAPCOREHEADER
*)header
;
1286 *width
= core
->bcWidth
;
1287 *height
= core
->bcHeight
;
1288 *bpp
= core
->bcBitCount
;
1292 DPRINT("(%ld): wrong size for header\n", header
->biSize
);
1296 // Converts a Device Independent Bitmap (DIB) to a Device Dependant Bitmap (DDB)
1297 // The specified Device Context (DC) defines what the DIB should be converted to
1298 PBITMAPOBJ FASTCALL
DIBtoDDB(HGLOBAL hPackedDIB
, HDC hdc
) // FIXME: This should be removed. All references to this function should
1299 // change to NtGdiSetDIBits
1302 PBITMAPOBJ pBmp
= NULL
;
1304 LPBYTE pbits
= NULL
;
1306 // Get a pointer to the packed DIB's data
1307 // pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
1310 pbits
= (LPBYTE
)(dib
+ DIB_BitmapInfoSize((BITMAPINFO
*)&dib
->dsBmih
, DIB_RGB_COLORS
));
1312 // Create a DDB from the DIB
1313 hBmp
= NtGdiCreateDIBitmap ( hdc
, &dib
->dsBmih
, CBM_INIT
,
1314 (LPVOID
)pbits
, (BITMAPINFO
*)&dib
->dsBmih
, DIB_RGB_COLORS
);
1316 // GlobalUnlock(hPackedDIB);
1318 // Retrieve the internal Pixmap from the DDB
1319 pBmp
= BITMAPOBJ_LockBitmap(hBmp
);
1325 DIB_MapPaletteColors(PDC dc
, CONST BITMAPINFO
* lpbmi
)
1332 palGDI
= PALETTE_LockPalette(dc
->w
.hPalette
);
1336 // RELEASEDCINFO(hDC);
1340 nNumColors
= 1 << lpbmi
->bmiHeader
.biBitCount
;
1341 if (lpbmi
->bmiHeader
.biClrUsed
)
1343 nNumColors
= min(nNumColors
, lpbmi
->bmiHeader
.biClrUsed
);
1346 lpRGB
= (RGBQUAD
*)ExAllocatePoolWithTag(PagedPool
, sizeof(RGBQUAD
) * nNumColors
, TAG_COLORMAP
);
1347 lpIndex
= (USHORT
*)&lpbmi
->bmiColors
[0];
1349 for (i
= 0; i
< nNumColors
; i
++)
1351 lpRGB
[i
].rgbRed
= palGDI
->IndexedColors
[*lpIndex
].peRed
;
1352 lpRGB
[i
].rgbGreen
= palGDI
->IndexedColors
[*lpIndex
].peGreen
;
1353 lpRGB
[i
].rgbBlue
= palGDI
->IndexedColors
[*lpIndex
].peBlue
;
1356 // RELEASEDCINFO(hDC);
1357 PALETTE_UnlockPalette(dc
->w
.hPalette
);
1362 PPALETTEENTRY STDCALL
1363 DIBColorTableToPaletteEntries (
1364 PPALETTEENTRY palEntries
,
1365 const RGBQUAD
*DIBColorTable
,
1371 for (i
= 0; i
< ColorCount
; i
++)
1373 palEntries
->peRed
= DIBColorTable
->rgbRed
;
1374 palEntries
->peGreen
= DIBColorTable
->rgbGreen
;
1375 palEntries
->peBlue
= DIBColorTable
->rgbBlue
;
1384 BuildDIBPalette (PBITMAPINFO bmi
, PINT paletteType
)
1388 PALETTEENTRY
*palEntries
= NULL
;
1391 // Determine Bits Per Pixel
1392 bits
= bmi
->bmiHeader
.biBitCount
;
1394 // Determine paletteType from Bits Per Pixel
1397 *paletteType
= PAL_INDEXED
;
1401 *paletteType
= PAL_BITFIELDS
;
1405 *paletteType
= PAL_BGR
;
1408 if (bmi
->bmiHeader
.biClrUsed
== 0)
1410 ColorCount
= 1 << bmi
->bmiHeader
.biBitCount
;
1414 ColorCount
= bmi
->bmiHeader
.biClrUsed
;
1417 if (PAL_INDEXED
== *paletteType
)
1419 palEntries
= ExAllocatePoolWithTag(PagedPool
, sizeof(PALETTEENTRY
)*ColorCount
, TAG_COLORMAP
);
1420 DIBColorTableToPaletteEntries(palEntries
, bmi
->bmiColors
, ColorCount
);
1422 hPal
= PALETTE_AllocPalette( *paletteType
, ColorCount
, (ULONG
*)palEntries
, 0, 0, 0 );
1423 if (NULL
!= palEntries
)
1425 ExFreePool(palEntries
);