📄 pngrutil.c
字号:
if (png_ptr->mode & PNG_HAVE_IDAT) png_ptr->mode |= PNG_AFTER_IDAT; if (length != 7) { png_warning(png_ptr, "Incorrect tIME chunk length"); png_crc_finish(png_ptr, length); return; } png_crc_read(png_ptr, buf, 7); if (png_crc_finish(png_ptr, 0)) return; mod_time.second = buf[6]; mod_time.minute = buf[5]; mod_time.hour = buf[4]; mod_time.day = buf[3]; mod_time.month = buf[2]; mod_time.year = png_get_uint_16(buf); png_set_tIME(png_ptr, info_ptr, &mod_time);}#endif#if defined(PNG_READ_tEXt_SUPPORTED)/* Note: this does not properly handle chunks that are > 64K under DOS */void /* PRIVATE */png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length){ png_textp text_ptr; png_charp key; png_charp text; png_uint_32 skip = 0; png_size_t slength; int ret; png_debug(1, "in png_handle_tEXt\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before tEXt"); if (png_ptr->mode & PNG_HAVE_IDAT) png_ptr->mode |= PNG_AFTER_IDAT;#ifdef PNG_MAX_MALLOC_64K if (length > (png_uint_32)65535L) { png_warning(png_ptr, "tEXt chunk too large to fit in memory"); skip = length - (png_uint_32)65535L; length = (png_uint_32)65535L; }#endif key = (png_charp)png_malloc_warn(png_ptr, length + 1); if (key == NULL) { png_warning(png_ptr, "No memory to process text chunk."); return; } slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)key, slength); if (png_crc_finish(png_ptr, skip)) { png_free(png_ptr, key); return; } key[slength] = 0x00; for (text = key; *text; text++) /* empty loop to find end of key */ ; if (text != key + slength) text++; text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text)); if (text_ptr == NULL) { png_warning(png_ptr, "Not enough memory to process text chunk."); png_free(png_ptr, key); return; } text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; text_ptr->key = key;#ifdef PNG_iTXt_SUPPORTED text_ptr->lang = NULL; text_ptr->lang_key = NULL; text_ptr->itxt_length = 0;#endif text_ptr->text = text; text_ptr->text_length = png_strlen(text); ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, key); png_free(png_ptr, text_ptr); if (ret) png_warning(png_ptr, "Insufficient memory to process text chunk.");}#endif#if defined(PNG_READ_zTXt_SUPPORTED)/* note: this does not correctly handle chunks that are > 64K under DOS */void /* PRIVATE */png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length){ png_textp text_ptr; png_charp chunkdata; png_charp text; int comp_type; int ret; png_size_t slength, prefix_len, data_len; png_debug(1, "in png_handle_zTXt\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before zTXt"); if (png_ptr->mode & PNG_HAVE_IDAT) png_ptr->mode |= PNG_AFTER_IDAT;#ifdef PNG_MAX_MALLOC_64K /* We will no doubt have problems with chunks even half this size, but there is no hard and fast rule to tell us where to stop. */ if (length > (png_uint_32)65535L) { png_warning(png_ptr,"zTXt chunk too large to fit in memory"); png_crc_finish(png_ptr, length); return; }#endif chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); if (chunkdata == NULL) { png_warning(png_ptr,"Out of memory processing zTXt chunk."); return; } slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunkdata, slength); if (png_crc_finish(png_ptr, 0)) { png_free(png_ptr, chunkdata); return; } chunkdata[slength] = 0x00; for (text = chunkdata; *text; text++) /* empty loop */ ; /* zTXt must have some text after the chunkdataword */ if (text == chunkdata + slength) { comp_type = PNG_TEXT_COMPRESSION_NONE; png_warning(png_ptr, "Zero length zTXt chunk"); } else { comp_type = *(++text); if (comp_type != PNG_TEXT_COMPRESSION_zTXt) { png_warning(png_ptr, "Unknown compression type in zTXt chunk"); comp_type = PNG_TEXT_COMPRESSION_zTXt; } text++; /* skip the compression_method byte */ } prefix_len = text - chunkdata; chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata, (png_size_t)length, prefix_len, &data_len); text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text)); if (text_ptr == NULL) { png_warning(png_ptr,"Not enough memory to process zTXt chunk."); png_free(png_ptr, chunkdata); return; } text_ptr->compression = comp_type; text_ptr->key = chunkdata;#ifdef PNG_iTXt_SUPPORTED text_ptr->lang = NULL; text_ptr->lang_key = NULL; text_ptr->itxt_length = 0;#endif text_ptr->text = chunkdata + prefix_len; text_ptr->text_length = data_len; ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, text_ptr); png_free(png_ptr, chunkdata); if (ret) png_error(png_ptr, "Insufficient memory to store zTXt chunk.");}#endif#if defined(PNG_READ_iTXt_SUPPORTED)/* note: this does not correctly handle chunks that are > 64K under DOS */void /* PRIVATE */png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length){ png_textp text_ptr; png_charp chunkdata; png_charp key, lang, text, lang_key; int comp_flag; int comp_type = 0; int ret; png_size_t slength, prefix_len, data_len; png_debug(1, "in png_handle_iTXt\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before iTXt"); if (png_ptr->mode & PNG_HAVE_IDAT) png_ptr->mode |= PNG_AFTER_IDAT;#ifdef PNG_MAX_MALLOC_64K /* We will no doubt have problems with chunks even half this size, but there is no hard and fast rule to tell us where to stop. */ if (length > (png_uint_32)65535L) { png_warning(png_ptr,"iTXt chunk too large to fit in memory"); png_crc_finish(png_ptr, length); return; }#endif chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); if (chunkdata == NULL) { png_warning(png_ptr, "No memory to process iTXt chunk."); return; } slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunkdata, slength); if (png_crc_finish(png_ptr, 0)) { png_free(png_ptr, chunkdata); return; } chunkdata[slength] = 0x00; for (lang = chunkdata; *lang; lang++) /* empty loop */ ; lang++; /* skip NUL separator */ /* iTXt must have a language tag (possibly empty), two compression bytes, translated keyword (possibly empty), and possibly some text after the keyword */ if (lang >= chunkdata + slength) { comp_flag = PNG_TEXT_COMPRESSION_NONE; png_warning(png_ptr, "Zero length iTXt chunk"); } else { comp_flag = *lang++; comp_type = *lang++; } for (lang_key = lang; *lang_key; lang_key++) /* empty loop */ ; lang_key++; /* skip NUL separator */ for (text = lang_key; *text; text++) /* empty loop */ ; text++; /* skip NUL separator */ prefix_len = text - chunkdata; key=chunkdata; if (comp_flag) chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata, (size_t)length, prefix_len, &data_len); else data_len=png_strlen(chunkdata + prefix_len); text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text)); if (text_ptr == NULL) { png_warning(png_ptr,"Not enough memory to process iTXt chunk."); png_free(png_ptr, chunkdata); return; } text_ptr->compression = (int)comp_flag + 1; text_ptr->lang_key = chunkdata+(lang_key-key); text_ptr->lang = chunkdata+(lang-key); text_ptr->itxt_length = data_len; text_ptr->text_length = 0; text_ptr->key = chunkdata; text_ptr->text = chunkdata + prefix_len; ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, text_ptr); png_free(png_ptr, chunkdata); if (ret) png_error(png_ptr, "Insufficient memory to store iTXt chunk.");}#endif/* This function is called when we haven't found a handler for a chunk. If there isn't a problem with the chunk itself (ie bad chunk name, CRC, or a critical chunk), the chunk is silently ignored -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which case it will be saved away to be written out later. */void /* PRIVATE */png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length){ png_uint_32 skip = 0; png_debug(1, "in png_handle_unknown\n"); if (png_ptr->mode & PNG_HAVE_IDAT) {#ifdef PNG_USE_LOCAL_ARRAYS PNG_IDAT;#endif if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */ png_ptr->mode |= PNG_AFTER_IDAT; } png_check_chunk_name(png_ptr, png_ptr->chunk_name); if (!(png_ptr->chunk_name[0] & 0x20)) {#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != HANDLE_CHUNK_ALWAYS#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) && png_ptr->read_user_chunk_fn == NULL#endif )#endif png_chunk_error(png_ptr, "unknown critical chunk"); }#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) { png_unknown_chunk chunk;#ifdef PNG_MAX_MALLOC_64K if (length > (png_uint_32)65535L) { png_warning(png_ptr, "unknown chunk too large to fit in memory"); skip = length - (png_uint_32)65535L; length = (png_uint_32)65535L; }#endif png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name); chunk.data = (png_bytep)png_malloc(png_ptr, length); chunk.size = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunk.data, length);#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) if(png_ptr->read_user_chunk_fn != NULL) { /* callback to user unknown chunk handler */ if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0) { if (!(png_ptr->chunk_name[0] & 0x20)) if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != HANDLE_CHUNK_ALWAYS) { png_free(png_ptr, chunk.data); png_chunk_error(png_ptr, "unknown critical chunk"); } png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); } } else#endif png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); png_free(png_ptr, chunk.data); } else#endif skip = length; png_crc_finish(png_ptr, skip);#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED) info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */#endif}/* This function is called to verify that a chunk name is valid. This function can't have the "critical chunk check" incorporated into it, since in the future we will need to be able to call user functions to handle unknown critical chunks after we check that the chunk name itself is valid. */#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))void /* PRIVATE */png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name){ png_debug(1, "in png_check_chunk_name\n"); if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) { png_chunk_error(png_ptr, "invalid chunk type"); }}/* Combines the row recently read in with the existing pixels in the row. This routine takes care of alpha and transparency if requested. This routine also handles the two methods of progressive display of interlaced images, depending on the mask value. The mask value describes which pixels are to be combined with the row. The pattern always repeats every 8 pixels, so just 8 bits are needed. A one indicates the pixel is to be combined, a zero indicates the pixel is to be skipped. This is in addition to any alpha or transparency value associated with the pixel. If you want all pixels to be combined, pass 0xff (255) in mask. */#ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROWvoid /* PRIVATE */png_combine_row(png_structp png_ptr, png_bytep row, int mask){ png_debug(1,"in png_combine_row\n"); if (mask == 0xff) { png_memcpy(row, png_ptr->row_buf + 1, (png_size_t)((png_ptr->width * png_ptr->row_info.pixel_depth + 7) >> 3)); } else { switch (png_ptr->row_info.pixel_depth) { case 1: { png_bytep sp = png_ptr->row_buf + 1; png_bytep dp = row; int s_inc, s_start, s_end; int m = 0x80; int shift; png_uint_32 i; png_uint_32 row_width = png_ptr->width;#if defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; s_end = 7; s_inc = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -