Repository navigation
Expand file tree
/
Copy pathimage.cpp
More file actions
131 lines (109 loc) · 4.23 KB
/
Copy pathimage.cpp
File metadata and controls
131 lines (109 loc) · 4.23 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
/*
by korenkonder
GitHub/GitLab: korenkonder
*/
#include "image.hpp"
static rgb565 rgb565_apply_color_tone(rgb565 col, const color_tone* col_tone);
static void rgb_to_ycc(vec3& rgb, vec3& ycc);
static void ycc_apply_col_tone_hue(vec3& ycc, const color_tone* col_tone);
static void ycc_to_rgb(vec3& ycc, vec3& rgb);
color_tone::color_tone() : reserved() {
blend = 1.0f;
offset = 0.0f;
hue = 0.0f;
saturation = 1.0f;
value = 0.0f;
contrast = 1.0f;
inverse = false;
}
void dxt1_image_apply_color_tone(int32_t width, int32_t height,
int32_t size, dxt1_block* data, const color_tone* col_tone) {
if (size <= 0)
return;
for (size_t i = (size - 1ULL) / sizeof(dxt1_block) + 1; i; i--, data++) {
data->color0 = rgb565_apply_color_tone(data->color0, col_tone);
data->color1 = rgb565_apply_color_tone(data->color1, col_tone);
if (*(uint16_t*)&data->color0 <= *(uint16_t*)&data->color1) {
data->indices[0] &= ~((data->indices[0] >> 1) & 0x5555);
data->indices[1] &= ~((data->indices[1] >> 1) & 0x5555);
}
}
}
void dxt5_image_apply_color_tone(int32_t width, int32_t height,
int32_t size, dxt5_block* data, const color_tone* col_tone) {
if (size <= 0)
return;
for (size_t i = (size - 1ULL) / sizeof(dxt5_block) + 1; i; i--, data++) {
data->color0 = rgb565_apply_color_tone(data->color0, col_tone);
data->color1 = rgb565_apply_color_tone(data->color1, col_tone);
if (*(uint16_t*)&data->color0 <= *(uint16_t*)&data->color1) {
data->color_indices[0] &= ~((data->color_indices[0] >> 1) & 0x5555);
data->color_indices[1] &= ~((data->color_indices[1] >> 1) & 0x5555);
}
}
}
void rgb565_image_apply_color_tone(int32_t width, int32_t height,
int32_t size, rgb565* data, const color_tone* col_tone) {
for (size_t i = (size - 1ULL) / sizeof(uint16_t) + 1; i; i--, data++)
*data = rgb565_apply_color_tone(*data, col_tone);
}
static rgb565 rgb565_apply_color_tone(rgb565 col, const color_tone* col_tone) {
const vec3 scale = {
(float_t)((1 << 5) - 1),
(float_t)((1 << 6) - 1),
(float_t)((1 << 5) - 1),
};
const vec3 inv_scale = {
(float_t)(1.0 / (double_t)((1 << 5) - 1)),
(float_t)(1.0 / (double_t)((1 << 6) - 1)),
(float_t)(1.0 / (double_t)((1 << 5) - 1)),
};
vec3 rgb;
if (col_tone->inverse) {
rgb.x = (float_t)((1 << 5) - 1 - col.r);
rgb.y = (float_t)((1 << 5) - 1 - col.g);
rgb.z = (float_t)((1 << 5) - 1 - col.b);
}
else {
rgb.x = (float_t)col.r;
rgb.y = (float_t)col.g;
rgb.z = (float_t)col.b;
}
rgb = vec3::clamp(rgb * inv_scale * col_tone->blend + col_tone->offset, 0.0f, 1.0f);
vec3 ycc;
rgb_to_ycc(rgb, ycc);
*(vec2*)&ycc.y = *(vec2*)&ycc.y * col_tone->saturation;
ycc_apply_col_tone_hue(ycc, col_tone);
ycc.x = (ycc.x + col_tone->value - 0.5f) * col_tone->contrast + 0.5f;
ycc.x = clamp_def(ycc.x, 0.0f, 1.0f);
*(vec2*)&ycc.y = vec2::clamp(*(vec2*)&ycc.y, -0.5f, 0.5f);
ycc_to_rgb(ycc, rgb);
rgb = vec3::clamp(rgb, 0.0f, 1.0f) * scale;
col.r = (uint8_t)rgb.x;
col.g = (uint8_t)rgb.y;
col.b = (uint8_t)rgb.z;
return col;
}
inline static void rgb_to_ycc(vec3& rgb, vec3& ycc) {
const vec3 _y_coef_601 = { 0.29891f, 0.58661f, 0.11448f };
const vec3 _cb_coef_601 = { -0.16874f, -0.33126f, 0.5f };
const vec3 _cr_coef_601 = { 0.5f, -0.41869f, -0.08131f };
ycc.x = vec3::dot(rgb, _y_coef_601);
ycc.y = vec3::dot(rgb, _cb_coef_601);
ycc.z = vec3::dot(rgb, _cr_coef_601);
}
inline static void ycc_apply_col_tone_hue(vec3& ycc, const color_tone* col_tone) {
float_t hue = col_tone->hue * DEG_TO_RAD_FLOAT;
float_t cos = cosf(hue);
float_t sin = sinf(hue);
ycc.y = ycc.y * cos + ycc.z * sin;
ycc.z = ycc.z * cos - ycc.y * sin;
}
inline static void ycc_to_rgb(vec3& ycc, vec3& rgb) {
const vec3 _red_coef_601 = { 1.0f, 0.0f, 1.402f };
const vec3 _grn_coef_601 = { 1.0f, -0.34414f, -0.71414f };
const vec3 _blu_coef_601 = { 1.0f, 1.772f, 0.0f };
rgb.x = vec3::dot(ycc, _red_coef_601);
rgb.y = vec3::dot(ycc, _grn_coef_601);
rgb.z = vec3::dot(ycc, _blu_coef_601);
}