PNGWriter.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2006 The Pentagram Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 #include "pent_include.h"
00020 
00021 #include "PNGWriter.h"
00022 #include "ODataSource.h"
00023 #include "Texture.h"
00024 
00025 #include <png.h>
00026 
00027 static void odatasource_png_write_data(png_structp png_ptr,
00028                                                                            png_bytep data, png_size_t length)
00029 {
00030         voidp write_io_ptr = png_get_io_ptr(png_ptr);
00031         ODataSource* ds = reinterpret_cast<ODataSource*>(write_io_ptr);
00032         ds->write(data, length);
00033 }
00034 
00035 static void odatasource_png_flush_data(png_structp png_ptr)
00036 {
00037         // not necessary
00038 }
00039 
00040 
00041 
00042 PNGWriter::PNGWriter(ODataSource* ods)
00043 {
00044         ds = ods;
00045         png = 0;
00046 }
00047 
00048 PNGWriter::~PNGWriter()
00049 {
00050 
00051 }
00052 
00053 bool PNGWriter::init(uint32 width, uint32 height, const std::string& comment)
00054 {
00055         this->width = width;
00056 
00057     png_structp png_ptr = png_create_write_struct
00058                 (PNG_LIBPNG_VER_STRING, 0, 0, 0);
00059     if (!png_ptr)
00060                 return false;
00061 
00062         png_infop info_ptr = png_create_info_struct(png_ptr);
00063     if (!info_ptr)
00064     {
00065                 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
00066                 return false;
00067     }
00068 
00069     if (setjmp(png_jmpbuf(png_ptr)))
00070     {
00071                 png_destroy_write_struct(&png_ptr, &info_ptr);
00072                 return false;
00073     }
00074 
00075         png_set_write_fn(png_ptr, ds, odatasource_png_write_data,
00076                                          odatasource_png_flush_data);
00077 
00078         png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
00079                                  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
00080                                  PNG_FILTER_TYPE_DEFAULT);
00081 
00082 
00083         if (!comment.empty()) {
00084                 std::string::size_type len = comment.size();
00085                 char* t = new char[len+1];
00086                 std::memcpy(t, comment.c_str(), len+1);
00087 
00088                 png_text_struct text[1];
00089                 text[0].compression = -1;
00090                 text[0].key = "Comment";
00091                 text[0].text = t;
00092                 text[0].text_length = comment.size();
00093 
00094                 png_set_text(png_ptr, info_ptr, text, 1);
00095 
00096                 delete[] t;
00097         }
00098 
00099         png_write_info(png_ptr, info_ptr);
00100 
00101     png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
00102 
00103         png_set_bgr(png_ptr);
00104 
00105         png = reinterpret_cast<void*>(png_ptr);
00106         info = reinterpret_cast<void*>(info_ptr);
00107 
00108         return true;
00109 }
00110 
00111 bool PNGWriter::writeRows(uint32 nrows, Texture* img)
00112 {
00113         png_bytep* row_pointers = 0;
00114         png_structp png_ptr = reinterpret_cast<png_structp>(png);
00115         png_infop info_ptr = reinterpret_cast<png_infop>(info);
00116         if (!png_ptr) return false;
00117 
00118         assert(img->width == static_cast<sint32>(width));
00119         assert(img->height >= static_cast<sint32>(nrows));
00120 
00121     if (setjmp(png_jmpbuf(png_ptr)))
00122     {
00123                 png_destroy_write_struct(&png_ptr, &info_ptr);
00124                 delete[] row_pointers;
00125                 return false;
00126     }
00127 
00128         row_pointers = new png_bytep[nrows];
00129 
00130         for (unsigned int i = 0; i < nrows; ++i) {
00131                 row_pointers[i] = reinterpret_cast<png_bytep>(&img->buffer[i*width]);
00132         }
00133 
00134         png_write_rows(png_ptr, row_pointers, nrows);
00135 
00136     png_write_flush(png_ptr);
00137 
00138         delete[] row_pointers;
00139 
00140         return true;
00141 }
00142 
00143 bool PNGWriter::finish()
00144 {
00145         png_structp png_ptr = reinterpret_cast<png_structp>(png);
00146         png_infop info_ptr = reinterpret_cast<png_infop>(info);
00147         if (!png_ptr) return false;
00148 
00149     if (setjmp(png_jmpbuf(png_ptr)))
00150     {
00151                 png_destroy_write_struct(&png_ptr, &info_ptr);
00152                 return false;
00153     }
00154 
00155         png_write_end(png_ptr, info_ptr);
00156         png_destroy_write_struct(&png_ptr, &info_ptr);
00157 
00158         return true;
00159 }

Generated on Fri Jul 27 22:27:30 2007 for pentagram by  doxygen 1.4.7