diff -urN optipng-0.5.4+0/src/opng.h optipng-0.5.5/src/opng.h --- optipng-0.5.4+0/src/opng.h 2006-08-11 00:01:00.000000000 -0300 +++ optipng-0.5.5/src/opng.h 2007-01-28 15:08:00.000000000 -0200 @@ -14,6 +14,9 @@ #define PNG_INTERNAL #include "png.h" +#if PNG_LIBPNG_VER >= 10400 +#include "pngpriv.h" +#endif #define OPNG_IO_STATE_SUPPORTED /* implemented here */ diff -urN optipng-0.5.4+0/src/opngreduc.c optipng-0.5.5/src/opngreduc.c --- optipng-0.5.4+0/src/opngreduc.c 2006-08-10 23:55:00.000000000 -0300 +++ optipng-0.5.5/src/opngreduc.c 2007-01-22 02:24:00.000000000 -0200 @@ -81,8 +81,9 @@ if (sig_bit != &info_ptr->sig_bit) goto error; if (png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values)) - if (trans != info_ptr->trans || num_trans != info_ptr->num_trans || - trans_values != &info_ptr->trans_values) + if ((trans != NULL && + (trans != info_ptr->trans || num_trans != info_ptr->num_trans)) || + (trans_values != NULL && trans_values != &info_ptr->trans_values)) goto error; /* Also check png_ptr. (It's not much, but we're doing what we can.) */ @@ -245,10 +246,10 @@ } /* Check for overflow. */ - if (*num_palette + 1 == max_tuples) + if (*num_palette >= max_tuples) { - *num_palette = *num_trans = *index = -1; - return -1; + *num_palette = *num_trans = *index = -1; + return -1; } /* Insert new tuple at [low]. */ @@ -267,6 +268,7 @@ trans[low] = (png_byte)alpha; ++(*num_trans); } + *index = low; return 1; } @@ -775,11 +777,11 @@ png_uint_32 result; png_bytepp row_ptr; png_bytep sample_ptr, alpha_row; - png_uint_32 height, width, i, j; + png_uint_32 height, width, channels, i, j; png_color palette[256]; png_byte trans[256]; int num_palette, num_trans, index; - unsigned int channels; + png_color_16p background; unsigned int red, green, blue, alpha, prev_red, prev_green, prev_blue, prev_alpha; @@ -830,6 +832,15 @@ } } } + if ((num_palette >= 0) && (info_ptr->valid & PNG_INFO_bKGD)) + { + /* bKGD must also have its own palette entry. */ + background = &info_ptr->background; + opng_insert_palette_entry(palette, &num_palette, trans, &num_trans, 256, + background->red, background->green, background->blue, 255, &index); + if (index >= 0) + background->index = (png_byte)index; + } /* Check if the uncompressed paletted image (pixels + PLTE + tRNS) * isn't bigger than the uncompressed RGB(A) image. diff -urN optipng-0.5.4+0/src/optipng.c optipng-0.5.5/src/optipng.c --- optipng-0.5.4+0/src/optipng.c 2006-08-11 00:27:00.000000000 -0300 +++ optipng-0.5.5/src/optipng.c 2007-01-28 15:25:00.000000000 -0200 @@ -452,12 +452,13 @@ const char *fmt = "[internal error] %s\n"; fprintf(stderr, fmt, msg); + fflush(stderr); if (global.logfile != NULL) { fprintf(global.logfile, fmt, msg); fflush(global.logfile); } - abort(); + osys_terminate(); } @@ -1048,7 +1049,7 @@ /* Copy the signature. */ if (fread(buf, 8, 1, infile) != 1 || png_sig_cmp(buf, 0, 8) != 0) Throw "Not a PNG file"; -#if (PNG_LIBPNG_VER_MAJOR * 10 + PNG_LIBPNG_VER_MINOR >= 14) || \ +#if (PNG_LIBPNG_VER >= 10400) || \ (PNG_LIBPNG_BUILD_TYPE & PNG_LIBPNG_BUILD_PRIVATE) png_write_sig(write_ptr); #else @@ -1082,7 +1083,8 @@ if (fread(buf, 1, length, infile) != length) /* data */ Throw "Read error"; png_write_chunk(write_ptr, chunk_name, buf, length); - fread(buf, 4, 1, infile); /* crc */ + if (fread(buf, 4, 1, infile) != 1) /* crc */ + Throw "Read error"; } while (memcmp(chunk_name, sig_IEND, 4) != 0); err_msg = NULL; /* everything is ok */ @@ -1173,8 +1175,8 @@ opng_info.strategy_set = strategy_set; opng_info.filter_set = filter_set; t1 = bitset_count(compr_level_set) * - bitset_count(strategy_set & ~(Z_HUFFMAN_ONLY | Z_RLE)); - t2 = bitset_count(strategy_set & (Z_HUFFMAN_ONLY | Z_RLE)); + bitset_count(strategy_set & ~((1 << Z_HUFFMAN_ONLY) | (1 << Z_RLE))); + t2 = bitset_count(strategy_set & ((1 << Z_HUFFMAN_ONLY) | (1 << Z_RLE))); opng_info.num_iterations = (t1 + t2) * bitset_count(mem_level_set) * bitset_count(filter_set); @@ -1419,7 +1421,8 @@ opng_image.interlace_type != cmdline.interlace) { opng_image.interlace_type = cmdline.interlace; - action = recompress; + if (action != create) + action = recompress; } init_file_size = opng_info.file_size; diff -urN optipng-0.5.4+0/src/osys.c optipng-0.5.5/src/osys.c --- optipng-0.5.4+0/src/osys.c 2006-08-07 12:57:00.000000000 -0300 +++ optipng-0.5.5/src/osys.c 2007-01-27 23:19:00.000000000 -0200 @@ -44,6 +45,7 @@ #endif +#include #include #include #include @@ -54,9 +56,11 @@ # include # include #endif +#if defined OSYS_DOS || defined OSYS_OS2 +# include +#endif #if defined OSYS_WINDOWS # include -# include #endif #include "osys.h" @@ -82,7 +86,9 @@ #define OSYS_FNAME_CHR_STAR '*' #define OSYS_FNAME_STR_STAR "*" -#if defined OSYS_DOS || defined OSYS_OS2 || defined OSYS_WINDOWS +#if defined OSYS_DOS || defined OSYS_OS2 || \ + defined OSYS_WINDOWS || defined __CYGWIN__ +# define OSYS_FNAME_DOS # define OSYS_FNAME_IGN_CASE 1 #else /* OSYS_UNIX and possibly others */ # define OSYS_FNAME_IGN_CASE 0 @@ -106,7 +112,7 @@ { fprintf(stderr, "Out of memory!\n"); fflush(stderr); - abort(); + osys_terminate(); } return result; } @@ -125,6 +131,34 @@ /** + * Prints an error message to stderr and terminates the program + * execution immediately, exiting with EXIT_FAILURE. + * This function does not raise SIGABRT, and it does not generate + * other files (like core dumps, where applicable). + **/ +void osys_terminate(void) +{ + fprintf(stderr, + "The execution of this program has been terminated abnormally.\n"); + fflush(stderr); + +#if defined OSYS_UNIX || defined OSYS_DOS || defined OSYS_OS2 + + _exit(EXIT_FAILURE); + +#elif defined OSYS_WINDOWS + + ExitProcess(EXIT_FAILURE); + +#else + + exit(EXIT_FAILURE); + +#endif +} + + +/** * Creates a backup file name. * On success, returns buffer. * On error, returns NULL. @@ -164,7 +198,12 @@ size_t dirlen; /* Extract file name from oldname. */ - for (fname = oldname; ; ) + fname = oldname; +#ifdef OSYS_FNAME_DOS + if (isalpha(fname[0]) && fname[1] == ':') + fname += 2; /* skip drive name */ +#endif + for ( ; ; ) { ptr = strpbrk(fname, OSYS_FNAME_STRLIST_SLASH); if (ptr == NULL) @@ -181,6 +220,11 @@ if (dirlen > 0) { strcpy(buffer, newdir); +#ifdef OSYS_FNAME_DOS + if (dirlen == 2 && buffer[1] == ':' && isalpha(buffer[0])) + (void)0; /* do nothing */ + else +#endif if (strchr(OSYS_FNAME_STRLIST_SLASH, buffer[dirlen - 1]) == NULL) buffer[dirlen++] = OSYS_FNAME_CHR_SLASH; /* append slash to dir */ } @@ -369,53 +413,65 @@ **/ int osys_dir_make(const char *dirname) { -#if defined OSYS_UNIX || defined OSYS_DOS || defined OSYS_OS2 + size_t len; - DIR *dir; + len = strlen(dirname); + if (len == 0) /* current directory */ + return 0; - if ((dir = opendir(dirname)) != NULL) - { - closedir(dir); +#ifdef OSYS_FNAME_DOS + if (len == 2 && dirname[1] == ':' && isalpha(dirname[0])) /* [DRIVE]: */ return 0; - } +#endif +#if defined OSYS_UNIX || defined OSYS_DOS || defined OSYS_OS2 + + { + DIR *dir; + + if ((dir = opendir(dirname)) != NULL) + { + closedir(dir); + return 0; + } + + /* There is no directory, so create one now. */ # if defined OSYS_DOS || defined OSYS_OS2 - return mkdir(dirname); + return mkdir(dirname); # else - return mkdir(dirname, 0777); + return mkdir(dirname, 0777); # endif + } #elif defined OSYS_WINDOWS - size_t len; - LPCTSTR format; - LPTSTR wildname; - HANDLE hFind; - WIN32_FIND_DATA wfd; - - len = strlen(dirname); - if (len == 0) /* current directory */ - return 0; - - /* See if dirname exists: find files in (dirname + "\\*"). */ - wildname = (LPTSTR)malloc((len + 3) * sizeof(TCHAR)); - if (wildname == NULL) /* out of memory */ - return -1; - if (strchr(OSYS_FNAME_STRLIST_SLASH, dirname[len - 1]) == NULL) - format = TEXT("%hs" OSYS_FNAME_STR_SLASH OSYS_FNAME_STR_STAR); - else - format = TEXT("%hs" OSYS_FNAME_STR_STAR); - wsprintf(wildname, format, dirname); - hFind = FindFirstFile(wildname, &wfd); - free(wildname); - if (hFind != INVALID_HANDLE_VALUE) { - FindClose(hFind); - return 0; - } + char *wildname; + HANDLE hFind; + WIN32_FIND_DATA wfd; + + /* See if dirname exists: find files in (dirname + "\\*"). */ + if (len + 3 < len) /* overflow */ + return -1; + wildname = (char *)malloc(len + 3); + if (wildname == NULL) /* out of memory */ + return -1; + strcpy(wildname, dirname); + if (strchr(OSYS_FNAME_STRLIST_SLASH, wildname[len - 1]) == NULL) + wildname[len++] = OSYS_FNAME_CHR_SLASH; + wildname[len++] = OSYS_FNAME_CHR_STAR; + wildname[len] = '\0'; + hFind = FindFirstFileA(wildname, &wfd); + free(wildname); + if (hFind != INVALID_HANDLE_VALUE) + { + FindClose(hFind); + return 0; + } - /* There is no directory, so create one now. */ - return CreateDirectoryA(dirname, NULL) ? 0 : -1; + /* There is no directory, so create one now. */ + return CreateDirectoryA(dirname, NULL) ? 0 : -1; + } #else diff -urN optipng-0.5.4+0/src/osys.h optipng-0.5.5/src/osys.h --- optipng-0.5.4+0/src/osys.h 2006-08-07 11:43:00.000000000 -0300 +++ optipng-0.5.5/src/osys.h 2007-01-27 23:14:00.000000000 -0200 @@ -34,6 +37,15 @@ /** + * Prints an error message to stderr and terminates the program + * execution immediately, exiting with EXIT_FAILURE. + * This function does not raise SIGABRT, and it does not generate + * other files (like core dumps, where applicable). + **/ +void osys_terminate(void); + + +/** * Creates a backup file name. * On success, returns buffer. * On error, returns NULL.