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 <iostream>
00036 #include "io_base.hpp"
00037
00038 namespace png
00039 {
00040
00048 class writer
00049 : public io_base
00050 {
00051 public:
00056 explicit writer(std::ostream& stream)
00057 : io_base(png_create_write_struct(PNG_LIBPNG_VER_STRING,
00058 static_cast< io_base* >(this),
00059 raise_error,
00060 0))
00061 {
00062 png_set_write_fn(m_png, & stream, write_data, flush_data);
00063 }
00064
00065 ~writer()
00066 {
00067 m_end_info.destroy();
00068 png_destroy_write_struct(& m_png, m_info.get_png_info_ptr());
00069 }
00070
00071 void write_png() const
00072 {
00073 if (setjmp(m_png->jmpbuf))
00074 {
00075 throw error(m_error);
00076 }
00077 png_write_png(m_png,
00078 m_info.get_png_info(),
00079 0,
00080 0);
00081 }
00082
00086 void write_info() const
00087 {
00088 if (setjmp(m_png->jmpbuf))
00089 {
00090 throw error(m_error);
00091 }
00092 m_info.write();
00093 }
00094
00098 void write_row(byte* bytes)
00099 {
00100 if (setjmp(m_png->jmpbuf))
00101 {
00102 throw error(m_error);
00103 }
00104 png_write_row(m_png, bytes);
00105 }
00106
00110 void write_end_info() const
00111 {
00112 if (setjmp(m_png->jmpbuf))
00113 {
00114 throw error(m_error);
00115 }
00116 m_end_info.write();
00117 }
00118
00119 private:
00120 static void write_data(png_struct* png, byte* data, size_t length)
00121 {
00122 io_base* io = static_cast< io_base* >(png_get_error_ptr(png));
00123 writer* wr = static_cast< writer* >(io);
00124 wr->reset_error();
00125 std::ostream* stream
00126 = reinterpret_cast< std::ostream* >(png_get_io_ptr(png));
00127 try
00128 {
00129 stream->write(reinterpret_cast< char* >(data), length);
00130 if (!stream->good())
00131 {
00132 wr->set_error("std::istream::write() failed");
00133 }
00134 }
00135 catch (std::exception const& error)
00136 {
00137 wr->set_error(error.what());
00138 }
00139 catch (...)
00140 {
00141 assert(!"caught something wrong");
00142 wr->set_error("write_data: caught something wrong");
00143 }
00144 if (wr->is_error())
00145 {
00146 wr->raise_error();
00147 }
00148 }
00149
00150 static void flush_data(png_struct* png)
00151 {
00152 io_base* io = static_cast< io_base* >(png_get_error_ptr(png));
00153 writer* wr = static_cast< writer* >(io);
00154 wr->reset_error();
00155 std::ostream* stream
00156 = reinterpret_cast< std::ostream* >(png_get_io_ptr(png));
00157 try
00158 {
00159 stream->flush();
00160 if (!stream->good())
00161 {
00162 wr->set_error("std::istream::flush() failed");
00163 }
00164 }
00165 catch (std::exception const& error)
00166 {
00167 wr->set_error(error.what());
00168 }
00169 catch (...)
00170 {
00171 assert(!"caught something wrong");
00172 wr->set_error("flush_data: caught something wrong");
00173 }
00174 if (wr->is_error())
00175 {
00176 wr->raise_error();
00177 }
00178 }
00179 };
00180
00181 }
00182
00183 #endif // PNGPP_WRITER_HPP_INCLUDED