// Copyright (C) 2003 Dolphin Project. // 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, version 2.0. // 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 2.0 for more details. // A copy of the GPL 2.0 should have been included with the program. // If not, see http://www.gnu.org/licenses/ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ #include "GLInterface.h" #include char* LoadPNG(const char *filename, u32 &width, u32 &height) { FILE *infile; /* PNG file pointer */ png_structp png_ptr; /* internally used by libpng */ png_infop info_ptr; /* user requested transforms */ char *image_data; /* raw png image data */ char sig[8]; /* PNG signature array */ /*char **row_pointers; */ int bit_depth; int color_type; png_uint_32 _width; png_uint_32 _height; unsigned int rowbytes; /* raw bytes at row n in image */ image_data = NULL; unsigned int i; png_bytepp row_pointers = NULL; /* Open the file. */ infile = fopen(filename, "rb"); if (!infile) return NULL; /* * 13.3 readpng_init() */ /* Check for the 8-byte signature */ fread(sig, 1, 8, infile); if (!png_check_sig((unsigned char *) sig, 8)) { fclose(infile); return NULL; } /* * Set up the PNG structs */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fclose(infile); return NULL; /* out of memory */ } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); fclose(infile); return NULL; /* out of memory */ } /* * block to handle libpng errors, * then check whether the PNG file had a bKGD chunk */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(infile); return NULL; } /* * takes our file stream pointer (infile) and * stores it in the png_ptr struct for later use. */ /* png_ptr->io_ptr = (png_voidp)infile;*/ png_init_io(png_ptr, infile); /* * lets libpng know that we already checked the 8 * signature bytes, so it should not expect to find * them at the current file pointer location */ png_set_sig_bytes(png_ptr, 8); /* Read the image */ /* * reads and processes not only the PNG file's IHDR chunk * but also any other chunks up to the first IDAT * (i.e., everything before the image data). */ /* read all the info up to the image data */ png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &_width, &_height, &bit_depth, &color_type, NULL, NULL, NULL); /* Set up some transforms. */ if (bit_depth > 8) png_set_strip_16(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); /* Update the png info struct.*/ png_read_update_info(png_ptr, info_ptr); /* Rowsize in bytes. */ rowbytes = png_get_rowbytes(png_ptr, info_ptr); /* Allocate the image_data buffer. */ if ((image_data = (char *) malloc(rowbytes * _height))==NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; } if ((row_pointers = (png_bytepp)malloc(_height*sizeof(png_bytep))) == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); free(image_data); image_data = NULL; return NULL; } /* set the individual row_pointers to point at the correct offsets */ for (i = 0; i < _height; ++i) row_pointers[i] = (png_byte*)(image_data + i*rowbytes); /* now we can go ahead and just read the whole image */ png_read_image(png_ptr, row_pointers); /* and we're done! (png_read_end() can be omitted if no processing of * post-IDAT text/time/etc. is desired) */ /* Clean up. */ free(row_pointers); /* Clean up. */ png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(infile); width = (u32)_width; height = (u32)_height; return image_data; }