Lines Matching +full:- +full:- +full:with +full:- +full:zlib
3 * Copyright (c) 2014-2017,2024 John Cunningham Bowler
9 * Tool to check and fix the zlib inflate 'too far back' problem.
35 # error "pngfix will not work with libpng prior to 1.6.3"
45 /* zlib.h defines the structure z_stream, an instance of which is included
50 /* We must ensure that zlib uses 'const' in declarations. */
53 #include <zlib.h>
55 /* zlib.h sometimes #defines const to nothing, undo this. */
59 /* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility
60 * with older builds.
126 /* The 8-byte signature as a pair of 32-bit quantities */
143 /* 80-bit number handling - a PNG image can be up to (2^31-1)x(2^31-1) 8-byte
144 * (16-bit RGBA) pixels in size; that's less than 2^65 bytes or 2^68 bits, so
145 * arithmetic of 80-bit numbers is sufficient. This representation uses an
149 * The arithmetic functions take zero to two uarb values together with the
196 /* This is a signed 32-bit add, except that to avoid overflow the value added in uarb_inc()
197 * or subtracted must be no more than 2^31-65536. A negative result in uarb_inc()
200 * in_digits+1 if add is known to be in the range -65535..65535. in uarb_inc()
212 while (add != 0 && add != (-1)) in uarb_inc()
220 while (out_digits > 0 && num[out_digits-1] == 0) in uarb_inc()
221 --out_digits; in uarb_inc()
227 while (out_digits > 1 && num[out_digits-1] == 0xffff) in uarb_inc()
228 --out_digits; in uarb_inc()
230 return -out_digits; in uarb_inc()
236 /* As above but this works with any 32-bit value and only does 'add' */ in uarb_add32()
241 return uarb_inc(num+1, in_digits-1, add >> 16)+1; in uarb_add32()
250 /* Primitive one-digit multiply - 'val' must be 0..65535. Note that this in uarb_mult_digit()
251 * primitive is a multiply and accumulate - the result of *num * val is added in uarb_mult_digit()
254 * This is a one-digit multiply, so the product may be up to one digit longer in uarb_mult_digit()
294 /* calculate acc += num * val, 'val' may be any 32-bit value, 'acc' and 'num' in uarb_mult32()
305 a_digits = uarb_mult_digit(acc+1, a_digits-1, num, n_digits, in uarb_mult32()
326 while (--i >= 0) in uarb_shift()
331 carry = (png_uint_16)((inout[i] << (16-right_shift)) & 0xffff); in uarb_shift()
345 /* Return -1/0/+1 according as a<b/a==b/a>b */ in uarb_cmp()
348 return -1; in uarb_cmp()
353 while (adigits-- > 0) in uarb_cmp()
355 return -1; in uarb_cmp()
383 if (num[--digits] > 0) in uarb_printx()
388 fprintf(out, "%.4x", num[--digits]); in uarb_printx()
414 n = (n << 16) + num[--digits]; in uarb_print()
424 * Hill, "The Art of Electronics" (Pseudo-Random Bit Sequences and Noise
435 /* There are thirty-three bits; the next bit in the sequence is bit-33 XOR in make_random_bytes()
436 * bit-20. The top 1 bit is in u1, the bottom 32 are in u0. in make_random_bytes()
442 png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff; in make_random_bytes()
466 * CRC checking uses a local pre-built implementation of the Ethernet CRC32.
467 * This is to avoid a function call to the zlib DLL and to optimize the
468 * byte-by-byte case.
527 * zlib and the result value is obtained by XORing with CRC_INIT, which is also
541 /* This is an alternative to the algorithm used in zlib, which requires four in crc_init_4()
544 * the parser below where length+chunk-name is read and chunk-name used to in crc_init_4()
546 * conditioning (xor with 0xffffffff) by storing the conditioned value. in crc_init_4()
558 * branches. The cost is that it uses a lot of 32-bit constants, which might in chunk_type_valid()
565 * 8-bit unit must be in the range 65-90 to be valid. So bit 5 in chunk_type_valid()
571 /* Subtract 65 for each 8-bit quantity, this must not overflow in chunk_type_valid()
572 * and each byte must then be in the range 0-25. in chunk_type_valid()
574 c -= PNG_U32(65,65,65,65); in chunk_type_valid()
580 c -= PNG_U32(25,25,25,26); in chunk_type_valid()
588 /* Information about a sequence of IDAT chunks, the chunks have been re-synced
607 list->next = NULL; in IDAT_list_init()
608 list->length = IDAT_INIT_LENGTH; in IDAT_list_init()
616 length = list->length; in IDAT_list_size()
618 return sizeof *list - sizeof list->lengths + in IDAT_list_size()
619 length * sizeof list->lengths[0]; in IDAT_list_size()
625 struct IDAT_list *list = IDAT_list->next; in IDAT_list_end()
631 struct IDAT_list *next = list->next; in IDAT_list_end()
643 struct IDAT_list *next = tail->next; in IDAT_list_extend()
650 unsigned int length = 2 * tail->length; in IDAT_list_extend()
652 if (length < tail->length) /* arithmetic overflow */ in IDAT_list_extend()
653 length = tail->length; in IDAT_list_extend()
662 next->next = NULL; in IDAT_list_extend()
663 next->length = length; in IDAT_list_extend()
664 tail->next = next; in IDAT_list_extend()
679 unsigned int skip :3; /* Non-critical chunks to skip */
681 # define SKIP_BAD_CRC 1 /* Chunks with a bad CRC */
688 png_uint_32 idat_max; /* 0 to perform no re-chunking */
691 # define TOO_FAR_BACK 0x01 /* found a too-far-back error */
712 IDAT_list_end(&global->idat_cache); in global_end()
713 rc = global->status_code; in global_end()
725 global->errors = 0; in global_init()
726 global->warnings = 0; in global_init()
727 global->quiet = 0; in global_init()
728 global->verbose = 0; in global_init()
729 global->idat_max = 0; /* no re-chunking of IDAT */ in global_init()
730 global->optimize_zlib = 0; in global_init()
731 global->skip = SKIP_NONE; in global_init()
732 global->status_code = 0; in global_init()
734 IDAT_list_init(&global->idat_cache); in global_init()
739 /* Return true if this chunk is to be skipped according to the --strip in skip_chunk_type()
741 * to handle the --strip=unsafe option. in skip_chunk_type()
760 if (global->skip >= SKIP_ALL) in skip_chunk_type()
764 /* Chunks that affect color interpretation - not used by libpng and rarely in skip_chunk_type()
769 if (global->skip >= SKIP_COLOR) in skip_chunk_type()
778 if (global->skip >= SKIP_TRANSFORM) in skip_chunk_type()
783 * interpretation nor libpng transforms - chunks that are effectively in skip_chunk_type()
789 if (global->skip >= SKIP_UNUSED) in skip_chunk_type()
795 * whether the safe-to-copy bit is set in the chunk type. in skip_chunk_type()
800 if (global->skip >= SKIP_UNUSED) /* as above */ in skip_chunk_type()
804 else if (global->skip >= SKIP_UNSAFE) in skip_chunk_type()
811 /* PER-FILE CONTROL STRUCTURE */
819 /* PUBLIC PER-FILE VARIABLES: CALLER INITIALIZE */
823 /* PUBLIC PER-FILE VARIABLES: SET BY PNG READ CODE */
841 /* PROTECTED PER-FILE VARIABLES: USED BY THE READ CODE */
852 * into the structure and can then be overwritten with the data for the next
868 # define STATE_CHUNKS 1 /* Non-IDAT chunks are being written */
871 /* Two pointers used to enable clean-up in the event of fatal errors and to
890 #define ZLIB_ERROR_CODE 3 /* generic zlib error */
898 /* Print a string with spaces replaced by '_' and non-printing characters by in emit_string()
920 case ZLIB_ERROR_CODE: return "zlib"; in strcode()
942 case ZLIB_ERROR_CODE: reason = "zlib error:"; break; in emit_error()
945 err = file->read_errno; in emit_error()
948 err = file->write_errno; in emit_error()
951 err = file->read_errno; in emit_error()
953 err = file->write_errno; in emit_error()
959 fprintf(stderr, "%s: %s %s [%s]\n", file->file_name, reason, what, in emit_error()
963 fprintf(stderr, "%s: %s %s\n", file->file_name, reason, what); in emit_error()
977 if (file->idat != NULL) in file_end()
978 IDAT_end(&file->idat); in file_end()
980 if (file->chunk != NULL) in file_end()
981 chunk_end(&file->chunk); in file_end()
983 rc = file->status_code; in file_end()
985 if (file->file != NULL) in file_end()
986 (void)fclose(file->file); in file_end()
988 if (file->out != NULL) in file_end()
996 * to ensure the close succeeded and in ANSI-C conformant code they must in file_end()
999 const int err = fflush(file->out) || ferror(file->out); in file_end()
1001 if (fclose(file->out) || err) in file_end()
1003 perror(file->out_name); in file_end()
1010 file->global->status_code |= rc; in file_end()
1014 return rc; /* status code: non-zero on read or write error */ in file_end()
1026 file->global = global; in file_init()
1028 file->file_name = file_name; in file_init()
1029 file->out_name = out_name; in file_init()
1030 file->status_code = 0; in file_init()
1031 file->read_errno = 0; in file_init()
1032 file->write_errno = 0; in file_init()
1034 file->file = NULL; in file_init()
1035 file->out = NULL; in file_init()
1038 file->read_count = 0; in file_init()
1039 file->state = STATE_SIGNATURE; in file_init()
1041 file->chunk = NULL; in file_init()
1042 file->idat = NULL; in file_init()
1044 file->alloc_ptr = alloc_ptr; in file_init()
1045 file->alloc = alloc; in file_init()
1049 file->file = fopen(file_name, "rb"); in file_init()
1051 if (file->file == NULL) in file_init()
1053 file->read_errno = errno; in file_init()
1054 file->status_code |= FILE_ERROR; in file_init()
1062 file->out = fopen(out_name, "wb"); in file_init()
1064 if (file->out == NULL) in file_init()
1066 file->write_errno = errno; in file_init()
1067 file->status_code |= WRITE_ERROR; in file_init()
1080 if (file->global->errors) in log_error()
1088 * function it will always return a-zA-Z, but the extra codes are just there in type_char()
1094 return "!abcdefghijklmnopqrstuvwxyz56789"[(v-96)&31]; in type_char()
1097 return "@ABCDEFGHIJKLMNOPQRSTUVWXYZ01234"[(v-64)&31]; in type_char()
1126 /* The chunk being read is typically identified by file->chunk or, if this is in stop()
1127 * NULL, by file->type. This may be wrong if libpng reads ahead, but this in stop()
1128 * only happens with IDAT where libpng reads the header then jumps around in stop()
1134 * IDAT ERR status code read-errno write-errno message file in stop()
1139 if (file->global->quiet < 2) /* need two quiets to stop this. */ in stop()
1143 if (file->chunk != NULL) in stop()
1147 type = file->type; in stop()
1155 printf(" ERR %.2x %s ", file->status_code, strcode(code)); in stop()
1159 emit_string(strerror(file->read_errno), stdout); in stop()
1161 emit_string(strerror(file->write_errno), stdout); in stop()
1165 fputs(file->file_name, stdout); in stop()
1169 file->status_code |= FILE_ERROR; in stop()
1170 longjmp(file->jmpbuf, code); in stop()
1183 if (file->global->errors) in type_message()
1185 fputs(file->file_name, stderr); in type_message()
1194 /* Input file positioning - we jump around in the input file while reading
1195 * stuff, these wrappers deal with the error handling.
1200 if (fgetpos(file->file, pos)) in file_getpos()
1203 perror(file->file_name); in file_getpos()
1211 if (fsetpos(file->file, pos)) in file_setpos()
1213 perror(file->file_name); in file_setpos()
1225 file_getpos(file, &file->data_pos); in getpos()
1229 /* Read utility - read a single byte, returns a value in the range 0..255 or EOF
1236 int ch = getc(file->file); in read_byte()
1240 ++(file->read_count); in read_byte()
1246 file->status_code |= INTERNAL_ERROR; in read_byte()
1247 file->read_errno = ERANGE; /* out of range character */ in read_byte()
1266 if (ferror(file->file)) in read_byte()
1267 file->read_errno = errno; in read_byte()
1269 else if (feof(file->file)) in read_byte()
1270 file->read_errno = 0; /* I.e. a regular EOF, no error */ in read_byte()
1273 file->read_errno = EDOM; in read_byte()
1280 file->status_code |= TRUNCATED; in read_byte()
1290 int ch = getc(file->file); in reread_byte()
1293 file->read_errno = errno; in reread_byte()
1316 /* Skip exactly 12 bytes in the input stream - used to skip a CRC and chunk in skip_12()
1321 if (fseek(file->file, 12, SEEK_CUR) != 0) in skip_12()
1324 file->read_errno = errno; in skip_12()
1332 /* Write one byte to the output - this causes a fatal error if the write in write_byte()
1337 if (file->out != NULL) in write_byte()
1339 if (putc(b, file->out) != b) in write_byte()
1341 file->write_errno = errno; in write_byte()
1342 file->status_code |= WRITE_ERROR; in write_byte()
1347 ++(file->write_count); in write_byte()
1374 /* CRC handling - read but calculate the CRC while doing so. */
1383 png_uint_32 crc = file->crc; in crc_read_many()
1394 while (--length > 0); in crc_read_many()
1396 file->crc = crc; in crc_read_many()
1408 png_uint_16 pd = file->bit_depth; in calc_image_size()
1410 switch (file->color_type) in calc_image_size()
1450 if (file->width < 1 || file->width > 0x7fffffff) in calc_image_size()
1453 else if (file->height < 1 || file->height > 0x7fffffff) in calc_image_size()
1456 else if (file->compression_method != 0) in calc_image_size()
1459 else if (file->filter_method != 0) in calc_image_size()
1462 else switch (file->interlace_method) in calc_image_size()
1475 png_uint_32 pw = PNG_PASS_COLS(file->width, pass); in calc_image_size()
1487 /* Add row_bytes * pass-height to the file image_bytes field in calc_image_size()
1489 image_digits = uarb_mult32(file->image_bytes, image_digits, in calc_image_size()
1491 PNG_PASS_ROWS(file->height, pass)); in calc_image_size()
1495 file->image_digits = image_digits; in calc_image_size()
1506 row_width, uarb_set(row_width, file->width), pd); in calc_image_size()
1510 /* Set row_bytes * image-height to the file image_bytes field */ in calc_image_size()
1511 file->image_digits = uarb_mult32(file->image_bytes, 0, in calc_image_size()
1512 row_bytes, digits, file->height); in calc_image_size()
1520 assert(file->image_digits >= 1 && file->image_digits <= 5); in calc_image_size()
1524 /* PER-CHUNK CONTROL STRUCTURE
1535 /* PUBLIC IDAT INFORMATION: SET BY THE ZLIB CODE */
1541 /* PUBLIC PER-CHUNK INFORMATION: USED BY CHUNK READ CODE */
1549 /* PUBLIC PER-CHUNK INFORMATION: FOR THE CHUNK WRITE CODE */
1559 type_message(chunk->file, chunk->chunk_type, message); in chunk_message()
1580 assert(file->chunk == NULL); in chunk_init()
1584 chunk->file = file; in chunk_init()
1585 chunk->global = file->global; in chunk_init()
1587 chunk->chunk_data_pos = file->data_pos; in chunk_init()
1588 chunk->chunk_length = file->length; in chunk_init()
1589 chunk->chunk_type = file->type; in chunk_init()
1591 /* Compressed/uncompressed size information (from the zlib control structure in chunk_init()
1594 chunk->uncompressed_digits = 0; in chunk_init()
1595 chunk->compressed_digits = 0; in chunk_init()
1597 file->chunk = chunk; in chunk_init()
1605 * includes any inter-chunk consistency check that libpng performs. Assume in current_type()
1609 if (file->chunk != NULL) in current_type()
1611 png_uint_32 type = file->chunk->chunk_type; in current_type()
1618 file->write_count == 8) in current_type()
1625 return file->type; in current_type()
1630 /* Reset the position to 'chunk_data_pos' - the start of the data for this in setpos()
1635 chunk->file->read_count = 8; in setpos()
1636 file_setpos(chunk->file, &chunk->chunk_data_pos); in setpos()
1639 /* Specific chunk handling - called for each chunk header, all special chunk
1642 /* The next functions handle special processing for those chunks with LZ data,
1645 * modification to the zlib header may be required.)
1647 * The compressed data is in zlib format (RFC1950) and consequently has a
1654 /* zTXt and iCCP have exactly the same form - keyword, null, compression in process_zTXt_iCCP()
1658 struct chunk *chunk = file->chunk; in process_zTXt_iCCP()
1662 assert(chunk != NULL && file->idat == NULL); in process_zTXt_iCCP()
1663 length = chunk->chunk_length; in process_zTXt_iCCP()
1668 --length; in process_zTXt_iCCP()
1672 --length; in process_zTXt_iCCP()
1687 struct chunk *chunk = file->chunk; in process_iTXt()
1691 assert(chunk != NULL && file->idat == NULL); in process_iTXt()
1692 length = chunk->chunk_length; in process_iTXt()
1697 --length; in process_iTXt()
1701 --length; in process_iTXt()
1706 --length; in process_iTXt()
1713 --length; in process_iTXt()
1720 --length; in process_iTXt()
1764 struct file *file = idat->file; in IDAT_end()
1770 assert(file->chunk != NULL); in IDAT_end()
1771 chunk_end(&file->chunk); in IDAT_end()
1777 file->state = STATE_CHUNKS; in IDAT_end()
1789 assert(file->chunk == NULL); in IDAT_init()
1790 assert(file->idat == NULL); in IDAT_init()
1794 idat->file = file; in IDAT_init()
1795 idat->global = file->global; in IDAT_init()
1797 /* Initialize the tail to the pre-allocated buffer and set the count to 0 in IDAT_init()
1800 idat->global->idat_cache.count = 0; in IDAT_init()
1801 idat->idat_list_head = idat->idat_list_tail = &idat->global->idat_cache; in IDAT_init()
1804 * stores the result in file->chunk: in IDAT_init()
1806 file->alloc(file, 0/*chunk*/); in IDAT_init()
1807 assert(file->chunk != NULL); in IDAT_init()
1812 file->idat = idat; in IDAT_init()
1821 png_uint_32 len = idat->global->idat_max; in rechunk_length()
1829 return idat->idat_length; /* use the cache */ in rechunk_length()
1834 cur = idat->idat_cur; in rechunk_length()
1835 count = idat->idat_count; in rechunk_length()
1837 assert(idat->idat_index == idat->idat_length && in rechunk_length()
1838 idat->idat_length == cur->lengths[count]); in rechunk_length()
1841 if (++count < cur->count) in rechunk_length()
1842 return cur->lengths[count]; in rechunk_length()
1845 assert(cur != idat->idat_list_tail); in rechunk_length()
1846 cur = cur->next; in rechunk_length()
1847 assert(cur != NULL && cur->count > 0); in rechunk_length()
1848 return cur->lengths[0]; in rechunk_length()
1853 /* The chunk size is the lesser of file->idat_max and the number in rechunk_length()
1856 png_uint_32 have = idat->idat_length - idat->idat_index; in rechunk_length()
1860 struct IDAT_list *cur = idat->idat_cur; in rechunk_length()
1861 unsigned int j = idat->idat_count+1; /* the next IDAT in the list */ in rechunk_length()
1874 for (; j < cur->count; ++j) in rechunk_length()
1876 have += cur->lengths[j]; in rechunk_length()
1882 if (cur == idat->idat_list_tail) in rechunk_length()
1885 cur = cur->next; in rechunk_length()
1901 * function does is establish whether the zlib header needs to be modified. in process_IDAT()
1905 * checks the zlib data and returns true. in process_IDAT()
1916 assert(file->idat != NULL && file->chunk != NULL); in process_IDAT()
1927 list = file->idat->idat_list_tail; in process_IDAT()
1929 if (list->count == list->length) in process_IDAT()
1937 list->count = 0; in process_IDAT()
1938 file->idat->idat_list_tail = list; in process_IDAT()
1942 list->lengths[(list->count)++] = file->chunk->chunk_length; in process_IDAT()
1947 if (file->type == png_IDAT) in process_IDAT()
1955 setpos(file->chunk); in process_IDAT()
1965 cmp = uarb_cmp(file->image_bytes, file->image_digits, in process_IDAT()
1966 file->chunk->uncompressed_bytes, file->chunk->uncompressed_digits); in process_IDAT()
1978 setpos(file->chunk); in process_IDAT()
1980 idat = file->idat; in process_IDAT()
1981 idat->idat_cur = idat->idat_list_head; in process_IDAT()
1982 idat->idat_length = idat->idat_cur->lengths[0]; in process_IDAT()
1983 idat->idat_count = 0; /* Count of chunks read in current list */ in process_IDAT()
1984 idat->idat_index = 0; /* Index into chunk data */ in process_IDAT()
1987 file->chunk->chunk_length = rechunk_length(idat, 1/*start*/); in process_IDAT()
1990 file->state = STATE_IDAT; in process_IDAT()
1999 /* ZLIB CONTROL STRUCTURE */
2000 struct zlib struct
2008 /* GLOBAL ZLIB INFORMATION: SET BY THE CALLER */
2011 /* GLOBAL ZLIB INFORMATION: SET BY THE ZLIB READ CODE */
2020 /* PROTECTED ZLIB INFORMATION: USED BY THE ZLIB ROUTINES */
2030 zlib_flevel(struct zlib *zlib) in zlib_flevel() argument
2032 switch (zlib->header[1] >> 6) in zlib_flevel()
2045 zlib_rc(struct zlib *zlib) in zlib_rc() argument
2046 /* Return a string for the zlib return code */ in zlib_rc()
2048 switch (zlib->rc) in zlib_rc()
2064 zlib_message(struct zlib *zlib, int unexpected) in zlib_message() argument
2065 /* Output a message given a zlib rc */ in zlib_message()
2067 if (zlib->global->errors) in zlib_message()
2069 const char *reason = zlib->z.msg; in zlib_message()
2074 fputs(zlib->file->file_name, stderr); in zlib_message()
2076 type_name(zlib->chunk->chunk_type, stderr); in zlib_message()
2078 unexpected ? "unexpected " : "", zlib->rc, zlib_rc(zlib), reason); in zlib_message()
2083 zlib_end(struct zlib *zlib) in zlib_end() argument
2088 if (!zlib->global->quiet) in zlib_end()
2090 if (zlib->ok_bits < 16) /* stream was read ok */ in zlib_end()
2094 if (zlib->cksum) in zlib_end()
2097 else if (zlib->ok_bits > zlib->file_bits) in zlib_end()
2098 reason = "TFB"; /* fixing a too-far-back error */ in zlib_end()
2100 else if (zlib->ok_bits == zlib->file_bits) in zlib_end()
2106 /* SUMMARY FORMAT (for a successful zlib inflate): in zlib_end()
2108 * IDAT reason flevel file-bits ok-bits compressed uncompressed file in zlib_end()
2110 type_name(zlib->chunk->chunk_type, stdout); in zlib_end()
2111 printf(" %s %s %d %d ", reason, zlib_flevel(zlib), zlib->file_bits, in zlib_end()
2112 zlib->ok_bits); in zlib_end()
2113 uarb_print(zlib->compressed_bytes, zlib->compressed_digits, stdout); in zlib_end()
2115 uarb_print(zlib->uncompressed_bytes, zlib->uncompressed_digits, in zlib_end()
2118 fputs(zlib->file->file_name, stdout); in zlib_end()
2124 /* This is a zlib read error; the chunk will be skipped. For an IDAT in zlib_end()
2129 * IDAT SKP flevel file-bits z-rc compressed message file in zlib_end()
2131 * z-rc is the zlib failure code; message is the error message with in zlib_end()
2132 * spaces replaced by '-'. The compressed byte count indicates where in zlib_end()
2133 * in the zlib stream the error occurred. in zlib_end()
2135 type_name(zlib->chunk->chunk_type, stdout); in zlib_end()
2136 printf(" SKP %s %d %s ", zlib_flevel(zlib), zlib->file_bits, in zlib_end()
2137 zlib_rc(zlib)); in zlib_end()
2138 uarb_print(zlib->compressed_bytes, zlib->compressed_digits, stdout); in zlib_end()
2140 emit_string(zlib->z.msg ? zlib->z.msg : "[no_message]", stdout); in zlib_end()
2142 fputs(zlib->file->file_name, stdout); in zlib_end()
2147 if (zlib->state >= 0) in zlib_end()
2149 zlib->rc = inflateEnd(&zlib->z); in zlib_end()
2151 if (zlib->rc != Z_OK) in zlib_end()
2152 zlib_message(zlib, 1/*unexpected*/); in zlib_end()
2155 CLEAR(*zlib); in zlib_end()
2159 zlib_reset(struct zlib *zlib, int window_bits) in zlib_reset() argument
2160 /* Reinitializes a zlib with a different window_bits */ in zlib_reset()
2162 assert(zlib->state >= 0); /* initialized by zlib_init */ in zlib_reset()
2164 zlib->z.next_in = Z_NULL; in zlib_reset()
2165 zlib->z.avail_in = 0; in zlib_reset()
2166 zlib->z.next_out = Z_NULL; in zlib_reset()
2167 zlib->z.avail_out = 0; in zlib_reset()
2169 zlib->window_bits = window_bits; in zlib_reset()
2170 zlib->compressed_digits = 0; in zlib_reset()
2171 zlib->uncompressed_digits = 0; in zlib_reset()
2173 zlib->state = 0; /* initialized, once */ in zlib_reset()
2174 zlib->rc = inflateReset2(&zlib->z, 0); in zlib_reset()
2175 if (zlib->rc != Z_OK) in zlib_reset()
2177 zlib_message(zlib, 1/*unexpected*/); in zlib_reset()
2185 zlib_init(struct zlib *zlib, struct IDAT *idat, struct chunk *chunk, in zlib_init() argument
2189 CLEAR(*zlib); in zlib_init()
2191 zlib->idat = idat; in zlib_init()
2192 zlib->chunk = chunk; in zlib_init()
2193 zlib->file = chunk->file; in zlib_init()
2194 zlib->global = chunk->global; in zlib_init()
2195 zlib->rewrite_offset = offset; /* never changed for this zlib */ in zlib_init()
2198 zlib->z.next_in = Z_NULL; in zlib_init()
2199 zlib->z.avail_in = 0; in zlib_init()
2200 zlib->z.zalloc = Z_NULL; in zlib_init()
2201 zlib->z.zfree = Z_NULL; in zlib_init()
2202 zlib->z.opaque = Z_NULL; in zlib_init()
2204 zlib->state = -1; in zlib_init()
2205 zlib->window_bits = window_bits; in zlib_init()
2207 zlib->compressed_digits = 0; in zlib_init()
2208 zlib->uncompressed_digits = 0; in zlib_init()
2213 zlib->file_bits = 24; in zlib_init()
2214 zlib->ok_bits = 16; /* unset */ in zlib_init()
2215 zlib->cksum = 0; /* set when a checksum error is detected */ in zlib_init()
2220 zlib->rc = inflateInit2(&zlib->z, 0); in zlib_init()
2221 if (zlib->rc != Z_OK) in zlib_init()
2223 zlib_message(zlib, 1/*unexpected*/); in zlib_init()
2229 zlib->state = 0; /* initialized */ in zlib_init()
2236 /* Return the zlib stream window bits required for data of the given size. */ in max_window_bits()
2256 zlib_advance(struct zlib *zlib, png_uint_32 nbytes) in zlib_advance() argument
2261 * -1: saw the "too far back" error in zlib_advance()
2263 * 1: saw Z_STREAM_END (zlib->extra_bytes indicates too much data) in zlib_advance()
2264 * 2: a zlib error that cannot be corrected (error message already in zlib_advance()
2267 # define ZLIB_TOO_FAR_BACK (-1) in zlib_advance()
2272 int state = zlib->state; in zlib_advance()
2275 struct file *file = zlib->file; in zlib_advance()
2291 int new_bits = zlib->window_bits; in zlib_advance()
2293 zlib->file_bits = file_bits; in zlib_advance()
2295 /* Check against the existing value - it may not need to be in zlib_advance()
2301 zlib->window_bits = ((file_bits > 15) ? 15 : file_bits); in zlib_advance()
2304 bIn = (png_byte)((bIn & 0xf) + ((new_bits-8) << 4)); in zlib_advance()
2307 zlib->header[0] = bIn; in zlib_advance()
2308 zlib->state = state = 1; in zlib_advance()
2316 b2 += 0x1f - ((zlib->header[0] << 8) + b2) % 0x1f; in zlib_advance()
2324 if (zlib->file_bits == zlib->window_bits) in zlib_advance()
2325 zlib->cksum = 1; in zlib_advance()
2331 zlib->header[1] = bIn; in zlib_advance()
2332 zlib->state = state = 2; in zlib_advance()
2339 /* For some streams, perhaps only those compressed with 'superfast in zlib_advance()
2345 zlib->z.next_in = &bIn; in zlib_advance()
2346 zlib->z.avail_in = 1; in zlib_advance()
2347 zlib->z.next_out = &bOut; in zlib_advance()
2348 zlib->z.avail_out = 0; /* Initially */ in zlib_advance()
2350 /* Initially use Z_NO_FLUSH in an attempt to persuade zlib to look at this in zlib_advance()
2351 * byte without confusing what is going on with output. in zlib_advance()
2361 zlib->z.next_out = &bOut, in zlib_advance()
2362 zlib->z.avail_out = 1, in zlib_advance()
2365 zlib->rc = inflate(&zlib->z, flush); in zlib_advance()
2366 out_bytes -= zlib->z.avail_out; in zlib_advance()
2368 switch (zlib->rc) in zlib_advance()
2371 if (zlib->z.avail_out == 0) in zlib_advance()
2374 if (zlib->z.avail_in == 0) in zlib_advance()
2377 /* Both avail_out and avail_in are 1 yet zlib returned a code in zlib_advance()
2380 zlib_message(zlib, 1/*unexpected*/); in zlib_advance()
2385 /* Zlib is supposed to have made progress: */ in zlib_advance()
2386 assert(zlib->z.avail_out == 0 || zlib->z.avail_in == 0); in zlib_advance()
2391 zlib->state = 3; /* end of stream */ in zlib_advance()
2396 zlib_message(zlib, 0/*stream error*/); in zlib_advance()
2402 if (zlib->z.msg != NULL && in zlib_advance()
2403 strcmp(zlib->z.msg, "invalid distance too far back") == 0) in zlib_advance()
2411 zlib_message(zlib, 0/*stream error*/); in zlib_advance()
2423 zlib->uncompressed_digits = uarb_add32(zlib->uncompressed_bytes, in zlib_advance()
2424 zlib->uncompressed_digits, out_bytes); in zlib_advance()
2430 assert(zlib->z.avail_in == 0 || endrc != ZLIB_OK); in zlib_advance()
2432 in_bytes += 1 - zlib->z.avail_in; in zlib_advance()
2438 zlib->compressed_digits = uarb_add32(zlib->compressed_bytes, in zlib_advance()
2439 zlib->compressed_digits, in_bytes - zlib->z.avail_in); in zlib_advance()
2441 /* At the end of the stream update the chunk with the accumulated in zlib_advance()
2444 if (endrc == ZLIB_STREAM_END && zlib->window_bits < zlib->ok_bits) in zlib_advance()
2446 struct chunk *chunk = zlib->chunk; in zlib_advance()
2448 chunk->uncompressed_digits = uarb_copy(chunk->uncompressed_bytes, in zlib_advance()
2449 zlib->uncompressed_bytes, zlib->uncompressed_digits); in zlib_advance()
2450 chunk->compressed_digits = uarb_copy(chunk->compressed_bytes, in zlib_advance()
2451 zlib->compressed_bytes, zlib->compressed_digits); in zlib_advance()
2452 chunk->rewrite_buffer[0] = zlib->header[0]; in zlib_advance()
2453 chunk->rewrite_buffer[1] = zlib->header[1]; in zlib_advance()
2455 if (zlib->window_bits != zlib->file_bits || zlib->cksum) in zlib_advance()
2458 chunk->rewrite_offset = zlib->rewrite_offset; in zlib_advance()
2459 chunk->rewrite_length = 2; in zlib_advance()
2464 chunk->rewrite_offset = 0; in zlib_advance()
2465 chunk->rewrite_length = 0; in zlib_advance()
2471 zlib->extra_bytes = nbytes - in_bytes; in zlib_advance()
2472 zlib->ok_bits = zlib->window_bits; in zlib_advance()
2479 zlib_run(struct zlib *zlib) in zlib_run() argument
2489 zlib->extra_bytes = 0; in zlib_run()
2491 if (zlib->idat != NULL) in zlib_run()
2493 struct IDAT_list *list = zlib->idat->idat_list_head; in zlib_run()
2494 struct IDAT_list *last = zlib->idat->idat_list_tail; in zlib_run()
2500 assert(zlib->rewrite_offset == 0); in zlib_run()
2507 unsigned int count = list->count; in zlib_run()
2515 skip_12(zlib->file); in zlib_run()
2519 rc = zlib_advance(zlib, list->lengths[i]); in zlib_run()
2531 if (zlib->global->errors && zlib->extra_bytes == 0) in zlib_run()
2539 if (check->lengths[j] > 0) in zlib_run()
2541 chunk_message(zlib->chunk, in zlib_run()
2549 check = check->next; in zlib_run()
2550 jcount = check->count; in zlib_run()
2559 list->lengths[i] -= zlib->extra_bytes; in zlib_run()
2560 list->count = i+1; in zlib_run()
2561 zlib->idat->idat_list_tail = list; in zlib_run()
2573 list = list->next; in zlib_run()
2579 struct chunk *chunk = zlib->chunk; in zlib_run()
2582 assert(zlib->rewrite_offset < chunk->chunk_length); in zlib_run()
2584 rc = zlib_advance(zlib, chunk->chunk_length - zlib->rewrite_offset); in zlib_run()
2587 * length to exclude them; the zlib data is always stored at the end of in zlib_run()
2591 chunk->chunk_length -= zlib->extra_bytes; in zlib_run()
2598 /* Check the stream of zlib compressed data in either idat (if given) or (if in zlib_check()
2602 * In either case the input file must be positioned at the first byte of zlib in zlib_check()
2605 * The return value is true on success, including the case where the zlib in zlib_check()
2612 struct zlib zlib; in zlib_check() local
2614 /* Record the start of the LZ data to allow a re-read. */ in zlib_check()
2618 if (zlib_init(&zlib, file->idat, file->chunk, 0/*window bits*/, offset)) in zlib_check()
2623 rc = zlib_run(&zlib); in zlib_check()
2629 file->status_code |= TOO_FAR_BACK; in zlib_check()
2630 min_bits = zlib.window_bits + 1; in zlib_check()
2635 if (!zlib.global->optimize_zlib && in zlib_check()
2636 zlib.window_bits == zlib.file_bits && !zlib.cksum) in zlib_check()
2641 zlib_end(&zlib); in zlib_check()
2645 max_bits = max_window_bits(zlib.uncompressed_bytes, in zlib_check()
2646 zlib.uncompressed_digits); in zlib_check()
2647 if (zlib.ok_bits < max_bits) in zlib_check()
2648 max_bits = zlib.ok_bits; in zlib_check()
2651 /* cksum is set if there is an error in the zlib header checksum in zlib_check()
2656 if (zlib.cksum) in zlib_check()
2657 chunk_message(zlib.chunk, "zlib checksum"); in zlib_check()
2663 zlib.z.msg = PNGZ_MSG_CAST("[truncated]"); in zlib_check()
2664 zlib_message(&zlib, 0/*expected*/); in zlib_check()
2671 zlib_end(&zlib); in zlib_check()
2675 /* Optimize window bits or fix a too-far-back error. min_bits and in zlib_check()
2679 while (min_bits < max_bits || max_bits < zlib.ok_bits/*if 16*/) in zlib_check()
2683 if (zlib_reset(&zlib, test_bits)) in zlib_check()
2686 rc = zlib_run(&zlib); in zlib_check()
2701 if (zlib.z.msg == NULL) in zlib_check()
2702 zlib.z.msg = PNGZ_MSG_CAST( in zlib_check()
2704 zlib_message(&zlib, 0/*stream error*/); in zlib_check()
2705 zlib_end(&zlib); in zlib_check()
2715 /* A fatal error; this happens if a too-far-back error was in zlib_check()
2719 zlib_end(&zlib); in zlib_check()
2726 zlib_end(&zlib); in zlib_check()
2732 assert(zlib.ok_bits == max_bits); in zlib_check()
2733 zlib_end(&zlib); in zlib_check()
2737 else /* zlib initialization failed - skip the chunk */ in zlib_check()
2739 zlib_end(&zlib); in zlib_check()
2754 * which is pretty much everything except the 'zlib' control structure.
2756 * The file structure is instantiated in the caller of the per-file routine, but
2757 * the per-file routine contains the chunk and IDAT control structures.
2766 * -> sync_stream
2767 * -> process_chunk
2768 * -> process_chunk
2769 * -> read_chunk
2784 png_uint_32 type = file->type; in process_chunk()
2786 if (file->global->verbose > 1) in process_chunk()
2789 type_name(file->type, stderr); in process_chunk()
2790 fprintf(stderr, " %lu 0x%.8x 0x%.8x\n", (unsigned long)file->length, in process_chunk()
2791 file->crc ^ 0xffffffff, file_crc); in process_chunk()
2798 if ((file->crc ^ 0xffffffff) != file_crc) in process_chunk()
2801 * than SKIP_BAD_CRC ignore the bad CRC and return the chunk, with a in process_chunk()
2805 file->status_code |= CRC_ERROR; in process_chunk()
2808 if (file->global->skip != SKIP_BAD_CRC) in process_chunk()
2811 /* This will cause an IEND with a bad CRC to stop */ in process_chunk()
2828 if (skip_chunk_type(file->global, type)) in process_chunk()
2837 file->alloc(file, 0/*chunk*/); in process_chunk()
2839 else if (file->idat == NULL) in process_chunk()
2840 file->alloc(file, 1/*IDAT*/); in process_chunk()
2845 assert(file->chunk != NULL); in process_chunk()
2846 assert(file->chunk->chunk_type == png_IDAT); in process_chunk()
2847 file->chunk->chunk_length = file->length; in process_chunk()
2852 * copy of the position of the first chunk, this is fine - process_IDAT does in process_chunk()
2855 file->length = next_length; in process_chunk()
2856 file->type = next_type; in process_chunk()
2859 /* Do per-type processing, note that if this code does not return from the in process_chunk()
2861 * it can be set in the per-chunk processing. in process_chunk()
2863 file->chunk->rewrite_length = 0; in process_chunk()
2864 file->chunk->rewrite_offset = 0; in process_chunk()
2871 /* Read this now and update the control structure with the information in process_chunk()
2876 struct chunk *chunk = file->chunk; in process_chunk()
2878 if (chunk->chunk_length != 13) in process_chunk()
2883 file->width = reread_4(file); in process_chunk()
2884 file->height = reread_4(file); in process_chunk()
2885 file->bit_depth = reread_byte(file); in process_chunk()
2886 file->color_type = reread_byte(file); in process_chunk()
2887 file->compression_method = reread_byte(file); in process_chunk()
2888 file->filter_method = reread_byte(file); in process_chunk()
2889 file->interlace_method = reread_byte(file); in process_chunk()
2902 chunk_end(&file->chunk); in process_chunk()
2903 file_setpos(file, &file->data_pos); in process_chunk()
2909 chunk_end(&file->chunk); in process_chunk()
2910 file_setpos(file, &file->data_pos); in process_chunk()
2922 * than IDAT this means that the zlib compressed data is fatally damaged and in process_chunk()
2935 file->length = next_length; in process_chunk()
2936 file->type = next_type; in process_chunk()
2943 /* Read a 32-bit value from an 8-byte circular buffer (used only below). in get32()
2961 file->status_code |= STREAM_ERROR; in sync_stream()
2963 if (file->global->verbose) in sync_stream()
2966 type_name(file->type, stderr); in sync_stream()
2971 file_setpos(file, &file->data_pos); in sync_stream()
2972 file->read_count = 8; in sync_stream()
2979 * length, chunk-type pair. in sync_stream()
2982 png_uint_32 type = file->type; in sync_stream()
2998 file->length = length; in sync_stream()
3015 nread -= nused & ~7; in sync_stream()
3016 nused -= nused & ~7; /* or, nused &= 7 ;-) */ in sync_stream()
3028 file->read_count -= 8; in sync_stream()
3039 /* This catches up with the circular buffer which gets filled above in sync_stream()
3040 * while checking a chunk header. This code is slightly tricky - if in sync_stream()
3086 png_uint_32 length = file->length; in read_chunk()
3087 png_uint_32 type = file->type; in read_chunk()
3095 if (file->global->verbose > 2) in read_chunk()
3102 /* Start the read_crc calculation with the chunk type, then read to the end in read_chunk()
3106 file->crc = crc_init_4(type); in read_chunk()
3130 file->read_count -= 8; in read_chunk()
3169 if (file->global->warnings) in warning_handler()
3173 /* Read callback - this is where the work gets done to check the stream before
3188 /* The callback always reads ahead by 8 bytes - the signature or chunk header in read_callback()
3189 * - these bytes are stored in chunk_length and chunk_type. This block is in read_callback()
3193 if (file->read_count < 8) in read_callback()
3195 assert(file->read_count == 0); in read_callback()
3196 assert((file->status_code & TRUNCATED) == 0); in read_callback()
3198 (void)read_4(file, &file->length); in read_callback()
3200 if (file->read_count == 4) in read_callback()
3201 (void)read_4(file, &file->type); in read_callback()
3203 if (file->read_count < 8) in read_callback()
3205 assert((file->status_code & TRUNCATED) != 0); in read_callback()
3209 if (file->state == STATE_SIGNATURE) in read_callback()
3211 if (file->length != sig1 || file->type != sig2) in read_callback()
3217 file->write_count = 0; in read_callback()
3222 assert(file->state == STATE_CHUNKS); in read_callback()
3227 if (file->length != 13 || file->type != png_IHDR) in read_callback()
3236 * byte-by-byte in the sequential reader prior to 1.7). in read_callback()
3238 chunk = file->chunk; in read_callback()
3242 length = chunk->chunk_length; in read_callback()
3243 type = chunk->chunk_type; in read_callback()
3251 length = file->length; in read_callback()
3252 type = file->type; in read_callback()
3269 if (file->state != STATE_SIGNATURE && chunk == NULL) in read_callback()
3271 assert(file->read_count == 8); in read_callback()
3272 assert(file->idat == NULL); in read_callback()
3274 chunk = file->chunk; in read_callback()
3278 length = chunk->chunk_length; in read_callback()
3279 type = chunk->chunk_type; in read_callback()
3282 file->write_count = 0; in read_callback()
3289 switch (file->write_count) in read_callback()
3306 if (file->state == STATE_SIGNATURE) in read_callback()
3309 * below (it's just a goto to the start with a decent compiler) in read_callback()
3313 file->read_count = 0; /* Forces a header read */ in read_callback()
3314 file->state = STATE_CHUNKS; /* IHDR: checked above */ in read_callback()
3325 * notice that for the IDAT stream this must only happen once - in read_callback()
3326 * on the first IDAT - to get back to the start of the list and in read_callback()
3329 chunk->write_crc = crc_init_4(type); in read_callback()
3330 if (file->state != STATE_IDAT && length > 0) in read_callback()
3341 switch (file->write_count - length) in read_callback()
3345 * chunk which is zlib data and which must be rewritten, in read_callback()
3350 if (file->state == STATE_IDAT) in read_callback()
3352 struct IDAT *idat = file->idat; in read_callback()
3357 * Because the IDAT stream can be re-chunked this stream is in read_callback()
3362 while (idat->idat_index >= idat->idat_length) in read_callback()
3365 struct IDAT_list *cur = idat->idat_cur; in read_callback()
3367 assert(idat->idat_index == idat->idat_length); in read_callback()
3368 assert(cur != NULL && cur->count > 0); in read_callback()
3371 if (++(idat->idat_count) >= cur->count) in read_callback()
3373 assert(idat->idat_count == cur->count); in read_callback()
3376 cur = cur->next; in read_callback()
3378 /* This is an internal error - read beyond the end of in read_callback()
3379 * the pre-calculated stream. in read_callback()
3381 if (cur == NULL || cur->count == 0) in read_callback()
3385 idat->idat_count = 0; in read_callback()
3386 idat->idat_cur = cur; in read_callback()
3389 idat->idat_index = 0; in read_callback()
3393 idat->idat_length = cur->lengths[idat->idat_count]; in read_callback()
3403 ++(idat->idat_index); in read_callback()
3410 if (chunk->rewrite_length > 0) in read_callback()
3412 if (chunk->rewrite_offset > 0) in read_callback()
3413 --(chunk->rewrite_offset); in read_callback()
3417 b = chunk->rewrite_buffer[0]; in read_callback()
3418 memmove(chunk->rewrite_buffer, chunk->rewrite_buffer+1, in read_callback()
3419 (sizeof chunk->rewrite_buffer)- in read_callback()
3420 (sizeof chunk->rewrite_buffer[0])); in read_callback()
3422 --(chunk->rewrite_length); in read_callback()
3426 chunk->write_crc = crc_one_byte(chunk->write_crc, b); in read_callback()
3435 case 8: b = chunk->write_crc >> 24; goto write_crc; in read_callback()
3436 case 9: b = chunk->write_crc >> 16; goto write_crc; in read_callback()
3437 case 10: b = chunk->write_crc >> 8; goto write_crc; in read_callback()
3440 b = chunk->write_crc; in read_callback()
3442 if (file->global->verbose > 2) in read_callback()
3447 chunk->write_crc ^ 0xffffffff); in read_callback()
3453 * the end of an *output* chunk - the length calculated by in read_callback()
3457 if (file->state == STATE_IDAT && in read_callback()
3458 (file->idat->idat_index < file->idat->idat_length || in read_callback()
3459 1+file->idat->idat_count < file->idat->idat_cur->count || in read_callback()
3460 file->idat->idat_cur != file->idat->idat_list_tail)) in read_callback()
3465 length = chunk->chunk_length = in read_callback()
3466 rechunk_length(file->idat, 0/*end*/); in read_callback()
3468 file->write_count = 0; /* for the new chunk */ in read_callback()
3469 --(file->write_count); /* fake out the increment below */ in read_callback()
3474 /* Entered at the end of a non-IDAT chunk and at the end of in read_callback()
3477 if (chunk->rewrite_length > 0 || chunk->rewrite_offset > 0) in read_callback()
3484 file->read_count = 8; in read_callback()
3485 file_setpos(file, &file->data_pos); in read_callback()
3487 if (file->idat == NULL) in read_callback()
3488 chunk_end(&file->chunk); in read_callback()
3491 IDAT_end(&file->idat); in read_callback()
3504 --count; in read_callback()
3523 return file_end(&control->file); in control_end()
3534 return &control->file; in get_control()
3540 struct control *control = voidcast(struct control*, file->alloc_ptr); in allocate()
3544 assert(file->idat == NULL); in allocate()
3545 IDAT_init(&control->idat, file); in allocate()
3550 assert(file->chunk == NULL); in allocate()
3551 chunk_init(&control->chunk, file); in allocate()
3562 return file_init(&control->file, global, file_name, out_name, control, in control_init()
3582 log_error(&control->file, LIBPNG_ERROR_CODE, "OOM allocating png_struct"); in read_png()
3583 control->file.status_code |= INTERNAL_ERROR; in read_png()
3587 rc = setjmp(control->file.jmpbuf); in read_png()
3592 * without this we may reject files based on built-in safety in read_png()
3606 if (control->file.global->verbose) in read_png()
3625 while (y-- > 0) in read_png()
3630 if (control->file.global->verbose) in read_png()
3647 if (global->verbose) in one_file()
3648 fprintf(stderr, "FILE %s -> %s\n", file_name, in one_file()
3667 /* ANSI C-90 limits strings to 509 characters, so use a string array: */ in usage()
3670 " Tests, optimizes and optionally fixes the zlib header in PNG files.", in usage()
3675 " By default files are just checked for readability with a summary of the", in usage()
3676 " of zlib issues founds for each compressed chunk and the IDAT stream in", in usage()
3678 " --optimize (-o):", in usage()
3680 " --strip=[none|crc|unsafe|unused|transform|color|all]:", in usage()
3682 " crc: Remove chunks with a bad CRC.", in usage()
3684 " is modified. This is set automatically if --max is given but", in usage()
3685 " may be cancelled by a later --strip=none.", in usage()
3702 " --max=<number>:", in usage()
3704 " chunks will be the maximum size permitted; 2^31-1 bytes. If the option", in usage()
3706 " option is given --strip=unsafe is set automatically. This may be", in usage()
3707 " cancelled if you know that all unknown unsafe-to-copy chunks really are", in usage()
3712 " --quiet (-q):", in usage()
3713 " Do not output the summaries except for files that cannot be read. With", in usage()
3714 " two --quiets these are not output either.", in usage()
3715 " --errors (-e):", in usage()
3716 " Output errors from libpng and the program (except too-far-back).", in usage()
3717 " --warnings (-w):", in usage()
3721 " --out=<file>:", in usage()
3724 " --suffix=<suffix>:", in usage()
3725 " Set --out=<name><suffix> for all following files unless overridden on", in usage()
3726 " a per-file basis by explicit --out.", in usage()
3727 " --prefix=<prefix>:", in usage()
3728 " Set --out=<prefix><name> for all the following files unless overridden", in usage()
3729 " on a per-file basis by explicit --out.", in usage()
3734 " --test:", in usage()
3744 " together - check one file at a time to get a meaningful error code!", in usage()
3745 " 0x01: The zlib too-far-back error existed in at least one chunk.", in usage()
3750 " exit code is less than 16 the file could be read (with corrections if a", in usage()
3751 " non-zero code is returned).", in usage()
3752 " 0x10: The file could not be read, even with corrections.", in usage()
3755 " If the command line arguments are incorrect the program exits with exit", in usage()
3756 " 255. Some older operating systems only support 7-bit exit codes, on those", in usage()
3764 " With the --quiet (-q) option the summaries are suppressed too and the", in usage()
3768 " The exit code says what problems were fixed. In particular the zlib error:", in usage()
3772 " caused by an incorrect optimization of a zlib stream is fixed in any", in usage()
3780 " Notice that some PNG files with the zlib optimization problem can still be", in usage()
3788 " The summary lines describe issues encountered with the zlib compressed", in usage()
3792 " chunk reason comp-level p1 p2 p3 p4 file", in usage()
3797 " chunk ERR status code read-errno write-errno message file", in usage()
3798 " chunk SKP comp-level file-bits zlib-rc compressed message file", in usage()
3799 " chunk ??? comp-level file-bits ok-bits compressed uncompress file", in usage()
3806 " CHK: A zlib header checksum was detected and fixed.", in usage()
3807 " TFB: The zlib too far back error was detected and fixed.", in usage()
3808 " OK : No errors were detected in the zlib stream and optimization", in usage()
3810 " OPT: The zlib stream window bits value could be improved (and was).", in usage()
3811 " SKP: The chunk was skipped because of a zlib issue (zlib-rc) with", in usage()
3816 " comp-level: The recorded compression level (FLEVEL) of a zlib stream", in usage()
3819 " string {warning,libpng,zlib,invalid,read,write,unexpected}.", in usage()
3820 " file-bits: The zlib window bits recorded in the file.", in usage()
3821 "$5 read-errno: A system errno value from a read translated by strerror(3).", in usage()
3822 " zlib-rc: A zlib return code as a string (see zlib.h).", in usage()
3823 " ok-bits: The smallest zlib window bits value that works.", in usage()
3824 "$6 write-errno:A system errno value from a write translated by strerror(3).", in usage()
3825 " compressed: The count of compressed bytes in the zlib stream, when the", in usage()
3829 " uncompress: The count of bytes from uncompressing the zlib stream; this", in usage()
3834 fprintf(stderr, "Usage: %s {[options] png-file}\n", prog); in usage()
3860 while (--argc > 0) in main()
3864 if (strcmp(*argv, "--debug") == 0) in main()
3872 else if (strncmp(*argv, "--max=", 6) == 0) in main()
3880 else if (strcmp(*argv, "--max") == 0) in main()
3888 else if (strcmp(*argv, "--optimize") == 0 || strcmp(*argv, "-o") == 0) in main()
3891 else if (strncmp(*argv, "--out=", 6) == 0) in main()
3894 else if (strncmp(*argv, "--suffix=", 9) == 0) in main()
3897 else if (strncmp(*argv, "--prefix=", 9) == 0) in main()
3900 else if (strcmp(*argv, "--strip=none") == 0) in main()
3903 else if (strcmp(*argv, "--strip=crc") == 0) in main()
3906 else if (strcmp(*argv, "--strip=unsafe") == 0) in main()
3909 else if (strcmp(*argv, "--strip=unused") == 0) in main()
3912 else if (strcmp(*argv, "--strip=transform") == 0) in main()
3915 else if (strcmp(*argv, "--strip=color") == 0) in main()
3918 else if (strcmp(*argv, "--strip=all") == 0) in main()
3921 else if (strcmp(*argv, "--errors") == 0 || strcmp(*argv, "-e") == 0) in main()
3924 else if (strcmp(*argv, "--warnings") == 0 || strcmp(*argv, "-w") == 0) in main()
3927 else if (strcmp(*argv, "--quiet") == 0 || strcmp(*argv, "-q") == 0) in main()
3936 else if (strcmp(*argv, "--verbose") == 0 || strcmp(*argv, "-v") == 0) in main()
3942 else if (strcmp(*argv, "--test") == 0) in main()
3947 else if ((*argv)[0] == '-') in main()
4024 "pngfix needs libpng with a zlib >=1.2.4 (not 0x%x)\n", in main()
4047 /* vi: set textwidth=80 shiftwidth=3 softtabstop=-1 expandtab: */