CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/ext/libpng17/pngread.c
Views: 1401
1/* pngread.c - read a PNG file2*3* Last changed in libpng 1.7.0 [(PENDING RELEASE)]4* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson5* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)6* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)7*8* This code is released under the libpng license.9* For conditions of distribution and use, see the disclaimer10* and license in png.h11*12* This file contains routines that an application calls directly to13* read a PNG file or stream.14*/1516#include "pngpriv.h"17#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)18# include <errno.h>19#endif20#define PNG_SRC_FILE PNG_SRC_FILE_pngread2122#ifdef PNG_READ_SUPPORTED23/* Create a PNG structure for reading, and allocate any memory needed. */24PNG_FUNCTION(png_structp,PNGAPI25png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,26png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)27{28#ifndef PNG_USER_MEM_SUPPORTED29png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,30error_fn, warn_fn, NULL, NULL, NULL);31#else32return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,33warn_fn, NULL, NULL, NULL);34}3536/* Alternate create PNG structure for reading, and allocate any memory37* needed.38*/39PNG_FUNCTION(png_structp,PNGAPI40png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,41png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,42png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)43{44png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,45error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);46#endif /* USER_MEM */4748if (png_ptr != NULL)49{50png_ptr->read_struct = 1;51png_ptr->critical_crc = crc_error_quit;52png_ptr->ancillary_crc = crc_warn_discard;5354# ifdef PNG_BENIGN_ERRORS_SUPPORTED55# if !PNG_RELEASE_BUILD56/* Always quit on error prior to release */57png_ptr->benign_error_action = PNG_ERROR;58png_ptr->app_warning_action = PNG_WARN;59png_ptr->app_error_action = PNG_ERROR;60# else /* RELEASE_BUILD */61/* Allow benign errors on read, subject to app control. */62png_ptr->benign_error_action = PNG_WARN;63# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED64png_ptr->app_error_action = PNG_WARN;65png_ptr->app_warning_action = PNG_WARN;66# else /* !BENIGN_READ_ERRORS */67/* libpng build without benign error support; the application68* author has to be assumed to be correct, so:69*/70png_ptr->app_warning_action = PNG_WARN;71png_ptr->app_error_action = PNG_ERROR;72# endif /* !BENIGN_READ_ERRORS */73# endif /* RELEASE_BUILD */7475/* This is always png_error unless explicitly changed: */76png_ptr->IDAT_error_action = PNG_ERROR;77# endif /* BENIGN_ERRORS */7879# ifdef PNG_SEQUENTIAL_READ_SUPPORTED80png_ptr->IDAT_size = PNG_IDAT_READ_SIZE;81# endif /* SEQUENTIAL_READ */8283# ifdef PNG_READ_GAMMA_SUPPORTED84/* Default gamma correction values: */85# if 0 /*NYI*/86png_ptr->gamma_accuracy = PNG_DEFAULT_GAMMA_ACCURACY;87# endif /*NYI*/88png_ptr->gamma_threshold = PNG_GAMMA_THRESHOLD_FIXED;89# endif /* READ_GAMMA */90}9192return png_ptr;93}949596#ifdef PNG_SEQUENTIAL_READ_SUPPORTED97/* Read the chunk header (length + type name).98* Put the type name into png_ptr->chunk_name, and return the length.99*/100static void101png_read_chunk_header(png_structrp png_ptr)102{103png_byte buf[8];104105#ifdef PNG_IO_STATE_SUPPORTED106png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;107#endif108109/* Read the length and the chunk name.110* This must be performed in a single I/O call.111*/112png_read_data(png_ptr, buf, 8);113114/* Put the chunk name into png_ptr->chunk_name. */115png_ptr->chunk_length = png_get_uint_31(png_ptr, buf);116png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);117118png_debug2(0, "Reading %lx chunk, length = %lu",119(unsigned long)png_ptr->chunk_name,120(unsigned long)png_ptr->chunk_length);121122/* Reset the crc and run it over the chunk name. */123png_reset_crc(png_ptr, buf + 4);124125#ifdef PNG_IO_STATE_SUPPORTED126png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;127#endif128}129130static void131png_read_sequential_unknown(png_structrp png_ptr, png_inforp info_ptr)132{133#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED134/* Read the data for an unknown chunk. The read buffer is used: */135png_bytep buffer = png_read_buffer(png_ptr, png_ptr->chunk_length,136PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)); /* error if critical */137138if (buffer != NULL)139{140if (png_ptr->chunk_length > 0U)141png_crc_read(png_ptr, buffer, png_ptr->chunk_length);142143png_crc_finish(png_ptr, 0);144png_handle_unknown(png_ptr, info_ptr, buffer);145}146147else /* out of memory on an ancillary chunk; skip the chunk */148#else /* !READ_UNKNOWN_CHUNKS */149/* or, no support for reading unknown chunks, so just skip it. */150PNG_UNUSED(info_ptr)151#endif /* !READ_UNKNOWN_CHUNKS */152png_crc_finish(png_ptr, png_ptr->chunk_length);153}154155/* Read the information before the actual image data. This has been156* changed in v0.90 to allow reading a file that already has the magic157* bytes read from the stream. You can tell libpng how many bytes have158* been read from the beginning of the stream (up to the maximum of 8)159* via png_set_sig_bytes(), and we will only check the remaining bytes160* here. The application can then have access to the signature bytes we161* read if it is determined that this isn't a valid PNG file.162*/163void PNGAPI164png_read_info(png_structrp png_ptr, png_inforp info_ptr)165{166png_debug(1, "in png_read_info");167168if (png_ptr == NULL || info_ptr == NULL)169return;170171/* Read and check the PNG file signature (this may do nothing if it has172* already been read.)173*/174png_read_sig(png_ptr, info_ptr);175176/* Loop reading chunks until an IDAT is encountered or we reach the end of177* the stream (IEND).178*179* Prior to 1.7.0 this function behaved very weirdly if called after the180* IDATs had been read; it would keep on reading chunks util it found181* another IDAT. This could cause it to read beyond IEND, damaging the182* state in the host stream. This is now caught by the check below.183*/184while ((png_ptr->mode & (PNG_HAVE_IEND|PNG_HAVE_IDAT)) == 0)185{186png_read_chunk_header(png_ptr);187switch (png_find_chunk_op(png_ptr))188{189default:190impossible("invalid chunk op");191/* FALL THROUGH */192case png_chunk_skip:193png_crc_finish(png_ptr, png_ptr->chunk_length);194break;195196case png_chunk_unknown:197png_read_sequential_unknown(png_ptr, info_ptr);198break;199200case png_chunk_process_all:201png_handle_chunk(png_ptr, info_ptr);202break;203204case png_chunk_process_part:205debug(png_ptr->mode & PNG_HAVE_IDAT);206return;207}208}209210/* The loop was ended by IDAT or IEND, but if an IEND was seen the read code211* (png_handle_position in pngrutil.c) should have errored out, therefore:212*/213#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED214affirm(png_ptr->chunk_name == png_IDAT && ((png_ptr->known_unknown)&1U));215#else216debug(png_ptr->chunk_name == png_IDAT);217impossible("unknown IDAT");218#endif219220/* And the code cannot have left it unread; it must have called one of the221* handlers, so we are skipping IDAT.222*/223}224225/* Initialize palette, background, etc, after transformations226* are set, but before any reading takes place. This allows227* the user to obtain a gamma-corrected palette, for example.228* If the user doesn't call this, we will do it ourselves.229*/230void PNGAPI231png_start_read_image(png_structrp png_ptr)232{233png_debug(1, "in png_start_read_image");234235if (png_ptr != NULL)236{237if (png_ptr->zowner != png_IDAT)238png_read_start_IDAT(png_ptr);239240/* New in 1.6.0 this avoids the bug of doing the initializations twice,241* it could be a warning but in practice it indicates that the app may242* have made png_get_ calls on png_ptr assuming that it hadn't been243* 'started'.244*/245else246png_app_error(png_ptr,247"png_start_read_image/png_read_update_info: duplicate call");248}249}250251static void252png_read_IDAT(png_structrp png_ptr)253{254/* Read more input data, up to png_struct::IDAT_size, stop at the end of the255* IDAT stream. pngset.c checks png_struct::IDAT_size to ensure that it will256* fit in a uInt.257*/258const uInt buffer_size = (uInt)/*SAFE*/png_ptr->IDAT_size;259uInt IDAT_size = 0;260png_bytep buffer =261png_read_buffer(png_ptr, buffer_size, 0/*error*/);262263png_ptr->zstream.next_in = buffer;264265while (png_ptr->chunk_name == png_IDAT && IDAT_size < buffer_size)266{267png_uint_32 l = png_ptr->chunk_length;268269while (l == 0) /* end of this IDAT */270{271png_crc_finish(png_ptr, 0);272png_read_chunk_header(png_ptr);273274if (png_ptr->chunk_name != png_IDAT) /* end of all IDAT */275{276png_ptr->mode |= PNG_AFTER_IDAT;277goto done;278}279280l = png_ptr->chunk_length;281}282283/* Read from the IDAT chunk into the buffer, up to png_struct::IDAT_size:284*/285if (l > buffer_size - IDAT_size) /* SAFE: while check */286l = buffer_size - IDAT_size;287288png_crc_read(png_ptr, buffer+IDAT_size, l);289IDAT_size += (uInt)/*SAFE*/l;290png_ptr->chunk_length -= l;291}292done:293294/* IDAT_size may be zero if the compressed image stream is truncated;295* this is likely given a broken PNG.296*/297png_ptr->zstream.next_in = buffer;298png_ptr->zstream.avail_in = IDAT_size;299}300301void PNGAPI302png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)303/* It is valid to call this API with both 'row' and 'dsp_row' NULL, all304* the processing gets done. This is only useful for, either, performance305* testing (but it skips png_combine_row) or if there is a user transform306* or user row callback which actually uses the row data.307*/308{309if (png_ptr == NULL)310return;311312png_debug2(1, "in png_read_row (row %lu, pass %d)",313(unsigned long)png_ptr->row_number, png_ptr->pass);314315/* Check the row number; if png_read_process_IDAT is called too many times316* if issues an affirm, but, while this is appropriate for the progressive317* reader, it is an app error if it happens here.318*319* Note that when the app does the interlace handling the last row will320* typically be before the last row in the image.321*/322if (png_ptr->read_started &&323(png_ptr->interlaced == PNG_INTERLACE_NONE ?324png_ptr->row_number == png_ptr->height-1U : (325# ifdef PNG_READ_INTERLACING_SUPPORTED326png_ptr->do_interlace ?327png_ptr->pass == 6U && png_ptr->row_number == png_ptr->height-1U :328# endif /* READ_INTERLACING */329png_ptr->pass == PNG_LAST_PASS(png_ptr->width, png_ptr->height) &&330PNG_LAST_PASS_ROW(png_ptr->row_number, png_ptr->pass,331png_ptr->height)332)333))334{335png_app_error(png_ptr, "Too many calls to png_read_row");336return;337}338339/* Check this right at the start; functions like png_read_process_IDAT340* regard this condition as an internal error:341*/342if (png_ptr->zowner != png_IDAT)343png_read_start_IDAT(png_ptr);344345/* So reading has started: */346png_ptr->read_started = 1;347348for (;;)349{350if (png_ptr->zstream.avail_in == 0)351png_read_IDAT(png_ptr);352353/* So... zstream.next_in may still be 0, but this may be enough for the354* next row if zlib is storing enough output state (it only need be enough355* for one byte, because png_read_process_IDAT keeps the next filter byte,356* so on the last row of the image only one byte might be required.)357*358* png_read_process_IDAT handles the case where the input has ended; mode359* has PNG_AFTER_IDAT set, by either doing png_error or using 0 bytes for360* the data (after issuing a warning.)361*/362switch (png_read_process_IDAT(png_ptr, row, dsp_row, 0/*no save*/))363{364case png_row_incomplete:365/* more IDAT data needed for row */366debug(png_ptr->zstream.avail_in == 0);367continue;368369case png_row_repeat:370/* row not in this pass, but the existing row in row_buffer or (if371* transforms are happening) png_struct::transformed_row is372* available from a previous row.373*/374/* FALL THROUGH */375case png_row_skip:376/* row not in pass and no appropriate data; skip this row, nothing377* more need be done, except the read_row_fn and then only if libpng378* is doing the interlace handling (this is the historical379* behavior!)380*/381# ifdef PNG_READ_INTERLACING_SUPPORTED382if (!png_ptr->do_interlace) continue;383# else /* !do_interlace */384continue;385# endif /* !do_interlace */386/* FALL THROUGH */387case png_row_process:388/* png_read_process_IDAT has done everything we need, the only extra389* required is to call the application row callback.390*/391if (png_ptr->read_row_fn != NULL)392png_ptr->read_row_fn(png_ptr, png_ptr->row_number,393png_ptr->pass);394/* And return now because the next row has been processed; so there395* is exactly one read_row_fn callback for each call to396* png_read_process_IDAT.397*/398return;399400default:401impossible("not reached");402}403}404}405406/* Read one or more rows of image data. If the image is interlaced,407* and png_set_interlace_handling() has been called, the rows need to408* contain the contents of the rows from the previous pass. If the409* image has alpha or transparency, and png_handle_alpha()[*] has been410* called, the rows contents must be initialized to the contents of the411* screen.412*413* "row" holds the actual image, and pixels are placed in it414* as they arrive. If the image is displayed after each pass, it will415* appear to "sparkle" in. "display_row" can be used to display a416* "chunky" progressive image, with finer detail added as it becomes417* available. If you do not want this "chunky" display, you may pass418* NULL for display_row. If you do not want the sparkle display, and419* you have not called png_handle_alpha(), you may pass NULL for rows.420* If you have called png_handle_alpha(), and the image has either an421* alpha channel or a transparency chunk, you must provide a buffer for422* rows. In this case, you do not have to provide a display_row buffer423* also, but you may. If the image is not interlaced, or if you have424* not called png_set_interlace_handling(), the display_row buffer will425* be ignored, so pass NULL to it.426*427* [*] png_handle_alpha() does not exist yet, as of this version of libpng428*/429430void PNGAPI431png_read_rows(png_structrp png_ptr, png_bytepp row,432png_bytepp display_row, png_uint_32 num_rows)433{434png_uint_32 i;435png_bytepp rp;436png_bytepp dp;437438png_debug(1, "in png_read_rows");439440if (png_ptr == NULL)441return;442443rp = row;444dp = display_row;445if (rp != NULL && dp != NULL)446for (i = 0; i < num_rows; i++)447{448png_bytep rptr = *rp++;449png_bytep dptr = *dp++;450451png_read_row(png_ptr, rptr, dptr);452}453454else if (rp != NULL)455for (i = 0; i < num_rows; i++)456{457png_bytep rptr = *rp;458png_read_row(png_ptr, rptr, NULL);459rp++;460}461462else if (dp != NULL)463for (i = 0; i < num_rows; i++)464{465png_bytep dptr = *dp;466png_read_row(png_ptr, NULL, dptr);467dp++;468}469}470#endif /* SEQUENTIAL_READ */471472#ifdef PNG_READ_IMAGE_SUPPORTED473/* Read the entire image. If the image has an alpha channel or a tRNS474* chunk, and you have called png_handle_alpha()[*], you will need to475* initialize the image to the current image that PNG will be overlaying.476* We set the num_rows again here, in case it was incorrectly set in477* png_read_start_IDAT() by a call to png_read_update_info() or478* png_start_read_image() if png_set_interlace_handling() wasn't called479* prior to either of these functions like it should have been. You can480* only call this function once. If you desire to have an image for481* each pass of a interlaced image, use png_read_rows() instead.482*483* [*] png_handle_alpha() does not exist yet, as of this version of libpng484*/485void PNGAPI486png_read_image(png_structrp png_ptr, png_bytepp image)487{488png_uint_32 image_height;489int pass, j;490491png_debug(1, "in png_read_image");492493if (png_ptr == NULL)494return;495496if (png_ptr->zowner != png_IDAT)497pass = png_set_interlace_handling(png_ptr);498499else500{501if (png_ptr->interlaced == 0)502pass = 1;503504else505pass = PNG_INTERLACE_ADAM7_PASSES;506}507508for (j = 0, image_height = png_ptr->height; j < pass; ++j)509{510png_bytepp rp = image;511png_uint_32 i;512513for (i = 0; i < image_height; i++)514{515png_read_row(png_ptr, *rp, NULL);516rp++;517}518}519}520#endif /* READ_IMAGE */521522#ifdef PNG_SEQUENTIAL_READ_SUPPORTED523/* Read the end of the PNG file. Will not read past the end of the524* file, will verify the end is accurate, and will read any comments525* or time information at the end of the file, if info is not NULL.526*/527void PNGAPI528png_read_end(png_structrp png_ptr, png_inforp info_ptr)529{530png_debug(1, "in png_read_end");531532if (png_ptr == NULL)533return;534535/* When this routine is entered it is possible that an IDAT chunk still536* remains to be read. There are three conditions:537*538* 1) The app decided to handle IDAT as unknown, libpng will have consumed539* the first IDAT in png_read_info, the rest will be consumed as normal540* chunks by calls to png_handle_chunk below.541*542* 2) The app did not start to read an image, so png_read_start_IDAT was543* not called and png_struct::zowner is not png_IDAT. The first IDAT544* must still be skipped then the code below will skip the remainder.545*546* 3) The app did start to read the image. png_struct::zowner is png_IDAT547* and we need to close down the IDAT reading code. There may also be548* pending IDAT chunks, these are passed to png_read_finish_IDAT here so549* that error detection happens. If the app didn't read all the rows550* libpng will issue an 'extra compressed data' error, we could supress551* that by warning that not all the rows have been read and setting552* png_struct::zstream_error if necessary.553*/554# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED555if (!(png_ptr->known_unknown & 1U))556# endif557{558if (png_ptr->zowner == png_IDAT)559{560/* Normal case: read to the end of the IDAT chunks. In about561* 5/PNG_IDAT_READ_SIZE cases (typically that's 1:820) zlib will have562* returned all the image data but not read up to the end of the563* Adler32 because the end of the stream had not been read. Make sure564* it gets read here:565*/566if (png_ptr->zstream.avail_in == 0)567png_read_IDAT(png_ptr);568569while (!png_read_finish_IDAT(png_ptr)) {570/* This will adjust zstream.next/avail_in appropriately and if571* necessary read the next chunk. After this avail_in may still572* be zero, but if it is then PNG_AFTER_IDAT should be set.573*/574debug(png_ptr->zstream.avail_in == 0);575png_read_IDAT(png_ptr);576debug(png_ptr->zstream.avail_in > 0 ||577(png_ptr->mode & PNG_AFTER_IDAT) != 0);578}579580debug(png_ptr->zstream.avail_in == 0 && png_ptr->zowner == 0);581582/* If this is still an IDAT then it hasn't been finished; at least583* the CRC has not been read. If there is data left in it then584* an error may need to be output. Note that the code below handles585* any additional chunks.586*/587if (png_ptr->chunk_name == png_IDAT)588{589if (png_ptr->chunk_length > 0 && !png_ptr->zstream_error)590{591png_chunk_benign_error(png_ptr, "too much IDAT data (read)");592png_ptr->zstream_error = 1;593}594595png_crc_finish(png_ptr, png_ptr->chunk_length);596png_read_chunk_header(png_ptr);597}598}599600else if (png_ptr->chunk_name == png_IDAT)601{602/* This IDAT has not been processed, the remainder will be finished603* in the loop. This is the case where IDAT is being skipped because604* the rows weren't read, this is OK, but warn anyway.605*/606png_crc_finish(png_ptr, png_ptr->chunk_length);607png_app_warning(png_ptr, "image reading skipped");608png_ptr->zstream_error = 1; /* Prevent 'too much IDAT' errors */609png_read_chunk_header(png_ptr);610}611612else /* This might work, if the signature was read, but just in case: */613png_app_error(png_ptr, "Missing call to png_read_info");614}615616# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED617else618{619/* IDAT is unknown, the chunk that terminated the loop must be an IDAT620* and it has been processed. Get a new chunk header.621*/622if (png_ptr->chunk_name == png_IDAT)623png_read_chunk_header(png_ptr);624625else626png_app_error(png_ptr,627"Missing call to png_read_info with unknown IDAT");628}629# endif630631if ((png_ptr->mode & PNG_HAVE_IEND) == 0) for (;;)632{633switch (png_find_chunk_op(png_ptr))634{635default:636impossible("invalid chunk op");637/* FALL THROUGH */638case png_chunk_skip:639png_crc_finish(png_ptr, png_ptr->chunk_length);640break;641642case png_chunk_unknown:643png_read_sequential_unknown(png_ptr, info_ptr);644break;645646case png_chunk_process_all:647png_handle_chunk(png_ptr, info_ptr);648break;649650case png_chunk_process_part:651debug(png_ptr->chunk_name == png_IDAT);652debug(!(png_ptr->mode & PNG_AFTER_IDAT));653if (png_ptr->chunk_length > 0 && !png_ptr->zstream_error)654{655png_chunk_benign_error(png_ptr, "too many IDAT chunks");656png_ptr->zstream_error = 1;657}658659/* Skip it: */660png_crc_finish(png_ptr, png_ptr->chunk_length);661return;662}663664if ((png_ptr->mode & PNG_HAVE_IEND) != 0)665break;666667png_read_chunk_header(png_ptr);668}669}670#endif /* SEQUENTIAL_READ */671672/* Free all memory used in the read struct */673static void674png_read_destroy(png_structrp png_ptr)675{676png_debug(1, "in png_read_destroy");677678png_read_free_row_buffers(png_ptr);679680png_free(png_ptr, png_ptr->read_buffer);681png_ptr->read_buffer = NULL;682683if (png_ptr->palette != NULL)684{685png_free(png_ptr, png_ptr->palette);686png_ptr->num_palette = 0;687png_ptr->palette = NULL;688}689690#ifdef PNG_READ_tRNS_SUPPORTED691if (png_ptr->trans_alpha != NULL)692{693png_free(png_ptr, png_ptr->trans_alpha);694png_ptr->num_trans = 0;695png_ptr->trans_alpha = NULL;696}697#endif698699if (png_ptr->zstream.state != NULL)700{701int ret = inflateEnd(&png_ptr->zstream);702703if (ret != Z_OK)704{705png_zstream_error(&png_ptr->zstream, ret);706png_warning(png_ptr, png_ptr->zstream.msg);707}708}709710#ifdef PNG_TRANSFORM_MECH_SUPPORTED711png_transform_free(png_ptr, &png_ptr->transform_list);712#endif713714#ifdef PNG_PROGRESSIVE_READ_SUPPORTED715png_free(png_ptr, png_ptr->save_buffer);716png_ptr->save_buffer = NULL;717#endif718719#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED720png_free(png_ptr, png_ptr->chunk_list);721png_ptr->chunk_list = NULL;722#endif723724/* NOTE: the 'setjmp' buffer may still be allocated and the memory and error725* callbacks are still set at this point. They are required to complete the726* destruction of the png_struct itself.727*/728}729730/* Free all memory used by the read */731void PNGAPI732png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,733png_infopp end_info_ptr_ptr)734{735png_structrp png_ptr = NULL;736737png_debug(1, "in png_destroy_read_struct");738739if (png_ptr_ptr != NULL)740png_ptr = *png_ptr_ptr;741742if (png_ptr == NULL)743return;744745/* libpng 1.6.0: use the API to destroy info structs to ensure consistent746* behavior. Prior to 1.6.0 libpng did extra 'info' destruction in this API.747* The extra was, apparently, unnecessary yet this hides memory leak bugs.748*/749png_destroy_info_struct(png_ptr, end_info_ptr_ptr);750png_destroy_info_struct(png_ptr, info_ptr_ptr);751752*png_ptr_ptr = NULL;753png_read_destroy(png_ptr);754png_destroy_png_struct(png_ptr);755}756757void PNGAPI758png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn)759{760if (png_ptr == NULL)761return;762763png_ptr->read_row_fn = read_row_fn;764}765766767#ifdef PNG_READ_PNG_SUPPORTED768#ifdef __GNUC__769/* This exists solely to work round a warning from GNU C. */770static int /* PRIVATE */771png_gt(size_t a, size_t b)772{773return a > b;774}775#else776# define png_gt(a,b) ((a) > (b))777#endif778779void PNGAPI780png_read_png(png_structrp png_ptr, png_inforp info_ptr, int transforms,781voidp params)782{783if (png_ptr == NULL || info_ptr == NULL)784return;785786/* png_read_info() gives us all of the information from the787* PNG file before the first IDAT (image data chunk).788*/789png_read_info(png_ptr, info_ptr);790if (png_gt(info_ptr->height, PNG_SIZE_MAX/(sizeof (png_bytep))))791png_error(png_ptr, "Image is too high to process with png_read_png()");792793/* -------------- image transformations start here ------------------- */794/* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM795* is not implemented. This will only happen in de-configured (non-default)796* libpng builds. The results can be unexpected - png_read_png may return797* short or mal-formed rows because the transform is skipped.798*/799800/* Tell libpng to strip 16-bit/color files down to 8 bits per color.801*/802if ((transforms & PNG_TRANSFORM_SCALE_16) != 0)803/* Added at libpng-1.5.4. "strip_16" produces the same result that it804* did in earlier versions, while "scale_16" is now more accurate.805*/806#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED807png_set_scale_16(png_ptr);808#else809png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported");810#endif811812/* If both SCALE and STRIP are required pngrtran will effectively cancel the813* latter by doing SCALE first. This is ok and allows apps not to check for814* which is supported to get the right answer.815*/816if ((transforms & PNG_TRANSFORM_STRIP_16) != 0)817#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED818png_set_strip_16(png_ptr);819#else820png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported");821#endif822823/* Strip alpha bytes from the input data without combining with824* the background (not recommended).825*/826if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0)827#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED828png_set_strip_alpha(png_ptr);829#else830png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported");831#endif832833/* Extract multiple pixels with bit depths of 1, 2, or 4 from a single834* byte into separate bytes (useful for paletted and grayscale images).835*/836if ((transforms & PNG_TRANSFORM_PACKING) != 0)837#ifdef PNG_READ_PACK_SUPPORTED838png_set_packing(png_ptr);839#else840png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");841#endif842843/* Change the order of packed pixels to least significant bit first844* (not useful if you are using png_set_packing).845*/846if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)847#ifdef PNG_READ_PACKSWAP_SUPPORTED848png_set_packswap(png_ptr);849#else850png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");851#endif852853/* Expand paletted colors into true RGB triplets854* Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel855* Expand paletted or RGB images with transparency to full alpha856* channels so the data will be available as RGBA quartets.857*/858if ((transforms & PNG_TRANSFORM_EXPAND) != 0)859#ifdef PNG_READ_EXPAND_SUPPORTED860png_set_expand(png_ptr);861#else862png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported");863#endif864865/* We don't handle background color, gamma transformation, or quantizing. */866867/* Invert monochrome files to have 0 as white and 1 as black */868if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)869#ifdef PNG_READ_INVERT_SUPPORTED870png_set_invert_mono(png_ptr);871#else872png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");873#endif874875/* If you want to shift the pixel values from the range [0,255] or876* [0,65535] to the original [0,7] or [0,31], or whatever range the877* colors were originally in:878*/879if ((transforms & PNG_TRANSFORM_SHIFT) != 0)880#ifdef PNG_READ_SHIFT_SUPPORTED881if ((info_ptr->valid & PNG_INFO_sBIT) != 0)882png_set_shift(png_ptr, &info_ptr->sig_bit);883#else884png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");885#endif886887/* Flip the RGB pixels to BGR (or RGBA to BGRA) */888if ((transforms & PNG_TRANSFORM_BGR) != 0)889#ifdef PNG_READ_BGR_SUPPORTED890png_set_bgr(png_ptr);891#else892png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");893#endif894895/* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */896if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)897#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED898png_set_swap_alpha(png_ptr);899#else900png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");901#endif902903/* Swap bytes of 16-bit files to least significant byte first */904if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)905#ifdef PNG_READ_SWAP_SUPPORTED906png_set_swap(png_ptr);907#else908png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");909#endif910911/* Added at libpng-1.2.41 */912/* Invert the alpha channel from opacity to transparency */913if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)914#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED915png_set_invert_alpha(png_ptr);916#else917png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");918#endif919920/* Added at libpng-1.2.41 */921/* Expand grayscale image to RGB */922if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0)923#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED924png_set_gray_to_rgb(png_ptr);925#else926png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported");927#endif928929/* Added at libpng-1.5.4 */930if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0)931#ifdef PNG_READ_EXPAND_16_SUPPORTED932png_set_expand_16(png_ptr);933#else934png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported");935#endif936937/* We don't handle adding filler bytes */938939/* We use png_read_image and rely on that for interlace handling, but we also940* call png_read_update_info therefore must turn on interlace handling now:941*/942(void)png_set_interlace_handling(png_ptr);943944/* Optional call to gamma correct and add the background to the palette945* and update info structure. REQUIRED if you are expecting libpng to946* update the palette for you (i.e., you selected such a transform above).947*/948png_read_update_info(png_ptr, info_ptr);949950/* -------------- image transformations end here ------------------- */951952png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);953if (info_ptr->row_pointers == NULL)954{955png_uint_32 iptr;956png_alloc_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);957958info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr,959info_ptr->height * (sizeof (png_bytep))));960961for (iptr=0; iptr<info_ptr->height; iptr++)962info_ptr->row_pointers[iptr] = NULL;963964info_ptr->free_me |= PNG_FREE_ROWS;965966for (iptr = 0; iptr < info_ptr->height; iptr++)967info_ptr->row_pointers[iptr] = png_voidcast(png_bytep,968png_malloc(png_ptr, rowbytes));969}970971png_read_image(png_ptr, info_ptr->row_pointers);972info_ptr->valid |= PNG_INFO_IDAT;973974/* Read rest of file, and get additional chunks in info_ptr - REQUIRED */975png_read_end(png_ptr, info_ptr);976977PNG_UNUSED(params)978}979#endif /* READ_PNG */980981#ifdef PNG_SIMPLIFIED_READ_SUPPORTED982/* SIMPLIFIED READ983*984* This code currently relies on the sequential reader, though it could easily985* be made to work with the progressive one.986*/987/* Arguments to png_image_finish_read: */988989/* Encoding of PNG data (used by the color-map code) */990# define P_NOTSET 0 /* File encoding not yet known */991# define P_sRGB 1 /* 8-bit encoded to sRGB gamma */992# define P_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */993# define P_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */994# define P_LINEAR8 4 /* 8-bit linear: only from a file value */995# define P_FILE8 5 /* 8-bit encoded to file gamma but not significant bits */996997/* Color-map processing: after libpng has run on the PNG image further998* processing may be needed to convert the data to color-map indices.999*/1000#define PNG_CMAP_NONE 01001#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */1002#define PNG_CMAP_TRANS 2 /* Process GA data to a background index */1003#define PNG_CMAP_RGB 3 /* Process RGB data */1004#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */10051006/* The following document where the background is for each processing case. */1007#define PNG_CMAP_NONE_BACKGROUND 2561008#define PNG_CMAP_GA_BACKGROUND 2311009#define PNG_CMAP_TRANS_BACKGROUND 2541010#define PNG_CMAP_RGB_BACKGROUND 2561011#define PNG_CMAP_RGB_ALPHA_BACKGROUND 21610121013typedef struct1014{1015/* Arguments: */1016png_imagep image;1017png_voidp buffer;1018ptrdiff_t row_stride;1019png_voidp colormap;1020png_const_colorp background;1021/* Local variables: */1022png_voidp local_row;1023png_voidp first_row;1024ptrdiff_t row_bytes; /* step between rows */1025int file_encoding; /* E_ values above */1026png_fixed_point file_to_sRGB; /* Cached correction factor */1027int colormap_processing; /* PNG_CMAP_ values above */1028png_byte sBIT[4]; /* Significant bits for channels */1029} png_image_read_control;10301031/* Do all the *safe* initialization - 'safe' means that png_error won't be1032* called, so setting up the jmp_buf is not required. This means that anything1033* called from here must *not* call png_malloc - it has to call png_malloc_warn1034* instead so that control is returned safely back to this routine.1035*/1036static int1037png_image_read_init(png_imagep image)1038{1039if (image->opaque == NULL)1040{1041png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image,1042png_safe_error, png_safe_warning);10431044/* And set the rest of the structure to NULL to ensure that the various1045* fields are consistent.1046*/1047memset(image, 0, (sizeof *image));1048image->version = PNG_IMAGE_VERSION;10491050if (png_ptr != NULL)1051{1052png_infop info_ptr = png_create_info_struct(png_ptr);10531054if (info_ptr != NULL)1055{1056png_controlp control = png_voidcast(png_controlp,1057png_malloc_warn(png_ptr, (sizeof *control)));10581059if (control != NULL)1060{1061memset(control, 0, (sizeof *control));10621063control->png_ptr = png_ptr;1064control->info_ptr = info_ptr;1065control->for_write = 0;10661067image->opaque = control;1068return 1;1069}10701071/* Error clean up */1072png_destroy_info_struct(png_ptr, &info_ptr);1073}10741075png_destroy_read_struct(&png_ptr, NULL, NULL);1076}10771078return png_image_error(image, "png_image_read: out of memory");1079}10801081return png_image_error(image, "png_image_read: opaque pointer not NULL");1082}10831084/* Utility to find the base format of a PNG file from a png_struct. */1085static png_uint_321086png_image_format(png_structrp png_ptr)1087{1088png_uint_32 format = 0;10891090if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)1091format |= PNG_FORMAT_FLAG_COLOR;10921093if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)1094format |= PNG_FORMAT_FLAG_ALPHA;10951096/* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS1097* sets the png_struct fields; that's all we are interested in here. The1098* precise interaction with an app call to png_set_tRNS and PNG file reading1099* is unclear.1100*/1101else if (png_ptr->num_trans > 0)1102format |= PNG_FORMAT_FLAG_ALPHA;11031104if (png_ptr->bit_depth == 16)1105format |= PNG_FORMAT_FLAG_LINEAR;11061107if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0)1108format |= PNG_FORMAT_FLAG_COLORMAP;11091110return format;1111}11121113/* Is the given gamma significantly different from sRGB?1114*/1115static int1116png_gamma_not_sRGB(png_fixed_point g)1117{1118/* An uninitialized gamma is assumed to be sRGB for the simplified API. */1119return g != 0 && !PNG_GAMMA_IS_sRGB(g);1120}11211122/* Do the main body of a 'png_image_begin_read' function; read the PNG file1123* header and fill in all the information. This is executed in a safe context,1124* unlike the init routine above.1125*/1126static int1127png_image_read_header(png_voidp argument)1128{1129png_imagep image = png_voidcast(png_imagep, argument);1130png_structrp png_ptr = image->opaque->png_ptr;1131png_inforp info_ptr = image->opaque->info_ptr;11321133#ifdef PNG_BENIGN_ERRORS_SUPPORTED1134png_set_benign_errors(png_ptr, 1/*warn*/);1135#endif1136png_read_info(png_ptr, info_ptr);11371138/* Do this the fast way; just read directly out of png_struct. */1139image->width = png_ptr->width;1140image->height = png_ptr->height;11411142{1143png_uint_32 format = png_image_format(png_ptr);11441145image->format = format;11461147#ifdef PNG_COLORSPACE_SUPPORTED1148/* Does the colorspace match sRGB? If there is no color endpoint1149* (colorant) information assume yes, otherwise require the1150* 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set. If the1151* colorspace has been determined to be invalid ignore it.1152*/1153if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags1154& (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB|1155PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS))1156image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB;1157#endif1158}11591160/* We need the maximum number of entries regardless of the format the1161* application sets here.1162*/1163{1164png_uint_32 cmap_entries;11651166switch (png_ptr->color_type)1167{1168case PNG_COLOR_TYPE_GRAY:1169cmap_entries = 1U << png_ptr->bit_depth;1170break;11711172case PNG_COLOR_TYPE_PALETTE:1173cmap_entries = png_ptr->num_palette;1174break;11751176default:1177cmap_entries = 256;1178break;1179}11801181if (cmap_entries > 256)1182cmap_entries = 256;11831184image->colormap_entries = cmap_entries;1185}11861187return 1;1188}11891190static void1191png_image_get_sBIT(png_image_read_control *display)1192/* Utility to cache the sBIT values. This uses the information from the1193* png_struct not png_info because it may be needed after the sBIT1194* information in png_info has been invalidated.1195*/1196{1197if (display->sBIT[0] == 0)1198{1199const png_const_structrp png_ptr = display->image->opaque->png_ptr;1200const unsigned int color_type = png_ptr->color_type;1201const png_byte bit_depth =1202(color_type & PNG_COLOR_MASK_PALETTE) ? 8U : png_ptr->bit_depth;12031204memset(display->sBIT, bit_depth, sizeof display->sBIT);12051206if (color_type & PNG_COLOR_MASK_COLOR)1207{1208if (png_ptr->sig_bit.red > 0 && png_ptr->sig_bit.red < bit_depth)1209display->sBIT[0] = png_ptr->sig_bit.red;1210if (png_ptr->sig_bit.green > 0 && png_ptr->sig_bit.green < bit_depth)1211display->sBIT[1] = png_ptr->sig_bit.green;1212if (png_ptr->sig_bit.blue > 0 && png_ptr->sig_bit.blue < bit_depth)1213display->sBIT[2] = png_ptr->sig_bit.blue;1214}12151216else1217{1218if (png_ptr->sig_bit.gray > 0 && png_ptr->sig_bit.gray < bit_depth)1219display->sBIT[2] = display->sBIT[1] = display->sBIT[0] =1220png_ptr->sig_bit.gray;1221}12221223if (color_type & PNG_COLOR_MASK_ALPHA)1224{1225if (png_ptr->sig_bit.alpha > 0 && png_ptr->sig_bit.alpha < bit_depth)1226display->sBIT[3] = png_ptr->sig_bit.alpha;1227}1228}1229}12301231#ifdef PNG_STDIO_SUPPORTED1232int PNGAPI1233png_image_begin_read_from_stdio(png_imagep image, FILE* file)1234{1235if (image != NULL && image->version == PNG_IMAGE_VERSION)1236{1237if (file != NULL)1238{1239if (png_image_read_init(image) != 0 &&1240png_image_init_io(image, file) != 0)1241return png_safe_execute(image, png_image_read_header, image);1242}12431244else1245return png_image_error(image,1246"png_image_begin_read_from_stdio: invalid argument");1247}12481249else if (image != NULL)1250return png_image_error(image,1251"png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");12521253return 0;1254}12551256int PNGAPI1257png_image_begin_read_from_file(png_imagep image, const char *file_name)1258{1259if (image != NULL && image->version == PNG_IMAGE_VERSION)1260{1261if (file_name != NULL)1262{1263FILE *fp = fopen(file_name, "rb");12641265if (fp != NULL)1266{1267if (png_image_read_init(image) != 0 &&1268png_image_init_io(image, fp) != 0)1269{1270image->opaque->owned_file = 1;1271return png_safe_execute(image, png_image_read_header, image);1272}12731274/* Clean up: just the opened file. */1275(void)fclose(fp);1276}12771278else1279return png_image_error(image, strerror(errno));1280}12811282else1283return png_image_error(image,1284"png_image_begin_read_from_file: invalid argument");1285}12861287else if (image != NULL)1288return png_image_error(image,1289"png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");12901291return 0;1292}1293#endif /* STDIO */12941295static void PNGCBAPI1296png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need)1297{1298if (png_ptr != NULL)1299{1300png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr);1301if (image != NULL)1302{1303png_controlp cp = image->opaque;1304if (cp != NULL)1305{1306png_const_bytep memory = cp->memory;1307png_size_t size = cp->size;13081309if (memory != NULL && size >= need)1310{1311memcpy(out, memory, need);1312cp->memory = memory + need;1313cp->size = size - need;1314return;1315}13161317png_error(png_ptr, "read beyond end of data");1318}1319}13201321png_error(png_ptr, "invalid memory read");1322}1323}13241325static int1326image_init_memory_io(png_voidp param)1327/* Set the read function and pointer for a memory read, the io pointer is1328* just the imagep so it is passed in directly.1329*/1330{1331png_imagep image = png_voidcast(png_imagep, param);1332png_set_read_fn(image->opaque->png_ptr, image, png_image_memory_read);1333return 1;1334}13351336int PNGAPI1337png_image_begin_read_from_memory(png_imagep image, png_const_voidp memory,1338png_size_t size)1339{1340if (image != NULL && image->version == PNG_IMAGE_VERSION)1341{1342if (memory != NULL && size > 0)1343{1344if (png_image_read_init(image) != 0)1345{1346/* Now set the IO functions to read from the memory buffer and1347* store it into io_ptr. Again do this in-place to avoid calling a1348* libpng function that requires error handling.1349*/1350image->opaque->memory = png_voidcast(png_const_bytep, memory);1351image->opaque->size = size;13521353return png_safe_execute(image, image_init_memory_io, image) &&1354png_safe_execute(image, png_image_read_header, image);1355}1356}13571358else1359return png_image_error(image,1360"png_image_begin_read_from_memory: invalid argument");1361}13621363else if (image != NULL)1364return png_image_error(image,1365"png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");13661367return 0;1368}13691370/* Utility function to skip chunks that are not used by the simplified image1371* read functions and an appropriate macro to call it.1372*/1373#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED1374static void1375png_image_skip_unused_chunks(png_structrp png_ptr)1376{1377/* Prepare the reader to ignore all recognized chunks whose data will not1378* be used, i.e., all chunks recognized by libpng except for those1379* involved in basic image reading:1380*1381* IHDR, PLTE, IDAT, IEND1382*1383* Or image data handling:1384*1385* tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT.1386*1387* This provides a small performance improvement and eliminates any1388* potential vulnerability to security problems in the unused chunks.1389*1390* At present the iCCP chunk data isn't used, so iCCP chunk can be ignored1391* too. This allows the simplified API to be compiled without iCCP support,1392* however if the support is there the chunk is still checked to detect1393* errors (which are unfortunately quite common.)1394*/1395{1396static PNG_CONST png_byte chunks_to_process[] = {139798, 75, 71, 68, '\0', /* bKGD */139899, 72, 82, 77, '\0', /* cHRM */1399103, 65, 77, 65, '\0', /* gAMA */1400# ifdef PNG_READ_iCCP_SUPPORTED1401105, 67, 67, 80, '\0', /* iCCP */1402# endif1403115, 66, 73, 84, '\0', /* sBIT */1404115, 82, 71, 66, '\0', /* sRGB */1405};14061407/* Ignore unknown chunks and all other chunks except for the1408* IHDR, PLTE, tRNS, IDAT, and IEND chunks.1409*/1410png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,1411NULL, -1);14121413/* But do not ignore image data handling chunks */1414png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,1415chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);1416}1417}14181419# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)1420#else1421# define PNG_SKIP_CHUNKS(p) ((void)0)1422#endif /* HANDLE_AS_UNKNOWN */14231424/* The following macro gives the exact rounded answer for all values in the1425* range 0..255 (it actually divides by 51.2, but the rounding still generates1426* the correct numbers 0..51427*/1428#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8)14291430/* Utility functions to make particular color-maps */1431static void1432set_file_encoding(png_image_read_control *display)1433{1434/* First test for an encoding close to linear: */1435if (png_need_gamma_correction(display->image->opaque->png_ptr,14360/*PNG gamma*/, 0/*not sRGB*/))1437{1438png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma;14391440/* Now look for one close to sRGB: */1441if (png_gamma_not_sRGB(g))1442display->file_encoding = P_FILE;14431444else1445display->file_encoding = P_sRGB;1446}14471448else1449display->file_encoding = P_LINEAR8;1450}14511452/* For colormap entries we end up doing the gamma correction here and the1453* following routines are provided to separate out the code. In all cases the1454* input value is in the range 0..255 and is encoded P_FILE with the gamma value1455* stored in the png_struct colorspace.1456*/1457static void1458init_correct(png_const_structrp png_ptr, png_fixed_point *correct)1459{1460/* Record the convertion necessary to get from the encoding values to1461* sRGB. If this overflows just store FP_1.1462*1463* NOTE: this code used to store, and use, a convertion factor to1464* linear then use the sRGB encoding tables to get back to sRGB, but1465* this smashes the low values; the ones which fall in the linear part1466* of the sRGB transfer function.1467*1468* The new version of this code assumes an encoding which is neither1469* linear nor sRGB is a power law transform of the sRGB curve, not1470* linear values. This is somewhat at odds with a precise reading of1471* the PNG spec, but given that we are trying to produce sRGB values1472* here it is most likely to be correct.1473*/1474affirm(png_ptr->colorspace.gamma > 0);14751476if (!png_muldiv(correct, PNG_GAMMA_sRGB_INVERSE, PNG_FP_1,1477png_ptr->colorspace.gamma))1478*correct = PNG_FP_1;1479}14801481static png_uint_321482update_for_sBIT(png_uint_32 value, unsigned int significant_bits,1483unsigned int bit_depth)1484/* Return a bit_depth value adjusted for the number of significant bits in1485* the value.1486*/1487{1488if (significant_bits < bit_depth)1489{1490value >>= bit_depth - significant_bits;1491/* Now scale back to bit_depth, taking care not to overflow when 'value'1492* is (1<<significant_bits)-1 by rounding *down* the rounding add below1493* (so, e.g. rather than 2, 1 is used when significant bits is 2).1494*/1495value = (value * ((1U<<bit_depth)-1U) + ((1U<<(significant_bits-1U))-1U))1496/ ((1U<<significant_bits)-1U);1497}14981499return value;15001501}15021503static png_uint_321504convert_to_sRGB(png_image_read_control *display, png_uint_32 value,1505unsigned int significant_bits)1506{1507/* Converts an 8-bit value from P_FILE to P_sRGB */1508png_const_structrp png_ptr = display->image->opaque->png_ptr;15091510debug(value <= 255U && significant_bits <= 8U && significant_bits > 0U);15111512if (display->file_to_sRGB == 0)1513init_correct(png_ptr, &display->file_to_sRGB);15141515/* Now simply apply this correction factor and scale back to 8 bits. */1516if (display->file_to_sRGB != PNG_FP_1)1517value = png_gamma_nxmbit_correct(value >> (8U-significant_bits),1518display->file_to_sRGB, significant_bits, 8U);15191520else if (significant_bits < 8U)1521value = update_for_sBIT(value, significant_bits, 8U);15221523return value;1524}15251526static png_uint_321527convert_to_linear(png_image_read_control *display, png_uint_32 value,1528unsigned int significant_bits)1529{1530/* Converts an 8-bit value from P_FILE to 16-bit P_LINEAR */1531png_const_structrp png_ptr = display->image->opaque->png_ptr;15321533debug(value <= 255U && significant_bits <= 8U && significant_bits > 0U);15341535if (display->file_to_sRGB == 0)1536init_correct(png_ptr, &display->file_to_sRGB);15371538/* Use this correction to get a 16-bit sRGB value: */1539if (display->file_to_sRGB != PNG_FP_1)1540value = png_gamma_nxmbit_correct(value >> (8U-significant_bits),1541display->file_to_sRGB, significant_bits, 16U);15421543else1544{1545value *= 257U;15461547if (significant_bits < 8U)1548value = update_for_sBIT(value, significant_bits, 16U);1549}15501551/* Now convert this back to linear, using the correct transfer function. */1552if (value <= 2650U /* 65535 * 0.04045 */)1553{1554/* We want to divide a 12-bit number by 12.92, do this by scaling to 321555* bits then dividing by 2^24, with rounding:1556*/1557value = (value * 1298546U + 649273U) >> 24;1558}15591560else1561{1562/* Calculate for v in the range 0.04045..1.0 calculate:1563*1564* ((v + 0.055)/1.055)^2.41565*1566* the gamma correction function needs a 16-bit value:1567*/1568value *= 62119U;1569value += 223904831U+32768U; /* cannot overflow; test with 65535 */1570value = png_gamma_nxmbit_correct(value >> 16, 240000, 16U, 16U);1571}15721573return value;1574}15751576static unsigned int1577decode_gamma(png_image_read_control *display, png_uint_32 value,1578unsigned int significant_bits, int encoding)1579{1580int do_sBIT = 0;15811582if (encoding == P_FILE) /* double check */1583encoding = display->file_encoding, do_sBIT = 1;15841585if (encoding == P_NOTSET) /* must be the file encoding */1586{1587set_file_encoding(display);1588encoding = display->file_encoding;1589}15901591switch (encoding)1592{1593case P_FILE:1594/* This is a file value, so the sBIT, if any, needs to be used. */1595value = convert_to_linear(display, value, significant_bits);1596break;15971598case P_sRGB:1599if (do_sBIT)1600value = update_for_sBIT(value, significant_bits, 8U);16011602value = png_sRGB_table[value];1603break;16041605case P_LINEAR:1606if (do_sBIT)1607value = update_for_sBIT(value, significant_bits, 16U);1608break;16091610case P_LINEAR8:1611value *= 257;1612if (do_sBIT)1613value = update_for_sBIT(value, significant_bits, 16U);1614break;16151616default:1617png_impossiblepp(display->image->opaque->png_ptr,1618"unexpected encoding");1619break;1620}16211622return value;1623}16241625static png_uint_321626png_colormap_compose(png_image_read_control *display,1627png_uint_32 foreground, unsigned int foreground_significant_bits,1628int foreground_encoding, png_uint_32 alpha,1629png_uint_32 background, int encoding)1630{1631/* The file value is composed on the background, the background has the given1632* encoding and so does the result, the file is encoded with P_FILE and the1633* file and alpha are 8-bit values. The (output) encoding will always be1634* P_LINEAR or P_sRGB.1635*/1636png_uint_32 f = decode_gamma(display, foreground,1637foreground_significant_bits, foreground_encoding);1638png_uint_32 b = decode_gamma(display, background, 0U/*UNUSED*/, encoding);16391640/* The alpha is always an 8-bit value (it comes from the palette), the value1641* scaled by 255 is what PNG_sRGB_FROM_LINEAR requires.1642*/1643f = f * alpha + b * (255-alpha);16441645if (encoding == P_LINEAR)1646{1647/* Scale to 65535; divide by 255, approximately (in fact this is extremely1648* accurate, it divides by 255.00000005937181414556, with no overflow.)1649*/1650f *= 257; /* Now scaled by 65535 */1651f += f >> 16;1652f = (f+32768) >> 16;1653}16541655else /* P_sRGB */1656f = PNG_sRGB_FROM_LINEAR(display->image->opaque->png_ptr, f);16571658return f;1659}16601661/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must1662* be 8-bit.1663*/1664static void1665png_create_colormap_entry(png_image_read_control *display,1666png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,1667png_uint_32 alpha, int encoding)1668{1669png_imagep image = display->image;1670# define png_ptr image->opaque->png_ptr /* for error messages */1671const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?1672P_LINEAR : P_sRGB;1673const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&1674(red != green || green != blue);1675int use_sBIT = encoding == P_FILE;16761677affirm(ip <= 255);1678implies(encoding != P_LINEAR, red <= 255U && green <= 255U && blue <= 255U1679&& display->sBIT[0] <= 8U && display->sBIT[1] <= 8U1680&& display->sBIT[2] <= 8U && display->sBIT[3] <= 8U);16811682/* This is a hack for the grayscale colormap below. */1683if (encoding == P_FILE8)1684encoding = P_FILE;16851686/* Update the cache with whether the file gamma is significantly different1687* from sRGB.1688*/1689if (encoding == P_FILE)1690{1691if (display->file_encoding == P_NOTSET)1692set_file_encoding(display);16931694/* Note that the cached value may be P_FILE too. */1695encoding = display->file_encoding;1696if (use_sBIT)1697png_image_get_sBIT(display);1698}16991700if (encoding == P_FILE)1701{1702if (convert_to_Y != 0 || output_encoding == P_LINEAR)1703{1704red = convert_to_linear(display, red,1705use_sBIT ? display->sBIT[0] : 8U);1706green = convert_to_linear(display, green,1707use_sBIT ? display->sBIT[1] : 8U);1708blue = convert_to_linear(display, blue,1709use_sBIT ? display->sBIT[2] : 8U);1710alpha *= 257U;1711if (use_sBIT)1712alpha = update_for_sBIT(alpha, display->sBIT[3], 16U);17131714encoding = P_LINEAR;1715use_sBIT = 0;1716}17171718else1719{1720red = convert_to_sRGB(display, red,1721use_sBIT ? display->sBIT[0] : 8U);1722green = convert_to_sRGB(display, green,1723use_sBIT ? display->sBIT[1] : 8U);1724blue = convert_to_sRGB(display, blue,1725use_sBIT ? display->sBIT[2] : 8U);1726if (use_sBIT)1727alpha = update_for_sBIT(alpha, display->sBIT[3], 8U);1728encoding = P_sRGB;1729use_sBIT = 0;1730}1731}17321733else if (encoding == P_LINEAR8)1734{1735/* This encoding corresponds to a colormap with linear RGB entries, this1736* is not a very sensible encoding but it does happen with the PNGSuite1737* test images.1738*/1739red *= 257;1740green *= 257;1741blue *= 257;1742alpha *= 257;1743if (use_sBIT)1744{1745red = update_for_sBIT(red, display->sBIT[0], 16U);1746green = update_for_sBIT(green, display->sBIT[1], 16U);1747blue = update_for_sBIT(blue, display->sBIT[2], 16U);1748alpha = update_for_sBIT(alpha, display->sBIT[3], 16U);1749use_sBIT = 0;1750}1751encoding = P_LINEAR;1752}17531754else if (encoding == P_sRGB &&1755(convert_to_Y != 0 || output_encoding == P_LINEAR))1756{1757/* The values are 8-bit sRGB values, but must be converted to 16-bit1758* linear.1759*/1760if (use_sBIT)1761{17621763red = convert_to_linear(display, red, display->sBIT[0]);1764green = convert_to_linear(display, green, display->sBIT[1]);1765blue = convert_to_linear(display, blue, display->sBIT[2]);1766alpha = update_for_sBIT(alpha * 257U, display->sBIT[3], 16U);1767use_sBIT = 0;1768}17691770else1771{1772red = png_sRGB_table[red];1773green = png_sRGB_table[green];1774blue = png_sRGB_table[blue];1775alpha *= 257;1776}17771778encoding = P_LINEAR;1779}17801781else if (encoding == P_sRGB && use_sBIT)1782{1783debug(output_encoding == P_sRGB); /* P_LINEAR handled above */1784red = update_for_sBIT(red, display->sBIT[0], 8U);1785green = update_for_sBIT(green, display->sBIT[1], 8U);1786blue = update_for_sBIT(blue, display->sBIT[2], 8U);1787alpha = update_for_sBIT(alpha, display->sBIT[3], 8U);1788use_sBIT = 0;1789}17901791debug(!use_sBIT); /* it should have been handled above */17921793/* This is set if the color isn't gray but the output is. */1794if (encoding == P_LINEAR)1795{1796if (convert_to_Y != 0)1797{1798/* NOTE: these values are copied from png_do_rgb_to_gray */1799png_uint_32 y = 6968 * red + 23434 * green + 2366 * blue;18001801if (output_encoding == P_LINEAR)1802y = (y + 16384) >> 15;18031804else1805{1806/* y is scaled by 32768, we need it scaled by 255: */1807y = (y + 128) >> 8;1808y *= 255;1809y = PNG_sRGB_FROM_LINEAR(png_ptr, (y + 64) >> 7);1810alpha = PNG_DIV257(alpha);1811encoding = P_sRGB;1812}18131814blue = red = green = y;1815}18161817else if (output_encoding == P_sRGB)1818{1819red = PNG_sRGB_FROM_LINEAR(png_ptr, red * 255);1820green = PNG_sRGB_FROM_LINEAR(png_ptr, green * 255);1821blue = PNG_sRGB_FROM_LINEAR(png_ptr, blue * 255);1822alpha = PNG_DIV257(alpha);1823encoding = P_sRGB;1824}1825}18261827if (encoding != output_encoding)1828png_impossiblepp(png_ptr, "bad encoding");18291830/* Store the value. */1831{1832# ifdef PNG_FORMAT_AFIRST_SUPPORTED1833const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&1834(image->format & PNG_FORMAT_FLAG_ALPHA) != 0;1835# else1836# define afirst 01837# endif1838# ifdef PNG_FORMAT_BGR_SUPPORTED1839const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;1840# else1841# define bgr 01842# endif18431844if (output_encoding == P_LINEAR)1845{1846png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap);18471848entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);18491850/* The linear 16-bit values must be pre-multiplied by the alpha channel1851* value, if less than 65535 (this is, effectively, composite on black1852* if the alpha channel is removed.)1853*/1854switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))1855{1856case 4:1857entry[afirst ? 0 : 3] = png_check_u16(png_ptr, alpha);1858/* FALL THROUGH */18591860case 3:1861if (alpha < 65535)1862{1863if (alpha > 0)1864{1865blue = (blue * alpha + 32767U)/65535U;1866green = (green * alpha + 32767U)/65535U;1867red = (red * alpha + 32767U)/65535U;1868}18691870else1871red = green = blue = 0;1872}1873entry[afirst + (2 ^ bgr)] = png_check_u16(png_ptr, blue);1874entry[afirst + 1] = png_check_u16(png_ptr, green);1875entry[afirst + bgr] = png_check_u16(png_ptr, red);1876break;18771878case 2:1879entry[1 ^ afirst] = png_check_u16(png_ptr, alpha);1880/* FALL THROUGH */18811882case 1:1883if (alpha < 65535)1884{1885if (alpha > 0)1886green = (green * alpha + 32767U)/65535U;18871888else1889green = 0;1890}1891entry[afirst] = png_check_u16(png_ptr, green);1892break;18931894default:1895break;1896}1897}18981899else /* output encoding is P_sRGB */1900{1901png_bytep entry = png_voidcast(png_bytep, display->colormap);19021903entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);19041905png_affirmpp(png_ptr, output_encoding == P_sRGB);19061907switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))1908{1909case 4:1910entry[afirst ? 0 : 3] = png_check_byte(png_ptr, alpha);19111912case 3:1913entry[afirst + (2 ^ bgr)] = png_check_byte(png_ptr, blue);1914entry[afirst + 1] = png_check_byte(png_ptr, green);1915entry[afirst + bgr] = png_check_byte(png_ptr, red);1916break;19171918case 2:1919entry[1 ^ afirst] = png_check_byte(png_ptr, alpha);19201921case 1:1922entry[afirst] = png_check_byte(png_ptr, green);1923break;19241925default:1926break;1927}1928}19291930# ifdef afirst1931# undef afirst1932# endif1933# ifdef bgr1934# undef bgr1935# endif1936}19371938# undef png_ptr1939}19401941static int1942make_gray_file_colormap(png_image_read_control *display)1943{1944unsigned int i;19451946for (i=0; i<256; ++i)1947png_create_colormap_entry(display, i, i, i, i, 255, P_FILE8);19481949return i;1950}19511952static int1953make_gray_colormap(png_image_read_control *display)1954{1955unsigned int i;19561957for (i=0; i<256; ++i)1958png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB);19591960return i;1961}1962#define PNG_GRAY_COLORMAP_ENTRIES 25619631964static int1965make_ga_colormap(png_image_read_control *display)1966{1967unsigned int i, a;19681969/* Alpha is retained, the output will be a color-map with entries1970* selected by six levels of alpha. One transparent entry, 6 gray1971* levels for all the intermediate alpha values, leaving 230 entries1972* for the opaque grays. The color-map entries are the six values1973* [0..5]*51, the GA processing uses PNG_DIV51(value) to find the1974* relevant entry.1975*1976* if (alpha > 229) // opaque1977* {1978* // The 231 entries are selected to make the math below work:1979* base = 0;1980* entry = (231 * gray + 128) >> 8;1981* }1982* else if (alpha < 26) // transparent1983* {1984* base = 231;1985* entry = 0;1986* }1987* else // partially opaque1988* {1989* base = 226 + 6 * PNG_DIV51(alpha);1990* entry = PNG_DIV51(gray);1991* }1992*/1993i = 0;1994while (i < 231)1995{1996unsigned int gray = (i * 256 + 115) / 231;1997png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB);1998}19992000/* 255 is used here for the component values for consistency with the code2001* that undoes premultiplication in pngwrite.c.2002*/2003png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB);20042005for (a=1; a<5; ++a)2006{2007unsigned int g;20082009for (g=0; g<6; ++g)2010png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,2011P_sRGB);2012}20132014return i;2015}20162017#define PNG_GA_COLORMAP_ENTRIES 25620182019static int2020make_rgb_colormap(png_image_read_control *display)2021{2022unsigned int i, r;20232024/* Build a 6x6x6 opaque RGB cube */2025for (i=r=0; r<6; ++r)2026{2027unsigned int g;20282029for (g=0; g<6; ++g)2030{2031unsigned int b;20322033for (b=0; b<6; ++b)2034png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,2035P_sRGB);2036}2037}20382039return i;2040}20412042#define PNG_RGB_COLORMAP_ENTRIES 21620432044/* Return a palette index to the above palette given three 8-bit sRGB values. */2045#define PNG_RGB_INDEX(r,g,b) \2046(png_check_byte(image->opaque->png_ptr,\20476 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b)))20482049static int2050png_image_read_colormap(png_voidp argument)2051{2052png_image_read_control *display =2053png_voidcast(png_image_read_control*, argument);2054const png_imagep image = display->image;20552056const png_structrp png_ptr = image->opaque->png_ptr;2057const png_uint_32 output_format = image->format;2058const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ?2059P_LINEAR : P_sRGB;20602061unsigned int cmap_entries;2062unsigned int output_processing; /* Output processing option */2063unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */20642065/* Background information; the background color and the index of this color2066* in the color-map if it exists (else 256).2067*/2068unsigned int background_index = 256;2069png_uint_32 back_r, back_g, back_b;20702071/* Flags to accumulate things that need to be done to the input. */2072int expand_tRNS = 0;20732074/* Exclude the NYI feature of compositing onto a color-mapped buffer; it is2075* very difficult to do, the results look awful, and it is difficult to see2076* what possible use it is because the application can't control the2077* color-map.2078*/2079if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 ||2080png_ptr->num_trans > 0) /* alpha in input */ &&2081((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */)2082{2083if (output_encoding == P_LINEAR) /* compose on black */2084back_b = back_g = back_r = 0;20852086else if (display->background == NULL /* no way to remove it */)2087png_error(png_ptr,2088"background color must be supplied to remove alpha/transparency");20892090/* Get a copy of the background color (this avoids repeating the checks2091* below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the2092* output format.2093*/2094else2095{2096back_g = display->background->green;2097if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0)2098{2099back_r = display->background->red;2100back_b = display->background->blue;2101}2102else2103back_b = back_r = back_g;2104}2105}21062107else if (output_encoding == P_LINEAR)2108back_b = back_r = back_g = 65535;21092110else2111back_b = back_r = back_g = 255;21122113/* Default the input file gamma if required - this is necessary because2114* libpng assumes that if no gamma information is present the data is in the2115* output format, but the simplified API deduces the gamma from the input2116* format.2117*/2118if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0)2119{2120/* Do this directly, not using the png_colorspace functions, to ensure2121* that it happens even if the colorspace is invalid (though probably if2122* it is the setting will be ignored) Note that the same thing can be2123* achieved at the application interface with png_set_gAMA.2124*/2125if (png_ptr->bit_depth == 16 &&2126(image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)2127png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR;21282129else2130png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE;21312132/* Make sure libpng doesn't ignore the setting: */2133if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)2134png_ptr->colorspace.flags = PNG_COLORSPACE_HAVE_GAMMA;21352136else2137png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;2138}21392140/* Decide what to do based on the PNG color type of the input data. The2141* utility function png_create_colormap_entry deals with most aspects of the2142* output transformations; this code works out how to produce bytes of2143* color-map entries from the original format.2144*/2145switch (png_ptr->color_type)2146{2147case PNG_COLOR_TYPE_GRAY:2148if (png_ptr->bit_depth <= 8)2149{2150/* There at most 256 colors in the output, regardless of2151* transparency.2152*/2153unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0;21542155cmap_entries = 1U << png_ptr->bit_depth;2156if (cmap_entries > image->colormap_entries)2157png_error(png_ptr, "gray[8] color-map: too few entries");21582159step = 255 / (cmap_entries - 1);2160output_processing = PNG_CMAP_NONE;21612162/* If there is a tRNS chunk then this either selects a transparent2163* value or, if the output has no alpha, the background color.2164*/2165if (png_ptr->num_trans > 0)2166{2167trans = png_ptr->trans_color.gray;21682169if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0)2170back_alpha = output_encoding == P_LINEAR ? 65535 : 255;2171}21722173/* png_create_colormap_entry just takes an RGBA and writes the2174* corresponding color-map entry using the format from 'image',2175* including the required conversion to sRGB or linear as2176* appropriate. The input values are always either sRGB (if the2177* gamma correction flag is 0) or 0..255 scaled file encoded values2178* (if the function must gamma correct them).2179*/2180for (i=val=0; i<cmap_entries; ++i, val += step)2181{2182/* 'i' is a file value. While this will result in duplicated2183* entries for 8-bit non-sRGB encoded files it is necessary to2184* have non-gamma corrected values to do tRNS handling.2185*/2186if (i != trans)2187png_create_colormap_entry(display, i, val, val, val, 255,2188P_FILE/*8-bit with file gamma*/);21892190/* Else this entry is transparent. The colors don't matter if2191* there is an alpha channel (back_alpha == 0), but it does no2192* harm to pass them in; the values are not set above so this2193* passes in white.2194*2195* NOTE: this preserves the full precision of the application2196* supplied background color when it is used.2197*/2198else2199{2200#ifdef __COVERITY__2201/* Coverity says back_r|g|b might be 16-bit values */2202png_affirmpp(png_ptr, back_r < 256 && back_g < 256 &&2203back_b < 256);2204#endif2205png_create_colormap_entry(display, i, back_r, back_g, back_b,2206back_alpha, output_encoding);2207}2208}22092210/* We need libpng to preserve the original encoding. */2211data_encoding = P_FILE;22122213/* The rows from libpng, while technically gray values, are now also2214* color-map indices; however, they may need to be expanded to 12215* byte per pixel. This is what png_set_packing does (i.e., it2216* unpacks the bit values into bytes.)2217*/2218if (png_ptr->bit_depth < 8)2219png_set_packing(png_ptr);2220}22212222else /* bit depth is 16 */2223{2224/* The 16-bit input values can be converted directly to 8-bit gamma2225* encoded values; however, if a tRNS chunk is present 257 color-map2226* entries are required. This means that the extra entry requires2227* special processing; add an alpha channel, sacrifice gray level2228* 254 and convert transparent (alpha==0) entries to that.2229*2230* Use libpng to chop the data to 8 bits. Convert it to sRGB at the2231* same time to minimize quality loss. If a tRNS chunk is present2232* this means libpng must handle it too; otherwise it is impossible2233* to do the exact match on the 16-bit value.2234*2235* If the output has no alpha channel *and* the background color is2236* gray then it is possible to let libpng handle the substitution by2237* ensuring that the corresponding gray level matches the background2238* color exactly.2239*/2240data_encoding = P_sRGB;22412242if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)2243png_error(png_ptr, "gray[16] color-map: too few entries");22442245cmap_entries = make_gray_colormap(display);22462247if (png_ptr->num_trans > 0)2248{2249unsigned int back_alpha;22502251if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)2252back_alpha = 0;22532254else2255{2256if (back_r == back_g && back_g == back_b)2257{2258/* Background is gray; no special processing will be2259* required.2260*/2261png_color_16 c;2262png_uint_32 gray = back_g;22632264if (output_encoding == P_LINEAR)2265{2266gray = PNG_sRGB_FROM_LINEAR(png_ptr, gray * 255);22672268/* And make sure the corresponding palette entry2269* matches.2270*/2271png_create_colormap_entry(display, gray, back_g, back_g,2272back_g, 65535, P_LINEAR);2273}22742275/* The background passed to libpng, however, must be the2276* sRGB value.2277*/2278c.index = 0; /*unused*/2279c.gray = c.red = c.green = c.blue =2280png_check_u16(png_ptr, gray);22812282/* NOTE: does this work without expanding tRNS to alpha?2283* It should be the color->gray case below apparently2284* doesn't.2285*/2286png_set_background_fixed(png_ptr, &c,2287PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,22880/*gamma: not used*/);22892290output_processing = PNG_CMAP_NONE;2291break;2292}2293/* Coverity claims that output_encoding cannot be 2 (P_LINEAR)2294* here.2295*/2296affirm(output_encoding != P_LINEAR);2297back_alpha = 255U;2298}22992300/* output_processing means that the libpng-processed row will be2301* 8-bit GA and it has to be processing to single byte color-map2302* values. Entry 254 is replaced by either a completely2303* transparent entry or by the background color at full2304* precision (and the background color is not a simple gray2305* level in this case.)2306*/2307expand_tRNS = 1;2308output_processing = PNG_CMAP_TRANS;2309background_index = 254;23102311/* And set (overwrite) color-map entry 254 to the actual2312* background color at full precision.2313*/2314#ifdef __COVERITY__2315/* Coverity says back_r|g|b might be 16-bit values */2316png_affirmpp(png_ptr, back_r < 256 && back_g < 256 &&2317back_b < 256);2318#endif2319png_create_colormap_entry(display, 254, back_r, back_g, back_b,2320back_alpha, output_encoding);2321}23222323else2324output_processing = PNG_CMAP_NONE;2325}2326break;23272328case PNG_COLOR_TYPE_GRAY_ALPHA:2329/* 8-bit or 16-bit PNG with two channels - gray and alpha. A minimum2330* of 65536 combinations. If, however, the alpha channel is to be2331* removed there are only 256 possibilities if the background is gray.2332* (Otherwise there is a subset of the 65536 possibilities defined by2333* the triangle between black, white and the background color.)2334*2335* Reduce 16-bit files to 8-bit and sRGB encode the result. No need to2336* worry about tRNS matching - tRNS is ignored if there is an alpha2337* channel.2338*/2339data_encoding = P_sRGB;23402341if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)2342{2343if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)2344png_error(png_ptr, "gray+alpha color-map: too few entries");23452346cmap_entries = make_ga_colormap(display);23472348background_index = PNG_CMAP_GA_BACKGROUND;2349output_processing = PNG_CMAP_GA;2350}23512352else /* alpha is removed */2353{2354/* Alpha must be removed as the PNG data is processed when the2355* background is a color because the G and A channels are2356* independent and the vector addition (non-parallel vectors) is a2357* 2-D problem.2358*2359* This can be reduced to the same algorithm as above by making a2360* colormap containing gray levels (for the opaque grays), a2361* background entry (for a transparent pixel) and a set of four six2362* level color values, one set for each intermediate alpha value.2363* See the comments in make_ga_colormap for how this works in the2364* per-pixel processing.2365*2366* If the background is gray, however, we only need a 256 entry gray2367* level color map. It is sufficient to make the entry generated2368* for the background color be exactly the color specified.2369*/2370if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 ||2371(back_r == back_g && back_g == back_b))2372{2373/* Background is gray; no special processing will be required. */2374png_color_16 c;2375png_uint_32 gray = back_g;23762377if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)2378png_error(png_ptr, "gray-alpha color-map: too few entries");23792380cmap_entries = make_gray_colormap(display);23812382if (output_encoding == P_LINEAR)2383{2384gray = PNG_sRGB_FROM_LINEAR(png_ptr, gray * 255);23852386/* And make sure the corresponding palette entry matches. */2387png_create_colormap_entry(display, gray, back_g, back_g,2388back_g, 65535, P_LINEAR);2389}23902391/* The background passed to libpng, however, must be the sRGB2392* value.2393*/2394c.index = 0; /*unused*/2395c.gray = c.red = c.green = c.blue = png_check_u16(png_ptr, gray);23962397png_set_background_fixed(png_ptr, &c,2398PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,23990/*gamma: not used*/);24002401output_processing = PNG_CMAP_NONE;2402}24032404else2405{2406png_uint_32 i, a;24072408/* This is the same as png_make_ga_colormap, above, except that2409* the entries are all opaque.2410*/2411if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)2412png_error(png_ptr, "ga-alpha color-map: too few entries");24132414i = 0;2415while (i < 231)2416{2417png_uint_32 gray = (i * 256 + 115) / 231;2418png_create_colormap_entry(display, i++, gray, gray, gray,2419255, P_sRGB);2420}24212422/* NOTE: this preserves the full precision of the application2423* background color.2424*2425* Coverity claims that output_encoding cannot be 2 (P_LINEAR)2426*/2427affirm(output_encoding != P_LINEAR);2428background_index = i;2429png_create_colormap_entry(display, i++, back_r, back_g, back_b,2430255U, output_encoding);24312432/* For non-opaque input composite on the sRGB background - this2433* requires inverting the encoding for each component. The input2434* is still converted to the sRGB encoding because this is a2435* reasonable approximate to the logarithmic curve of human2436* visual sensitivity, at least over the narrow range which PNG2437* represents. Consequently 'G' is always sRGB encoded, while2438* 'A' is linear. We need the linear background colors.2439*/2440if (output_encoding == P_sRGB) /* else already linear */2441{2442/* This may produce a value not exactly matching the2443* background, but that's ok because these numbers are only2444* used when alpha != 02445*/2446back_r = png_sRGB_table[back_r];2447back_g = png_sRGB_table[back_g];2448back_b = png_sRGB_table[back_b];2449}24502451for (a=1; a<5; ++a)2452{2453unsigned int g;24542455/* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled2456* by an 8-bit alpha value (0..255).2457*/2458png_uint_32 alpha = 51 * a;2459png_uint_32 back_rx = (255-alpha) * back_r;2460png_uint_32 back_gx = (255-alpha) * back_g;2461png_uint_32 back_bx = (255-alpha) * back_b;24622463for (g=0; g<6; ++g)2464{2465png_uint_32 gray = png_sRGB_table[g*51] * alpha;24662467png_create_colormap_entry(display, i++,2468PNG_sRGB_FROM_LINEAR(png_ptr, gray + back_rx),2469PNG_sRGB_FROM_LINEAR(png_ptr, gray + back_gx),2470PNG_sRGB_FROM_LINEAR(png_ptr, gray + back_bx),2471255, P_sRGB);2472}2473}24742475cmap_entries = i;2476output_processing = PNG_CMAP_GA;2477}2478}2479break;24802481case PNG_COLOR_TYPE_RGB:2482case PNG_COLOR_TYPE_RGB_ALPHA:2483/* Exclude the case where the output is gray; we can always handle this2484* with the cases above.2485*/2486if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0)2487{2488/* The color-map will be grayscale, so we may as well convert the2489* input RGB values to a simple grayscale and use the grayscale2490* code above.2491*2492* NOTE: calling this apparently damages the recognition of the2493* transparent color in background color handling; call2494* png_set_tRNS_to_alpha before png_set_background_fixed.2495*/2496png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,2497-1);2498data_encoding = P_sRGB;24992500/* The output will now be one or two 8-bit gray or gray+alpha2501* channels. The more complex case arises when the input has alpha.2502*/2503if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||2504png_ptr->num_trans > 0) &&2505(output_format & PNG_FORMAT_FLAG_ALPHA) != 0)2506{2507/* Both input and output have an alpha channel, so no background2508* processing is required; just map the GA bytes to the right2509* color-map entry.2510*/2511expand_tRNS = 1;25122513if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)2514png_error(png_ptr, "rgb[ga] color-map: too few entries");25152516cmap_entries = make_ga_colormap(display);2517background_index = PNG_CMAP_GA_BACKGROUND;2518output_processing = PNG_CMAP_GA;2519}25202521else2522{2523/* Either the input or the output has no alpha channel, so there2524* will be no non-opaque pixels in the color-map; it will just be2525* grayscale.2526*/2527if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)2528png_error(png_ptr, "rgb[gray] color-map: too few entries");25292530/* Ideally this code would use libpng to do the gamma correction,2531* but if an input alpha channel is to be removed we will hit the2532* libpng bug in gamma+compose+rgb-to-gray (the double gamma2533* correction bug). Fix this by dropping the gamma correction in2534* this case and doing it in the palette; this will result in2535* duplicate palette entries, but that's better than the2536* alternative of double gamma correction.2537*/2538if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||2539png_ptr->num_trans > 0) &&2540png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0)2541{2542cmap_entries = make_gray_file_colormap(display);2543data_encoding = P_FILE;2544}25452546else2547cmap_entries = make_gray_colormap(display);25482549/* But if the input has alpha or transparency it must be removed2550*/2551if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||2552png_ptr->num_trans > 0)2553{2554png_color_16 c;2555png_uint_32 gray = back_g;25562557/* We need to ensure that the application background exists in2558* the colormap and that completely transparent pixels map to2559* it. Achieve this simply by ensuring that the entry2560* selected for the background really is the background color.2561*/2562if (data_encoding == P_FILE) /* from the fixup above */2563{2564/* The app supplied a gray which is in output_encoding, we2565* need to convert it to a value of the input (P_FILE)2566* encoding then set this palette entry to the required2567* output encoding.2568*/2569if (output_encoding == P_sRGB)2570gray = png_sRGB_table[gray]; /* now P_LINEAR */25712572gray = png_gamma_nxmbit_correct(gray,2573png_ptr->colorspace.gamma, 16U, 8U);25742575/* And make sure the corresponding palette entry contains2576* exactly the required sRGB value.2577*/2578png_create_colormap_entry(display, gray, back_g, back_g,2579back_g, 0/*unused*/, output_encoding);2580}25812582else if (output_encoding == P_LINEAR)2583{2584gray = PNG_sRGB_FROM_LINEAR(png_ptr, gray * 255);25852586/* And make sure the corresponding palette entry matches.2587*/2588png_create_colormap_entry(display, gray, back_g, back_g,2589back_g, 0/*unused*/, P_LINEAR);2590}25912592/* The background passed to libpng, however, must be the2593* output (normally sRGB) value.2594*/2595c.index = 0; /*unused*/2596c.gray = c.red = c.green = c.blue =2597png_check_u16(png_ptr, gray);25982599/* NOTE: the following is apparently a bug in libpng. Without2600* it the transparent color recognition in2601* png_set_background_fixed seems to go wrong.2602*/2603expand_tRNS = 1;2604png_set_background_fixed(png_ptr, &c,2605PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,26060/*gamma: not used*/);2607}26082609output_processing = PNG_CMAP_NONE;2610}2611}26122613else /* output is color */2614{2615/* We could use png_quantize here so long as there is no transparent2616* color or alpha; png_quantize ignores alpha. Easier overall just2617* to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube.2618* Consequently we always want libpng to produce sRGB data.2619*/2620data_encoding = P_sRGB;26212622/* Is there any transparency or alpha? */2623if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||2624png_ptr->num_trans > 0)2625{2626/* Is there alpha in the output too? If so all four channels are2627* processed into a special RGB cube with alpha support.2628*/2629if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)2630{2631png_uint_32 r;26322633if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)2634png_error(png_ptr, "rgb+alpha color-map: too few entries");26352636cmap_entries = make_rgb_colormap(display);26372638/* Add a transparent entry. */2639png_create_colormap_entry(display, cmap_entries, 255, 255,2640255, 0, P_sRGB);26412642/* This is stored as the background index for the processing2643* algorithm.2644*/2645background_index = cmap_entries++;26462647/* Add 27 r,g,b entries each with alpha 0.5. */2648for (r=0; r<256; r = (r << 1) | 0x7f)2649{2650png_uint_32 g;26512652for (g=0; g<256; g = (g << 1) | 0x7f)2653{2654png_uint_32 b;26552656/* This generates components with the values 0, 127 and2657* 2552658*/2659for (b=0; b<256; b = (b << 1) | 0x7f)2660png_create_colormap_entry(display, cmap_entries++,2661r, g, b, 128, P_sRGB);2662}2663}26642665expand_tRNS = 1;2666output_processing = PNG_CMAP_RGB_ALPHA;2667}26682669else2670{2671/* Alpha/transparency must be removed. The background must2672* exist in the color map (achieved by setting adding it after2673* the 666 color-map). If the standard processing code will2674* pick up this entry automatically that's all that is2675* required; libpng can be called to do the background2676* processing.2677*/2678unsigned int sample_size =2679PNG_IMAGE_SAMPLE_SIZE(output_format);2680png_uint_32 r, g, b; /* sRGB background */26812682if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)2683png_error(png_ptr, "rgb-alpha color-map: too few entries");26842685cmap_entries = make_rgb_colormap(display);26862687png_create_colormap_entry(display, cmap_entries, back_r,2688back_g, back_b, 0/*unused*/, output_encoding);26892690if (output_encoding == P_LINEAR)2691{2692r = PNG_sRGB_FROM_LINEAR(png_ptr, back_r * 255);2693g = PNG_sRGB_FROM_LINEAR(png_ptr, back_g * 255);2694b = PNG_sRGB_FROM_LINEAR(png_ptr, back_b * 255);2695}26962697else2698{2699r = back_r;2700g = back_g;2701b = back_g;2702}27032704/* Compare the newly-created color-map entry with the one the2705* PNG_CMAP_RGB algorithm will use. If the two entries don't2706* match, add the new one and set this as the background2707* index.2708*/2709if (memcmp((png_const_bytep)display->colormap +2710sample_size * cmap_entries,2711(png_const_bytep)display->colormap +2712sample_size * PNG_RGB_INDEX(r,g,b),2713sample_size) != 0)2714{2715/* The background color must be added. */2716background_index = cmap_entries++;27172718/* Add 27 r,g,b entries each with created by composing with2719* the background at alpha 0.5.2720*/2721for (r=0; r<256; r = (r << 1) | 0x7f)2722{2723for (g=0; g<256; g = (g << 1) | 0x7f)2724{2725/* This generates components with the values 0, 1272726* and 2552727*/2728for (b=0; b<256; b = (b << 1) | 0x7f)2729png_create_colormap_entry(display, cmap_entries++,2730png_colormap_compose(display, r, 8U, P_sRGB,2731128U, back_r, output_encoding),2732png_colormap_compose(display, g, 8U, P_sRGB,2733128U, back_g, output_encoding),2734png_colormap_compose(display, b, 8U, P_sRGB,2735128U, back_b, output_encoding),27360/*unused*/, output_encoding);2737}2738}27392740expand_tRNS = 1;2741output_processing = PNG_CMAP_RGB_ALPHA;2742}27432744else /* background color is in the standard color-map */2745{2746png_color_16 c;27472748c.index = 0; /*unused*/2749c.red = png_check_u16(png_ptr, back_r);2750c.gray = c.green = png_check_u16(png_ptr, back_g);2751c.blue = png_check_u16(png_ptr, back_b);27522753png_set_background_fixed(png_ptr, &c,2754PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,27550/*gamma: not used*/);27562757output_processing = PNG_CMAP_RGB;2758}2759}2760}27612762else /* no alpha or transparency in the input */2763{2764/* Alpha in the output is irrelevant, simply map the opaque input2765* pixels to the 6x6x6 color-map.2766*/2767if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries)2768png_error(png_ptr, "rgb color-map: too few entries");27692770cmap_entries = make_rgb_colormap(display);2771output_processing = PNG_CMAP_RGB;2772}2773}2774break;27752776case PNG_COLOR_TYPE_PALETTE:2777/* It's already got a color-map. It may be necessary to eliminate the2778* tRNS entries though.2779*/2780{2781unsigned int num_trans = png_ptr->num_trans;2782png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL;2783png_const_colorp colormap = png_ptr->palette;2784const int do_background = trans != NULL &&2785(output_format & PNG_FORMAT_FLAG_ALPHA) == 0;2786unsigned int i;27872788/* Just in case: */2789if (trans == NULL)2790num_trans = 0;27912792output_processing = PNG_CMAP_NONE;2793data_encoding = P_FILE; /* Don't change from color-map indices */2794cmap_entries = png_ptr->num_palette;2795if (cmap_entries > 256)2796cmap_entries = 256;27972798if (cmap_entries > image->colormap_entries)2799png_error(png_ptr, "palette color-map: too few entries");28002801for (i=0; i < cmap_entries; ++i)2802{2803if (do_background != 0 && i < num_trans && trans[i] < 255)2804{2805if (trans[i] == 0)2806png_create_colormap_entry(display, i, back_r, back_g,2807back_b, 0, output_encoding);28082809else2810{2811unsigned int alpha;28122813/* Must compose the PNG file color in the color-map entry2814* on the sRGB color in 'back'.2815*/2816png_image_get_sBIT(display);2817alpha = update_for_sBIT(trans[i], display->sBIT[3], 8U);28182819/* Do the sBIT handling here because it only applies to the2820* values from the colormap, not the background. Passing2821* output_encoding to png_create_colormap_entry prevents2822* this being duplicated.2823*/2824png_create_colormap_entry(display, i,2825png_colormap_compose(display, colormap[i].red,2826display->sBIT[0], P_FILE, alpha, back_r,2827output_encoding),2828png_colormap_compose(display, colormap[i].green,2829display->sBIT[1], P_FILE, alpha, back_g,2830output_encoding),2831png_colormap_compose(display, colormap[i].blue,2832display->sBIT[2], P_FILE, alpha, back_b,2833output_encoding),2834output_encoding == P_LINEAR ?2835update_for_sBIT(alpha*257U, display->sBIT[3], 16U) :2836trans[i],2837output_encoding);2838}2839}28402841else2842png_create_colormap_entry(display, i, colormap[i].red,2843colormap[i].green, colormap[i].blue,2844i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);2845}28462847/* The PNG data may have indices packed in fewer than 8 bits, it2848* must be expanded if so.2849*/2850if (png_ptr->bit_depth < 8)2851png_set_packing(png_ptr);2852}2853break;28542855default:2856png_error(png_ptr, "invalid PNG color type");2857/*NOT REACHED*/2858}28592860/* Now deal with the output processing */2861if (expand_tRNS != 0 && png_ptr->num_trans > 0 &&2862(png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0)2863png_set_tRNS_to_alpha(png_ptr);28642865switch (data_encoding)2866{2867default:2868impossible("bad data option");2869break;28702871case P_sRGB:2872/* Change to 8-bit sRGB */2873png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);2874/* FALL THROUGH */28752876case P_FILE:2877if (png_ptr->bit_depth > 8)2878png_set_scale_16(png_ptr);2879break;2880}28812882affirm(cmap_entries <= 256 && cmap_entries <= image->colormap_entries);28832884image->colormap_entries = cmap_entries;28852886/* Double check using the recorded background index */2887switch (output_processing)2888{2889case PNG_CMAP_NONE:2890if (background_index != PNG_CMAP_NONE_BACKGROUND)2891goto bad_background;2892break;28932894case PNG_CMAP_GA:2895if (background_index != PNG_CMAP_GA_BACKGROUND)2896goto bad_background;2897break;28982899case PNG_CMAP_TRANS:2900if (background_index >= cmap_entries ||2901background_index != PNG_CMAP_TRANS_BACKGROUND)2902goto bad_background;2903break;29042905case PNG_CMAP_RGB:2906if (background_index != PNG_CMAP_RGB_BACKGROUND)2907goto bad_background;2908break;29092910case PNG_CMAP_RGB_ALPHA:2911if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND)2912goto bad_background;2913break;29142915default:2916impossible("bad processing option");29172918bad_background:2919impossible("bad background index");2920}29212922display->colormap_processing = output_processing;29232924return 1/*ok*/;2925}29262927/* The final part of the color-map read called from png_image_finish_read. */2928static int2929png_image_read_and_map(png_voidp argument)2930{2931png_image_read_control *display = png_voidcast(png_image_read_control*,2932argument);2933png_imagep image = display->image;2934png_structrp png_ptr = image->opaque->png_ptr;2935int passes;29362937/* Called when the libpng data must be transformed into the color-mapped2938* form. There is a local row buffer in display->local and this routine must2939* do the interlace handling.2940*/2941switch (png_ptr->interlaced)2942{2943case PNG_INTERLACE_NONE:2944passes = 1;2945break;29462947case PNG_INTERLACE_ADAM7:2948passes = PNG_INTERLACE_ADAM7_PASSES;2949break;29502951default:2952png_error(png_ptr, "unknown interlace type");2953}29542955{2956png_uint_32 height = image->height;2957png_uint_32 width = image->width;2958int proc = display->colormap_processing;2959png_bytep first_row = png_voidcast(png_bytep, display->first_row);2960ptrdiff_t step_row = display->row_bytes;2961int pass;29622963for (pass = 0; pass < passes; ++pass)2964{2965unsigned int startx, stepx, stepy;2966png_uint_32 y;29672968if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)2969{2970/* The row may be empty for a short image: */2971if (PNG_PASS_COLS(width, pass) == 0)2972continue;29732974startx = PNG_PASS_START_COL(pass);2975stepx = PNG_PASS_COL_OFFSET(pass);2976y = PNG_PASS_START_ROW(pass);2977stepy = PNG_PASS_ROW_OFFSET(pass);2978}29792980else2981{2982y = 0;2983startx = 0;2984stepx = stepy = 1;2985}29862987for (; y<height; y += stepy)2988{2989png_bytep inrow = png_voidcast(png_bytep, display->local_row);2990png_bytep outrow = first_row + y * step_row;2991png_const_bytep end_row = outrow + width;29922993/* Read read the libpng data into the temporary buffer. */2994png_read_row(png_ptr, inrow, NULL);29952996/* Now process the row according to the processing option, note2997* that the caller verifies that the format of the libpng output2998* data is as required.2999*/3000outrow += startx;3001switch (proc)3002{3003case PNG_CMAP_GA:3004for (; outrow < end_row; outrow += stepx)3005{3006/* The data is always in the PNG order */3007unsigned int gray = *inrow++;3008unsigned int alpha = *inrow++;3009unsigned int entry;30103011/* NOTE: this code is copied as a comment in3012* make_ga_colormap above. Please update the3013* comment if you change this code!3014*/3015if (alpha > 229) /* opaque */3016{3017entry = (231 * gray + 128) >> 8;3018}3019else if (alpha < 26) /* transparent */3020{3021entry = 231;3022}3023else /* partially opaque */3024{3025entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray);3026}30273028*outrow = png_check_byte(png_ptr, entry);3029}3030break;30313032case PNG_CMAP_TRANS:3033for (; outrow < end_row; outrow += stepx)3034{3035png_byte gray = *inrow++;3036png_byte alpha = *inrow++;30373038if (alpha == 0)3039*outrow = PNG_CMAP_TRANS_BACKGROUND;30403041else if (gray != PNG_CMAP_TRANS_BACKGROUND)3042*outrow = gray;30433044else3045*outrow = PNG_CMAP_TRANS_BACKGROUND+1;3046}3047break;30483049case PNG_CMAP_RGB:3050for (; outrow < end_row; outrow += stepx)3051{3052*outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]);3053inrow += 3;3054}3055break;30563057case PNG_CMAP_RGB_ALPHA:3058for (; outrow < end_row; outrow += stepx)3059{3060unsigned int alpha = inrow[3];30613062/* Because the alpha entries only hold alpha==0.5 values3063* split the processing at alpha==0.25 (64) and 0.753064* (196).3065*/30663067if (alpha >= 196)3068*outrow = PNG_RGB_INDEX(inrow[0], inrow[1],3069inrow[2]);30703071else if (alpha < 64)3072*outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;30733074else3075{3076/* Likewise there are three entries for each of r, g3077* and b. We could select the entry by popcount on3078* the top two bits on those architectures that3079* support it, this is what the code below does,3080* crudely.3081*/3082unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1;30833084/* Here are how the values map:3085*3086* 0x00 .. 0x3f -> 03087* 0x40 .. 0xbf -> 13088* 0xc0 .. 0xff -> 23089*3090* So, as above with the explicit alpha checks, the3091* breakpoints are at 64 and 196.3092*/3093if (inrow[0] & 0x80) back_i += 9; /* red */3094if (inrow[0] & 0x40) back_i += 9;3095if (inrow[0] & 0x80) back_i += 3; /* green */3096if (inrow[0] & 0x40) back_i += 3;3097if (inrow[0] & 0x80) back_i += 1; /* blue */3098if (inrow[0] & 0x40) back_i += 1;30993100*outrow = png_check_byte(png_ptr, back_i);3101}31023103inrow += 4;3104}3105break;31063107default:3108break;3109}3110}3111}3112}31133114return 1;3115}31163117static int3118png_image_read_colormapped(png_voidp argument)3119{3120png_image_read_control *display = png_voidcast(png_image_read_control*,3121argument);3122png_imagep image = display->image;3123png_controlp control = image->opaque;3124png_structrp png_ptr = control->png_ptr;3125png_inforp info_ptr = control->info_ptr;3126int color_type, bit_depth;3127int passes = 0; /* As a flag */31283129PNG_SKIP_CHUNKS(png_ptr);31303131/* Update the 'info' structure and make sure the result is as required; first3132* make sure to turn on the interlace handling if it will be required3133* (because it can't be turned on *after* the call to png_read_update_info!)3134*/3135if (display->colormap_processing == PNG_CMAP_NONE)3136passes = png_set_interlace_handling(png_ptr);31373138png_read_update_info(png_ptr, info_ptr);31393140/* Avoid the 'easy access' functions below because this allows them to be3141* disabled; there are not useful with the simplified API.3142*/3143color_type = PNG_COLOR_TYPE_FROM_FORMAT(info_ptr->format);3144bit_depth = info_ptr->bit_depth;31453146/* The expected output can be deduced from the colormap_processing option. */3147switch (display->colormap_processing)3148{3149case PNG_CMAP_NONE:3150/* Output must be one channel and one byte per pixel, the output3151* encoding can be anything.3152*/3153if ((color_type == PNG_COLOR_TYPE_PALETTE ||3154color_type == PNG_COLOR_TYPE_GRAY) && bit_depth == 8)3155break;31563157goto bad_output;31583159case PNG_CMAP_TRANS:3160case PNG_CMAP_GA:3161/* Output must be two channels and the 'G' one must be sRGB, the latter3162* can be checked with an exact number because it should have been set3163* to this number above!3164*/3165if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA && bit_depth == 8 &&3166!png_need_gamma_correction(png_ptr, png_memory_gamma(png_ptr),31671/*sRGB*/) &&3168image->colormap_entries == 256)3169break;31703171goto bad_output;31723173case PNG_CMAP_RGB:3174/* Output must be 8-bit sRGB encoded RGB */3175if (color_type == PNG_COLOR_TYPE_RGB && bit_depth == 8 &&3176!png_need_gamma_correction(png_ptr, png_memory_gamma(png_ptr),31771/*sRGB*/) &&3178image->colormap_entries == 216)3179break;31803181goto bad_output;31823183case PNG_CMAP_RGB_ALPHA:3184/* Output must be 8-bit sRGB encoded RGBA */3185if (color_type == PNG_COLOR_TYPE_RGB_ALPHA && bit_depth == 8 &&3186!png_need_gamma_correction(png_ptr, png_memory_gamma(png_ptr),31871/*sRGB*/) &&3188image->colormap_entries == 244 /* 216 + 1 + 27 */)3189break;31903191/* goto bad_output; */3192/* FALL THROUGH */31933194default:3195bad_output:3196impossible("bad color-map processing");3197}31983199/* Now read the rows. Do this here if it is possible to read directly into3200* the output buffer, otherwise allocate a local row buffer of the maximum3201* size libpng requires and call the relevant processing routine safely.3202*/3203{3204png_voidp first_row = display->buffer;3205ptrdiff_t row_bytes = display->row_stride;32063207/* The following expression is designed to work correctly whether it gives3208* a signed or an unsigned result.3209*/3210if (row_bytes < 0)3211{3212char *ptr = png_voidcast(char*, first_row);3213ptr += (image->height-1) * (-row_bytes);3214first_row = png_voidcast(png_voidp, ptr);3215}32163217display->first_row = first_row;3218display->row_bytes = row_bytes;3219}32203221if (passes == 0)3222{3223int result;3224png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));32253226display->local_row = row;3227result = png_safe_execute(image, png_image_read_and_map, display);3228display->local_row = NULL;3229png_free(png_ptr, row);32303231return result;3232}32333234else3235{3236png_alloc_size_t row_bytes = display->row_bytes;32373238while (--passes >= 0)3239{3240png_uint_32 y = image->height;3241png_bytep row = png_voidcast(png_bytep, display->first_row);32423243while (y-- > 0)3244{3245png_read_row(png_ptr, row, NULL);3246row += row_bytes;3247}3248}32493250return 1;3251}3252}32533254/* Just the row reading part of png_image_read. */3255static int3256png_image_read_composite(png_voidp argument)3257{3258png_image_read_control *display = png_voidcast(png_image_read_control*,3259argument);3260png_imagep image = display->image;3261png_structrp png_ptr = image->opaque->png_ptr;3262int passes;32633264switch (png_ptr->interlaced)3265{3266case PNG_INTERLACE_NONE:3267passes = 1;3268break;32693270case PNG_INTERLACE_ADAM7:3271passes = PNG_INTERLACE_ADAM7_PASSES;3272break;32733274default:3275png_error(png_ptr, "unknown interlace type");3276}32773278{3279png_uint_32 height = image->height;3280png_uint_32 width = image->width;3281ptrdiff_t step_row = display->row_bytes;3282unsigned int channels =3283(image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;3284int pass;32853286for (pass = 0; pass < passes; ++pass)3287{3288unsigned int startx, stepx, stepy;3289png_uint_32 y;32903291if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)3292{3293/* The row may be empty for a short image: */3294if (PNG_PASS_COLS(width, pass) == 0)3295continue;32963297startx = PNG_PASS_START_COL(pass) * channels;3298stepx = PNG_PASS_COL_OFFSET(pass) * channels;3299y = PNG_PASS_START_ROW(pass);3300stepy = PNG_PASS_ROW_OFFSET(pass);3301}33023303else3304{3305y = 0;3306startx = 0;3307stepx = channels;3308stepy = 1;3309}33103311for (; y<height; y += stepy)3312{3313png_bytep inrow = png_voidcast(png_bytep, display->local_row);3314png_bytep outrow;3315png_const_bytep end_row;33163317/* Read the row, which is packed: */3318png_read_row(png_ptr, inrow, NULL);33193320outrow = png_voidcast(png_bytep, display->first_row);3321outrow += y * step_row;3322end_row = outrow + width * channels;33233324/* Now do the composition on each pixel in this row. */3325outrow += startx;3326for (; outrow < end_row; outrow += stepx)3327{3328png_byte alpha = inrow[channels];33293330if (alpha > 0) /* else no change to the output */3331{3332unsigned int c;33333334for (c=0; c<channels; ++c)3335{3336png_uint_32 component = inrow[c];33373338if (alpha < 255) /* else just use component */3339{3340/* This is PNG_OPTIMIZED_ALPHA, the component value3341* is a linear 8-bit value. Combine this with the3342* current outrow[c] value which is sRGB encoded.3343* Arithmetic here is 16-bits to preserve the output3344* values correctly.3345*/3346component *= 257*255; /* =65535 */3347component += (255-alpha)*png_sRGB_table[outrow[c]];33483349/* So 'component' is scaled by 255*65535 and is3350* therefore appropriate for the sRGB to linear3351* conversion table.3352*/3353component =3354PNG_sRGB_FROM_LINEAR(png_ptr, component);3355}33563357outrow[c] = png_check_byte(png_ptr, component);3358}3359}33603361inrow += channels+1; /* components and alpha channel */3362}3363}3364}3365}33663367return 1;3368}33693370/* The do_local_background case; called when all the following transforms are to3371* be done:3372*3373* PNG_READ_RGB_TO_GRAY3374* PNG_READ_COMPOSITE3375* PNG_READ_GAMMA3376*3377* This is a work-around for the fact that both the PNG_READ_RGB_TO_GRAY and3378* PNG_COMPOSITE code performs gamma correction, so we get double gamma3379* correction. The fix-up is to prevent the PNG_COMPOSITE operation from3380* happening inside libpng, so this routine sees an 8 or 16-bit gray+alpha3381* row and handles the removal or pre-multiplication of the alpha channel.3382*/3383static int3384png_image_read_background(png_voidp argument)3385{3386png_image_read_control *display = png_voidcast(png_image_read_control*,3387argument);3388png_imagep image = display->image;3389png_structrp png_ptr = image->opaque->png_ptr;3390png_inforp info_ptr = image->opaque->info_ptr;3391png_uint_32 height = image->height;3392png_uint_32 width = image->width;3393int pass, passes;33943395/* Double check the convoluted logic below. We expect to get here with3396* libpng doing rgb to gray and gamma correction but background processing3397* left to the png_image_read_background function. The rows libpng produce3398* might be 8 or 16-bit but should always have two channels; gray plus alpha.3399*/3400affirm(PNG_COLOR_TYPE_FROM_FORMAT(info_ptr->format) ==3401PNG_COLOR_TYPE_GRAY_ALPHA);3402debug(png_get_channels(png_ptr, info_ptr) == 2);34033404/* Expect the 8-bit case to always remove the alpha channel */3405if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 &&3406(image->format & PNG_FORMAT_FLAG_ALPHA) != 0)3407png_error(png_ptr, "unexpected 8-bit transformation");34083409switch (png_ptr->interlaced)3410{3411case PNG_INTERLACE_NONE:3412passes = 1;3413break;34143415case PNG_INTERLACE_ADAM7:3416passes = PNG_INTERLACE_ADAM7_PASSES;3417break;34183419default:3420png_error(png_ptr, "unknown interlace type");3421}34223423/* Use direct access to info_ptr here because otherwise the simplified API3424* would require PNG_EASY_ACCESS_SUPPORTED (just for this.) Note this is3425* checking the value after libpng expansions, not the original value in the3426* PNG.3427*/3428switch (info_ptr->bit_depth)3429{3430default:3431png_error(png_ptr, "unexpected bit depth");3432break;34333434case 8:3435/* 8-bit sRGB gray values with an alpha channel; the alpha channel is3436* to be removed by composing on a background: either the row if3437* display->background is NULL or display->background->green if not.3438* Unlike the code above ALPHA_OPTIMIZED has *not* been done.3439*/3440{3441png_bytep first_row = png_voidcast(png_bytep, display->first_row);3442ptrdiff_t step_row = display->row_bytes;34433444for (pass = 0; pass < passes; ++pass)3445{3446png_bytep row = png_voidcast(png_bytep, display->first_row);3447unsigned int startx, stepx, stepy;3448png_uint_32 y;34493450if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)3451{3452/* The row may be empty for a short image: */3453if (PNG_PASS_COLS(width, pass) == 0)3454continue;34553456startx = PNG_PASS_START_COL(pass);3457stepx = PNG_PASS_COL_OFFSET(pass);3458y = PNG_PASS_START_ROW(pass);3459stepy = PNG_PASS_ROW_OFFSET(pass);3460}34613462else3463{3464y = 0;3465startx = 0;3466stepx = stepy = 1;3467}34683469if (display->background == NULL)3470{3471for (; y<height; y += stepy)3472{3473png_bytep inrow = png_voidcast(png_bytep,3474display->local_row);3475png_bytep outrow = first_row + y * step_row;3476png_const_bytep end_row = outrow + width;34773478/* Read the row, which is packed: */3479png_read_row(png_ptr, inrow, NULL);34803481/* Now do the composition on each pixel in this row. */3482outrow += startx;3483for (; outrow < end_row; outrow += stepx)3484{3485png_byte alpha = inrow[1];34863487if (alpha > 0) /* else no change to the output */3488{3489png_uint_32 component = inrow[0];34903491if (alpha < 255) /* else just use component */3492{3493/* Since PNG_OPTIMIZED_ALPHA was not set it is3494* necessary to invert the sRGB transfer3495* function and multiply the alpha out.3496*/3497component = png_sRGB_table[component] * alpha;3498component += png_sRGB_table[outrow[0]] *3499(255-alpha);3500component =3501PNG_sRGB_FROM_LINEAR(png_ptr, component);3502}35033504outrow[0] = png_check_byte(png_ptr, component);3505}35063507inrow += 2; /* gray and alpha channel */3508}3509}3510}35113512else /* constant background value */3513{3514png_byte background8 = display->background->green;3515png_uint_16 background = png_sRGB_table[background8];35163517for (; y<height; y += stepy)3518{3519png_bytep inrow = png_voidcast(png_bytep,3520display->local_row);3521png_bytep outrow = first_row + y * step_row;3522png_const_bytep end_row = outrow + width;35233524/* Read the row, which is packed: */3525png_read_row(png_ptr, inrow, NULL);35263527/* Now do the composition on each pixel in this row. */3528outrow += startx;3529for (; outrow < end_row; outrow += stepx)3530{3531png_byte alpha = inrow[1];35323533if (alpha > 0) /* else use background */3534{3535png_uint_32 component = inrow[0];35363537if (alpha < 255) /* else just use component */3538{3539component = png_sRGB_table[component] * alpha;3540component += background * (255-alpha);3541component =3542PNG_sRGB_FROM_LINEAR(png_ptr, component);3543}35443545outrow[0] = png_check_byte(png_ptr, component);3546}35473548else3549outrow[0] = background8;35503551inrow += 2; /* gray and alpha channel */3552}35533554row += display->row_bytes;3555}3556}3557}3558}3559break;35603561case 16:3562/* 16-bit linear with pre-multiplied alpha; the pre-multiplication must3563* still be done and, maybe, the alpha channel removed. This code also3564* handles the alpha-first option.3565*/3566{3567png_uint_16p first_row = png_voidcast(png_uint_16p,3568display->first_row);3569/* The division by two is safe because the caller passed in a3570* stride which was multiplied by 2 (below) to get row_bytes.3571*/3572ptrdiff_t step_row = display->row_bytes / 2;3573int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;3574unsigned int outchannels = 1+preserve_alpha;3575int swap_alpha = 0;35763577#ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED3578if (preserve_alpha != 0 &&3579(image->format & PNG_FORMAT_FLAG_AFIRST) != 0)3580swap_alpha = 1;3581#endif35823583for (pass = 0; pass < passes; ++pass)3584{3585unsigned int startx, stepx, stepy;3586png_uint_32 y;35873588/* The 'x' start and step are adjusted to output components here.3589*/3590if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)3591{3592/* The row may be empty for a short image: */3593if (PNG_PASS_COLS(width, pass) == 0)3594continue;35953596startx = PNG_PASS_START_COL(pass) * outchannels;3597stepx = PNG_PASS_COL_OFFSET(pass) * outchannels;3598y = PNG_PASS_START_ROW(pass);3599stepy = PNG_PASS_ROW_OFFSET(pass);3600}36013602else3603{3604y = 0;3605startx = 0;3606stepx = outchannels;3607stepy = 1;3608}36093610for (; y<height; y += stepy)3611{3612png_const_uint_16p inrow;3613png_uint_16p outrow = first_row + y*step_row;3614png_uint_16p end_row = outrow + width * outchannels;36153616/* Read the row, which is packed: */3617png_read_row(png_ptr, png_voidcast(png_bytep,3618display->local_row), NULL);3619inrow = png_voidcast(png_const_uint_16p, display->local_row);36203621/* Now do the pre-multiplication on each pixel in this row.3622*/3623outrow += startx;3624for (; outrow < end_row; outrow += stepx)3625{3626png_uint_32 component = inrow[0];3627png_uint_16 alpha = inrow[1];36283629if (alpha > 0) /* else 0 */3630{3631if (alpha < 65535) /* else just use component */3632{3633component *= alpha;3634component += 32767;3635component /= 65535;3636}3637}36383639else3640component = 0;36413642outrow[swap_alpha] =3643png_check_u16(png_ptr, component);3644if (preserve_alpha != 0)3645outrow[1 ^ swap_alpha] = alpha;36463647inrow += 2; /* components and alpha channel */3648}3649}3650}3651}3652break;3653}36543655return 1;3656}36573658/* The guts of png_image_finish_read as a png_safe_execute callback. */3659static int3660png_image_read_direct(png_voidp argument)3661{3662png_image_read_control *display = png_voidcast(png_image_read_control*,3663argument);3664png_imagep image = display->image;3665png_structrp png_ptr = image->opaque->png_ptr;3666png_inforp info_ptr = image->opaque->info_ptr;36673668png_uint_32 format = image->format;3669int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0;3670int do_local_compose = 0;3671int do_local_background = 0; /* to avoid double gamma correction bug */3672int passes = 0;36733674/* Add transforms to ensure the correct output format is produced then check3675* that the required implementation support is there. Always expand; always3676* need 8 bits minimum, no palette and expanded tRNS.3677*/3678png_set_expand(png_ptr);36793680/* Now check the format to see if it was modified. */3681{3682png_uint_32 base_format = png_image_format(png_ptr) &3683PNG_BIC_MASK(PNG_FORMAT_FLAG_COLORMAP) /* removed by png_set_expand */;3684png_uint_32 change = format ^ base_format;3685png_fixed_point output_gamma;3686int mode; /* alpha mode */36873688/* Do this first so that we have a record if rgb to gray is happening. */3689if ((change & PNG_FORMAT_FLAG_COLOR) != 0)3690{3691/* gray<->color transformation required. */3692if ((format & PNG_FORMAT_FLAG_COLOR) != 0)3693png_set_gray_to_rgb(png_ptr);36943695else3696{3697/* libpng can't do both rgb to gray and3698* background/pre-multiplication if there is also significant gamma3699* correction, because both operations require linear colors and3700* the code only supports one transform doing the gamma correction.3701* Handle this by doing the pre-multiplication or background3702* operation in this code, if necessary.3703*3704* TODO: fix this by rewriting pngrtran.c (!)3705*3706* For the moment (given that fixing this in pngrtran.c is an3707* enormous change) 'do_local_background' is used to indicate that3708* the problem exists.3709*/3710if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)3711do_local_background = 1/*maybe*/;37123713png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,3714PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);3715}37163717change &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR);3718}37193720/* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise.3721*/3722{3723png_fixed_point input_gamma_default;37243725if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 &&3726(image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)3727input_gamma_default = PNG_GAMMA_LINEAR;3728else3729input_gamma_default = PNG_DEFAULT_sRGB;37303731/* Call png_set_alpha_mode to set the default for the input gamma; the3732* output gamma is set by a second call below.3733*/3734png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default);3735}37363737if (linear != 0)3738{3739/* If there *is* an alpha channel in the input it must be multiplied3740* out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG.3741*/3742if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)3743mode = PNG_ALPHA_STANDARD; /* associated alpha */37443745else3746mode = PNG_ALPHA_PNG;37473748output_gamma = PNG_GAMMA_LINEAR;3749}37503751else3752{3753mode = PNG_ALPHA_PNG;3754output_gamma = PNG_DEFAULT_sRGB;3755}37563757/* If 'do_local_background' is set check for the presence of gamma3758* correction; this is part of the work-round for the libpng bug3759* described above.3760*3761* TODO: fix libpng and remove this.3762*/3763if (do_local_background != 0)3764{3765/* This is intended to be a safe check to see if libpng will perform3766* gamma work in pngrtran.c; if it will *not* be performed the3767* do_local_background flag is cancelled.3768*/3769if (!png_need_gamma_correction(png_ptr, 0/*PNG gamma*/,3770output_gamma != PNG_GAMMA_LINEAR))3771do_local_background = 0;37723773else if (mode == PNG_ALPHA_STANDARD)3774{3775do_local_background = 2/*required*/;3776mode = PNG_ALPHA_PNG; /* prevent libpng doing it */3777}37783779/* else leave as 1 for the checks below */3780}37813782/* If the bit-depth changes then handle that here. */3783if ((change & PNG_FORMAT_FLAG_LINEAR) != 0)3784{3785if (linear != 0 /*16-bit output*/)3786png_set_expand_16(png_ptr);37873788else /* 8-bit output */3789png_set_scale_16(png_ptr);37903791change &= PNG_BIC_MASK(PNG_FORMAT_FLAG_LINEAR);3792}37933794/* Now the background/alpha channel changes. */3795if ((change & PNG_FORMAT_FLAG_ALPHA) != 0)3796{3797/* Removing an alpha channel requires composition for the 8-bit3798* formats; for the 16-bit it is already done, above, by the3799* pre-multiplication and the channel just needs to be stripped.3800*/3801if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)3802{3803/* If RGB->gray is happening the alpha channel must be left and the3804* operation completed locally.3805*3806* TODO: fix libpng and remove this.3807*/3808if (do_local_background != 0)3809do_local_background = 2/*required*/;38103811/* 16-bit output: just remove the channel */3812else if (linear != 0) /* compose on black (well, pre-multiply) */3813png_set_strip_alpha(png_ptr);38143815/* 8-bit output: do an appropriate compose */3816else if (display->background != NULL)3817{3818png_color_16 c;38193820c.index = 0; /*unused*/3821c.red = display->background->red;3822c.green = display->background->green;3823c.blue = display->background->blue;3824c.gray = display->background->green;38253826/* This is always an 8-bit sRGB value, using the 'green' channel3827* for gray is much better than calculating the luminance here;3828* we can get off-by-one errors in that calculation relative to3829* the app expectations and that will show up in transparent3830* pixels.3831*/3832png_set_background_fixed(png_ptr, &c,3833PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,38340/*gamma: not used*/);3835}38363837else /* compose on row: implemented below. */3838{3839do_local_compose = 1;3840/* This leaves the alpha channel in the output, so it has to be3841* removed by the code below. Set the encoding to the 'OPTIMIZE'3842* one so the code only has to hack on the pixels that require3843* composition.3844*/3845mode = PNG_ALPHA_OPTIMIZED;3846}3847}38483849else /* output needs an alpha channel */3850{3851/* This is tricky because it happens before the swap operation has3852* been accomplished; however, the swap does *not* swap the added3853* alpha channel (weird API), so it must be added in the correct3854* place.3855*/3856png_uint_32 filler; /* opaque filler */3857int where;38583859if (linear != 0)3860filler = 65535;38613862else3863filler = 255;38643865#ifdef PNG_FORMAT_AFIRST_SUPPORTED3866if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)3867{3868where = PNG_FILLER_BEFORE;3869change &= PNG_BIC_MASK(PNG_FORMAT_FLAG_AFIRST);3870}38713872else3873#endif3874where = PNG_FILLER_AFTER;38753876png_set_add_alpha(png_ptr, filler, where);3877}38783879/* This stops the (irrelevant) call to swap_alpha below. */3880change &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);3881}38823883/* Now set the alpha mode correctly; this is always done, even if there is3884* no alpha channel in either the input or the output because it correctly3885* sets the output gamma.3886*/3887png_set_alpha_mode_fixed(png_ptr, mode, output_gamma);38883889# ifdef PNG_FORMAT_BGR_SUPPORTED3890if ((change & PNG_FORMAT_FLAG_BGR) != 0)3891{3892/* Check only the output format; PNG is never BGR; don't do this if3893* the output is gray, but fix up the 'format' value in that case.3894*/3895if ((format & PNG_FORMAT_FLAG_COLOR) != 0)3896png_set_bgr(png_ptr);38973898else3899format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_BGR);39003901change &= PNG_BIC_MASK(PNG_FORMAT_FLAG_BGR);3902}3903# endif39043905# ifdef PNG_FORMAT_AFIRST_SUPPORTED3906if ((change & PNG_FORMAT_FLAG_AFIRST) != 0)3907{3908/* Only relevant if there is an alpha channel - it's particularly3909* important to handle this correctly because do_local_compose may3910* be set above and then libpng will keep the alpha channel for this3911* code to remove.3912*/3913if ((format & PNG_FORMAT_FLAG_ALPHA) != 0)3914{3915/* Disable this if doing a local background,3916* TODO: remove this when local background is no longer required.3917*/3918if (do_local_background != 2)3919png_set_swap_alpha(png_ptr);3920}39213922else3923format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_AFIRST);39243925change &= PNG_BIC_MASK(PNG_FORMAT_FLAG_AFIRST);3926}3927# endif39283929/* If the *output* is 16-bit then we need to check for a byte-swap on this3930* architecture.3931*/3932if (linear != 0)3933{3934PNG_CONST png_uint_16 le = 0x0001;39353936if ((*(png_const_bytep) & le) != 0)3937png_set_swap(png_ptr);3938}39393940/* If change is not now 0 some transformation is missing - error out. */3941if (change != 0)3942png_error(png_ptr, "png_read_image: unsupported transformation");3943}39443945PNG_SKIP_CHUNKS(png_ptr);39463947/* Update the 'info' structure and make sure the result is as required; first3948* make sure to turn on the interlace handling if it will be required3949* (because it can't be turned on *after* the call to png_read_update_info!)3950*3951* TODO: remove the do_local_background fixup below.3952*/3953if (do_local_compose == 0 && do_local_background != 2)3954passes = png_set_interlace_handling(png_ptr);39553956png_read_update_info(png_ptr, info_ptr);39573958{3959png_uint_32 out_format = png_memory_format(png_ptr);39603961/* Swapping is expected for the 16-bit format: */3962out_format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_SWAPPED);39633964/* The remaining upper bits should never be set: */3965affirm(!(out_format & ~0x3FU));39663967if ((out_format & PNG_FORMAT_FLAG_ALPHA) != 0)3968{3969/* do_local_compose removes this channel below. */3970if (do_local_compose != 0 ||3971/* do_local_background does the same if required. */3972(do_local_background == 2 &&3973(format & PNG_FORMAT_FLAG_ALPHA) == 0))3974out_format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);3975}39763977else3978affirm(do_local_compose == 0 /* else alpha channel lost */);39793980switch (png_memory_channel_depth(png_ptr))3981{3982case 16: affirm((out_format & PNG_FORMAT_FLAG_LINEAR) != 0); break;3983case 8: affirm((out_format & PNG_FORMAT_FLAG_LINEAR) == 0); break;3984default: impossible("unexpected bit depth"); break;3985}39863987# ifdef PNG_FORMAT_AFIRST_SUPPORTED3988if (do_local_background == 2)3989{3990/* do_local_background should be handling the swap: */3991affirm(!(out_format & PNG_FORMAT_FLAG_AFIRST));39923993if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)3994out_format |= PNG_FORMAT_FLAG_AFIRST;3995}3996# endif39973998/* This is actually an internal error. */3999affirm(out_format == format /* else unimplemented transformations */);4000}40014002/* Now read the rows. If do_local_compose is set then it is necessary to use4003* a local row buffer. The output will be GA, RGBA or BGRA and must be4004* converted to G, RGB or BGR as appropriate. The 'local_row' member of the4005* display acts as a flag.4006*/4007{4008png_voidp first_row = display->buffer;4009ptrdiff_t row_bytes = display->row_stride;40104011if (linear != 0)4012row_bytes *= 2;40134014/* The following expression is designed to work correctly whether it gives4015* a signed or an unsigned result.4016*/4017if (row_bytes < 0)4018{4019char *ptr = png_voidcast(char*, first_row);4020ptr += (image->height-1) * (-row_bytes);4021first_row = png_voidcast(png_voidp, ptr);4022}40234024display->first_row = first_row;4025display->row_bytes = row_bytes;4026}40274028if (do_local_compose != 0)4029{4030int result;4031png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));40324033display->local_row = row;4034result = png_safe_execute(image, png_image_read_composite, display);4035display->local_row = NULL;4036png_free(png_ptr, row);40374038return result;4039}40404041else if (do_local_background == 2)4042{4043int result;4044png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));40454046display->local_row = row;4047result = png_safe_execute(image, png_image_read_background, display);4048display->local_row = NULL;4049png_free(png_ptr, row);40504051return result;4052}40534054else4055{4056png_alloc_size_t row_bytes = display->row_bytes;40574058while (--passes >= 0)4059{4060png_uint_32 y = image->height;4061png_bytep row = png_voidcast(png_bytep, display->first_row);40624063while (y-- > 0)4064{4065png_read_row(png_ptr, row, NULL);4066row += row_bytes;4067}4068}40694070return 1;4071}4072}40734074int PNGAPI4075png_image_finish_read(png_imagep image, png_const_colorp background,4076void *buffer, ptrdiff_t row_stride, void *colormap)4077{4078if (image != NULL && image->version == PNG_IMAGE_VERSION)4079{4080/* Check for row_stride overflow. This check is not performed on the4081* original PNG format because it may not occur in the output PNG format4082* and libpng deals with the issues of reading the original.4083*/4084const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);40854086/* The test is slightly evil: it assumes that a signed pointer difference4087* (ptrdiff_t) can hold a maximum value of half, rounded down, of the4088* maximum of a (size_t). This is almost certain to be true.4089*/4090if (image->width <= (PNG_SIZE_MAX >> 1)/channels) /* no overflow */4091{4092png_alloc_size_t check;4093const png_alloc_size_t png_row_stride =4094(png_alloc_size_t)/*SAFE*/image->width * channels;40954096if (row_stride == 0)4097row_stride = (ptrdiff_t)png_row_stride;40984099if (row_stride < 0)4100check = -row_stride;41014102else4103check = row_stride;41044105if (image->opaque != NULL && buffer != NULL && check >= png_row_stride)4106{4107/* Now check for overflow of the image buffer calculation; this4108* limits the whole image size to PNG_SIZE_MAX bytes.4109*4110* The PNG_IMAGE_BUFFER_SIZE macro is:4111*4112* (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride))4113*4114* We have no way of guaranteeing that the application used the4115* correct type for 'row_stride' if it used the macro, so this is4116* technically not completely safe, but this is the case throughout4117* libpng; the app is responsible for making sure the calcualtion of4118* buffer sizes does not overflow.4119*/4120if (image->height <= PNG_SIZE_MAX /4121PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format) / check)4122{4123if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||4124(image->colormap_entries > 0 && colormap != NULL))4125{4126int result;4127png_image_read_control display;41284129memset(&display, 0, (sizeof display));4130display.image = image;4131display.buffer = buffer;4132display.row_stride = row_stride;4133display.colormap = colormap;4134display.background = background;4135display.local_row = NULL;41364137/* Choose the correct 'end' routine; for the color-map case4138* all the setup has already been done.4139*/4140if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)4141result =4142png_safe_execute(image,4143png_image_read_colormap, &display) &&4144png_safe_execute(image,4145png_image_read_colormapped, &display);41464147else4148result =4149png_safe_execute(image,4150png_image_read_direct, &display);41514152png_image_free(image);4153return result;4154}41554156else4157return png_image_error(image,4158"png_image_finish_read[color-map]: no color-map");4159}41604161else4162return png_image_error(image,4163"png_image_finish_read: image too large");4164}41654166else4167return png_image_error(image,4168"png_image_finish_read: invalid argument");4169}41704171else4172return png_image_error(image,4173"png_image_finish_read: row_stride too large");4174}41754176else if (image != NULL)4177return png_image_error(image,4178"png_image_finish_read: damaged PNG_IMAGE_VERSION");41794180return 0;4181}41824183#endif /* SIMPLIFIED_READ */4184#endif /* READ */418541864187