ReactOS 0.4.17-dev-1268-g5608ce5
bitmap.c File Reference
#include <precomp.h>
#include <pseh/pseh2.h>
#include <debug.h>
Include dependency graph for bitmap.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define WIDTH_BYTES_ALIGN32(cx, bpp)   ((((cx) * (bpp) + 31) & ~31) >> 3)
 
#define MaxScanLines   6000
 
#define MaxHeight   2000
 
#define MaxSourceHeight   2000
 
#define IS_ALIGNED(Pointer, Alignment)    (((ULONG_PTR)(void *)(Pointer)) % (Alignment) == 0)
 

Functions

ULONG FASTCALL BitmapFormat (ULONG cBits, ULONG iCompression)
 
INT FASTCALL DIB_BitmapInfoSize (const BITMAPINFO *info, WORD coloruse, BOOL max)
 
UINT FASTCALL DIB_BitmapMaxBitsSize (PBITMAPINFO Info, UINT ScanLines)
 
INT WINAPI DIB_GetBitmapInfo (const BITMAPINFOHEADER *header, PLONG width, PLONG height, PWORD planes, PWORD bpp, PLONG compr, PLONG size)
 
int WINAPI GdiGetBitmapBitsSize (BITMAPINFO *lpbmi)
 
HBITMAP WINAPI CreateDIBSection (HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
 
HBITMAP WINAPI CreateBitmap (INT Width, INT Height, UINT Planes, UINT BitsPixel, CONST VOID *pUnsafeBits)
 
HBITMAP WINAPI CreateBitmapIndirect (const BITMAP *pbm)
 
HBITMAP WINAPI CreateDiscardableBitmap (HDC hDC, INT Width, INT Height)
 
HBITMAP WINAPI CreateCompatibleBitmap (HDC hDC, INT Width, INT Height)
 
INT WINAPI GetDIBits (HDC hDC, HBITMAP hbmp, UINT uStartScan, UINT cScanLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT uUsage)
 
HBITMAP WINAPI CreateDIBitmap (HDC hDC, const BITMAPINFOHEADER *Header, DWORD Init, LPCVOID Bits, const BITMAPINFO *Data, UINT ColorUse)
 
INT WINAPI SetDIBits (HDC hDC, HBITMAP hBitmap, UINT uStartScan, UINT cScanLines, CONST VOID *lpvBits, CONST BITMAPINFO *lpbmi, UINT fuColorUse)
 
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)
 
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)
 
DWORD WINAPI GetBitmapAttributes (HBITMAP hbm)
 
HBITMAP WINAPI SetBitmapAttributes (HBITMAP hbm, DWORD dwFlags)
 
HBITMAP WINAPI ClearBitmapAttributes (HBITMAP hbm, DWORD dwFlags)
 

Variables

UCHAR gajBitsPerFormat [11]
 

Macro Definition Documentation

◆ IS_ALIGNED

#define IS_ALIGNED (   Pointer,
  Alignment 
)     (((ULONG_PTR)(void *)(Pointer)) % (Alignment) == 0)

◆ MaxHeight

#define MaxHeight   2000

◆ MaxScanLines

#define MaxScanLines   6000

◆ MaxSourceHeight

#define MaxSourceHeight   2000

◆ NDEBUG

#define NDEBUG

Definition at line 5 of file bitmap.c.

◆ WIDTH_BYTES_ALIGN32

#define WIDTH_BYTES_ALIGN32 (   cx,
  bpp 
)    ((((cx) * (bpp) + 31) & ~31) >> 3)

Definition at line 55 of file bitmap.c.

Function Documentation

◆ BitmapFormat()

ULONG FASTCALL BitmapFormat ( ULONG  cBits,
ULONG  iCompression 
)

Definition at line 11 of file bitmap.c.

12{
13 switch (iCompression)
14 {
15 case BI_RGB:
16 /* Fall through */
17 case BI_BITFIELDS:
18 if (cBits <= 1) return BMF_1BPP;
19 if (cBits <= 4) return BMF_4BPP;
20 if (cBits <= 8) return BMF_8BPP;
21 if (cBits <= 16) return BMF_16BPP;
22 if (cBits <= 24) return BMF_24BPP;
23 if (cBits <= 32) return BMF_32BPP;
24 return 0;
25
26 case BI_RLE4:
27 return BMF_4RLE;
28
29 case BI_RLE8:
30 return BMF_8RLE;
31
32 default:
33 return 0;
34 }
35}
#define BI_RLE4
Definition: precomp.h:47
#define BI_BITFIELDS
Definition: mmreg.h:507
#define BI_RGB
Definition: uefivid.c:46
#define BMF_16BPP
Definition: winddi.h:358
#define BMF_8BPP
Definition: winddi.h:357
#define BMF_1BPP
Definition: winddi.h:355
#define BMF_24BPP
Definition: winddi.h:359
#define BMF_32BPP
Definition: winddi.h:360
#define BMF_8RLE
Definition: winddi.h:362
#define BMF_4RLE
Definition: winddi.h:361
#define BMF_4BPP
Definition: winddi.h:356
#define BI_RLE8
Definition: wingdi.h:35

Referenced by SetDIBitsToDevice().

◆ ClearBitmapAttributes()

HBITMAP WINAPI ClearBitmapAttributes ( HBITMAP  hbm,
DWORD  dwFlags 
)

Definition at line 1234 of file bitmap.c.

1235{
1236 if ( dwFlags & ~SC_BB_STOCKOBJ )
1237 {
1238 return NULL;
1239 }
1241}
#define NULL
Definition: types.h:112
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define SC_BB_STOCKOBJ
Definition: ntgdihdl.h:199
_In_ HBITMAP hbm
Definition: ntgdi.h:2804
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiClearBitmapAttributes(_In_ HBITMAP hbm, _In_ DWORD dwFlags)

Referenced by Test_BitmapAttributes().

◆ CreateBitmap()

HBITMAP WINAPI CreateBitmap ( INT  Width,
INT  Height,
UINT  Planes,
UINT  BitsPixel,
CONST VOID *  pUnsafeBits 
)

Definition at line 310 of file bitmap.c.

316{
317 if (Width && Height)
318 {
319 return NtGdiCreateBitmap(Width, Height, Planes, BitsPixel, (LPBYTE) pUnsafeBits);
320 }
321 else
322 {
323 /* Return 1x1 bitmap */
325 }
326}
_Check_return_ _In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ PDXGKARG_SYSTEM_DISPLAY_ENABLE_FLAGS _Out_ UINT _Out_ UINT * Height
Definition: dispmprt.h:1445
_Check_return_ _In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ PDXGKARG_SYSTEM_DISPLAY_ENABLE_FLAGS _Out_ UINT * Width
Definition: dispmprt.h:1444
#define DEFAULT_BITMAP
Definition: ntgdityp.h:195
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiCreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBPP, _In_opt_ LPBYTE pjInit)
unsigned char * LPBYTE
Definition: typedefs.h:53
HGDIOBJ WINAPI GetStockObject(_In_ int)

◆ CreateBitmapIndirect()

HBITMAP WINAPI CreateBitmapIndirect ( const BITMAP *  pbm)

Definition at line 333 of file bitmap.c.

335{
337
338 /* Note windows xp/2003 does not check if pbm is NULL or not */
339 if ((pbm->bmWidthBytes != 0) && (!(pbm->bmWidthBytes & 1)))
340
341 {
342 bitmap = CreateBitmap(pbm->bmWidth, pbm->bmHeight, pbm->bmPlanes, pbm->bmBitsPixel,
343 pbm->bmBits);
344 }
345 else
346 {
348 }
349
350 return bitmap;
351}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
static HBITMAP
Definition: button.c:44
Definition: uimain.c:89
LONG bmHeight
Definition: wingdi.h:1869
LONG bmWidth
Definition: wingdi.h:1868
LONG bmWidthBytes
Definition: wingdi.h:1870
LPVOID bmBits
Definition: wingdi.h:1873
WORD bmPlanes
Definition: wingdi.h:1871
WORD bmBitsPixel
Definition: wingdi.h:1872
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)

◆ CreateCompatibleBitmap()

HBITMAP WINAPI CreateCompatibleBitmap ( HDC  hDC,
INT  Width,
INT  Height 
)

Definition at line 365 of file bitmap.c.

369{
370 PDC_ATTR pDc_Attr;
371
373 return NULL;
374
375 if (!Width || !Height)
377
378 if (!(pDc_Attr->ulDirty_ & DC_DIBSECTION))
379 {
381 }
382 else
383 {
384 HBITMAP hBmp = NULL;
385 struct
386 {
388 BITMAPINFOHEADER bmih;
389 RGBQUAD rgbquad[256];
390 } buffer;
391 DIBSECTION* pDIBs = (DIBSECTION*) &buffer;
392 BITMAPINFO* pbmi = (BITMAPINFO*) &buffer.bmih;
393
395
396 if (GetObjectA(hBmp, sizeof(DIBSECTION), pDIBs) != sizeof(DIBSECTION))
397 return NULL;
398
399 if (pDIBs->dsBm.bmBitsPixel <= 8)
400 GetDIBColorTable(hDC, 0, 256, buffer.rgbquad);
401
402 pDIBs->dsBmih.biWidth = Width;
403 pDIBs->dsBmih.biHeight = Height;
404
406 }
407 return NULL;
408}
static HDC hDC
Definition: 3dtext.c:33
ULONG RGBQUAD
Definition: precomp.h:49
#define GDI_OBJECT_TYPE_DC
Definition: gdi.h:46
#define GDI_OBJECT_TYPE_BITMAP
Definition: gdi.h:48
PVOID GdiGetHandleUserData(_In_ HGDIOBJ hobj)
Definition: gditools.c:94
GLuint buffer
Definition: glext.h:5915
#define DC_DIBSECTION
Definition: ntgdihdl.h:137
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiCreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO pbmi
Definition: ntgdi.h:2808
__kernel_entry W32KAPI HANDLE APIENTRY NtGdiGetDCObject(_In_ HDC hdc, _In_ INT itype)
BITMAP dsBm
Definition: wingdi.h:2115
BITMAPINFOHEADER dsBmih
Definition: wingdi.h:2116
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:253
UINT WINAPI GetDIBColorTable(HDC hDC, UINT iStartIndex, UINT cEntries, RGBQUAD *pColors)
Definition: palette.c:123
#define DIB_RGB_COLORS
Definition: wingdi.h:367
int WINAPI GetObjectA(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)

◆ CreateDIBitmap()

HBITMAP WINAPI CreateDIBitmap ( HDC  hDC,
const BITMAPINFOHEADER *  Header,
DWORD  Init,
LPCVOID  Bits,
const BITMAPINFO *  Data,
UINT  ColorUse 
)

Definition at line 467 of file bitmap.c.

474{
475 LONG Width, Height, Compression, DibSize;
476 WORD Planes, BitsPerPixel;
477// PDC_ATTR pDc_Attr;
478 UINT cjBmpScanSize = 0;
480 PBITMAPINFO pbmiConverted;
481 UINT cjInfoSize;
482
483 /* Convert the BITMAPINFO if it is a COREINFO */
484 pbmiConverted = ConvertBitmapInfo(Data, ColorUse, &cjInfoSize, FALSE);
485
486 /* Check for CBM_CREATDIB */
487 if (Init & CBM_CREATDIB)
488 {
489 if (cjInfoSize == 0)
490 {
491 goto Exit;
492 }
493 else if (Init & CBM_INIT)
494 {
495 if (Bits == NULL)
496 {
497 goto Exit;
498 }
499 }
500 else
501 {
502 Bits = NULL;
503 }
504
505 /* CBM_CREATDIB needs Data. */
506 if (pbmiConverted == NULL)
507 {
508 DPRINT1("CBM_CREATDIB needs a BITMAPINFO!\n");
509 goto Exit;
510 }
511
512 /* It only works with PAL or RGB */
513 if (ColorUse > DIB_PAL_COLORS)
514 {
515 DPRINT1("Invalid ColorUse: %lu\n", ColorUse);
517 goto Exit;
518 }
519
520 /* Use the header from the data */
521 Header = &Data->bmiHeader;
522 }
523 else
524 {
525 if (Init & CBM_INIT)
526 {
527 if (Bits != NULL)
528 {
529 if (cjInfoSize == 0)
530 {
531 goto Exit;
532 }
533 }
534 else
535 {
536 Init &= ~CBM_INIT;
537 }
538 }
539 }
540
541 /* Header is required */
542 if (!Header)
543 {
544 DPRINT1("Header is NULL\n");
546 goto Exit;
547 }
548
549 /* Get the bitmap format and dimensions */
550 if (DIB_GetBitmapInfo(Header, &Width, &Height, &Planes, &BitsPerPixel, &Compression, &DibSize) == -1)
551 {
552 DPRINT1("DIB_GetBitmapInfo failed!\n");
554 goto Exit;
555 }
556
557 /* Check if the Compr is incompatible */
558 if ((Compression == BI_JPEG) || (Compression == BI_PNG))
559 {
560 DPRINT1("Invalid compression: %lu!\n", Compression);
561 goto Exit;
562 }
563
564 /* Only DIB_RGB_COLORS (0), DIB_PAL_COLORS (1) and 2 are valid. */
565 if (ColorUse > DIB_PAL_COLORS + 1)
566 {
567 DPRINT1("Invalid compression: %lu!\n", Compression);
569 goto Exit;
570 }
571
572 /* If some Bits are given, only DIB_PAL_COLORS and DIB_RGB_COLORS are valid */
573 if (Bits && (ColorUse > DIB_PAL_COLORS))
574 {
575 DPRINT1("Invalid ColorUse: %lu\n", ColorUse);
577 goto Exit;
578 }
579
580 /* Negative width is not allowed */
581 if (Width < 0)
582 {
583 DPRINT1("Negative width: %li\n", Width);
584 goto Exit;
585 }
586
587 /* Top-down DIBs have a negative height. */
588 Height = abs(Height);
589
590// For Icm support.
591// GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
592
593 cjBmpScanSize = GdiGetBitmapBitsSize(pbmiConverted);
594
595 DPRINT("pBMI %p, Size bpp %u, dibsize %d, Conv %u, BSS %u\n",
596 Data, BitsPerPixel, DibSize, cjInfoSize, cjBmpScanSize);
597
598 if (!Width || !Height)
599 {
601 }
602 else
603 {
605 Width,
606 Height,
607 Init,
608 (LPBYTE)Bits,
609 (LPBITMAPINFO)pbmiConverted,
610 ColorUse,
611 cjInfoSize,
612 cjBmpScanSize,
613 0, 0);
614 }
615
616Exit:
617 /* Cleanup converted BITMAPINFO */
618 if ((pbmiConverted != NULL) && (pbmiConverted != Data))
619 {
620 RtlFreeHeap(RtlGetProcessHeap(), 0, pbmiConverted);
621 }
622
623 return hBitmap;
624}
#define CBM_CREATDIB
#define DPRINT1
Definition: precomp.h:8
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
Definition: Header.h:9
#define FALSE
Definition: types.h:117
static HBITMAP hBitmap
Definition: timezone.c:26
#define abs(i)
Definition: fconv.c:206
unsigned short WORD
Definition: ntddk_ex.h:93
LPBITMAPINFO WINAPI ConvertBitmapInfo(CONST BITMAPINFO *BitmapInfo, UINT ColorSpec, UINT *BitmapInfoSize, BOOL FollowedByData)
Definition: utils.c:178
VOID WINAPI GdiSetLastError(DWORD dwErrCode)
Definition: misc.c:873
unsigned int UINT
Definition: sysinfo.c:13
long LONG
Definition: pedump.c:60
__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)
#define DPRINT
Definition: sndvol32.h:73
static void Exit(void)
Definition: sock.c:1330
int WINAPI GdiGetBitmapBitsSize(BITMAPINFO *lpbmi)
Definition: bitmap.c:217
INT WINAPI DIB_GetBitmapInfo(const BITMAPINFOHEADER *header, PLONG width, PLONG height, PWORD planes, PWORD bpp, PLONG compr, PLONG size)
Definition: bitmap.c:153
#define DIB_PAL_COLORS
Definition: wingdi.h:366
#define BI_JPEG
Definition: wingdi.h:38
#define CBM_INIT
Definition: wingdi.h:365
#define BI_PNG
Definition: wingdi.h:39

◆ CreateDIBSection()

HBITMAP WINAPI CreateDIBSection ( HDC  hDC,
CONST BITMAPINFO *  BitmapInfo,
UINT  Usage,
VOID **  Bits,
HANDLE  hSection,
DWORD  dwOffset 
)

Definition at line 253 of file bitmap.c.

260{
261 PBITMAPINFO pConvertedInfo;
262 UINT ConvertedInfoSize;
264 PVOID bmBits = NULL;
265
266 pConvertedInfo = ConvertBitmapInfo(BitmapInfo,
267 Usage,
268 &ConvertedInfoSize,
269 FALSE);
270 if (pConvertedInfo)
271 {
272 // Verify header due to converted may == info.
273 if (pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
274 {
275 if (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
276 pConvertedInfo->bmiHeader.biCompression == BI_PNG)
277 {
279 return NULL;
280 }
281 }
283 hSection,
284 dwOffset,
285 pConvertedInfo,
286 Usage,
287 ConvertedInfoSize,
288 0, // fl
289 0, // dwColorSpace
290 &bmBits);
291 if (!hBitmap)
292 bmBits = NULL;
293
294 if (BitmapInfo != pConvertedInfo)
295 RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
296 }
297
298 if (Bits)
299 *Bits = bmBits;
300
301 return hBitmap;
302}
_Must_inspect_result_ _In_ USAGE _In_ USHORT _In_ USAGE Usage
Definition: hidpi.h:384
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2053
__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)
ULONG biCompression
Definition: precomp.h:37
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1922
_In_ const BITMAPINFO _In_ UINT _In_opt_ HANDLE hSection
Definition: wingdi.h:3685

Referenced by alpha_blend_hdc_pixels(), alpha_blend_image(), ARGB2BMP(), BeginBufferedPaint(), BITMAP_CopyImage(), BITMAP_LoadImageW(), BitmapFromClipboardDIB(), ConvertBitmapTo32Bpp(), ConvertToBlackAndWhite(), CreatDibBitmap(), Create24BppBitmap(), Create32BitHBITMAP(), create_bitmap(), create_dib(), create_dib_section(), create_hatch_bitmap(), create_render_dc(), create_target_dibsection(), create_test_bitmap(), create_test_icon(), CreateCompatibleBitmap(), CreateDIBWithProperties(), CreateFrameBufferBitmap(), ATL::CImage::CreateInternal(), CShellLink::CreateShortcutIcon(), CreateStarBitmap(), do_test_copy_image(), draw_graphics(), DrawDibBegin(), DrawShadowText(), GdipCreateBitmapFromGdiDib(), GdipCreateHBITMAPFromBitmap(), GdipDrawImagePointsRect(), GdipGetDC(), get_bitmap_info(), ImageList_CreateImage(), InitBitmap(), InitLogo(), InitPerBitDepth(), IntCreate32BppBitmap(), mi_paint_rect(), mstsc_ProtocolIOThread(), PaintCells(), PlayEnhMetaFileRecord(), serializeBMP(), CUIFBitmapDC::SetDIB(), START_TEST(), test_32bit_ddb(), test_alpha_hdc(), test_arcs(), test_BitBlt(), test_bitmap_colors(), test_bitmap_font_glyph_index(), test_bitmap_rendering(), test_bitmapinfoheadersize(), test_boundsrect(), test_clipping(), test_color_table(), test_CreateIcon(), test_data_handles(), test_device_caps(), test_dib_formats(), test_DIB_PAL_COLORS(), Test_Dibsection(), Test_DIBSectionEntry(), test_dibsections(), test_display_dc(), test_DrawDib_sizeimage(), test_DrawIcon(), test_DrawIconEx(), test_DrawState(), test_emf_AlphaBlend(), test_emf_BitBlt(), test_emf_blit(), test_emf_mask_blit(), test_gdi_interop_hdc(), test_GdiAlphaBlend(), test_GdiGradientFill(), test_GdipCreateBitmapFromHBITMAP(), test_GetCursorFrameInfo(), Test_GetDIBColorTable(), test_GetDIBits_BI_BITFIELDS(), test_GetDIBits_scanlines(), test_GetDIBits_selected_DIB(), test_GetDIBits_top_down(), test_hdc_caching(), test_Image_StretchMode(), test_ImageList_DrawIndirect(), test_load_save_dib(), Test_MaskBlt_16bpp(), Test_MaskBlt_1bpp(), Test_MaskBlt_32bpp(), Test_MaskBlt_Brush(), test_mf_blit(), test_mono_dibsection(), Test_NtGdiBitBlt_generic(), Test_NtGdiDoPalette_SetDIBColorTable(), test_palette_brush(), test_path_state(), test_pattern_brush(), Test_SelectDIBSection(), Test_SetDIBits(), test_SetDIBits(), test_SetDIBits_RLE4(), test_SetDIBits_RLE8(), test_SetDIBitsToDevice(), test_SetDIBitsToDevice_RLE8(), Test_SetPixel_PAL(), test_simple_graphics(), Test_SrcMono(), test_StretchBlt(), test_StretchBlt_TopDownOptions(), test_StretchDIBits(), test_WICCreateBitmapFromSectionEx(), UXTHEME_DrawThemePartToDib(), and WinGCreateBitmap().

◆ CreateDiscardableBitmap()

HBITMAP WINAPI CreateDiscardableBitmap ( HDC  hDC,
INT  Width,
INT  Height 
)

Definition at line 355 of file bitmap.c.

359{
361}
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)

◆ DIB_BitmapInfoSize()

INT FASTCALL DIB_BitmapInfoSize ( const BITMAPINFO *  info,
WORD  coloruse,
BOOL  max 
)

Definition at line 65 of file bitmap.c.

69{
70 unsigned int colors, size, masks = 0;
71
72 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
73 {
74 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *) info;
75 size = sizeof(BITMAPCOREHEADER);
76 if (core->bcBitCount == 0)
77 {
78 return size;
79 }
80 if (core->bcBitCount <= 8)
81 {
82 colors = 1 << core->bcBitCount;
83 if (coloruse == DIB_RGB_COLORS)
84 size += colors * sizeof(RGBTRIPLE);
85 else
86 size += colors * sizeof(WORD);
87 }
88 return size;
89 }
90 else /* assume BITMAPINFOHEADER */
91 {
92 if (info->bmiHeader.biBitCount == 0)
93 {
94 return info->bmiHeader.biSize;
95 }
96 colors = max ? (1 << info->bmiHeader.biBitCount) : info->bmiHeader.biClrUsed;
97 if (colors > 256)
98 colors = 256;
99 if (!colors && (info->bmiHeader.biBitCount <= 8))
100 colors = 1 << info->bmiHeader.biBitCount;
101 if (info->bmiHeader.biCompression == BI_BITFIELDS)
102 masks = 3;
103 size = max(info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD));
104 return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
105 }
106}
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
if(dx< 0)
Definition: linetemp.h:194
static const BYTE masks[8]
Definition: dib.c:3008
#define max(a, b)
Definition: svc.c:63
struct tagRGBTRIPLE RGBTRIPLE
struct tagBITMAPCOREHEADER BITMAPCOREHEADER
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList

Referenced by GetDIBits(), IntSynthesizeBitmap(), and IntSynthesizeDib().

◆ DIB_BitmapMaxBitsSize()

UINT FASTCALL DIB_BitmapMaxBitsSize ( PBITMAPINFO  Info,
UINT  ScanLines 
)

Definition at line 115 of file bitmap.c.

118{
119 UINT Ret;
120
121 if (!Info)
122 return 0;
123
124 if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
125 {
127 Ret = WIDTH_BYTES_ALIGN32(Core->bcWidth * Core->bcPlanes,
128 Core->bcBitCount) * ScanLines;
129 }
130 else /* assume BITMAPINFOHEADER */
131 {
132 if ((Info->bmiHeader.biCompression == BI_RGB) || (Info->bmiHeader.biCompression == BI_BITFIELDS))
133 {
135 Info->bmiHeader.biWidth * Info->bmiHeader.biPlanes,
136 Info->bmiHeader.biBitCount) * ScanLines;
137 }
138 else
139 {
140 Ret = Info->bmiHeader.biSizeImage;
141 }
142 }
143 return Ret;
144}
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
#define WIDTH_BYTES_ALIGN32(cx, bpp)
Definition: bitmap.c:55
struct tagBITMAPCOREHEADER * PBITMAPCOREHEADER

Referenced by GetDIBits(), and SetDIBitsToDevice().

◆ DIB_GetBitmapInfo()

INT WINAPI DIB_GetBitmapInfo ( const BITMAPINFOHEADER *  header,
PLONG  width,
PLONG  height,
PWORD  planes,
PWORD  bpp,
PLONG  compr,
PLONG  size 
)

Definition at line 153 of file bitmap.c.

161{
162 if (header->biSize == sizeof(BITMAPCOREHEADER))
163 {
165 *width = core->bcWidth;
166 *height = core->bcHeight;
167 *planes = core->bcPlanes;
168 *bpp = core->bcBitCount;
169 *compr = 0;
170 *size = 0;
171 return 0;
172 }
173
174 if (header->biSize == sizeof(BITMAPINFOHEADER))
175 {
176 *width = header->biWidth;
177 *height = header->biHeight;
178 *planes = header->biPlanes;
179 *bpp = header->biBitCount;
180 *compr = header->biCompression;
181 *size = header->biSizeImage;
182 return 1;
183 }
184
185 if (header->biSize == sizeof(BITMAPV4HEADER))
186 {
188 *width = v4hdr->bV4Width;
189 *height = v4hdr->bV4Height;
190 *planes = v4hdr->bV4Planes;
191 *bpp = v4hdr->bV4BitCount;
192 *compr = v4hdr->bV4V4Compression;
193 *size = v4hdr->bV4SizeImage;
194 return 4;
195 }
196
197 if (header->biSize == sizeof(BITMAPV5HEADER))
198 {
199 BITMAPV5HEADER *v5hdr = (BITMAPV5HEADER *) header;
200 *width = v5hdr->bV5Width;
201 *height = v5hdr->bV5Height;
202 *planes = v5hdr->bV5Planes;
203 *bpp = v5hdr->bV5BitCount;
204 *compr = v5hdr->bV5Compression;
205 *size = v5hdr->bV5SizeImage;
206 return 5;
207 }
208 DPRINT("(%lu): wrong size for header\n", header->biSize);
209 return -1;
210}
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
WORD bV4Planes
Definition: wingdi.h:1941
DWORD bV4SizeImage
Definition: wingdi.h:1944
DWORD bV4V4Compression
Definition: wingdi.h:1943
LONG bV4Height
Definition: wingdi.h:1940
LONG bV4Width
Definition: wingdi.h:1939
WORD bV4BitCount
Definition: wingdi.h:1942
static int __cdecl compr(const void *a, const void *b)
Definition: bidi.c:640
ULONG bpp[]
Definition: xlate.c:19

Referenced by CreateDIBitmap().

◆ GdiGetBitmapBitsSize()

int WINAPI GdiGetBitmapBitsSize ( BITMAPINFO *  lpbmi)

Definition at line 217 of file bitmap.c.

219{
220 UINT Ret;
221
222 if (!lpbmi)
223 return 0;
224
225 if (lpbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
226 {
228 Ret =
230 Core->bcBitCount) * Core->bcHeight;
231 }
232 else /* assume BITMAPINFOHEADER */
233 {
234 if (!(lpbmi->bmiHeader.biCompression) || (lpbmi->bmiHeader.biCompression == BI_BITFIELDS))
235 {
237 lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biPlanes,
238 lpbmi->bmiHeader.biBitCount) * abs(lpbmi->bmiHeader.biHeight);
239 }
240 else
241 {
242 Ret = lpbmi->bmiHeader.biSizeImage;
243 }
244 }
245 return Ret;
246}
USHORT biBitCount
Definition: precomp.h:36

Referenced by ConvertBitmapInfo(), CreateDIBitmap(), and StretchDIBits().

◆ GetBitmapAttributes()

DWORD WINAPI GetBitmapAttributes ( HBITMAP  hbm)

Definition at line 1206 of file bitmap.c.

1207{
1209 {
1210 return SC_BB_STOCKOBJ;
1211 }
1212 return 0;
1213}
#define GDI_HANDLE_IS_STOCKOBJ(h)
Definition: gdi.h:37

Referenced by Test_BitmapAttributes().

◆ GetDIBits()

INT WINAPI GetDIBits ( HDC  hDC,
HBITMAP  hbmp,
UINT  uStartScan,
UINT  cScanLines,
LPVOID  lpvBits,
LPBITMAPINFO  lpbmi,
UINT  uUsage 
)

Definition at line 412 of file bitmap.c.

420{
422 UINT cjInfoSize;
423
424 if (!hDC || !GdiValidateHandle((HGDIOBJ) hDC) || !lpbmi)
425 {
427 return 0;
428 }
429
430 /* Caller must provide maximum size possible */
431 cjInfoSize = DIB_BitmapInfoSize(lpbmi, uUsage, TRUE);
432
433 if (lpvBits)
434 {
435 if (lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
436 {
437 if (lpbmi->bmiHeader.biCompression == BI_JPEG
438 || lpbmi->bmiHeader.biCompression == BI_PNG)
439 {
441 return 0;
442 }
443 }
444 cjMaxBits = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
445 }
446 else
447 {
448 cjMaxBits = 0;
449 }
450
452 hbmp,
453 uStartScan,
454 cScanLines,
455 lpvBits,
456 lpbmi,
457 uUsage,
458 cjMaxBits,
459 cjInfoSize);
460}
HBITMAP hbmp
#define TRUE
Definition: types.h:120
BOOL WINAPI GdiValidateHandle(HGDIOBJ)
Definition: misc.c:712
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO _In_ UINT _In_ UINT cjMaxBits
Definition: ntgdi.h:2810
UINT FASTCALL DIB_BitmapMaxBitsSize(PBITMAPINFO Info, UINT ScanLines)
Definition: bitmap.c:115
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO *info, WORD coloruse, BOOL max)
Definition: bitmap.c:65
W32KAPI INT WINAPI NtGdiGetDIBitsInternal(HDC hdc, HBITMAP hbitmap, UINT startscan, UINT lines, void *bits, BITMAPINFO *info, UINT coloruse, UINT max_bits, UINT max_info)

◆ SetBitmapAttributes()

HBITMAP WINAPI SetBitmapAttributes ( HBITMAP  hbm,
DWORD  dwFlags 
)

Definition at line 1220 of file bitmap.c.

1221{
1222 if ( dwFlags & ~SC_BB_STOCKOBJ )
1223 {
1224 return NULL;
1225 }
1227}
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiSetBitmapAttributes(_In_ HBITMAP hbm, _In_ DWORD dwFlags)

Referenced by Test_BitmapAttributes().

◆ SetDIBits()

INT WINAPI SetDIBits ( HDC  hDC,
HBITMAP  hBitmap,
UINT  uStartScan,
UINT  cScanLines,
CONST VOID *  lpvBits,
CONST BITMAPINFO *  lpbmi,
UINT  fuColorUse 
)

Definition at line 631 of file bitmap.c.

639{
640 HDC hDCc, SavehDC, nhDC;
641 DWORD dwWidth, dwHeight;
642 HGDIOBJ hOldBitmap;
643 HPALETTE hPal = NULL;
644 INT LinesCopied = 0;
645 BOOL newDC = FALSE;
646
647 if (fuColorUse != DIB_RGB_COLORS && fuColorUse != DIB_PAL_COLORS)
648 return 0;
649
651 return 0;
652
653 if (lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
654 {
655 if (lpbmi->bmiHeader.biCompression == BI_JPEG
656 || lpbmi->bmiHeader.biCompression == BI_PNG)
657 {
659 return 0;
660 }
661 }
662
663 if (lpbmi->bmiHeader.biCompression == BI_BITFIELDS)
664 {
665 DWORD *masks = (DWORD *)lpbmi->bmiColors;
666 if (!masks[0] || !masks[1] || !masks[2])
667 {
669 return 0;
670 }
671 }
672
673 hDCc = NtGdiGetDCforBitmap(hBitmap); // hDC can be NULL, so, get it from the bitmap.
674 SavehDC = hDCc;
675 if (!hDCc) // No DC associated with bitmap, Clone or Create one.
676 {
677 nhDC = CreateCompatibleDC(hDC);
678 if (!nhDC)
679 return 0;
680 newDC = TRUE;
681 SavehDC = nhDC;
682 }
683 else if (!SaveDC(hDCc))
684 return 0;
685
686 hOldBitmap = SelectObject(SavehDC, hBitmap);
687
688 if (hOldBitmap)
689 {
690 if (hDC)
691 hPal = SelectPalette(SavehDC, (HPALETTE) GetCurrentObject(hDC, OBJ_PAL), FALSE);
692
693 if (lpbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
694 {
695 PBITMAPCOREINFO pbci = (PBITMAPCOREINFO) lpbmi;
696 dwWidth = pbci->bmciHeader.bcWidth;
697 dwHeight = pbci->bmciHeader.bcHeight;
698 }
699 else
700 {
701 dwWidth = lpbmi->bmiHeader.biWidth;
702 dwHeight = abs(lpbmi->bmiHeader.biHeight);
703 }
704
705 LinesCopied = SetDIBitsToDevice(SavehDC, 0, 0, dwWidth, dwHeight, 0, 0, uStartScan,
706 cScanLines, (void *) lpvBits, (LPBITMAPINFO) lpbmi, fuColorUse);
707
708 if (hDC)
709 SelectPalette(SavehDC, hPal, FALSE);
710
711 SelectObject(SavehDC, hOldBitmap);
712 }
713
714 if (newDC)
715 DeleteDC(SavehDC);
716 else
717 RestoreDC(SavehDC, -1);
718
719 return LinesCopied;
720}
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GDI_HANDLE_GET_TYPE(h)
Definition: gdi.h:31
static HDC
Definition: bitmap.c:43
#define OBJ_PAL
Definition: objidl.idl:1018
__kernel_entry W32KAPI HDC APIENTRY NtGdiGetDCforBitmap(_In_ HBITMAP hsurf)
BITMAPCOREHEADER bmciHeader
Definition: wingdi.h:1899
int32_t INT
Definition: typedefs.h:58
struct _BITMAPCOREINFO * PBITMAPCOREINFO
int WINAPI SetDIBitsToDevice(_In_ HDC, _In_ int, _In_ int, _In_ DWORD, _In_ DWORD, _In_ int, _In_ int, _In_ UINT, _In_ UINT, _In_ CONST VOID *, _In_ CONST BITMAPINFO *, _In_ UINT)
HPALETTE WINAPI SelectPalette(_In_ HDC, _In_ HPALETTE, _In_ BOOL)
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:428
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
BOOL WINAPI RestoreDC(_In_ HDC, _In_ int)
BOOL WINAPI DeleteDC(_In_ HDC)
int WINAPI SaveDC(_In_ HDC)

◆ SetDIBitsToDevice()

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 at line 728 of file bitmap.c.

741{
742 PDC_ATTR pDc_Attr;
743 PBITMAPINFO pConvertedInfo;
744 UINT ConvertedInfoSize;
745 INT LinesCopied = 0;
746 UINT cjBmpScanSize = 0;
747 BOOL Hit = FALSE;
748 PVOID pvSafeBits = (PVOID) Bits;
749 UINT bmiHeight, ScanLinesOrig = ScanLines, ImageSizeOrig;
750 BOOL top_down;
751 INT src_y = 0;
752 ULONG iFormat, cBitsPixel, cjBits, cjWidth;
753
754 // HACK: Temporay hack for Half-Life
755 #define MaxScanLines 6000
756 #define MaxHeight 2000
757 #define MaxSourceHeight 2000
758 #define IS_ALIGNED(Pointer, Alignment) \
759 (((ULONG_PTR)(void *)(Pointer)) % (Alignment) == 0)
760
761 if (!ScanLines || !lpbmi || !Bits)
762 return 0;
763
764 DPRINT("hdc %p, XDest %d, YDest, %d, Width %d, Height %d\n"
765 " XSrc %d, YSrc %d, StartScan %d, ScanLines %d, ColorUse %d\n"
766 " biHeight %d, biWidth %d\n"
767 " lpbmi %p, SizeImage %d\n"
768 " biCompression %d, biBitCount %d\n",
769 hdc, XDest, YDest, Width, Height,
770 XSrc, YSrc, StartScan, ScanLines, ColorUse,
771 lpbmi->bmiHeader.biHeight, lpbmi->bmiHeader.biWidth,
772 lpbmi, lpbmi->bmiHeader.biSizeImage,
773 lpbmi->bmiHeader.biCompression, lpbmi->bmiHeader.biBitCount);
774
775 if (lpbmi->bmiHeader.biWidth < 0)
776 return 0;
777
778 if (ColorUse && ColorUse != DIB_PAL_COLORS && ColorUse != DIB_PAL_COLORS + 1)
779 return 0;
780
781 pConvertedInfo = ConvertBitmapInfo(lpbmi, ColorUse, &ConvertedInfoSize, FALSE);
782 if (!pConvertedInfo)
783 return 0;
784
785 if (ScanLines > MaxScanLines)
786 {
787 LinesCopied = 0;
788 goto Exit;
789 }
790
791 ImageSizeOrig = pConvertedInfo->bmiHeader.biSizeImage;
792
793 bmiHeight = abs(pConvertedInfo->bmiHeader.biHeight);
794 top_down = (pConvertedInfo->bmiHeader.biHeight < 0);
795 if ((StartScan > bmiHeight) && (ScanLines > bmiHeight))
796 {
797 DPRINT("Returning ScanLines of '%d'\n", ScanLines);
798 LinesCopied = ScanLines;
799 goto Exit;
800 }
801
802 if (pConvertedInfo->bmiHeader.biHeight == 0)
803 {
804 LinesCopied = 0;
805 goto Exit;
806 }
807
808 if (!IS_ALIGNED(Bits, 2) && (ScanLines > Height))
809 {
810 LinesCopied = 0;
811 goto Exit;
812 }
813
814 /* Below code modeled after Wine's nulldrv_SetDIBitsToDevice */
815 if (StartScan <= YSrc + bmiHeight)
816 {
817 if ((pConvertedInfo->bmiHeader.biCompression == BI_RLE8) ||
818 (pConvertedInfo->bmiHeader.biCompression == BI_RLE4))
819 {
820 StartScan = 0;
821 ScanLines = bmiHeight;
822 }
823 else
824 {
825 if (StartScan >= bmiHeight)
826 {
827 LinesCopied = 0;
828 goto Exit;
829 }
830 if (!top_down && ScanLines > bmiHeight - StartScan)
831 {
832 ScanLines = bmiHeight - StartScan;
833 }
834 src_y = StartScan + ScanLines - (YSrc + Height);
835 if (!top_down)
836 {
837 /* get rid of unnecessary lines */
838 if ((src_y < 0 || src_y >= (INT)ScanLines) &&
839 pConvertedInfo->bmiHeader.biCompression != BI_BITFIELDS)
840 {
841 LinesCopied = ScanLines;
842 goto Exit;
843 }
844 if (YDest >= 0)
845 {
846 LinesCopied = ScanLines + StartScan;
847 ScanLines -= src_y;
848 }
849 else
850 {
851 LinesCopied = ScanLines - src_y;
852 }
853 }
854 else if (src_y < 0 || src_y >= (INT)ScanLines)
855 {
856 if (lpbmi->bmiHeader.biHeight < 0 &&
857 StartScan > MaxScanLines)
858 {
859 ScanLines = lpbmi->bmiHeader.biHeight - StartScan;
860 }
861 DPRINT("Returning ScanLines of '%d'\n", ScanLines);
862 LinesCopied = ScanLines;
863 goto Exit;
864 }
865 else
866 {
867 LinesCopied = ScanLines;
868 }
869 }
870 }
871
874 0,
875 hdc,
876 XDest,
877 YDest,
878 Width,
879 Height,
880 XSrc,
881 YSrc,
882 StartScan,
883 ScanLines,
884 Bits,
885 lpbmi,
886 ColorUse);
887
888 // Handle the "Special Case"!
889 {
890 PLDC pldc;
893 {
894 pldc = GdiGetLDC(hdc);
895 if (pldc)
896 {
897 if (pldc->Flags & LDC_STARTPAGE) StartPage(hdc);
898
899 if (pldc->Flags & LDC_SAPCALLBACK) GdiSAPCallback(pldc);
900
901 if (pldc->Flags & LDC_KILL_DOCUMENT)
902 {
903 LinesCopied = 0;
904 goto Exit;
905 }
906 }
907 else
908 {
910 LinesCopied = 0;
911 goto Exit;
912 }
913 }
914 }
915
916 if ((pConvertedInfo->bmiHeader.biCompression == BI_RLE8) ||
917 (pConvertedInfo->bmiHeader.biCompression == BI_RLE4))
918 {
919 /* For compressed data, we must set the whole thing */
920 StartScan = 0;
921 ScanLines = pConvertedInfo->bmiHeader.biHeight;
922 }
923
924 cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO) lpbmi, ScanLines);
925
926 pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
927 if (pvSafeBits)
928 {
930 {
931 RtlCopyMemory(pvSafeBits, Bits, cjBmpScanSize);
932 }
934 {
935 Hit = TRUE;
936 }
937 _SEH2_END;
938
939 if (Hit)
940 {
941 // We don't die, we continue on with a allocated safe pointer to kernel
942 // space.....
943
944 if (!IS_ALIGNED(Bits, 2)) // If both Read Exception and mis-aligned
945 {
946 LinesCopied = 0;
947 goto Exit;
948 }
949
950 DPRINT1("SetDIBitsToDevice fail to read BitMapInfo: %p or Bits: %p & Size: %u\n",
951 pConvertedInfo, Bits, cjBmpScanSize);
952 }
953 DPRINT("SetDIBitsToDevice Allocate Bits %u!!!\n", cjBmpScanSize);
954 }
955
957 {
958 DPRINT1("SetDIBitsToDevice called on invalid DC %p (not owned?)\n", hdc);
960 LinesCopied = 0;
961 goto Exit;
962 }
963
964 /* Calculation of ScanLines for NtGdiSetDIBitsToDeviceInternal */
965 if (YDest >= 0)
966 {
967 ScanLines = min(abs(Height), ScanLines);
968 if (YSrc > 0)
969 ScanLines += YSrc;
970 }
971 else
972 {
973 ScanLines = min(ScanLines,
974 abs(pConvertedInfo->bmiHeader.biHeight) - StartScan);
975 }
976
977 if (YDest >= 0 && YSrc > 0 && bmiHeight <= MaxHeight)
978 {
979 ScanLines += YSrc;
980 }
981
982 /* Find Format from lpbmi which is now pConvertedInfo */
983 iFormat = BitmapFormat(pConvertedInfo->bmiHeader.biBitCount,
984 pConvertedInfo->bmiHeader.biCompression);
985
986 /* Get bits per pixel from the format */
987 cBitsPixel = gajBitsPerFormat[iFormat];
988
989 cjWidth = WIDTH_BYTES_ALIGN32(pConvertedInfo->bmiHeader.biWidth, cBitsPixel);
990
991 /* Calculate the correct bitmap size in bytes */
992 if (!NT_SUCCESS(RtlULongMult(cjWidth, max(ScanLines, LinesCopied), &cjBits)))
993 {
994 DPRINT1("Overflow calculating size: cjWidth %lu, ScanLines %lu\n",
995 cjWidth, max(ScanLines, LinesCopied));
996 goto Exit;
997 }
998
999 /* Make sure the buffer is large enough */
1000 if (pConvertedInfo->bmiHeader.biSizeImage < cjBits)
1001 {
1002 DPRINT("Buffer is too small, required: %lu, got %lu\n",
1003 cjBits, pConvertedInfo->bmiHeader.biSizeImage);
1004 if (pConvertedInfo->bmiHeader.biCompression == BI_RGB)
1005 {
1006 pConvertedInfo->bmiHeader.biSizeImage = cjBits;
1007 }
1008 }
1009
1010 if (YDest >= 0)
1011 {
1012 ScanLines = min(abs(Height), ScanLines);
1013 if (YSrc > 0)
1014 {
1015 ScanLines += YSrc;
1016 if (Height + YDest + 1 < ScanLines)
1017 YSrc = 0;
1018 }
1019 }
1020
1021 /*
1022 if ( !pDc_Attr || // DC is Public
1023 ColorUse == DIB_PAL_COLORS ||
1024 ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
1025 (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
1026 pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
1027 {
1028 LinesCopied = NtGdiSetDIBitsToDeviceInternal(hdc, XDest, YDest,
1029 Width, Height, XSrc, YSrc,
1030 StartScan, ScanLines, (LPBYTE) pvSafeBits,
1031 (LPBITMAPINFO) pConvertedInfo, ColorUse,
1032 cjBmpScanSize, ConvertedInfoSize,
1033 TRUE,
1034 NULL);
1035 }
1036
1037 if (bmiHeight > MaxScanLines)
1038 {
1039 LinesCopied = ScanLines;
1040 }
1041
1042 if (YDest < 0)
1043 {
1044 if (top_down)
1045 LinesCopied = ScanLines;
1046 else
1047 LinesCopied = ScanLines - src_y;
1048 }
1049
1050 if (pConvertedInfo->bmiHeader.biCompression == BI_RLE8 ||
1051 pConvertedInfo->bmiHeader.biCompression == BI_RLE4)
1052 {
1053 LinesCopied = bmiHeight;
1054 }
1055
1056 if (pConvertedInfo->bmiHeader.biHeight < 0 && YDest >= 0)
1057 {
1058 if (Width * ScanLinesOrig > ImageSizeOrig && ImageSizeOrig != 0)
1059 {
1060 LinesCopied = 0;
1061 }
1062 else
1063 {
1064 LinesCopied = ScanLinesOrig;
1065 }
1066 }
1067
1068Exit:
1069 if (Bits != pvSafeBits)
1070 RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
1071 if (lpbmi != pConvertedInfo)
1072 RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
1073
1074 return LinesCopied;
1075}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
VOID GdiSAPCallback(PLDC pldc)
Definition: misc.c:819
#define HANDLE_METADC(_RetType, _Func, dwError, hdc,...)
Definition: gdi32p.h:615
PLDC FASTCALL GdiGetLDC(HDC hDC)
Definition: misc.c:785
@ GDILoObjType_LO_METADC16_TYPE
Definition: gdi_private.h:49
@ GDILoObjType_LO_DC_TYPE
Definition: gdi_private.h:34
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
HDC hdc
Definition: main.c:9
#define min(a, b)
Definition: monoChain.cc:55
#define LDC_KILL_DOCUMENT
Definition: ntgdihdl.h:158
#define LDC_SAPCALLBACK
Definition: ntgdihdl.h:150
#define LDC_STARTPAGE
Definition: ntgdihdl.h:153
__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 _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
Definition: ntgdihdl.h:263
ULONG Flags
Definition: ntgdihdl.h:265
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
UCHAR gajBitsPerFormat[11]
Definition: bitmap.c:39
#define MaxScanLines
ULONG FASTCALL BitmapFormat(ULONG cBits, ULONG iCompression)
Definition: bitmap.c:11
#define MaxHeight
#define IS_ALIGNED(Pointer, Alignment)
_In_ SIZEL _In_ ULONG iFormat
Definition: winddi.h:3468
int WINAPI StartPage(_In_ HDC)

◆ StretchDIBits()

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 at line 1082 of file bitmap.c.

1097{
1098 PDC_ATTR pDc_Attr;
1099 PBITMAPINFO pConvertedInfo = NULL;
1100 UINT ConvertedInfoSize = 0;
1101 INT LinesCopied = 0;
1102 UINT cjBmpScanSize = 0;
1103 PVOID pvSafeBits = NULL;
1104 BOOL Hit = FALSE;
1105
1106 DPRINT("StretchDIBits %p : %p : %u\n", lpBits, lpBitsInfo, iUsage);
1107
1108 HANDLE_METADC( int,
1110 0,
1111 hdc,
1112 XDest,
1113 YDest,
1114 nDestWidth,
1115 nDestHeight,
1116 XSrc,
1117 YSrc,
1118 nSrcWidth,
1119 nSrcHeight,
1120 lpBits,
1121 lpBitsInfo,
1122 iUsage,
1123 dwRop );
1124
1125 if ( GdiConvertAndCheckDC(hdc) == NULL ) return 0;
1126
1127 pConvertedInfo = ConvertBitmapInfo(lpBitsInfo, iUsage, &ConvertedInfoSize, FALSE);
1128 if (!pConvertedInfo)
1129 {
1130 return 0;
1131 }
1132
1133 cjBmpScanSize = GdiGetBitmapBitsSize((BITMAPINFO *) pConvertedInfo);
1134
1135 if (lpBits)
1136 {
1137 pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
1138 if (pvSafeBits)
1139 {
1140 _SEH2_TRY
1141 {
1142 RtlCopyMemory(pvSafeBits, lpBits, cjBmpScanSize);
1143 }
1145 {
1146 Hit = TRUE;
1147 }
1148 _SEH2_END
1149
1150 if (Hit)
1151 {
1152 // We don't die, we continue on with a allocated safe pointer to kernel
1153 // space.....
1154 DPRINT1("StretchDIBits fail to read BitMapInfo: %p or Bits: %p & Size: %u\n",
1155 pConvertedInfo, lpBits, cjBmpScanSize);
1156 }
1157 DPRINT("StretchDIBits Allocate Bits %u!!!\n", cjBmpScanSize);
1158 }
1159 }
1160
1161 if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID) & pDc_Attr))
1162 {
1163 DPRINT1("StretchDIBits called on invalid DC %p (not owned?)\n", hdc);
1165 LinesCopied = 0;
1166 goto Exit;
1167 }
1168 /*
1169 if ( !pDc_Attr ||
1170 iUsage == DIB_PAL_COLORS ||
1171 ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
1172 (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
1173 pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
1174 {
1175 LinesCopied = NtGdiStretchDIBitsInternal( hdc,
1176 XDest,
1177 YDest,
1178 nDestWidth,
1179 nDestHeight,
1180 XSrc,
1181 YSrc,
1182 nSrcWidth,
1183 nSrcHeight,
1184 pvSafeBits,
1185 pConvertedInfo,
1186 (DWORD) iUsage,
1187 dwRop,
1188 ConvertedInfoSize,
1189 cjBmpScanSize,
1190 NULL );
1191 }
1192Exit:
1193 if (pvSafeBits)
1194 RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
1195 if (lpBitsInfo != pConvertedInfo)
1196 RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
1197
1198 return LinesCopied;
1199}
HDC WINAPI GdiConvertAndCheckDC(HDC hdc)
Definition: dc.c:403
__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)
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO _In_ UINT iUsage
Definition: ntgdi.h:2809
int WINAPI StretchDIBits(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ const VOID *, _In_ const BITMAPINFO *, _In_ UINT, _In_ DWORD)

Variable Documentation

◆ gajBitsPerFormat

UCHAR gajBitsPerFormat[11]
Initial value:
=
{
0,
1,
4,
8,
16,
24,
32,
4,
8,
0,
0,
}

Definition at line 39 of file bitmap.c.

Referenced by SetDIBitsToDevice().