Logo Search packages:      
Sourcecode: 3depict version File versions  Download package


 *    Copyright (C) 2002 Thomas Schumm <pansi@phong.org>
 *    MOdifications 2010 D Haley
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.

 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    GNU General Public License for more details.

 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.

#ifdef __cplusplus 
      extern "C" { 

//Unavailable definitions under mac & windows (not sure why)
#if defined(__APPLE__) || defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
#define png_infopp_NULL (png_infopp)NULL
#define int_p_NULL (int*)NULL

#include "pngread.h"

int check_if_png(const char *file_name, FILE **fp, unsigned int bytes_to_check)
   char buf[bytes_to_check];

   /* Open the prospective PNG file. */
   if ((*fp = fopen(file_name, "rb")) == NULL)
      return 0;

   /* Read in some of the signature bytes */
   if (fread(buf, 1, bytes_to_check, *fp) != bytes_to_check)
      return 0;

   /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
      Return nonzero (true) if they match */

   return(!png_sig_cmp(buf, (png_size_t)0, bytes_to_check));

/* Read a PNG file.  You may want to return an error code if the read
 * fails (depending upon the failure).  There are two "prototypes" given
 * here - one where we are given the filename, and we need to open the
 * file, and the other where we are given an open file (possibly with
 * some or all of the magic bytes read - see comments above).
int read_png(FILE *fp, unsigned int sig_read, png_bytep **row_pointers,
             png_uint_32 *width, png_uint_32 *height)  /* file is already open */
   png_structp png_ptr;
   png_infop info_ptr;
/*   png_uint_32 width, height; */
   int bit_depth, color_type, interlace_type;

   /* Create and initialize the png_struct with the desired error handler
    * functions.  If you want to use the default stderr and longjump method,
    * you can supply NULL for the last three parameters.  We also supply the
    * the compiler header file version, so that we know if the application
    * was compiled with a compatible version of the library.  REQUIRED
   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

   if (png_ptr == NULL)
      return (-1);

   /* Allocate/initialize the memory for image information.  REQUIRED. */
   info_ptr = png_create_info_struct(png_ptr);
   if (info_ptr == NULL)
      png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
      return (-1);

   /* Set error handling if you are using the setjmp/longjmp method (this is
    * the normal method of doing things with libpng).  REQUIRED unless you
    * set up your own error handlers in the png_create_read_struct() earlier.

   if (setjmp(png_jmpbuf(png_ptr)))
      /* Free all of the memory associated with the png_ptr and info_ptr */
      png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
      /* If we get here, we had a problem reading the file */
      return (-1);

   /* One of the following I/O initialization methods is REQUIRED */
   /* Set up the input control if you are using standard C streams */
   png_init_io(png_ptr, fp);

   /* If we have already read some of the signature */
   png_set_sig_bytes(png_ptr, sig_read);

   /* OK, you're doing it the hard way, with the lower-level functions */

   /* The call to png_read_info() gives us all of the information from the
    * PNG file before the first IDAT (image data chunk).  REQUIRED
   png_read_info(png_ptr, info_ptr);

   /* png_get_IHDR pulls useful data out of info_ptr. */
   png_get_IHDR(png_ptr, info_ptr, width, height, &bit_depth, &color_type,
       &interlace_type, int_p_NULL, int_p_NULL);

/* Set up the data transformations you want.  Note that these are all
 * optional.  Only call them if you want/need them.  Many of the
 * transformations only work on specific types of images, and many
 * are mutually exclusive.

   /* tell libpng to strip 16 bit/color files down to 8 bits/color */
   if (bit_depth == 16)

   /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
    * byte into separate bytes (useful for paletted and grayscale images).
   if (bit_depth < 8)

   /* Expand paletted colors into true RGB triplets */
   if (color_type == PNG_COLOR_TYPE_PALETTE)

   /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
   if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
#if defined(__APPLE__) || defined(__WIN32) || defined(__WIN64)
   /* Expand paletted or RGB images with transparency to full alpha for RGBA */
   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
   /* Expand grayscale images to RGB */
   if (color_type == PNG_COLOR_TYPE_GRAY ||
       color_type == PNG_COLOR_TYPE_GRAY_ALPHA)

   /* Strip alpha bytes from the input data without combining with the
    * background (not recommended).

   /* Set the background color to draw transparent and alpha images over.
    * It is possible to set the red, green, and blue components directly
    * for paletted images instead of supplying a palette index.  Note that
    * even if the PNG file supplies a background, you are not required to
    * use it - you should use the (solid) application background if it has one.

/*   png_color_16 my_background; */ /*, *image_background; */
   /* use black for now */
/*    my_background.red = my_background.green = my_background.blue = 0; */

/*   if (png_get_bKGD(png_ptr, info_ptr, &image_background))
      png_set_background(png_ptr, image_background,
                         PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
   else */
     /* use black by default */
/*       png_set_background(png_ptr, &my_background, */
/*                          PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); */

   /* Some suggestions as to how to get a screen gamma value */

   /* Note that screen gamma is the display_exponent, which includes
    * the CRT_exponent and any correction for viewing conditions */
   /* this should be user configurable somehow... */
   double screen_gamma = 2.2;  /* A good guess for a PC monitors in a dimly
                                  lit room */
   /* screen_gamma = 1.7;  or 1.0; */  /* A good guess for Mac systems */

   /* Tell libpng to handle the gamma conversion for you.  The final call
    * is a good guess for PC generated images, but it should be configurable
    * by the user at run time by the user.  It is strongly suggested that
    * your application support gamma correction.
    * 0.45455 is a "guess" for images with no particular gamma

   int intent;

   if (png_get_sRGB(png_ptr, info_ptr, &intent))
      png_set_gamma(png_ptr, screen_gamma, 0.45455);
      double image_gamma;
      if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
         png_set_gamma(png_ptr, screen_gamma, image_gamma);
         png_set_gamma(png_ptr, screen_gamma, 0.45455);

   png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);

   /* Optional call to gamma correct and add the background to the palette
    * and update info structure.  REQUIRED if you are expecting libpng to
    * update the palette for you (ie you selected such a transform above).
   png_read_update_info(png_ptr, info_ptr);

   /* Allocate the memory to hold the image using the fields of info_ptr. */

   /* The easiest way to read the image: */
   if (!(*row_pointers = malloc(*height * sizeof(png_bytep)))) {
     return (-1);
   int row;

   for (row = 0; row < *height; row++)
      (*row_pointers)[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr,

   /* Read the entire image in one go */
   png_read_image(png_ptr, *row_pointers);

   /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
   png_read_end(png_ptr, info_ptr);
   /* At this point you have read the entire image */

   /* clean up after the read, and free any memory allocated - REQUIRED */
   png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);

   /* close the file */

   /* that's it */
   return (0);

#ifdef __cplusplus 

Generated by  Doxygen 1.6.0   Back to index