png++  0.2.9
consumer.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_CONSUMER_HPP_INCLUDED
32 #define PNGPP_CONSUMER_HPP_INCLUDED
33 
34 #include <cassert>
35 #include <stdexcept>
36 #include <iostream>
37 #include <istream>
38 
39 #include "config.hpp"
40 #include "error.hpp"
41 #include "streaming_base.hpp"
42 #include "reader.hpp"
43 #include "pixel_buffer.hpp"
44 
45 namespace png
46 {
47 
121  template< typename pixel,
122  class pixcon,
123  class info_holder = def_image_info_holder,
124  bool interlacing_supported = false >
125  class consumer
126  : public streaming_base< pixel, info_holder >
127  {
128  public:
130 
135  {
136  void operator()(io_base&) const {}
137  };
138 
143  template< typename istream >
144  void read(istream& stream)
145  {
146  read(stream, transform_identity());
147  }
148 
157  template< typename istream, class transformation >
158  void read(istream& stream, transformation const& transform)
159  {
160  reader< istream > rd(stream);
161  rd.read_info();
162  transform(rd);
163 
164 #if __BYTE_ORDER == __LITTLE_ENDIAN
166  {
167 #ifdef PNG_READ_SWAP_SUPPORTED
168  rd.set_swap();
169 #else
170  throw error("Cannot read 16-bit image: recompile with PNG_READ_SWAP_SUPPORTED.");
171 #endif
172  }
173 #endif
174 
175  // interlace handling _must_ be set up prior to info update
176  size_t pass_count;
178  {
179 #ifdef PNG_READ_INTERLACING_SUPPORTED
180  pass_count = rd.set_interlace_handling();
181 #else
182  throw error("Cannot read interlaced image: interlace handling disabled.");
183 #endif
184  }
185  else
186  {
187  pass_count = 1;
188  }
189 
190  rd.update_info();
191  if (rd.get_color_type() != traits::get_color_type()
192  || rd.get_bit_depth() != traits::get_bit_depth())
193  {
194  throw std::logic_error("color type and/or bit depth mismatch"
195  " in png::consumer::read()");
196  }
197 
198  this->get_info() = rd.get_image_info();
199 
200  pixcon* pixel_con = static_cast< pixcon* >(this);
201  if (pass_count > 1 && !interlacing_supported)
202  {
203  skip_interlaced_rows(rd, pass_count);
204  pass_count = 1;
205  }
206  read_rows(rd, pass_count, pixel_con);
207 
208  rd.read_end_info();
209  }
210 
211  protected:
213 
219  : base(info)
220  {
221  }
222 
223  private:
224  template< typename istream >
225  void skip_interlaced_rows(reader< istream >& rd, size_t pass_count)
226  {
227  typedef std::vector< pixel > row;
228  typedef row_traits< row > row_traits_type;
229  row dummy_row(this->get_info().get_width());
230  for (size_t pass = 1; pass < pass_count; ++pass)
231  {
232  rd.read_row(reinterpret_cast< byte* >
233  (row_traits_type::get_data(dummy_row)));
234  }
235  }
236 
237  template< typename istream >
238  void read_rows(reader< istream >& rd, size_t pass_count,
239  pixcon* pixel_con)
240  {
241  for (size_t pass = 0; pass < pass_count; ++pass)
242  {
243  pixel_con->reset(pass);
244 
245  for (uint_32 pos = 0; pos < this->get_info().get_height(); ++pos)
246  {
247  rd.read_row(pixel_con->get_next_row(pos));
248  }
249  }
250  }
251  };
252 
253 } // namespace png
254 
255 #endif // PNGPP_CONSUMER_HPP_INCLUDED
int get_bit_depth() const
Definition: io_base.hpp:150
The pixel row traits class template. Provides a common way to get starting address of the row for pac...
Definition: pixel_buffer.hpp:53
Base class for PNG reader/writer classes.
Definition: io_base.hpp:62
void read_info()
Reads info about PNG image.
Definition: reader.hpp:108
pixel_traits< pixel > traits
Definition: consumer.hpp:129
color_type get_color_type() const
Definition: io_base.hpp:140
The PNG reader class template. This is the low-level reading interface–use image class or consumer c...
Definition: reader.hpp:65
Pixel traits class template.
Definition: pixel_traits.hpp:48
image_info const & get_info() const
Definition: streaming_base.hpp:107
uint_32 get_height() const
Definition: image_info.hpp:77
Holds information about PNG image.
Definition: image_info.hpp:47
void read_row(byte *bytes)
Reads a row of image data at a time.
Definition: reader.hpp:120
void read_end_info()
Reads ending info about PNG image.
Definition: reader.hpp:132
png_uint_32 uint_32
Definition: types.hpp:41
A base class template for consumer and generator classes. Provides default reset() method implementat...
Definition: streaming_base.hpp:90
Pixel consumer class template.
Definition: consumer.hpp:125
void read(istream &stream, transformation const &transform)
Reads an image from the stream using custom io transformation.
Definition: consumer.hpp:158
int set_interlace_handling() const
Definition: io_base.hpp:376
void update_info()
Definition: reader.hpp:141
Definition: types.hpp:81
void operator()(io_base &) const
Definition: consumer.hpp:136
The default io transformation: does nothing.
Definition: consumer.hpp:134
Holds information about PNG image. Adapter class for IO image operations.
Definition: info.hpp:45
consumer(image_info &info)
Constructs a consumer object using passed image_info object to store image information.
Definition: consumer.hpp:218
image_info const & get_image_info() const
Definition: io_base.hpp:97
Definition: color.hpp:36
interlace_type get_interlace_type() const
Definition: io_base.hpp:160
void read(istream &stream)
Reads an image from the stream using default io transformation.
Definition: consumer.hpp:144
Exception class to represent runtime errors related to png++ operation.
Definition: error.hpp:57
streaming_base< pixel, info_holder > base
Definition: consumer.hpp:212
void set_swap() const
Definition: io_base.hpp:312