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