From 6595b27601ff72318acbcec25861ba1c824777df Mon Sep 17 00:00:00 2001 From: Matthias Kramm Date: Tue, 30 Mar 2010 20:29:38 -0700 Subject: [PATCH] png speed improvement draft --- config.h.in | 8 +++++ configure | 2 +- configure.in | 6 +++- lib/mem.c | 8 ++++- lib/mem.h | 5 ++++ lib/png.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 116 insertions(+), 6 deletions(-) diff --git a/config.h.in b/config.h.in index 72c6e56..7f99da5 100644 --- a/config.h.in +++ b/config.h.in @@ -82,6 +82,9 @@ /* Define if you have the srand48 function. */ #undef HAVE_SRAND48 +/* Define if you have the calloc function. */ +#undef HAVE_CALLOC + /* Define if you have the stat function. */ #undef HAVE_STAT @@ -274,4 +277,9 @@ #endif #endif +// supply a substitute calloc function if necessary +#ifndef HAVE_CALLOC +#define calloc rfx_calloc_replacement +#endif + #endif diff --git a/configure b/configure index c8bd491..6a86e25 100755 --- a/configure +++ b/configure @@ -5423,7 +5423,7 @@ _ACEOF fi #needed for jpeglib - for ac_func in popen wcschr wcsdup mkstemp stat mmap lrand48 rand srand48 srand bcopy bzero time getrusage mallinfo open64 + for ac_func in popen wcschr wcsdup mkstemp stat mmap lrand48 rand srand48 srand bcopy bzero time getrusage mallinfo open64 calloc do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.in b/configure.in index 1a5efbe..515718a 100644 --- a/configure.in +++ b/configure.in @@ -272,7 +272,7 @@ dnl Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIZE_T AC_STRUCT_TM AC_CHECK_TYPE(boolean,int) #needed for jpeglib - AC_CHECK_FUNCS(popen wcschr wcsdup mkstemp stat mmap lrand48 rand srand48 srand bcopy bzero time getrusage mallinfo open64) + AC_CHECK_FUNCS(popen wcschr wcsdup mkstemp stat mmap lrand48 rand srand48 srand bcopy bzero time getrusage mallinfo open64 calloc) AC_CHECK_SIZEOF([signed char]) AC_CHECK_SIZEOF([signed short]) @@ -578,6 +578,10 @@ AH_BOTTOM([ #endif #endif +// supply a substitute calloc function if necessary +#ifndef HAVE_CALLOC +#define calloc rfx_calloc_replacement +#endif #endif // __config_h__ ]) diff --git a/lib/mem.c b/lib/mem.c index 8e619dc..6dd58f5 100644 --- a/lib/mem.c +++ b/lib/mem.c @@ -66,7 +66,7 @@ void* rfx_calloc(int size) return 0; } #ifdef HAVE_CALLOC - ptr = calloc(size); + ptr = calloc(1, size); #else ptr = malloc(size); #endif @@ -80,6 +80,12 @@ void* rfx_calloc(int size) #endif return ptr; } +#ifndef HAVE_CALLOC +void* rfx_calloc_replacement(int nmemb, int size) +{ + rfx_calloc(nmemb*size); +} +#endif #ifdef MEMORY_INFO long rfx_memory_used() diff --git a/lib/mem.h b/lib/mem.h index 5214c76..a963500 100644 --- a/lib/mem.h +++ b/lib/mem.h @@ -5,11 +5,16 @@ extern "C" { #endif +#include "../config.h" + #define ALLOC_ARRAY(type, num) (((type)*)rfxalloc(sizeof(type)*(num))) void* rfx_alloc(int size); void* rfx_calloc(int size); void* rfx_realloc(void*data, int size); void rfx_free(void*data); +#ifndef HAVE_CALLOC +void* rfx_calloc_replacement(int nmemb, int size) +#endif #ifdef MEMORY_INFO long rfx_memory_used(); char* rfx_memory_used_str(); diff --git a/lib/png.c b/lib/png.c index 9ab0325..f6edc12 100644 --- a/lib/png.c +++ b/lib/png.c @@ -1376,7 +1376,7 @@ static int png_apply_specific_filter_32(int filtermode, unsigned char*dest, unsi } return filtermode; } - + static int*num_bits_table = 0; static void make_num_bits_table() @@ -1395,13 +1395,93 @@ static void make_num_bits_table() } } +static int png_find_best_filter_8(unsigned char*src, int width, int y) +{ + /* + + FFFF I X X M M EEEE + F I X X MM MM E + FFF I X M M M EEE + F I X X M M E + F I X X M M EEEE + + */ + return 0; +} + +static int png_find_best_filter_32(unsigned char*src, int width, int y) +{ + make_num_bits_table(); + + int num_filters = y>0?5:2; //don't apply y-direction filter in first line + + int srcwidth = y?width*4:0; + int x; + unsigned char*pairs[5]; + pairs[0] = calloc(1, 8192); + pairs[1] = calloc(1, 8192); + pairs[2] = calloc(1, 8192); + pairs[3] = calloc(1, 8192); + pairs[4] = calloc(1, 8192); + + unsigned char old[5]; + + old[0] = src[3]; + old[1] = src[3]; + old[2] = src[3] - src[3-srcwidth]; + old[3] = src[3] - src[3-srcwidth]; + old[4] = src[3] - PaethPredictor(0, src[3-srcwidth], 0); + + int different_pairs[5] = {0,0,0,0,0}; + + int w = width*4; + for(x=4;x>3; + int b = 1<<(v&7); + if(!pairs[i][p]&b) { + pairs[i][p]|=b; + different_pairs[i]++; + } + } + memcpy(old, dest, sizeof(old)); + } + int f; + int best_nr = 0; + int best_energy = INT_MAX; + for(f=0;f0?5:2; //don't apply y-direction filter in first line - int f; int best_nr = 0; +#if 0 + int f; int best_energy = INT_MAX; int w = width*(bpp/8); unsigned char* pairs = malloc(8192); @@ -1432,11 +1512,17 @@ static int png_apply_filter(unsigned char*dest, unsigned char*src, int width, in best_energy = energy; } } + free(pairs); +#else + if(bpp==8) + best_nr = png_find_best_filter_8(src, width, y); + else + best_nr = png_find_best_filter_32(src, width, y); +#endif if(bpp==8) png_apply_specific_filter_8(best_nr, dest, src, width); else png_apply_specific_filter_32(best_nr, dest, src, width); - free(pairs); return best_nr; } @@ -1475,6 +1561,7 @@ EXPORT void savePNG(const char*filename, unsigned char*data, int width, int heig if(!numcolors) { int num = png_get_number_of_palette_entries((COL*)data, width, height, palette, &has_alpha); + num = 256; if(num<=255) { //printf("image has %d different colors (alpha=%d)\n", num, has_alpha); data2 = malloc(width*height); -- 1.7.10.4