2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 /* Don't copy more bytes than the buffer has */
32 Bytes
= min(Bytes
, psurf
->SurfObj
.cjBits
);
34 RtlCopyMemory(psurf
->SurfObj
.pvBits
, Bits
, Bytes
);
47 LONG lDeltaDst
, lDeltaSrc
;
48 ULONG nWidth
, nHeight
, cBitsPixel
;
50 nWidth
= psurf
->SurfObj
.sizlBitmap
.cx
;
51 nHeight
= psurf
->SurfObj
.sizlBitmap
.cy
;
52 cBitsPixel
= BitsPerFormat(psurf
->SurfObj
.iBitmapFormat
);
55 pjDst
= psurf
->SurfObj
.pvScan0
;
57 lDeltaDst
= psurf
->SurfObj
.lDelta
;
58 lDeltaSrc
= WIDTH_BYTES_ALIGN16(nWidth
, cBitsPixel
);
63 memcpy(pjDst
, pjSrc
, lDeltaSrc
);
75 IN ULONG cjWidthBytes
,
79 IN OPTIONAL PVOID pvBits
,
87 if (iFormat
< BMF_1BPP
|| iFormat
> BMF_PNG
) return NULL
;
89 /* Allocate a surface */
90 psurf
= SURFACE_AllocSurface(STYPE_BITMAP
, nWidth
, nHeight
, iFormat
);
93 DPRINT1("SURFACE_AllocSurface failed.\n");
97 /* Get the handle for the bitmap and the surfobj */
98 hbmp
= (HBITMAP
)psurf
->SurfObj
.hsurf
;
99 pso
= &psurf
->SurfObj
;
101 /* The infamous RLE hack */
102 if (iFormat
== BMF_4RLE
|| iFormat
== BMF_8RLE
)
104 PVOID pvCompressedBits
;
110 lDelta
= WIDTH_BYTES_ALIGN32(nWidth
, gajBitsPerFormat
[iFormat
]);
112 pvCompressedBits
= pvBits
;
113 pvBits
= EngAllocMem(FL_ZERO_MEMORY
, lDelta
* nHeight
, TAG_DIB
);
116 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
117 SURFACE_FreeSurfaceByHandle(hbmp
);
120 DecompressBitmap(sizl
, pvCompressedBits
, pvBits
, lDelta
, iFormat
);
121 fjBitmap
|= BMF_RLE_HACK
;
123 iFormat
= iFormat
== BMF_4RLE
? BMF_4BPP
: BMF_8BPP
;
124 psurf
->SurfObj
.iBitmapFormat
= iFormat
;
127 /* Mark as API bitmap */
128 psurf
->flags
|= (flags
| API_BITMAP
);
130 /* Set the bitmap bits */
131 if (!SURFACE_bSetBitmapBits(psurf
, fjBitmap
, cjWidthBytes
, pvBits
))
133 /* Bail out if that failed */
134 DPRINT1("SURFACE_bSetBitmapBits failed.\n");
135 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
136 SURFACE_FreeSurfaceByHandle(hbmp
);
140 /* Unlock the surface and return */
141 SURFACE_UnlockSurface(psurf
);
145 /* Creates a DDB surface,
146 * as in CreateCompatibleBitmap or CreateBitmap.
155 IN OPTIONAL PVOID pvBits
)
157 /* Call the extended function */
158 return GreCreateBitmapEx(nWidth
,
161 BitmapFormat(cBitsPixel
* cPlanes
, BI_RGB
),
162 0, /* no bitmap flags */
165 DDB_SURFACE
/* DDB */);
175 IN OPTIONAL LPBYTE pUnsafeBits
)
178 ULONG cRealBpp
, cjWidthBytes
, iFormat
;
181 /* Calculate bitmap format and real bits per pixel. */
182 iFormat
= BitmapFormat(cBitsPixel
* cPlanes
, BI_RGB
);
183 cRealBpp
= gajBitsPerFormat
[iFormat
];
185 /* Calculate width and image size in bytes */
186 cjWidthBytes
= WIDTH_BYTES_ALIGN16(nWidth
, cRealBpp
);
187 cjSize
= cjWidthBytes
* nHeight
;
189 /* Check parameters (possible overflow of cjWidthBytes!) */
190 if (iFormat
== 0 || nWidth
<= 0 || nWidth
>= 0x8000000 || nHeight
<= 0 ||
191 cBitsPixel
> 32 || cPlanes
> 32 || cjSize
>= 0x100000000ULL
)
193 DPRINT1("Invalid bitmap format! Width=%d, Height=%d, Bpp=%d, Planes=%d\n",
194 nWidth
, nHeight
, cBitsPixel
, cPlanes
);
195 EngSetLastError(ERROR_INVALID_PARAMETER
);
199 /* Call internal function. */
200 hbmp
= GreCreateBitmapEx(nWidth
, nHeight
, 0, iFormat
, 0, 0, NULL
, DDB_SURFACE
);
202 if (pUnsafeBits
&& hbmp
)
204 PSURFACE psurf
= SURFACE_LockSurface(hbmp
);
207 ProbeForRead(pUnsafeBits
, cjSize
, 1);
208 UnsafeSetBitmapBits(psurf
, 0, pUnsafeBits
);
210 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
212 SURFACE_UnlockSurface(psurf
);
213 SURFACE_FreeSurfaceByHandle(hbmp
);
214 _SEH2_YIELD(return NULL
;)
218 SURFACE_UnlockSurface(psurf
);
226 IntCreateCompatibleBitmap(
233 /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
234 if (0 == Width
|| 0 == Height
)
236 return NtGdiGetStockObject(DEFAULT_BITMAP
);
239 if (Dc
->dctype
!= DC_TYPE_MEMORY
)
243 Bmp
= GreCreateBitmap(abs(Width
),
246 Dc
->ppdev
->gdiinfo
.cBitsPixel
,
248 psurf
= SURFACE_ShareLockSurface(Bmp
);
251 psurf
->ppal
= PALETTE_ShareLockPalette(Dc
->ppdev
->devinfo
.hpalDefault
);
253 psurf
->flags
= API_BITMAP
;
254 psurf
->hdc
= NULL
; // Fixme
255 SURFACE_ShareUnlockSurface(psurf
);
261 PSURFACE psurf
= Dc
->dclevel
.pSurface
;
262 Count
= BITMAP_GetObject(psurf
, sizeof(dibs
), &dibs
);
264 if (Count
== sizeof(BITMAP
))
268 Bmp
= GreCreateBitmap(abs(Width
),
271 dibs
.dsBm
.bmBitsPixel
,
273 psurfBmp
= SURFACE_LockSurface(Bmp
);
276 psurfBmp
->ppal
= psurf
->ppal
;
277 GDIOBJ_IncrementShareCount((POBJ
)psurf
->ppal
);
279 psurfBmp
->flags
= API_BITMAP
;
280 psurfBmp
->hdc
= NULL
; // Fixme
281 SURFACE_UnlockSurface(psurfBmp
);
283 else if (Count
== sizeof(DIBSECTION
))
285 /* A DIB section is selected in the DC */
286 BYTE buf
[sizeof(BITMAPINFOHEADER
) + 256*sizeof(RGBQUAD
)] = {0};
288 BITMAPINFO
* bi
= (BITMAPINFO
*)buf
;
290 bi
->bmiHeader
.biSize
= sizeof(bi
->bmiHeader
);
291 bi
->bmiHeader
.biWidth
= Width
;
292 bi
->bmiHeader
.biHeight
= Height
;
293 bi
->bmiHeader
.biPlanes
= dibs
.dsBmih
.biPlanes
;
294 bi
->bmiHeader
.biBitCount
= dibs
.dsBmih
.biBitCount
;
295 bi
->bmiHeader
.biCompression
= dibs
.dsBmih
.biCompression
;
296 bi
->bmiHeader
.biSizeImage
= 0;
297 bi
->bmiHeader
.biXPelsPerMeter
= dibs
.dsBmih
.biXPelsPerMeter
;
298 bi
->bmiHeader
.biYPelsPerMeter
= dibs
.dsBmih
.biYPelsPerMeter
;
299 bi
->bmiHeader
.biClrUsed
= dibs
.dsBmih
.biClrUsed
;
300 bi
->bmiHeader
.biClrImportant
= dibs
.dsBmih
.biClrImportant
;
302 if (bi
->bmiHeader
.biCompression
== BI_BITFIELDS
)
304 /* Copy the color masks */
305 RtlCopyMemory(bi
->bmiColors
, dibs
.dsBitfields
, 3*sizeof(RGBQUAD
));
307 else if (bi
->bmiHeader
.biBitCount
<= 8)
309 /* Copy the color table */
315 EngSetLastError(ERROR_INVALID_HANDLE
);
319 PalGDI
= PALETTE_LockPalette(psurf
->ppal
->BaseObject
.hHmgr
);
322 Index
< 256 && Index
< PalGDI
->NumColors
;
325 bi
->bmiColors
[Index
].rgbRed
= PalGDI
->IndexedColors
[Index
].peRed
;
326 bi
->bmiColors
[Index
].rgbGreen
= PalGDI
->IndexedColors
[Index
].peGreen
;
327 bi
->bmiColors
[Index
].rgbBlue
= PalGDI
->IndexedColors
[Index
].peBlue
;
328 bi
->bmiColors
[Index
].rgbReserved
= 0;
330 PALETTE_UnlockPalette(PalGDI
);
333 Bmp
= DIB_CreateDIBSection(Dc
,
347 NtGdiCreateCompatibleBitmap(
355 if (Width
<= 0 || Height
<= 0 || (Width
* Height
) > 0x3FFFFFFF)
357 EngSetLastError(ERROR_INVALID_PARAMETER
);
362 return GreCreateBitmap(Width
, Height
, 1, 1, 0);
366 DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n",
367 hDC
, Width
, Height
, Dc
->ppdev
->gdiinfo
.cBitsPixel
);
371 EngSetLastError(ERROR_INVALID_HANDLE
);
375 Bmp
= IntCreateCompatibleBitmap(Dc
, Width
, Height
);
377 DPRINT("\t\t%04x\n", Bmp
);
383 NtGdiGetBitmapDimension(
393 psurfBmp
= SURFACE_LockSurface(hBitmap
);
394 if (psurfBmp
== NULL
)
396 EngSetLastError(ERROR_INVALID_HANDLE
);
402 ProbeForWrite(Dimension
, sizeof(SIZE
), 1);
403 *Dimension
= psurfBmp
->sizlDim
;
405 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
411 SURFACE_UnlockSurface(psurfBmp
);
417 NtGdiGetPixel(HDC hDC
, INT XPos
, INT YPos
)
420 COLORREF Result
= (COLORREF
)CLR_INVALID
; // default to failure
421 BOOL bInRect
= FALSE
;
431 EngSetLastError(ERROR_INVALID_HANDLE
);
435 if (dc
->dctype
== DC_TYPE_INFO
)
441 XPos
+= dc
->ptlDCOrig
.x
;
442 YPos
+= dc
->ptlDCOrig
.y
;
443 if ((dc
->rosdc
.CombinedClip
== NULL
) ||
444 (RECTL_bPointInRect(&dc
->rosdc
.CombinedClip
->rclBounds
, XPos
, YPos
)))
447 psurf
= dc
->dclevel
.pSurface
;
450 pso
= &psurf
->SurfObj
;
451 EXLATEOBJ_vInitialize(&exlo
, psurf
->ppal
, &gpalRGB
, 0, 0xffffff, 0);
452 // check if this DC has a DIB behind it...
453 if (pso
->pvScan0
) // STYPE_BITMAP == pso->iType
456 Result
= XLATEOBJ_iXlate(&exlo
.xlo
,
457 DibFunctionsForBitmapFormat
[pso
->iBitmapFormat
].DIB_GetPixel(pso
, XPos
, YPos
));
460 EXLATEOBJ_vCleanup(&exlo
);
465 // if Result is still CLR_INVALID, then the "quick" method above didn't work
466 if (bInRect
&& Result
== CLR_INVALID
)
468 // FIXME: create a 1x1 32BPP DIB, and blit to it
469 HDC hDCTmp
= NtGdiCreateCompatibleDC(hDC
);
472 static const BITMAPINFOHEADER bih
= { sizeof(BITMAPINFOHEADER
), 1, 1, 1, 32, BI_RGB
, 0, 0, 0, 0, 0 };
474 RtlMoveMemory(&(bi
.bmiHeader
), &bih
, sizeof(bih
));
475 hBmpTmp
= NtGdiCreateDIBitmapInternal(hDC
,
476 bi
.bmiHeader
.biWidth
,
477 bi
.bmiHeader
.biHeight
,
482 bi
.bmiHeader
.biBitCount
,
483 bi
.bmiHeader
.biSizeImage
,
487 //HBITMAP hBmpTmp = GreCreateBitmap(1, 1, 1, 32, NULL);
490 HBITMAP hBmpOld
= (HBITMAP
)NtGdiSelectBitmap(hDCTmp
, hBmpTmp
);
495 NtGdiBitBlt(hDCTmp
, 0, 0, 1, 1, hDC
, XPos
, YPos
, SRCCOPY
, 0, 0);
496 NtGdiSelectBitmap(hDCTmp
, hBmpOld
);
498 // our bitmap is no longer selected, so we can access it's stuff...
499 psurf
= SURFACE_LockSurface(hBmpTmp
);
502 // Dont you need to convert something here?
503 Result
= *(COLORREF
*)psurf
->SurfObj
.pvScan0
;
504 SURFACE_UnlockSurface(psurf
);
507 GreDeleteObject(hBmpTmp
);
509 NtGdiDeleteObjectApp(hDCTmp
);
527 /* Don't copy more bytes than the buffer has */
528 Bytes
= min(Bytes
, psurf
->SurfObj
.cjBits
);
531 /* FIXME: Call DDI CopyBits here if available */
534 DPRINT("Calling device specific BitmapBits\n");
535 if (psurf
->DDBitmap
->funcs
->pBitmapBits
)
537 ret
= psurf
->DDBitmap
->funcs
->pBitmapBits(hbitmap
,
544 ERR_(bitmap
)("BitmapBits == NULL??\n");
551 RtlCopyMemory(Bits
, psurf
->SurfObj
.pvBits
, Bytes
);
565 LONG lDeltaDst
, lDeltaSrc
;
566 ULONG nWidth
, nHeight
, cBitsPixel
;
568 nWidth
= psurf
->SurfObj
.sizlBitmap
.cx
;
569 nHeight
= psurf
->SurfObj
.sizlBitmap
.cy
;
570 cBitsPixel
= BitsPerFormat(psurf
->SurfObj
.iBitmapFormat
);
573 pjSrc
= psurf
->SurfObj
.pvScan0
;
575 lDeltaSrc
= psurf
->SurfObj
.lDelta
;
576 lDeltaDst
= WIDTH_BYTES_ALIGN16(nWidth
, cBitsPixel
);
581 RtlCopyMemory(pjDst
, pjSrc
, lDeltaDst
);
591 OUT OPTIONAL PBYTE pUnsafeBits
)
596 if (pUnsafeBits
!= NULL
&& Bytes
== 0)
601 psurf
= SURFACE_LockSurface(hBitmap
);
604 EngSetLastError(ERROR_INVALID_HANDLE
);
608 bmSize
= WIDTH_BYTES_ALIGN16(psurf
->SurfObj
.sizlBitmap
.cx
,
609 BitsPerFormat(psurf
->SurfObj
.iBitmapFormat
)) *
610 abs(psurf
->SurfObj
.sizlBitmap
.cy
);
612 /* If the bits vector is null, the function should return the read size */
613 if (pUnsafeBits
== NULL
)
615 SURFACE_UnlockSurface(psurf
);
619 /* Don't copy more bytes than the buffer has */
620 Bytes
= min(Bytes
, bmSize
);
622 // FIXME: use MmSecureVirtualMemory
625 ProbeForWrite(pUnsafeBits
, Bytes
, 1);
626 UnsafeGetBitmapBits(psurf
, Bytes
, pUnsafeBits
);
629 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
635 SURFACE_UnlockSurface(psurf
);
645 IN PBYTE pUnsafeBits
)
650 if (pUnsafeBits
== NULL
|| Bytes
== 0)
655 psurf
= SURFACE_LockSurface(hBitmap
);
658 EngSetLastError(ERROR_INVALID_HANDLE
);
664 ProbeForRead(pUnsafeBits
, Bytes
, 1);
665 UnsafeSetBitmapBits(psurf
, Bytes
, pUnsafeBits
);
668 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
674 SURFACE_UnlockSurface(psurf
);
680 NtGdiSetBitmapDimension(
692 psurf
= SURFACE_LockSurface(hBitmap
);
695 EngSetLastError(ERROR_INVALID_HANDLE
);
703 ProbeForWrite(Size
, sizeof(SIZE
), 1);
704 *Size
= psurf
->sizlDim
;
706 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
713 /* The dimension is changed even if writing the old value failed */
714 psurf
->sizlDim
.cx
= Width
;
715 psurf
->sizlDim
.cy
= Height
;
717 SURFACE_UnlockSurface(psurf
);
722 VOID
IntHandleSpecialColorType(HDC hDC
, COLORREF
* Color
)
726 PALETTEENTRY palEntry
;
729 switch (*Color
>> 24)
731 case 0x10: /* DIBINDEX */
732 if (IntGetDIBColorTable(hDC
, LOWORD(*Color
), 1, &quad
) == 1)
734 *Color
= RGB(quad
.rgbRed
, quad
.rgbGreen
, quad
.rgbBlue
);
738 /* Out of color table bounds - use black */
739 *Color
= RGB(0, 0, 0);
742 case 0x02: /* PALETTERGB */
743 pdc
= DC_LockDc(hDC
);
744 if (pdc
->dclevel
.hpal
!= NtGdiGetStockObject(DEFAULT_PALETTE
))
746 index
= NtGdiGetNearestPaletteIndex(pdc
->dclevel
.hpal
, *Color
);
747 IntGetPaletteEntries(pdc
->dclevel
.hpal
, index
, 1, &palEntry
);
748 *Color
= RGB(palEntry
.peRed
, palEntry
.peGreen
, palEntry
.peBlue
);
752 /* Use the pure color */
753 *Color
= *Color
& 0x00FFFFFF;
757 case 0x01: /* PALETTEINDEX */
758 pdc
= DC_LockDc(hDC
);
759 if (IntGetPaletteEntries(pdc
->dclevel
.hpal
, LOWORD(*Color
), 1, &palEntry
) == 1)
761 *Color
= RGB(palEntry
.peRed
, palEntry
.peGreen
, palEntry
.peBlue
);
765 /* Index does not exist, use zero index */
766 IntGetPaletteEntries(pdc
->dclevel
.hpal
, 0, 1, &palEntry
);
767 *Color
= RGB(palEntry
.peRed
, palEntry
.peGreen
, palEntry
.peBlue
);
772 DPRINT("Unsupported color type %d passed\n", *Color
>> 24);
787 if ((Color
& 0xFF000000) != 0)
789 IntHandleSpecialColorType(hDC
, &Color
);
792 hBrush
= NtGdiCreateSolidBrush(Color
, NULL
);
796 OldBrush
= NtGdiSelectBrush(hDC
, hBrush
);
797 if (OldBrush
== NULL
)
799 GreDeleteObject(hBrush
);
803 NtGdiPatBlt(hDC
, X
, Y
, 1, 1, PATCOPY
);
804 NtGdiSelectBrush(hDC
, OldBrush
);
805 GreDeleteObject(hBrush
);
817 DPRINT("0 NtGdiSetPixel X %ld Y %ld C %ld\n", X
, Y
, Color
);
819 if (GdiSetPixelV(hDC
,X
,Y
,Color
))
821 Color
= NtGdiGetPixel(hDC
,X
,Y
);
822 DPRINT("1 NtGdiSetPixel X %ld Y %ld C %ld\n", X
, Y
, Color
);
826 Color
= (COLORREF
)CLR_INVALID
;
827 DPRINT("2 NtGdiSetPixel X %ld Y %ld C %ld\n", X
, Y
, Color
);
832 /* Internal Functions */
835 BITMAP_CopyBitmap(HBITMAP hBitmap
)
839 SURFACE
*Bitmap
, *resBitmap
;
847 Bitmap
= SURFACE_ShareLockSurface(hBitmap
);
853 BITMAP_GetObject(Bitmap
, sizeof(BITMAP
), (PVOID
)&bm
);
855 if (Bitmap
->SurfObj
.lDelta
>= 0)
856 bm
.bmHeight
= -bm
.bmHeight
;
858 Size
.cx
= abs(bm
.bmWidth
);
859 Size
.cy
= abs(bm
.bmHeight
);
860 res
= GreCreateBitmapEx(Size
.cx
,
863 Bitmap
->SurfObj
.iBitmapFormat
,
864 Bitmap
->SurfObj
.fjBitmap
,
865 Bitmap
->SurfObj
.cjBits
,
872 resBitmap
= SURFACE_ShareLockSurface(res
);
875 IntSetBitmapBits(resBitmap
, Bitmap
->SurfObj
.cjBits
, Bitmap
->SurfObj
.pvBits
);
876 GDIOBJ_IncrementShareCount(&Bitmap
->ppal
->BaseObject
);
877 GDIOBJ_ShareUnlockObjByPtr(&resBitmap
->ppal
->BaseObject
);
878 resBitmap
->ppal
= Bitmap
->ppal
;
879 SURFACE_ShareUnlockSurface(resBitmap
);
883 GreDeleteObject(res
);
888 SURFACE_ShareUnlockSurface(Bitmap
);
894 BITMAP_GetObject(SURFACE
*psurf
, INT Count
, LPVOID buffer
)
898 if (!buffer
) return sizeof(BITMAP
);
899 if ((UINT
)Count
< sizeof(BITMAP
)) return 0;
901 /* always fill a basic BITMAP structure */
904 pBitmap
->bmWidth
= psurf
->SurfObj
.sizlBitmap
.cx
;
905 pBitmap
->bmHeight
= psurf
->SurfObj
.sizlBitmap
.cy
;
906 pBitmap
->bmPlanes
= 1;
907 pBitmap
->bmBitsPixel
= BitsPerFormat(psurf
->SurfObj
.iBitmapFormat
);
908 pBitmap
->bmWidthBytes
= WIDTH_BYTES_ALIGN16(pBitmap
->bmWidth
, pBitmap
->bmBitsPixel
);
910 /* Check for DIB section */
913 /* Set bmBits in this case */
914 pBitmap
->bmBits
= psurf
->SurfObj
.pvBits
;
915 /* DIBs data are 32 bits aligned */
916 pBitmap
->bmWidthBytes
= WIDTH_BYTES_ALIGN32(pBitmap
->bmWidth
, pBitmap
->bmBitsPixel
);
918 if (Count
>= sizeof(DIBSECTION
))
920 /* Fill rest of DIBSECTION */
921 PDIBSECTION pds
= buffer
;
923 pds
->dsBmih
.biSize
= sizeof(BITMAPINFOHEADER
);
924 pds
->dsBmih
.biWidth
= pds
->dsBm
.bmWidth
;
925 pds
->dsBmih
.biHeight
= pds
->dsBm
.bmHeight
;
926 pds
->dsBmih
.biPlanes
= pds
->dsBm
.bmPlanes
;
927 pds
->dsBmih
.biBitCount
= pds
->dsBm
.bmBitsPixel
;
929 switch (psurf
->SurfObj
.iBitmapFormat
)
934 pds
->dsBmih
.biCompression
= BI_RGB
;
938 if (psurf
->ppal
->flFlags
& PAL_RGB16_555
)
939 pds
->dsBmih
.biCompression
= BI_RGB
;
941 pds
->dsBmih
.biCompression
= BI_BITFIELDS
;
946 /* 24/32bpp BI_RGB is actually BGR format */
947 if (psurf
->ppal
->flFlags
& PAL_BGR
)
948 pds
->dsBmih
.biCompression
= BI_RGB
;
950 pds
->dsBmih
.biCompression
= BI_BITFIELDS
;
954 pds
->dsBmih
.biCompression
= BI_RLE4
;
957 pds
->dsBmih
.biCompression
= BI_RLE8
;
960 pds
->dsBmih
.biCompression
= BI_JPEG
;
963 pds
->dsBmih
.biCompression
= BI_PNG
;
966 ASSERT(FALSE
); /* this shouldn't happen */
969 pds
->dsBmih
.biSizeImage
= psurf
->SurfObj
.cjBits
;
970 pds
->dsBmih
.biXPelsPerMeter
= 0;
971 pds
->dsBmih
.biYPelsPerMeter
= 0;
972 pds
->dsBmih
.biClrUsed
= psurf
->ppal
->NumColors
;
973 pds
->dsBmih
.biClrImportant
= psurf
->biClrImportant
;
974 pds
->dsBitfields
[0] = psurf
->ppal
->RedMask
;
975 pds
->dsBitfields
[1] = psurf
->ppal
->GreenMask
;
976 pds
->dsBitfields
[2] = psurf
->ppal
->BlueMask
;
977 pds
->dshSection
= psurf
->hDIBSection
;
978 pds
->dsOffset
= psurf
->dwOffset
;
980 return sizeof(DIBSECTION
);
985 /* not set according to wine test, confirmed in win2k */
986 pBitmap
->bmBits
= NULL
;
989 return sizeof(BITMAP
);
1001 PSURFACE psurf
= SURFACE_LockSurface(hsurf
);
1005 SURFACE_UnlockSurface(psurf
);