ReactOS  0.4.15-dev-3272-g6e356a9
bitmap.c
Go to the documentation of this file.
1 #include <precomp.h>
2 
3 #include <pseh/pseh2.h>
4 
5 #define NDEBUG
6 #include <debug.h>
7 
8 // From Yuan, ScanLineSize = (Width * bitcount + 31)/32
9 #define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3)
10 
11 /*
12  * DIB_BitmapInfoSize
13  *
14  * Return the size of the bitmap info structure including color table.
15  * 11/16/1999 (RJJ) lifted from wine
16  */
17 
18 INT
20  const BITMAPINFO * info,
21  WORD coloruse,
22  BOOL max)
23 {
24  unsigned int colors, size, masks = 0;
25 
26  if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
27  {
28  const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *) info;
29  size = sizeof(BITMAPCOREHEADER);
30  if (core->bcBitCount <= 8)
31  {
32  colors = 1 << core->bcBitCount;
33  if (coloruse == DIB_RGB_COLORS)
34  size += colors * sizeof(RGBTRIPLE);
35  else
36  size += colors * sizeof(WORD);
37  }
38  return size;
39  }
40  else /* assume BITMAPINFOHEADER */
41  {
42  colors = max ? (1 << info->bmiHeader.biBitCount) : info->bmiHeader.biClrUsed;
43  if (colors > 256)
44  colors = 256;
45  if (!colors && (info->bmiHeader.biBitCount <= 8))
46  colors = 1 << info->bmiHeader.biBitCount;
47  if (info->bmiHeader.biCompression == BI_BITFIELDS)
48  masks = 3;
49  size = max(info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD));
50  return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
51  }
52 }
53 
54 /*
55  * Return the full scan size for a bitmap.
56  *
57  * Based on Wine, Utils.c and Windows Graphics Prog pg 595, SDK amvideo.h.
58  */
59 UINT
63  UINT ScanLines)
64 {
65  UINT Ret;
66 
67  if (!Info)
68  return 0;
69 
70  if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
71  {
73  Ret = WIDTH_BYTES_ALIGN32(Core->bcWidth * Core->bcPlanes,
74  Core->bcBitCount) * ScanLines;
75  }
76  else /* assume BITMAPINFOHEADER */
77  {
78  if ((Info->bmiHeader.biCompression == BI_RGB) || (Info->bmiHeader.biCompression == BI_BITFIELDS))
79  {
80  Ret = WIDTH_BYTES_ALIGN32(
81  Info->bmiHeader.biWidth * Info->bmiHeader.biPlanes,
82  Info->bmiHeader.biBitCount) * ScanLines;
83  }
84  else
85  {
86  Ret = Info->bmiHeader.biSizeImage;
87  }
88  }
89  return Ret;
90 }
91 
92 /*
93  * DIB_GetBitmapInfo is complete copy of wine cvs 2/9-2006
94  * from file dib.c from gdi32.dll or orginal version
95  * did not calc the info right for some headers.
96  */
97 INT
98 WINAPI
100  const BITMAPINFOHEADER *header,
101  PLONG width,
102  PLONG height,
103  PWORD planes,
104  PWORD bpp,
105  PLONG compr,
106  PLONG size)
107 {
108  if (header->biSize == sizeof(BITMAPCOREHEADER))
109  {
111  *width = core->bcWidth;
112  *height = core->bcHeight;
113  *planes = core->bcPlanes;
114  *bpp = core->bcBitCount;
115  *compr = 0;
116  *size = 0;
117  return 0;
118  }
119 
120  if (header->biSize == sizeof(BITMAPINFOHEADER))
121  {
122  *width = header->biWidth;
123  *height = header->biHeight;
124  *planes = header->biPlanes;
125  *bpp = header->biBitCount;
126  *compr = header->biCompression;
127  *size = header->biSizeImage;
128  return 1;
129  }
130 
131  if (header->biSize == sizeof(BITMAPV4HEADER))
132  {
133  BITMAPV4HEADER *v4hdr = (BITMAPV4HEADER *) header;
134  *width = v4hdr->bV4Width;
135  *height = v4hdr->bV4Height;
136  *planes = v4hdr->bV4Planes;
137  *bpp = v4hdr->bV4BitCount;
138  *compr = v4hdr->bV4V4Compression;
139  *size = v4hdr->bV4SizeImage;
140  return 4;
141  }
142 
143  if (header->biSize == sizeof(BITMAPV5HEADER))
144  {
145  BITMAPV5HEADER *v5hdr = (BITMAPV5HEADER *) header;
146  *width = v5hdr->bV5Width;
147  *height = v5hdr->bV5Height;
148  *planes = v5hdr->bV5Planes;
149  *bpp = v5hdr->bV5BitCount;
150  *compr = v5hdr->bV5Compression;
151  *size = v5hdr->bV5SizeImage;
152  return 5;
153  }
154  DPRINT("(%lu): wrong size for header\n", header->biSize);
155  return -1;
156 }
157 
158 /*
159  * @implemented
160  */
161 int
162 WINAPI
164  BITMAPINFO *lpbmi)
165 {
166  UINT Ret;
167 
168  if (!lpbmi)
169  return 0;
170 
171  if (lpbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
172  {
173  PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER) lpbmi;
174  Ret =
175  WIDTH_BYTES_ALIGN32(Core->bcWidth * Core->bcPlanes,
176  Core->bcBitCount) * Core->bcHeight;
177  }
178  else /* assume BITMAPINFOHEADER */
179  {
180  if (!(lpbmi->bmiHeader.biCompression) || (lpbmi->bmiHeader.biCompression == BI_BITFIELDS))
181  {
182  Ret = WIDTH_BYTES_ALIGN32(
183  lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biPlanes,
184  lpbmi->bmiHeader.biBitCount) * abs(lpbmi->bmiHeader.biHeight);
185  }
186  else
187  {
188  Ret = lpbmi->bmiHeader.biSizeImage;
189  }
190  }
191  return Ret;
192 }
193 
194 /*
195  * @implemented
196  */
197 HBITMAP
198 WINAPI
200  HDC hDC,
201  CONST BITMAPINFO *BitmapInfo,
202  UINT Usage,
203  VOID **Bits,
205  DWORD dwOffset)
206 {
207  PBITMAPINFO pConvertedInfo;
208  UINT ConvertedInfoSize;
209  HBITMAP hBitmap = NULL;
210  PVOID bmBits = NULL;
211 
212  pConvertedInfo = ConvertBitmapInfo(BitmapInfo, Usage, &ConvertedInfoSize,
213  FALSE);
214 
215  if (pConvertedInfo)
216  {
217  // Verify header due to converted may == info.
218  if (pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
219  {
220  if (pConvertedInfo->bmiHeader.biCompression == BI_JPEG
221  || pConvertedInfo->bmiHeader.biCompression == BI_PNG)
222  {
224  return NULL;
225  }
226  }
227  bmBits = Bits;
229  ConvertedInfoSize, 0, // fl
230  0, // dwColorSpace
231  &bmBits);
232 
233  if (BitmapInfo != pConvertedInfo)
234  RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
235 
236  if (!hBitmap)
237  {
238  bmBits = NULL;
239  }
240  }
241 
242  if (Bits)
243  *Bits = bmBits;
244 
245  return hBitmap;
246 }
247 
248 
249 /*
250  * @implemented
251  */
252 HBITMAP
253 WINAPI
255  INT Width,
256  INT Height,
257  UINT Planes,
258  UINT BitsPixel,
259  CONST VOID* pUnsafeBits)
260 {
261  if (Width && Height)
262  {
263  return NtGdiCreateBitmap(Width, Height, Planes, BitsPixel, (LPBYTE) pUnsafeBits);
264  }
265  else
266  {
267  /* Return 1x1 bitmap */
269  }
270 }
271 
272 /*
273  * @implemented
274  */
275 HBITMAP
276 WINAPI
278  const BITMAP *pbm)
279 {
280  HBITMAP bitmap = NULL;
281 
282  /* Note windows xp/2003 does not check if pbm is NULL or not */
283  if ((pbm->bmWidthBytes != 0) && (!(pbm->bmWidthBytes & 1)))
284 
285  {
286  bitmap = CreateBitmap(pbm->bmWidth, pbm->bmHeight, pbm->bmPlanes, pbm->bmBitsPixel,
287  pbm->bmBits);
288  }
289  else
290  {
292  }
293 
294  return bitmap;
295 }
296 
297 HBITMAP
298 WINAPI
300  HDC hDC,
301  INT Width,
302  INT Height)
303 {
304  return CreateCompatibleBitmap(hDC, Width, Height);
305 }
306 
307 HBITMAP
308 WINAPI
310  HDC hDC,
311  INT Width,
312  INT Height)
313 {
314  PDC_ATTR pDc_Attr;
315 
316  if (!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID) & pDc_Attr))
317  return NULL;
318 
319  if (!Width || !Height)
321 
322  if (!(pDc_Attr->ulDirty_ & DC_DIBSECTION))
323  {
324  return NtGdiCreateCompatibleBitmap(hDC, Width, Height);
325  }
326  else
327  {
328  HBITMAP hBmp = NULL;
329  struct
330  {
331  BITMAP bitmap;
332  BITMAPINFOHEADER bmih;
333  RGBQUAD rgbquad[256];
334  } buffer;
335  DIBSECTION* pDIBs = (DIBSECTION*) &buffer;
336  BITMAPINFO* pbmi = (BITMAPINFO*) &buffer.bmih;
337 
339 
340  if (GetObjectA(hBmp, sizeof(DIBSECTION), pDIBs) != sizeof(DIBSECTION))
341  return NULL;
342 
343  if (pDIBs->dsBm.bmBitsPixel <= 8)
344  GetDIBColorTable(hDC, 0, 256, buffer.rgbquad);
345 
346  pDIBs->dsBmih.biWidth = Width;
347  pDIBs->dsBmih.biHeight = Height;
348 
350  }
351  return NULL;
352 }
353 
354 INT
355 WINAPI
357  HDC hDC,
358  HBITMAP hbmp,
359  UINT uStartScan,
360  UINT cScanLines,
361  LPVOID lpvBits,
362  LPBITMAPINFO lpbmi,
363  UINT uUsage)
364 {
365  UINT cjBmpScanSize;
366  UINT cjInfoSize;
367 
368  if (!hDC || !GdiValidateHandle((HGDIOBJ) hDC) || !lpbmi)
369  {
371  return 0;
372  }
373 
374  cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
375  /* Caller must provide maximum size possible */
376  cjInfoSize = DIB_BitmapInfoSize(lpbmi, uUsage, TRUE);
377 
378  if (lpvBits)
379  {
380  if (lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
381  {
382  if (lpbmi->bmiHeader.biCompression == BI_JPEG
383  || lpbmi->bmiHeader.biCompression == BI_PNG)
384  {
386  return 0;
387  }
388  }
389  }
390 
391  return NtGdiGetDIBitsInternal(hDC, hbmp, uStartScan, cScanLines, lpvBits, lpbmi, uUsage,
392  cjBmpScanSize, cjInfoSize);
393 }
394 
395 /*
396  * @implemented
397  */
398 HBITMAP
399 WINAPI
401  HDC hDC,
402  const BITMAPINFOHEADER *Header,
403  DWORD Init,
404  LPCVOID Bits,
405  const BITMAPINFO *Data,
406  UINT ColorUse)
407 {
408  LONG Width, Height, Compression, DibSize;
409  WORD Planes, BitsPerPixel;
410 // PDC_ATTR pDc_Attr;
411  UINT cjBmpScanSize = 0;
412  HBITMAP hBitmap = NULL;
413  PBITMAPINFO pbmiConverted;
414  UINT cjInfoSize;
415 
416  /* Convert the BITMAPINFO if it is a COREINFO */
417  pbmiConverted = ConvertBitmapInfo(Data, ColorUse, &cjInfoSize, FALSE);
418 
419  /* Check for CBM_CREATDIB */
420  if (Init & CBM_CREATDIB)
421  {
422  if (cjInfoSize == 0)
423  {
424  goto Exit;
425  }
426  else if (Init & CBM_INIT)
427  {
428  if (Bits == NULL)
429  {
430  goto Exit;
431  }
432  }
433  else
434  {
435  Bits = NULL;
436  }
437 
438  /* CBM_CREATDIB needs Data. */
439  if (pbmiConverted == NULL)
440  {
441  DPRINT1("CBM_CREATDIB needs a BITMAPINFO!\n");
442  goto Exit;
443  }
444 
445  /* It only works with PAL or RGB */
446  if (ColorUse > DIB_PAL_COLORS)
447  {
448  DPRINT1("Invalid ColorUse: %lu\n", ColorUse);
450  goto Exit;
451  }
452 
453  /* Use the header from the data */
454  Header = &Data->bmiHeader;
455  }
456  else
457  {
458  if (Init & CBM_INIT)
459  {
460  if (Bits != NULL)
461  {
462  if (cjInfoSize == 0)
463  {
464  goto Exit;
465  }
466  }
467  else
468  {
469  Init &= ~CBM_INIT;
470  }
471  }
472  }
473 
474  /* Header is required */
475  if (!Header)
476  {
477  DPRINT1("Header is NULL\n");
479  goto Exit;
480  }
481 
482  /* Get the bitmap format and dimensions */
483  if (DIB_GetBitmapInfo(Header, &Width, &Height, &Planes, &BitsPerPixel, &Compression, &DibSize) == -1)
484  {
485  DPRINT1("DIB_GetBitmapInfo failed!\n");
487  goto Exit;
488  }
489 
490  /* Check if the Compr is incompatible */
491  if ((Compression == BI_JPEG) || (Compression == BI_PNG))
492  {
493  DPRINT1("Invalid compression: %lu!\n", Compression);
494  goto Exit;
495  }
496 
497  /* Only DIB_RGB_COLORS (0), DIB_PAL_COLORS (1) and 2 are valid. */
498  if (ColorUse > DIB_PAL_COLORS + 1)
499  {
500  DPRINT1("Invalid compression: %lu!\n", Compression);
502  goto Exit;
503  }
504 
505  /* If some Bits are given, only DIB_PAL_COLORS and DIB_RGB_COLORS are valid */
506  if (Bits && (ColorUse > DIB_PAL_COLORS))
507  {
508  DPRINT1("Invalid ColorUse: %lu\n", ColorUse);
510  goto Exit;
511  }
512 
513  /* Negative width is not allowed */
514  if (Width < 0)
515  {
516  DPRINT1("Negative width: %li\n", Width);
517  goto Exit;
518  }
519 
520  /* Top-down DIBs have a negative height. */
521  Height = abs(Height);
522 
523 // For Icm support.
524 // GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
525 
526  cjBmpScanSize = GdiGetBitmapBitsSize(pbmiConverted);
527 
528  DPRINT("pBMI %p, Size bpp %u, dibsize %d, Conv %u, BSS %u\n",
529  Data, BitsPerPixel, DibSize, cjInfoSize, cjBmpScanSize);
530 
531  if (!Width || !Height)
532  {
534  }
535  else
536  {
538  Width,
539  Height,
540  Init,
541  (LPBYTE)Bits,
542  (LPBITMAPINFO)pbmiConverted,
543  ColorUse,
544  cjInfoSize,
545  cjBmpScanSize,
546  0, 0);
547  }
548 
549 Exit:
550  /* Cleanup converted BITMAPINFO */
551  if ((pbmiConverted != NULL) && (pbmiConverted != Data))
552  {
553  RtlFreeHeap(RtlGetProcessHeap(), 0, pbmiConverted);
554  }
555 
556  return hBitmap;
557 }
558 
559 /*
560  * @implemented
561  */
562 INT
563 WINAPI
565  HDC hDC,
567  UINT uStartScan,
568  UINT cScanLines,
569  CONST VOID *lpvBits,
570  CONST BITMAPINFO *lpbmi,
571  UINT fuColorUse)
572 {
573  HDC hDCc, SavehDC, nhDC;
575  HGDIOBJ hOldBitmap;
576  HPALETTE hPal = NULL;
577  INT LinesCopied = 0;
578  BOOL newDC = FALSE;
579 
580  if (!lpvBits || (GDI_HANDLE_GET_TYPE(hBitmap) != GDI_OBJECT_TYPE_BITMAP))
581  return 0;
582 
583  if (lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
584  {
585  if (lpbmi->bmiHeader.biCompression == BI_JPEG
586  || lpbmi->bmiHeader.biCompression == BI_PNG)
587  {
589  return 0;
590  }
591  }
592 
593  hDCc = NtGdiGetDCforBitmap(hBitmap); // hDC can be NULL, so, get it from the bitmap.
594  SavehDC = hDCc;
595  if (!hDCc) // No DC associated with bitmap, Clone or Create one.
596  {
597  nhDC = CreateCompatibleDC(hDC);
598  if (!nhDC)
599  return 0;
600  newDC = TRUE;
601  SavehDC = nhDC;
602  }
603  else if (!SaveDC(hDCc))
604  return 0;
605 
606  hOldBitmap = SelectObject(SavehDC, hBitmap);
607 
608  if (hOldBitmap)
609  {
610  if (hDC)
611  hPal = SelectPalette(SavehDC, (HPALETTE) GetCurrentObject(hDC, OBJ_PAL), FALSE);
612 
613  if (lpbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
614  {
615  PBITMAPCOREINFO pbci = (PBITMAPCOREINFO) lpbmi;
616  dwWidth = pbci->bmciHeader.bcWidth;
617  dwHeight = pbci->bmciHeader.bcHeight;
618  }
619  else
620  {
621  dwWidth = lpbmi->bmiHeader.biWidth;
622  dwHeight = abs(lpbmi->bmiHeader.biHeight);
623  }
624 
625  LinesCopied = SetDIBitsToDevice(SavehDC, 0, 0, dwWidth, dwHeight, 0, 0, uStartScan,
626  cScanLines, (void *) lpvBits, (LPBITMAPINFO) lpbmi, fuColorUse);
627 
628  if (hDC)
629  SelectPalette(SavehDC, hPal, FALSE);
630 
631  SelectObject(SavehDC, hOldBitmap);
632  }
633 
634  if (newDC)
635  DeleteDC(SavehDC);
636  else
637  RestoreDC(SavehDC, -1);
638 
639  return LinesCopied;
640 }
641 
642 /*
643  * @implemented
644  *
645  */
646 INT
647 WINAPI
649  HDC hdc,
650  int XDest,
651  int YDest,
652  DWORD Width,
653  DWORD Height,
654  int XSrc,
655  int YSrc,
656  UINT StartScan,
657  UINT ScanLines,
658  CONST VOID *Bits,
659  CONST BITMAPINFO *lpbmi,
660  UINT ColorUse)
661 {
662  PDC_ATTR pDc_Attr;
663  PBITMAPINFO pConvertedInfo;
664  UINT ConvertedInfoSize;
665  INT LinesCopied = 0;
666  UINT cjBmpScanSize = 0;
667  BOOL Hit = FALSE;
668  PVOID pvSafeBits = (PVOID) Bits;
669 
670  if (!ScanLines || !lpbmi || !Bits)
671  return 0;
672 
673  if (ColorUse && ColorUse != DIB_PAL_COLORS && ColorUse != DIB_PAL_COLORS + 1)
674  return 0;
675 
676  pConvertedInfo = ConvertBitmapInfo(lpbmi, ColorUse, &ConvertedInfoSize, FALSE);
677  if (!pConvertedInfo)
678  return 0;
679 
682  0,
683  hdc,
684  XDest,
685  YDest,
686  Width,
687  Height,
688  XSrc,
689  YSrc,
690  StartScan,
691  ScanLines,
692  Bits,
693  lpbmi,
694  ColorUse);
695 
696  // Handle the "Special Case"!
697  {
698  PLDC pldc;
699  ULONG hType = GDI_HANDLE_GET_TYPE(hdc);
701  {
702  pldc = GdiGetLDC(hdc);
703  if (pldc)
704  {
705  if (pldc->Flags & LDC_STARTPAGE) StartPage(hdc);
706 
707  if (pldc->Flags & LDC_SAPCALLBACK) GdiSAPCallback(pldc);
708 
709  if (pldc->Flags & LDC_KILL_DOCUMENT)
710  {
711  LinesCopied = 0;
712  goto Exit;
713  }
714  }
715  else
716  {
718  LinesCopied = 0;
719  goto Exit;
720  }
721  }
722  }
723 
724  if ((pConvertedInfo->bmiHeader.biCompression == BI_RLE8) ||
725  (pConvertedInfo->bmiHeader.biCompression == BI_RLE4))
726  {
727  /* For compressed data, we must set the whole thing */
728  StartScan = 0;
729  ScanLines = pConvertedInfo->bmiHeader.biHeight;
730  }
731 
732  cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO) lpbmi, ScanLines);
733 
734  pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
735  if (pvSafeBits)
736  {
737  _SEH2_TRY
738  {
739  RtlCopyMemory(pvSafeBits, Bits, cjBmpScanSize);
740  }
742  {
743  Hit = TRUE;
744  }
745  _SEH2_END
746 
747  if (Hit)
748  {
749  // We don't die, we continue on with a allocated safe pointer to kernel
750  // space.....
751  DPRINT1("SetDIBitsToDevice fail to read BitMapInfo: %p or Bits: %p & Size: %u\n",
752  pConvertedInfo, Bits, cjBmpScanSize);
753  }
754  DPRINT("SetDIBitsToDevice Allocate Bits %u!!!\n", cjBmpScanSize);
755  }
756 
757  if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID) & pDc_Attr))
758  {
760  return 0;
761  }
762  /*
763  if ( !pDc_Attr || // DC is Public
764  ColorUse == DIB_PAL_COLORS ||
765  ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
766  (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
767  pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
768  {
769  LinesCopied = NtGdiSetDIBitsToDeviceInternal(hdc, XDest, YDest, Width, Height, XSrc, YSrc,
770  StartScan, ScanLines, (LPBYTE) pvSafeBits, (LPBITMAPINFO) pConvertedInfo, ColorUse,
771  cjBmpScanSize, ConvertedInfoSize,
772  TRUE,
773  NULL);
774  }
775 Exit:
776  if (Bits != pvSafeBits)
777  RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
778  if (lpbmi != pConvertedInfo)
779  RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
780 
781  return LinesCopied;
782 }
783 
784 /*
785  * @unimplemented
786  */
787 int
788 WINAPI
790  HDC hdc,
791  int XDest,
792  int YDest,
793  int nDestWidth,
794  int nDestHeight,
795  int XSrc,
796  int YSrc,
797  int nSrcWidth,
798  int nSrcHeight,
799  CONST VOID *lpBits,
800  CONST BITMAPINFO *lpBitsInfo,
801  UINT iUsage,
802  DWORD dwRop)
803 
804 {
805  PDC_ATTR pDc_Attr;
806  PBITMAPINFO pConvertedInfo = NULL;
807  UINT ConvertedInfoSize = 0;
808  INT LinesCopied = 0;
809  UINT cjBmpScanSize = 0;
810  PVOID pvSafeBits = NULL;
811  BOOL Hit = FALSE;
812 
813  DPRINT("StretchDIBits %p : %p : %u\n", lpBits, lpBitsInfo, iUsage);
814 
815  HANDLE_METADC( int,
817  0,
818  hdc,
819  XDest,
820  YDest,
821  nDestWidth,
822  nDestHeight,
823  XSrc,
824  YSrc,
825  nSrcWidth,
826  nSrcHeight,
827  lpBits,
828  lpBitsInfo,
829  iUsage,
830  dwRop );
831 
832  if ( GdiConvertAndCheckDC(hdc) == NULL ) return 0;
833 
834  pConvertedInfo = ConvertBitmapInfo(lpBitsInfo, iUsage, &ConvertedInfoSize, FALSE);
835  if (!pConvertedInfo)
836  {
837  return 0;
838  }
839 
840  cjBmpScanSize = GdiGetBitmapBitsSize((BITMAPINFO *) pConvertedInfo);
841 
842  if (lpBits)
843  {
844  pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
845  if (pvSafeBits)
846  {
847  _SEH2_TRY
848  {
849  RtlCopyMemory(pvSafeBits, lpBits, cjBmpScanSize);
850  }
852  {
853  Hit = TRUE;
854  }
855  _SEH2_END
856 
857  if (Hit)
858  {
859  // We don't die, we continue on with a allocated safe pointer to kernel
860  // space.....
861  DPRINT1("StretchDIBits fail to read BitMapInfo: %p or Bits: %p & Size: %u\n",
862  pConvertedInfo, lpBits, cjBmpScanSize);
863  }
864  DPRINT("StretchDIBits Allocate Bits %u!!!\n", cjBmpScanSize);
865  }
866  }
867 
868  if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID) & pDc_Attr))
869  {
871  return 0;
872  }
873  /*
874  if ( !pDc_Attr ||
875  iUsage == DIB_PAL_COLORS ||
876  ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
877  (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
878  pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
879  {
880  LinesCopied = NtGdiStretchDIBitsInternal( hdc,
881  XDest,
882  YDest,
883  nDestWidth,
884  nDestHeight,
885  XSrc,
886  YSrc,
887  nSrcWidth,
888  nSrcHeight,
889  pvSafeBits,
890  pConvertedInfo,
891  (DWORD) iUsage,
892  dwRop,
893  ConvertedInfoSize,
894  cjBmpScanSize,
895  NULL );
896  }
897  if (pvSafeBits)
898  RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
899  if (lpBitsInfo != pConvertedInfo)
900  RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
901 
902  return LinesCopied;
903 }
904 
905 /*
906  * @implemented
907  */
908 DWORD
909 WINAPI
911 {
913  {
914  return SC_BB_STOCKOBJ;
915  }
916  return 0;
917 }
918 
919 /*
920  * @implemented
921  */
922 HBITMAP
923 WINAPI
925 {
926  if ( dwFlags & ~SC_BB_STOCKOBJ )
927  {
928  return NULL;
929  }
931 }
932 
933 /*
934  * @implemented
935  */
936 HBITMAP
937 WINAPI
939 {
940  if ( dwFlags & ~SC_BB_STOCKOBJ )
941  {
942  return NULL;
943  }
945 }
946 
947 
HGDIOBJ WINAPI GetStockObject(_In_ int)
int WINAPI GetObjectA(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
HBITMAP WINAPI CreateDiscardableBitmap(HDC hDC, INT Width, INT Height)
Definition: bitmap.c:299
#define abs(i)
Definition: fconv.c:206
GLint GLint GLsizei width
Definition: gl.h:1546
BITMAPINFOHEADER dsBmih
Definition: wingdi.h:1670
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI GetBitmapAttributes(HBITMAP hbm)
Definition: bitmap.c:910
HDC WINAPI GdiConvertAndCheckDC(HDC hdc)
Definition: dc.c:403
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiCreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBPP, _In_opt_ LPBYTE pjInit)
DWORD bV4SizeImage
Definition: wingdi.h:1498
#define WIDTH_BYTES_ALIGN32(cx, bpp)
Definition: bitmap.c:9
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiCreateDIBitmapInternal(_In_ HDC hdc, _In_ INT cx, _In_ INT cy, _In_ DWORD fInit, _In_reads_bytes_opt_(cjMaxBits) LPBYTE pjInit, _In_reads_bytes_opt_(cjMaxInitInfo) LPBITMAPINFO pbmi, _In_ DWORD iUsage, _In_ UINT cjMaxInitInfo, _In_ UINT cjMaxBits, _In_ FLONG f, _In_ HANDLE hcmXform)
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1476
__kernel_entry 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_reads_bytes_opt_(cjMaxBits) LPBYTE pjInit, _In_ LPBITMAPINFO pbmi, _In_ DWORD dwUsage, _In_ DWORD dwRop4, _In_ UINT cjMaxInfo, _In_ UINT cjMaxBits, _In_opt_ HANDLE hcmXform)
HBITMAP WINAPI ClearBitmapAttributes(HBITMAP hbm, DWORD dwFlags)
Definition: bitmap.c:938
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiCreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
#define DIB_PAL_COLORS
Definition: wingdi.h:366
INT WINAPI GetDIBits(HDC hDC, HBITMAP hbmp, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uUsage)
Definition: bitmap.c:356
#define TRUE
Definition: types.h:120
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO pbmi
Definition: ntgdi.h:2780
_Must_inspect_result_ _In_ USAGE _In_ USHORT _In_ USAGE Usage
Definition: hidpi.h:382
HBITMAP WINAPI CreateBitmap(INT Width, INT Height, UINT Planes, UINT BitsPixel, CONST VOID *pUnsafeBits)
Definition: bitmap.c:254
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
struct _BITMAPCOREINFO * PBITMAPCOREINFO
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define DC_DIBSECTION
Definition: ntgdihdl.h:159
INT WINAPI SetDIBits(HDC hDC, HBITMAP hBitmap, UINT uStartScan, UINT cScanLines, CONST VOID *lpvBits, CONST BITMAPINFO *lpbmi, UINT fuColorUse)
Definition: bitmap.c:564
#define BI_JPEG
Definition: wingdi.h:38
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
GLuint buffer
Definition: glext.h:5915
LONG bV4Height
Definition: wingdi.h:1494
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
HBITMAP WINAPI SetBitmapAttributes(HBITMAP hbm, DWORD dwFlags)
Definition: bitmap.c:924
UINT FASTCALL DIB_BitmapMaxBitsSize(PBITMAPINFO Info, UINT ScanLines)
Definition: bitmap.c:61
int WINAPI StretchDIBits(HDC hdc, int XDest, int YDest, int nDestWidth, int nDestHeight, int XSrc, int YSrc, int nSrcWidth, int nSrcHeight, CONST VOID *lpBits, CONST BITMAPINFO *lpBitsInfo, UINT iUsage, DWORD dwRop)
Definition: bitmap.c:789
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define FASTCALL
Definition: nt_native.h:50
int32_t INT
Definition: typedefs.h:58
#define BI_BITFIELDS
Definition: mmreg.h:507
#define HANDLE_METADC(_RetType, _Func, dwError, hdc,...)
Definition: gdi32p.h:589
ULONG Flags
Definition: ntgdihdl.h:287
_SEH2_TRY
Definition: create.c:4226
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2032
int WINAPI StartPage(_In_ HDC)
_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
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO *info, WORD coloruse, BOOL max)
Definition: bitmap.c:19
BITMAPCOREHEADER bmciHeader
Definition: wingdi.h:1453
#define LDC_KILL_DOCUMENT
Definition: ntgdihdl.h:180
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiCreateDIBSection(_In_ HDC hdc, _In_opt_ HANDLE hSectionApp, _In_ DWORD dwOffset, _In_reads_bytes_opt_(cjHeader) LPBITMAPINFO pbmi, _In_ DWORD iUsage, _In_ UINT cjHeader, _In_ FLONG fl, _In_ ULONG_PTR dwColorSpace, _Outptr_ PVOID *ppvBits)
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
Definition: Header.h:8
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
DWORD biCompression
Definition: amvideo.idl:35
static int __cdecl compr(const void *a, const void *b)
Definition: bidi.c:641
HPALETTE WINAPI SelectPalette(_In_ HDC, _In_ HPALETTE, _In_ BOOL)
WORD bV4BitCount
Definition: wingdi.h:1496
__kernel_entry W32KAPI HDC APIENTRY NtGdiGetDCforBitmap(_In_ HBITMAP hsurf)
#define GDI_HANDLE_IS_STOCKOBJ(h)
Definition: gdi.h:37
HBITMAP WINAPI CreateCompatibleBitmap(HDC hDC, INT Width, INT Height)
Definition: bitmap.c:309
struct tagRGBTRIPLE RGBTRIPLE
#define DEFAULT_BITMAP
Definition: ntgdityp.h:195
UINT WINAPI GetDIBColorTable(HDC hDC, UINT iStartIndex, UINT cEntries, RGBQUAD *pColors)
Definition: palette.c:123
DWORD bV4V4Compression
Definition: wingdi.h:1497
void * PVOID
Definition: retypes.h:9
WORD bV4Planes
Definition: wingdi.h:1495
static const WCHAR dwHeight[]
Definition: provider.c:63
__kernel_entry W32KAPI HANDLE APIENTRY NtGdiGetDCObject(_In_ HDC hdc, _In_ INT itype)
LONG bV4Width
Definition: wingdi.h:1493
#define GDI_HANDLE_GET_TYPE(h)
Definition: gdi.h:31
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
HBITMAP hbmp
WORD * PWORD
Definition: pedump.c:67
#define LDC_STARTPAGE
Definition: ntgdihdl.h:175
Definition: uimain.c:88
VOID GdiSAPCallback(PLDC pldc)
Definition: misc.c:819
PLDC FASTCALL GdiGetLDC(HDC hDC)
Definition: misc.c:785
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:595
ULONG RGBQUAD
Definition: precomp.h:50
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
static void Exit(void)
Definition: sock.c:1331
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiClearBitmapAttributes(_In_ HBITMAP hbm, _In_ DWORD dwFlags)
#define WINAPI
Definition: msvc.h:6
HBITMAP WINAPI CreateDIBitmap(HDC hDC, const BITMAPINFOHEADER *Header, DWORD Init, LPCVOID Bits, const BITMAPINFO *Data, UINT ColorUse)
Definition: bitmap.c:400
struct tagBITMAPCOREHEADER BITMAPCOREHEADER
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SC_BB_STOCKOBJ
Definition: ntgdihdl.h:221
DWORD biSizeImage
Definition: amvideo.idl:36
#define SetLastError(x)
Definition: compat.h:611
#define OBJ_PAL
Definition: objidl.idl:1413
HBITMAP WINAPI CreateBitmapIndirect(const BITMAP *pbm)
Definition: bitmap.c:277
Definition: ntgdihdl.h:284
__kernel_entry W32KAPI INT APIENTRY NtGdiSetDIBitsToDeviceInternal(_In_ HDC hdcDest, _In_ INT xDst, _In_ INT yDst, _In_ DWORD cx, _In_ DWORD cy, _In_ INT xSrc, _In_ INT ySrc, _In_ DWORD iStartScan, _In_ DWORD cNumScan, _In_reads_bytes_(cjMaxBits) LPBYTE pInitBits, _In_reads_bytes_(cjMaxInfo) LPBITMAPINFO pbmi, _In_ DWORD iUsage, _In_ UINT cjMaxBits, _In_ UINT cjMaxInfo, _In_ BOOL bTransformCoordinates, _In_opt_ HANDLE hcmXform)
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiSetBitmapAttributes(_In_ HBITMAP hbm, _In_ DWORD dwFlags)
#define GDI_OBJECT_TYPE_DC
Definition: gdi.h:46
HDC hdc
Definition: main.c:9
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define GDI_OBJECT_TYPE_BITMAP
Definition: gdi.h:48
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
#define LDC_SAPCALLBACK
Definition: ntgdihdl.h:172
static HDC hDC
Definition: 3dtext.c:33
VOID WINAPI GdiSetLastError(DWORD dwErrCode)
Definition: misc.c:873
_SEH2_END
Definition: create.c:4400
int WINAPI GdiGetBitmapBitsSize(BITMAPINFO *lpbmi)
Definition: bitmap.c:163
PVOID GdiGetHandleUserData(_In_ HGDIOBJ hobj)
Definition: gditools.c:68
BOOL WINAPI DeleteDC(_In_ HDC)
#define BI_PNG
Definition: wingdi.h:39
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:199
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
Definition: bl.h:1331
struct tagBITMAPCOREHEADER * PBITMAPCOREHEADER
static HDC
Definition: bitmap.c:44
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO _In_ UINT iUsage
Definition: ntgdi.h:2780
BITMAP dsBm
Definition: wingdi.h:1669
unsigned int UINT
Definition: ndis.h:50
int WINAPI SaveDC(_In_ HDC)
#define NULL
Definition: types.h:112
#define BI_RLE4
Definition: precomp.h:48
#define DPRINT1
Definition: precomp.h:8
CONST void * LPCVOID
Definition: windef.h:191
#define CBM_CREATDIB
INT WINAPI SetDIBitsToDevice(HDC hdc, int XDest, int YDest, DWORD Width, DWORD Height, int XSrc, int YSrc, UINT StartScan, UINT ScanLines, CONST VOID *Bits, CONST BITMAPINFO *lpbmi, UINT ColorUse)
Definition: bitmap.c:648
INT WINAPI DIB_GetBitmapInfo(const BITMAPINFOHEADER *header, PLONG width, PLONG height, PWORD planes, PWORD bpp, PLONG compr, PLONG size)
Definition: bitmap.c:99
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
DWORD bpp
Definition: surface.c:185
static HBITMAP bitmap
Definition: clipboard.c:1344
LPBITMAPINFO WINAPI ConvertBitmapInfo(CONST BITMAPINFO *BitmapInfo, UINT ColorSpec, UINT *BitmapInfoSize, BOOL FollowedByData)
Definition: utils.c:178
static HBITMAP
Definition: button.c:44
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define DPRINT
Definition: sndvol32.h:71
#define DIB_RGB_COLORS
Definition: wingdi.h:367
#define BI_RLE8
Definition: wingdi.h:35
signed int * PLONG
Definition: retypes.h:5
BOOL WINAPI RestoreDC(_In_ HDC, _In_ int)
_In_ const BITMAPINFO _In_ UINT _In_opt_ HANDLE hSection
Definition: wingdi.h:3239
#define BI_RGB
Definition: precomp.h:47
static HBITMAP hBitmap
Definition: timezone.c:26
#define CONST
Definition: pedump.c:81
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:428
static const WCHAR dwWidth[]
Definition: provider.c:62
BOOL WINAPI GdiValidateHandle(HGDIOBJ)
Definition: misc.c:712
static const BYTE masks[8]
Definition: dib.c:2760