diff --git a/src/SConscript b/src/SConscript index 8f4dfab..98a693c 100644 --- a/src/SConscript +++ b/src/SConscript @@ -9,6 +9,7 @@ files = Split(""" object.cc object_sphere.cc scene.cc + writer_png.cc """) lib = env.Library('charles', files) diff --git a/src/writer.h b/src/writer.h new file mode 100644 index 0000000..8809074 --- /dev/null +++ b/src/writer.h @@ -0,0 +1,21 @@ +/* writer.h + * + * Writers handle the interface between (mostly) C libraries to write various image formats and the rest of Charles. + * + * Eryn Wells + */ + +#ifndef __WRITER_H__ +#define __WRITER_H__ + +#include +#include "scene.h" + + +class Writer +{ +public: + virtual int write_scene(const Scene &scene, const std::string &filename) = 0; +}; + +#endif diff --git a/src/writer_png.c b/src/writer_png.cc similarity index 71% rename from src/writer_png.c rename to src/writer_png.cc index a6920ca..a882d43 100644 --- a/src/writer_png.c +++ b/src/writer_png.cc @@ -5,33 +5,37 @@ * Eryn Wells */ +#include +#include +#include -#include -#include - -#include - +#include "scene.h" #include "writer_png.h" +extern "C" { +#include +} + static void png_user_error(png_structp png, png_const_charp msg); static void png_user_warning(png_structp png, png_const_charp msg); /* - * write_scene_png -- + * PNGWriter::write_scene -- * - * Write the given scene to file in PNG format. + * Write the given scene to a file in PNG format. */ int -write_scene_png(Scene *scene, FILE *file) +PNGWriter::write_scene(const Scene &scene, const std::string &filename) { - if (!scene->is_rendered) { + if (!scene.is_rendered()) { return -1; } + FILE *file = fopen(filename.c_str(), "wb"); if (!file) { - return -2; + return -1; } // Set up the PNG data structures. libpng requires two: a PNG object and an info object. @@ -39,7 +43,6 @@ write_scene_png(Scene *scene, FILE *file) if (!png) { return -3; } - png_infop png_info = png_create_info_struct(png); if (!png_info) { return -4; @@ -59,7 +62,7 @@ write_scene_png(Scene *scene, FILE *file) * - No compression */ png_set_IHDR(png, png_info, - scene->width, scene->height, + scene.get_width(), scene.get_height(), 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, @@ -72,21 +75,24 @@ write_scene_png(Scene *scene, FILE *file) png_write_info(png, png_info); // Write it! + const Color *pixels = scene.get_pixels(); + png_byte *row = NULL; int nbytes = 0; - for (int y = 0; y < scene->height; y++) { - png_byte *row = malloc(png_sizeof(png_byte) * scene->width * 3); + for (int y = 0; y < scene.get_height(); y++) { + row = new png_byte[scene.get_width() * 3]; if (row == NULL) { // TODO: DANGER! WILL ROBINSON! } - for (int x = 0; x < scene->width; x++) { - row[x*3+0] = scene->pixels[y * scene->width + x].red; - row[x*3+1] = scene->pixels[y * scene->width + x].green; - row[x*3+2] = scene->pixels[y * scene->width + x].blue; + for (int x = 0; x < scene.get_width(); x++) { + Color c = pixels[y * scene.get_width() + x]; + row[x*3+0] = 0xff * c.red; + row[x*3+1] = 0xff * c.green; + row[x*3+2] = 0xff * c.blue; nbytes += 3; } png_write_row(png, row); - free(row); + delete[] row; } // Clean up! @@ -103,6 +109,7 @@ write_scene_png(Scene *scene, FILE *file) * * Called by libpng when it encounters an error. */ + /* static */ void png_user_error(png_structp png, png_const_charp msg) @@ -116,6 +123,7 @@ png_user_error(png_structp png, * * Called by libpng when it encounters an warning. */ + /* static */ void png_user_warning(png_structp png, png_const_charp msg) diff --git a/src/writer_png.h b/src/writer_png.h index 7a7ab97..5a3918f 100644 --- a/src/writer_png.h +++ b/src/writer_png.h @@ -5,15 +5,17 @@ * Eryn Wells */ +#ifndef __WRITER_PNG_H__ +#define __WRITER_PNG_H__ -#ifndef __WRITER_PNG_H -#define __WRITER_PNG_H - -#include -#include "scene.h" +#include "writer.h" -int write_scene_png(Scene *scene, FILE *file); - +class PNGWriter + : public Writer +{ +public: + int write_scene(const Scene &scene, const std::string &filename); +}; #endif