Coverage Report

Created: 2025-09-08 07:52

/src/libheif/libheif/error.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * HEIF codec.
3
 * Copyright (c) 2017 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_ERROR_H
22
#define LIBHEIF_ERROR_H
23
24
#include <cinttypes>
25
#include <cstddef>
26
27
#include <vector>
28
#include <string>
29
#include <memory>
30
#include <limits>
31
#include <istream>
32
#include <ostream>
33
#include <sstream>
34
35
#include "libheif/heif.h"
36
#include <cassert>
37
#include <variant>
38
39
40
class ErrorBuffer
41
{
42
public:
43
48.5k
  ErrorBuffer() = default;
44
45
  void set_success()
46
35.8k
  {
47
35.8k
    m_error_message = c_success;
48
35.8k
  }
49
50
  void set_error(const std::string& err)
51
16.2k
  {
52
16.2k
    m_buffer = err;
53
16.2k
    m_error_message = m_buffer.c_str();
54
16.2k
  }
55
56
  const char* get_error() const
57
52.1k
  {
58
52.1k
    return m_error_message;
59
52.1k
  }
60
61
private:
62
  constexpr static const char* c_success = "Success";
63
  std::string m_buffer;
64
  const char* m_error_message = c_success;
65
};
66
67
68
class Error
69
{
70
public:
71
  enum heif_error_code error_code = heif_error_Ok;
72
  enum heif_suberror_code sub_error_code = heif_suberror_Unspecified;
73
  std::string message;
74
75
  Error();
76
77
  Error(heif_error_code c,
78
        heif_suberror_code sc = heif_suberror_Unspecified,
79
        const std::string& msg = "");
80
81
  static Error from_heif_error(const heif_error&);
82
83
  static const Error Ok;
84
85
  static const Error InternalError;
86
87
  static const char kSuccess[];
88
89
454k
  bool operator==(const Error& other) const { return error_code == other.error_code; }
90
91
211k
  bool operator!=(const Error& other) const { return !(*this == other); }
92
93
4.73k
  Error operator||(const Error& other) const {
94
4.73k
    if (error_code != heif_error_Ok) {
95
0
      return *this;
96
0
    }
97
4.73k
    else {
98
4.73k
      return other;
99
4.73k
    }
100
4.73k
  }
101
102
638k
  operator bool() const { return error_code != heif_error_Ok; }
103
104
  static const char* get_error_string(heif_error_code err);
105
106
  static const char* get_error_string(heif_suberror_code err);
107
108
  heif_error error_struct(ErrorBuffer* error_buffer) const;
109
};
110
111
112
inline std::ostream& operator<<(std::ostream& ostr, const Error& err)
113
0
{
114
0
  ostr << err.error_code << "/" << err.sub_error_code;
115
0
  return ostr;
116
0
}
117
118
119
template <typename T> class Result
120
{
121
public:
122
0
  Result() = default;
Unexecuted instantiation: Result<std::__1::shared_ptr<HeifPixelImage> >::Result()
Unexecuted instantiation: Result<Encoder::CodedImageData>::Result()
123
124
112k
  Result(const T& v) : m_data(v) {}
Result<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::Result(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Line
Count
Source
124
32.4k
  Result(const T& v) : m_data(v) {}
Result<std::__1::shared_ptr<HeifPixelImage> >::Result(std::__1::shared_ptr<HeifPixelImage> const&)
Line
Count
Source
124
17.6k
  Result(const T& v) : m_data(v) {}
Result<std::__1::vector<std::__1::shared_ptr<Box>, std::__1::allocator<std::__1::shared_ptr<Box> > > >::Result(std::__1::vector<std::__1::shared_ptr<Box>, std::__1::allocator<std::__1::shared_ptr<Box> > > const&)
Line
Count
Source
124
2.94k
  Result(const T& v) : m_data(v) {}
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem_Grid> >::Result(std::__1::shared_ptr<ImageItem_Grid> const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem_Overlay> >::Result(std::__1::shared_ptr<ImageItem_Overlay> const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem_Tiled> >::Result(std::__1::shared_ptr<ImageItem_Tiled> const&)
Unexecuted instantiation: Result<DataExtent>::Result(DataExtent const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<HeifPixelImage const> >::Result(std::__1::shared_ptr<HeifPixelImage const> const&)
Unexecuted instantiation: Result<heif_tai_timestamp_packet>::Result(heif_tai_timestamp_packet const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem> >::Result(std::__1::shared_ptr<ImageItem> const&)
Unexecuted instantiation: Result<unsigned int>::Result(unsigned int const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<Track> >::Result(std::__1::shared_ptr<Track> const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<Track const> >::Result(std::__1::shared_ptr<Track const> const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<Track_Visual> >::Result(std::__1::shared_ptr<Track_Visual> const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<Track_Metadata> >::Result(std::__1::shared_ptr<Track_Metadata> const&)
Unexecuted instantiation: Result<unsigned long>::Result(unsigned long const&)
Unexecuted instantiation: Result<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::Result(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Result<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*>::Result(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >* const&)
Line
Count
Source
124
14.7k
  Result(const T& v) : m_data(v) {}
Result<std::__1::shared_ptr<Decoder> >::Result(std::__1::shared_ptr<Decoder> const&)
Line
Count
Source
124
44.4k
  Result(const T& v) : m_data(v) {}
Unexecuted instantiation: Result<std::__1::shared_ptr<SEIMessage> >::Result(std::__1::shared_ptr<SEIMessage> const&)
Unexecuted instantiation: Result<Encoder::CodedImageData>::Result(Encoder::CodedImageData const&)
Unexecuted instantiation: Result<heif_raw_sequence_sample*>::Result(heif_raw_sequence_sample* const&)
125
126
38.9k
  Result(const Error& e) : m_data(e) {}
Unexecuted instantiation: Result<std::__1::shared_ptr<Decoder> >::Result(Error const&)
Result<std::__1::shared_ptr<HeifPixelImage> >::Result(Error const&)
Line
Count
Source
126
36.4k
  Result(const Error& e) : m_data(e) {}
Unexecuted instantiation: Result<std::__1::vector<std::__1::shared_ptr<Box>, std::__1::allocator<std::__1::shared_ptr<Box> > > >::Result(Error const&)
Unexecuted instantiation: Result<Encoder::CodedImageData>::Result(Error const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem_Grid> >::Result(Error const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem_Overlay> >::Result(Error const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem_Tiled> >::Result(Error const&)
Unexecuted instantiation: Result<DataExtent>::Result(Error const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<HeifPixelImage const> >::Result(Error const&)
Unexecuted instantiation: Result<heif_tai_timestamp_packet>::Result(Error const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem> >::Result(Error const&)
Unexecuted instantiation: Result<unsigned int>::Result(Error const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<Track> >::Result(Error const&)
Unexecuted instantiation: Result<std::__1::shared_ptr<Track const> >::Result(Error const&)
Result<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::Result(Error const&)
Line
Count
Source
126
2.27k
  Result(const Error& e) : m_data(e) {}
Unexecuted instantiation: Result<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::Result(Error const&)
Result<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*>::Result(Error const&)
Line
Count
Source
126
255
  Result(const Error& e) : m_data(e) {}
Unexecuted instantiation: Result<std::__1::shared_ptr<SEIMessage> >::Result(Error const&)
Unexecuted instantiation: Result<heif_raw_sequence_sample*>::Result(Error const&)
127
128
329k
  operator bool() const { return std::holds_alternative<T>(m_data); }
Result<std::__1::shared_ptr<HeifPixelImage> >::operator bool() const
Line
Count
Source
128
108k
  operator bool() const { return std::holds_alternative<T>(m_data); }
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem> >::operator bool() const
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem_Overlay> >::operator bool() const
Unexecuted instantiation: Result<Encoder::CodedImageData>::operator bool() const
Result<std::__1::shared_ptr<Decoder> >::operator bool() const
Line
Count
Source
128
88.9k
  operator bool() const { return std::holds_alternative<T>(m_data); }
Result<std::__1::vector<std::__1::shared_ptr<Box>, std::__1::allocator<std::__1::shared_ptr<Box> > > >::operator bool() const
Line
Count
Source
128
5.88k
  operator bool() const { return std::holds_alternative<T>(m_data); }
Result<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::operator bool() const
Line
Count
Source
128
82.2k
  operator bool() const { return std::holds_alternative<T>(m_data); }
Unexecuted instantiation: Result<DataExtent>::operator bool() const
Unexecuted instantiation: Result<std::__1::shared_ptr<HeifPixelImage const> >::operator bool() const
Unexecuted instantiation: Result<std::__1::shared_ptr<Track> >::operator bool() const
Unexecuted instantiation: Result<unsigned long>::operator bool() const
Unexecuted instantiation: Result<std::__1::shared_ptr<Track const> >::operator bool() const
Result<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*>::operator bool() const
Line
Count
Source
128
44.8k
  operator bool() const { return std::holds_alternative<T>(m_data); }
Unexecuted instantiation: Result<std::__1::shared_ptr<SEIMessage> >::operator bool() const
Unexecuted instantiation: Result<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::operator bool() const
Unexecuted instantiation: Result<heif_tai_timestamp_packet>::operator bool() const
129
130
  //void set(const T& v) { m_data = v; }
131
132
  // Pointer-like access for `r->member`
133
  T* operator->()
134
29.4k
  {
135
29.4k
    assert(*this); // Uses the operator bool() above
136
29.4k
    return &std::get<T>(m_data);
137
29.4k
  }
Unexecuted instantiation: Result<Encoder::CodedImageData>::operator->()
Unexecuted instantiation: Result<std::__1::vector<std::__1::shared_ptr<Box>, std::__1::allocator<std::__1::shared_ptr<Box> > > >::operator->()
Result<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::operator->()
Line
Count
Source
134
29.4k
  {
135
29.4k
    assert(*this); // Uses the operator bool() above
136
29.4k
    return &std::get<T>(m_data);
137
29.4k
  }
138
139
  // Dereference access for `*r`
140
  T& operator*()
141
112k
  {
142
112k
    assert(*this);
143
112k
    return std::get<T>(m_data);
144
112k
  }
Result<std::__1::shared_ptr<HeifPixelImage> >::operator*()
Line
Count
Source
141
17.6k
  {
142
17.6k
    assert(*this);
143
17.6k
    return std::get<T>(m_data);
144
17.6k
  }
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem> >::operator*()
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem_Overlay> >::operator*()
Unexecuted instantiation: Result<Encoder::CodedImageData>::operator*()
Result<std::__1::shared_ptr<Decoder> >::operator*()
Line
Count
Source
141
44.4k
  {
142
44.4k
    assert(*this);
143
44.4k
    return std::get<T>(m_data);
144
44.4k
  }
Result<std::__1::vector<std::__1::shared_ptr<Box>, std::__1::allocator<std::__1::shared_ptr<Box> > > >::operator*()
Line
Count
Source
141
2.94k
  {
142
2.94k
    assert(*this);
143
2.94k
    return std::get<T>(m_data);
144
2.94k
  }
Result<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::operator*()
Line
Count
Source
141
17.7k
  {
142
17.7k
    assert(*this);
143
17.7k
    return std::get<T>(m_data);
144
17.7k
  }
Unexecuted instantiation: Result<DataExtent>::operator*()
Unexecuted instantiation: Result<std::__1::shared_ptr<HeifPixelImage const> >::operator*()
Unexecuted instantiation: Result<std::__1::shared_ptr<Track> >::operator*()
Unexecuted instantiation: Result<unsigned long>::operator*()
Unexecuted instantiation: Result<std::__1::shared_ptr<Track const> >::operator*()
Result<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*>::operator*()
Line
Count
Source
141
29.5k
  {
142
29.5k
    assert(*this);
143
29.5k
    return std::get<T>(m_data);
144
29.5k
  }
Unexecuted instantiation: Result<std::__1::shared_ptr<SEIMessage> >::operator*()
Unexecuted instantiation: Result<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::operator*()
Unexecuted instantiation: Result<heif_tai_timestamp_packet>::operator*()
145
146
  [[nodiscard]] bool is_error() const {
147
    return std::holds_alternative<Error>(m_data);
148
  }
149
150
  // Accessor for the error, if it exists
151
  [[nodiscard]] const Error& error() const
152
24.8k
  {
153
24.8k
    if (*this) {
154
0
      return Error::Ok;
155
0
    }
156
157
24.8k
    return std::get<Error>(m_data);
158
24.8k
  }
Unexecuted instantiation: Result<Encoder::CodedImageData>::error() const
Unexecuted instantiation: Result<std::__1::shared_ptr<Decoder> >::error() const
Unexecuted instantiation: Result<std::__1::vector<std::__1::shared_ptr<Box>, std::__1::allocator<std::__1::shared_ptr<Box> > > >::error() const
Result<std::__1::shared_ptr<HeifPixelImage> >::error() const
Line
Count
Source
152
24.2k
  {
153
24.2k
    if (*this) {
154
0
      return Error::Ok;
155
0
    }
156
157
24.2k
    return std::get<Error>(m_data);
158
24.2k
  }
Result<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >::error() const
Line
Count
Source
152
356
  {
153
356
    if (*this) {
154
0
      return Error::Ok;
155
0
    }
156
157
356
    return std::get<Error>(m_data);
158
356
  }
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem> >::error() const
Unexecuted instantiation: Result<DataExtent>::error() const
Unexecuted instantiation: Result<std::__1::shared_ptr<HeifPixelImage const> >::error() const
Unexecuted instantiation: Result<std::__1::shared_ptr<Track> >::error() const
Result<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >*>::error() const
Line
Count
Source
152
255
  {
153
255
    if (*this) {
154
0
      return Error::Ok;
155
0
    }
156
157
255
    return std::get<Error>(m_data);
158
255
  }
Unexecuted instantiation: Result<std::__1::shared_ptr<SEIMessage> >::error() const
Unexecuted instantiation: Result<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::error() const
Unexecuted instantiation: Result<heif_tai_timestamp_packet>::error() const
159
160
  // Directly get the C error struct.
161
  heif_error error_struct(ErrorBuffer* error_buffer) const
162
12.1k
  {
163
12.1k
    if (*this) {
164
0
      return heif_error_success;
165
0
    }
166
167
12.1k
    return std::get<Error>(m_data).error_struct(error_buffer);
168
12.1k
  }
Result<std::__1::shared_ptr<HeifPixelImage> >::error_struct(ErrorBuffer*) const
Line
Count
Source
162
12.1k
  {
163
12.1k
    if (*this) {
164
0
      return heif_error_success;
165
0
    }
166
167
12.1k
    return std::get<Error>(m_data).error_struct(error_buffer);
168
12.1k
  }
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem> >::error_struct(ErrorBuffer*) const
Unexecuted instantiation: Result<std::__1::shared_ptr<ImageItem_Overlay> >::error_struct(ErrorBuffer*) const
169
170
  std::variant<T, Error> m_data;
171
};
172
173
#endif