2 * $Id: dib.c,v 1.36 2003/11/08 11:19:47 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.
22 #undef WIN32_LEAN_AND_MEAN
25 #include <win32k/bitmaps.h>
26 #include <win32k/debug.h>
27 #include "../eng/handle.h"
28 #include <ntos/minmax.h>
29 #include <include/error.h>
30 #include <include/inteng.h>
31 #include <include/eng.h>
32 #include <include/dib.h>
33 #include <internal/safe.h>
34 #include <include/surface.h>
35 #include <include/palette.h>
38 #include <win32k/debug1.h>
40 UINT STDCALL
NtGdiSetDIBColorTable(HDC hDC
,
43 CONST RGBQUAD
*Colors
)
46 PALETTEENTRY
* palEntry
;
50 if (!(dc
= (PDC
)AccessUserObject((ULONG
)hDC
))) return 0;
52 if (!(palette
= (PPALOBJ
)PALETTE_LockPalette((ULONG
)dc
->DevInfo
->hpalDefault
)))
54 // GDI_ReleaseObj( hdc );
58 // Transfer color info
60 if (dc
->w
.bitsPerPixel
<= 8)
62 palEntry
= palette
->logpalette
->palPalEntry
+ StartIndex
;
63 if (StartIndex
+ Entries
> (UINT
) (1 << dc
->w
.bitsPerPixel
))
64 Entries
= (1 << dc
->w
.bitsPerPixel
) - StartIndex
;
66 if (StartIndex
+ Entries
> palette
->logpalette
->palNumEntries
)
67 Entries
= palette
->logpalette
->palNumEntries
- StartIndex
;
69 for (end
= Colors
+ Entries
; Colors
< end
; palEntry
++, Colors
++)
71 palEntry
->peRed
= Colors
->rgbRed
;
72 palEntry
->peGreen
= Colors
->rgbGreen
;
73 palEntry
->peBlue
= Colors
->rgbBlue
;
81 PALETTE_UnlockPalette(dc
->DevInfo
->hpalDefault
);
82 // GDI_ReleaseObj(hdc);
87 // Converts a DIB to a device-dependent bitmap
95 CONST BITMAPINFO
*bmi
,
100 HBITMAP SourceBitmap
, DestBitmap
;
103 PSURFOBJ DestSurf
, SourceSurf
;
111 HPALETTE DDB_Palette
, DIB_Palette
;
112 ULONG DDB_Palette_Type
, DIB_Palette_Type
;
113 const BYTE
*vBits
= (const BYTE
*)Bits
;
114 INT scanDirection
= 1, DIBWidth
;
117 if (!(dc
= DC_LockDc(hDC
)))
120 if (!(bitmap
= BITMAPOBJ_LockBitmap(hBitmap
)))
127 //if (ColorUse == DIB_PAL_COLORS)
128 // lpRGB = DIB_MapPaletteColors(hDC, bmi);
130 // lpRGB = &bmi->bmiColors[0];
132 // Create a temporary surface for the destination bitmap
133 DestBitmap
= BitmapToSurf(bitmap
);
135 DestSurf
= (PSURFOBJ
) AccessUserObject( (ULONG
)DestBitmap
);
136 DestGDI
= (PSURFGDI
) AccessInternalObject( (ULONG
)DestBitmap
);
138 // Create source surface
139 SourceSize
.cx
= bmi
->bmiHeader
.biWidth
;
140 SourceSize
.cy
= abs(bmi
->bmiHeader
.biHeight
);
142 // Determine width of DIB
143 DIBWidth
= DIB_GetDIBWidthBytes(SourceSize
.cx
, bmi
->bmiHeader
.biBitCount
);
145 // Determine DIB Vertical Orientation
146 if(bmi
->bmiHeader
.biHeight
> 0)
149 vBits
+= DIBWidth
* bmi
->bmiHeader
.biHeight
- DIBWidth
;
152 SourceBitmap
= EngCreateBitmap(SourceSize
,
153 DIBWidth
* scanDirection
,
154 BitmapFormat(bmi
->bmiHeader
.biBitCount
, bmi
->bmiHeader
.biCompression
),
157 SourceSurf
= (PSURFOBJ
)AccessUserObject((ULONG
)SourceBitmap
);
159 // Destination palette obtained from the hDC
160 hDCPalette
= PALETTE_LockPalette(dc
->DevInfo
->hpalDefault
);
161 if (NULL
== hDCPalette
)
163 EngDeleteSurface(SourceBitmap
);
164 EngDeleteSurface(DestBitmap
);
165 BITMAPOBJ_UnlockBitmap(hBitmap
);
167 SetLastWin32Error(ERROR_INVALID_HANDLE
);
170 DDB_Palette_Type
= hDCPalette
->Mode
;
171 DDB_Palette
= dc
->DevInfo
->hpalDefault
;
172 PALETTE_UnlockPalette(dc
->DevInfo
->hpalDefault
);
174 // Source palette obtained from the BITMAPINFO
175 DIB_Palette
= BuildDIBPalette ( (PBITMAPINFO
)bmi
, (PINT
)&DIB_Palette_Type
);
176 if (NULL
== DIB_Palette
)
178 EngDeleteSurface(SourceBitmap
);
179 EngDeleteSurface(DestBitmap
);
180 BITMAPOBJ_UnlockBitmap(hBitmap
);
182 SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES
);
186 // Determine XLATEOBJ for color translation
187 XlateObj
= IntEngCreateXlate(DDB_Palette_Type
, DIB_Palette_Type
, DDB_Palette
, DIB_Palette
);
188 if (NULL
== XlateObj
)
190 PALETTE_FreePalette(DIB_Palette
);
191 EngDeleteSurface(SourceBitmap
);
192 EngDeleteSurface(DestBitmap
);
193 BITMAPOBJ_UnlockBitmap(hBitmap
);
195 SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES
);
203 // Determine destination rectangle
206 DestRect
.right
= SourceSize
.cx
;
207 DestRect
.bottom
= SourceSize
.cy
;
209 copyBitsResult
= EngCopyBits(DestSurf
, SourceSurf
, NULL
, XlateObj
, &DestRect
, &ZeroPoint
);
211 // If it succeeded, return number of scanlines copies
212 if(copyBitsResult
== TRUE
)
214 result
= SourceSize
.cy
- 1;
218 EngDeleteXlate(XlateObj
);
219 PALETTE_FreePalette(DIB_Palette
);
220 EngDeleteSurface(SourceBitmap
);
221 EngDeleteSurface(DestBitmap
);
223 // if (ColorUse == DIB_PAL_COLORS)
224 // WinFree((LPSTR)lpRGB);
226 BITMAPOBJ_UnlockBitmap(hBitmap
);
233 NtGdiSetDIBitsToDevice(
244 CONST BITMAPINFO
*bmi
,
251 UINT STDCALL
NtGdiGetDIBColorTable(HDC hDC
,
259 // Converts a device-dependent bitmap to a DIB
260 INT STDCALL
NtGdiGetDIBits(HDC hDC
,
265 LPBITMAPINFO UnsafeInfo
,
269 BITMAPCOREHEADER
*Core
;
270 PBITMAPOBJ BitmapObj
;
283 BitmapObj
= BITMAPOBJ_LockBitmap(hBitmap
);
284 if (NULL
== BitmapObj
)
286 SetLastWin32Error(ERROR_INVALID_HANDLE
);
290 RtlZeroMemory(&Info
, sizeof(BITMAPINFO
));
291 Status
= MmCopyFromCaller(&(Info
.bmiHeader
.biSize
),
292 &(UnsafeInfo
->bmiHeader
.biSize
),
294 if (! NT_SUCCESS(Status
))
296 SetLastNtError(Status
);
297 BITMAPOBJ_UnlockBitmap(hBitmap
);
301 /* If the bits are not requested, UnsafeInfo can point to either a
302 BITMAPINFOHEADER or a BITMAPCOREHEADER */
303 if (sizeof(BITMAPINFOHEADER
) != Info
.bmiHeader
.biSize
&&
304 (sizeof(BITMAPCOREHEADER
) != Info
.bmiHeader
.biSize
||
307 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
308 BITMAPOBJ_UnlockBitmap(hBitmap
);
312 Status
= MmCopyFromCaller(&(Info
.bmiHeader
),
313 &(UnsafeInfo
->bmiHeader
),
314 Info
.bmiHeader
.biSize
);
315 if (! NT_SUCCESS(Status
))
317 SetLastNtError(Status
);
318 BITMAPOBJ_UnlockBitmap(hBitmap
);
324 if (sizeof(BITMAPINFOHEADER
) == Info
.bmiHeader
.biSize
)
326 if (0 != Info
.bmiHeader
.biBitCount
)
328 DPRINT("NtGdiGetDIBits(): This operation isn't fully implemented yet.");
332 Info
.bmiHeader
.biWidth
= BitmapObj
->bitmap
.bmWidth
;
333 Info
.bmiHeader
.biHeight
= BitmapObj
->bitmap
.bmHeight
;
334 Info
.bmiHeader
.biPlanes
= BitmapObj
->bitmap
.bmPlanes
;
335 Info
.bmiHeader
.biBitCount
= BitmapObj
->bitmap
.bmBitsPixel
;
336 Info
.bmiHeader
.biCompression
= BI_RGB
;
337 Info
.bmiHeader
.biSizeImage
= BitmapObj
->bitmap
.bmHeight
* BitmapObj
->bitmap
.bmWidthBytes
;
341 Core
= (BITMAPCOREHEADER
*)(&Info
.bmiHeader
);
342 if (0 != Core
->bcBitCount
)
347 Core
->bcWidth
= BitmapObj
->bitmap
.bmWidth
;
348 Core
->bcHeight
= BitmapObj
->bitmap
.bmHeight
;
349 Core
->bcPlanes
= BitmapObj
->bitmap
.bmPlanes
;
350 Core
->bcBitCount
= BitmapObj
->bitmap
.bmBitsPixel
;
353 Status
= MmCopyToCaller(UnsafeInfo
, &Info
, Info
.bmiHeader
.biSize
);
354 if (! NT_SUCCESS(Status
))
356 SetLastNtError(Status
);
357 BITMAPOBJ_UnlockBitmap(hBitmap
);
362 else if (0 == StartScan
&& Info
.bmiHeader
.biHeight
== (LONG
) (StartScan
+ ScanLines
) &&
363 Info
.bmiHeader
.biWidth
== BitmapObj
->bitmap
.bmWidth
&&
364 Info
.bmiHeader
.biHeight
== BitmapObj
->bitmap
.bmHeight
&&
365 Info
.bmiHeader
.biPlanes
== BitmapObj
->bitmap
.bmPlanes
&&
366 Info
.bmiHeader
.biBitCount
== BitmapObj
->bitmap
.bmBitsPixel
&&
367 8 < Info
.bmiHeader
.biBitCount
)
369 Info
.bmiHeader
.biSizeImage
= BitmapObj
->bitmap
.bmHeight
* BitmapObj
->bitmap
.bmWidthBytes
;
370 Status
= MmCopyToCaller(Bits
, BitmapObj
->bitmap
.bmBits
, Info
.bmiHeader
.biSizeImage
);
371 if (! NT_SUCCESS(Status
))
373 SetLastNtError(Status
);
374 BITMAPOBJ_UnlockBitmap(hBitmap
);
377 RtlZeroMemory(&InfoWithBitFields
, sizeof(InfoWithBitFields
));
378 RtlCopyMemory(&(InfoWithBitFields
.Info
), &Info
, sizeof(BITMAPINFO
));
379 if (BI_BITFIELDS
== Info
.bmiHeader
.biCompression
)
381 DCObj
= DC_LockDc(hDC
);
384 SetLastWin32Error(ERROR_INVALID_HANDLE
);
385 BITMAPOBJ_UnlockBitmap(hBitmap
);
388 PalGdi
= PALETTE_LockPalette(DCObj
->w
.hPalette
);
389 BitField
= (DWORD
*) ((char *) &InfoWithBitFields
+ InfoWithBitFields
.Info
.bmiHeader
.biSize
);
390 BitField
[0] = PalGdi
->RedMask
;
391 BitField
[1] = PalGdi
->GreenMask
;
392 BitField
[2] = PalGdi
->BlueMask
;
393 PALETTE_UnlockPalette(DCObj
->w
.hPalette
);
394 InfoSize
= InfoWithBitFields
.Info
.bmiHeader
.biSize
+ 3 * sizeof(DWORD
);
399 InfoSize
= Info
.bmiHeader
.biSize
;
401 Status
= MmCopyToCaller(UnsafeInfo
, &InfoWithBitFields
, InfoSize
);
402 if (! NT_SUCCESS(Status
))
404 SetLastNtError(Status
);
405 BITMAPOBJ_UnlockBitmap(hBitmap
);
414 BITMAPOBJ_UnlockBitmap(hBitmap
);
419 INT STDCALL
NtGdiStretchDIBits(HDC hDC
,
429 CONST BITMAPINFO
*BitsInfo
,
436 LONG STDCALL
NtGdiGetBitmapBits(HBITMAP hBitmap
,
443 bmp
= BITMAPOBJ_LockBitmap (hBitmap
);
449 /* If the bits vector is null, the function should return the read size */
452 return bmp
->bitmap
.bmWidthBytes
* bmp
->bitmap
.bmHeight
;
457 DPRINT ("(%ld): Negative number of bytes passed???\n", Count
);
461 /* Only get entire lines */
462 height
= Count
/ bmp
->bitmap
.bmWidthBytes
;
463 if (height
> bmp
->bitmap
.bmHeight
)
465 height
= bmp
->bitmap
.bmHeight
;
467 Count
= height
* bmp
->bitmap
.bmWidthBytes
;
470 DPRINT("Less then one entire line requested\n");
474 DPRINT("(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
475 hBitmap
, Count
, Bits
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
476 1 << bmp
->bitmap
.bmBitsPixel
, height
);
478 /* FIXME: Call DDI CopyBits here if available */
481 DPRINT("Calling device specific BitmapBits\n");
482 if(bmp
->DDBitmap
->funcs
->pBitmapBits
)
484 ret
= bmp
->DDBitmap
->funcs
->pBitmapBits(hbitmap
, bits
, count
,
489 ERR_(bitmap
)("BitmapBits == NULL??\n");
496 if(!bmp
->bitmap
.bmBits
)
498 DPRINT ("Bitmap is empty\n");
503 memcpy(Bits
, bmp
->bitmap
.bmBits
, Count
);
511 // The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
512 // The DDB that is created will be whatever bit depth your reference DC is
513 HBITMAP STDCALL
NtGdiCreateDIBitmap(HDC hdc
, const BITMAPINFOHEADER
*header
,
514 DWORD init
, LPCVOID bits
, const BITMAPINFO
*data
,
523 if (DIB_GetBitmapInfo( header
, &width
, &height
, &bpp
, &compr
) == -1) return 0;
524 if (height
< 0) height
= -height
;
526 // Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
527 // colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.
529 // Now create the bitmap
530 if (init
== CBM_INIT
)
532 handle
= NtGdiCreateCompatibleBitmap(hdc
, width
, height
);
537 NtGdiSetDIBits(hdc
, handle
, 0, height
, bits
, data
, coloruse
);
541 handle
= NtGdiCreateBitmap(width
, height
, 1, bpp
, NULL
);
547 HBITMAP STDCALL
NtGdiCreateDIBSection(HDC hDC
,
548 CONST BITMAPINFO
*bmi
,
556 BOOL bDesktopDC
= FALSE
;
558 // If the reference hdc is null, take the desktop dc
561 hDC
= NtGdiCreateCompatableDC(0);
565 if ((dc
= DC_LockDc(hDC
)))
567 hbitmap
= DIB_CreateDIBSection ( dc
, (BITMAPINFO
*)bmi
, Usage
, Bits
,
568 hSection
, dwOffset
, 0);
579 DIB_CreateDIBSection(
580 PDC dc
, BITMAPINFO
*bmi
, UINT usage
,
581 LPVOID
*bits
, HANDLE section
,
582 DWORD offset
, DWORD ovr_pitch
)
585 BITMAPOBJ
*bmp
= NULL
;
586 DIBSECTION
*dib
= NULL
;
588 // Fill BITMAP32 structure with DIB data
589 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
595 DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
596 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
597 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
599 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
601 bm
.bmWidth
= bi
->biWidth
;
602 bm
.bmHeight
= effHeight
;
603 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
: (ULONG
) DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
605 bm
.bmPlanes
= bi
->biPlanes
;
606 bm
.bmBitsPixel
= bi
->biBitCount
;
609 // Get storage location for DIB bits. Only use biSizeImage if it's valid and
610 // we're dealing with a compressed bitmap. Otherwise, use width * height.
611 totalSize
= bi
->biSizeImage
&& bi
->biCompression
!= BI_RGB
612 ? bi
->biSizeImage
: (ULONG
) (bm
.bmWidthBytes
* effHeight
);
615 /* bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS,
616 0L, offset, totalSize); */
617 DbgPrint("DIB_CreateDIBSection: Cannot yet handle section DIBs\n");
618 else if (ovr_pitch
&& offset
)
619 bm
.bmBits
= (LPVOID
) offset
;
622 bm
.bmBits
= EngAllocUserMem(totalSize
, 0);
625 /* bm.bmBits = ExAllocatePool(NonPagedPool, totalSize); */
627 if(usage
== DIB_PAL_COLORS
) memcpy(bmi
->bmiColors
, (UINT
*)DIB_MapPaletteColors(dc
, bmi
), sizeof(UINT
*));
629 // Allocate Memory for DIB and fill structure
632 dib
= ExAllocatePool(PagedPool
, sizeof(DIBSECTION
));
633 RtlZeroMemory(dib
, sizeof(DIBSECTION
));
640 dib
->dsBmih
.biSizeImage
= totalSize
;
642 /* Set dsBitfields values */
643 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
645 dib
->dsBitfields
[0] = dib
->dsBitfields
[1] = dib
->dsBitfields
[2] = 0;
647 else switch(bi
->biBitCount
)
650 dib
->dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
651 dib
->dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
652 dib
->dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
656 dib
->dsBitfields
[0] = 0xff;
657 dib
->dsBitfields
[1] = 0xff00;
658 dib
->dsBitfields
[2] = 0xff0000;
662 dib
->dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff;
663 dib
->dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0xff00;
664 dib
->dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0xff0000;
667 dib
->dshSection
= section
;
668 dib
->dsOffset
= offset
;
671 // Create Device Dependent Bitmap and add DIB pointer
674 res
= NtGdiCreateDIBitmap(dc
->hSelf
, bi
, 0, NULL
, bmi
, usage
);
679 bmp
= BITMAPOBJ_LockBitmap(res
);
682 NtGdiDeleteObject(bmp
);
685 bmp
->dib
= (DIBSECTION
*) dib
;
686 /* Install user-mode bits instead of kernel-mode bits */
687 ExFreePool(bmp
->bitmap
.bmBits
);
688 bmp
->bitmap
.bmBits
= bm
.bmBits
;
690 /* WINE NOTE: WINE makes use of a colormap, which is a color translation table between the DIB and the X physical
691 device. Obviously, this is left out of the ReactOS implementation. Instead, we call
692 NtGdiSetDIBColorTable. */
693 if(bi
->biBitCount
== 1) { Entries
= 2; } else
694 if(bi
->biBitCount
== 4) { Entries
= 16; } else
695 if(bi
->biBitCount
== 8) { Entries
= 256; }
697 bmp
->ColorMap
= ExAllocatePool(NonPagedPool
, sizeof(RGBQUAD
)*Entries
);
698 RtlCopyMemory(bmp
->ColorMap
, bmi
->bmiColors
, sizeof(RGBQUAD
)*Entries
);
701 // Clean up in case of errors
702 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
)
704 DPRINT("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n", res
, bmp
, dib
, bm
.bmBits
);
708 UnmapViewOfFile(bm.bmBits), bm.bmBits = NULL;
710 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
713 if (dib
) { ExFreePool(dib
); dib
= NULL
; }
714 if (bmp
) { bmp
= NULL
; }
715 if (res
) { BITMAPOBJ_FreeBitmap(res
); res
= 0; }
720 BITMAPOBJ_UnlockBitmap(res
);
723 // Return BITMAP handle and storage location
724 if (NULL
!= bm
.bmBits
&& NULL
!= bits
)
732 /***********************************************************************
733 * DIB_GetDIBWidthBytes
735 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
736 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
737 * 11/16/1999 (RJJ) lifted from wine
739 INT FASTCALL
DIB_GetDIBWidthBytes (INT width
, INT depth
)
745 case 1: words
= (width
+ 31) / 32; break;
746 case 4: words
= (width
+ 7) / 8; break;
747 case 8: words
= (width
+ 3) / 4; break;
749 case 16: words
= (width
+ 1) / 2; break;
750 case 24: words
= (width
* 3 + 3)/4; break;
753 DPRINT("(%d): Unsupported depth\n", depth
);
761 /***********************************************************************
762 * DIB_GetDIBImageBytes
764 * Return the number of bytes used to hold the image in a DIB bitmap.
765 * 11/16/1999 (RJJ) lifted from wine
768 INT STDCALL
DIB_GetDIBImageBytes (INT width
, INT height
, INT depth
)
770 return DIB_GetDIBWidthBytes( width
, depth
) * (height
< 0 ? -height
: height
);
773 /***********************************************************************
776 * Return the size of the bitmap info structure including color table.
777 * 11/16/1999 (RJJ) lifted from wine
780 INT FASTCALL
DIB_BitmapInfoSize (const BITMAPINFO
* info
, WORD coloruse
)
784 if (info
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
786 BITMAPCOREHEADER
*core
= (BITMAPCOREHEADER
*)info
;
787 colors
= (core
->bcBitCount
<= 8) ? 1 << core
->bcBitCount
: 0;
788 return sizeof(BITMAPCOREHEADER
) + colors
* ((coloruse
== DIB_RGB_COLORS
) ? sizeof(RGBTRIPLE
) : sizeof(WORD
));
790 else /* assume BITMAPINFOHEADER */
792 colors
= info
->bmiHeader
.biClrUsed
;
793 if (!colors
&& (info
->bmiHeader
.biBitCount
<= 8)) colors
= 1 << info
->bmiHeader
.biBitCount
;
794 return sizeof(BITMAPINFOHEADER
) + colors
* ((coloruse
== DIB_RGB_COLORS
) ? sizeof(RGBQUAD
) : sizeof(WORD
));
798 INT STDCALL
DIB_GetBitmapInfo (const BITMAPINFOHEADER
*header
,
804 if (header
->biSize
== sizeof(BITMAPINFOHEADER
))
806 *width
= header
->biWidth
;
807 *height
= header
->biHeight
;
808 *bpp
= header
->biBitCount
;
809 *compr
= header
->biCompression
;
812 if (header
->biSize
== sizeof(BITMAPCOREHEADER
))
814 BITMAPCOREHEADER
*core
= (BITMAPCOREHEADER
*)header
;
815 *width
= core
->bcWidth
;
816 *height
= core
->bcHeight
;
817 *bpp
= core
->bcBitCount
;
821 DPRINT("(%ld): wrong size for header\n", header
->biSize
);
825 // Converts a Device Independent Bitmap (DIB) to a Device Dependant Bitmap (DDB)
826 // The specified Device Context (DC) defines what the DIB should be converted to
827 PBITMAPOBJ FASTCALL
DIBtoDDB(HGLOBAL hPackedDIB
, HDC hdc
) // FIXME: This should be removed. All references to this function should
828 // change to NtGdiSetDIBits
831 PBITMAPOBJ pBmp
= NULL
;
835 // Get a pointer to the packed DIB's data
836 // pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
839 pbits
= (LPBYTE
)(dib
+ DIB_BitmapInfoSize((BITMAPINFO
*)&dib
->dsBmih
, DIB_RGB_COLORS
));
841 // Create a DDB from the DIB
842 hBmp
= NtGdiCreateDIBitmap ( hdc
, &dib
->dsBmih
, CBM_INIT
,
843 (LPVOID
)pbits
, (BITMAPINFO
*)&dib
->dsBmih
, DIB_RGB_COLORS
);
845 // GlobalUnlock(hPackedDIB);
847 // Retrieve the internal Pixmap from the DDB
848 pBmp
= BITMAPOBJ_LockBitmap(hBmp
);
854 DIB_MapPaletteColors(PDC dc
, CONST BITMAPINFO
* lpbmi
)
861 palObj
= (PPALOBJ
) PALETTE_LockPalette(dc
->DevInfo
->hpalDefault
);
865 // RELEASEDCINFO(hDC);
869 nNumColors
= 1 << lpbmi
->bmiHeader
.biBitCount
;
870 if (lpbmi
->bmiHeader
.biClrUsed
)
872 nNumColors
= min(nNumColors
, lpbmi
->bmiHeader
.biClrUsed
);
875 lpRGB
= (RGBQUAD
*)ExAllocatePool(NonPagedPool
, sizeof(RGBQUAD
) * nNumColors
);
876 lpIndex
= (DWORD
*)&lpbmi
->bmiColors
[0];
878 for (i
= 0; i
< nNumColors
; i
++)
880 lpRGB
[i
].rgbRed
= palObj
->logpalette
->palPalEntry
[*lpIndex
].peRed
;
881 lpRGB
[i
].rgbGreen
= palObj
->logpalette
->palPalEntry
[*lpIndex
].peGreen
;
882 lpRGB
[i
].rgbBlue
= palObj
->logpalette
->palPalEntry
[*lpIndex
].peBlue
;
885 // RELEASEDCINFO(hDC);
886 PALETTE_UnlockPalette(dc
->DevInfo
->hpalDefault
);
891 PPALETTEENTRY STDCALL
892 DIBColorTableToPaletteEntries (
893 PPALETTEENTRY palEntries
,
894 const RGBQUAD
*DIBColorTable
,
900 for (i
= 0; i
< ColorCount
; i
++)
902 palEntries
->peRed
= DIBColorTable
->rgbRed
;
903 palEntries
->peGreen
= DIBColorTable
->rgbGreen
;
904 palEntries
->peBlue
= DIBColorTable
->rgbBlue
;
913 BuildDIBPalette (PBITMAPINFO bmi
, PINT paletteType
)
917 PALETTEENTRY
*palEntries
= NULL
;
920 // Determine Bits Per Pixel
921 bits
= bmi
->bmiHeader
.biBitCount
;
923 // Determine paletteType from Bits Per Pixel
926 *paletteType
= PAL_INDEXED
;
930 *paletteType
= PAL_BITFIELDS
;
934 *paletteType
= PAL_BGR
;
937 if (bmi
->bmiHeader
.biClrUsed
== 0)
939 ColorCount
= 1 << bmi
->bmiHeader
.biBitCount
;
943 ColorCount
= bmi
->bmiHeader
.biClrUsed
;
946 if (PAL_INDEXED
== *paletteType
)
948 palEntries
= ExAllocatePool(NonPagedPool
, sizeof(PALETTEENTRY
)*ColorCount
);
949 DIBColorTableToPaletteEntries(palEntries
, bmi
->bmiColors
, ColorCount
);
951 hPal
= PALETTE_AllocPalette( *paletteType
, ColorCount
, (ULONG
*)palEntries
, 0, 0, 0 );
952 if (NULL
!= palEntries
)
954 ExFreePool(palEntries
);