From fc3afe18a82d4230b618d94cdb4e191df41f285e Mon Sep 17 00:00:00 2001 From: Dirk Farin Date: Thu, 21 Nov 2024 12:59:06 +0100 Subject: [PATCH] YCbCr444_to_YCbCr420_average: handle case where alpha bit depth != color bit depth (#1404) --- libheif/color-conversion/chroma_sampling.cc | 34 ++++++++++++--------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/libheif/color-conversion/chroma_sampling.cc b/libheif/color-conversion/chroma_sampling.cc index 47b63d3cdf..f2dfc81f79 100644 --- a/libheif/color-conversion/chroma_sampling.cc +++ b/libheif/color-conversion/chroma_sampling.cc @@ -142,10 +142,10 @@ Op_YCbCr444_to_YCbCr420_average::convert_colorspace(const std::shared_ptr } } - const Pixel* in_y, * in_cb, * in_cr, * in_a; + const Pixel* in_y, * in_cb, * in_cr; uint32_t in_y_stride = 0, in_cb_stride = 0, in_cr_stride = 0, in_a_stride = 0; - Pixel* out_y, * out_cb, * out_cr, * out_a; + Pixel* out_y, * out_cb, * out_cr; uint32_t out_y_stride = 0, out_cb_stride = 0, out_cr_stride = 0, out_a_stride = 0; in_y = (const Pixel*) input->get_plane(heif_channel_Y, &in_y_stride); @@ -155,27 +155,30 @@ Op_YCbCr444_to_YCbCr420_average::convert_colorspace(const std::shared_ptr out_cb = (Pixel*) outimg->get_plane(heif_channel_Cb, &out_cb_stride); out_cr = (Pixel*) outimg->get_plane(heif_channel_Cr, &out_cr_stride); - if (has_alpha) { - in_a = (const Pixel*) input->get_plane(heif_channel_Alpha, &in_a_stride); - out_a = (Pixel*) outimg->get_plane(heif_channel_Alpha, &out_a_stride); - } - else { - in_a = nullptr; - out_a = nullptr; - } - - if (hdr) { in_y_stride /= 2; in_cb_stride /= 2; in_cr_stride /= 2; - in_a_stride /= 2; out_y_stride /= 2; out_cb_stride /= 2; out_cr_stride /= 2; - out_a_stride /= 2; } + + // We only copy the alpha, do not access it as 16 bit + const uint8_t* in_a; + uint8_t* out_a; + + if (has_alpha) { + in_a = input->get_plane(heif_channel_Alpha, &in_a_stride); + out_a = outimg->get_plane(heif_channel_Alpha, &out_a_stride); + } + else { + in_a = nullptr; + out_a = nullptr; + } + + // --- fill right and bottom borders if the image size is odd if (height & 1) { @@ -229,7 +232,8 @@ Op_YCbCr444_to_YCbCr420_average::convert_colorspace(const std::shared_ptr memcpy(&out_y[y * out_y_stride], &in_y[y * in_y_stride], copyWidth); if (has_alpha) { - memcpy(&out_a[y * out_a_stride], &in_a[y * in_a_stride], copyWidth); + uint32_t alphaCopyWidth = (bpp_a > 8 ? width * 2 : width); + memcpy(&out_a[y * out_a_stride], &in_a[y * in_a_stride], alphaCopyWidth); } }