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