png++
0.2.9
|
00001 /* 00002 * Copyright (C) 2007,2008 Alex Shulgin 00003 * 00004 * This file is part of png++ the C++ wrapper for libpng. PNG++ is free 00005 * software; the exact copying conditions are as follows: 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright notice, 00011 * this list of conditions and the following disclaimer. 00012 * 00013 * 2. Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in the 00015 * documentation and/or other materials provided with the distribution. 00016 * 00017 * 3. The name of the author may not be used to endorse or promote products 00018 * derived from this software without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00021 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00022 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00023 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00024 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00025 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00026 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00027 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00028 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 */ 00031 #ifndef PNGPP_WRITER_HPP_INCLUDED 00032 #define PNGPP_WRITER_HPP_INCLUDED 00033 00034 #include <cassert> 00035 #include "io_base.hpp" 00036 00037 namespace png 00038 { 00039 00065 template< class ostream > 00066 class writer 00067 : public io_base 00068 { 00069 public: 00074 explicit writer(ostream& stream) 00075 : io_base(png_create_write_struct(PNG_LIBPNG_VER_STRING, 00076 static_cast< io_base* >(this), 00077 raise_error, 00078 0)) 00079 { 00080 png_set_write_fn(m_png, & stream, write_data, flush_data); 00081 } 00082 00083 ~writer() 00084 { 00085 m_end_info.destroy(); 00086 png_destroy_write_struct(& m_png, m_info.get_png_info_ptr()); 00087 } 00088 00089 void write_png() const 00090 { 00091 if (setjmp(png_jmpbuf(m_png))) 00092 { 00093 throw error(m_error); 00094 } 00095 png_write_png(m_png, 00096 m_info.get_png_info(), 00097 /* transforms = */ 0, 00098 /* params = */ 0); 00099 } 00100 00104 void write_info() const 00105 { 00106 if (setjmp(png_jmpbuf(m_png))) 00107 { 00108 throw error(m_error); 00109 } 00110 m_info.write(); 00111 } 00112 00116 void write_row(byte* bytes) 00117 { 00118 if (setjmp(png_jmpbuf(m_png))) 00119 { 00120 throw error(m_error); 00121 } 00122 png_write_row(m_png, bytes); 00123 } 00124 00128 void write_end_info() const 00129 { 00130 if (setjmp(png_jmpbuf(m_png))) 00131 { 00132 throw error(m_error); 00133 } 00134 m_end_info.write(); 00135 } 00136 00137 private: 00138 static void write_data(png_struct* png, byte* data, png_size_t length) 00139 { 00140 io_base* io = static_cast< io_base* >(png_get_error_ptr(png)); 00141 writer* wr = static_cast< writer* >(io); 00142 wr->reset_error(); 00143 ostream* stream = reinterpret_cast< ostream* >(png_get_io_ptr(png)); 00144 try 00145 { 00146 stream->write(reinterpret_cast< char* >(data), length); 00147 if (!stream->good()) 00148 { 00149 wr->set_error("ostream::write() failed"); 00150 } 00151 } 00152 catch (std::exception const& error) 00153 { 00154 wr->set_error(error.what()); 00155 } 00156 catch (...) 00157 { 00158 assert(!"caught something wrong"); 00159 wr->set_error("write_data: caught something wrong"); 00160 } 00161 if (wr->is_error()) 00162 { 00163 wr->raise_error(); 00164 } 00165 } 00166 00167 static void flush_data(png_struct* png) 00168 { 00169 io_base* io = static_cast< io_base* >(png_get_error_ptr(png)); 00170 writer* wr = static_cast< writer* >(io); 00171 wr->reset_error(); 00172 ostream* stream = reinterpret_cast< ostream* >(png_get_io_ptr(png)); 00173 try 00174 { 00175 stream->flush(); 00176 if (!stream->good()) 00177 { 00178 wr->set_error("ostream::flush() failed"); 00179 } 00180 } 00181 catch (std::exception const& error) 00182 { 00183 wr->set_error(error.what()); 00184 } 00185 catch (...) 00186 { 00187 assert(!"caught something wrong"); 00188 wr->set_error("flush_data: caught something wrong"); 00189 } 00190 if (wr->is_error()) 00191 { 00192 wr->raise_error(); 00193 } 00194 } 00195 }; 00196 00197 } // namespace png 00198 00199 #endif // PNGPP_WRITER_HPP_INCLUDED