14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* pngread.c - read a PNG file 34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Last changed in libpng 1.6.17 [March 26, 2015] 54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson 64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This code is released under the libpng license. 104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * For conditions of distribution and use, see the disclaimer 114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and license in png.h 124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This file contains routines that an application calls directly to 144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * read a PNG file or stream. 154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "pngpriv.h" 184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) 194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# include <errno.h> 204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SUPPORTED 234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Create a PNG structure for reading, and allocate any memory needed. */ 254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannPNG_FUNCTION(png_structp,PNGAPI 264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, 274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) 284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifndef PNG_USER_MEM_SUPPORTED 304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, 314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error_fn, warn_fn, NULL, NULL, NULL); 324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_create_read_struct_2(user_png_ver, error_ptr, error_fn, 344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann warn_fn, NULL, NULL, NULL); 354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Alternate create PNG structure for reading, and allocate any memory 384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * needed. 394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannPNG_FUNCTION(png_structp,PNGAPI 414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, 424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, 434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) 444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, 464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); 474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* USER_MEM */ 484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr != NULL) 504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->mode = PNG_IS_READ_STRUCT; 524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Added in libpng-1.6.0; this can be used to detect a read structure if 544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * required (it will be zero in a write structure.) 554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_SEQUENTIAL_READ_SUPPORTED 574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE; 584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED 614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; 624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* In stable builds only warn if an application error can be completely 644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * handled. 654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# if PNG_RELEASE_BUILD 674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; 684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* TODO: delay this, it can be done in png_init_io (if the app doesn't 724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * do it itself) avoiding setting the default function if it is not 734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * required. 744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_read_fn(png_ptr, NULL, NULL); 764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_ptr; 794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Read the information before the actual image data. This has been 844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * changed in v0.90 to allow reading a file that already has the magic 854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * bytes read from the stream. You can tell libpng how many bytes have 864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * been read from the beginning of the stream (up to the maximum of 8) 874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * via png_set_sig_bytes(), and we will only check the remaining bytes 884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * here. The application can then have access to the signature bytes we 894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * read if it is determined that this isn't a valid PNG file. 904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_read_info(png_structrp png_ptr, png_inforp info_ptr) 934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int keep; 964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_read_info"); 994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL || info_ptr == NULL) 1014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 1024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Read and check the PNG file signature. */ 1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_sig(png_ptr, info_ptr); 1054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (;;) 1074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 1084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 length = png_read_chunk_header(png_ptr); 1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 chunk_name = png_ptr->chunk_name; 1104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* IDAT logic needs to happen here to simplify getting the two flags 1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * right. 1134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (chunk_name == png_IDAT) 1154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 1164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) 1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_chunk_error(png_ptr, "Missing IHDR before IDAT"); 1184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 1204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_ptr->mode & PNG_HAVE_PLTE) == 0) 1214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_chunk_error(png_ptr, "Missing PLTE before IDAT"); 1224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) 1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_chunk_benign_error(png_ptr, "Too many IDATs found"); 1254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->mode |= PNG_HAVE_IDAT; 1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) 1304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; 1324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->mode |= PNG_AFTER_IDAT; 1334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This should be a binary subdivision search or a hash for 1364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * matching the chunk name rather than a linear search. 1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 1384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (chunk_name == png_IHDR) 1394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_IHDR(png_ptr, info_ptr, length); 1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_IEND) 1424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_IEND(png_ptr, info_ptr, length); 1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 1454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) 1464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 1474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_unknown(png_ptr, info_ptr, length, keep); 1484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (chunk_name == png_PLTE) 1504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->mode |= PNG_HAVE_PLTE; 1514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_IDAT) 1534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 1544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->idat_size = 0; /* It has been consumed */ 1554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 1564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 1594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_PLTE) 1604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_PLTE(png_ptr, info_ptr, length); 1614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_IDAT) 1634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 1644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->idat_size = length; 1654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 1664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_bKGD_SUPPORTED 1694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_bKGD) 1704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_bKGD(png_ptr, info_ptr, length); 1714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 1724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_cHRM_SUPPORTED 1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_cHRM) 1754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_cHRM(png_ptr, info_ptr, length); 1764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 1774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_gAMA_SUPPORTED 1794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_gAMA) 1804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_gAMA(png_ptr, info_ptr, length); 1814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 1824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_hIST_SUPPORTED 1844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_hIST) 1854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_hIST(png_ptr, info_ptr, length); 1864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 1874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_oFFs_SUPPORTED 1894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_oFFs) 1904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_oFFs(png_ptr, info_ptr, length); 1914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 1924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_pCAL_SUPPORTED 1944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_pCAL) 1954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_pCAL(png_ptr, info_ptr, length); 1964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 1974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_sCAL_SUPPORTED 1994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_sCAL) 2004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_sCAL(png_ptr, info_ptr, length); 2014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_pHYs_SUPPORTED 2044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_pHYs) 2054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_pHYs(png_ptr, info_ptr, length); 2064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_sBIT_SUPPORTED 2094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_sBIT) 2104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_sBIT(png_ptr, info_ptr, length); 2114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_sRGB_SUPPORTED 2144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_sRGB) 2154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_sRGB(png_ptr, info_ptr, length); 2164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_iCCP_SUPPORTED 2194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_iCCP) 2204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_iCCP(png_ptr, info_ptr, length); 2214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_sPLT_SUPPORTED 2244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_sPLT) 2254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_sPLT(png_ptr, info_ptr, length); 2264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_tEXt_SUPPORTED 2294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_tEXt) 2304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_tEXt(png_ptr, info_ptr, length); 2314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_tIME_SUPPORTED 2344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_tIME) 2354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_tIME(png_ptr, info_ptr, length); 2364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_tRNS_SUPPORTED 2394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_tRNS) 2404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_tRNS(png_ptr, info_ptr, length); 2414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_zTXt_SUPPORTED 2444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_zTXt) 2454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_zTXt(png_ptr, info_ptr, length); 2464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_iTXt_SUPPORTED 2494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_iTXt) 2504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_iTXt(png_ptr, info_ptr, length); 2514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 2544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_unknown(png_ptr, info_ptr, length, 2554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_HANDLE_CHUNK_AS_DEFAULT); 2564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 2574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 2584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SEQUENTIAL_READ */ 2594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Optional call to update the users info_ptr structure */ 2614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 2624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_read_update_info(png_structrp png_ptr, png_inforp info_ptr) 2634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 2644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_read_update_info"); 2654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr != NULL) 2674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 2684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) 2694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 2704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_start_row(png_ptr); 2714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_READ_TRANSFORMS_SUPPORTED 2734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_transform_info(png_ptr, info_ptr); 2744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# else 2754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED(info_ptr) 2764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 2774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 2784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* New in 1.6.0 this avoids the bug of doing the initializations twice */ 2804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 2814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, 2824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_read_update_info/png_start_read_image: duplicate call"); 2834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 2844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 2854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 2874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Initialize palette, background, etc, after transformations 2884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * are set, but before any reading takes place. This allows 2894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the user to obtain a gamma-corrected palette, for example. 2904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * If the user doesn't call this, we will do it ourselves. 2914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 2924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 2934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_start_read_image(png_structrp png_ptr) 2944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 2954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_start_read_image"); 2964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr != NULL) 2984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 2994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) 3004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_start_row(png_ptr); 3014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* New in 1.6.0 this avoids the bug of doing the initializations twice */ 3034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 3044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, 3054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_start_read_image/png_read_update_info: duplicate call"); 3064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SEQUENTIAL_READ */ 3094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 3114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_MNG_FEATURES_SUPPORTED 3124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Undoes intrapixel differencing, 3134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * NOTE: this is apparently only supported in the 'sequential' reader. 3144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 3154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void 3164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_do_read_intrapixel(png_row_infop row_info, png_bytep row) 3174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 3184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_do_read_intrapixel"); 3194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ( 3214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) 3224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 3234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int bytes_per_pixel; 3244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 row_width = row_info->width; 3254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (row_info->bit_depth == 8) 3274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 3284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep rp; 3294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 i; 3304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (row_info->color_type == PNG_COLOR_TYPE_RGB) 3324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bytes_per_pixel = 3; 3334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 3354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bytes_per_pixel = 4; 3364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 3384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 3394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) 3414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 3424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); 3434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); 3444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (row_info->bit_depth == 16) 3474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 3484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep rp; 3494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 i; 3504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (row_info->color_type == PNG_COLOR_TYPE_RGB) 3524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bytes_per_pixel = 6; 3534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 3554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bytes_per_pixel = 8; 3564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 3584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 3594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) 3614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 3624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); 3634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); 3644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); 3654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 red = (s0 + s1 + 65536) & 0xffff; 3664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; 3674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *(rp ) = (png_byte)((red >> 8) & 0xff); 3684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *(rp + 1) = (png_byte)(red & 0xff); 3694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *(rp + 4) = (png_byte)((blue >> 8) & 0xff); 3704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *(rp + 5) = (png_byte)(blue & 0xff); 3714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* MNG_FEATURES */ 3764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 3784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) 3794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 3804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_row_info row_info; 3814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 3834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 3844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug2(1, "in png_read_row (row %lu, pass %d)", 3864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (unsigned long)png_ptr->row_number, png_ptr->pass); 3874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* png_read_start_row sets the information (in particular iwidth) for this 3894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * interlace pass. 3904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 3914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) 3924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_start_row(png_ptr); 3934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 1.5.6: row_info moved out of png_struct to a local here. */ 3954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ 3964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row_info.color_type = png_ptr->color_type; 3974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row_info.bit_depth = png_ptr->bit_depth; 3984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row_info.channels = png_ptr->channels; 3994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row_info.pixel_depth = png_ptr->pixel_depth; 4004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); 4014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_WARNINGS_SUPPORTED 4034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->row_number == 0 && png_ptr->pass == 0) 4044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Check for transforms that have been set but were defined out */ 4064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) 4074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) 4084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); 4094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 4104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) 4124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & PNG_FILLER) != 0) 4134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); 4144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 4154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ 4174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann !defined(PNG_READ_PACKSWAP_SUPPORTED) 4184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & PNG_PACKSWAP) != 0) 4194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); 4204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 4214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) 4234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & PNG_PACK) != 0) 4244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); 4254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 4264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) 4284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & PNG_SHIFT) != 0) 4294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); 4304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 4314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) 4334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & PNG_BGR) != 0) 4344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); 4354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 4364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) 4384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) 4394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); 4404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 4414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* WARNINGS */ 4434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_INTERLACING_SUPPORTED 4454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If interlaced and we do not need a new row, combine row and return. 4464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Notice that the pixels we have from previous rows have been transformed 4474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * already; we can only combine like with like (transformed or 4484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * untransformed) and, because of the libpng API for interlaced images, this 4494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * means we must transform before de-interlacing. 4504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 4514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->interlaced != 0 && 4524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_ptr->transformations & PNG_INTERLACE) != 0) 4534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (png_ptr->pass) 4554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0: 4574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->row_number & 0x07) 4584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (dsp_row != NULL) 4604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_combine_row(png_ptr, dsp_row, 1/*display*/); 4614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_finish_row(png_ptr); 4624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 4634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 4654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 1: 4674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) 4684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (dsp_row != NULL) 4704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_combine_row(png_ptr, dsp_row, 1/*display*/); 4714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_finish_row(png_ptr); 4734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 4744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 4764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 2: 4784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->row_number & 0x07) != 4) 4794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (dsp_row != NULL && (png_ptr->row_number & 4)) 4814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_combine_row(png_ptr, dsp_row, 1/*display*/); 4824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_finish_row(png_ptr); 4844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 4854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 4874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 3: 4894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->row_number & 3) || png_ptr->width < 3) 4904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (dsp_row != NULL) 4924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_combine_row(png_ptr, dsp_row, 1/*display*/); 4934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_finish_row(png_ptr); 4954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 4964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 4984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 4: 5004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->row_number & 3) != 2) 5014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (dsp_row != NULL && (png_ptr->row_number & 2)) 5034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_combine_row(png_ptr, dsp_row, 1/*display*/); 5044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_finish_row(png_ptr); 5064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 5074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 5094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 5: 5114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->row_number & 1) || png_ptr->width < 2) 5124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (dsp_row != NULL) 5144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_combine_row(png_ptr, dsp_row, 1/*display*/); 5154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_finish_row(png_ptr); 5174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 5184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 5204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 5224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 6: 5234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->row_number & 1) == 0) 5244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_finish_row(png_ptr); 5264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 5274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 5294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 5324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) 5344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "Invalid attempt to read row data"); 5354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Fill the row with IDAT data: */ 5374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1); 5384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) 5404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) 5424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, 5434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->prev_row + 1, png_ptr->row_buf[0]); 5444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 5454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "bad adaptive filter value"); 5464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before 5494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 1.5.6, while the buffer really is this big in current versions of libpng 5504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it may not be in the future, so this was changed just to copy the 5514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * interlaced count: 5524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 5534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); 5544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_MNG_FEATURES_SUPPORTED 5564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && 5574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) 5584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Intrapixel differencing */ 5604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1); 5614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 5634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_TRANSFORMS_SUPPORTED 5654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->transformations) 5664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_do_read_transformations(png_ptr, &row_info); 5674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 5684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The transformed pixel depth should match the depth now in row_info. */ 5704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->transformed_pixel_depth == 0) 5714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->transformed_pixel_depth = row_info.pixel_depth; 5734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) 5744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "sequential row overflow"); 5754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) 5784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "internal sequential row size calculation error"); 5794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_INTERLACING_SUPPORTED 5814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Expand interlaced rows to full size */ 5824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->interlaced != 0 && 5834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_ptr->transformations & PNG_INTERLACE) != 0) 5844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->pass < 6) 5864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, 5874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->transformations); 5884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (dsp_row != NULL) 5904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_combine_row(png_ptr, dsp_row, 1/*display*/); 5914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (row != NULL) 5934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_combine_row(png_ptr, row, 0/*row*/); 5944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 5974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 5984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (row != NULL) 6004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_combine_row(png_ptr, row, -1/*ignored*/); 6014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (dsp_row != NULL) 6034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_combine_row(png_ptr, dsp_row, -1/*ignored*/); 6044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 6054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_finish_row(png_ptr); 6064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->read_row_fn != NULL) 6084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); 6094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 6114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SEQUENTIAL_READ */ 6124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 6144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Read one or more rows of image data. If the image is interlaced, 6154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and png_set_interlace_handling() has been called, the rows need to 6164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * contain the contents of the rows from the previous pass. If the 6174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * image has alpha or transparency, and png_handle_alpha()[*] has been 6184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * called, the rows contents must be initialized to the contents of the 6194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * screen. 6204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 6214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * "row" holds the actual image, and pixels are placed in it 6224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * as they arrive. If the image is displayed after each pass, it will 6234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * appear to "sparkle" in. "display_row" can be used to display a 6244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * "chunky" progressive image, with finer detail added as it becomes 6254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * available. If you do not want this "chunky" display, you may pass 6264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * NULL for display_row. If you do not want the sparkle display, and 6274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * you have not called png_handle_alpha(), you may pass NULL for rows. 6284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * If you have called png_handle_alpha(), and the image has either an 6294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * alpha channel or a transparency chunk, you must provide a buffer for 6304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * rows. In this case, you do not have to provide a display_row buffer 6314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * also, but you may. If the image is not interlaced, or if you have 6324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * not called png_set_interlace_handling(), the display_row buffer will 6334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * be ignored, so pass NULL to it. 6344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 6354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * [*] png_handle_alpha() does not exist yet, as of this version of libpng 6364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 6374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 6394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_read_rows(png_structrp png_ptr, png_bytepp row, 6404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytepp display_row, png_uint_32 num_rows) 6414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 6424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 i; 6434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytepp rp; 6444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytepp dp; 6454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_read_rows"); 6474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 6494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 6504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann rp = row; 6524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dp = display_row; 6534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (rp != NULL && dp != NULL) 6544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < num_rows; i++) 6554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 6564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep rptr = *rp++; 6574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep dptr = *dp++; 6584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_row(png_ptr, rptr, dptr); 6604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 6614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (rp != NULL) 6634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < num_rows; i++) 6644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 6654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep rptr = *rp; 6664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_row(png_ptr, rptr, NULL); 6674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann rp++; 6684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 6694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (dp != NULL) 6714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < num_rows; i++) 6724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 6734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep dptr = *dp; 6744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_row(png_ptr, NULL, dptr); 6754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dp++; 6764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 6774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 6784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SEQUENTIAL_READ */ 6794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 6814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Read the entire image. If the image has an alpha channel or a tRNS 6824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * chunk, and you have called png_handle_alpha()[*], you will need to 6834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * initialize the image to the current image that PNG will be overlaying. 6844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * We set the num_rows again here, in case it was incorrectly set in 6854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_read_start_row() by a call to png_read_update_info() or 6864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_start_read_image() if png_set_interlace_handling() wasn't called 6874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * prior to either of these functions like it should have been. You can 6884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * only call this function once. If you desire to have an image for 6894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * each pass of a interlaced image, use png_read_rows() instead. 6904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 6914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * [*] png_handle_alpha() does not exist yet, as of this version of libpng 6924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 6934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 6944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_read_image(png_structrp png_ptr, png_bytepp image) 6954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 6964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 i, image_height; 6974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int pass, j; 6984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytepp rp; 6994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_read_image"); 7014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 7034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 7044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_INTERLACING_SUPPORTED 7064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) 7074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 7084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pass = png_set_interlace_handling(png_ptr); 7094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And make sure transforms are initialized. */ 7104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_start_read_image(png_ptr); 7114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 7124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 7134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 7144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->interlaced != 0 && 7154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_ptr->transformations & PNG_INTERLACE) == 0) 7164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 7174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Caller called png_start_read_image or png_read_update_info without 7184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * first turning on the PNG_INTERLACE transform. We can fix this here, 7194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * but the caller should do it! 7204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 7214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Interlace handling should be turned on when " 7224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "using png_read_image"); 7234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Make sure this is set correctly */ 7244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->num_rows = png_ptr->height; 7254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 7264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in 7284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the above error case. 7294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 7304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pass = png_set_interlace_handling(png_ptr); 7314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 7324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 7334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->interlaced) 7344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, 7354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "Cannot read interlaced image -- interlace handler disabled"); 7364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pass = 1; 7384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 7394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image_height=png_ptr->height; 7414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (j = 0; j < pass; j++) 7434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 7444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann rp = image; 7454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < image_height; i++) 7464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 7474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_row(png_ptr, *rp, NULL); 7484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann rp++; 7494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 7504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 7514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 7524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SEQUENTIAL_READ */ 7534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 7554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Read the end of the PNG file. Will not read past the end of the 7564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * file, will verify the end is accurate, and will read any comments 7574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * or time information at the end of the file, if info is not NULL. 7584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 7594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 7604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_read_end(png_structrp png_ptr, png_inforp info_ptr) 7614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 7624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 7634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int keep; 7644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 7654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_read_end"); 7674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 7694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 7704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If png_read_end is called in the middle of reading the rows there may 7724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * still be pending IDAT data and an owned zstream. Deal with this here. 7734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 7744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 7754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0) 7764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 7774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_finish_IDAT(png_ptr); 7784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED 7804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Report invalid palette index; added at libng-1.5.10 */ 7814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 7824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->num_palette_max > png_ptr->num_palette) 7834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_benign_error(png_ptr, "Read palette index exceeding num_palette"); 7844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 7854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann do 7874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 7884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 length = png_read_chunk_header(png_ptr); 7894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 chunk_name = png_ptr->chunk_name; 7904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (chunk_name != png_IDAT) 7924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; 7934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (chunk_name == png_IEND) 7954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_IEND(png_ptr, info_ptr, length); 7964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_IHDR) 7984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_IHDR(png_ptr, info_ptr, length); 7994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (info_ptr == NULL) 8014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_crc_finish(png_ptr, length); 8024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 8044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) 8054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 8064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (chunk_name == png_IDAT) 8074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 8084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) 8094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) 8104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_benign_error(png_ptr, ".Too many IDATs found"); 8114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 8124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_unknown(png_ptr, info_ptr, length, keep); 8134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (chunk_name == png_PLTE) 8144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->mode |= PNG_HAVE_PLTE; 8154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 8164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_IDAT) 8194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 8204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Zero length IDATs are legal after the last IDAT has been 8214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * read, but not after other chunks have been read. 1.6 does not 8224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * always read all the deflate data; specifically it cannot be relied 8234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * upon to read the Adler32 at the end. If it doesn't ignore IDAT 8244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * chunks which are longer than zero as well: 8254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 8264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) 8274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) 8284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_benign_error(png_ptr, "..Too many IDATs found"); 8294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_crc_finish(png_ptr, length); 8314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 8324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_PLTE) 8334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_PLTE(png_ptr, info_ptr, length); 8344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_bKGD_SUPPORTED 8364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_bKGD) 8374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_bKGD(png_ptr, info_ptr, length); 8384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_cHRM_SUPPORTED 8414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_cHRM) 8424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_cHRM(png_ptr, info_ptr, length); 8434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_gAMA_SUPPORTED 8464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_gAMA) 8474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_gAMA(png_ptr, info_ptr, length); 8484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_hIST_SUPPORTED 8514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_hIST) 8524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_hIST(png_ptr, info_ptr, length); 8534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_oFFs_SUPPORTED 8564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_oFFs) 8574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_oFFs(png_ptr, info_ptr, length); 8584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_pCAL_SUPPORTED 8614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_pCAL) 8624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_pCAL(png_ptr, info_ptr, length); 8634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_sCAL_SUPPORTED 8664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_sCAL) 8674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_sCAL(png_ptr, info_ptr, length); 8684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_pHYs_SUPPORTED 8714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_pHYs) 8724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_pHYs(png_ptr, info_ptr, length); 8734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_sBIT_SUPPORTED 8764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_sBIT) 8774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_sBIT(png_ptr, info_ptr, length); 8784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_sRGB_SUPPORTED 8814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_sRGB) 8824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_sRGB(png_ptr, info_ptr, length); 8834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_iCCP_SUPPORTED 8864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_iCCP) 8874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_iCCP(png_ptr, info_ptr, length); 8884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_sPLT_SUPPORTED 8914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_sPLT) 8924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_sPLT(png_ptr, info_ptr, length); 8934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_tEXt_SUPPORTED 8964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_tEXt) 8974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_tEXt(png_ptr, info_ptr, length); 8984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_tIME_SUPPORTED 9014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_tIME) 9024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_tIME(png_ptr, info_ptr, length); 9034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 9044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_tRNS_SUPPORTED 9064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_tRNS) 9074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_tRNS(png_ptr, info_ptr, length); 9084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 9094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_zTXt_SUPPORTED 9114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_zTXt) 9124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_zTXt(png_ptr, info_ptr, length); 9134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 9144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_iTXt_SUPPORTED 9164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (chunk_name == png_iTXt) 9174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_iTXt(png_ptr, info_ptr, length); 9184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 9194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 9214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_handle_unknown(png_ptr, info_ptr, length, 9224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_HANDLE_CHUNK_AS_DEFAULT); 9234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } while ((png_ptr->mode & PNG_HAVE_IEND) == 0); 9244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 9254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SEQUENTIAL_READ */ 9264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Free all memory used in the read struct */ 9284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void 9294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_read_destroy(png_structrp png_ptr) 9304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 9314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_read_destroy"); 9324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED 9344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_destroy_gamma_table(png_ptr); 9354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 9364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->big_row_buf); 9384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->big_row_buf = NULL; 9394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->big_prev_row); 9404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->big_prev_row = NULL; 9414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->read_buffer); 9424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->read_buffer = NULL; 9434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_QUANTIZE_SUPPORTED 9454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->palette_lookup); 9464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->palette_lookup = NULL; 9474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->quantize_index); 9484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->quantize_index = NULL; 9494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 9504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->free_me & PNG_FREE_PLTE) != 0) 9524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 9534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_zfree(png_ptr, png_ptr->palette); 9544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->palette = NULL; 9554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 9564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->free_me &= ~PNG_FREE_PLTE; 9574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_tRNS_SUPPORTED) || \ 9594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) 9604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->free_me & PNG_FREE_TRNS) != 0) 9614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 9624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->trans_alpha); 9634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->trans_alpha = NULL; 9644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 9654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->free_me &= ~PNG_FREE_TRNS; 9664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 9674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann inflateEnd(&png_ptr->zstream); 9694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_PROGRESSIVE_READ_SUPPORTED 9714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->save_buffer); 9724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->save_buffer = NULL; 9734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 9744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \ 9764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) 9774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->unknown_chunk.data); 9784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->unknown_chunk.data = NULL; 9794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 9804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED 9824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->chunk_list); 9834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->chunk_list = NULL; 9844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 9854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error 9874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * callbacks are still set at this point. They are required to complete the 9884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * destruction of the png_struct itself. 9894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 9904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 9914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Free all memory used by the read */ 9934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 9944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, 9954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_infopp end_info_ptr_ptr) 9964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 9974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_structrp png_ptr = NULL; 9984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_destroy_read_struct"); 10004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr_ptr != NULL) 10024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr = *png_ptr_ptr; 10034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 10054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 10064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* libpng 1.6.0: use the API to destroy info structs to ensure consistent 10084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * behavior. Prior to 1.6.0 libpng did extra 'info' destruction in this API. 10094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The extra was, apparently, unnecessary yet this hides memory leak bugs. 10104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_destroy_info_struct(png_ptr, end_info_ptr_ptr); 10124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_destroy_info_struct(png_ptr, info_ptr_ptr); 10134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *png_ptr_ptr = NULL; 10154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_destroy(png_ptr); 10164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_destroy_png_struct(png_ptr); 10174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 10184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 10204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn) 10214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 10224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 10234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 10244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->read_row_fn = read_row_fn; 10264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 10274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 10304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_INFO_IMAGE_SUPPORTED 10314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 10324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_read_png(png_structrp png_ptr, png_inforp info_ptr, 10334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int transforms, 10344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann voidp params) 10354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 10364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL || info_ptr == NULL) 10374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 10384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* png_read_info() gives us all of the information from the 10404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG file before the first IDAT (image data chunk). 10414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_info(png_ptr, info_ptr); 10434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep))) 10444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "Image is too high to process with png_read_png()"); 10454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* -------------- image transformations start here ------------------- */ 10474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM 10484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is not implemented. This will only happen in de-configured (non-default) 10494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * libpng builds. The results can be unexpected - png_read_png may return 10504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * short or mal-formed rows because the transform is skipped. 10514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Tell libpng to strip 16-bit/color files down to 8 bits per color. 10544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_SCALE_16) != 0) 10564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Added at libpng-1.5.4. "strip_16" produces the same result that it 10574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * did in earlier versions, while "scale_16" is now more accurate. 10584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED 10604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_scale_16(png_ptr); 10614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 10624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported"); 10634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 10644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If both SCALE and STRIP are required pngrtran will effectively cancel the 10664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * latter by doing SCALE first. This is ok and allows apps not to check for 10674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * which is supported to get the right answer. 10684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_STRIP_16) != 0) 10704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED 10714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_strip_16(png_ptr); 10724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 10734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported"); 10744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 10754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Strip alpha bytes from the input data without combining with 10774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the background (not recommended). 10784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0) 10804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED 10814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_strip_alpha(png_ptr); 10824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 10834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported"); 10844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 10854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single 10874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * byte into separate bytes (useful for paletted and grayscale images). 10884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_PACKING) != 0) 10904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_PACK_SUPPORTED 10914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_packing(png_ptr); 10924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 10934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); 10944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 10954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Change the order of packed pixels to least significant bit first 10974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (not useful if you are using png_set_packing). 10984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) 11004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_PACKSWAP_SUPPORTED 11014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_packswap(png_ptr); 11024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 11034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); 11044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 11054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Expand paletted colors into true RGB triplets 11074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel 11084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Expand paletted or RGB images with transparency to full alpha 11094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * channels so the data will be available as RGBA quartets. 11104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 11114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_EXPAND) != 0) 11124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_EXPAND_SUPPORTED 11134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_expand(png_ptr); 11144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 11154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported"); 11164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 11174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* We don't handle background color or gamma transformation or quantizing. 11194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 11204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Invert monochrome files to have 0 as white and 1 as black 11224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 11234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) 11244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_INVERT_SUPPORTED 11254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_invert_mono(png_ptr); 11264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 11274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); 11284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 11294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If you want to shift the pixel values from the range [0,255] or 11314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * [0,65535] to the original [0,7] or [0,31], or whatever range the 11324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * colors were originally in: 11334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 11344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_SHIFT) != 0) 11354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SHIFT_SUPPORTED 11364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((info_ptr->valid & PNG_INFO_sBIT) != 0) 11374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_shift(png_ptr, &info_ptr->sig_bit); 11384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 11394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); 11404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 11414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ 11434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_BGR) != 0) 11444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_BGR_SUPPORTED 11454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_bgr(png_ptr); 11464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 11474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); 11484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 11494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ 11514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) 11524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED 11534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_swap_alpha(png_ptr); 11544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 11554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); 11564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 11574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Swap bytes of 16-bit files to least significant byte first */ 11594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) 11604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SWAP_SUPPORTED 11614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_swap(png_ptr); 11624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 11634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); 11644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 11654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Added at libpng-1.2.41 */ 11674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Invert the alpha channel from opacity to transparency */ 11684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) 11694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED 11704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_invert_alpha(png_ptr); 11714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 11724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); 11734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 11744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Added at libpng-1.2.41 */ 11764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Expand grayscale image to RGB */ 11774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0) 11784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 11794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_gray_to_rgb(png_ptr); 11804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 11814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported"); 11824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 11834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Added at libpng-1.5.4 */ 11854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0) 11864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_EXPAND_16_SUPPORTED 11874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_expand_16(png_ptr); 11884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 11894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported"); 11904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 11914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* We don't handle adding filler bytes */ 11934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* We use png_read_image and rely on that for interlace handling, but we also 11954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * call png_read_update_info therefore must turn on interlace handling now: 11964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 11974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (void)png_set_interlace_handling(png_ptr); 11984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Optional call to gamma correct and add the background to the palette 12004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and update info structure. REQUIRED if you are expecting libpng to 12014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * update the palette for you (i.e., you selected such a transform above). 12024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 12034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_update_info(png_ptr, info_ptr); 12044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* -------------- image transformations end here ------------------- */ 12064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); 12084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr->row_pointers == NULL) 12094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 12104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 iptr; 12114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr, 12134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->height * (sizeof (png_bytep)))); 12144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (iptr=0; iptr<info_ptr->height; iptr++) 12164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->row_pointers[iptr] = NULL; 12174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->free_me |= PNG_FREE_ROWS; 12194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (iptr = 0; iptr < info_ptr->height; iptr++) 12214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->row_pointers[iptr] = png_voidcast(png_bytep, 12224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_malloc(png_ptr, info_ptr->rowbytes)); 12234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 12244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_image(png_ptr, info_ptr->row_pointers); 12264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid |= PNG_INFO_IDAT; 12274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ 12294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_end(png_ptr, info_ptr); 12304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED(params) 12324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 12334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* INFO_IMAGE */ 12344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SEQUENTIAL_READ */ 12354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SIMPLIFIED_READ_SUPPORTED 12374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* SIMPLIFIED READ 12384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 12394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This code currently relies on the sequential reader, though it could easily 12404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * be made to work with the progressive one. 12414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 12424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Arguments to png_image_finish_read: */ 12434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Encoding of PNG data (used by the color-map code) */ 12454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define P_NOTSET 0 /* File encoding not yet known */ 12464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define P_sRGB 1 /* 8-bit encoded to sRGB gamma */ 12474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define P_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */ 12484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define P_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */ 12494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define P_LINEAR8 4 /* 8-bit linear: only from a file value */ 12504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Color-map processing: after libpng has run on the PNG image further 12524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * processing may be needed to convert the data to color-map indices. 12534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 12544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_CMAP_NONE 0 12554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */ 12564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_CMAP_TRANS 2 /* Process GA data to a background index */ 12574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_CMAP_RGB 3 /* Process RGB data */ 12584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */ 12594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The following document where the background is for each processing case. */ 12614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_CMAP_NONE_BACKGROUND 256 12624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_CMAP_GA_BACKGROUND 231 12634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_CMAP_TRANS_BACKGROUND 254 12644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_CMAP_RGB_BACKGROUND 256 12654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216 12664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmanntypedef struct 12684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 12694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Arguments: */ 12704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_imagep image; 12714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_voidp buffer; 12724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_int_32 row_stride; 12734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_voidp colormap; 12744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_colorp background; 12754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Local variables: */ 12764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_voidp local_row; 12774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_voidp first_row; 12784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptrdiff_t row_bytes; /* step between rows */ 12794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int file_encoding; /* E_ values above */ 12804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point gamma_to_linear; /* For P_FILE, reciprocal of gamma */ 12814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int colormap_processing; /* PNG_CMAP_ values above */ 12824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} png_image_read_control; 12834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Do all the *safe* initialization - 'safe' means that png_error won't be 12854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * called, so setting up the jmp_buf is not required. This means that anything 12864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * called from here must *not* call png_malloc - it has to call png_malloc_warn 12874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * instead so that control is returned safely back to this routine. 12884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 12894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 12904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_read_init(png_imagep image) 12914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 12924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (image->opaque == NULL) 12934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 12944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image, 12954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_safe_error, png_safe_warning); 12964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And set the rest of the structure to NULL to ensure that the various 12984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * fields are consistent. 12994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 13004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann memset(image, 0, (sizeof *image)); 13014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->version = PNG_IMAGE_VERSION; 13024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr != NULL) 13044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 13054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_infop info_ptr = png_create_info_struct(png_ptr); 13064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr != NULL) 13084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 13094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_controlp control = png_voidcast(png_controlp, 13104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_malloc_warn(png_ptr, (sizeof *control))); 13114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (control != NULL) 13134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 13144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann memset(control, 0, (sizeof *control)); 13154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann control->png_ptr = png_ptr; 13174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann control->info_ptr = info_ptr; 13184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann control->for_write = 0; 13194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->opaque = control; 13214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 13224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 13234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Error clean up */ 13254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_destroy_info_struct(png_ptr, &info_ptr); 13264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 13274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_destroy_read_struct(&png_ptr, NULL, NULL); 13294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 13304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, "png_image_read: out of memory"); 13324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 13334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, "png_image_read: opaque pointer not NULL"); 13354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 13364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Utility to find the base format of a PNG file from a png_struct. */ 13384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_uint_32 13394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_format(png_structrp png_ptr) 13404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 13414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 format = 0; 13424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) 13444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann format |= PNG_FORMAT_FLAG_COLOR; 13454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) 13474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann format |= PNG_FORMAT_FLAG_ALPHA; 13484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS 13504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * sets the png_struct fields; that's all we are interested in here. The 13514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * precise interaction with an app call to png_set_tRNS and PNG file reading 13524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is unclear. 13534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 13544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (png_ptr->num_trans > 0) 13554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann format |= PNG_FORMAT_FLAG_ALPHA; 13564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->bit_depth == 16) 13584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann format |= PNG_FORMAT_FLAG_LINEAR; 13594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0) 13614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann format |= PNG_FORMAT_FLAG_COLORMAP; 13624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return format; 13644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 13654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Is the given gamma significantly different from sRGB? The test is the same 13674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * one used in pngrtran.c when deciding whether to do gamma correction. The 13684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * arithmetic optimizes the division by using the fact that the inverse of the 13694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * file sRGB gamma is 2.2 13704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 13714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 13724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_gamma_not_sRGB(png_fixed_point g) 13734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 13744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (g < PNG_FP_1) 13754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 13764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* An uninitialized gamma is assumed to be sRGB for the simplified API. */ 13774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (g == 0) 13784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 13794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */); 13814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 13824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 13844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 13854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Do the main body of a 'png_image_begin_read' function; read the PNG file 13874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * header and fill in all the information. This is executed in a safe context, 13884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * unlike the init routine above. 13894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 13904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 13914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_read_header(png_voidp argument) 13924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 13934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_imagep image = png_voidcast(png_imagep, argument); 13944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_structrp png_ptr = image->opaque->png_ptr; 13954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_inforp info_ptr = image->opaque->info_ptr; 13964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_benign_errors(png_ptr, 1/*warn*/); 13984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_info(png_ptr, info_ptr); 13994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Do this the fast way; just read directly out of png_struct. */ 14014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->width = png_ptr->width; 14024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->height = png_ptr->height; 14034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 14054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 format = png_image_format(png_ptr); 14064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->format = format; 14084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_COLORSPACE_SUPPORTED 14104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Does the colorspace match sRGB? If there is no color endpoint 14114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (colorant) information assume yes, otherwise require the 14124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set. If the 14134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * colorspace has been determined to be invalid ignore it. 14144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 14154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags 14164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB| 14174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS)) 14184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB; 14194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 14204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 14214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* We need the maximum number of entries regardless of the format the 14234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * application sets here. 14244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 14254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 14264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 cmap_entries; 14274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (png_ptr->color_type) 14294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 14304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_COLOR_TYPE_GRAY: 14314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = 1U << png_ptr->bit_depth; 14324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 14334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_COLOR_TYPE_PALETTE: 14354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = png_ptr->num_palette; 14364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 14374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 14394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = 256; 14404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 14414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 14424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cmap_entries > 256) 14444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = 256; 14454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->colormap_entries = cmap_entries; 14474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 14484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 14504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 14514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_STDIO_SUPPORTED 14534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI 14544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_begin_read_from_stdio(png_imagep image, FILE* file) 14554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 14564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (image != NULL && image->version == PNG_IMAGE_VERSION) 14574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 14584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (file != NULL) 14594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 14604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_image_read_init(image) != 0) 14614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 14624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is slightly evil, but png_init_io doesn't do anything other 14634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * than this and we haven't changed the standard IO functions so 14644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * this saves a 'safe' function. 14654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 14664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->opaque->png_ptr->io_ptr = file; 14674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_safe_execute(image, png_image_read_header, image); 14684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 14694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 14704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 14724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, 14734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_image_begin_read_from_stdio: invalid argument"); 14744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 14754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (image != NULL) 14774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, 14784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); 14794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 14814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 14824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI 14844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_begin_read_from_file(png_imagep image, const char *file_name) 14854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 14864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (image != NULL && image->version == PNG_IMAGE_VERSION) 14874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 14884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (file_name != NULL) 14894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 14904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FILE *fp = fopen(file_name, "rb"); 14914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (fp != NULL) 14934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 14944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_image_read_init(image) != 0) 14954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 14964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->opaque->png_ptr->io_ptr = fp; 14974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->opaque->owned_file = 1; 14984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_safe_execute(image, png_image_read_header, image); 14994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 15004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Clean up: just the opened file. */ 15024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (void)fclose(fp); 15034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 15044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 15064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, strerror(errno)); 15074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 15084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 15104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, 15114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_image_begin_read_from_file: invalid argument"); 15124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 15134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (image != NULL) 15154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, 15164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); 15174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 15194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 15204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* STDIO */ 15214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void PNGCBAPI 15234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need) 15244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 15254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr != NULL) 15264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 15274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr); 15284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (image != NULL) 15294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 15304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_controlp cp = image->opaque; 15314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cp != NULL) 15324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 15334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_bytep memory = cp->memory; 15344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_size_t size = cp->size; 15354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (memory != NULL && size >= need) 15374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 15384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann memcpy(out, memory, need); 15394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cp->memory = memory + need; 15404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cp->size = size - need; 15414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 15424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 15434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "read beyond end of data"); 15454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 15464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 15474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "invalid memory read"); 15494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 15504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 15514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI png_image_begin_read_from_memory(png_imagep image, 15534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_voidp memory, png_size_t size) 15544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 15554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (image != NULL && image->version == PNG_IMAGE_VERSION) 15564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 15574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (memory != NULL && size > 0) 15584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 15594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_image_read_init(image) != 0) 15604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 15614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now set the IO functions to read from the memory buffer and 15624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * store it into io_ptr. Again do this in-place to avoid calling a 15634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * libpng function that requires error handling. 15644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 15654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->opaque->memory = png_voidcast(png_const_bytep, memory); 15664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->opaque->size = size; 15674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->opaque->png_ptr->io_ptr = image; 15684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->opaque->png_ptr->read_data_fn = png_image_memory_read; 15694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_safe_execute(image, png_image_read_header, image); 15714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 15724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 15734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 15754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, 15764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_image_begin_read_from_memory: invalid argument"); 15774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 15784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (image != NULL) 15804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, 15814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); 15824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 15844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 15854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Utility function to skip chunks that are not used by the simplified image 15874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * read functions and an appropriate macro to call it. 15884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 15894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 15904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void 15914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_skip_unused_chunks(png_structrp png_ptr) 15924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 15934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Prepare the reader to ignore all recognized chunks whose data will not 15944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * be used, i.e., all chunks recognized by libpng except for those 15954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * involved in basic image reading: 15964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 15974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * IHDR, PLTE, IDAT, IEND 15984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 15994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Or image data handling: 16004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 16014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT. 16024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 16034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This provides a small performance improvement and eliminates any 16044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * potential vulnerability to security problems in the unused chunks. 16054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 16064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored 16074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * too. This allows the simplified API to be compiled without iCCP support, 16084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * however if the support is there the chunk is still checked to detect 16094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * errors (which are unfortunately quite common.) 16104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 16114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 16124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann static PNG_CONST png_byte chunks_to_process[] = { 16134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 98, 75, 71, 68, '\0', /* bKGD */ 16144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 99, 72, 82, 77, '\0', /* cHRM */ 16154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 103, 65, 77, 65, '\0', /* gAMA */ 16164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_READ_iCCP_SUPPORTED 16174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 105, 67, 67, 80, '\0', /* iCCP */ 16184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 16194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 115, 66, 73, 84, '\0', /* sBIT */ 16204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 115, 82, 71, 66, '\0', /* sRGB */ 16214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann }; 16224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Ignore unknown chunks and all other chunks except for the 16244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * IHDR, PLTE, tRNS, IDAT, and IEND chunks. 16254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 16264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER, 16274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann NULL, -1); 16284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* But do not ignore image data handling chunks */ 16304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT, 16314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5); 16324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 16334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 16344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p) 16364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 16374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define PNG_SKIP_CHUNKS(p) ((void)0) 16384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* HANDLE_AS_UNKNOWN */ 16394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The following macro gives the exact rounded answer for all values in the 16414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * range 0..255 (it actually divides by 51.2, but the rounding still generates 16424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the correct numbers 0..5 16434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 16444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8) 16454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Utility functions to make particular color-maps */ 16474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void 16484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannset_file_encoding(png_image_read_control *display) 16494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 16504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma; 16514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_gamma_significant(g) != 0) 16524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 16534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_gamma_not_sRGB(g) != 0) 16544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 16554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->file_encoding = P_FILE; 16564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->gamma_to_linear = png_reciprocal(g); 16574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 16584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 16604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->file_encoding = P_sRGB; 16614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 16624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 16644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->file_encoding = P_LINEAR8; 16654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 16664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic unsigned int 16684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmanndecode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) 16694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 16704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (encoding == P_FILE) /* double check */ 16714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann encoding = display->file_encoding; 16724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (encoding == P_NOTSET) /* must be the file encoding */ 16744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 16754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann set_file_encoding(display); 16764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann encoding = display->file_encoding; 16774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 16784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (encoding) 16804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 16814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case P_FILE: 16824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann value = png_gamma_16bit_correct(value*257, display->gamma_to_linear); 16834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 16844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case P_sRGB: 16864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann value = png_sRGB_table[value]; 16874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 16884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case P_LINEAR: 16904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 16914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case P_LINEAR8: 16934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann value *= 257; 16944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 16954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef __GNUC__ 16974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 16984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(display->image->opaque->png_ptr, 16994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "unexpected encoding (internal error)"); 17004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 17014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 17024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return value; 17044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 17054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_uint_32 17074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colormap_compose(png_image_read_control *display, 17084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha, 17094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 background, int encoding) 17104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 17114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The file value is composed on the background, the background has the given 17124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * encoding and so does the result, the file is encoded with P_FILE and the 17134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * file and alpha are 8-bit values. The (output) encoding will always be 17144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * P_LINEAR or P_sRGB. 17154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 17164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 f = decode_gamma(display, foreground, foreground_encoding); 17174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 b = decode_gamma(display, background, encoding); 17184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The alpha is always an 8-bit value (it comes from the palette), the value 17204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires. 17214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 17224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann f = f * alpha + b * (255-alpha); 17234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (encoding == P_LINEAR) 17254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 17264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Scale to 65535; divide by 255, approximately (in fact this is extremely 17274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * accurate, it divides by 255.00000005937181414556, with no overflow.) 17284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 17294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann f *= 257; /* Now scaled by 65535 */ 17304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann f += f >> 16; 17314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann f = (f+32768) >> 16; 17324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 17334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* P_sRGB */ 17354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann f = PNG_sRGB_FROM_LINEAR(f); 17364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return f; 17384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 17394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must 17414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * be 8-bit. 17424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 17434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void 17444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_create_colormap_entry(png_image_read_control *display, 17454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, 17464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 alpha, int encoding) 17474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 17484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_imagep image = display->image; 17494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? 17504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann P_LINEAR : P_sRGB; 17514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && 17524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (red != green || green != blue); 17534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ip > 255) 17554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(image->opaque->png_ptr, "color-map index out of range"); 17564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Update the cache with whether the file gamma is significantly different 17584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * from sRGB. 17594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 17604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (encoding == P_FILE) 17614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 17624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (display->file_encoding == P_NOTSET) 17634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann set_file_encoding(display); 17644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Note that the cached value may be P_FILE too, but if it is then the 17664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * gamma_to_linear member has been set. 17674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 17684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann encoding = display->file_encoding; 17694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 17704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (encoding == P_FILE) 17724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 17734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point g = display->gamma_to_linear; 17744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann red = png_gamma_16bit_correct(red*257, g); 17764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann green = png_gamma_16bit_correct(green*257, g); 17774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann blue = png_gamma_16bit_correct(blue*257, g); 17784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (convert_to_Y != 0 || output_encoding == P_LINEAR) 17804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 17814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann alpha *= 257; 17824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann encoding = P_LINEAR; 17834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 17844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 17864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 17874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann red = PNG_sRGB_FROM_LINEAR(red * 255); 17884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann green = PNG_sRGB_FROM_LINEAR(green * 255); 17894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann blue = PNG_sRGB_FROM_LINEAR(blue * 255); 17904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann encoding = P_sRGB; 17914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 17924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 17934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (encoding == P_LINEAR8) 17954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 17964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This encoding occurs quite frequently in test cases because PngSuite 17974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * includes a gAMA 1.0 chunk with most images. 17984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 17994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann red *= 257; 18004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann green *= 257; 18014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann blue *= 257; 18024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann alpha *= 257; 18034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann encoding = P_LINEAR; 18044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 18054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (encoding == P_sRGB && 18074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (convert_to_Y != 0 || output_encoding == P_LINEAR)) 18084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The values are 8-bit sRGB values, but must be converted to 16-bit 18104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * linear. 18114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 18124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann red = png_sRGB_table[red]; 18134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann green = png_sRGB_table[green]; 18144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann blue = png_sRGB_table[blue]; 18154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann alpha *= 257; 18164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann encoding = P_LINEAR; 18174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 18184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is set if the color isn't gray but the output is. */ 18204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (encoding == P_LINEAR) 18214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (convert_to_Y != 0) 18234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* NOTE: these values are copied from png_do_rgb_to_gray */ 18254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 y = (png_uint_32)6968 * red + (png_uint_32)23434 * green + 18264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_uint_32)2366 * blue; 18274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (output_encoding == P_LINEAR) 18294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann y = (y + 16384) >> 15; 18304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 18324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* y is scaled by 32768, we need it scaled by 255: */ 18344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann y = (y + 128) >> 8; 18354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann y *= 255; 18364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7); 18374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann alpha = PNG_DIV257(alpha); 18384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann encoding = P_sRGB; 18394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 18404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann blue = red = green = y; 18424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 18434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (output_encoding == P_sRGB) 18454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann red = PNG_sRGB_FROM_LINEAR(red * 255); 18474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann green = PNG_sRGB_FROM_LINEAR(green * 255); 18484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann blue = PNG_sRGB_FROM_LINEAR(blue * 255); 18494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann alpha = PNG_DIV257(alpha); 18504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann encoding = P_sRGB; 18514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 18524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 18534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (encoding != output_encoding) 18554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(image->opaque->png_ptr, "bad encoding (internal error)"); 18564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Store the value. */ 18584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_FORMAT_AFIRST_SUPPORTED 18604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && 18614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; 18624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# else 18634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define afirst 0 18644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 18654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_FORMAT_BGR_SUPPORTED 18664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; 18674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# else 18684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define bgr 0 18694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 18704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (output_encoding == P_LINEAR) 18724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap); 18744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); 18764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The linear 16-bit values must be pre-multiplied by the alpha channel 18784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value, if less than 65535 (this is, effectively, composite on black 18794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * if the alpha channel is removed.) 18804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 18814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) 18824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 4: 18844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry[afirst ? 0 : 3] = (png_uint_16)alpha; 18854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* FALL THROUGH */ 18864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 3: 18884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha < 65535) 18894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha > 0) 18914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann blue = (blue * alpha + 32767U)/65535U; 18934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann green = (green * alpha + 32767U)/65535U; 18944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann red = (red * alpha + 32767U)/65535U; 18954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 18964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 18984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann red = green = blue = 0; 18994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 19004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry[afirst + (2 ^ bgr)] = (png_uint_16)blue; 19014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry[afirst + 1] = (png_uint_16)green; 19024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry[afirst + bgr] = (png_uint_16)red; 19034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 19044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 2: 19064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry[1 ^ afirst] = (png_uint_16)alpha; 19074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* FALL THROUGH */ 19084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 1: 19104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha < 65535) 19114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 19124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha > 0) 19134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann green = (green * alpha + 32767U)/65535U; 19144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 19164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann green = 0; 19174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 19184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry[afirst] = (png_uint_16)green; 19194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 19204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 19224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 19234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 19244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 19254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* output encoding is P_sRGB */ 19274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 19284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep entry = png_voidcast(png_bytep, display->colormap); 19294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); 19314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) 19334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 19344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 4: 19354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry[afirst ? 0 : 3] = (png_byte)alpha; 19364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 3: 19374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry[afirst + (2 ^ bgr)] = (png_byte)blue; 19384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry[afirst + 1] = (png_byte)green; 19394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry[afirst + bgr] = (png_byte)red; 19404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 19414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 2: 19434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry[1 ^ afirst] = (png_byte)alpha; 19444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 1: 19454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry[afirst] = (png_byte)green; 19464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 19474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 19494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 19504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 19514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 19524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef afirst 19544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# undef afirst 19554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 19564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef bgr 19574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# undef bgr 19584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 19594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 19604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 19614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 19634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannmake_gray_file_colormap(png_image_read_control *display) 19644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 19654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int i; 19664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i=0; i<256; ++i) 19684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i, i, i, i, 255, P_FILE); 19694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return i; 19714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 19724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 19744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannmake_gray_colormap(png_image_read_control *display) 19754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 19764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int i; 19774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i=0; i<256; ++i) 19794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB); 19804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return i; 19824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 19834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_GRAY_COLORMAP_ENTRIES 256 19844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 19864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannmake_ga_colormap(png_image_read_control *display) 19874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 19884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int i, a; 19894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Alpha is retained, the output will be a color-map with entries 19914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * selected by six levels of alpha. One transparent entry, 6 gray 19924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * levels for all the intermediate alpha values, leaving 230 entries 19934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * for the opaque grays. The color-map entries are the six values 19944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the 19954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * relevant entry. 19964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 19974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * if (alpha > 229) // opaque 19984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * { 19994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * // The 231 entries are selected to make the math below work: 20004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * base = 0; 20014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * entry = (231 * gray + 128) >> 8; 20024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * } 20034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * else if (alpha < 26) // transparent 20044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * { 20054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * base = 231; 20064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * entry = 0; 20074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * } 20084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * else // partially opaque 20094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * { 20104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * base = 226 + 6 * PNG_DIV51(alpha); 20114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * entry = PNG_DIV51(gray); 20124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * } 20134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 20144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann i = 0; 20154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (i < 231) 20164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 20174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int gray = (i * 256 + 115) / 231; 20184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB); 20194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 20204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 255 is used here for the component values for consistency with the code 20224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * that undoes premultiplication in pngwrite.c. 20234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 20244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB); 20254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (a=1; a<5; ++a) 20274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 20284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int g; 20294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (g=0; g<6; ++g) 20314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51, 20324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann P_sRGB); 20334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 20344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return i; 20364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 20374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_GA_COLORMAP_ENTRIES 256 20394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 20414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannmake_rgb_colormap(png_image_read_control *display) 20424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 20434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int i, r; 20444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Build a 6x6x6 opaque RGB cube */ 20464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i=r=0; r<6; ++r) 20474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 20484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int g; 20494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (g=0; g<6; ++g) 20514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 20524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int b; 20534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (b=0; b<6; ++b) 20554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255, 20564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann P_sRGB); 20574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 20584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 20594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return i; 20614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 20624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_RGB_COLORMAP_ENTRIES 216 20644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Return a palette index to the above palette given three 8-bit sRGB values. */ 20664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define PNG_RGB_INDEX(r,g,b) \ 20674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b))) 20684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 20704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_read_colormap(png_voidp argument) 20714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 20724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_image_read_control *display = 20734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_voidcast(png_image_read_control*, argument); 20744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const png_imagep image = display->image; 20754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const png_structrp png_ptr = image->opaque->png_ptr; 20774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const png_uint_32 output_format = image->format; 20784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ? 20794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann P_LINEAR : P_sRGB; 20804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int cmap_entries; 20824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int output_processing; /* Output processing option */ 20834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */ 20844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Background information; the background color and the index of this color 20864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * in the color-map if it exists (else 256). 20874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 20884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int background_index = 256; 20894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 back_r, back_g, back_b; 20904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Flags to accumulate things that need to be done to the input. */ 20924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int expand_tRNS = 0; 20934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is 20954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * very difficult to do, the results look awful, and it is difficult to see 20964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * what possible use it is because the application can't control the 20974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * color-map. 20984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 20994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 || 21004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->num_trans > 0) /* alpha in input */ && 21014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */) 21024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 21034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (output_encoding == P_LINEAR) /* compose on black */ 21044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_b = back_g = back_r = 0; 21054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (display->background == NULL /* no way to remove it */) 21074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, 21084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "a background color must be supplied to remove alpha/transparency"); 21094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Get a copy of the background color (this avoids repeating the checks 21114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the 21124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * output format. 21134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 21154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 21164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_g = display->background->green; 21174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0) 21184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 21194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_r = display->background->red; 21204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_b = display->background->blue; 21214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 21224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 21234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_b = back_r = back_g; 21244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 21254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 21264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (output_encoding == P_LINEAR) 21284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_b = back_r = back_g = 65535; 21294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 21314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_b = back_r = back_g = 255; 21324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Default the input file gamma if required - this is necessary because 21344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * libpng assumes that if no gamma information is present the data is in the 21354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * output format, but the simplified API deduces the gamma from the input 21364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * format. 21374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0) 21394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 21404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Do this directly, not using the png_colorspace functions, to ensure 21414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * that it happens even if the colorspace is invalid (though probably if 21424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it is the setting will be ignored) Note that the same thing can be 21434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * achieved at the application interface with png_set_gAMA. 21444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->bit_depth == 16 && 21464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) 21474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR; 21484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 21504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE; 21514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; 21534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 21544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Decide what to do based on the PNG color type of the input data. The 21564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * utility function png_create_colormap_entry deals with most aspects of the 21574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * output transformations; this code works out how to produce bytes of 21584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * color-map entries from the original format. 21594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (png_ptr->color_type) 21614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 21624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_COLOR_TYPE_GRAY: 21634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->bit_depth <= 8) 21644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 21654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* There at most 256 colors in the output, regardless of 21664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * transparency. 21674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0; 21694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = 1U << png_ptr->bit_depth; 21714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cmap_entries > image->colormap_entries) 21724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "gray[8] color-map: too few entries"); 21734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann step = 255 / (cmap_entries - 1); 21754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_NONE; 21764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If there is a tRNS chunk then this either selects a transparent 21784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value or, if the output has no alpha, the background color. 21794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->num_trans > 0) 21814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 21824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann trans = png_ptr->trans_color.gray; 21834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) 21854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_alpha = output_encoding == P_LINEAR ? 65535 : 255; 21864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 21874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* png_create_colormap_entry just takes an RGBA and writes the 21894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * corresponding color-map entry using the format from 'image', 21904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * including the required conversion to sRGB or linear as 21914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * appropriate. The input values are always either sRGB (if the 21924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * gamma correction flag is 0) or 0..255 scaled file encoded values 21934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (if the function must gamma correct them). 21944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i=val=0; i<cmap_entries; ++i, val += step) 21964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 21974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 'i' is a file value. While this will result in duplicated 21984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * entries for 8-bit non-sRGB encoded files it is necessary to 21994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * have non-gamma corrected values to do tRNS handling. 22004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 22014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (i != trans) 22024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i, val, val, val, 255, 22034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann P_FILE/*8-bit with file gamma*/); 22044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Else this entry is transparent. The colors don't matter if 22064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * there is an alpha channel (back_alpha == 0), but it does no 22074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * harm to pass them in; the values are not set above so this 22084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * passes in white. 22094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 22104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * NOTE: this preserves the full precision of the application 22114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * supplied background color when it is used. 22124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 22134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 22144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i, back_r, back_g, back_b, 22154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_alpha, output_encoding); 22164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 22174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* We need libpng to preserve the original encoding. */ 22194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann data_encoding = P_FILE; 22204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The rows from libpng, while technically gray values, are now also 22224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * color-map indices; however, they may need to be expanded to 1 22234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * byte per pixel. This is what png_set_packing does (i.e., it 22244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * unpacks the bit values into bytes.) 22254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 22264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->bit_depth < 8) 22274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_packing(png_ptr); 22284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 22294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* bit depth is 16 */ 22314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 22324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The 16-bit input values can be converted directly to 8-bit gamma 22334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * encoded values; however, if a tRNS chunk is present 257 color-map 22344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * entries are required. This means that the extra entry requires 22354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * special processing; add an alpha channel, sacrifice gray level 22364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 254 and convert transparent (alpha==0) entries to that. 22374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 22384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Use libpng to chop the data to 8 bits. Convert it to sRGB at the 22394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * same time to minimize quality loss. If a tRNS chunk is present 22404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * this means libpng must handle it too; otherwise it is impossible 22414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to do the exact match on the 16-bit value. 22424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 22434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * If the output has no alpha channel *and* the background color is 22444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * gray then it is possible to let libpng handle the substitution by 22454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * ensuring that the corresponding gray level matches the background 22464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * color exactly. 22474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 22484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann data_encoding = P_sRGB; 22494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) 22514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "gray[16] color-map: too few entries"); 22524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = make_gray_colormap(display); 22544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->num_trans > 0) 22564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 22574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int back_alpha; 22584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) 22604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_alpha = 0; 22614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 22634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 22644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (back_r == back_g && back_g == back_b) 22654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 22664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Background is gray; no special processing will be 22674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * required. 22684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 22694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_color_16 c; 22704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 gray = back_g; 22714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (output_encoding == P_LINEAR) 22734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 22744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann gray = PNG_sRGB_FROM_LINEAR(gray * 255); 22754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And make sure the corresponding palette entry 22774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * matches. 22784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 22794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, gray, back_g, back_g, 22804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_g, 65535, P_LINEAR); 22814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 22824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The background passed to libpng, however, must be the 22844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * sRGB value. 22854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 22864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.index = 0; /*unused*/ 22874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.gray = c.red = c.green = c.blue = (png_uint_16)gray; 22884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* NOTE: does this work without expanding tRNS to alpha? 22904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * It should be the color->gray case below apparently 22914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * doesn't. 22924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 22934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_background_fixed(png_ptr, &c, 22944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, 22954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 0/*gamma: not used*/); 22964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_NONE; 22984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 22994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef __COVERITY__ 23014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Coverity claims that output_encoding cannot be 2 (P_LINEAR) 23024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * here. 23034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 23044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_alpha = 255; 23054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 23064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_alpha = output_encoding == P_LINEAR ? 65535 : 255; 23074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 23084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* output_processing means that the libpng-processed row will be 23114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 8-bit GA and it has to be processing to single byte color-map 23124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * values. Entry 254 is replaced by either a completely 23134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * transparent entry or by the background color at full 23144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * precision (and the background color is not a simple gray 23154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * level in this case.) 23164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 23174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann expand_tRNS = 1; 23184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_TRANS; 23194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann background_index = 254; 23204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And set (overwrite) color-map entry 254 to the actual 23224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * background color at full precision. 23234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 23244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, 254, back_r, back_g, back_b, 23254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_alpha, output_encoding); 23264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 23294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_NONE; 23304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 23324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_COLOR_TYPE_GRAY_ALPHA: 23344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 8-bit or 16-bit PNG with two channels - gray and alpha. A minimum 23354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * of 65536 combinations. If, however, the alpha channel is to be 23364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * removed there are only 256 possibilities if the background is gray. 23374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (Otherwise there is a subset of the 65536 possibilities defined by 23384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the triangle between black, white and the background color.) 23394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 23404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Reduce 16-bit files to 8-bit and sRGB encode the result. No need to 23414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * worry about tRNS matching - tRNS is ignored if there is an alpha 23424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * channel. 23434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 23444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann data_encoding = P_sRGB; 23454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) 23474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 23484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) 23494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "gray+alpha color-map: too few entries"); 23504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = make_ga_colormap(display); 23524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann background_index = PNG_CMAP_GA_BACKGROUND; 23544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_GA; 23554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* alpha is removed */ 23584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 23594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Alpha must be removed as the PNG data is processed when the 23604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * background is a color because the G and A channels are 23614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * independent and the vector addition (non-parallel vectors) is a 23624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 2-D problem. 23634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 23644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This can be reduced to the same algorithm as above by making a 23654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * colormap containing gray levels (for the opaque grays), a 23664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * background entry (for a transparent pixel) and a set of four six 23674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * level color values, one set for each intermediate alpha value. 23684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * See the comments in make_ga_colormap for how this works in the 23694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * per-pixel processing. 23704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 23714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * If the background is gray, however, we only need a 256 entry gray 23724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * level color map. It is sufficient to make the entry generated 23734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * for the background color be exactly the color specified. 23744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 23754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 || 23764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (back_r == back_g && back_g == back_b)) 23774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 23784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Background is gray; no special processing will be required. */ 23794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_color_16 c; 23804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 gray = back_g; 23814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) 23834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "gray-alpha color-map: too few entries"); 23844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = make_gray_colormap(display); 23864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (output_encoding == P_LINEAR) 23884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 23894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann gray = PNG_sRGB_FROM_LINEAR(gray * 255); 23904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And make sure the corresponding palette entry matches. */ 23924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, gray, back_g, back_g, 23934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_g, 65535, P_LINEAR); 23944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The background passed to libpng, however, must be the sRGB 23974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value. 23984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 23994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.index = 0; /*unused*/ 24004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.gray = c.red = c.green = c.blue = (png_uint_16)gray; 24014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_background_fixed(png_ptr, &c, 24034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, 24044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 0/*gamma: not used*/); 24054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_NONE; 24074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 24084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 24104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 24114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 i, a; 24124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is the same as png_make_ga_colormap, above, except that 24144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the entries are all opaque. 24154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 24164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) 24174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "ga-alpha color-map: too few entries"); 24184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann i = 0; 24204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (i < 231) 24214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 24224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 gray = (i * 256 + 115) / 231; 24234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i++, gray, gray, gray, 24244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 255, P_sRGB); 24254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 24264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* NOTE: this preserves the full precision of the application 24284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * background color. 24294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 24304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann background_index = i; 24314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i++, back_r, back_g, back_b, 24324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef __COVERITY__ 24334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Coverity claims that output_encoding cannot be 2 (P_LINEAR) 24344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * here. 24354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 255U, 24364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 24374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_encoding == P_LINEAR ? 65535U : 255U, 24384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 24394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_encoding); 24404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* For non-opaque input composite on the sRGB background - this 24424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * requires inverting the encoding for each component. The input 24434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is still converted to the sRGB encoding because this is a 24444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * reasonable approximate to the logarithmic curve of human 24454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * visual sensitivity, at least over the narrow range which PNG 24464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * represents. Consequently 'G' is always sRGB encoded, while 24474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 'A' is linear. We need the linear background colors. 24484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 24494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (output_encoding == P_sRGB) /* else already linear */ 24504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 24514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This may produce a value not exactly matching the 24524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * background, but that's ok because these numbers are only 24534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * used when alpha != 0 24544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 24554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_r = png_sRGB_table[back_r]; 24564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_g = png_sRGB_table[back_g]; 24574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_b = png_sRGB_table[back_b]; 24584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 24594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (a=1; a<5; ++a) 24614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 24624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int g; 24634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled 24654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * by an 8-bit alpha value (0..255). 24664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 24674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 alpha = 51 * a; 24684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 back_rx = (255-alpha) * back_r; 24694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 back_gx = (255-alpha) * back_g; 24704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 back_bx = (255-alpha) * back_b; 24714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (g=0; g<6; ++g) 24734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 24744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 gray = png_sRGB_table[g*51] * alpha; 24754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i++, 24774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_sRGB_FROM_LINEAR(gray + back_rx), 24784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_sRGB_FROM_LINEAR(gray + back_gx), 24794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB); 24804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 24814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 24824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = i; 24844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_GA; 24854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 24864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 24874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 24884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_COLOR_TYPE_RGB: 24904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_COLOR_TYPE_RGB_ALPHA: 24914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Exclude the case where the output is gray; we can always handle this 24924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * with the cases above. 24934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 24944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0) 24954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 24964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The color-map will be grayscale, so we may as well convert the 24974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * input RGB values to a simple grayscale and use the grayscale 24984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * code above. 24994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 25004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * NOTE: calling this apparently damages the recognition of the 25014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * transparent color in background color handling; call 25024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_set_tRNS_to_alpha before png_set_background_fixed. 25034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 25044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1, 25054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann -1); 25064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann data_encoding = P_sRGB; 25074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The output will now be one or two 8-bit gray or gray+alpha 25094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * channels. The more complex case arises when the input has alpha. 25104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 25114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 25124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->num_trans > 0) && 25134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (output_format & PNG_FORMAT_FLAG_ALPHA) != 0) 25144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Both input and output have an alpha channel, so no background 25164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * processing is required; just map the GA bytes to the right 25174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * color-map entry. 25184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 25194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann expand_tRNS = 1; 25204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) 25224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "rgb[ga] color-map: too few entries"); 25234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = make_ga_colormap(display); 25254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann background_index = PNG_CMAP_GA_BACKGROUND; 25264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_GA; 25274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 25304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Either the input or the output has no alpha channel, so there 25324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * will be no non-opaque pixels in the color-map; it will just be 25334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * grayscale. 25344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 25354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) 25364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "rgb[gray] color-map: too few entries"); 25374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Ideally this code would use libpng to do the gamma correction, 25394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * but if an input alpha channel is to be removed we will hit the 25404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * libpng bug in gamma+compose+rgb-to-gray (the double gamma 25414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * correction bug). Fix this by dropping the gamma correction in 25424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * this case and doing it in the palette; this will result in 25434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * duplicate palette entries, but that's better than the 25444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * alternative of double gamma correction. 25454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 25464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 25474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->num_trans > 0) && 25484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0) 25494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = make_gray_file_colormap(display); 25514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann data_encoding = P_FILE; 25524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 25554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = make_gray_colormap(display); 25564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* But if the input has alpha or transparency it must be removed 25584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 25594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 25604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->num_trans > 0) 25614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_color_16 c; 25634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 gray = back_g; 25644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* We need to ensure that the application background exists in 25664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the colormap and that completely transparent pixels map to 25674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it. Achieve this simply by ensuring that the entry 25684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * selected for the background really is the background color. 25694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 25704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (data_encoding == P_FILE) /* from the fixup above */ 25714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The app supplied a gray which is in output_encoding, we 25734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * need to convert it to a value of the input (P_FILE) 25744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * encoding then set this palette entry to the required 25754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * output encoding. 25764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 25774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (output_encoding == P_sRGB) 25784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann gray = png_sRGB_table[gray]; /* now P_LINEAR */ 25794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann gray = PNG_DIV257(png_gamma_16bit_correct(gray, 25814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->colorspace.gamma)); /* now P_FILE */ 25824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And make sure the corresponding palette entry contains 25844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * exactly the required sRGB value. 25854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 25864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, gray, back_g, back_g, 25874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_g, 0/*unused*/, output_encoding); 25884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (output_encoding == P_LINEAR) 25914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann gray = PNG_sRGB_FROM_LINEAR(gray * 255); 25934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And make sure the corresponding palette entry matches. 25954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 25964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, gray, back_g, back_g, 25974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_g, 0/*unused*/, P_LINEAR); 25984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The background passed to libpng, however, must be the 26014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * output (normally sRGB) value. 26024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 26034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.index = 0; /*unused*/ 26044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.gray = c.red = c.green = c.blue = (png_uint_16)gray; 26054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* NOTE: the following is apparently a bug in libpng. Without 26074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it the transparent color recognition in 26084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_set_background_fixed seems to go wrong. 26094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 26104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann expand_tRNS = 1; 26114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_background_fixed(png_ptr, &c, 26124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, 26134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 0/*gamma: not used*/); 26144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 26154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_NONE; 26174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 26184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 26194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* output is color */ 26214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* We could use png_quantize here so long as there is no transparent 26234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * color or alpha; png_quantize ignores alpha. Easier overall just 26244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube. 26254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Consequently we always want libpng to produce sRGB data. 26264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 26274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann data_encoding = P_sRGB; 26284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Is there any transparency or alpha? */ 26304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || 26314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->num_trans > 0) 26324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Is there alpha in the output too? If so all four channels are 26344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * processed into a special RGB cube with alpha support. 26354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 26364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) 26374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 r; 26394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) 26414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "rgb+alpha color-map: too few entries"); 26424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = make_rgb_colormap(display); 26444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Add a transparent entry. */ 26464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, cmap_entries, 255, 255, 26474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 255, 0, P_sRGB); 26484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is stored as the background index for the processing 26504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * algorithm. 26514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 26524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann background_index = cmap_entries++; 26534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Add 27 r,g,b entries each with alpha 0.5. */ 26554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (r=0; r<256; r = (r << 1) | 0x7f) 26564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 g; 26584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (g=0; g<256; g = (g << 1) | 0x7f) 26604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 b; 26624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This generates components with the values 0, 127 and 26644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 255 26654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 26664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (b=0; b<256; b = (b << 1) | 0x7f) 26674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, cmap_entries++, 26684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r, g, b, 128, P_sRGB); 26694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 26704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 26714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann expand_tRNS = 1; 26734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_RGB_ALPHA; 26744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 26754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 26774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Alpha/transparency must be removed. The background must 26794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * exist in the color map (achieved by setting adding it after 26804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the 666 color-map). If the standard processing code will 26814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * pick up this entry automatically that's all that is 26824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * required; libpng can be called to do the background 26834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * processing. 26844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 26854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int sample_size = 26864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_IMAGE_SAMPLE_SIZE(output_format); 26874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 r, g, b; /* sRGB background */ 26884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) 26904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "rgb-alpha color-map: too few entries"); 26914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = make_rgb_colormap(display); 26934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, cmap_entries, back_r, 26954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_g, back_b, 0/*unused*/, output_encoding); 26964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (output_encoding == P_LINEAR) 26984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r = PNG_sRGB_FROM_LINEAR(back_r * 255); 27004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann g = PNG_sRGB_FROM_LINEAR(back_g * 255); 27014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann b = PNG_sRGB_FROM_LINEAR(back_b * 255); 27024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 27034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 27054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 27064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r = back_r; 27074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann g = back_g; 27084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann b = back_g; 27094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 27104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Compare the newly-created color-map entry with the one the 27124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG_CMAP_RGB algorithm will use. If the two entries don't 27134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * match, add the new one and set this as the background 27144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * index. 27154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 27164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (memcmp((png_const_bytep)display->colormap + 27174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann sample_size * cmap_entries, 27184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_const_bytep)display->colormap + 27194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann sample_size * PNG_RGB_INDEX(r,g,b), 27204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann sample_size) != 0) 27214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 27224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The background color must be added. */ 27234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann background_index = cmap_entries++; 27244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Add 27 r,g,b entries each with created by composing with 27264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the background at alpha 0.5. 27274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 27284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (r=0; r<256; r = (r << 1) | 0x7f) 27294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 27304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (g=0; g<256; g = (g << 1) | 0x7f) 27314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 27324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This generates components with the values 0, 127 27334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and 255 27344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 27354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (b=0; b<256; b = (b << 1) | 0x7f) 27364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, cmap_entries++, 27374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colormap_compose(display, r, P_sRGB, 128, 27384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_r, output_encoding), 27394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colormap_compose(display, g, P_sRGB, 128, 27404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_g, output_encoding), 27414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colormap_compose(display, b, P_sRGB, 128, 27424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_b, output_encoding), 27434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 0/*unused*/, output_encoding); 27444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 27454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 27464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann expand_tRNS = 1; 27484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_RGB_ALPHA; 27494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 27504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* background color is in the standard color-map */ 27524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 27534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_color_16 c; 27544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.index = 0; /*unused*/ 27564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.red = (png_uint_16)back_r; 27574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.gray = c.green = (png_uint_16)back_g; 27584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.blue = (png_uint_16)back_b; 27594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_background_fixed(png_ptr, &c, 27614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, 27624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 0/*gamma: not used*/); 27634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_RGB; 27654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 27664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 27674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 27684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* no alpha or transparency in the input */ 27704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 27714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Alpha in the output is irrelevant, simply map the opaque input 27724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * pixels to the 6x6x6 color-map. 27734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 27744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries) 27754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "rgb color-map: too few entries"); 27764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = make_rgb_colormap(display); 27784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_RGB; 27794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 27804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 27814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 27824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_COLOR_TYPE_PALETTE: 27844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* It's already got a color-map. It may be necessary to eliminate the 27854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * tRNS entries though. 27864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 27874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 27884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int num_trans = png_ptr->num_trans; 27894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL; 27904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_colorp colormap = png_ptr->palette; 27914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const int do_background = trans != NULL && 27924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (output_format & PNG_FORMAT_FLAG_ALPHA) == 0; 27934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int i; 27944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Just in case: */ 27964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (trans == NULL) 27974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann num_trans = 0; 27984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_processing = PNG_CMAP_NONE; 28004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann data_encoding = P_FILE; /* Don't change from color-map indices */ 28014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = png_ptr->num_palette; 28024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cmap_entries > 256) 28034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmap_entries = 256; 28044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cmap_entries > image->colormap_entries) 28064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "palette color-map: too few entries"); 28074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i=0; i < cmap_entries; ++i) 28094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 28104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (do_background != 0 && i < num_trans && trans[i] < 255) 28114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 28124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (trans[i] == 0) 28134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i, back_r, back_g, 28144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann back_b, 0, output_encoding); 28154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 28174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 28184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Must compose the PNG file color in the color-map entry 28194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * on the sRGB color in 'back'. 28204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 28214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i, 28224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colormap_compose(display, colormap[i].red, P_FILE, 28234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann trans[i], back_r, output_encoding), 28244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colormap_compose(display, colormap[i].green, P_FILE, 28254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann trans[i], back_g, output_encoding), 28264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colormap_compose(display, colormap[i].blue, P_FILE, 28274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann trans[i], back_b, output_encoding), 28284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_encoding == P_LINEAR ? trans[i] * 257U : 28294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann trans[i], 28304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_encoding); 28314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 28324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 28334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 28354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_create_colormap_entry(display, i, colormap[i].red, 28364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colormap[i].green, colormap[i].blue, 28374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/); 28384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 28394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The PNG data may have indices packed in fewer than 8 bits, it 28414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * must be expanded if so. 28424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 28434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->bit_depth < 8) 28444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_packing(png_ptr); 28454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 28464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 28474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 28494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "invalid PNG color type"); 28504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /*NOT REACHED*/ 28514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 28524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now deal with the output processing */ 28544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (expand_tRNS != 0 && png_ptr->num_trans > 0 && 28554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0) 28564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_tRNS_to_alpha(png_ptr); 28574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (data_encoding) 28594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 28604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case P_sRGB: 28614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Change to 8-bit sRGB */ 28624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB); 28634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* FALL THROUGH */ 28644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case P_FILE: 28664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->bit_depth > 8) 28674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_scale_16(png_ptr); 28684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 28694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef __GNUC__ 28714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 28724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "bad data option (internal error)"); 28734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 28744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 28754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cmap_entries > 256 || cmap_entries > image->colormap_entries) 28774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "color map overflow (BAD internal error)"); 28784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->colormap_entries = cmap_entries; 28804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Double check using the recorded background index */ 28824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (output_processing) 28834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 28844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_NONE: 28854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (background_index != PNG_CMAP_NONE_BACKGROUND) 28864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto bad_background; 28874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 28884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_GA: 28904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (background_index != PNG_CMAP_GA_BACKGROUND) 28914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto bad_background; 28924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 28934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_TRANS: 28954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (background_index >= cmap_entries || 28964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann background_index != PNG_CMAP_TRANS_BACKGROUND) 28974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto bad_background; 28984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 28994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_RGB: 29014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (background_index != PNG_CMAP_RGB_BACKGROUND) 29024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto bad_background; 29034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 29044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_RGB_ALPHA: 29064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND) 29074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto bad_background; 29084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 29094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 29114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "bad processing option (internal error)"); 29124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bad_background: 29144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "bad background index (internal error)"); 29154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 29164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->colormap_processing = output_processing; 29184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1/*ok*/; 29204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 29214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The final part of the color-map read called from png_image_finish_read. */ 29234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 29244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_read_and_map(png_voidp argument) 29254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 29264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_image_read_control *display = png_voidcast(png_image_read_control*, 29274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann argument); 29284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_imagep image = display->image; 29294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_structrp png_ptr = image->opaque->png_ptr; 29304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int passes; 29314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Called when the libpng data must be transformed into the color-mapped 29334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * form. There is a local row buffer in display->local and this routine must 29344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * do the interlace handling. 29354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 29364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (png_ptr->interlaced) 29374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_INTERLACE_NONE: 29394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann passes = 1; 29404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 29414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_INTERLACE_ADAM7: 29434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann passes = PNG_INTERLACE_ADAM7_PASSES; 29444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 29454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 29474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "unknown interlace type"); 29484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 29494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 height = image->height; 29524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 width = image->width; 29534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int proc = display->colormap_processing; 29544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep first_row = png_voidcast(png_bytep, display->first_row); 29554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptrdiff_t step_row = display->row_bytes; 29564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int pass; 29574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (pass = 0; pass < passes; ++pass) 29594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int startx, stepx, stepy; 29614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 y; 29624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) 29644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The row may be empty for a short image: */ 29664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_PASS_COLS(width, pass) == 0) 29674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann continue; 29684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann startx = PNG_PASS_START_COL(pass); 29704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepx = PNG_PASS_COL_OFFSET(pass); 29714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann y = PNG_PASS_START_ROW(pass); 29724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepy = PNG_PASS_ROW_OFFSET(pass); 29734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 29744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 29764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann y = 0; 29784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann startx = 0; 29794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepx = stepy = 1; 29804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 29814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; y<height; y += stepy) 29834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep inrow = png_voidcast(png_bytep, display->local_row); 29854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep outrow = first_row + y * step_row; 29864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_bytep end_row = outrow + width; 29874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Read read the libpng data into the temporary buffer. */ 29894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_row(png_ptr, inrow, NULL); 29904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now process the row according to the processing option, note 29924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * that the caller verifies that the format of the libpng output 29934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * data is as required. 29944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 29954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow += startx; 29964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (proc) 29974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_GA: 29994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; outrow < end_row; outrow += stepx) 30004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The data is always in the PNG order */ 30024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int gray = *inrow++; 30034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int alpha = *inrow++; 30044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int entry; 30054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* NOTE: this code is copied as a comment in 30074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * make_ga_colormap above. Please update the 30084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * comment if you change this code! 30094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 30104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha > 229) /* opaque */ 30114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry = (231 * gray + 128) >> 8; 30134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (alpha < 26) /* transparent */ 30154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry = 231; 30174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* partially opaque */ 30194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray); 30214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *outrow = (png_byte)entry; 30244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 30264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_TRANS: 30284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; outrow < end_row; outrow += stepx) 30294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_byte gray = *inrow++; 30314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_byte alpha = *inrow++; 30324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha == 0) 30344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *outrow = PNG_CMAP_TRANS_BACKGROUND; 30354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (gray != PNG_CMAP_TRANS_BACKGROUND) 30374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *outrow = gray; 30384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 30404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1); 30414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 30434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_RGB: 30454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; outrow < end_row; outrow += stepx) 30464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]); 30484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann inrow += 3; 30494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 30514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_RGB_ALPHA: 30534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; outrow < end_row; outrow += stepx) 30544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int alpha = inrow[3]; 30564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Because the alpha entries only hold alpha==0.5 values 30584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * split the processing at alpha==0.25 (64) and 0.75 30594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (196). 30604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 30614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha >= 196) 30634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], 30644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann inrow[2]); 30654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (alpha < 64) 30674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND; 30684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 30704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Likewise there are three entries for each of r, g 30724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and b. We could select the entry by popcount on 30734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the top two bits on those architectures that 30744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * support it, this is what the code below does, 30754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * crudely. 30764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 30774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1; 30784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Here are how the values map: 30804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 30814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 0x00 .. 0x3f -> 0 30824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 0x40 .. 0xbf -> 1 30834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 0xc0 .. 0xff -> 2 30844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 30854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * So, as above with the explicit alpha checks, the 30864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * breakpoints are at 64 and 196. 30874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 30884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (inrow[0] & 0x80) back_i += 9; /* red */ 30894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (inrow[0] & 0x40) back_i += 9; 30904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (inrow[0] & 0x80) back_i += 3; /* green */ 30914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (inrow[0] & 0x40) back_i += 3; 30924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (inrow[0] & 0x80) back_i += 1; /* blue */ 30934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (inrow[0] & 0x40) back_i += 1; 30944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *outrow = (png_byte)back_i; 30964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann inrow += 4; 30994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 31014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 31034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 31044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 31104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 31114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 31134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_read_colormapped(png_voidp argument) 31144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 31154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_image_read_control *display = png_voidcast(png_image_read_control*, 31164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann argument); 31174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_imagep image = display->image; 31184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_controlp control = image->opaque; 31194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_structrp png_ptr = control->png_ptr; 31204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_inforp info_ptr = control->info_ptr; 31214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int passes = 0; /* As a flag */ 31234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_SKIP_CHUNKS(png_ptr); 31254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Update the 'info' structure and make sure the result is as required; first 31274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * make sure to turn on the interlace handling if it will be required 31284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (because it can't be turned on *after* the call to png_read_update_info!) 31294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 31304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (display->colormap_processing == PNG_CMAP_NONE) 31314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann passes = png_set_interlace_handling(png_ptr); 31324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_update_info(png_ptr, info_ptr); 31344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The expected output can be deduced from the colormap_processing option. */ 31364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (display->colormap_processing) 31374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 31384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_NONE: 31394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Output must be one channel and one byte per pixel, the output 31404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * encoding can be anything. 31414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 31424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE || 31434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->color_type == PNG_COLOR_TYPE_GRAY) && 31444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->bit_depth == 8) 31454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 31464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto bad_output; 31484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_TRANS: 31504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_GA: 31514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Output must be two channels and the 'G' one must be sRGB, the latter 31524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * can be checked with an exact number because it should have been set 31534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to this number above! 31544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 31554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && 31564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->bit_depth == 8 && 31574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->screen_gamma == PNG_GAMMA_sRGB && 31584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->colormap_entries == 256) 31594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 31604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto bad_output; 31624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_RGB: 31644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Output must be 8-bit sRGB encoded RGB */ 31654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr->color_type == PNG_COLOR_TYPE_RGB && 31664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->bit_depth == 8 && 31674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->screen_gamma == PNG_GAMMA_sRGB && 31684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->colormap_entries == 216) 31694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 31704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto bad_output; 31724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_CMAP_RGB_ALPHA: 31744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Output must be 8-bit sRGB encoded RGBA */ 31754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA && 31764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->bit_depth == 8 && 31774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->screen_gamma == PNG_GAMMA_sRGB && 31784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->colormap_entries == 244 /* 216 + 1 + 27 */) 31794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 31804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* goto bad_output; */ 31824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* FALL THROUGH */ 31834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 31854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bad_output: 31864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "bad color-map processing (internal error)"); 31874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now read the rows. Do this here if it is possible to read directly into 31904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the output buffer, otherwise allocate a local row buffer of the maximum 31914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * size libpng requires and call the relevant processing routine safely. 31924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 31934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 31944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_voidp first_row = display->buffer; 31954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptrdiff_t row_bytes = display->row_stride; 31964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The following expression is designed to work correctly whether it gives 31984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * a signed or an unsigned result. 31994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 32004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (row_bytes < 0) 32014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann char *ptr = png_voidcast(char*, first_row); 32034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptr += (image->height-1) * (-row_bytes); 32044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann first_row = png_voidcast(png_voidp, ptr); 32054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 32064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->first_row = first_row; 32084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->row_bytes = row_bytes; 32094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 32104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (passes == 0) 32124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int result; 32144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); 32154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->local_row = row; 32174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result = png_safe_execute(image, png_image_read_and_map, display); 32184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->local_row = NULL; 32194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, row); 32204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return result; 32224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 32234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 32254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_alloc_size_t row_bytes = display->row_bytes; 32274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (--passes >= 0) 32294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 y = image->height; 32314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep row = png_voidcast(png_bytep, display->first_row); 32324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (y-- > 0) 32344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_row(png_ptr, row, NULL); 32364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row += row_bytes; 32374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 32384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 32394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 32414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 32424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 32434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Just the row reading part of png_image_read. */ 32454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 32464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_read_composite(png_voidp argument) 32474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 32484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_image_read_control *display = png_voidcast(png_image_read_control*, 32494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann argument); 32504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_imagep image = display->image; 32514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_structrp png_ptr = image->opaque->png_ptr; 32524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int passes; 32534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (png_ptr->interlaced) 32554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_INTERLACE_NONE: 32574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann passes = 1; 32584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 32594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_INTERLACE_ADAM7: 32614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann passes = PNG_INTERLACE_ADAM7_PASSES; 32624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 32634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 32654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "unknown interlace type"); 32664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 32674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 height = image->height; 32704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 width = image->width; 32714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptrdiff_t step_row = display->row_bytes; 32724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int channels = 32734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; 32744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int pass; 32754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (pass = 0; pass < passes; ++pass) 32774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int startx, stepx, stepy; 32794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 y; 32804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) 32824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The row may be empty for a short image: */ 32844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_PASS_COLS(width, pass) == 0) 32854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann continue; 32864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann startx = PNG_PASS_START_COL(pass) * channels; 32884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepx = PNG_PASS_COL_OFFSET(pass) * channels; 32894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann y = PNG_PASS_START_ROW(pass); 32904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepy = PNG_PASS_ROW_OFFSET(pass); 32914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 32924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 32944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann y = 0; 32964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann startx = 0; 32974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepx = channels; 32984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepy = 1; 32994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; y<height; y += stepy) 33024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 33034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep inrow = png_voidcast(png_bytep, display->local_row); 33044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep outrow; 33054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_bytep end_row; 33064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Read the row, which is packed: */ 33084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_row(png_ptr, inrow, NULL); 33094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow = png_voidcast(png_bytep, display->first_row); 33114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow += y * step_row; 33124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann end_row = outrow + width * channels; 33134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now do the composition on each pixel in this row. */ 33154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow += startx; 33164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; outrow < end_row; outrow += stepx) 33174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 33184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_byte alpha = inrow[channels]; 33194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha > 0) /* else no change to the output */ 33214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 33224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int c; 33234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (c=0; c<channels; ++c) 33254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 33264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 component = inrow[c]; 33274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha < 255) /* else just use component */ 33294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 33304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is PNG_OPTIMIZED_ALPHA, the component value 33314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is a linear 8-bit value. Combine this with the 33324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * current outrow[c] value which is sRGB encoded. 33334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Arithmetic here is 16-bits to preserve the output 33344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * values correctly. 33354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 33364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component *= 257*255; /* =65535 */ 33374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component += (255-alpha)*png_sRGB_table[outrow[c]]; 33384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* So 'component' is scaled by 255*65535 and is 33404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * therefore appropriate for the sRGB to linear 33414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * conversion table. 33424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 33434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component = PNG_sRGB_FROM_LINEAR(component); 33444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow[c] = (png_byte)component; 33474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann inrow += channels+1; /* components and alpha channel */ 33514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 33574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 33584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The do_local_background case; called when all the following transforms are to 33604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * be done: 33614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 33624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG_RGB_TO_GRAY 33634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG_COMPOSITE 33644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG_GAMMA 33654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 33664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This is a work-around for the fact that both the PNG_RGB_TO_GRAY and 33674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG_COMPOSITE code performs gamma correction, so we get double gamma 33684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * correction. The fix-up is to prevent the PNG_COMPOSITE operation from 33694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * happening inside libpng, so this routine sees an 8 or 16-bit gray+alpha 33704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * row and handles the removal or pre-multiplication of the alpha channel. 33714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 33724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 33734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_read_background(png_voidp argument) 33744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 33754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_image_read_control *display = png_voidcast(png_image_read_control*, 33764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann argument); 33774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_imagep image = display->image; 33784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_structrp png_ptr = image->opaque->png_ptr; 33794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_inforp info_ptr = image->opaque->info_ptr; 33804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 height = image->height; 33814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 width = image->width; 33824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int pass, passes; 33834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Double check the convoluted logic below. We expect to get here with 33854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * libpng doing rgb to gray and gamma correction but background processing 33864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * left to the png_image_read_background function. The rows libpng produce 33874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * might be 8 or 16-bit but should always have two channels; gray plus alpha. 33884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 33894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) 33904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "lost rgb to gray"); 33914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & PNG_COMPOSE) != 0) 33934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "unexpected compose"); 33944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_get_channels(png_ptr, info_ptr) != 2) 33964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "lost/gained channels"); 33974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Expect the 8-bit case to always remove the alpha channel */ 33994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 && 34004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (image->format & PNG_FORMAT_FLAG_ALPHA) != 0) 34014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "unexpected 8-bit transformation"); 34024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (png_ptr->interlaced) 34044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 34054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_INTERLACE_NONE: 34064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann passes = 1; 34074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 34084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_INTERLACE_ADAM7: 34104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann passes = PNG_INTERLACE_ADAM7_PASSES; 34114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 34124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 34144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "unknown interlace type"); 34154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 34164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Use direct access to info_ptr here because otherwise the simplified API 34184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * would require PNG_EASY_ACCESS_SUPPORTED (just for this.) Note this is 34194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * checking the value after libpng expansions, not the original value in the 34204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG. 34214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 34224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (info_ptr->bit_depth) 34234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 34244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 8: 34254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 8-bit sRGB gray values with an alpha channel; the alpha channel is 34264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to be removed by composing on a background: either the row if 34274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * display->background is NULL or display->background->green if not. 34284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Unlike the code above ALPHA_OPTIMIZED has *not* been done. 34294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 34304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 34314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep first_row = png_voidcast(png_bytep, display->first_row); 34324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptrdiff_t step_row = display->row_bytes; 34334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (pass = 0; pass < passes; ++pass) 34354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 34364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep row = png_voidcast(png_bytep, 34374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->first_row); 34384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int startx, stepx, stepy; 34394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 y; 34404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) 34424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 34434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The row may be empty for a short image: */ 34444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_PASS_COLS(width, pass) == 0) 34454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann continue; 34464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann startx = PNG_PASS_START_COL(pass); 34484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepx = PNG_PASS_COL_OFFSET(pass); 34494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann y = PNG_PASS_START_ROW(pass); 34504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepy = PNG_PASS_ROW_OFFSET(pass); 34514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 34524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 34544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 34554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann y = 0; 34564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann startx = 0; 34574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepx = stepy = 1; 34584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 34594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (display->background == NULL) 34614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 34624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; y<height; y += stepy) 34634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 34644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep inrow = png_voidcast(png_bytep, 34654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->local_row); 34664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep outrow = first_row + y * step_row; 34674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_bytep end_row = outrow + width; 34684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Read the row, which is packed: */ 34704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_row(png_ptr, inrow, NULL); 34714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now do the composition on each pixel in this row. */ 34734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow += startx; 34744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; outrow < end_row; outrow += stepx) 34754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 34764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_byte alpha = inrow[1]; 34774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha > 0) /* else no change to the output */ 34794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 34804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 component = inrow[0]; 34814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha < 255) /* else just use component */ 34834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 34844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Since PNG_OPTIMIZED_ALPHA was not set it is 34854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * necessary to invert the sRGB transfer 34864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * function and multiply the alpha out. 34874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 34884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component = png_sRGB_table[component] * alpha; 34894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component += png_sRGB_table[outrow[0]] * 34904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (255-alpha); 34914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component = PNG_sRGB_FROM_LINEAR(component); 34924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 34934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow[0] = (png_byte)component; 34954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 34964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann inrow += 2; /* gray and alpha channel */ 34984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 34994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 35004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 35014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* constant background value */ 35034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 35044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_byte background8 = display->background->green; 35054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_16 background = png_sRGB_table[background8]; 35064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; y<height; y += stepy) 35084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 35094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep inrow = png_voidcast(png_bytep, 35104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->local_row); 35114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep outrow = first_row + y * step_row; 35124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_bytep end_row = outrow + width; 35134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Read the row, which is packed: */ 35154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_row(png_ptr, inrow, NULL); 35164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now do the composition on each pixel in this row. */ 35184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow += startx; 35194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; outrow < end_row; outrow += stepx) 35204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 35214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_byte alpha = inrow[1]; 35224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha > 0) /* else use background */ 35244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 35254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 component = inrow[0]; 35264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha < 255) /* else just use component */ 35284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 35294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component = png_sRGB_table[component] * alpha; 35304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component += background * (255-alpha); 35314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component = PNG_sRGB_FROM_LINEAR(component); 35324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 35334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow[0] = (png_byte)component; 35354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 35364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 35384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow[0] = background8; 35394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann inrow += 2; /* gray and alpha channel */ 35414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 35424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row += display->row_bytes; 35444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 35454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 35464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 35474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 35484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 35494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 16: 35514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must 35524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * still be done and, maybe, the alpha channel removed. This code also 35534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * handles the alpha-first option. 35544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 35554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 35564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_16p first_row = png_voidcast(png_uint_16p, 35574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->first_row); 35584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The division by two is safe because the caller passed in a 35594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * stride which was multiplied by 2 (below) to get row_bytes. 35604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 35614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptrdiff_t step_row = display->row_bytes / 2; 35624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; 35634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int outchannels = 1+preserve_alpha; 35644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int swap_alpha = 0; 35654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED 35674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (preserve_alpha != 0 && 35684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (image->format & PNG_FORMAT_FLAG_AFIRST) != 0) 35694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann swap_alpha = 1; 35704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 35714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (pass = 0; pass < passes; ++pass) 35734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 35744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int startx, stepx, stepy; 35754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 y; 35764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The 'x' start and step are adjusted to output components here. 35784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 35794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) 35804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 35814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The row may be empty for a short image: */ 35824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_PASS_COLS(width, pass) == 0) 35834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann continue; 35844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann startx = PNG_PASS_START_COL(pass) * outchannels; 35864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepx = PNG_PASS_COL_OFFSET(pass) * outchannels; 35874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann y = PNG_PASS_START_ROW(pass); 35884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepy = PNG_PASS_ROW_OFFSET(pass); 35894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 35904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 35924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 35934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann y = 0; 35944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann startx = 0; 35954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepx = outchannels; 35964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann stepy = 1; 35974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 35984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; y<height; y += stepy) 36004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 36014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_uint_16p inrow; 36024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_16p outrow = first_row + y*step_row; 36034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_16p end_row = outrow + width * outchannels; 36044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Read the row, which is packed: */ 36064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_row(png_ptr, png_voidcast(png_bytep, 36074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->local_row), NULL); 36084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann inrow = png_voidcast(png_const_uint_16p, display->local_row); 36094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now do the pre-multiplication on each pixel in this row. 36114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 36124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow += startx; 36134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (; outrow < end_row; outrow += stepx) 36144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 36154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 component = inrow[0]; 36164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_16 alpha = inrow[1]; 36174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha > 0) /* else 0 */ 36194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 36204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (alpha < 65535) /* else just use component */ 36214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 36224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component *= alpha; 36234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component += 32767; 36244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component /= 65535; 36254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 36264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 36274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 36294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann component = 0; 36304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow[swap_alpha] = (png_uint_16)component; 36324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (preserve_alpha != 0) 36334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann outrow[1 ^ swap_alpha] = alpha; 36344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann inrow += 2; /* components and alpha channel */ 36364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 36374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 36384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 36394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 36404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 36414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef __GNUC__ 36434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 36444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "unexpected bit depth"); 36454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 36464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 36474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 36494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 36504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The guts of png_image_finish_read as a png_safe_execute callback. */ 36524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 36534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_read_direct(png_voidp argument) 36544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 36554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_image_read_control *display = png_voidcast(png_image_read_control*, 36564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann argument); 36574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_imagep image = display->image; 36584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_structrp png_ptr = image->opaque->png_ptr; 36594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_inforp info_ptr = image->opaque->info_ptr; 36604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 format = image->format; 36624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0; 36634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int do_local_compose = 0; 36644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int do_local_background = 0; /* to avoid double gamma correction bug */ 36654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int passes = 0; 36664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Add transforms to ensure the correct output format is produced then check 36684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * that the required implementation support is there. Always expand; always 36694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * need 8 bits minimum, no palette and expanded tRNS. 36704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 36714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_expand(png_ptr); 36724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now check the format to see if it was modified. */ 36744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 36754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 base_format = png_image_format(png_ptr) & 36764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */; 36774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 change = format ^ base_format; 36784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point output_gamma; 36794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int mode; /* alpha mode */ 36804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Do this first so that we have a record if rgb to gray is happening. */ 36824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((change & PNG_FORMAT_FLAG_COLOR) != 0) 36834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 36844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* gray<->color transformation required. */ 36854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((format & PNG_FORMAT_FLAG_COLOR) != 0) 36864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_gray_to_rgb(png_ptr); 36874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 36894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 36904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* libpng can't do both rgb to gray and 36914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * background/pre-multiplication if there is also significant gamma 36924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * correction, because both operations require linear colors and 36934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the code only supports one transform doing the gamma correction. 36944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Handle this by doing the pre-multiplication or background 36954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * operation in this code, if necessary. 36964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 36974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * TODO: fix this by rewriting pngrtran.c (!) 36984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 36994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * For the moment (given that fixing this in pngrtran.c is an 37004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * enormous change) 'do_local_background' is used to indicate that 37014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the problem exists. 37024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 37034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) 37044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann do_local_background = 1/*maybe*/; 37054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, 37074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); 37084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 37094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann change &= ~PNG_FORMAT_FLAG_COLOR; 37114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 37124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise. 37144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 37154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 37164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point input_gamma_default; 37174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 && 37194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) 37204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann input_gamma_default = PNG_GAMMA_LINEAR; 37214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 37224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann input_gamma_default = PNG_DEFAULT_sRGB; 37234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Call png_set_alpha_mode to set the default for the input gamma; the 37254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * output gamma is set by a second call below. 37264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 37274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default); 37284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 37294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (linear != 0) 37314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 37324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If there *is* an alpha channel in the input it must be multiplied 37334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG. 37344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 37354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) 37364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann mode = PNG_ALPHA_STANDARD; /* associated alpha */ 37374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 37394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann mode = PNG_ALPHA_PNG; 37404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_gamma = PNG_GAMMA_LINEAR; 37424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 37434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 37454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 37464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann mode = PNG_ALPHA_PNG; 37474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann output_gamma = PNG_DEFAULT_sRGB; 37484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 37494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If 'do_local_background' is set check for the presence of gamma 37514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * correction; this is part of the work-round for the libpng bug 37524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * described above. 37534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 37544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * TODO: fix libpng and remove this. 37554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 37564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (do_local_background != 0) 37574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 37584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point gtest; 37594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is 'png_gamma_threshold' from pngrtran.c; the test used for 37614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * gamma correction, the screen gamma hasn't been set on png_struct 37624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * yet; it's set below. png_struct::gamma, however, is set to the 37634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * final value. 37644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 37654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma, 37664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0) 37674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann do_local_background = 0; 37684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (mode == PNG_ALPHA_STANDARD) 37704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 37714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann do_local_background = 2/*required*/; 37724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann mode = PNG_ALPHA_PNG; /* prevent libpng doing it */ 37734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 37744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* else leave as 1 for the checks below */ 37764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 37774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If the bit-depth changes then handle that here. */ 37794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((change & PNG_FORMAT_FLAG_LINEAR) != 0) 37804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 37814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (linear != 0 /*16-bit output*/) 37824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_expand_16(png_ptr); 37834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* 8-bit output */ 37854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_scale_16(png_ptr); 37864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann change &= ~PNG_FORMAT_FLAG_LINEAR; 37884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 37894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now the background/alpha channel changes. */ 37914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((change & PNG_FORMAT_FLAG_ALPHA) != 0) 37924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 37934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Removing an alpha channel requires composition for the 8-bit 37944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * formats; for the 16-bit it is already done, above, by the 37954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * pre-multiplication and the channel just needs to be stripped. 37964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 37974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) 37984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 37994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If RGB->gray is happening the alpha channel must be left and the 38004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * operation completed locally. 38014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 38024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * TODO: fix libpng and remove this. 38034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 38044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (do_local_background != 0) 38054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann do_local_background = 2/*required*/; 38064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 16-bit output: just remove the channel */ 38084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (linear != 0) /* compose on black (well, pre-multiply) */ 38094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_strip_alpha(png_ptr); 38104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 8-bit output: do an appropriate compose */ 38124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (display->background != NULL) 38134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 38144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_color_16 c; 38154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.index = 0; /*unused*/ 38174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.red = display->background->red; 38184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.green = display->background->green; 38194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.blue = display->background->blue; 38204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c.gray = display->background->green; 38214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is always an 8-bit sRGB value, using the 'green' channel 38234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * for gray is much better than calculating the luminance here; 38244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * we can get off-by-one errors in that calculation relative to 38254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the app expectations and that will show up in transparent 38264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * pixels. 38274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 38284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_background_fixed(png_ptr, &c, 38294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, 38304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 0/*gamma: not used*/); 38314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 38324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* compose on row: implemented below. */ 38344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 38354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann do_local_compose = 1; 38364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This leaves the alpha channel in the output, so it has to be 38374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * removed by the code below. Set the encoding to the 'OPTIMIZE' 38384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * one so the code only has to hack on the pixels that require 38394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * composition. 38404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 38414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann mode = PNG_ALPHA_OPTIMIZED; 38424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 38434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 38444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* output needs an alpha channel */ 38464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 38474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is tricky because it happens before the swap operation has 38484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * been accomplished; however, the swap does *not* swap the added 38494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * alpha channel (weird API), so it must be added in the correct 38504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * place. 38514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 38524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 filler; /* opaque filler */ 38534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int where; 38544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (linear != 0) 38564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann filler = 65535; 38574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 38594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann filler = 255; 38604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FORMAT_AFIRST_SUPPORTED 38624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) 38634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 38644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann where = PNG_FILLER_BEFORE; 38654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann change &= ~PNG_FORMAT_FLAG_AFIRST; 38664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 38674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 38694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 38704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann where = PNG_FILLER_AFTER; 38714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_add_alpha(png_ptr, filler, where); 38734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 38744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This stops the (irrelevant) call to swap_alpha below. */ 38764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann change &= ~PNG_FORMAT_FLAG_ALPHA; 38774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 38784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now set the alpha mode correctly; this is always done, even if there is 38804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * no alpha channel in either the input or the output because it correctly 38814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * sets the output gamma. 38824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 38834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_alpha_mode_fixed(png_ptr, mode, output_gamma); 38844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_FORMAT_BGR_SUPPORTED 38864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((change & PNG_FORMAT_FLAG_BGR) != 0) 38874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 38884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Check only the output format; PNG is never BGR; don't do this if 38894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the output is gray, but fix up the 'format' value in that case. 38904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 38914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((format & PNG_FORMAT_FLAG_COLOR) != 0) 38924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_bgr(png_ptr); 38934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 38954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann format &= ~PNG_FORMAT_FLAG_BGR; 38964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann change &= ~PNG_FORMAT_FLAG_BGR; 38984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 38994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 39004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_FORMAT_AFIRST_SUPPORTED 39024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((change & PNG_FORMAT_FLAG_AFIRST) != 0) 39034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Only relevant if there is an alpha channel - it's particularly 39054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * important to handle this correctly because do_local_compose may 39064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * be set above and then libpng will keep the alpha channel for this 39074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * code to remove. 39084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 39094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((format & PNG_FORMAT_FLAG_ALPHA) != 0) 39104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Disable this if doing a local background, 39124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * TODO: remove this when local background is no longer required. 39134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 39144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (do_local_background != 2) 39154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_swap_alpha(png_ptr); 39164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 39194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann format &= ~PNG_FORMAT_FLAG_AFIRST; 39204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann change &= ~PNG_FORMAT_FLAG_AFIRST; 39224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 39244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If the *output* is 16-bit then we need to check for a byte-swap on this 39264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * architecture. 39274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 39284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (linear != 0) 39294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CONST png_uint_16 le = 0x0001; 39314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((*(png_const_bytep) & le) != 0) 39334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_swap(png_ptr); 39344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If change is not now 0 some transformation is missing - error out. */ 39374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (change != 0) 39384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "png_read_image: unsupported transformation"); 39394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_SKIP_CHUNKS(png_ptr); 39424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Update the 'info' structure and make sure the result is as required; first 39444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * make sure to turn on the interlace handling if it will be required 39454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (because it can't be turned on *after* the call to png_read_update_info!) 39464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 39474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * TODO: remove the do_local_background fixup below. 39484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 39494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (do_local_compose == 0 && do_local_background != 2) 39504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann passes = png_set_interlace_handling(png_ptr); 39514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_update_info(png_ptr, info_ptr); 39534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 info_format = 0; 39564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) 39584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_format |= PNG_FORMAT_FLAG_COLOR; 39594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) 39614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* do_local_compose removes this channel below. */ 39634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (do_local_compose == 0) 39644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* do_local_background does the same if required. */ 39664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (do_local_background != 2 || 39674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (format & PNG_FORMAT_FLAG_ALPHA) != 0) 39684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_format |= PNG_FORMAT_FLAG_ALPHA; 39694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (do_local_compose != 0) /* internal error */ 39734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "png_image_read: alpha channel lost"); 39744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr->bit_depth == 16) 39764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_format |= PNG_FORMAT_FLAG_LINEAR; 39774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FORMAT_BGR_SUPPORTED 39794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & PNG_BGR) != 0) 39804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_format |= PNG_FORMAT_FLAG_BGR; 39814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 39824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FORMAT_AFIRST_SUPPORTED 39844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (do_local_background == 2) 39854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) 39874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_format |= PNG_FORMAT_FLAG_AFIRST; 39884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 || 39914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 && 39924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0)) 39934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (do_local_background == 2) 39954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "unexpected alpha swap transformation"); 39964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_format |= PNG_FORMAT_FLAG_AFIRST; 39984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 40004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is actually an internal error. */ 40024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_format != format) 40034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "png_read_image: invalid transformations"); 40044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now read the rows. If do_local_compose is set then it is necessary to use 40074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * a local row buffer. The output will be GA, RGBA or BGRA and must be 40084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * converted to G, RGB or BGR as appropriate. The 'local_row' member of the 40094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * display acts as a flag. 40104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 40114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_voidp first_row = display->buffer; 40134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptrdiff_t row_bytes = display->row_stride; 40144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (linear != 0) 40164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row_bytes *= 2; 40174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The following expression is designed to work correctly whether it gives 40194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * a signed or an unsigned result. 40204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 40214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (row_bytes < 0) 40224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann char *ptr = png_voidcast(char*, first_row); 40244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptr += (image->height-1) * (-row_bytes); 40254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann first_row = png_voidcast(png_voidp, ptr); 40264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->first_row = first_row; 40294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->row_bytes = row_bytes; 40304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (do_local_compose != 0) 40334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int result; 40354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); 40364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->local_row = row; 40384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result = png_safe_execute(image, png_image_read_composite, display); 40394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->local_row = NULL; 40404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, row); 40414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return result; 40434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (do_local_background == 2) 40464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int result; 40484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); 40494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->local_row = row; 40514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result = png_safe_execute(image, png_image_read_background, display); 40524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display->local_row = NULL; 40534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, row); 40544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return result; 40564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 40594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_alloc_size_t row_bytes = display->row_bytes; 40614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (--passes >= 0) 40634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 y = image->height; 40654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep row = png_voidcast(png_bytep, display->first_row); 40664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (y-- > 0) 40684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_read_row(png_ptr, row, NULL); 40704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row += row_bytes; 40714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 40754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 40774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI 40794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_finish_read(png_imagep image, png_const_colorp background, 40804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann void *buffer, png_int_32 row_stride, void *colormap) 40814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 40824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (image != NULL && image->version == PNG_IMAGE_VERSION) 40834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Check for row_stride overflow. This check is not performed on the 40854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * original PNG format because it may not occur in the output PNG format 40864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and libpng deals with the issues of reading the original. 40874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 40884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); 40894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (image->width <= 0x7FFFFFFFU/channels) /* no overflow */ 40914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 check; 40934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann const png_uint_32 png_row_stride = image->width * channels; 40944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (row_stride == 0) 40964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann row_stride = (png_int_32)/*SAFE*/png_row_stride; 40974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (row_stride < 0) 40994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann check = -row_stride; 41004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 41024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann check = row_stride; 41034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (image->opaque != NULL && buffer != NULL && check >= png_row_stride) 41054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 41064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now check for overflow of the image buffer calculation; this 41074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * limits the whole image size to 32 bits for API compatibility with 41084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. 41094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 41104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (image->height <= 0xFFFFFFFF/png_row_stride) 41114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 41124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || 41134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (image->colormap_entries > 0 && colormap != NULL)) 41144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 41154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int result; 41164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_image_read_control display; 41174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann memset(&display, 0, (sizeof display)); 41194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display.image = image; 41204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display.buffer = buffer; 41214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display.row_stride = row_stride; 41224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display.colormap = colormap; 41234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display.background = background; 41244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann display.local_row = NULL; 41254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Choose the correct 'end' routine; for the color-map case 41274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * all the setup has already been done. 41284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 41294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0) 41304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result = png_safe_execute(image, 41314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_image_read_colormap, &display) && 41324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_safe_execute(image, 41334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_image_read_colormapped, &display); 41344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 41364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result = 41374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_safe_execute(image, 41384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_image_read_direct, &display); 41394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_image_free(image); 41414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return result; 41424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 41434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 41454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, 41464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_image_finish_read[color-map]: no color-map"); 41474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 41484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 41504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, 41514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_image_finish_read: image too large"); 41524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 41534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 41554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, 41564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_image_finish_read: invalid argument"); 41574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 41584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 41604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, 41614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_image_finish_read: row_stride too large"); 41624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 41634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (image != NULL) 41654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_image_error(image, 41664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "png_image_finish_read: damaged PNG_IMAGE_VERSION"); 41674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 41694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 41704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SIMPLIFIED_READ */ 41724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ */ 4173