Back to index

extremetuxracer  0.5beta
png_reader.cpp
Go to the documentation of this file.
00001 /* 
00002  * PPRacer 
00003  * Copyright (C) 2004-2005 Volker Stroebel <volker@planetpenguin.de>
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  * 
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018  */
00019 
00020 #include "png_reader.h"
00021 
00022 namespace pp {
00023 
00024 ReaderPNG::ReaderPNG(const char *fileName)
00025 {
00026        png_byte header[4]; 
00027        
00028        data = NULL; 
00029        
00030        FILE *fp = fopen(fileName, "rb");
00031     if (!fp){
00032               return;
00033     }
00034        
00035     fread(header, 1, 4, fp);
00036     bool is_png = !png_sig_cmp(header, 0, 4);
00037        if (!is_png)
00038     {
00039               fclose(fp);
00040         return;
00041        }
00042               
00043     png_structp png_ptr = png_create_read_struct
00044        (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00045               
00046     if (!png_ptr){
00047               fclose(fp);
00048         return;
00049        }
00050 
00051        
00052     png_infop info_ptr = png_create_info_struct(png_ptr);
00053     if (!info_ptr)
00054     {
00055         png_destroy_read_struct(&png_ptr,
00056            (png_infopp)NULL, (png_infopp)NULL);
00057               fclose(fp);
00058         return;
00059     }
00060 
00061     png_infop end_info = png_create_info_struct(png_ptr);
00062     if (!end_info)
00063     {
00064         png_destroy_read_struct(&png_ptr, &info_ptr,
00065           (png_infopp)NULL);
00066               fclose(fp);
00067         return;
00068     }
00069 
00070        png_init_io(png_ptr, fp);
00071        png_set_sig_bytes(png_ptr, 4);
00072        
00073        png_read_info(png_ptr, info_ptr);
00074               
00075        png_uint_32 width, height;
00076        int bit_depth, color_type, interlace_type;
00077        
00078        
00079        png_get_IHDR(png_ptr, info_ptr, &width, &height,
00080        &bit_depth, &color_type, &interlace_type,int_p_NULL, int_p_NULL);
00081        
00082        if(bit_depth == 16)
00083         png_set_strip_16(png_ptr);
00084        
00085        if(color_type == PNG_COLOR_TYPE_PALETTE &&
00086         bit_depth <= 8)
00087        {
00088               png_set_expand(png_ptr);
00089               png_read_update_info(png_ptr, info_ptr);
00090               png_get_IHDR(png_ptr, info_ptr, &width, &height,
00091                         &bit_depth, &color_type, &interlace_type,int_p_NULL, int_p_NULL);
00092        }
00093        
00094        if( color_type == PNG_COLOR_TYPE_GRAY ||
00095               color_type == PNG_COLOR_TYPE_GRAY_ALPHA ){
00096               png_set_gray_to_rgb(png_ptr);
00097               png_read_update_info(png_ptr, info_ptr);
00098               png_get_IHDR(png_ptr, info_ptr, &width, &height,
00099                         &bit_depth, &color_type, &interlace_type,int_p_NULL, int_p_NULL);
00100        }
00101               
00102        this->width=width;
00103        this->height=height;
00104                      
00105        if ( color_type==PNG_COLOR_TYPE_RGB){
00106               depth=3;
00107               loadData(png_ptr, 3);
00108        } else if ( color_type==PNG_COLOR_TYPE_RGB_ALPHA){
00109               depth=4;
00110               loadData(png_ptr, 4);
00111        } else {
00112               fflush(stdout);                    
00113               data = NULL;
00114        }
00115        
00116        png_read_end(png_ptr, info_ptr);
00117        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
00118        fclose(fp);
00119 }
00120 
00121 void
00122 ReaderPNG::loadData(png_structp png_ptr, int depth)
00124 {
00125        png_bytep *row_pointers = new png_bytep[height];
00126        data = new unsigned char[width*height*depth];
00127               
00128        for (unsigned int i=0; i<height; i++)
00129               row_pointers[height-1-i]=data + i*width*depth;
00130        
00131        png_read_image(png_ptr, row_pointers);
00132        delete [] row_pointers;
00133 }
00134 
00135 ReaderPNG::~ReaderPNG()
00136 {
00137        if(data!=NULL) delete(data);
00138 }
00139 
00140 } //namespace pp