15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* pngwrite.c - general routines to write a PNG file 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Last changed in libpng 1.2.45 [July 7, 2011] 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 1998-2011 Glenn Randers-Pehrson 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This code is released under the libpng license. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For conditions of distribution and use, see the disclaimer 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and license in png.h 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Get internal access to png.h */ 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PNG_INTERNAL 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PNG_NO_PEDANTIC_WARNINGS 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "png.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_SUPPORTED 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Writes all the PNG information. This is the suggested way to use the 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * library. If you have a new chunk to add, make a function to write it, 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and put it in the correct location here. If you want the chunk written 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * after the image data, put it in png_write_end(). I strongly encourage 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the chunk, as that will keep the code from breaking if you want to just 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * write a plain PNG file. If you have long comments, I suggest writing 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * them in png_write_end(), and compressing them. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_write_info_before_PLTE"); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL || info_ptr == NULL) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write PNG signature */ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_sig(png_ptr); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_MNG_FEATURES_SUPPORTED 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \ 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->mng_features_permitted)) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->mng_features_permitted = 0; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write IHDR information. */ 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->filter_type, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_INTERLACING_SUPPORTED 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->interlace_type); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The rest of these check to see if the valid field has the appropriate 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * flag set, and if it does, writes the chunk. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_gAMA_SUPPORTED 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_gAMA) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ifdef PNG_FLOATING_POINT_SUPPORTED 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_gAMA(png_ptr, info_ptr->gamma); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_FIXED_POINT_SUPPORTED 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# endif 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_sRGB_SUPPORTED 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_sRGB) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_iCCP_SUPPORTED 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_iCCP) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_sBIT_SUPPORTED 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_sBIT) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_cHRM_SUPPORTED 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_cHRM) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_FLOATING_POINT_SUPPORTED 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_cHRM(png_ptr, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->x_white, info_ptr->y_white, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->x_red, info_ptr->y_red, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->x_green, info_ptr->y_green, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->x_blue, info_ptr->y_blue); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ifdef PNG_FIXED_POINT_SUPPORTED 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_cHRM_fixed(png_ptr, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->int_x_white, info_ptr->int_y_white, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->int_x_red, info_ptr->int_y_red, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->int_x_green, info_ptr->int_y_green, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->int_x_blue, info_ptr->int_y_blue); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# endif 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->unknown_chunks_num) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_unknown_chunk *up; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(5, "writing extra chunks"); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (up = info_ptr->unknown_chunks; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) up++) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int keep = png_handle_as_unknown(png_ptr, up->name); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (keep != PNG_HANDLE_CHUNK_NEVER && 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) up->location && !(up->location & PNG_HAVE_PLTE) && 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !(up->location & PNG_HAVE_IDAT) && 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (up->size == 0) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Writing zero-length unknown chunk"); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_chunk(png_ptr, up->name, up->data, up->size); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_write_info(png_structp png_ptr, png_infop info_ptr) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_write_info"); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL || info_ptr == NULL) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_info_before_PLTE(png_ptr, info_ptr); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_PLTE) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_PLTE(png_ptr, info_ptr->palette, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)info_ptr->num_palette); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, "Valid palette required for paletted images"); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_tRNS_SUPPORTED 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_tRNS) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Invert the alpha channel (in tRNS) */ 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->transformations & PNG_INVERT_ALPHA) && 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0; j<(int)info_ptr->num_trans; j++) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values), 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->num_trans, info_ptr->color_type); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_bKGD_SUPPORTED 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_bKGD) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_hIST_SUPPORTED 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_hIST) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_oFFs_SUPPORTED 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_oFFs) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->offset_unit_type); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_pCAL_SUPPORTED 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_pCAL) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->pcal_units, info_ptr->pcal_params); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_sCAL_SUPPORTED 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_sCAL) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_sCAL_SUPPORTED 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_sCAL(png_ptr, (int)info_ptr->scal_unit, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->scal_pixel_width, info_ptr->scal_pixel_height); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* !FLOATING_POINT */ 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_FIXED_POINT_SUPPORTED 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->scal_s_width, info_ptr->scal_s_height); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* FIXED_POINT */ 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* FLOATING_POINT */ 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* !WRITE_sCAL */ 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "png_write_sCAL not supported; sCAL chunk not written."); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* WRITE_sCAL */ 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* sCAL */ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_pHYs_SUPPORTED 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_pHYs) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* pHYs */ 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_tIME_SUPPORTED 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_tIME) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_tIME(png_ptr, &(info_ptr->mod_time)); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->mode |= PNG_WROTE_tIME; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* tIME */ 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_sPLT_SUPPORTED 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_sPLT) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* sPLT */ 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_TEXT_SUPPORTED 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check to see if we need to write text chunks */ 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < info_ptr->num_text; i++) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug2(2, "Writing header text chunk %d, type %d", i, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].compression); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* An internationalized chunk? */ 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->text[i].compression > 0) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_iTXt_SUPPORTED 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write international chunk */ 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_iTXt(png_ptr, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].compression, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].key, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].lang, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].lang_key, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].text); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Unable to write international text"); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Mark this chunk as written */ 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If we want a compressed text chunk */ 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_zTXt_SUPPORTED 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write compressed chunk */ 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_zTXt(png_ptr, info_ptr->text[i].key, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].text, 0, 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].compression); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Unable to write compressed text"); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Mark this chunk as written */ 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_tEXt_SUPPORTED 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write uncompressed chunk */ 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_tEXt(png_ptr, info_ptr->text[i].key, 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].text, 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Mark this chunk as written */ 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Can't get here */ 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Unable to write uncompressed text"); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* tEXt */ 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->unknown_chunks_num) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_unknown_chunk *up; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(5, "writing extra chunks"); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (up = info_ptr->unknown_chunks; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) up++) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int keep = png_handle_as_unknown(png_ptr, up->name); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (keep != PNG_HANDLE_CHUNK_NEVER && 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) up->location && (up->location & PNG_HAVE_PLTE) && 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !(up->location & PNG_HAVE_IDAT) && 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !(up->location & PNG_AFTER_IDAT) && 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_chunk(png_ptr, up->name, up->data, up->size); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Writes the end of the PNG file. If you don't want to write comments or 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * time information, you can pass NULL for info. If you already wrote these 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in png_write_info(), do not write them again here. If you have long 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * comments, I suggest writing them here, and compressing them. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_write_end(png_structp png_ptr, png_infop info_ptr) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_write_end"); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(png_ptr->mode & PNG_HAVE_IDAT)) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, "No IDATs written into file"); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* See if user wants us to write information chunks */ 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr != NULL) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_TEXT_SUPPORTED 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; /* local index variable */ 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_tIME_SUPPORTED 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check to see if user has supplied a time chunk */ 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((info_ptr->valid & PNG_INFO_tIME) && 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !(png_ptr->mode & PNG_WROTE_tIME)) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_tIME(png_ptr, &(info_ptr->mod_time)); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_TEXT_SUPPORTED 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Loop through comment chunks */ 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < info_ptr->num_text; i++) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug2(2, "Writing trailer text chunk %d, type %d", i, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].compression); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* An internationalized chunk? */ 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->text[i].compression > 0) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_iTXt_SUPPORTED 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write international chunk */ 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_iTXt(png_ptr, 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].compression, 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].key, 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].lang, 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].lang_key, 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].text); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Unable to write international text"); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Mark this chunk as written */ 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_zTXt_SUPPORTED 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write compressed chunk */ 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_zTXt(png_ptr, info_ptr->text[i].key, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].text, 0, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].compression); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Unable to write compressed text"); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Mark this chunk as written */ 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_tEXt_SUPPORTED 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write uncompressed chunk */ 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_tEXt(png_ptr, info_ptr->text[i].key, 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].text, 0); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Unable to write uncompressed text"); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Mark this chunk as written */ 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->unknown_chunks_num) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_unknown_chunk *up; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(5, "writing extra chunks"); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (up = info_ptr->unknown_chunks; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) up++) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int keep = png_handle_as_unknown(png_ptr, up->name); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (keep != PNG_HANDLE_CHUNK_NEVER && 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) up->location && (up->location & PNG_AFTER_IDAT) && 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_chunk(png_ptr, up->name, up->data, up->size); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->mode |= PNG_AFTER_IDAT; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write end of PNG file */ 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_IEND(png_ptr); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and restored again in libpng-1.2.30, may cause some applications that 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * do not set png_ptr->output_flush_fn to crash. If your application 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * experiences a problem, please try building libpng with 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * png-mng-implement at lists.sf.net . 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_FLUSH_SUPPORTED 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_flush(png_ptr); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# endif 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_CONVERT_tIME_SUPPORTED 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* "tm" structure is not supported on WindowsCE */ 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_convert_from_struct_tm"); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptime->year = (png_uint_16)(1900 + ttime->tm_year); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptime->month = (png_byte)(ttime->tm_mon + 1); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptime->day = (png_byte)ttime->tm_mday; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptime->hour = (png_byte)ttime->tm_hour; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptime->minute = (png_byte)ttime->tm_min; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptime->second = (png_byte)ttime->tm_sec; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_convert_from_time_t(png_timep ptime, time_t ttime) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct tm *tbuf; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_convert_from_time_t"); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tbuf = gmtime(&ttime); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_convert_from_struct_tm(ptime, tbuf); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Initialize png_ptr structure, and allocate any memory needed */ 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_structp PNGAPI 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr, 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error_ptr error_fn, png_error_ptr warn_fn) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_MEM_SUPPORTED 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL)); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Alternate initialize png_ptr structure, and allocate any memory needed */ 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_structp PNGAPI 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_malloc_ptr malloc_fn, png_free_ptr free_fn) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_USER_MEM_SUPPORTED */ 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_SETJMP_SUPPORTED 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) volatile 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_structp png_ptr; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_SETJMP_SUPPORTED 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef USE_FAR_KEYWORD 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jmp_buf jmpbuf; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_create_write_struct"); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_MEM_SUPPORTED 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_USER_MEM_SUPPORTED */ 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Added at libpng-1.2.6 */ 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_SET_USER_LIMITS_SUPPORTED 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->user_width_max = PNG_USER_WIDTH_MAX; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_SETJMP_SUPPORTED 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef USE_FAR_KEYWORD 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (setjmp(jmpbuf)) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (setjmp(png_ptr->jmpbuf)) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->zbuf); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zbuf = NULL; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_MEM_SUPPORTED 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_destroy_struct_2((png_voidp)png_ptr, 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_free_ptr)free_fn, (png_voidp)mem_ptr); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_destroy_struct((png_voidp)png_ptr); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef USE_FAR_KEYWORD 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf)); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_MEM_SUPPORTED 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_USER_MEM_SUPPORTED */ 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (user_png_ver) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = 0; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (user_png_ver[i] != png_libpng_ver[i]) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (png_libpng_ver[i++]); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we must recompile any applications that use any older library version. 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For versions after libpng 1.0, we will be compatible, so we need 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * only check the first digit. 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (user_png_ver[0] == '0' && user_png_ver[2] < '9')) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char msg[80]; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (user_png_ver) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_snprintf(msg, 80, 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Application was compiled with png.h from libpng-%.20s", 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_png_ver); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, msg); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_snprintf(msg, 80, 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Application is running with png.c from libpng-%.20s", 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_libpng_ver); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, msg); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_ERROR_NUMBERS_SUPPORTED 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags = 0; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Incompatible libpng version in application and library"); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize zbuf - compression buffer */ 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zbuf_size = PNG_ZBUF_SIZE; 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)png_ptr->zbuf_size); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL, 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_flush_ptr_NULL); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT, 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, png_doublep_NULL, png_doublep_NULL); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_SETJMP_SUPPORTED 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Applications that neglect to set up their own setjmp() and then 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * encounter a png_error() will longjmp here. Since the jmpbuf is 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * then meaningless we abort instead of returning. 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef USE_FAR_KEYWORD 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (setjmp(jmpbuf)) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PNG_ABORT(); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf)); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (setjmp(png_ptr->jmpbuf)) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PNG_ABORT(); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (png_ptr); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Initialize png_ptr structure, and allocate any memory needed */ 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_1_0_X) || defined(PNG_1_2_X) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Deprecated. */ 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef png_write_init 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_write_init(png_structp png_ptr) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We only come here via pre-1.0.7-compiled applications */ 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver, 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_size_t png_struct_size, png_size_t png_info_size) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We only come here via pre-1.0.12-compiled applications */ 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) return; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_sizeof(png_struct) > png_struct_size || 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_sizeof(png_info) > png_info_size) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char msg[80]; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->warning_fn = NULL; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (user_png_ver) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_snprintf(msg, 80, 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Application was compiled with png.h from libpng-%.20s", 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_png_ver); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, msg); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_snprintf(msg, 80, 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Application is running with png.c from libpng-%.20s", 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_libpng_ver); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, msg); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_sizeof(png_struct) > png_struct_size) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->error_fn = NULL; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_ERROR_NUMBERS_SUPPORTED 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags = 0; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The png struct allocated by the application for writing is" 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " too small."); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_sizeof(png_info) > png_info_size) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->error_fn = NULL; 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_ERROR_NUMBERS_SUPPORTED 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags = 0; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The info struct allocated by the application for writing is" 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " too small."); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_init_3(&png_ptr, user_png_ver, png_struct_size); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_1_0_X || PNG_1_2_X */ 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_size_t png_struct_size) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_structp png_ptr = *ptr_ptr; 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_SETJMP_SUPPORTED 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jmp_buf tmp_jmp; /* to save current jump buffer */ 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i = 0; 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (user_png_ver[i] != png_libpng_ver[i]) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_LEGACY_SUPPORTED 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->warning_fn = NULL; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Application uses deprecated png_write_init() and should be recompiled."); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (png_libpng_ver[i++]); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_write_init_3"); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_SETJMP_SUPPORTED 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Save jump buffer and error functions */ 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf)); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_sizeof(png_struct) > png_struct_size) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_destroy_struct(png_ptr); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ptr_ptr = png_ptr; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Reset all variables to 0 */ 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memset(png_ptr, 0, png_sizeof(png_struct)); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Added at libpng-1.2.6 */ 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_SET_USER_LIMITS_SUPPORTED 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->user_width_max = PNG_USER_WIDTH_MAX; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_SETJMP_SUPPORTED 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Restore jump buffer */ 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf)); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL, 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_flush_ptr_NULL); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize zbuf - compression buffer */ 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zbuf_size = PNG_ZBUF_SIZE; 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)png_ptr->zbuf_size); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT, 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, png_doublep_NULL, png_doublep_NULL); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Write a few rows of image data. If the image is interlaced, 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * either you will have to write the 7 sub images, or, if you 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * have called png_set_interlace_handling(), you will have to 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "write" the image seven times. 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_write_rows(png_structp png_ptr, png_bytepp row, 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 num_rows) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; /* row counter */ 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytepp rp; /* row pointer */ 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_write_rows"); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Loop through the rows */ 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, rp = row; i < num_rows; i++, rp++) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_row(png_ptr, *rp); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Write the image. You only need to call this function once, even 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if you are writing an interlaced image. 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_write_image(png_structp png_ptr, png_bytepp image) 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_uint_32 i; /* row index */ 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pass, num_pass; /* pass variables */ 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_bytepp rp; /* points to current row */ 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_write_image"); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_INTERLACING_SUPPORTED 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize interlace handling. If image is not interlaced, 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this will set pass to 1 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_pass = png_set_interlace_handling(png_ptr); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_pass = 1; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Loop through passes */ 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (pass = 0; pass < num_pass; pass++) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Loop through image */ 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, rp = image; i < png_ptr->height; i++, rp++) 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_row(png_ptr, *rp); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Called by user to write a row of image data */ 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_write_row(png_structp png_ptr, png_bytep row) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug2(1, "in png_write_row (row %ld, pass %d)", 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_number, png_ptr->pass); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Initialize transformations and other stuff if first time */ 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->row_number == 0 && png_ptr->pass == 0) 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Make sure we wrote the header info */ 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "png_write_info was never called before png_write_row."); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check for transforms that have been set but were defined out */ 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_INVERT_MONO) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "PNG_WRITE_INVERT_SUPPORTED is not defined."); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_FILLER) 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "PNG_WRITE_FILLER_SUPPORTED is not defined."); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defined(PNG_READ_PACKSWAP_SUPPORTED) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_PACKSWAP) 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "PNG_WRITE_PACKSWAP_SUPPORTED is not defined."); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_PACK) 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined."); 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_SHIFT) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined."); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_BGR) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined."); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations & PNG_SWAP_BYTES) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined."); 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_start_row(png_ptr); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_INTERLACING_SUPPORTED 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If interlaced and not interested in row, return */ 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (png_ptr->pass) 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0: 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->row_number & 0x07) 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_finish_row(png_ptr); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_finish_row(png_ptr); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->row_number & 0x07) != 4) 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_finish_row(png_ptr); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_finish_row(png_ptr); 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->row_number & 0x03) != 2) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_finish_row(png_ptr); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 5: 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_finish_row(png_ptr); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 6: 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(png_ptr->row_number & 0x01)) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_finish_row(png_ptr); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Set up row info for transformations */ 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.color_type = png_ptr->color_type; 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.width = png_ptr->usr_width; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.channels = png_ptr->usr_channels; 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth; 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.channels); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.width); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type); 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug1(3, "row_info->width = %lu", png_ptr->row_info.width); 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug1(3, "row_info->bit_depth = %d", png_ptr->row_info.bit_depth); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug1(3, "row_info->pixel_depth = %d", png_ptr->row_info.pixel_depth); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug1(3, "row_info->rowbytes = %lu", png_ptr->row_info.rowbytes); 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Copy user's row into buffer, leaving room for filter byte. */ 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row, 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_info.rowbytes); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_INTERLACING_SUPPORTED 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Handle interlacing */ 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->interlaced && png_ptr->pass < 6 && 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->transformations & PNG_INTERLACE)) 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_write_interlace(&(png_ptr->row_info), 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->row_buf + 1, png_ptr->pass); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This should always get caught above, but still ... */ 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(png_ptr->row_info.width)) 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_finish_row(png_ptr); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Handle other transformations */ 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->transformations) 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_write_transformations(png_ptr); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_MNG_FEATURES_SUPPORTED 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write filter_method 64 (intrapixel differencing) only if 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2. Libpng did not write a PNG signature (this filter_method is only 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * used in PNG datastreams that are embedded in MNG datastreams) and 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3. The application called png_permit_mng_features with a mask that 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * included PNG_FLAG_MNG_FILTER_64 and 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4. The filter_method is 64 and 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5. The color_type is RGB or RGBA 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Intrapixel differencing */ 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Find a filter if necessary, filter the row and write it out. */ 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_find_filter(png_ptr, &(png_ptr->row_info)); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->write_row_fn != NULL) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_FLUSH_SUPPORTED 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Set the automatic flush interval or 0 to turn flushing off */ 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_flush(png_structp png_ptr, int nrows) 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_flush"); 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Flush the current output buffers now */ 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_write_flush(png_structp png_ptr) 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int wrote_IDAT; 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_write_flush"); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We have already written out all of the data */ 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->row_number >= png_ptr->num_rows) 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Compress the data */ 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH); 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wrote_IDAT = 0; 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check for compression errors */ 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret != Z_OK) 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->zstream.msg != NULL) 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, png_ptr->zstream.msg); 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, "zlib error"); 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(png_ptr->zstream.avail_out)) 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write the IDAT and reset the zlib output buffer */ 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_IDAT(png_ptr, png_ptr->zbuf, 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zbuf_size); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zstream.next_out = png_ptr->zbuf; 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wrote_IDAT = 1; 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while(wrote_IDAT == 1); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If there is any data left to be output, write it into a new IDAT */ 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->zbuf_size != png_ptr->zstream.avail_out) 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write the IDAT and reset the zlib output buffer */ 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_IDAT(png_ptr, png_ptr->zbuf, 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zbuf_size - png_ptr->zstream.avail_out); 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zstream.next_out = png_ptr->zbuf; 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flush_rows = 0; 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_flush(png_ptr); 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_WRITE_FLUSH_SUPPORTED */ 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Free all memory used by the write */ 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_structp png_ptr = NULL; 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_infop info_ptr = NULL; 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_MEM_SUPPORTED 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free_ptr free_fn = NULL; 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_voidp mem_ptr = NULL; 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_destroy_write_struct"); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr_ptr != NULL) 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr = *png_ptr_ptr; 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_MEM_SUPPORTED 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free_fn = png_ptr->free_fn; 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mem_ptr = png_ptr->mem_ptr; 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_MEM_SUPPORTED 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr != NULL) 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free_fn = png_ptr->free_fn; 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mem_ptr = png_ptr->mem_ptr; 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr_ptr != NULL) 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_ptr = *info_ptr_ptr; 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr != NULL) 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr != NULL) 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->num_chunk_list) 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->chunk_list); 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->chunk_list = NULL; 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->num_chunk_list = 0; 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_MEM_SUPPORTED 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_voidp)mem_ptr); 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_destroy_struct((png_voidp)info_ptr); 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *info_ptr_ptr = NULL; 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr != NULL) 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_destroy(png_ptr); 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_MEM_SUPPORTED 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_voidp)mem_ptr); 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_destroy_struct((png_voidp)png_ptr); 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *png_ptr_ptr = NULL; 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Free any memory used in png_ptr struct (old method) */ 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void /* PRIVATE */ 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_write_destroy(png_structp png_ptr) 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_SETJMP_SUPPORTED 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jmp_buf tmp_jmp; /* Save jump buffer */ 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error_ptr error_fn; 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error_ptr warning_fn; 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_voidp error_ptr; 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_MEM_SUPPORTED 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free_ptr free_fn; 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_write_destroy"); 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Free any memory zlib uses */ 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deflateEnd(&png_ptr->zstream); 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Free our memory. png_free checks NULL for us. */ 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->zbuf); 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->row_buf); 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_FILTER_SUPPORTED 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->prev_row); 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->sub_row); 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->up_row); 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->avg_row); 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->paeth_row); 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_TIME_RFC1123_SUPPORTED 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->time_buffer); 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->prev_filters); 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->filter_weights); 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->inv_filter_weights); 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->filter_costs); 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_free(png_ptr, png_ptr->inv_filter_costs); 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_SETJMP_SUPPORTED 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Reset structure */ 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf)); 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_fn = png_ptr->error_fn; 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) warning_fn = png_ptr->warning_fn; 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ptr = png_ptr->error_ptr; 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_MEM_SUPPORTED 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free_fn = png_ptr->free_fn; 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memset(png_ptr, 0, png_sizeof(png_struct)); 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->error_fn = error_fn; 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->warning_fn = warning_fn; 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->error_ptr = error_ptr; 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_USER_MEM_SUPPORTED 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->free_fn = free_fn; 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_SETJMP_SUPPORTED 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf)); 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Allow the application to select one or more row filters to use. */ 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_filter(png_structp png_ptr, int method, int filters) 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_filter"); 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_MNG_FEATURES_SUPPORTED 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (method == PNG_INTRAPIXEL_DIFFERENCING)) 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method = PNG_FILTER_TYPE_BASE; 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (method == PNG_FILTER_TYPE_BASE) 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (filters & (PNG_ALL_FILTERS | 0x07)) 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_FILTER_SUPPORTED 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 5: 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 6: 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 7: png_warning(png_ptr, "Unknown row filter for method 0"); 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_WRITE_FILTER_SUPPORTED */ 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_FILTER_VALUE_NONE: 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->do_filter = PNG_FILTER_NONE; break; 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_FILTER_SUPPORTED 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_FILTER_VALUE_SUB: 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->do_filter = PNG_FILTER_SUB; break; 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_FILTER_VALUE_UP: 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->do_filter = PNG_FILTER_UP; break; 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_FILTER_VALUE_AVG: 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->do_filter = PNG_FILTER_AVG; break; 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PNG_FILTER_VALUE_PAETH: 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->do_filter = PNG_FILTER_PAETH; break; 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: png_ptr->do_filter = (png_byte)filters; break; 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: png_warning(png_ptr, "Unknown row filter for method 0"); 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_WRITE_FILTER_SUPPORTED */ 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If we have allocated the row_buf, this means we have already started 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * with the image and we should have allocated all of the filter buffers 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * that have been selected. If prev_row isn't already allocated, then 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it is too late to start using the filters that need it, since we 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * will be missing the data in the previous row. If an application 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * wants to start and stop using particular filters during compression, 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it should start out with all of the filters, and then add and 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * remove them after the start of compression. 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->row_buf != NULL) 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_FILTER_SUPPORTED 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->rowbytes + 1)); 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL) 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->prev_row == NULL) 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Can't add Up filter after starting"); 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->do_filter &= ~PNG_FILTER_UP; 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->up_row = (png_bytep)png_malloc(png_ptr, 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->rowbytes + 1)); 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL) 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->prev_row == NULL) 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Can't add Average filter after starting"); 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->do_filter &= ~PNG_FILTER_AVG; 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->rowbytes + 1)); 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((png_ptr->do_filter & PNG_FILTER_PAETH) && 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->paeth_row == NULL) 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->prev_row == NULL) 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Can't add Paeth filter after starting"); 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH); 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_ptr->rowbytes + 1)); 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->do_filter == PNG_NO_FILTERS) 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_WRITE_FILTER_SUPPORTED */ 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->do_filter = PNG_FILTER_NONE; 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_error(png_ptr, "Unknown custom filter method"); 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This allows us to influence the way in which libpng chooses the "best" 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * filter for the current scanline. While the "minimum-sum-of-absolute- 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * differences metric is relatively fast and effective, there is some 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * question as to whether it can be improved upon by trying to keep the 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * filtered data going to zlib more consistent, hopefully resulting in 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * better compression. 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_weights, png_doublep filter_weights, 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_doublep filter_costs) 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_filter_heuristics"); 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST) 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Unknown filter heuristic method"); 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT) 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_weights < 0 || filter_weights == NULL || 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_weights = 0; 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->num_prev_filters = (png_byte)num_weights; 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->heuristic_method = (png_byte)heuristic_method; 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_weights > 0) 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->prev_filters == NULL) 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(png_sizeof(png_byte) * num_weights)); 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* To make sure that the weighting starts out fairly */ 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_weights; i++) 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->prev_filters[i] = 255; 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->filter_weights == NULL) 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_weights; i++) 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->inv_filter_weights[i] = 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_weights; i++) 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (filter_weights[i] < 0.0) 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->inv_filter_weights[i] = 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->inv_filter_weights[i] = 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5); 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->filter_weights[i] = 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5); 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If, in the future, there are other filter methods, this would 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * need to be based on png_ptr->filter. 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr->filter_costs == NULL) 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->inv_filter_costs[i] = 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->filter_costs[i] = PNG_COST_FACTOR; 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Here is where we set the relative costs of the different filters. We 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * should take the desired compression level into account when setting 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the costs, so that Paeth, for instance, has a high relative cost at low 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * compression levels, while it has a lower relative cost at higher 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * compression settings. The filter types are in order of increasing 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * relative cost, so it would be possible to do this with an algorithm. 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (filter_costs == NULL || filter_costs[i] < 0.0) 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->inv_filter_costs[i] = 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->filter_costs[i] = PNG_COST_FACTOR; 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (filter_costs[i] >= 1.0) 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->inv_filter_costs[i] = 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5); 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->filter_costs[i] = 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5); 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_compression_level(png_structp png_ptr, int level) 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_compression_level"); 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zlib_level = level; 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_compression_mem_level(png_structp png_ptr, int mem_level) 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_compression_mem_level"); 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zlib_mem_level = mem_level; 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_compression_strategy(png_structp png_ptr, int strategy) 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_compression_strategy"); 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zlib_strategy = strategy; 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_compression_window_bits(png_structp png_ptr, int window_bits) 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_bits > 15) 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (window_bits < 8) 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef WBITS_8_OK 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Avoid libpng bug with 256-byte windows */ 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_bits == 8) 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Compression window is being reset to 512"); 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_bits = 9; 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zlib_window_bits = window_bits; 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_compression_method(png_structp png_ptr, int method) 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_compression_method"); 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (method != 8) 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_warning(png_ptr, "Only compression method 8 is supported by PNG"); 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->zlib_method = method; 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->write_row_fn = write_row_fn; 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_user_transform_fn) 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_debug(1, "in png_set_write_user_transform_fn"); 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL) 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->transformations |= PNG_USER_TRANSFORM; 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_ptr->write_user_transform_fn = write_user_transform_fn; 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_INFO_IMAGE_SUPPORTED 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PNGAPI 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)png_write_png(png_structp png_ptr, png_infop info_ptr, 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int transforms, voidp params) 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (png_ptr == NULL || info_ptr == NULL) 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write the file header information. */ 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_info(png_ptr, info_ptr); 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ------ these transformations don't touch the info structure ------- */ 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_INVERT_SUPPORTED 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Invert monochrome pixels */ 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transforms & PNG_TRANSFORM_INVERT_MONO) 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_invert_mono(png_ptr); 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_SHIFT_SUPPORTED 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Shift the pixels up to a legal bit depth and fill in 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * as appropriate to correctly scale the image. 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((transforms & PNG_TRANSFORM_SHIFT) 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (info_ptr->valid & PNG_INFO_sBIT)) 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_shift(png_ptr, &info_ptr->sig_bit); 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_PACK_SUPPORTED 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Pack pixels into bytes */ 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transforms & PNG_TRANSFORM_PACKING) 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_packing(png_ptr); 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Swap location of alpha bytes from ARGB to RGBA */ 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transforms & PNG_TRANSFORM_SWAP_ALPHA) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_swap_alpha(png_ptr); 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_FILLER_SUPPORTED 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Pack XRGB/RGBX/ARGB/RGBA into * RGB (4 channels -> 3 channels) */ 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_BGR_SUPPORTED 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Flip BGR pixels to RGB */ 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transforms & PNG_TRANSFORM_BGR) 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_bgr(png_ptr); 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_SWAP_SUPPORTED 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Swap bytes of 16-bit files to most significant byte first */ 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_swap(png_ptr); 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_PACKSWAP_SUPPORTED 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Swap bits of 1, 2, 4 bit packed pixel formats */ 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transforms & PNG_TRANSFORM_PACKSWAP) 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_packswap(png_ptr); 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Invert the alpha channel from opacity to transparency */ 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transforms & PNG_TRANSFORM_INVERT_ALPHA) 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_set_invert_alpha(png_ptr); 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ----------------------- end of transformations ------------------- */ 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Write the bits */ 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info_ptr->valid & PNG_INFO_IDAT) 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_image(png_ptr, info_ptr->row_pointers); 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* It is REQUIRED to call this to finish writing the rest of the file */ 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) png_write_end(png_ptr, info_ptr); 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transforms = transforms; /* Quiet compiler warnings */ 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params = params; 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* PNG_WRITE_SUPPORTED */ 1594