pandorafms/extras/anytermd/libpbe/include/WritePngFile.hh

104 lines
3.0 KiB
C++

// include/WritePngFile.hh
// This file is part of libpbe; see http://svn.chezphil.org/libpbe/
// (C) 2009 Philip Endecott
// 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; either version 2 of the License, or
// any later version.
//
// 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 for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef libpbe_WritePngFile_hh
#define libpbe_WritePngFile_hh
#include <png.h>
#include <boost/noncopyable.hpp>
// WritePngFile is a wrapper around libpng's facilities for writing
// a PNG file. The ctor takes a filename, image dimensions and so on;
// you then supply pixel data row-at-a-time. This is a small subsit
// of libpng's facilities.
//
// Boost.GIL also has a libpng wrapper, but I believe that it only
// supports writing whole images.
namespace pbe {
struct WritePngFile {
FILE* f;
png_structp png_p;
png_infop info_p;
static FILE* check_fopen(const char* fn, const char* mode) {
FILE* f = fopen(fn,mode);
if (!f) {
throw "fopen() failed";
}
return f;
}
static png_structp check_png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn) {
png_structp p = png_create_write_struct(user_png_ver, error_ptr, error_fn, warn_fn);
if (!p) {
throw "png_create_write_struct() failed";
}
return p;
}
static png_infop check_png_create_info_struct(png_structp png_ptr) {
png_infop i = png_create_info_struct(png_ptr);
if (!i) {
throw "png_create_info_struct() failed";
}
return i;
}
static void error_fn(png_structp, png_const_charp error_msg) {
throw error_msg;
}
WritePngFile(const char* fn, uint32_t width, uint32_t height,
int bit_depth=8, int colour_type=PNG_COLOR_TYPE_RGB_ALPHA):
f(check_fopen(fn,"wb")),
png_p(check_png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, &error_fn, 0)),
info_p(check_png_create_info_struct(png_p))
{
png_init_io(png_p,f);
png_set_IHDR(png_p, info_p, width, height, bit_depth, colour_type,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_p, info_p);
}
~WritePngFile() {
png_write_end(png_p, info_p);
png_destroy_write_struct(&png_p,&info_p); // frees both
fclose(f);
}
void write_row(const uint32_t* data) {
png_write_row(png_p, const_cast<png_byte*>(reinterpret_cast<const png_byte*>(data)));
}
};
};
#endif