wrc: Make the bitmap size checking more generic, and add support for V5 bitmaps.

This commit is contained in:
Alexandre Julliard 2010-04-21 14:07:50 +02:00
parent b32653235a
commit 1ffab3ab4e

View File

@ -206,41 +206,42 @@ fontdir_t *new_fontdir(raw_data_t *rd, int *memopt)
/* /*
* Convert bitmaps to proper endian * Convert bitmaps to proper endian
*/ */
static void convert_bitmap_swap_v3(BITMAPINFOHEADER *bih) static void convert_bitmap_swap(BITMAPV5HEADER *bh, DWORD size)
{ {
bih->biSize = BYTESWAP_DWORD(bih->biSize); bh->bV5Size = BYTESWAP_DWORD(bh->bV5Size);
bih->biWidth = BYTESWAP_DWORD(bih->biWidth); bh->bV5Width = BYTESWAP_DWORD(bh->bV5Width);
bih->biHeight = BYTESWAP_DWORD(bih->biHeight); bh->bV5Height = BYTESWAP_DWORD(bh->bV5Height);
bih->biPlanes = BYTESWAP_WORD(bih->biPlanes); bh->bV5Planes = BYTESWAP_WORD(bh->bV5Planes);
bih->biBitCount = BYTESWAP_WORD(bih->biBitCount); bh->bV5BitCount = BYTESWAP_WORD(bh->bV5BitCount);
bih->biCompression = BYTESWAP_DWORD(bih->biCompression); bh->bV5Compression = BYTESWAP_DWORD(bh->bV5Compression);
bih->biSizeImage = BYTESWAP_DWORD(bih->biSizeImage); bh->bV5SizeImage = BYTESWAP_DWORD(bh->bV5SizeImage);
bih->biXPelsPerMeter = BYTESWAP_DWORD(bih->biXPelsPerMeter); bh->bV5XPelsPerMeter = BYTESWAP_DWORD(bh->bV5XPelsPerMeter);
bih->biYPelsPerMeter = BYTESWAP_DWORD(bih->biYPelsPerMeter); bh->bV5YPelsPerMeter = BYTESWAP_DWORD(bh->bV5YPelsPerMeter);
bih->biClrUsed = BYTESWAP_DWORD(bih->biClrUsed); bh->bV5ClrUsed = BYTESWAP_DWORD(bh->bV5ClrUsed);
bih->biClrImportant = BYTESWAP_DWORD(bih->biClrImportant); bh->bV5ClrImportant = BYTESWAP_DWORD(bh->bV5ClrImportant);
} if (size == sizeof(BITMAPINFOHEADER)) return;
bh->bV5RedMask = BYTESWAP_DWORD(bh->bV5RedMask);
static void convert_bitmap_swap_v4(BITMAPV4HEADER *b4h) bh->bV5GreenMask = BYTESWAP_DWORD(bh->bV5GreenMask);
{ bh->bV5BlueMask = BYTESWAP_DWORD(bh->bV5BlueMask);
convert_bitmap_swap_v3((BITMAPINFOHEADER *)b4h); bh->bV5AlphaMask = BYTESWAP_DWORD(bh->bV5AlphaMask);
b4h->bV4RedMask = BYTESWAP_DWORD(b4h->bV4RedMask); bh->bV5CSType = BYTESWAP_DWORD(bh->bV5CSType);
b4h->bV4GreenMask = BYTESWAP_DWORD(b4h->bV4GreenMask); bh->bV5Endpoints.ciexyzRed.ciexyzX = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzRed.ciexyzX);
b4h->bV4BlueMask = BYTESWAP_DWORD(b4h->bV4BlueMask); bh->bV5Endpoints.ciexyzRed.ciexyzY = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzRed.ciexyzY);
b4h->bV4AlphaMask = BYTESWAP_DWORD(b4h->bV4AlphaMask); bh->bV5Endpoints.ciexyzRed.ciexyzZ = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzRed.ciexyzZ);
b4h->bV4CSType = BYTESWAP_DWORD(b4h->bV4CSType); bh->bV5Endpoints.ciexyzGreen.ciexyzX = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzGreen.ciexyzX);
b4h->bV4Endpoints.ciexyzRed.ciexyzX = BYTESWAP_DWORD(b4h->bV4Endpoints.ciexyzRed.ciexyzX); bh->bV5Endpoints.ciexyzGreen.ciexyzY = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzGreen.ciexyzY);
b4h->bV4Endpoints.ciexyzRed.ciexyzY = BYTESWAP_DWORD(b4h->bV4Endpoints.ciexyzRed.ciexyzY); bh->bV5Endpoints.ciexyzGreen.ciexyzZ = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzGreen.ciexyzZ);
b4h->bV4Endpoints.ciexyzRed.ciexyzZ = BYTESWAP_DWORD(b4h->bV4Endpoints.ciexyzRed.ciexyzZ); bh->bV5Endpoints.ciexyzBlue.ciexyzX = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzBlue.ciexyzX);
b4h->bV4Endpoints.ciexyzGreen.ciexyzX = BYTESWAP_DWORD(b4h->bV4Endpoints.ciexyzGreen.ciexyzX); bh->bV5Endpoints.ciexyzBlue.ciexyzY = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzBlue.ciexyzY);
b4h->bV4Endpoints.ciexyzGreen.ciexyzY = BYTESWAP_DWORD(b4h->bV4Endpoints.ciexyzGreen.ciexyzY); bh->bV5Endpoints.ciexyzBlue.ciexyzZ = BYTESWAP_DWORD(bh->bV5Endpoints.ciexyzBlue.ciexyzZ);
b4h->bV4Endpoints.ciexyzGreen.ciexyzZ = BYTESWAP_DWORD(b4h->bV4Endpoints.ciexyzGreen.ciexyzZ); bh->bV5GammaRed = BYTESWAP_DWORD(bh->bV5GammaRed);
b4h->bV4Endpoints.ciexyzBlue.ciexyzX = BYTESWAP_DWORD(b4h->bV4Endpoints.ciexyzBlue.ciexyzX); bh->bV5GammaGreen = BYTESWAP_DWORD(bh->bV5GammaGreen);
b4h->bV4Endpoints.ciexyzBlue.ciexyzY = BYTESWAP_DWORD(b4h->bV4Endpoints.ciexyzBlue.ciexyzY); bh->bV5GammaBlue = BYTESWAP_DWORD(bh->bV5GammaBlue);
b4h->bV4Endpoints.ciexyzBlue.ciexyzZ = BYTESWAP_DWORD(b4h->bV4Endpoints.ciexyzBlue.ciexyzZ); if (size == sizeof(BITMAPV4HEADER)) return;
b4h->bV4GammaRed = BYTESWAP_DWORD(b4h->bV4GammaRed); bh->bV5Intent = BYTESWAP_DWORD(bh->bV5Intent);
b4h->bV4GammaGreen = BYTESWAP_DWORD(b4h->bV4GammaGreen); bh->bV5ProfileData = BYTESWAP_DWORD(bh->bV5ProfileData);
b4h->bV4GammaBlue = BYTESWAP_DWORD(b4h->bV4GammaBlue); bh->bV5ProfileSize = BYTESWAP_DWORD(bh->bV5ProfileSize);
bh->bV5Reserved = BYTESWAP_DWORD(bh->bV5Reserved);
} }
static void convert_bitmap_swap_os2(BITMAPOS2HEADER *boh) static void convert_bitmap_swap_os2(BITMAPOS2HEADER *boh)
@ -254,31 +255,13 @@ static void convert_bitmap_swap_os2(BITMAPOS2HEADER *boh)
#define FL_SIGBE 0x01 #define FL_SIGBE 0x01
#define FL_SIZEBE 0x02 #define FL_SIZEBE 0x02
#define FL_V4 0x04
#define FL_OS2 0x08
static int convert_bitmap(char *data, int size) static int convert_bitmap(char *data, int size)
{ {
BITMAPINFOHEADER *bih = (BITMAPINFOHEADER *)data; BITMAPV5HEADER *bih = (BITMAPV5HEADER *)data;
BITMAPV4HEADER *b4h = (BITMAPV4HEADER *)data;
BITMAPOS2HEADER *boh = (BITMAPOS2HEADER *)data; BITMAPOS2HEADER *boh = (BITMAPOS2HEADER *)data;
DWORD bmsize;
int type = 0; int type = 0;
int returnSize = 0; /* size to be returned */ int returnSize = 0; /* size to be returned */
#ifdef WORDS_BIGENDIAN
DWORD bisizel = BYTESWAP_DWORD(sizeof(BITMAPINFOHEADER));
DWORD b4sizel = BYTESWAP_DWORD(sizeof(BITMAPV4HEADER));
DWORD bosizel = BYTESWAP_DWORD(sizeof(BITMAPOS2HEADER));
DWORD bisizeb = sizeof(BITMAPINFOHEADER);
DWORD b4sizeb = sizeof(BITMAPV4HEADER);
DWORD bosizeb = sizeof(BITMAPOS2HEADER);
#else
DWORD bisizel = sizeof(BITMAPINFOHEADER);
DWORD b4sizel = sizeof(BITMAPV4HEADER);
DWORD bosizel = sizeof(BITMAPOS2HEADER);
DWORD bisizeb = BYTESWAP_DWORD(sizeof(BITMAPINFOHEADER));
DWORD b4sizeb = BYTESWAP_DWORD(sizeof(BITMAPV4HEADER));
DWORD bosizeb = BYTESWAP_DWORD(sizeof(BITMAPOS2HEADER));
#endif
/* /*
* Originally the bih and b4h pointers were simply incremented here, * Originally the bih and b4h pointers were simply incremented here,
@ -299,47 +282,40 @@ static int convert_bitmap(char *data, int size)
} }
if(bih->biSize == bisizel) bmsize = bih->bV5Size;
{ if (bmsize >> 16) /* assume swapped */
/* Little endian */ {
} #ifndef WORDS_BIGENDIAN
else if(bih->biSize == bisizeb) type |= FL_SIZEBE;
{ #endif
type |= FL_SIZEBE; bmsize = BYTESWAP_DWORD( bmsize );
} }
else if(bih->biSize == b4sizel) else
{ {
type |= FL_V4; #ifdef WORDS_BIGENDIAN
} type |= FL_SIZEBE;
else if(bih->biSize == b4sizeb) #endif
{ }
type |= FL_SIZEBE | FL_V4;
} switch (bmsize)
else if(!bih->biSize || bih->biSize == bosizel) {
{ case sizeof(BITMAPOS2HEADER):
type |= FL_OS2; case sizeof(BITMAPINFOHEADER):
} case sizeof(BITMAPV4HEADER):
else if(bih->biSize == bosizeb) case sizeof(BITMAPV5HEADER):
{ break;
type |= FL_SIZEBE | FL_OS2; default:
} parser_error("Invalid bitmap format, bih->biSize = %d", bih->bV5Size);
else }
parser_error("Invalid bitmap format, bih->biSize = %d", bih->biSize);
switch(type) switch(type)
{ {
default:
break;
case FL_SIZEBE: case FL_SIZEBE:
case FL_SIZEBE | FL_V4: parser_warning("Bitmap signature little-endian, but size big-endian\n");
case FL_SIZEBE | FL_OS2: break;
parser_warning("Bitmap v%c signature little-endian, but size big-endian\n", type & FL_V4 ? '4' : '3');
break;
case FL_SIGBE: case FL_SIGBE:
case FL_SIGBE | FL_V4: parser_warning("Bitmap signature big-endian, but size little-endian\n");
case FL_SIGBE | FL_OS2: break;
parser_warning("Bitmap v%c signature big-endian, but size little-endian\n", type & FL_V4 ? '4' : '3');
break;
} }
switch(byteorder) switch(byteorder)
@ -350,14 +326,10 @@ static int convert_bitmap(char *data, int size)
case WRC_BO_BIG: case WRC_BO_BIG:
if(!(type & FL_SIZEBE)) if(!(type & FL_SIZEBE))
{ {
if(type & FL_V4) if (bmsize == sizeof(BITMAPOS2HEADER))
convert_bitmap_swap_v4(b4h); convert_bitmap_swap_os2(boh);
else if(type & FL_OS2) else
{ convert_bitmap_swap(bih, bmsize);
convert_bitmap_swap_os2(boh);
}
else
convert_bitmap_swap_v3(bih);
} }
break; break;
#ifndef WORDS_BIGENDIAN #ifndef WORDS_BIGENDIAN
@ -366,14 +338,10 @@ static int convert_bitmap(char *data, int size)
case WRC_BO_LITTLE: case WRC_BO_LITTLE:
if(type & FL_SIZEBE) if(type & FL_SIZEBE)
{ {
if(type & FL_V4) if (bmsize == sizeof(BITMAPOS2HEADER))
convert_bitmap_swap_v4(b4h); convert_bitmap_swap_os2(boh);
else if(type & FL_OS2) else
{ convert_bitmap_swap(bih, bmsize);
convert_bitmap_swap_os2(boh);
}
else
convert_bitmap_swap_v3(bih);
} }
break; break;
} }
@ -388,7 +356,6 @@ static int convert_bitmap(char *data, int size)
} }
#undef FL_SIGBE #undef FL_SIGBE
#undef FL_SIZEBE #undef FL_SIZEBE
#undef FL_V4
/* /*
* Cursor and icon splitter functions used when allocating * Cursor and icon splitter functions used when allocating