📄 pngpread.c
字号:
/* pngpread.c - read a png file in push mode * * libpng 1.0.12 - June 8, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */#define PNG_INTERNAL#include "png.h"#ifdef PNG_PROGRESSIVE_READ_SUPPORTED/* push model modes */#define PNG_READ_SIG_MODE 0#define PNG_READ_CHUNK_MODE 1#define PNG_READ_IDAT_MODE 2#define PNG_SKIP_MODE 3#define PNG_READ_tEXt_MODE 4#define PNG_READ_zTXt_MODE 5#define PNG_READ_DONE_MODE 6#define PNG_READ_iTXt_MODE 7#define PNG_ERROR_MODE 8void PNGAPIpng_process_data(png_structp png_ptr, png_infop info_ptr, png_bytep buffer, png_size_t buffer_size){ png_push_restore_buffer(png_ptr, buffer, buffer_size); while (png_ptr->buffer_size) { png_process_some_data(png_ptr, info_ptr); }}/* What we do with the incoming data depends on what we were previously * doing before we ran out of data... */void /* PRIVATE */png_process_some_data(png_structp png_ptr, png_infop info_ptr){ switch (png_ptr->process_mode) { case PNG_READ_SIG_MODE: { png_push_read_sig(png_ptr, info_ptr); break; } case PNG_READ_CHUNK_MODE: { png_push_read_chunk(png_ptr, info_ptr); break; } case PNG_READ_IDAT_MODE: { png_push_read_IDAT(png_ptr); break; }#if defined(PNG_READ_tEXt_SUPPORTED) case PNG_READ_tEXt_MODE: { png_push_read_tEXt(png_ptr, info_ptr); break; }#endif#if defined(PNG_READ_zTXt_SUPPORTED) case PNG_READ_zTXt_MODE: { png_push_read_zTXt(png_ptr, info_ptr); break; }#endif#if defined(PNG_READ_iTXt_SUPPORTED) case PNG_READ_iTXt_MODE: { png_push_read_iTXt(png_ptr, info_ptr); break; }#endif case PNG_SKIP_MODE: { png_push_crc_finish(png_ptr); break; } default: { png_ptr->buffer_size = 0; break; } }}/* Read any remaining signature bytes from the stream and compare them with * the correct PNG signature. It is possible that this routine is called * with bytes already read from the signature, either because they have been * checked by the calling application, or because of multiple calls to this * routine. */void /* PRIVATE */png_push_read_sig(png_structp png_ptr, png_infop info_ptr){ png_size_t num_checked = png_ptr->sig_bytes, num_to_check = 8 - num_checked; if (png_ptr->buffer_size < num_to_check) { num_to_check = png_ptr->buffer_size; } png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+num_to_check); if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) { if (num_checked < 4 && png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) png_error(png_ptr, "Not a PNG file"); else png_error(png_ptr, "PNG file corrupted by ASCII conversion"); } else { if (png_ptr->sig_bytes >= 8) { png_ptr->process_mode = PNG_READ_CHUNK_MODE; } }}void /* PRIVATE */png_push_read_chunk(png_structp png_ptr, png_infop info_ptr){#ifdef PNG_USE_LOCAL_ARRAYS PNG_IHDR; PNG_IDAT; PNG_IEND; PNG_PLTE;#if defined(PNG_READ_bKGD_SUPPORTED) PNG_bKGD;#endif#if defined(PNG_READ_cHRM_SUPPORTED) PNG_cHRM;#endif#if defined(PNG_READ_gAMA_SUPPORTED) PNG_gAMA;#endif#if defined(PNG_READ_hIST_SUPPORTED) PNG_hIST;#endif#if defined(PNG_READ_iCCP_SUPPORTED) PNG_iCCP;#endif#if defined(PNG_READ_iTXt_SUPPORTED) PNG_iTXt;#endif#if defined(PNG_READ_oFFs_SUPPORTED) PNG_oFFs;#endif#if defined(PNG_READ_pCAL_SUPPORTED) PNG_pCAL;#endif#if defined(PNG_READ_pHYs_SUPPORTED) PNG_pHYs;#endif#if defined(PNG_READ_sBIT_SUPPORTED) PNG_sBIT;#endif#if defined(PNG_READ_sCAL_SUPPORTED) PNG_sCAL;#endif#if defined(PNG_READ_sRGB_SUPPORTED) PNG_sRGB;#endif#if defined(PNG_READ_sPLT_SUPPORTED) PNG_sPLT;#endif#if defined(PNG_READ_tEXt_SUPPORTED) PNG_tEXt;#endif#if defined(PNG_READ_tIME_SUPPORTED) PNG_tIME;#endif#if defined(PNG_READ_tRNS_SUPPORTED) PNG_tRNS;#endif#if defined(PNG_READ_zTXt_SUPPORTED) PNG_zTXt;#endif#endif /* PNG_USE_LOCAL_ARRAYS */ /* First we make sure we have enough data for the 4 byte chunk name * and the 4 byte chunk length before proceeding with decoding the * chunk data. To fully decode each of these chunks, we also make * sure we have enough data in the buffer for the 4 byte CRC at the * end of every chunk (except IDAT, which is handled separately). */ if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) { png_byte chunk_length[4]; if (png_ptr->buffer_size < 8) { png_push_save_buffer(png_ptr); return; } png_push_fill_buffer(png_ptr, chunk_length, 4); png_ptr->push_length = png_get_uint_32(chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; } if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); } else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); } else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) { /* If we reach an IDAT chunk, this means we have read all of the * header chunks, and we can start reading the image (or if this * is called after the image has been read - we have an error). */ if (png_ptr->mode & PNG_HAVE_IDAT) { if (png_ptr->push_length == 0) return; if (png_ptr->mode & PNG_AFTER_IDAT) png_error(png_ptr, "Too many IDAT's found"); } png_ptr->idat_size = png_ptr->push_length; png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->process_mode = PNG_READ_IDAT_MODE; png_push_have_info(png_ptr, info_ptr); png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; png_ptr->zstream.next_out = png_ptr->row_buf; return; } else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); png_ptr->process_mode = PNG_READ_DONE_MODE; png_push_have_end(png_ptr, info_ptr); }#if defined(PNG_READ_gAMA_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_sBIT_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_cHRM_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_sRGB_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_iCCP_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_sPLT_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_tRNS_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_bKGD_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_hIST_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_pHYs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_oFFs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_pCAL_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_sCAL_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_tIME_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_tEXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) { png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_zTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) { png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); }#endif#if defined(PNG_READ_iTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) { png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); }#endif else { png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); } png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;}void /* PRIVATE */png_push_crc_skip(png_structp png_ptr, png_uint_32 skip){ png_ptr->process_mode = PNG_SKIP_MODE; png_ptr->skip_length = skip;}void /* PRIVATE */png_push_crc_finish(png_structp png_ptr){ if (png_ptr->skip_length && png_ptr->save_buffer_size) { png_size_t save_size; if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size) save_size = (png_size_t)png_ptr->skip_length; else save_size = png_ptr->save_buffer_size; png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); png_ptr->skip_length -= save_size; png_ptr->buffer_size -= save_size; png_ptr->save_buffer_size -= save_size; png_ptr->save_buffer_ptr += save_size; } if (png_ptr->skip_length && png_ptr->current_buffer_size) { png_size_t save_size; if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size) save_size = (png_size_t)png_ptr->skip_length; else save_size = png_ptr->current_buffer_size; png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -