ReactOS 0.4.16-dev-340-g0540c21
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 1108 of file dibobj.c.

1122{
1123 PBITMAPINFO pbmiSafe;
1124 HANDLE hSecure = NULL;
1125 INT iResult = 0;
1126 UINT cjAlloc;
1127
1128 /* Check for bad iUsage */
1129 if (iUsage > 2) return 0;
1130
1131 /* Check if the size of the bitmap info is large enough */
1132 if (cjMaxInfo < sizeof(BITMAPCOREHEADER))
1133 {
1134 return 0;
1135 }
1136
1137 /* Use maximum size */
1138 cjMaxInfo = min(cjMaxInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD));
1139
1140 // HACK: the underlying code sucks and doesn't care for the size, so we
1141 // give it the maximum ever needed
1142 cjAlloc = sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD);
1143
1144 /* Allocate a buffer the bitmapinfo */
1145 pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjAlloc, 'imBG');
1146 if (!pbmiSafe)
1147 {
1148 /* Fail */
1149 return 0;
1150 }
1151
1152 /* Use SEH */
1153 _SEH2_TRY
1154 {
1155 /* Probe and copy the BITMAPINFO */
1157 RtlCopyMemory(pbmiSafe, pbmi, cjMaxInfo);
1158 }
1160 {
1161 goto cleanup;
1162 }
1163 _SEH2_END;
1164
1165 /* Check if the header size is large enough */
1166 if ((pbmiSafe->bmiHeader.biSize < sizeof(BITMAPCOREHEADER)) ||
1167 (pbmiSafe->bmiHeader.biSize > cjMaxInfo))
1168 {
1169 goto cleanup;
1170 }
1171
1172 /* Check if the caller provided bitmap bits */
1173 if (pjBits)
1174 {
1175 /* Secure the user mode memory */
1176 hSecure = EngSecureMem(pjBits, cjMaxBits);
1177 if (!hSecure)
1178 {
1179 goto cleanup;
1180 }
1181 }
1182
1183 /* Now call the internal function */
1184 iResult = GreGetDIBitsInternal(hdc,
1185 hbm,
1186 iStartScan,
1187 cScans,
1188 pjBits,
1189 pbmiSafe,
1190 iUsage,
1191 cjMaxBits,
1192 cjMaxInfo);
1193
1194 /* Check for success */
1195 if (iResult)
1196 {
1197 /* Use SEH to copy back to user mode */
1198 _SEH2_TRY
1199 {
1200 /* Copy the data back */
1203 RtlCopyMemory(pbmi, pbmiSafe, cjMaxInfo);
1204 }
1206 {
1207 /* Ignore */
1208 (VOID)0;
1209 }
1210 _SEH2_END;
1211 }
1212
1213cleanup:
1214 if (hSecure) EngUnsecureMem(hSecure);
1215 ExFreePoolWithTag(pbmiSafe, 'imBG');
1216
1217 return iResult;
1218}
#define VOID
Definition: acefi.h:82
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO *info, WORD coloruse)
Definition: dibobj.c:2165
INT APIENTRY GreGetDIBitsInternal(HDC hDC, HBITMAP hBitmap, UINT StartScan, UINT ScanLines, LPBYTE Bits, LPBITMAPINFO Info, UINT Usage, UINT MaxBits, UINT MaxInfo)
Definition: dibobj.c:717
#define NULL
Definition: types.h:112
static void cleanup(void)
Definition: main.c:1335
ULONG RGBQUAD
Definition: precomp.h:59
#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
unsigned short WORD
Definition: ntddk_ex.h:93
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#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:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
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:71
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:46
ULONG biCompression
Definition: precomp.h:47
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 2165 of file dibobj.c.

2166{
2167 unsigned int colors, size, masks = 0;
2168 unsigned int colorsize;
2169
2170 colorsize = (coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) :
2171 (coloruse == DIB_PAL_INDICES) ? 0 :
2172 sizeof(WORD);
2173
2174 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
2175 {
2176 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
2177 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
2178 return sizeof(BITMAPCOREHEADER) + colors * colorsize;
2179 }
2180 else /* Assume BITMAPINFOHEADER */
2181 {
2182 colors = info->bmiHeader.biClrUsed;
2183 if (colors > 256) colors = 256;
2184 if (!colors && (info->bmiHeader.biBitCount <= 8))
2185 colors = 1 << info->bmiHeader.biBitCount;
2186 if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
2187 size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
2188 return size + colors * colorsize;
2189 }
2190}
#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 2238 of file dibobj.c.

2239{
2241 BITMAPINFO* pNewBmi ;
2242 UINT numColors = 0, ColorsSize = 0;
2243
2244 if(pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) return (BITMAPINFO*)pbmi;
2245 if(pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) return NULL;
2246
2247 if(pbmci->bmciHeader.bcBitCount <= 8)
2248 {
2249 numColors = 1 << pbmci->bmciHeader.bcBitCount;
2250 if(Usage == DIB_PAL_COLORS)
2251 {
2252 ColorsSize = numColors * sizeof(WORD);
2253 }
2254 else
2255 {
2256 ColorsSize = numColors * sizeof(RGBQUAD);
2257 }
2258 }
2259 else if (Usage == DIB_PAL_COLORS)
2260 {
2261 /* Invalid at high-res */
2262 return NULL;
2263 }
2264
2265 pNewBmi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + ColorsSize, TAG_DIB);
2266 if(!pNewBmi) return NULL;
2267
2268 RtlZeroMemory(pNewBmi, sizeof(BITMAPINFOHEADER) + ColorsSize);
2269
2270 pNewBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2271 pNewBmi->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount;
2272 pNewBmi->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth;
2273 pNewBmi->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight;
2274 pNewBmi->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes;
2275 pNewBmi->bmiHeader.biCompression = BI_RGB ;
2277 pNewBmi->bmiHeader.biHeight,
2278 pNewBmi->bmiHeader.biBitCount);
2279 pNewBmi->bmiHeader.biClrUsed = numColors;
2280
2281 if(Usage == DIB_PAL_COLORS)
2282 {
2283 RtlCopyMemory(pNewBmi->bmiColors, pbmci->bmciColors, ColorsSize);
2284 }
2285 else
2286 {
2287 UINT i;
2288 for(i=0; i<numColors; i++)
2289 {
2290 pNewBmi->bmiColors[i].rgbRed = pbmci->bmciColors[i].rgbtRed;
2291 pNewBmi->bmiColors[i].rgbGreen = pbmci->bmciColors[i].rgbtGreen;
2292 pNewBmi->bmiColors[i].rgbBlue = pbmci->bmciColors[i].rgbtBlue;
2293 }
2294 }
2295
2296 return pNewBmi ;
2297}
INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth)
Definition: dibobj.c:2153
#define BI_RGB
Definition: precomp.h:56
_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:103
UCHAR rgbRed
Definition: bootanim.c:105
UCHAR rgbGreen
Definition: bootanim.c:104
#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 1912 of file dibobj.c.

1920{
1921 HBITMAP res = 0;
1922 SURFACE *bmp = NULL;
1923 void *mapBits = NULL;
1924 PPALETTE ppalDIB = NULL;
1925
1926 // Fill BITMAP32 structure with DIB data
1927 CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
1928 INT effHeight;
1929 ULONG totalSize;
1930 BITMAP bm;
1931 //SIZEL Size;
1932 HANDLE hSecure;
1933
1934 DPRINT("format (%ld,%ld), planes %u, bpp %u, size %lu, colors %lu (%s)\n",
1935 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
1936 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1937
1938 /* CreateDIBSection should fail for compressed formats */
1939 if (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8)
1940 {
1941 DPRINT1("no compressed format allowed\n");
1942 return (HBITMAP)NULL;
1943 }
1944
1945 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
1946 bm.bmType = 0;
1947 bm.bmWidth = bi->biWidth;
1948 bm.bmHeight = effHeight;
1949 bm.bmWidthBytes = ovr_pitch ? ovr_pitch : WIDTH_BYTES_ALIGN32(bm.bmWidth, bi->biBitCount);
1950
1951 bm.bmPlanes = bi->biPlanes;
1952 bm.bmBitsPixel = bi->biBitCount;
1953 bm.bmBits = NULL;
1954
1955 // Get storage location for DIB bits. Only use biSizeImage if it's valid and
1956 // we're dealing with a compressed bitmap. Otherwise, use width * height.
1957 totalSize = (bi->biSizeImage && (bi->biCompression != BI_RGB) && (bi->biCompression != BI_BITFIELDS))
1958 ? bi->biSizeImage : (ULONG)(bm.bmWidthBytes * effHeight);
1959
1960 if (section)
1961 {
1964 DWORD mapOffset;
1966 SIZE_T mapSize;
1967
1969 &Sbi,
1970 sizeof Sbi,
1971 0);
1972 if (!NT_SUCCESS(Status))
1973 {
1974 DPRINT1("ZwQuerySystemInformation failed (0x%lx)\n", Status);
1975 return NULL;
1976 }
1977
1978 mapOffset = offset - (offset % Sbi.AllocationGranularity);
1979 mapSize = totalSize + (offset - mapOffset);
1980
1981 SectionOffset.LowPart = mapOffset;
1982 SectionOffset.HighPart = 0;
1983
1984 Status = ZwMapViewOfSection(section,
1986 &mapBits,
1987 0,
1988 0,
1990 &mapSize,
1991 ViewShare,
1992 0,
1994 if (!NT_SUCCESS(Status))
1995 {
1996 DPRINT1("ZwMapViewOfSection failed (0x%lx)\n", Status);
1998 return NULL;
1999 }
2000
2001 if (mapBits) bm.bmBits = (char *)mapBits + (offset - mapOffset);
2002 }
2003 else if (ovr_pitch && offset)
2004 bm.bmBits = UlongToPtr(offset);
2005 else
2006 {
2007 offset = 0;
2008 bm.bmBits = EngAllocUserMem(totalSize, 0);
2009 if(!bm.bmBits)
2010 {
2011 DPRINT1("Failed to allocate memory\n");
2012 goto cleanup;
2013 }
2014 }
2015
2016// hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE);
2017 hSecure = (HANDLE)0x1; // HACK OF UNIMPLEMENTED KERNEL STUFF !!!!
2018
2019 // Create Device Dependent Bitmap and add DIB pointer
2020 //Size.cx = bm.bmWidth;
2021 //Size.cy = abs(bm.bmHeight);
2022 res = GreCreateBitmapEx(bm.bmWidth,
2023 abs(bm.bmHeight),
2024 bm.bmWidthBytes,
2025 BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
2027 ((bi->biHeight < 0) ? BMF_TOPDOWN : 0),
2028 totalSize,
2029 bm.bmBits,
2030 0);
2031 if (!res)
2032 {
2033 DPRINT1("GreCreateBitmapEx failed\n");
2035 goto cleanup;
2036 }
2037 bmp = SURFACE_ShareLockSurface(res); // HACK
2038 if (NULL == bmp)
2039 {
2040 DPRINT1("SURFACE_LockSurface failed\n");
2042 goto cleanup;
2043 }
2044
2045 /* WINE NOTE: WINE makes use of a colormap, which is a color translation
2046 table between the DIB and the X physical device. Obviously,
2047 this is left out of the ReactOS implementation. Instead,
2048 we call NtGdiSetDIBColorTable. */
2049 bmp->hDIBSection = section;
2050 bmp->hSecure = hSecure;
2051 bmp->dwOffset = offset;
2052 bmp->flags = API_BITMAP;
2053 bmp->biClrImportant = bi->biClrImportant;
2054
2055 /* Create a palette for the DIB */
2056 ppalDIB = CreateDIBPalette(bmi, dc, usage);
2057
2058 // Clean up in case of errors
2059cleanup:
2060 if (!res || !bmp || !bm.bmBits || !ppalDIB)
2061 {
2062 DPRINT("Got an error res=%p, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
2063 if (bm.bmBits)
2064 {
2065 // MmUnsecureVirtualMemory(hSecure); // FIXME: Implement this!
2066 if (section)
2067 {
2068 ZwUnmapViewOfSection(NtCurrentProcess(), mapBits);
2069 bm.bmBits = NULL;
2070 }
2071 else if (!offset)
2072 EngFreeUserMem(bm.bmBits), bm.bmBits = NULL;
2073 }
2074
2075 if (bmp)
2076 {
2078 bmp = NULL;
2079 }
2080
2081 if (res)
2082 {
2084 res = 0;
2085 }
2086
2087 if(ppalDIB)
2088 {
2090 }
2091 }
2092
2093 if (bmp)
2094 {
2095 /* If we're here, everything went fine */
2096 SURFACE_vSetPalette(bmp, ppalDIB);
2099 }
2100
2101 // Return BITMAP handle and storage location
2102 if (NULL != bm.bmBits && NULL != bits)
2103 {
2104 *bits = bm.bmBits;
2105 }
2106
2107 return res;
2108}
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:33
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define BI_RLE4
Definition: precomp.h:57
#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:73
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:22
#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 2302 of file dibobj.c.

2303{
2304 BITMAPCOREINFO* pbmci;
2305 if(converted == orig)
2306 return;
2307
2308 if(usage == -1)
2309 {
2310 /* Caller don't want any conversion */
2311 ExFreePoolWithTag(converted, TAG_DIB);
2312 return;
2313 }
2314
2315 /* Perform inverse conversion */
2316 pbmci = (BITMAPCOREINFO*)orig;
2317
2318 ASSERT(pbmci->bmciHeader.bcSize == sizeof(BITMAPCOREHEADER));
2319 pbmci->bmciHeader.bcBitCount = converted->bmiHeader.biBitCount;
2320 pbmci->bmciHeader.bcWidth = converted->bmiHeader.biWidth;
2321 pbmci->bmciHeader.bcHeight = converted->bmiHeader.biHeight;
2322 pbmci->bmciHeader.bcPlanes = converted->bmiHeader.biPlanes;
2323
2324 if(pbmci->bmciHeader.bcBitCount <= 8)
2325 {
2326 UINT numColors = converted->bmiHeader.biClrUsed;
2327 if(!numColors) numColors = 1 << pbmci->bmciHeader.bcBitCount;
2328 if(usage == DIB_PAL_COLORS)
2329 {
2330 RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(WORD));
2331 RtlCopyMemory(pbmci->bmciColors, converted->bmiColors, numColors * sizeof(WORD));
2332 }
2333 else
2334 {
2335 UINT i;
2336 RtlZeroMemory(pbmci->bmciColors, (1 << pbmci->bmciHeader.bcBitCount) * sizeof(RGBTRIPLE));
2337 for(i=0; i<numColors; i++)
2338 {
2339 pbmci->bmciColors[i].rgbtRed = converted->bmiColors[i].rgbRed;
2340 pbmci->bmciColors[i].rgbtGreen = converted->bmiColors[i].rgbGreen;
2341 pbmci->bmciColors[i].rgbtBlue = converted->bmiColors[i].rgbBlue;
2342 }
2343 }
2344 }
2345 /* Now free it, it's not needed anymore */
2346 ExFreePoolWithTag(converted, TAG_DIB);
2347}
#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 2118 of file dibobj.c.

2120{
2121 if (header->biSize == sizeof(BITMAPCOREHEADER))
2122 {
2123 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
2124 *width = core->bcWidth;
2125 *height = core->bcHeight;
2126 *planes = core->bcPlanes;
2127 *bpp = core->bcBitCount;
2128 *compr = BI_RGB;
2129 *size = 0;
2130 return 0;
2131 }
2132 if (header->biSize >= sizeof(BITMAPINFOHEADER)) /* Assume BITMAPINFOHEADER */
2133 {
2134 *width = header->biWidth;
2135 *height = header->biHeight;
2136 *planes = header->biPlanes;
2137 *bpp = header->biBitCount;
2138 *compr = header->biCompression;
2139 *size = header->biSizeImage;
2140 return 1;
2141 }
2142 DPRINT1("(%u): unknown/wrong size for header\n", header->biSize );
2143 return -1;
2144}
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 2153 of file dibobj.c.

2154{
2155 return WIDTH_BYTES_ALIGN32(width, depth) * (height < 0 ? -height : height);
2156}
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 2194 of file dibobj.c.

2195{
2196 PPALETTE ppalNew;
2197 ULONG nNumColors,i;
2198 USHORT *lpIndex;
2199 HPALETTE hpal;
2200
2201 if (!(ppalDc->flFlags & PAL_INDEXED))
2202 {
2203 return NULL;
2204 }
2205
2206 nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
2207 if (lpbmi->bmiHeader.biClrUsed)
2208 {
2209 nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
2210 }
2211
2212 ppalNew = PALETTE_AllocPalWithHandle(PAL_INDEXED, nNumColors, NULL, 0, 0, 0);
2213 if (ppalNew == NULL)
2214 {
2215 DPRINT1("Could not allocate palette\n");
2216 return NULL;
2217 }
2218
2219 lpIndex = (USHORT *)((PBYTE)lpbmi + lpbmi->bmiHeader.biSize);
2220
2221 for (i = 0; i < nNumColors; i++)
2222 {
2223 ULONG iColorIndex = *lpIndex % ppalDc->NumColors;
2224 ppalNew->IndexedColors[i] = ppalDc->IndexedColors[iColorIndex];
2225 lpIndex++;
2226 }
2227
2228 hpal = ppalNew->BaseObject.hHmgr;
2229 PALETTE_UnlockPalette(ppalNew);
2230
2231 return hpal;
2232}
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 1794 of file dibobj.c.

1798{
1800 PBYTE pjBits;
1801 UINT cjInfo, cjBits;
1802 HBITMAP hbm;
1803
1804 /* We only support BITMAPINFOHEADER, make sure the size is ok */
1805 if (cjPackedDIB < sizeof(BITMAPINFOHEADER))
1806 {
1807 return NULL;
1808 }
1809
1810 /* The packed DIB starts with the BITMAPINFOHEADER */
1811 pbmi = pvPackedDIB;
1812
1813 if (cjPackedDIB < pbmi->bmiHeader.biSize)
1814 {
1815 return NULL;
1816 }
1817
1818 /* Calculate the info size and make sure the packed DIB is large enough */
1819 cjInfo = DIB_BitmapInfoSize(pbmi, uUsage);
1820 if (cjPackedDIB <= cjInfo)
1821 {
1822 return NULL;
1823 }
1824
1825 /* The bitmap bits start after the header */
1826 pjBits = (PBYTE)pvPackedDIB + cjInfo;
1827 cjBits = cjPackedDIB - cjInfo;
1828
1833 pjBits,
1834 pbmi,
1835 uUsage,
1836 0,
1837 cjBits,
1838 NULL);
1839
1840 return hbm;
1841}
#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:1718
#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 1718 of file dibobj.c.

1729{
1730 PDC Dc;
1731 HBITMAP Bmp;
1732 USHORT bpp, planes;
1734 HDC hdcDest;
1735
1736 if (!hDc) /* 1bpp monochrome bitmap */
1737 {
1738 // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
1739 hdcDest = NtGdiCreateCompatibleDC(0);
1740 if(!hdcDest)
1741 {
1742 DPRINT1("NtGdiCreateCompatibleDC failed\n");
1743 return NULL;
1744 }
1745 }
1746 else
1747 {
1748 hdcDest = hDc;
1749 }
1750
1751 Dc = DC_LockDc(hdcDest);
1752 if (!Dc)
1753 {
1754 DPRINT1("Failed to lock hdcDest %p\n", hdcDest);
1756 return NULL;
1757 }
1758 /* It's OK to set bpp=0 here, as IntCreateDIBitmap will create a compatible Bitmap
1759 * if bpp != 1 and ignore the real value that was passed */
1760 if (pbmi)
1761 {
1762 if (pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1763 {
1765 bpp = CoreHeader->bcBitCount;
1766 planes = CoreHeader->bcPlanes ? CoreHeader->bcPlanes : 1;
1768 }
1769 else
1770 {
1772 planes = pbmi->bmiHeader.biPlanes ? pbmi->bmiHeader.biPlanes : 1;
1774 }
1775 }
1776 else
1777 {
1778 bpp = 0;
1779 planes = 0;
1780 compression = 0;
1781 }
1782 Bmp = IntCreateDIBitmap(Dc, cx, cy, planes, bpp, compression, fInit, pjInit, cjMaxBits, pbmi, iUsage);
1783 DC_UnlockDc(Dc);
1784
1785 if(!hDc)
1786 {
1787 NtGdiDeleteObjectApp(hdcDest);
1788 }
1789 return Bmp;
1790}
_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:1540
static HDC
Definition: imagelist.c:88
__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 717 of file dibobj.c.

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

1552{
1554 BOOL fColor;
1555 ULONG BmpFormat = 0;
1556
1557 if (planes && bpp)
1558 BmpFormat = BitmapFormat(planes * bpp, compression);
1559
1560 // Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
1561 // colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.
1562
1563 if (BmpFormat != BMF_1BPP) fColor = TRUE;
1564 else if ((coloruse > DIB_RGB_COLORS) || ((init & CBM_INIT) == 0) || !data) fColor = FALSE;
1565 else
1566 {
1567 const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize);
1568 DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
1569
1570 // Check if the first color of the colormap is black
1571 if (col == RGB(0, 0, 0))
1572 {
1573 rgb++;
1574 col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
1575
1576 // If the second color is white, create a monochrome bitmap
1577 fColor = (col != RGB(0xff,0xff,0xff));
1578 }
1579 else fColor = TRUE;
1580 }
1581
1582 // Now create the bitmap
1583 if (fColor)
1584 {
1585 if (init & CBM_CREATDIB)
1586 {
1587 PSURFACE Surface;
1588 PPALETTE Palette;
1589
1590 /* Undocumented flag which creates a DDB of the format specified by the bitmap info. */
1592 if (!handle)
1593 {
1594 DPRINT1("IntCreateCompatibleBitmap() failed!\n");
1595 return NULL;
1596 }
1597
1598 /* The palette must also match the given data */
1600 ASSERT(Surface);
1601 Palette = CreateDIBPalette(data, Dc, coloruse);
1602 if (Palette == NULL)
1603 {
1606 return NULL;
1607 }
1608
1609 SURFACE_vSetPalette(Surface, Palette);
1610
1613 }
1614 else
1615 {
1616 /* Create a regular compatible bitmap, in the same format as the device */
1618 }
1619 }
1620 else
1621 {
1623 abs(height),
1624 1,
1625 1,
1626 NULL);
1627 }
1628
1629 if (height < 0)
1630 height = -height;
1631
1632 if ((NULL != handle) && (CBM_INIT & init))
1633 {
1634 IntSetDIBits(Dc, handle, 0, height, bits, cjMaxBits, data, coloruse);
1635 }
1636
1637 return handle;
1638}
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:89
_In_ HFONT _Out_ PUINT Height
Definition: font.h:88
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\n");
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 1644 of file dibobj.c.

1656{
1658 PBYTE safeBits = NULL;
1659 HBITMAP hbmResult = NULL;
1660
1661 if (pjInit == NULL)
1662 {
1663 fInit &= ~CBM_INIT;
1664 }
1665
1666 if(pjInit && (fInit & CBM_INIT))
1667 {
1668 if (cjMaxBits == 0) return NULL;
1670 if(!safeBits)
1671 {
1672 DPRINT1("Failed to allocate %lu bytes\n", cjMaxBits);
1674 return NULL;
1675 }
1676 }
1677
1678 _SEH2_TRY
1679 {
1680 if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
1681 if(pjInit && (fInit & CBM_INIT))
1682 {
1683 ProbeForRead(pjInit, cjMaxBits, 1);
1684 RtlCopyMemory(safeBits, pjInit, cjMaxBits);
1685 }
1686 }
1688 {
1690 }
1691 _SEH2_END;
1692
1693 if(!NT_SUCCESS(Status))
1694 {
1695 DPRINT1("Got an exception! pjInit = %p\n", pjInit);
1697 goto cleanup;
1698 }
1699
1700 hbmResult = GreCreateDIBitmapInternal(hDc,
1701 cx,
1702 cy,
1703 fInit,
1704 safeBits,
1705 pbmi,
1706 iUsage,
1707 fl,
1708 cjMaxBits,
1709 hcmXform);
1710
1711cleanup:
1712 if (safeBits) ExFreePoolWithTag(safeBits, TAG_DIB);
1713 return hbmResult;
1714}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
_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 1845 of file dibobj.c.

1855{
1856 HBITMAP hbitmap = 0;
1857 DC *dc;
1858 BOOL bDesktopDC = FALSE;
1860
1861 if (!bmi) return hbitmap; // Make sure.
1862
1863 _SEH2_TRY
1864 {
1865 ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
1866 ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
1867 ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, (WORD)Usage), 1);
1868 }
1870 {
1872 }
1873 _SEH2_END;
1874
1875 if(!NT_SUCCESS(Status))
1876 {
1878 return NULL;
1879 }
1880
1881 // If the reference hdc is null, take the desktop dc
1882 if (hDC == 0)
1883 {
1885 bDesktopDC = TRUE;
1886 }
1887
1888 if ((dc = DC_LockDc(hDC)))
1889 {
1891 bmi,
1892 Usage,
1893 Bits,
1894 hSection,
1895 dwOffset,
1896 0);
1897 DC_UnlockDc(dc);
1898 }
1899 else
1900 {
1902 }
1903
1904 if (bDesktopDC)
1906
1907 return hbitmap;
1908}
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 DPRINT("StartScan %d ScanLines %d Bits %p bmi %p ColorUse %d\n"
522 " Height %d Width %d SizeImage %d\n"
523 " biHeight %d biWidth %d biBitCount %d\n"
524 " XSrc %d YSrc %d xDext %d yDest %d\n",
525 StartScan, ScanLines, Bits, bmi, ColorUse,
526 Height, Width, bmi->bmiHeader.biSizeImage,
527 bmi->bmiHeader.biHeight, bmi->bmiHeader.biWidth,
528 bmi->bmiHeader.biBitCount,
529 XSrc, YSrc, XDest, YDest);
530
531 if (YDest >= 0)
532 {
533 ScanLines = min(abs(Height), ScanLines);
534 if (YSrc > 0)
535 ScanLines += YSrc;
536 }
537 else
538 {
539 ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
540 }
541
542 if (ScanLines == 0)
543 {
544 DPRINT1("ScanLines == 0\n");
545 ret = 0;
546 goto Exit;
547 }
548
549 pDC = DC_LockDc(hDC);
550 if (!pDC)
551 {
553 ret = 0;
554 goto Exit;
555 }
556
557 if (pDC->dctype == DCTYPE_INFO)
558 {
559 ret = 0;
560 goto Exit;
561 }
562
563 rcDest.left = XDest;
564 rcDest.top = YDest;
565 if (bTransformCoordinates)
566 {
567 IntLPtoDP(pDC, (LPPOINT)&rcDest, 2);
568 }
569 rcDest.left += pDC->ptlDCOrig.x;
570 rcDest.top += pDC->ptlDCOrig.y;
571 rcDest.right = rcDest.left + Width;
572 rcDest.bottom = rcDest.top + Height;
573 rcDest.top += StartScan;
574
575 if (pDC->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
576 {
577 IntUpdateBoundsRect(pDC, &rcDest);
578 }
579
580 ptSource.x = XSrc;
581 ptSource.y = YSrc;
582
583 SourceSize.cx = bmi->bmiHeader.biWidth;
584 SourceSize.cy = ScanLines;
585 if (YDest >= 0 && YSrc > 0)
586 {
587 ScanLines += YSrc;
588 }
589
590 //DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount);
591
592 hSourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
593 ScanLines,
594 0,
595 BitmapFormat(bmi->bmiHeader.biBitCount,
596 bmi->bmiHeader.biCompression),
597 bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
598 bmi->bmiHeader.biSizeImage,
599 Bits,
600 0);
601
602 if (!hSourceBitmap)
603 {
605 ret = 0;
606 goto Exit;
607 }
608
609 pSourceSurf = EngLockSurface((HSURF)hSourceBitmap);
610 if (!pSourceSurf)
611 {
612 ret = 0;
613 goto Exit;
614 }
615
616 /* HACK: If this is a RLE bitmap, only the relevant pixels must be set. */
617 if ((bmi->bmiHeader.biCompression == BI_RLE8) || (bmi->bmiHeader.biCompression == BI_RLE4))
618 {
619 hMaskBitmap = IntGdiCreateMaskFromRLE(bmi->bmiHeader.biWidth,
620 ScanLines,
621 bmi->bmiHeader.biCompression,
622 Bits,
623 cjMaxBits);
624 if (!hMaskBitmap)
625 {
627 ret = 0;
628 goto Exit;
629 }
630 pMaskSurf = EngLockSurface((HSURF)hMaskBitmap);
631 if (!pMaskSurf)
632 {
633 ret = 0;
634 goto Exit;
635 }
636 }
637
638 /* Create a palette for the DIB */
639 ppalDIB = CreateDIBPalette(bmi, pDC, ColorUse);
640 if (!ppalDIB)
641 {
643 ret = 0;
644 goto Exit;
645 }
646
647 /* This is actually a blit */
648 DC_vPrepareDCsForBlit(pDC, &rcDest, NULL, NULL);
649 pSurf = pDC->dclevel.pSurface;
650 if (!pSurf)
651 {
652 DC_vFinishBlit(pDC, NULL);
653 ret = ScanLines;
654 goto Exit;
655 }
656
657 ASSERT(pSurf->ppal);
658
659 /* Initialize EXLATEOBJ */
661 ppalDIB,
662 pSurf->ppal,
663 RGB(0xff, 0xff, 0xff),
664 pDC->pdcattr->crBackgroundClr,
665 pDC->pdcattr->crForegroundClr);
666
667 pDestSurf = &pSurf->SurfObj;
668
669 /* Copy the bits */
670 DPRINT("BitsToDev with rcDest=(%d|%d) (%d|%d), ptSource=(%d|%d) w=%d h=%d\n",
671 rcDest.left, rcDest.top, rcDest.right, rcDest.bottom,
672 ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy);
673
674 /* This fixes the large Google text on Google.com from being upside down */
675 if (rcDest.top > rcDest.bottom)
676 {
677 RECTL_vMakeWellOrdered(&rcDest);
678 ptSource.y -= SourceSize.cy;
679 }
680
681 bResult = IntEngBitBlt(pDestSurf,
682 pSourceSurf,
683 pMaskSurf,
684 (CLIPOBJ *)&pDC->co,
685 &exlo.xlo,
686 &rcDest,
687 &ptSource,
688 pMaskSurf ? &ptSource : NULL,
689 NULL,
690 NULL,
692
693 /* Cleanup EXLATEOBJ */
694 EXLATEOBJ_vCleanup(&exlo);
695
696 /* We're done */
697 DC_vFinishBlit(pDC, NULL);
698
699 ret = bResult ? ScanLines : 0;
700
701Exit:
702
703 if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
704 if (pSourceSurf) EngUnlockSurface(pSourceSurf);
705 if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
706 if (pMaskSurf) EngUnlockSurface(pMaskSurf);
707 if (hMaskBitmap) EngDeleteSurface((HSURF)hMaskBitmap);
708 if (pDC) DC_UnlockDc(pDC);
709 ExFreePoolWithTag(pbmiSafe, 'pmTG');
710
711 return ret;
712}
#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 1223 of file dibobj.c.

1240{
1241 SIZEL sizel;
1242 RECTL rcSrc, rcDst;
1243 PDC pdc;
1244 HBITMAP hbmTmp = 0;
1245 PSURFACE psurfTmp = 0, psurfDst = 0;
1246 PPALETTE ppalDIB = 0;
1247 EXLATEOBJ exlo;
1248 PBYTE pvBits;
1249
1250 LPBITMAPINFO pbmiSafe;
1251 UINT cjAlloc;
1252 HBITMAP hBitmap, hOldBitmap = NULL;
1253 HDC hdcMem;
1254 HPALETTE hPal = NULL;
1255 ULONG BmpFormat = 0;
1256 INT LinesCopied = 0;
1257
1258 /* Check for bad iUsage */
1259 if (dwUsage > 2) return 0;
1260
1261 /* We must have LPBITMAPINFO */
1262 if (!pbmi)
1263 {
1264 DPRINT1("Error, Invalid Parameter.\n");
1266 return 0;
1267 }
1268
1269 /* Check if the size of the bitmap info is large enough */
1270 if (cjMaxInfo < sizeof(BITMAPCOREHEADER))
1271 {
1272 return 0;
1273 }
1274
1275 /* Use maximum size */
1276 cjMaxInfo = min(cjMaxInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD));
1277
1278 // HACK: the underlying code sucks and doesn't care for the size, so we
1279 // give it the maximum ever needed
1280 cjAlloc = sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD);
1281
1282 /* Allocate a buffer the bitmapinfo */
1283 pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjAlloc, 'imBG');
1284 if (!pbmiSafe)
1285 {
1286 /* Fail */
1287 return 0;
1288 }
1289
1290 /* Use SEH */
1291 _SEH2_TRY
1292 {
1293 /* Probe and copy the BITMAPINFO */
1295 RtlCopyMemory(pbmiSafe, pbmi, cjMaxInfo);
1296 }
1298 {
1299 ExFreePoolWithTag(pbmiSafe, 'imBG');
1300 return 0;
1301 }
1302 _SEH2_END;
1303
1304 /* Check if the header size is large enough */
1305 if ((pbmiSafe->bmiHeader.biSize < sizeof(BITMAPCOREHEADER)) ||
1306 (pbmiSafe->bmiHeader.biSize > cjMaxInfo))
1307 {
1308 ExFreePoolWithTag(pbmiSafe, 'imBG');
1309 return 0;
1310 }
1311
1312 if (!(pdc = DC_LockDc(hdc)))
1313 {
1315 return 0;
1316 }
1317
1318 /* Check for info / mem DC without surface */
1319 if (!pdc->dclevel.pSurface)
1320 {
1321 DC_UnlockDc(pdc);
1322 // CHECKME
1323 return TRUE;
1324 }
1325
1326 /* Transform dest size */
1327 sizel.cx = cxDst;
1328 sizel.cy = cyDst;
1329 IntLPtoDP(pdc, (POINTL*)&sizel, 1);
1330 DC_UnlockDc(pdc);
1331
1332 if (pjInit && (cjMaxBits > 0))
1333 {
1335 if (!pvBits)
1336 {
1337 return 0;
1338 }
1339
1340 _SEH2_TRY
1341 {
1342 ProbeForRead(pjInit, cjMaxBits, 1);
1343 RtlCopyMemory(pvBits, pjInit, cjMaxBits);
1344 }
1346 {
1347 ExFreePoolWithTag(pvBits, TAG_DIB);
1348 return 0;
1349 }
1350 _SEH2_END;
1351 }
1352 else
1353 {
1354 pvBits = NULL;
1355 }
1356
1357 /* Here we select between the dwRop with SRCCOPY or not. */
1358 if (dwRop == SRCCOPY)
1359 {
1361 if (hdcMem == NULL)
1362 {
1363 DPRINT1("NtGdiCreateCompatibleDC failed to create hdc.\n");
1365 return 0;
1366 }
1367
1369 abs(pbmiSafe->bmiHeader.biWidth),
1370 abs(pbmiSafe->bmiHeader.biHeight));
1371 if (hBitmap == NULL)
1372 {
1373 DPRINT1("NtGdiCreateCompatibleBitmap failed to create bitmap.\n");
1374 DPRINT1("hdc : 0x%08x \n", hdc);
1375 DPRINT1("width : 0x%08x \n", pbmiSafe->bmiHeader.biWidth);
1376 DPRINT1("height : 0x%08x \n", pbmiSafe->bmiHeader.biHeight);
1378 return 0;
1379 }
1380
1381 /* Select the bitmap into hdcMem, and save a handle to the old bitmap */
1382 hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
1383
1384 if (dwUsage == DIB_PAL_COLORS)
1385 {
1387 hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
1388 }
1389
1390 pdc = DC_LockDc(hdcMem);
1391 if (pdc != NULL)
1392 {
1393 IntSetDIBits(pdc, hBitmap, 0, abs(pbmiSafe->bmiHeader.biHeight), pvBits,
1394 cjMaxBits, pbmiSafe, dwUsage);
1395 DC_UnlockDc(pdc);
1396 }
1397
1398 /* Origin for DIBitmap may be bottom left (positive biHeight) or top
1399 left (negative biHeight) */
1400 if (cxSrc == cxDst && cySrc == cyDst)
1401 {
1402 NtGdiBitBlt(hdc, xDst, yDst, cxDst, cyDst,
1403 hdcMem, xSrc, abs(pbmiSafe->bmiHeader.biHeight) - cySrc - ySrc,
1404 dwRop, 0, 0);
1405 }
1406 else
1407 {
1408 NtGdiStretchBlt(hdc, xDst, yDst, cxDst, cyDst,
1409 hdcMem, xSrc, abs(pbmiSafe->bmiHeader.biHeight) - cySrc - ySrc,
1410 cxSrc, cySrc, dwRop, 0);
1411 }
1412
1413 /* cleanup */
1414 if (hPal)
1416
1417 if (hOldBitmap)
1418 NtGdiSelectBitmap(hdcMem, hOldBitmap);
1419
1422
1423 } /* End of dwRop == SRCCOPY */
1424 else
1425 { /* Start of dwRop != SRCCOPY */
1426 /* FIXME: Locking twice is cheesy, coord tranlation in UM will fix it */
1427 if (!(pdc = DC_LockDc(hdc)))
1428 {
1429 DPRINT1("Could not lock dc\n");
1431 goto cleanup;
1432 }
1433
1434 /* Calculate source and destination rect */
1435 rcSrc.left = xSrc;
1436 rcSrc.top = ySrc;
1437 rcSrc.right = xSrc + abs(cxSrc);
1438 rcSrc.bottom = ySrc + abs(cySrc);
1439 rcDst.left = xDst;
1440 rcDst.top = yDst;
1441 rcDst.right = rcDst.left + cxDst;
1442 rcDst.bottom = rcDst.top + cyDst;
1443 IntLPtoDP(pdc, (POINTL*)&rcDst, 2);
1444 RECTL_vOffsetRect(&rcDst, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
1445
1446 if (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
1447 {
1448 IntUpdateBoundsRect(pdc, &rcDst);
1449 }
1450
1451 BmpFormat = BitmapFormat(pbmiSafe->bmiHeader.biBitCount,
1452 pbmiSafe->bmiHeader.biCompression);
1453
1454 hbmTmp = GreCreateBitmapEx(pbmiSafe->bmiHeader.biWidth,
1455 abs(pbmiSafe->bmiHeader.biHeight),
1456 0,
1457 BmpFormat,
1458 pbmiSafe->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
1459 cjMaxBits,
1460 pvBits,
1461 0);
1462
1463 if (!hbmTmp)
1464 {
1465 goto cleanup;
1466 }
1467
1468 psurfTmp = SURFACE_ShareLockSurface(hbmTmp);
1469 if (!psurfTmp)
1470 {
1471 goto cleanup;
1472 }
1473
1474 /* Create a palette for the DIB */
1475 ppalDIB = CreateDIBPalette(pbmiSafe, pdc, dwUsage);
1476 if (!ppalDIB)
1477 {
1478 goto cleanup;
1479 }
1480
1481 /* Prepare DC for blit */
1482 DC_vPrepareDCsForBlit(pdc, &rcDst, NULL, NULL);
1483
1484 psurfDst = pdc->dclevel.pSurface;
1485
1486 /* Initialize XLATEOBJ */
1488 ppalDIB,
1489 psurfDst->ppal,
1490 RGB(0xff, 0xff, 0xff),
1491 pdc->pdcattr->crBackgroundClr,
1492 pdc->pdcattr->crForegroundClr);
1493
1494 /* Perform the stretch operation */
1495 IntEngStretchBlt(&psurfDst->SurfObj,
1496 &psurfTmp->SurfObj,
1497 NULL,
1498 (CLIPOBJ *)&pdc->co,
1499 &exlo.xlo,
1500 &pdc->dclevel.ca,
1501 &rcDst,
1502 &rcSrc,
1503 NULL,
1504 &pdc->eboFill.BrushObject,
1505 NULL,
1506 WIN32_ROP3_TO_ENG_ROP4(dwRop));
1507
1508 /* Cleanup */
1509 DC_vFinishBlit(pdc, NULL);
1510 EXLATEOBJ_vCleanup(&exlo);
1511
1512 cleanup:
1513 if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB);
1514 if (psurfTmp) SURFACE_ShareUnlockSurface(psurfTmp);
1515 if (hbmTmp) GreDeleteObject(hbmTmp);
1516 if (pdc) DC_UnlockDc(pdc);
1517 }
1518
1519 if (pvBits) ExFreePoolWithTag(pvBits, TAG_DIB);
1520
1521 /* This is not what MSDN says is returned from this function, but it
1522 * follows Wine's dlls/gdi32/dib.c function nulldrv_StretchDIBits
1523 * and it fixes over 100 gdi32:dib regression tests. */
1524 if (dwRop == SRCCOPY)
1525 {
1526 LinesCopied = abs(pbmiSafe->bmiHeader.biHeight);
1527 }
1528 else
1529 {
1530 LinesCopied = pbmiSafe->bmiHeader.biHeight;
1531 }
1532
1533 ExFreePoolWithTag(pbmiSafe, 'imBG');
1534
1535 return LinesCopied;
1536}
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().