wrc: Make the bitmap size checking more generic, and add support for V5 bitmaps.
authorAlexandre Julliard <julliard@winehq.org>
Wed, 21 Apr 2010 12:07:50 +0000 (14:07 +0200)
committerAlexandre Julliard <julliard@winehq.org>
Wed, 21 Apr 2010 12:07:50 +0000 (14:07 +0200)
tools/wrc/newstruc.c

index 6ed49dca1e2cc0e1e72e15594573146b1f201eaf..603eb0c4dc40f6fddddcf64500bc7819517cc5f8 100644 (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