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
192 (BitmapInfo
->bmiHeader
.biSize
!= sizeof(BITMAPCOREHEADER
) &&
193 (BitmapInfo
->bmiHeader
.biSize
< sizeof(BITMAPINFOHEADER
) ||
194 BitmapInfo
->bmiHeader
.biSize
> sizeof(BITMAPV5HEADER
))))
200 * Now calculate the color table size. Also if the bitmap info contains
201 * invalid color information it's rejected here.
204 if (!CalculateColorTableSize(&BitmapInfo
->bmiHeader
, &ColorSpec
,
211 * Calculate the size of image data if applicable. We must be careful
212 * to do proper aligning on line ends.
217 if (BitmapInfo
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
220 CoreBitmapInfo
->bmciHeader
.bcHeight
*
221 CoreBitmapInfo
->bmciHeader
.bcWidth
*
222 CoreBitmapInfo
->bmciHeader
.bcBitCount
;
223 DataSize
= ((DataSize
+ 31) & ~31) / 8;
224 DataSize
*= CoreBitmapInfo
->bmciHeader
.bcPlanes
;
228 if (BitmapInfo
->bmiHeader
.biCompression
== BI_RGB
||
229 BitmapInfo
->bmiHeader
.biCompression
== BI_BITFIELDS
)
232 abs(BitmapInfo
->bmiHeader
.biHeight
) *
233 BitmapInfo
->bmiHeader
.biWidth
*
234 BitmapInfo
->bmiHeader
.biBitCount
;
235 DataSize
= ((DataSize
+ 31) & ~31) / 8;
236 DataSize
*= BitmapInfo
->bmiHeader
.biPlanes
;
240 DataSize
= BitmapInfo
->bmiHeader
.biSizeImage
;
246 * If BitmapInfo was originally BITMAPCOREINFO then we need to convert
247 * it to the standard BITMAPINFO layout.
250 if (BitmapInfo
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
252 Size
= sizeof(BITMAPINFOHEADER
);
253 if (ColorSpec
== DIB_RGB_COLORS
)
254 Size
+= PaletteEntryCount
* sizeof(RGBQUAD
);
256 Size
+= PaletteEntryCount
* sizeof(USHORT
);
259 NewBitmapInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Size
);
260 if (NewBitmapInfo
== NULL
)
265 NewBitmapInfo
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
266 NewBitmapInfo
->bmiHeader
.biWidth
= CoreBitmapInfo
->bmciHeader
.bcWidth
;
267 NewBitmapInfo
->bmiHeader
.biHeight
= CoreBitmapInfo
->bmciHeader
.bcHeight
;
268 NewBitmapInfo
->bmiHeader
.biPlanes
= CoreBitmapInfo
->bmciHeader
.bcPlanes
;
269 NewBitmapInfo
->bmiHeader
.biBitCount
= CoreBitmapInfo
->bmciHeader
.bcBitCount
;
270 NewBitmapInfo
->bmiHeader
.biCompression
= BI_RGB
;
271 NewBitmapInfo
->bmiHeader
.biSizeImage
= 0;
272 NewBitmapInfo
->bmiHeader
.biXPelsPerMeter
= 0;
273 NewBitmapInfo
->bmiHeader
.biYPelsPerMeter
= 0;
274 NewBitmapInfo
->bmiHeader
.biClrUsed
= 0;
275 NewBitmapInfo
->bmiHeader
.biClrImportant
= 0;
277 if (PaletteEntryCount
!= 0)
279 if (ColorSpec
== DIB_RGB_COLORS
)
283 for (Index
= 0; Index
< PaletteEntryCount
; Index
++)
285 NewBitmapInfo
->bmiColors
[Index
].rgbRed
=
286 CoreBitmapInfo
->bmciColors
[Index
].rgbtRed
;
287 NewBitmapInfo
->bmiColors
[Index
].rgbGreen
=
288 CoreBitmapInfo
->bmciColors
[Index
].rgbtGreen
;
289 NewBitmapInfo
->bmiColors
[Index
].rgbBlue
=
290 CoreBitmapInfo
->bmciColors
[Index
].rgbtBlue
;
291 NewBitmapInfo
->bmiColors
[Index
].rgbReserved
= 0;
296 RtlCopyMemory(NewBitmapInfo
->bmiColors
,
297 CoreBitmapInfo
->bmciColors
,
298 PaletteEntryCount
* sizeof(USHORT
));
304 ULONG_PTR NewDataPtr
, OldDataPtr
;
306 if (ColorSpec
== DIB_RGB_COLORS
)
308 NewDataPtr
= (ULONG_PTR
)(NewBitmapInfo
->bmiColors
+
310 OldDataPtr
= (ULONG_PTR
)(CoreBitmapInfo
->bmciColors
+
315 NewDataPtr
= (ULONG_PTR
)(NewBitmapInfo
->bmiColors
) +
316 PaletteEntryCount
* sizeof(USHORT
);
317 OldDataPtr
= (ULONG_PTR
)(CoreBitmapInfo
->bmciColors
) +
318 PaletteEntryCount
* sizeof(USHORT
);
321 RtlCopyMemory((PVOID
)NewDataPtr
, (PVOID
)OldDataPtr
, DataSize
);
325 Size
= NewBitmapInfo
->bmiHeader
.biSize
;
326 if (ColorSpec
== DIB_RGB_COLORS
)
327 Size
+= PaletteEntryCount
* sizeof(RGBQUAD
);
329 Size
+= PaletteEntryCount
* sizeof(USHORT
);
331 *BitmapInfoSize
= Size
;
333 return NewBitmapInfo
;
338 LogFontA2W(LPLOGFONTW pW
, CONST LOGFONTA
*pA
)
340 #define COPYS(f,len) MultiByteToWideChar ( CP_THREAD_ACP, 0, pA->f, len, pW->f, len )
341 #define COPYN(f) pW->f = pA->f
346 COPYN(lfOrientation
);
352 COPYN(lfOutPrecision
);
353 COPYN(lfClipPrecision
);
355 COPYN(lfPitchAndFamily
);
356 COPYS(lfFaceName
,LF_FACESIZE
);
364 LogFontW2A(LPLOGFONTA pA
, CONST LOGFONTW
*pW
)
366 #define COPYS(f,len) WideCharToMultiByte ( CP_THREAD_ACP, 0, pW->f, len, pA->f, len, NULL, NULL )
367 #define COPYN(f) pA->f = pW->f
372 COPYN(lfOrientation
);
378 COPYN(lfOutPrecision
);
379 COPYN(lfClipPrecision
);
381 COPYN(lfPitchAndFamily
);
382 COPYS(lfFaceName
,LF_FACESIZE
);
390 EnumLogFontExW2A( LPENUMLOGFONTEXA fontA
, CONST ENUMLOGFONTEXW
*fontW
)
392 LogFontW2A( (LPLOGFONTA
)fontA
, (CONST LOGFONTW
*)fontW
);
394 WideCharToMultiByte( CP_THREAD_ACP
, 0, fontW
->elfFullName
, -1,
395 (LPSTR
) fontA
->elfFullName
, LF_FULLFACESIZE
, NULL
, NULL
);
396 fontA
->elfFullName
[LF_FULLFACESIZE
-1] = '\0';
397 WideCharToMultiByte( CP_THREAD_ACP
, 0, fontW
->elfStyle
, -1,
398 (LPSTR
) fontA
->elfStyle
, LF_FACESIZE
, NULL
, NULL
);
399 fontA
->elfStyle
[LF_FACESIZE
-1] = '\0';
400 WideCharToMultiByte( CP_THREAD_ACP
, 0, fontW
->elfScript
, -1,
401 (LPSTR
) fontA
->elfScript
, LF_FACESIZE
, NULL
, NULL
);
402 fontA
->elfScript
[LF_FACESIZE
-1] = '\0';