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_GENERATOR_HPP_INCLUDED
00032 #define PNGPP_GENERATOR_HPP_INCLUDED
00033
00034 #include <cassert>
00035 #include <stdexcept>
00036 #include <iostream>
00037 #include <ostream>
00038
00039 #include <endian.h>
00040
00041 #include "error.hpp"
00042 #include "streaming_base.hpp"
00043 #include "writer.hpp"
00044
00045 namespace png
00046 {
00047
00113 template< typename pixel,
00114 class pixgen,
00115 class info_holder = def_image_info_holder,
00116 bool interlacing_supported = false >
00117 class generator
00118 : public streaming_base< pixel, info_holder >
00119 {
00120 public:
00129 template< typename ostream >
00130 void write(ostream& stream)
00131 {
00132 writer< ostream > wr(stream);
00133 wr.set_image_info(this->get_info());
00134 wr.write_info();
00135
00136 #if __BYTE_ORDER == __LITTLE_ENDIAN
00137 if (pixel_traits< pixel >::get_bit_depth() == 16)
00138 {
00139 #ifdef PNG_WRITE_SWAP_SUPPORTED
00140 wr.set_swap();
00141 #else
00142 throw error("Cannot write 16-bit image --"
00143 " recompile with PNG_WRITE_SWAP_SUPPORTED.");
00144 #endif
00145 }
00146 #endif
00147
00148 size_t pass_count;
00149 if (this->get_info().get_interlace_type() != interlace_none)
00150 {
00151 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
00152 if (interlacing_supported)
00153 {
00154 pass_count = wr.set_interlace_handling();
00155 }
00156 else
00157 {
00158 throw std::logic_error("Cannot write interlaced image --"
00159 " generator does not support it.");
00160 }
00161 #else
00162 throw error("Cannot write interlaced image --"
00163 " interlace handling disabled.");
00164 #endif
00165 }
00166 else
00167 {
00168 pass_count = 1;
00169 }
00170 pixgen* pixel_gen = static_cast< pixgen* >(this);
00171 for (size_t pass = 0; pass < pass_count; ++pass)
00172 {
00173 pixel_gen->reset(pass);
00174
00175 for (size_t pos = 0; pos < this->get_info().get_height(); ++pos)
00176 {
00177 wr.write_row(pixel_gen->get_next_row(pos));
00178 }
00179 }
00180
00181 wr.write_end_info();
00182 }
00183
00184 protected:
00185 typedef streaming_base< pixel, info_holder > base;
00186
00191 explicit generator(image_info& info)
00192 : base(info)
00193 {
00194 }
00195
00200 generator(size_t width, size_t height)
00201 : base(width, height)
00202 {
00203 }
00204 };
00205
00206 }
00207
00208 #endif // PNGPP_GENERATOR_HPP_INCLUDED