ReactOS  0.4.15-dev-2996-gf777e6b
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  }
155  else
156  {
157  /* The colors are an array of RGBTRIPLE values */
159 
160  /* Loop all color indices in the DIB */
161  for (i = 0; i < cColors; i++)
162  {
163  /* Get the color value and translate it to a COLORREF */
164  RGBTRIPLE rgb = prgb[i];
165  COLORREF crColor = RGB(rgb.rgbtRed, rgb.rgbtGreen, rgb.rgbtBlue);
166 
167  /* Set the RGB value in the palette */
168  PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
169  }
170  }
171  }
172  else
173  {
174  /* This is a bitfield / RGB palette */
175  ULONG flRedMask, flGreenMask, flBlueMask;
176 
177  /* Check if the DIB contains bitfield values */
178  if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
180  {
181  /* Check if we have a v4/v5 header */
182  if (pbmi->bmiHeader.biSize >= sizeof(BITMAPV4HEADER))
183  {
184  /* The masks are dedicated fields in the header */
186  flRedMask = pbmV4Header->bV4RedMask;
187  flGreenMask = pbmV4Header->bV4GreenMask;
188  flBlueMask = pbmV4Header->bV4BlueMask;
189  }
190  else
191  {
192  /* The masks are the first 3 values in the DIB color table */
193  PDWORD pdwColors = (PVOID)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
194  flRedMask = pdwColors[0];
195  flGreenMask = pdwColors[1];
196  flBlueMask = pdwColors[2];
197  }
198  }
199  else
200  {
201  /* Check what bit depth we have. Note: optimization flags are
202  calculated in PALETTE_AllocPalette() */
203  if (cBitsPixel == 16)
204  {
205  /* This is an RGB 555 palette */
206  flRedMask = 0x7C00;
207  flGreenMask = 0x03E0;
208  flBlueMask = 0x001F;
209  }
210  else
211  {
212  /* This is an RGB 888 palette */
213  flRedMask = 0xFF0000;
214  flGreenMask = 0x00FF00;
215  flBlueMask = 0x0000FF;
216  }
217  }
218 
219  /* Allocate the bitfield palette */
221  0,
222  NULL,
223  flRedMask,
224  flGreenMask,
225  flBlueMask);
226  }
227 
228  /* We're done, return the palette */
229  return ppal;
230 }
231 
232 // Converts a DIB to a device-dependent bitmap
233 static INT
234 FASTCALL
236  PDC DC,
238  UINT StartScan,
239  UINT ScanLines,
240  CONST VOID *Bits,
242  CONST BITMAPINFO *bmi,
243  UINT ColorUse)
244 {
245  HBITMAP SourceBitmap;
246  PSURFACE psurfDst, psurfSrc;
247  INT result = 0;
248  RECT rcDst;
249  POINTL ptSrc;
250  EXLATEOBJ exlo;
251  PPALETTE ppalDIB = 0;
252  ULONG cjSizeImage;
253 
254  if (!bmi || !Bits) return 0;
255 
256  /* Check for uncompressed formats */
257  if ((bmi->bmiHeader.biCompression == BI_RGB) ||
258  (bmi->bmiHeader.biCompression == BI_BITFIELDS))
259  {
260  /* Calculate the image size */
261  cjSizeImage = DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
262  ScanLines,
263  bmi->bmiHeader.biBitCount);
264  }
265  /* Check if the header provided an image size */
266  else if (bmi->bmiHeader.biSizeImage != 0)
267  {
268  /* Use the given size */
269  cjSizeImage = bmi->bmiHeader.biSizeImage;
270  }
271  else
272  {
273  /* Compressed format without a size. This is invalid. */
274  DPRINT1("Compressed format without a size!");
275  return 0;
276  }
277 
278  /* Check if the size that we have is ok */
279  if ((cjSizeImage > cjMaxBits) || (cjSizeImage == 0))
280  {
281  DPRINT1("Invalid bitmap size! cjSizeImage = %lu, cjMaxBits = %lu\n",
282  cjSizeImage, cjMaxBits);
283  return 0;
284  }
285 
286  SourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
287  ScanLines,
288  0,
289  BitmapFormat(bmi->bmiHeader.biBitCount,
290  bmi->bmiHeader.biCompression),
291  bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
292  cjSizeImage,
293  (PVOID)Bits,
294  0);
295  if (!SourceBitmap)
296  {
297  DPRINT1("Error: Could not create a bitmap.\n");
299  return 0;
300  }
301 
302  psurfDst = SURFACE_ShareLockSurface(hBitmap);
303  psurfSrc = SURFACE_ShareLockSurface(SourceBitmap);
304 
305  if(!(psurfSrc && psurfDst))
306  {
307  DPRINT1("Error: Could not lock surfaces\n");
308  goto cleanup;
309  }
310 
311  /* Create a palette for the DIB */
312  ppalDIB = CreateDIBPalette(bmi, DC, ColorUse);
313  if (!ppalDIB)
314  {
316  goto cleanup;
317  }
318 
319  /* Initialize EXLATEOBJ */
320  EXLATEOBJ_vInitialize(&exlo,
321  ppalDIB,
322  psurfDst->ppal,
323  RGB(0xff, 0xff, 0xff),
324  RGB(0xff, 0xff, 0xff), //DC->pdcattr->crBackgroundClr,
325  0); // DC->pdcattr->crForegroundClr);
326 
327  rcDst.top = StartScan;
328  rcDst.left = 0;
329  rcDst.bottom = rcDst.top + ScanLines;
330  rcDst.right = psurfDst->SurfObj.sizlBitmap.cx;
331  ptSrc.x = 0;
332  ptSrc.y = 0;
333 
334  result = IntEngCopyBits(&psurfDst->SurfObj,
335  &psurfSrc->SurfObj,
336  NULL,
337  &exlo.xlo,
338  &rcDst,
339  &ptSrc);
340  if(result)
341  result = ScanLines;
342 
343  EXLATEOBJ_vCleanup(&exlo);
344 
345 cleanup:
346  if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
347  if(psurfSrc) SURFACE_ShareUnlockSurface(psurfSrc);
348  if(psurfDst) SURFACE_ShareUnlockSurface(psurfDst);
349  GreDeleteObject(SourceBitmap);
350 
351  return result;
352 }
353 
354 static
355 HBITMAP
357  DWORD Width,
358  DWORD Height,
359  ULONG Compression,
360  const BYTE* Bits,
361  DWORD BitsSize)
362 {
363  HBITMAP Mask;
364  DWORD x, y;
365  SURFOBJ* SurfObj;
366  UINT i = 0;
367  BYTE Data, NumPixels, ToSkip;
368 
369  ASSERT((Compression == BI_RLE8) || (Compression == BI_RLE4));
370 
371  /* Create the bitmap */
372  Mask = GreCreateBitmapEx(Width, Height, 0, BMF_1BPP, 0, 0, NULL, 0);
373  if (!Mask)
374  return NULL;
375 
376  SurfObj = EngLockSurface((HSURF)Mask);
377  if (!SurfObj)
378  {
380  return NULL;
381  }
382  ASSERT(SurfObj->pvBits != NULL);
383 
384  x = y = 0;
385 
386  while (i < BitsSize)
387  {
388  NumPixels = Bits[i];
389  Data = Bits[i + 1];
390  i += 2;
391 
392  if (NumPixels != 0)
393  {
394  if ((x + NumPixels) > Width)
395  NumPixels = Width - x;
396 
397  if (NumPixels == 0)
398  continue;
399 
400  DIB_1BPP_HLine(SurfObj, x, x + NumPixels, y, 1);
401  x += NumPixels;
402  continue;
403  }
404 
405  if (Data < 3)
406  {
407  switch (Data)
408  {
409  case 0:
410  /* End of line */
411  y++;
412  if (y == Height)
413  goto done;
414  x = 0;
415  break;
416  case 1:
417  /* End of file */
418  goto done;
419  case 2:
420  /* Jump */
421  if (i >= (BitsSize - 1))
422  goto done;
423  x += Bits[i];
424  if (x > Width)
425  x = Width;
426  y += Bits[i + 1];
427  if (y >= Height)
428  goto done;
429  i += 2;
430  break;
431  }
432  /* Done for this run */
433  continue;
434  }
435 
436  /* Embedded data into the RLE */
437  NumPixels = Data;
438  if (Compression == BI_RLE8)
439  ToSkip = NumPixels;
440  else
441  ToSkip = (NumPixels / 2) + (NumPixels & 1);
442 
443  if ((i + ToSkip) > BitsSize)
444  goto done;
445  ToSkip = (ToSkip + 1) & ~1;
446 
447  if ((x + NumPixels) > Width)
448  NumPixels = Width - x;
449 
450  if (NumPixels != 0)
451  {
452  DIB_1BPP_HLine(SurfObj, x, x + NumPixels, y, 1);
453  x += NumPixels;
454  }
455  i += ToSkip;
456  }
457 
458 done:
459  EngUnlockSurface(SurfObj);
460  return Mask;
461 }
462 
463 W32KAPI
464 INT
465 APIENTRY
467  IN HDC hDC,
468  IN INT XDest,
469  IN INT YDest,
470  IN DWORD Width,
471  IN DWORD Height,
472  IN INT XSrc,
473  IN INT YSrc,
474  IN DWORD StartScan,
475  IN DWORD ScanLines,
476  IN LPBYTE Bits,
477  IN LPBITMAPINFO bmi,
478  IN DWORD ColorUse,
479  IN UINT cjMaxBits,
480  IN UINT cjMaxInfo,
481  IN BOOL bTransformCoordinates,
483 {
484  INT ret;
485  PDC pDC = NULL;
486  HBITMAP hSourceBitmap = NULL, hMaskBitmap = NULL;
487  SURFOBJ *pDestSurf, *pSourceSurf = NULL, *pMaskSurf = NULL;
488  SURFACE *pSurf;
489  RECTL rcDest;
490  POINTL ptSource;
491  //INT DIBWidth;
492  SIZEL SourceSize;
493  EXLATEOBJ exlo;
494  PPALETTE ppalDIB = NULL;
495  LPBITMAPINFO pbmiSafe;
496  BOOL bResult;
497 
498  if (!Bits) return 0;
499 
500  pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjMaxInfo, 'pmTG');
501  if (!pbmiSafe) return 0;
502 
503  _SEH2_TRY
504  {
505  ProbeForRead(bmi, cjMaxInfo, 1);
506  ProbeForRead(Bits, cjMaxBits, 1);
507  RtlCopyMemory(pbmiSafe, bmi, cjMaxInfo);
508  bmi = pbmiSafe;
509  }
511  {
512  ret = 0;
513  goto Exit;
514  }
515  _SEH2_END;
516 
517  ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
518  if (ScanLines == 0)
519  {
520  DPRINT1("ScanLines == 0\n");
521  ret = 0;
522  goto Exit;
523  }
524 
525  pDC = DC_LockDc(hDC);
526  if (!pDC)
527  {
529  ret = 0;
530  goto Exit;
531  }
532 
533  if (pDC->dctype == DC_TYPE_INFO)
534  {
535  ret = 0;
536  goto Exit;
537  }
538 
539  rcDest.left = XDest;
540  rcDest.top = YDest;
541  if (bTransformCoordinates)
542  {
543  IntLPtoDP(pDC, (LPPOINT)&rcDest, 2);
544  }
545  rcDest.left += pDC->ptlDCOrig.x;
546  rcDest.top += pDC->ptlDCOrig.y;
547  rcDest.right = rcDest.left + Width;
548  rcDest.bottom = rcDest.top + Height;
549  rcDest.top += StartScan;
550 
551  if (pDC->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
552  {
553  IntUpdateBoundsRect(pDC, &rcDest);
554  }
555 
556  ptSource.x = XSrc;
557  ptSource.y = YSrc;
558 
559  SourceSize.cx = bmi->bmiHeader.biWidth;
560  SourceSize.cy = ScanLines;
561 
562  //DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount);
563 
564  hSourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
565  ScanLines,
566  0,
567  BitmapFormat(bmi->bmiHeader.biBitCount,
568  bmi->bmiHeader.biCompression),
569  bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
570  bmi->bmiHeader.biSizeImage,
571  Bits,
572  0);
573 
574  if (!hSourceBitmap)
575  {
577  ret = 0;
578  goto Exit;
579  }
580 
581  pSourceSurf = EngLockSurface((HSURF)hSourceBitmap);
582  if (!pSourceSurf)
583  {
584  ret = 0;
585  goto Exit;
586  }
587 
588  /* HACK: If this is a RLE bitmap, only the relevant pixels must be set. */
589  if ((bmi->bmiHeader.biCompression == BI_RLE8) || (bmi->bmiHeader.biCompression == BI_RLE4))
590  {
591  hMaskBitmap = IntGdiCreateMaskFromRLE(bmi->bmiHeader.biWidth,
592  ScanLines,
593  bmi->bmiHeader.biCompression,
594  Bits,
595  cjMaxBits);
596  if (!hMaskBitmap)
597  {
599  ret = 0;
600  goto Exit;
601  }
602  pMaskSurf = EngLockSurface((HSURF)hMaskBitmap);
603  if (!pMaskSurf)
604  {
605  ret = 0;
606  goto Exit;
607  }
608  }
609 
610  /* Create a palette for the DIB */
611  ppalDIB = CreateDIBPalette(bmi, pDC, ColorUse);
612  if (!ppalDIB)
613  {
615  ret = 0;
616  goto Exit;
617  }
618 
619  /* This is actually a blit */
620  DC_vPrepareDCsForBlit(pDC, &rcDest, NULL, NULL);
621  pSurf = pDC->dclevel.pSurface;
622  if (!pSurf)
623  {
624  DC_vFinishBlit(pDC, NULL);
625  ret = ScanLines;
626  goto Exit;
627  }
628 
629  ASSERT(pSurf->ppal);
630 
631  /* Initialize EXLATEOBJ */
632  EXLATEOBJ_vInitialize(&exlo,
633  ppalDIB,
634  pSurf->ppal,
635  RGB(0xff, 0xff, 0xff),
636  pDC->pdcattr->crBackgroundClr,
637  pDC->pdcattr->crForegroundClr);
638 
639  pDestSurf = &pSurf->SurfObj;
640 
641  /* Copy the bits */
642  DPRINT("BitsToDev with rcDest=(%d|%d) (%d|%d), ptSource=(%d|%d) w=%d h=%d\n",
643  rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
644  ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy);
645 
646  /* This fixes the large Google text on Google.com from being upside down */
647  if (rcDest.top > rcDest.bottom)
648  {
649  RECTL_vMakeWellOrdered(&rcDest);
650  ptSource.y -= SourceSize.cy;
651  }
652 
653  bResult = IntEngBitBlt(pDestSurf,
654  pSourceSurf,
655  pMaskSurf,
656  (CLIPOBJ *)&pDC->co,
657  &exlo.xlo,
658  &rcDest,
659  &ptSource,
660  pMaskSurf ? &ptSource : NULL,
661  NULL,
662  NULL,
664 
665  /* Cleanup EXLATEOBJ */
666  EXLATEOBJ_vCleanup(&exlo);
667 
668  /* We're done */
669  DC_vFinishBlit(pDC, NULL);
670 
671  ret = bResult ? ScanLines : 0;
672 
673 Exit:
674 
675  if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
676  if (pSourceSurf) EngUnlockSurface(pSourceSurf);
677  if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
678  if (pMaskSurf) EngUnlockSurface(pMaskSurf);
679  if (hMaskBitmap) EngDeleteSurface((HSURF)hMaskBitmap);
680  if (pDC) DC_UnlockDc(pDC);
681  ExFreePoolWithTag(pbmiSafe, 'pmTG');
682 
683  return ret;
684 }
685 
686 
687 /* Converts a device-dependent bitmap to a DIB */
688 INT
689 APIENTRY
691  HDC hDC,
693  UINT StartScan,
694  UINT ScanLines,
695  LPBYTE Bits,
697  UINT Usage,
698  UINT MaxBits,
699  UINT MaxInfo)
700 {
701  BITMAPCOREINFO* pbmci = NULL;
702  PSURFACE psurf = NULL;
703  PDC pDC;
704  LONG width, height;
705  WORD planes, bpp;
706  DWORD compr, size ;
707  USHORT i;
708  int bitmap_type;
709  RGBQUAD* rgbQuads;
710  VOID* colorPtr;
711 
712  DPRINT("Entered GreGetDIBitsInternal()\n");
713 
714  if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap)
715  return 0;
716 
717  pDC = DC_LockDc(hDC);
718  if (pDC == NULL || pDC->dctype == DC_TYPE_INFO)
719  {
720  ScanLines = 0;
721  goto done;
722  }
723 
724  /* Get a pointer to the source bitmap object */
726  if (psurf == NULL)
727  {
728  ScanLines = 0;
729  goto done;
730  }
731 
732  colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize;
733  rgbQuads = colorPtr;
734 
735  bitmap_type = DIB_GetBitmapInfo(&Info->bmiHeader,
736  &width,
737  &height,
738  &planes,
739  &bpp,
740  &compr,
741  &size);
742  if(bitmap_type == -1)
743  {
744  DPRINT1("Wrong bitmap format\n");
746  ScanLines = 0;
747  goto done;
748  }
749  else if(bitmap_type == 0)
750  {
751  /* We need a BITMAPINFO to create a DIB, but we have to fill
752  * the BITMAPCOREINFO we're provided */
753  pbmci = (BITMAPCOREINFO*)Info;
754  /* fill in the the bit count, so we can calculate the right ColorsSize during the conversion */
757  if(Info == NULL)
758  {
759  DPRINT1("Error, could not convert the BITMAPCOREINFO!\n");
760  ScanLines = 0;
761  goto done;
762  }
763  rgbQuads = Info->bmiColors;
764  }
765 
766  /* Validate input:
767  - negative width is always an invalid value
768  - non-null Bits and zero bpp is an invalid combination
769  - only check the rest of the input params if either bpp is non-zero or Bits are set */
770  if (width < 0 || (bpp == 0 && Bits))
771  {
772  ScanLines = 0;
773  goto done;
774  }
775 
776  if (Bits || bpp)
777  {
778  if ((height == 0 || width == 0) || (compr && compr != BI_BITFIELDS && compr != BI_RGB))
779  {
780  ScanLines = 0;
781  goto done;
782  }
783  }
784 
785  Info->bmiHeader.biClrUsed = 0;
786  Info->bmiHeader.biClrImportant = 0;
787 
788  /* Fill in the structure */
789  switch(bpp)
790  {
791  case 0: /* Only info */
792  Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
793  Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
794  -psurf->SurfObj.sizlBitmap.cy :
795  psurf->SurfObj.sizlBitmap.cy;
796  Info->bmiHeader.biPlanes = 1;
797  Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
798  Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( Info->bmiHeader.biWidth,
799  Info->bmiHeader.biHeight,
800  Info->bmiHeader.biBitCount);
801  Info->bmiHeader.biCompression = (Info->bmiHeader.biBitCount == 16 || Info->bmiHeader.biBitCount == 32) ?
803  Info->bmiHeader.biXPelsPerMeter = 0;
804  Info->bmiHeader.biYPelsPerMeter = 0;
805 
806  if (Info->bmiHeader.biBitCount <= 8 && Info->bmiHeader.biClrUsed == 0)
807  Info->bmiHeader.biClrUsed = 1 << Info->bmiHeader.biBitCount;
808 
809  ScanLines = 1;
810  goto done;
811 
812  case 1:
813  case 4:
814  case 8:
815  Info->bmiHeader.biClrUsed = 1 << bpp;
816 
817  /* If the bitmap is a DIB section and has the same format as what
818  * is requested, go ahead! */
819  if((psurf->hSecure) &&
820  (BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bpp))
821  {
822  if(Usage == DIB_RGB_COLORS)
823  {
824  ULONG colors = min(psurf->ppal->NumColors, 256);
825  if(colors != 256) Info->bmiHeader.biClrUsed = colors;
826  for(i = 0; i < colors; i++)
827  {
828  rgbQuads[i].rgbRed = psurf->ppal->IndexedColors[i].peRed;
829  rgbQuads[i].rgbGreen = psurf->ppal->IndexedColors[i].peGreen;
830  rgbQuads[i].rgbBlue = psurf->ppal->IndexedColors[i].peBlue;
831  rgbQuads[i].rgbReserved = 0;
832  }
833  }
834  else
835  {
836  for(i = 0; i < 256; i++)
837  ((WORD*)rgbQuads)[i] = i;
838  }
839  }
840  else
841  {
842  if(Usage == DIB_PAL_COLORS)
843  {
844  for(i = 0; i < 256; i++)
845  {
846  ((WORD*)rgbQuads)[i] = i;
847  }
848  }
849  else if(bpp > 1 && bpp == BitsPerFormat(psurf->SurfObj.iBitmapFormat))
850  {
851  /* For color DDBs in native depth (mono DDBs always have
852  a black/white palette):
853  Generate the color map from the selected palette */
854  PPALETTE pDcPal = PALETTE_ShareLockPalette(pDC->dclevel.hpal);
855  if(!pDcPal)
856  {
857  ScanLines = 0 ;
858  goto done ;
859  }
860  for (i = 0; i < pDcPal->NumColors; i++)
861  {
862  rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
863  rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
864  rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
865  rgbQuads[i].rgbReserved = 0;
866  }
868  }
869  else
870  {
871  switch (bpp)
872  {
873  case 1:
874  rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = rgbQuads[0].rgbBlue = 0;
875  rgbQuads[0].rgbReserved = 0;
876  rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = rgbQuads[1].rgbBlue = 0xff;
877  rgbQuads[1].rgbReserved = 0;
878  break;
879 
880  case 4:
881  /* The EGA palette is the first and last 8 colours of the default palette
882  with the innermost pair swapped */
883  RtlCopyMemory(rgbQuads, DefLogPaletteQuads, 7 * sizeof(RGBQUAD));
884  RtlCopyMemory(rgbQuads + 7, DefLogPaletteQuads + 12, 1 * sizeof(RGBQUAD));
885  RtlCopyMemory(rgbQuads + 8, DefLogPaletteQuads + 7, 1 * sizeof(RGBQUAD));
886  RtlCopyMemory(rgbQuads + 9, DefLogPaletteQuads + 13, 7 * sizeof(RGBQUAD));
887  break;
888 
889  case 8:
890  {
891  INT i;
892 
893  memcpy(rgbQuads, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
894  memcpy(rgbQuads + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
895 
896  for (i = 10; i < 246; i++)
897  {
898  rgbQuads[i].rgbRed = (i & 0x07) << 5;
899  rgbQuads[i].rgbGreen = (i & 0x38) << 2;
900  rgbQuads[i].rgbBlue = i & 0xc0;
901  rgbQuads[i].rgbReserved = 0;
902  }
903  }
904  }
905  }
906  }
907  break;
908 
909  case 15:
910  if (Info->bmiHeader.biCompression == BI_BITFIELDS)
911  {
912  ((PDWORD)Info->bmiColors)[0] = 0x7c00;
913  ((PDWORD)Info->bmiColors)[1] = 0x03e0;
914  ((PDWORD)Info->bmiColors)[2] = 0x001f;
915  }
916  break;
917 
918  case 16:
919  if (Info->bmiHeader.biCompression == BI_BITFIELDS)
920  {
921  if (psurf->hSecure)
922  {
923  ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
924  ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
925  ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
926  }
927  else
928  {
929  ((PDWORD)Info->bmiColors)[0] = 0xf800;
930  ((PDWORD)Info->bmiColors)[1] = 0x07e0;
931  ((PDWORD)Info->bmiColors)[2] = 0x001f;
932  }
933  }
934  break;
935 
936  case 24:
937  case 32:
938  if (Info->bmiHeader.biCompression == BI_BITFIELDS)
939  {
940  if (psurf->hSecure)
941  {
942  ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
943  ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
944  ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
945  }
946  else
947  {
948  ((PDWORD)Info->bmiColors)[0] = 0xff0000;
949  ((PDWORD)Info->bmiColors)[1] = 0x00ff00;
950  ((PDWORD)Info->bmiColors)[2] = 0x0000ff;
951  }
952  }
953  break;
954 
955  default:
956  ScanLines = 0;
957  goto done;
958  }
959 
960  Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
961  Info->bmiHeader.biPlanes = 1;
962 
963  if(Bits && ScanLines)
964  {
965  /* Create a DIBSECTION, blt it, profit */
966  PVOID pDIBits ;
967  HBITMAP hBmpDest;
968  PSURFACE psurfDest;
969  EXLATEOBJ exlo;
970  RECT rcDest;
971  POINTL srcPoint;
972  BOOL ret ;
973  int newLines = -1;
974 
975  if (StartScan >= abs(Info->bmiHeader.biHeight))
976  {
977  ScanLines = 1;
978  goto done;
979  }
980  else
981  {
982  ScanLines = min(ScanLines, abs(Info->bmiHeader.biHeight) - StartScan);
983  }
984 
985  if (abs(Info->bmiHeader.biHeight) < psurf->SurfObj.sizlBitmap.cy)
986  {
987  StartScan += psurf->SurfObj.sizlBitmap.cy - abs(Info->bmiHeader.biHeight);
988  }
989  /* Fixup values */
990  Info->bmiHeader.biHeight = (height < 0) ?
991  -(LONG)ScanLines : ScanLines;
992  /* Create the DIB */
993  hBmpDest = DIB_CreateDIBSection(pDC, Info, Usage, &pDIBits, NULL, 0, 0);
994  /* Restore them */
995  Info->bmiHeader.biHeight = height;
996 
997  if(!hBmpDest)
998  {
999  DPRINT1("Unable to create a DIB Section!\n");
1001  ScanLines = 0;
1002  goto done ;
1003  }
1004 
1005  psurfDest = SURFACE_ShareLockSurface(hBmpDest);
1006 
1007  RECTL_vSetRect(&rcDest, 0, 0, Info->bmiHeader.biWidth, ScanLines);
1008  Info->bmiHeader.biWidth = width;
1009  srcPoint.x = 0;
1010 
1011  if (abs(Info->bmiHeader.biHeight) <= psurf->SurfObj.sizlBitmap.cy)
1012  {
1013  srcPoint.y = psurf->SurfObj.sizlBitmap.cy - StartScan - ScanLines;
1014  }
1015  else
1016  {
1017  /* Determine the actual number of lines copied from the */
1018  /* original bitmap. It might be different from ScanLines. */
1019  newLines = abs(Info->bmiHeader.biHeight) - psurf->SurfObj.sizlBitmap.cy;
1020  newLines = min((int)(StartScan + ScanLines - newLines), psurf->SurfObj.sizlBitmap.cy);
1021  if (newLines > 0)
1022  {
1023  srcPoint.y = psurf->SurfObj.sizlBitmap.cy - newLines;
1024  if (StartScan > psurf->SurfObj.sizlBitmap.cy)
1025  {
1026  newLines -= (StartScan - psurf->SurfObj.sizlBitmap.cy);
1027  }
1028  }
1029  else
1030  {
1031  newLines = 0;
1032  srcPoint.y = psurf->SurfObj.sizlBitmap.cy;
1033  }
1034  }
1035 
1036  EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0xffffff, 0xffffff, 0);
1037 
1038  ret = IntEngCopyBits(&psurfDest->SurfObj,
1039  &psurf->SurfObj,
1040  NULL,
1041  &exlo.xlo,
1042  &rcDest,
1043  &srcPoint);
1044 
1045  SURFACE_ShareUnlockSurface(psurfDest);
1046 
1047  if(!ret)
1048  ScanLines = 0;
1049  else
1050  {
1051  RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, ScanLines, bpp));
1052  }
1053  /* Update if line count has changed */
1054  if (newLines != -1)
1055  {
1056  ScanLines = (UINT)newLines;
1057  }
1058  GreDeleteObject(hBmpDest);
1059  EXLATEOBJ_vCleanup(&exlo);
1060  }
1061  else
1062  {
1063  /* Signals success and not the actual number of scan lines*/
1064  ScanLines = 1;
1065  }
1066 
1067 done:
1068 
1069  if (pbmci)
1071 
1072  if (psurf)
1074 
1075  if (pDC)
1076  DC_UnlockDc(pDC);
1077 
1078  return ScanLines;
1079 }
1080 
1081 _Success_(return!=0)
1083 INT
1084 APIENTRY
1085 NtGdiGetDIBitsInternal(
1086  _In_ HDC hdc,
1087  _In_ HBITMAP hbm,
1089  _In_ UINT cScans,
1092  _In_ UINT iUsage,
1095 {
1096  PBITMAPINFO pbmiSafe;
1097  HANDLE hSecure = NULL;
1098  INT iResult = 0;
1099  UINT cjAlloc;
1100 
1101  /* Check for bad iUsage */
1102  if (iUsage > 2) return 0;
1103 
1104  /* Check if the size of the bitmap info is large enough */
1105  if (cjMaxInfo < sizeof(BITMAPCOREHEADER))
1106  {
1107  return 0;
1108  }
1109 
1110  /* Use maximum size */
1111  cjMaxInfo = min(cjMaxInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD));
1112 
1113  // HACK: the underlying code sucks and doesn't care for the size, so we
1114  // give it the maximum ever needed
1115  cjAlloc = sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD);
1116 
1117  /* Allocate a buffer the bitmapinfo */
1118  pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjAlloc, 'imBG');
1119  if (!pbmiSafe)
1120  {
1121  /* Fail */
1122  return 0;
1123  }
1124 
1125  /* Use SEH */
1126  _SEH2_TRY
1127  {
1128  /* Probe and copy the BITMAPINFO */
1130  RtlCopyMemory(pbmiSafe, pbmi, cjMaxInfo);
1131  }
1133  {
1134  goto cleanup;
1135  }
1136  _SEH2_END;
1137 
1138  /* Check if the header size is large enough */
1139  if ((pbmiSafe->bmiHeader.biSize < sizeof(BITMAPCOREHEADER)) ||
1140  (pbmiSafe->bmiHeader.biSize > cjMaxInfo))
1141  {
1142  goto cleanup;
1143  }
1144 
1145  /* Check if the caller provided bitmap bits */
1146  if (pjBits)
1147  {
1148  /* Secure the user mode memory */
1149  hSecure = EngSecureMem(pjBits, cjMaxBits);
1150  if (!hSecure)
1151  {
1152  goto cleanup;
1153  }
1154  }
1155 
1156  /* Now call the internal function */
1157  iResult = GreGetDIBitsInternal(hdc,
1158  hbm,
1159  iStartScan,
1160  cScans,
1161  pjBits,
1162  pbmiSafe,
1163  iUsage,
1164  cjMaxBits,
1165  cjMaxInfo);
1166 
1167  /* Check for success */
1168  if (iResult)
1169  {
1170  /* Use SEH to copy back to user mode */
1171  _SEH2_TRY
1172  {
1173  /* Copy the data back */
1176  RtlCopyMemory(pbmi, pbmiSafe, cjMaxInfo);
1177  }
1179  {
1180  /* Ignore */
1181  (VOID)0;
1182  }
1183  _SEH2_END;
1184  }
1185 
1186 cleanup:
1187  if (hSecure) EngUnsecureMem(hSecure);
1188  ExFreePoolWithTag(pbmiSafe, 'imBG');
1189 
1190  return iResult;
1191 }
1192 
1193 
1194 W32KAPI
1195 INT
1196 APIENTRY
1198  IN HDC hdc,
1199  IN INT xDst,
1200  IN INT yDst,
1201  IN INT cxDst,
1202  IN INT cyDst,
1203  IN INT xSrc,
1204  IN INT ySrc,
1205  IN INT cxSrc,
1206  IN INT cySrc,
1207  IN OPTIONAL LPBYTE pjInit,
1209  IN DWORD dwUsage,
1210  IN DWORD dwRop, // MS ntgdi.h says dwRop4(?)
1211  IN UINT cjMaxInfo,
1212  IN UINT cjMaxBits,
1213  IN HANDLE hcmXform)
1214 {
1215  SIZEL sizel;
1216  RECTL rcSrc, rcDst;
1217  PDC pdc;
1218  HBITMAP hbmTmp = 0;
1219  PSURFACE psurfTmp = 0, psurfDst = 0;
1220  PPALETTE ppalDIB = 0;
1221  EXLATEOBJ exlo;
1222  PBYTE pvBits;
1223 
1224  LPBITMAPINFO pbmiSafe;
1225  UINT cjAlloc;
1226  HBITMAP hBitmap, hOldBitmap = NULL;
1227  HDC hdcMem;
1228  HPALETTE hPal = NULL;
1229  ULONG BmpFormat = 0;
1230  INT LinesCopied = 0;
1231 
1232  /* Check for bad iUsage */
1233  if (dwUsage > 2) return 0;
1234 
1235  /* We must have LPBITMAPINFO */
1236  if (!pbmi)
1237  {
1238  DPRINT1("Error, Invalid Parameter.\n");
1240  return 0;
1241  }
1242 
1243  /* Check if the size of the bitmap info is large enough */
1244  if (cjMaxInfo < sizeof(BITMAPCOREHEADER))
1245  {
1246  return 0;
1247  }
1248 
1249  /* Use maximum size */
1250  cjMaxInfo = min(cjMaxInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD));
1251 
1252  // HACK: the underlying code sucks and doesn't care for the size, so we
1253  // give it the maximum ever needed
1254  cjAlloc = sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD);
1255 
1256  /* Allocate a buffer the bitmapinfo */
1257  pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjAlloc, 'imBG');
1258  if (!pbmiSafe)
1259  {
1260  /* Fail */
1261  return 0;
1262  }
1263 
1264  /* Use SEH */
1265  _SEH2_TRY
1266  {
1267  /* Probe and copy the BITMAPINFO */
1269  RtlCopyMemory(pbmiSafe, pbmi, cjMaxInfo);
1270  }
1272  {
1273  ExFreePoolWithTag(pbmiSafe, 'imBG');
1274  return 0;
1275  }
1276  _SEH2_END;
1277 
1278  /* Check if the header size is large enough */
1279  if ((pbmiSafe->bmiHeader.biSize < sizeof(BITMAPCOREHEADER)) ||
1280  (pbmiSafe->bmiHeader.biSize > cjMaxInfo))
1281  {
1282  ExFreePoolWithTag(pbmiSafe, 'imBG');
1283  return 0;
1284  }
1285 
1286  if (!(pdc = DC_LockDc(hdc)))
1287  {
1289  return 0;
1290  }
1291 
1292  /* Check for info / mem DC without surface */
1293  if (!pdc->dclevel.pSurface)
1294  {
1295  DC_UnlockDc(pdc);
1296  // CHECKME
1297  return TRUE;
1298  }
1299 
1300  /* Transform dest size */
1301  sizel.cx = cxDst;
1302  sizel.cy = cyDst;
1303  IntLPtoDP(pdc, (POINTL*)&sizel, 1);
1304  DC_UnlockDc(pdc);
1305 
1306  if (pjInit && (cjMaxBits > 0))
1307  {
1309  if (!pvBits)
1310  {
1311  return 0;
1312  }
1313 
1314  _SEH2_TRY
1315  {
1316  ProbeForRead(pjInit, cjMaxBits, 1);
1317  RtlCopyMemory(pvBits, pjInit, cjMaxBits);
1318  }
1320  {
1321  ExFreePoolWithTag(pvBits, TAG_DIB);
1322  return 0;
1323  }
1324  _SEH2_END;
1325  }
1326  else
1327  {
1328  pvBits = NULL;
1329  }
1330 
1331  /* Here we select between the dwRop with SRCCOPY or not. */
1332  if (dwRop == SRCCOPY)
1333  {
1335  if (hdcMem == NULL)
1336  {
1337  DPRINT1("NtGdiCreateCompatibleDC failed to create hdc.\n");
1339  return 0;
1340  }
1341 
1343  abs(pbmiSafe->bmiHeader.biWidth),
1344  abs(pbmiSafe->bmiHeader.biHeight));
1345  if (hBitmap == NULL)
1346  {
1347  DPRINT1("NtGdiCreateCompatibleBitmap failed to create bitmap.\n");
1348  DPRINT1("hdc : 0x%08x \n", hdc);
1349  DPRINT1("width : 0x%08x \n", pbmiSafe->bmiHeader.biWidth);
1350  DPRINT1("height : 0x%08x \n", pbmiSafe->bmiHeader.biHeight);
1352  return 0;
1353  }
1354 
1355  /* Select the bitmap into hdcMem, and save a handle to the old bitmap */
1356  hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
1357 
1358  if (dwUsage == DIB_PAL_COLORS)
1359  {
1361  hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
1362  }
1363 
1364  pdc = DC_LockDc(hdcMem);
1365  if (pdc != NULL)
1366  {
1367  IntSetDIBits(pdc, hBitmap, 0, abs(pbmiSafe->bmiHeader.biHeight), pvBits,
1368  cjMaxBits, pbmiSafe, dwUsage);
1369  DC_UnlockDc(pdc);
1370  }
1371 
1372  /* Origin for DIBitmap may be bottom left (positive biHeight) or top
1373  left (negative biHeight) */
1374  if (cxSrc == cxDst && cySrc == cyDst)
1375  {
1376  NtGdiBitBlt(hdc, xDst, yDst, cxDst, cyDst,
1377  hdcMem, xSrc, abs(pbmiSafe->bmiHeader.biHeight) - cySrc - ySrc,
1378  dwRop, 0, 0);
1379  }
1380  else
1381  {
1382  NtGdiStretchBlt(hdc, xDst, yDst, cxDst, cyDst,
1383  hdcMem, xSrc, abs(pbmiSafe->bmiHeader.biHeight) - cySrc - ySrc,
1384  cxSrc, cySrc, dwRop, 0);
1385  }
1386 
1387  /* cleanup */
1388  if (hPal)
1389  GdiSelectPalette(hdcMem, hPal, FALSE);
1390 
1391  if (hOldBitmap)
1392  NtGdiSelectBitmap(hdcMem, hOldBitmap);
1393 
1396 
1397  } /* End of dwRop == SRCCOPY */
1398  else
1399  { /* Start of dwRop != SRCCOPY */
1400  /* FIXME: Locking twice is cheesy, coord tranlation in UM will fix it */
1401  if (!(pdc = DC_LockDc(hdc)))
1402  {
1403  DPRINT1("Could not lock dc\n");
1405  goto cleanup;
1406  }
1407 
1408  /* Calculate source and destination rect */
1409  rcSrc.left = xSrc;
1410  rcSrc.top = ySrc;
1411  rcSrc.right = xSrc + abs(cxSrc);
1412  rcSrc.bottom = ySrc + abs(cySrc);
1413  rcDst.left = xDst;
1414  rcDst.top = yDst;
1415  rcDst.right = rcDst.left + cxDst;
1416  rcDst.bottom = rcDst.top + cyDst;
1417  IntLPtoDP(pdc, (POINTL*)&rcDst, 2);
1418  RECTL_vOffsetRect(&rcDst, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
1419 
1420  if (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
1421  {
1422  IntUpdateBoundsRect(pdc, &rcDst);
1423  }
1424 
1425  BmpFormat = BitmapFormat(pbmiSafe->bmiHeader.biBitCount,
1426  pbmiSafe->bmiHeader.biCompression);
1427 
1428  hbmTmp = GreCreateBitmapEx(pbmiSafe->bmiHeader.biWidth,
1429  abs(pbmiSafe->bmiHeader.biHeight),
1430  0,
1431  BmpFormat,
1432  pbmiSafe->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
1433  cjMaxBits,
1434  pvBits,
1435  0);
1436 
1437  if (!hbmTmp)
1438  {
1439  goto cleanup;
1440  }
1441 
1442  psurfTmp = SURFACE_ShareLockSurface(hbmTmp);
1443  if (!psurfTmp)
1444  {
1445  goto cleanup;
1446  }
1447 
1448  /* Create a palette for the DIB */
1449  ppalDIB = CreateDIBPalette(pbmiSafe, pdc, dwUsage);
1450  if (!ppalDIB)
1451  {
1452  goto cleanup;
1453  }
1454 
1455  /* Prepare DC for blit */
1456  DC_vPrepareDCsForBlit(pdc, &rcDst, NULL, NULL);
1457 
1458  psurfDst = pdc->dclevel.pSurface;
1459 
1460  /* Initialize XLATEOBJ */
1461  EXLATEOBJ_vInitialize(&exlo,
1462  ppalDIB,
1463  psurfDst->ppal,
1464  RGB(0xff, 0xff, 0xff),
1465  pdc->pdcattr->crBackgroundClr,
1466  pdc->pdcattr->crForegroundClr);
1467 
1468  /* Perform the stretch operation */
1469  IntEngStretchBlt(&psurfDst->SurfObj,
1470  &psurfTmp->SurfObj,
1471  NULL,
1472  (CLIPOBJ *)&pdc->co,
1473  &exlo.xlo,
1474  &pdc->dclevel.ca,
1475  &rcDst,
1476  &rcSrc,
1477  NULL,
1478  &pdc->eboFill.BrushObject,
1479  NULL,
1480  WIN32_ROP3_TO_ENG_ROP4(dwRop));
1481 
1482  /* Cleanup */
1483  DC_vFinishBlit(pdc, NULL);
1484  EXLATEOBJ_vCleanup(&exlo);
1485 
1486  cleanup:
1487  if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
1488  if (psurfTmp) SURFACE_ShareUnlockSurface(psurfTmp);
1489  if (hbmTmp) GreDeleteObject(hbmTmp);
1490  if (pdc) DC_UnlockDc(pdc);
1491  }
1492 
1493  if (pbmiSafe) ExFreePoolWithTag(pbmiSafe, 'imBG');
1494  if (pvBits) ExFreePoolWithTag(pvBits, TAG_DIB);
1495 
1496  /* This is not what MSDN says is returned from this function, but it
1497  * follows Wine's dlls/gdi32/dib.c function nulldrv_StretchDIBits
1498  * and it fixes over 100 gdi32:dib regression tests. */
1499  if (dwRop == SRCCOPY)
1500  {
1501  LinesCopied = abs(pbmiSafe->bmiHeader.biHeight);
1502  }
1503  else
1504  {
1505  LinesCopied = pbmiSafe->bmiHeader.biHeight;
1506  }
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:1197
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:1437
#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
#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:1502
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:1475
#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:1503
#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:365
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:466
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:364
BITMAPCOREHEADER bmciHeader
Definition: wingdi.h:1452
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:690
_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:1453
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:1476
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
Definition: xlate.c:8
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:1081
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:1439
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:356
__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:1438
#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:1504
#define DPRINT
Definition: sndvol32.h:71
#define DIB_RGB_COLORS
Definition: wingdi.h:366
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:235
#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:3238
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:332
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