Skip to content

Commit

Permalink
kvazaar: support for 10 bit input images
Browse files Browse the repository at this point in the history
  • Loading branch information
farindk committed Nov 25, 2024
1 parent 5bccf49 commit 5816f6a
Showing 1 changed file with 23 additions and 7 deletions.
30 changes: 23 additions & 7 deletions libheif/plugins/encoder_kvazaar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -348,14 +348,17 @@ static void append_chunk_data(kvz_data_chunk* data, std::vector<uint8_t>& out)
}


static void copy_plane(kvz_pixel* out_p, uint32_t out_stride, const uint8_t* in_p, uint32_t in_stride, int w, int h, int padded_width, int padded_height)
static void copy_plane(kvz_pixel* out_p, uint32_t out_stride, const uint8_t* in_p, uint32_t in_stride, int w, int h, int padded_width, int padded_height,
int bit_depth)
{
int bpp = (bit_depth > 8) ? 2 : 1;

for (int y = 0; y < padded_height; y++) {
int sy = std::min(y, h - 1); // source y
memcpy(out_p + y * out_stride, in_p + sy * in_stride, w);
memcpy(out_p + y * out_stride, in_p + sy * in_stride, w * bpp);

if (padded_width > w) {
memset(out_p + y * out_stride + w, *(in_p + sy * in_stride + w - 1), padded_width - w);
memset(out_p + y * out_stride + w, *(in_p + sy * in_stride + w - 1), (padded_width - w) * bpp);
}
}
}
Expand All @@ -372,9 +375,22 @@ static struct heif_error kvazaar_encode_image(void* encoder_raw, const struct he
struct encoder_struct_kvazaar* encoder = (struct encoder_struct_kvazaar*) encoder_raw;

int bit_depth = heif_image_get_bits_per_pixel_range(image, heif_channel_Y);
int bit_depth_chroma = 0;
bool isGreyscale = (heif_image_get_colorspace(image) == heif_colorspace_monochrome);
heif_chroma chroma = heif_image_get_chroma_format(image);

if (!isGreyscale) {
bit_depth_chroma = heif_image_get_bits_per_pixel_range(image, heif_channel_Cb);
if (bit_depth != bit_depth_chroma) {
struct heif_error err = {
heif_error_Encoder_plugin_error,
heif_suberror_Unsupported_bit_depth,
"Luma bit depth must equal the chroma bit depth"
};
return err;
}
}

// Kvazaar uses a hard-coded bit depth (https://github.com/ultravideo/kvazaar/issues/399).
// Check whether this matches to the image bit depth.
// TODO: we should check the bit depth supported by the encoder (like query_input_colorspace2()) and output a warning
Expand Down Expand Up @@ -588,22 +604,22 @@ static struct heif_error kvazaar_encode_image(void* encoder_raw, const struct he
int stride;
const uint8_t* data = heif_image_get_plane_readonly(image, heif_channel_Y, &stride);

copy_plane(pic->y, pic->stride, data, stride, input_width, input_height, encoded_width, encoded_height);
copy_plane(pic->y, pic->stride, data, stride, input_width, input_height, encoded_width, encoded_height, bit_depth);
}
else {
int stride;
const uint8_t* data;

data = heif_image_get_plane_readonly(image, heif_channel_Y, &stride);
copy_plane(pic->y, pic->stride, data, stride, input_width, input_height, encoded_width, encoded_height);
copy_plane(pic->y, pic->stride, data, stride, input_width, input_height, encoded_width, encoded_height, bit_depth);

data = heif_image_get_plane_readonly(image, heif_channel_Cb, &stride);
copy_plane(pic->u, pic->stride >> chroma_stride_shift, data, stride, input_chroma_width, input_chroma_height,
encoded_width >> chroma_stride_shift, encoded_height >> chroma_height_shift);
encoded_width >> chroma_stride_shift, encoded_height >> chroma_height_shift, bit_depth_chroma);

data = heif_image_get_plane_readonly(image, heif_channel_Cr, &stride);
copy_plane(pic->v, pic->stride >> chroma_stride_shift, data, stride, input_chroma_width, input_chroma_height,
encoded_width >> chroma_stride_shift, encoded_height >> chroma_height_shift);
encoded_width >> chroma_stride_shift, encoded_height >> chroma_height_shift, bit_depth_chroma);
}

auto uencoder = make_guard(api->encoder_open(config), [api](kvz_encoder* e) { api->encoder_close(e); });
Expand Down

0 comments on commit 5816f6a

Please sign in to comment.