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