📄 pngcrush.c
字号:
#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200
#define PNG_FLAG_CRC_CRITICAL_USE 0x0400
#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800
#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
PNG_FLAG_CRC_ANCILLARY_NOWARN)
#define PNG_PACK 0x0004
#define PNG_DITHER 0x0040
#define PNG_BACKGROUND 0x0080
#define PNG_16_TO_8 0x0400
#define PNG_RGBA 0x0800
#define PNG_EXPAND 0x1000
#define PNG_GAMMA 0x2000
#define PNG_GRAY_TO_RGB 0x4000
#define PNG_FILLER 0x8000L
#define PNG_USER_TRANSFORM 0x100000L
#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */
/*
* We don't need some of the extra libpng transformations
* so they are ifdef'ed out in pngcrush.h, which is included by
* pngcrush's local copy of libpng's pngconf.h which is included
* by png.h
*
*/
/* defined so I can write to a file on gui/windowing platforms */
/* #define STDERR stderr */
#define STDERR stdout /* for DOS */
#ifndef PNGCRUSH_LIBPNG_VER
# define PNGCRUSH_LIBPNG_VER PNG_LIBPNG_VER
#endif
#ifdef PNG_MNG_FEATURES_SUPPORTED
# define PNGCRUSH_LOCO
#endif
#ifndef PNG_UINT_31_MAX
#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
#endif
/* These macros were renamed in libpng-1.2.6 */
#ifndef PNG_HANDLE_CHUNK_ALWAYS
#define PNG_HANDLE_CHUNK_ALWAYS HANDLE_CHUNK_ALWAYS
#define PNG_HANDLE_CHUNK_NEVER HANDLE_CHUNK_NEVER
#define PNG_HANDLE_CHUNK_IF_SAFE HANDLE_CHUNK_IF_SAFE
#endif
#if defined(__DJGPP__)
# if ((__DJGPP__ == 2) && (__DJGPP_MINOR__ == 0))
# include <libc/dosio.h> /* for _USE_LFN, djgpp 2.0 only */
# endif
# define SLASH "\\"
# define DOT "."
#else
# ifdef __riscos
# define SLASH "."
# define DOT "/"
# else
# define SLASH "/"
# define DOT "."
# endif
#endif
#ifndef GAS_VERSION
# define GAS_VERSION "2.9.5(?)" /* used only in help/usage screen */
#endif
#if !defined(__TURBOC__) && !defined(_MSC_VER) && !defined(_MBCS) && \
!defined(__riscos)
# include <unistd.h>
#endif
#ifndef __riscos
# include <sys/types.h>
# include <sys/stat.h>
# include <utime.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#if defined(_MBCS) || defined(WIN32) || defined(__WIN32__)
# include <direct.h>
#endif
#define DEFAULT_MODE 0
#define DIRECTORY_MODE 1
#define EXTENSION_MODE 2
#define DIREX_MODE 3
#define FOPEN(file, how) fopen(file, how)
#define FCLOSE(file) {fclose(file); file=NULL;--number_of_open_files;};
#define P0 if(first_trial && verbose > 0)printf
#define P1 if(verbose > 1)printf
#define P2 if(verbose > 2)printf
#define STRNGIFY_STAGE1(x) #x
#define STRNGIFY(x) STRNGIFY_STAGE1(x)
#define STR_BUF_SIZE 256
#define MAX_IDAT_SIZE 524288L
#define MAX_METHODS 200
#define MAX_METHODSP1 (MAX_METHODS+1)
#define DEFAULT_METHODS 10
#define FAKE_PAUSE_STRING "P"
#ifdef Z_RLE
# define NUM_STRATEGIES 4
#else
# define NUM_STRATEGIES 3
#endif
#ifdef __TURBOC__
# include <mem.h>
#endif
#ifndef CLOCKS_PER_SEC
# define CLOCKS_PER_SEC 1000
#endif
#ifdef __STDC__
# define TIME_T clock_t
#else
# if CLOCKS_PER_SEC <= 100
# define TIME_T long
# else
# define TIME_T float
# endif
#endif
struct options_help {
int verbosity; /* if verbose >= this value, then print line */
const char *textline; /* static string with newline chopped off */
};
/* input and output filenames */
static PNG_CONST char *progname;
static PNG_CONST char *inname = "pngtest" DOT "png";
static PNG_CONST char *outname = "pngout" DOT "png";
static PNG_CONST char *mngname = "mngout" DOT "mng";
static PNG_CONST char *directory_name = "pngcrush" DOT "bak";
static PNG_CONST char *extension = "_C" DOT "png";
static png_uint_32 width, height;
static png_uint_32 measured_idat_length;
static int found_gAMA = 0;
static int found_cHRM = 0;
static int found_CgBI = 0;
static int found_any_chunk = 0;
static int image_is_immutable = 0;
static int pngcrush_must_exit = 0;
static int all_chunks_are_safe = 0;
static int number_of_open_files;
static int do_pplt = 0;
#ifdef PNGCRUSH_MULTIPLE_ROWS
static png_uint_32 max_rows_at_a_time = 1;
static png_uint_32 rows_at_a_time;
#endif
char pplt_string[1024];
char *ip, *op, *dot;
char in_string[STR_BUF_SIZE];
char prog_string[STR_BUF_SIZE];
char out_string[STR_BUF_SIZE];
char in_extension[STR_BUF_SIZE];
static int text_inputs = 0;
int text_where[10]; /* 0: no text; 1: before PLTE; 2: after PLTE */
int text_compression[10]; /* -1: uncompressed tEXt; 0: compressed zTXt
1: uncompressed iTXt; 2: compressed iTXt */
char text_text[20480]; /* It would be nice to png_malloc this, but we
* don't have a png_ptr yet when we need it. */
char text_keyword[800];
/* PNG_iTXt_SUPPORTED */
char text_lang[800];
char text_lang_key[800];
/* PNG_iCCP_SUPPORTED */
int iccp_length = 0;
char *iccp_text;
char *iccp_file;
char iccp_name[80];
int best;
char buffer[256];
/* Set up the "cexcept" Try/Throw/Catch exception handler. */
#include "cexcept.h"
define_exception_type(const char *);
extern struct exception_context the_exception_context[1];
struct exception_context the_exception_context[1];
png_const_charp msg;
static png_uint_32 total_input_length = 0;
static png_uint_32 total_output_length = 0;
static int pngcrush_mode = DEFAULT_MODE;
static int resolution = 0;
static int remove_chunks = 0;
static int output_color_type;
static int output_bit_depth;
static int force_output_color_type = 8;
static int force_output_bit_depth = 0;
static int input_color_type;
static int input_bit_depth;
static int trial;
static int first_trial = 0;
static int verbose = 1;
static int fix = 0;
static int things_have_changed = 0;
static int global_things_have_changed = 0;
static int default_compression_window = 15;
static int force_compression_window = 0;
static int compression_mem_level = 9;
static int final_method = 0;
static int brute_force = 0;
static int brute_force_level = 0;
static int brute_force_filter = 0;
static int brute_force_strategy = 0;
static int brute_force_levels[10] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
static int brute_force_filters[6] = { 1, 1, 1, 1, 1, 1 };
#ifdef Z_RLE
static int brute_force_strategies[NUM_STRATEGIES] = { 1, 1, 1, 1 };
#else
static int brute_force_strategies[NUM_STRATEGIES] = { 1, 1, 1 };
#endif
static int method = 10;
static int pauses = 0;
static int nosave = 0;
static int nofilecheck = 0;
#ifdef PNGCRUSH_LOCO
static int new_mng = 0;
#endif
static png_bytep row_buf;
#ifdef PNGCRUSH_MULTIPLE_ROWS
static png_bytepp row_pointers;
#endif
static int z_strategy;
static int best_of_three;
static int methods_specified = 0;
static int intent = -1;
static int ster_mode = -1;
static int new_time_stamp = 1;
static int plte_len = -1;
#ifdef PNG_FIXED_POINT_SUPPORTED
static int specified_gamma = 0;
static int image_specified_gamma = 0;
static int force_specified_gamma = 0;
#else
static double specified_gamma = 0.0;
static double image_specified_gamma = 0;
static double force_specified_gamma = 0.0;
#endif
static int double_gamma = 0;
static int names;
static int have_trns = 0;
static png_uint_16 trns_index = 0;
static png_uint_16 trns_red = 0;
static png_uint_16 trns_green = 0;
static png_uint_16 trns_blue = 0;
static png_uint_16 trns_gray = 0;
static png_byte trns_array[256];
static png_byte trans_in[256];
static png_uint_16 num_trans_in;
static int have_bkgd = 0;
static png_uint_16 bkgd_red = 0;
static png_uint_16 bkgd_green = 0;
static png_uint_16 bkgd_blue = 0;
static png_colorp palette;
static int num_palette;
#ifdef REORDER_PALETTE
static png_byte palette_reorder[256];
#endif
static png_structp read_ptr, write_ptr, mng_ptr;
static png_infop read_info_ptr, write_info_ptr;
static png_infop end_info_ptr;
static png_infop write_end_info_ptr;
static FILE *fpin, *fpout, *mng_out;
png_uint_32 measure_idats(FILE * fpin);
#ifdef PNGCRUSH_LOCO
static int do_loco = 0;
static int input_format = 0; /* 0: PNG 1: MNG */
static int output_format = 0;
#endif
static int do_color_count;
static int reduction_ok = 0;
#ifdef PNGCRUSH_COUNT_COLORS
int count_colors(FILE * fpin);
static int num_rgba, reduce_to_gray, it_is_opaque;
#endif
png_uint_32 png_measure_idat(png_structp png_ptr);
static png_uint_32 idat_length[MAX_METHODSP1];
static int filter_type, zlib_level;
static png_bytep png_row_filters = NULL;
static float t_start, t_stop, t_decode, t_encode, t_misc;
static png_uint_32 max_idat_size = MAX_IDAT_SIZE; /* increases the IDAT size */
static png_uint_32 crushed_idat_size = 0x3ffffffL;
static int already_crushed = 0;
int ia;
/* prototypes */
static void png_cexcept_error(png_structp png_ptr, png_const_charp msg);
void PNGAPI png_default_read_data(png_structp png_ptr, png_bytep data,
png_size_t length);
void png_read_transform_info(png_structp png_ptr, png_infop info_ptr);
void PNGAPI png_default_write_data(png_structp png_ptr, png_bytep data,
png_size_t length);
void png_reset_crc(png_structp png_ptr);
void png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length);
void png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length);
int png_crc_error(png_structp png_ptr);
int png_crc_finish(png_structp png_ptr, png_uint_32 skip);
void png_save_uint_32(png_bytep buf, png_uint_32 i);
#ifdef PNG_USER_MEM_SUPPORTED
png_voidp png_debug_malloc(png_structp png_ptr, png_uint_32 size);
void png_debug_free(png_structp png_ptr, png_voidp ptr);
#endif
void png_crush_pause(void);
#ifdef __riscos
static int fileexists(const char *name)
static int filesize(const char *name)
static int mkdir(const char *name, int ignored)
static void setfiletype(const char *name)
#endif
int keep_unknown_chunk(png_const_charp name, char *argv[]);
int keep_chunk(png_const_charp name, char *argv[]);
void show_result(void);
png_uint_32 measure_idats(FILE * fpin);
png_uint_32 png_measure_idat(png_structp png_ptr);
#ifdef PNGCRUSH_COUNT_COLORS
int count_colors(FILE * fpin);
#endif
void print_version_info(void);
void print_usage(int retval);
#if (!defined(PNGCRUSH_H))
/*
* ============================================================
* We aren't using the bundled libpng functions, so we must
* reproduce the libpng routines that aren't exported by libpng
* ============================================================
*/
#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
png_uint_32 /* PRIVATE */
png_get_uint_32(png_bytep buf)
{
png_uint_32 i = ((png_uint_32)(*buf) << 24) +
((png_uint_32)(*(buf + 1)) << 16) +
((png_uint_32)(*(buf + 2)) << 8) +
(png_uint_32)(*(buf + 3));
return (i);
}
#else
# define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
#endif
png_uint_32 /* PRIVATE */
png_get_uint_31(png_structp png_ptr, png_bytep buf)
{
png_uint_32 i = png_get_uint_32(buf);
if (i > PNG_UINT_31_MAX)
png_error(png_ptr, "PNG unsigned integer out of range.\n");
return (i);
}
void /* PRIVATE */
png_save_uint_32(png_bytep buf, png_uint_32 i)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -