Coverage Report

Created: 2026-07-16 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libheif/libheif/codecs/decoder.h
Line
Count
Source
1
/*
2
 * HEIF codec.
3
 * Copyright (c) 2024 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 HEIF_DECODER_H
22
#define HEIF_DECODER_H
23
24
#include "libheif/heif.h"
25
#include "box.h"
26
#include "error.h"
27
#include "file.h"
28
#include "security_limits.h"
29
30
#include <memory>
31
#include <optional>
32
#include <string>
33
#include <utility>
34
#include <vector>
35
#include "image-items/hevc.h"
36
37
38
// Image dimensions in luma samples. Reused wherever libheif needs to pass
39
// a (width, height) pair around — initially for SPS-derived coded sizes,
40
// but designed to fit other uses (ispe, image-item dimensions) over time.
41
struct ImageSize
42
{
43
  uint32_t width;
44
  uint32_t height;
45
};
46
47
48
// Specifies the input data for decoding.
49
// For images, this points to the iloc extents.
50
// For sequences, this points to the track data.
51
struct DataExtent
52
{
53
  std::shared_ptr<HeifFile> m_file;
54
  enum class Source : uint8_t { Raw, Image, FileRange } m_source = Source::Raw;
55
56
  // --- raw data
57
  mutable std::vector<uint8_t> m_raw; // also for cached data
58
59
  // Holds m_raw's allocation against the file's max_total_memory budget.
60
  // Released when DataExtent is destroyed (or moved-from).
61
  mutable MemoryHandle m_raw_memory_handle;
62
63
  // --- image
64
  heif_item_id m_item_id = 0;
65
66
  // --- file range
67
  uint64_t m_offset = 0;
68
  uint32_t m_size = 0;
69
70
  void set_from_image_item(std::shared_ptr<HeifFile> file, heif_item_id item);
71
72
  void set_file_range(std::shared_ptr<HeifFile> file, uint64_t offset, uint32_t size);
73
74
  Result<std::vector<uint8_t>*> read_data() const;
75
76
  Result<std::vector<uint8_t>> read_data(uint64_t offset, uint64_t size) const;
77
};
78
79
80
class Decoder
81
{
82
public:
83
  static std::shared_ptr<Decoder> alloc_for_infe_type(const ImageItem* item);
84
85
  static std::shared_ptr<Decoder> alloc_for_sequence_sample_description_box(std::shared_ptr<const class Box_VisualSampleEntry> sample_description_box);
86
87
88
  virtual ~Decoder();
89
90
  virtual heif_compression_format get_compression_format() const = 0;
91
92
0
  void set_data_extent(DataExtent extent) { m_data_extent = std::move(extent); }
93
94
0
  const DataExtent& get_data_extent() const { return m_data_extent; }
95
96
  // --- information about the image format
97
98
  [[nodiscard]] virtual int get_luma_bits_per_pixel() const = 0;
99
100
  [[nodiscard]] virtual int get_chroma_bits_per_pixel() const = 0;
101
102
  [[nodiscard]] virtual Error get_coded_image_colorspace(heif_colorspace*, heif_chroma*) const = 0;
103
104
  // --- raw data access
105
106
  // Returns a stream of packets. Each packet is starts with a 4-byte size (MSB first).
107
  [[nodiscard]] virtual Result<std::vector<uint8_t>> read_bitstream_configuration_data() const = 0;
108
109
  // Returns the *coded* picture size from the codec configuration record (the
110
  // SPS for HEVC/AVC/VVC) — i.e. the buffer dimensions the decoder will
111
  // actually allocate, BEFORE conformance-window cropping. The cropped output
112
  // size is unsuitable for security checks: a malicious file can declare a
113
  // huge SPS picture size with a near-equal-sized conformance window, so the
114
  // displayed image looks small while the decoder still allocates the full
115
  // uncropped buffer.
116
  //
117
  // Returns nullopt when the codec does not store dimensions in its
118
  // configuration record (e.g. AV1's av1C) or when no SPS NAL is present.
119
  // Returns Error only on a structurally invalid configuration record.
120
  [[nodiscard]] virtual Result<std::optional<ImageSize>>
121
  get_coded_image_size_from_config() const
122
0
  {
123
0
    return std::optional<ImageSize>{};
124
0
  }
125
126
  Result<std::vector<uint8_t>> get_compressed_data(bool with_configuration_NALs) const;
127
128
  // --- decoding
129
130
  // Decode a stream image that contains exactly one image. Decoder input is flushed and
131
  // it always should return an image.
132
  virtual Result<std::shared_ptr<HeifPixelImage>>
133
  decode_single_frame_from_compressed_data(const heif_decoding_options& options,
134
                                           const heif_security_limits* limits);
135
136
  // Push data for one frame into decoder.
137
  virtual Error
138
  decode_sequence_frame_from_compressed_data(bool upload_configuration_NALs,
139
                                             const heif_decoding_options& options,
140
                                             uintptr_t user_data,
141
                                             const heif_security_limits* limits);
142
143
  virtual Error flush_decoder();
144
145
  // Get a decoded frame from the decoder.
146
  // It may return NULL when there is buffering in the codec.
147
  virtual Result<std::shared_ptr<HeifPixelImage> > get_decoded_frame(const heif_decoding_options& options,
148
                                                                     uintptr_t* out_user_data,
149
                                                                     const heif_security_limits* limits);
150
151
  // Release the codec plugin decoder context (frees worker threads).
152
  // Safe to call multiple times. The decoder will be re-created on next use.
153
  void release_decoder();
154
155
private:
156
  DataExtent m_data_extent;
157
158
  const heif_decoder_plugin* m_decoder_plugin = nullptr;
159
  void* m_decoder = nullptr;
160
161
  // get the decoder plugin if it is not set already
162
  Error require_decoder_plugin(const heif_decoding_options& options);
163
};
164
165
#endif