VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
grpng.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file grpng.h
19 ///
20 
21 #ifndef GR_PNG__H
22 #define GR_PNG__H
23 
24 #include "gdef.h"
25 #include "grdef.h"
26 #include "grimagedata.h"
27 #include "grimagebuffer.h"
28 #include "gpath.h"
29 #include "gexception.h"
30 #include <istream>
31 #include <map>
32 #include <utility>
33 #include <string>
34 #include <cstdio>
35 #include <vector>
36 
37 namespace Gr
38 {
39  class Png ;
40  class PngInfo ;
41  class PngReader ;
42  class PngWriter ;
43  //
44  class PngImp ;
45  class PngTagsImp ;
46  class PngReaderImp ;
47  class PngWriterImp ;
48 }
49 
50 /// \class Gr::Png
51 /// A static class providing information about the png library.
52 ///
53 class Gr::Png
54 {
55 public:
56  G_EXCEPTION( Error , "png error" ) ;
57 
58  static bool available() ;
59  ///< Returns true if the png library is available.
60 
61 private:
62  Png() ;
63 } ;
64 
65 /// \class Gr::PngInfo
66 /// A class that reads a png header in order to provide the image dimensions.
67 /// The number of channels is not provided because PngReader always transforms to
68 /// three channels. An implementation of PngInfo is available even without libpng.
69 /// Png files must have the IHDR as the first chunk, so it is sufficient to supply
70 /// only 30 bytes to be correctly parsed.
71 ///
73 {
74 public:
75  explicit PngInfo( std::istream & ) ;
76  ///< Constructor.
77 
78  PngInfo( const unsigned char * p , size_t ) ;
79  ///< Constructor.
80 
81  PngInfo( const char * p , size_t ) ;
82  ///< Constructor overload for char.
83 
84  PngInfo( const ImageBuffer & ) ;
85  ///< Constructor overload for ImageBuffer.
86 
87  bool valid() const ;
88  ///< Returns true if successfully constructed.
89 
90  int dx() const ;
91  ///< Returns the image width. Returns zero on error.
92 
93  int dy() const ;
94  ///< Returns the image height. Returns zero on error.
95 
96 private:
97  PngInfo( const PngInfo & ) ;
98  void operator=( const PngInfo & ) ;
99  void init( const unsigned char * , size_t ) ;
100  void init( std::istream & ) ;
101  static std::pair<int,int> parse( const unsigned char * , size_t ) ;
102 
103 private:
104  int m_dx ;
105  int m_dy ;
106 } ;
107 
108 /// \class Gr::PngReader
109 /// A read interface for libpng.
110 ///
112 {
113 public:
114  typedef std::multimap<std::string,std::string> Map ;
115 
116  PngReader( int scale = 1 , bool monochrome_out = false ) ;
117  ///< Constructor.
118 
119  ~PngReader() ;
120  ///< Destructor.
121 
122  void setup( int scale , bool monochrome_out = false ) ;
123  ///< Sets the decoding scale factor.
124 
125  void decode( ImageData & out , const G::Path & in ) ;
126  ///< Decodes a png file into an image. Throws on error.
127 
128  void decode( ImageData & out , const char * p_in , size_t n ) ;
129  ///< Decodes a png data buffer into an image. Throws on error.
130 
131  void decode( ImageData & out , const unsigned char * p_in , size_t n ) ;
132  ///< Decodes a png data buffer into an image. Throws on error.
133 
134  void decode( ImageData & out , const ImageBuffer & ) ;
135  ///< Decodes a png image buffer into an image. Throws on error.
136 
137  Map tags() const ;
138  ///< Returns the text tags from the last decode().
139 
140 private:
141  PngReader( const PngReader & ) ;
142  void operator=( const PngReader & ) ;
143 
144 private:
145  int m_scale ;
146  bool m_monochrome_out ;
147  Map m_tags ;
148 } ;
149 
150 /// \class Gr::PngWriter
151 /// An interface for writing a raw dgb image as a png file.
152 ///
154 {
155 public:
156  typedef std::multimap<std::string,std::string> Map ;
157 
158  struct Output /// Abstract interface for Gr::PngWriter::write().
159  {
160  virtual void operator()( const unsigned char * , size_t ) = 0 ;
161  virtual ~Output() {}
162  } ;
163 
164  explicit PngWriter( const ImageData & , Map tags = Map() ) ;
165  ///< Constructor with the raw image data prepared in a ImageData
166  ///< object. The references are kept.
167 
168  ~PngWriter() ;
169  ///< Destructor.
170 
171  void write( const G::Path & path ) ;
172  ///< Writes to file.
173 
174  void write( Output & out ) ;
175  ///< Writes to an Output interface.
176 
177 private:
178  PngWriter( const PngWriter & ) ;
179  void operator=( const PngWriter & ) ;
180 
181 private:
182  PngWriterImp * m_imp ;
183 } ;
184 
185 
186 inline
187 Gr::PngInfo::PngInfo( std::istream & stream ) :
188  m_dx(0) ,
189  m_dy(0)
190 {
191  init( stream ) ;
192 }
193 
194 inline
195 Gr::PngInfo::PngInfo( const unsigned char * p , size_t n ) :
196  m_dx(0) ,
197  m_dy(0)
198 {
199  init( p , n ) ;
200 }
201 
202 inline
203 Gr::PngInfo::PngInfo( const char * p , size_t n ) :
204  m_dx(0) ,
205  m_dy(0)
206 {
207  init( reinterpret_cast<const unsigned char *>(p) , n ) ;
208 }
209 
210 inline
211 Gr::PngInfo::PngInfo( const ImageBuffer & image_buffer ) :
212  m_dx(0) ,
213  m_dy(0)
214 {
216  imagebuf buf( image_buffer ) ;
217  std::istream in( &buf ) ;
218  init( in ) ;
219 }
220 
221 inline
222 bool Gr::PngInfo::valid() const
223 {
224  return m_dx > 0 && m_dy > 0 ;
225 }
226 
227 inline
228 int Gr::PngInfo::dx() const
229 {
230  return m_dx ;
231 }
232 
233 inline
234 int Gr::PngInfo::dy() const
235 {
236  return m_dy ;
237 }
238 
239 inline
240 std::pair<int,int> Gr::PngInfo::parse( const unsigned char * p , size_t n )
241 {
242  unsigned int dx = 0U ;
243  unsigned int dy = 0U ;
244  if( n > 29U &&
245  p[0] == 0x89 && p[1] == 0x50 && p[2] == 0x4e && p[3] == 0x47 && // .PNG
246  p[4] == 0x0d && p[5] == 0x0a && p[6] == 0x1a && p[7] == 0x0a &&
247  p[12] == 0x49 && p[13] == 0x48 && p[14] == 0x44 && p[15] == 0x52 ) // IHDR
248  {
249  dx += p[16] ; dx <<= 8 ;
250  dx += p[17] ; dx <<= 8 ;
251  dx += p[18] ; dx <<= 8 ;
252  dx += p[19] ;
253  dy += p[20] ; dy <<= 8 ;
254  dy += p[21] ; dy <<= 8 ;
255  dy += p[22] ; dy <<= 8 ;
256  dy += p[23] ;
257  }
258  return std::make_pair( static_cast<int>(dx) , static_cast<int>(dy) ) ;
259 }
260 
261 #endif
~PngReader()
Destructor.
Definition: grpng_none.cpp:29
PngInfo(std::istream &)
Constructor.
Definition: grpng.h:187
Map tags() const
Returns the text tags from the last decode().
Definition: grpng_none.cpp:34
A read interface for libpng.
Definition: grpng.h:111
A traits class that can be specialised for Gr::ImageBuffer candidates.
Definition: grtraits.h:34
A holder for image data, having eight bits per sample and one or three channels.
Definition: grimagedata.h:46
Vectors ImageBuffer
An ImageBuffer is used to hold raw image data, typically in more than one chunk.
Definition: grimagebuffer.h:47
A class that reads a png header in order to provide the image dimensions.
Definition: grpng.h:72
PngWriter(const ImageData &, Map tags=Map())
Constructor with the raw image data prepared in a ImageData object.
Definition: grpng_none.cpp:35
A static class providing information about the png library.
Definition: grpng.h:53
A private pimple-pattern class for Gr::PngWriter.
Definition: grpng_none.cpp:26
int dy() const
Returns the image height. Returns zero on error.
Definition: grpng.h:234
void decode(ImageData &out, const G::Path &in)
Decodes a png file into an image. Throws on error.
Definition: grpng_none.cpp:32
int dx() const
Returns the image width. Returns zero on error.
Definition: grpng.h:228
bool valid() const
Returns true if successfully constructed.
Definition: grpng.h:222
PngReader(int scale=1, bool monochrome_out=false)
Constructor.
Definition: grpng_none.cpp:28
void setup(int scale, bool monochrome_out=false)
Sets the decoding scale factor.
Definition: grpng_none.cpp:30
static bool available()
Returns true if the png library is available.
Definition: grpng_none.cpp:27
~PngWriter()
Destructor.
Definition: grpng_png.cpp:507
A Path object represents a file system path.
Definition: gpath.h:72
An interface for writing a raw dgb image as a png file.
Definition: grpng.h:153
Abstract interface for Gr::PngWriter::write().
Definition: grpng.h:158
void write(const G::Path &path)
Writes to file.
Definition: grpng_none.cpp:36