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