png++  0.2.7
writer.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007,2008 Alex Shulgin
3  *
4  * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
5  * software; the exact copying conditions are as follows:
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * 3. The name of the author may not be used to endorse or promote products
18  * derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
23  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
25  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 #ifndef PNGPP_WRITER_HPP_INCLUDED
32 #define PNGPP_WRITER_HPP_INCLUDED
33 
34 #include <cassert>
35 #include "io_base.hpp"
36 
37 namespace png
38 {
39 
65  template< class ostream >
66  class writer
67  : public io_base
68  {
69  public:
74  explicit writer(ostream& stream)
75  : io_base(png_create_write_struct(PNG_LIBPNG_VER_STRING,
76  static_cast< io_base* >(this),
78  0))
79  {
80  png_set_write_fn(m_png, & stream, write_data, flush_data);
81  }
82 
84  {
86  png_destroy_write_struct(& m_png, m_info.get_png_info_ptr());
87  }
88 
89  void write_png() const
90  {
91  if (setjmp(png_jmpbuf(m_png)))
92  {
93  throw error(m_error);
94  }
95  png_write_png(m_png,
97  /* transforms = */ 0,
98  /* params = */ 0);
99  }
100 
104  void write_info() const
105  {
106  if (setjmp(png_jmpbuf(m_png)))
107  {
108  throw error(m_error);
109  }
110  m_info.write();
111  }
112 
116  void write_row(byte* bytes)
117  {
118  if (setjmp(png_jmpbuf(m_png)))
119  {
120  throw error(m_error);
121  }
122  png_write_row(m_png, bytes);
123  }
124 
128  void write_end_info() const
129  {
130  if (setjmp(png_jmpbuf(m_png)))
131  {
132  throw error(m_error);
133  }
134  m_end_info.write();
135  }
136 
137  private:
138  static void write_data(png_struct* png, byte* data, size_t length)
139  {
140  io_base* io = static_cast< io_base* >(png_get_error_ptr(png));
141  writer* wr = static_cast< writer* >(io);
142  wr->reset_error();
143  ostream* stream = reinterpret_cast< ostream* >(png_get_io_ptr(png));
144  try
145  {
146  stream->write(reinterpret_cast< char* >(data), length);
147  if (!stream->good())
148  {
149  wr->set_error("ostream::write() failed");
150  }
151  }
152  catch (std::exception const& error)
153  {
154  wr->set_error(error.what());
155  }
156  catch (...)
157  {
158  assert(!"caught something wrong");
159  wr->set_error("write_data: caught something wrong");
160  }
161  if (wr->is_error())
162  {
163  wr->raise_error();
164  }
165  }
166 
167  static void flush_data(png_struct* png)
168  {
169  io_base* io = static_cast< io_base* >(png_get_error_ptr(png));
170  writer* wr = static_cast< writer* >(io);
171  wr->reset_error();
172  ostream* stream = reinterpret_cast< ostream* >(png_get_io_ptr(png));
173  try
174  {
175  stream->flush();
176  if (!stream->good())
177  {
178  wr->set_error("ostream::flush() failed");
179  }
180  }
181  catch (std::exception const& error)
182  {
183  wr->set_error(error.what());
184  }
185  catch (...)
186  {
187  assert(!"caught something wrong");
188  wr->set_error("flush_data: caught something wrong");
189  }
190  if (wr->is_error())
191  {
192  wr->raise_error();
193  }
194  }
195  };
196 
197 } // namespace png
198 
199 #endif // PNGPP_WRITER_HPP_INCLUDED
end_info m_end_info
Definition: io_base.hpp:461
void write() const
Definition: info.hpp:96
writer(ostream &stream)
Constructs a writer prepared to write PNG image into a stream.
Definition: writer.hpp:74
Base class for PNG reader/writer classes.
Definition: io_base.hpp:62
~writer()
Definition: writer.hpp:83
io_base(png_struct *png)
Definition: io_base.hpp:68
void write_png() const
Definition: writer.hpp:89
bool is_error() const
Definition: io_base.hpp:442
void write_info() const
Write info about PNG image.
Definition: writer.hpp:104
info m_info
Definition: io_base.hpp:460
void write() const
Definition: end_info.hpp:64
std::string m_error
Definition: io_base.hpp:462
void raise_error()
Definition: io_base.hpp:447
png_struct * m_png
Definition: io_base.hpp:459
png_info * get_png_info() const
Definition: info_base.hpp:59
png_info ** get_png_info_ptr()
Definition: info_base.hpp:64
png_byte byte
Definition: types.hpp:39
void write_end_info() const
Reads ending info about PNG image.
Definition: writer.hpp:128
void reset_error()
Definition: io_base.hpp:430
PNG writer class template. This is the low-level writing interface–use image class or generator clas...
Definition: writer.hpp:66
void destroy()
Definition: end_info.hpp:53
Definition: color.hpp:36
Exception class to represent runtime errors related to png++ operation.
Definition: error.hpp:47
void set_error(char const *message)
Definition: io_base.hpp:424
void write_row(byte *bytes)
Writes a row of image data at a time.
Definition: writer.hpp:116