avoid the use of png_jmpbuf. libpng's setjmp crap is just bug after bug. don't use it at any cost. luckily libpng still provides for an error callback, so use that with our own setjmp+longjmp calls. hopefully things will be less fucked that way.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4614 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
a3d4e46edc
commit
1c46aefb39
1 changed files with 56 additions and 35 deletions
|
@ -784,9 +784,7 @@ typedef struct {
|
|||
int filelen;
|
||||
} pngreadinfo_t;
|
||||
|
||||
void PNGAPI png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length);
|
||||
|
||||
void VARGS readpngdata(png_structp png_ptr,png_bytep data,png_size_t len)
|
||||
static void VARGS readpngdata(png_structp png_ptr,png_bytep data,png_size_t len)
|
||||
{
|
||||
pngreadinfo_t *ri = (pngreadinfo_t*)qpng_get_io_ptr(png_ptr);
|
||||
if (ri->readposition+len > ri->filelen)
|
||||
|
@ -798,6 +796,25 @@ void VARGS readpngdata(png_structp png_ptr,png_bytep data,png_size_t len)
|
|||
ri->readposition+=len;
|
||||
}
|
||||
|
||||
struct pngerr
|
||||
{
|
||||
const char *fname;
|
||||
jmp_buf jbuf;
|
||||
};
|
||||
static void VARGS png_onerror(png_structp png_ptr, png_const_charp error_msg)
|
||||
{
|
||||
struct pngerr *err = png_get_error_ptr(png_ptr);
|
||||
Con_Printf("libpng %s: %s", err->fname, error_msg);
|
||||
longjmp(err->jbuf, 1);
|
||||
abort();
|
||||
}
|
||||
|
||||
static void VARGS png_onwarning(png_structp png_ptr, png_const_charp warning_msg)
|
||||
{
|
||||
struct pngerr *err = png_get_error_ptr(png_ptr);
|
||||
Con_Printf("libpng %s: %s\n", err->fname, warning_msg);
|
||||
}
|
||||
|
||||
qbyte *png_rgba;
|
||||
qbyte *ReadPNGFile(qbyte *buf, int length, int *width, int *height, const char *fname)
|
||||
{
|
||||
|
@ -808,15 +825,28 @@ qbyte *ReadPNGFile(qbyte *buf, int length, int *width, int *height, const char *
|
|||
unsigned long rowbytes;
|
||||
pngreadinfo_t ri;
|
||||
png_uint_32 pngwidth, pngheight;
|
||||
struct pngerr errctx;
|
||||
|
||||
memcpy(header, buf, 8);
|
||||
|
||||
errctx.fname = fname;
|
||||
if (setjmp(errctx.jbuf))
|
||||
{
|
||||
error:
|
||||
if (data)
|
||||
BZ_Free(data);
|
||||
if (rowpointers)
|
||||
BZ_Free(rowpointers);
|
||||
qpng_destroy_read_struct(&png, &pnginfo, NULL);
|
||||
return (png_rgba = NULL);
|
||||
}
|
||||
|
||||
if (qpng_sig_cmp(header, 0, 8))
|
||||
{
|
||||
return (png_rgba = NULL);
|
||||
}
|
||||
|
||||
if (!(png = qpng_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
|
||||
if (!(png = qpng_create_read_struct(PNG_LIBPNG_VER_STRING, &errctx, png_onerror, png_onwarning)))
|
||||
{
|
||||
return (png_rgba = NULL);
|
||||
}
|
||||
|
@ -827,17 +857,6 @@ qbyte *ReadPNGFile(qbyte *buf, int length, int *width, int *height, const char *
|
|||
return (png_rgba = NULL);
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png)))
|
||||
{
|
||||
error:
|
||||
if (data)
|
||||
BZ_Free(data);
|
||||
if (rowpointers)
|
||||
BZ_Free(rowpointers);
|
||||
qpng_destroy_read_struct(&png, &pnginfo, NULL);
|
||||
return (png_rgba = NULL);
|
||||
}
|
||||
|
||||
ri.data=buf;
|
||||
ri.readposition=8;
|
||||
ri.filelen=length;
|
||||
|
@ -923,6 +942,7 @@ int Image_WritePNG (char *filename, int compression, qbyte *pixels, int width, i
|
|||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_byte **row_pointers;
|
||||
struct pngerr errctx;
|
||||
|
||||
if (!FS_NativePath(filename, FS_GAMEONLY, name, sizeof(name)))
|
||||
return false;
|
||||
|
@ -934,36 +954,37 @@ int Image_WritePNG (char *filename, int compression, qbyte *pixels, int width, i
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(png_ptr = qpng_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
|
||||
errctx.fname = filename;
|
||||
if (setjmp(errctx.jbuf))
|
||||
{
|
||||
err:
|
||||
qpng_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(png_ptr = qpng_create_write_struct(PNG_LIBPNG_VER_STRING, &errctx, png_onerror, png_onwarning)))
|
||||
{
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(info_ptr = qpng_create_info_struct(png_ptr)))
|
||||
if (!(info_ptr = qpng_create_info_struct(png_ptr)))
|
||||
{
|
||||
qpng_destroy_write_struct(&png_ptr, (png_infopp) NULL);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
err:
|
||||
qpng_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
qpng_init_io(png_ptr, fp);
|
||||
compression = bound(0, compression, 100);
|
||||
|
||||
// had to add these when I migrated from libpng 1.4.x to 1.5.x
|
||||
#ifndef Z_NO_COMPRESSION
|
||||
#define Z_NO_COMPRESSION 0
|
||||
#define Z_NO_COMPRESSION 0
|
||||
#endif
|
||||
#ifndef Z_BEST_COMPRESSION
|
||||
#define Z_BEST_COMPRESSION 9
|
||||
#define Z_BEST_COMPRESSION 9
|
||||
#endif
|
||||
qpng_set_compression_level(png_ptr, Z_NO_COMPRESSION + (compression*(Z_BEST_COMPRESSION-Z_NO_COMPRESSION))/100);
|
||||
|
||||
|
@ -1168,7 +1189,7 @@ fill_input_buffer (j_decompress_ptr cinfo)
|
|||
if (src->start_of_file) /* Treat empty input file as fatal error */
|
||||
ERREXIT(cinfo, JERR_INPUT_EMPTY);
|
||||
WARNMS(cinfo, JWRN_JPEG_EOF);
|
||||
/* Insert a fake EOI marker */
|
||||
/* Insert a fake EOI marker */
|
||||
src->buffer[0] = (JOCTET) 0xFF;
|
||||
src->buffer[1] = (JOCTET) JPEG_EOI;
|
||||
nbytes = 2;
|
||||
|
@ -1533,12 +1554,12 @@ qboolean screenshotJPEG(char *filename, int compression, qbyte *screendata, int
|
|||
|
||||
while (cinfo.next_scanline < cinfo.image_height)
|
||||
{
|
||||
*row_pointer = &buffer[(cinfo.image_height - cinfo.next_scanline - 1) * cinfo.image_width * 3];
|
||||
#ifdef DYNAMIC_LIBJPEG
|
||||
qjpeg_write_scanlines(&cinfo, row_pointer, 1);
|
||||
#else
|
||||
jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
||||
#endif
|
||||
*row_pointer = &buffer[(cinfo.image_height - cinfo.next_scanline - 1) * cinfo.image_width * 3];
|
||||
#ifdef DYNAMIC_LIBJPEG
|
||||
qjpeg_write_scanlines(&cinfo, row_pointer, 1);
|
||||
#else
|
||||
jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
||||
#endif
|
||||
}
|
||||
#ifdef DYNAMIC_LIBJPEG
|
||||
qjpeg_finish_compress(&cinfo);
|
||||
|
|
Loading…
Reference in a new issue