4 * @name CalculateColorTableSize
6 * Internal routine to calculate the number of color table entries.
8 * @param BitmapInfoHeader
9 * Input bitmap information header, can be any version of
10 * BITMAPINFOHEADER or BITMAPCOREHEADER.
13 * Pointer to variable which specifiing the color mode (DIB_RGB_COLORS
14 * or DIB_RGB_COLORS). On successful return this value is normalized
15 * according to the bitmap info.
17 * @param ColorTableSize
18 * On successful return this variable is filled with number of
19 * entries in color table for the image with specified parameters.
22 * TRUE if the input values together form a valid image, FALSE otherwise.
26 CalculateColorTableSize(
27 CONST BITMAPINFOHEADER
*BitmapInfoHeader
,
36 * At first get some basic parameters from the passed BitmapInfoHeader
37 * structure. It can have one of the following formats:
38 * - BITMAPCOREHEADER (the oldest one with totally different layout
40 * - BITMAPINFOHEADER (the standard and most common header)
41 * - BITMAPV4HEADER (extension of BITMAPINFOHEADER)
42 * - BITMAPV5HEADER (extension of BITMAPV4HEADER)
45 if (BitmapInfoHeader
->biSize
== sizeof(BITMAPCOREHEADER
))
47 BitCount
= ((LPBITMAPCOREHEADER
)BitmapInfoHeader
)->bcBitCount
;
53 BitCount
= BitmapInfoHeader
->biBitCount
;
54 ClrUsed
= BitmapInfoHeader
->biClrUsed
;
55 Compression
= BitmapInfoHeader
->biCompression
;
61 if (*ColorSpec
== DIB_PAL_COLORS
)
62 *ColorSpec
= DIB_RGB_COLORS
;
64 if (BitCount
!= 16 && BitCount
!= 32)
68 * For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in
69 * the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask).
70 * For BITMAPINFOHEADER the color masks are stored in the palette.
73 if (BitmapInfoHeader
->biSize
> sizeof(BITMAPINFOHEADER
))
84 *ColorTableSize
= ClrUsed
? min(ClrUsed
, 2) : 2;
88 *ColorTableSize
= ClrUsed
? min(ClrUsed
, 16) : 16;
92 *ColorTableSize
= ClrUsed
? min(ClrUsed
, 256) : 256;
96 if (*ColorSpec
== DIB_PAL_COLORS
)
97 *ColorSpec
= DIB_RGB_COLORS
;
98 if (BitCount
!= 16 && BitCount
!= 24 && BitCount
!= 32)
100 *ColorTableSize
= ClrUsed
;
107 *ColorTableSize
= ClrUsed
? min(ClrUsed
, 16) : 16;
115 *ColorTableSize
= ClrUsed
? min(ClrUsed
, 256) : 256;
122 *ColorTableSize
= ClrUsed
;
131 * @name ConvertBitmapInfo
133 * Internal routine to convert a user-passed BITMAPINFO structure into
134 * unified BITMAPINFO structure.
137 * Input bitmap info, can be any version of BITMAPINFO or
140 * Specifies whether the bmiColors member of the BITMAPINFO structure
141 * contains a valid color table and, if so, whether the entries in
142 * this color table contain explicit red, green, blue (DIB_RGB_COLORS)
143 * values or palette indexes (DIB_PAL_COLORS).
144 * @param BitmapInfoSize
145 * On successful return contains the size of the returned BITMAPINFO
146 * structure. If FollowedByData is TRUE the size includes the number
147 * of bytes occupied by the image data.
148 * @param FollowedByData
149 * Specifies if the BITMAPINFO header is immediately followed
150 * by the actual bitmap data (eg. as passed to CreateDIBPatternBrush).
153 * Either the original BitmapInfo or newly allocated structure is
154 * returned. For the later case the caller is responsible for freeing the
155 * memory using RtlFreeHeap with the current process heap.
158 * PBITMAPINFO NewBitmapInfo;
159 * UINT NewBitmapInfoSize;
161 * NewBitmapInfo = ConvertBitmapInfo(OldBitmapInfo, DIB_RGB_COLORS,
162 * &NewBitmapInfoSize, FALSE);
165 * <do something with the bitmap info>
166 * if (NewBitmapInfo != OldBitmapInfo)
167 * RtlFreeHeap(RtlGetProcessHeap(), 0, NewBitmapInfo);
173 CONST BITMAPINFO
*BitmapInfo
,
175 UINT
*BitmapInfoSize
,
178 LPBITMAPINFO NewBitmapInfo
= (LPBITMAPINFO
)BitmapInfo
;
179 LPBITMAPCOREINFO CoreBitmapInfo
= (LPBITMAPCOREINFO
)BitmapInfo
;
182 UINT PaletteEntryCount
= 0;
185 * At first check if the passed BitmapInfo structure has valid size. It
186 * can have one of these headers: BITMAPCOREHEADER, BITMAPINFOHEADER,
187 * BITMAPV4HEADER or BITMAPV5HEADER (see CalculateColorTableSize for
191 if (BitmapInfo
->bmiHeader
.biSize
!= sizeof(BITMAPCOREHEADER
) &&
192 (BitmapInfo
->bmiHeader
.biSize
< sizeof(BITMAPINFOHEADER
) ||
193 BitmapInfo
->bmiHeader
.biSize
> sizeof(BITMAPV5HEADER
)))
199 * Now calculate the color table size. Also if the bitmap info contains
200 * invalid color information it's rejected here.
203 if (!CalculateColorTableSize(&BitmapInfo
->bmiHeader
, &ColorSpec
,
210 * Calculate the size of image data if applicable. We must be careful
211 * to do proper aligning on line ends.
216 if (BitmapInfo
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
219 CoreBitmapInfo
->bmciHeader
.bcHeight
*
220 CoreBitmapInfo
->bmciHeader
.bcWidth
*
221 CoreBitmapInfo
->bmciHeader
.bcBitCount
;
222 DataSize
= ((DataSize
+ 31) & ~31) / 8;
223 DataSize
*= CoreBitmapInfo
->bmciHeader
.bcPlanes
;
227 if (BitmapInfo
->bmiHeader
.biCompression
== BI_RGB
||
228 BitmapInfo
->bmiHeader
.biCompression
== BI_BITFIELDS
)
231 abs(BitmapInfo
->bmiHeader
.biHeight
) *
232 BitmapInfo
->bmiHeader
.biWidth
*
233 BitmapInfo
->bmiHeader
.biBitCount
;
234 DataSize
= ((DataSize
+ 31) & ~31) / 8;
235 DataSize
*= BitmapInfo
->bmiHeader
.biPlanes
;
239 DataSize
= BitmapInfo
->bmiHeader
.biSizeImage
;
245 * If BitmapInfo was originally BITMAPCOREINFO then we need to convert
246 * it to the standard BITMAPINFO layout.
249 if (BitmapInfo
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
251 Size
= sizeof(BITMAPINFOHEADER
);
252 if (ColorSpec
== DIB_RGB_COLORS
)
253 Size
+= PaletteEntryCount
* sizeof(RGBQUAD
);
255 Size
+= PaletteEntryCount
* sizeof(USHORT
);
258 NewBitmapInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Size
);
259 if (NewBitmapInfo
== NULL
)
264 NewBitmapInfo
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
265 NewBitmapInfo
->bmiHeader
.biWidth
= CoreBitmapInfo
->bmciHeader
.bcWidth
;
266 NewBitmapInfo
->bmiHeader
.biHeight
= CoreBitmapInfo
->bmciHeader
.bcHeight
;
267 NewBitmapInfo
->bmiHeader
.biPlanes
= CoreBitmapInfo
->bmciHeader
.bcPlanes
;
268 NewBitmapInfo
->bmiHeader
.biBitCount
= CoreBitmapInfo
->bmciHeader
.bcBitCount
;
269 NewBitmapInfo
->bmiHeader
.biCompression
= BI_RGB
;
270 NewBitmapInfo
->bmiHeader
.biSizeImage
= 0;
271 NewBitmapInfo
->bmiHeader
.biXPelsPerMeter
= 0;
272 NewBitmapInfo
->bmiHeader
.biYPelsPerMeter
= 0;
273 NewBitmapInfo
->bmiHeader
.biClrUsed
= 0;
274 NewBitmapInfo
->bmiHeader
.biClrImportant
= 0;
276 if (PaletteEntryCount
!= 0)
278 if (ColorSpec
== DIB_RGB_COLORS
)
282 for (Index
= 0; Index
< PaletteEntryCount
; Index
++)
284 NewBitmapInfo
->bmiColors
[Index
].rgbRed
=
285 CoreBitmapInfo
->bmciColors
[Index
].rgbtRed
;
286 NewBitmapInfo
->bmiColors
[Index
].rgbGreen
=
287 CoreBitmapInfo
->bmciColors
[Index
].rgbtGreen
;
288 NewBitmapInfo
->bmiColors
[Index
].rgbBlue
=
289 CoreBitmapInfo
->bmciColors
[Index
].rgbtBlue
;
290 NewBitmapInfo
->bmiColors
[Index
].rgbReserved
= 0;
295 RtlCopyMemory(NewBitmapInfo
->bmiColors
,
296 CoreBitmapInfo
->bmciColors
,
297 PaletteEntryCount
* sizeof(USHORT
));
303 ULONG_PTR NewDataPtr
, OldDataPtr
;
305 if (ColorSpec
== DIB_RGB_COLORS
)
307 NewDataPtr
= (ULONG_PTR
)(NewBitmapInfo
->bmiColors
+
309 OldDataPtr
= (ULONG_PTR
)(CoreBitmapInfo
->bmciColors
+
314 NewDataPtr
= (ULONG_PTR
)(NewBitmapInfo
->bmiColors
) +
315 PaletteEntryCount
* sizeof(USHORT
);
316 OldDataPtr
= (ULONG_PTR
)(CoreBitmapInfo
->bmciColors
) +
317 PaletteEntryCount
* sizeof(USHORT
);
320 RtlCopyMemory((PVOID
)NewDataPtr
, (PVOID
)OldDataPtr
, DataSize
);
324 Size
= NewBitmapInfo
->bmiHeader
.biSize
;
325 if (ColorSpec
== DIB_RGB_COLORS
)
326 Size
+= PaletteEntryCount
* sizeof(RGBQUAD
);
328 Size
+= PaletteEntryCount
* sizeof(USHORT
);
330 *BitmapInfoSize
= Size
;
332 return NewBitmapInfo
;
337 LogFontA2W(LPLOGFONTW pW
, CONST LOGFONTA
*pA
)
339 #define COPYS(f,len) MultiByteToWideChar ( CP_THREAD_ACP, 0, pA->f, len, pW->f, len )
340 #define COPYN(f) pW->f = pA->f
345 COPYN(lfOrientation
);
351 COPYN(lfOutPrecision
);
352 COPYN(lfClipPrecision
);
354 COPYN(lfPitchAndFamily
);
355 COPYS(lfFaceName
,LF_FACESIZE
);
363 LogFontW2A(LPLOGFONTA pA
, CONST LOGFONTW
*pW
)
365 #define COPYS(f,len) WideCharToMultiByte ( CP_THREAD_ACP, 0, pW->f, len, pA->f, len, NULL, NULL )
366 #define COPYN(f) pA->f = pW->f
371 COPYN(lfOrientation
);
377 COPYN(lfOutPrecision
);
378 COPYN(lfClipPrecision
);
380 COPYN(lfPitchAndFamily
);
381 COPYS(lfFaceName
,LF_FACESIZE
);
389 EnumLogFontExW2A( LPENUMLOGFONTEXA fontA
, CONST ENUMLOGFONTEXW
*fontW
)
391 LogFontW2A( (LPLOGFONTA
)fontA
, (CONST LOGFONTW
*)fontW
);
393 WideCharToMultiByte( CP_THREAD_ACP
, 0, fontW
->elfFullName
, -1,
394 (LPSTR
) fontA
->elfFullName
, LF_FULLFACESIZE
, NULL
, NULL
);
395 fontA
->elfFullName
[LF_FULLFACESIZE
-1] = '\0';
396 WideCharToMultiByte( CP_THREAD_ACP
, 0, fontW
->elfStyle
, -1,
397 (LPSTR
) fontA
->elfStyle
, LF_FACESIZE
, NULL
, NULL
);
398 fontA
->elfStyle
[LF_FACESIZE
-1] = '\0';
399 WideCharToMultiByte( CP_THREAD_ACP
, 0, fontW
->elfScript
, -1,
400 (LPSTR
) fontA
->elfScript
, LF_FACESIZE
, NULL
, NULL
);
401 fontA
->elfScript
[LF_FACESIZE
-1] = '\0';