Skip to content

Commit

Permalink
Merge pull request #1080 from bradh/rgb565
Browse files Browse the repository at this point in the history
colorconversion: add support for promoting < 8 bit planar to 8 bit planar
  • Loading branch information
farindk authored Dec 26, 2023
2 parents c4255a2 + 3a186f8 commit aa4cb58
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 3 deletions.
23 changes: 21 additions & 2 deletions libheif/color-conversion/hdr_sdr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,27 @@ Op_to_sdr_planes::convert_colorspace(const std::shared_ptr<const HeifPixelImage>
int in = p_in[y * stride_in + x];
p_out[y * stride_out + x] = (uint8_t) (in >> shift); // TODO: I think no rounding here, but am not sure.
}
}
else {
} else if (input_bits < 8) {
int width = input->get_width(channel);
int height = input->get_height(channel);
if (!outimg->add_plane(channel, width, height, 8)) {
return nullptr;
}

int shift = 8 - input_bits;

int stride_in;
const uint8_t* p_in = input->get_plane(channel, &stride_in);

int stride_out;
uint8_t* p_out = outimg->get_plane(channel, &stride_out);

for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++) {
int in = p_in[y * stride_in + x];
p_out[y * stride_out + x] = (uint8_t) (in << shift); // TODO: I think no rounding here, but am not sure.
}
} else {
outimg->copy_new_plane_from(input, channel, channel);
}
}
Expand Down
2 changes: 1 addition & 1 deletion libheif/pixelimage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ void HeifPixelImage::fill_new_plane(heif_channel dst_channel, uint16_t value, in

int num_interleaved = num_interleaved_pixels_per_plane(m_chroma);

if (bpp == 8) {
if (bpp <= 8) {
uint8_t* dst;
int dst_stride = 0;
dst = get_plane(dst_channel, &dst_stride);
Expand Down
37 changes: 37 additions & 0 deletions tests/conversion.cc
Original file line number Diff line number Diff line change
Expand Up @@ -615,14 +615,17 @@ static void fill_plane(std::shared_ptr<HeifPixelImage>& img, heif_channel channe

static void assert_plane(std::shared_ptr<HeifPixelImage>& img, heif_channel channel, const std::vector<uint8_t>& pixels)
{
INFO("channel: " << channel);
int w = img->get_width(channel);
int h = img->get_height(channel);

int stride;
uint8_t* p = img->get_plane(channel, &stride);

for (int y = 0; y < h; y++) {
INFO("row: " << y);
for (int x = 0; x < w; x++) {
INFO("column: " << x);
REQUIRE((int)p[y * stride + x] == (int)pixels[y * w + x]);
}
}
Expand Down Expand Up @@ -665,3 +668,37 @@ TEST_CASE("Bilinear upsampling", "[heif_image]")
50, 38, 13, 0
});
}

TEST_CASE("RGB 5-6-5 to RGB")
{
heif_color_conversion_options options = {};

std::shared_ptr<HeifPixelImage> img = std::make_shared<HeifPixelImage>();
const int width = 3;
const int height = 2;
img->create(width, height, heif_colorspace_RGB, heif_chroma_444);
img->add_plane(heif_channel_R, width, height, 5);
REQUIRE(img->get_bits_per_pixel(heif_channel_R) == 5);
img->add_plane(heif_channel_G, width, height, 6);
REQUIRE(img->get_bits_per_pixel(heif_channel_G) == 6);
img->add_plane(heif_channel_B, width, height, 5);
REQUIRE(img->get_bits_per_pixel(heif_channel_B) == 5);

uint8_t v = 1;
for (heif_channel plane: {heif_channel_R, heif_channel_G, heif_channel_B}) {
int dst_stride = 0;
uint8_t *dst = img->get_plane(plane, &dst_stride);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
dst[y * dst_stride + x] = v;
v += 1;
}
}
}

std::shared_ptr<HeifPixelImage> out = convert_colorspace(img, heif_colorspace_RGB, heif_chroma_444, nullptr, 8, options);

assert_plane(out, heif_channel_R, {8, 16, 24, 32, 40, 48});
assert_plane(out, heif_channel_G, {28, 32, 36, 40, 44, 48});
assert_plane(out, heif_channel_B, {104, 112, 120, 128, 136, 144});
}

0 comments on commit aa4cb58

Please sign in to comment.