Home | History | Annotate | Download | only in tools

Lines Matching full:file

392 uarb_printx(uarb num, int digits, FILE *out)
409 uarb_print(uarb num, int digits, FILE *out)
687 unsigned int errors :1; /* print file errors to stderr */
708 # define FILE_ERROR 0x10 /* could not read the file */
713 struct IDAT_list idat_cache; /* Cache of file IDAT information buffers */
824 /* PER-FILE CONTROL STRUCTURE */
827 struct file
832 /* PUBLIC PER-FILE VARIABLES: CALLER INITIALIZE */
834 const char * out_name; /* Name of output file (if required) */
836 /* PUBLIC PER-FILE VARIABLES: SET BY PNG READ CODE */
837 /* File specific result codes */
854 /* PROTECTED PER-FILE VARIABLES: USED BY THE READ CODE */
855 FILE * file; /* Original PNG file */
856 FILE * out; /* If a new one is being written */
896 void (*alloc)(struct file*,int idat);
910 emit_string(const char *str, FILE *out)
943 emit_error(struct file *file, int code, const char *what)
958 err = file->read_errno;
961 err = file->write_errno;
964 err = file->read_errno;
966 err = file->write_errno;
972 fprintf(stderr, "%s: %s %s [%s]\n", file->file_name, reason, what,
976 fprintf(stderr, "%s: %s %s\n", file->file_name, reason, what);
983 file_end(struct file *file)
990 if (file->idat != NULL)
991 IDAT_end(&file->idat);
993 if (file->chunk != NULL)
994 chunk_end(&file->chunk);
996 rc = file->status_code;
998 if (file->file
999 (void)fclose(file->file);
1001 if (file->out != NULL)
1006 if (ferror(file->out) | fflush(file->out) | fclose(file->out))
1008 perror(file->out_name);
1009 emit_error(file, READ_ERROR_CODE, "output write error");
1015 file->global->status_code |= rc;
1017 CLEAR(*file);
1023 file_init(struct file *file, struct global *global, const char *file_name,
1024 const char *out_name, void *alloc_ptr, void (*alloc)(struct file*,int))
1025 /* Initialize a file control structure. This will open the given files as
1027 * above) on a file open error.
1030 CLEAR(*file);
1031 file->global = global;
1033 file->file_name = file_name;
1034 file->out_name = out_name;
1035 file->status_code = 0;
1036 file->read_errno = 0;
1037 file->write_errno = 0;
1039 file->file = NULL;
1040 file->out = NULL;
1043 file->read_count = 0;
1044 file->state = STATE_SIGNATURE;
1046 file->chunk = NULL;
1047 file->idat = NULL;
1049 file->alloc_ptr = alloc_ptr;
1050 file->alloc = alloc;
1054 file->file = fopen(file_name, "rb");
1056 if (file->file == NULL)
1058 file->read_errno = errno;
1059 file->status_code |= FILE_ERROR;
1060 /* Always output: please give a readable file! */
1067 file->out = fopen(out_name, "wb");
1069 if (file->out == NULL)
1071 file->write_errno = errno;
1072 file->status_code |= WRITE_ERROR;
1082 log_error(struct file *file, int code, const char *what)
1085 if (file->global->errors)
1086 emit_error(file, code, what);
1106 type_name(png_uint_32 type, FILE *out)
1115 type_sep(FILE *out)
1121 static png_uint_32 current_type(struct file *file, int code);
1124 stop(struct file *file, int code, const char *what)
1125 /* Return control when a PNG file cannot be read. This outputs an 'ERR'
1129 log_error(file, code, what);
1131 /* The chunk being read is typically identified by file->chunk or, if this is
1132 * NULL, by file->type. This may be wrong if libpng reads ahead, but this
1139 * IDAT ERR status code read-errno write-errno message file
1144 if (file->global->quiet < 2) /* need two quiets to stop this. */
1148 if (file->chunk != NULL)
1149 type = current_type(file, code); /* Gropes in struct chunk and IDAT */
1152 type = file->type;
1160 printf(" ERR %.2x %s ", file->status_code, strcode(code));
1164 emit_string(strerror(file->read_errno), stdout);
1166 emit_string(strerror(file->write_errno), stdout);
1170 fputs(file->file_name, stdout);
1174 file->status_code |= FILE_ERROR;
1175 longjmp(file->jmpbuf, code);
1179 stop_invalid(struct file *file, const char *what)
1181 stop(file, INVALID_ERROR_CODE, what);
1185 type_message(struct file *file, png_uint_32 type, const char *what)
1188 if (file->global->errors)
1190 fputs(file->file_name, stderr);
1199 /* Input file positioning - we jump around in the input file while reading
1203 file_getpos(struct file *file, fpos_t *pos)
1205 if (fgetpos(file->file, pos))
1208 perror(file->file_name);
1209 stop(file, READ_ERROR_CODE, "fgetpos");
1214 file_setpos(struct file *file, const fpos_t *pos)
1216 if (fsetpos(file->file, pos))
1218 perror(file->file_name);
1219 stop(file, READ_ERROR_CODE, "fsetpos");
1224 getpos(struct file *file)
1230 file_getpos(file, &file->data_pos);
1239 read_byte(struct file *file)
1241 int ch = getc(file->file);
1245 ++(file->read_count);
1251 file->status_code |= INTERNAL_ERROR;
1252 file->read_errno = ERANGE; /* out of range character */
1255 emit_error(file, UNEXPECTED_ERROR_CODE, "file read");
1262 return read_byte(file);
1271 if (ferror(file->file))
1272 file->read_errno = errno;
1274 else if (feof(file->file))
1275 file->read_errno = 0; /* I.e. a regular EOF, no error */
1278 file->read_errno = EDOM;
1285 file->status_code |= TRUNCATED;
1290 reread_byte(struct file *file)
1295 int ch = getc(file->file);
1298 file->read_errno = errno;
1301 stop(file, UNEXPECTED_ERROR_CODE, "reread");
1307 reread_4(struct file *file)
1314 result = (result << 8) + reread_byte(file);
1320 skip_12(struct file *file)
1326 if (fseek(file->file, 12, SEEK_CUR) != 0)
1329 file->read_errno = errno;
1331 stop(file, UNEXPECTED_ERROR_CODE, "reskip");
1336 write_byte(struct file *file, int b)
1338 * fails and the read of this PNG file immediately terminates. Just
1339 * increments the write count if there is no output file.
1342 if (file->out != NULL)
1344 if (putc(b, file->out) != b)
1346 file->write_errno = errno;
1347 file->status_code |= WRITE_ERROR;
1348 stop(file, WRITE_ERROR_CODE, "write byte");
1352 ++(file->write_count);
1357 read_4(struct file *file, png_uint_32 *pu)
1367 int ch = read_byte(file);
1381 crc_read_many(struct file *file, png_uint_32 length)
1388 png_uint_32 crc = file->crc;
1392 int ch = read_byte(file);
1401 file->crc = crc;
1408 calc_image_size(struct file *file)
1413 png_uint_16 pd = file->bit_depth;
1415 switch (file->color_type)
1418 stop_invalid(file, "IHDR: colour type");
1421 stop_invalid(file, "IHDR: bit depth");
1455 if (file->width < 1 || file->width > 0x7fffffff)
1456 stop_invalid(file, "IHDR: width");
1458 else if (file->height < 1 || file->height > 0x7fffffff)
1459 stop_invalid(file, "IHDR: height");
1461 else if (file->compression_method != 0)
1462 stop_invalid(file, "IHDR: compression method");
1464 else if (file->filter_method != 0)
1465 stop_invalid(file, "IHDR: filter method");
1467 else switch (file->interlace_method)
1480 png_uint_32 pw = PNG_PASS_COLS(file->width, pass);
1492 /* Add row_bytes * pass-height to the file image_bytes field
1494 image_digits = uarb_mult32(file->image_bytes, image_digits,
1496 PNG_PASS_ROWS(file->height, pass));
1500 file->image_digits = image_digits;
1511 row_width, uarb_set(row_width, file->width), pd);
1515 /* Set row_bytes * image-height to the file image_bytes field */
1516 file->image_digits = uarb_mult32(file->image_bytes, 0,
1517 row_bytes, digits, file->height);
1522 stop_invalid(file, "IHDR: interlace method");
1525 assert(file->image_digits >= 1 && file->image_digits <= 5);
1537 struct file * file;
1547 /* This information is filled in by chunk_init from the data in the file
1564 type_message(chunk->file, chunk->chunk_type, message);
1577 chunk_init(struct chunk * const chunk, struct file * const file)
1578 /* When a chunk is initialized the file length/type/pos are copied into the
1579 * corresponding chunk fields and the new chunk is registered in the file
1582 * NOTE: this routine must onely be called from the file alloc routine!
1585 assert(file->chunk == NULL);
1589 chunk->file = file;
1590 chunk->global = file->global;
1592 chunk->chunk_data_pos = file->data_pos;
1593 chunk->chunk_length = file->length;
1594 chunk->chunk_type = file->type;
1602 file->chunk = chunk;
1606 current_type(struct file *file, int code)
1611 * that if the chunk_type is png_IDAT and the file write count is 8 this is
1614 if (file->chunk != NULL)
1616 png_uint_32 type = file->chunk->chunk_type;
1623 file->write_count == 8)
1630 return file->type;
1636 * chunk. As a side effect the read_count in the file is reset to 8, just
1640 chunk->file->read_count = 8;
1641 file_setpos(chunk->file, &chunk->chunk_data_pos);
1655 static int zlib_check(struct file *file, png_uint_32 offset);
1658 process_zTXt_iCCP(struct file *file)
1663 struct chunk *chunk = file->chunk;
1667 assert(chunk != NULL && file->idat == NULL);
1675 if (reread_byte(file) == 0) /* keyword null terminator */
1679 (void)reread_byte(file); /* compression method */
1680 return zlib_check(file, index);
1689 process_iTXt(struct file *file)
1692 struct chunk *chunk = file->chunk;
1696 assert(chunk != NULL && file->idat == NULL);
1704 if (reread_byte(file) == 0) /* keyword null terminator */
1708 if (reread_byte(file) == 0) /* uncompressed text */
1713 (void)reread_byte(file); /* compression method */
1720 if (reread_byte(file) == 0) /* terminator */
1727 if (reread_byte(file) == 0) /* terminator */
1728 return zlib_check(file, index);
1738 log_error(file, INVALID_ERROR_CODE, "iTXt chunk length");
1747 struct file * file;
1769 struct file *file = idat->file;
1775 assert(file->chunk != NULL);
1776 chunk_end(&file->chunk);
1782 file->state = STATE_CHUNKS;
1786 IDAT_init(struct IDAT * const idat, struct file * const file)
1789 * structure using the file alloc routine.
1791 * NOTE: this routine must only be called from the file alloc routine!
1794 assert(file->chunk == NULL);
1795 assert(file->idat == NULL);
1799 idat->file = file;
1800 idat->global = file->global;
1809 * stores the result in file->chunk:
1811 file->alloc(file, 0/*chunk*/);
1812 assert(file->chunk != NULL);
1817 file->idat = idat;
1858 /* The chunk size is the lesser of file->idat_max and the number
1902 process_IDAT(struct file *file)
1921 assert(file->idat != NULL && file->chunk != NULL);
1932 list = file->idat->idat_list_tail;
1939 stop(file, READ_ERROR_CODE, "out of memory");
1943 file->idat->idat_list_tail = list;
1947 list->lengths[(list->count)++] = file->chunk->chunk_length;
1949 /* The type of the next chunk was recorded in the file control structure by
1952 if (file->type == png_IDAT)
1960 setpos(file->chunk);
1962 if (zlib_check(file, 0))
1970 cmp = uarb_cmp(file->image_bytes, file->image_digits,
1971 file->chunk->uncompressed_bytes, file->chunk->uncompressed_digits);
1974 type_message(file, png_IDAT, "extra uncompressed data");
1977 stop(file, LIBPNG_ERROR_CODE, "IDAT: uncompressed data too small");
1983 setpos(file->chunk);
1985 idat = file->idat;
1992 file->chunk->chunk_length = rechunk_length(idat);
1995 file->state = STATE_IDAT;
2001 stop(file, ZLIB_ERROR_CODE, "could not uncompress IDAT");
2010 struct file * file;
2021 int file_bits; /* window bits from the file */
2079 fputs(zlib->file->file_name, stderr);
2113 * IDAT reason flevel file-bits ok-bits compressed uncompressed file
2123 fputs(zlib->file->file_name, stdout);
2134 * IDAT SKP flevel file-bits z-rc compressed message file
2147 fputs(zlib->file->file_name, stdout);
2198 zlib->file = chunk->file;
2280 struct file *file = zlib->file;
2288 png_byte bIn = reread_byte(file);
2519 skip_12(zlib->file);
2601 zlib_check(struct file *file, png_uint_32 offset)
2606 * In either case the input file must be positioned at the first byte of zlib
2619 file_getpos(file, &start_pos);
2621 /* First test the existing (file) window bits: */
2622 if (zlib_init(&zlib, file->idat, file->chunk, 0/*window bits*/, offset))
2633 file->status_code |= TOO_FAR_BACK;
2656 * calculation in the original file (and this may be the only reason
2657 * a rewrite is required). We can't rely on the file window bits in
2689 file_setpos(file, &start_pos);
2749 /* The strategy here is to run a regular libpng PNG file read but examine the
2750 * input data (from the file) before passing it to libpng so as to be aware of
2760 * The file structure is instantiated in the caller of the per-file routine, but
2761 * the per-file routine contains the chunk and IDAT control structures.
2776 static void read_chunk(struct file *file);
2778 process_chunk(struct file *file, png_uint_32 file_crc, png_uint_32 next_length,
2788 const png_uint_32 type = file->type;
2790 if (file->global->verbose > 1)
2793 type_name(file->type, stderr);
2794 fprintf(stderr, " %lu 0x%.8x 0x%.8x\n", (unsigned long)file->length,
2795 file->crc ^ 0xffffffff, file_crc);
2802 if ((file->crc ^ 0xffffffff) != file_crc)
2809 file->status_code |= CRC_ERROR;
2812 if (file->global->skip != SKIP_BAD_CRC)
2813 type_message(file, type, "bad CRC");
2817 stop(file, READ_ERROR_CODE, "bad CRC in critical chunk");
2821 type_message(file, type, "skipped: bad CRC");
2832 if (skip_chunk_type(file->global, type))
2841 file->alloc(file, 0/*chunk*/);
2843 else if (file->idat == NULL)
2844 file->alloc(file, 1/*IDAT*/);
2849 assert(file->chunk != NULL);
2850 assert(file->chunk->chunk_type == png_IDAT);
2851 file->chunk->chunk_length = file->length;
2859 file->length = next_length;
2860 file->type = next_type;
2861 getpos(file);
2867 file->chunk->rewrite_length = 0;
2868 file->chunk->rewrite_offset = 0;
2880 struct chunk *chunk = file->chunk;
2883 stop_invalid(file, "IHDR length");
2887 file->width = reread_4(file);
2888 file->height = reread_4(file);
2889 file->bit_depth = reread_byte(file);
2890 file->color_type = reread_byte(file);
2891 file->compression_method = reread_byte(file);
2892 file->filter_method = reread_byte(file);
2893 file->interlace_method = reread_byte(file);
2898 calc_image_size(file);
2904 if (process_zTXt_iCCP(file))
2906 chunk_end(&file->chunk);
2907 file_setpos(file, &file->data_pos);
2911 if (process_iTXt(file))
2913 chunk_end(&file->chunk);
2914 file_setpos(file, &file->data_pos);
2918 if (process_IDAT(file))
2932 read_chunk(file);
2939 file->length = next_length;
2940 file->type = next_type;
2941 getpos(file);
2942 read_chunk(file);
2958 sync_stream(struct file *file)
2965 file->status_code |= STREAM_ERROR;
2967 if (file->global->verbose)
2970 type_name(file->type, stderr);
2975 file_setpos(file, &file->data_pos);
2976 file->read_count = 8;
2978 if (read_4(file, &file_crc) == 4) /* else completely truncated */
2986 png_uint_32 type = file->type;
3002 file->length = length;
3003 process_chunk(file, file_crc, 0, 0);
3012 ch = read_byte(file);
3032 file->read_count -= 8;
3033 process_chunk(file, file_crc, next_length, next_type);
3047 * process_chunk. So the invariant that IEND leaves the file position
3053 ch = read_byte(file);
3072 stop(file, READ_ERROR_CODE, "damaged PNG stream");
3076 read_chunk(struct file *file)
3077 /* On entry file::data_pos must be set to the position of the first byte
3078 * of the chunk data *and* the input file must be at this position. This
3080 * based on file::length and file::type and also resets these fields and
3081 * file::data_pos for the chunk after this one. For an IDAT chunk the whole
3083 * encountered, and the file fields will be set for the chunk after the end
3086 * For IEND the file::type field will be set to 0, and nothing beyond the end
3090 png_uint_32 length = file->length;
3091 png_uint_32 type = file->type;
3093 /* After IEND file::type is set to 0, if libpng attempts to read
3097 stop(file, UNEXPECTED_ERROR_CODE, "read beyond IEND");
3099 if (file->global->verbose > 2)
3110 file->crc = crc_init_4(type);
3111 if (crc_read_many(file, length)) /* else it was truncated */
3113 png_uint_32 file_crc; /* CRC read from file */
3114 unsigned int nread = read_4(file, &file_crc);
3122 nread += read_4(file, &next_length);
3127 nread += read_4(file, &next_type);
3134 file->read_count -= 8;
3135 process_chunk(file, file_crc, next_length, next_type);
3143 process_chunk(file, file_crc, 0, 0);
3154 * the PNG file.
3156 sync_stream(file);
3159 /* This returns a file
3160 static struct file *get_control(png_const_structrp png_ptr);
3171 struct file *file = get_control(png_ptr);
3173 if (file->global->warnings)
3174 emit_error(file, LIBPNG_WARNING_CODE, message);
3184 struct file *file = get_control(png_ptr);
3190 stop(file, UNEXPECTED_ERROR_CODE, "read callback for 0 bytes");
3197 if (file->read_count < 8)
3199 assert(file->read_count == 0);
3200 assert((file->status_code & TRUNCATED) == 0);
3202 (void)read_4(file, &file->length);
3204 if (file->read_count == 4)
3205 (void)read_4(file, &file->type);
3207 if (file->read_count < 8)
3209 assert((file->status_code & TRUNCATED) != 0);
3210 stop(file, READ_ERROR_CODE, "not a PNG (too short)");
3213 if (file->state == STATE_SIGNATURE)
3215 if (file->length != sig1 || file->type != sig2)
3216 stop(file, LIBPNG_ERROR_CODE, "not a PNG (signature)");
3221 file->write_count = 0;
3226 assert(file->state == STATE_CHUNKS);
3231 if (file->length != 13 || file->type != png_IHDR)
3232 stop(file, LIBPNG_ERROR_CODE, "not a PNG (IHDR)");
3235 getpos(file);
3242 chunk = file->chunk;
3255 length = file->length;
3256 type = file->type;
3264 * a chunk control structure and sets the file length/type/data_pos fields
3273 if (file->state != STATE_SIGNATURE && chunk == NULL)
3275 assert(file->read_count == 8);
3276 assert(file->idat == NULL);
3277 read_chunk(file);
3278 chunk = file->chunk;
3286 file->write_count = 0;
3293 switch (file->write_count)
3310 if (file->state == STATE_SIGNATURE)
3317 file->read_count = 0; /* Forces a header read */
3318 file->state = STATE_CHUNKS; /* IHDR: checked above */
3334 if (file->state != STATE_IDAT && length > 0)
3345 switch (file->write_count - length)
3348 * the file. The only exception is for that part of a
3354 if (file->state == STATE_IDAT)
3356 struct IDAT *idat = file->idat;
3386 stop(file, UNEXPECTED_ERROR_CODE,
3400 skip_12(file);
3411 b = reread_byte(file);
3446 if (file->global->verbose > 2)
3461 if (file->state == STATE_IDAT &&
3462 (file->idat->idat_index < file->idat->idat_length ||
3463 1+file->idat->idat_count < file->idat->idat_cur->count ||
3464 file->idat->idat_cur != file->idat->idat_list_tail))
3469 length = chunk->chunk_length = rechunk_length(file->idat);
3471 file->write_count = 0; /* for the new chunk */
3472 --(file->write_count); /* fake out the increment below */
3481 stop(file, UNEXPECTED_ERROR_CODE, "pending rewrite");
3484 * chunk and move the input file to the position after the
3487 file->read_count = 8;
3488 file_setpos(file, &file->data_pos);
3490 if (file->idat == NULL)
3491 chunk_end(&file->chunk);
3494 IDAT_end(&file->idat);
3508 write_byte(file, (png_byte)b); /* increments chunk_write */
3513 /* Bundle the file and an uninitialized chunk and IDAT control structure
3518 struct file file;
3526 return file_end(&control->file);
3529 static struct file *
3532 /* This just returns the (file*). The chunk and idat control structures
3537 return &control->file;
3541 allocate(struct file *file, int allocate_idat)
3543 struct control *control = png_voidcast(struct control*, file->alloc_ptr);
3547 assert(file->idat == NULL);
3548 IDAT_init(&control->idat, file);
3553 assert(file->chunk == NULL);
3554 chunk_init(&control->chunk, file);
3561 /* This wraps file_init(&control::file) and simply returns the result from
3565 return file_init(&control->file, global, file_name, out_name, control,
3572 * defined for file::status_code as above.
3586 log_error(&control->file, LIBPNG_ERROR_CODE, "OOM allocating png_struct");
3587 control->file.status_code |= INTERNAL_ERROR;
3591 rc = setjmp(control->file.jmpbuf);
3600 if (control->file.global->verbose)
3634 if (control->file.global->verbose)
3637 /* Make sure to read to the end of the file: */
3654 fprintf(stderr, "FILE %s -> %s\n", file_name,
3677 " Optionally, when fixing, strips ancilliary chunks from the file.",
3683 " the file.",
3717 " By default the program only outputs summaries for each file.",
3727 " --out=<file>:",
3728 " Write the optimized/corrected version of the next PNG to <file>. This",
3732 " a per-file basis by explicit --out.",
3735 " on a per-file basis by explicit --out.",
3742 " output as this would produce a broken file.",
3749 " the following codes. Notice that the results for each file are combined",
3750 " together - check one file at a time to get a meaningful error code!",
3754 " 0x08: The file was truncated.",
3755 " Errors less than 16 are potentially recoverable, for a single file if the",
3756 " exit code is less than 16 the file could be read (with corrections if a",
3758 " 0x10: The file could not be read, even with corrections.",
3759 " 0x20: The output file could not be written.",
3768 " checks each PNG file on the command line for errors. By default errors are",
3771 " program only outputs unexpected errors (internal errors and file open",
3773 " Various known problems in PNG files are fixed while the file is being read",
3783 " Setting one of the \"OUTPUT\" options causes the possibly modified file to",
3784 " be written to a new file.",
3798 " chunk reason comp-level p1 p2 p3 p4 file",
3803 " chunk ERR status code read-errno write-errno message file",
3804 " chunk SKP comp-level file-bits zlib-rc compressed message file",
3805 " chunk ??? comp-level file-bits ok-bits compressed uncompress file",
3809 "$1 chunk: The chunk type of a chunk in the file or 'HEAD' if a problem",
3819 " ERR: The read of the file was aborted. The parameters explain why.",
3824 "$4 code: The file exit code; where stop was called, as a fairly terse",
3826 " file-bits: The zlib window bits recorded in the file.",
3837 "$8 file: The name of the file (this may contain spaces).",
3840 fprintf(stderr, "Usage: %s {[options] png-file}\n", prog);
3860 int done = 0; /* if at least one file is processed */
3969 fprintf(stderr, "%s: output file name too long: %s%s%s\n",
3992 fprintf(stderr, "%s: output file name too long: %s%s\n",