Skip to content

Commit

Permalink
jpeg2000: fix parsing header for getting chroma format and bit depths
Browse files Browse the repository at this point in the history
  • Loading branch information
farindk committed Sep 15, 2024
1 parent d2ea2d2 commit a680e3d
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 20 deletions.
38 changes: 27 additions & 11 deletions libheif/codecs/image_item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,13 @@ Error ImageItem::get_coded_image_colorspace(heif_colorspace* out_colorspace, hei
*out_chroma = (heif_chroma) (av1C->get_configuration().get_heif_chroma());
}
else if (auto j2kH = m_heif_context->get_heif_file()->get_property<Box_j2kH>(id)) {
Result<std::vector<uint8_t>> dataResult = get_compressed_image_data();
if (dataResult.error) {
return dataResult.error;
}

JPEG2000MainHeader jpeg2000Header;
err = jpeg2000Header.parseHeader(*m_heif_context->get_heif_file(), id);
err = jpeg2000Header.parseHeader(*dataResult);
if (err) {
return err;
}
Expand Down Expand Up @@ -1079,16 +1084,8 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem::decode_from_compressed_data(h
}


Result<std::shared_ptr<HeifPixelImage>> ImageItem::decode_compressed_image(const struct heif_decoding_options& options,
bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const
Result<std::vector<uint8_t>> ImageItem::get_compressed_image_data() const
{
// --- find the decoder plugin with the correct compression format

heif_compression_format compression_format = get_compression_format();
if (compression_format == heif_compression_undefined) {
return Error{heif_error_Decoder_plugin_error, heif_suberror_Unsupported_codec, "Decoding not supported"};
}

// --- get the compressed image data

// data from configuration blocks
Expand All @@ -1107,5 +1104,24 @@ Result<std::shared_ptr<HeifPixelImage>> ImageItem::decode_compressed_image(const
return error;
}

return decode_from_compressed_data(compression_format, options, data);
return data;
}


Result<std::shared_ptr<HeifPixelImage>> ImageItem::decode_compressed_image(const struct heif_decoding_options& options,
bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const
{
// --- find the decoder plugin with the correct compression format

heif_compression_format compression_format = get_compression_format();
if (compression_format == heif_compression_undefined) {
return Error{heif_error_Decoder_plugin_error, heif_suberror_Unsupported_codec, "Decoding not supported"};
}

Result<std::vector<uint8_t>> dataResult = get_compressed_image_data();
if (dataResult.error) {
return dataResult.error;
}

return decode_from_compressed_data(compression_format, options, *dataResult);
}
2 changes: 2 additions & 0 deletions libheif/codecs/image_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ class ImageItem : public ErrorBuffer
virtual Result<std::shared_ptr<HeifPixelImage>> decode_compressed_image(const struct heif_decoding_options& options,
bool decode_tile_only, uint32_t tile_x0, uint32_t tile_y0) const;

virtual Result<std::vector<uint8_t>> get_compressed_image_data() const;

Error check_for_valid_image_size(uint32_t width, uint32_t height) const;

// === encoding ===
Expand Down
23 changes: 16 additions & 7 deletions libheif/codecs/jpeg2000.cc
Original file line number Diff line number Diff line change
Expand Up @@ -312,12 +312,11 @@ std::string Box_j2kH::dump(Indent& indent) const
}


Error JPEG2000MainHeader::parseHeader(const HeifFile& file, const heif_item_id imageID)
Error JPEG2000MainHeader::parseHeader(const std::vector<uint8_t>& compressedImageData)
{
Error err = file.get_compressed_image_data(imageID, &headerData);
if (err) {
return err;
}
// TODO: it is very inefficient to store the whole image data when we only need the header

headerData = compressedImageData;
return doParse();
}

Expand Down Expand Up @@ -569,8 +568,13 @@ Result<std::vector<uint8_t>> ImageItem_JPEG2000::read_bitstream_configuration_da

int ImageItem_JPEG2000::get_luma_bits_per_pixel() const
{
Result<std::vector<uint8_t>> imageDataResult = get_compressed_image_data();
if (imageDataResult.error) {
return -1;
}

JPEG2000MainHeader header;
Error err = header.parseHeader(*get_file(), get_id());
Error err = header.parseHeader(*imageDataResult);
if (err) {
return -1;
}
Expand All @@ -580,8 +584,13 @@ int ImageItem_JPEG2000::get_luma_bits_per_pixel() const

int ImageItem_JPEG2000::get_chroma_bits_per_pixel() const
{
Result<std::vector<uint8_t>> imageDataResult = get_compressed_image_data();
if (imageDataResult.error) {
return -1;
}

JPEG2000MainHeader header;
Error err = header.parseHeader(*get_file(), get_id());
Error err = header.parseHeader(*imageDataResult);
if (err) {
return -1;
}
Expand Down
2 changes: 1 addition & 1 deletion libheif/codecs/jpeg2000.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ struct JPEG2000MainHeader
public:
JPEG2000MainHeader() = default;

Error parseHeader(const HeifFile& file, const heif_item_id imageID);
Error parseHeader(const std::vector<uint8_t>& compressedImageData);

// Use parseHeader instead - these are mainly for unit testing
Error doParse();
Expand Down
8 changes: 7 additions & 1 deletion libheif/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include <sstream>

#include "libheif/heif.h"

#include <cassert>

static constexpr char kSuccess[] = "Success";

Expand Down Expand Up @@ -115,6 +115,12 @@ template <typename T> class Result

operator bool() const { return error.error_code == heif_error_Ok; }

T& operator*()
{
assert(error.error_code == heif_error_Ok);
return value;
}

T value;
Error error;
};
Expand Down

0 comments on commit a680e3d

Please sign in to comment.