671242f350d172e106580348e24bab66b0d7e6a5vboxsync/*---------------------------------------------------------------------------
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync rpng - simple PNG display program readpng.c
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync ---------------------------------------------------------------------------
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync Copyright (c) 1998-2000 Greg Roelofs. All rights reserved.
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync This software is provided "as is," without warranty of any kind,
671242f350d172e106580348e24bab66b0d7e6a5vboxsync express or implied. In no event shall the author or contributors
671242f350d172e106580348e24bab66b0d7e6a5vboxsync be held liable for any damages arising in any way from the use of
671242f350d172e106580348e24bab66b0d7e6a5vboxsync this software.
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync Permission is granted to anyone to use this software for any purpose,
671242f350d172e106580348e24bab66b0d7e6a5vboxsync including commercial applications, and to alter it and redistribute
671242f350d172e106580348e24bab66b0d7e6a5vboxsync it freely, subject to the following restrictions:
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync 1. Redistributions of source code must retain the above copyright
671242f350d172e106580348e24bab66b0d7e6a5vboxsync notice, disclaimer, and this list of conditions.
671242f350d172e106580348e24bab66b0d7e6a5vboxsync 2. Redistributions in binary form must reproduce the above copyright
671242f350d172e106580348e24bab66b0d7e6a5vboxsync notice, disclaimer, and this list of conditions in the documenta-
671242f350d172e106580348e24bab66b0d7e6a5vboxsync tion and/or other materials provided with the distribution.
671242f350d172e106580348e24bab66b0d7e6a5vboxsync 3. All advertising materials mentioning features or use of this
671242f350d172e106580348e24bab66b0d7e6a5vboxsync software must display the following acknowledgment:
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync This product includes software developed by Greg Roelofs
671242f350d172e106580348e24bab66b0d7e6a5vboxsync and contributors for the book, "PNG: The Definitive Guide,"
671242f350d172e106580348e24bab66b0d7e6a5vboxsync published by O'Reilly and Associates.
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync ---------------------------------------------------------------------------*/
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync#include <stdio.h>
671242f350d172e106580348e24bab66b0d7e6a5vboxsync#include <stdlib.h>
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync#include "png.h" /* libpng header; includes zlib.h */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync#include "readpng.h" /* typedefs, common macros, public prototypes */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync/* future versions of libpng will provide this macro: */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync#ifndef png_jmpbuf
671242f350d172e106580348e24bab66b0d7e6a5vboxsync# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync#endif
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsyncstatic png_structp png_ptr = NULL;
671242f350d172e106580348e24bab66b0d7e6a5vboxsyncstatic png_infop info_ptr = NULL;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsyncpng_uint_32 width, height;
671242f350d172e106580348e24bab66b0d7e6a5vboxsyncint bit_depth, color_type;
671242f350d172e106580348e24bab66b0d7e6a5vboxsyncuch *image_data = NULL;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsyncvoid readpng_version_info(void)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync{
671242f350d172e106580348e24bab66b0d7e6a5vboxsync fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n",
671242f350d172e106580348e24bab66b0d7e6a5vboxsync PNG_LIBPNG_VER_STRING, png_libpng_ver);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n",
671242f350d172e106580348e24bab66b0d7e6a5vboxsync ZLIB_VERSION, zlib_version);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync}
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync/* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsyncint readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync{
671242f350d172e106580348e24bab66b0d7e6a5vboxsync uch sig[8];
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* first do a quick check that the file really is a PNG image; could
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * have used slightly more general png_sig_cmp() function instead */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync fread(sig, 1, 8, infile);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (!png_check_sig(sig, 8))
671242f350d172e106580348e24bab66b0d7e6a5vboxsync return 1; /* bad signature */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* could pass pointers to user-defined error handlers instead of NULLs: */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (!png_ptr)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync return 4; /* out of memory */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync info_ptr = png_create_info_struct(png_ptr);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (!info_ptr) {
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_destroy_read_struct(&png_ptr, NULL, NULL);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync return 4; /* out of memory */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync }
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* we could create a second info struct here (end_info), but it's only
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * useful if we want to keep pre- and post-IDAT chunk info separated
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * (mainly for PNG-aware image editors and converters) */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* setjmp() must be called in every function that calls a PNG-reading
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * libpng function */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (setjmp(png_jmpbuf(png_ptr))) {
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync return 2;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync }
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_init_io(png_ptr, infile);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* alternatively, could make separate calls to png_get_image_width(),
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * etc., but want bit_depth and color_type for later [don't care about
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * compression_type and filter_type => NULLs] */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
671242f350d172e106580348e24bab66b0d7e6a5vboxsync NULL, NULL, NULL);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *pWidth = width;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *pHeight = height;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* OK, that's all we need for now; return happy */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync return 0;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync}
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync/* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * scales values to 8-bit if necessary */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsyncint readpng_get_bgcolor(uch *red, uch *green, uch *blue)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync{
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_color_16p pBackground;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* setjmp() must be called in every function that calls a PNG-reading
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * libpng function */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (setjmp(png_jmpbuf(png_ptr))) {
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync return 2;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync }
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD))
671242f350d172e106580348e24bab66b0d7e6a5vboxsync return 1;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* it is not obvious from the libpng documentation, but this function
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * takes a pointer to a pointer, and it always returns valid red, green
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * and blue values, regardless of color_type: */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_get_bKGD(png_ptr, info_ptr, &pBackground);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* however, it always returns the raw bKGD data, regardless of any
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * bit-depth transformations, so check depth and adjust if necessary */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (bit_depth == 16) {
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *red = pBackground->red >> 8;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *green = pBackground->green >> 8;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *blue = pBackground->blue >> 8;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (bit_depth == 1)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *red = *green = *blue = pBackground->gray? 255 : 0;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync else if (bit_depth == 2)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *red = *green = *blue = (255/3) * pBackground->gray;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync else /* bit_depth == 4 */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *red = *green = *blue = (255/15) * pBackground->gray;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync } else {
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *red = (uch)pBackground->red;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *green = (uch)pBackground->green;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *blue = (uch)pBackground->blue;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync }
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync return 0;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync}
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync/* display_exponent == LUT_exponent * CRT_exponent */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsyncuch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync{
671242f350d172e106580348e24bab66b0d7e6a5vboxsync double gamma;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_uint_32 i, rowbytes;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_bytepp row_pointers = NULL;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* setjmp() must be called in every function that calls a PNG-reading
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * libpng function */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (setjmp(png_jmpbuf(png_ptr))) {
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync return NULL;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync }
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * transparency chunks to full alpha channel; strip 16-bit-per-sample
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * images to 8 bits per sample; and convert grayscale to RGB[A] */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (color_type == PNG_COLOR_TYPE_PALETTE)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_set_expand(png_ptr);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_set_expand(png_ptr);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_set_expand(png_ptr);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (bit_depth == 16)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_set_strip_16(png_ptr);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (color_type == PNG_COLOR_TYPE_GRAY ||
671242f350d172e106580348e24bab66b0d7e6a5vboxsync color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_set_gray_to_rgb(png_ptr);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* unlike the example in the libpng documentation, we have *no* idea where
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * this file may have come from--so if it doesn't have a file gamma, don't
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * do any correction ("do no harm") */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (png_get_gAMA(png_ptr, info_ptr, &gamma))
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_set_gamma(png_ptr, display_exponent, gamma);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* all transformations have been registered; now update info_ptr data,
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * get rowbytes and channels, and allocate image memory */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_read_update_info(png_ptr, info_ptr);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync *pChannels = (int)png_get_channels(png_ptr, info_ptr);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) {
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync return NULL;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync }
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) {
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync free(image_data);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync image_data = NULL;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync return NULL;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync }
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync Trace((stderr, "readpng_get_image: channels = %d, rowbytes = %ld, height = %ld\n", *pChannels, rowbytes, height));
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* set the individual row_pointers to point at the correct offsets */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync for (i = 0; i < height; ++i)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync row_pointers[i] = image_data + i*rowbytes;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* now we can go ahead and just read the whole image */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_read_image(png_ptr, row_pointers);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync /* and we're done! (png_read_end() can be omitted if no processing of
671242f350d172e106580348e24bab66b0d7e6a5vboxsync * post-IDAT text/time/etc. is desired) */
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync free(row_pointers);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync row_pointers = NULL;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_read_end(png_ptr, NULL);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync return image_data;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync}
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsyncvoid readpng_cleanup(int free_image_data)
671242f350d172e106580348e24bab66b0d7e6a5vboxsync{
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (free_image_data && image_data) {
671242f350d172e106580348e24bab66b0d7e6a5vboxsync free(image_data);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync image_data = NULL;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync }
671242f350d172e106580348e24bab66b0d7e6a5vboxsync
671242f350d172e106580348e24bab66b0d7e6a5vboxsync if (png_ptr && info_ptr) {
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
671242f350d172e106580348e24bab66b0d7e6a5vboxsync png_ptr = NULL;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync info_ptr = NULL;
671242f350d172e106580348e24bab66b0d7e6a5vboxsync }
671242f350d172e106580348e24bab66b0d7e6a5vboxsync}