libfacade 1.1
A library for manipulating PNG images with payloads.
Loading...
Searching...
No Matches
png.hpp
Go to the documentation of this file.
1#ifndef __FACADE_PNG_HPP
2#define __FACADE_PNG_HPP
3
76
77#include <algorithm>
78#include <cmath>
79#include <cstddef>
80#include <cstdint>
81#include <cstring>
82#include <fstream>
83#include <limits>
84#include <map>
85#include <optional>
86#include <set>
87#include <string>
88#include <type_traits>
89#include <utility>
90#include <variant>
91#include <vector>
92
93#include <facade/platform.hpp>
94#include <facade/exception.hpp>
95#include <facade/utility.hpp>
96
97namespace facade
98{
99namespace png
100{
103 class
104 PACK(1)
105 EXPORT
107 {
108 std::uint8_t _tag[4];
109
110 public:
111 ChunkTag() { std::memset(this->_tag, 0, sizeof(std::uint8_t) * 4); }
112 ChunkTag(const std::uint8_t *tag, std::size_t size) { this->set_tag(tag, size); }
113 ChunkTag(const char *tag) { this->set_tag(std::string(tag)); }
114 ChunkTag(const std::string tag) { this->set_tag(tag); }
115 ChunkTag(const ChunkTag &other) { this->set_tag(&other._tag[0], 4); }
116
117 bool operator==(const ChunkTag &other) const;
118
126 void set_tag(const std::string tag);
127
136 void set_tag(const std::uint8_t *tag, std::size_t size);
137
140 std::uint8_t *tag();
141
144 const std::uint8_t *tag() const;
145
148 std::string to_string() const;
149 };
150 UNPACK()
151
152 class ChunkPtr;
153
158 class
159 EXPORT
161 {
162 ChunkTag _tag;
163 std::vector<std::uint8_t> _data;
164
165 public:
166 ChunkVec(const ChunkTag tag) : _tag(tag) {}
167 ChunkVec(const ChunkTag tag, const void *ptr, std::size_t size)
168 : _tag(tag),
169 _data(&reinterpret_cast<const std::uint8_t *>(ptr)[0],
170 &reinterpret_cast<const std::uint8_t *>(ptr)[size]) {}
171 ChunkVec(const ChunkTag tag, const std::vector<std::uint8_t> &data) : _tag(tag), _data(data) {}
172 ChunkVec(const ChunkVec &other) : _tag(other._tag), _data(other._data) {}
173
174 bool operator==(const ChunkVec &other) const;
175
178 std::size_t length() const;
179
182 ChunkTag &tag();
185 const ChunkTag &tag() const;
186
189 std::vector<std::uint8_t> &data();
192 const std::vector<std::uint8_t> &data() const;
196 void set_data(std::vector<std::uint8_t> &data);
197
200 std::uint32_t crc() const;
201
206 std::pair<std::vector<std::uint8_t>, ChunkPtr> to_chunk_ptr() const;
207
210 template <typename T>
211 T& upcast() {
212 static_assert(std::is_base_of<ChunkVec, T>::value,
213 "Upcast type must derive ChunkVec");
214
215 return *static_cast<T*>(this);
216 }
217
220 template <typename T>
221 const T& upcast() const {
222 static_assert(std::is_base_of<ChunkVec, T>::value,
223 "Upcast type must derive ChunkVec");
224
225 return *static_cast<const T*>(this);
226 }
227
232 ChunkVec &as_chunk_vec();
233
238 const ChunkVec &as_chunk_vec() const;
239 };
240
247 class
248 EXPORT
250 {
251 const std::uint32_t *_length;
252 const ChunkTag *_tag;
253 const std::uint8_t *_data;
254 const std::uint32_t *_crc;
255
256 ChunkPtr(const std::uint32_t *length, const ChunkTag *tag, const std::uint8_t *data, const std::uint32_t *crc)
257 : _length(length),
258 _tag(tag),
259 _data(data),
260 _crc(crc) {}
261
262 public:
263 ChunkPtr() : _length(nullptr), _tag(nullptr), _data(nullptr), _crc(nullptr) {}
264 ChunkPtr(const ChunkPtr &other)
265 : _length(other._length),
266 _tag(other._tag),
267 _data(other._data),
268 _crc(other._crc) {}
269
279 static ChunkPtr parse(const void *ptr, std::size_t size, std::size_t offset);
286 static ChunkPtr parse(const std::vector<std::uint8_t> &vec, std::size_t offset);
287
290 std::size_t length() const;
293 ChunkTag tag() const;
296 std::vector<std::uint8_t> data() const;
301 std::uint32_t crc() const;
305 bool validate() const;
311 std::size_t chunk_size() const;
316 std::vector<std::uint8_t> chunk_data() const;
319 ChunkVec to_chunk_vec() const;
320 };
321
325 {
331 };
332
357 template <typename _Base=std::uint8_t, std::size_t _Bits=sizeof(_Base)*8>
358 class
359 PACK(1)
360 EXPORT
361 Sample
362 {
363 static_assert(_Bits == 1 || _Bits == 2 || _Bits == 4 || _Bits == 8 || _Bits == 16,
364 "Bits must be 1, 2, 4, 8 or 16.");
365 static_assert(std::is_same<_Base,std::uint8_t>::value || std::is_same<_Base,std::uint16_t>::value,
366 "Base must be uint8_t or uint16_t.");
367 static_assert((std::is_same<_Base,std::uint16_t>::value && _Bits == 16) ||
368 (std::is_same<_Base,std::uint8_t>::value && _Bits <= 8),
369 "Bit size does not match the base type.");
370
371 _Base _value;
372
373 public:
375 using Base = _Base;
377 const static std::size_t Bits = _Bits;
379 const static std::size_t Max = (1 << Bits) - 1;
380
381 Sample() : _value(0) {}
382 Sample(Base value) { this->set_value(value); }
383 Sample(const Sample &other) { this->set_value(other._value); }
384
388 Base operator*() const { return this->value(); }
392 Sample &operator=(Base value) { this->set_value(value); return *this; }
393
396 Base value() const {
397 if constexpr (Bits == 16) { return endian_swap_16(this->_value); }
398 else { return this->_value & this->Max; }
399 }
400
408 void set_value(Base value) {
409 if (value > this->Max) { throw exception::IntegerOverflow(value, this->Max); }
410
411 if constexpr (Bits == 1 || Bits == 2 || Bits == 4)
412 {
413 this->_value = value & this->Max;
414 }
415 else if constexpr (Bits == 16) { this->_value = endian_swap_16(value); }
416 else { this->_value = value; }
417 }
418 };
419 UNPACK()
420
421 using Sample1Bit = Sample<std::uint8_t, 1>;
422 using Sample2Bit = Sample<std::uint8_t, 2>;
423 using Sample4Bit = Sample<std::uint8_t, 4>;
424 using Sample8Bit = Sample<std::uint8_t>;
425 using Sample16Bit = Sample<std::uint16_t>;
426
437 template <typename _Base=std::uint8_t, std::size_t _Bits=sizeof(_Base)*8>
438 class GrayscalePixel : public Sample<_Base, _Bits>
439 {
440 public:
441 GrayscalePixel() : Sample<_Base, _Bits>(0) {}
442 GrayscalePixel(_Base value) : Sample<_Base, _Bits>(value) {}
443 GrayscalePixel(const GrayscalePixel &other) : Sample<_Base, _Bits>(other) {}
444
445 /* TODO: color conversion functions */
446 };
447
458
464 template <typename _Sample=Sample8Bit>
465 class
466 PACK(1)
467 EXPORT
469 {
470 static_assert(std::is_same<_Sample,Sample8Bit>::value || std::is_same<_Sample,Sample16Bit>::value,
471 "Sample type must be Sample8Bit or Sample16Bit.");
472
473 _Sample _red, _green, _blue;
474
475 public:
477 using Sample = _Sample;
479 using Base = typename Sample::Base;
481 const static std::size_t Max = Sample::Max;
483 const static std::size_t Bits = Sample::Bits*3;
484
485 TrueColorPixel() : _red(0), _green(0), _blue(0) {}
487 : _red(red),
488 _green(green),
489 _blue(blue) {}
491 : _red(other._red),
492 _green(other._green),
493 _blue(other._blue) {}
494
497 Sample &red() { return this->_red; }
500 const Sample &red() const { return this->_red; }
501
504 Sample &green() { return this->_green; }
507 const Sample &green() const { return this->_green; }
508
511 Sample &blue() { return this->_blue; }
514 const Sample &blue() const { return this->_blue;}
515 };
516 UNPACK()
517
518
522
530 template <std::size_t _Bits=sizeof(std::uint8_t)*8>
531 class PalettePixel : public Sample<std::uint8_t, _Bits>
532 {
533 static_assert(_Bits == 1 || _Bits == 2 || _Bits == 4 || _Bits == 8,
534 "Bits can only be 1, 2, 4, or 8.");
535
536 public:
537 PalettePixel() : Sample<std::uint8_t, _Bits>() {}
538 PalettePixel(std::uint8_t value) : Sample<std::uint8_t, _Bits>(value) {}
539 PalettePixel(const PalettePixel &other) : Sample<std::uint8_t, _Bits>(other) {}
540
541 /* TODO: convert to rgb */
542 };
543
552
558 template <typename _Base=std::uint8_t>
559 class
560 PACK(1)
561 EXPORT
562 AlphaGrayscalePixel : public GrayscalePixel<_Base>
563 {
564 static_assert(std::is_same<_Base,std::uint8_t>::value || std::is_same<_Base,std::uint16_t>::value,
565 "Base must be uint8_t or uint16_t.");
566 public:
567 //using Sample = Sample<_Base>;
570 using Base = _Base;
571
572 private:
573 Sample<_Base> _alpha;
574
575 public:
576 const static std::size_t Bits = Sample<_Base>::Bits*2;
577
578 AlphaGrayscalePixel() : _alpha(0), GrayscalePixel<_Base>() {}
579 AlphaGrayscalePixel(Sample<_Base> value, Sample<_Base> alpha) : _alpha(alpha), GrayscalePixel<_Base>(value) {}
580 AlphaGrayscalePixel(const AlphaGrayscalePixel &other) : _alpha(other._alpha), GrayscalePixel<_Base>(other) {}
581
584 Sample<_Base> &alpha() { return this->_alpha; }
585
588 const Sample<_Base> &alpha() const { return this->_alpha; }
589 };
590 UNPACK()
591
592
596
602 template <typename _Sample=Sample8Bit>
603 class
604 PACK(1)
605 EXPORT
606 AlphaTrueColorPixel : public TrueColorPixel<_Sample>
607 {
608 _Sample _alpha;
609
610 public:
611 const static std::size_t Bits=_Sample::Bits*4;
612
613 AlphaTrueColorPixel() : _alpha(0), TrueColorPixel<_Sample>() {}
614 AlphaTrueColorPixel(_Sample red, _Sample green, _Sample blue, _Sample alpha)
615 : _alpha(alpha),
616 TrueColorPixel<_Sample>(red, green, blue) {}
618 : _alpha(other._alpha),
619 TrueColorPixel<_Sample>(other) {}
620
623 _Sample &alpha() { return this->_alpha; }
624
627 const _Sample &alpha() const { return this->_alpha; }
628 };
629 UNPACK()
630
631
635
656 };
657
660 using Pixel = std::variant<GrayscalePixel1Bit,
675
677#define ASSERT_PIXEL(pixel) static_assert(std::is_same<pixel, GrayscalePixel1Bit>::value || \
678 std::is_same<pixel, GrayscalePixel2Bit>::value || \
679 std::is_same<pixel, GrayscalePixel4Bit>::value || \
680 std::is_same<pixel, GrayscalePixel8Bit>::value || \
681 std::is_same<pixel, GrayscalePixel16Bit>::value || \
682 std::is_same<pixel, TrueColorPixel8Bit>::value || \
683 std::is_same<pixel, TrueColorPixel16Bit>::value || \
684 std::is_same<pixel, PalettePixel1Bit>::value || \
685 std::is_same<pixel, PalettePixel2Bit>::value || \
686 std::is_same<pixel, PalettePixel4Bit>::value || \
687 std::is_same<pixel, PalettePixel8Bit>::value || \
688 std::is_same<pixel, AlphaGrayscalePixel8Bit>::value || \
689 std::is_same<pixel, AlphaGrayscalePixel16Bit>::value || \
690 std::is_same<pixel, AlphaTrueColorPixel8Bit>::value || \
691 std::is_same<pixel, AlphaTrueColorPixel16Bit>::value, \
692 #pixel " is not a base pixel-type.")
693
703 template <typename PixelType>
704 class
705 EXPORT
707 {
708 ASSERT_PIXEL(PixelType);
709
710 union {
711 std::uint8_t bits;
712 std::uint8_t bytes[PixelType::Bits/8];
713 } _data;
714
715 public:
717 PixelSpan(const PixelSpan &other) { std::memcpy(&this->_data, &other._data, sizeof(this->_data)); }
718
723 const static std::size_t Samples = (8 / PixelType::Bits) + static_cast<int>(PixelType::Bits > 8);
724
729 Pixel operator[](std::size_t index) const { return this->get(index); }
730
733 const std::uint8_t *data() const {
734 auto u8_ptr = reinterpret_cast<const std::uint8_t *>(&this->_data);
735 return u8_ptr;
736 }
737
740 std::size_t data_size() const { return sizeof(PixelType); }
741
747 Pixel get(std::size_t index=0) const {
748 if (index > this->Samples) { throw exception::OutOfBounds(index, this->Samples); }
749
750 if constexpr (PixelType::Bits < 8) {
751 auto bits = this->_data.bits;
752 bits >>= (this->Samples - 1 - index) * PixelType::Bits;
753 bits &= PixelType::Max;
754
755 return PixelType(bits);
756 }
757 else { return *reinterpret_cast<const PixelType *>(&this->_data.bytes[0]); }
758 }
759
768 void set(const Pixel &pixel, std::size_t index=0) {
769 if (!std::holds_alternative<PixelType>(pixel)) { throw exception::PixelMismatch(); }
770 if (index > this->Samples) { throw exception::OutOfBounds(index, this->Samples); }
771
772 if constexpr (PixelType::Bits < 8)
773 {
774 auto bits = this->_data.bits;
775 auto shift = (this->Samples - 1 - index) * PixelType::Bits;
776 auto mask = (PixelType::Max << shift) ^ 0xFF;
777
778 auto value = std::get<PixelType>(pixel).value();
779 this->_data.bits = (bits & mask) | (value << shift);
780 }
781 else {
782 std::memcpy(&this->_data.bytes[0], &pixel, PixelType::Bits/8);
783 }
784 }
785 };
786
789 template <typename PixelType>
790 using PixelRow = std::vector<PixelSpan<PixelType>>;
791
796 template <typename PixelType>
797 EXPORT std::vector<std::uint8_t> pixels_to_raw(const PixelRow<PixelType> &pixels)
798 {
799 std::vector<std::uint8_t> result;
800
801 for (auto &span : pixels)
802 {
803 auto data = span.data();
804 result.insert(result.end(), &data[0], &data[span.data_size()]);
805 }
806
807 return result;
808 }
809
813 class
814 EXPORT
815 Header : public ChunkVec
816 {
817 public:
818 Header() : ChunkVec(std::string("IHDR"), std::vector<std::uint8_t>(13)) {}
819 Header(const void *ptr, std::size_t size) : ChunkVec(std::string("IHDR"), ptr, size) {}
820 Header(const std::vector<std::uint8_t> &vec) : ChunkVec(std::string("IHDR"), vec) {}
821 Header(std::uint32_t width, std::uint32_t height, std::uint8_t bit_depth,
822 std::uint8_t color_type, std::uint8_t compression_method=0,
823 std::uint8_t filter_method=0, std::uint8_t interlace_method=0)
824 : ChunkVec(std::string("IHDR"), std::vector<std::uint8_t>(13))
825 {
826 this->set(width,
827 height,
828 bit_depth,
829 color_type,
830 compression_method,
831 filter_method,
832 interlace_method);
833 }
834 Header(const Header &other) : ChunkVec(other) {}
835
846 void set(std::uint32_t width, std::uint32_t height, std::uint8_t bit_depth,
847 std::uint8_t color_type, std::uint8_t compression_method=0,
848 std::uint8_t filter_method=0, std::uint8_t interlace_method=0);
849
852 std::uint32_t width() const;
855 void set_width(std::uint32_t width);
856
858 std::uint32_t height() const;
860 void set_height(std::uint32_t height);
861
863 std::uint8_t bit_depth() const;
865 void set_bit_depth(std::uint8_t bit_depth);
866
868 std::uint8_t color_type() const;
870 void set_color_type(std::uint8_t color_type);
871
873 std::uint8_t compression_method() const;
875 void set_compression_method(std::uint8_t compression_method);
876
878 std::uint8_t filter_method() const;
880 void set_filter_method(std::uint8_t filter_method);
881
883 std::uint8_t interlace_method() const;
885 void set_interlace_method(std::uint8_t interlace_method);
886
892 PixelEnum pixel_type() const;
896 std::size_t pixel_size() const;
899 std::size_t buffer_size() const;
900 };
901
904 class
905 EXPORT
906 Text : public ChunkVec {
907 public:
908 Text() : ChunkVec(std::string("tEXt")) {}
909 Text(std::string keyword, std::string text) : ChunkVec(std::string("tEXt")) {
910 this->set_keyword(keyword);
911 this->set_text(text);
912 }
913 Text(const Text &other) : ChunkVec(other) {}
914
915 protected:
919 std::optional<std::size_t> null_terminator() const;
920
923 std::size_t text_offset() const;
924
925 public:
929 bool has_keyword() const;
934 std::string keyword() const;
940 void set_keyword(std::string keyword, bool validate=true);
941
945 bool has_text() const;
948 std::string text() const;
951 void set_text(std::string text);
952 };
953
956 class
957 EXPORT
958 ZText : public ChunkVec {
959 public:
960 ZText() : ChunkVec(std::string("zTXt")) {}
961 ZText(std::string keyword, std::string text) : ChunkVec(std::string("zTXt")) {
962 this->set_keyword(keyword);
963 this->set_compression_method(0);
964 this->set_text(text);
965 }
966 ZText(const Text &other) : ChunkVec(other) {}
967
968 protected:
972 std::optional<std::size_t> null_terminator() const;
973
976 std::size_t text_offset() const;
977
978 public:
982 bool has_keyword() const;
987 std::string keyword() const;
993 void set_keyword(std::string keyword, bool validate=true);
994
996 std::uint8_t compression_method() const;
1001 void set_compression_method(std::uint8_t compression_method);
1002
1006 bool has_text() const;
1009 std::string text() const;
1012 void set_text(std::string text);
1013 };
1014
1017 class
1018 EXPORT
1019 End : public ChunkVec {
1020 public:
1021 End() : ChunkVec(std::string("IEND")) {}
1022 End(const End &other) : ChunkVec(other) {}
1023 };
1024
1028 {
1029 NONE = 0,
1033 PAETH
1035
1039 template <typename PixelType>
1040 class
1041 EXPORT
1043 {
1044 ASSERT_PIXEL(PixelType);
1045
1046 public:
1049
1050 private:
1051 std::uint8_t _filter_type;
1052 std::vector<Span> _pixel_data;
1053
1054 public:
1055 ScanlineBase() : _filter_type(0) {}
1056 ScanlineBase(std::uint8_t filter_type, std::size_t width)
1057 : _filter_type(filter_type),
1058 _pixel_data(width / Span::Samples + static_cast<int>(width % Span::Samples != 0)) {}
1059 ScanlineBase(std::uint8_t filter_type, std::vector<Span> pixel_data) : _filter_type(filter_type), _pixel_data(pixel_data) {}
1060 ScanlineBase(const ScanlineBase &other) : _filter_type(other._filter_type), _pixel_data(other._pixel_data) {}
1061
1069 static ScanlineBase read_line(const std::vector<std::uint8_t> &raw_data, std::size_t offset, std::size_t width);
1070
1078 static std::vector<ScanlineBase> from_raw(const Header &header, const std::vector<std::uint8_t> &raw_data);
1079
1083 Pixel operator[](std::size_t index) const;
1084
1087 std::uint8_t filter_type() const;
1090 void set_filter_type(std::uint8_t filter_type);
1091
1092#if !defined(LIBFACADE_WIN32)
1093 __attribute__((used))
1094#endif
1097 const std::vector<Span> &pixel_data() const;
1098
1104 std::size_t pixel_span() const;
1110 std::size_t pixel_width() const;
1111
1118 Span &get_span(std::size_t index);
1125 const Span &get_span(std::size_t index) const;
1134 void set_span(const Span &span, std::size_t index);
1135
1142 Pixel get_pixel(std::size_t index) const;
1149 void set_pixel(const Pixel &pixel, std::size_t index);
1150
1153 std::vector<std::uint8_t> to_raw() const;
1154
1165 ScanlineBase reconstruct(std::optional<ScanlineBase> previous) const;
1171 ScanlineBase filter(std::optional<ScanlineBase> previous) const;
1180 ScanlineBase filter(FilterType filter_type, std::optional<ScanlineBase> previous) const;
1181 };
1182
1213
1233
1236 class
1237 EXPORT
1238 Scanline : public ScanlineVariant
1239 {
1240 public:
1242 Scanline(const GrayscaleScanline1Bit &scanline) : ScanlineVariant(scanline) {}
1243 Scanline(const GrayscaleScanline2Bit &scanline) : ScanlineVariant(scanline) {}
1244 Scanline(const GrayscaleScanline4Bit &scanline) : ScanlineVariant(scanline) {}
1245 Scanline(const GrayscaleScanline8Bit &scanline) : ScanlineVariant(scanline) {}
1246 Scanline(const GrayscaleScanline16Bit &scanline) : ScanlineVariant(scanline) {}
1247 Scanline(const TrueColorScanline8Bit &scanline) : ScanlineVariant(scanline) {}
1248 Scanline(const TrueColorScanline16Bit &scanline) : ScanlineVariant(scanline) {}
1249 Scanline(const PaletteScanline1Bit &scanline) : ScanlineVariant(scanline) {}
1250 Scanline(const PaletteScanline2Bit &scanline) : ScanlineVariant(scanline) {}
1251 Scanline(const PaletteScanline4Bit &scanline) : ScanlineVariant(scanline) {}
1252 Scanline(const PaletteScanline8Bit &scanline) : ScanlineVariant(scanline) {}
1257 Scanline(const Scanline &other) : ScanlineVariant(other) {}
1258
1262 Pixel operator[](std::size_t index) const;
1263
1267 std::uint8_t filter_type() const;
1271 void set_filter_type(std::uint8_t filter_type);
1272
1276 std::size_t pixel_span() const;
1280 std::size_t pixel_width() const;
1281
1285 Pixel get_pixel(std::size_t index) const;
1289 void set_pixel(const Pixel &pixel, std::size_t index);
1290
1294 std::vector<std::uint8_t> to_raw() const;
1295 };
1296
1302 class
1303 EXPORT
1304 Image
1305 {
1306 public:
1308 static const std::uint8_t Signature[8];
1309
1310 protected:
1312 std::map<std::string, std::vector<ChunkVec>> chunk_map;
1314 std::optional<std::vector<std::uint8_t>> trailing_data;
1316 std::optional<std::vector<Scanline>> image_data;
1317
1318 public:
1320 Image(const void *ptr, std::size_t size, bool validate=true) { this->parse(ptr, size, validate); }
1321 Image(const std::vector<std::uint8_t> &data, bool validate=true) { this->parse(data, validate); }
1322 Image(const std::string &filename, bool validate=true) { this->parse(filename, validate); }
1323 Image(const Image &other) : chunk_map(other.chunk_map), trailing_data(other.trailing_data), image_data(other.image_data) {}
1324
1326 Image &operator=(const Image &other);
1327
1331 Scanline &operator[](std::size_t index);
1335 const Scanline &operator[](std::size_t index) const;
1336
1340 bool has_chunk(const std::string &tag) const;
1345 std::vector<ChunkVec> get_chunks(const std::string &tag) const;
1348 void add_chunk(const ChunkVec &chunk);
1349
1352 bool has_trailing_data() const;
1357 std::vector<std::uint8_t> &get_trailing_data();
1362 const std::vector<std::uint8_t> &get_trailing_data() const;
1365 void set_trailing_data(const std::vector<std::uint8_t> &data);
1368 void clear_trailing_data();
1369
1378 void parse(const void *ptr, std::size_t size, bool validate=true);
1382 void parse(const std::vector<std::uint8_t> &data, bool validate=true);
1388 void parse(const std::string &filename, bool validate=true);
1389
1397 void load();
1398
1404 Scanline &scanline(std::size_t index);
1410 const Scanline &scanline(std::size_t index) const;
1411
1414 bool has_header() const;
1419 Header &header();
1424 const Header &header() const;
1427 Header &new_header();
1428
1432 std::size_t width() const;
1436 std::size_t height() const;
1437
1440 bool has_image_data() const;
1445 bool is_loaded() const;
1446
1450 void decompress();
1461 void compress(std::optional<std::size_t> chunk_size=8192, int level=-1);
1462
1467 void reconstruct();
1472 void filter();
1473
1480 std::vector<std::uint8_t> to_file() const;
1485 void save(const std::string &filename) const;
1486
1489 bool has_text() const;
1496 Text &add_text(const std::string &keyword, const std::string &text);
1500 void remove_text(const Text &text);
1504 void remove_text(const std::string &keyword, const std::string &text);
1508 std::vector<Text> get_text(const std::string &keyword) const;
1509
1512 bool has_ztext() const;
1519 ZText &add_ztext(const std::string &keyword, const std::string &text);
1523 void remove_ztext(const ZText &ztext);
1527 void remove_ztext(const std::string &keyword, const std::string &text);
1531 std::vector<ZText> get_ztext(const std::string &keyword) const;
1532 };
1533}}
1534
1535#endif
An exception thrown when a given integer overflows.
Definition: exception.hpp:264
An exception thrown when the operation goes out of bounds.
Definition: exception.hpp:48
An exception thrown when pixel types do not match up.
Definition: exception.hpp:184
A grayscale pixel with alpha channel.
Definition: png.hpp:563
Sample< _Base > & alpha()
The alpha channel of this pixel.
Definition: png.hpp:584
AlphaGrayscalePixel(Sample< _Base > value, Sample< _Base > alpha)
Definition: png.hpp:579
AlphaGrayscalePixel(const AlphaGrayscalePixel &other)
Definition: png.hpp:580
AlphaGrayscalePixel()
Definition: png.hpp:578
_Base Base
The type base of the samples in this pixel.
Definition: png.hpp:570
const Sample< _Base > & alpha() const
The const alpha channel of this pixel.
Definition: png.hpp:588
An RGB pixel with alpha channel.
Definition: png.hpp:607
_Sample & alpha()
The alpha channel of this pixel.
Definition: png.hpp:623
const _Sample & alpha() const
The const alpha channel of this pixel.
Definition: png.hpp:627
AlphaTrueColorPixel(_Sample red, _Sample green, _Sample blue, _Sample alpha)
Definition: png.hpp:614
AlphaTrueColorPixel(const AlphaTrueColorPixel &other)
Definition: png.hpp:617
AlphaTrueColorPixel()
Definition: png.hpp:613
The chunk class responsible for parsing the raw data of a PNG file.
Definition: png.hpp:250
ChunkPtr()
Definition: png.hpp:263
ChunkPtr(const ChunkPtr &other)
Definition: png.hpp:264
The string tag identifying a given facade::png::ChunkVec or facade::png::ChunkPtr.
Definition: png.hpp:107
ChunkTag()
Definition: png.hpp:111
ChunkTag(const char *tag)
Definition: png.hpp:113
ChunkTag(const std::uint8_t *tag, std::size_t size)
Definition: png.hpp:112
ChunkTag(const std::string tag)
Definition: png.hpp:114
ChunkTag(const ChunkTag &other)
Definition: png.hpp:115
A vector-based version of a given PNG chunk.
Definition: png.hpp:161
T & upcast()
Create a reference to a higher-level ChunkVec object, such as facade::png::Header.
Definition: png.hpp:211
ChunkVec(const ChunkTag tag, const void *ptr, std::size_t size)
Definition: png.hpp:167
ChunkVec(const ChunkVec &other)
Definition: png.hpp:172
ChunkVec(const ChunkTag tag)
Definition: png.hpp:166
const T & upcast() const
Create a const reference to a higher-level ChunkVec object, such as facade::png::Header.
Definition: png.hpp:221
ChunkVec(const ChunkTag tag, const std::vector< std::uint8_t > &data)
Definition: png.hpp:171
The end chunk for a given PNG file.
Definition: png.hpp:1019
End()
Definition: png.hpp:1021
End(const End &other)
Definition: png.hpp:1022
A grayscale pixel object, based on the facade::png::Sample class.
Definition: png.hpp:439
GrayscalePixel()
Definition: png.hpp:441
GrayscalePixel(_Base value)
Definition: png.hpp:442
GrayscalePixel(const GrayscalePixel &other)
Definition: png.hpp:443
A PNG header object.
Definition: png.hpp:816
Header(std::uint32_t width, std::uint32_t height, std::uint8_t bit_depth, std::uint8_t color_type, std::uint8_t compression_method=0, std::uint8_t filter_method=0, std::uint8_t interlace_method=0)
Definition: png.hpp:821
Header(const std::vector< std::uint8_t > &vec)
Definition: png.hpp:820
Header()
Definition: png.hpp:818
Header(const Header &other)
Definition: png.hpp:834
Header(const void *ptr, std::size_t size)
Definition: png.hpp:819
A class for loading and manipulating PNG images.
Definition: png.hpp:1305
Image(const Image &other)
Definition: png.hpp:1323
Image(const std::string &filename, bool validate=true)
Definition: png.hpp:1322
Image(const std::vector< std::uint8_t > &data, bool validate=true)
Definition: png.hpp:1321
std::optional< std::vector< std::uint8_t > > trailing_data
A container for trailing data, if present when parsing or when writing afterward.
Definition: png.hpp:1314
Image()
Definition: png.hpp:1319
Image(const void *ptr, std::size_t size, bool validate=true)
Definition: png.hpp:1320
std::map< std::string, std::vector< ChunkVec > > chunk_map
A map of chunk tags to their corresponding facade::png::ChunkVec types.
Definition: png.hpp:1312
std::optional< std::vector< Scanline > > image_data
The loaded image data from the compressed IDAT chunks.
Definition: png.hpp:1316
A paletted pixel object.
Definition: png.hpp:532
PalettePixel(const PalettePixel &other)
Definition: png.hpp:539
PalettePixel()
Definition: png.hpp:537
PalettePixel(std::uint8_t value)
Definition: png.hpp:538
A span of data representing the underlying bits or bytes of a pixel.
Definition: png.hpp:707
Pixel get(std::size_t index=0) const
Retrieve a facade::png::Pixel variant of the underlying pixel type at the given index.
Definition: png.hpp:747
PixelSpan(const PixelSpan &other)
Definition: png.hpp:717
std::uint8_t bits
Definition: png.hpp:711
void set(const Pixel &pixel, std::size_t index=0)
Set a given facade::png::Pixel variant at the given offset.
Definition: png.hpp:768
const std::uint8_t * data() const
Return the underlying raw byte data representing this pixel span.
Definition: png.hpp:733
std::size_t data_size() const
Return the size of this pixel span.
Definition: png.hpp:740
Pixel operator[](std::size_t index) const
Syntactic sugar to get a facade::png::Pixel variant out of this span.
Definition: png.hpp:729
PixelSpan()
Definition: png.hpp:716
A sample of data for a given pixel.
Definition: png.hpp:362
Sample(const Sample &other)
Definition: png.hpp:383
Base value() const
Get the value retained by this sample.
Definition: png.hpp:396
Base operator*() const
Syntactic sugar to get the value of this sample.
Definition: png.hpp:388
Sample(Base value)
Definition: png.hpp:382
static const std::size_t Bits
The size, in bits, of this sample.
Definition: png.hpp:377
void set_value(Base value)
Assign the given value to this sample.
Definition: png.hpp:408
Sample()
Definition: png.hpp:381
static const std::size_t Max
The maximum value that can be used with this sample.
Definition: png.hpp:379
Sample & operator=(Base value)
Syntactic sugar to assign the value of this sample.
Definition: png.hpp:392
_Base Base
The base type used by this sample.
Definition: png.hpp:375
The base scanline class containing a row of facade::png::PixelSpan of the given pixel type.
Definition: png.hpp:1043
ScanlineBase(const ScanlineBase &other)
Definition: png.hpp:1060
std::size_t pixel_width() const
Return the size, in samples, of the given scanline.
__attribute__((used)) const std std::size_t pixel_span() const
Return a const reference to the underlying pixel data array.
ScanlineBase filter(std::optional< ScanlineBase > previous) const
Calculate all filters and determine the best compressed filter among them.
ScanlineBase(std::uint8_t filter_type, std::vector< Span > pixel_data)
Definition: png.hpp:1059
ScanlineBase(std::uint8_t filter_type, std::size_t width)
Definition: png.hpp:1056
ScanlineBase filter(FilterType filter_type, std::optional< ScanlineBase > previous) const
Calculate the given filter type on this scanline.
ScanlineBase()
Definition: png.hpp:1055
Span & get_span(std::size_t index)
Get the facade::png::PixelSpan reference at the given index.
A wrapper object for ScanlineVariant.
Definition: png.hpp:1239
Scanline(const GrayscaleScanline4Bit &scanline)
Definition: png.hpp:1244
Scanline(const GrayscaleScanline16Bit &scanline)
Definition: png.hpp:1246
Scanline(const AlphaTrueColorScanline8Bit &scanline)
Definition: png.hpp:1255
Scanline(const Scanline &other)
Definition: png.hpp:1257
Scanline(const AlphaTrueColorScanline16Bit &scanline)
Definition: png.hpp:1256
Scanline(const TrueColorScanline16Bit &scanline)
Definition: png.hpp:1248
Scanline()
Definition: png.hpp:1241
Scanline(const TrueColorScanline8Bit &scanline)
Definition: png.hpp:1247
Scanline(const GrayscaleScanline2Bit &scanline)
Definition: png.hpp:1243
Scanline(const PaletteScanline2Bit &scanline)
Definition: png.hpp:1250
Scanline(const PaletteScanline4Bit &scanline)
Definition: png.hpp:1251
Scanline(const AlphaGrayscaleScanline8Bit &scanline)
Definition: png.hpp:1253
Scanline(const PaletteScanline1Bit &scanline)
Definition: png.hpp:1249
Scanline(const GrayscaleScanline8Bit &scanline)
Definition: png.hpp:1245
Scanline(const PaletteScanline8Bit &scanline)
Definition: png.hpp:1252
Scanline(const GrayscaleScanline1Bit &scanline)
Definition: png.hpp:1242
Scanline(const AlphaGrayscaleScanline16Bit &scanline)
Definition: png.hpp:1254
A tEXt chunk object.
Definition: png.hpp:906
Text(std::string keyword, std::string text)
Definition: png.hpp:909
Text()
Definition: png.hpp:908
Text(const Text &other)
Definition: png.hpp:913
An RGB pixel object.
Definition: png.hpp:469
_Sample Sample
The sample class that was used in creating this class.
Definition: png.hpp:477
Sample & blue()
Retrieve a reference to the blue channel.
Definition: png.hpp:511
const Sample & blue() const
Retrieve a const reference to the blue channel.
Definition: png.hpp:514
TrueColorPixel(const TrueColorPixel &other)
Definition: png.hpp:490
typename Sample::Base Base
The base type of the sample class used in creating this class.
Definition: png.hpp:479
Sample & red()
Retrieve a reference to the red channel.
Definition: png.hpp:497
const Sample & green() const
Retrieve a const reference to the green channel.
Definition: png.hpp:507
TrueColorPixel(Sample red, Sample green, Sample blue)
Definition: png.hpp:486
Sample & green()
Retrieve a reference to the green channel.
Definition: png.hpp:504
TrueColorPixel()
Definition: png.hpp:485
const Sample & red() const
Retrieve a const reference to the red channel.
Definition: png.hpp:500
A compressed text chunk.
Definition: png.hpp:958
ZText()
Definition: png.hpp:960
ZText(std::string keyword, std::string text)
Definition: png.hpp:961
ZText(const Text &other)
Definition: png.hpp:966
A collection of exceptions thrown by the library.
TrueColorPixel< Sample16Bit > TrueColorPixel16Bit
A facade::png::TrueColorPixel with a 16-bit facade::png::Sample value.
Definition: png.hpp:521
GrayscalePixel< std::uint8_t > GrayscalePixel8Bit
A facade::png::GrayscalePixel with an 8-bit facade::png::Sample value.
Definition: png.hpp:455
PalettePixel< 2 > PalettePixel2Bit
A facade::png::PalettePixel object with a 2-bit facade::png::Sample value.
Definition: png.hpp:547
std::variant< GrayscaleScanline1Bit, GrayscaleScanline2Bit, GrayscaleScanline4Bit, GrayscaleScanline8Bit, GrayscaleScanline16Bit, TrueColorScanline8Bit, TrueColorScanline16Bit, PaletteScanline1Bit, PaletteScanline2Bit, PaletteScanline4Bit, PaletteScanline8Bit, AlphaGrayscaleScanline8Bit, AlphaGrayscaleScanline16Bit, AlphaTrueColorScanline8Bit, AlphaTrueColorScanline16Bit > ScanlineVariant
A variant type containing all accepted scanline types.
Definition: png.hpp:1232
ColorType
The color type represented in the PNG file.
Definition: png.hpp:325
@ PALETTE
Definition: png.hpp:328
@ TRUE_COLOR
Definition: png.hpp:327
@ GRAYSCALE
Definition: png.hpp:326
@ ALPHA_GRAYSCALE
Definition: png.hpp:329
@ ALPHA_TRUE_COLOR
Definition: png.hpp:330
ScanlineBase< GrayscalePixel16Bit > GrayscaleScanline16Bit
A 16-bit grayscale scanline, using facade::png::GrayscalePixel16Bit as a pixel base.
Definition: png.hpp:1192
std::vector< PixelSpan< PixelType > > PixelRow
A vector of a facade::png::PixelSpan of the given pixel type.
Definition: png.hpp:790
AlphaGrayscalePixel< std::uint8_t > AlphaGrayscalePixel8Bit
An facade::png::AlphaGrayscalePixel with an 8-bit facade::png::Sample size.
Definition: png.hpp:593
AlphaGrayscalePixel< std::uint16_t > AlphaGrayscalePixel16Bit
An facade::png::AlphaGrayscalePixel with a 16-bit facade::png::Sample size.
Definition: png.hpp:595
ScanlineBase< PalettePixel1Bit > PaletteScanline1Bit
A 1-bit palette scanline, using facade::png::PalettePixel1Bit as a pixel base.
Definition: png.hpp:1198
ScanlineBase< AlphaTrueColorPixel8Bit > AlphaTrueColorScanline8Bit
An 8-bit RGB scanline with alpha channel, using facade::png::AlphaTrueColorPixel8Bit as a pixel base.
Definition: png.hpp:1210
ScanlineBase< PalettePixel2Bit > PaletteScanline2Bit
A 2-bit palette scanline, using facade::png::PalettePixel2Bit as a pixel base.
Definition: png.hpp:1200
ScanlineBase< TrueColorPixel8Bit > TrueColorScanline8Bit
An 8-bit RGB scanline, using facade::png::TrueColorPixel8Bit as a pixel base.
Definition: png.hpp:1194
GrayscalePixel< std::uint8_t, 1 > GrayscalePixel1Bit
A facade::png::GrayscalePixel with a 1-bit facade::png::Sample value.
Definition: png.hpp:449
GrayscalePixel< std::uint16_t > GrayscalePixel16Bit
A facade::png::GrayscalePixel with a 16-bit facade::png::Sample value.
Definition: png.hpp:457
PalettePixel< 1 > PalettePixel1Bit
A facade::png::PalettePixel object with a 1-bit facade::png::Sample value.
Definition: png.hpp:545
ScanlineBase< AlphaGrayscalePixel16Bit > AlphaGrayscaleScanline16Bit
A 16-bit grayscale scanline with alpha channel, using facade::png::AlphaGrayscalePixel16Bit as a pixe...
Definition: png.hpp:1208
TrueColorPixel< Sample8Bit > TrueColorPixel8Bit
A facade::png::TrueColorPixel with an 8-bit facade::png::Sample value.
Definition: png.hpp:519
AlphaTrueColorPixel< Sample8Bit > AlphaTrueColorPixel8Bit
An facade::png::AlphaTrueColorPixel with an 8-bit facade::png::Sample size.
Definition: png.hpp:632
ScanlineBase< PalettePixel8Bit > PaletteScanline8Bit
An 8-bit palette scanline, using facade::png::PalettePixel8Bit as a pixel base.
Definition: png.hpp:1204
ScanlineBase< AlphaGrayscalePixel8Bit > AlphaGrayscaleScanline8Bit
An 8-bit grayscale scanline with alpha channel, using facade::png::AlphaGrayscalePixel8Bit as a pixel...
Definition: png.hpp:1206
EXPORT std::vector< std::uint8_t > pixels_to_raw(const PixelRow< PixelType > &pixels)
Convert a row of facade::png::PixelSpan of the given pixel type into a vector of bytes.
Definition: png.hpp:797
std::variant< GrayscalePixel1Bit, GrayscalePixel2Bit, GrayscalePixel4Bit, GrayscalePixel8Bit, GrayscalePixel16Bit, TrueColorPixel8Bit, TrueColorPixel16Bit, PalettePixel1Bit, PalettePixel2Bit, PalettePixel4Bit, PalettePixel8Bit, AlphaGrayscalePixel8Bit, AlphaGrayscalePixel16Bit, AlphaTrueColorPixel8Bit, AlphaTrueColorPixel16Bit > Pixel
The variant type corresponding to all known pixel types for PNG images.
Definition: png.hpp:674
PalettePixel< 8 > PalettePixel8Bit
A facade::png::PalettePixel object with an 8-bit facade::png::Sample value.
Definition: png.hpp:551
ScanlineBase< PalettePixel4Bit > PaletteScanline4Bit
A 4-bit palette scanline, using facade::png::PalettePixel4Bit as a pixel base.
Definition: png.hpp:1202
ScanlineBase< GrayscalePixel1Bit > GrayscaleScanline1Bit
A 1-bit grayscale scanline, using facade::png::GrayscalePixel1Bit as a pixel base.
Definition: png.hpp:1184
ScanlineBase< GrayscalePixel2Bit > GrayscaleScanline2Bit
A 2-bit grayscale scanline, using facade::png::GrayscalePixel2Bit as a pixel base.
Definition: png.hpp:1186
FilterType
The filter type to use for a given scanline.
Definition: png.hpp:1028
@ AVERAGE
Definition: png.hpp:1032
@ PAETH
Definition: png.hpp:1033
@ SUB
Definition: png.hpp:1030
@ NONE
Definition: png.hpp:1029
@ UP
Definition: png.hpp:1031
ScanlineBase< TrueColorPixel16Bit > TrueColorScanline16Bit
A 16-bit RGB scanline, using facade::png::TrueColorPixel16Bit as a pixel base.
Definition: png.hpp:1196
GrayscalePixel< std::uint8_t, 4 > GrayscalePixel4Bit
A facade::png::GrayscalePixel with a 4-bit facade::png::Sample value.
Definition: png.hpp:453
GrayscalePixel< std::uint8_t, 2 > GrayscalePixel2Bit
A facade::png::GrayscalePixel with a 2-bit facade::png::Sample value.
Definition: png.hpp:451
PixelEnum
An enum representing all available pixel types.
Definition: png.hpp:640
@ PALETTE_PIXEL_1BIT
Definition: png.hpp:648
@ ALPHA_TRUE_COLOR_PIXEL_16BIT
Definition: png.hpp:655
@ ALPHA_GRAYSCALE_PIXEL_16BIT
Definition: png.hpp:653
@ GRAYSCALE_PIXEL_1BIT
Definition: png.hpp:641
@ GRAYSCALE_PIXEL_8BIT
Definition: png.hpp:644
@ PALETTE_PIXEL_8BIT
Definition: png.hpp:651
@ GRAYSCALE_PIXEL_16BIT
Definition: png.hpp:645
@ PALETTE_PIXEL_4BIT
Definition: png.hpp:650
@ TRUE_COLOR_PIXEL_16BIT
Definition: png.hpp:647
@ ALPHA_TRUE_COLOR_PIXEL_8BIT
Definition: png.hpp:654
@ TRUE_COLOR_PIXEL_8BIT
Definition: png.hpp:646
@ GRAYSCALE_PIXEL_2BIT
Definition: png.hpp:642
@ PALETTE_PIXEL_2BIT
Definition: png.hpp:649
@ ALPHA_GRAYSCALE_PIXEL_8BIT
Definition: png.hpp:652
@ GRAYSCALE_PIXEL_4BIT
Definition: png.hpp:643
PalettePixel< 4 > PalettePixel4Bit
A facade::png::PalettePixel object with a 4-bit facade::png::Sample value.
Definition: png.hpp:549
ScanlineBase< GrayscalePixel4Bit > GrayscaleScanline4Bit
A 4-bit grayscale scanline, using facade::png::GrayscalePixel4Bit as a pixel base.
Definition: png.hpp:1188
ScanlineBase< GrayscalePixel8Bit > GrayscaleScanline8Bit
An 8-bit grayscale scanline, using facade::png::GrayscalePixel8Bit as a pixel base.
Definition: png.hpp:1190
Definition: exception.hpp:14
EXPORT std::uint16_t endian_swap_16(std::uint16_t value)
Swap the endianness of a 16-bit value.
Definition: utility.cpp:5
EXPORT std::vector< std::uint8_t > compress(const void *ptr, std::size_t size, int level)
Compress the given data buffer with the given compression level.
Definition: utility.cpp:30
EXPORT std::vector< std::uint8_t > decompress(const void *ptr, std::size_t size)
Decompress the given data buffer with zlib's inflate algorithm.
Definition: utility.cpp:67
Various macros and defines that help determine the platform of the compiler.
#define PACK(alignment)
Definition: platform.hpp:53
#define EXPORT
Definition: platform.hpp:46
#define UNPACK()
Definition: platform.hpp:54
__attribute__((used)) const std
Definition: png.cpp:617
#define ASSERT_PIXEL(pixel)
Macro that creates a static_assert that the given argument class is a known base pixel type.
Definition: png.hpp:677
Functions relating to the needs of images in the program.