Skip to content

Commit

Permalink
add Decoder_uncompressed class
Browse files Browse the repository at this point in the history
  • Loading branch information
farindk committed Oct 3, 2024
1 parent 6295206 commit 73fb313
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 164 deletions.
4 changes: 3 additions & 1 deletion libheif/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ if (WITH_UNCOMPRESSED_CODEC)
codecs/uncompressed/unc_boxes.h
codecs/uncompressed/unc_boxes.cc
codecs/uncompressed/unc_image.h
codecs/uncompressed/unc_image.cc)
codecs/uncompressed/unc_image.cc
codecs/uncompressed/unc_dec.h
codecs/uncompressed/unc_dec.cc)
endif ()

write_basic_package_version_file(${PROJECT_NAME}-config-version.cmake COMPATIBILITY ExactVersion)
Expand Down
48 changes: 1 addition & 47 deletions libheif/codecs/image_item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ Error ImageItem::get_coded_image_colorspace(heif_colorspace* out_colorspace, hei
return err;
}

// TODO: should we use this or maybe use this just as an additional check that pixi and coded colorspace match?
auto pixi = m_heif_context->get_heif_file()->get_property<Box_pixi>(id);
if (pixi && pixi->get_num_channels() == 1) {
*out_colorspace = heif_colorspace_monochrome;
Expand All @@ -453,53 +454,6 @@ Error ImageItem::get_coded_image_colorspace(heif_colorspace* out_colorspace, hei
auto decoder = get_decoder();
assert(decoder);
return decoder->get_coded_image_colorspace(out_colorspace, out_chroma);

// TODO: this should be codec specific. JPEG 2000, for example, can use RGB internally.

*out_colorspace = heif_colorspace_YCbCr;
*out_chroma = heif_chroma_undefined;

if (auto hvcC = m_heif_context->get_heif_file()->get_property<Box_hvcC>(id)) {
*out_chroma = (heif_chroma) (hvcC->get_configuration().chroma_format);
}
else if (auto vvcC = m_heif_context->get_heif_file()->get_property<Box_vvcC>(id)) {
*out_chroma = (heif_chroma) (vvcC->get_configuration().chroma_format_idc);
}
else if (auto av1C = m_heif_context->get_heif_file()->get_property<Box_av1C>(id)) {
*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(*dataResult);
if (err) {
return err;
}
*out_chroma = jpeg2000Header.get_chroma_format();
}
#if WITH_UNCOMPRESSED_CODEC
else if (auto uncC = m_heif_context->get_heif_file()->get_property<Box_uncC>(id)) {
if (uncC->get_version() == 1) {
// This is the shortform case, no cmpd box, and always some kind of RGB
*out_colorspace = heif_colorspace_RGB;
if (uncC->get_profile() == fourcc("rgb3")) {
*out_chroma = heif_chroma_interleaved_RGB;
}
else if ((uncC->get_profile() == fourcc("rgba")) || (uncC->get_profile() == fourcc("abgr"))) {
*out_chroma = heif_chroma_interleaved_RGBA;
}
}
if (auto cmpd = m_heif_context->get_heif_file()->get_property<Box_cmpd>(id)) {
UncompressedImageCodec::get_heif_chroma_uncompressed(uncC, cmpd, out_chroma, out_colorspace);
}
}
#endif

return err;
}


Expand Down
148 changes: 148 additions & 0 deletions libheif/codecs/uncompressed/unc_dec.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* HEIF codec.
* Copyright (c) 2024 Dirk Farin <[email protected]>
*
* This file is part of libheif.
*
* libheif is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* libheif is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libheif. If not, see <http://www.gnu.org/licenses/>.
*/

#include "codecs/uncompressed/unc_dec.h"
#include "codecs/uncompressed/unc_image.h"
#include "error.h"
#include "context.h"

#include <string>


Result<std::vector<uint8_t>> Decoder_uncompressed::read_bitstream_configuration_data() const
{
return std::vector<uint8_t>{};
}


int Decoder_uncompressed::get_luma_bits_per_pixel() const
{
assert(m_uncC);

if (!m_cmpd) {
if (isKnownUncompressedFrameConfigurationBoxProfile(m_uncC)) {
return 8;
}
else {
return -1;
}
}

int luma_bits = 0;
int alternate_channel_bits = 0;
for (Box_uncC::Component component : m_uncC->get_components()) {
uint16_t component_index = component.component_index;
if (component_index >= m_cmpd->get_components().size()) {
return -1;
}
auto component_type = m_cmpd->get_components()[component_index].component_type;
switch (component_type) {
case component_type_monochrome:
case component_type_red:
case component_type_green:
case component_type_blue:
alternate_channel_bits = std::max(alternate_channel_bits, (int) component.component_bit_depth);
break;
case component_type_Y:
luma_bits = std::max(luma_bits, (int) component.component_bit_depth);
break;
// TODO: there are other things we'll need to handle eventually, like palette.
}
}
if (luma_bits > 0) {
return luma_bits;
}
else if (alternate_channel_bits > 0) {
return alternate_channel_bits;
}
else {
return 8;
}
}

int Decoder_uncompressed::get_chroma_bits_per_pixel() const
{
if (m_uncC && m_uncC->get_version() == 1) {
// All of the version 1 cases are 8 bit
return 8;
}

if (!m_uncC || !m_cmpd) {
return -1;
}

int chroma_bits = 0;
int alternate_channel_bits = 0;
for (Box_uncC::Component component : m_uncC->get_components()) {
uint16_t component_index = component.component_index;
if (component_index >= m_cmpd->get_components().size()) {
return -1;
}
auto component_type = m_cmpd->get_components()[component_index].component_type;
switch (component_type) {
case component_type_monochrome:
case component_type_red:
case component_type_green:
case component_type_blue:
alternate_channel_bits = std::max(alternate_channel_bits, (int) component.component_bit_depth);
break;
case component_type_Cb:
case component_type_Cr:
chroma_bits = std::max(chroma_bits, (int) component.component_bit_depth);
break;
// TODO: there are other things we'll need to handle eventually, like palette.
}
}
if (chroma_bits > 0) {
return chroma_bits;
}
else if (alternate_channel_bits > 0) {
return alternate_channel_bits;
}
else {
return 8;
}
}


Error Decoder_uncompressed::get_coded_image_colorspace(heif_colorspace* out_colorspace, heif_chroma* out_chroma) const
{
if (m_uncC->get_version() == 1) {
// This is the shortform case, no cmpd box, and always some kind of RGB
*out_colorspace = heif_colorspace_RGB;
if (m_uncC->get_profile() == fourcc("rgb3")) {
*out_chroma = heif_chroma_interleaved_RGB;
}
else if ((m_uncC->get_profile() == fourcc("rgba")) || (m_uncC->get_profile() == fourcc("abgr"))) {
*out_chroma = heif_chroma_interleaved_RGBA;
}

return Error::Ok;
}
else if (m_cmpd) {
UncompressedImageCodec::get_heif_chroma_uncompressed(m_uncC, m_cmpd, out_chroma, out_colorspace);
return Error::Ok;
}
else {
return {heif_error_Invalid_input,
heif_suberror_Unspecified,
"Missing 'cmpd' box."};
}
}
57 changes: 57 additions & 0 deletions libheif/codecs/uncompressed/unc_dec.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* HEIF codec.
* Copyright (c) 2024 Dirk Farin <[email protected]>
*
* This file is part of libheif.
*
* libheif is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* libheif is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libheif. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef HEIF_UNC_DEC_H
#define HEIF_UNC_DEC_H

#include "libheif/heif.h"
#include "box.h"
#include "error.h"

#include <memory>
#include <vector>
#include "codecs/decoder.h"

class Box_uncC;
class Box_cmpd;


class Decoder_uncompressed : public Decoder
{
public:
explicit Decoder_uncompressed(const std::shared_ptr<const Box_uncC>& uncC,
const std::shared_ptr<const Box_cmpd>& cmpd) : m_uncC(uncC), m_cmpd(cmpd) {}

heif_compression_format get_compression_format() const override { return heif_compression_uncompressed; }

int get_luma_bits_per_pixel() const override;

int get_chroma_bits_per_pixel() const override;

Error get_coded_image_colorspace(heif_colorspace*, heif_chroma*) const override;

Result<std::vector<uint8_t>> read_bitstream_configuration_data() const override;

private:
const std::shared_ptr<const Box_uncC> m_uncC;
const std::shared_ptr<const Box_cmpd> m_cmpd;
};

#endif
Loading

0 comments on commit 73fb313

Please sign in to comment.