Richard Goedeken avatar Richard Goedeken committed ea7ca05 Merge

merged heads, fixing conflicts in src/TextureFilters.cpp

Comments (0)

Files changed (6)

projects/unix/Makefile

 
 CXXFLAGS += $(CFLAGS)
 ifeq ($(LTO), 1)
-  CFLAGS += -flto
-  CXXFLAGS += -flto
-  LDFLAGS += -fuse-linker-plugin $(CXXFLAGS)
+  CFLAGS += -flto -ffunction-sections -fdata-sections
+  CXXFLAGS += -flto -ffunction-sections -fdata-sections
+  LDFLAGS += -fuse-linker-plugin -Wl,--gc-sections $(CXXFLAGS)
 endif
 
 # standard build rules
     ConfigSetDefaultBool(l_ConfigVideoRice, "SkipFrame", FALSE, "If this option is enabled, the plugin will skip every other frame");
     ConfigSetDefaultBool(l_ConfigVideoRice, "TexRectOnly", FALSE, "If enabled, texture enhancement will be done only for TxtRect ucode");
     ConfigSetDefaultBool(l_ConfigVideoRice, "SmallTextureOnly", FALSE, "If enabled, texture enhancement will be done only for textures width+height<=128");
+    ConfigSetDefaultBool(l_ConfigVideoRice, "LoadHiResCRCOnly", TRUE, "Select hi-resolution textures based only on the CRC and ignore format+size information (Glide64 compatibility)");
     ConfigSetDefaultBool(l_ConfigVideoRice, "LoadHiResTextures", FALSE, "Enable hi-resolution texture file loading");
     ConfigSetDefaultBool(l_ConfigVideoRice, "DumpTexturesToFiles", FALSE, "Enable texture dumping");
     ConfigSetDefaultBool(l_ConfigVideoRice, "ShowFPS", FALSE, "Display On-screen FPS");
     options.bTexRectOnly = ConfigGetParamBool(l_ConfigVideoRice, "TexRectOnly");
     options.bSmallTextureOnly = ConfigGetParamBool(l_ConfigVideoRice, "SmallTextureOnly");
     options.bLoadHiResTextures = ConfigGetParamBool(l_ConfigVideoRice, "LoadHiResTextures");
+    options.bLoadHiResCRCOnly = ConfigGetParamBool(l_ConfigVideoRice, "LoadHiResCRCOnly");
     options.bDumpTexturesToFiles = ConfigGetParamBool(l_ConfigVideoRice, "DumpTexturesToFiles");
     options.bShowFPS = ConfigGetParamBool(l_ConfigVideoRice, "ShowFPS");
 
     BOOL    bSmallTextureOnly;
     BOOL    bDumpTexturesToFiles;
     BOOL    bLoadHiResTextures;
+    BOOL    bLoadHiResCRCOnly;
 
     int     OpenglDepthBufferSetting;
     int     OpenglRenderSetting;

src/TextureFilters.cpp

  RGBA_PNG_FOR_ALL_CI,
 };
 typedef struct {
-    int width;
-    int height;
+    unsigned int width;
+    unsigned int height;
     int fmt;
     int siz;
     int crc32;
     int pal_crc32;
     char *foldername;
+    char *filename;
+    char *filename_a;
     //char name[40];
-    char RGBNameTail[23];
-    char AlphaNameTail[20];
     TextureType type;
     bool        bSeparatedAlpha;
 } ExtTxtrInfo;
     {
         struct BMGImageStruct img;
         memset(&img, 0, sizeof(BMGImageStruct));
-        BMG_Error code = ReadPNG(pSrcFile, &img);
+        BMG_Error code = ReadPNGInfo(pSrcFile, &img);
         if( code == BMG_OK )
         {
             pSrcInfo->Width = img.width;
                 //strcpy(newinfo.name,g_curRomInfo.szGameName);
                 newinfo.foldername = new char[strlen(foldername)+1];
                 strcpy(newinfo.foldername,foldername);
+                // store the filename
+                newinfo.filename = strdup(foundfilename);
+                newinfo.filename_a = NULL;
                 // Store the format
                 newinfo.fmt = fmt;
                 // Store the size (bit-size, not texture size)
                 newinfo.type = type;
                 //Indicate if there is a separate alpha file that has to be loaded
                 newinfo.bSeparatedAlpha = bSeparatedAlpha;
-                // Determine the begin of the string indicating the texture and corresponding the apha type (if any)
-                // That assures that if there would be a non-supported type, RGBNameTail & AlphaNameTail would at
-                // least be NULL
-                newinfo.RGBNameTail[0] = newinfo.AlphaNameTail[0] = 0;
-
-                // Store the extention of the texture and also the extention of the alpha channel (if existing)
-                // (I won't comment the following lines as they should be really obvious. If not, contact microdev @ emutalk)
-                switch ( type )
-                {
-                    case RGB_PNG:
-                        strcpy(newinfo.RGBNameTail, "_rgb.png");
-                        strcpy(newinfo.AlphaNameTail, "_a.png");
-                        break;
-                    case COLOR_INDEXED_BMP:
-                        strcpy(newinfo.RGBNameTail, "_ci.bmp");
-                        break;
-                    case RGBA_PNG_FOR_CI:
-                        // This format has the PAL CRC
-                        strcpy(newinfo.RGBNameTail, right(ptr,22));
-                        break;
-                    case RGBA_PNG_FOR_ALL_CI:
-                        strcpy(newinfo.RGBNameTail, "_allciByRGBA.png");
-                        break;
-                    default:
-                        strcpy(newinfo.RGBNameTail, "_all.png");
-                        break;
+                if (bSeparatedAlpha) {
+                    char filename2[PATH_MAX];
+                    strcpy(filename2, foundfilename);
+                    strcpy(filename2+strlen(filename2)-8,"_a.png");
+                    newinfo.filename_a = strdup(filename2);
                 }
-
                 // Generate the key for the record describing the hires texture.
                 // This key is used to find it back in the list
                 // The key format is: <DRAM(texture)-CRC-8byte><PAL(palette)-CRC-6byte(2bytes have been truncated to have space for format and size)><format-1byte><size-1byte>
                 uint64 crc64 = newinfo.crc32;
                 crc64 <<= 32;
-                crc64 |= (newinfo.pal_crc32&0xFFFFFF00)|(newinfo.fmt<<4)|newinfo.siz;
+                if (options.bLoadHiResCRCOnly)
+                    crc64 |= newinfo.pal_crc32&0xFFFFFFFF;
+                else
+                    crc64 |= (newinfo.pal_crc32&0xFFFFFF00)|(newinfo.fmt<<4)|newinfo.siz;
                 // Add the new record to the list
                 infos.add(crc64,newinfo);
             }
     {
         if( gHiresTxtrInfos[i].foldername )
             delete [] gHiresTxtrInfos[i].foldername;
+        if( gHiresTxtrInfos[i].filename )
+            delete [] gHiresTxtrInfos[i].filename;
+        if( gHiresTxtrInfos[i].filename_a )
+            delete [] gHiresTxtrInfos[i].filename_a;
     }
 
     gHiresTxtrInfos.clear();
     {
         if( gTxtrDumpInfos[i].foldername )  
             delete [] gTxtrDumpInfos[i].foldername;
+        if( gTxtrDumpInfos[i].filename )
+            delete [] gTxtrDumpInfos[i].filename;
+        if( gTxtrDumpInfos[i].filename_a )
+            delete [] gTxtrDumpInfos[i].filename_a;
     }
 
     gTxtrDumpInfos.clear();
 {
     // init scale shift
     int scaleShift = 0;
- 
     // check if the original texture dimensions (x and y) scaled with the current shift is still smaller or of the same size as the hires one
-    while (info.height > (int) entry.ti.HeightToLoad * (1 << scaleShift) && info.width > (int) entry.ti.WidthToLoad * (1 << scaleShift))
+    while(info.height >= entry.ti.HeightToLoad*(1<<scaleShift)  && info.width >= entry.ti.WidthToLoad*(1<<scaleShift))
     {
+        // check if the original texture dimensions (x and y)scaled with the current shift have the same size as the hires one
+        if(info.height == entry.ti.HeightToLoad*(1<<scaleShift)  && info.width == entry.ti.WidthToLoad*(1<<scaleShift))
+            // found appropriate scale shift, return it
+            return scaleShift;
+
         scaleShift++;
     }
-    // if the ratio of the 2 textures' dimensions is an even power of 2, then the hi-res texture is allowed
-    if (info.height == (int) entry.ti.HeightToLoad * (1 << scaleShift) && info.width == (int) entry.ti.WidthToLoad * (1 << scaleShift))
-    {
-        // found appropriate scale shift, return it
-        return scaleShift;
-    }
 
     // original texture dimensions (x or y or both) scaled with the last scale shift have become larger than the dimensions
     // of the hires texture. That means the dimensions of the hires replacement are not power of 2 of the original texture.
-    // Therefore indicate invalid scale shift
-    return -1;
+    // Therefore indicate a crop shift (or -1 when the hires_texture was smaller from the beginning)
+    scaleShift -= 1;
+    return scaleShift;
 }
 
 
     uint64 crc64a = entry.dwCRC;
     crc64a <<= 32;
     uint64 crc64b = crc64a;
-    // crc64a = <DRAM-CRC-8bytes><FFFFFF><format-1byte><size-1byte>
-    crc64a |= (0xFFFFFF00|(entry.ti.Format<<4)|entry.ti.Size);
-    // crc64b = <DRAM-CRC-8bytes><palette-crc-6bytes (lowest 2 bytes are removed)><format-1byte><size-1byte>
-    crc64b |= ((entry.dwPalCRC&0xFFFFFF00)|(entry.ti.Format<<4)|entry.ti.Size);
+    if (options.bLoadHiResCRCOnly) {
+        crc64a |= (0xFFFFFFFF);
+        crc64b |= (entry.dwPalCRC&0xFFFFFFFF);
+    } else {
+        crc64a |= (0xFFFFFF00|(entry.ti.Format<<4)|entry.ti.Size);
+        crc64b |= ((entry.dwPalCRC&0xFFFFFF00)|(entry.ti.Format<<4)|entry.ti.Size);
+    }
+
     // infos is the list containing the references to the detected external textures
     // get the number of items contained in this list
-
     int infosize = infos.size();
     int indexb=-1;
     // try to identify the external texture that
 
         newinfo.pal_crc32 = entry.dwPalCRC;
         newinfo.foldername = NULL;
-        newinfo.RGBNameTail[0] = newinfo.AlphaNameTail[0] = 0;
+        newinfo.filename = NULL;
+        newinfo.filename_a = NULL;
 
         uint64 crc64 = newinfo.crc32;
         crc64 <<= 32;
-        crc64 |= (newinfo.pal_crc32&0xFFFFFF00)|(newinfo.fmt<<4)|newinfo.siz;
+        if (options.bLoadHiResCRCOnly)
+            crc64 |= newinfo.pal_crc32&0xFFFFFFFF;
+        else
+            crc64 |= (newinfo.pal_crc32&0xFFFFFF00)|(newinfo.fmt<<4)|newinfo.siz;
         gTxtrDumpInfos.add(crc64,newinfo);
 
     }
     char filename_a[PATH_MAX];
 
     strcpy(filename_rgb, gHiresTxtrInfos[idx].foldername);
+    strcat(filename_rgb, gHiresTxtrInfos[idx].filename);
 
-    sprintf(filename_rgb+strlen(filename_rgb), "%s#%08X#%d#%d", g_curRomInfo.szGameName, entry.dwCRC, entry.ti.Format, entry.ti.Size);
-    strcpy(filename_a,filename_rgb);
-    strcat(filename_rgb,gHiresTxtrInfos[idx].RGBNameTail);
-    strcat(filename_a,gHiresTxtrInfos[idx].AlphaNameTail);
+    if (gHiresTxtrInfos[idx].filename_a) {
+        strcpy(filename_a, gHiresTxtrInfos[idx].foldername);
+        strcat(filename_a, gHiresTxtrInfos[idx].filename_a);
+    } else {
+        strcpy(filename_a, "");
+    }
 
     // Load BMP image to buffer_rbg
     unsigned char *buf_rgba = NULL;
             return;
     }
 
-    if( !bResRGBA )
+    if( !bResRGBA || !buf_rgba )
     {
         DebugMessage(M64MSG_ERROR, "RGBBuffer creation failed for file '%s'.", filename_rgb);
         return;
     int scale = 1 << scaleShift;
     int mirrorx = 1;
     int mirrory = 1;
+    int input_height_shift = height - entry.ti.HeightToLoad * scale;
+    int input_pitch_a = width;
+    int input_pitch_rgb = width;
+    width = entry.ti.WidthToLoad * scale;
+    height = entry.ti.HeightToLoad * scale;
     if (entry.ti.WidthToCreate/entry.ti.WidthToLoad == 2) mirrorx = 2;
     if (entry.ti.HeightToCreate/entry.ti.HeightToLoad == 2) mirrory = 2;
     entry.pEnhancedTexture = CDeviceBuilder::GetBuilder()->CreateTexture(entry.ti.WidthToCreate*scale, entry.ti.HeightToCreate*scale);
 
         if( gHiresTxtrInfos[idx].type == RGB_PNG )
         {
-            unsigned char *pRGB = buf_rgba;
-            unsigned char *pA = buf_a;
+            input_pitch_rgb *= 3;
+            input_pitch_a *= 3;
 
             if (info.lPitch < width * 4)
                 DebugMessage(M64MSG_ERROR, "Texture pitch %i less than width %i times 4", info.lPitch, width);
                 DebugMessage(M64MSG_ERROR, "Texture source height %i greater than destination height %i", height, info.dwHeight);
 
             // Update the texture by using the buffer
-            for( int i=height-1; i>=0; i--)
+            for( int i=0; i<height; i++)
             {
-                unsigned char* pdst = (unsigned char*)info.lpSurface + i*info.lPitch;
+                unsigned char *pRGB = buf_rgba + (input_height_shift + i) * input_pitch_rgb;
+                unsigned char *pA = buf_a + (input_height_shift + i) * input_pitch_a;
+                unsigned char* pdst = (unsigned char*)info.lpSurface + (height - i - 1)*info.lPitch;
                 for( int j=0; j<width; j++)
                 {
                     *pdst++ = *pRGB++;      // R
         }
         else
         {
+            input_pitch_rgb *= 4;
+
             // Update the texture by using the buffer
-            uint32 *pRGB = (uint32*)buf_rgba;
             for( int i=height-1; i>=0; i--)
             {
-                uint32 *pdst = (uint32*)((unsigned char*)info.lpSurface + i*info.lPitch);
+                uint32 *pRGB = (uint32*)(buf_rgba + (input_height_shift + i) * input_pitch_rgb);
+                uint32 *pdst = (uint32*)((unsigned char*)info.lpSurface + (height - i - 1)*info.lPitch);
                 for( int j=0; j<width; j++)
                 {
                     *pdst++ = *pRGB++;      // RGBA

src/liblinux/pngrw.c

 #  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
 #endif
 
-/****************************************************************************/
-/*
-* this function will expand 1 byte of a 4-color bit values to 2 bytes of
-* a 16 color bit value.
-*/
-static void Expand2to4( char *b4, char b2, int NumBytes )
-{
-    struct TwoBit
-    {
-        unsigned char b1 : 2;
-        unsigned char b2 : 2;
-        unsigned char b3 : 2;
-        unsigned char b4 : 2;
-    } bit2;
-
-    struct FourBit
-    {
-        unsigned char b1 : 4;
-        unsigned char b2 : 4;
-        unsigned char b3 : 4;
-        unsigned char b4 : 4;
-    } bit4;
-
-    memcpy( (void *)&bit2, (void *)&b2, 1 );
-    bit4.b3 = bit2.b1;
-    bit4.b4 = bit2.b2;
-    bit4.b1 = bit2.b3;
-    bit4.b2 = bit2.b4;
-    memcpy( (void *)b4, (void *)&bit4, NumBytes );
-}
 
 /* this stuff is necessary because the normal png_init_io() method crashes in Win32 */
 static void user_read_data(png_structp png_read, png_bytep data, png_size_t length)
 
     FILE * volatile     file = NULL;
     int                 BitDepth;
-    int                 BitsPerPixel;
-    int                 FixedBitDepth;
     int                 ColorType;
-    int                 ImageChannels;
     int                 InterlaceType;
     unsigned char       signature[8];
     png_structp volatile png_ptr = NULL;
     png_infop   volatile info_ptr = NULL;
     png_infop   volatile end_info = NULL;
-    png_colorp          PNGPalette = NULL;
     png_color_16       *ImageBackground = NULL;
     png_bytep           trns = NULL;
     int                 NumTrans = 0;
-    int                 i, j, k;
+    int                 i, k;
     png_color_16p       TransColors = NULL;
     png_uint_32         Width, Height;
 
-    unsigned char      *bits, *p, *q;
+    unsigned char      *bits;
     unsigned char** volatile rows = NULL;
-    int                 NumColors = 0;
-    unsigned char       BgdRed = 0;
-    unsigned char       BgdGreen = 0;
-    unsigned char       BgdBlue = 0;
-    int                 PaletteTo32 = 0;
 
     BMGError tmp;
-    unsigned int DIBLineWidth;
 
     /* error handler */
     error = setjmp( err_jmp );
 
     img->width = (unsigned int) Width;
     img->height = (unsigned int) Height;
-    ImageChannels = png_get_channels( png_ptr, info_ptr );
-    FixedBitDepth = BitDepth;
 
-    /* convert 2 pixel images to 4 pixel images */
-    if ( BitDepth == 2 )
-        FixedBitDepth = 4;
-
-/* There is logic in the following code that will
-    convert 16-bit grayscale images to 8-bit paletted images and
-    convert 16-bit color images to 24-bit RGB images */
-    if ( BitDepth == 16 )
-        FixedBitDepth = 8;
-    BitsPerPixel = FixedBitDepth *
-            ( ColorType & PNG_COLOR_MASK_ALPHA && !(ColorType & PNG_COLOR_MASK_COLOR)?
-            ImageChannels - 1 : ImageChannels );
-
-    img->bits_per_pixel = (unsigned char)BitsPerPixel;
+    img->bits_per_pixel = (unsigned char)32;
+    img->scan_width = Width * 4;
 
     /* convert 16-bit images to 8-bit images */
     if (BitDepth == 16)
         png_set_strip_16(png_ptr);
 
+    /* These are not really required per Rice format spec,
+     * but is done just in case someone uses them.
+     */
+    /* convert palette color to rgb color */
+    if (ColorType == PNG_COLOR_TYPE_PALETTE) {
+        png_set_palette_to_rgb(png_ptr);
+        ColorType = PNG_COLOR_TYPE_RGB;
+    }
+
+    /* expand 1,2,4 bit gray scale to 8 bit gray scale */
+    if (ColorType == PNG_COLOR_TYPE_GRAY && BitDepth < 8)
+        png_set_expand_gray_1_2_4_to_8(png_ptr);
+
+    /* convert gray scale or gray scale + alpha to rgb color */
+    if (ColorType == PNG_COLOR_TYPE_GRAY ||
+        ColorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
+        png_set_gray_to_rgb(png_ptr);
+        ColorType = PNG_COLOR_TYPE_RGB;
+    }
+
+    /* add alpha channel if any */
+    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+        png_set_tRNS_to_alpha(png_ptr);
+        ColorType = PNG_COLOR_TYPE_RGB_ALPHA;
+    }
+
+    /* convert rgb to rgba */
+    if (ColorType == PNG_COLOR_TYPE_RGB) {
+        png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+        ColorType = PNG_COLOR_TYPE_RGB_ALPHA;
+    }
+
+    png_set_bgr(png_ptr);
+
     /* set the background color if one is found */
     if ( png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD) )
         png_get_bKGD(png_ptr, info_ptr, &ImageBackground);
     if ( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS ) )
         png_get_tRNS( png_ptr, info_ptr, &trns, &NumTrans, &TransColors );
 
-    /* Get the background color if we have transparent pixels */
-    if ( NumTrans > 0 )
-    {
-        if ( NumTrans == 1 )
-        {
-    // we will shove the background color into the palette array
-    // or pixel location
-            if ( ImageBackground )
-            {
-                BgdRed   = (unsigned char)ImageBackground->red;
-                BgdGreen = (unsigned char)ImageBackground->green;
-                BgdBlue  = (unsigned char)ImageBackground->blue;
-            }
-    // if the alpha component == 0 then set the transparenct index
-    // and let the user deal with it
-            else if ( trns[0] == 0 )
-                img->transparency_index = 0;
-    // otherwise we must perform blending so we will need to create
-    // a 32-bit ARGB image.
-            else
-                PaletteTo32 = 1;
-        }
-    // if we have more than 1 transparent color then create a 32-bit ARGB
-    // image
-        else
-            PaletteTo32 = 1;
-    }
-
-    /* convert all palette based images to 8-bit arrays */
-    if ( BitDepth < 8 && PaletteTo32 == 1 )
-    {
-        BitDepth = 8;
-        png_set_packing(png_ptr);
-    }
-
-    /* calculate the the scan line width */
-/* 8 & 16-bit images with an alpha component are converted to 32-bit
-    true color images in order to retain the alpha component in the bitmap */
-    if ( ColorType & PNG_COLOR_MASK_ALPHA && BitsPerPixel == 8 )
-    {
-        img->bits_per_pixel = 32U;
-        DIBLineWidth = 4U * (unsigned int) Width;
-    }
-/* paletted images with more than 1 transparency index or a non-zero alpha
-    component are converted to 32-bit ABGR images */
-    else if ( ColorType & PNG_COLOR_MASK_PALETTE && PaletteTo32 == 1 )
-    {
-        img->bits_per_pixel = 32U;
-        DIBLineWidth = 4U * (unsigned int) Width;
-    }
-    else
-    {
-        DIBLineWidth = img->scan_width = ( BitsPerPixel * (unsigned int) Width + 7 ) / 8;
-        if ( img->opt_for_bmp > 0 && img->scan_width % 4 )
-            img->scan_width += 4 - img->scan_width % 4;
-    }
-
-/* Determine palette parameters.  We will not create a palette for
-    grayscale images that have an alpha component.  Those images will be
-    expanded to 32-bit true color images in order to retain the alpha
-    component in the bitmap. */
-    if ( BitsPerPixel <= 8 && !(ColorType & PNG_COLOR_MASK_ALPHA))
-    {
-        if ( ColorType & PNG_COLOR_MASK_PALETTE )
-        {
-            png_get_PLTE( png_ptr, info_ptr, &PNGPalette, &NumColors );
-            if ( NumTrans == 1 && PaletteTo32 == 0 && ImageBackground != NULL )
-            {
-                PNGPalette[0].red   =
-                        AlphaComp(PNGPalette[0].red,   trns[0], BgdRed);
-                PNGPalette[0].green =
-                        AlphaComp(PNGPalette[0].green, trns[0], BgdGreen);
-                PNGPalette[0].blue  =
-                        AlphaComp(PNGPalette[0].blue,  trns[0], BgdBlue);
-            }
-        }
-        else  /* gray scale */
-            NumColors = 1 << (BitDepth == 2 ? 2 : FixedBitDepth);
-    }
-
-    /* set up palette parameters */
-    if ( PaletteTo32 != 1 && BitsPerPixel <= 8 &&
-        !(ColorType & PNG_COLOR_MASK_ALPHA) )
-    {
-        img->palette_size = (unsigned short)NumColors;
-        img->bytes_per_palette_entry = img->opt_for_bmp > 0 ? 4U : 3U;
-    }
+    img->palette_size = (unsigned short)0;
+    img->bytes_per_palette_entry = 4U;
 
     tmp = AllocateBMGImage( img );
     if ( tmp != BMG_OK )
         longjmp( err_jmp, (int)tmp );
 
-
-    if ( img->palette != NULL )
-    {
-        /* color palette */
-        if ( ColorType & PNG_COLOR_MASK_PALETTE )
-        {
-            bits = img->palette;
-            for ( i = 0; i < NumColors; 
-                        i++, bits += img->bytes_per_palette_entry )
-            {
-                bits[2] = PNGPalette[i].red;
-                bits[1] = PNGPalette[i].green;
-                bits[0] = PNGPalette[i].blue;
-            }
-        }
-        else /* Gray scale palette */
-        {
-            j = 255 / (NumColors - 1);
-            bits = img->palette;
-            for ( i = 0; i < NumColors; 
-                        i++, bits += img->bytes_per_palette_entry )
-            {
-                memset( (void *)bits, i*j, 3 );
-            }
-
-            if ( NumTrans == 1 && ImageBackground != NULL )
-            {
-                img->palette[2] = BgdRed;
-                img->palette[1] = BgdGreen;
-                img->palette[0] = BgdBlue;
-            }
-        }
-    }
-
     png_read_update_info( png_ptr, info_ptr );
 
     /* create buffer to read data to */
     /* read the entire image into rows */
     png_read_image( png_ptr, rows );
 
-/* extract bits
-    The following logic is convoluted compared to the simple examples
-    provided with the source.  I wrote the code this way to ensure that
-    hBitmap cantained the minimal amount of information needed to store
-    the image as well as capturing all alpha components */
     bits = img->bits + (Height - 1) * img->scan_width;
     for ( i = 0; i < (int)Height; i++ )
     {
-        p = rows[i];
-        switch ( BitDepth )
-        {
-            case 1:
-            case 4:
-                memcpy((void *)bits, (void *)p, DIBLineWidth);
-                break;
-            case 2:
-                for ( j = 0; j < (int)(Width/2); j += 2 )
-                    Expand2to4((char*)&bits[j], p[j/2], 2);
-                if ( Width % 2 )
-                    Expand2to4((char*)&bits[Width/2+1], p[Width/4+1], 1);
-                break;
-            case 8:
-                /* 16-bit images were converted to 8-bit */
-            case 16:
-                /* this section for data with alpha components */
-                if ( ColorType & PNG_COLOR_MASK_ALPHA )
-                {
-        /* expand this format to a 32-bit true color image so that
-                    the alpha term is retained in the bitmap */
-                    if ( BitsPerPixel == 8 )
-                    {
-                        for ( q = bits; q < bits + img->scan_width;
-                                        q += 4, p+=2)
-                        {
-                            memset( (void *)q, *p, 3 );
-                            q[3] = p[1];
-                        }
-                    }
-                    else  /* BitsPerPixel == 32 */
-                    {
-                        for ( j = 0; j < (int)(4*Width); j += 4 )
-                        {
-                            bits[j+3] = p[j+3];
-                            bits[j+2] = p[j  ];
-                            bits[j+1] = p[j+1];
-                            bits[j  ] = p[j+2];
-                        }
-                    }
-                }
-        /* this section is for paletted images that contain multiple
-                transparency values or non-zero alpha transparencies */
-                else if ( PaletteTo32 == 1 )
-                {
-                    for ( q = bits; q < bits + img->scan_width; q += 4, p++ )
-                    {
-                        png_colorp pal = PNGPalette + *p;
-                        q[0] = pal->blue;
-                        q[1] = pal->green;
-                        q[2] = pal->red;
-                        if ( *p >= NumTrans )
-                            q[3] = 0xFF;
-                        else
-                            q[3] = trns[*p];
-                    }
-                }
-                /* no alpha component */
-                else
-                {
-                    if ( BitsPerPixel == 8 )
-                        memcpy( (void *)bits, (void *)p, DIBLineWidth );
-                    else /* BitsPerPixel == 24 */
-                    {
-                        for ( j = 0; j < (int)(3*Width); j += 3 )
-                        {
-                            if ( TransColors != NULL &&
-                                        ImageBackground != NULL )
-                            {
-                                if ( TransColors->red == p[j] &&
-                                        TransColors->green == p[j+1] &&
-                                        TransColors->blue == p[j+2] )
-                                {
-                                    bits[j+2] = BgdRed;
-                                    bits[j+1] = BgdGreen;
-                                    bits[j  ] = BgdBlue;
-                                }
-                                else
-                                {
-                                    bits[j+2] = p[j  ];
-                                    bits[j+1] = p[j+1];
-                                    bits[j  ] = p[j+2];
-                                }
-                            }
-                            else
-                            {
-                                bits[j+2] = p[j  ];
-                                bits[j+1] = p[j+1];
-                                bits[j  ] = p[j+2];
-                            }
-                        }
-                    }
-                }
-                break;
-        }
-
+        memcpy(bits, rows[i], 4*Width);
         bits -= img->scan_width;
     }
 
     return BMG_OK;
 }
 
+BMGError ReadPNGInfo( const char *filename,
+        struct BMGImageStruct * volatile img )
+{
+    jmp_buf             err_jmp;
+    int                 error;
+
+    FILE * volatile     file = NULL;
+    int                 BitDepth;
+    int                 ColorType;
+    int                 InterlaceType;
+    unsigned char       signature[8];
+    png_structp volatile png_ptr = NULL;
+    png_infop   volatile info_ptr = NULL;
+    png_infop   volatile end_info = NULL;
+    png_uint_32         Width, Height;
+
+    /* error handler */
+    error = setjmp( err_jmp );
+    if (error != 0)
+    {
+        if (end_info != NULL)
+            png_destroy_read_struct((png_structp *) &png_ptr, (png_infop *) &info_ptr, (png_infop *) &end_info);
+        else if (info_ptr != NULL)
+            png_destroy_read_struct((png_structp *) &png_ptr, (png_infop *) &info_ptr, NULL);
+        else if (png_ptr != NULL)
+            png_destroy_read_struct((png_structp *) &png_ptr, NULL, NULL);
+        if (img)
+            FreeBMGImage(img);
+        if (file)
+            fclose(file);
+        SetLastBMGError((BMGError) error);
+        return (BMGError) error;
+    }
+
+    if ( img == NULL )
+        longjmp ( err_jmp, (int)errInvalidBMGImage );
+
+    file = fopen( filename, "rb" );
+    if ( !file || fread( signature, 1, 8, file ) != 8)
+        longjmp ( err_jmp, (int)errFileOpen );
+
+    /* check the signature */
+    if ( png_sig_cmp( signature, 0, 8 ) != 0 )
+        longjmp( err_jmp, (int)errUnsupportedFileFormat );
+
+    /* create a pointer to the png read structure */
+    png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
+    if ( !png_ptr )
+        longjmp( err_jmp, (int)errMemoryAllocation );
+
+    /* create a pointer to the png info structure */
+    info_ptr = png_create_info_struct( png_ptr );
+    if ( !info_ptr )
+        longjmp( err_jmp, (int)errMemoryAllocation );
+
+    /* create a pointer to the png end-info structure */
+    end_info = png_create_info_struct(png_ptr);
+    if (!end_info)
+        longjmp( err_jmp, (int)errMemoryAllocation );
+
+    /* bamboozle the PNG longjmp buffer */
+    /*generic PNG error handler*/
+    /* error will always == 1 which == errLib */
+//    error = png_setjmp(png_ptr);
+    error = setjmp( png_jmpbuf( png_ptr ) );
+    if ( error > 0 )
+        longjmp( err_jmp, error );
+
+    /* set function pointers in the PNG library, for read callbacks */
+    png_set_read_fn(png_ptr, (png_voidp) file, user_read_data);
+
+    /*let the read functions know that we have already read the 1st 8 bytes */
+    png_set_sig_bytes( png_ptr, 8 );
+
+    /* read all PNG data up to the image data */
+    png_read_info( png_ptr, info_ptr );
+
+    /* extract the data we need to form the HBITMAP from the PNG header */
+    png_get_IHDR( png_ptr, info_ptr, &Width, &Height, &BitDepth, &ColorType,
+        &InterlaceType, NULL, NULL);
+
+    img->width = (unsigned int) Width;
+    img->height = (unsigned int) Height;
+
+    img->bits_per_pixel = (unsigned char)32;
+    img->scan_width = Width * 4;
+
+    img->palette_size = (unsigned short)0;
+    img->bytes_per_palette_entry = 4U;
+    img->bits = NULL;
+
+    png_destroy_read_struct((png_structp *) &png_ptr, (png_infop *) &info_ptr, (png_infop *) &end_info);
+    fclose( file );
+
+    return BMG_OK;
+}
+
 /*
 WritePNG - writes the contents of a BMGImageStruct to a PNG file.
 

src/liblinux/pngrw.h

 
 extern
 BMGError  ReadPNG( const char *filename, struct BMGImageStruct * volatile img );
+extern
+BMGError  ReadPNGInfo( const char *filename, struct BMGImageStruct * volatile img );
 
 extern
 BMGError  WritePNG( const char *filename,
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.