Path: blob/master/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c
41154 views
/*1* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation. Oracle designates this6* particular file as subject to the "Classpath" exception as provided7* by Oracle in the LICENSE file that accompanied this code.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/2324/* pngpread.c - read a png file in push mode25*26* This file is available under and governed by the GNU General Public27* License version 2 only, as published by the Free Software Foundation.28* However, the following notice accompanied the original version of this29* file and, per its terms, should not be removed:30*31* Copyright (c) 2018 Cosmin Truta32* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson33* Copyright (c) 1996-1997 Andreas Dilger34* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.35*36* This code is released under the libpng license.37* For conditions of distribution and use, see the disclaimer38* and license in png.h39*/4041#include "pngpriv.h"4243#ifdef PNG_PROGRESSIVE_READ_SUPPORTED4445/* Push model modes */46#define PNG_READ_SIG_MODE 047#define PNG_READ_CHUNK_MODE 148#define PNG_READ_IDAT_MODE 249#define PNG_READ_tEXt_MODE 450#define PNG_READ_zTXt_MODE 551#define PNG_READ_DONE_MODE 652#define PNG_READ_iTXt_MODE 753#define PNG_ERROR_MODE 85455#define PNG_PUSH_SAVE_BUFFER_IF_FULL \56if (png_ptr->push_length + 4 > png_ptr->buffer_size) \57{ png_push_save_buffer(png_ptr); return; }58#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \59if (png_ptr->buffer_size < N) \60{ png_push_save_buffer(png_ptr); return; }6162void PNGAPI63png_process_data(png_structrp png_ptr, png_inforp info_ptr,64png_bytep buffer, size_t buffer_size)65{66if (png_ptr == NULL || info_ptr == NULL)67return;6869png_push_restore_buffer(png_ptr, buffer, buffer_size);7071while (png_ptr->buffer_size)72{73png_process_some_data(png_ptr, info_ptr);74}75}7677size_t PNGAPI78png_process_data_pause(png_structrp png_ptr, int save)79{80if (png_ptr != NULL)81{82/* It's easiest for the caller if we do the save; then the caller doesn't83* have to supply the same data again:84*/85if (save != 0)86png_push_save_buffer(png_ptr);87else88{89/* This includes any pending saved bytes: */90size_t remaining = png_ptr->buffer_size;91png_ptr->buffer_size = 0;9293/* So subtract the saved buffer size, unless all the data94* is actually 'saved', in which case we just return 095*/96if (png_ptr->save_buffer_size < remaining)97return remaining - png_ptr->save_buffer_size;98}99}100101return 0;102}103104png_uint_32 PNGAPI105png_process_data_skip(png_structrp png_ptr)106{107/* TODO: Deprecate and remove this API.108* Somewhere the implementation of this seems to have been lost,109* or abandoned. It was only to support some internal back-door access110* to png_struct) in libpng-1.4.x.111*/112png_app_warning(png_ptr,113"png_process_data_skip is not implemented in any current version of libpng");114return 0;115}116117/* What we do with the incoming data depends on what we were previously118* doing before we ran out of data...119*/120void /* PRIVATE */121png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)122{123if (png_ptr == NULL)124return;125126switch (png_ptr->process_mode)127{128case PNG_READ_SIG_MODE:129{130png_push_read_sig(png_ptr, info_ptr);131break;132}133134case PNG_READ_CHUNK_MODE:135{136png_push_read_chunk(png_ptr, info_ptr);137break;138}139140case PNG_READ_IDAT_MODE:141{142png_push_read_IDAT(png_ptr);143break;144}145146default:147{148png_ptr->buffer_size = 0;149break;150}151}152}153154/* Read any remaining signature bytes from the stream and compare them with155* the correct PNG signature. It is possible that this routine is called156* with bytes already read from the signature, either because they have been157* checked by the calling application, or because of multiple calls to this158* routine.159*/160void /* PRIVATE */161png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)162{163size_t num_checked = png_ptr->sig_bytes; /* SAFE, does not exceed 8 */164size_t num_to_check = 8 - num_checked;165166if (png_ptr->buffer_size < num_to_check)167{168num_to_check = png_ptr->buffer_size;169}170171png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),172num_to_check);173png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);174175if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))176{177if (num_checked < 4 &&178png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))179png_error(png_ptr, "Not a PNG file");180181else182png_error(png_ptr, "PNG file corrupted by ASCII conversion");183}184else185{186if (png_ptr->sig_bytes >= 8)187{188png_ptr->process_mode = PNG_READ_CHUNK_MODE;189}190}191}192193void /* PRIVATE */194png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)195{196png_uint_32 chunk_name;197#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED198int keep; /* unknown handling method */199#endif200201/* First we make sure we have enough data for the 4-byte chunk name202* and the 4-byte chunk length before proceeding with decoding the203* chunk data. To fully decode each of these chunks, we also make204* sure we have enough data in the buffer for the 4-byte CRC at the205* end of every chunk (except IDAT, which is handled separately).206*/207if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)208{209png_byte chunk_length[4];210png_byte chunk_tag[4];211212PNG_PUSH_SAVE_BUFFER_IF_LT(8)213png_push_fill_buffer(png_ptr, chunk_length, 4);214png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);215png_reset_crc(png_ptr);216png_crc_read(png_ptr, chunk_tag, 4);217png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);218png_check_chunk_name(png_ptr, png_ptr->chunk_name);219png_check_chunk_length(png_ptr, png_ptr->push_length);220png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;221}222223chunk_name = png_ptr->chunk_name;224225if (chunk_name == png_IDAT)226{227if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)228png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;229230/* If we reach an IDAT chunk, this means we have read all of the231* header chunks, and we can start reading the image (or if this232* is called after the image has been read - we have an error).233*/234if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)235png_error(png_ptr, "Missing IHDR before IDAT");236237else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&238(png_ptr->mode & PNG_HAVE_PLTE) == 0)239png_error(png_ptr, "Missing PLTE before IDAT");240241png_ptr->process_mode = PNG_READ_IDAT_MODE;242243if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)244if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)245if (png_ptr->push_length == 0)246return;247248png_ptr->mode |= PNG_HAVE_IDAT;249250if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)251png_benign_error(png_ptr, "Too many IDATs found");252}253254if (chunk_name == png_IHDR)255{256if (png_ptr->push_length != 13)257png_error(png_ptr, "Invalid IHDR length");258259PNG_PUSH_SAVE_BUFFER_IF_FULL260png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);261}262263else if (chunk_name == png_IEND)264{265PNG_PUSH_SAVE_BUFFER_IF_FULL266png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);267268png_ptr->process_mode = PNG_READ_DONE_MODE;269png_push_have_end(png_ptr, info_ptr);270}271272#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED273else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)274{275PNG_PUSH_SAVE_BUFFER_IF_FULL276png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep);277278if (chunk_name == png_PLTE)279png_ptr->mode |= PNG_HAVE_PLTE;280}281#endif282283else if (chunk_name == png_PLTE)284{285PNG_PUSH_SAVE_BUFFER_IF_FULL286png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);287}288289else if (chunk_name == png_IDAT)290{291png_ptr->idat_size = png_ptr->push_length;292png_ptr->process_mode = PNG_READ_IDAT_MODE;293png_push_have_info(png_ptr, info_ptr);294png_ptr->zstream.avail_out =295(uInt) PNG_ROWBYTES(png_ptr->pixel_depth,296png_ptr->iwidth) + 1;297png_ptr->zstream.next_out = png_ptr->row_buf;298return;299}300301#ifdef PNG_READ_gAMA_SUPPORTED302else if (png_ptr->chunk_name == png_gAMA)303{304PNG_PUSH_SAVE_BUFFER_IF_FULL305png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);306}307308#endif309#ifdef PNG_READ_sBIT_SUPPORTED310else if (png_ptr->chunk_name == png_sBIT)311{312PNG_PUSH_SAVE_BUFFER_IF_FULL313png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);314}315316#endif317#ifdef PNG_READ_cHRM_SUPPORTED318else if (png_ptr->chunk_name == png_cHRM)319{320PNG_PUSH_SAVE_BUFFER_IF_FULL321png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);322}323324#endif325#ifdef PNG_READ_sRGB_SUPPORTED326else if (chunk_name == png_sRGB)327{328PNG_PUSH_SAVE_BUFFER_IF_FULL329png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);330}331332#endif333#ifdef PNG_READ_iCCP_SUPPORTED334else if (png_ptr->chunk_name == png_iCCP)335{336PNG_PUSH_SAVE_BUFFER_IF_FULL337png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);338}339340#endif341#ifdef PNG_READ_sPLT_SUPPORTED342else if (chunk_name == png_sPLT)343{344PNG_PUSH_SAVE_BUFFER_IF_FULL345png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);346}347348#endif349#ifdef PNG_READ_tRNS_SUPPORTED350else if (chunk_name == png_tRNS)351{352PNG_PUSH_SAVE_BUFFER_IF_FULL353png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);354}355356#endif357#ifdef PNG_READ_bKGD_SUPPORTED358else if (chunk_name == png_bKGD)359{360PNG_PUSH_SAVE_BUFFER_IF_FULL361png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);362}363364#endif365#ifdef PNG_READ_hIST_SUPPORTED366else if (chunk_name == png_hIST)367{368PNG_PUSH_SAVE_BUFFER_IF_FULL369png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);370}371372#endif373#ifdef PNG_READ_pHYs_SUPPORTED374else if (chunk_name == png_pHYs)375{376PNG_PUSH_SAVE_BUFFER_IF_FULL377png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);378}379380#endif381#ifdef PNG_READ_oFFs_SUPPORTED382else if (chunk_name == png_oFFs)383{384PNG_PUSH_SAVE_BUFFER_IF_FULL385png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);386}387#endif388389#ifdef PNG_READ_pCAL_SUPPORTED390else if (chunk_name == png_pCAL)391{392PNG_PUSH_SAVE_BUFFER_IF_FULL393png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);394}395396#endif397#ifdef PNG_READ_sCAL_SUPPORTED398else if (chunk_name == png_sCAL)399{400PNG_PUSH_SAVE_BUFFER_IF_FULL401png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);402}403404#endif405#ifdef PNG_READ_tIME_SUPPORTED406else if (chunk_name == png_tIME)407{408PNG_PUSH_SAVE_BUFFER_IF_FULL409png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);410}411412#endif413#ifdef PNG_READ_tEXt_SUPPORTED414else if (chunk_name == png_tEXt)415{416PNG_PUSH_SAVE_BUFFER_IF_FULL417png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);418}419420#endif421#ifdef PNG_READ_zTXt_SUPPORTED422else if (chunk_name == png_zTXt)423{424PNG_PUSH_SAVE_BUFFER_IF_FULL425png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);426}427428#endif429#ifdef PNG_READ_iTXt_SUPPORTED430else if (chunk_name == png_iTXt)431{432PNG_PUSH_SAVE_BUFFER_IF_FULL433png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);434}435#endif436437else438{439PNG_PUSH_SAVE_BUFFER_IF_FULL440png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,441PNG_HANDLE_CHUNK_AS_DEFAULT);442}443444png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;445}446447void PNGCBAPI448png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length)449{450png_bytep ptr;451452if (png_ptr == NULL)453return;454455ptr = buffer;456if (png_ptr->save_buffer_size != 0)457{458size_t save_size;459460if (length < png_ptr->save_buffer_size)461save_size = length;462463else464save_size = png_ptr->save_buffer_size;465466memcpy(ptr, png_ptr->save_buffer_ptr, save_size);467length -= save_size;468ptr += save_size;469png_ptr->buffer_size -= save_size;470png_ptr->save_buffer_size -= save_size;471png_ptr->save_buffer_ptr += save_size;472}473if (length != 0 && png_ptr->current_buffer_size != 0)474{475size_t save_size;476477if (length < png_ptr->current_buffer_size)478save_size = length;479480else481save_size = png_ptr->current_buffer_size;482483memcpy(ptr, png_ptr->current_buffer_ptr, save_size);484png_ptr->buffer_size -= save_size;485png_ptr->current_buffer_size -= save_size;486png_ptr->current_buffer_ptr += save_size;487}488}489490void /* PRIVATE */491png_push_save_buffer(png_structrp png_ptr)492{493if (png_ptr->save_buffer_size != 0)494{495if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)496{497size_t i, istop;498png_bytep sp;499png_bytep dp;500501istop = png_ptr->save_buffer_size;502for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;503i < istop; i++, sp++, dp++)504{505*dp = *sp;506}507}508}509if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >510png_ptr->save_buffer_max)511{512size_t new_max;513png_bytep old_buffer;514515if (png_ptr->save_buffer_size > PNG_SIZE_MAX -516(png_ptr->current_buffer_size + 256))517{518png_error(png_ptr, "Potential overflow of save_buffer");519}520521new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;522old_buffer = png_ptr->save_buffer;523png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,524(size_t)new_max);525526if (png_ptr->save_buffer == NULL)527{528png_free(png_ptr, old_buffer);529png_error(png_ptr, "Insufficient memory for save_buffer");530}531532if (old_buffer)533memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);534else if (png_ptr->save_buffer_size)535png_error(png_ptr, "save_buffer error");536png_free(png_ptr, old_buffer);537png_ptr->save_buffer_max = new_max;538}539if (png_ptr->current_buffer_size)540{541memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,542png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);543png_ptr->save_buffer_size += png_ptr->current_buffer_size;544png_ptr->current_buffer_size = 0;545}546png_ptr->save_buffer_ptr = png_ptr->save_buffer;547png_ptr->buffer_size = 0;548}549550void /* PRIVATE */551png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,552size_t buffer_length)553{554png_ptr->current_buffer = buffer;555png_ptr->current_buffer_size = buffer_length;556png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;557png_ptr->current_buffer_ptr = png_ptr->current_buffer;558}559560void /* PRIVATE */561png_push_read_IDAT(png_structrp png_ptr)562{563if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)564{565png_byte chunk_length[4];566png_byte chunk_tag[4];567568/* TODO: this code can be commoned up with the same code in push_read */569PNG_PUSH_SAVE_BUFFER_IF_LT(8)570png_push_fill_buffer(png_ptr, chunk_length, 4);571png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);572png_reset_crc(png_ptr);573png_crc_read(png_ptr, chunk_tag, 4);574png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);575png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;576577if (png_ptr->chunk_name != png_IDAT)578{579png_ptr->process_mode = PNG_READ_CHUNK_MODE;580581if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)582png_error(png_ptr, "Not enough compressed data");583584return;585}586587png_ptr->idat_size = png_ptr->push_length;588}589590if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)591{592size_t save_size = png_ptr->save_buffer_size;593png_uint_32 idat_size = png_ptr->idat_size;594595/* We want the smaller of 'idat_size' and 'current_buffer_size', but they596* are of different types and we don't know which variable has the fewest597* bits. Carefully select the smaller and cast it to the type of the598* larger - this cannot overflow. Do not cast in the following test - it599* will break on either 16-bit or 64-bit platforms.600*/601if (idat_size < save_size)602save_size = (size_t)idat_size;603604else605idat_size = (png_uint_32)save_size;606607png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);608609png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);610611png_ptr->idat_size -= idat_size;612png_ptr->buffer_size -= save_size;613png_ptr->save_buffer_size -= save_size;614png_ptr->save_buffer_ptr += save_size;615}616617if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0)618{619size_t save_size = png_ptr->current_buffer_size;620png_uint_32 idat_size = png_ptr->idat_size;621622/* We want the smaller of 'idat_size' and 'current_buffer_size', but they623* are of different types and we don't know which variable has the fewest624* bits. Carefully select the smaller and cast it to the type of the625* larger - this cannot overflow.626*/627if (idat_size < save_size)628save_size = (size_t)idat_size;629630else631idat_size = (png_uint_32)save_size;632633png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);634635png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);636637png_ptr->idat_size -= idat_size;638png_ptr->buffer_size -= save_size;639png_ptr->current_buffer_size -= save_size;640png_ptr->current_buffer_ptr += save_size;641}642643if (png_ptr->idat_size == 0)644{645PNG_PUSH_SAVE_BUFFER_IF_LT(4)646png_crc_finish(png_ptr, 0);647png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;648png_ptr->mode |= PNG_AFTER_IDAT;649png_ptr->zowner = 0;650}651}652653void /* PRIVATE */654png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,655size_t buffer_length)656{657/* The caller checks for a non-zero buffer length. */658if (!(buffer_length > 0) || buffer == NULL)659png_error(png_ptr, "No IDAT data (internal error)");660661/* This routine must process all the data it has been given662* before returning, calling the row callback as required to663* handle the uncompressed results.664*/665png_ptr->zstream.next_in = buffer;666/* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */667png_ptr->zstream.avail_in = (uInt)buffer_length;668669/* Keep going until the decompressed data is all processed670* or the stream marked as finished.671*/672while (png_ptr->zstream.avail_in > 0 &&673(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)674{675int ret;676677/* We have data for zlib, but we must check that zlib678* has someplace to put the results. It doesn't matter679* if we don't expect any results -- it may be the input680* data is just the LZ end code.681*/682if (!(png_ptr->zstream.avail_out > 0))683{684/* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */685png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,686png_ptr->iwidth) + 1);687688png_ptr->zstream.next_out = png_ptr->row_buf;689}690691/* Using Z_SYNC_FLUSH here means that an unterminated692* LZ stream (a stream with a missing end code) can still693* be handled, otherwise (Z_NO_FLUSH) a future zlib694* implementation might defer output and therefore695* change the current behavior (see comments in inflate.c696* for why this doesn't happen at present with zlib 1.2.5).697*/698ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH);699700/* Check for any failure before proceeding. */701if (ret != Z_OK && ret != Z_STREAM_END)702{703/* Terminate the decompression. */704png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;705png_ptr->zowner = 0;706707/* This may be a truncated stream (missing or708* damaged end code). Treat that as a warning.709*/710if (png_ptr->row_number >= png_ptr->num_rows ||711png_ptr->pass > 6)712png_warning(png_ptr, "Truncated compressed data in IDAT");713714else715{716if (ret == Z_DATA_ERROR)717png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch");718else719png_error(png_ptr, "Decompression error in IDAT");720}721722/* Skip the check on unprocessed input */723return;724}725726/* Did inflate output any data? */727if (png_ptr->zstream.next_out != png_ptr->row_buf)728{729/* Is this unexpected data after the last row?730* If it is, artificially terminate the LZ output731* here.732*/733if (png_ptr->row_number >= png_ptr->num_rows ||734png_ptr->pass > 6)735{736/* Extra data. */737png_warning(png_ptr, "Extra compressed data in IDAT");738png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;739png_ptr->zowner = 0;740741/* Do no more processing; skip the unprocessed742* input check below.743*/744return;745}746747/* Do we have a complete row? */748if (png_ptr->zstream.avail_out == 0)749png_push_process_row(png_ptr);750}751752/* And check for the end of the stream. */753if (ret == Z_STREAM_END)754png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;755}756757/* All the data should have been processed, if anything758* is left at this point we have bytes of IDAT data759* after the zlib end code.760*/761if (png_ptr->zstream.avail_in > 0)762png_warning(png_ptr, "Extra compression data in IDAT");763}764765void /* PRIVATE */766png_push_process_row(png_structrp png_ptr)767{768/* 1.5.6: row_info moved out of png_struct to a local here. */769png_row_info row_info;770771row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */772row_info.color_type = png_ptr->color_type;773row_info.bit_depth = png_ptr->bit_depth;774row_info.channels = png_ptr->channels;775row_info.pixel_depth = png_ptr->pixel_depth;776row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);777778if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)779{780if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)781png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,782png_ptr->prev_row + 1, png_ptr->row_buf[0]);783else784png_error(png_ptr, "bad adaptive filter value");785}786787/* libpng 1.5.6: the following line was copying png_ptr->rowbytes before788* 1.5.6, while the buffer really is this big in current versions of libpng789* it may not be in the future, so this was changed just to copy the790* interlaced row count:791*/792memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);793794#ifdef PNG_READ_TRANSFORMS_SUPPORTED795if (png_ptr->transformations != 0)796png_do_read_transformations(png_ptr, &row_info);797#endif798799/* The transformed pixel depth should match the depth now in row_info. */800if (png_ptr->transformed_pixel_depth == 0)801{802png_ptr->transformed_pixel_depth = row_info.pixel_depth;803if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)804png_error(png_ptr, "progressive row overflow");805}806807else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)808png_error(png_ptr, "internal progressive row size calculation error");809810811#ifdef PNG_READ_INTERLACING_SUPPORTED812/* Expand interlaced rows to full size */813if (png_ptr->interlaced != 0 &&814(png_ptr->transformations & PNG_INTERLACE) != 0)815{816if (png_ptr->pass < 6)817png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,818png_ptr->transformations);819820switch (png_ptr->pass)821{822case 0:823{824int i;825for (i = 0; i < 8 && png_ptr->pass == 0; i++)826{827png_push_have_row(png_ptr, png_ptr->row_buf + 1);828png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */829}830831if (png_ptr->pass == 2) /* Pass 1 might be empty */832{833for (i = 0; i < 4 && png_ptr->pass == 2; i++)834{835png_push_have_row(png_ptr, NULL);836png_read_push_finish_row(png_ptr);837}838}839840if (png_ptr->pass == 4 && png_ptr->height <= 4)841{842for (i = 0; i < 2 && png_ptr->pass == 4; i++)843{844png_push_have_row(png_ptr, NULL);845png_read_push_finish_row(png_ptr);846}847}848849if (png_ptr->pass == 6 && png_ptr->height <= 4)850{851png_push_have_row(png_ptr, NULL);852png_read_push_finish_row(png_ptr);853}854855break;856}857858case 1:859{860int i;861for (i = 0; i < 8 && png_ptr->pass == 1; i++)862{863png_push_have_row(png_ptr, png_ptr->row_buf + 1);864png_read_push_finish_row(png_ptr);865}866867if (png_ptr->pass == 2) /* Skip top 4 generated rows */868{869for (i = 0; i < 4 && png_ptr->pass == 2; i++)870{871png_push_have_row(png_ptr, NULL);872png_read_push_finish_row(png_ptr);873}874}875876break;877}878879case 2:880{881int i;882883for (i = 0; i < 4 && png_ptr->pass == 2; i++)884{885png_push_have_row(png_ptr, png_ptr->row_buf + 1);886png_read_push_finish_row(png_ptr);887}888889for (i = 0; i < 4 && png_ptr->pass == 2; i++)890{891png_push_have_row(png_ptr, NULL);892png_read_push_finish_row(png_ptr);893}894895if (png_ptr->pass == 4) /* Pass 3 might be empty */896{897for (i = 0; i < 2 && png_ptr->pass == 4; i++)898{899png_push_have_row(png_ptr, NULL);900png_read_push_finish_row(png_ptr);901}902}903904break;905}906907case 3:908{909int i;910911for (i = 0; i < 4 && png_ptr->pass == 3; i++)912{913png_push_have_row(png_ptr, png_ptr->row_buf + 1);914png_read_push_finish_row(png_ptr);915}916917if (png_ptr->pass == 4) /* Skip top two generated rows */918{919for (i = 0; i < 2 && png_ptr->pass == 4; i++)920{921png_push_have_row(png_ptr, NULL);922png_read_push_finish_row(png_ptr);923}924}925926break;927}928929case 4:930{931int i;932933for (i = 0; i < 2 && png_ptr->pass == 4; i++)934{935png_push_have_row(png_ptr, png_ptr->row_buf + 1);936png_read_push_finish_row(png_ptr);937}938939for (i = 0; i < 2 && png_ptr->pass == 4; i++)940{941png_push_have_row(png_ptr, NULL);942png_read_push_finish_row(png_ptr);943}944945if (png_ptr->pass == 6) /* Pass 5 might be empty */946{947png_push_have_row(png_ptr, NULL);948png_read_push_finish_row(png_ptr);949}950951break;952}953954case 5:955{956int i;957958for (i = 0; i < 2 && png_ptr->pass == 5; i++)959{960png_push_have_row(png_ptr, png_ptr->row_buf + 1);961png_read_push_finish_row(png_ptr);962}963964if (png_ptr->pass == 6) /* Skip top generated row */965{966png_push_have_row(png_ptr, NULL);967png_read_push_finish_row(png_ptr);968}969970break;971}972973default:974case 6:975{976png_push_have_row(png_ptr, png_ptr->row_buf + 1);977png_read_push_finish_row(png_ptr);978979if (png_ptr->pass != 6)980break;981982png_push_have_row(png_ptr, NULL);983png_read_push_finish_row(png_ptr);984}985}986}987else988#endif989{990png_push_have_row(png_ptr, png_ptr->row_buf + 1);991png_read_push_finish_row(png_ptr);992}993}994995void /* PRIVATE */996png_read_push_finish_row(png_structrp png_ptr)997{998#ifdef PNG_READ_INTERLACING_SUPPORTED999/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */10001001/* Start of interlace block */1002static const png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};10031004/* Offset to next interlace block */1005static const png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};10061007/* Start of interlace block in the y direction */1008static const png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};10091010/* Offset to next interlace block in the y direction */1011static const png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};10121013/* Height of interlace block. This is not currently used - if you need1014* it, uncomment it here and in png.h1015static const png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};1016*/1017#endif10181019png_ptr->row_number++;1020if (png_ptr->row_number < png_ptr->num_rows)1021return;10221023#ifdef PNG_READ_INTERLACING_SUPPORTED1024if (png_ptr->interlaced != 0)1025{1026png_ptr->row_number = 0;1027memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);10281029do1030{1031png_ptr->pass++;1032if ((png_ptr->pass == 1 && png_ptr->width < 5) ||1033(png_ptr->pass == 3 && png_ptr->width < 3) ||1034(png_ptr->pass == 5 && png_ptr->width < 2))1035png_ptr->pass++;10361037if (png_ptr->pass > 7)1038png_ptr->pass--;10391040if (png_ptr->pass >= 7)1041break;10421043png_ptr->iwidth = (png_ptr->width +1044png_pass_inc[png_ptr->pass] - 1 -1045png_pass_start[png_ptr->pass]) /1046png_pass_inc[png_ptr->pass];10471048if ((png_ptr->transformations & PNG_INTERLACE) != 0)1049break;10501051png_ptr->num_rows = (png_ptr->height +1052png_pass_yinc[png_ptr->pass] - 1 -1053png_pass_ystart[png_ptr->pass]) /1054png_pass_yinc[png_ptr->pass];10551056} while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);1057}1058#endif /* READ_INTERLACING */1059}10601061void /* PRIVATE */1062png_push_have_info(png_structrp png_ptr, png_inforp info_ptr)1063{1064if (png_ptr->info_fn != NULL)1065(*(png_ptr->info_fn))(png_ptr, info_ptr);1066}10671068void /* PRIVATE */1069png_push_have_end(png_structrp png_ptr, png_inforp info_ptr)1070{1071if (png_ptr->end_fn != NULL)1072(*(png_ptr->end_fn))(png_ptr, info_ptr);1073}10741075void /* PRIVATE */1076png_push_have_row(png_structrp png_ptr, png_bytep row)1077{1078if (png_ptr->row_fn != NULL)1079(*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,1080(int)png_ptr->pass);1081}10821083#ifdef PNG_READ_INTERLACING_SUPPORTED1084void PNGAPI1085png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,1086png_const_bytep new_row)1087{1088if (png_ptr == NULL)1089return;10901091/* new_row is a flag here - if it is NULL then the app callback was called1092* from an empty row (see the calls to png_struct::row_fn below), otherwise1093* it must be png_ptr->row_buf+11094*/1095if (new_row != NULL)1096png_combine_row(png_ptr, old_row, 1/*blocky display*/);1097}1098#endif /* READ_INTERLACING */10991100void PNGAPI1101png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,1102png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,1103png_progressive_end_ptr end_fn)1104{1105if (png_ptr == NULL)1106return;11071108png_ptr->info_fn = info_fn;1109png_ptr->row_fn = row_fn;1110png_ptr->end_fn = end_fn;11111112png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);1113}11141115png_voidp PNGAPI1116png_get_progressive_ptr(png_const_structrp png_ptr)1117{1118if (png_ptr == NULL)1119return (NULL);11201121return png_ptr->io_ptr;1122}1123#endif /* PROGRESSIVE_READ */112411251126