Coverage Report

Created: 2026-10-28 07:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libheif/libheif/codecs/uncompressed/unc_decoder.h
Line
Count
Source
1
/*
2
 * HEIF codec.
3
 * Copyright (c) 2023 Dirk Farin <dirk.farin@gmail.com>
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 LIBHEIF_UNC_DECODER_H
22
#define LIBHEIF_UNC_DECODER_H
23
24
#include <cstdint>
25
#include <memory>
26
#include <vector>
27
28
#include "error.h"
29
#include "unc_codec.h"
30
#include "unc_boxes.h"
31
32
class HeifPixelImage;
33
class MemoryHandle;
34
struct DataExtent;
35
struct heif_security_limits;
36
37
38
// Validate the uncC component formats, bit depths and pixel packing. These are
39
// image-size independent invariants, so this must run on every decode entry
40
// point -- both the full-image path (unc_decoder::decode_full_image) and the
41
// per-tile path (UncompressedImageCodec::decode_uncompressed_image_tile).
42
Error check_hard_limits(const std::shared_ptr<const Box_uncC>& uncC);
43
44
45
class unc_decoder
46
{
47
public:
48
1.18k
  virtual ~unc_decoder() = default;
49
50
863
  virtual void ensure_channel_list(std::shared_ptr<HeifPixelImage>& img) {}
51
52
  // The size of 'tile_data' is charged to 'tile_data_memory_handle', which has to
53
  // live as long as 'tile_data'.
54
  Error fetch_tile_data(const DataExtent& dataExtent,
55
                        const UncompressedImageCodec::unci_properties& properties,
56
                        uint32_t tile_x, uint32_t tile_y,
57
                        std::vector<uint8_t>& tile_data,
58
                        MemoryHandle& tile_data_memory_handle);
59
60
  virtual Error decode_tile(const std::vector<uint8_t>& tile_data,
61
                            std::shared_ptr<HeifPixelImage>& img,
62
                            uint32_t out_x0, uint32_t out_y0) = 0;
63
64
  Error decode_image(const DataExtent& extent,
65
                     const UncompressedImageCodec::unci_properties& properties,
66
                     std::shared_ptr<HeifPixelImage>& img);
67
68
  static Result<std::shared_ptr<HeifPixelImage>> decode_full_image(
69
      const UncompressedImageCodec::unci_properties& properties,
70
      const DataExtent& extent,
71
      const heif_security_limits* limits);
72
73
protected:
74
  unc_decoder(uint32_t width, uint32_t height,
75
              const std::shared_ptr<const Box_cmpd>& cmpd,
76
              const std::shared_ptr<const Box_uncC>& uncC,
77
              const std::vector<uint32_t>& uncC_index_to_comp_ids);
78
79
  virtual Result<std::vector<uint64_t>> get_tile_data_sizes() const = 0;
80
81
  const Error get_compressed_image_data_uncompressed(const DataExtent& dataExtent,
82
                                                     const UncompressedImageCodec::unci_properties& properties,
83
                                                     std::vector<uint8_t>* data,
84
                                                     uint64_t range_start_offset, uint64_t range_size,
85
                                                     uint32_t tile_idx,
86
                                                     const Box_iloc::Item* item) const;
87
88
  // Decompress the complete item. This is used when the compressed units do not give
89
  // access to the individual tiles (UncompressedImageCodec::TileAccess::whole_item).
90
  // The item has to decompress to exactly 'expected_size' bytes.
91
  Result<std::vector<uint8_t>> decompress_whole_item(const DataExtent& dataExtent,
92
                                                     const UncompressedImageCodec::unci_properties& properties,
93
                                                     uint64_t expected_size) const;
94
95
  Result<std::vector<uint8_t>> do_decompress_data(std::shared_ptr<const Box_cmpC>& cmpC_box,
96
                                                  const std::vector<uint8_t>& compressed_data,
97
                                                  const heif_security_limits* limits,
98
                                                  uint64_t max_output_size = UINT64_MAX) const;
99
100
  const uint32_t m_width;
101
  const uint32_t m_height;
102
  const std::shared_ptr<const Box_cmpd> m_cmpd;
103
  const std::shared_ptr<const Box_uncC> m_uncC;
104
  const std::vector<uint32_t> m_uncC_index_to_comp_ids;
105
  uint32_t m_tile_height;
106
  uint32_t m_tile_width;
107
};
108
109
110
class unc_decoder_factory
111
{
112
public:
113
0
  virtual ~unc_decoder_factory() = default;
114
115
  static Result<std::unique_ptr<unc_decoder>> get_unc_decoder(
116
      uint32_t width, uint32_t height,
117
      const std::shared_ptr<const Box_cmpd>& cmpd,
118
      const std::shared_ptr<const Box_uncC>& uncC,
119
      const std::vector<uint32_t>& uncC_index_to_comp_ids);
120
121
protected:
122
  static bool check_common_requirements(const std::shared_ptr<const Box_uncC>& uncC);
123
124
  static bool has_any_multi_byte_components(const std::shared_ptr<const Box_uncC>& uncC);
125
126
  virtual bool can_decode(const std::shared_ptr<const Box_uncC>& uncC) const = 0;
127
128
  virtual std::unique_ptr<unc_decoder> create(
129
      uint32_t width, uint32_t height,
130
      const std::shared_ptr<const Box_cmpd>& cmpd,
131
      const std::shared_ptr<const Box_uncC>& uncC,
132
      const std::vector<uint32_t>& uncC_index_to_comp_ids) const = 0;
133
};
134
135
#endif