Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-08-23 12:04:21 +0000
committerStijn Buys <ingar@osirion.org>2008-08-23 12:04:21 +0000
commit02e9a70009f79064043033abc5e597930aa11079 (patch)
tree606615f7ed162f9acc1e91f03b9745a12637d41a /src/render/pngfile.cc
parent375b7d96a3974a03416c600b579048e48f1580a2 (diff)
PNG support
Diffstat (limited to 'src/render/pngfile.cc')
-rw-r--r--src/render/pngfile.cc122
1 files changed, 122 insertions, 0 deletions
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 <string.h>
+#include <png.h>
+
+#include <iostream>
+
+#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;
+}
+
+}