Skip to content

Commit

Permalink
more color conversion ops: handle case where alpha bit depth != color…
Browse files Browse the repository at this point in the history
… bit depth (#1404)
  • Loading branch information
farindk committed Nov 21, 2024
1 parent accdab0 commit 2e02ee2
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 29 deletions.
48 changes: 27 additions & 21 deletions libheif/color-conversion/chroma_sampling.cc
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,10 @@ Op_YCbCr444_to_YCbCr422_average<Pixel>::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);
Expand All @@ -378,9 +378,12 @@ Op_YCbCr444_to_YCbCr422_average<Pixel>::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);

const uint8_t* in_a;
uint8_t* out_a;

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);
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;
Expand All @@ -392,11 +395,9 @@ Op_YCbCr444_to_YCbCr422_average<Pixel>::convert_colorspace(const std::shared_ptr
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;
}

// --- fill right border if the image size is odd
Expand Down Expand Up @@ -432,7 +433,8 @@ Op_YCbCr444_to_YCbCr422_average<Pixel>::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);
}
}

Expand Down Expand Up @@ -557,10 +559,10 @@ Op_YCbCr420_bilinear_to_YCbCr444<Pixel>::convert_colorspace(const std::shared_pt
}
}

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);
Expand All @@ -570,9 +572,12 @@ Op_YCbCr420_bilinear_to_YCbCr444<Pixel>::convert_colorspace(const std::shared_pt
out_cb = (Pixel*) outimg->get_plane(heif_channel_Cb, &out_cb_stride);
out_cr = (Pixel*) outimg->get_plane(heif_channel_Cr, &out_cr_stride);

const uint8_t* in_a;
uint8_t* out_a;

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);
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;
Expand All @@ -584,11 +589,9 @@ Op_YCbCr420_bilinear_to_YCbCr444<Pixel>::convert_colorspace(const std::shared_pt
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;
}

/*
Expand Down Expand Up @@ -709,7 +712,8 @@ Op_YCbCr420_bilinear_to_YCbCr444<Pixel>::convert_colorspace(const std::shared_pt
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);
}
}

Expand Down Expand Up @@ -835,10 +839,10 @@ Op_YCbCr422_bilinear_to_YCbCr444<Pixel>::convert_colorspace(const std::shared_pt
}
}

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);
Expand All @@ -848,9 +852,12 @@ Op_YCbCr422_bilinear_to_YCbCr444<Pixel>::convert_colorspace(const std::shared_pt
out_cb = (Pixel*) outimg->get_plane(heif_channel_Cb, &out_cb_stride);
out_cr = (Pixel*) outimg->get_plane(heif_channel_Cr, &out_cr_stride);

const uint8_t* in_a;
uint8_t* out_a;

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);
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;
Expand All @@ -862,11 +869,9 @@ Op_YCbCr422_bilinear_to_YCbCr444<Pixel>::convert_colorspace(const std::shared_pt
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;
}

/*
Expand Down Expand Up @@ -933,7 +938,8 @@ Op_YCbCr422_bilinear_to_YCbCr444<Pixel>::convert_colorspace(const std::shared_pt
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);
}
}

Expand Down
19 changes: 11 additions & 8 deletions libheif/color-conversion/rgb2yuv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,10 @@ Op_RGB_to_YCbCr<Pixel>::convert_colorspace(const std::shared_ptr<const HeifPixel
}
}

const Pixel* in_r, * in_g, * in_b, * in_a;
const Pixel* in_r, * in_g, * in_b;
uint32_t in_r_stride = 0, in_g_stride = 0, in_b_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_r = (const Pixel*) input->get_plane(heif_channel_R, &in_r_stride);
Expand All @@ -149,9 +149,12 @@ Op_RGB_to_YCbCr<Pixel>::convert_colorspace(const std::shared_ptr<const HeifPixel
out_cb = (Pixel*) outimg->get_plane(heif_channel_Cb, &out_cb_stride);
out_cr = (Pixel*) outimg->get_plane(heif_channel_Cr, &out_cr_stride);

const uint8_t* in_a;
uint8_t* out_a;

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);
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;
Expand All @@ -162,11 +165,9 @@ Op_RGB_to_YCbCr<Pixel>::convert_colorspace(const std::shared_ptr<const HeifPixel
in_r_stride /= 2;
in_g_stride /= 2;
in_b_stride /= 2;
in_a_stride /= 2;
out_y_stride /= 2;
out_cb_stride /= 2;
out_cr_stride /= 2;
out_a_stride /= 2;
}

uint16_t halfRange = (uint16_t) (1 << (bpp - 1));
Expand Down Expand Up @@ -269,9 +270,11 @@ Op_RGB_to_YCbCr<Pixel>::convert_colorspace(const std::shared_ptr<const HeifPixel


if (has_alpha) {
int copyWidth = (hdr ? width * 2 : width);
int bpp_a = input->get_bits_per_pixel(heif_channel_Alpha);
int alphaCopyWidth = (bpp_a > 8 ? width * 2 : width);

for (y = 0; y < height; y++) {
memcpy(&out_a[y * out_a_stride], &in_a[y * in_a_stride], copyWidth);
memcpy(&out_a[y * out_a_stride], &in_a[y * in_a_stride], alphaCopyWidth);
}
}

Expand Down

0 comments on commit 2e02ee2

Please sign in to comment.