Sync with trunk r62529.
[reactos.git] / win32ss / gdi / ntgdi / bitmaps.c
1 /*
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>
7 */
8
9 #include <win32k.h>
10
11 #define NDEBUG
12 #include <debug.h>
13
14 void
15 NTAPI
16 UnsafeSetBitmapBits(
17 PSURFACE psurf,
18 IN ULONG cjBits,
19 IN PVOID pvBits)
20 {
21 PUCHAR pjDst, pjSrc;
22 LONG lDeltaDst, lDeltaSrc;
23 ULONG nWidth, nHeight, cBitsPixel;
24
25 nWidth = psurf->SurfObj.sizlBitmap.cx;
26 nHeight = psurf->SurfObj.sizlBitmap.cy;
27 cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
28
29 /* Get pointers */
30 pjDst = psurf->SurfObj.pvScan0;
31 pjSrc = pvBits;
32 lDeltaDst = psurf->SurfObj.lDelta;
33 lDeltaSrc = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
34
35 while (nHeight--)
36 {
37 /* Copy one line */
38 memcpy(pjDst, pjSrc, lDeltaSrc);
39 pjSrc += lDeltaSrc;
40 pjDst += lDeltaDst;
41 }
42
43 }
44
45 HBITMAP
46 NTAPI
47 GreCreateBitmapEx(
48 _In_ ULONG nWidth,
49 _In_ ULONG nHeight,
50 _In_ ULONG cjWidthBytes,
51 _In_ ULONG iFormat,
52 _In_ USHORT fjBitmap,
53 _In_ ULONG cjSizeImage,
54 _In_opt_ PVOID pvBits,
55 _In_ FLONG flags)
56 {
57 PSURFACE psurf;
58 HBITMAP hbmp;
59 PVOID pvCompressedBits = NULL;
60
61 /* Verify format */
62 if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
63
64 /* The infamous RLE hack */
65 if ((iFormat == BMF_4RLE) || (iFormat == BMF_8RLE))
66 {
67 pvCompressedBits = pvBits;
68 pvBits = NULL;
69 iFormat = (iFormat == BMF_4RLE) ? BMF_4BPP : BMF_8BPP;
70 }
71
72 /* Allocate a surface */
73 psurf = SURFACE_AllocSurface(STYPE_BITMAP,
74 nWidth,
75 nHeight,
76 iFormat,
77 fjBitmap,
78 cjWidthBytes,
79 pvBits);
80 if (!psurf)
81 {
82 DPRINT1("SURFACE_AllocSurface failed.\n");
83 return NULL;
84 }
85
86 /* The infamous RLE hack */
87 if (pvCompressedBits)
88 {
89 SIZEL sizl;
90 LONG lDelta;
91
92 sizl.cx = nWidth;
93 sizl.cy = nHeight;
94 lDelta = WIDTH_BYTES_ALIGN32(nWidth, gajBitsPerFormat[iFormat]);
95
96 pvBits = psurf->SurfObj.pvBits;
97 DecompressBitmap(sizl, pvCompressedBits, pvBits, lDelta, iFormat);
98 }
99
100 /* Get the handle for the bitmap */
101 hbmp = (HBITMAP)psurf->SurfObj.hsurf;
102
103 /* Mark as API bitmap */
104 psurf->flags |= (flags | API_BITMAP);
105
106 /* Unlock the surface and return */
107 SURFACE_UnlockSurface(psurf);
108 return hbmp;
109 }
110
111 /* Creates a DDB surface,
112 * as in CreateCompatibleBitmap or CreateBitmap.
113 * Note that each scanline must be 32bit aligned!
114 */
115 HBITMAP
116 NTAPI
117 GreCreateBitmap(
118 _In_ ULONG nWidth,
119 _In_ ULONG nHeight,
120 _In_ ULONG cPlanes,
121 _In_ ULONG cBitsPixel,
122 _In_opt_ PVOID pvBits)
123 {
124 /* Call the extended function */
125 return GreCreateBitmapEx(nWidth,
126 nHeight,
127 0, /* Auto width */
128 BitmapFormat(cBitsPixel * cPlanes, BI_RGB),
129 0, /* No bitmap flags */
130 0, /* Auto size */
131 pvBits,
132 DDB_SURFACE /* DDB */);
133 }
134
135 HBITMAP
136 APIENTRY
137 NtGdiCreateBitmap(
138 IN INT nWidth,
139 IN INT nHeight,
140 IN UINT cPlanes,
141 IN UINT cBitsPixel,
142 IN OPTIONAL LPBYTE pUnsafeBits)
143 {
144 HBITMAP hbmp;
145 ULONG cRealBpp, cjWidthBytes, iFormat, fjBitmap;
146 ULONGLONG cjSize;
147 PSURFACE psurf;
148
149 /* Calculate bitmap format and real bits per pixel. */
150 iFormat = BitmapFormat(cBitsPixel * cPlanes, BI_RGB);
151 cRealBpp = gajBitsPerFormat[iFormat];
152
153 /* Calculate width and image size in bytes */
154 cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cRealBpp);
155 cjSize = (ULONGLONG)cjWidthBytes * nHeight;
156
157 /* Check parameters (possible overflow of cjSize!) */
158 if ((iFormat == 0) || (nWidth <= 0) || (nWidth >= 0x8000000) || (nHeight <= 0) ||
159 (cBitsPixel > 32) || (cPlanes > 32) || (cjSize >= 0x100000000ULL))
160 {
161 DPRINT1("Invalid bitmap format! Width=%d, Height=%d, Bpp=%u, Planes=%u\n",
162 nWidth, nHeight, cBitsPixel, cPlanes);
163 EngSetLastError(ERROR_INVALID_PARAMETER);
164 return NULL;
165 }
166
167 /* Allocations larger than PAGE_SIZE go into user mem */
168 fjBitmap = (cjSize > PAGE_SIZE) ? BMF_USERMEM : 0;
169
170 /* Allocate the surface (but don't set the bits) */
171 psurf = SURFACE_AllocSurface(STYPE_BITMAP,
172 nWidth,
173 nHeight,
174 iFormat,
175 fjBitmap,
176 0,
177 NULL);
178 if (!psurf)
179 {
180 DPRINT1("SURFACE_AllocSurface failed.\n");
181 return NULL;
182 }
183
184 /* Mark as API and DDB bitmap */
185 psurf->flags |= (API_BITMAP | DDB_SURFACE);
186
187 /* Check if we have bits to set */
188 if (pUnsafeBits)
189 {
190 /* Protect with SEH and copy the bits */
191 _SEH2_TRY
192 {
193 ProbeForRead(pUnsafeBits, (SIZE_T)cjSize, 1);
194 UnsafeSetBitmapBits(psurf, 0, pUnsafeBits);
195 }
196 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
197 {
198 GDIOBJ_vDeleteObject(&psurf->BaseObject);
199 _SEH2_YIELD(return NULL;)
200 }
201 _SEH2_END
202 }
203 else
204 {
205 /* Zero the bits */
206 RtlZeroMemory(psurf->SurfObj.pvBits, psurf->SurfObj.cjBits);
207 }
208
209 /* Get the handle for the bitmap */
210 hbmp = (HBITMAP)psurf->SurfObj.hsurf;
211
212 /* Unlock the surface */
213 SURFACE_UnlockSurface(psurf);
214
215 return hbmp;
216 }
217
218
219 HBITMAP FASTCALL
220 IntCreateCompatibleBitmap(
221 PDC Dc,
222 INT Width,
223 INT Height)
224 {
225 HBITMAP Bmp = NULL;
226 PPALETTE ppal;
227
228 /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
229 if (0 == Width || 0 == Height)
230 {
231 return NtGdiGetStockObject(DEFAULT_BITMAP);
232 }
233
234 if (Dc->dctype != DC_TYPE_MEMORY)
235 {
236 PSURFACE psurf;
237
238 Bmp = GreCreateBitmap(abs(Width),
239 abs(Height),
240 1,
241 Dc->ppdev->gdiinfo.cBitsPixel,
242 NULL);
243 psurf = SURFACE_ShareLockSurface(Bmp);
244 ASSERT(psurf);
245
246 /* Dereference old palette and set new palette */
247 ppal = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
248 ASSERT(ppal);
249 SURFACE_vSetPalette(psurf, ppal);
250 PALETTE_ShareUnlockPalette(ppal);
251
252 /* Set flags */
253 psurf->flags = API_BITMAP;
254 psurf->hdc = NULL; // FIXME:
255 SURFACE_ShareUnlockSurface(psurf);
256 }
257 else
258 {
259 DIBSECTION dibs;
260 INT Count;
261 PSURFACE psurf = Dc->dclevel.pSurface;
262 if(!psurf) psurf = psurfDefaultBitmap;
263 Count = BITMAP_GetObject(psurf, sizeof(dibs), &dibs);
264
265 if (Count == sizeof(BITMAP))
266 {
267 PSURFACE psurfBmp;
268
269 Bmp = GreCreateBitmap(abs(Width),
270 abs(Height),
271 1,
272 dibs.dsBm.bmBitsPixel,
273 NULL);
274 psurfBmp = SURFACE_ShareLockSurface(Bmp);
275 ASSERT(psurfBmp);
276
277 /* Dereference old palette and set new palette */
278 SURFACE_vSetPalette(psurfBmp, psurf->ppal);
279
280 /* Set flags */
281 psurfBmp->flags = API_BITMAP;
282 psurfBmp->hdc = NULL; // FIXME:
283 SURFACE_ShareUnlockSurface(psurfBmp);
284 }
285 else if (Count == sizeof(DIBSECTION))
286 {
287 /* A DIB section is selected in the DC */
288 BYTE buf[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)] = {0};
289 PVOID Bits;
290 BITMAPINFO* bi = (BITMAPINFO*)buf;
291
292 bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
293 bi->bmiHeader.biWidth = Width;
294 bi->bmiHeader.biHeight = Height;
295 bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes;
296 bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount;
297 bi->bmiHeader.biCompression = dibs.dsBmih.biCompression;
298 bi->bmiHeader.biSizeImage = 0;
299 bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
300 bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
301 bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed;
302 bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
303
304 if (bi->bmiHeader.biCompression == BI_BITFIELDS)
305 {
306 /* Copy the color masks */
307 RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3*sizeof(RGBQUAD));
308 }
309 else if (bi->bmiHeader.biBitCount <= 8)
310 {
311 /* Copy the color table */
312 UINT Index;
313 PPALETTE PalGDI;
314
315 if (!psurf->ppal)
316 {
317 EngSetLastError(ERROR_INVALID_HANDLE);
318 return 0;
319 }
320
321 PalGDI = psurf->ppal;
322
323 for (Index = 0;
324 Index < 256 && Index < PalGDI->NumColors;
325 Index++)
326 {
327 bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
328 bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
329 bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
330 bi->bmiColors[Index].rgbReserved = 0;
331 }
332 }
333
334 Bmp = DIB_CreateDIBSection(Dc,
335 bi,
336 DIB_RGB_COLORS,
337 &Bits,
338 NULL,
339 0,
340 0);
341 return Bmp;
342 }
343 }
344 return Bmp;
345 }
346
347 HBITMAP APIENTRY
348 NtGdiCreateCompatibleBitmap(
349 HDC hDC,
350 INT Width,
351 INT Height)
352 {
353 HBITMAP Bmp;
354 PDC Dc;
355
356 /* Check parameters */
357 if ((Width <= 0) || (Height <= 0) || ((Width * Height) > 0x3FFFFFFF))
358 {
359 EngSetLastError(ERROR_INVALID_PARAMETER);
360 return NULL;
361 }
362
363 if (!hDC)
364 return GreCreateBitmap(Width, Height, 1, 1, 0);
365
366 Dc = DC_LockDc(hDC);
367
368 DPRINT("NtGdiCreateCompatibleBitmap(%p,%d,%d, bpp:%u) = \n",
369 hDC, Width, Height, Dc->ppdev->gdiinfo.cBitsPixel);
370
371 if (NULL == Dc)
372 {
373 EngSetLastError(ERROR_INVALID_HANDLE);
374 return NULL;
375 }
376
377 Bmp = IntCreateCompatibleBitmap(Dc, Width, Height);
378
379 DC_UnlockDc(Dc);
380 return Bmp;
381 }
382
383 BOOL
384 APIENTRY
385 NtGdiGetBitmapDimension(
386 HBITMAP hBitmap,
387 LPSIZE psizDim)
388 {
389 PSURFACE psurfBmp;
390 BOOL bResult = TRUE;
391
392 if (hBitmap == NULL)
393 return FALSE;
394
395 /* Lock the bitmap */
396 psurfBmp = SURFACE_ShareLockSurface(hBitmap);
397 if (psurfBmp == NULL)
398 {
399 EngSetLastError(ERROR_INVALID_HANDLE);
400 return FALSE;
401 }
402
403 /* Use SEH to copy the data to the caller */
404 _SEH2_TRY
405 {
406 ProbeForWrite(psizDim, sizeof(SIZE), 1);
407 *psizDim = psurfBmp->sizlDim;
408 }
409 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
410 {
411 bResult = FALSE;
412 }
413 _SEH2_END
414
415 /* Unlock the bitmap */
416 SURFACE_ShareUnlockSurface(psurfBmp);
417
418 return bResult;
419 }
420
421
422 VOID
423 FASTCALL
424 UnsafeGetBitmapBits(
425 PSURFACE psurf,
426 DWORD Bytes,
427 OUT PBYTE pvBits)
428 {
429 PUCHAR pjDst, pjSrc;
430 LONG lDeltaDst, lDeltaSrc;
431 ULONG nWidth, nHeight, cBitsPixel;
432
433 nWidth = psurf->SurfObj.sizlBitmap.cx;
434 nHeight = psurf->SurfObj.sizlBitmap.cy;
435 cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
436
437 /* Get pointers */
438 pjSrc = psurf->SurfObj.pvScan0;
439 pjDst = pvBits;
440 lDeltaSrc = psurf->SurfObj.lDelta;
441 lDeltaDst = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
442
443 while (nHeight--)
444 {
445 /* Copy one line */
446 RtlCopyMemory(pjDst, pjSrc, lDeltaDst);
447 pjSrc += lDeltaSrc;
448 pjDst += lDeltaDst;
449 }
450 }
451
452 LONG
453 APIENTRY
454 NtGdiGetBitmapBits(
455 HBITMAP hBitmap,
456 ULONG cjBuffer,
457 OUT OPTIONAL PBYTE pUnsafeBits)
458 {
459 PSURFACE psurf;
460 ULONG cjSize;
461 LONG ret;
462
463 /* Check parameters */
464 if (pUnsafeBits != NULL && cjBuffer == 0)
465 {
466 return 0;
467 }
468
469 /* Lock the bitmap */
470 psurf = SURFACE_ShareLockSurface(hBitmap);
471 if (!psurf)
472 {
473 EngSetLastError(ERROR_INVALID_HANDLE);
474 return 0;
475 }
476
477 /* Calculate the size of the bitmap in bytes */
478 cjSize = WIDTH_BYTES_ALIGN16(psurf->SurfObj.sizlBitmap.cx,
479 BitsPerFormat(psurf->SurfObj.iBitmapFormat)) *
480 abs(psurf->SurfObj.sizlBitmap.cy);
481
482 /* If the bits vector is null, the function should return the read size */
483 if (pUnsafeBits == NULL)
484 {
485 SURFACE_ShareUnlockSurface(psurf);
486 return cjSize;
487 }
488
489 /* Don't copy more bytes than the buffer has */
490 cjBuffer = min(cjBuffer, cjSize);
491
492 // FIXME: Use MmSecureVirtualMemory
493 _SEH2_TRY
494 {
495 ProbeForWrite(pUnsafeBits, cjBuffer, 1);
496 UnsafeGetBitmapBits(psurf, cjBuffer, pUnsafeBits);
497 ret = cjBuffer;
498 }
499 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
500 {
501 ret = 0;
502 }
503 _SEH2_END
504
505 SURFACE_ShareUnlockSurface(psurf);
506
507 return ret;
508 }
509
510
511 LONG APIENTRY
512 NtGdiSetBitmapBits(
513 HBITMAP hBitmap,
514 DWORD Bytes,
515 IN PBYTE pUnsafeBits)
516 {
517 LONG ret;
518 PSURFACE psurf;
519
520 if (pUnsafeBits == NULL || Bytes == 0)
521 {
522 return 0;
523 }
524
525 psurf = SURFACE_ShareLockSurface(hBitmap);
526 if (psurf == NULL)
527 {
528 EngSetLastError(ERROR_INVALID_HANDLE);
529 return 0;
530 }
531
532 _SEH2_TRY
533 {
534 ProbeForRead(pUnsafeBits, Bytes, 1);
535 UnsafeSetBitmapBits(psurf, Bytes, pUnsafeBits);
536 ret = 1;
537 }
538 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
539 {
540 ret = 0;
541 }
542 _SEH2_END
543
544 SURFACE_ShareUnlockSurface(psurf);
545
546 return ret;
547 }
548
549 BOOL APIENTRY
550 NtGdiSetBitmapDimension(
551 HBITMAP hBitmap,
552 INT Width,
553 INT Height,
554 LPSIZE Size)
555 {
556 PSURFACE psurf;
557 BOOL Ret = TRUE;
558
559 if (hBitmap == NULL)
560 return FALSE;
561
562 psurf = SURFACE_ShareLockSurface(hBitmap);
563 if (psurf == NULL)
564 {
565 EngSetLastError(ERROR_INVALID_HANDLE);
566 return FALSE;
567 }
568
569 if (Size)
570 {
571 _SEH2_TRY
572 {
573 ProbeForWrite(Size, sizeof(SIZE), 1);
574 *Size = psurf->sizlDim;
575 }
576 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
577 {
578 Ret = FALSE;
579 }
580 _SEH2_END
581 }
582
583 /* The dimension is changed even if writing the old value failed */
584 psurf->sizlDim.cx = Width;
585 psurf->sizlDim.cy = Height;
586
587 SURFACE_ShareUnlockSurface(psurf);
588
589 return Ret;
590 }
591
592 /* Internal Functions */
593
594 HBITMAP
595 FASTCALL
596 BITMAP_CopyBitmap(HBITMAP hBitmap)
597 {
598 HBITMAP hbmNew;
599 SURFACE *psurfSrc, *psurfNew;
600
601 /* Fail, if no source bitmap is given */
602 if (hBitmap == NULL) return 0;
603
604 /* Lock the source bitmap */
605 psurfSrc = SURFACE_ShareLockSurface(hBitmap);
606 if (psurfSrc == NULL)
607 {
608 return 0;
609 }
610
611 /* Allocate a new bitmap with the same dimensions as the source bmp */
612 hbmNew = GreCreateBitmapEx(psurfSrc->SurfObj.sizlBitmap.cx,
613 psurfSrc->SurfObj.sizlBitmap.cy,
614 abs(psurfSrc->SurfObj.lDelta),
615 psurfSrc->SurfObj.iBitmapFormat,
616 psurfSrc->SurfObj.fjBitmap & BMF_TOPDOWN,
617 psurfSrc->SurfObj.cjBits,
618 NULL,
619 psurfSrc->flags);
620
621 if (hbmNew)
622 {
623 /* Lock the new bitmap */
624 psurfNew = SURFACE_ShareLockSurface(hbmNew);
625 if (psurfNew)
626 {
627 /* Copy the bitmap bits to the new bitmap buffer */
628 RtlCopyMemory(psurfNew->SurfObj.pvBits,
629 psurfSrc->SurfObj.pvBits,
630 psurfNew->SurfObj.cjBits);
631
632
633 /* Reference the palette of the source bitmap and use it */
634 SURFACE_vSetPalette(psurfNew, psurfSrc->ppal);
635
636 /* Unlock the new surface */
637 SURFACE_ShareUnlockSurface(psurfNew);
638 }
639 else
640 {
641 /* Failed to lock the bitmap, shouldn't happen */
642 GreDeleteObject(hbmNew);
643 hbmNew = NULL;
644 }
645 }
646
647 /* Unlock the source bitmap and return the handle of the new bitmap */
648 SURFACE_ShareUnlockSurface(psurfSrc);
649 return hbmNew;
650 }
651
652 INT APIENTRY
653 BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer)
654 {
655 PBITMAP pBitmap;
656
657 if (!buffer) return sizeof(BITMAP);
658 if ((UINT)Count < sizeof(BITMAP)) return 0;
659
660 /* Always fill a basic BITMAP structure */
661 pBitmap = buffer;
662 pBitmap->bmType = 0;
663 pBitmap->bmWidth = psurf->SurfObj.sizlBitmap.cx;
664 pBitmap->bmHeight = psurf->SurfObj.sizlBitmap.cy;
665 pBitmap->bmPlanes = 1;
666 pBitmap->bmBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
667 pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN16(pBitmap->bmWidth, pBitmap->bmBitsPixel);
668
669 /* Check for DIB section */
670 if (psurf->hSecure)
671 {
672 /* Set bmBits in this case */
673 pBitmap->bmBits = psurf->SurfObj.pvBits;
674 /* DIBs data are 32 bits aligned */
675 pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN32(pBitmap->bmWidth, pBitmap->bmBitsPixel);
676
677 if (Count >= sizeof(DIBSECTION))
678 {
679 /* Fill rest of DIBSECTION */
680 PDIBSECTION pds = buffer;
681
682 pds->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
683 pds->dsBmih.biWidth = pds->dsBm.bmWidth;
684 pds->dsBmih.biHeight = pds->dsBm.bmHeight;
685 pds->dsBmih.biPlanes = pds->dsBm.bmPlanes;
686 pds->dsBmih.biBitCount = pds->dsBm.bmBitsPixel;
687
688 switch (psurf->SurfObj.iBitmapFormat)
689 {
690 case BMF_1BPP:
691 case BMF_4BPP:
692 case BMF_8BPP:
693 pds->dsBmih.biCompression = BI_RGB;
694 break;
695
696 case BMF_16BPP:
697 if (psurf->ppal->flFlags & PAL_RGB16_555)
698 pds->dsBmih.biCompression = BI_RGB;
699 else
700 pds->dsBmih.biCompression = BI_BITFIELDS;
701 break;
702
703 case BMF_24BPP:
704 case BMF_32BPP:
705 /* 24/32bpp BI_RGB is actually BGR format */
706 if (psurf->ppal->flFlags & PAL_BGR)
707 pds->dsBmih.biCompression = BI_RGB;
708 else
709 pds->dsBmih.biCompression = BI_BITFIELDS;
710 break;
711
712 case BMF_4RLE:
713 pds->dsBmih.biCompression = BI_RLE4;
714 break;
715 case BMF_8RLE:
716 pds->dsBmih.biCompression = BI_RLE8;
717 break;
718 case BMF_JPEG:
719 pds->dsBmih.biCompression = BI_JPEG;
720 break;
721 case BMF_PNG:
722 pds->dsBmih.biCompression = BI_PNG;
723 break;
724 default:
725 ASSERT(FALSE); /* This shouldn't happen */
726 }
727
728 pds->dsBmih.biSizeImage = psurf->SurfObj.cjBits;
729 pds->dsBmih.biXPelsPerMeter = 0;
730 pds->dsBmih.biYPelsPerMeter = 0;
731 pds->dsBmih.biClrUsed = psurf->ppal->NumColors;
732 pds->dsBmih.biClrImportant = psurf->biClrImportant;
733 pds->dsBitfields[0] = psurf->ppal->RedMask;
734 pds->dsBitfields[1] = psurf->ppal->GreenMask;
735 pds->dsBitfields[2] = psurf->ppal->BlueMask;
736 pds->dshSection = psurf->hDIBSection;
737 pds->dsOffset = psurf->dwOffset;
738
739 return sizeof(DIBSECTION);
740 }
741 }
742 else
743 {
744 /* Not set according to wine test, confirmed in win2k */
745 pBitmap->bmBits = NULL;
746 }
747
748 return sizeof(BITMAP);
749 }
750
751 /*
752 * @implemented
753 */
754 HDC
755 APIENTRY
756 NtGdiGetDCforBitmap(
757 IN HBITMAP hsurf)
758 {
759 HDC hdc = NULL;
760 PSURFACE psurf = SURFACE_ShareLockSurface(hsurf);
761 if (psurf)
762 {
763 hdc = psurf->hdc;
764 SURFACE_ShareUnlockSurface(psurf);
765 }
766 return hdc;
767 }
768
769
770 /* EOF */