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
1 changed files with 74 additions and 107 deletions

View File

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