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 DataSize
= DIB_BitmapBitsSize((PBITMAPINFO
)BitmapInfo
);
221 * If BitmapInfo was originally BITMAPCOREINFO then we need to convert
222 * it to the standard BITMAPINFO layout.
225 if (BitmapInfo
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
227 Size
= sizeof(BITMAPINFOHEADER
);
228 if (ColorSpec
== DIB_RGB_COLORS
)
229 Size
+= PaletteEntryCount
* sizeof(RGBQUAD
);
231 Size
+= PaletteEntryCount
* sizeof(USHORT
);
234 NewBitmapInfo
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Size
);
235 if (NewBitmapInfo
== NULL
)
240 NewBitmapInfo
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
241 NewBitmapInfo
->bmiHeader
.biWidth
= CoreBitmapInfo
->bmciHeader
.bcWidth
;
242 NewBitmapInfo
->bmiHeader
.biHeight
= CoreBitmapInfo
->bmciHeader
.bcHeight
;
243 NewBitmapInfo
->bmiHeader
.biPlanes
= CoreBitmapInfo
->bmciHeader
.bcPlanes
;
244 NewBitmapInfo
->bmiHeader
.biBitCount
= CoreBitmapInfo
->bmciHeader
.bcBitCount
;
245 NewBitmapInfo
->bmiHeader
.biCompression
= BI_RGB
;
246 NewBitmapInfo
->bmiHeader
.biSizeImage
= 0;
247 NewBitmapInfo
->bmiHeader
.biXPelsPerMeter
= 0;
248 NewBitmapInfo
->bmiHeader
.biYPelsPerMeter
= 0;
249 NewBitmapInfo
->bmiHeader
.biClrUsed
= 0;
250 NewBitmapInfo
->bmiHeader
.biClrImportant
= 0;
252 if (PaletteEntryCount
!= 0)
254 if (ColorSpec
== DIB_RGB_COLORS
)
258 for (Index
= 0; Index
< PaletteEntryCount
; Index
++)
260 NewBitmapInfo
->bmiColors
[Index
].rgbRed
=
261 CoreBitmapInfo
->bmciColors
[Index
].rgbtRed
;
262 NewBitmapInfo
->bmiColors
[Index
].rgbGreen
=
263 CoreBitmapInfo
->bmciColors
[Index
].rgbtGreen
;
264 NewBitmapInfo
->bmiColors
[Index
].rgbBlue
=
265 CoreBitmapInfo
->bmciColors
[Index
].rgbtBlue
;
266 NewBitmapInfo
->bmiColors
[Index
].rgbReserved
= 0;
271 RtlCopyMemory(NewBitmapInfo
->bmiColors
,
272 CoreBitmapInfo
->bmciColors
,
273 PaletteEntryCount
* sizeof(USHORT
));
279 ULONG_PTR NewDataPtr
, OldDataPtr
;
281 if (ColorSpec
== DIB_RGB_COLORS
)
283 NewDataPtr
= (ULONG_PTR
)(NewBitmapInfo
->bmiColors
+
285 OldDataPtr
= (ULONG_PTR
)(CoreBitmapInfo
->bmciColors
+
290 NewDataPtr
= (ULONG_PTR
)(NewBitmapInfo
->bmiColors
) +
291 PaletteEntryCount
* sizeof(USHORT
);
292 OldDataPtr
= (ULONG_PTR
)(CoreBitmapInfo
->bmciColors
) +
293 PaletteEntryCount
* sizeof(USHORT
);
296 RtlCopyMemory((PVOID
)NewDataPtr
, (PVOID
)OldDataPtr
, DataSize
);
300 Size
= NewBitmapInfo
->bmiHeader
.biSize
;
301 if (ColorSpec
== DIB_RGB_COLORS
)
302 Size
+= PaletteEntryCount
* sizeof(RGBQUAD
);
304 Size
+= PaletteEntryCount
* sizeof(USHORT
);
306 *BitmapInfoSize
= Size
;
308 return NewBitmapInfo
;
313 LogFontA2W(LPLOGFONTW pW
, CONST LOGFONTA
*pA
)
315 #define COPYS(f,len) MultiByteToWideChar ( CP_THREAD_ACP, 0, pA->f, len, pW->f, len )
316 #define COPYN(f) pW->f = pA->f
321 COPYN(lfOrientation
);
327 COPYN(lfOutPrecision
);
328 COPYN(lfClipPrecision
);
330 COPYN(lfPitchAndFamily
);
331 COPYS(lfFaceName
,LF_FACESIZE
);
332 pW
->lfFaceName
[LF_FACESIZE
- 1] = '\0';
340 LogFontW2A(LPLOGFONTA pA
, CONST LOGFONTW
*pW
)
342 #define COPYS(f,len) WideCharToMultiByte ( CP_THREAD_ACP, 0, pW->f, len, pA->f, len, NULL, NULL )
343 #define COPYN(f) pA->f = pW->f
348 COPYN(lfOrientation
);
354 COPYN(lfOutPrecision
);
355 COPYN(lfClipPrecision
);
357 COPYN(lfPitchAndFamily
);
358 COPYS(lfFaceName
,LF_FACESIZE
);
359 pA
->lfFaceName
[LF_FACESIZE
- 1] = '\0';
367 EnumLogFontExW2A( LPENUMLOGFONTEXA fontA
, CONST ENUMLOGFONTEXW
*fontW
)
369 LogFontW2A( (LPLOGFONTA
)fontA
, (CONST LOGFONTW
*)fontW
);
371 WideCharToMultiByte( CP_THREAD_ACP
, 0, fontW
->elfFullName
, -1,
372 (LPSTR
) fontA
->elfFullName
, LF_FULLFACESIZE
, NULL
, NULL
);
373 fontA
->elfFullName
[LF_FULLFACESIZE
-1] = '\0';
374 WideCharToMultiByte( CP_THREAD_ACP
, 0, fontW
->elfStyle
, -1,
375 (LPSTR
) fontA
->elfStyle
, LF_FACESIZE
, NULL
, NULL
);
376 fontA
->elfStyle
[LF_FACESIZE
-1] = '\0';
377 WideCharToMultiByte( CP_THREAD_ACP
, 0, fontW
->elfScript
, -1,
378 (LPSTR
) fontA
->elfScript
, LF_FACESIZE
, NULL
, NULL
);
379 fontA
->elfScript
[LF_FACESIZE
-1] = '\0';