2 * COPYRIGHT: GNU GPL, See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Bitmap functions
5 * FILE: subsys/win32k/objects/bitmaps.c
6 * PROGRAMER: Timo Kreuzer <timo.kreuzer@reactos.org>
22 LONG lDeltaDst
, lDeltaSrc
;
23 ULONG nWidth
, nHeight
, cBitsPixel
;
25 nWidth
= psurf
->SurfObj
.sizlBitmap
.cx
;
26 nHeight
= psurf
->SurfObj
.sizlBitmap
.cy
;
27 cBitsPixel
= BitsPerFormat(psurf
->SurfObj
.iBitmapFormat
);
30 pjDst
= psurf
->SurfObj
.pvScan0
;
32 lDeltaDst
= psurf
->SurfObj
.lDelta
;
33 lDeltaSrc
= WIDTH_BYTES_ALIGN16(nWidth
, cBitsPixel
);
38 memcpy(pjDst
, pjSrc
, lDeltaSrc
);
50 _In_ ULONG cjWidthBytes
,
53 _In_ ULONG cjSizeImage
,
54 _In_opt_ PVOID pvBits
,
61 if (iFormat
< BMF_1BPP
|| iFormat
> BMF_PNG
) return NULL
;
63 /* Allocate a surface */
64 psurf
= SURFACE_AllocSurface(STYPE_BITMAP
, nWidth
, nHeight
, iFormat
);
67 DPRINT1("SURFACE_AllocSurface failed.\n");
71 /* Get the handle for the bitmap */
72 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
74 /* The infamous RLE hack */
75 if (iFormat
== BMF_4RLE
|| iFormat
== BMF_8RLE
)
77 PVOID pvCompressedBits
;
83 lDelta
= WIDTH_BYTES_ALIGN32(nWidth
, gajBitsPerFormat
[iFormat
]);
85 pvCompressedBits
= pvBits
;
86 pvBits
= EngAllocMem(FL_ZERO_MEMORY
, lDelta
* nHeight
, TAG_DIB
);
89 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
90 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
93 DecompressBitmap(sizl
, pvCompressedBits
, pvBits
, lDelta
, iFormat
);
94 fjBitmap
|= BMF_RLE_HACK
;
96 iFormat
= iFormat
== BMF_4RLE
? BMF_4BPP
: BMF_8BPP
;
97 psurf
->SurfObj
.iBitmapFormat
= iFormat
;
100 /* Mark as API bitmap */
101 psurf
->flags
|= (flags
| API_BITMAP
);
103 /* Set the bitmap bits */
104 if (!SURFACE_bSetBitmapBits(psurf
, fjBitmap
, cjWidthBytes
, pvBits
))
106 /* Bail out if that failed */
107 DPRINT1("SURFACE_bSetBitmapBits failed.\n");
108 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
109 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
113 /* Unlock the surface and return */
114 SURFACE_UnlockSurface(psurf
);
118 /* Creates a DDB surface,
119 * as in CreateCompatibleBitmap or CreateBitmap.
120 * Note that each scanline must be 32bit aligned!
128 _In_ ULONG cBitsPixel
,
129 _In_opt_ PVOID pvBits
)
131 /* Call the extended function */
132 return GreCreateBitmapEx(nWidth
,
135 BitmapFormat(cBitsPixel
* cPlanes
, BI_RGB
),
136 0, /* No bitmap flags */
139 DDB_SURFACE
/* DDB */);
149 IN OPTIONAL LPBYTE pUnsafeBits
)
152 ULONG cRealBpp
, cjWidthBytes
, iFormat
;
155 /* Calculate bitmap format and real bits per pixel. */
156 iFormat
= BitmapFormat(cBitsPixel
* cPlanes
, BI_RGB
);
157 cRealBpp
= gajBitsPerFormat
[iFormat
];
159 /* Calculate width and image size in bytes */
160 cjWidthBytes
= WIDTH_BYTES_ALIGN16(nWidth
, cRealBpp
);
161 cjSize
= (ULONGLONG
)cjWidthBytes
* nHeight
;
163 /* Check parameters (possible overflow of cjSize!) */
164 if ((iFormat
== 0) || (nWidth
<= 0) || (nWidth
>= 0x8000000) || (nHeight
<= 0) ||
165 (cBitsPixel
> 32) || (cPlanes
> 32) || (cjSize
>= 0x100000000ULL
))
167 DPRINT1("Invalid bitmap format! Width=%d, Height=%d, Bpp=%d, Planes=%d\n",
168 nWidth
, nHeight
, cBitsPixel
, cPlanes
);
169 EngSetLastError(ERROR_INVALID_PARAMETER
);
173 /* Call internal function. */
174 hbmp
= GreCreateBitmapEx(nWidth
, nHeight
, 0, iFormat
, 0, 0, NULL
, DDB_SURFACE
);
176 if (pUnsafeBits
&& hbmp
)
178 PSURFACE psurf
= SURFACE_ShareLockSurface(hbmp
);
181 ProbeForRead(pUnsafeBits
, (SIZE_T
)cjSize
, 1);
182 UnsafeSetBitmapBits(psurf
, 0, pUnsafeBits
);
184 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
186 GDIOBJ_vDeleteObject(&psurf
->BaseObject
);
187 _SEH2_YIELD(return NULL
;)
191 SURFACE_ShareUnlockSurface(psurf
);
199 IntCreateCompatibleBitmap(
206 /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
207 if (0 == Width
|| 0 == Height
)
209 return NtGdiGetStockObject(DEFAULT_BITMAP
);
212 if (Dc
->dctype
!= DC_TYPE_MEMORY
)
216 Bmp
= GreCreateBitmap(abs(Width
),
219 Dc
->ppdev
->gdiinfo
.cBitsPixel
,
221 psurf
= SURFACE_ShareLockSurface(Bmp
);
224 psurf
->ppal
= PALETTE_ShareLockPalette(Dc
->ppdev
->devinfo
.hpalDefault
);
226 psurf
->flags
= API_BITMAP
;
227 psurf
->hdc
= NULL
; // FIXME:
228 SURFACE_ShareUnlockSurface(psurf
);
234 PSURFACE psurf
= Dc
->dclevel
.pSurface
;
235 Count
= BITMAP_GetObject(psurf
, sizeof(dibs
), &dibs
);
237 if (Count
== sizeof(BITMAP
))
241 Bmp
= GreCreateBitmap(abs(Width
),
244 dibs
.dsBm
.bmBitsPixel
,
246 psurfBmp
= SURFACE_ShareLockSurface(Bmp
);
249 psurfBmp
->ppal
= psurf
->ppal
;
250 GDIOBJ_vReferenceObjectByPointer((POBJ
)psurf
->ppal
);
252 psurfBmp
->flags
= API_BITMAP
;
253 psurfBmp
->hdc
= NULL
; // FIXME:
254 SURFACE_ShareUnlockSurface(psurfBmp
);
256 else if (Count
== sizeof(DIBSECTION
))
258 /* A DIB section is selected in the DC */
259 BYTE buf
[sizeof(BITMAPINFOHEADER
) + 256*sizeof(RGBQUAD
)] = {0};
261 BITMAPINFO
* bi
= (BITMAPINFO
*)buf
;
263 bi
->bmiHeader
.biSize
= sizeof(bi
->bmiHeader
);
264 bi
->bmiHeader
.biWidth
= Width
;
265 bi
->bmiHeader
.biHeight
= Height
;
266 bi
->bmiHeader
.biPlanes
= dibs
.dsBmih
.biPlanes
;
267 bi
->bmiHeader
.biBitCount
= dibs
.dsBmih
.biBitCount
;
268 bi
->bmiHeader
.biCompression
= dibs
.dsBmih
.biCompression
;
269 bi
->bmiHeader
.biSizeImage
= 0;
270 bi
->bmiHeader
.biXPelsPerMeter
= dibs
.dsBmih
.biXPelsPerMeter
;
271 bi
->bmiHeader
.biYPelsPerMeter
= dibs
.dsBmih
.biYPelsPerMeter
;
272 bi
->bmiHeader
.biClrUsed
= dibs
.dsBmih
.biClrUsed
;
273 bi
->bmiHeader
.biClrImportant
= dibs
.dsBmih
.biClrImportant
;
275 if (bi
->bmiHeader
.biCompression
== BI_BITFIELDS
)
277 /* Copy the color masks */
278 RtlCopyMemory(bi
->bmiColors
, dibs
.dsBitfields
, 3*sizeof(RGBQUAD
));
280 else if (bi
->bmiHeader
.biBitCount
<= 8)
282 /* Copy the color table */
288 EngSetLastError(ERROR_INVALID_HANDLE
);
292 PalGDI
= psurf
->ppal
;
295 Index
< 256 && Index
< PalGDI
->NumColors
;
298 bi
->bmiColors
[Index
].rgbRed
= PalGDI
->IndexedColors
[Index
].peRed
;
299 bi
->bmiColors
[Index
].rgbGreen
= PalGDI
->IndexedColors
[Index
].peGreen
;
300 bi
->bmiColors
[Index
].rgbBlue
= PalGDI
->IndexedColors
[Index
].peBlue
;
301 bi
->bmiColors
[Index
].rgbReserved
= 0;
305 Bmp
= DIB_CreateDIBSection(Dc
,
319 NtGdiCreateCompatibleBitmap(
327 if (Width
<= 0 || Height
<= 0 || (Width
* Height
) > 0x3FFFFFFF)
329 EngSetLastError(ERROR_INVALID_PARAMETER
);
334 return GreCreateBitmap(Width
, Height
, 1, 1, 0);
338 DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n",
339 hDC
, Width
, Height
, Dc
->ppdev
->gdiinfo
.cBitsPixel
);
343 EngSetLastError(ERROR_INVALID_HANDLE
);
347 Bmp
= IntCreateCompatibleBitmap(Dc
, Width
, Height
);
349 DPRINT("\t\t%04x\n", Bmp
);
355 NtGdiGetBitmapDimension(
365 psurfBmp
= SURFACE_ShareLockSurface(hBitmap
);
366 if (psurfBmp
== NULL
)
368 EngSetLastError(ERROR_INVALID_HANDLE
);
374 ProbeForWrite(Dimension
, sizeof(SIZE
), 1);
375 *Dimension
= psurfBmp
->sizlDim
;
377 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
383 SURFACE_ShareUnlockSurface(psurfBmp
);
389 NtGdiGetPixel(HDC hDC
, INT XPos
, INT YPos
)
392 COLORREF Result
= (COLORREF
)CLR_INVALID
; // Default to failure
393 BOOL bInRect
= FALSE
;
403 EngSetLastError(ERROR_INVALID_HANDLE
);
407 if (dc
->dctype
== DC_TYPE_INFO
)
413 XPos
+= dc
->ptlDCOrig
.x
;
414 YPos
+= dc
->ptlDCOrig
.y
;
415 if ((dc
->rosdc
.CombinedClip
== NULL
) ||
416 (RECTL_bPointInRect(&dc
->rosdc
.CombinedClip
->rclBounds
, XPos
, YPos
)))
419 psurf
= dc
->dclevel
.pSurface
;
422 pso
= &psurf
->SurfObj
;
423 EXLATEOBJ_vInitialize(&exlo
, psurf
->ppal
, &gpalRGB
, 0, 0xffffff, 0);
424 // Check if this DC has a DIB behind it...
425 if (pso
->pvScan0
) // STYPE_BITMAP == pso->iType
428 Result
= XLATEOBJ_iXlate(&exlo
.xlo
,
429 DibFunctionsForBitmapFormat
[pso
->iBitmapFormat
].DIB_GetPixel(pso
, XPos
, YPos
));
432 EXLATEOBJ_vCleanup(&exlo
);
437 // If Result is still CLR_INVALID, then the "quick" method above didn't work
438 if (bInRect
&& Result
== CLR_INVALID
)
440 // FIXME: create a 1x1 32BPP DIB, and blit to it
441 HDC hDCTmp
= NtGdiCreateCompatibleDC(hDC
);
444 static const BITMAPINFOHEADER bih
= { sizeof(BITMAPINFOHEADER
), 1, 1, 1, 32, BI_RGB
, 0, 0, 0, 0, 0 };
446 RtlMoveMemory(&(bi
.bmiHeader
), &bih
, sizeof(bih
));
447 hBmpTmp
= NtGdiCreateDIBitmapInternal(hDC
,
448 bi
.bmiHeader
.biWidth
,
449 bi
.bmiHeader
.biHeight
,
454 bi
.bmiHeader
.biBitCount
,
455 bi
.bmiHeader
.biSizeImage
,
459 //HBITMAP hBmpTmp = GreCreateBitmap(1, 1, 1, 32, NULL);
462 HBITMAP hBmpOld
= (HBITMAP
)NtGdiSelectBitmap(hDCTmp
, hBmpTmp
);
465 NtGdiBitBlt(hDCTmp
, 0, 0, 1, 1, hDC
, XPos
, YPos
, SRCCOPY
, 0, 0);
466 NtGdiSelectBitmap(hDCTmp
, hBmpOld
);
468 // Our bitmap is no longer selected, so we can access it's stuff...
469 psurf
= SURFACE_ShareLockSurface(hBmpTmp
);
472 // Dont you need to convert something here?
473 Result
= *(COLORREF
*)psurf
->SurfObj
.pvScan0
;
474 SURFACE_ShareUnlockSurface(psurf
);
477 GreDeleteObject(hBmpTmp
);
479 NtGdiDeleteObjectApp(hDCTmp
);
494 LONG lDeltaDst
, lDeltaSrc
;
495 ULONG nWidth
, nHeight
, cBitsPixel
;
497 nWidth
= psurf
->SurfObj
.sizlBitmap
.cx
;
498 nHeight
= psurf
->SurfObj
.sizlBitmap
.cy
;
499 cBitsPixel
= BitsPerFormat(psurf
->SurfObj
.iBitmapFormat
);
502 pjSrc
= psurf
->SurfObj
.pvScan0
;
504 lDeltaSrc
= psurf
->SurfObj
.lDelta
;
505 lDeltaDst
= WIDTH_BYTES_ALIGN16(nWidth
, cBitsPixel
);
510 RtlCopyMemory(pjDst
, pjSrc
, lDeltaDst
);
521 OUT OPTIONAL PBYTE pUnsafeBits
)
527 /* Check parameters */
528 if (pUnsafeBits
!= NULL
&& cjBuffer
== 0)
533 /* Lock the bitmap */
534 psurf
= SURFACE_ShareLockSurface(hBitmap
);
537 EngSetLastError(ERROR_INVALID_HANDLE
);
541 /* Calculate the size of the bitmap in bytes */
542 cjSize
= WIDTH_BYTES_ALIGN16(psurf
->SurfObj
.sizlBitmap
.cx
,
543 BitsPerFormat(psurf
->SurfObj
.iBitmapFormat
)) *
544 abs(psurf
->SurfObj
.sizlBitmap
.cy
);
546 /* If the bits vector is null, the function should return the read size */
547 if (pUnsafeBits
== NULL
)
549 SURFACE_ShareUnlockSurface(psurf
);
553 /* Don't copy more bytes than the buffer has */
554 cjBuffer
= min(cjBuffer
, cjSize
);
556 // FIXME: Use MmSecureVirtualMemory
559 ProbeForWrite(pUnsafeBits
, cjBuffer
, 1);
560 UnsafeGetBitmapBits(psurf
, cjBuffer
, pUnsafeBits
);
563 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
569 SURFACE_ShareUnlockSurface(psurf
);
579 IN PBYTE pUnsafeBits
)
584 if (pUnsafeBits
== NULL
|| Bytes
== 0)
589 psurf
= SURFACE_ShareLockSurface(hBitmap
);
592 EngSetLastError(ERROR_INVALID_HANDLE
);
598 ProbeForRead(pUnsafeBits
, Bytes
, 1);
599 UnsafeSetBitmapBits(psurf
, Bytes
, pUnsafeBits
);
602 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
608 SURFACE_ShareUnlockSurface(psurf
);
614 NtGdiSetBitmapDimension(
626 psurf
= SURFACE_ShareLockSurface(hBitmap
);
629 EngSetLastError(ERROR_INVALID_HANDLE
);
637 ProbeForWrite(Size
, sizeof(SIZE
), 1);
638 *Size
= psurf
->sizlDim
;
640 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
647 /* The dimension is changed even if writing the old value failed */
648 psurf
->sizlDim
.cx
= Width
;
649 psurf
->sizlDim
.cy
= Height
;
651 SURFACE_ShareUnlockSurface(psurf
);
656 VOID
IntHandleSpecialColorType(HDC hDC
, COLORREF
* Color
)
660 PALETTEENTRY palEntry
;
663 switch (*Color
>> 24)
665 case 0x10: /* DIBINDEX */
666 if (IntGetDIBColorTable(hDC
, LOWORD(*Color
), 1, &quad
) == 1)
668 *Color
= RGB(quad
.rgbRed
, quad
.rgbGreen
, quad
.rgbBlue
);
672 /* Out of color table bounds - use black */
673 *Color
= RGB(0, 0, 0);
676 case 0x02: /* PALETTERGB */
677 pdc
= DC_LockDc(hDC
);
678 if (pdc
->dclevel
.hpal
!= NtGdiGetStockObject(DEFAULT_PALETTE
))
680 index
= NtGdiGetNearestPaletteIndex(pdc
->dclevel
.hpal
, *Color
);
681 IntGetPaletteEntries(pdc
->dclevel
.hpal
, index
, 1, &palEntry
);
682 *Color
= RGB(palEntry
.peRed
, palEntry
.peGreen
, palEntry
.peBlue
);
686 /* Use the pure color */
687 *Color
= *Color
& 0x00FFFFFF;
691 case 0x01: /* PALETTEINDEX */
692 pdc
= DC_LockDc(hDC
);
693 if (IntGetPaletteEntries(pdc
->dclevel
.hpal
, LOWORD(*Color
), 1, &palEntry
) == 1)
695 *Color
= RGB(palEntry
.peRed
, palEntry
.peGreen
, palEntry
.peBlue
);
699 /* Index does not exist, use zero index */
700 IntGetPaletteEntries(pdc
->dclevel
.hpal
, 0, 1, &palEntry
);
701 *Color
= RGB(palEntry
.peRed
, palEntry
.peGreen
, palEntry
.peBlue
);
706 DPRINT("Unsupported color type %d passed\n", *Color
>> 24);
721 if ((Color
& 0xFF000000) != 0)
723 IntHandleSpecialColorType(hDC
, &Color
);
726 hBrush
= NtGdiCreateSolidBrush(Color
, NULL
);
730 OldBrush
= NtGdiSelectBrush(hDC
, hBrush
);
731 if (OldBrush
== NULL
)
733 GreDeleteObject(hBrush
);
737 NtGdiPatBlt(hDC
, X
, Y
, 1, 1, PATCOPY
);
738 NtGdiSelectBrush(hDC
, OldBrush
);
739 GreDeleteObject(hBrush
);
751 DPRINT("0 NtGdiSetPixel X %ld Y %ld C %ld\n", X
, Y
, Color
);
753 if (GdiSetPixelV(hDC
,X
,Y
,Color
))
755 Color
= NtGdiGetPixel(hDC
,X
,Y
);
756 DPRINT("1 NtGdiSetPixel X %ld Y %ld C %ld\n", X
, Y
, Color
);
760 Color
= (COLORREF
)CLR_INVALID
;
761 DPRINT("2 NtGdiSetPixel X %ld Y %ld C %ld\n", X
, Y
, Color
);
766 /* Internal Functions */
770 BITMAP_CopyBitmap(HBITMAP hBitmap
)
773 SURFACE
*psurfSrc
, *psurfNew
;
775 /* Fail, if no source bitmap is given */
776 if (hBitmap
== NULL
) return 0;
778 /* Lock the source bitmap */
779 psurfSrc
= SURFACE_ShareLockSurface(hBitmap
);
780 if (psurfSrc
== NULL
)
785 /* Allocate a new bitmap with the same dimensions as the source bmp */
786 hbmNew
= GreCreateBitmapEx(psurfSrc
->SurfObj
.sizlBitmap
.cx
,
787 psurfSrc
->SurfObj
.sizlBitmap
.cy
,
788 abs(psurfSrc
->SurfObj
.lDelta
),
789 psurfSrc
->SurfObj
.iBitmapFormat
,
790 psurfSrc
->SurfObj
.fjBitmap
,
791 psurfSrc
->SurfObj
.cjBits
,
797 /* Lock the new bitmap */
798 psurfNew
= SURFACE_ShareLockSurface(hbmNew
);
801 /* Copy the bitmap bits to the new bitmap buffer */
802 RtlCopyMemory(psurfNew
->SurfObj
.pvBits
,
803 psurfSrc
->SurfObj
.pvBits
,
804 psurfNew
->SurfObj
.cjBits
);
806 /* Dereference the new bitmaps palette, we will use a different */
807 GDIOBJ_vDereferenceObject(&psurfNew
->ppal
->BaseObject
);
809 /* Reference the palette of the source bitmap and use it */
810 GDIOBJ_vReferenceObjectByPointer(&psurfSrc
->ppal
->BaseObject
);
811 psurfNew
->ppal
= psurfSrc
->ppal
;
813 /* Unlock the new surface */
814 SURFACE_ShareUnlockSurface(psurfNew
);
818 /* Failed to lock the bitmap, shouldn't happen */
819 GreDeleteObject(hbmNew
);
824 /* Unlock the source bitmap and return the handle of the new bitmap */
825 SURFACE_ShareUnlockSurface(psurfSrc
);
830 BITMAP_GetObject(SURFACE
*psurf
, INT Count
, LPVOID buffer
)
834 if (!buffer
) return sizeof(BITMAP
);
835 if ((UINT
)Count
< sizeof(BITMAP
)) return 0;
837 /* Always fill a basic BITMAP structure */
840 pBitmap
->bmWidth
= psurf
->SurfObj
.sizlBitmap
.cx
;
841 pBitmap
->bmHeight
= psurf
->SurfObj
.sizlBitmap
.cy
;
842 pBitmap
->bmPlanes
= 1;
843 pBitmap
->bmBitsPixel
= BitsPerFormat(psurf
->SurfObj
.iBitmapFormat
);
844 pBitmap
->bmWidthBytes
= WIDTH_BYTES_ALIGN16(pBitmap
->bmWidth
, pBitmap
->bmBitsPixel
);
846 /* Check for DIB section */
849 /* Set bmBits in this case */
850 pBitmap
->bmBits
= psurf
->SurfObj
.pvBits
;
851 /* DIBs data are 32 bits aligned */
852 pBitmap
->bmWidthBytes
= WIDTH_BYTES_ALIGN32(pBitmap
->bmWidth
, pBitmap
->bmBitsPixel
);
854 if (Count
>= sizeof(DIBSECTION
))
856 /* Fill rest of DIBSECTION */
857 PDIBSECTION pds
= buffer
;
859 pds
->dsBmih
.biSize
= sizeof(BITMAPINFOHEADER
);
860 pds
->dsBmih
.biWidth
= pds
->dsBm
.bmWidth
;
861 pds
->dsBmih
.biHeight
= pds
->dsBm
.bmHeight
;
862 pds
->dsBmih
.biPlanes
= pds
->dsBm
.bmPlanes
;
863 pds
->dsBmih
.biBitCount
= pds
->dsBm
.bmBitsPixel
;
865 switch (psurf
->SurfObj
.iBitmapFormat
)
870 pds
->dsBmih
.biCompression
= BI_RGB
;
874 if (psurf
->ppal
->flFlags
& PAL_RGB16_555
)
875 pds
->dsBmih
.biCompression
= BI_RGB
;
877 pds
->dsBmih
.biCompression
= BI_BITFIELDS
;
882 /* 24/32bpp BI_RGB is actually BGR format */
883 if (psurf
->ppal
->flFlags
& PAL_BGR
)
884 pds
->dsBmih
.biCompression
= BI_RGB
;
886 pds
->dsBmih
.biCompression
= BI_BITFIELDS
;
890 pds
->dsBmih
.biCompression
= BI_RLE4
;
893 pds
->dsBmih
.biCompression
= BI_RLE8
;
896 pds
->dsBmih
.biCompression
= BI_JPEG
;
899 pds
->dsBmih
.biCompression
= BI_PNG
;
902 ASSERT(FALSE
); /* This shouldn't happen */
905 pds
->dsBmih
.biSizeImage
= psurf
->SurfObj
.cjBits
;
906 pds
->dsBmih
.biXPelsPerMeter
= 0;
907 pds
->dsBmih
.biYPelsPerMeter
= 0;
908 pds
->dsBmih
.biClrUsed
= psurf
->ppal
->NumColors
;
909 pds
->dsBmih
.biClrImportant
= psurf
->biClrImportant
;
910 pds
->dsBitfields
[0] = psurf
->ppal
->RedMask
;
911 pds
->dsBitfields
[1] = psurf
->ppal
->GreenMask
;
912 pds
->dsBitfields
[2] = psurf
->ppal
->BlueMask
;
913 pds
->dshSection
= psurf
->hDIBSection
;
914 pds
->dsOffset
= psurf
->dwOffset
;
916 return sizeof(DIBSECTION
);
921 /* Not set according to wine test, confirmed in win2k */
922 pBitmap
->bmBits
= NULL
;
925 return sizeof(BITMAP
);
937 PSURFACE psurf
= SURFACE_ShareLockSurface(hsurf
);
941 SURFACE_ShareUnlockSurface(psurf
);