Skip to content

Commit f542f13

Browse files
committed
Linux: adding patches from libheif repo
1 parent 2fe6a43 commit f542f13

17 files changed

+791
-2
lines changed
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
From 2c8d963dfc0b967e6c78259ba0a99185b27206d8 Mon Sep 17 00:00:00 2001
2+
From: Dirk Farin <[email protected]>
3+
Date: Mon, 12 Jul 2021 14:10:20 +0200
4+
Subject: [PATCH] Op_RGB24_32_to_YCbCr: move chroma 4:2:0 sampling position to
5+
center (#521)
6+
7+
---
8+
libheif/heif_colorconversion.cc | 166 +++++++++++++++++++++++++++++---
9+
1 file changed, 150 insertions(+), 16 deletions(-)
10+
11+
diff --git a/libheif/heif_colorconversion.cc b/libheif/heif_colorconversion.cc
12+
index 7e420912..8803ffc8 100644
13+
--- a/libheif/heif_colorconversion.cc
14+
+++ b/libheif/heif_colorconversion.cc
15+
@@ -34,6 +34,9 @@ using namespace heif;
16+
#define DEBUG_ME 0
17+
#define DEBUG_PIPELINE_CREATION 0
18+
19+
+#define USE_CENTER_CHROMA_422 0
20+
+
21+
+
22+
std::ostream& operator<<(std::ostream& ostr, heif_colorspace c)
23+
{
24+
switch (c) {
25+
@@ -1944,6 +1947,25 @@ static inline uint8_t clip_f_u8(float fx)
26+
}
27+
28+
29+
+inline void set_chroma_pixels(uint8_t* out_cb, uint8_t* out_cr,
30+
+ uint8_t r, uint8_t g, uint8_t b,
31+
+ const RGB_to_YCbCr_coefficients& coeffs,
32+
+ bool full_range_flag)
33+
+{
34+
+ float cb = r * coeffs.c[1][0] + g * coeffs.c[1][1] + b * coeffs.c[1][2];
35+
+ float cr = r * coeffs.c[2][0] + g * coeffs.c[2][1] + b * coeffs.c[2][2];
36+
+
37+
+ if (full_range_flag) {
38+
+ *out_cb = clip_f_u8(cb + 128);
39+
+ *out_cr = clip_f_u8(cr + 128);
40+
+ }
41+
+ else {
42+
+ *out_cb = (uint8_t) clip_f_u8(cb * 0.875f + 128.0f);
43+
+ *out_cr = (uint8_t) clip_f_u8(cr * 0.875f + 128.0f);
44+
+ }
45+
+}
46+
+
47+
+
48+
std::shared_ptr<HeifPixelImage>
49+
Op_RGB24_32_to_YCbCr::convert_colorspace(const std::shared_ptr<const HeifPixelImage>& input,
50+
ColorState target_state,
51+
@@ -2024,30 +2046,142 @@ Op_RGB24_32_to_YCbCr::convert_colorspace(const std::shared_ptr<const HeifPixelIm
52+
}
53+
}
54+
55+
- for (int y = 0; y < height; y += chromaSubV) {
56+
- const uint8_t* p = &in_p[y * in_stride];
57+
+ if (chromaSubH == 1 && chromaSubV == 1) {
58+
+ // chroma 4:4:4
59+
60+
- for (int x = 0; x < width; x += chromaSubH) {
61+
- uint8_t r = p[0];
62+
- uint8_t g = p[1];
63+
- uint8_t b = p[2];
64+
- p += bytes_per_pixel * chromaSubH;
65+
+ for (int y = 0; y < height; y++) {
66+
+ const uint8_t* p = &in_p[y * in_stride];
67+
68+
- float cb = r * coeffs.c[1][0] + g * coeffs.c[1][1] + b * coeffs.c[1][2];
69+
- float cr = r * coeffs.c[2][0] + g * coeffs.c[2][1] + b * coeffs.c[2][2];
70+
+ for (int x = 0; x < width; x++) {
71+
+ uint8_t r = p[0];
72+
+ uint8_t g = p[1];
73+
+ uint8_t b = p[2];
74+
+ p += bytes_per_pixel;
75+
+
76+
+ set_chroma_pixels(out_cb + y * out_cb_stride + x,
77+
+ out_cr + y * out_cr_stride + x,
78+
+ r, g, b,
79+
+ coeffs, full_range_flag);
80+
+ }
81+
+ }
82+
+ }
83+
+ else if (chromaSubH == 2 && chromaSubV == 2) {
84+
+ // chroma 4:2:0
85+
86+
- if (full_range_flag) {
87+
- out_cb[(y / chromaSubV) * out_cb_stride + (x / chromaSubH)] = clip_f_u8(cb + 128);
88+
- out_cr[(y / chromaSubV) * out_cr_stride + (x / chromaSubH)] = clip_f_u8(cr + 128);
89+
+ for (int y = 0; y < (height & ~1); y += 2) {
90+
+ const uint8_t* p = &in_p[y * in_stride];
91+
+
92+
+ for (int x = 0; x < (width & ~1); x += 2) {
93+
+ uint8_t r = uint8_t((p[0] + p[bytes_per_pixel + 0] + p[in_stride + 0] + p[bytes_per_pixel + in_stride + 0]) / 4);
94+
+ uint8_t g = uint8_t((p[1] + p[bytes_per_pixel + 1] + p[in_stride + 1] + p[bytes_per_pixel + in_stride + 1]) / 4);
95+
+ uint8_t b = uint8_t((p[2] + p[bytes_per_pixel + 2] + p[in_stride + 2] + p[bytes_per_pixel + in_stride + 2]) / 4);
96+
+
97+
+ p += bytes_per_pixel * 2;
98+
+
99+
+ set_chroma_pixels(out_cb + (y / 2) * out_cb_stride + (x / 2),
100+
+ out_cr + (y / 2) * out_cr_stride + (x / 2),
101+
+ r, g, b,
102+
+ coeffs, full_range_flag);
103+
}
104+
- else {
105+
- out_cb[(y / chromaSubV) * out_cb_stride + (x / chromaSubH)] = (uint8_t) clip_f_u8(cb * 0.875f + 128.0f);
106+
- out_cr[(y / chromaSubV) * out_cr_stride + (x / chromaSubH)] = (uint8_t) clip_f_u8(cr * 0.875f + 128.0f);
107+
+ }
108+
+
109+
+ // 4:2:0 right column (if odd width)
110+
+ if (width & 1) {
111+
+ int x = width - 1;
112+
+ const uint8_t* p = &in_p[x * bytes_per_pixel];
113+
+
114+
+ for (int y = 0; y < height; y += 2) {
115+
+ uint8_t r, g, b;
116+
+ if (y + 1 < height) {
117+
+ r = uint8_t((p[0] + p[in_stride + 0]) / 2);
118+
+ g = uint8_t((p[1] + p[in_stride + 1]) / 2);
119+
+ b = uint8_t((p[2] + p[in_stride + 2]) / 2);
120+
+ }
121+
+ else {
122+
+ r = p[0];
123+
+ g = p[1];
124+
+ b = p[2];
125+
+ }
126+
+
127+
+ set_chroma_pixels(out_cb + (y / 2) * out_cb_stride + (x / 2),
128+
+ out_cr + (y / 2) * out_cr_stride + (x / 2),
129+
+ r, g, b,
130+
+ coeffs, full_range_flag);
131+
+
132+
+ p += in_stride * 2;
133+
+ }
134+
+ }
135+
+
136+
+ // 4:2:0 bottom row (if odd height)
137+
+ if (height & 1) {
138+
+ int y = height - 1;
139+
+ const uint8_t* p = &in_p[y * in_stride];
140+
+
141+
+ for (int x = 0; x < width; x += 2) {
142+
+ uint8_t r, g, b;
143+
+ if (x + 1 < width) {
144+
+ r = uint8_t((p[0] + p[bytes_per_pixel + 0]) / 2);
145+
+ g = uint8_t((p[1] + p[bytes_per_pixel + 1]) / 2);
146+
+ b = uint8_t((p[2] + p[bytes_per_pixel + 2]) / 2);
147+
+ }
148+
+ else {
149+
+ r = p[0];
150+
+ g = p[1];
151+
+ b = p[2];
152+
+ }
153+
+
154+
+ set_chroma_pixels(out_cb + (y / 2) * out_cb_stride + (x / 2),
155+
+ out_cr + (y / 2) * out_cr_stride + (x / 2),
156+
+ r, g, b,
157+
+ coeffs, full_range_flag);
158+
+
159+
+ p += bytes_per_pixel * 2;
160+
}
161+
}
162+
}
163+
+ else if (chromaSubH == 2 && chromaSubV == 1) {
164+
+ // chroma 4:2:2
165+
+
166+
+ for (int y = 0; y < height; y++) {
167+
+ const uint8_t* p = &in_p[y * in_stride];
168+
+
169+
+ for (int x = 0; x < width; x += 2) {
170+
+ uint8_t r, g, b;
171+
+
172+
+ // TODO: it still is an open question where the 'correct' chroma sample positions are for 4:2:2
173+
+ // Since 4:2:2 is primarily used for video content and as there is no way to signal center position for h.265,
174+
+ // we currently use left-aligned sampling. See the discussion here: https://github.com/strukturag/libheif/issues/521
175+
+#if USE_CENTER_CHROMA_422
176+
+ if (x + 1 < width) {
177+
+ r = uint8_t((p[0] + p[bytes_per_pixel + 0]) / 2);
178+
+ g = uint8_t((p[1] + p[bytes_per_pixel + 1]) / 2);
179+
+ b = uint8_t((p[2] + p[bytes_per_pixel + 2]) / 2);
180+
+ }
181+
+ else {
182+
+ r = p[0];
183+
+ g = p[1];
184+
+ b = p[2];
185+
+ }
186+
+#else
187+
+ r = p[0];
188+
+ g = p[1];
189+
+ b = p[2];
190+
+#endif
191+
+
192+
+ p += bytes_per_pixel * 2;
193+
+
194+
+ set_chroma_pixels(out_cb + y * out_cb_stride + (x / 2),
195+
+ out_cr + y * out_cr_stride + (x / 2),
196+
+ r, g, b,
197+
+ coeffs, full_range_flag);
198+
+ }
199+
+ }
200+
+ }
201+
+
202+
203+
if (has_alpha) {
204+
+ assert(bytes_per_pixel == 4);
205+
+
206+
for (int y = 0; y < height; y++) {
207+
for (int x = 0; x < width; x++) {
208+
uint8_t a = in_p[y * in_stride + x * 4 + 3];
209+
@@ -2460,7 +2594,7 @@ Op_to_sdr_planes::convert_colorspace(const std::shared_ptr<const HeifPixelImage>
210+
if (input->has_channel(channel)) {
211+
int input_bits = input->get_bits_per_pixel(channel);
212+
213+
- if (input_bits>8) {
214+
+ if (input_bits > 8) {
215+
int width = input->get_width(channel);
216+
int height = input->get_height(channel);
217+
outimg->add_plane(channel, width, height, 8);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
From ab0af732fd3c2ebf0211a0a072c76789c8d38d39 Mon Sep 17 00:00:00 2001
2+
From: Dirk Farin <[email protected]>
3+
Date: Mon, 12 Jul 2021 16:50:18 +0200
4+
Subject: [PATCH] Op_RRGGBBxx_HDR_to_YCbCr420: move chroma 4:2:0 sampling
5+
position to center (#521)
6+
7+
---
8+
libheif/heif_colorconversion.cc | 19 +++++++++++++++++++
9+
1 file changed, 19 insertions(+)
10+
11+
diff --git a/libheif/heif_colorconversion.cc b/libheif/heif_colorconversion.cc
12+
index 8803ffc8..92f78b4e 100644
13+
--- a/libheif/heif_colorconversion.cc
14+
+++ b/libheif/heif_colorconversion.cc
15+
@@ -2786,6 +2786,25 @@ Op_RRGGBBxx_HDR_to_YCbCr420::convert_colorspace(const std::shared_ptr<const Heif
16+
float g = static_cast<float>((in[2 + le] << 8) | in[3 - le]);
17+
float b = static_cast<float>((in[4 + le] << 8) | in[5 - le]);
18+
19+
+ int dx = (x + 1 < width) ? bytesPerPixel : 0;
20+
+ int dy = (y + 1 < height) ? in_p_stride : 0;
21+
+
22+
+ r += static_cast<float>((in[0 + le + dx] << 8) | in[1 - le + dx]);
23+
+ g += static_cast<float>((in[2 + le + dx] << 8) | in[3 - le + dx]);
24+
+ b += static_cast<float>((in[4 + le + dx] << 8) | in[5 - le + dx]);
25+
+
26+
+ r += static_cast<float>((in[0 + le + dy] << 8) | in[1 - le + dy]);
27+
+ g += static_cast<float>((in[2 + le + dy] << 8) | in[3 - le + dy]);
28+
+ b += static_cast<float>((in[4 + le + dy] << 8) | in[5 - le + dy]);
29+
+
30+
+ r += static_cast<float>((in[0 + le + dx + dy] << 8) | in[1 - le + dx + dy]);
31+
+ g += static_cast<float>((in[2 + le + dx + dy] << 8) | in[3 - le + dx + dy]);
32+
+ b += static_cast<float>((in[4 + le + dx + dy] << 8) | in[5 - le + dx + dy]);
33+
+
34+
+ r *= 0.25f;
35+
+ g *= 0.25f;
36+
+ b *= 0.25f;
37+
+
38+
float cb = r * coeffs.c[1][0] + g * coeffs.c[1][1] + b * coeffs.c[1][2];
39+
float cr = r * coeffs.c[2][0] + g * coeffs.c[2][1] + b * coeffs.c[2][2];
40+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
From 2dfc9b2c04ce77c0d85af37a4f66c0ee2dbe058d Mon Sep 17 00:00:00 2001
2+
From: Dirk Farin <[email protected]>
3+
Date: Mon, 12 Jul 2021 17:00:09 +0200
4+
Subject: [PATCH] Op_RGB_to_YCbCr: move chroma 4:2:0 sampling position to
5+
center (#521)
6+
7+
---
8+
libheif/heif_colorconversion.cc | 21 +++++++++++++++++++++
9+
1 file changed, 21 insertions(+)
10+
11+
diff --git a/libheif/heif_colorconversion.cc b/libheif/heif_colorconversion.cc
12+
index 92f78b4e..f85bcccb 100644
13+
--- a/libheif/heif_colorconversion.cc
14+
+++ b/libheif/heif_colorconversion.cc
15+
@@ -723,6 +723,27 @@ Op_RGB_to_YCbCr<Pixel>::convert_colorspace(const std::shared_ptr<const HeifPixel
16+
float g = in_g[y * in_g_stride + x];
17+
float b = in_b[y * in_b_stride + x];
18+
19+
+ if (subH > 1 || subV > 1) {
20+
+ int x2 = (x + 1 < width && subH == 2 && subV == 2) ? x + 1 : x; // subV==2 -> Do not center for 4:2:2 (see comment in Op_RGB24_32_to_YCbCr, github issue #521)
21+
+ int y2 = (y + 1 < height && subV == 2) ? y + 1 : y;
22+
+
23+
+ r += in_r[y * in_r_stride + x2];
24+
+ g += in_g[y * in_g_stride + x2];
25+
+ b += in_b[y * in_b_stride + x2];
26+
+
27+
+ r += in_r[y2 * in_r_stride + x];
28+
+ g += in_g[y2 * in_g_stride + x];
29+
+ b += in_b[y2 * in_b_stride + x];
30+
+
31+
+ r += in_r[y2 * in_r_stride + x2];
32+
+ g += in_g[y2 * in_g_stride + x2];
33+
+ b += in_b[y2 * in_b_stride + x2];
34+
+
35+
+ r *= 0.25f;
36+
+ g *= 0.25f;
37+
+ b *= 0.25f;
38+
+ }
39+
+
40+
float cb, cr;
41+
42+
cb = r * coeffs.c[1][0] + g * coeffs.c[1][1] + b * coeffs.c[1][2];
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
From 487c3d821df79178edd18a62285449d8d1f70160 Mon Sep 17 00:00:00 2001
2+
From: Dirk Farin <[email protected]>
3+
Date: Mon, 12 Jul 2021 18:16:11 +0200
4+
Subject: [PATCH] AVIF: signal chroma sample position when encoding (#521)
5+
6+
---
7+
libheif/heif_encoder_aom.cc | 6 ++++++
8+
libheif/heif_encoder_rav1e.cc | 8 ++++++--
9+
2 files changed, 12 insertions(+), 2 deletions(-)
10+
11+
diff --git a/libheif/heif_encoder_aom.cc b/libheif/heif_encoder_aom.cc
12+
index 65a72e29..6bc2f25f 100644
13+
--- a/libheif/heif_encoder_aom.cc
14+
+++ b/libheif/heif_encoder_aom.cc
15+
@@ -590,23 +590,28 @@ struct heif_error aom_encode_image(void* encoder_raw, const struct heif_image* i
16+
aom_img_fmt_t img_format = AOM_IMG_FMT_NONE;
17+
18+
int chroma_height = 0;
19+
+ int chroma_sample_position = AOM_CSP_UNKNOWN;
20+
21+
switch (chroma) {
22+
case heif_chroma_420:
23+
case heif_chroma_monochrome:
24+
img_format = AOM_IMG_FMT_I420;
25+
chroma_height = (source_height+1)/2;
26+
+ chroma_sample_position = AOM_CSP_UNKNOWN; // TODO: change this to CSP_CENTER in the future (https://github.com/AOMediaCodec/av1-avif/issues/88)
27+
break;
28+
case heif_chroma_422:
29+
img_format = AOM_IMG_FMT_I422;
30+
chroma_height = (source_height+1)/2;
31+
+ chroma_sample_position = AOM_CSP_COLOCATED;
32+
break;
33+
case heif_chroma_444:
34+
img_format = AOM_IMG_FMT_I444;
35+
chroma_height = source_height;
36+
+ chroma_sample_position = AOM_CSP_COLOCATED;
37+
break;
38+
default:
39+
img_format = AOM_IMG_FMT_NONE;
40+
+ chroma_sample_position = AOM_CSP_UNKNOWN;
41+
assert(false);
42+
break;
43+
}
44+
@@ -760,6 +765,7 @@ struct heif_error aom_encode_image(void* encoder_raw, const struct heif_image* i
45+
46+
// In aom, color_range defaults to limited range (0). Set it to full range (1).
47+
aom_codec_control(&codec, AV1E_SET_COLOR_RANGE, nclx ? nclx->get_full_range_flag() : 1);
48+
+ aom_codec_control(&codec, AV1E_SET_CHROMA_SAMPLE_POSITION, chroma_sample_position);
49+
50+
if (nclx &&
51+
(input_class == heif_image_input_class_normal ||
52+
diff --git a/libheif/heif_encoder_rav1e.cc b/libheif/heif_encoder_rav1e.cc
53+
index cec32080..14ce68f1 100644
54+
--- a/libheif/heif_encoder_rav1e.cc
55+
+++ b/libheif/heif_encoder_rav1e.cc
56+
@@ -515,7 +515,9 @@ struct heif_error rav1e_encode_image(void* encoder_raw, const struct heif_image*
57+
58+
uint8_t yShift = 0;
59+
RaChromaSampling chromaSampling;
60+
+ RaChromaSamplePosition chromaPosition;
61+
RaPixelRange rav1eRange;
62+
+
63+
if (input_class == heif_image_input_class_alpha) {
64+
chromaSampling = RA_CHROMA_SAMPLING_CS420; // I can't seem to get RA_CHROMA_SAMPLING_CS400 to work right now, unfortunately
65+
}
66+
@@ -523,12 +525,15 @@ struct heif_error rav1e_encode_image(void* encoder_raw, const struct heif_image*
67+
switch (chroma) {
68+
case heif_chroma_444:
69+
chromaSampling = RA_CHROMA_SAMPLING_CS444;
70+
+ chromaPosition = RA_CHROMA_SAMPLE_POSITION_COLOCATED;
71+
break;
72+
case heif_chroma_422:
73+
chromaSampling = RA_CHROMA_SAMPLING_CS422;
74+
+ chromaPosition = RA_CHROMA_SAMPLE_POSITION_COLOCATED;
75+
break;
76+
case heif_chroma_420:
77+
chromaSampling = RA_CHROMA_SAMPLING_CS420;
78+
+ chromaPosition = RA_CHROMA_SAMPLE_POSITION_UNKNOWN; // TODO: set to CENTER when AV1 and rav1e supports this
79+
yShift = 1;
80+
break;
81+
default:
82+
@@ -548,8 +553,7 @@ struct heif_error rav1e_encode_image(void* encoder_raw, const struct heif_image*
83+
auto rav1eConfigRaw = rav1e_config_default();
84+
auto rav1eConfig = std::shared_ptr<RaConfig>(rav1eConfigRaw, [](RaConfig* c) { rav1e_config_unref(c); });
85+
86+
- if (rav1e_config_set_pixel_format(rav1eConfig.get(), (uint8_t) bitDepth, chromaSampling,
87+
- RA_CHROMA_SAMPLE_POSITION_UNKNOWN, rav1eRange) < 0) {
88+
+ if (rav1e_config_set_pixel_format(rav1eConfig.get(), (uint8_t) bitDepth, chromaSampling, chromaPosition, rav1eRange) < 0) {
89+
return heif_error_codec_library_error;
90+
}
91+

libheif/linux/libheif/014-expose-aom-decoder-errors.patch renamed to libheif/linux/libheif/018-expose-aom-decoder-errors.patch

File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)