1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*---------------------------------------------------------------------------
2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   rpng2 - progressive-model PNG display program                 readpng2.c
4893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
5893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ---------------------------------------------------------------------------
6893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
7893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      Copyright (c) 1998-2007 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 */
58893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "png.h"        /* libpng header; includes zlib.h and setjmp.h */
60893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "readpng2.h"   /* typedefs, common macros, public prototypes */
61893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
63893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* local prototypes */
64893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr);
66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,
67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                 png_uint_32 row_num, int pass);
68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr);
69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void readpng2_error_handler(png_structp png_ptr, png_const_charp msg);
70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
71893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid readpng2_version_info(void)
75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
77893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__)) && \
78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /*
80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * WARNING:  This preprocessor approach means that the following code
81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *           cannot be used with a libpng DLL older than 1.2.0--the
82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *           compiled-in symbols for the new functions will not exist.
83893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *           (Could use dlopen() and dlsym() on Unix and corresponding
84893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *           calls for Windows, but not portable...)
85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     */
86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int mmxsupport = png_mmx_support();
88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (mmxsupport < 0)
89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr, "   Compiled with libpng %s; using libpng %s "
90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              "without MMX support.\n", PNG_LIBPNG_VER_STRING, png_libpng_ver);
91893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        else {
92893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int compilerID;
93893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 mmx_mask = png_get_mmx_flagmask(
94893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              PNG_SELECT_READ | PNG_SELECT_WRITE, &compilerID);
95893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
96893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr, "   Compiled with libpng %s; using libpng %s "
97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              "with MMX support\n   (%s version).", PNG_LIBPNG_VER_STRING,
98893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_libpng_ver, compilerID == 1? "MSVC++" :
99893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              (compilerID == 2? "GNU C" : "unknown"));
100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr, "  Processor (x86%s) %s MMX instructions.\n",
101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(__x86_64__)
102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              "_64",
103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              "",
105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              mmxsupport? "supports" : "does not support");
107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (mmxsupport > 0) {
108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                int num_optims = 0;
109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                fprintf(stderr,
111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  "      Potential MMX optimizations supported by libpng:\n");
112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (mmx_mask & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)
113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++num_optims;
114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (mmx_mask & PNG_ASM_FLAG_MMX_READ_FILTER_UP)
115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++num_optims;
116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (mmx_mask & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)
117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++num_optims;
118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (mmx_mask & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)
119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++num_optims;
120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (num_optims)
121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr,
122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      "         decoding %s row filters (reading)\n",
123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      (num_optims == 4)? "all non-trivial" : "some");
124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (mmx_mask & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) {
125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, "         combining rows (reading)\n");
126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++num_optims;
127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (mmx_mask & PNG_ASM_FLAG_MMX_READ_INTERLACE) {
129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr,
130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      "         expanding interlacing (reading)\n");
131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++num_optims;
132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                mmx_mask &= ~( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | PNG_ASM_FLAG_MMX_READ_INTERLACE    \
135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | PNG_ASM_FLAG_MMX_READ_FILTER_UP    \
137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (mmx_mask) {
140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, "         other (unknown)\n");
141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    ++num_optims;
142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                }
143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                if (num_optims == 0)
144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    fprintf(stderr, "         (none)\n");
145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf(stderr, "   Compiled with libpng %s; using libpng %s "
150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      "without MMX support.\n", PNG_LIBPNG_VER_STRING, png_libpng_ver);
151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf(stderr, "   Compiled with zlib %s; using zlib %s.\n",
154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      ZLIB_VERSION, zlib_version);
155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint readpng2_check_sig(uch *sig, int num)
161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1625f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott    return !png_sig_cmp(sig, 0, num);
163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* returns 0 for success, 2 for libpng problem, 4 for out of memory */
169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint readpng2_init(mainprog_info *mainprog_ptr)
171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_structp  png_ptr;       /* note:  temporary variables! */
173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_infop  info_ptr;
174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* could also replace libpng warning-handler (final NULL), but no need: */
177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      readpng2_error_handler, NULL);
180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!png_ptr)
181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 4;   /* out of memory */
182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    info_ptr = png_create_info_struct(png_ptr);
184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!info_ptr) {
185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_destroy_read_struct(&png_ptr, NULL, NULL);
186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 4;   /* out of memory */
187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* we could create a second info struct here (end_info), but it's only
191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * useful if we want to keep pre- and post-IDAT chunk info separated
192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * (mainly for PNG-aware image editors and converters) */
193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* setjmp() must be called in every function that calls a PNG-reading
196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * libpng function, unless an alternate error handler was installed--
197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * but compatible error handlers must either use longjmp() themselves
198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * (as in this program) or exit immediately, so here we are: */
199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (setjmp(mainprog_ptr->jmpbuf)) {
201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 2;
203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* prepare the reader to ignore all recognized chunks whose data won't be
208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * used, i.e., all chunks recognized by libpng except for IHDR, PLTE, IDAT,
209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * IEND, tRNS, bKGD, gAMA, and sRGB (small performance improvement) */
210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* These byte strings were copied from png.h.  If a future libpng
212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * version recognizes more chunks, add them to this list.  If a
213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * future version of readpng2.c recognizes more chunks, delete them
214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * from this list. */
215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        static const png_byte chunks_to_ignore[] = {
216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             99,  72,  82,  77, '\0',  /* cHRM */
217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            104,  73,  83,  84, '\0',  /* hIST */
218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            105,  67,  67,  80, '\0',  /* iCCP */
219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            105,  84,  88, 116, '\0',  /* iTXt */
220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            111,  70,  70, 115, '\0',  /* oFFs */
221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            112,  67,  65,  76, '\0',  /* pCAL */
222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            112,  72,  89, 115, '\0',  /* pHYs */
223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            115,  66,  73,  84, '\0',  /* sBIT */
224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            115,  67,  65,  76, '\0',  /* sCAL */
225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            115,  80,  76,  84, '\0',  /* sPLT */
226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            115,  84,  69,  82, '\0',  /* sTER */
227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            116,  69,  88, 116, '\0',  /* tEXt */
228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            116,  73,  77,  69, '\0',  /* tIME */
229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            122,  84,  88, 116, '\0'   /* zTXt */
230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        };
231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_set_keep_unknown_chunks(png_ptr, 1 /* PNG_HANDLE_CHUNK_NEVER */,
233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          chunks_to_ignore, sizeof(chunks_to_ignore)/5);
234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_UNKNOWN_CHUNKS_SUPPORTED */
236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* instead of doing png_init_io() here, now we set up our callback
239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * functions for progressive decoding */
240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_set_progressive_read_fn(png_ptr, mainprog_ptr,
242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      readpng2_info_callback, readpng2_row_callback, readpng2_end_callback);
243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /*
246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * may as well enable or disable MMX routines here, if supported;
247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *
248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * to enable all:  mask = png_get_mmx_flagmask (
249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *                   PNG_SELECT_READ | PNG_SELECT_WRITE, &compilerID);
250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *                 flags = png_get_asm_flags (png_ptr);
251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *                 flags |= mask;
252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *                 png_set_asm_flags (png_ptr, flags);
253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *
254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * to disable all:  mask = png_get_mmx_flagmask (
255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *                   PNG_SELECT_READ | PNG_SELECT_WRITE, &compilerID);
256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *                  flags = png_get_asm_flags (png_ptr);
257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *                  flags &= ~mask;
258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *                  png_set_asm_flags (png_ptr, flags);
259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     */
260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__)) && \
262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /*
264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * WARNING:  This preprocessor approach means that the following code
265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *           cannot be used with a libpng DLL older than 1.2.0--the
266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *           compiled-in symbols for the new functions will not exist.
267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *           (Could use dlopen() and dlsym() on Unix and corresponding
268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     *           calls for Windows, but not portable...)
269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     */
270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_uint_32 mmx_disable_mask = 0;
273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_uint_32 asm_flags, mmx_mask;
274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        int compilerID;
275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (mainprog_ptr->nommxfilters)
277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                | PNG_ASM_FLAG_MMX_READ_FILTER_UP    \
279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (mainprog_ptr->nommxcombine)
282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            mmx_disable_mask |= PNG_ASM_FLAG_MMX_READ_COMBINE_ROW;
283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (mainprog_ptr->nommxinterlace)
284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            mmx_disable_mask |= PNG_ASM_FLAG_MMX_READ_INTERLACE;
285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        asm_flags = png_get_asm_flags(png_ptr);
286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask);
287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* Now query libpng's asm settings, just for yuks.  Note that this
290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * differs from the querying of its *potential* MMX capabilities
291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * in readpng2_version_info(); this is true runtime verification. */
292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        asm_flags = png_get_asm_flags(png_ptr);
294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        mmx_mask = png_get_mmx_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE,
295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          &compilerID);
296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_COMPILED)
297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr,
298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              "  MMX support (%s version) is compiled into libpng\n",
299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              compilerID == 1? "MSVC++" :
300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              (compilerID == 2? "GNU C" : "unknown"));
301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        else
302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr, "  MMX support is not compiled into libpng\n");
303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "  MMX instructions are %ssupported by CPU\n",
304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU)? "" : "not ");
305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "  MMX read support for combining rows is %sabled\n",
306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)? "en" : "dis");
307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr,
308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "  MMX read support for expanding interlacing is %sabled\n",
309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE)? "en" : "dis");
310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "  MMX read support for \"sub\" filter is %sabled\n",
311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "en" : "dis");
312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "  MMX read support for \"up\" filter is %sabled\n",
313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "en" : "dis");
314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "  MMX read support for \"avg\" filter is %sabled\n",
315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "en" : "dis");
316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "  MMX read support for \"Paeth\" filter is %sabled\n",
317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "en" : "dis");
318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        asm_flags &= (mmx_mask & ~( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  | PNG_ASM_FLAG_MMX_READ_INTERLACE    \
320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  | PNG_ASM_FLAG_MMX_READ_FILTER_UP    \
322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ));
324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (asm_flags)
325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf(stderr,
326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              "  additional MMX support is also enabled (0x%02lx)\n",
327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              asm_flags);
328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else  /* !PNG_ASSEMBLER_CODE_SUPPORTED */
329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr, "  MMX querying is disabled in libpng.\n");
330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* make sure we save our pointers for use in readpng2_decode_data() */
336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_ptr->png_ptr = png_ptr;
338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_ptr->info_ptr = info_ptr;
339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* and that's all there is to initialization */
342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return 0;
344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* returns 0 for success, 2 for libpng (longjmp) problem */
350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length)
352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* setjmp() must be called in every function that calls a PNG-reading
358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * libpng function */
359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (setjmp(mainprog_ptr->jmpbuf)) {
361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        mainprog_ptr->png_ptr = NULL;
363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        mainprog_ptr->info_ptr = NULL;
364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return 2;
365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* hand off the next chunk of input data to libpng for decoding */
369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_process_data(png_ptr, info_ptr, rawbuf, length);
371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return 0;
373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr)
379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_info  *mainprog_ptr;
381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    int  color_type, bit_depth;
3825f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott    png_uint_32 width, height;
383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    double  gamma;
384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* setjmp() doesn't make sense here, because we'd either have to exit(),
387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * longjmp() ourselves, or return control to libpng, which doesn't want
388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * to see us again.  By not doing anything here, libpng will instead jump
389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * to readpng2_decode_data(), which can return an error value to the main
390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * program. */
391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* retrieve the pointer to our special-purpose struct, using the png_ptr
394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * that libpng passed back to us (i.e., not a global this time--there's
395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * no real difference for a single image, but for a multithreaded browser
396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * decoding several PNG images at the same time, one needs to avoid mixing
397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * up different images' structs) */
398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_ptr = png_get_progressive_ptr(png_ptr);
400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (mainprog_ptr == NULL) {         /* we be hosed */
402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr,
403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "readpng2 error:  main struct not recoverable in info_callback.\n");
404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fflush(stderr);
405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return;
406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /*
407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * Alternatively, we could call our error-handler just like libpng
408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * does, which would effectively terminate the program.  Since this
409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * can only happen if png_ptr gets redirected somewhere odd or the
410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * main PNG struct gets wiped, we're probably toast anyway.  (If
411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * png_ptr itself is NULL, we would not have been called.)
412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         */
413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* this is just like in the non-progressive case */
417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4185f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
4195f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott       NULL, NULL, NULL);
4205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott    mainprog_ptr->width = (ulg)width;
4215f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott    mainprog_ptr->height = (ulg)height;
422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* since we know we've read all of the PNG file's "header" (i.e., up
425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * to IDAT), we can check for a background color here */
426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (mainprog_ptr->need_bgcolor &&
428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD))
429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_color_16p pBackground;
431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* it is not obvious from the libpng documentation, but this function
433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * takes a pointer to a pointer, and it always returns valid red,
434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * green and blue values, regardless of color_type: */
435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_get_bKGD(png_ptr, info_ptr, &pBackground);
436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        /* however, it always returns the raw bKGD data, regardless of any
438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         * bit-depth transformations, so check depth and adjust if necessary */
439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (bit_depth == 16) {
440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            mainprog_ptr->bg_red   = pBackground->red   >> 8;
441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            mainprog_ptr->bg_green = pBackground->green >> 8;
442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            mainprog_ptr->bg_blue  = pBackground->blue  >> 8;
443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (bit_depth == 1)
445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                mainprog_ptr->bg_red = mainprog_ptr->bg_green =
446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  mainprog_ptr->bg_blue = pBackground->gray? 255 : 0;
447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else if (bit_depth == 2)
448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                mainprog_ptr->bg_red = mainprog_ptr->bg_green =
449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  mainprog_ptr->bg_blue = (255/3) * pBackground->gray;
450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* bit_depth == 4 */
451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                mainprog_ptr->bg_red = mainprog_ptr->bg_green =
452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  mainprog_ptr->bg_blue = (255/15) * pBackground->gray;
453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        } else {
454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            mainprog_ptr->bg_red   = (uch)pBackground->red;
455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            mainprog_ptr->bg_green = (uch)pBackground->green;
456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            mainprog_ptr->bg_blue  = (uch)pBackground->blue;
457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* as before, let libpng expand palette images to RGB, low-bit-depth
462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * grayscale images to 8 bits, transparency chunks to full alpha channel;
463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * strip 16-bit-per-sample images to 8 bits per sample; and convert
464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * grayscale to RGB[A] */
465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (color_type == PNG_COLOR_TYPE_PALETTE)
467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_set_expand(png_ptr);
468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_set_expand(png_ptr);
470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_set_expand(png_ptr);
472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (bit_depth == 16)
473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_set_strip_16(png_ptr);
474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (color_type == PNG_COLOR_TYPE_GRAY ||
475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_set_gray_to_rgb(png_ptr);
477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* Unlike the basic viewer, which was designed to operate on local files,
480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * this program is intended to simulate a web browser--even though we
481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * actually read from a local file, too.  But because we are pretending
482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * that most of the images originate on the Internet, we follow the recom-
483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * mendation of the sRGB proposal and treat unlabelled images (no gAMA
484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * chunk) as existing in the sRGB color space.  That is, we assume that
485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * such images have a file gamma of 0.45455, which corresponds to a PC-like
486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * display system.  This change in assumptions will have no effect on a
487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * PC-like system, but on a Mac, SGI, NeXT or other system with a non-
488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * identity lookup table, it will darken unlabelled images, which effec-
489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * tively favors images from PC-like systems over those originating on
490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the local platform.  Note that mainprog_ptr->display_exponent is the
491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * "gamma" value for the entire display system, i.e., the product of
492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * LUT_exponent and CRT_exponent. */
493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (png_get_gAMA(png_ptr, info_ptr, &gamma))
495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_set_gamma(png_ptr, mainprog_ptr->display_exponent, gamma);
496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else
497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_set_gamma(png_ptr, mainprog_ptr->display_exponent, 0.45455);
498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* we'll let libpng expand interlaced images, too */
501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_ptr->passes = png_set_interlace_handling(png_ptr);
503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* all transformations have been registered; now update info_ptr data and
506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * then get rowbytes and channels */
507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_read_update_info(png_ptr, info_ptr);
509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_ptr->rowbytes = (int)png_get_rowbytes(png_ptr, info_ptr);
511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_ptr->channels = png_get_channels(png_ptr, info_ptr);
512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* Call the main program to allocate memory for the image buffer and
515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * initialize windows and whatnot.  (The old-style function-pointer
516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * invocation is used for compatibility with a few supposedly ANSI
517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * compilers that nevertheless barf on "fn_ptr()"-style syntax.) */
518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    (*mainprog_ptr->mainprog_init)();
520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* and that takes care of initialization */
523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return;
525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void readpng2_row_callback(png_structp png_ptr, png_bytep new_row,
532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  png_uint_32 row_num, int pass)
533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_info  *mainprog_ptr;
535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* first check whether the row differs from the previous pass; if not,
538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * nothing to combine or display */
539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!new_row)
541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return;
542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* retrieve the pointer to our special-purpose struct so we can access
545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * the old rows and image-display callback function */
546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_ptr = png_get_progressive_ptr(png_ptr);
548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* save the pass number for optional use by the front end */
551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_ptr->pass = pass;
553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* have libpng either combine the new row data with the existing row data
556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * from previous passes (if interlaced) or else just copy the new row
557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * into the main program's image buffer */
558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_progressive_combine_row(png_ptr, mainprog_ptr->row_pointers[row_num],
560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      new_row);
561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* finally, call the display routine in the main program with the number
564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * of the row we just updated */
565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    (*mainprog_ptr->mainprog_display_row)(row_num);
567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* and we're ready for more */
570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return;
572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr)
579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_info  *mainprog_ptr;
581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* retrieve the pointer to our special-purpose struct */
584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_ptr = png_get_progressive_ptr(png_ptr);
586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* let the main program know that it should flush any buffered image
589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * data to the display now and set a "done" flag or whatever, but note
590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * that it SHOULD NOT DESTROY THE PNG STRUCTS YET--in other words, do
591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * NOT call readpng2_cleanup() either here or in the finish_display()
592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * routine; wait until control returns to the main program via
593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * readpng2_decode_data() */
594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    (*mainprog_ptr->mainprog_finish_display)();
596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* all done */
599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return;
601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid readpng2_cleanup(mainprog_info *mainprog_ptr)
608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (png_ptr && info_ptr)
613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_ptr->png_ptr = NULL;
616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_ptr->info_ptr = NULL;
617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic void readpng2_error_handler(png_structp png_ptr, png_const_charp msg)
624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_info  *mainprog_ptr;
626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    /* This function, aside from the extra step of retrieving the "error
628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * pointer" (below) and the fact that it exists within the application
629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * rather than within libpng, is essentially identical to libpng's
630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * default error handler.  The second point is critical:  since both
631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * setjmp() and longjmp() are called from the same code, they are
632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * guaranteed to have compatible notions of how big a jmp_buf is,
633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * regardless of whether _BSD_SOURCE or anything else has (or has not)
634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     * been defined. */
635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf(stderr, "readpng2 libpng error: %s\n", msg);
637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fflush(stderr);
638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    mainprog_ptr = png_get_error_ptr(png_ptr);
640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (mainprog_ptr == NULL) {         /* we are completely hosed now */
641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf(stderr,
642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          "readpng2 severe error:  jmpbuf not recoverable; terminating.\n");
643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fflush(stderr);
644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit(99);
645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    longjmp(mainprog_ptr->jmpbuf, 1);
648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
649