Skip to content
This repository was archived by the owner on Oct 25, 2023. It is now read-only.

Commit b07e060

Browse files
committed
PNG: Create PNG encoder/decoder
Signed-off-by: Quentin Guidée <[email protected]>
1 parent 94bdce4 commit b07e060

16 files changed

+727
-0
lines changed

src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
add_subdirectory(common)
22

33
add_subdirectory(bmp)
4+
add_subdirectory(png)
45
add_subdirectory(qoi)
56

67
add_library(image formats.hpp formats.cpp)
@@ -9,5 +10,6 @@ target_link_libraries(image
910
common
1011

1112
bmp
13+
png
1214
qoi
1315
)

src/formats.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
#include <exception>
44

55
#include "bmp_format.hpp"
6+
#include "png_format.hpp"
67
#include "qoi_format.hpp"
78

89
const std::unordered_map<std::string, Format> Formats::FORMATS {
910
{ "qoi", QOI_FORMAT },
1011
{ "bmp", BMP_FORMAT },
12+
{ "png", PNG_FORMAT },
1113
};
1214

1315
const Format& Formats::get_by_id(const std::string& format_id)

src/png/CMakeLists.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
set(HEADERS
2+
png_common.hpp
3+
png_decoder.hpp
4+
png_format.hpp
5+
png_encoder.hpp
6+
png_settings.hpp
7+
)
8+
9+
set(SOURCES
10+
png_common.cpp
11+
png_decoder.cpp
12+
png_encoder.cpp
13+
)
14+
15+
add_library(png ${HEADERS} ${SOURCES})
16+
target_include_directories(png PUBLIC ${CMAKE_CURRENT_LIST_DIR})
17+
target_link_libraries(png common)

src/png/png_common.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "png_common.hpp"

src/png/png_common.hpp

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
#include <string>
5+
6+
#include "pixel.hpp"
7+
#include "raw_image.hpp"
8+
#include "stream.hpp"
9+
10+
namespace PNG {
11+
12+
constexpr uint64_t SIGNATURE = 0x89504E470D0A1A0A;
13+
14+
// clang-format off
15+
constexpr uint32_t CHUNK_NAME_HEADER = 0x49484452; // IHDR
16+
constexpr uint32_t CHUNK_NAME_PALETTE = 0x504C5445; // PLTE
17+
constexpr uint32_t CHUNK_NAME_IMAGE_DATA = 0x49444154; // IDAT
18+
constexpr uint32_t CHUNK_NAME_IMAGE_TRAILER = 0x49454E44; // IEND
19+
20+
constexpr uint32_t CHUNK_NAME_PRIMARY_CHROMA_AND_WHITE_POINTS = 0x6348524D; // cHRM
21+
constexpr uint32_t CHUNK_NAME_IMAGE_GAMMA = 0x67414D41; // gAMA
22+
constexpr uint32_t CHUNK_NAME_ICC_PROFILE = 0x69434350; // iCCP
23+
constexpr uint32_t CHUNK_NAME_SIGNIFICANT_BIT = 0x73424954; // sBIT
24+
constexpr uint32_t CHUNK_NAME_STANDARD_RGB = 0x73524742; // sRGB
25+
constexpr uint32_t CHUNK_NAME_BACKGROUND_COLOR = 0x624B4744; // bKGD
26+
constexpr uint32_t CHUNK_NAME_IMAGE_HISTOGRAM = 0x68495354; // hIST
27+
constexpr uint32_t CHUNK_NAME_TRANSPARENCY = 0x74524E53; // tRNS
28+
constexpr uint32_t CHUNK_NAME_PHYSICAL_PIXEL_DIMENSIONS = 0x70485973; // pHYs
29+
constexpr uint32_t CHUNK_NAME_SUGGESTED_PALETTE = 0x73504C54; // sPLT
30+
constexpr uint32_t CHUNK_NAME_IMAGE_LAST_MODIFICATION_TIME = 0x74494D45; // tIME
31+
constexpr uint32_t CHUNK_NAME_INTERNATIONAL_TEXTUAL_DATA = 0x69545874; // iTXt
32+
constexpr uint32_t CHUNK_NAME_TEXTUAL_DATA = 0x74455874; // tEXt
33+
constexpr uint32_t CHUNK_NAME_COMPRESSED_TEXTUAL_DATA = 0x7A545874; // zTXt
34+
// clang-format on
35+
36+
enum class BitDepth : uint8_t
37+
{
38+
BD_1 = 1,
39+
BD_2 = 2,
40+
BD_4 = 4,
41+
BD_8 = 8,
42+
BD_16 = 16,
43+
};
44+
45+
enum class ColorType : uint8_t
46+
{
47+
GREYSCALE = 0,
48+
TRUE_COLOR = 2,
49+
INDEXED_COLOR = 3,
50+
GREYSCALE_WITH_ALPHA = 4,
51+
TRUE_COLOR_WITH_ALPHA = 6,
52+
};
53+
54+
enum class CompressionMethod : uint8_t
55+
{
56+
DEFLATE_INFLATE = 0,
57+
};
58+
59+
enum class FilterMethod : uint8_t
60+
{
61+
ADAPTIVE = 0,
62+
};
63+
64+
enum class InterlaceMethod : uint8_t
65+
{
66+
STANDARD = 0,
67+
ADAM_7 = 1,
68+
};
69+
70+
enum class RenderingIntent : uint8_t
71+
{
72+
PERCEPTUAL = 0,
73+
RELATIVE_COLORIMETRIC = 1,
74+
SATURATION = 2,
75+
ABSOLUTE_COLORIMETRIC = 3,
76+
};
77+
78+
enum class UnitSpecifier : uint8_t
79+
{
80+
UNKNOWN = 0,
81+
METER = 1,
82+
};
83+
84+
struct Date
85+
{
86+
uint16_t year;
87+
uint8_t month;
88+
uint8_t day;
89+
uint8_t hour;
90+
uint8_t minute;
91+
uint8_t second;
92+
};
93+
94+
class TextualData
95+
{
96+
protected:
97+
std::string keyword;
98+
std::string text;
99+
100+
public:
101+
TextualData(const std::string& keyword, const std::string& text) :
102+
keyword { keyword }, text { text } {}
103+
104+
virtual ~TextualData() = default;
105+
106+
const std::string& get_keyword() const { return keyword; }
107+
virtual const std::string& get_text() const { return text; }
108+
};
109+
110+
class CompressedTextualData : public TextualData
111+
{
112+
protected:
113+
uint8_t compression_method;
114+
115+
public:
116+
CompressedTextualData(const std::string& keyword, const std::string& text, uint8_t compression_method) :
117+
TextualData { keyword, text }, compression_method { compression_method } {}
118+
119+
virtual ~CompressedTextualData() = default;
120+
121+
// TODO: Uncompress text
122+
const std::string& get_text() const override { return text; }
123+
};
124+
125+
struct InternationalTextualData : public CompressedTextualData
126+
{
127+
protected:
128+
std::string language_tag;
129+
uint8_t compression_flag;
130+
131+
public:
132+
InternationalTextualData(const std::string& keyword, const std::string& text, uint8_t compression_flag, uint8_t compression_method, const std::string& language_tag) :
133+
CompressedTextualData { keyword, text, compression_method },
134+
language_tag { language_tag },
135+
compression_flag { compression_flag }
136+
{
137+
}
138+
139+
virtual ~InternationalTextualData() = default;
140+
141+
const std::string& get_language_tag() const { return language_tag; }
142+
uint8_t get_compression_flag() const { return compression_flag; }
143+
};
144+
145+
}

0 commit comments

Comments
 (0)