Skip to content

Commit 657bd9d

Browse files
committed
evc: add decoder
1 parent 76af5e7 commit 657bd9d

File tree

6 files changed

+159
-8
lines changed

6 files changed

+159
-8
lines changed

libheif/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ set(libheif_sources
8989
codecs/avc_dec.cc
9090
codecs/evc_boxes.cc
9191
codecs/evc_boxes.h
92+
codecs/evc_dec.h
93+
codecs/evc_dec.cc
9294
image-items/mask_image.h
9395
image-items/mask_image.cc
9496
image-items/image_item.h

libheif/codecs/decoder.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
#include "jpeg_boxes.h"
4040
#include "jpeg2000_boxes.h"
4141
#include "codecs/uncompressed/unc_dec.h"
42-
42+
#include "codecs/evc_dec.h"
43+
#include "evc_boxes.h"
4344

4445
void DataExtent::set_from_image_item(std::shared_ptr<HeifFile> file, heif_item_id item)
4546
{
@@ -132,6 +133,10 @@ std::shared_ptr<Decoder> Decoder::alloc_for_infe_type(const HeifContext* ctx, he
132133
return std::make_shared<Decoder_uncompressed>(uncC,cmpd);
133134
}
134135
#endif
136+
case fourcc("evc1"): {
137+
auto evcC = ctx->get_heif_file()->get_property<Box_evcC>(id);
138+
return std::make_shared<Decoder_EVC>(evcC);
139+
}
135140
case fourcc("mski"): {
136141
return nullptr; // do we need a decoder for this?
137142
}

libheif/codecs/evc_boxes.cc

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,13 @@ std::string Box_evcC::get_chroma_format_as_text() const
123123
{
124124
switch (m_configuration.chroma_format_idc)
125125
{
126-
case 0:
126+
case CHROMA_FORMAT_MONOCHROME:
127127
return std::string("Monochrome");
128-
case 1:
128+
case CHROMA_FORMAT_420:
129129
return std::string("4:2:0");
130-
case 2:
130+
case CHROMA_FORMAT_422:
131131
return std::string("4:2:2");
132-
case 3:
132+
case CHROMA_FORMAT_444:
133133
return std::string("4:4:4");
134134
default:
135135
return std::string("Invalid");
@@ -169,3 +169,16 @@ Error Box_evcC::write(StreamWriter& writer) const
169169

170170
return Error::Ok;
171171
}
172+
173+
void Box_evcC::get_header_nals(std::vector<uint8_t>& data) const
174+
{
175+
for (const auto& array : m_nal_array) {
176+
for (const auto& nalu : array.nal_units) {
177+
data.push_back((nalu.size() >> 24) & 0xFF);
178+
data.push_back((nalu.size() >> 16) & 0xFF);
179+
data.push_back((nalu.size() >> 8) & 0xFF);
180+
data.push_back((nalu.size() >> 0) & 0xFF);
181+
data.insert(data.end(), nalu.begin(), nalu.end());
182+
}
183+
}
184+
}

libheif/codecs/evc_boxes.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,17 @@
2626
#include <string>
2727
#include <vector>
2828

29-
// #include "image-items/image_item.h"
30-
31-
3229
class Box_evcC : public Box {
3330
public:
3431
Box_evcC() { set_short_type(fourcc("evcC")); }
3532

3633
bool is_essential() const override { return true; }
3734

35+
static const uint8_t CHROMA_FORMAT_MONOCHROME = 0;
36+
static const uint8_t CHROMA_FORMAT_420 = 1;
37+
static const uint8_t CHROMA_FORMAT_422 = 2;
38+
static const uint8_t CHROMA_FORMAT_444 = 3;
39+
3840
struct configuration {
3941
uint8_t configurationVersion = 1;
4042
uint8_t profile_idc;
@@ -63,6 +65,8 @@ class Box_evcC : public Box {
6365

6466
Error write(StreamWriter &writer) const override;
6567

68+
void get_header_nals(std::vector<uint8_t>& data) const;
69+
6670
protected:
6771
Error parse(BitstreamRange &range, const heif_security_limits* limits) override;
6872

libheif/codecs/evc_dec.cc

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* HEIF codec.
3+
* Copyright (c) 2024 Dirk Farin <[email protected]>
4+
*
5+
* This file is part of libheif.
6+
*
7+
* libheif is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Lesser General Public License as
9+
* published by the Free Software Foundation, either version 3 of
10+
* the License, or (at your option) any later version.
11+
*
12+
* libheif is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public License
18+
* along with libheif. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
#include "evc_dec.h"
22+
#include "evc_boxes.h"
23+
#include "error.h"
24+
#include "context.h"
25+
26+
#include <string>
27+
28+
29+
Result<std::vector<uint8_t>> Decoder_EVC::read_bitstream_configuration_data() const
30+
{
31+
std::vector<uint8_t> data;
32+
m_evcC->get_header_nals(data);
33+
return data;
34+
}
35+
36+
37+
int Decoder_EVC::get_luma_bits_per_pixel() const
38+
{
39+
return m_evcC->get_configuration().bit_depth_luma;
40+
}
41+
42+
43+
int Decoder_EVC::get_chroma_bits_per_pixel() const
44+
{
45+
return m_evcC->get_configuration().bit_depth_chroma;
46+
}
47+
48+
49+
Error Decoder_EVC::get_coded_image_colorspace(heif_colorspace* out_colorspace, heif_chroma* out_chroma) const
50+
{
51+
switch (m_evcC->get_configuration().chroma_format_idc) {
52+
case Box_evcC::CHROMA_FORMAT_MONOCHROME:
53+
*out_chroma = heif_chroma_monochrome;
54+
*out_colorspace = heif_colorspace_monochrome;
55+
return Error::Ok;
56+
case Box_evcC::CHROMA_FORMAT_420:
57+
*out_chroma = heif_chroma_420;
58+
*out_colorspace = heif_colorspace_YCbCr;
59+
return Error::Ok;
60+
case Box_evcC::CHROMA_FORMAT_422:
61+
*out_chroma = heif_chroma_422;
62+
*out_colorspace = heif_colorspace_YCbCr;
63+
return Error::Ok;
64+
case Box_evcC::CHROMA_FORMAT_444:
65+
*out_chroma = heif_chroma_444;
66+
*out_colorspace = heif_colorspace_YCbCr;
67+
return Error::Ok;
68+
default:
69+
*out_chroma = heif_chroma_undefined;
70+
*out_colorspace = heif_colorspace_undefined;
71+
return Error{heif_error_Invalid_input, heif_suberror_Decompression_invalid_data, "unsupported (impossible?) EVC chroma value"};
72+
}
73+
}
74+

libheif/codecs/evc_dec.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* HEIF codec.
3+
* Copyright (c) 2024 Dirk Farin <[email protected]>
4+
*
5+
* This file is part of libheif.
6+
*
7+
* libheif is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Lesser General Public License as
9+
* published by the Free Software Foundation, either version 3 of
10+
* the License, or (at your option) any later version.
11+
*
12+
* libheif is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public License
18+
* along with libheif. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
#ifndef HEIF_EVC_DEC_H
22+
#define HEIF_EVC_DEC_H
23+
24+
#include "libheif/heif.h"
25+
#include "error.h"
26+
27+
#include <memory>
28+
#include <vector>
29+
#include <codecs/decoder.h>
30+
31+
class Box_evcC;
32+
33+
34+
class Decoder_EVC : public Decoder
35+
{
36+
public:
37+
explicit Decoder_EVC(const std::shared_ptr<const Box_evcC>& evcC) : m_evcC(evcC) {}
38+
39+
heif_compression_format get_compression_format() const override { return heif_compression_EVC; }
40+
41+
int get_luma_bits_per_pixel() const override;
42+
43+
int get_chroma_bits_per_pixel() const override;
44+
45+
Error get_coded_image_colorspace(heif_colorspace*, heif_chroma*) const override;
46+
47+
Result<std::vector<uint8_t>> read_bitstream_configuration_data() const override;
48+
49+
private:
50+
const std::shared_ptr<const Box_evcC> m_evcC;
51+
};
52+
53+
#endif

0 commit comments

Comments
 (0)