ReactOS  0.4.14-dev-41-g31d7680
utils.c
Go to the documentation of this file.
1 #include <precomp.h>
2 
3 /* LoadLPK global variables */
8 
33  CONST BITMAPINFOHEADER *BitmapInfoHeader,
34  UINT *ColorSpec,
35  UINT *ColorTableSize)
36 {
37  WORD BitCount;
38  DWORD ClrUsed;
39  DWORD Compression;
40 
41  /*
42  * At first get some basic parameters from the passed BitmapInfoHeader
43  * structure. It can have one of the following formats:
44  * - BITMAPCOREHEADER (the oldest one with totally different layout
45  * from the others)
46  * - BITMAPINFOHEADER (the standard and most common header)
47  * - BITMAPV4HEADER (extension of BITMAPINFOHEADER)
48  * - BITMAPV5HEADER (extension of BITMAPV4HEADER)
49  */
50 
51  if (BitmapInfoHeader->biSize == sizeof(BITMAPCOREHEADER))
52  {
53  BitCount = ((LPBITMAPCOREHEADER)BitmapInfoHeader)->bcBitCount;
54  ClrUsed = 0;
55  Compression = BI_RGB;
56  }
57  else
58  {
59  BitCount = BitmapInfoHeader->biBitCount;
60  ClrUsed = BitmapInfoHeader->biClrUsed;
61  Compression = BitmapInfoHeader->biCompression;
62  }
63 
64  switch (Compression)
65  {
66  case BI_BITFIELDS:
67  if (*ColorSpec == DIB_PAL_COLORS)
68  *ColorSpec = DIB_RGB_COLORS;
69 
70  if (BitCount != 16 && BitCount != 32)
71  return FALSE;
72 
73  /*
74  * For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in
75  * the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask).
76  * For BITMAPINFOHEADER the color masks are stored in the palette.
77  */
78 
79  if (BitmapInfoHeader->biSize > sizeof(BITMAPINFOHEADER))
80  *ColorTableSize = 0;
81  else
82  *ColorTableSize = 3;
83 
84  return TRUE;
85 
86  case BI_RGB:
87  switch (BitCount)
88  {
89  case 1:
90  *ColorTableSize = ClrUsed ? min(ClrUsed, 2) : 2;
91  return TRUE;
92 
93  case 4:
94  *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
95  return TRUE;
96 
97  case 8:
98  *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;
99  return TRUE;
100 
101  default:
102  if (*ColorSpec == DIB_PAL_COLORS)
103  *ColorSpec = DIB_RGB_COLORS;
104  if (BitCount != 16 && BitCount != 24 && BitCount != 32)
105  return FALSE;
106  *ColorTableSize = ClrUsed;
107  return TRUE;
108  }
109 
110  case BI_RLE4:
111  if (BitCount == 4)
112  {
113  *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
114  return TRUE;
115  }
116  return FALSE;
117 
118  case BI_RLE8:
119  if (BitCount == 8)
120  {
121  *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;
122  return TRUE;
123  }
124  return FALSE;
125 
126  case BI_JPEG:
127  case BI_PNG:
128  *ColorTableSize = ClrUsed;
129  return TRUE;
130 
131  default:
132  return FALSE;
133  }
134 }
135 
179  CONST BITMAPINFO *BitmapInfo,
180  UINT ColorSpec,
181  UINT *BitmapInfoSize,
182  BOOL FollowedByData)
183 {
184  LPBITMAPINFO NewBitmapInfo = (LPBITMAPINFO)BitmapInfo;
185  LPBITMAPCOREINFO CoreBitmapInfo = (LPBITMAPCOREINFO)BitmapInfo;
186  DWORD Size = 0;
187  ULONG DataSize = 0;
188  UINT PaletteEntryCount = 0;
189 
190  /*
191  * At first check if the passed BitmapInfo structure has valid size. It
192  * can have one of these headers: BITMAPCOREHEADER, BITMAPINFOHEADER,
193  * BITMAPV4HEADER or BITMAPV5HEADER (see CalculateColorTableSize for
194  * description).
195  */
196 
197  if ( !BitmapInfo ||
198  (BitmapInfo->bmiHeader.biSize != sizeof(BITMAPCOREHEADER) &&
199  (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER) ||
200  BitmapInfo->bmiHeader.biSize > sizeof(BITMAPV5HEADER))))
201  {
202  return NULL;
203  }
204 
205  /*
206  * Now calculate the color table size. Also if the bitmap info contains
207  * invalid color information it's rejected here.
208  */
209 
210  if (!CalculateColorTableSize(&BitmapInfo->bmiHeader, &ColorSpec,
211  &PaletteEntryCount))
212  {
213  return NULL;
214  }
215 
216  /*
217  * Calculate the size of image data if applicable. We must be careful
218  * to do proper aligning on line ends.
219  */
220 
221  if (FollowedByData)
222  {
223  DataSize = GdiGetBitmapBitsSize((PBITMAPINFO)BitmapInfo );
224  }
225 
226  /*
227  * If BitmapInfo was originally BITMAPCOREINFO then we need to convert
228  * it to the standard BITMAPINFO layout.
229  */
230 
231  if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
232  {
233  Size = sizeof(BITMAPINFOHEADER);
234  if (ColorSpec == DIB_RGB_COLORS)
235  Size += PaletteEntryCount * sizeof(RGBQUAD);
236  else
237  Size += PaletteEntryCount * sizeof(USHORT);
238  Size += DataSize;
239 
240  NewBitmapInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
241  if (NewBitmapInfo == NULL)
242  {
243  return NULL;
244  }
245 
246  NewBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
247  NewBitmapInfo->bmiHeader.biWidth = CoreBitmapInfo->bmciHeader.bcWidth;
248  NewBitmapInfo->bmiHeader.biHeight = CoreBitmapInfo->bmciHeader.bcHeight;
249  NewBitmapInfo->bmiHeader.biPlanes = CoreBitmapInfo->bmciHeader.bcPlanes;
250  NewBitmapInfo->bmiHeader.biBitCount = CoreBitmapInfo->bmciHeader.bcBitCount;
251  NewBitmapInfo->bmiHeader.biCompression = BI_RGB;
252  NewBitmapInfo->bmiHeader.biSizeImage = 0;
253  NewBitmapInfo->bmiHeader.biXPelsPerMeter = 0;
254  NewBitmapInfo->bmiHeader.biYPelsPerMeter = 0;
255  NewBitmapInfo->bmiHeader.biClrUsed = 0;
256  NewBitmapInfo->bmiHeader.biClrImportant = 0;
257 
258  if (PaletteEntryCount != 0)
259  {
260  if (ColorSpec == DIB_RGB_COLORS)
261  {
262  ULONG Index;
263 
264  for (Index = 0; Index < PaletteEntryCount; Index++)
265  {
266  NewBitmapInfo->bmiColors[Index].rgbRed =
267  CoreBitmapInfo->bmciColors[Index].rgbtRed;
268  NewBitmapInfo->bmiColors[Index].rgbGreen =
269  CoreBitmapInfo->bmciColors[Index].rgbtGreen;
270  NewBitmapInfo->bmiColors[Index].rgbBlue =
271  CoreBitmapInfo->bmciColors[Index].rgbtBlue;
272  NewBitmapInfo->bmiColors[Index].rgbReserved = 0;
273  }
274  }
275  else
276  {
277  RtlCopyMemory(NewBitmapInfo->bmiColors,
278  CoreBitmapInfo->bmciColors,
279  PaletteEntryCount * sizeof(USHORT));
280  }
281  }
282 
283  if (FollowedByData)
284  {
285  ULONG_PTR NewDataPtr, OldDataPtr;
286 
287  if (ColorSpec == DIB_RGB_COLORS)
288  {
289  NewDataPtr = (ULONG_PTR)(NewBitmapInfo->bmiColors +
290  PaletteEntryCount);
291  OldDataPtr = (ULONG_PTR)(CoreBitmapInfo->bmciColors +
292  PaletteEntryCount);
293  }
294  else
295  {
296  NewDataPtr = (ULONG_PTR)(NewBitmapInfo->bmiColors) +
297  PaletteEntryCount * sizeof(USHORT);
298  OldDataPtr = (ULONG_PTR)(CoreBitmapInfo->bmciColors) +
299  PaletteEntryCount * sizeof(USHORT);
300  }
301 
302  RtlCopyMemory((PVOID)NewDataPtr, (PVOID)OldDataPtr, DataSize);
303  }
304  }
305  else
306  {
307  /* Verify some data validity */
308  switch (BitmapInfo->bmiHeader.biCompression)
309  {
310  case BI_RLE8:
311  if (BitmapInfo->bmiHeader.biBitCount != 8)
312  return NULL;
313  if (BitmapInfo->bmiHeader.biHeight < 0)
314  return NULL;
315  break;
316  case BI_RLE4:
317  if (BitmapInfo->bmiHeader.biBitCount != 4)
318  return NULL;
319  if (BitmapInfo->bmiHeader.biHeight < 0)
320  return NULL;
321  break;
322  default:
323  break;
324  }
325 
326  /* Non "standard" formats must have a valid size set */
327  if ((BitmapInfo->bmiHeader.biCompression != BI_RGB) &&
328  (BitmapInfo->bmiHeader.biCompression != BI_BITFIELDS))
329  {
330  if (BitmapInfo->bmiHeader.biSizeImage == 0)
331  return NULL;
332  }
333  }
334 
335  Size = NewBitmapInfo->bmiHeader.biSize;
336  if (ColorSpec == DIB_RGB_COLORS)
337  Size += PaletteEntryCount * sizeof(RGBQUAD);
338  else
339  Size += PaletteEntryCount * sizeof(USHORT);
340  Size += DataSize;
341  *BitmapInfoSize = Size;
342 
343  return NewBitmapInfo;
344 }
345 
346 VOID
347 WINAPI
349 {
350 #define COPYS(f,len) MultiByteToWideChar ( CP_THREAD_ACP, 0, pA->f, len, pW->f, len )
351 #define COPYN(f) pW->f = pA->f
352 
353  COPYN(lfHeight);
354  COPYN(lfWidth);
355  COPYN(lfEscapement);
356  COPYN(lfOrientation);
357  COPYN(lfWeight);
358  COPYN(lfItalic);
359  COPYN(lfUnderline);
360  COPYN(lfStrikeOut);
361  COPYN(lfCharSet);
362  COPYN(lfOutPrecision);
363  COPYN(lfClipPrecision);
364  COPYN(lfQuality);
365  COPYN(lfPitchAndFamily);
366  COPYS(lfFaceName,LF_FACESIZE);
367  pW->lfFaceName[LF_FACESIZE - 1] = '\0';
368 
369 #undef COPYN
370 #undef COPYS
371 }
372 
373 VOID
374 WINAPI
376 {
377 #define COPYS(f,len) WideCharToMultiByte ( CP_THREAD_ACP, 0, pW->f, len, pA->f, len, NULL, NULL )
378 #define COPYN(f) pA->f = pW->f
379 
380  COPYN(lfHeight);
381  COPYN(lfWidth);
382  COPYN(lfEscapement);
383  COPYN(lfOrientation);
384  COPYN(lfWeight);
385  COPYN(lfItalic);
386  COPYN(lfUnderline);
387  COPYN(lfStrikeOut);
388  COPYN(lfCharSet);
389  COPYN(lfOutPrecision);
390  COPYN(lfClipPrecision);
391  COPYN(lfQuality);
392  COPYN(lfPitchAndFamily);
393  COPYS(lfFaceName,LF_FACESIZE);
394  pA->lfFaceName[LF_FACESIZE - 1] = '\0';
395 
396 #undef COPYN
397 #undef COPYS
398 }
399 
400 VOID
401 WINAPI
403 {
404  LogFontW2A( (LPLOGFONTA)fontA, (CONST LOGFONTW *)fontW );
405 
406  WideCharToMultiByte( CP_THREAD_ACP, 0, fontW->elfFullName, -1,
407  (LPSTR) fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
408  fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
409  WideCharToMultiByte( CP_THREAD_ACP, 0, fontW->elfStyle, -1,
410  (LPSTR) fontA->elfStyle, LF_FACESIZE, NULL, NULL );
411  fontA->elfStyle[LF_FACESIZE-1] = '\0';
412  WideCharToMultiByte( CP_THREAD_ACP, 0, fontW->elfScript, -1,
413  (LPSTR) fontA->elfScript, LF_FACESIZE, NULL, NULL );
414  fontA->elfScript[LF_FACESIZE-1] = '\0';
415 }
416 
417 /*
418 * LPK.DLL loader function
419 *
420 * Returns TRUE if a valid parameter was passed and loading was successful,
421 * returns FALSE otherwise.
422 */
423 BOOL WINAPI LoadLPK(INT LpkFunctionID)
424 {
425  if(!hLpk) // Check if the DLL is already loaded
426  hLpk = LoadLibraryW(L"lpk.dll");
427 
428  if (hLpk)
429  {
430  switch (LpkFunctionID)
431  {
432  case LPK_INIT:
433  return TRUE;
434 
435  case LPK_ETO:
436  if (!LpkExtTextOut) // Check if the function is already loaded
437  LpkExtTextOut = (LPKETO) GetProcAddress(hLpk, "LpkExtTextOut");
438 
439  if (!LpkExtTextOut)
440  {
441  FreeLibrary(hLpk);
442  return FALSE;
443  }
444 
445  return TRUE;
446 
447  case LPK_GCP:
448  if (!LpkGetCharacterPlacement) // Check if the function is already loaded
449  LpkGetCharacterPlacement = (LPKGCP) GetProcAddress(hLpk, "LpkGetCharacterPlacement");
450 
452  {
453  FreeLibrary(hLpk);
454  return FALSE;
455  }
456 
457  return TRUE;
458 
459  case LPK_GTEP:
460  if (!LpkGetTextExtentExPoint) // Check if the function is already loaded
461  LpkGetTextExtentExPoint = (LPKGTEP) GetProcAddress(hLpk, "LpkGetTextExtentExPoint");
462 
464  {
465  FreeLibrary(hLpk);
466  return FALSE;
467  }
468 
469  return TRUE;
470 
471  default:
472  FreeLibrary(hLpk);
473  return FALSE;
474  }
475  }
476 
477  else
478  return FALSE;
479 }
#define COPYN(f)
BYTE rgbtBlue
Definition: wingdi.h:1433
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define LF_FACESIZE
Definition: dimm.idl:39
#define LF_FULLFACESIZE
Definition: wingdi.h:41
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1471
#define WideCharToMultiByte
Definition: compat.h:101
DWORD biClrImportant
Definition: amvideo.idl:40
struct tagBITMAPINFO * LPBITMAPINFO
#define DIB_PAL_COLORS
Definition: wingdi.h:365
LPKETO LpkExtTextOut
Definition: utils.c:5
int WINAPI GdiGetBitmapBitsSize(BITMAPINFO *lpbmi)
Definition: bitmap.c:161
LONG biXPelsPerMeter
Definition: amvideo.idl:37
struct tagBITMAPINFOHEADER BITMAPINFOHEADER
#define BI_JPEG
Definition: wingdi.h:38
char * LPSTR
Definition: xmlstorage.h:182
LONG biYPelsPerMeter
Definition: amvideo.idl:38
int32_t INT
Definition: typedefs.h:56
#define BI_BITFIELDS
Definition: mmreg.h:507
UCHAR rgbBlue
Definition: inbv.c:170
CHAR lfFaceName[LF_FACESIZE]
Definition: wingdi.h:1889
uint32_t ULONG_PTR
Definition: typedefs.h:63
UCHAR rgbGreen
Definition: inbv.c:171
UCHAR rgbRed
Definition: inbv.c:172
BITMAPCOREHEADER bmciHeader
Definition: wingdi.h:1448
LPKGTEP LpkGetTextExtentExPoint
Definition: utils.c:7
VOID WINAPI LogFontW2A(LPLOGFONTA pA, CONST LOGFONTW *pW)
Definition: utils.c:375
unsigned int BOOL
Definition: ntddk_ex.h:94
DWORD biCompression
Definition: amvideo.idl:35
#define LoadLibraryW(x)
Definition: compat.h:404
smooth NULL
Definition: ftsmooth.c:416
RGBTRIPLE bmciColors[1]
Definition: wingdi.h:1449
DWORD(WINAPI * LPKGCP)(HDC hdc, LPCWSTR lpString, INT uCount, INT nMaxExtent, LPGCP_RESULTSW lpResults, DWORD dwFlags, DWORD dwUnused)
Definition: gdi32p.h:44
#define COPYS(f, len)
HINSTANCE hLpk
Definition: utils.c:4
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
struct tagRGBQUAD RGBQUAD
#define FreeLibrary(x)
Definition: compat.h:405
RGBQUAD bmiColors[1]
Definition: wingdi.h:1472
struct tagBITMAPCOREHEADER * LPBITMAPCOREHEADER
#define WINAPI
Definition: msvc.h:8
static const UCHAR Index[8]
Definition: usbohci.c:18
BOOL(WINAPI * LPKGTEP)(HDC hdc, LPCWSTR lpString, INT cString, INT nMaxExtent, LPINT lpnFit, LPINT lpnDx, LPSIZE lpSize, DWORD dwUnused, int unknown)
Definition: gdi32p.h:55
unsigned short WORD
Definition: ntddk_ex.h:93
#define LPK_GTEP
Definition: gdi32p.h:84
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD biSizeImage
Definition: amvideo.idl:36
struct _BITMAPCOREINFO * LPBITMAPCOREINFO
static const WCHAR fontW[]
Definition: editor.c:78
static const WCHAR L[]
Definition: oid.c:1250
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
BOOL WINAPI LoadLPK(INT LpkFunctionID)
Definition: utils.c:423
#define LPK_ETO
Definition: gdi32p.h:82
VOID WINAPI EnumLogFontExW2A(LPENUMLOGFONTEXA fontA, CONST ENUMLOGFONTEXW *fontW)
Definition: utils.c:402
VOID WINAPI LogFontA2W(LPLOGFONTW pW, CONST LOGFONTA *pA)
Definition: utils.c:348
unsigned short USHORT
Definition: pedump.c:61
#define BI_PNG
Definition: wingdi.h:39
#define min(a, b)
Definition: monoChain.cc:55
BYTE rgbtRed
Definition: wingdi.h:1435
unsigned int UINT
Definition: ndis.h:50
#define BI_RLE4
Definition: precomp.h:35
unsigned int ULONG
Definition: retypes.h:1
#define LPK_INIT
Definition: gdi32p.h:81
LPBITMAPINFO WINAPI ConvertBitmapInfo(CONST BITMAPINFO *BitmapInfo, UINT ColorSpec, UINT *BitmapInfoSize, BOOL FollowedByData)
Definition: utils.c:178
#define ULONG_PTR
Definition: config.h:101
#define LPK_GCP
Definition: gdi32p.h:83
#define GetProcAddress(x, y)
Definition: compat.h:410
BYTE rgbtGreen
Definition: wingdi.h:1434
UCHAR rgbReserved
Definition: inbv.c:173
WCHAR lfFaceName[LF_FACESIZE]
Definition: wingdi.h:1905
LPKGCP LpkGetCharacterPlacement
Definition: utils.c:6
#define DIB_RGB_COLORS
Definition: wingdi.h:366
#define CP_THREAD_ACP
Definition: winnls.h:230
BOOL(WINAPI * LPKETO)(HDC hdc, int x, int y, UINT fuOptions, const RECT *lprc, LPCWSTR lpString, UINT uCount, const INT *lpDx, INT unknown)
Definition: gdi32p.h:31
#define BI_RLE8
Definition: wingdi.h:35
#define BI_RGB
Definition: precomp.h:34
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
#define CONST
Definition: pedump.c:81
BOOL WINAPI CalculateColorTableSize(CONST BITMAPINFOHEADER *BitmapInfoHeader, UINT *ColorSpec, UINT *ColorTableSize)
Definition: utils.c:32