1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*--------------------------------------------------------------------------- 2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wpng - simple PNG-writing program writepng.c 4893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 5893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project --------------------------------------------------------------------------- 6893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 73cc83ac4b563ffa7a1bae9572f5fc3c1ee5f8a10Leon Scroggins III Copyright (c) 1998-2007, 2017 Greg Roelofs. All rights reserved. 8893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 9893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project This software is provided "as is," without warranty of any kind, 10893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project express or implied. In no event shall the author or contributors 11893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project be held liable for any damages arising in any way from the use of 12893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project this software. 13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 14893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project The contents of this file are DUAL-LICENSED. You may modify and/or 15893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project redistribute this software according to the terms of one of the 16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project following two licenses (at your option): 17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 18893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 19893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project LICENSE 1 ("BSD-like with advertising clause"): 20893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 21893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Permission is granted to anyone to use this software for any purpose, 22893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project including commercial applications, and to alter it and redistribute 23893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project it freely, subject to the following restrictions: 24893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 25893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1. Redistributions of source code must retain the above copyright 26893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project notice, disclaimer, and this list of conditions. 27893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2. Redistributions in binary form must reproduce the above copyright 28893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project notice, disclaimer, and this list of conditions in the documenta- 29893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project tion and/or other materials provided with the distribution. 30893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3. All advertising materials mentioning features or use of this 31893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project software must display the following acknowledgment: 32893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 33893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project This product includes software developed by Greg Roelofs 34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project and contributors for the book, "PNG: The Definitive Guide," 35893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project published by O'Reilly and Associates. 36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 37893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 38893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project LICENSE 2 (GNU GPL v2 or later): 39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project This program is free software; you can redistribute it and/or modify 41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project it under the terms of the GNU General Public License as published by 42893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project the Free Software Foundation; either version 2 of the License, or 43893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (at your option) any later version. 44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project This program is distributed in the hope that it will be useful, 46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project but WITHOUT ANY WARRANTY; without even the implied warranty of 47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 48893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project GNU General Public License for more details. 49893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 50893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project You should have received a copy of the GNU General Public License 51893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project along with this program; if not, write to the Free Software Foundation, 52893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 53893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 54893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ---------------------------------------------------------------------------*/ 55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 56893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdlib.h> /* for exit() prototype */ 58ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#include <zlib.h> 59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 60ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#include "png.h" /* libpng header, includes setjmp.h */ 61893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "writepng.h" /* typedefs, common macros, public prototypes */ 62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 63893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 64893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* local prototype */ 65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void writepng_error_handler(png_structp png_ptr, png_const_charp msg); 67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid writepng_version_info(void) 71893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n", 73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_LIBPNG_VER_STRING, png_libpng_ver); 74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n", 75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ZLIB_VERSION, zlib_version); 76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 77893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* returns 0 for success, 2 for libpng problem, 4 for out of memory, 11 for 82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * unexpected pnmtype; note that outfile might be stdout */ 83893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 84893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint writepng_init(mainprog_info *mainprog_ptr) 85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_structp png_ptr; /* note: temporary variables! */ 87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_infop info_ptr; 88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int color_type, interlace_type; 89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 91893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* could also replace libpng warning-handler (final NULL), but no need: */ 92893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 939b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett png_ptr = png_create_write_struct(png_get_libpng_ver(NULL), mainprog_ptr, 94893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project writepng_error_handler, NULL); 95893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!png_ptr) 96893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 4; /* out of memory */ 97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 98893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr = png_create_info_struct(png_ptr); 99893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!info_ptr) { 100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_destroy_write_struct(&png_ptr, NULL); 101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 4; /* out of memory */ 102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* setjmp() must be called in every function that calls a PNG-writing 106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * libpng function, unless an alternate error handler was installed-- 107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * but compatible error handlers must either use longjmp() themselves 108ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik * (as in this program) or some other method to return control to 109ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik * application code, so here we go: */ 110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (setjmp(mainprog_ptr->jmpbuf)) { 112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_destroy_write_struct(&png_ptr, &info_ptr); 113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 2; 114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* make sure outfile is (re)opened in BINARY mode */ 118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_init_io(png_ptr, mainprog_ptr->outfile); 120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* set the compression levels--in general, always want to leave filtering 123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * turned on (except for palette images) and allow all of the filters, 124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * which is the default; want 32K zlib window, unless entire image buffer 125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * is 16K or smaller (unknown here)--also the default; usually want max 126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * compression (NOT the default); and remaining compression flags should 127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * be left alone */ 128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); 130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* 131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project >> this is default for no filtering; Z_FILTERED is default otherwise: 132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY); 133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project >> these are all defaults: 134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_compression_mem_level(png_ptr, 8); 135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_compression_window_bits(png_ptr, 15); 136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_compression_method(png_ptr, 8); 137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* set the image parameters appropriately */ 141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mainprog_ptr->pnmtype == 5) 143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project color_type = PNG_COLOR_TYPE_GRAY; 144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (mainprog_ptr->pnmtype == 6) 145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project color_type = PNG_COLOR_TYPE_RGB; 146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (mainprog_ptr->pnmtype == 8) 147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project color_type = PNG_COLOR_TYPE_RGB_ALPHA; 148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else { 149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_destroy_write_struct(&png_ptr, &info_ptr); 150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 11; 151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project interlace_type = mainprog_ptr->interlaced? PNG_INTERLACE_ADAM7 : 154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_INTERLACE_NONE; 155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_IHDR(png_ptr, info_ptr, mainprog_ptr->width, mainprog_ptr->height, 157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mainprog_ptr->sample_depth, color_type, interlace_type, 158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); 159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mainprog_ptr->gamma > 0.0) 161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_gAMA(png_ptr, info_ptr, mainprog_ptr->gamma); 162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mainprog_ptr->have_bg) { /* we know it's RGBA, not gray+alpha */ 164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_color_16 background; 165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project background.red = mainprog_ptr->bg_red; 167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project background.green = mainprog_ptr->bg_green; 168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project background.blue = mainprog_ptr->bg_blue; 169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_bKGD(png_ptr, info_ptr, &background); 170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mainprog_ptr->have_time) { 173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_time modtime; 174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_convert_from_time_t(&modtime, mainprog_ptr->modtime); 176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_tIME(png_ptr, info_ptr, &modtime); 177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mainprog_ptr->have_text) { 180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_text text[6]; 181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int num_text = 0; 182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mainprog_ptr->have_text & TEXT_TITLE) { 184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].key = "Title"; 186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].text = mainprog_ptr->title; 187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++num_text; 188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mainprog_ptr->have_text & TEXT_AUTHOR) { 190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].key = "Author"; 192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].text = mainprog_ptr->author; 193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++num_text; 194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mainprog_ptr->have_text & TEXT_DESC) { 196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].key = "Description"; 198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].text = mainprog_ptr->desc; 199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++num_text; 200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mainprog_ptr->have_text & TEXT_COPY) { 202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].key = "Copyright"; 204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].text = mainprog_ptr->copyright; 205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++num_text; 206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mainprog_ptr->have_text & TEXT_EMAIL) { 208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].key = "E-mail"; 210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].text = mainprog_ptr->email; 211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++num_text; 212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mainprog_ptr->have_text & TEXT_URL) { 214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; 215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].key = "URL"; 216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text[num_text].text = mainprog_ptr->url; 217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++num_text; 218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_text(png_ptr, info_ptr, text, num_text); 220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* write all chunks up to (but not including) first IDAT */ 224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_write_info(png_ptr, info_ptr); 226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* if we wanted to write any more text info *after* the image data, we 229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * would set up text struct(s) here and call png_set_text() again, with 230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * just the new data; png_set_tIME() could also go here, but it would 231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * have no effect since we already called it above (only one tIME chunk 232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * allowed) */ 233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* set up the transformations: for now, just pack low-bit-depth pixels 236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * into bytes (one, two or four pixels per byte) */ 237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_packing(png_ptr); 239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* png_set_shift(png_ptr, &sig_bit); to scale low-bit-depth values */ 240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* make sure we save our pointers for use in writepng_encode_image() */ 243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mainprog_ptr->png_ptr = png_ptr; 245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mainprog_ptr->info_ptr = info_ptr; 246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* OK, that's all we need to do for now; return happy */ 249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 0; 251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* returns 0 for success, 2 for libpng (longjmp) problem */ 258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint writepng_encode_image(mainprog_info *mainprog_ptr) 260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; 262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; 263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* as always, setjmp() must be called in every function that calls a 266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * PNG-writing libpng function */ 267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (setjmp(mainprog_ptr->jmpbuf)) { 269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_destroy_write_struct(&png_ptr, &info_ptr); 270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mainprog_ptr->png_ptr = NULL; 271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mainprog_ptr->info_ptr = NULL; 272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 2; 273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* and now we just write the whole image; libpng takes care of interlacing 277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * for us */ 278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_write_image(png_ptr, mainprog_ptr->row_pointers); 280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* since that's it, we also close out the end of the PNG file now--if we 283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * had any text or time info to write after the IDATs, second argument 284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * would be info_ptr, but we optimize slightly by sending NULL pointer: */ 285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_write_end(png_ptr, NULL); 287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 0; 289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* returns 0 if succeeds, 2 if libpng problem */ 296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint writepng_encode_row(mainprog_info *mainprog_ptr) /* NON-interlaced only! */ 298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; 300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; 301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* as always, setjmp() must be called in every function that calls a 304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * PNG-writing libpng function */ 305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (setjmp(mainprog_ptr->jmpbuf)) { 307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_destroy_write_struct(&png_ptr, &info_ptr); 308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mainprog_ptr->png_ptr = NULL; 309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mainprog_ptr->info_ptr = NULL; 310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 2; 311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* image_data points at our one row of image data */ 315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_write_row(png_ptr, mainprog_ptr->image_data); 317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 0; 319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* returns 0 if succeeds, 2 if libpng problem */ 326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint writepng_encode_finish(mainprog_info *mainprog_ptr) /* NON-interlaced! */ 328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; 330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; 331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* as always, setjmp() must be called in every function that calls a 334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * PNG-writing libpng function */ 335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (setjmp(mainprog_ptr->jmpbuf)) { 337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_destroy_write_struct(&png_ptr, &info_ptr); 338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mainprog_ptr->png_ptr = NULL; 339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mainprog_ptr->info_ptr = NULL; 340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 2; 341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* close out PNG file; if we had any text or time info to write after 345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the IDATs, second argument would be info_ptr: */ 346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_write_end(png_ptr, NULL); 348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return 0; 350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid writepng_cleanup(mainprog_info *mainprog_ptr) 357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; 359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; 360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr && info_ptr) 362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_destroy_write_struct(&png_ptr, &info_ptr); 363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void writepng_error_handler(png_structp png_ptr, png_const_charp msg) 370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mainprog_info *mainprog_ptr; 372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* This function, aside from the extra step of retrieving the "error 374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * pointer" (below) and the fact that it exists within the application 375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * rather than within libpng, is essentially identical to libpng's 376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * default error handler. The second point is critical: since both 377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * setjmp() and longjmp() are called from the same code, they are 378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * guaranteed to have compatible notions of how big a jmp_buf is, 379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * regardless of whether _BSD_SOURCE or anything else has (or has not) 380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * been defined. */ 381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, "writepng libpng error: %s\n", msg); 383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fflush(stderr); 384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mainprog_ptr = png_get_error_ptr(png_ptr); 386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mainprog_ptr == NULL) { /* we are completely hosed now */ 387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fprintf(stderr, 388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "writepng severe error: jmpbuf not recoverable; terminating.\n"); 389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project fflush(stderr); 390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project exit(99); 391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 393ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik /* Now we have our data structure we can use the information in it 394ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik * to return control to our own higher level code (all the points 395ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik * where 'setjmp' is called in this file.) This will work with other 396ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik * error handling mechanisms as well - libpng always calls png_error 397ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik * when it can proceed no further, thus, so long as the error handler 398ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik * is intercepted, application code can do its own error recovery. 399ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik */ 400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project longjmp(mainprog_ptr->jmpbuf, 1); 401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 402