Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
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
parent375b7d96a3974a03416c600b579048e48f1580a2 (diff)
PNG support
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/filesystem/diskfile.cc5
-rw-r--r--src/filesystem/diskfile.h1
-rw-r--r--src/filesystem/file.cc5
-rw-r--r--src/filesystem/file.h2
-rw-r--r--src/render/Makefile.am5
-rw-r--r--src/render/image.h2
-rw-r--r--src/render/pngfile.cc122
-rw-r--r--src/render/pngfile.h34
-rw-r--r--src/render/textures.cc34
-rw-r--r--src/render/tga.cc2
11 files changed, 199 insertions, 15 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 15dfcb9..a3a5c03 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -40,5 +40,5 @@ osirion_LDADD = $(top_builddir)/src/game/libgame.la \
$(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/model/libmodel.la \
$(top_builddir)/src/math/libmath.la $(top_builddir)/src/auxiliary/libauxiliary.la \
$(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/sys/libsys.la \
- $(top_builddir)/src/auxiliary/libauxiliary.la $(AL_LIBS) $(GL_LIBS) $(HOST_LIBS) $(ICON_CLIENT)
+ $(top_builddir)/src/auxiliary/libauxiliary.la $(AL_LIBS) $(GL_LIBS) $(HOST_LIBS) $(LIBPNG_LIBS) $(ICON_CLIENT)
osirion_LDFLAGS = $(LIBSDL_LIBS)
diff --git a/src/filesystem/diskfile.cc b/src/filesystem/diskfile.cc
index 56e2727..6554f1e 100644
--- a/src/filesystem/diskfile.cc
+++ b/src/filesystem/diskfile.cc
@@ -20,6 +20,11 @@ DiskFile::~DiskFile()
fclose(diskfile_handle);
}
+FILE *DiskFile::handle()
+{
+ return diskfile_handle;
+}
+
bool DiskFile::open(const char *filename)
{
if (diskfile_handle) {
diff --git a/src/filesystem/diskfile.h b/src/filesystem/diskfile.h
index b71576d..7da1a88 100644
--- a/src/filesystem/diskfile.h
+++ b/src/filesystem/diskfile.h
@@ -31,6 +31,7 @@ public:
virtual size_t read(void *buffer, size_t count);
+ virtual FILE *handle();
void skip(size_t count);
private:
diff --git a/src/filesystem/file.cc b/src/filesystem/file.cc
index 07f8870..91ac9f9 100644
--- a/src/filesystem/file.cc
+++ b/src/filesystem/file.cc
@@ -13,5 +13,10 @@ File::File() {}
File::~File() {}
+FILE *File::handle()
+{
+ return 0;
+}
+
} // namespace filesystem
diff --git a/src/filesystem/file.h b/src/filesystem/file.h
index 37ac8b4..daef174 100644
--- a/src/filesystem/file.h
+++ b/src/filesystem/file.h
@@ -27,6 +27,8 @@ public:
/// close file
virtual void close() = 0;
+ virtual FILE *handle();
+
/// read bytes
virtual size_t read(void *buffer, size_t count) = 0;
diff --git a/src/render/Makefile.am b/src/render/Makefile.am
index 7069f97..99b1847 100644
--- a/src/render/Makefile.am
+++ b/src/render/Makefile.am
@@ -9,7 +9,8 @@ endif
librender_la_LDFLAGS = -avoid-version -no-undefined @GL_LIBS@
librender_la_LIBADD = $(top_builddir)/src/math/libmath.la
-librender_la_SOURCES = camera.cc draw.cc dust.cc gl.cc image.cc render.cc \
- text.cc textures.cc tga.cc
+librender_la_SOURCES = camera.cc draw.cc dust.cc gl.cc image.cc pngfile.cc \
+ render.cc text.cc textures.cc tga.cc
noinst_HEADERS = camera.h draw.h dust.h gl.h image.h render.h text.h textures.h \
tga.h
+_SOURCES = pngfile.h
diff --git a/src/render/image.h b/src/render/image.h
index a129773..c9cc029 100644
--- a/src/render/image.h
+++ b/src/render/image.h
@@ -7,6 +7,8 @@
#ifndef __INCLUDED_RENDER_IMAGE_H__
#define __INCLUDED_RENDER_IMAGE_H__
+#include <string>
+
namespace render {
/// RGB (24bpp) or RGBA (32bpp) image data
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;
+}
+
+}
diff --git a/src/render/pngfile.h b/src/render/pngfile.h
new file mode 100644
index 0000000..a7beb7c
--- /dev/null
+++ b/src/render/pngfile.h
@@ -0,0 +1,34 @@
+/*
+ render/png.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+
+#ifndef _INCLUDED_RENDER_PNGFILE_H_
+#define _INCLUDED_RENDER_PNGFILE_H_
+
+#include "render/image.h"
+
+namespace render
+{
+
+/// a class for loading and saving .png files
+class PNG {
+
+public:
+ /// load a PNG image file from disk
+ /** @param filename short path to the filename to be loaded
+ */
+ static Image *load(const char * filename);
+
+ /// write an image to a PNG file
+ /** @param filename short path to the file to write the image data to
+ */
+ static void save(const char *filename, Image & image);
+};
+
+}
+
+#endif //_INCLUDED_RENDER_PNGFILE_H_
+
diff --git a/src/render/textures.cc b/src/render/textures.cc
index 2bc6c05..6ceb7cd 100644
--- a/src/render/textures.cc
+++ b/src/render/textures.cc
@@ -9,6 +9,7 @@
#include "render/gl.h"
#include "render/textures.h"
#include "render/tga.h"
+#include "render/pngfile.h"
#include "sys/sys.h"
#include "core/application.h"
@@ -66,23 +67,34 @@ size_t Textures::load(std::string name, bool filter)
if (it != registry.end())
return (*it).second;
- // try the tga version
- std::string filename(name);
- filename.append(".tga");
- Image *image = TGA::load(filename.c_str());
- if (!image) {
- // add to the registry with id 0 (texture not found)
- registry[name] = 0;
- return 0;
- }
-
if (index == MAXTEXTURES) {
con_error << "Texture limit " << MAXTEXTURES << " exceeded!" << std::endl;
- delete image;
registry[name] = 0;
return 0;
}
+ std::string filename;
+ Image *image = 0;
+
+ // try the png version
+ filename.assign(name);
+ filename.append(".png");
+ image = PNG::load(filename.c_str());
+
+ if (!image) {
+ // try the tga version
+ filename.assign(name);
+ filename.append(".tga");
+ image = TGA::load(filename.c_str());
+
+ if (!image) {
+ // add to the registry with id 0 (texture not found)
+ con_warn << "Could not open " << filename << std::endl;
+ registry[name] = 0;
+ return 0;
+ }
+ }
+
size_t id = index;
glGenTextures(1, &textures[id]);
diff --git a/src/render/tga.cc b/src/render/tga.cc
index 6a85130..9703ce8 100644
--- a/src/render/tga.cc
+++ b/src/render/tga.cc
@@ -51,7 +51,7 @@ Image *TGA::load(const char *filename)
filesystem::File *tga_file = filesystem::open(filename);
if (!tga_file) {
- con_warn << "Could not open " << filename << std::endl;
+ //con_warn << "Could not open " << filename << std::endl;
return 0;
}