Gorgon Game Engine
LZMA.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <string.h>
4 #include <vector>
5 #include <functional>
6 #include <algorithm>
7 #include <istream>
8 #include <cstring>
9 
10 #include "../Types.h"
11 
12 
13 namespace Gorgon { namespace Encoding {
14 
16  namespace lzma {
17 
18  //Streamer bases
19  class Reader {
20  public:
21  int (*Read)(void *p, void *buf, size_t *size);
22  };
23 
24  class Writer {
25  public:
26  std::size_t (*Write)(void *p, const void *buf, size_t size);
27  };
28 
29 
30 
31  //Vector streamers
32  class VectorReader;
33  int ReadVector(void *p, void *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  std::size_t 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  inline int ReadVector(void *p, void *buf, size_t *size) {
58  VectorReader *reader = (VectorReader*)p;
59  *size = std::min(*size, reader->Buf.size() - reader->BufPos);
60  if (*size)
61  std::memcpy(buf, &reader->Buf[reader->BufPos], *size);
62  reader->BufPos += *size;
63  return 0;
64  }
65 
66  class VectorWriter;
67  std::size_t WriteVector(void *p, const void *buf, size_t size);
68  class VectorWriter : public Writer {
69  public:
70  VectorWriter(std::vector<Byte> &Buf) : Buf(Buf) {
71  Write=&WriteVector;
72  }
73 
74  std::vector<Byte> &Buf;
75  };
76  inline Writer *ReadyWriteStruct(std::vector<Byte> &vec) {
77  return new VectorWriter(vec);
78  }
79  inline std::size_t WriteVector(void *p, const void *buf, size_t size) {
80  VectorWriter *writer = (VectorWriter*)p;
81  if (size)
82  {
83  std::size_t oldSize = writer->Buf.size();
84  writer->Buf.resize(oldSize + size);
85  std::memcpy(&writer->Buf[oldSize], buf, size);
86  }
87  return size;
88  }
89 
90 
91  //Array streamers
92  class ArrayReader;
93  int ReadArray(void *p, void *buf, size_t *size);
94 
95  class ArrayReader : public Reader {
96  public:
97  ArrayReader(const Byte *Buf) : Buf(Buf), BufPos(0) {
98  Read=&ReadArray;
99  }
100 
101  const Byte *Buf;
102  std::size_t BufPos;
103  };
104  inline Reader *ReadyReadStruct(const Byte *vec) {
105  return new ArrayReader(vec);
106  }
107  inline unsigned long long GetReadSize(const Byte *vec) {
108  return (unsigned long long)(long long)-1;
109  }
110  inline void ArraySeek(Reader *r, long long addr) {
111  ArrayReader *reader=(ArrayReader *)r;
112  reader->BufPos+=(unsigned)addr;
113  }
114  inline std::function<void(Reader*, long long)> SeekFn(const Byte *vec) {
115  return &ArraySeek;
116  }
117  inline int ReadArray(void *p, void *buf, size_t *size) {
118  ArrayReader *reader = (ArrayReader*)p;
119  std::memcpy(buf, &reader->Buf[reader->BufPos], *size);
120  reader->BufPos += *size;
121  return 0;
122  }
123 
124  class ArrayWriter;
125  std::size_t WriteArray(void *p, const void *buf, size_t size);
126  class ArrayWriter : public Writer {
127  public:
128  ArrayWriter(Byte *Buf) : Buf(Buf), BufPos(0) {
129  Write=&WriteArray;
130  }
131 
132  Byte *Buf;
133  std::size_t BufPos;
134  };
135  inline Writer *ReadyWriteStruct(Byte *vec) {
136  return new ArrayWriter(vec);
137  }
138  inline std::size_t WriteArray(void *p, const void *buf, size_t size) {
139  ArrayWriter *writer = (ArrayWriter*)p;
140  if (size)
141  {
142  std::memcpy(&writer->Buf[writer->BufPos], buf, size);
143  writer->BufPos+=size;
144  }
145  return size;
146  }
147 
148 
149  //String streamers
150  class StringReader;
151  int ReadString(void *p, void *buf, size_t *size);
152 
153  class StringReader : public Reader {
154  public:
155  StringReader(const std::string &Buf) : Buf(Buf), BufPos(0) {
156  Read=&ReadString;
157  }
158 
159  const std::string &Buf;
160  std::size_t BufPos;
161  };
162  inline Reader *ReadyReadStruct(const std::string &vec) {
163  return new StringReader(vec);
164  }
165  inline unsigned long long GetReadSize(const std::string &vec) {
166  return vec.size();
167  }
168  inline void StringSeek(Reader *r, long long addr) {
169  StringReader *reader=(StringReader *)r;
170  reader->BufPos+=(unsigned)addr;
171  }
172  inline std::function<void(Reader*, long long)> SeekFn(const std::string &vec) {
173  return &StringSeek;
174  }
175  inline int ReadString(void *p, void *buf, size_t *size) {
176  StringReader *reader = (StringReader*)p;
177  *size = std::min(*size, reader->Buf.size() - reader->BufPos);
178  if (*size)
179  std::memcpy(buf, &reader->Buf[reader->BufPos], *size);
180  reader->BufPos += *size;
181  return 0;
182  }
183 
184  class StringWriter;
185  std::size_t WriteString(void *p, const void *buf, size_t size);
186  class StringWriter : public Writer {
187  public:
188  StringWriter(std::string &Buf) : Buf(Buf), BufPos(0) {
189  Write=&WriteString;
190  }
191 
192  std::string &Buf;
193  std::size_t BufPos;
194  };
195  inline Writer *ReadyWriteStruct(std::string &vec) {
196  return new StringWriter(vec);
197  }
198  inline std::size_t WriteString(void *p, const void *buf, size_t size) {
199  StringWriter *writer = (StringWriter*)p;
200  if (size)
201  {
202  std::size_t oldSize = writer->Buf.size();
203  writer->Buf.resize(oldSize + size);
204  std::memcpy(&writer->Buf[oldSize], buf, size);
205  }
206  return size;
207  }
208 
209  //File streamers
210  class FileReader;
211  int ReadFile(void *p, void *buf, size_t *size);
212  unsigned long long GetReadSize(std::istream &f);
213  class FileReader : public Reader {
214  public:
215  FileReader(std::istream &Buf) : Buf(Buf) {
216  Read=&ReadFile;
217  }
218 
219  std::istream &Buf;
220  };
221  inline Reader *ReadyReadStruct(std::istream &f) {
222  return new FileReader(f);
223  }
224  inline unsigned long long GetReadSize(std::istream &f) {
225  auto c=f.tellg();
226  f.seekg(0, std::ios::end);
227  auto e=f.tellg();
228  f.seekg(c, std::ios::beg);
229  return e-c;
230  }
231  inline void FileSeek(Reader *r, long long addr) {
232  FileReader *reader=(FileReader *)r;
233  reader->Buf.seekg(addr, std::ios::cur);
234  }
235  inline std::function<void(Reader*, long long)> SeekFn(std::istream &vec) {
236  return &FileSeek;
237  }
238  inline int ReadFile(void *p, void *buf, size_t *size) {
239  FileReader *reader = (FileReader*)p;
240  reader->Buf.read((char*)buf, *size);
241  *size=(size_t)reader->Buf.gcount();
242  if(size>0 && reader->Buf.fail())
243  reader->Buf.clear();
244  return 0;
245  }
246 
247  class FileWriter;
248  std::size_t WriteFile(void *p, const void *buf, size_t size);
249  class FileWriter : public Writer {
250  public:
251  FileWriter(std::ostream &Buf) : Buf(Buf) {
252  Write=&WriteFile;
253  }
254 
255  std::ostream &Buf;
256  };
257  inline Writer *ReadyWriteStruct(std::ostream &f) {
258  return new FileWriter(f);
259  }
260  inline std::size_t WriteFile(void *p, const void *buf, size_t size) {
261  FileWriter *writer = (FileWriter*)p;
262  writer->Buf.write((char*)buf, size);
263 
264  return size;
265  }
266  }
268 
279  class LZMA {
280  public:
281 
283  typedef std::function<void(float)> ProgressNotification;
284 
286  LZMA(bool useuncompressedsize=true) : UseUncompressedSize(useuncompressedsize) { }
287 
292  template <class I_, class O_>
293  void Encode(I_ &input, O_ &output) {
294  encode(lzma::ReadyReadStruct(input), lzma::ReadyWriteStruct(output), lzma::GetReadSize(input), nullptr);
295  }
296 
301  template <class I_, class O_>
302  void Encode(I_ &input, O_ &output, ProgressNotification notifier) {
303  encode(lzma::ReadyReadStruct(input), lzma::ReadyWriteStruct(output), lzma::GetReadSize(input), &notifier);
304  }
305 
316  template <class I_, class O_>
317  void Decode(I_ &input, O_ &output, Byte *compressionproperties=nullptr, unsigned long long fsize=(unsigned long long)(long long)-1) {
318  decode(lzma::ReadyReadStruct(input), lzma::ReadyWriteStruct(output), lzma::GetReadSize(input), lzma::SeekFn(input), compressionproperties, fsize, nullptr);
319  }
320 
332  template <class I_, class O_>
333  void Decode(I_ &input, O_ &output, LZMA::ProgressNotification notifier, Byte *compressionproperties=nullptr, unsigned long long fsize=(unsigned long long)(long long)-1) {
334  decode(lzma::ReadyReadStruct(input), lzma::ReadyWriteStruct(output), lzma::GetReadSize(input), lzma::SeekFn(input), compressionproperties, fsize, &notifier);
335  }
336 
338  int PropertySize();
339 
342 
343  protected:
345  void encode(lzma::Reader *reader, lzma::Writer *writer, unsigned long long size, ProgressNotification *notifier);
346 
348  void decode(lzma::Reader *reader, lzma::Writer *writer, unsigned long long size, std::function<void(lzma::Reader*, long long)> seekfn, Byte *cprops, unsigned long long fsize, ProgressNotification *notifier);
349 
350  };
351 
353  extern LZMA Lzma;
354 
355  }}
Gorgon::Encoding::png::WriteVector
void WriteVector(png_struct *p, unsigned char *buf, size_t size)
Definition: PNG.cpp:39
Gorgon::Encoding::LZMA::LZMA
LZMA(bool useuncompressedsize=true)
Default constructor.
Definition: LZMA.h:286
Gorgon::Encoding::png::ReadFile
void ReadFile(png_struct_def *p, unsigned char *buf, size_t size)
Definition: PNG.cpp:12
Gorgon::IO::WriteArray
void WriteArray(std::ostream &stream, const T_ *data, unsigned long size)
Writes an array to the stream.
Definition: Stream.h:294
Gorgon::Encoding::LZMA::Encode
void Encode(I_ &input, O_ &output)
Encodes the given data to LZMA compressed data.
Definition: LZMA.h:293
Gorgon::Encoding::png::ReadArray
void ReadArray(png_struct *p, unsigned char *buf, size_t size)
Definition: PNG.cpp:23
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::Encoding::png::ReadVector
void ReadVector(png_struct *p, unsigned char *buf, size_t size)
Definition: PNG.cpp:32
Gorgon::Encoding::LZMA::Encode
void Encode(I_ &input, O_ &output, ProgressNotification notifier)
Encodes the given data to LZMA compressed data.
Definition: LZMA.h:302
Gorgon::Encoding::LZMA::ProgressNotification
std::function< void(float)> ProgressNotification
Callback to notify progress. The value is reported between 0 and 1.
Definition: LZMA.h:283
LZMA.h
Gorgon::Encoding::Lzma
LZMA Lzma
A default constructed LZMA object.
Definition: LZMA.cpp:196
Gorgon::Encoding::LZMA::UseUncompressedSize
bool UseUncompressedSize
Whether to encode uncompressed size with the compression properties. Default value for this variable ...
Definition: LZMA.h:341
Gorgon::Encoding::LZMA::Decode
void Decode(I_ &input, O_ &output, LZMA::ProgressNotification notifier, Byte *compressionproperties=nullptr, unsigned long long fsize=(unsigned long long)(long long) -1)
Decodes LZMA compressed data.
Definition: LZMA.h:333
Gorgon::Encoding::LZMA::PropertySize
int PropertySize()
The size of the compression property data appended in front of the compressed data.
Definition: LZMA.cpp:189
Gorgon::Byte
unsigned char Byte
Represents smallest cell in memory.
Definition: Types.h:9
Gorgon::Encoding::LZMA::decode
void decode(lzma::Reader *reader, lzma::Writer *writer, unsigned long long size, std::function< void(lzma::Reader *, long long)> seekfn, Byte *cprops, unsigned long long fsize, ProgressNotification *notifier)
Performs actual decompression, notifier and cprops can be nullptr.
Definition: LZMA.cpp:85
Gorgon::end
std::vector< T_ >::const_iterator end(enum_type_id< T_ >)
Definition: Enum.h:288
Gorgon::Encoding::LZMA
This class allows encoding and decoding data using LZMA compression algorithm.
Definition: LZMA.h:279
Gorgon::Encoding::LZMA::encode
void encode(lzma::Reader *reader, lzma::Writer *writer, unsigned long long size, ProgressNotification *notifier)
Performs actual compression, notifier can be nullptr.
Definition: LZMA.cpp:37
Gorgon::Encoding::LZMA::Decode
void Decode(I_ &input, O_ &output, Byte *compressionproperties=nullptr, unsigned long long fsize=(unsigned long long)(long long) -1)
Decodes LZMA compressed data.
Definition: LZMA.h:317
Gorgon::IO::WriteString
void WriteString(std::ostream &stream, const std::string &value)
Writes a string without its size.
Definition: Stream.h:285
Gorgon::IO::ReadString
std::string ReadString(std::istream &stream)
Reads a string from a given stream.
Definition: Stream.h:135
Gorgon::Encoding::png::WriteFile
void WriteFile(png_struct *p, unsigned char *buf, size_t size)
Definition: PNG.cpp:19