ReactOS 0.4.15-dev-6067-g0b695a6
dibobj.c File Reference
#include <win32k.h>
#include <debug.h>
Include dependency graph for dibobj.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

PPALETTE NTAPI CreateDIBPalette (_In_ const BITMAPINFO *pbmi, _In_ PDC pdc, _In_ ULONG iUsage)
 
static INT FASTCALL IntSetDIBits (PDC DC, HBITMAP hBitmap, UINT StartScan, UINT ScanLines, CONST VOID *Bits, ULONG cjMaxBits, CONST BITMAPINFO *bmi, UINT ColorUse)
 
static HBITMAP IntGdiCreateMaskFromRLE (DWORD Width, DWORD Height, ULONG Compression, const BYTE *Bits, DWORD BitsSize)
 
W32KAPI INT APIENTRY NtGdiSetDIBitsToDeviceInternal (IN HDC hDC, IN INT XDest, IN INT YDest, IN DWORD Width, IN DWORD Height, IN INT XSrc, IN INT YSrc, IN DWORD StartScan, IN DWORD ScanLines, IN LPBYTE Bits, IN LPBITMAPINFO bmi, IN DWORD ColorUse, IN UINT cjMaxBits, IN UINT cjMaxInfo, IN BOOL bTransformCoordinates, IN OPTIONAL HANDLE hcmXform)
 
INT APIENTRY GreGetDIBitsInternal (HDC hDC, HBITMAP hBitmap, UINT StartScan, UINT ScanLines, LPBYTE Bits, LPBITMAPINFO Info, UINT Usage, UINT MaxBits, UINT MaxInfo)
 
 _Success_ (return!=0)
 
W32KAPI INT APIENTRY NtGdiStretchDIBitsInternal (IN HDC hdc, IN INT xDst, IN INT yDst, IN INT cxDst, IN INT cyDst, IN INT xSrc, IN INT ySrc, IN INT cxSrc, IN INT cySrc, IN OPTIONAL LPBYTE pjInit, IN LPBITMAPINFO pbmi, IN DWORD dwUsage, IN DWORD dwRop, IN UINT cjMaxInfo, IN UINT cjMaxBits, IN HANDLE hcmXform)
 
HBITMAP FASTCALL IntCreateDIBitmap (PDC Dc, INT width, INT height, UINT planes, UINT bpp, ULONG compression, DWORD init, LPBYTE bits, ULONG cjMaxBits, PBITMAPINFO data, DWORD coloruse)
 
HBITMAP APIENTRY NtGdiCreateDIBitmapInternal (IN HDC hDc, IN INT cx, IN INT cy, IN DWORD fInit, IN OPTIONAL LPBYTE pjInit, IN OPTIONAL LPBITMAPINFO pbmi, IN DWORD iUsage, IN UINT cjMaxInitInfo, IN UINT cjMaxBits, IN FLONG fl, IN HANDLE hcmXform)
 
HBITMAP NTAPI GreCreateDIBitmapInternal (IN HDC hDc, IN INT cx, IN INT cy, IN DWORD fInit, IN OPTIONAL LPBYTE pjInit, IN OPTIONAL PBITMAPINFO pbmi, IN DWORD iUsage, IN FLONG fl, IN UINT cjMaxBits, IN HANDLE hcmXform)
 
HBITMAP NTAPI GreCreateDIBitmapFromPackedDIB (_In_reads_(cjPackedDIB) PVOID pvPackedDIB, _In_ UINT cjPackedDIB, _In_ ULONG uUsage)
 
HBITMAP APIENTRY NtGdiCreateDIBSection (IN HDC hDC, IN OPTIONAL HANDLE hSection, IN DWORD dwOffset, IN BITMAPINFO *bmi, IN DWORD Usage, IN UINT cjHeader, IN FLONG fl, IN ULONG_PTR dwColorSpace, OUT PVOID *Bits)
 
HBITMAP APIENTRY DIB_CreateDIBSection (PDC dc, CONST BITMAPINFO *bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch)
 
int FASTCALL DIB_GetBitmapInfo (const BITMAPINFOHEADER *header, LONG *width, LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size)
 
INT APIENTRY DIB_GetDIBImageBytes (INT width, INT height, INT depth)
 
INT FASTCALL DIB_BitmapInfoSize (const BITMAPINFO *info, WORD coloruse)
 
HPALETTE FASTCALL DIB_MapPaletteColors (PPALETTE ppalDc, CONST BITMAPINFO *lpbmi)
 
BITMAPINFO *FASTCALL DIB_ConvertBitmapInfo (CONST BITMAPINFO *pbmi, DWORD Usage)
 
VOID FASTCALL DIB_FreeConvertedBitmapInfo (BITMAPINFO *converted, BITMAPINFO *orig, DWORD usage)
 

Variables

static const RGBQUAD DefLogPaletteQuads [20]
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 11 of file dibobj.c.

Function Documentation

◆ _Success_()

_Success_ ( return!  = 0)

Definition at line 1085 of file dibobj.c.

1099{
1100 PBITMAPINFO pbmiSafe;
1101 HANDLE hSecure = NULL;
1102 INT iResult = 0;
1103 UINT cjAlloc;
1104
1105 /* Check for bad iUsage */
1106 if (iUsage > 2) return 0;
1107
1108 /* Check if the size of the bitmap info is large enough */
1109 if (cjMaxInfo < sizeof(BITMAPCOREHEADER))
1110 {
1111 return 0;
1112 }
1113
1114 /* Use maximum size */
1115 cjMaxInfo = min(cjMaxInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD));
1116
1117 // HACK: the underlying code sucks and doesn't care for the size, so we
1118 // give it the maximum ever needed
1119 cjAlloc = sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD);
1120
1121 /* Allocate a buffer the bitmapinfo */
1122 pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjAlloc, 'imBG');
1123 if (!pbmiSafe)
1124 {
1125 /* Fail */
1126 return 0;
1127 }
1128
1129 /* Use SEH */
1130 _SEH2_TRY
1131 {
1132 /* Probe and copy the BITMAPINFO */
1134 RtlCopyMemory(pbmiSafe, pbmi, cjMaxInfo);
1135 }
1137 {
1138 goto cleanup;
1139 }
1140 _SEH2_END;
1141
1142 /* Check if the header size is large enough */
1143 if ((pbmiSafe->bmiHeader.biSize < sizeof(BITMAPCOREHEADER)) ||
1144 (pbmiSafe->bmiHeader.biSize > cjMaxInfo))
1145 {
1146 goto cleanup;
1147 }
1148
1149 /* Check if the caller provided bitmap bits */
1150 if (pjBits)
1151 {
1152 /* Secure the user mode memory */
1153 hSecure = EngSecureMem(pjBits, cjMaxBits);
1154 if (!hSecure)
1155 {
1156 goto cleanup;
1157 }
1158 }
1159
1160 /* Now call the internal function */
1161 iResult = GreGetDIBitsInternal(hdc,
1162 hbm,
1163 iStartScan,
1164 cScans,
1165 pjBits,
1166 pbmiSafe,
1167 iUsage,
1168 cjMaxBits,
1169 cjMaxInfo);
1170
1171 /* Check for success */
1172 if (iResult)
1173 {
1174 /* Use SEH to copy back to user mode */
1175 _SEH2_TRY
1176 {
1177 /* Copy the data back */
1180 RtlCopyMemory(pbmi, pbmiSafe, cjMaxInfo);
1181 }
1183 {
1184 /* Ignore */
1185 (VOID)0;
1186 }
1187 _SEH2_END;
1188 }
1189
1190cleanup:
1191 if (hSecure) EngUnsecureMem(hSecure);
1192 ExFreePoolWithTag(pbmiSafe, 'imBG');
1193
1194 return iResult;
1195}
#define VOID
Definition: acefi.h:82
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO *info, WORD coloruse)
Definition: dibobj.c:2145
INT APIENTRY GreGetDIBitsInternal(HDC hDC, HBITMAP hBitmap, UINT StartScan, UINT ScanLines, LPBYTE Bits, LPBITMAPINFO Info, UINT Usage, UINT MaxBits, UINT MaxInfo)
Definition: dibobj.c:694
#define NULL
Definition: types.h:112
static void cleanup(void)
Definition: main.c:1335
ULONG RGBQUAD
Definition: precomp.h:50
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned short WORD
Definition: ntddk_ex.h:93
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
HDC hdc
Definition: main.c:9
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO _In_ UINT _In_ UINT _In_ UINT cjMaxInfo
Definition: ntgdi.h:2783
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO _In_ UINT _In_ UINT cjMaxBits
Definition: ntgdi.h:2782
_In_ HBITMAP _In_ UINT _In_ UINT cScans
Definition: ntgdi.h:2778
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO pbmi
Definition: ntgdi.h:2780
_In_ HBITMAP _In_ UINT _In_ UINT _Inout_ LPBITMAPINFO _In_ UINT iUsage
Definition: ntgdi.h:2781
_In_ HBITMAP _In_ UINT iStartScan
Definition: ntgdi.h:2777
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1476
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
ENGAPI HANDLE APIENTRY EngSecureMem(_In_reads_bytes_(cjLength) PVOID Address, _In_ ULONG cjLength)
ENGAPI VOID APIENTRY EngUnsecureMem(_In_ HANDLE hSecure)

◆ CreateDIBPalette()

PPALETTE NTAPI CreateDIBPalette ( _In_ const BITMAPINFO pbmi,
_In_ PDC  pdc,
_In_ ULONG  iUsage 
)

Definition at line 41 of file dibobj.c.

45{
46 PPALETTE ppal;
47 ULONG i, cBitsPixel, cColors;
48
50 {
52 cBitsPixel = pbci->bmciHeader.bcBitCount;
53 }
54 else
55 {
56 cBitsPixel = pbmi->bmiHeader.biBitCount;
57 }
58
59 /* Check if the colors are indexed */
60 if (cBitsPixel <= 8)
61 {
62 /* We create a "full" palette */
63 cColors = 1 << cBitsPixel;
64
65 /* Allocate the palette */
67 cColors,
68 NULL,
69 0,
70 0,
71 0);
72 if (ppal == NULL)
73 {
74 DPRINT1("Failed to allocate palette.\n");
75 return NULL;
76 }
77
78 /* Check if the BITMAPINFO specifies how many colors to use */
79 if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
80 (pbmi->bmiHeader.biClrUsed != 0))
81 {
82 /* This is how many colors we can actually process */
83 cColors = min(cColors, pbmi->bmiHeader.biClrUsed);
84 }
85
86 /* Check how to use the colors */
88 {
89 COLORREF crColor;
90
91 /* The colors are an array of WORD indices into the DC palette */
92 PWORD pwColors = (PWORD)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
93
94 /* Use the DCs palette or, if no DC is given, the default one */
95 PPALETTE ppalDC = pdc ? pdc->dclevel.ppal : gppalDefault;
96
97 /* Loop all color indices in the DIB */
98 for (i = 0; i < cColors; i++)
99 {
100 /* Get the palette index and handle wraparound when exceeding
101 the number of colors in the DC palette */
102 WORD wIndex = pwColors[i] % ppalDC->NumColors;
103
104 /* USe the RGB value from the DC palette */
105 crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, wIndex);
106 PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
107 }
108 }
109 else if (iUsage == DIB_PAL_BRUSHHACK)
110 {
111 /* The colors are an array of WORD indices into the DC palette */
112 PWORD pwColors = (PWORD)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
113
114 /* Loop all color indices in the DIB */
115 for (i = 0; i < cColors; i++)
116 {
117 /* Set the index directly as the RGB color, the real palette
118 containing RGB values will be calculated when the brush is
119 realized */
120 PALETTE_vSetRGBColorForIndex(ppal, i, pwColors[i]);
121 }
122
123 /* Mark the palette as a brush hack palette */
124 ppal->flFlags |= PAL_BRUSHHACK;
125 }
126// else if (iUsage == 2)
127// {
128 // FIXME: this one is undocumented
129// ASSERT(FALSE);
130// }
131 else if (pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
132 {
133 /* The colors are an array of RGBQUAD values */
134 RGBQUAD *prgb = (RGBQUAD*)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
135 RGBQUAD colors[256] = {{0}};
136
137 // FIXME: do we need to handle PALETTEINDEX / PALETTERGB macro?
138
139 /* Use SEH to verify we can READ prgb[] succesfully */
141 {
142 RtlCopyMemory(colors, prgb, cColors * sizeof(colors[0]));
143 }
145 {
146 /* Do Nothing */
147 }
148 _SEH2_END;
149
150 for (i = 0; i < cColors; ++i)
151 {
152 /* Get the color value and translate it to a COLORREF */
153 COLORREF crColor = RGB(colors[i].rgbRed, colors[i].rgbGreen, colors[i].rgbBlue);
154
155 /* Set the RGB value in the palette */
156 PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
157 }
158 }
159 else
160 {
161 /* The colors are an array of RGBTRIPLE values */
163
164 /* Loop all color indices in the DIB */
165 for (i = 0; i < cColors; i++)
166 {
167 /* Get the color value and translate it to a COLORREF */
168 RGBTRIPLE rgb = prgb[i];
169 COLORREF crColor = RGB(rgb.rgbtRed, rgb.rgbtGreen, rgb.rgbtBlue);
170
171 /* Set the RGB value in the palette */
172 PALETTE_vSetRGBColorForIndex(ppal, i, crColor);
173 }
174 }
175 }
176 else
177 {
178 /* This is a bitfield / RGB palette */
179 ULONG flRedMask, flGreenMask, flBlueMask;
180
181 /* Check if the DIB contains bitfield values */
182 if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
184 {
185 /* Check if we have a v4/v5 header */
186 if (pbmi->bmiHeader.biSize >= sizeof(BITMAPV4HEADER))
187 {
188 /* The masks are dedicated fields in the header */
190 flRedMask = pbmV4Header->bV4RedMask;
191 flGreenMask = pbmV4Header->bV4GreenMask;
192 flBlueMask = pbmV4Header->bV4BlueMask;
193 }
194 else
195 {
196 /* The masks are the first 3 values in the DIB color table */
197 PDWORD pdwColors = (PVOID)((PCHAR)pbmi + pbmi->bmiHeader.biSize);
198 flRedMask = pdwColors[0];
199 flGreenMask = pdwColors[1];
200 flBlueMask = pdwColors[2];
201 }
202 }
203 else
204 {
205 /* Check what bit depth we have. Note: optimization flags are
206 calculated in PALETTE_AllocPalette() */
207 if (cBitsPixel == 16)
208 {
209 /* This is an RGB 555 palette */
210 flRedMask = 0x7C00;
211 flGreenMask = 0x03E0;
212 flBlueMask = 0x001F;
213 }
214 else
215 {
216 /* This is an RGB 888 palette */
217 flRedMask = 0xFF0000;
218 flGreenMask = 0x00FF00;
219 flBlueMask = 0x0000FF;
220 }
221 }
222
223 /* Allocate the bitfield palette */
225 0,
226 NULL,
227 flRedMask,
228 flGreenMask,
229 flBlueMask);
230 }
231
232 /* We're done, return the palette */
233 return ppal;
234}
#define DPRINT1
Definition: precomp.h:8
#define RGB(r, g, b)
Definition: precomp.h:62
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define BI_BITFIELDS
Definition: mmreg.h:507
WORD * PWORD
Definition: pedump.c:67
DWORD * PDWORD
Definition: pedump.c:68
DWORD bV4GreenMask
Definition: wingdi.h:1504
DWORD bV4RedMask
Definition: wingdi.h:1503
DWORD bV4BlueMask
Definition: wingdi.h:1505
BITMAPCOREHEADER bmciHeader
Definition: wingdi.h:1453
ULONG NumColors
Definition: palette.h:41
FLONG flFlags
Definition: palette.h:40
USHORT biBitCount
Definition: precomp.h:37
ULONG biCompression
Definition: precomp.h:38
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define DIB_PAL_BRUSHHACK
Definition: dib.h:36
PPALETTE NTAPI PALETTE_AllocPalette(_In_ ULONG iMode, _In_ ULONG cColors, _In_opt_ const PALETTEENTRY *pEntries, _In_ FLONG flRed, _In_ FLONG flGreen, _In_ FLONG flBlue)
Definition: palette.c:135
PALETTE * gppalDefault
Definition: palette.c:20
FORCEINLINE VOID PALETTE_vSetRGBColorForIndex(PPALETTE ppal, ULONG ulIndex, COLORREF crColor)
Definition: palette.h:152
@ PAL_BRUSHHACK
Definition: palette.h:23
FORCEINLINE ULONG PALETTE_ulGetRGBColorFromIndex(PPALETTE ppal, ULONG ulIndex)
Definition: palette.h:142
#define PAL_BITFIELDS
Definition: winddi.h:1562
_In_ ULONG _In_ ULONG rgb
Definition: winddi.h:3521
#define PAL_INDEXED
Definition: winddi.h:1561
DWORD COLORREF
Definition: windef.h:300
struct _BITMAPCOREINFO * PBITMAPCOREINFO
#define DIB_PAL_COLORS
Definition: wingdi.h:366
struct BITMAPV4HEADER * PBITMAPV4HEADER

Referenced by DIB_CreateDIBSection(), IntCreateDIBitmap(), IntSetDIBits(), NtGdiSetDIBitsToDeviceInternal(), and NtGdiStretchDIBitsInternal().

◆ DIB_BitmapInfoSize()

INT FASTCALL DIB_BitmapInfoSize ( const BITMAPINFO info,
WORD  coloruse 
)

Definition at line 2145 of file dibobj.c.

2146{
2147 unsigned int colors, size, masks = 0;
2148 unsigned int colorsize;
2149
2150 colorsize = (coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) :
2151 (coloruse == DIB_PAL_INDICES) ? 0 :
2152 sizeof(WORD);
2153
2154 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
2155 {
2156 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
2157 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
2158 return sizeof(BITMAPCOREHEADER) + colors * colorsize;
2159 }
2160 else /* Assume BITMAPINFOHEADER */
2161 {
2162 colors = info->bmiHeader.biClrUsed;
2163 if (colors > 256) colors = 256;
2164 if (!colors && (info->bmiHeader.biBitCount <= 8))
2165 colors = 1 << info->bmiHeader.biBitCount;
2166 if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
2167 size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
2168 return size + colors * colorsize;
2169 }
2170}
#define DIB_PAL_INDICES
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:2760
#define max(a, b)
Definition: svc.c:63
#define DIB_RGB_COLORS
Definition: wingdi.h:367

Referenced by _Success_(), GreCreateDIBitmapFromPackedDIB(), and NtGdiCreateDIBSection().

◆ DIB_ConvertBitmapInfo()

BITMAPINFO *FASTCALL DIB_ConvertBitmapInfo ( CONST BITMAPINFO pbmi,
DWORD  Usage 
)

Definition at line 2218 of file dibobj.c.

2219{
2221 BITMAPINFO* pNewBmi ;
2222 UINT numColors = 0, ColorsSize = 0;
2223
2224 if(pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) return (BITMAPINFO*)pbmi;
2225 if(pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) return NULL;
2226
2227 if(pbmci->bmciHeader.bcBitCount <= 8)
2228 {
2229 numColors = 1 << pbmci->bmciHeader.bcBitCount;
2230 if(Usage == DIB_PAL_COLORS)
2231 {
2232 ColorsSize = numColors * sizeof(WORD);
2233 }
2234 else
2235 {
2236 ColorsSize = numColors * sizeof(RGBQUAD);
2237 }
2238 }
2239 else if (Usage == DIB_PAL_COLORS)
2240 {
2241 /* Invalid at high-res */
2242 return NULL;
2243 }
2244
2245 pNewBmi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + ColorsSize, TAG_DIB);
2246 if(!pNewBmi) return NULL;
2247
2248 RtlZeroMemory(pNewBmi, sizeof(BITMAPINFOHEADER) + ColorsSize);
2249
2250 pNewBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2251 pNewBmi->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount;
2252 pNewBmi->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth;
2253 pNewBmi->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight;
2254 pNewBmi->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes;
2255 pNewBmi->bmiHeader.biCompression = BI_RGB ;
2257 pNewBmi->bmiHeader.biHeight,
2258 pNewBmi->bmiHeader.biBitCount);
2259 pNewBmi->bmiHeader.biClrUsed = numColors;
2260
2261 if(Usage == DIB_PAL_COLORS)
2262 {
2263 RtlCopyMemory(pNewBmi->bmiColors, pbmci->bmciColors, ColorsSize);
2264 }
2265 else
2266 {
2267 UINT i;
2268 for(i=0; i<numColors; i++)
2269 {
2270 pNewBmi->bmiColors[i].rgbRed = pbmci->bmciColors[i].rgbtRed;
2271 pNewBmi->bmiColors[i].rgbGreen = pbmci->bmciColors[i].rgbtGreen;
2272 pNewBmi->bmiColors[i].rgbBlue = pbmci->bmciColors[i].rgbtBlue;
2273 }
2274 }
2275
2276 return pNewBmi ;
2277}
INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth)
Definition: dibobj.c:2133
#define BI_RGB
Definition: precomp.h:47
_Must_inspect_result_ _In_ USAGE _In_ USHORT _In_ USAGE Usage
Definition: hidpi.h:384
#define CONST
Definition: pedump.c:81
RGBQUAD bmiColors[1]
Definition: wingdi.h:1477
UCHAR rgbBlue
Definition: bootanim.c:97
UCHAR rgbRed
Definition: bootanim.c:99
UCHAR rgbGreen
Definition: bootanim.c:98
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define TAG_DIB
Definition: tags.h:17

Referenced by GreGetDIBitsInternal(), IntSynthesizeBitmap(), and UserLoadImage().

◆ DIB_CreateDIBSection()

HBITMAP APIENTRY DIB_CreateDIBSection ( PDC  dc,
CONST BITMAPINFO bmi,
UINT  usage,
LPVOID bits,
HANDLE  section,
DWORD  offset,
DWORD  ovr_pitch 
)

Definition at line 1891 of file dibobj.c.

1899{
1900 HBITMAP res = 0;
1901 SURFACE *bmp = NULL;
1902 void *mapBits = NULL;
1903 PPALETTE ppalDIB = NULL;
1904
1905 // Fill BITMAP32 structure with DIB data
1906 CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
1907 INT effHeight;
1908 ULONG totalSize;
1909 BITMAP bm;
1910 //SIZEL Size;
1911 HANDLE hSecure;
1912
1913 DPRINT("format (%ld,%ld), planes %u, bpp %u, size %lu, colors %lu (%s)\n",
1914 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
1915 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1916
1917 /* CreateDIBSection should fail for compressed formats */
1918 if (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8)
1919 {
1920 DPRINT1("no compressed format allowed\n");
1921 return (HBITMAP)NULL;
1922 }
1923
1924 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
1925 bm.bmType = 0;
1926 bm.bmWidth = bi->biWidth;
1927 bm.bmHeight = effHeight;
1928 bm.bmWidthBytes = ovr_pitch ? ovr_pitch : WIDTH_BYTES_ALIGN32(bm.bmWidth, bi->biBitCount);
1929
1930 bm.bmPlanes = bi->biPlanes;
1931 bm.bmBitsPixel = bi->biBitCount;
1932 bm.bmBits = NULL;
1933
1934 // Get storage location for DIB bits. Only use biSizeImage if it's valid and
1935 // we're dealing with a compressed bitmap. Otherwise, use width * height.
1936 totalSize = (bi->biSizeImage && (bi->biCompression != BI_RGB) && (bi->biCompression != BI_BITFIELDS))
1937 ? bi->biSizeImage : (ULONG)(bm.bmWidthBytes * effHeight);
1938
1939 if (section)
1940 {
1943 DWORD mapOffset;
1945 SIZE_T mapSize;
1946
1948 &Sbi,
1949 sizeof Sbi,
1950 0);
1951 if (!NT_SUCCESS(Status))
1952 {
1953 DPRINT1("ZwQuerySystemInformation failed (0x%lx)\n", Status);
1954 return NULL;
1955 }
1956
1957 mapOffset = offset - (offset % Sbi.AllocationGranularity);
1958 mapSize = totalSize + (offset - mapOffset);
1959
1960 SectionOffset.LowPart = mapOffset;
1961 SectionOffset.HighPart = 0;
1962
1963 Status = ZwMapViewOfSection(section,
1965 &mapBits,
1966 0,
1967 0,
1969 &mapSize,
1970 ViewShare,
1971 0,
1973 if (!NT_SUCCESS(Status))
1974 {
1975 DPRINT1("ZwMapViewOfSection failed (0x%lx)\n", Status);
1977 return NULL;
1978 }
1979
1980 if (mapBits) bm.bmBits = (char *)mapBits + (offset - mapOffset);
1981 }
1982 else if (ovr_pitch && offset)
1983 bm.bmBits = UlongToPtr(offset);
1984 else
1985 {
1986 offset = 0;
1987 bm.bmBits = EngAllocUserMem(totalSize, 0);
1988 if(!bm.bmBits)
1989 {
1990 DPRINT1("Failed to allocate memory\n");
1991 goto cleanup;
1992 }
1993 }
1994
1995// hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE);
1996 hSecure = (HANDLE)0x1; // HACK OF UNIMPLEMENTED KERNEL STUFF !!!!
1997
1998
1999 // Create Device Dependent Bitmap and add DIB pointer
2000 //Size.cx = bm.bmWidth;
2001 //Size.cy = abs(bm.bmHeight);
2002 res = GreCreateBitmapEx(bm.bmWidth,
2003 abs(bm.bmHeight),
2004 bm.bmWidthBytes,
2005 BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
2007 ((bi->biHeight < 0) ? BMF_TOPDOWN : 0),
2008 totalSize,
2009 bm.bmBits,
2010 0);
2011 if (!res)
2012 {
2013 DPRINT1("GreCreateBitmapEx failed\n");
2015 goto cleanup;
2016 }
2017 bmp = SURFACE_ShareLockSurface(res); // HACK
2018 if (NULL == bmp)
2019 {
2020 DPRINT1("SURFACE_LockSurface failed\n");
2022 goto cleanup;
2023 }
2024
2025 /* WINE NOTE: WINE makes use of a colormap, which is a color translation
2026 table between the DIB and the X physical device. Obviously,
2027 this is left out of the ReactOS implementation. Instead,
2028 we call NtGdiSetDIBColorTable. */
2029 bmp->hDIBSection = section;
2030 bmp->hSecure = hSecure;
2031 bmp->dwOffset = offset;
2032 bmp->flags = API_BITMAP;
2033 bmp->biClrImportant = bi->biClrImportant;
2034
2035 /* Create a palette for the DIB */
2036 ppalDIB = CreateDIBPalette(bmi, dc, usage);
2037
2038 // Clean up in case of errors
2039cleanup:
2040 if (!res || !bmp || !bm.bmBits || !ppalDIB)
2041 {
2042 DPRINT("Got an error res=%p, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
2043 if (bm.bmBits)
2044 {
2045 // MmUnsecureVirtualMemory(hSecure); // FIXME: Implement this!
2046 if (section)
2047 {
2048 ZwUnmapViewOfSection(NtCurrentProcess(), mapBits);
2049 bm.bmBits = NULL;
2050 }
2051 else if (!offset)
2052 EngFreeUserMem(bm.bmBits), bm.bmBits = NULL;
2053 }
2054
2055 if (bmp)
2056 {
2058 bmp = NULL;
2059 }
2060
2061 if (res)
2062 {
2064 res = 0;
2065 }
2066
2067 if(ppalDIB)
2068 {
2070 }
2071 }
2072
2073 if (bmp)
2074 {
2075 /* If we're here, everything went fine */
2076 SURFACE_vSetPalette(bmp, ppalDIB);
2079 }
2080
2081 // Return BITMAP handle and storage location
2082 if (NULL != bm.bmBits && NULL != bits)
2083 {
2084 *bits = bm.bmBits;
2085 }
2086
2087 return res;
2088}
LONG NTSTATUS
Definition: precomp.h:26
HBITMAP NTAPI GreCreateBitmapEx(_In_ ULONG nWidth, _In_ ULONG nHeight, _In_ ULONG cjWidthBytes, _In_ ULONG iFormat, _In_ USHORT fjBitmap, _In_ ULONG cjSizeImage, _In_opt_ PVOID pvBits, _In_ FLONG flags)
Definition: bitmaps.c:101
PPALETTE NTAPI CreateDIBPalette(_In_ const BITMAPINFO *pbmi, _In_ PDC pdc, _In_ ULONG iUsage)
Definition: dibobj.c:41
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define BI_RLE4
Definition: precomp.h:48
#define UlongToPtr(u)
Definition: config.h:106
#define abs(i)
Definition: fconv.c:206
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
@ SystemBasicInformation
Definition: ntddk_ex.h:11
Status
Definition: gdiplustypes.h:25
GLuint res
Definition: glext.h:9613
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
static const WCHAR dc[]
BITMAP bmp
Definition: alphablend.c:62
static HBITMAP
Definition: button.c:44
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:407
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define NtCurrentProcess()
Definition: nt_native.h:1657
@ ViewShare
Definition: nt_native.h:1278
#define DPRINT
Definition: sndvol32.h:71
Definition: bl.h:1331
Definition: parser.c:56
#define WIDTH_BYTES_ALIGN32(cx, bpp)
Definition: swimpl.c:16
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
ULONG FASTCALL BitmapFormat(ULONG cBits, ULONG iCompression)
Definition: surface.c:39
#define SURFACE_ShareUnlockSurface(pBMObj)
Definition: surface.h:102
FORCEINLINE VOID SURFACE_vSetPalette(_Inout_ PSURFACE psurf, _In_ PPALETTE ppal)
Definition: surface.h:136
@ API_BITMAP
Definition: surface.h:76
#define SURFACE_ShareLockSurface(hBMObj)
Definition: surface.h:91
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
#define PALETTE_ShareUnlockPalette(ppal)
Definition: palette.h:59
#define BMF_DONTCACHE
Definition: winddi.h:1182
ENGAPI VOID APIENTRY EngFreeUserMem(_Pre_notnull_ __drv_freesMem(UserMem) PVOID pv)
#define BMF_TOPDOWN
Definition: winddi.h:1180
#define BMF_USERMEM
Definition: winddi.h:1183
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:28
#define BMF_NOZEROINIT
Definition: winddi.h:1181
#define ERROR_NO_SYSTEM_RESOURCES
Definition: winerror.h:931
#define BI_RLE8
Definition: wingdi.h:35

Referenced by GreGetDIBitsInternal(), IntCreateCompatibleBitmap(), and NtGdiCreateDIBSection().

◆ DIB_FreeConvertedBitmapInfo()

VOID FASTCALL DIB_FreeConvertedBitmapInfo ( BITMAPINFO converted,
BITMAPINFO orig,
DWORD  usage 
)

Definition at line 2282 of file dibobj.c.

2283{
2284 BITMAPCOREINFO* pbmci;
2285 if(converted == orig)
2286 return;
2287
2288 if(usage == -1)
2289 {
2290 /* Caller don't want any conversion */
2291 ExFreePoolWithTag(converted, TAG_DIB);
2292 return;
2293 }
2294
2295 /* Perform inverse conversion */
2296 pbmci = (BITMAPCOREINFO*)orig;
2297
2298 ASSERT(pbmci->bmciHeader.bcSize == sizeof(BITMAPCOREHEADER));
2299 pbmci->bmciHeader.bcBitCount = converted->bmiHeader.biBitCount;
2300 pbmci->bmciHeader.bcWidth = converted->bmiHeader.biWidth;
2301 pbmci->bmciHeader.bcHeight = converted->bmiHeader.biHeight;
2302 pbmci->bmciHeader.bcPlanes = converted->bmiHeader.biPlanes;
2303
2304 if(pbmci->bmciHeader.bcBitCount <= 8)
2305 {
2306 UINT numColors = converted->bmiHeader.biClrUsed;
2307 if(!numColors) numColors = 1 << pbmci->bmciHeader.bcBitCount;
2308 if(usage == DIB_PAL_COLORS)
2309 {
2310 RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(WORD));
2311 RtlCopyMemory(pbmci->bmciColors, converted->bmiColors, numColors * sizeof(WORD));
2312 }
2313 else
2314 {
2315 UINT i;
2316 RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(RGBTRIPLE));
2317 for(i=0; i<numColors; i++)
2318 {
2319 pbmci->bmciColors[i].rgbtRed = converted->bmiColors[i].rgbRed;
2320 pbmci->bmciColors[i].rgbtGreen = converted->bmiColors[i].rgbGreen;
2321 pbmci->bmciColors[i].rgbtBlue = converted->bmiColors[i].rgbBlue;
2322 }
2323 }
2324 }
2325 /* Now free it, it's not needed anymore */
2326 ExFreePoolWithTag(converted, TAG_DIB);
2327}
#define ASSERT(a)
Definition: mode.c:44
RGBTRIPLE bmciColors[1]
Definition: wingdi.h:1454
BYTE rgbtGreen
Definition: wingdi.h:1439
BYTE rgbtBlue
Definition: wingdi.h:1438
BYTE rgbtRed
Definition: wingdi.h:1440

Referenced by GreGetDIBitsInternal(), IntSynthesizeBitmap(), and UserLoadImage().

◆ DIB_GetBitmapInfo()

int FASTCALL DIB_GetBitmapInfo ( const BITMAPINFOHEADER header,
LONG width,
LONG height,
WORD planes,
WORD bpp,
DWORD compr,
DWORD size 
)

Definition at line 2098 of file dibobj.c.

2100{
2101 if (header->biSize == sizeof(BITMAPCOREHEADER))
2102 {
2103 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
2104 *width = core->bcWidth;
2105 *height = core->bcHeight;
2106 *planes = core->bcPlanes;
2107 *bpp = core->bcBitCount;
2108 *compr = BI_RGB;
2109 *size = 0;
2110 return 0;
2111 }
2112 if (header->biSize >= sizeof(BITMAPINFOHEADER)) /* Assume BITMAPINFOHEADER */
2113 {
2114 *width = header->biWidth;
2115 *height = header->biHeight;
2116 *planes = header->biPlanes;
2117 *bpp = header->biBitCount;
2118 *compr = header->biCompression;
2119 *size = header->biSizeImage;
2120 return 1;
2121 }
2122 DPRINT1("(%u): unknown/wrong size for header\n", header->biSize );
2123 return -1;
2124}
DWORD bpp
Definition: surface.c:185
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
static int __cdecl compr(const void *a, const void *b)
Definition: bidi.c:641

Referenced by GreGetDIBitsInternal().

◆ DIB_GetDIBImageBytes()

INT APIENTRY DIB_GetDIBImageBytes ( INT  width,
INT  height,
INT  depth 
)

Definition at line 2133 of file dibobj.c.

2134{
2135 return WIDTH_BYTES_ALIGN32(width, depth) * (height < 0 ? -height : height);
2136}
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546

Referenced by DIB_ConvertBitmapInfo(), GreGetDIBitsInternal(), and IntSetDIBits().

◆ DIB_MapPaletteColors()

HPALETTE FASTCALL DIB_MapPaletteColors ( PPALETTE  ppalDc,
CONST BITMAPINFO lpbmi 
)

Definition at line 2174 of file dibobj.c.

2175{
2176 PPALETTE ppalNew;
2177 ULONG nNumColors,i;
2178 USHORT *lpIndex;
2179 HPALETTE hpal;
2180
2181 if (!(ppalDc->flFlags & PAL_INDEXED))
2182 {
2183 return NULL;
2184 }
2185
2186 nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
2187 if (lpbmi->bmiHeader.biClrUsed)
2188 {
2189 nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
2190 }
2191
2192 ppalNew = PALETTE_AllocPalWithHandle(PAL_INDEXED, nNumColors, NULL, 0, 0, 0);
2193 if (ppalNew == NULL)
2194 {
2195 DPRINT1("Could not allocate palette\n");
2196 return NULL;
2197 }
2198
2199 lpIndex = (USHORT *)((PBYTE)lpbmi + lpbmi->bmiHeader.biSize);
2200
2201 for (i = 0; i < nNumColors; i++)
2202 {
2203 ULONG iColorIndex = *lpIndex % ppalDc->NumColors;
2204 ppalNew->IndexedColors[i] = ppalDc->IndexedColors[iColorIndex];
2205 lpIndex++;
2206 }
2207
2208 hpal = ppalNew->BaseObject.hHmgr;
2209 PALETTE_UnlockPalette(ppalNew);
2210
2211 return hpal;
2212}
HGDIOBJ hHmgr(VOID)
Definition: baseobj.hpp:95
BYTE * PBYTE
Definition: pedump.c:66
unsigned short USHORT
Definition: pedump.c:61
BASEOBJECT BaseObject
Definition: palette.h:36
PALETTEENTRY * IndexedColors
Definition: palette.h:42
PPALETTE NTAPI PALETTE_AllocPalWithHandle(_In_ ULONG iMode, _In_ ULONG cColors, _In_opt_ const PALETTEENTRY *pEntries, _In_ FLONG flRed, _In_ FLONG flGreen, _In_ FLONG flBlue)
Definition: palette.c:209
#define PALETTE_UnlockPalette(pPalette)
Definition: palette.h:56

◆ GreCreateDIBitmapFromPackedDIB()

HBITMAP NTAPI GreCreateDIBitmapFromPackedDIB ( _In_reads_(cjPackedDIB) PVOID  pvPackedDIB,
_In_ UINT  cjPackedDIB,
_In_ ULONG  uUsage 
)

Definition at line 1773 of file dibobj.c.

1777{
1779 PBYTE pjBits;
1780 UINT cjInfo, cjBits;
1781 HBITMAP hbm;
1782
1783 /* We only support BITMAPINFOHEADER, make sure the size is ok */
1784 if (cjPackedDIB < sizeof(BITMAPINFOHEADER))
1785 {
1786 return NULL;
1787 }
1788
1789 /* The packed DIB starts with the BITMAPINFOHEADER */
1790 pbmi = pvPackedDIB;
1791
1792 if (cjPackedDIB < pbmi->bmiHeader.biSize)
1793 {
1794 return NULL;
1795 }
1796
1797 /* Calculate the info size and make sure the packed DIB is large enough */
1798 cjInfo = DIB_BitmapInfoSize(pbmi, uUsage);
1799 if (cjPackedDIB <= cjInfo)
1800 {
1801 return NULL;
1802 }
1803
1804 /* The bitmap bits start after the header */
1805 pjBits = (PBYTE)pvPackedDIB + cjInfo;
1806 cjBits = cjPackedDIB - cjInfo;
1807
1812 pjBits,
1813 pbmi,
1814 uUsage,
1815 0,
1816 cjBits,
1817 NULL);
1818
1819 return hbm;
1820}
#define CBM_CREATDIB
HBITMAP NTAPI GreCreateDIBitmapInternal(IN HDC hDc, IN INT cx, IN INT cy, IN DWORD fInit, IN OPTIONAL LPBYTE pjInit, IN OPTIONAL PBITMAPINFO pbmi, IN DWORD iUsage, IN FLONG fl, IN UINT cjMaxBits, IN HANDLE hcmXform)
Definition: dibobj.c:1697
#define CBM_INIT
Definition: wingdi.h:365

Referenced by NtGdiCreateDIBBrush().

◆ GreCreateDIBitmapInternal()

HBITMAP NTAPI GreCreateDIBitmapInternal ( IN HDC  hDc,
IN INT  cx,
IN INT  cy,
IN DWORD  fInit,
IN OPTIONAL LPBYTE  pjInit,
IN OPTIONAL PBITMAPINFO  pbmi,
IN DWORD  iUsage,
IN FLONG  fl,
IN UINT  cjMaxBits,
IN HANDLE  hcmXform 
)

Definition at line 1697 of file dibobj.c.

1708{
1709 PDC Dc;
1710 HBITMAP Bmp;
1711 USHORT bpp, planes;
1713 HDC hdcDest;
1714
1715 if (!hDc) /* 1bpp monochrome bitmap */
1716 {
1717 // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
1718 hdcDest = NtGdiCreateCompatibleDC(0);
1719 if(!hdcDest)
1720 {
1721 DPRINT1("NtGdiCreateCompatibleDC failed\n");
1722 return NULL;
1723 }
1724 }
1725 else
1726 {
1727 hdcDest = hDc;
1728 }
1729
1730 Dc = DC_LockDc(hdcDest);
1731 if (!Dc)
1732 {
1733 DPRINT1("Failed to lock hdcDest %p\n", hdcDest);
1735 return NULL;
1736 }
1737 /* It's OK to set bpp=0 here, as IntCreateDIBitmap will create a compatible Bitmap
1738 * if bpp != 1 and ignore the real value that was passed */
1739 if (pbmi)
1740 {
1741 if (pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1742 {
1744 bpp = CoreHeader->bcBitCount;
1745 planes = CoreHeader->bcPlanes ? CoreHeader->bcPlanes : 1;
1747 }
1748 else
1749 {
1751 planes = pbmi->bmiHeader.biPlanes ? pbmi->bmiHeader.biPlanes : 1;
1753 }
1754 }
1755 else
1756 {
1757 bpp = 0;
1758 planes = 0;
1759 compression = 0;
1760 }
1761 Bmp = IntCreateDIBitmap(Dc, cx, cy, planes, bpp, compression, fInit, pjInit, cjMaxBits, pbmi, iUsage);
1762 DC_UnlockDc(Dc);
1763
1764 if(!hDc)
1765 {
1766 NtGdiDeleteObjectApp(hdcDest);
1767 }
1768 return Bmp;
1769}
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY _In_ uint8_t compression
Definition: btrfs_drv.h:1365
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:238
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:220
HBITMAP FASTCALL IntCreateDIBitmap(PDC Dc, INT width, INT height, UINT planes, UINT bpp, ULONG compression, DWORD init, LPBYTE bits, ULONG cjMaxBits, PBITMAPINFO data, DWORD coloruse)
Definition: dibobj.c:1519
static HDC
Definition: imagelist.c:92
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiDeleteObjectApp(_In_ HANDLE hobj)
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
_Out_opt_ int * cx
Definition: commctrl.h:585
Definition: polytest.cpp:41

Referenced by GreCreateDIBitmapFromPackedDIB(), IntSynthesizeBitmap(), NtGdiCreateDIBitmapInternal(), and UserLoadImage().

◆ GreGetDIBitsInternal()

INT APIENTRY GreGetDIBitsInternal ( HDC  hDC,
HBITMAP  hBitmap,
UINT  StartScan,
UINT  ScanLines,
LPBYTE  Bits,
LPBITMAPINFO  Info,
UINT  Usage,
UINT  MaxBits,
UINT  MaxInfo 
)

Definition at line 694 of file dibobj.c.

704{
705 BITMAPCOREINFO* pbmci = NULL;
706 PSURFACE psurf = NULL;
707 PDC pDC;
709 WORD planes, bpp;
710 DWORD compr, size ;
711 USHORT i;
712 int bitmap_type;
713 RGBQUAD* rgbQuads;
714 VOID* colorPtr;
715
716 DPRINT("Entered GreGetDIBitsInternal()\n");
717
718 if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap)
719 return 0;
720
721 pDC = DC_LockDc(hDC);
722 if (pDC == NULL || pDC->dctype == DCTYPE_INFO)
723 {
724 ScanLines = 0;
725 goto done;
726 }
727
728 /* Get a pointer to the source bitmap object */
730 if (psurf == NULL)
731 {
732 ScanLines = 0;
733 goto done;
734 }
735
736 colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize;
737 rgbQuads = colorPtr;
738
739 bitmap_type = DIB_GetBitmapInfo(&Info->bmiHeader,
740 &width,
741 &height,
742 &planes,
743 &bpp,
744 &compr,
745 &size);
746 if(bitmap_type == -1)
747 {
748 DPRINT1("Wrong bitmap format\n");
750 ScanLines = 0;
751 goto done;
752 }
753 else if(bitmap_type == 0)
754 {
755 /* We need a BITMAPINFO to create a DIB, but we have to fill
756 * the BITMAPCOREINFO we're provided */
757 pbmci = (BITMAPCOREINFO*)Info;
758 /* fill in the the bit count, so we can calculate the right ColorsSize during the conversion */
761 if(Info == NULL)
762 {
763 DPRINT1("Error, could not convert the BITMAPCOREINFO!\n");
764 ScanLines = 0;
765 goto done;
766 }
767 rgbQuads = Info->bmiColors;
768 }
769
770 /* Validate input:
771 - negative width is always an invalid value
772 - non-null Bits and zero bpp is an invalid combination
773 - only check the rest of the input params if either bpp is non-zero or Bits are set */
774 if (width < 0 || (bpp == 0 && Bits))
775 {
776 ScanLines = 0;
777 goto done;
778 }
779
780 if (Bits || bpp)
781 {
782 if ((height == 0 || width == 0) || (compr && compr != BI_BITFIELDS && compr != BI_RGB))
783 {
784 ScanLines = 0;
785 goto done;
786 }
787 }
788
789 Info->bmiHeader.biClrUsed = 0;
790 Info->bmiHeader.biClrImportant = 0;
791
792 /* Fill in the structure */
793 switch(bpp)
794 {
795 case 0: /* Only info */
796 Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
797 Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
798 -psurf->SurfObj.sizlBitmap.cy :
799 psurf->SurfObj.sizlBitmap.cy;
800 Info->bmiHeader.biPlanes = 1;
801 Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
802 Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( Info->bmiHeader.biWidth,
803 Info->bmiHeader.biHeight,
804 Info->bmiHeader.biBitCount);
805 Info->bmiHeader.biCompression = (Info->bmiHeader.biBitCount == 16 || Info->bmiHeader.biBitCount == 32) ?
807 Info->bmiHeader.biXPelsPerMeter = 0;
808 Info->bmiHeader.biYPelsPerMeter = 0;
809
810 if (Info->bmiHeader.biBitCount <= 8 && Info->bmiHeader.biClrUsed == 0)
811 Info->bmiHeader.biClrUsed = 1 << Info->bmiHeader.biBitCount;
812
813 ScanLines = 1;
814 goto done;
815
816 case 1:
817 case 4:
818 case 8:
819 Info->bmiHeader.biClrUsed = 1 << bpp;
820
821 /* If the bitmap is a DIB section and has the same format as what
822 * is requested, go ahead! */
823 if((psurf->hSecure) &&
825 {
826 if(Usage == DIB_RGB_COLORS)
827 {
828 ULONG colors = min(psurf->ppal->NumColors, 256);
829 if(colors != 256) Info->bmiHeader.biClrUsed = colors;
830 for(i = 0; i < colors; i++)
831 {
832 rgbQuads[i].rgbRed = psurf->ppal->IndexedColors[i].peRed;
833 rgbQuads[i].rgbGreen = psurf->ppal->IndexedColors[i].peGreen;
834 rgbQuads[i].rgbBlue = psurf->ppal->IndexedColors[i].peBlue;
835 rgbQuads[i].rgbReserved = 0;
836 }
837 }
838 else
839 {
840 for(i = 0; i < 256; i++)
841 ((WORD*)rgbQuads)[i] = i;
842 }
843 }
844 else
845 {
846 if(Usage == DIB_PAL_COLORS)
847 {
848 for(i = 0; i < 256; i++)
849 {
850 ((WORD*)rgbQuads)[i] = i;
851 }
852 }
853 else if(bpp > 1 && bpp == BitsPerFormat(psurf->SurfObj.iBitmapFormat))
854 {
855 /* For color DDBs in native depth (mono DDBs always have
856 a black/white palette):
857 Generate the color map from the selected palette */
858 PPALETTE pDcPal = PALETTE_ShareLockPalette(pDC->dclevel.hpal);
859 if(!pDcPal)
860 {
861 ScanLines = 0 ;
862 goto done ;
863 }
864 for (i = 0; i < pDcPal->NumColors; i++)
865 {
866 rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
867 rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
868 rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
869 rgbQuads[i].rgbReserved = 0;
870 }
872 }
873 else
874 {
875 switch (bpp)
876 {
877 case 1:
878 rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = rgbQuads[0].rgbBlue = 0;
879 rgbQuads[0].rgbReserved = 0;
880 rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = rgbQuads[1].rgbBlue = 0xff;
881 rgbQuads[1].rgbReserved = 0;
882 break;
883
884 case 4:
885 /* The EGA palette is the first and last 8 colours of the default palette
886 with the innermost pair swapped */
887 RtlCopyMemory(rgbQuads, DefLogPaletteQuads, 7 * sizeof(RGBQUAD));
888 RtlCopyMemory(rgbQuads + 7, DefLogPaletteQuads + 12, 1 * sizeof(RGBQUAD));
889 RtlCopyMemory(rgbQuads + 8, DefLogPaletteQuads + 7, 1 * sizeof(RGBQUAD));
890 RtlCopyMemory(rgbQuads + 9, DefLogPaletteQuads + 13, 7 * sizeof(RGBQUAD));
891 break;
892
893 case 8:
894 {
895 INT i;
896
897 memcpy(rgbQuads, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
898 memcpy(rgbQuads + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
899
900 for (i = 10; i < 246; i++)
901 {
902 rgbQuads[i].rgbRed = (i & 0x07) << 5;
903 rgbQuads[i].rgbGreen = (i & 0x38) << 2;
904 rgbQuads[i].rgbBlue = i & 0xc0;
905 rgbQuads[i].rgbReserved = 0;
906 }
907 }
908 }
909 }
910 }
911 break;
912
913 case 15:
914 if (Info->bmiHeader.biCompression == BI_BITFIELDS)
915 {
916 ((PDWORD)Info->bmiColors)[0] = 0x7c00;
917 ((PDWORD)Info->bmiColors)[1] = 0x03e0;
918 ((PDWORD)Info->bmiColors)[2] = 0x001f;
919 }
920 break;
921
922 case 16:
923 if (Info->bmiHeader.biCompression == BI_BITFIELDS)
924 {
925 if (psurf->hSecure)
926 {
927 ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
928 ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
929 ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
930 }
931 else
932 {
933 ((PDWORD)Info->bmiColors)[0] = 0xf800;
934 ((PDWORD)Info->bmiColors)[1] = 0x07e0;
935 ((PDWORD)Info->bmiColors)[2] = 0x001f;
936 }
937 }
938 break;
939
940 case 24:
941 case 32:
942 if (Info->bmiHeader.biCompression == BI_BITFIELDS)
943 {
944 if (psurf->hSecure)
945 {
946 ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
947 ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
948 ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
949 }
950 else
951 {
952 ((PDWORD)Info->bmiColors)[0] = 0xff0000;
953 ((PDWORD)Info->bmiColors)[1] = 0x00ff00;
954 ((PDWORD)Info->bmiColors)[2] = 0x0000ff;
955 }
956 }
957 break;
958
959 default:
960 ScanLines = 0;
961 goto done;
962 }
963
964 Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
965 Info->bmiHeader.biPlanes = 1;
966
967 if(Bits && ScanLines)
968 {
969 /* Create a DIBSECTION, blt it, profit */
970 PVOID pDIBits ;
971 HBITMAP hBmpDest;
972 PSURFACE psurfDest;
973 EXLATEOBJ exlo;
974 RECT rcDest;
975 POINTL srcPoint;
976 BOOL ret ;
977 int newLines = -1;
978
979 if (StartScan >= abs(Info->bmiHeader.biHeight))
980 {
981 ScanLines = 1;
982 goto done;
983 }
984 else
985 {
986 ScanLines = min(ScanLines, abs(Info->bmiHeader.biHeight) - StartScan);
987 }
988
989 if (abs(Info->bmiHeader.biHeight) < psurf->SurfObj.sizlBitmap.cy)
990 {
991 StartScan += psurf->SurfObj.sizlBitmap.cy - abs(Info->bmiHeader.biHeight);
992 }
993 /* Fixup values */
994 Info->bmiHeader.biHeight = (height < 0) ?
995 -(LONG)ScanLines : ScanLines;
996 /* Create the DIB */
997 hBmpDest = DIB_CreateDIBSection(pDC, Info, Usage, &pDIBits, NULL, 0, 0);
998 /* Restore them */
999 Info->bmiHeader.biHeight = height;
1000
1001 if(!hBmpDest)
1002 {
1003 DPRINT1("Unable to create a DIB Section!\n");
1005 ScanLines = 0;
1006 goto done ;
1007 }
1008
1009 psurfDest = SURFACE_ShareLockSurface(hBmpDest);
1010
1011 RECTL_vSetRect(&rcDest, 0, 0, Info->bmiHeader.biWidth, ScanLines);
1012 Info->bmiHeader.biWidth = width;
1013 srcPoint.x = 0;
1014
1015 if (abs(Info->bmiHeader.biHeight) <= psurf->SurfObj.sizlBitmap.cy)
1016 {
1017 srcPoint.y = psurf->SurfObj.sizlBitmap.cy - StartScan - ScanLines;
1018 }
1019 else
1020 {
1021 /* Determine the actual number of lines copied from the */
1022 /* original bitmap. It might be different from ScanLines. */
1023 newLines = abs(Info->bmiHeader.biHeight) - psurf->SurfObj.sizlBitmap.cy;
1024 newLines = min((int)(StartScan + ScanLines - newLines), psurf->SurfObj.sizlBitmap.cy);
1025 if (newLines > 0)
1026 {
1027 srcPoint.y = psurf->SurfObj.sizlBitmap.cy - newLines;
1028 if (StartScan > psurf->SurfObj.sizlBitmap.cy)
1029 {
1030 newLines -= (StartScan - psurf->SurfObj.sizlBitmap.cy);
1031 }
1032 }
1033 else
1034 {
1035 newLines = 0;
1036 srcPoint.y = psurf->SurfObj.sizlBitmap.cy;
1037 }
1038 }
1039
1040 EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0xffffff, 0xffffff, 0);
1041
1042 ret = IntEngCopyBits(&psurfDest->SurfObj,
1043 &psurf->SurfObj,
1044 NULL,
1045 &exlo.xlo,
1046 &rcDest,
1047 &srcPoint);
1048
1049 SURFACE_ShareUnlockSurface(psurfDest);
1050
1051 if(!ret)
1052 ScanLines = 0;
1053 else
1054 {
1055 RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, ScanLines, bpp));
1056 }
1057 /* Update if line count has changed */
1058 if (newLines != -1)
1059 {
1060 ScanLines = (UINT)newLines;
1061 }
1062 GreDeleteObject(hBmpDest);
1063 EXLATEOBJ_vCleanup(&exlo);
1064 }
1065 else
1066 {
1067 /* Signals success and not the actual number of scan lines*/
1068 ScanLines = 1;
1069 }
1070
1071done:
1072
1073 if (pbmci)
1075
1076 if (psurf)
1078
1079 if (pDC)
1080 DC_UnlockDc(pDC);
1081
1082 return ScanLines;
1083}
static HDC hDC
Definition: 3dtext.c:33
BOOL APIENTRY IntEngCopyBits(SURFOBJ *psoTrg, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclTrg, POINTL *pptlSrc)
Definition: bitblt_new.c:678
@ DCTYPE_INFO
Definition: dc.h:43
static const RGBQUAD DefLogPaletteQuads[20]
Definition: dibobj.c:14
BITMAPINFO *FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO *pbmi, DWORD Usage)
Definition: dibobj.c:2218
int FASTCALL DIB_GetBitmapInfo(const BITMAPINFOHEADER *header, LONG *width, LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size)
Definition: dibobj.c:2098
VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO *converted, BITMAPINFO *orig, DWORD usage)
Definition: dibobj.c:2282
HBITMAP APIENTRY DIB_CreateDIBSection(PDC dc, CONST BITMAPINFO *bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch)
Definition: dibobj.c:1891
static HBITMAP hBitmap
Definition: timezone.c:26
unsigned int BOOL
Definition: ntddk_ex.h:94
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
long LONG
Definition: pedump.c:60
XLATEOBJ xlo
Definition: xlateobj.h:21
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
SURFOBJ SurfObj
Definition: surface.h:8
HANDLE hSecure
Definition: surface.h:32
struct _PALETTE *const ppal
Definition: surface.h:11
USHORT fjBitmap
Definition: winddi.h:1217
SIZEL sizlBitmap
Definition: winddi.h:1209
ULONG iBitmapFormat
Definition: winddi.h:1215
unsigned char * LPBYTE
Definition: typedefs.h:53
int ret
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
#define BitsPerFormat(Format)
Definition: surface.h:109
#define PALETTE_ShareLockPalette(hpal)
Definition: palette.h:57
FORCEINLINE VOID RECTL_vSetRect(_Out_ RECTL *prcl, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
Definition: rect.h:5
VOID NTAPI EXLATEOBJ_vInitialize(_Out_ PEXLATEOBJ pexlo, _In_opt_ PALETTE *ppalSrc, _In_opt_ PALETTE *ppalDst, _In_ COLORREF crSrcBackColor, _In_ COLORREF crDstBackColor, _In_ COLORREF crDstForeColor)
Definition: xlateobj.c:358
VOID NTAPI EXLATEOBJ_vCleanup(_Inout_ PEXLATEOBJ pexlo)
Definition: xlateobj.c:649

Referenced by _Success_(), and IntSynthesizeDib().

◆ IntCreateDIBitmap()

HBITMAP FASTCALL IntCreateDIBitmap ( PDC  Dc,
INT  width,
INT  height,
UINT  planes,
UINT  bpp,
ULONG  compression,
DWORD  init,
LPBYTE  bits,
ULONG  cjMaxBits,
PBITMAPINFO  data,
DWORD  coloruse 
)

Definition at line 1519 of file dibobj.c.

1531{
1533 BOOL fColor;
1534 ULONG BmpFormat = 0;
1535
1536 if (planes && bpp)
1537 BmpFormat = BitmapFormat(planes * bpp, compression);
1538
1539 // Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
1540 // colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.
1541
1542 if (BmpFormat != BMF_1BPP) fColor = TRUE;
1543 else if ((coloruse > DIB_RGB_COLORS) || ((init & CBM_INIT) == 0) || !data) fColor = FALSE;
1544 else
1545 {
1546 const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize);
1547 DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
1548
1549 // Check if the first color of the colormap is black
1550 if (col == RGB(0, 0, 0))
1551 {
1552 rgb++;
1553 col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
1554
1555 // If the second color is white, create a monochrome bitmap
1556 fColor = (col != RGB(0xff,0xff,0xff));
1557 }
1558 else fColor = TRUE;
1559 }
1560
1561 // Now create the bitmap
1562 if (fColor)
1563 {
1564 if (init & CBM_CREATDIB)
1565 {
1566 PSURFACE Surface;
1567 PPALETTE Palette;
1568
1569 /* Undocumented flag which creates a DDB of the format specified by the bitmap info. */
1571 if (!handle)
1572 {
1573 DPRINT1("IntCreateCompatibleBitmap() failed!\n");
1574 return NULL;
1575 }
1576
1577 /* The palette must also match the given data */
1579 ASSERT(Surface);
1580 Palette = CreateDIBPalette(data, Dc, coloruse);
1581 if (Palette == NULL)
1582 {
1585 return NULL;
1586 }
1587
1588 SURFACE_vSetPalette(Surface, Palette);
1589
1592 }
1593 else
1594 {
1595 /* Create a regular compatible bitmap, in the same format as the device */
1597 }
1598 }
1599 else
1600 {
1602 abs(height),
1603 1,
1604 1,
1605 NULL);
1606 }
1607
1608 if (height < 0)
1609 height = -height;
1610
1611 if ((NULL != handle) && (CBM_INIT & init))
1612 {
1613 IntSetDIBits(Dc, handle, 0, height, bits, cjMaxBits, data, coloruse);
1614 }
1615
1616 return handle;
1617}
HBITMAP FASTCALL IntCreateCompatibleBitmap(PDC Dc, INT Width, INT Height, UINT Planes, UINT Bpp)
Definition: bitmaps.c:273
HBITMAP NTAPI GreCreateBitmap(_In_ ULONG nWidth, _In_ ULONG nHeight, _In_ ULONG cPlanes, _In_ ULONG cBitsPixel, _In_opt_ PVOID pvBits)
Definition: bitmaps.c:172
static INT FASTCALL IntSetDIBits(PDC DC, HBITMAP hBitmap, UINT StartScan, UINT ScanLines, CONST VOID *Bits, ULONG cjMaxBits, CONST BITMAPINFO *bmi, UINT ColorUse)
Definition: dibobj.c:239
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define BMF_1BPP
Definition: winddi.h:355
static int init
Definition: wintirpc.c:33

Referenced by GreCreateDIBitmapInternal().

◆ IntGdiCreateMaskFromRLE()

static HBITMAP IntGdiCreateMaskFromRLE ( DWORD  Width,
DWORD  Height,
ULONG  Compression,
const BYTE Bits,
DWORD  BitsSize 
)
static

Definition at line 360 of file dibobj.c.

366{
368 DWORD x, y;
369 SURFOBJ* SurfObj;
370 UINT i = 0;
371 BYTE Data, NumPixels, ToSkip;
372
373 ASSERT((Compression == BI_RLE8) || (Compression == BI_RLE4));
374
375 /* Create the bitmap */
377 if (!Mask)
378 return NULL;
379
380 SurfObj = EngLockSurface((HSURF)Mask);
381 if (!SurfObj)
382 {
384 return NULL;
385 }
386 ASSERT(SurfObj->pvBits != NULL);
387
388 x = y = 0;
389
390 while (i < BitsSize)
391 {
392 NumPixels = Bits[i];
393 Data = Bits[i + 1];
394 i += 2;
395
396 if (NumPixels != 0)
397 {
398 if ((x + NumPixels) > Width)
399 NumPixels = Width - x;
400
401 if (NumPixels == 0)
402 continue;
403
404 DIB_1BPP_HLine(SurfObj, x, x + NumPixels, y, 1);
405 x += NumPixels;
406 continue;
407 }
408
409 if (Data < 3)
410 {
411 switch (Data)
412 {
413 case 0:
414 /* End of line */
415 y++;
416 if (y == Height)
417 goto done;
418 x = 0;
419 break;
420 case 1:
421 /* End of file */
422 goto done;
423 case 2:
424 /* Jump */
425 if (i >= (BitsSize - 1))
426 goto done;
427 x += Bits[i];
428 if (x > Width)
429 x = Width;
430 y += Bits[i + 1];
431 if (y >= Height)
432 goto done;
433 i += 2;
434 break;
435 }
436 /* Done for this run */
437 continue;
438 }
439
440 /* Embedded data into the RLE */
441 NumPixels = Data;
442 if (Compression == BI_RLE8)
443 ToSkip = NumPixels;
444 else
445 ToSkip = (NumPixels / 2) + (NumPixels & 1);
446
447 if ((i + ToSkip) > BitsSize)
448 goto done;
449 ToSkip = (ToSkip + 1) & ~1;
450
451 if ((x + NumPixels) > Width)
452 NumPixels = Width - x;
453
454 if (NumPixels != 0)
455 {
456 DIB_1BPP_HLine(SurfObj, x, x + NumPixels, y, 1);
457 x += NumPixels;
458 }
459 i += ToSkip;
460 }
461
462done:
463 EngUnlockSurface(SurfObj);
464 return Mask;
465}
unsigned int Mask
Definition: fpcontrol.c:82
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
PVOID pvBits
Definition: winddi.h:1211
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:126
_In_ HFONT _Out_ PUINT Height
Definition: font.h:125
VOID DIB_1BPP_HLine(SURFOBJ *, LONG, LONG, LONG, ULONG)
Definition: dib1bpp.c:38
ENGAPI SURFOBJ *APIENTRY EngLockSurface(_In_ HSURF hsurf)
Definition: surface.c:607
typedef HSURF(APIENTRY FN_DrvEnableSurface)(_In_ DHPDEV dhpdev)
ENGAPI VOID APIENTRY EngUnlockSurface(_In_ _Post_ptr_invalid_ SURFOBJ *pso)
Definition: surface.c:628
unsigned char BYTE
Definition: xxhash.c:193

Referenced by NtGdiSetDIBitsToDeviceInternal().

◆ IntSetDIBits()

static INT FASTCALL IntSetDIBits ( PDC  DC,
HBITMAP  hBitmap,
UINT  StartScan,
UINT  ScanLines,
CONST VOID Bits,
ULONG  cjMaxBits,
CONST BITMAPINFO bmi,
UINT  ColorUse 
)
static

Definition at line 239 of file dibobj.c.

248{
249 HBITMAP SourceBitmap;
250 PSURFACE psurfDst, psurfSrc;
251 INT result = 0;
252 RECT rcDst;
253 POINTL ptSrc;
254 EXLATEOBJ exlo;
255 PPALETTE ppalDIB = 0;
256 ULONG cjSizeImage;
257
258 if (!bmi || !Bits) return 0;
259
260 /* Check for uncompressed formats */
261 if ((bmi->bmiHeader.biCompression == BI_RGB) ||
262 (bmi->bmiHeader.biCompression == BI_BITFIELDS))
263 {
264 /* Calculate the image size */
265 cjSizeImage = DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
266 ScanLines,
267 bmi->bmiHeader.biBitCount);
268 }
269 /* Check if the header provided an image size */
270 else if (bmi->bmiHeader.biSizeImage != 0)
271 {
272 /* Use the given size */
273 cjSizeImage = bmi->bmiHeader.biSizeImage;
274 }
275 else
276 {
277 /* Compressed format without a size. This is invalid. */
278 DPRINT1("Compressed format without a size!");
279 return 0;
280 }
281
282 /* Check if the size that we have is ok */
283 if ((cjSizeImage > cjMaxBits) || (cjSizeImage == 0))
284 {
285 DPRINT1("Invalid bitmap size! cjSizeImage = %lu, cjMaxBits = %lu\n",
286 cjSizeImage, cjMaxBits);
287 return 0;
288 }
289
290 SourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
291 ScanLines,
292 0,
293 BitmapFormat(bmi->bmiHeader.biBitCount,
294 bmi->bmiHeader.biCompression),
295 bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
296 cjSizeImage,
297 (PVOID)Bits,
298 0);
299 if (!SourceBitmap)
300 {
301 DPRINT1("Error: Could not create a bitmap.\n");
303 return 0;
304 }
305
307 psurfSrc = SURFACE_ShareLockSurface(SourceBitmap);
308
309 if(!(psurfSrc && psurfDst))
310 {
311 DPRINT1("Error: Could not lock surfaces\n");
312 goto cleanup;
313 }
314
315 /* Create a palette for the DIB */
316 ppalDIB = CreateDIBPalette(bmi, DC, ColorUse);
317 if (!ppalDIB)
318 {
320 goto cleanup;
321 }
322
323 /* Initialize EXLATEOBJ */
325 ppalDIB,
326 psurfDst->ppal,
327 RGB(0xff, 0xff, 0xff),
328 RGB(0xff, 0xff, 0xff), //DC->pdcattr->crBackgroundClr,
329 0); // DC->pdcattr->crForegroundClr);
330
331 rcDst.top = StartScan;
332 rcDst.left = 0;
333 rcDst.bottom = rcDst.top + ScanLines;
334 rcDst.right = psurfDst->SurfObj.sizlBitmap.cx;
335 ptSrc.x = 0;
336 ptSrc.y = 0;
337
338 result = IntEngCopyBits(&psurfDst->SurfObj,
339 &psurfSrc->SurfObj,
340 NULL,
341 &exlo.xlo,
342 &rcDst,
343 &ptSrc);
344 if(result)
345 result = ScanLines;
346
347 EXLATEOBJ_vCleanup(&exlo);
348
349cleanup:
350 if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
351 if(psurfSrc) SURFACE_ShareUnlockSurface(psurfSrc);
352 if(psurfDst) SURFACE_ShareUnlockSurface(psurfDst);
353 GreDeleteObject(SourceBitmap);
354
355 return result;
356}
GLuint64EXT * result
Definition: glext.h:11304
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306

Referenced by IntCreateDIBitmap(), and NtGdiStretchDIBitsInternal().

◆ NtGdiCreateDIBitmapInternal()

HBITMAP APIENTRY NtGdiCreateDIBitmapInternal ( IN HDC  hDc,
IN INT  cx,
IN INT  cy,
IN DWORD  fInit,
IN OPTIONAL LPBYTE  pjInit,
IN OPTIONAL LPBITMAPINFO  pbmi,
IN DWORD  iUsage,
IN UINT  cjMaxInitInfo,
IN UINT  cjMaxBits,
IN FLONG  fl,
IN HANDLE  hcmXform 
)

Definition at line 1623 of file dibobj.c.

1635{
1637 PBYTE safeBits = NULL;
1638 HBITMAP hbmResult = NULL;
1639
1640 if (pjInit == NULL)
1641 {
1642 fInit &= ~CBM_INIT;
1643 }
1644
1645 if(pjInit && (fInit & CBM_INIT))
1646 {
1647 if (cjMaxBits == 0) return NULL;
1649 if(!safeBits)
1650 {
1651 DPRINT1("Failed to allocate %lu bytes\n", cjMaxBits);
1653 return NULL;
1654 }
1655 }
1656
1657 _SEH2_TRY
1658 {
1659 if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
1660 if(pjInit && (fInit & CBM_INIT))
1661 {
1662 ProbeForRead(pjInit, cjMaxBits, 1);
1663 RtlCopyMemory(safeBits, pjInit, cjMaxBits);
1664 }
1665 }
1667 {
1669 }
1670 _SEH2_END;
1671
1672 if(!NT_SUCCESS(Status))
1673 {
1674 DPRINT1("Got an exception! pjInit = %p\n", pjInit);
1676 goto cleanup;
1677 }
1678
1679 hbmResult = GreCreateDIBitmapInternal(hDc,
1680 cx,
1681 cy,
1682 fInit,
1683 safeBits,
1684 pbmi,
1685 iUsage,
1686 fl,
1687 cjMaxBits,
1688 hcmXform);
1689
1690cleanup:
1691 if (safeBits) ExFreePoolWithTag(safeBits, TAG_DIB);
1692 return hbmResult;
1693}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:37
_In_ FLONG fl
Definition: winddi.h:1279
_In_ HANDLE hcmXform
Definition: winddi.h:3687

◆ NtGdiCreateDIBSection()

HBITMAP APIENTRY NtGdiCreateDIBSection ( IN HDC  hDC,
IN OPTIONAL HANDLE  hSection,
IN DWORD  dwOffset,
IN BITMAPINFO bmi,
IN DWORD  Usage,
IN UINT  cjHeader,
IN FLONG  fl,
IN ULONG_PTR  dwColorSpace,
OUT PVOID Bits 
)

Definition at line 1824 of file dibobj.c.

1834{
1835 HBITMAP hbitmap = 0;
1836 DC *dc;
1837 BOOL bDesktopDC = FALSE;
1839
1840 if (!bmi) return hbitmap; // Make sure.
1841
1842 _SEH2_TRY
1843 {
1844 ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
1845 ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
1846 ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, (WORD)Usage), 1);
1847 }
1849 {
1851 }
1852 _SEH2_END;
1853
1854 if(!NT_SUCCESS(Status))
1855 {
1857 return NULL;
1858 }
1859
1860 // If the reference hdc is null, take the desktop dc
1861 if (hDC == 0)
1862 {
1864 bDesktopDC = TRUE;
1865 }
1866
1867 if ((dc = DC_LockDc(hDC)))
1868 {
1870 bmi,
1871 Usage,
1872 Bits,
1873 hSection,
1874 dwOffset,
1875 0);
1876 DC_UnlockDc(dc);
1877 }
1878 else
1879 {
1881 }
1882
1883 if (bDesktopDC)
1885
1886 return hbitmap;
1887}
static HBITMAP hbitmap
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2033
_In_ const BITMAPINFO _In_ UINT _In_opt_ HANDLE hSection
Definition: wingdi.h:3239

◆ NtGdiSetDIBitsToDeviceInternal()

W32KAPI INT APIENTRY NtGdiSetDIBitsToDeviceInternal ( IN HDC  hDC,
IN INT  XDest,
IN INT  YDest,
IN DWORD  Width,
IN DWORD  Height,
IN INT  XSrc,
IN INT  YSrc,
IN DWORD  StartScan,
IN DWORD  ScanLines,
IN LPBYTE  Bits,
IN LPBITMAPINFO  bmi,
IN DWORD  ColorUse,
IN UINT  cjMaxBits,
IN UINT  cjMaxInfo,
IN BOOL  bTransformCoordinates,
IN OPTIONAL HANDLE  hcmXform 
)

Definition at line 470 of file dibobj.c.

487{
488 INT ret;
489 PDC pDC = NULL;
490 HBITMAP hSourceBitmap = NULL, hMaskBitmap = NULL;
491 SURFOBJ *pDestSurf, *pSourceSurf = NULL, *pMaskSurf = NULL;
492 SURFACE *pSurf;
493 RECTL rcDest;
494 POINTL ptSource;
495 //INT DIBWidth;
496 SIZEL SourceSize;
497 EXLATEOBJ exlo;
498 PPALETTE ppalDIB = NULL;
499 LPBITMAPINFO pbmiSafe;
500 BOOL bResult;
501
502 if (!Bits) return 0;
503
504 pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjMaxInfo, 'pmTG');
505 if (!pbmiSafe) return 0;
506
508 {
509 ProbeForRead(bmi, cjMaxInfo, 1);
510 ProbeForRead(Bits, cjMaxBits, 1);
511 RtlCopyMemory(pbmiSafe, bmi, cjMaxInfo);
512 bmi = pbmiSafe;
513 }
515 {
516 ret = 0;
517 goto Exit;
518 }
519 _SEH2_END;
520
521 ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
522 if (ScanLines == 0)
523 {
524 DPRINT1("ScanLines == 0\n");
525 ret = 0;
526 goto Exit;
527 }
528
529 pDC = DC_LockDc(hDC);
530 if (!pDC)
531 {
533 ret = 0;
534 goto Exit;
535 }
536
537 if (pDC->dctype == DCTYPE_INFO)
538 {
539 ret = 0;
540 goto Exit;
541 }
542
543 rcDest.left = XDest;
544 rcDest.top = YDest;
545 if (bTransformCoordinates)
546 {
547 IntLPtoDP(pDC, (LPPOINT)&rcDest, 2);
548 }
549 rcDest.left += pDC->ptlDCOrig.x;
550 rcDest.top += pDC->ptlDCOrig.y;
551 rcDest.right = rcDest.left + Width;
552 rcDest.bottom = rcDest.top + Height;
553 rcDest.top += StartScan;
554
555 if (pDC->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
556 {
557 IntUpdateBoundsRect(pDC, &rcDest);
558 }
559
560 ptSource.x = XSrc;
561 ptSource.y = YSrc;
562
563 SourceSize.cx = bmi->bmiHeader.biWidth;
564 SourceSize.cy = ScanLines;
565
566 //DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount);
567
568 hSourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
569 ScanLines,
570 0,
571 BitmapFormat(bmi->bmiHeader.biBitCount,
572 bmi->bmiHeader.biCompression),
573 bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
574 bmi->bmiHeader.biSizeImage,
575 Bits,
576 0);
577
578 if (!hSourceBitmap)
579 {
581 ret = 0;
582 goto Exit;
583 }
584
585 pSourceSurf = EngLockSurface((HSURF)hSourceBitmap);
586 if (!pSourceSurf)
587 {
588 ret = 0;
589 goto Exit;
590 }
591
592 /* HACK: If this is a RLE bitmap, only the relevant pixels must be set. */
593 if ((bmi->bmiHeader.biCompression == BI_RLE8) || (bmi->bmiHeader.biCompression == BI_RLE4))
594 {
595 hMaskBitmap = IntGdiCreateMaskFromRLE(bmi->bmiHeader.biWidth,
596 ScanLines,
597 bmi->bmiHeader.biCompression,
598 Bits,
599 cjMaxBits);
600 if (!hMaskBitmap)
601 {
603 ret = 0;
604 goto Exit;
605 }
606 pMaskSurf = EngLockSurface((HSURF)hMaskBitmap);
607 if (!pMaskSurf)
608 {
609 ret = 0;
610 goto Exit;
611 }
612 }
613
614 /* Create a palette for the DIB */
615 ppalDIB = CreateDIBPalette(bmi, pDC, ColorUse);
616 if (!ppalDIB)
617 {
619 ret = 0;
620 goto Exit;
621 }
622
623 /* This is actually a blit */
624 DC_vPrepareDCsForBlit(pDC, &rcDest, NULL, NULL);
625 pSurf = pDC->dclevel.pSurface;
626 if (!pSurf)
627 {
628 DC_vFinishBlit(pDC, NULL);
629 ret = ScanLines;
630 goto Exit;
631 }
632
633 ASSERT(pSurf->ppal);
634
635 /* Initialize EXLATEOBJ */
637 ppalDIB,
638 pSurf->ppal,
639 RGB(0xff, 0xff, 0xff),
640 pDC->pdcattr->crBackgroundClr,
641 pDC->pdcattr->crForegroundClr);
642
643 pDestSurf = &pSurf->SurfObj;
644
645 /* Copy the bits */
646 DPRINT("BitsToDev with rcDest=(%d|%d) (%d|%d), ptSource=(%d|%d) w=%d h=%d\n",
647 rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
648 ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy);
649
650 /* This fixes the large Google text on Google.com from being upside down */
651 if (rcDest.top > rcDest.bottom)
652 {
653 RECTL_vMakeWellOrdered(&rcDest);
654 ptSource.y -= SourceSize.cy;
655 }
656
657 bResult = IntEngBitBlt(pDestSurf,
658 pSourceSurf,
659 pMaskSurf,
660 (CLIPOBJ *)&pDC->co,
661 &exlo.xlo,
662 &rcDest,
663 &ptSource,
664 pMaskSurf ? &ptSource : NULL,
665 NULL,
666 NULL,
668
669 /* Cleanup EXLATEOBJ */
670 EXLATEOBJ_vCleanup(&exlo);
671
672 /* We're done */
673 DC_vFinishBlit(pDC, NULL);
674
675 ret = bResult ? ScanLines : 0;
676
677Exit:
678
679 if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
680 if (pSourceSurf) EngUnlockSurface(pSourceSurf);
681 if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
682 if (pMaskSurf) EngUnlockSurface(pMaskSurf);
683 if (hMaskBitmap) EngDeleteSurface((HSURF)hMaskBitmap);
684 if (pDC) DC_UnlockDc(pDC);
685 ExFreePoolWithTag(pbmiSafe, 'pmTG');
686
687 return ret;
688}
#define R3_OPINDEX_SRCCOPY
Definition: bitblt.h:27
static BOOLEAN IntLPtoDP(DC *pdc, PPOINTL ppt, UINT count)
Definition: coord.h:182
VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdcDest, const RECT *rcDest, PDC pdcSrc, const RECT *rcSrc)
Definition: dclife.c:505
VOID FASTCALL DC_vFinishBlit(PDC pdc1, PDC pdc2)
Definition: dclife.c:614
VOID FASTCALL IntUpdateBoundsRect(PDC, PRECTL)
Definition: dcutil.c:694
@ DC_ACCUM_APP
Definition: dc.h:25
@ DC_ACCUM_WMGR
Definition: dc.h:24
static HBITMAP IntGdiCreateMaskFromRLE(DWORD Width, DWORD Height, ULONG Compression, const BYTE *Bits, DWORD BitsSize)
Definition: dibobj.c:360
#define ROP4_FROM_INDEX(index)
Definition: inteng.h:42
#define ROP4_MASK
Definition: inteng.h:55
static void Exit(void)
Definition: sock.c:1330
long bottom
Definition: polytest.cpp:53
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
long left
Definition: polytest.cpp:53
BOOL APIENTRY IntEngBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclTrg, POINTL *pptlSrc, POINTL *pptlMask, BRUSHOBJ *pbo, POINTL *pptlBrush, ROP4 Rop4)
Definition: bitblt.c:656
VOID FASTCALL RECTL_vMakeWellOrdered(_Inout_ RECTL *prcl)
Definition: rect.c:81
ENGAPI BOOL APIENTRY EngDeleteSurface(_In_ _Post_ptr_invalid_ HSURF hsurf)
Definition: surface.c:567

◆ NtGdiStretchDIBitsInternal()

W32KAPI INT APIENTRY NtGdiStretchDIBitsInternal ( IN HDC  hdc,
IN INT  xDst,
IN INT  yDst,
IN INT  cxDst,
IN INT  cyDst,
IN INT  xSrc,
IN INT  ySrc,
IN INT  cxSrc,
IN INT  cySrc,
IN OPTIONAL LPBYTE  pjInit,
IN LPBITMAPINFO  pbmi,
IN DWORD  dwUsage,
IN DWORD  dwRop,
IN UINT  cjMaxInfo,
IN UINT  cjMaxBits,
IN HANDLE  hcmXform 
)

Definition at line 1201 of file dibobj.c.

1218{
1219 SIZEL sizel;
1220 RECTL rcSrc, rcDst;
1221 PDC pdc;
1222 HBITMAP hbmTmp = 0;
1223 PSURFACE psurfTmp = 0, psurfDst = 0;
1224 PPALETTE ppalDIB = 0;
1225 EXLATEOBJ exlo;
1226 PBYTE pvBits;
1227
1228 LPBITMAPINFO pbmiSafe;
1229 UINT cjAlloc;
1230 HBITMAP hBitmap, hOldBitmap = NULL;
1231 HDC hdcMem;
1232 HPALETTE hPal = NULL;
1233 ULONG BmpFormat = 0;
1234 INT LinesCopied = 0;
1235
1236 /* Check for bad iUsage */
1237 if (dwUsage > 2) return 0;
1238
1239 /* We must have LPBITMAPINFO */
1240 if (!pbmi)
1241 {
1242 DPRINT1("Error, Invalid Parameter.\n");
1244 return 0;
1245 }
1246
1247 /* Check if the size of the bitmap info is large enough */
1248 if (cjMaxInfo < sizeof(BITMAPCOREHEADER))
1249 {
1250 return 0;
1251 }
1252
1253 /* Use maximum size */
1254 cjMaxInfo = min(cjMaxInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD));
1255
1256 // HACK: the underlying code sucks and doesn't care for the size, so we
1257 // give it the maximum ever needed
1258 cjAlloc = sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD);
1259
1260 /* Allocate a buffer the bitmapinfo */
1261 pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjAlloc, 'imBG');
1262 if (!pbmiSafe)
1263 {
1264 /* Fail */
1265 return 0;
1266 }
1267
1268 /* Use SEH */
1269 _SEH2_TRY
1270 {
1271 /* Probe and copy the BITMAPINFO */
1273 RtlCopyMemory(pbmiSafe, pbmi, cjMaxInfo);
1274 }
1276 {
1277 ExFreePoolWithTag(pbmiSafe, 'imBG');
1278 return 0;
1279 }
1280 _SEH2_END;
1281
1282 /* Check if the header size is large enough */
1283 if ((pbmiSafe->bmiHeader.biSize < sizeof(BITMAPCOREHEADER)) ||
1284 (pbmiSafe->bmiHeader.biSize > cjMaxInfo))
1285 {
1286 ExFreePoolWithTag(pbmiSafe, 'imBG');
1287 return 0;
1288 }
1289
1290 if (!(pdc = DC_LockDc(hdc)))
1291 {
1293 return 0;
1294 }
1295
1296 /* Check for info / mem DC without surface */
1297 if (!pdc->dclevel.pSurface)
1298 {
1299 DC_UnlockDc(pdc);
1300 // CHECKME
1301 return TRUE;
1302 }
1303
1304 /* Transform dest size */
1305 sizel.cx = cxDst;
1306 sizel.cy = cyDst;
1307 IntLPtoDP(pdc, (POINTL*)&sizel, 1);
1308 DC_UnlockDc(pdc);
1309
1310 if (pjInit && (cjMaxBits > 0))
1311 {
1313 if (!pvBits)
1314 {
1315 return 0;
1316 }
1317
1318 _SEH2_TRY
1319 {
1320 ProbeForRead(pjInit, cjMaxBits, 1);
1321 RtlCopyMemory(pvBits, pjInit, cjMaxBits);
1322 }
1324 {
1325 ExFreePoolWithTag(pvBits, TAG_DIB);
1326 return 0;
1327 }
1328 _SEH2_END;
1329 }
1330 else
1331 {
1332 pvBits = NULL;
1333 }
1334
1335 /* Here we select between the dwRop with SRCCOPY or not. */
1336 if (dwRop == SRCCOPY)
1337 {
1339 if (hdcMem == NULL)
1340 {
1341 DPRINT1("NtGdiCreateCompatibleDC failed to create hdc.\n");
1343 return 0;
1344 }
1345
1347 abs(pbmiSafe->bmiHeader.biWidth),
1348 abs(pbmiSafe->bmiHeader.biHeight));
1349 if (hBitmap == NULL)
1350 {
1351 DPRINT1("NtGdiCreateCompatibleBitmap failed to create bitmap.\n");
1352 DPRINT1("hdc : 0x%08x \n", hdc);
1353 DPRINT1("width : 0x%08x \n", pbmiSafe->bmiHeader.biWidth);
1354 DPRINT1("height : 0x%08x \n", pbmiSafe->bmiHeader.biHeight);
1356 return 0;
1357 }
1358
1359 /* Select the bitmap into hdcMem, and save a handle to the old bitmap */
1360 hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
1361
1362 if (dwUsage == DIB_PAL_COLORS)
1363 {
1365 hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
1366 }
1367
1368 pdc = DC_LockDc(hdcMem);
1369 if (pdc != NULL)
1370 {
1371 IntSetDIBits(pdc, hBitmap, 0, abs(pbmiSafe->bmiHeader.biHeight), pvBits,
1372 cjMaxBits, pbmiSafe, dwUsage);
1373 DC_UnlockDc(pdc);
1374 }
1375
1376 /* Origin for DIBitmap may be bottom left (positive biHeight) or top
1377 left (negative biHeight) */
1378 if (cxSrc == cxDst && cySrc == cyDst)
1379 {
1380 NtGdiBitBlt(hdc, xDst, yDst, cxDst, cyDst,
1381 hdcMem, xSrc, abs(pbmiSafe->bmiHeader.biHeight) - cySrc - ySrc,
1382 dwRop, 0, 0);
1383 }
1384 else
1385 {
1386 NtGdiStretchBlt(hdc, xDst, yDst, cxDst, cyDst,
1387 hdcMem, xSrc, abs(pbmiSafe->bmiHeader.biHeight) - cySrc - ySrc,
1388 cxSrc, cySrc, dwRop, 0);
1389 }
1390
1391 /* cleanup */
1392 if (hPal)
1394
1395 if (hOldBitmap)
1396 NtGdiSelectBitmap(hdcMem, hOldBitmap);
1397
1400
1401 } /* End of dwRop == SRCCOPY */
1402 else
1403 { /* Start of dwRop != SRCCOPY */
1404 /* FIXME: Locking twice is cheesy, coord tranlation in UM will fix it */
1405 if (!(pdc = DC_LockDc(hdc)))
1406 {
1407 DPRINT1("Could not lock dc\n");
1409 goto cleanup;
1410 }
1411
1412 /* Calculate source and destination rect */
1413 rcSrc.left = xSrc;
1414 rcSrc.top = ySrc;
1415 rcSrc.right = xSrc + abs(cxSrc);
1416 rcSrc.bottom = ySrc + abs(cySrc);
1417 rcDst.left = xDst;
1418 rcDst.top = yDst;
1419 rcDst.right = rcDst.left + cxDst;
1420 rcDst.bottom = rcDst.top + cyDst;
1421 IntLPtoDP(pdc, (POINTL*)&rcDst, 2);
1422 RECTL_vOffsetRect(&rcDst, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
1423
1424 if (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
1425 {
1426 IntUpdateBoundsRect(pdc, &rcDst);
1427 }
1428
1429 BmpFormat = BitmapFormat(pbmiSafe->bmiHeader.biBitCount,
1430 pbmiSafe->bmiHeader.biCompression);
1431
1432 hbmTmp = GreCreateBitmapEx(pbmiSafe->bmiHeader.biWidth,
1433 abs(pbmiSafe->bmiHeader.biHeight),
1434 0,
1435 BmpFormat,
1436 pbmiSafe->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
1437 cjMaxBits,
1438 pvBits,
1439 0);
1440
1441 if (!hbmTmp)
1442 {
1443 goto cleanup;
1444 }
1445
1446 psurfTmp = SURFACE_ShareLockSurface(hbmTmp);
1447 if (!psurfTmp)
1448 {
1449 goto cleanup;
1450 }
1451
1452 /* Create a palette for the DIB */
1453 ppalDIB = CreateDIBPalette(pbmiSafe, pdc, dwUsage);
1454 if (!ppalDIB)
1455 {
1456 goto cleanup;
1457 }
1458
1459 /* Prepare DC for blit */
1460 DC_vPrepareDCsForBlit(pdc, &rcDst, NULL, NULL);
1461
1462 psurfDst = pdc->dclevel.pSurface;
1463
1464 /* Initialize XLATEOBJ */
1466 ppalDIB,
1467 psurfDst->ppal,
1468 RGB(0xff, 0xff, 0xff),
1469 pdc->pdcattr->crBackgroundClr,
1470 pdc->pdcattr->crForegroundClr);
1471
1472 /* Perform the stretch operation */
1473 IntEngStretchBlt(&psurfDst->SurfObj,
1474 &psurfTmp->SurfObj,
1475 NULL,
1476 (CLIPOBJ *)&pdc->co,
1477 &exlo.xlo,
1478 &pdc->dclevel.ca,
1479 &rcDst,
1480 &rcSrc,
1481 NULL,
1482 &pdc->eboFill.BrushObject,
1483 NULL,
1484 WIN32_ROP3_TO_ENG_ROP4(dwRop));
1485
1486 /* Cleanup */
1487 DC_vFinishBlit(pdc, NULL);
1488 EXLATEOBJ_vCleanup(&exlo);
1489
1490 cleanup:
1491 if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
1492 if (psurfTmp) SURFACE_ShareUnlockSurface(psurfTmp);
1493 if (hbmTmp) GreDeleteObject(hbmTmp);
1494 if (pdc) DC_UnlockDc(pdc);
1495 }
1496
1497 if (pvBits) ExFreePoolWithTag(pvBits, TAG_DIB);
1498
1499 /* This is not what MSDN says is returned from this function, but it
1500 * follows Wine's dlls/gdi32/dib.c function nulldrv_StretchDIBits
1501 * and it fixes over 100 gdi32:dib regression tests. */
1502 if (dwRop == SRCCOPY)
1503 {
1504 LinesCopied = abs(pbmiSafe->bmiHeader.biHeight);
1505 }
1506 else
1507 {
1508 LinesCopied = pbmiSafe->bmiHeader.biHeight;
1509 }
1510
1511 ExFreePoolWithTag(pbmiSafe, 'imBG');
1512
1513 return LinesCopied;
1514}
HPALETTE NTAPI GdiSelectPalette(_In_ HDC hDC, _In_ HPALETTE hpal, _In_ BOOL ForceBackground)
#define GDI_OBJECT_TYPE_PALETTE
Definition: gdi.h:49
BOOL APIENTRY IntEngStretchBlt(SURFOBJ *DestObj, SURFOBJ *SourceObj, SURFOBJ *Mask, CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation, COLORADJUSTMENT *pca, RECTL *DestRect, RECTL *SourceRect, POINTL *pMaskOrigin, BRUSHOBJ *Brush, POINTL *BrushOrigin, ULONG Mode)
#define WIN32_ROP3_TO_ENG_ROP4(dwRop4)
Definition: intgdi.h:4
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiCreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiBitBlt(_In_ HDC hdcDst, _In_ INT x, _In_ INT y, _In_ INT cx, _In_ INT cy, _In_opt_ HDC hdcSrc, _In_ INT xSrc, _In_ INT ySrc, _In_ DWORD rop4, _In_ DWORD crBackColor, _In_ FLONG fl)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiStretchBlt(_In_ HDC hdcDst, _In_ INT xDst, _In_ INT yDst, _In_ INT cxDst, _In_ INT cyDst, _In_opt_ HDC hdcSrc, _In_ INT xSrc, _In_ INT ySrc, _In_ INT cxSrc, _In_ INT cySrc, _In_ DWORD dwRop, _In_ DWORD dwBackColor)
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiSelectBitmap(_In_ HDC hdc, _In_ HBITMAP hbm)
__kernel_entry W32KAPI HANDLE APIENTRY NtGdiGetDCObject(_In_ HDC hdc, _In_ INT itype)
HDC hdcMem
Definition: welcome.c:104
FORCEINLINE VOID RECTL_vOffsetRect(_Inout_ RECTL *prcl, _In_ INT cx, _In_ INT cy)
Definition: rect.h:31
#define SRCCOPY
Definition: wingdi.h:333

Variable Documentation

◆ DefLogPaletteQuads

const RGBQUAD DefLogPaletteQuads[20]
static
Initial value:
=
{
{ 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x80, 0x00 },
{ 0x00, 0x80, 0x00, 0x00 },
{ 0x00, 0x80, 0x80, 0x00 },
{ 0x80, 0x00, 0x00, 0x00 },
{ 0x80, 0x00, 0x80, 0x00 },
{ 0x80, 0x80, 0x00, 0x00 },
{ 0xc0, 0xc0, 0xc0, 0x00 },
{ 0xc0, 0xdc, 0xc0, 0x00 },
{ 0xf0, 0xca, 0xa6, 0x00 },
{ 0xf0, 0xfb, 0xff, 0x00 },
{ 0xa4, 0xa0, 0xa0, 0x00 },
{ 0x80, 0x80, 0x80, 0x00 },
{ 0x00, 0x00, 0xff, 0x00 },
{ 0x00, 0xff, 0x00, 0x00 },
{ 0x00, 0xff, 0xff, 0x00 },
{ 0xff, 0x00, 0x00, 0x00 },
{ 0xff, 0x00, 0xff, 0x00 },
{ 0xff, 0xff, 0x00, 0x00 },
{ 0xff, 0xff, 0xff, 0x00 }
}

Definition at line 14 of file dibobj.c.

Referenced by GreGetDIBitsInternal().