This repository was archived by the owner on Jan 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathqoi.h
More file actions
141 lines (113 loc) · 3.59 KB
/
qoi.h
File metadata and controls
141 lines (113 loc) · 3.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#ifndef QOI_FORMAT_CODEC_QOI_H_
#define QOI_FORMAT_CODEC_QOI_H_
#include "utils.h"
constexpr uint8_t QOI_OP_INDEX_TAG = 0x00;
constexpr uint8_t QOI_OP_DIFF_TAG = 0x40;
constexpr uint8_t QOI_OP_LUMA_TAG = 0x80;
constexpr uint8_t QOI_OP_RUN_TAG = 0xc0;
constexpr uint8_t QOI_OP_RGB_TAG = 0xfe;
constexpr uint8_t QOI_OP_RGBA_TAG = 0xff;
constexpr uint8_t QOI_PADDING[8] = {0u, 0u, 0u, 0u, 0u, 0u, 0u, 1u};
constexpr uint8_t QOI_MASK_2 = 0xc0;
/**
* @brief encode the raw pixel data of an image to qoi format.
*
* @param[in] width image width in pixels
* @param[in] height image height in pixels
* @param[in] channels number of color channels, 3 = RGB, 4 = RGBA
* @param[in] colorspace image color space, 0 = sRGB with linear alpha, 1 = all channels linear
*
* @return bool true if it is a valid qoi format image, false otherwise
*/
bool QoiEncode(uint32_t width, uint32_t height, uint8_t channels, uint8_t colorspace = 0);
/**
* @brief decode the qoi format of an image to raw pixel data
*
* @param[out] width image width in pixels
* @param[out] height image height in pixels
* @param[out] channels number of color channels, 3 = RGB, 4 = RGBA
* @param[out] colorspace image color space, 0 = sRGB with linear alpha, 1 = all channels linear
*
* @return bool true if it is a valid qoi format image, false otherwise
*/
bool QoiDecode(uint32_t &width, uint32_t &height, uint8_t &channels, uint8_t &colorspace);
bool QoiEncode(uint32_t width, uint32_t height, uint8_t channels, uint8_t colorspace) {
// qoi-header part
// write magic bytes "qoif"
QoiWriteChar('q');
QoiWriteChar('o');
QoiWriteChar('i');
QoiWriteChar('f');
// write image width
QoiWriteU32(width);
// write image height
QoiWriteU32(height);
// write channel number
QoiWriteU8(channels);
// write color space specifier
QoiWriteU8(colorspace);
/* qoi-data part */
int run = 0;
int px_num = width * height;
uint8_t history[64][4];
memset(history, 0, sizeof(history));
uint8_t r, g, b, a;
a = 255u;
uint8_t pre_r, pre_g, pre_b, pre_a;
pre_r = 0u;
pre_g = 0u;
pre_b = 0u;
pre_a = 255u;
for (int i = 0; i < px_num; ++i) {
r = QoiReadU8();
g = QoiReadU8();
b = QoiReadU8();
if (channels == 4) a = QoiReadU8();
// TODO
pre_r = r;
pre_g = g;
pre_b = b;
pre_a = a;
}
// qoi-padding part
for (int i = 0; i < sizeof(QOI_PADDING) / sizeof(QOI_PADDING[0]); ++i) {
QoiWriteU8(QOI_PADDING[i]);
}
return true;
}
bool QoiDecode(uint32_t &width, uint32_t &height, uint8_t &channels, uint8_t &colorspace) {
char c1 = QoiReadChar();
char c2 = QoiReadChar();
char c3 = QoiReadChar();
char c4 = QoiReadChar();
if (c1 != 'q' || c2 != 'o' || c3 != 'i' || c4 != 'f') {
return false;
}
// read image width
width = QoiReadU32();
// read image height
height = QoiReadU32();
// read channel number
channels = QoiReadU8();
// read color space specifier
colorspace = QoiReadU8();
int run = 0;
int px_num = width * height;
uint8_t history[64][4];
memset(history, 0, sizeof(history));
uint8_t r, g, b, a;
a = 255u;
for (int i = 0; i < px_num; ++i) {
// TODO
QoiWriteU8(r);
QoiWriteU8(g);
QoiWriteU8(b);
if (channels == 4) QoiWriteU8(a);
}
bool valid = true;
for (int i = 0; i < sizeof(QOI_PADDING) / sizeof(QOI_PADDING[0]); ++i) {
if (QoiReadU8() != QOI_PADDING[i]) valid = false;
}
return valid;
}
#endif // QOI_FORMAT_CODEC_QOI_H_