Gorgon Game Engine
PNG.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vector>
4 #include <fstream>
5 #include <functional>
6 
7 #include "../Types.h"
8 #include "../Geometry/Size.h"
9 #include "../Containers/Image.h"
10 
11 extern "C" {
12  struct png_struct_def;
13 }
14 
15 namespace Gorgon { namespace Encoding {
16 
18  namespace png {
19 
20  //Streamer bases
21  class Reader {
22  public:
23  void (*Read)(png_struct_def *p, unsigned char *buf, size_t size);
24  };
25 
26  class Writer {
27  public:
28  void (*Write)(png_struct_def *p, unsigned char *buf, size_t size);
29  };
30 
31  //Vector streamers
32  class VectorReader;
33  void ReadVector(png_struct_def *p, unsigned char *buf, size_t size);
34 
35  class VectorReader : public Reader {
36  public:
37  VectorReader(const std::vector<Byte> &Buf) : Buf(Buf), BufPos(0) {
38  Read=&ReadVector;
39  }
40 
41  const std::vector<Byte> &Buf;
42  unsigned BufPos;
43  };
44  inline Reader *ReadyReadStruct(const std::vector<Byte> &vec) {
45  return new VectorReader(vec);
46  }
47  inline unsigned long long GetReadSize(const std::vector<Byte> &vec) {
48  return vec.size();
49  }
50  inline void VectorSeek(Reader *r, long long addr) {
51  VectorReader *reader=(VectorReader *)r;
52  reader->BufPos+=(unsigned)addr;
53  }
54  inline std::function<void(Reader*, long long)> SeekFn(const std::vector<Byte> &vec) {
55  return &VectorSeek;
56  }
57 
58  class VectorWriter;
59  void WriteVector(png_struct_def *p, unsigned char *buf, size_t size);
60  class VectorWriter : public Writer {
61  public:
62  VectorWriter(std::vector<Byte> &Buf) : Buf(Buf) {
63  Write=&WriteVector;
64  }
65 
66  std::vector<Byte> &Buf;
67  };
68  inline Writer *ReadyWriteStruct(std::vector<Byte> &vec) {
69  return new VectorWriter(vec);
70  }
71 
72  class ArrayWrapper {
73  public:
74  ArrayWrapper() = default;
75  ArrayWrapper(const Byte *data, std::size_t size) : data(data), size(size) { }
76 
77  const Byte *data = nullptr;
78  std::size_t size = 0;
79  };
80 
81  //Array streamers
82  class ArrayReader;
83  void ReadArray(png_struct_def *p, unsigned char *buf, size_t size);
84 
85  class ArrayReader : public Reader {
86  public:
87  ArrayReader(ArrayWrapper Buf) : Buf(Buf), BufPos(0) {
88  Read=&ReadArray;
89  }
90 
91  ArrayWrapper Buf;
92  unsigned BufPos;
93  };
94  inline Reader *ReadyReadStruct(ArrayWrapper f) {
95  return new ArrayReader(f);
96  }
97  inline unsigned long long GetReadSize(const ArrayWrapper &vec) {
98  return vec.size;
99  }
100  inline void ArraySeek(Reader *r, long long addr) {
101  ArrayReader *reader=(ArrayReader *)r;
102  reader->BufPos+=(unsigned)addr;
103  }
104  inline std::function<void(Reader*, long long)> SeekFn(const ArrayWrapper &) {
105  return &ArraySeek;
106  }
107 
108 
109  //File streamers
110  class FileReader;
111  void ReadFile(png_struct_def *p, unsigned char *buf, size_t size);
112  unsigned long long GetReadSize(std::istream &f);
113  class FileReader : public Reader {
114  public:
115  FileReader(std::istream &Buf) : Buf(Buf) {
116  Read=&ReadFile;
117  }
118 
119  std::istream &Buf;
120  };
121  inline Reader *ReadyReadStruct(std::istream &f) {
122  return new FileReader(f);
123  }
124  inline unsigned long long GetReadSize(std::istream &f) {
125  auto c=f.tellg();
126  f.seekg(0, std::ios::end);
127  auto e=f.tellg();
128  f.seekg(c, std::ios::beg);
129  return e-c;
130  }
131  inline void FileSeek(Reader *r, long long addr) {
132  FileReader *reader=(FileReader *)r;
133  reader->Buf.seekg(addr, std::ios::cur);
134  }
135  inline std::function<void(Reader*, long long)> SeekFn(std::istream &vec) {
136  return &FileSeek;
137  }
138 
139  class FileWriter;
140  void WriteFile(png_struct_def *p, unsigned char *buf, size_t size);
141  class FileWriter : public Writer {
142  public:
143  FileWriter(std::ostream &Buf) : Buf(Buf) {
144  Write=&WriteFile;
145  }
146 
147  std::ostream &Buf;
148  };
149  inline Writer *ReadyWriteStruct(std::ostream &f) {
150  return new FileWriter(f);
151  }
152  }
154 
156  class PNG {
157  public:
158 
163  void Encode(const Containers::Image &input, std::ostream &output, bool replace_colormode = false) {
164  encode(input, png::ReadyWriteStruct(output), replace_colormode);
165  }
166 
169  void Encode(const Containers::Image &input, const std::string &output, bool replace_colormode = false) {
170  std::ofstream file(output, std::ios::binary);
171  if(!file.is_open()) throw std::runtime_error("Cannot open file");
172  encode(input, png::ReadyWriteStruct(file), replace_colormode);
173  }
174 
179  void Encode(const Containers::Image &input, std::vector<Byte> &output, bool replace_colormode = false) {
180  encode(input, png::ReadyWriteStruct(output), replace_colormode);
181  }
182 
186  void Decode(std::istream &input, Containers::Image &output) {
187  return decode(png::ReadyReadStruct(input), output);
188  }
189 
193  void Decode(const std::string &input, Containers::Image &output) {
194  std::ifstream file(input, std::ios::binary);
195  if(!file.is_open()) throw std::runtime_error("Cannot open file");
196  return decode(png::ReadyReadStruct(file), output);
197  }
198 
202  void Decode(std::vector<Byte> &input, Containers::Image &output) {
203  return decode(png::ReadyReadStruct(input), output);
204  }
205 
209  void Decode(const Byte *input, std::size_t size, Containers::Image &output) {
210  return decode(png::ReadyReadStruct(png::ArrayWrapper(input, size)), output);
211  }
212 
213 
214  protected:
216  void encode(const Containers::Image &input, png::Writer *write, bool replace_colormode);
217 
219  void decode(png::Reader *reader, Containers::Image &output);
220 
221  };
222 
224  extern PNG Png;
225 
226 } }
Gorgon::Resource::GID::PNG
constexpr Type PNG
PNG compression.
Definition: GID.h:126
Gorgon::Containers::basic_Image::GetMode
Graphics::ColorMode GetMode() const
Returns the color mode of the image.
Definition: Image.h:1311
Gorgon::Containers::basic_Image::Resize
void Resize(const Geometry::Size &size, Graphics::ColorMode mode)
Resizes the image to the given size and color mode.
Definition: Image.h:71
Gorgon::Graphics::ColorMode
ColorMode
Color modes for images.
Definition: Color.h:16
Gorgon::Encoding::Png
PNG Png
A ready to use PNG class.
Definition: PNG.cpp:304
Gorgon::Graphics::ColorMode::RGB
@ RGB
24bit red, green, blue color mode that has red component in the lowest byte order
Gorgon::Graphics::ColorMode::Invalid
@ Invalid
This is used to mark invalid color data.
Gorgon::Encoding::png::WriteVector
void WriteVector(png_struct *p, unsigned char *buf, size_t size)
Definition: PNG.cpp:39
Gorgon::Containers::basic_Image::RawData
Byte * RawData()
Returns the raw data pointer.
Definition: Image.h:211
Gorgon::Geometry::basic_Size::Height
T_ Height
Height of this size object.
Definition: Size.h:261
Gorgon::Graphics::ColorMode::RGBA
@ RGBA
32bit red, green, blue and alpha channel image. Red component is in the lowest byte order and
Gorgon::Encoding::PNG::Encode
void Encode(const Containers::Image &input, std::vector< Byte > &output, bool replace_colormode=false)
Encodes a given input.
Definition: PNG.h:179
Gorgon::Encoding::PNG::Encode
void Encode(const Containers::Image &input, std::ostream &output, bool replace_colormode=false)
Encodes a given input.
Definition: PNG.h:163
Gorgon::Encoding::png::ReadFile
void ReadFile(png_struct_def *p, unsigned char *buf, size_t size)
Definition: PNG.cpp:12
Gorgon::Encoding::PNG::encode
void encode(const Containers::Image &input, png::Writer *write, bool replace_colormode)
Performs actual encoding.
Definition: PNG.cpp:189
Gorgon::Encoding::png::ReadArray
void ReadArray(png_struct *p, unsigned char *buf, size_t size)
Definition: PNG.cpp:23
Gorgon::Encoding::PNG::decode
void decode(png::Reader *reader, Containers::Image &output)
Performs actual decoding.
Definition: PNG.cpp:50
Gorgon::Graphics::ColorMode::Grayscale
@ Grayscale
8bit gray scale color mode
Gorgon::Containers::basic_Image::GetTotalSize
unsigned long GetTotalSize() const
Total size of this image in number units.
Definition: Image.h:1306
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::Geometry::basic_Size
This class represents a 2D geometric size.
Definition: Size.h:23
Gorgon::Encoding::PNG::Encode
void Encode(const Containers::Image &input, const std::string &output, bool replace_colormode=false)
Encodes a given input.
Definition: PNG.h:169
PNG.h
Gorgon::Encoding::png::ReadVector
void ReadVector(png_struct *p, unsigned char *buf, size_t size)
Definition: PNG.cpp:32
Gorgon::Encoding::PNG
Encodes or decodes PNG compression.
Definition: PNG.h:156
Gorgon::Graphics::ColorMode::Alpha
@ Alpha
8bit alpha only color mode
Gorgon::Byte
unsigned char Byte
Represents smallest cell in memory.
Definition: Types.h:9
Gorgon::Containers::basic_Image
This class is a container for image data.
Definition: Image.h:19
Gorgon::Encoding::PNG::Decode
void Decode(std::istream &input, Containers::Image &output)
Decodes the given PNG data.
Definition: PNG.h:186
Gorgon::Geometry::basic_Size::Width
T_ Width
Width of this size object.
Definition: Size.h:258
Gorgon::end
std::vector< T_ >::const_iterator end(enum_type_id< T_ >)
Definition: Enum.h:288
Gorgon::Encoding::PNG::Decode
void Decode(const std::string &input, Containers::Image &output)
Decodes the given PNG data.
Definition: PNG.h:193
Gorgon::Encoding::PNG::Decode
void Decode(const Byte *input, std::size_t size, Containers::Image &output)
Decodes the given PNG data.
Definition: PNG.h:209
Gorgon::Encoding::PNG::Decode
void Decode(std::vector< Byte > &input, Containers::Image &output)
Decodes the given PNG data.
Definition: PNG.h:202
Gorgon::Containers::basic_Image::GetSize
Geometry::Size GetSize() const
Returns the size of the image.
Definition: Image.h:1291
Gorgon::Containers::basic_Image::GetChannelsPerPixel
unsigned GetChannelsPerPixel() const
Returns the number units occupied by a single pixel of this image.
Definition: Image.h:1326
Gorgon::Encoding::png::WriteFile
void WriteFile(png_struct *p, unsigned char *buf, size_t size)
Definition: PNG.cpp:19