00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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(m_png->jmpbuf))
00092 {
00093 throw error(m_error);
00094 }
00095 png_write_png(m_png,
00096 m_info.get_png_info(),
00097 0,
00098 0);
00099 }
00100
00104 void write_info() const
00105 {
00106 if (setjmp(m_png->jmpbuf))
00107 {
00108 throw error(m_error);
00109 }
00110 m_info.write();
00111 }
00112
00116 void write_row(byte* bytes)
00117 {
00118 if (setjmp(m_png->jmpbuf))
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(m_png->jmpbuf))
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, 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 }
00198
00199 #endif // PNGPP_WRITER_HPP_INCLUDED