X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=image_png.c;h=4267331be738462ceaacfd07541f5bedab60861a;hb=1b6062f6c60a2525501e1133052d87307ee02e36;hp=4dc0fd93072fbc4e559d0de03c5b508b35a10ad6;hpb=8022854493e5595b924ed2d573255bff8faf6d4f;p=xonotic%2Fdarkplaces.git diff --git a/image_png.c b/image_png.c index 4dc0fd93..4267331b 100644 --- a/image_png.c +++ b/image_png.c @@ -37,8 +37,8 @@ static void* (*qpng_create_write_struct) (const char*, void*, void(*)(void *pn static void* (*qpng_create_info_struct) (void*); static void (*qpng_read_info) (void*, void*); static void (*qpng_set_compression_level) (void*, int); +static void (*qpng_set_filter) (void*, int, int); static void (*qpng_set_expand) (void*); -static void (*qpng_set_gray_1_2_4_to_8) (void*); static void (*qpng_set_palette_to_rgb) (void*); static void (*qpng_set_tRNS_to_alpha) (void*); static void (*qpng_set_gray_to_rgb) (void*); @@ -59,7 +59,7 @@ static unsigned int (*qpng_get_rowbytes) (void*, void*); static unsigned char (*qpng_get_channels) (void*, void*); static unsigned char (*qpng_get_bit_depth) (void*, void*); static unsigned int (*qpng_get_IHDR) (void*, void*, unsigned long*, unsigned long*, int *, int *, int *, int *, int *); -static char* (*qpng_get_libpng_ver) (void*); +static unsigned int (*qpng_access_version_number) (void); // FIXME is this return type right? It is a png_uint_32 in libpng static void (*qpng_write_info) (void*, void*); static void (*qpng_write_row) (void*, unsigned char*); static void (*qpng_write_end) (void*, void*); @@ -73,8 +73,8 @@ static dllfunction_t pngfuncs[] = {"png_create_info_struct", (void **) &qpng_create_info_struct}, {"png_read_info", (void **) &qpng_read_info}, {"png_set_compression_level", (void **) &qpng_set_compression_level}, + {"png_set_filter", (void **) &qpng_set_filter}, {"png_set_expand", (void **) &qpng_set_expand}, - {"png_set_gray_1_2_4_to_8", (void **) &qpng_set_gray_1_2_4_to_8}, {"png_set_palette_to_rgb", (void **) &qpng_set_palette_to_rgb}, {"png_set_tRNS_to_alpha", (void **) &qpng_set_tRNS_to_alpha}, {"png_set_gray_to_rgb", (void **) &qpng_set_gray_to_rgb}, @@ -95,7 +95,7 @@ static dllfunction_t pngfuncs[] = {"png_get_channels", (void **) &qpng_get_channels}, {"png_get_bit_depth", (void **) &qpng_get_bit_depth}, {"png_get_IHDR", (void **) &qpng_get_IHDR}, - {"png_get_libpng_ver", (void **) &qpng_get_libpng_ver}, + {"png_access_version_number", (void **) &qpng_access_version_number}, {"png_write_info", (void **) &qpng_write_info}, {"png_write_row", (void **) &qpng_write_row}, {"png_write_end", (void **) &qpng_write_end}, @@ -126,10 +126,14 @@ qboolean PNG_OpenLibrary (void) const char* dllnames [] = { #if WIN32 + "libpng14-14.dll", + "libpng14.dll", "libpng12.dll", #elif defined(MACOSX) + "libpng14.14.dylib", "libpng12.0.dylib", #else + "libpng14.so.14", // WTF libtool guidelines anyone? "libpng12.so.0", "libpng.so", // FreeBSD #endif @@ -165,7 +169,8 @@ void PNG_CloseLibrary (void) ================================================================= */ -#define PNG_LIBPNG_VER_STRING "1.2.4" +#define PNG_LIBPNG_VER_STRING_12 "1.2.4" +#define PNG_LIBPNG_VER_STRING_14 "1.4.0" #define PNG_COLOR_MASK_PALETTE 1 #define PNG_COLOR_MASK_COLOR 2 @@ -251,7 +256,7 @@ void PNG_warning_fn(void *png, const char *message) extern int image_width; extern int image_height; -unsigned char *PNG_LoadImage_BGRA (const unsigned char *raw, int filesize) +unsigned char *PNG_LoadImage_BGRA (const unsigned char *raw, int filesize, int *miplevel) { unsigned int c; unsigned int y; @@ -267,7 +272,10 @@ unsigned char *PNG_LoadImage_BGRA (const unsigned char *raw, int filesize) if(qpng_sig_cmp(raw, 0, filesize)) return NULL; - png = (void *)qpng_create_read_struct(PNG_LIBPNG_VER_STRING, 0, PNG_error_fn, PNG_warning_fn); + png = (void *)qpng_create_read_struct( + (qpng_access_version_number() / 100 == 102) ? PNG_LIBPNG_VER_STRING_12 : PNG_LIBPNG_VER_STRING_14, // nasty hack to support both libpng12 and libpng14 + 0, PNG_error_fn, PNG_warning_fn + ); if(!png) return NULL; @@ -278,7 +286,9 @@ unsigned char *PNG_LoadImage_BGRA (const unsigned char *raw, int filesize) // 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 -#if defined(MACOSX) || defined(WIN32) +#ifdef WIN64 + if (setjmp((_JBTYPE *)png)) +#elif defined(MACOSX) || defined(WIN32) if (setjmp((int *)png)) #else if (setjmp((__jmp_buf_tag *)png)) @@ -337,12 +347,7 @@ unsigned char *PNG_LoadImage_BGRA (const unsigned char *raw, int filesize) 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) - { qpng_set_gray_to_rgb(png); - if (my_png.BitDepth < 8) - qpng_set_gray_1_2_4_to_8(png); - } - if (qpng_get_valid(png, pnginfo, PNG_INFO_tRNS)) qpng_set_tRNS_to_alpha(png); if (my_png.BitDepth == 8 && !(my_png.ColorType & PNG_COLOR_MASK_ALPHA)) @@ -417,13 +422,22 @@ unsigned char *PNG_LoadImage_BGRA (const unsigned char *raw, int filesize) ================================================================= */ +#define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 +#define PNG_INTERLACE_NONE 0 #define PNG_INTERLACE_ADAM7 1 #define PNG_FILTER_TYPE_BASE 0 #define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE #define PNG_COMPRESSION_TYPE_BASE 0 #define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE - +#define PNG_NO_FILTERS 0x00 +#define PNG_FILTER_NONE 0x08 +#define PNG_FILTER_SUB 0x10 +#define PNG_FILTER_UP 0x20 +#define PNG_FILTER_AVG 0x40 +#define PNG_FILTER_PAETH 0x80 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) /* ==================== @@ -432,7 +446,7 @@ PNG_SaveImage_preflipped Save a preflipped PNG image to a file ==================== */ -qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height, unsigned char *data) +qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height, qboolean has_alpha, unsigned char *data) { unsigned int offset, linesize; qfile_t* file = NULL; @@ -447,7 +461,10 @@ qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height, return false; } - png = (void *)qpng_create_write_struct(PNG_LIBPNG_VER_STRING, 0, PNG_error_fn, PNG_warning_fn); + png = (void *)qpng_create_write_struct( + (qpng_access_version_number() / 100 == 102) ? PNG_LIBPNG_VER_STRING_12 : PNG_LIBPNG_VER_STRING_14, // nasty hack to support both libpng12 and libpng14 + 0, PNG_error_fn, PNG_warning_fn + ); if(!png) return false; pnginfo = (void *)qpng_create_info_struct(png); @@ -464,7 +481,9 @@ qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height, // 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 -#if defined(MACOSX) || defined(WIN32) +#ifdef WIN64 + if (setjmp((_JBTYPE *)png)) +#elif defined(MACOSX) || defined(WIN32) if (setjmp((int *)png)) #else if (setjmp((__jmp_buf_tag *)png)) @@ -484,16 +503,17 @@ qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height, my_png.outfile = file; qpng_set_write_fn(png, ioBuffer, PNG_fWriteData, PNG_fFlushData); - qpng_set_compression_level(png, Z_BEST_COMPRESSION); - - qpng_set_IHDR(png, pnginfo, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_ADAM7, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + //qpng_set_compression_level(png, Z_BEST_COMPRESSION); + qpng_set_compression_level(png, Z_BEST_SPEED); + qpng_set_IHDR(png, pnginfo, width, height, 8, has_alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB, PNG_INTERLACE_ADAM7, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + qpng_set_filter(png, 0, PNG_NO_FILTERS); qpng_write_info(png, pnginfo); qpng_set_packing(png); qpng_set_bgr(png); passes = qpng_set_interlace_handling(png); - linesize = width * 3; + linesize = width * (has_alpha ? 4 : 3); offset = linesize * (height - 1); for(i = 0; i < passes; ++i) for(j = 0; j < height; ++j) @@ -503,5 +523,6 @@ qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height, qpng_destroy_write_struct(&png, &pnginfo); FS_Close (file); + return true; }