ReactOS 0.4.15-dev-7788-g1ad9096
dibobj.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS win32 kernel mode subsystem
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: win32ss/gdi/ntgdi/dibobj.c
5 * PURPOSE: Dib object functions
6 * PROGRAMMER:
7 */
8
9#include <win32k.h>
10
11#define NDEBUG
12#include <debug.h>
13
14static const RGBQUAD DefLogPaletteQuads[20] = /* Copy of Default Logical Palette */
15{
16 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
17 { 0x00, 0x00, 0x00, 0x00 },
18 { 0x00, 0x00, 0x80, 0x00 },
19 { 0x00, 0x80, 0x00, 0x00 },
20 { 0x00, 0x80, 0x80, 0x00 },
21 { 0x80, 0x00, 0x00, 0x00 },
22 { 0x80, 0x00, 0x80, 0x00 },
23 { 0x80, 0x80, 0x00, 0x00 },
24 { 0xc0, 0xc0, 0xc0, 0x00 },
25 { 0xc0, 0xdc, 0xc0, 0x00 },
26 { 0xf0, 0xca, 0xa6, 0x00 },
27 { 0xf0, 0xfb, 0xff, 0x00 },
28 { 0xa4, 0xa0, 0xa0, 0x00 },
29 { 0x80, 0x80, 0x80, 0x00 },
30 { 0x00, 0x00, 0xff, 0x00 },
31 { 0x00, 0xff, 0x00, 0x00 },
32 { 0x00, 0xff, 0xff, 0x00 },
33 { 0xff, 0x00, 0x00, 0x00 },
34 { 0xff, 0x00, 0xff, 0x00 },
35 { 0xff, 0xff, 0x00, 0x00 },
36 { 0xff, 0xff, 0xff, 0x00 }
37};
38
42 _In_ const BITMAPINFO *pbmi,
43 _In_ PDC pdc,
45{
46 PPALETTE ppal;
47 ULONG i, cBitsPixel, cColors;
48
50 {
52 cBitsPixel = pbci->bmciHeader.bcBitCount;
53 }
54 else
55 {
56 cBitsPixel = pbmi->bmiHeader.biBitCount;
57 }
58
59 /* Check if the colors are indexed */
60 if (cBitsPixel <= 8)
61 {
62 /* We create a "full" palette */
63 cColors = 1 << cBitsPixel;
64
65 /* Allocate the palette */
67 cColors,
68 NULL,
69 0,
70 0,
71 0);
72 if (ppal == NULL)
73 {
74 DPRINT1("Failed to allocate palette.\n");
75 return NULL;
76 }
77
78 /* Check if the BITMAPINFO specifies how many colors to use */
79 if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
80 (pbmi->bmiHeader.biClrUsed != 0))
81 {
82 /* This is how many colors we can actually process */
83 cColors = min(cColors, pbmi->bmiHeader.biClrUsed);
84 }
85
86 /* Check how to use the colors */
88 {
89 COLORREF crColor;
90
91 /* The colors are an array of WORD indices into the DC palette */
92 PWORD pwColors = (PWORD)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
93
94 /* Use the DCs palette or, if no DC is given, the default one */
95 PPALETTE ppalDC = pdc ? pdc->dclevel.ppal : gppalDefault;
96
97 /* Loop all color indices in the DIB */
98 for (i = 0; i < cColors; i++)
99 {
100 /* Get the palette index and handle wraparound when exceeding
101 the number of colors in the DC palette */
102 WORD wIndex = pwColors[i] % ppalDC->NumColors;
103
104 /* USe the RGB value from the DC palette */
105 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, wIndex);
106 PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
107 }
108 }
109 else if (iUsage == DIB_PAL_BRUSHHACK)
110 {
111 /* The colors are an array of WORD indices into the DC palette */
112 PWORD pwColors = (PWORD)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
113
114 /* Loop all color indices in the DIB */
115 for (i = 0; i < cColors; i++)
116 {
117 /* Set the index directly as the RGB color, the real palette
118 containing RGB values will be calculated when the brush is
119 realized */
120 PALETTE_vSetRGBColorForIndex(ppal, i, pwColors[i]);
121 }
122
123 /* Mark the palette as a brush hack palette */
124 ppal->flFlags |= PAL_BRUSHHACK;
125 }
126// else if (iUsage == 2)
127// {
128 // FIXME: this one is undocumented
129// ASSERT(FALSE);
130// }
131 else if (pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
132 {
133 /* The colors are an array of RGBQUAD values */
134 RGBQUAD *prgb = (RGBQUAD*)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
135 RGBQUAD colors[256] = {{0}};
136
137 // FIXME: do we need to handle PALETTEINDEX / PALETTERGB macro?
138
139 /* Use SEH to verify we can READ prgb[] succesfully */
141 {
142 RtlCopyMemory(colors, prgb, cColors * sizeof(colors[0]));
143 }
145 {
146 /* Do Nothing */
147 }
148 _SEH2_END;
149
150 for (i = 0; i < cColors; ++i)
151 {
152 /* Get the color value and translate it to a COLORREF */
153 COLORREF crColor = RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue);
154
155 /* Set the RGB value in the palette */
156 PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
157 }
158 }
159 else
160 {
161 /* The colors are an array of RGBTRIPLE values */
163
164 /* Loop all color indices in the DIB */
165 for (i = 0; i < cColors; i++)
166 {
167 /* Get the color value and translate it to a COLORREF */
168 RGBTRIPLE rgb = prgb[i];
169 COLORREF crColor = RGB(rgb.rgbtRed, rgb.rgbtGreen, rgb.rgbtBlue);
170
171 /* Set the RGB value in the palette */
172 PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
173 }
174 }
175 }
176 else
177 {
178 /* This is a bitfield / RGB palette */
179 ULONG flRedMask, flGreenMask, flBlueMask;
180
181 /* Check if the DIB contains bitfield values */
182 if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
184 {
185 /* Check if we have a v4/v5 header */
186 if (pbmi->bmiHeader.biSize >= sizeof(BITMAPV4HEADER))
187 {
188 /* The masks are dedicated fields in the header */
190 flRedMask = pbmV4Header->bV4RedMask;
191 flGreenMask = pbmV4Header->bV4GreenMask;
192 flBlueMask = pbmV4Header->bV4BlueMask;
193 }
194 else
195 {
196 /* The masks are the first 3 values in the DIB color table */
197 PDWORD pdwColors = (PVOID)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
198 flRedMask = pdwColors[0];
199 flGreenMask = pdwColors[1];
200 flBlueMask = pdwColors[2];
201 }
202 }
203 else
204 {
205 /* Check what bit depth we have. Note: optimization flags are
206 calculated in PALETTE_AllocPalette() */
207 if (cBitsPixel == 16)
208 {
209 /* This is an RGB 555 palette */
210 flRedMask = 0x7C00;
211 flGreenMask = 0x03E0;
212 flBlueMask = 0x001F;
213 }
214 else
215 {
216 /* This is an RGB 888 palette */
217 flRedMask = 0xFF0000;
218 flGreenMask = 0x00FF00;
219 flBlueMask = 0x0000FF;
220 }
221 }
222
223 /* Allocate the bitfield palette */
225 0,
226 NULL,
227 flRedMask,
228 flGreenMask,
229 flBlueMask);
230 }
231
232 /* We're done, return the palette */
233 return ppal;
234}
235
236// Converts a DIB to a device-dependent bitmap
237static INT
240 PDC DC,
242 UINT StartScan,
243 UINT ScanLines,
244 CONST VOID *Bits,
246 CONST BITMAPINFO *bmi,
247 UINT ColorUse)
248{
249 HBITMAP SourceBitmap;
250 PSURFACE psurfDst, psurfSrc;
251 INT result = 0;
252 RECT rcDst;
253 POINTL ptSrc;
254 EXLATEOBJ exlo;
255 PPALETTE ppalDIB = 0;
256 ULONG cjSizeImage;
257
258 if (!bmi || !Bits) return 0;
259
260 /* Check for uncompressed formats */
261 if ((bmi->bmiHeader.biCompression == BI_RGB) ||
262 (bmi->bmiHeader.biCompression == BI_BITFIELDS))
263 {
264 /* Calculate the image size */
265 cjSizeImage = DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
266 ScanLines,
267 bmi->bmiHeader.biBitCount);
268 }
269 /* Check if the header provided an image size */
270 else if (bmi->bmiHeader.biSizeImage != 0)
271 {
272 /* Use the given size */
273 cjSizeImage = bmi->bmiHeader.biSizeImage;
274 }
275 else
276 {
277 /* Compressed format without a size. This is invalid. */
278 DPRINT1("Compressed format without a size\n");
279 return 0;
280 }
281
282 /* Check if the size that we have is ok */
283 if ((cjSizeImage > cjMaxBits) || (cjSizeImage == 0))
284 {
285 DPRINT1("Invalid bitmap size! cjSizeImage = %lu, cjMaxBits = %lu\n",
286 cjSizeImage, cjMaxBits);
287 return 0;
288 }
289
290 SourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
291 ScanLines,
292 0,
293 BitmapFormat(bmi->bmiHeader.biBitCount,
294 bmi->bmiHeader.biCompression),
295 bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
296 cjSizeImage,
297 (PVOID)Bits,
298 0);
299 if (!SourceBitmap)
300 {
301 DPRINT1("Error: Could not create a bitmap.\n");
303 return 0;
304 }
305
307 psurfSrc = SURFACE_ShareLockSurface(SourceBitmap);
308
309 if(!(psurfSrc && psurfDst))
310 {
311 DPRINT1("Error: Could not lock surfaces\n");
312 goto cleanup;
313 }
314
315 /* Create a palette for the DIB */
316 ppalDIB = CreateDIBPalette(bmi, DC, ColorUse);
317 if (!ppalDIB)
318 {
320 goto cleanup;
321 }
322
323 /* Initialize EXLATEOBJ */
325 ppalDIB,
326 psurfDst->ppal,
327 RGB(0xff, 0xff, 0xff),
328 RGB(0xff, 0xff, 0xff), //DC->pdcattr->crBackgroundClr,
329 0); // DC->pdcattr->crForegroundClr);
330
331 rcDst.top = StartScan;
332 rcDst.left = 0;
333 rcDst.bottom = rcDst.top + ScanLines;
334 rcDst.right = psurfDst->SurfObj.sizlBitmap.cx;
335 ptSrc.x = 0;
336 ptSrc.y = 0;
337
338 result = IntEngCopyBits(&psurfDst->SurfObj,
339 &psurfSrc->SurfObj,
340 NULL,
341 &exlo.xlo,
342 &rcDst,
343 &ptSrc);
344 if(result)
345 result = ScanLines;
346
347 EXLATEOBJ_vCleanup(&exlo);
348
349cleanup:
350 if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
351 if(psurfSrc) SURFACE_ShareUnlockSurface(psurfSrc);
352 if(psurfDst) SURFACE_ShareUnlockSurface(psurfDst);
353 GreDeleteObject(SourceBitmap);
354
355 return result;
356}
357
358static
361 DWORD Width,
363 ULONG Compression,
364 const BYTE* Bits,
365 DWORD BitsSize)
366{
368 DWORD x, y;
369 SURFOBJ* SurfObj;
370 UINT i = 0;
371 BYTE Data, NumPixels, ToSkip;
372
373 ASSERT((Compression == BI_RLE8) || (Compression == BI_RLE4));
374
375 /* Create the bitmap */
377 if (!Mask)
378 return NULL;
379
380 SurfObj = EngLockSurface((HSURF)Mask);
381 if (!SurfObj)
382 {
384 return NULL;
385 }
386 ASSERT(SurfObj->pvBits != NULL);
387
388 x = y = 0;
389
390 while (i < BitsSize)
391 {
392 NumPixels = Bits[i];
393 Data = Bits[i + 1];
394 i += 2;
395
396 if (NumPixels != 0)
397 {
398 if ((x + NumPixels) > Width)
399 NumPixels = Width - x;
400
401 if (NumPixels == 0)
402 continue;
403
404 DIB_1BPP_HLine(SurfObj, x, x + NumPixels, y, 1);
405 x += NumPixels;
406 continue;
407 }
408
409 if (Data < 3)
410 {
411 switch (Data)
412 {
413 case 0:
414 /* End of line */
415 y++;
416 if (y == Height)
417 goto done;
418 x = 0;
419 break;
420 case 1:
421 /* End of file */
422 goto done;
423 case 2:
424 /* Jump */
425 if (i >= (BitsSize - 1))
426 goto done;
427 x += Bits[i];
428 if (x > Width)
429 x = Width;
430 y += Bits[i + 1];
431 if (y >= Height)
432 goto done;
433 i += 2;
434 break;
435 }
436 /* Done for this run */
437 continue;
438 }
439
440 /* Embedded data into the RLE */
441 NumPixels = Data;
442 if (Compression == BI_RLE8)
443 ToSkip = NumPixels;
444 else
445 ToSkip = (NumPixels / 2) + (NumPixels & 1);
446
447 if ((i + ToSkip) > BitsSize)
448 goto done;
449 ToSkip = (ToSkip + 1) & ~1;
450
451 if ((x + NumPixels) > Width)
452 NumPixels = Width - x;
453
454 if (NumPixels != 0)
455 {
456 DIB_1BPP_HLine(SurfObj, x, x + NumPixels, y, 1);
457 x += NumPixels;
458 }
459 i += ToSkip;
460 }
461
462done:
463 EngUnlockSurface(SurfObj);
464 return Mask;
465}
466
468INT
471 IN HDC hDC,
472 IN INT XDest,
473 IN INT YDest,
474 IN DWORD Width,
476 IN INT XSrc,
477 IN INT YSrc,
478 IN DWORD StartScan,
479 IN DWORD ScanLines,
480 IN LPBYTE Bits,
481 IN LPBITMAPINFO bmi,
482 IN DWORD ColorUse,
485 IN BOOL bTransformCoordinates,
487{
488 INT ret;
489 PDC pDC = NULL;
490 HBITMAP hSourceBitmap = NULL, hMaskBitmap = NULL;
491 SURFOBJ *pDestSurf, *pSourceSurf = NULL, *pMaskSurf = NULL;
492 SURFACE *pSurf;
493 RECTL rcDest;
494 POINTL ptSource;
495 //INT DIBWidth;
496 SIZEL SourceSize;
497 EXLATEOBJ exlo;
498 PPALETTE ppalDIB = NULL;
499 LPBITMAPINFO pbmiSafe;
500 BOOL bResult;
501
502 if (!Bits) return 0;
503
504 pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjMaxInfo, 'pmTG');
505 if (!pbmiSafe) return 0;
506
508 {
509 ProbeForRead(bmi, cjMaxInfo, 1);
510 ProbeForRead(Bits, cjMaxBits, 1);
511 RtlCopyMemory(pbmiSafe, bmi, cjMaxInfo);
512 bmi = pbmiSafe;
513 }
515 {
516 ret = 0;
517 goto Exit;
518 }
519 _SEH2_END;
520
521 DPRINT("StartScan %d ScanLines %d Bits %p bmi %p ColorUse %d\n"
522 " Height %d Width %d SizeImage %d\n"
523 " biHeight %d biWidth %d biBitCount %d\n"
524 " XSrc %d YSrc %d xDext %d yDest %d\n",
525 StartScan, ScanLines, Bits, bmi, ColorUse,
526 Height, Width, bmi->bmiHeader.biSizeImage,
527 bmi->bmiHeader.biHeight, bmi->bmiHeader.biWidth,
528 bmi->bmiHeader.biBitCount,
529 XSrc, YSrc, XDest, YDest);
530
531 if (YDest >= 0)
532 {
533 ScanLines = min(abs(Height), ScanLines);
534 if (YSrc > 0)
535 ScanLines += YSrc;
536 }
537 else
538 {
539 ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
540 }
541
542 if (ScanLines == 0)
543 {
544 DPRINT1("ScanLines == 0\n");
545 ret = 0;
546 goto Exit;
547 }
548
549 pDC = DC_LockDc(hDC);
550 if (!pDC)
551 {
553 ret = 0;
554 goto Exit;
555 }
556
557 if (pDC->dctype == DCTYPE_INFO)
558 {
559 ret = 0;
560 goto Exit;
561 }
562
563 rcDest.left = XDest;
564 rcDest.top = YDest;
565 if (bTransformCoordinates)
566 {
567 IntLPtoDP(pDC, (LPPOINT)&rcDest, 2);
568 }
569 rcDest.left += pDC->ptlDCOrig.x;
570 rcDest.top += pDC->ptlDCOrig.y;
571 rcDest.right = rcDest.left + Width;
572 rcDest.bottom = rcDest.top + Height;
573 rcDest.top += StartScan;
574
575 if (pDC->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
576 {
577 IntUpdateBoundsRect(pDC, &rcDest);
578 }
579
580 ptSource.x = XSrc;
581 ptSource.y = YSrc;
582
583 SourceSize.cx = bmi->bmiHeader.biWidth;
584 SourceSize.cy = ScanLines;
585 if (YDest >= 0 && YSrc > 0)
586 {
587 ScanLines += YSrc;
588 }
589
590 //DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount);
591
592 hSourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
593 ScanLines,
594 0,
595 BitmapFormat(bmi->bmiHeader.biBitCount,
596 bmi->bmiHeader.biCompression),
597 bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
598 bmi->bmiHeader.biSizeImage,
599 Bits,
600 0);
601
602 if (!hSourceBitmap)
603 {
605 ret = 0;
606 goto Exit;
607 }
608
609 pSourceSurf = EngLockSurface((HSURF)hSourceBitmap);
610 if (!pSourceSurf)
611 {
612 ret = 0;
613 goto Exit;
614 }
615
616 /* HACK: If this is a RLE bitmap, only the relevant pixels must be set. */
617 if ((bmi->bmiHeader.biCompression == BI_RLE8) || (bmi->bmiHeader.biCompression == BI_RLE4))
618 {
619 hMaskBitmap = IntGdiCreateMaskFromRLE(bmi->bmiHeader.biWidth,
620 ScanLines,
621 bmi->bmiHeader.biCompression,
622 Bits,
623 cjMaxBits);
624 if (!hMaskBitmap)
625 {
627 ret = 0;
628 goto Exit;
629 }
630 pMaskSurf = EngLockSurface((HSURF)hMaskBitmap);
631 if (!pMaskSurf)
632 {
633 ret = 0;
634 goto Exit;
635 }
636 }
637
638 /* Create a palette for the DIB */
639 ppalDIB = CreateDIBPalette(bmi, pDC, ColorUse);
640 if (!ppalDIB)
641 {
643 ret = 0;
644 goto Exit;
645 }
646
647 /* This is actually a blit */
648 DC_vPrepareDCsForBlit(pDC, &rcDest, NULL, NULL);
649 pSurf = pDC->dclevel.pSurface;
650 if (!pSurf)
651 {
652 DC_vFinishBlit(pDC, NULL);
653 ret = ScanLines;
654 goto Exit;
655 }
656
657 ASSERT(pSurf->ppal);
658
659 /* Initialize EXLATEOBJ */
661 ppalDIB,
662 pSurf->ppal,
663 RGB(0xff, 0xff, 0xff),
664 pDC->pdcattr->crBackgroundClr,
665 pDC->pdcattr->crForegroundClr);
666
667 pDestSurf = &pSurf->SurfObj;
668
669 /* Copy the bits */
670 DPRINT("BitsToDev with rcDest=(%d|%d) (%d|%d), ptSource=(%d|%d) w=%d h=%d\n",
671 rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
672 ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy);
673
674 /* This fixes the large Google text on Google.com from being upside down */
675 if (rcDest.top > rcDest.bottom)
676 {
677 RECTL_vMakeWellOrdered(&rcDest);
678 ptSource.y -= SourceSize.cy;
679 }
680
681 bResult = IntEngBitBlt(pDestSurf,
682 pSourceSurf,
683 pMaskSurf,
684 (CLIPOBJ *)&pDC->co,
685 &exlo.xlo,
686 &rcDest,
687 &ptSource,
688 pMaskSurf ? &ptSource : NULL,
689 NULL,
690 NULL,
692
693 /* Cleanup EXLATEOBJ */
694 EXLATEOBJ_vCleanup(&exlo);
695
696 /* We're done */
697 DC_vFinishBlit(pDC, NULL);
698
699 ret = bResult ? ScanLines : 0;
700
701Exit:
702
703 if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
704 if (pSourceSurf) EngUnlockSurface(pSourceSurf);
705 if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
706 if (pMaskSurf) EngUnlockSurface(pMaskSurf);
707 if (hMaskBitmap) EngDeleteSurface((HSURF)hMaskBitmap);
708 if (pDC) DC_UnlockDc(pDC);
709 ExFreePoolWithTag(pbmiSafe, 'pmTG');
710
711 return ret;
712}
713
714/* Converts a device-dependent bitmap to a DIB */
715INT
718 HDC hDC,
720 UINT StartScan,
721 UINT ScanLines,
722 LPBYTE Bits,
724 UINT Usage,
725 UINT MaxBits,
726 UINT MaxInfo)
727{
728 BITMAPCOREINFO* pbmci = NULL;
729 PSURFACE psurf = NULL;
730 PDC pDC;
732 WORD planes, bpp;
733 DWORD compr, size ;
734 USHORT i;
735 int bitmap_type;
736 RGBQUAD* rgbQuads;
737 VOID* colorPtr;
738
739 DPRINT("Entered GreGetDIBitsInternal()\n");
740
741 if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap)
742 return 0;
743
744 pDC = DC_LockDc(hDC);
745 if (pDC == NULL || pDC->dctype == DCTYPE_INFO)
746 {
747 ScanLines = 0;
748 goto done;
749 }
750
751 /* Get a pointer to the source bitmap object */
753 if (psurf == NULL)
754 {
755 ScanLines = 0;
756 goto done;
757 }
758
759 colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize;
760 rgbQuads = colorPtr;
761
762 bitmap_type = DIB_GetBitmapInfo(&Info->bmiHeader,
763 &width,
764 &height,
765 &planes,
766 &bpp,
767 &compr,
768 &size);
769 if(bitmap_type == -1)
770 {
771 DPRINT1("Wrong bitmap format\n");
773 ScanLines = 0;
774 goto done;
775 }
776 else if(bitmap_type == 0)
777 {
778 /* We need a BITMAPINFO to create a DIB, but we have to fill
779 * the BITMAPCOREINFO we're provided */
780 pbmci = (BITMAPCOREINFO*)Info;
781 /* fill in the the bit count, so we can calculate the right ColorsSize during the conversion */
784 if(Info == NULL)
785 {
786 DPRINT1("Error, could not convert the BITMAPCOREINFO!\n");
787 ScanLines = 0;
788 goto done;
789 }
790 rgbQuads = Info->bmiColors;
791 }
792
793 /* Validate input:
794 - negative width is always an invalid value
795 - non-null Bits and zero bpp is an invalid combination
796 - only check the rest of the input params if either bpp is non-zero or Bits are set */
797 if (width < 0 || (bpp == 0 && Bits))
798 {
799 ScanLines = 0;
800 goto done;
801 }
802
803 if (Bits || bpp)
804 {
805 if ((height == 0 || width == 0) || (compr && compr != BI_BITFIELDS && compr != BI_RGB))
806 {
807 ScanLines = 0;
808 goto done;
809 }
810 }
811
812 Info->bmiHeader.biClrUsed = 0;
813 Info->bmiHeader.biClrImportant = 0;
814
815 /* Fill in the structure */
816 switch(bpp)
817 {
818 case 0: /* Only info */
819 Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
820 Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
821 -psurf->SurfObj.sizlBitmap.cy :
822 psurf->SurfObj.sizlBitmap.cy;
823 Info->bmiHeader.biPlanes = 1;
824 Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
825 Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( Info->bmiHeader.biWidth,
826 Info->bmiHeader.biHeight,
827 Info->bmiHeader.biBitCount);
828 Info->bmiHeader.biCompression = (Info->bmiHeader.biBitCount == 16 || Info->bmiHeader.biBitCount == 32) ?
830 Info->bmiHeader.biXPelsPerMeter = 0;
831 Info->bmiHeader.biYPelsPerMeter = 0;
832
833 if (Info->bmiHeader.biBitCount <= 8 && Info->bmiHeader.biClrUsed == 0)
834 Info->bmiHeader.biClrUsed = 1 << Info->bmiHeader.biBitCount;
835
836 ScanLines = 1;
837 goto done;
838
839 case 1:
840 case 4:
841 case 8:
842 Info->bmiHeader.biClrUsed = 1 << bpp;
843
844 /* If the bitmap is a DIB section and has the same format as what
845 * is requested, go ahead! */
846 if((psurf->hSecure) &&
848 {
849 if(Usage == DIB_RGB_COLORS)
850 {
851 ULONG colors = min(psurf->ppal->NumColors, 256);
852 if(colors != 256) Info->bmiHeader.biClrUsed = colors;
853 for(i = 0; i < colors; i++)
854 {
855 rgbQuads[i].rgbRed = psurf->ppal->IndexedColors[i].peRed;
856 rgbQuads[i].rgbGreen = psurf->ppal->IndexedColors[i].peGreen;
857 rgbQuads[i].rgbBlue = psurf->ppal->IndexedColors[i].peBlue;
858 rgbQuads[i].rgbReserved = 0;
859 }
860 }
861 else
862 {
863 for(i = 0; i < 256; i++)
864 ((WORD*)rgbQuads)[i] = i;
865 }
866 }
867 else
868 {
869 if(Usage == DIB_PAL_COLORS)
870 {
871 for(i = 0; i < 256; i++)
872 {
873 ((WORD*)rgbQuads)[i] = i;
874 }
875 }
876 else if(bpp > 1 && bpp == BitsPerFormat(psurf->SurfObj.iBitmapFormat))
877 {
878 /* For color DDBs in native depth (mono DDBs always have
879 a black/white palette):
880 Generate the color map from the selected palette */
881 PPALETTE pDcPal = PALETTE_ShareLockPalette(pDC->dclevel.hpal);
882 if(!pDcPal)
883 {
884 ScanLines = 0 ;
885 goto done ;
886 }
887 for (i = 0; i < pDcPal->NumColors; i++)
888 {
889 rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
890 rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
891 rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
892 rgbQuads[i].rgbReserved = 0;
893 }
895 }
896 else
897 {
898 switch (bpp)
899 {
900 case 1:
901 rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = rgbQuads[0].rgbBlue = 0;
902 rgbQuads[0].rgbReserved = 0;
903 rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = rgbQuads[1].rgbBlue = 0xff;
904 rgbQuads[1].rgbReserved = 0;
905 break;
906
907 case 4:
908 /* The EGA palette is the first and last 8 colours of the default palette
909 with the innermost pair swapped */
910 RtlCopyMemory(rgbQuads, DefLogPaletteQuads, 7 * sizeof(RGBQUAD));
911 RtlCopyMemory(rgbQuads + 7, DefLogPaletteQuads + 12, 1 * sizeof(RGBQUAD));
912 RtlCopyMemory(rgbQuads + 8, DefLogPaletteQuads + 7, 1 * sizeof(RGBQUAD));
913 RtlCopyMemory(rgbQuads + 9, DefLogPaletteQuads + 13, 7 * sizeof(RGBQUAD));
914 break;
915
916 case 8:
917 {
918 INT i;
919
920 memcpy(rgbQuads, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
921 memcpy(rgbQuads + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
922
923 for (i = 10; i < 246; i++)
924 {
925 rgbQuads[i].rgbRed = (i & 0x07) << 5;
926 rgbQuads[i].rgbGreen = (i & 0x38) << 2;
927 rgbQuads[i].rgbBlue = i & 0xc0;
928 rgbQuads[i].rgbReserved = 0;
929 }
930 }
931 }
932 }
933 }
934 break;
935
936 case 15:
937 if (Info->bmiHeader.biCompression == BI_BITFIELDS)
938 {
939 ((PDWORD)Info->bmiColors)[0] = 0x7c00;
940 ((PDWORD)Info->bmiColors)[1] = 0x03e0;
941 ((PDWORD)Info->bmiColors)[2] = 0x001f;
942 }
943 break;
944
945 case 16:
946 if (Info->bmiHeader.biCompression == BI_BITFIELDS)
947 {
948 if (psurf->hSecure)
949 {
950 ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
951 ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
952 ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
953 }
954 else
955 {
956 ((PDWORD)Info->bmiColors)[0] = 0xf800;
957 ((PDWORD)Info->bmiColors)[1] = 0x07e0;
958 ((PDWORD)Info->bmiColors)[2] = 0x001f;
959 }
960 }
961 break;
962
963 case 24:
964 case 32:
965 if (Info->bmiHeader.biCompression == BI_BITFIELDS)
966 {
967 if (psurf->hSecure)
968 {
969 ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
970 ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
971 ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
972 }
973 else
974 {
975 ((PDWORD)Info->bmiColors)[0] = 0xff0000;
976 ((PDWORD)Info->bmiColors)[1] = 0x00ff00;
977 ((PDWORD)Info->bmiColors)[2] = 0x0000ff;
978 }
979 }
980 break;
981
982 default:
983 ScanLines = 0;
984 goto done;
985 }
986
987 Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
988 Info->bmiHeader.biPlanes = 1;
989
990 if(Bits && ScanLines)
991 {
992 /* Create a DIBSECTION, blt it, profit */
993 PVOID pDIBits ;
994 HBITMAP hBmpDest;
995 PSURFACE psurfDest;
996 EXLATEOBJ exlo;
997 RECT rcDest;
998 POINTL srcPoint;
999 BOOL ret ;
1000 int newLines = -1;
1001
1002 if (StartScan >= abs(Info->bmiHeader.biHeight))
1003 {
1004 ScanLines = 1;
1005 goto done;
1006 }
1007 else
1008 {
1009 ScanLines = min(ScanLines, abs(Info->bmiHeader.biHeight) - StartScan);
1010 }
1011
1012 if (abs(Info->bmiHeader.biHeight) < psurf->SurfObj.sizlBitmap.cy)
1013 {
1014 StartScan += psurf->SurfObj.sizlBitmap.cy - abs(Info->bmiHeader.biHeight);
1015 }
1016 /* Fixup values */
1017 Info->bmiHeader.biHeight = (height < 0) ?
1018 -(LONG)ScanLines : ScanLines;
1019 /* Create the DIB */
1020 hBmpDest = DIB_CreateDIBSection(pDC, Info, Usage, &pDIBits, NULL, 0, 0);
1021 /* Restore them */
1022 Info->bmiHeader.biHeight = height;
1023
1024 if(!hBmpDest)
1025 {
1026 DPRINT1("Unable to create a DIB Section!\n");
1028 ScanLines = 0;
1029 goto done ;
1030 }
1031
1032 psurfDest = SURFACE_ShareLockSurface(hBmpDest);
1033
1034 RECTL_vSetRect(&rcDest, 0, 0, Info->bmiHeader.biWidth, ScanLines);
1035 Info->bmiHeader.biWidth = width;
1036 srcPoint.x = 0;
1037
1038 if (abs(Info->bmiHeader.biHeight) <= psurf->SurfObj.sizlBitmap.cy)
1039 {
1040 srcPoint.y = psurf->SurfObj.sizlBitmap.cy - StartScan - ScanLines;
1041 }
1042 else
1043 {
1044 /* Determine the actual number of lines copied from the */
1045 /* original bitmap. It might be different from ScanLines. */
1046 newLines = abs(Info->bmiHeader.biHeight) - psurf->SurfObj.sizlBitmap.cy;
1047 newLines = min((int)(StartScan + ScanLines - newLines), psurf->SurfObj.sizlBitmap.cy);
1048 if (newLines > 0)
1049 {
1050 srcPoint.y = psurf->SurfObj.sizlBitmap.cy - newLines;
1051 if (StartScan > psurf->SurfObj.sizlBitmap.cy)
1052 {
1053 newLines -= (StartScan - psurf->SurfObj.sizlBitmap.cy);
1054 }
1055 }
1056 else
1057 {
1058 newLines = 0;
1059 srcPoint.y = psurf->SurfObj.sizlBitmap.cy;
1060 }
1061 }
1062
1063 EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0xffffff, 0xffffff, 0);
1064
1065 ret = IntEngCopyBits(&psurfDest->SurfObj,
1066 &psurf->SurfObj,
1067 NULL,
1068 &exlo.xlo,
1069 &rcDest,
1070 &srcPoint);
1071
1072 SURFACE_ShareUnlockSurface(psurfDest);
1073
1074 if(!ret)
1075 ScanLines = 0;
1076 else
1077 {
1078 RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, ScanLines, bpp));
1079 }
1080 /* Update if line count has changed */
1081 if (newLines != -1)
1082 {
1083 ScanLines = (UINT)newLines;
1084 }
1085 GreDeleteObject(hBmpDest);
1086 EXLATEOBJ_vCleanup(&exlo);
1087 }
1088 else
1089 {
1090 /* Signals success and not the actual number of scan lines*/
1091 ScanLines = 1;
1092 }
1093
1094done:
1095
1096 if (pbmci)
1098
1099 if (psurf)
1101
1102 if (pDC)
1103 DC_UnlockDc(pDC);
1104
1105 return ScanLines;
1106}
1107
1108_Success_(return!=0)
1110INT
1112NtGdiGetDIBitsInternal(
1113 _In_ HDC hdc,
1122{
1123 PBITMAPINFO pbmiSafe;
1124 HANDLE hSecure = NULL;
1125 INT iResult = 0;
1126 UINT cjAlloc;
1127
1128 /* Check for bad iUsage */
1129 if (iUsage > 2) return 0;
1130
1131 /* Check if the size of the bitmap info is large enough */
1132 if (cjMaxInfo < sizeof(BITMAPCOREHEADER))
1133 {
1134 return 0;
1135 }
1136
1137 /* Use maximum size */
1138 cjMaxInfo = min(cjMaxInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD));
1139
1140 // HACK: the underlying code sucks and doesn't care for the size, so we
1141 // give it the maximum ever needed
1142 cjAlloc = sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD);
1143
1144 /* Allocate a buffer the bitmapinfo */
1145 pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjAlloc, 'imBG');
1146 if (!pbmiSafe)
1147 {
1148 /* Fail */
1149 return 0;
1150 }
1151
1152 /* Use SEH */
1153 _SEH2_TRY
1154 {
1155 /* Probe and copy the BITMAPINFO */
1157 RtlCopyMemory(pbmiSafe, pbmi, cjMaxInfo);
1158 }
1160 {
1161 goto cleanup;
1162 }
1163 _SEH2_END;
1164
1165 /* Check if the header size is large enough */
1166 if ((pbmiSafe->bmiHeader.biSize < sizeof(BITMAPCOREHEADER)) ||
1167 (pbmiSafe->bmiHeader.biSize > cjMaxInfo))
1168 {
1169 goto cleanup;
1170 }
1171
1172 /* Check if the caller provided bitmap bits */
1173 if (pjBits)
1174 {
1175 /* Secure the user mode memory */
1176 hSecure = EngSecureMem(pjBits, cjMaxBits);
1177 if (!hSecure)
1178 {
1179 goto cleanup;
1180 }
1181 }
1182
1183 /* Now call the internal function */
1184 iResult = GreGetDIBitsInternal(hdc,
1185 hbm,
1186 iStartScan,
1187 cScans,
1188 pjBits,
1189 pbmiSafe,
1190 iUsage,
1191 cjMaxBits,
1192 cjMaxInfo);
1193
1194 /* Check for success */
1195 if (iResult)
1196 {
1197 /* Use SEH to copy back to user mode */
1198 _SEH2_TRY
1199 {
1200 /* Copy the data back */
1203 RtlCopyMemory(pbmi, pbmiSafe, cjMaxInfo);
1204 }
1206 {
1207 /* Ignore */
1208 (VOID)0;
1209 }
1210 _SEH2_END;
1211 }
1212
1213cleanup:
1214 if (hSecure) EngUnsecureMem(hSecure);
1215 ExFreePoolWithTag(pbmiSafe, 'imBG');
1216
1217 return iResult;
1218}
1219
1220W32KAPI
1221INT
1224 IN HDC hdc,
1225 IN INT xDst,
1226 IN INT yDst,
1227 IN INT cxDst,
1228 IN INT cyDst,
1229 IN INT xSrc,
1230 IN INT ySrc,
1231 IN INT cxSrc,
1232 IN INT cySrc,
1233 IN OPTIONAL LPBYTE pjInit,
1235 IN DWORD dwUsage,
1236 IN DWORD dwRop, // MS ntgdi.h says dwRop4(?)
1240{
1241 SIZEL sizel;
1242 RECTL rcSrc, rcDst;
1243 PDC pdc;
1244 HBITMAP hbmTmp = 0;
1245 PSURFACE psurfTmp = 0, psurfDst = 0;
1246 PPALETTE ppalDIB = 0;
1247 EXLATEOBJ exlo;
1248 PBYTE pvBits;
1249
1250 LPBITMAPINFO pbmiSafe;
1251 UINT cjAlloc;
1252 HBITMAP hBitmap, hOldBitmap = NULL;
1253 HDC hdcMem;
1254 HPALETTE hPal = NULL;
1255 ULONG BmpFormat = 0;
1256 INT LinesCopied = 0;
1257
1258 /* Check for bad iUsage */
1259 if (dwUsage > 2) return 0;
1260
1261 /* We must have LPBITMAPINFO */
1262 if (!pbmi)
1263 {
1264 DPRINT1("Error, Invalid Parameter.\n");
1266 return 0;
1267 }
1268
1269 /* Check if the size of the bitmap info is large enough */
1270 if (cjMaxInfo < sizeof(BITMAPCOREHEADER))
1271 {
1272 return 0;
1273 }
1274
1275 /* Use maximum size */
1276 cjMaxInfo = min(cjMaxInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD));
1277
1278 // HACK: the underlying code sucks and doesn't care for the size, so we
1279 // give it the maximum ever needed
1280 cjAlloc = sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD);
1281
1282 /* Allocate a buffer the bitmapinfo */
1283 pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjAlloc, 'imBG');
1284 if (!pbmiSafe)
1285 {
1286 /* Fail */
1287 return 0;
1288 }
1289
1290 /* Use SEH */
1291 _SEH2_TRY
1292 {
1293 /* Probe and copy the BITMAPINFO */
1295 RtlCopyMemory(pbmiSafe, pbmi, cjMaxInfo);
1296 }
1298 {
1299 ExFreePoolWithTag(pbmiSafe, 'imBG');
1300 return 0;
1301 }
1302 _SEH2_END;
1303
1304 /* Check if the header size is large enough */
1305 if ((pbmiSafe->bmiHeader.biSize < sizeof(BITMAPCOREHEADER)) ||
1306 (pbmiSafe->bmiHeader.biSize > cjMaxInfo))
1307 {
1308 ExFreePoolWithTag(pbmiSafe, 'imBG');
1309 return 0;
1310 }
1311
1312 if (!(pdc = DC_LockDc(hdc)))
1313 {
1315 return 0;
1316 }
1317
1318 /* Check for info / mem DC without surface */
1319 if (!pdc->dclevel.pSurface)
1320 {
1321 DC_UnlockDc(pdc);
1322 // CHECKME
1323 return TRUE;
1324 }
1325
1326 /* Transform dest size */
1327 sizel.cx = cxDst;
1328 sizel.cy = cyDst;
1329 IntLPtoDP(pdc, (POINTL*)&sizel, 1);
1330 DC_UnlockDc(pdc);
1331
1332 if (pjInit && (cjMaxBits > 0))
1333 {
1335 if (!pvBits)
1336 {
1337 return 0;
1338 }
1339
1340 _SEH2_TRY
1341 {
1342 ProbeForRead(pjInit, cjMaxBits, 1);
1343 RtlCopyMemory(pvBits, pjInit, cjMaxBits);
1344 }
1346 {
1347 ExFreePoolWithTag(pvBits, TAG_DIB);
1348 return 0;
1349 }
1350 _SEH2_END;
1351 }
1352 else
1353 {
1354 pvBits = NULL;
1355 }
1356
1357 /* Here we select between the dwRop with SRCCOPY or not. */
1358 if (dwRop == SRCCOPY)
1359 {
1361 if (hdcMem == NULL)
1362 {
1363 DPRINT1("NtGdiCreateCompatibleDC failed to create hdc.\n");
1365 return 0;
1366 }
1367
1369 abs(pbmiSafe->bmiHeader.biWidth),
1370 abs(pbmiSafe->bmiHeader.biHeight));
1371 if (hBitmap == NULL)
1372 {
1373 DPRINT1("NtGdiCreateCompatibleBitmap failed to create bitmap.\n");
1374 DPRINT1("hdc : 0x%08x \n", hdc);
1375 DPRINT1("width : 0x%08x \n", pbmiSafe->bmiHeader.biWidth);
1376 DPRINT1("height : 0x%08x \n", pbmiSafe->bmiHeader.biHeight);
1378 return 0;
1379 }
1380
1381 /* Select the bitmap into hdcMem, and save a handle to the old bitmap */
1382 hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
1383
1384 if (dwUsage == DIB_PAL_COLORS)
1385 {
1387 hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
1388 }
1389
1390 pdc = DC_LockDc(hdcMem);
1391 if (pdc != NULL)
1392 {
1393 IntSetDIBits(pdc, hBitmap, 0, abs(pbmiSafe->bmiHeader.biHeight), pvBits,
1394 cjMaxBits, pbmiSafe, dwUsage);
1395 DC_UnlockDc(pdc);
1396 }
1397
1398 /* Origin for DIBitmap may be bottom left (positive biHeight) or top
1399 left (negative biHeight) */
1400 if (cxSrc == cxDst && cySrc == cyDst)
1401 {
1402 NtGdiBitBlt(hdc, xDst, yDst, cxDst, cyDst,
1403 hdcMem, xSrc, abs(pbmiSafe->bmiHeader.biHeight) - cySrc - ySrc,
1404 dwRop, 0, 0);
1405 }
1406 else
1407 {
1408 NtGdiStretchBlt(hdc, xDst, yDst, cxDst, cyDst,
1409 hdcMem, xSrc, abs(pbmiSafe->bmiHeader.biHeight) - cySrc - ySrc,
1410 cxSrc, cySrc, dwRop, 0);
1411 }
1412
1413 /* cleanup */
1414 if (hPal)
1416
1417 if (hOldBitmap)
1418 NtGdiSelectBitmap(hdcMem, hOldBitmap);
1419
1422
1423 } /* End of dwRop == SRCCOPY */
1424 else
1425 { /* Start of dwRop != SRCCOPY */
1426 /* FIXME: Locking twice is cheesy, coord tranlation in UM will fix it */
1427 if (!(pdc = DC_LockDc(hdc)))
1428 {
1429 DPRINT1("Could not lock dc\n");
1431 goto cleanup;
1432 }
1433
1434 /* Calculate source and destination rect */
1435 rcSrc.left = xSrc;
1436 rcSrc.top = ySrc;
1437 rcSrc.right = xSrc + abs(cxSrc);
1438 rcSrc.bottom = ySrc + abs(cySrc);
1439 rcDst.left = xDst;
1440 rcDst.top = yDst;
1441 rcDst.right = rcDst.left + cxDst;
1442 rcDst.bottom = rcDst.top + cyDst;
1443 IntLPtoDP(pdc, (POINTL*)&rcDst, 2);
1444 RECTL_vOffsetRect(&rcDst, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
1445
1446 if (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
1447 {
1448 IntUpdateBoundsRect(pdc, &rcDst);
1449 }
1450
1451 BmpFormat = BitmapFormat(pbmiSafe->bmiHeader.biBitCount,
1452 pbmiSafe->bmiHeader.biCompression);
1453
1454 hbmTmp = GreCreateBitmapEx(pbmiSafe->bmiHeader.biWidth,
1455 abs(pbmiSafe->bmiHeader.biHeight),
1456 0,
1457 BmpFormat,
1458 pbmiSafe->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
1459 cjMaxBits,
1460 pvBits,
1461 0);
1462
1463 if (!hbmTmp)
1464 {
1465 goto cleanup;
1466 }
1467
1468 psurfTmp = SURFACE_ShareLockSurface(hbmTmp);
1469 if (!psurfTmp)
1470 {
1471 goto cleanup;
1472 }
1473
1474 /* Create a palette for the DIB */
1475 ppalDIB = CreateDIBPalette(pbmiSafe, pdc, dwUsage);
1476 if (!ppalDIB)
1477 {
1478 goto cleanup;
1479 }
1480
1481 /* Prepare DC for blit */
1482 DC_vPrepareDCsForBlit(pdc, &rcDst, NULL, NULL);
1483
1484 psurfDst = pdc->dclevel.pSurface;
1485
1486 /* Initialize XLATEOBJ */
1488 ppalDIB,
1489 psurfDst->ppal,
1490 RGB(0xff, 0xff, 0xff),
1491 pdc->pdcattr->crBackgroundClr,
1492 pdc->pdcattr->crForegroundClr);
1493
1494 /* Perform the stretch operation */
1495 IntEngStretchBlt(&psurfDst->SurfObj,
1496 &psurfTmp->SurfObj,
1497 NULL,
1498 (CLIPOBJ *)&pdc->co,
1499 &exlo.xlo,
1500 &pdc->dclevel.ca,
1501 &rcDst,
1502 &rcSrc,
1503 NULL,
1504 &pdc->eboFill.BrushObject,
1505 NULL,
1506 WIN32_ROP3_TO_ENG_ROP4(dwRop));
1507
1508 /* Cleanup */
1509 DC_vFinishBlit(pdc, NULL);
1510 EXLATEOBJ_vCleanup(&exlo);
1511
1512 cleanup:
1513 if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
1514 if (psurfTmp) SURFACE_ShareUnlockSurface(psurfTmp);
1515 if (hbmTmp) GreDeleteObject(hbmTmp);
1516 if (pdc) DC_UnlockDc(pdc);
1517 }
1518
1519 if (pvBits) ExFreePoolWithTag(pvBits, TAG_DIB);
1520
1521 /* This is not what MSDN says is returned from this function, but it
1522 * follows Wine's dlls/gdi32/dib.c function nulldrv_StretchDIBits
1523 * and it fixes over 100 gdi32:dib regression tests. */
1524 if (dwRop == SRCCOPY)
1525 {
1526 LinesCopied = abs(pbmiSafe->bmiHeader.biHeight);
1527 }
1528 else
1529 {
1530 LinesCopied = pbmiSafe->bmiHeader.biHeight;
1531 }
1532
1533 ExFreePoolWithTag(pbmiSafe, 'imBG');
1534
1535 return LinesCopied;
1536}
1537
1538HBITMAP
1541 PDC Dc,
1542 INT width,
1543 INT height,
1544 UINT planes,
1545 UINT bpp,
1547 DWORD init,
1548 LPBYTE bits,
1551 DWORD coloruse)
1552{
1554 BOOL fColor;
1555 ULONG BmpFormat = 0;
1556
1557 if (planes && bpp)
1558 BmpFormat = BitmapFormat(planes * bpp, compression);
1559
1560 // Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
1561 // colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.
1562
1563 if (BmpFormat != BMF_1BPP) fColor = TRUE;
1564 else if ((coloruse > DIB_RGB_COLORS) || ((init & CBM_INIT) == 0) || !data) fColor = FALSE;
1565 else
1566 {
1567 const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize);
1568 DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
1569
1570 // Check if the first color of the colormap is black
1571 if (col == RGB(0, 0, 0))
1572 {
1573 rgb++;
1574 col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
1575
1576 // If the second color is white, create a monochrome bitmap
1577 fColor = (col != RGB(0xff,0xff,0xff));
1578 }
1579 else fColor = TRUE;
1580 }
1581
1582 // Now create the bitmap
1583 if (fColor)
1584 {
1585 if (init & CBM_CREATDIB)
1586 {
1587 PSURFACE Surface;
1588 PPALETTE Palette;
1589
1590 /* Undocumented flag which creates a DDB of the format specified by the bitmap info. */
1592 if (!handle)
1593 {
1594 DPRINT1("IntCreateCompatibleBitmap() failed!\n");
1595 return NULL;
1596 }
1597
1598 /* The palette must also match the given data */
1600 ASSERT(Surface);
1601 Palette = CreateDIBPalette(data, Dc, coloruse);
1602 if (Palette == NULL)
1603 {
1606 return NULL;
1607 }
1608
1609 SURFACE_vSetPalette(Surface, Palette);
1610
1613 }
1614 else
1615 {
1616 /* Create a regular compatible bitmap, in the same format as the device */
1618 }
1619 }
1620 else
1621 {
1623 abs(height),
1624 1,
1625 1,
1626 NULL);
1627 }
1628
1629 if (height < 0)
1630 height = -height;
1631
1632 if ((NULL != handle) && (CBM_INIT & init))
1633 {
1634 IntSetDIBits(Dc, handle, 0, height, bits, cjMaxBits, data, coloruse);
1635 }
1636
1637 return handle;
1638}
1639
1640// The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
1641// The DDB that is created will be whatever bit depth your reference DC is
1642HBITMAP
1645 IN HDC hDc,
1646 IN INT cx,
1647 IN INT cy,
1648 IN DWORD fInit,
1649 IN OPTIONAL LPBYTE pjInit,
1651 IN DWORD iUsage,
1652 IN UINT cjMaxInitInfo,
1654 IN FLONG fl,
1656{
1658 PBYTE safeBits = NULL;
1659 HBITMAP hbmResult = NULL;
1660
1661 if (pjInit == NULL)
1662 {
1663 fInit &= ~CBM_INIT;
1664 }
1665
1666 if(pjInit && (fInit & CBM_INIT))
1667 {
1668 if (cjMaxBits == 0) return NULL;
1670 if(!safeBits)
1671 {
1672 DPRINT1("Failed to allocate %lu bytes\n", cjMaxBits);
1674 return NULL;
1675 }
1676 }
1677
1678 _SEH2_TRY
1679 {
1680 if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
1681 if(pjInit && (fInit & CBM_INIT))
1682 {
1683 ProbeForRead(pjInit, cjMaxBits, 1);
1684 RtlCopyMemory(safeBits, pjInit, cjMaxBits);
1685 }
1686 }
1688 {
1690 }
1691 _SEH2_END;
1692
1693 if(!NT_SUCCESS(Status))
1694 {
1695 DPRINT1("Got an exception! pjInit = %p\n", pjInit);
1697 goto cleanup;
1698 }
1699
1700 hbmResult = GreCreateDIBitmapInternal(hDc,
1701 cx,
1702 cy,
1703 fInit,
1704 safeBits,
1705 pbmi,
1706 iUsage,
1707 fl,
1708 cjMaxBits,
1709 hcmXform);
1710
1711cleanup:
1712 if (safeBits) ExFreePoolWithTag(safeBits, TAG_DIB);
1713 return hbmResult;
1714}
1715
1716HBITMAP
1717NTAPI
1719 IN HDC hDc,
1720 IN INT cx,
1721 IN INT cy,
1722 IN DWORD fInit,
1723 IN OPTIONAL LPBYTE pjInit,
1725 IN DWORD iUsage,
1726 IN FLONG fl,
1729{
1730 PDC Dc;
1731 HBITMAP Bmp;
1732 USHORT bpp, planes;
1734 HDC hdcDest;
1735
1736 if (!hDc) /* 1bpp monochrome bitmap */
1737 {
1738 // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
1739 hdcDest = NtGdiCreateCompatibleDC(0);
1740 if(!hdcDest)
1741 {
1742 DPRINT1("NtGdiCreateCompatibleDC failed\n");
1743 return NULL;
1744 }
1745 }
1746 else
1747 {
1748 hdcDest = hDc;
1749 }
1750
1751 Dc = DC_LockDc(hdcDest);
1752 if (!Dc)
1753 {
1754 DPRINT1("Failed to lock hdcDest %p\n", hdcDest);
1756 return NULL;
1757 }
1758 /* It's OK to set bpp=0 here, as IntCreateDIBitmap will create a compatible Bitmap
1759 * if bpp != 1 and ignore the real value that was passed */
1760 if (pbmi)
1761 {
1762 if (pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1763 {
1765 bpp = CoreHeader->bcBitCount;
1766 planes = CoreHeader->bcPlanes ? CoreHeader->bcPlanes : 1;
1768 }
1769 else
1770 {
1772 planes = pbmi->bmiHeader.biPlanes ? pbmi->bmiHeader.biPlanes : 1;
1774 }
1775 }
1776 else
1777 {
1778 bpp = 0;
1779 planes = 0;
1780 compression = 0;
1781 }
1782 Bmp = IntCreateDIBitmap(Dc, cx, cy, planes, bpp, compression, fInit, pjInit, cjMaxBits, pbmi, iUsage);
1783 DC_UnlockDc(Dc);
1784
1785 if(!hDc)
1786 {
1787 NtGdiDeleteObjectApp(hdcDest);
1788 }
1789 return Bmp;
1790}
1791
1792HBITMAP
1793NTAPI
1795 _In_reads_(cjPackedDIB )PVOID pvPackedDIB,
1796 _In_ UINT cjPackedDIB,
1797 _In_ ULONG uUsage)
1798{
1800 PBYTE pjBits;
1801 UINT cjInfo, cjBits;
1802 HBITMAP hbm;
1803
1804 /* We only support BITMAPINFOHEADER, make sure the size is ok */
1805 if (cjPackedDIB < sizeof(BITMAPINFOHEADER))
1806 {
1807 return NULL;
1808 }
1809
1810 /* The packed DIB starts with the BITMAPINFOHEADER */
1811 pbmi = pvPackedDIB;
1812
1813 if (cjPackedDIB < pbmi->bmiHeader.biSize)
1814 {
1815 return NULL;
1816 }
1817
1818 /* Calculate the info size and make sure the packed DIB is large enough */
1819 cjInfo = DIB_BitmapInfoSize(pbmi, uUsage);
1820 if (cjPackedDIB <= cjInfo)
1821 {
1822 return NULL;
1823 }
1824
1825 /* The bitmap bits start after the header */
1826 pjBits = (PBYTE)pvPackedDIB + cjInfo;
1827 cjBits = cjPackedDIB - cjInfo;
1828
1833 pjBits,
1834 pbmi,
1835 uUsage,
1836 0,
1837 cjBits,
1838 NULL);
1839
1840 return hbm;
1841}
1842
1843HBITMAP
1846 IN HDC hDC,
1849 IN BITMAPINFO* bmi,
1850 IN DWORD Usage,
1851 IN UINT cjHeader,
1852 IN FLONG fl,
1853 IN ULONG_PTR dwColorSpace,
1854 OUT PVOID *Bits)
1855{
1856 HBITMAP hbitmap = 0;
1857 DC *dc;
1858 BOOL bDesktopDC = FALSE;
1860
1861 if (!bmi) return hbitmap; // Make sure.
1862
1863 _SEH2_TRY
1864 {
1865 ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
1866 ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
1867 ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, (WORD)Usage), 1);
1868 }
1870 {
1872 }
1873 _SEH2_END;
1874
1875 if(!NT_SUCCESS(Status))
1876 {
1878 return NULL;
1879 }
1880
1881 // If the reference hdc is null, take the desktop dc
1882 if (hDC == 0)
1883 {
1885 bDesktopDC = TRUE;
1886 }
1887
1888 if ((dc = DC_LockDc(hDC)))
1889 {
1891 bmi,
1892 Usage,
1893 Bits,
1894 hSection,
1895 dwOffset,
1896 0);
1897 DC_UnlockDc(dc);
1898 }
1899 else
1900 {
1902 }
1903
1904 if (bDesktopDC)
1906
1907 return hbitmap;
1908}
1909
1910HBITMAP
1913 PDC dc,
1914 CONST BITMAPINFO *bmi,
1915 UINT usage,
1916 LPVOID *bits,
1918 DWORD offset,
1919 DWORD ovr_pitch)
1920{
1921 HBITMAP res = 0;
1922 SURFACE *bmp = NULL;
1923 void *mapBits = NULL;
1924 PPALETTE ppalDIB = NULL;
1925
1926 // Fill BITMAP32 structure with DIB data
1927 CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
1928 INT effHeight;
1929 ULONG totalSize;
1930 BITMAP bm;
1931 //SIZEL Size;
1932 HANDLE hSecure;
1933
1934 DPRINT("format (%ld,%ld), planes %u, bpp %u, size %lu, colors %lu (%s)\n",
1935 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
1936 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1937
1938 /* CreateDIBSection should fail for compressed formats */
1939 if (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8)
1940 {
1941 DPRINT1("no compressed format allowed\n");
1942 return (HBITMAP)NULL;
1943 }
1944
1945 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
1946 bm.bmType = 0;
1947 bm.bmWidth = bi->biWidth;
1948 bm.bmHeight = effHeight;
1949 bm.bmWidthBytes = ovr_pitch ? ovr_pitch : WIDTH_BYTES_ALIGN32(bm.bmWidth, bi->biBitCount);
1950
1951 bm.bmPlanes = bi->biPlanes;
1952 bm.bmBitsPixel = bi->biBitCount;
1953 bm.bmBits = NULL;
1954
1955 // Get storage location for DIB bits. Only use biSizeImage if it's valid and
1956 // we're dealing with a compressed bitmap. Otherwise, use width * height.
1957 totalSize = (bi->biSizeImage && (bi->biCompression != BI_RGB) && (bi->biCompression != BI_BITFIELDS))
1958 ? bi->biSizeImage : (ULONG)(bm.bmWidthBytes * effHeight);
1959
1960 if (section)
1961 {
1964 DWORD mapOffset;
1966 SIZE_T mapSize;
1967
1969 &Sbi,
1970 sizeof Sbi,
1971 0);
1972 if (!NT_SUCCESS(Status))
1973 {
1974 DPRINT1("ZwQuerySystemInformation failed (0x%lx)\n", Status);
1975 return NULL;
1976 }
1977
1978 mapOffset = offset - (offset % Sbi.AllocationGranularity);
1979 mapSize = totalSize + (offset - mapOffset);
1980
1981 SectionOffset.LowPart = mapOffset;
1982 SectionOffset.HighPart = 0;
1983
1984 Status = ZwMapViewOfSection(section,
1986 &mapBits,
1987 0,
1988 0,
1990 &mapSize,
1991 ViewShare,
1992 0,
1994 if (!NT_SUCCESS(Status))
1995 {
1996 DPRINT1("ZwMapViewOfSection failed (0x%lx)\n", Status);
1998 return NULL;
1999 }
2000
2001 if (mapBits) bm.bmBits = (char *)mapBits + (offset - mapOffset);
2002 }
2003 else if (ovr_pitch && offset)
2004 bm.bmBits = UlongToPtr(offset);
2005 else
2006 {
2007 offset = 0;
2008 bm.bmBits = EngAllocUserMem(totalSize, 0);
2009 if(!bm.bmBits)
2010 {
2011 DPRINT1("Failed to allocate memory\n");
2012 goto cleanup;
2013 }
2014 }
2015
2016// hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE);
2017 hSecure = (HANDLE)0x1; // HACK OF UNIMPLEMENTED KERNEL STUFF !!!!
2018
2019 // Create Device Dependent Bitmap and add DIB pointer
2020 //Size.cx = bm.bmWidth;
2021 //Size.cy = abs(bm.bmHeight);
2022 res = GreCreateBitmapEx(bm.bmWidth,
2023 abs(bm.bmHeight),
2024 bm.bmWidthBytes,
2025 BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
2027 ((bi->biHeight < 0) ? BMF_TOPDOWN : 0),
2028 totalSize,
2029 bm.bmBits,
2030 0);
2031 if (!res)
2032 {
2033 DPRINT1("GreCreateBitmapEx failed\n");
2035 goto cleanup;
2036 }
2037 bmp = SURFACE_ShareLockSurface(res); // HACK
2038 if (NULL == bmp)
2039 {
2040 DPRINT1("SURFACE_LockSurface failed\n");
2042 goto cleanup;
2043 }
2044
2045 /* WINE NOTE: WINE makes use of a colormap, which is a color translation
2046 table between the DIB and the X physical device. Obviously,
2047 this is left out of the ReactOS implementation. Instead,
2048 we call NtGdiSetDIBColorTable. */
2049 bmp->hDIBSection = section;
2050 bmp->hSecure = hSecure;
2051 bmp->dwOffset = offset;
2052 bmp->flags = API_BITMAP;
2053 bmp->biClrImportant = bi->biClrImportant;
2054
2055 /* Create a palette for the DIB */
2056 ppalDIB = CreateDIBPalette(bmi, dc, usage);
2057
2058 // Clean up in case of errors
2059cleanup:
2060 if (!res || !bmp || !bm.bmBits || !ppalDIB)
2061 {
2062 DPRINT("Got an error res=%p, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
2063 if (bm.bmBits)
2064 {
2065 // MmUnsecureVirtualMemory(hSecure); // FIXME: Implement this!
2066 if (section)
2067 {
2068 ZwUnmapViewOfSection(NtCurrentProcess(), mapBits);
2069 bm.bmBits = NULL;
2070 }
2071 else if (!offset)
2072 EngFreeUserMem(bm.bmBits), bm.bmBits = NULL;
2073 }
2074
2075 if (bmp)
2076 {
2078 bmp = NULL;
2079 }
2080
2081 if (res)
2082 {
2084 res = 0;
2085 }
2086
2087 if(ppalDIB)
2088 {
2090 }
2091 }
2092
2093 if (bmp)
2094 {
2095 /* If we're here, everything went fine */
2096 SURFACE_vSetPalette(bmp, ppalDIB);
2099 }
2100
2101 // Return BITMAP handle and storage location
2102 if (NULL != bm.bmBits && NULL != bits)
2103 {
2104 *bits = bm.bmBits;
2105 }
2106
2107 return res;
2108}
2109
2110/***********************************************************************
2111 * DIB_GetBitmapInfo
2112 *
2113 * Get the info from a bitmap header.
2114 * Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
2115 */
2116int
2119 LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
2120{
2121 if (header->biSize == sizeof(BITMAPCOREHEADER))
2122 {
2123 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
2124 *width = core->bcWidth;
2125 *height = core->bcHeight;
2126 *planes = core->bcPlanes;
2127 *bpp = core->bcBitCount;
2128 *compr = BI_RGB;
2129 *size = 0;
2130 return 0;
2131 }
2132 if (header->biSize >= sizeof(BITMAPINFOHEADER)) /* Assume BITMAPINFOHEADER */
2133 {
2134 *width = header->biWidth;
2135 *height = header->biHeight;
2136 *planes = header->biPlanes;
2137 *bpp = header->biBitCount;
2138 *compr = header->biCompression;
2139 *size = header->biSizeImage;
2140 return 1;
2141 }
2142 DPRINT1("(%u): unknown/wrong size for header\n", header->biSize );
2143 return -1;
2144}
2145
2146/***********************************************************************
2147 * DIB_GetDIBImageBytes
2148 *
2149 * Return the number of bytes used to hold the image in a DIB bitmap.
2150 * 11/16/1999 (RJJ) lifted from wine
2151 */
2152
2154{
2155 return WIDTH_BYTES_ALIGN32(width, depth) * (height < 0 ? -height : height);
2156}
2157
2158/***********************************************************************
2159 * DIB_BitmapInfoSize
2160 *
2161 * Return the size of the bitmap info structure including color table.
2162 * 11/16/1999 (RJJ) lifted from wine
2163 */
2164
2166{
2167 unsigned int colors, size, masks = 0;
2168 unsigned int colorsize;
2169
2170 colorsize = (coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) :
2171 (coloruse == DIB_PAL_INDICES) ? 0 :
2172 sizeof(WORD);
2173
2174 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
2175 {
2176 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
2177 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
2178 return sizeof(BITMAPCOREHEADER) + colors * colorsize;
2179 }
2180 else /* Assume BITMAPINFOHEADER */
2181 {
2182 colors = info->bmiHeader.biClrUsed;
2183 if (colors > 256) colors = 256;
2184 if (!colors && (info->bmiHeader.biBitCount <= 8))
2185 colors = 1 << info->bmiHeader.biBitCount;
2186 if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
2187 size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
2188 return size + colors * colorsize;
2189 }
2190}
2191
2192HPALETTE
2195{
2196 PPALETTE ppalNew;
2197 ULONG nNumColors,i;
2198 USHORT *lpIndex;
2199 HPALETTE hpal;
2200
2201 if (!(ppalDc->flFlags & PAL_INDEXED))
2202 {
2203 return NULL;
2204 }
2205
2206 nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
2207 if (lpbmi->bmiHeader.biClrUsed)
2208 {
2209 nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
2210 }
2211
2212 ppalNew = PALETTE_AllocPalWithHandle(PAL_INDEXED, nNumColors, NULL, 0, 0, 0);
2213 if (ppalNew == NULL)
2214 {
2215 DPRINT1("Could not allocate palette\n");
2216 return NULL;
2217 }
2218
2219 lpIndex = (USHORT *)((PBYTE)lpbmi + lpbmi->bmiHeader.biSize);
2220
2221 for (i = 0; i < nNumColors; i++)
2222 {
2223 ULONG iColorIndex = *lpIndex % ppalDc->NumColors;
2224 ppalNew->IndexedColors[i] = ppalDc->IndexedColors[iColorIndex];
2225 lpIndex++;
2226 }
2227
2228 hpal = ppalNew->BaseObject.hHmgr;
2229 PALETTE_UnlockPalette(ppalNew);
2230
2231 return hpal;
2232}
2233
2234/* Converts a BITMAPCOREINFO to a BITMAPINFO structure,
2235 * or does nothing if it's already a BITMAPINFO (or V4 or V5) */
2239{
2241 BITMAPINFO* pNewBmi ;
2242 UINT numColors = 0, ColorsSize = 0;
2243
2244 if(pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) return (BITMAPINFO*)pbmi;
2245 if(pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) return NULL;
2246
2247 if(pbmci->bmciHeader.bcBitCount <= 8)
2248 {
2249 numColors = 1 << pbmci->bmciHeader.bcBitCount;
2250 if(Usage == DIB_PAL_COLORS)
2251 {
2252 ColorsSize = numColors * sizeof(WORD);
2253 }
2254 else
2255 {
2256 ColorsSize = numColors * sizeof(RGBQUAD);
2257 }
2258 }
2259 else if (Usage == DIB_PAL_COLORS)
2260 {
2261 /* Invalid at high-res */
2262 return NULL;
2263 }
2264
2265 pNewBmi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + ColorsSize, TAG_DIB);
2266 if(!pNewBmi) return NULL;
2267
2268 RtlZeroMemory(pNewBmi, sizeof(BITMAPINFOHEADER) + ColorsSize);
2269
2270 pNewBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2271 pNewBmi->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount;
2272 pNewBmi->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth;
2273 pNewBmi->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight;
2274 pNewBmi->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes;
2275 pNewBmi->bmiHeader.biCompression = BI_RGB ;
2277 pNewBmi->bmiHeader.biHeight,
2278 pNewBmi->bmiHeader.biBitCount);
2279 pNewBmi->bmiHeader.biClrUsed = numColors;
2280
2281 if(Usage == DIB_PAL_COLORS)
2282 {
2283 RtlCopyMemory(pNewBmi->bmiColors, pbmci->bmciColors, ColorsSize);
2284 }
2285 else
2286 {
2287 UINT i;
2288 for(i=0; i<numColors; i++)
2289 {
2290 pNewBmi->bmiColors[i].rgbRed = pbmci->bmciColors[i].rgbtRed;
2291 pNewBmi->bmiColors[i].rgbGreen = pbmci->bmciColors[i].rgbtGreen;
2292 pNewBmi->bmiColors[i].rgbBlue = pbmci->bmciColors[i].rgbtBlue;
2293 }
2294 }
2295
2296 return pNewBmi ;
2297}
2298
2299/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */
2300VOID
2303{
2304 BITMAPCOREINFO* pbmci;
2305 if(converted == orig)
2306 return;
2307
2308 if(usage == -1)
2309 {
2310 /* Caller don't want any conversion */
2311 ExFreePoolWithTag(converted, TAG_DIB);
2312 return;
2313 }
2314
2315 /* Perform inverse conversion */
2316 pbmci = (BITMAPCOREINFO*)orig;
2317
2318 ASSERT(pbmci->bmciHeader.bcSize == sizeof(BITMAPCOREHEADER));
2319 pbmci->bmciHeader.bcBitCount = converted->bmiHeader.biBitCount;
2320 pbmci->bmciHeader.bcWidth = converted->bmiHeader.biWidth;
2321 pbmci->bmciHeader.bcHeight = converted->bmiHeader.biHeight;
2322 pbmci->bmciHeader.bcPlanes = converted->bmiHeader.biPlanes;
2323
2324 if(pbmci->bmciHeader.bcBitCount <= 8)
2325 {
2326 UINT numColors = converted->bmiHeader.biClrUsed;
2327 if(!numColors) numColors = 1 << pbmci->bmciHeader.bcBitCount;
2328 if(usage == DIB_PAL_COLORS)
2329 {
2330 RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(WORD));
2331 RtlCopyMemory(pbmci->bmciColors, converted->bmiColors, numColors * sizeof(WORD));
2332 }
2333 else
2334 {
2335 UINT i;
2336 RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(RGBTRIPLE));
2337 for(i=0; i<numColors; i++)
2338 {
2339 pbmci->bmciColors[i].rgbtRed = converted->bmiColors[i].rgbRed;
2340 pbmci->bmciColors[i].rgbtGreen = converted->bmiColors[i].rgbGreen;
2341 pbmci->bmciColors[i].rgbtBlue = converted->bmiColors[i].rgbBlue;
2342 }
2343 }
2344 }
2345 /* Now free it, it's not needed anymore */
2346 ExFreePoolWithTag(converted, TAG_DIB);
2347}
2348
2349/* EOF */
static HDC hDC
Definition: 3dtext.c:33
#define DIB_PAL_INDICES
#define CBM_CREATDIB
static HBITMAP hbitmap
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define R3_OPINDEX_SRCCOPY
Definition: bitblt.h:27
BOOL APIENTRY IntEngCopyBits(SURFOBJ *psoTrg, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclTrg, POINTL *pptlSrc)
Definition: bitblt_new.c:678
HBITMAP FASTCALL IntCreateCompatibleBitmap(PDC Dc, INT Width, INT Height, UINT Planes, UINT Bpp)
Definition: bitmaps.c:273
HBITMAP NTAPI GreCreateBitmapEx(_In_ ULONG nWidth, _In_ ULONG nHeight, _In_ ULONG cjWidthBytes, _In_ ULONG iFormat, _In_ USHORT fjBitmap, _In_ ULONG cjSizeImage, _In_opt_ PVOID pvBits, _In_ FLONG flags)
Definition: bitmaps.c:101
HBITMAP NTAPI GreCreateBitmap(_In_ ULONG nWidth, _In_ ULONG nHeight, _In_ ULONG cPlanes, _In_ ULONG cBitsPixel, _In_opt_ PVOID pvBits)
Definition: bitmaps.c:172
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY _In_ uint8_t compression
Definition: btrfs_drv.h:1365
HGDIOBJ hHmgr(VOID)
Definition: baseobj.hpp:95
static BOOLEAN IntLPtoDP(DC *pdc, PPOINTL ppt, UINT count)
Definition: coord.h:182
VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdcDest, const RECT *rcDest, PDC pdcSrc, const RECT *rcSrc)
Definition: dclife.c:505
VOID FASTCALL DC_vFinishBlit(PDC pdc1, PDC pdc2)
Definition: dclife.c:614
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:238
VOID FASTCALL IntUpdateBoundsRect(PDC, PRECTL)
Definition: dcutil.c:694
HPALETTE NTAPI GdiSelectPalette(_In_ HDC hDC, _In_ HPALETTE hpal, _In_ BOOL ForceBackground)
@ DCTYPE_INFO
Definition: dc.h:43
@ DC_ACCUM_APP
Definition: dc.h:25
@ DC_ACCUM_WMGR
Definition: dc.h:24
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:220
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
HBITMAP NTAPI GreCreateDIBitmapFromPackedDIB(_In_reads_(cjPackedDIB) PVOID pvPackedDIB, _In_ UINT cjPackedDIB, _In_ ULONG uUsage)
Definition: dibobj.c:1794
static const RGBQUAD DefLogPaletteQuads[20]
Definition: dibobj.c:14
BITMAPINFO *FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO *pbmi, DWORD Usage)
Definition: dibobj.c:2238
int FASTCALL DIB_GetBitmapInfo(const BITMAPINFOHEADER *header, LONG *width, LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size)
Definition: dibobj.c:2118
VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO *converted, BITMAPINFO *orig, DWORD usage)
Definition: dibobj.c:2302
static INT FASTCALL IntSetDIBits(PDC DC, HBITMAP hBitmap, UINT StartScan, UINT ScanLines, CONST VOID *Bits, ULONG cjMaxBits, CONST BITMAPINFO *bmi, UINT ColorUse)
Definition: dibobj.c:239
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO *info, WORD coloruse)
Definition: dibobj.c:2165
W32KAPI INT APIENTRY NtGdiSetDIBitsToDeviceInternal(IN HDC hDC, IN INT XDest, IN INT YDest, IN DWORD Width, IN DWORD Height, IN INT XSrc, IN INT YSrc, IN DWORD StartScan, IN DWORD ScanLines, IN LPBYTE Bits, IN LPBITMAPINFO bmi, IN DWORD ColorUse, IN UINT cjMaxBits, IN UINT cjMaxInfo, IN BOOL bTransformCoordinates, IN OPTIONAL HANDLE hcmXform)
Definition: dibobj.c:470
HBITMAP NTAPI GreCreateDIBitmapInternal(IN HDC hDc, IN INT cx, IN INT cy, IN DWORD fInit, IN OPTIONAL LPBYTE pjInit, IN OPTIONAL PBITMAPINFO pbmi, IN DWORD iUsage, IN FLONG fl, IN UINT cjMaxBits, IN HANDLE hcmXform)
Definition: dibobj.c:1718
HBITMAP APIENTRY NtGdiCreateDIBSection(IN HDC hDC, IN OPTIONAL HANDLE hSection, IN DWORD dwOffset, IN BITMAPINFO *bmi, IN DWORD Usage, IN UINT cjHeader, IN FLONG fl, IN ULONG_PTR dwColorSpace, OUT PVOID *Bits)
Definition: dibobj.c:1845
HPALETTE FASTCALL DIB_MapPaletteColors(PPALETTE ppalDc, CONST BITMAPINFO *lpbmi)
Definition: dibobj.c:2194
static HBITMAP IntGdiCreateMaskFromRLE(DWORD Width, DWORD Height, ULONG Compression, const BYTE *Bits, DWORD BitsSize)
Definition: dibobj.c:360
INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth)
Definition: dibobj.c:2153
W32KAPI INT APIENTRY NtGdiStretchDIBitsInternal(IN HDC hdc, IN INT xDst, IN INT yDst, IN INT cxDst, IN INT cyDst, IN INT xSrc, IN INT ySrc, IN INT cxSrc, IN INT cySrc, IN OPTIONAL LPBYTE pjInit, IN LPBITMAPINFO pbmi, IN DWORD dwUsage, IN DWORD dwRop, IN UINT cjMaxInfo, IN UINT cjMaxBits, IN HANDLE hcmXform)
Definition: dibobj.c:1223
PPALETTE NTAPI CreateDIBPalette(_In_ const BITMAPINFO *pbmi, _In_ PDC pdc, _In_ ULONG iUsage)
Definition: dibobj.c:41
INT APIENTRY GreGetDIBitsInternal(HDC hDC, HBITMAP hBitmap, UINT StartScan, UINT ScanLines, LPBYTE Bits, LPBITMAPINFO Info, UINT Usage, UINT MaxBits, UINT MaxInfo)
Definition: dibobj.c:717
HBITMAP APIENTRY NtGdiCreateDIBitmapInternal(IN HDC hDc, IN INT cx, IN INT cy, IN DWORD fInit, IN OPTIONAL LPBYTE pjInit, IN OPTIONAL LPBITMAPINFO pbmi, IN DWORD iUsage, IN UINT cjMaxInitInfo, IN UINT cjMaxBits, IN FLONG fl, IN HANDLE hcmXform)
Definition: dibobj.c:1644
HBITMAP APIENTRY DIB_CreateDIBSection(PDC dc, CONST BITMAPINFO *bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch)
Definition: dibobj.c:1912
HBITMAP FASTCALL IntCreateDIBitmap(PDC Dc, INT width, INT height, UINT planes, UINT bpp, ULONG compression, DWORD init, LPBYTE bits, ULONG cjMaxBits, PBITMAPINFO data, DWORD coloruse)
Definition: dibobj.c:1540
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static HBITMAP hBitmap
Definition: timezone.c:26
DWORD bpp
Definition: surface.c:185
#define APIENTRY
Definition: api.h:79
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
static void cleanup(void)
Definition: main.c:1335
#define BI_RLE4
Definition: precomp.h:48
#define BI_RGB
Definition: precomp.h:47
#define RGB(r, g, b)
Definition: precomp.h:62
ULONG RGBQUAD
Definition: precomp.h:50
#define UlongToPtr(u)
Definition: config.h:106
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define abs(i)
Definition: fconv.c:206
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
@ SystemBasicInformation
Definition: ntddk_ex.h:11
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int Mask
Definition: fpcontrol.c:82
#define GDI_OBJECT_TYPE_PALETTE
Definition: gdi.h:49
Status
Definition: gdiplustypes.h:25
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLuint64EXT * result
Definition: glext.h:11304
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Must_inspect_result_ _In_ USAGE _In_ USHORT _In_ USAGE Usage
Definition: hidpi.h:384
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ROP4_FROM_INDEX(index)
Definition: inteng.h:42
#define ROP4_MASK
Definition: inteng.h:55
BOOL APIENTRY IntEngStretchBlt(SURFOBJ *DestObj, SURFOBJ *SourceObj, SURFOBJ *Mask, CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation, COLORADJUSTMENT *pca, RECTL *DestRect, RECTL *SourceRect, POINTL *pMaskOrigin, BRUSHOBJ *Brush, POINTL *BrushOrigin, ULONG Mode)
#define WIN32_ROP3_TO_ENG_ROP4(dwRop4)
Definition: intgdi.h:4
if(dx< 0)
Definition: linetemp.h:194
static const WCHAR dc[]
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define BI_BITFIELDS
Definition: mmreg.h:507
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
BITMAP bmp
Definition: alphablend.c:62
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:92
static const BYTE masks[8]
Definition: dib.c:2760
#define min(a, b)
Definition: monoChain.cc:55
#define _Success_(expr)
Definition: ms_sal.h:259
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
#define _Out_writes_bytes_opt_(size)
Definition: ms_sal.h:351
#define _In_reads_(size)
Definition: ms_sal.h:319
unsigned int UINT
Definition: ndis.h:50
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:407
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define FASTCALL
Definition: nt_native.h:50
#define NtCurrentProcess()
Definition: nt_native.h:1657
@ ViewShare
Definition: nt_native.h:1278
unsigned long FLONG
Definition: ntbasedef.h:366
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiCreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO _In_ UINT _In_ UINT _In_ UINT cjMaxInfo
Definition: ntgdi.h:2783
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO _In_ UINT _In_ UINT cjMaxBits
Definition: ntgdi.h:2782
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2033
__kernel_entry W32KAPI BOOL APIENTRY NtGdiBitBlt(_In_ HDC hdcDst, _In_ INT x, _In_ INT y, _In_ INT cx, _In_ INT cy, _In_opt_ HDC hdcSrc, _In_ INT xSrc, _In_ INT ySrc, _In_ DWORD rop4, _In_ DWORD crBackColor, _In_ FLONG fl)
#define W32KAPI
Definition: ntgdi.h:9
__kernel_entry W32KAPI BOOL APIENTRY NtGdiStretchBlt(_In_ HDC hdcDst, _In_ INT xDst, _In_ INT yDst, _In_ INT cxDst, _In_ INT cyDst, _In_opt_ HDC hdcSrc, _In_ INT xSrc, _In_ INT ySrc, _In_ INT cxSrc, _In_ INT cySrc, _In_ DWORD dwRop, _In_ DWORD dwBackColor)
_In_ HBITMAP _In_ UINT _In_ UINT cScans
Definition: ntgdi.h:2778
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiSelectBitmap(_In_ HDC hdc, _In_ HBITMAP hbm)
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO pbmi
Definition: ntgdi.h:2780
__kernel_entry W32KAPI HANDLE APIENTRY NtGdiGetDCObject(_In_ HDC hdc, _In_ INT itype)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiDeleteObjectApp(_In_ HANDLE hobj)
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO _In_ UINT iUsage
Definition: ntgdi.h:2781
_In_ HBITMAP _In_ UINT iStartScan
Definition: ntgdi.h:2777
#define CONST
Definition: pedump.c:81
WORD * PWORD
Definition: pedump.c:67
BYTE * PBYTE
Definition: pedump.c:66
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
_Out_opt_ int * cx
Definition: commctrl.h:585
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
static void Exit(void)
Definition: sock.c:1330
#define __kernel_entry
Definition: specstrings.h:355
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
DWORD bV4GreenMask
Definition: wingdi.h:1504
DWORD bV4RedMask
Definition: wingdi.h:1503
DWORD bV4BlueMask
Definition: wingdi.h:1505
Definition: polytest.cpp:41
long bottom
Definition: polytest.cpp:53
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
long left
Definition: polytest.cpp:53
BITMAPCOREHEADER bmciHeader
Definition: wingdi.h:1453
RGBTRIPLE bmciColors[1]
Definition: wingdi.h:1454
Definition: bl.h:1331
XLATEOBJ xlo
Definition: xlateobj.h:21
BASEOBJECT BaseObject
Definition: palette.h:36
ULONG NumColors
Definition: palette.h:41
PALETTEENTRY * IndexedColors
Definition: palette.h:42
FLONG flFlags
Definition: palette.h:40
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
SURFOBJ SurfObj
Definition: surface.h:8
HANDLE hSecure
Definition: surface.h:32
struct _PALETTE *const ppal
Definition: surface.h:11
USHORT fjBitmap
Definition: winddi.h:1217
SIZEL sizlBitmap
Definition: winddi.h:1209
PVOID pvBits
Definition: winddi.h:1211
ULONG iBitmapFormat
Definition: winddi.h:1215
Definition: parser.c:56
USHORT biBitCount
Definition: precomp.h:37
ULONG biCompression
Definition: precomp.h:38
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1476
RGBQUAD bmiColors[1]
Definition: wingdi.h:1477
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
UCHAR rgbBlue
Definition: bootanim.c:103
UCHAR rgbRed
Definition: bootanim.c:105
UCHAR rgbGreen
Definition: bootanim.c:104
BYTE rgbtGreen
Definition: wingdi.h:1439
BYTE rgbtBlue
Definition: wingdi.h:1438
BYTE rgbtRed
Definition: wingdi.h:1440
#define max(a, b)
Definition: svc.c:63
#define WIDTH_BYTES_ALIGN32(cx, bpp)
Definition: swimpl.c:16
unsigned char * LPBYTE
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:89
_In_ HFONT _Out_ PUINT Height
Definition: font.h:88
static int __cdecl compr(const void *a, const void *b)
Definition: bidi.c:641
int ret
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
HDC hdcMem
Definition: welcome.c:104
VOID DIB_1BPP_HLine(SURFOBJ *, LONG, LONG, LONG, ULONG)
Definition: dib1bpp.c:38
BOOL APIENTRY IntEngBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclTrg, POINTL *pptlSrc, POINTL *pptlMask, BRUSHOBJ *pbo, POINTL *pptlBrush, ROP4 Rop4)
Definition: bitblt.c:656
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
ULONG FASTCALL BitmapFormat(ULONG cBits, ULONG iCompression)
Definition: surface.c:39
#define SURFACE_ShareUnlockSurface(pBMObj)
Definition: surface.h:102
FORCEINLINE VOID SURFACE_vSetPalette(_Inout_ PSURFACE psurf, _In_ PPALETTE ppal)
Definition: surface.h:136
@ API_BITMAP
Definition: surface.h:76
#define SURFACE_ShareLockSurface(hBMObj)
Definition: surface.h:91
#define BitsPerFormat(Format)
Definition: surface.h:109
#define DIB_PAL_BRUSHHACK
Definition: dib.h:36
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
PPALETTE NTAPI PALETTE_AllocPalWithHandle(_In_ ULONG iMode, _In_ ULONG cColors, _In_opt_ const PALETTEENTRY *pEntries, _In_ FLONG flRed, _In_ FLONG flGreen, _In_ FLONG flBlue)
Definition: palette.c:209
PPALETTE NTAPI PALETTE_AllocPalette(_In_ ULONG iMode, _In_ ULONG cColors, _In_opt_ const PALETTEENTRY *pEntries, _In_ FLONG flRed, _In_ FLONG flGreen, _In_ FLONG flBlue)
Definition: palette.c:135
PALETTE * gppalDefault
Definition: palette.c:20
#define PALETTE_UnlockPalette(pPalette)
Definition: palette.h:56
FORCEINLINE VOID PALETTE_vSetRGBColorForIndex(PPALETTE ppal, ULONG ulIndex, COLORREF crColor)
Definition: palette.h:152
@ PAL_BRUSHHACK
Definition: palette.h:23
#define PALETTE_ShareLockPalette(hpal)
Definition: palette.h:57
#define PALETTE_ShareUnlockPalette(ppal)
Definition: palette.h:59
FORCEINLINE ULONG PALETTE_ulGetRGBColorFromIndex(PPALETTE ppal, ULONG ulIndex)
Definition: palette.h:142
VOID FASTCALL RECTL_vMakeWellOrdered(_Inout_ RECTL *prcl)
Definition: rect.c:81
FORCEINLINE VOID RECTL_vSetRect(_Out_ RECTL *prcl, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
Definition: rect.h:5
FORCEINLINE VOID RECTL_vOffsetRect(_Inout_ RECTL *prcl, _In_ INT cx, _In_ INT cy)
Definition: rect.h:31
#define TAG_DIB
Definition: tags.h:17
ENGAPI BOOL APIENTRY EngDeleteSurface(_In_ _Post_ptr_invalid_ HSURF hsurf)
Definition: surface.c:567
_In_ FLONG fl
Definition: winddi.h:1279
#define BMF_1BPP
Definition: winddi.h:355
#define PAL_BITFIELDS
Definition: winddi.h:1562
_In_ HANDLE hcmXform
Definition: winddi.h:3687
ENGAPI SURFOBJ *APIENTRY EngLockSurface(_In_ HSURF hsurf)
Definition: surface.c:607
#define BMF_DONTCACHE
Definition: winddi.h:1182
_In_ ULONG _In_ ULONG rgb
Definition: winddi.h:3521
ENGAPI VOID APIENTRY EngFreeUserMem(_Pre_notnull_ __drv_freesMem(UserMem) PVOID pv)
#define BMF_TOPDOWN
Definition: winddi.h:1180
#define BMF_USERMEM
Definition: winddi.h:1183
typedef HSURF(APIENTRY FN_DrvEnableSurface)(_In_ DHPDEV dhpdev)
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
ENGAPI HANDLE APIENTRY EngSecureMem(_In_reads_bytes_(cjLength) PVOID Address, _In_ ULONG cjLength)
#define PAL_INDEXED
Definition: winddi.h:1561
#define BMF_NOZEROINIT
Definition: winddi.h:1181
ENGAPI VOID APIENTRY EngUnsecureMem(_In_ HANDLE hSecure)
ENGAPI VOID APIENTRY EngUnlockSurface(_In_ _Post_ptr_invalid_ SURFOBJ *pso)
Definition: surface.c:628
DWORD COLORREF
Definition: windef.h:300
#define ERROR_NO_SYSTEM_RESOURCES
Definition: winerror.h:931
_In_ const BITMAPINFO _In_ UINT _In_opt_ HANDLE hSection
Definition: wingdi.h:3239
struct _BITMAPCOREINFO * PBITMAPCOREINFO
#define DIB_RGB_COLORS
Definition: wingdi.h:367
#define DIB_PAL_COLORS
Definition: wingdi.h:366
#define SRCCOPY
Definition: wingdi.h:333
struct BITMAPV4HEADER * PBITMAPV4HEADER
#define CBM_INIT
Definition: wingdi.h:365
#define BI_RLE8
Definition: wingdi.h:35
static int init
Definition: wintirpc.c:33
VOID NTAPI EXLATEOBJ_vInitialize(_Out_ PEXLATEOBJ pexlo, _In_opt_ PALETTE *ppalSrc, _In_opt_ PALETTE *ppalDst, _In_ COLORREF crSrcBackColor, _In_ COLORREF crDstBackColor, _In_ COLORREF crDstForeColor)
Definition: xlateobj.c:358
VOID NTAPI EXLATEOBJ_vCleanup(_Inout_ PEXLATEOBJ pexlo)
Definition: xlateobj.c:649
unsigned char BYTE
Definition: xxhash.c:193