/*------------------------------------------------------------------------- LoadPng.cxx Some routines to make it easier to load PNG images This is *NOT* intended to be a complete PNG-loader Written by Per Liedman, started February 2000. Copyright (C) 2000 Per Liedman, liedman@home.se 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 2 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 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ---------------------------------------------------------------------------*/ #include #include // reads char *loadPng( char *filename, int *width, int *height ) { char *header[8]; FILE *fp = fopen(filename, "rb"); if (!fp) { //fprintf(stderr, "loadPng: Unable to open file \"%s\".\n", filename); return NULL; } // check to see if this might be PNG fread( header, 1, 8, fp ); if (png_sig_cmp((png_bytep)header, 0, 8)) { //fprintf(stderr, "loadPng: File \"%s\" is not a PNG image.\n", filename); return NULL; } // allocate some structures png_structp png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if (!png_ptr) { //fprintf(stderr, "loadPng: Unable to allocate read structure.\n", filename); return NULL; } png_infop info_ptr = png_create_info_struct( png_ptr ); if (!png_ptr) { //fprintf(stderr, "loadPng: Unable to allocate info structure.\n", filename); return NULL; } png_infop end_info = png_create_info_struct( png_ptr ); if (!end_info) { //fprintf(stderr, "loadPng: Unable to allocate secondary info structure.\n", filename); return NULL; } // initialize IO png_init_io(png_ptr, fp); png_set_sig_bytes( png_ptr, 8 ); png_read_info( png_ptr, info_ptr ); double gamma; if ( png_get_gAMA(png_ptr, info_ptr, &gamma) ) { png_set_gamma( png_ptr, 2.0, gamma ); } else { png_set_gamma( png_ptr, 2.0, 0.45455 ); } if ( png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE ) png_set_expand( png_ptr ); png_read_update_info( png_ptr, info_ptr ); *width = png_get_image_width (png_ptr, info_ptr); *height = png_get_image_height(png_ptr, info_ptr); // allocate image chunk png_bytep *rows = new png_bytep[*height]; char *image = new char[(*width) * (*height)*3]; // 24 bits per pixel for (int i = 0; i < *height; i++) { rows[i] = (png_bytep)(image + i * (*width) * 3); } png_read_image(png_ptr, rows); delete[] rows; png_read_end( png_ptr, end_info ); png_destroy_read_struct( &png_ptr, &info_ptr, &end_info ); fclose( fp ); return image; }