18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* pngwutil.c - utilities to write a PNG file 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Last changed in libpng 1.2.19 August 18, 2007 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * For conditions of distribution and use, see copyright notice in png.h 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 1998-2007 Glenn Randers-Pehrson 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PNG_INTERNAL 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "png.h" 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_WRITE_SUPPORTED 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Place a 32-bit number into a buffer in PNG byte order. We work 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * with unsigned numbers for convenience, although one supported 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ancillary chunk uses signed (two's complement) numbers. 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid PNGAPI 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_save_uint_32(png_bytep buf, png_uint_32 i) 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = (png_byte)((i >> 24) & 0xff); 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[1] = (png_byte)((i >> 16) & 0xff); 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[2] = (png_byte)((i >> 8) & 0xff); 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[3] = (png_byte)(i & 0xff); 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* The png_save_int_32 function assumes integers are stored in two's 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * complement format. If this isn't the case, then this routine needs to 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * be modified to write data in two's complement format. 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid PNGAPI 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_save_int_32(png_bytep buf, png_int_32 i) 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = (png_byte)((i >> 24) & 0xff); 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[1] = (png_byte)((i >> 16) & 0xff); 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[2] = (png_byte)((i >> 8) & 0xff); 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[3] = (png_byte)(i & 0xff); 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Place a 16-bit number into a buffer in PNG byte order. 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The parameter is declared unsigned int, not png_uint_16, 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * just to avoid potential problems on pre-ANSI C compilers. 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid PNGAPI 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_save_uint_16(png_bytep buf, unsigned int i) 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = (png_byte)((i >> 8) & 0xff); 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[1] = (png_byte)(i & 0xff); 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Write a PNG chunk all at once. The type is an array of ASCII characters 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * representing the chunk name. The array must be at least 4 bytes in 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * length, and does not need to be null terminated. To be safe, pass the 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * pre-defined chunk names here, and if you need a new one, define it 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * where the others are defined. The length is the length of the data. 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * All the data must be present. If that is not possible, use the 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * functions instead. 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid PNGAPI 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_chunk(png_structp png_ptr, png_bytep chunk_name, 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep data, png_size_t length) 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(png_ptr == NULL) return; 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length); 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, data, length); 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_end(png_ptr); 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Write the start of a PNG chunk. The type is the chunk type. 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The total_length is the sum of the lengths of all the data you will be 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * passing in png_write_chunk_data(). 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid PNGAPI 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_chunk_start(png_structp png_ptr, png_bytep chunk_name, 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 length) 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[4]; 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length); 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(png_ptr == NULL) return; 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write the length */ 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf, length); 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_data(png_ptr, buf, (png_size_t)4); 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write the chunk name */ 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_data(png_ptr, chunk_name, (png_size_t)4); 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* reset the crc and run it over the chunk name */ 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_reset_crc(png_ptr); 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_calculate_crc(png_ptr, chunk_name, (png_size_t)4); 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Write the data of a PNG chunk started with png_write_chunk_start(). 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Note that multiple calls to this function are allowed, and that the 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * sum of the lengths from these calls *must* add up to the total_length 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * given to png_write_chunk_start(). 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid PNGAPI 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length) 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write the data, and run the CRC over it */ 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(png_ptr == NULL) return; 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (data != NULL && length > 0) 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_calculate_crc(png_ptr, data, length); 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_data(png_ptr, data, length); 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Finish a chunk started with png_write_chunk_start(). */ 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid PNGAPI 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_chunk_end(png_structp png_ptr) 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[4]; 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(png_ptr == NULL) return; 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write the crc */ 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf, png_ptr->crc); 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_data(png_ptr, buf, (png_size_t)4); 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Simple function to write the signature. If we have already written 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the magic bytes of the signature, or more likely, the PNG stream is 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * being embedded into another stream and doesn't need its own signature, 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * we should call png_set_sig_bytes() to tell libpng how many of the 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * bytes have already been written. 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_sig(png_structp png_ptr) 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write the rest of the 8 byte signature */ 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_size_t)8 - png_ptr->sig_bytes); 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(png_ptr->sig_bytes < 3) 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED) 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This pair of functions encapsulates the operation of (a) compressing a 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * text string, and (b) issuing it later as a series of chunk data writes. 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The compression_state structure is shared context for these functions 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * set up by the caller in order to make the whole mess thread-safe. 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *input; /* the uncompressed input data */ 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int input_len; /* its length */ 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int num_output_ptr; /* number of output pointers used */ 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int max_output_ptr; /* size of output_ptr */ 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charpp output_ptr; /* array of pointers to output */ 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} compression_state; 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* compress given text into storage in the png_ptr structure */ 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int /* PRIVATE */ 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_text_compress(png_structp png_ptr, 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charp text, png_size_t text_len, int compression, 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project compression_state *comp) 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->num_output_ptr = 0; 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->max_output_ptr = 0; 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->output_ptr = NULL; 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->input = NULL; 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->input_len = 0; 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* we may just want to pass the text right through */ 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (compression == PNG_TEXT_COMPRESSION_NONE) 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->input = text; 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->input_len = text_len; 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return((int)text_len); 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (compression >= PNG_TEXT_COMPRESSION_LAST) 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char msg[50]; 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_snprintf(msg, 50, "Unknown compression type %d", compression); 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, msg); 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Unknown compression type"); 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* We can't write the chunk until we find out how much data we have, 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * which means we need to run the compressor first and save the 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * output. This shouldn't be a problem, as the vast majority of 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * comments should be reasonable, but we will set up an array of 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * malloc'd pointers to be sure. 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If we knew the application was well behaved, we could simplify this 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * greatly by assuming we can always malloc an output buffer large 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * enough to hold the compressed text ((1001 * text_len / 1000) + 12) 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and malloc this directly. The only time this would be a bad idea is 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if we can't malloc more than 64K and we have 64K of random input 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * data, or if the input string is incredibly large (although this 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * wouldn't cause a failure, just a slowdown due to swapping). 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* set up the compression buffers */ 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.avail_in = (uInt)text_len; 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.next_in = (Bytef *)text; 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf; 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* this is the same compression loop as in png_write_row() */ 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* compress the data */ 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret != Z_OK) 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* error */ 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->zstream.msg != NULL) 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, png_ptr->zstream.msg); 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, "zlib error"); 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* check to see if we need more room */ 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->zstream.avail_out)) 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* make sure the output array has room */ 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (comp->num_output_ptr >= comp->max_output_ptr) 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int old_max; 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project old_max = comp->max_output_ptr; 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->max_output_ptr = comp->num_output_ptr + 4; 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (comp->output_ptr != NULL) 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charpp old_ptr; 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project old_ptr = comp->output_ptr; 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->output_ptr = (png_charpp)png_malloc(png_ptr, 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_uint_32)(comp->max_output_ptr * 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_sizeof (png_charpp))); 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_memcpy(comp->output_ptr, old_ptr, old_max 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * png_sizeof (png_charp)); 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, old_ptr); 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->output_ptr = (png_charpp)png_malloc(png_ptr, 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_uint_32)(comp->max_output_ptr * 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_sizeof (png_charp))); 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* save the data */ 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr, 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_uint_32)png_ptr->zbuf_size); 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zbuf_size); 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->num_output_ptr++; 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* and reset the buffer */ 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.next_out = png_ptr->zbuf; 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* continue until we don't have any more to compress */ 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (png_ptr->zstream.avail_in); 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* finish the compression */ 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* tell zlib we are finished */ 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = deflate(&png_ptr->zstream, Z_FINISH); 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret == Z_OK) 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* check to see if we need more room */ 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->zstream.avail_out)) 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* check to make sure our output array has room */ 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (comp->num_output_ptr >= comp->max_output_ptr) 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int old_max; 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project old_max = comp->max_output_ptr; 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->max_output_ptr = comp->num_output_ptr + 4; 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (comp->output_ptr != NULL) 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charpp old_ptr; 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project old_ptr = comp->output_ptr; 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* This could be optimized to realloc() */ 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->output_ptr = (png_charpp)png_malloc(png_ptr, 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_uint_32)(comp->max_output_ptr * 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_sizeof (png_charpp))); 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_memcpy(comp->output_ptr, old_ptr, 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project old_max * png_sizeof (png_charp)); 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, old_ptr); 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->output_ptr = (png_charpp)png_malloc(png_ptr, 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_uint_32)(comp->max_output_ptr * 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_sizeof (png_charp))); 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* save off the data */ 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->output_ptr[comp->num_output_ptr] = 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zbuf_size); 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->num_output_ptr++; 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* and reset the buffer pointers */ 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.next_out = png_ptr->zbuf; 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (ret != Z_STREAM_END) 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* we got an error */ 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->zstream.msg != NULL) 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, png_ptr->zstream.msg); 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, "zlib error"); 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (ret != Z_STREAM_END); 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* text length is number of buffers plus last buffer */ 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project text_len = png_ptr->zbuf_size * comp->num_output_ptr; 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out; 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return((int)text_len); 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* ship the compressed text out via chunk writes */ 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void /* PRIVATE */ 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_compressed_data_out(png_structp png_ptr, compression_state *comp) 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* handle the no-compression case */ 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (comp->input) 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (png_bytep)comp->input, 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_size_t)comp->input_len); 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write saved output buffers, if any */ 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < comp->num_output_ptr; i++) 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i], 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zbuf_size); 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, comp->output_ptr[i]); 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->output_ptr[i]=NULL; 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (comp->max_output_ptr != 0) 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, comp->output_ptr); 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp->output_ptr=NULL; 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write anything left in zbuf */ 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, png_ptr->zbuf, 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zbuf_size - png_ptr->zstream.avail_out); 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* reset zlib for another zTXt/iTXt or image data */ 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project deflateReset(&png_ptr->zstream); 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.data_type = Z_BINARY; 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Write the IHDR chunk, and update the png_struct with the necessary 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * information. Note that the rest of this code depends upon this 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * information being correct. 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int bit_depth, int color_type, int compression_type, int filter_type, 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int interlace_type) 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_IHDR; 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[13]; /* buffer to store the IHDR info */ 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_IHDR\n"); 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Check that we have valid input data from the application info */ 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (color_type) 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case PNG_COLOR_TYPE_GRAY: 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (bit_depth) 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 4: 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 8: 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 16: png_ptr->channels = 1; break; 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: png_error(png_ptr,"Invalid bit depth for grayscale image"); 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case PNG_COLOR_TYPE_RGB: 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bit_depth != 8 && bit_depth != 16) 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, "Invalid bit depth for RGB image"); 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->channels = 3; 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case PNG_COLOR_TYPE_PALETTE: 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (bit_depth) 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 4: 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 8: png_ptr->channels = 1; break; 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: png_error(png_ptr, "Invalid bit depth for paletted image"); 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case PNG_COLOR_TYPE_GRAY_ALPHA: 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bit_depth != 8 && bit_depth != 16) 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->channels = 2; 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case PNG_COLOR_TYPE_RGB_ALPHA: 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bit_depth != 8 && bit_depth != 16) 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, "Invalid bit depth for RGBA image"); 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->channels = 4; 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, "Invalid image color type specified"); 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (compression_type != PNG_COMPRESSION_TYPE_BASE) 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid compression type specified"); 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project compression_type = PNG_COMPRESSION_TYPE_BASE; 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Write filter_method 64 (intrapixel differencing) only if 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 2. Libpng did not write a PNG signature (this filter_method is only 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * used in PNG datastreams that are embedded in MNG datastreams) and 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 3. The application called png_permit_mng_features with a mask that 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * included PNG_FLAG_MNG_FILTER_64 and 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 4. The filter_method is 64 and 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 5. The color_type is RGB or RGBA 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_MNG_FEATURES_SUPPORTED) 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (color_type == PNG_COLOR_TYPE_RGB || 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project color_type == PNG_COLOR_TYPE_RGB_ALPHA) && 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project filter_type != PNG_FILTER_TYPE_BASE) 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid filter type specified"); 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project filter_type = PNG_FILTER_TYPE_BASE; 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_WRITE_INTERLACING_SUPPORTED 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (interlace_type != PNG_INTERLACE_NONE && 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project interlace_type != PNG_INTERLACE_ADAM7) 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid interlace type specified"); 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project interlace_type = PNG_INTERLACE_ADAM7; 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project interlace_type=PNG_INTERLACE_NONE; 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* save off the relevent information */ 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->bit_depth = (png_byte)bit_depth; 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->color_type = (png_byte)color_type; 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->interlaced = (png_byte)interlace_type; 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_MNG_FEATURES_SUPPORTED) 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->filter_type = (png_byte)filter_type; 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->compression_type = (png_byte)compression_type; 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->width = width; 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->height = height; 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* set the usr info, so any transformations can modify it */ 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->usr_width = png_ptr->width; 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->usr_bit_depth = png_ptr->bit_depth; 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->usr_channels = png_ptr->channels; 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* pack the header information into the buffer */ 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf, width); 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 4, height); 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[8] = (png_byte)bit_depth; 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[9] = (png_byte)color_type; 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[10] = (png_byte)compression_type; 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[11] = (png_byte)filter_type; 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[12] = (png_byte)interlace_type; 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write the chunk */ 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13); 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* initialize zlib with PNG info */ 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.zalloc = png_zalloc; 5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.zfree = png_zfree; 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.opaque = (voidpf)png_ptr; 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->do_filter)) 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->bit_depth < 8) 5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->do_filter = PNG_FILTER_NONE; 5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->do_filter = PNG_ALL_FILTERS; 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)) 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->do_filter != PNG_FILTER_NONE) 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zlib_strategy = Z_FILTERED; 5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY; 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL)) 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL)) 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zlib_mem_level = 8; 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS)) 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zlib_window_bits = 15; 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD)) 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zlib_method = 8; 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (deflateInit2(&png_ptr->zstream, png_ptr->zlib_level, 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zlib_method, png_ptr->zlib_window_bits, 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zlib_mem_level, png_ptr->zlib_strategy) != Z_OK) 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, "zlib failed to initialize compressor"); 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.next_out = png_ptr->zbuf; 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* libpng is not interested in zstream.data_type */ 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* set it to a predefined value, to avoid its evaluation inside zlib */ 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.data_type = Z_BINARY; 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->mode = PNG_HAVE_IHDR; 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write the palette. We are careful not to trust png_color to be in the 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * correct order for PNG, so people can redefine it to any convenient 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * structure. 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_PLTE; 5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_colorp pal_ptr; 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[3]; 5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_PLTE\n"); 5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (( 5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_MNG_FEATURES_SUPPORTED) 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && 5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project num_pal == 0) || num_pal > 256) 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, "Invalid number of colors in palette"); 5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid number of colors in palette"); 5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) 5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Ignoring request to write a PLTE chunk in grayscale PNG"); 5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->num_palette = (png_uint_16)num_pal; 5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug1(3, "num_palette = %d\n", png_ptr->num_palette); 5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_start(png_ptr, png_PLTE, num_pal * 3); 5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_NO_POINTER_INDEXING 5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = pal_ptr->red; 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[1] = pal_ptr->green; 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[2] = pal_ptr->blue; 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, buf, (png_size_t)3); 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* This is a little slower but some buggy compilers need to do this instead */ 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pal_ptr=palette; 5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < num_pal; i++) 5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = pal_ptr[i].red; 5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[1] = pal_ptr[i].green; 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[2] = pal_ptr[i].blue; 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, buf, (png_size_t)3); 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_end(png_ptr); 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->mode |= PNG_HAVE_PLTE; 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write an IDAT chunk */ 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) 6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_IDAT; 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_IDAT\n"); 6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Optimize the CMF field in the zlib stream. */ 6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* This hack of the zlib stream is compliant to the stream specification. */ 6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IDAT) && 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned int z_cmf = data[0]; /* zlib compression method and flags */ 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Avoid memory underflows and multiplication overflows. */ 6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* The conditions below are practically always satisfied; 6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project however, they still must be checked. */ 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (length >= 2 && 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->height < 16384 && png_ptr->width < 16384) 6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 uncompressed_idat_size = png_ptr->height * 6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((png_ptr->width * 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->channels * png_ptr->bit_depth + 15) >> 3); 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned int z_cinfo = z_cmf >> 4; 6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned int half_z_window_size = 1 << (z_cinfo + 7); 6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (uncompressed_idat_size <= half_z_window_size && 6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project half_z_window_size >= 256) 6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project z_cinfo--; 6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project half_z_window_size >>= 1; 6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); 6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (data[0] != (png_byte)z_cmf) 6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data[0] = (png_byte)z_cmf; 6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data[1] &= 0xe0; 6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f); 6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, 6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Invalid zlib compression method or flags in IDAT"); 6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length); 6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->mode |= PNG_HAVE_IDAT; 6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write an IEND chunk */ 6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_IEND(png_structp png_ptr) 6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_IEND; 6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_IEND\n"); 6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL, 6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_size_t)0); 6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->mode |= PNG_HAVE_IEND; 6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_gAMA_SUPPORTED) 6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write a gAMA chunk */ 6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_gAMA(png_structp png_ptr, double file_gamma) 6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_gAMA; 6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 igamma; 6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[4]; 6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_gAMA\n"); 6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* file_gamma is saved in 1/100,000ths */ 6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5); 6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf, igamma); 6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); 6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED 6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) 6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_gAMA; 6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[4]; 6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_gAMA\n"); 6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* file_gamma is saved in 1/100,000ths */ 7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf, (png_uint_32)file_gamma); 7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); 7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_sRGB_SUPPORTED) 7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write a sRGB chunk */ 7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_sRGB(png_structp png_ptr, int srgb_intent) 7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_sRGB; 7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[1]; 7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_sRGB\n"); 7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(srgb_intent >= PNG_sRGB_INTENT_LAST) 7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, 7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Invalid sRGB rendering intent specified"); 7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0]=(png_byte)srgb_intent; 7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1); 7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_iCCP_SUPPORTED) 7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write an iCCP chunk */ 7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, 7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charp profile, int profile_len) 7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_iCCP; 7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t name_len; 7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charp new_name; 7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project compression_state comp; 7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int embedded_profile_len = 0; 7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_iCCP\n"); 7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.num_output_ptr = 0; 7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.max_output_ptr = 0; 7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.output_ptr = NULL; 7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.input = NULL; 7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.input_len = 0; 7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (name == NULL || (name_len = png_check_keyword(png_ptr, name, 7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &new_name)) == 0) 7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Empty keyword in iCCP chunk"); 7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (compression_type != PNG_COMPRESSION_TYPE_BASE) 7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Unknown compression type in iCCP chunk"); 7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (profile == NULL) 7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project profile_len = 0; 7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (profile_len > 3) 7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project embedded_profile_len = 7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((*( (png_bytep)profile ))<<24) | 7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((*( (png_bytep)profile+1))<<16) | 7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((*( (png_bytep)profile+2))<< 8) | 7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((*( (png_bytep)profile+3)) ); 7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (profile_len < embedded_profile_len) 7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, 7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Embedded profile length too large in iCCP chunk"); 7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (profile_len > embedded_profile_len) 7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, 7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Truncating profile to actual length in iCCP chunk"); 7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project profile_len = embedded_profile_len; 7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (profile_len) 7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len, 7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COMPRESSION_TYPE_BASE, &comp); 7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* make sure we include the NULL after the name and the compression type */ 7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_start(png_ptr, png_iCCP, 7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_uint_32)name_len+profile_len+2); 7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_name[name_len+1]=0x00; 7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2); 7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (profile_len) 7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_compressed_data_out(png_ptr, &comp); 7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_end(png_ptr); 7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, new_name); 7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_sPLT_SUPPORTED) 8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write a sPLT chunk */ 8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) 8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_sPLT; 8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t name_len; 8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charp new_name; 8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte entrybuf[10]; 8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int entry_size = (spalette->depth == 8 ? 6 : 10); 8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int palette_size = entry_size * spalette->nentries; 8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_sPLT_entryp ep; 8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_NO_POINTER_INDEXING 8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_sPLT\n"); 8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr, 8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project spalette->name, &new_name))==0) 8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Empty keyword in sPLT chunk"); 8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* make sure we include the NULL after the name */ 8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_start(png_ptr, png_sPLT, 8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_uint_32)(name_len + 2 + palette_size)); 8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1); 8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1); 8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* loop through each palette entry, writing appropriately */ 8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_NO_POINTER_INDEXING 8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (ep = spalette->entries; ep<spalette->entries+spalette->nentries; ep++) 8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (spalette->depth == 8) 8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project entrybuf[0] = (png_byte)ep->red; 8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project entrybuf[1] = (png_byte)ep->green; 8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project entrybuf[2] = (png_byte)ep->blue; 8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project entrybuf[3] = (png_byte)ep->alpha; 8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(entrybuf + 4, ep->frequency); 8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(entrybuf + 0, ep->red); 8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(entrybuf + 2, ep->green); 8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(entrybuf + 4, ep->blue); 8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(entrybuf + 6, ep->alpha); 8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(entrybuf + 8, ep->frequency); 8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); 8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ep=spalette->entries; 8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i=0; i>spalette->nentries; i++) 8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (spalette->depth == 8) 8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project entrybuf[0] = (png_byte)ep[i].red; 8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project entrybuf[1] = (png_byte)ep[i].green; 8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project entrybuf[2] = (png_byte)ep[i].blue; 8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project entrybuf[3] = (png_byte)ep[i].alpha; 8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(entrybuf + 4, ep[i].frequency); 8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(entrybuf + 0, ep[i].red); 8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(entrybuf + 2, ep[i].green); 8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(entrybuf + 4, ep[i].blue); 8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(entrybuf + 6, ep[i].alpha); 8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(entrybuf + 8, ep[i].frequency); 8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, entrybuf, entry_size); 8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_end(png_ptr); 8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, new_name); 8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_sBIT_SUPPORTED) 8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write the sBIT chunk */ 8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) 8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_sBIT; 8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[4]; 8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t size; 8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_sBIT\n"); 8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* make sure we don't depend upon the order of PNG_COLOR_8 */ 8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (color_type & PNG_COLOR_MASK_COLOR) 8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte maxbits; 8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 : 9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->usr_bit_depth); 9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sbit->red == 0 || sbit->red > maxbits || 9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sbit->green == 0 || sbit->green > maxbits || 9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sbit->blue == 0 || sbit->blue > maxbits) 9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid sBIT depth specified"); 9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = sbit->red; 9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[1] = sbit->green; 9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[2] = sbit->blue; 9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size = 3; 9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth) 9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid sBIT depth specified"); 9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = sbit->gray; 9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size = 1; 9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (color_type & PNG_COLOR_MASK_ALPHA) 9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) 9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid sBIT depth specified"); 9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[size++] = sbit->alpha; 9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size); 9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_cHRM_SUPPORTED) 9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write the cHRM chunk */ 9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_cHRM(png_structp png_ptr, double white_x, double white_y, 9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project double red_x, double red_y, double green_x, double green_y, 9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project double blue_x, double blue_y) 9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_cHRM; 9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[32]; 9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 itemp; 9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_cHRM\n"); 9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* each value is saved in 1/100,000ths */ 9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 || 9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project white_x + white_y > 1.0) 9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid cHRM white point specified"); 9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_NO_CONSOLE_IO) 9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr,"white_x=%f, white_y=%f\n",white_x, white_y); 9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project itemp = (png_uint_32)(white_x * 100000.0 + 0.5); 9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf, itemp); 9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project itemp = (png_uint_32)(white_y * 100000.0 + 0.5); 9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 4, itemp); 9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (red_x < 0 || red_y < 0 || red_x + red_y > 1.0) 9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid cHRM red point specified"); 9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project itemp = (png_uint_32)(red_x * 100000.0 + 0.5); 9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 8, itemp); 9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project itemp = (png_uint_32)(red_y * 100000.0 + 0.5); 9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 12, itemp); 9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (green_x < 0 || green_y < 0 || green_x + green_y > 1.0) 9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid cHRM green point specified"); 9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project itemp = (png_uint_32)(green_x * 100000.0 + 0.5); 9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 16, itemp); 9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project itemp = (png_uint_32)(green_y * 100000.0 + 0.5); 9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 20, itemp); 9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (blue_x < 0 || blue_y < 0 || blue_x + blue_y > 1.0) 9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid cHRM blue point specified"); 9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project itemp = (png_uint_32)(blue_x * 100000.0 + 0.5); 9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 24, itemp); 9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project itemp = (png_uint_32)(blue_y * 100000.0 + 0.5); 9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 28, itemp); 9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); 9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED 10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, 10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, 10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, 10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_fixed_point blue_y) 10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_cHRM; 10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[32]; 10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_cHRM\n"); 10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* each value is saved in 1/100,000ths */ 10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L) 10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid fixed cHRM white point specified"); 10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_NO_CONSOLE_IO) 10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr,"white_x=%ld, white_y=%ld\n",white_x, white_y); 10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf, (png_uint_32)white_x); 10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 4, (png_uint_32)white_y); 10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (red_x + red_y > 100000L) 10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid cHRM fixed red point specified"); 10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 8, (png_uint_32)red_x); 10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 12, (png_uint_32)red_y); 10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (green_x + green_y > 100000L) 10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid fixed cHRM green point specified"); 10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 16, (png_uint_32)green_x); 10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 20, (png_uint_32)green_y); 10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (blue_x + blue_y > 100000L) 10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid fixed cHRM blue point specified"); 10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 24, (png_uint_32)blue_x); 10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 28, (png_uint_32)blue_y); 10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); 10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_tRNS_SUPPORTED) 10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write the tRNS chunk */ 10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, 10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int num_trans, int color_type) 10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_tRNS; 10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[6]; 10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_tRNS\n"); 10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (color_type == PNG_COLOR_TYPE_PALETTE) 10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) 10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr,"Invalid number of transparent colors specified"); 10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write the chunk out as it is */ 10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans, (png_size_t)num_trans); 10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (color_type == PNG_COLOR_TYPE_GRAY) 10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* one 16 bit value */ 10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(tran->gray >= (1 << png_ptr->bit_depth)) 10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, 10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); 10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(buf, tran->gray); 10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2); 10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (color_type == PNG_COLOR_TYPE_RGB) 10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* three 16 bit values */ 10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(buf, tran->red); 10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(buf + 2, tran->green); 10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(buf + 4, tran->blue); 10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) 10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, 10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); 10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6); 11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Can't write tRNS with an alpha channel"); 11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_bKGD_SUPPORTED) 11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write the background chunk */ 11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) 11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_bKGD; 11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[6]; 11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_bKGD\n"); 11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (color_type == PNG_COLOR_TYPE_PALETTE) 11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( 11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_MNG_FEATURES_SUPPORTED) 11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_ptr->num_palette || 11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && 11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project back->index > png_ptr->num_palette) 11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid background palette index"); 11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = back->index; 11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1); 11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (color_type & PNG_COLOR_MASK_COLOR) 11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(buf, back->red); 11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(buf + 2, back->green); 11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(buf + 4, back->blue); 11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) 11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, 11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); 11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6); 11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(back->gray >= (1 << png_ptr->bit_depth)) 11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, 11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); 11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(buf, back->gray); 11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2); 11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_hIST_SUPPORTED) 11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write the histogram */ 11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) 11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_hIST; 11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[3]; 11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_hIST\n"); 11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (num_hist > (int)png_ptr->num_palette) 11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist, 11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->num_palette); 11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid number of histogram entries specified"); 11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); 11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < num_hist; i++) 11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(buf, hist[i]); 11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, buf, (png_size_t)2); 11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_end(png_ptr); 11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ 11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) 11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, 11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and if invalid, correct the keyword rather than discarding the entire 11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * chunk. The PNG 1.0 specification requires keywords 1-79 characters in 11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * length, forbids leading or trailing whitespace, multiple internal spaces, 11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. 12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The new_key is allocated to hold the corrected keyword and must be freed 12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * by the calling routine. This avoids problems with trying to write to 12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * static keywords without having to have duplicate copies of the strings. 12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_size_t /* PRIVATE */ 12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) 12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t key_len; 12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charp kp, dp; 12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int kflag; 12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int kwarn=0; 12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_check_keyword\n"); 12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *new_key = NULL; 12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (key == NULL || (key_len = png_strlen(key)) == 0) 12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "zero length keyword"); 12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ((png_size_t)0); 12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug1(2, "Keyword to be checked is '%s'\n", key); 12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2)); 12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*new_key == NULL) 12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Out of memory while procesing keyword"); 12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ((png_size_t)0); 12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Replace non-printing characters with a blank and print a warning */ 12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++) 12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((png_byte)*kp < 0x20 || 12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1)) 12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) 12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char msg[40]; 12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_snprintf(msg, 40, 12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "invalid keyword character 0x%02X", (png_byte)*kp); 12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, msg); 12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "invalid character in keyword"); 12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp = ' '; 12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp = *kp; 12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp = '\0'; 12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Remove any trailing white space. */ 12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kp = *new_key + key_len - 1; 12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*kp == ' ') 12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "trailing spaces removed from keyword"); 12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (*kp == ' ') 12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(kp--) = '\0'; 12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project key_len--; 12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Remove any leading white space. */ 12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kp = *new_key; 12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*kp == ' ') 12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "leading spaces removed from keyword"); 12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (*kp == ' ') 12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kp++; 12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project key_len--; 12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp); 12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Remove multiple internal spaces. */ 12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (kflag = 0, dp = *new_key; *kp != '\0'; kp++) 12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*kp == ' ' && kflag == 0) 12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(dp++) = *kp; 12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kflag = 1; 12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (*kp == ' ') 12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project key_len--; 12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kwarn=1; 12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(dp++) = *kp; 12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kflag = 0; 13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp = '\0'; 13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(kwarn) 13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "extra interior spaces removed from keyword"); 13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (key_len == 0) 13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, *new_key); 13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *new_key=NULL; 13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Zero length keyword"); 13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (key_len > 79) 13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "keyword length must be 1 - 79 characters"); 13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_key[79] = '\0'; 13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project key_len = 79; 13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (key_len); 13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_tEXt_SUPPORTED) 13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write a tEXt chunk */ 13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, 13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t text_len) 13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_tEXt; 13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t key_len; 13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charp new_key; 13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_tEXt\n"); 13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) 13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Empty keyword in tEXt chunk"); 13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (text == NULL || *text == '\0') 13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project text_len = 0; 13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project text_len = png_strlen(text); 13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* make sure we include the 0 after the key */ 13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_start(png_ptr, (png_bytep)png_tEXt, (png_uint_32)key_len+text_len+1); 13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We leave it to the application to meet PNG-1.0 requirements on the 13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of 13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. 13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. 13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1); 13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (text_len) 13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (png_bytep)text, text_len); 13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_end(png_ptr); 13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, new_key); 13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_zTXt_SUPPORTED) 13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write a compressed text chunk */ 13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, 13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t text_len, int compression) 13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_zTXt; 13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t key_len; 13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buf[1]; 13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charp new_key; 13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project compression_state comp; 13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_zTXt\n"); 13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.num_output_ptr = 0; 13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.max_output_ptr = 0; 13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.output_ptr = NULL; 13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.input = NULL; 13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.input_len = 0; 13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) 13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Empty keyword in zTXt chunk"); 13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE) 13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_tEXt(png_ptr, new_key, text, (png_size_t)0); 13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, new_key); 13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project text_len = png_strlen(text); 14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* compute the compressed data; do it now for the length */ 14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project text_len = png_text_compress(png_ptr, text, text_len, compression, 14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &comp); 14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write start of chunk */ 14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, (png_uint_32) 14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (key_len+text_len+2)); 14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write key */ 14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1); 14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, new_key); 14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = (png_byte)compression; 14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write compression */ 14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1); 14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write the compressed data */ 14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_compressed_data_out(png_ptr, &comp); 14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* close the chunk */ 14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_end(png_ptr); 14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_iTXt_SUPPORTED) 14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write an iTXt chunk */ 14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_iTXt(png_structp png_ptr, int compression, png_charp key, 14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charp lang, png_charp lang_key, png_charp text) 14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_iTXt; 14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t lang_len, key_len, lang_key_len, text_len; 14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charp new_lang, new_key; 14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte cbuf[2]; 14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project compression_state comp; 14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_iTXt\n"); 14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.num_output_ptr = 0; 14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.max_output_ptr = 0; 14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.output_ptr = NULL; 14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project comp.input = NULL; 14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) 14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Empty keyword in iTXt chunk"); 14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0) 14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Empty language field in iTXt chunk"); 14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project new_lang = NULL; 14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lang_len = 0; 14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (lang_key == NULL) 14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lang_key_len = 0; 14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lang_key_len = png_strlen(lang_key); 14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (text == NULL) 14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project text_len = 0; 14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project text_len = png_strlen(text); 14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* compute the compressed data; do it now for the length */ 14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project text_len = png_text_compress(png_ptr, text, text_len, compression-2, 14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &comp); 14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* make sure we include the compression flag, the compression byte, 14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and the NULs after the key, lang, and lang_key parts */ 14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_start(png_ptr, (png_bytep)png_iTXt, 14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_uint_32)( 14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5 /* comp byte, comp flag, terminators for key, lang and lang_key */ 14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project + key_len 14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project + lang_len 14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project + lang_key_len 14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project + text_len)); 14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We leave it to the application to meet PNG-1.0 requirements on the 14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of 14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. 14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. 14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1); 14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* set the compression flag */ 14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (compression == PNG_ITXT_COMPRESSION_NONE || \ 14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project compression == PNG_TEXT_COMPRESSION_NONE) 14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbuf[0] = 0; 14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else /* compression == PNG_ITXT_COMPRESSION_zTXt */ 14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbuf[0] = 1; 14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* set the compression method */ 14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbuf[1] = 0; 14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, cbuf, 2); 15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cbuf[0] = 0; 15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf), lang_len + 1); 15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), lang_key_len + 1); 15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_compressed_data_out(png_ptr, &comp); 15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_end(png_ptr); 15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, new_key); 15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (new_lang) 15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, new_lang); 15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_oFFs_SUPPORTED) 15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write the oFFs chunk */ 15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, 15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int unit_type) 15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_oFFs; 15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[9]; 15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_oFFs\n"); 15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (unit_type >= PNG_OFFSET_LAST) 15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); 15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_int_32(buf, x_offset); 15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_int_32(buf + 4, y_offset); 15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[8] = (png_byte)unit_type; 15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); 15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_pCAL_SUPPORTED) 15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write the pCAL chunk (described in the PNG extensions document) */ 15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, 15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_int_32 X1, int type, int nparams, png_charp units, png_charpp params) 15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_pCAL; 15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t purpose_len, units_len, total_len; 15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32p params_len; 15468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[10]; 15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charp new_purpose; 15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams); 15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type >= PNG_EQUATION_LAST) 15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); 15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1; 15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug1(3, "pCAL purpose length = %d\n", (int)purpose_len); 15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); 15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug1(3, "pCAL units length = %d\n", (int)units_len); 15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_len = purpose_len + units_len + 10; 15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams 15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *png_sizeof(png_uint_32))); 15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Find the length of each parameter, making sure we don't count the 15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project null terminator for the last parameter. */ 15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < nparams; i++) 15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1); 15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug2(3, "pCAL parameter %d length = %lu\n", i, params_len[i]); 15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_len += (png_size_t)params_len[i]; 15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug1(3, "pCAL total length = %d\n", (int)total_len); 15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len); 15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len); 15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_int_32(buf, X0); 15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_int_32(buf + 4, X1); 15778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[8] = (png_byte)type; 15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[9] = (png_byte)nparams; 15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, buf, (png_size_t)10); 15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len); 15818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, new_purpose); 15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < nparams; i++) 15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_data(png_ptr, (png_bytep)params[i], 15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_size_t)params_len[i]); 15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_free(png_ptr, params_len); 15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk_end(png_ptr); 15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_sCAL_SUPPORTED) 15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write the sCAL chunk */ 15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) 15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_sCAL(png_structp png_ptr, int unit, double width, double height) 16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_sCAL; 16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buf[64]; 16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t total_len; 16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_sCAL\n"); 16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = (char)unit; 16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(_WIN32_WCE) 16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* sprintf() function is not supported on WindowsCE */ 16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wchar_t wc_buf[32]; 16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size_t wc_len; 16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project swprintf(wc_buf, TEXT("%12.12e"), width); 16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wc_len = wcslen(wc_buf); 16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, NULL); 16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_len = wc_len + 2; 16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project swprintf(wc_buf, TEXT("%12.12e"), height); 16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wc_len = wcslen(wc_buf); 16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len, 16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, NULL); 16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_len += wc_len; 16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_snprintf(buf + 1, 63, "%12.12e", width); 16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_len = 1 + png_strlen(buf + 1) + 1; 16288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_snprintf(buf + total_len, 64-total_len, "%12.12e", height); 16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_len += png_strlen(buf + total_len); 16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len); 16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, png_sCAL, (png_bytep)buf, total_len); 16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED 16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, 16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_charp height) 16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_sCAL; 16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[64]; 16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t wlen, hlen, total_len; 16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_sCAL_s\n"); 16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wlen = png_strlen(width); 16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hlen = png_strlen(height); 16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total_len = wlen + hlen + 2; 16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (total_len > 64) 16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Can't write sCAL (buffer too small)"); 16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = (png_byte)unit; 16598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_memcpy(buf + 1, width, wlen + 1); /* append the '\0' here */ 16608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_memcpy(buf + wlen + 2, height, hlen); /* do NOT append the '\0' here */ 16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug1(3, "sCAL total length = %u\n", (unsigned int)total_len); 16638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, png_sCAL, buf, total_len); 16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 16658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 16678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_pHYs_SUPPORTED) 16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* write the pHYs chunk */ 16718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 16728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, 16738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 y_pixels_per_unit, 16748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int unit_type) 16758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 16768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 16778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_pHYs; 16788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 16798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[9]; 16808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_pHYs\n"); 16828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (unit_type >= PNG_RESOLUTION_LAST) 16838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); 16848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf, x_pixels_per_unit); 16868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_32(buf + 4, y_pixels_per_unit); 16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[8] = (png_byte)unit_type; 16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); 16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 16928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_tIME_SUPPORTED) 16948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Write the tIME chunk. Use either png_convert_from_struct_tm() 16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * or png_convert_from_time_t(), or fill in the structure yourself. 16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_tIME(png_structp png_ptr, png_timep mod_time) 16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_tIME; 17028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 17038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte buf[7]; 17048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_tIME\n"); 17068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (mod_time->month > 12 || mod_time->month < 1 || 17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mod_time->day > 31 || mod_time->day < 1 || 17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mod_time->hour > 23 || mod_time->second > 60) 17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 17108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_warning(png_ptr, "Invalid time specified for tIME chunk"); 17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_save_uint_16(buf, mod_time->year); 17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[2] = mod_time->month; 17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[3] = mod_time->day; 17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[4] = mod_time->hour; 17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[5] = mod_time->minute; 17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[6] = mod_time->second; 17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7); 17228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 17238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 17248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* initializes the row writing capability of libpng */ 17268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_start_row(png_structp png_ptr) 17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 17308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* start of interlace block */ 17338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 17348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* offset to next interlace block */ 17368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 17378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* start of interlace block in the y direction */ 17398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 17408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* offset to next interlace block in the y direction */ 17428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 17438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 17448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t buf_size; 17468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_start_row\n"); 17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf_size = (png_size_t)(PNG_ROWBYTES( 17498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->usr_channels*png_ptr->usr_bit_depth,png_ptr->width)+1); 17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* set up row buffer */ 17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size); 17538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; 17548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_NO_WRITE_FILTERING 17568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* set up filtering buffer, if using this filter */ 17578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->do_filter & PNG_FILTER_SUB) 17588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 17598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, 17608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_ptr->rowbytes + 1)); 17618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; 17628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* We only need to keep the previous row if we are using one of these. */ 17658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) 17668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 17678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* set up previous row buffer */ 17688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size); 17698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_memset(png_ptr->prev_row, 0, buf_size); 17708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->do_filter & PNG_FILTER_UP) 17728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 17738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->up_row = (png_bytep)png_malloc(png_ptr, 17748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_ptr->rowbytes + 1)); 17758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; 17768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->do_filter & PNG_FILTER_AVG) 17798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 17808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, 17818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_ptr->rowbytes + 1)); 17828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; 17838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->do_filter & PNG_FILTER_PAETH) 17868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 17878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, 17888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_ptr->rowbytes + 1)); 17898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; 17908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_NO_WRITE_FILTERING */ 17928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 17938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 17948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_WRITE_INTERLACING_SUPPORTED 17958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if interlaced, we need to set up width and height of pass */ 17968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->interlaced) 17978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 17988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->transformations & PNG_INTERLACE)) 17998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 18008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - 18018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_pass_ystart[0]) / png_pass_yinc[0]; 18028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 - 18038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_pass_start[0]) / png_pass_inc[0]; 18048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 18068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 18078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->num_rows = png_ptr->height; 18088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->usr_width = png_ptr->width; 18098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 18128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 18138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 18148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->num_rows = png_ptr->height; 18158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->usr_width = png_ptr->width; 18168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 18188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.next_out = png_ptr->zbuf; 18198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 18208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Internal use only. Called when finished processing a row of data. */ 18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_finish_row(png_structp png_ptr) 18248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 18268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 18278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* start of interlace block */ 18298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 18308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* offset to next interlace block */ 18328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 18338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* start of interlace block in the y direction */ 18358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 18368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* offset to next interlace block in the y direction */ 18388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 18398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 18408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 18428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_finish_row\n"); 18448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* next row */ 18458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->row_number++; 18468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* see if we are done */ 18488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->row_number < png_ptr->num_rows) 18498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 18508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_WRITE_INTERLACING_SUPPORTED 18528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if interlaced, go to next pass */ 18538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->interlaced) 18548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 18558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->row_number = 0; 18568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->transformations & PNG_INTERLACE) 18578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 18588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->pass++; 18598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 18618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 18628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* loop until we find a non-zero width or height pass */ 18638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do 18648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 18658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->pass++; 18668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->pass >= 7) 18678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 18688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->usr_width = (png_ptr->width + 18698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_pass_inc[png_ptr->pass] - 1 - 18708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_pass_start[png_ptr->pass]) / 18718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_pass_inc[png_ptr->pass]; 18728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->num_rows = (png_ptr->height + 18738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_pass_yinc[png_ptr->pass] - 1 - 18748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_pass_ystart[png_ptr->pass]) / 18758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_pass_yinc[png_ptr->pass]; 18768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->transformations & PNG_INTERLACE) 18778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 18788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); 18798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* reset the row above the image for the next pass */ 18838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->pass < 7) 18848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 18858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->prev_row != NULL) 18868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_memset(png_ptr->prev_row, 0, 18878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* 18888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->usr_bit_depth,png_ptr->width))+1); 18898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 18908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 18928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 18938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 18948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if we get here, we've just written the last row, so we need 18958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project to flush the compressor */ 18968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do 18978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 18988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* tell the compressor we are done */ 18998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = deflate(&png_ptr->zstream, Z_FINISH); 19008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* check for an error */ 19018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret == Z_OK) 19028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 19038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* check to see if we need more room */ 19048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->zstream.avail_out)) 19058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 19068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); 19078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.next_out = png_ptr->zbuf; 19088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 19098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (ret != Z_STREAM_END) 19128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 19138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->zstream.msg != NULL) 19148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, png_ptr->zstream.msg); 19158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 19168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, "zlib error"); 19178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (ret != Z_STREAM_END); 19198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write any extra space */ 19218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) 19228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 19238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - 19248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.avail_out); 19258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project deflateReset(&png_ptr->zstream); 19288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.data_type = Z_BINARY; 19298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 19308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_INTERLACING_SUPPORTED) 19328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Pick out the correct pixels for the interlace pass. 19338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The basic idea here is to go through the row with a source 19348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * pointer and a destination pointer (sp and dp), and copy the 19358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * correct pixels for the pass. As the row gets compacted, 19368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * sp will always be >= dp, so we should never overwrite anything. 19378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * See the default: case for the easiest code to understand. 19388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 19398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 19408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) 19418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 19428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 19438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 19448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* start of interlace block */ 19468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 19478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* offset to next interlace block */ 19498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 19508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 19518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_do_write_interlace\n"); 19538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* we don't have to do anything on the last pass (6) */ 19548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED) 19558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (row != NULL && row_info != NULL && pass < 6) 19568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 19578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (pass < 6) 19588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 19598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 19608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* each pixel depth is handled separately */ 19618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (row_info->pixel_depth) 19628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 19638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 19648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 19658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep sp; 19668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep dp; 19678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int shift; 19688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int d; 19698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int value; 19708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 19718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 row_width = row_info->width; 19728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dp = row; 19748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project d = 0; 19758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift = 7; 19768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = png_pass_start[pass]; i < row_width; 19778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i += png_pass_inc[pass]) 19788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 19798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sp = row + (png_size_t)(i >> 3); 19808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; 19818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project d |= (value << shift); 19828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (shift == 0) 19848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 19858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift = 7; 19868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp++ = (png_byte)d; 19878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project d = 0; 19888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 19908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift--; 19918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 19928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (shift != 7) 19948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp = (png_byte)d; 19958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 19968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 19978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 19988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 19998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep sp; 20008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep dp; 20018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int shift; 20028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int d; 20038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int value; 20048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 20058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 row_width = row_info->width; 20068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dp = row; 20088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift = 6; 20098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project d = 0; 20108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = png_pass_start[pass]; i < row_width; 20118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i += png_pass_inc[pass]) 20128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 20138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sp = row + (png_size_t)(i >> 2); 20148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; 20158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project d |= (value << shift); 20168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (shift == 0) 20188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 20198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift = 6; 20208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp++ = (png_byte)d; 20218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project d = 0; 20228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 20248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift -= 2; 20258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (shift != 6) 20278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp = (png_byte)d; 20288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 20298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 4: 20318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 20328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep sp; 20338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep dp; 20348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int shift; 20358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int d; 20368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int value; 20378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 20388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 row_width = row_info->width; 20398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dp = row; 20418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift = 4; 20428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project d = 0; 20438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = png_pass_start[pass]; i < row_width; 20448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i += png_pass_inc[pass]) 20458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 20468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sp = row + (png_size_t)(i >> 1); 20478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; 20488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project d |= (value << shift); 20498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (shift == 0) 20518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 20528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift = 4; 20538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp++ = (png_byte)d; 20548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project d = 0; 20558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 20578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift -= 4; 20588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (shift != 4) 20608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp = (png_byte)d; 20618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 20628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 20648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 20658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep sp; 20668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep dp; 20678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 20688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 row_width = row_info->width; 20698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_size_t pixel_bytes; 20708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 20718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* start at the beginning */ 20728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dp = row; 20738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* find out how many bytes each pixel takes up */ 20748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pixel_bytes = (row_info->pixel_depth >> 3); 20758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* loop through the row, only looking at the pixels that 20768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project matter */ 20778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = png_pass_start[pass]; i < row_width; 20788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i += png_pass_inc[pass]) 20798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 20808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* find out where the original pixel is */ 20818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sp = row + (png_size_t)i * pixel_bytes; 20828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* move the pixel */ 20838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dp != sp) 20848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_memcpy(dp, sp, pixel_bytes); 20858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* next pixel */ 20868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dp += pixel_bytes; 20878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 20898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* set new row width */ 20928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project row_info->width = (row_info->width + 20938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_pass_inc[pass] - 1 - 20948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_pass_start[pass]) / 20958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_pass_inc[pass]; 20968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, 20978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project row_info->width); 20988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 20998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 21008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 21018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* This filters the row, chooses which filter to use, if it has not already 21038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * been specified by the application, and then writes the row out with the 21048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * chosen filter. 21058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 21068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) 21078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PNG_HISHIFT 10 21088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PNG_LOMASK ((png_uint_32)0xffffL) 21098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) 21108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 21118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_find_filter(png_structp png_ptr, png_row_infop row_info) 21128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 21138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep prev_row, best_row, row_buf; 21148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 mins, bpp; 21158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_byte filter_to_do = png_ptr->do_filter; 21168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 row_bytes = row_info->rowbytes; 21178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) 21188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int num_p_filters = (int)png_ptr->num_prev_filters; 21198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 21208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_find_filter\n"); 21228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* find out how many bytes offset each pixel is */ 21238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bpp = (row_info->pixel_depth + 7) >> 3; 21248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project prev_row = png_ptr->prev_row; 21268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project best_row = row_buf = png_ptr->row_buf; 21278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_NO_WRITE_FILTER 21288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mins = PNG_MAXSUM; 21298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* The prediction method we use is to find which method provides the 21318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * smallest value when summing the absolute values of the distances 21328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * from zero, using anything >= 128 as negative numbers. This is known 21338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * as the "minimum sum of absolute differences" heuristic. Other 21348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * heuristics are the "weighted minimum sum of absolute differences" 21358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (experimental and can in theory improve compression), and the "zlib 21368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * predictive" method (not implemented yet), which does test compressions 21378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of lines using different filter methods, and then chooses the 21388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (series of) filter(s) that give minimum compressed data size (VERY 21398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * computationally expensive). 21408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 21418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * GRR 980525: consider also 21428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (1) minimum sum of absolute differences from running average (i.e., 21438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * keep running sum of non-absolute differences & count of bytes) 21448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * [track dispersion, too? restart average if dispersion too large?] 21458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (1b) minimum sum of absolute differences from sliding average, probably 21468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * with window size <= deflate window (usually 32K) 21478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (2) minimum sum of squared differences from zero or running average 21488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (i.e., ~ root-mean-square approach) 21498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 21508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* We don't need to test the 'no filter' case if this is the only filter 21538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * that has been chosen, as it doesn't actually do anything to the data. 21548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 21558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((filter_to_do & PNG_FILTER_NONE) && 21568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project filter_to_do != PNG_FILTER_NONE) 21578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 21588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep rp; 21598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 sum = 0; 21608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 21618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int v; 21628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) 21648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 21658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v = *rp; 21668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum += (v < 128) ? v : 256 - v; 21678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 21688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) 21708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 21718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 21728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 sumhi, sumlo; 21738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int j; 21748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = sum & PNG_LOMASK; 21758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */ 21768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Reduce the sum if we match any of the previous rows */ 21788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < num_p_filters; j++) 21798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 21808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) 21818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 21828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = (sumlo * png_ptr->filter_weights[j]) >> 21838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 21848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sumhi * png_ptr->filter_weights[j]) >> 21858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 21868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 21878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 21888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Factor in the cost of this filter (this is here for completeness, 21908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but it makes no sense to have a "cost" for the NONE filter, as 21918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * it has the minimum possible computational cost - none). 21928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 21938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> 21948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 21958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> 21968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 21978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 21988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sumhi > PNG_HIMASK) 21998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = PNG_MAXSUM; 22008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 22018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = (sumhi << PNG_HISHIFT) + sumlo; 22028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 22048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mins = sum; 22058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* sub filter */ 22088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (filter_to_do == PNG_FILTER_SUB) 22098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* it's the only filter so no testing is needed */ 22108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 22118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep rp, lp, dp; 22128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 22138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; 22148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i++, rp++, dp++) 22158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 22168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp = *rp; 22178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (lp = row_buf + 1; i < row_bytes; 22198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i++, rp++, lp++, dp++) 22208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 22218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); 22228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project best_row = png_ptr->sub_row; 22248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (filter_to_do & PNG_FILTER_SUB) 22278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 22288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep rp, dp, lp; 22298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 sum = 0, lmins = mins; 22308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 22318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int v; 22328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) 22348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* We temporarily increase the "minimum sum" by the factor we 22358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * would reduce the sum of this filter, so that we can do the 22368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * early exit comparison without scaling the sum each time. 22378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 22388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 22398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 22408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int j; 22418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 lmhi, lmlo; 22428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmlo = lmins & PNG_LOMASK; 22438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; 22448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < num_p_filters; j++) 22468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 22478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) 22488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 22498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> 22508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 22518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> 22528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 22538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> 22578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 22588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> 22598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 22608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (lmhi > PNG_HIMASK) 22628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmins = PNG_MAXSUM; 22638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 22648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmins = (lmhi << PNG_HISHIFT) + lmlo; 22658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 22678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; 22698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i++, rp++, dp++) 22708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 22718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v = *dp = *rp; 22728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum += (v < 128) ? v : 256 - v; 22748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (lp = row_buf + 1; i < row_bytes; 22768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i++, rp++, lp++, dp++) 22778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 22788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); 22798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum += (v < 128) ? v : 256 - v; 22818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sum > lmins) /* We are already worse, don't continue. */ 22838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 22848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 22858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) 22878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 22888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 22898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int j; 22908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 sumhi, sumlo; 22918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = sum & PNG_LOMASK; 22928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; 22938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < num_p_filters; j++) 22958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 22968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) 22978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 22988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >> 22998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 23008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >> 23018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 23028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> 23068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 23078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> 23088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 23098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sumhi > PNG_HIMASK) 23118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = PNG_MAXSUM; 23128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 23138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = (sumhi << PNG_HISHIFT) + sumlo; 23148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 23168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sum < mins) 23188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 23198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mins = sum; 23208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project best_row = png_ptr->sub_row; 23218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* up filter */ 23258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (filter_to_do == PNG_FILTER_UP) 23268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 23278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep rp, dp, pp; 23288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 23298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, 23318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pp = prev_row + 1; i < row_bytes; 23328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i++, rp++, pp++, dp++) 23338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 23348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); 23358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project best_row = png_ptr->up_row; 23378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (filter_to_do & PNG_FILTER_UP) 23408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 23418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep rp, dp, pp; 23428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 sum = 0, lmins = mins; 23438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 23448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int v; 23458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) 23488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 23498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 23508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int j; 23518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 lmhi, lmlo; 23528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmlo = lmins & PNG_LOMASK; 23538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; 23548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < num_p_filters; j++) 23568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 23578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) 23588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 23598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> 23608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 23618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> 23628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 23638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> 23678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 23688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> 23698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 23708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (lmhi > PNG_HIMASK) 23728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmins = PNG_MAXSUM; 23738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 23748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmins = (lmhi << PNG_HISHIFT) + lmlo; 23758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 23778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, 23798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pp = prev_row + 1; i < row_bytes; i++) 23808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 23818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); 23828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum += (v < 128) ? v : 256 - v; 23848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sum > lmins) /* We are already worse, don't continue. */ 23868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 23878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 23888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) 23908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 23918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 23928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int j; 23938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 sumhi, sumlo; 23948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = sum & PNG_LOMASK; 23958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; 23968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 23978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < num_p_filters; j++) 23988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 23998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) 24008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 24018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = (sumlo * png_ptr->filter_weights[j]) >> 24028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 24038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sumhi * png_ptr->filter_weights[j]) >> 24048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 24058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> 24098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 24108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> 24118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 24128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sumhi > PNG_HIMASK) 24148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = PNG_MAXSUM; 24158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 24168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = (sumhi << PNG_HISHIFT) + sumlo; 24178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 24198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sum < mins) 24218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 24228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mins = sum; 24238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project best_row = png_ptr->up_row; 24248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* avg filter */ 24288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (filter_to_do == PNG_FILTER_AVG) 24298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 24308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep rp, dp, pp, lp; 24318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 24328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, 24338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pp = prev_row + 1; i < bpp; i++) 24348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 24358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); 24368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (lp = row_buf + 1; i < row_bytes; i++) 24388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 24398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) 24408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project & 0xff); 24418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project best_row = png_ptr->avg_row; 24438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (filter_to_do & PNG_FILTER_AVG) 24468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 24478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep rp, dp, pp, lp; 24488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 sum = 0, lmins = mins; 24498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 24508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int v; 24518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) 24538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 24548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 24558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int j; 24568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 lmhi, lmlo; 24578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmlo = lmins & PNG_LOMASK; 24588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; 24598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < num_p_filters; j++) 24618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 24628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG) 24638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 24648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> 24658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 24668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> 24678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 24688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> 24728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 24738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> 24748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 24758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (lmhi > PNG_HIMASK) 24778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmins = PNG_MAXSUM; 24788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 24798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmins = (lmhi << PNG_HISHIFT) + lmlo; 24808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 24828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, 24848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pp = prev_row + 1; i < bpp; i++) 24858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 24868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); 24878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum += (v < 128) ? v : 256 - v; 24898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 24908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (lp = row_buf + 1; i < row_bytes; i++) 24918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 24928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v = *dp++ = 24938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff); 24948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum += (v < 128) ? v : 256 - v; 24968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 24978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sum > lmins) /* We are already worse, don't continue. */ 24988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 24998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) 25028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 25038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 25048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int j; 25058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 sumhi, sumlo; 25068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = sum & PNG_LOMASK; 25078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; 25088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < num_p_filters; j++) 25108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 25118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) 25128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 25138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = (sumlo * png_ptr->filter_weights[j]) >> 25148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 25158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sumhi * png_ptr->filter_weights[j]) >> 25168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 25178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> 25218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 25228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> 25238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 25248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sumhi > PNG_HIMASK) 25268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = PNG_MAXSUM; 25278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 25288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = (sumhi << PNG_HISHIFT) + sumlo; 25298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 25318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sum < mins) 25338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 25348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mins = sum; 25358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project best_row = png_ptr->avg_row; 25368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Paeth filter */ 25408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (filter_to_do == PNG_FILTER_PAETH) 25418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 25428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep rp, dp, pp, cp, lp; 25438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 25448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, 25458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pp = prev_row + 1; i < bpp; i++) 25468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 25478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); 25488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) 25518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 25528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int a, b, c, pa, pb, pc, p; 25538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project b = *pp++; 25558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c = *cp++; 25568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a = *lp++; 25578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = b - c; 25598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pc = a - c; 25608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_ABS 25628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pa = abs(p); 25638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pb = abs(pc); 25648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pc = abs(p + pc); 25658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 25668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pa = p < 0 ? -p : p; 25678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pb = pc < 0 ? -pc : pc; 25688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pc = (p + pc) < 0 ? -(p + pc) : p + pc; 25698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 25708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; 25728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); 25748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project best_row = png_ptr->paeth_row; 25768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 25778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (filter_to_do & PNG_FILTER_PAETH) 25798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 25808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep rp, dp, pp, cp, lp; 25818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 sum = 0, lmins = mins; 25828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 i; 25838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int v; 25848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) 25868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 25878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 25888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int j; 25898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 lmhi, lmlo; 25908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmlo = lmins & PNG_LOMASK; 25918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; 25928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 25938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < num_p_filters; j++) 25948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 25958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) 25968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 25978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> 25988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 25998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> 26008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 26018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 26028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 26038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> 26058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 26068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> 26078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 26088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (lmhi > PNG_HIMASK) 26108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmins = PNG_MAXSUM; 26118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 26128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lmins = (lmhi << PNG_HISHIFT) + lmlo; 26138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 26148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 26158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, 26178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pp = prev_row + 1; i < bpp; i++) 26188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 26198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); 26208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum += (v < 128) ? v : 256 - v; 26228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 26238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++) 26258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 26268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int a, b, c, pa, pb, pc, p; 26278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project b = *pp++; 26298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project c = *cp++; 26308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a = *lp++; 26318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_SLOW_PAETH 26338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = b - c; 26348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pc = a - c; 26358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_ABS 26368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pa = abs(p); 26378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pb = abs(pc); 26388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pc = abs(p + pc); 26398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 26408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pa = p < 0 ? -p : p; 26418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pb = pc < 0 ? -pc : pc; 26428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pc = (p + pc) < 0 ? -(p + pc) : p + pc; 26438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 26448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; 26458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* PNG_SLOW_PAETH */ 26468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = a + b - c; 26478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pa = abs(p - a); 26488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pb = abs(p - b); 26498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pc = abs(p - c); 26508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (pa <= pb && pa <= pc) 26518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = a; 26528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (pb <= pc) 26538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = b; 26548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 26558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = c; 26568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_SLOW_PAETH */ 26578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); 26598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum += (v < 128) ? v : 256 - v; 26618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sum > lmins) /* We are already worse, don't continue. */ 26638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 26648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 26658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) 26678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) 26688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 26698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int j; 26708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_uint_32 sumhi, sumlo; 26718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = sum & PNG_LOMASK; 26728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; 26738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 0; j < num_p_filters; j++) 26758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 26768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) 26778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 26788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = (sumlo * png_ptr->filter_weights[j]) >> 26798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 26808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sumhi * png_ptr->filter_weights[j]) >> 26818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_WEIGHT_SHIFT; 26828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 26838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 26848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> 26868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 26878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> 26888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PNG_COST_SHIFT; 26898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sumhi > PNG_HIMASK) 26918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = PNG_MAXSUM; 26928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 26938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sum = (sumhi << PNG_HISHIFT) + sumlo; 26948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 26958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 26968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 26978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sum < mins) 26988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 26998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project best_row = png_ptr->paeth_row; 27008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 27018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 27028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_NO_WRITE_FILTER */ 27038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Do the actual writing of the filtered row data from the chosen filter. */ 27048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_filtered_row(png_ptr, best_row); 27068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) 27088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Save the type of filter we picked this time for future calculations */ 27098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->num_prev_filters > 0) 27108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 27118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int j; 27128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (j = 1; j < num_p_filters; j++) 27138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 27148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1]; 27158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 27168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->prev_filters[j] = best_row[0]; 27178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 27188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 27198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 27208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Do the actual writing of a previously filtered row. */ 27238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */ 27248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) 27258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 27268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug(1, "in png_write_filtered_row\n"); 27278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_debug1(2, "filter = %d\n", filtered_row[0]); 27288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* set up the zlib input buffer */ 27298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.next_in = filtered_row; 27318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1; 27328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* repeat until we have compressed all the data */ 27338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do 27348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 27358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; /* return of zlib */ 27368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* compress the data */ 27388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); 27398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* check for compression errors */ 27408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret != Z_OK) 27418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 27428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->zstream.msg != NULL) 27438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, png_ptr->zstream.msg); 27448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 27458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_error(png_ptr, "zlib error"); 27468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 27478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* see if it is time to write another IDAT */ 27498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!(png_ptr->zstream.avail_out)) 27508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 27518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* write the IDAT and reset the zlib output buffer */ 27528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); 27538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.next_out = png_ptr->zbuf; 27548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 27558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 27568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* repeat until all data has been compressed */ 27578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (png_ptr->zstream.avail_in); 27588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* swap the current and previous rows */ 27608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->prev_row != NULL) 27618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 27628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_bytep tptr; 27638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tptr = png_ptr->prev_row; 27658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->prev_row = png_ptr->row_buf; 27668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->row_buf = tptr; 27678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 27688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* finish row - updates counters and flushes zlib if last row */ 27708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_finish_row(png_ptr); 27718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_WRITE_FLUSH_SUPPORTED) 27738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->flush_rows++; 27748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (png_ptr->flush_dist > 0 && 27768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_ptr->flush_rows >= png_ptr->flush_dist) 27778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 27788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project png_write_flush(png_ptr); 27798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 27808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 27818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 27828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_WRITE_SUPPORTED */ 2783