static void (*qpng_set_sig_bytes) (void*, int);
static int (*qpng_sig_cmp) (const unsigned char*, size_t, size_t);
-static void* (*qpng_create_read_struct) (const char*, void*, void*, void*);
+static void* (*qpng_create_read_struct) (const char*, void*, void(*)(void *png, const char *message), void(*)(void *png, const char *message));
static void* (*qpng_create_info_struct) (void*);
static void (*qpng_read_info) (void*, void*);
static void (*qpng_set_expand) (void*);
static void (*qpng_read_image) (void*, unsigned char**);
static void (*qpng_read_end) (void*, void*);
static void (*qpng_destroy_read_struct) (void**, void**, void**);
-static void (*qpng_set_read_fn) (void*, void*, void*);
+static void (*qpng_set_read_fn) (void*, void*, void(*)(void *png, unsigned char *data, size_t length));
static unsigned int (*qpng_get_valid) (void*, void*, unsigned int);
static unsigned int (*qpng_get_rowbytes) (void*, void*);
static unsigned char (*qpng_get_channels) (void*, void*);
return true;
// Load the DLL
- if (! Sys_LoadLibrary (dllnames, &png_dll, pngfuncs))
- {
- Con_Printf ("PNG support disabled\n");
- return false;
- }
-
- Con_Printf ("PNG support enabled\n");
- return true;
+ return Sys_LoadLibrary (dllnames, &png_dll, pngfuncs);
}
extern int image_width;
extern int image_height;
-unsigned char *PNG_LoadImage (const unsigned char *raw, int filesize, int matchwidth, int matchheight)
+unsigned char *PNG_LoadImage_BGRA (const unsigned char *raw, int filesize)
{
+ unsigned int c;
unsigned int y;
void *png, *pnginfo;
- unsigned char *imagedata;
+ unsigned char *imagedata = NULL;
unsigned char ioBuffer[8192];
// FIXME: register an error handler so that abort() won't be called on error
if(qpng_sig_cmp(raw, 0, filesize))
return NULL;
- png = (void *)qpng_create_read_struct(PNG_LIBPNG_VER_STRING, 0, (void *)PNG_error_fn, (void *)PNG_warning_fn);
+ png = (void *)qpng_create_read_struct(PNG_LIBPNG_VER_STRING, 0, PNG_error_fn, PNG_warning_fn);
if(!png)
return NULL;
+ // this must be memset before the setjmp error handler, because it relies
+ // on the fields in this struct for cleanup
+ memset(&my_png, 0, sizeof(my_png));
+
// NOTE: this relies on jmp_buf being the first thing in the png structure
// created by libpng! (this is correct for libpng 1.2.x)
#ifdef __cplusplus
-#ifdef MACOSX
+#if defined(MACOSX) || defined(WIN32)
if (setjmp((int *)png))
#else
if (setjmp((__jmp_buf_tag *)png))
if (setjmp(png))
#endif
{
+ if (my_png.Data)
+ Mem_Free(my_png.Data);
+ my_png.Data = NULL;
+ if (my_png.FRowPtrs)
+ Mem_Free(my_png.FRowPtrs);
+ my_png.FRowPtrs = NULL;
qpng_destroy_read_struct(&png, &pnginfo, 0);
return NULL;
}
}
qpng_set_sig_bytes(png, 0);
- memset(&my_png, 0, sizeof(my_png));
my_png.tmpBuf = raw;
my_png.tmpBuflength = filesize;
my_png.tmpi = 0;
//my_png.Interlace = 0;
//my_png.Compression = 0;
//my_png.Filter = 0;
- qpng_set_read_fn(png, ioBuffer, (void *)PNG_fReadData);
+ qpng_set_read_fn(png, ioBuffer, PNG_fReadData);
qpng_read_info(png, pnginfo);
qpng_get_IHDR(png, pnginfo, &my_png.Width, &my_png.Height,&my_png.BitDepth, &my_png.ColorType, &my_png.Interlace, &my_png.Compression, &my_png.Filter);
}
#endif
-if ((matchwidth && my_png.Width != (unsigned long)matchwidth) || (matchheight && my_png.Height != (unsigned long)matchheight))
- {
- qpng_destroy_read_struct(&png, &pnginfo, 0);
- return NULL;
- }
if (my_png.ColorType == PNG_COLOR_TYPE_PALETTE)
qpng_set_palette_to_rgb(png);
if (my_png.ColorType == PNG_COLOR_TYPE_GRAY || my_png.ColorType == PNG_COLOR_TYPE_GRAY_ALPHA)
my_png.FRowPtrs = (unsigned char **)Mem_Alloc(tempmempool, my_png.Height * sizeof(*my_png.FRowPtrs));
if (my_png.FRowPtrs)
{
- my_png.Data = (unsigned char *)Mem_Alloc(tempmempool, my_png.Height * my_png.FRowBytes);
- if(my_png.Data)
+ imagedata = (unsigned char *)Mem_Alloc(tempmempool, my_png.Height * my_png.FRowBytes);
+ if(imagedata)
{
+ my_png.Data = imagedata;
for(y = 0;y < my_png.Height;y++)
my_png.FRowPtrs[y] = my_png.Data + y * my_png.FRowBytes;
qpng_read_image(png, my_png.FRowPtrs);
}
else
- Con_DPrintf("PNG_LoadImage : not enough memory\n");
+ {
+ Con_Printf("PNG_LoadImage : not enough memory\n");
+ qpng_destroy_read_struct(&png, &pnginfo, 0);
+ Mem_Free(my_png.FRowPtrs);
+ return NULL;
+ }
Mem_Free(my_png.FRowPtrs);
+ my_png.FRowPtrs = NULL;
}
else
- Con_DPrintf("PNG_LoadImage : not enough memory\n");
+ {
+ Con_Printf("PNG_LoadImage : not enough memory\n");
+ qpng_destroy_read_struct(&png, &pnginfo, 0);
+ return NULL;
+ }
qpng_read_end(png, pnginfo);
qpng_destroy_read_struct(&png, &pnginfo, 0);
image_width = (int)my_png.Width;
image_height = (int)my_png.Height;
- imagedata = my_png.Data;
if (my_png.BitDepth != 8)
{
Con_Printf ("PNG_LoadImage : bad color depth\n");
Mem_Free(imagedata);
- imagedata = NULL;
+ return NULL;
+ }
+
+ // swizzle RGBA to BGRA
+ for (y = 0;y < (unsigned int)(image_width*image_height*4);y += 4)
+ {
+ c = imagedata[y+0];
+ imagedata[y+0] = imagedata[y+2];
+ imagedata[y+2] = c;
}
return imagedata;