From 02e9a70009f79064043033abc5e597930aa11079 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sat, 23 Aug 2008 12:04:21 +0000 Subject: PNG support --- src/render/pngfile.cc | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/render/pngfile.cc (limited to 'src/render/pngfile.cc') diff --git a/src/render/pngfile.cc b/src/render/pngfile.cc new file mode 100644 index 0000000..14884f0 --- /dev/null +++ b/src/render/pngfile.cc @@ -0,0 +1,122 @@ +/* + render/png.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +/* +Notes: + +http://www.zarb.org/~gc/html/libpng.html + +*/ + +#include +#include + +#include + +#include "filesystem/filesystem.h" +#include "render/pngfile.h" +#include "sys/sys.h" + +namespace render { + +Image *PNG::load(const char *filename) +{ + Image *image = 0; + + if (!filename) + return 0; + + filesystem::File *png_file = filesystem::open(filename); + if (!png_file) { + //con_warn << "Could not open " << filename << std::endl; + return 0; + } + + png_byte header[8]; + memset(header, 0, sizeof(header)); + + if (!png_file->read(header, 8)) { + con_warn << "Error reading " << filename << std::endl; + filesystem::close(png_file); + return 0; + } + if (png_sig_cmp(header, 0, 8)) { + con_warn << "Error reading " << filename << ": not a PNG file!" << std::endl; + filesystem::close(png_file); + return 0; + } + + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) { + con_warn << "Error reading " << filename << ": png_create_read_struct failed!" << std::endl; + filesystem::close(png_file); + return 0; + } + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + con_warn << "Error reading " << filename << ": png_create_info_struct failed!" << std::endl; + filesystem::close(png_file); + return 0; + } + if (setjmp(png_jmpbuf(png_ptr))) { + con_warn << "Error reading " << filename << ": error during init_io!" << std::endl; + filesystem::close(png_file); + return 0; + } + + /* read the PNG header */ + png_init_io(png_ptr, png_file->handle()); + png_set_sig_bytes(png_ptr, 8); + + png_read_info(png_ptr, info_ptr); + + int png_width = info_ptr->width; + int png_height = info_ptr->height; + //int png_color_type = info_ptr->color_type; + int png_depth = info_ptr->bit_depth; + + //int number_of_passes = png_set_interlace_handling(png_ptr); + png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); + + if (png_depth != 8) { + con_warn << "Error reading " << filename << ": bits per channel must be 8!" << std::endl; + filesystem::close(png_file); + return 0; + } + + unsigned int channels = info_ptr->rowbytes / png_width; + image = new Image(png_width, png_height, channels); + + /* read image data */ + if (setjmp(png_jmpbuf(png_ptr))) { + con_warn << "Error reading " << filename << std::endl; + filesystem::close(png_file); + delete image; + return 0; + } + + png_bytep row_pointers[png_height]; + + for (size_t i=0; i < (size_t)png_height; i++) + row_pointers[i] = (png_bytep) (*image)[i * info_ptr->rowbytes]; + + png_read_image(png_ptr, row_pointers); + + filesystem::close(png_file); + + con_debug << " " << filename << " " << png_width << "x" << png_height << "x" << channels * png_depth << "bpp" << std::endl; + + return image; +} + +void PNG::save(const char *filename, Image & image) +{ + con_warn << "PNG::save stub" << std::endl; +} + +} -- cgit v1.2.3