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

Commit fa4c795

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

18 files changed

+804
-0
lines changed

Diff for: src/CMakeLists.txt

+2
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
)

Diff for: src/common/bits.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include "bits.hpp"
2+
3+
uint8_t reverse_byte(uint8_t value)
4+
{
5+
value = (value & 0b11110000) >> 4 | (value & 0b00001111) << 4;
6+
value = (value & 0b11001100) >> 2 | (value & 0b00110011) << 2;
7+
value = (value & 0b10101010) >> 1 | (value & 0b01010101) << 1;
8+
return value;
9+
}

Diff for: src/common/bits.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,5 @@ T generate_bitmask(uint8_t number_of_set_bits)
2929
{
3030
return (1 << number_of_set_bits) - 1;
3131
}
32+
33+
uint8_t reverse_byte(uint8_t value);

Diff for: src/formats.cpp

+2
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)

Diff for: src/png/CMakeLists.txt

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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)
18+
19+
find_package(ZLIB REQUIRED)
20+
target_link_libraries(png ZLIB::ZLIB)

Diff for: src/png/png_common.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "png_common.hpp"

Diff for: src/png/png_common.hpp

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
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+
static constexpr uint64_t SIGNATURE = 0x89504E470D0A1A0A;
13+
14+
// clang-format off
15+
static constexpr uint32_t CHUNK_NAME_HEADER = 0x49484452; // IHDR
16+
static constexpr uint32_t CHUNK_NAME_PALETTE = 0x504C5445; // PLTE
17+
static constexpr uint32_t CHUNK_NAME_IMAGE_DATA = 0x49444154; // IDAT
18+
static constexpr uint32_t CHUNK_NAME_IMAGE_TRAILER = 0x49454E44; // IEND
19+
20+
static constexpr uint32_t CHUNK_NAME_PRIMARY_CHROMA_AND_WHITE_POINTS = 0x6348524D; // cHRM
21+
static constexpr uint32_t CHUNK_NAME_IMAGE_GAMMA = 0x67414D41; // gAMA
22+
static constexpr uint32_t CHUNK_NAME_ICC_PROFILE = 0x69434350; // iCCP
23+
static constexpr uint32_t CHUNK_NAME_SIGNIFICANT_BIT = 0x73424954; // sBIT
24+
static constexpr uint32_t CHUNK_NAME_STANDARD_RGB = 0x73524742; // sRGB
25+
static constexpr uint32_t CHUNK_NAME_BACKGROUND_COLOR = 0x624B4744; // bKGD
26+
static constexpr uint32_t CHUNK_NAME_IMAGE_HISTOGRAM = 0x68495354; // hIST
27+
static constexpr uint32_t CHUNK_NAME_TRANSPARENCY = 0x74524E53; // tRNS
28+
static constexpr uint32_t CHUNK_NAME_PHYSICAL_PIXEL_DIMENSIONS = 0x70485973; // pHYs
29+
static constexpr uint32_t CHUNK_NAME_SUGGESTED_PALETTE = 0x73504C54; // sPLT
30+
static constexpr uint32_t CHUNK_NAME_IMAGE_LAST_MODIFICATION_TIME = 0x74494D45; // tIME
31+
static constexpr uint32_t CHUNK_NAME_INTERNATIONAL_TEXTUAL_DATA = 0x69545874; // iTXt
32+
static constexpr uint32_t CHUNK_NAME_TEXTUAL_DATA = 0x74455874; // tEXt
33+
static 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 FilterType : uint8_t
65+
{
66+
NONE = 0,
67+
SUB = 1,
68+
UP = 2,
69+
AVERAGE = 3,
70+
PAETH = 4,
71+
};
72+
73+
enum class InterlaceMethod : uint8_t
74+
{
75+
STANDARD = 0,
76+
ADAM_7 = 1,
77+
};
78+
79+
enum class RenderingIntent : uint8_t
80+
{
81+
PERCEPTUAL = 0,
82+
RELATIVE_COLORIMETRIC = 1,
83+
SATURATION = 2,
84+
ABSOLUTE_COLORIMETRIC = 3,
85+
};
86+
87+
enum class UnitSpecifier : uint8_t
88+
{
89+
UNKNOWN = 0,
90+
METER = 1,
91+
};
92+
93+
struct Date
94+
{
95+
uint16_t year;
96+
uint8_t month;
97+
uint8_t day;
98+
uint8_t hour;
99+
uint8_t minute;
100+
uint8_t second;
101+
};
102+
103+
class TextualData
104+
{
105+
protected:
106+
std::string keyword;
107+
std::string text;
108+
109+
public:
110+
TextualData(const std::string& keyword, const std::string& text) :
111+
keyword { keyword }, text { text } {}
112+
113+
virtual ~TextualData() = default;
114+
115+
const std::string& get_keyword() const { return keyword; }
116+
virtual const std::string& get_text() const { return text; }
117+
};
118+
119+
class CompressedTextualData : public TextualData
120+
{
121+
protected:
122+
uint8_t compression_method;
123+
124+
public:
125+
CompressedTextualData(const std::string& keyword, const std::string& text, uint8_t compression_method) :
126+
TextualData { keyword, text }, compression_method { compression_method } {}
127+
128+
virtual ~CompressedTextualData() = default;
129+
130+
// TODO: Uncompress text
131+
const std::string& get_text() const override { return text; }
132+
};
133+
134+
struct InternationalTextualData : public CompressedTextualData
135+
{
136+
protected:
137+
std::string language_tag;
138+
uint8_t compression_flag;
139+
140+
public:
141+
InternationalTextualData(const std::string& keyword, const std::string& text, uint8_t compression_flag, uint8_t compression_method, const std::string& language_tag) :
142+
CompressedTextualData { keyword, text, compression_method },
143+
language_tag { language_tag },
144+
compression_flag { compression_flag }
145+
{
146+
}
147+
148+
virtual ~InternationalTextualData() = default;
149+
150+
const std::string& get_language_tag() const { return language_tag; }
151+
uint8_t get_compression_flag() const { return compression_flag; }
152+
};
153+
154+
}

0 commit comments

Comments
 (0)