Coverage Report

Created: 2025-06-16 07:00

/src/libheif/libheif/error.cc
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
#include "error.h"
22
23
#include <cassert>
24
#include <cstring>
25
26
// static
27
const char Error::kSuccess[] = "Success";
28
const char* cUnknownError = "Unknown error";
29
30
31
const Error Error::Ok(heif_error_Ok);
32
33
const Error Error::InternalError{heif_error_Unsupported_feature, // TODO: use better value
34
                                 heif_suberror_Unspecified,
35
                                 "Internal error"};
36
37
38
48.6k
Error::Error() = default;
39
40
41
Error::Error(heif_error_code c,
42
                   heif_suberror_code sc,
43
                   const std::string& msg)
44
12.2k
    : error_code(c),
45
12.2k
      sub_error_code(sc),
46
12.2k
      message(msg)
47
12.2k
{
48
12.2k
}
49
50
51
Error Error::from_heif_error(const heif_error& c_error)
52
829
{
53
  // unpack the concatenated error message and extract the last part only
54
55
829
  const char* err_string = get_error_string(c_error.code);
56
829
  const char* sub_err_string = get_error_string(c_error.subcode);
57
58
829
  std::string msg = c_error.message;
59
829
  if (msg.starts_with(err_string)) {
60
0
    msg = msg.substr(strlen(err_string));
61
62
0
    if (msg.starts_with(": ")) {
63
0
      msg = msg.substr(2);
64
0
    }
65
66
0
    if (msg.starts_with(sub_err_string)) {
67
0
      msg = msg.substr(strlen(sub_err_string));
68
69
0
      if (msg.starts_with(": ")) {
70
0
        msg = msg.substr(2);
71
0
      }
72
0
    }
73
0
  }
74
75
829
  return {c_error.code, c_error.subcode, msg};
76
829
}
77
78
79
const char* Error::get_error_string(heif_error_code err)
80
9.23k
{
81
9.23k
  switch (err) {
82
0
    case heif_error_Ok:
83
0
      return "Success";
84
0
    case heif_error_Input_does_not_exist:
85
0
      return "Input file does not exist";
86
4.56k
    case heif_error_Invalid_input:
87
4.56k
      return "Invalid input";
88
733
    case heif_error_Unsupported_filetype:
89
733
      return "Unsupported file-type";
90
1.78k
    case heif_error_Unsupported_feature:
91
1.78k
      return "Unsupported feature";
92
0
    case heif_error_Usage_error:
93
0
      return "Usage error";
94
298
    case heif_error_Memory_allocation_error:
95
298
      return "Memory allocation error";
96
1.68k
    case heif_error_Decoder_plugin_error:
97
1.68k
      return "Decoder plugin generated an error";
98
0
    case heif_error_Encoder_plugin_error:
99
0
      return "Encoder plugin generated an error";
100
0
    case heif_error_Encoding_error:
101
0
      return "Error during encoding or writing output file";
102
0
    case heif_error_Color_profile_does_not_exist:
103
0
      return "Color profile does not exist";
104
178
    case heif_error_Plugin_loading_error:
105
178
      return "Error while loading plugin";
106
0
    case heif_error_Canceled:
107
0
      return "Canceled by user";
108
0
    case heif_error_End_of_sequence:
109
0
      return "End of sequence";
110
9.23k
  }
111
112
0
  assert(false);
113
0
  return "Unknown error";
114
9.23k
}
115
116
const char* Error::get_error_string(heif_suberror_code err)
117
9.23k
{
118
9.23k
  switch (err) {
119
2.84k
    case heif_suberror_Unspecified:
120
2.84k
      return "Unspecified";
121
122
      // --- Invalid_input ---
123
124
2.52k
    case heif_suberror_End_of_data:
125
2.52k
      return "Unexpected end of file";
126
121
    case heif_suberror_Invalid_box_size:
127
121
      return "Invalid box size";
128
12
    case heif_suberror_Invalid_grid_data:
129
12
      return "Invalid grid data";
130
85
    case heif_suberror_Missing_grid_images:
131
85
      return "Missing grid images";
132
138
    case heif_suberror_No_ftyp_box:
133
138
      return "No 'ftyp' box";
134
1
    case heif_suberror_No_idat_box:
135
1
      return "No 'idat' box";
136
82
    case heif_suberror_No_meta_box:
137
82
      return "No 'meta' box";
138
0
    case heif_suberror_No_hdlr_box:
139
0
      return "No 'hdlr' box";
140
13
    case heif_suberror_No_hvcC_box:
141
13
      return "No 'hvcC' box";
142
0
    case heif_suberror_No_vvcC_box:
143
0
      return "No 'vvcC' box";
144
32
    case heif_suberror_No_av1C_box:
145
32
      return "No 'av1C' box";
146
0
    case heif_suberror_No_avcC_box:
147
0
      return "No 'avcC' box";
148
104
    case heif_suberror_No_pitm_box:
149
104
      return "No 'pitm' box";
150
12
    case heif_suberror_No_ipco_box:
151
12
      return "No 'ipco' box";
152
17
    case heif_suberror_No_ipma_box:
153
17
      return "No 'ipma' box";
154
7
    case heif_suberror_No_iloc_box:
155
7
      return "No 'iloc' box";
156
12
    case heif_suberror_No_iinf_box:
157
12
      return "No 'iinf' box";
158
49
    case heif_suberror_No_iprp_box:
159
49
      return "No 'iprp' box";
160
47
    case heif_suberror_No_iref_box:
161
47
      return "No 'iref' box";
162
0
    case heif_suberror_No_infe_box:
163
0
      return "No 'infe' box";
164
51
    case heif_suberror_No_pict_handler:
165
51
      return "Not a 'pict' handler";
166
26
    case heif_suberror_Ipma_box_references_nonexisting_property:
167
26
      return "'ipma' box references a non-existing property";
168
93
    case heif_suberror_No_properties_assigned_to_item:
169
93
      return "No properties assigned to item";
170
127
    case heif_suberror_No_item_data:
171
127
      return "Item has no data";
172
0
    case heif_suberror_Invalid_clean_aperture:
173
0
      return "Invalid clean-aperture specification";
174
12
    case heif_suberror_Invalid_overlay_data:
175
12
      return "Invalid overlay data";
176
0
    case heif_suberror_Overlay_image_outside_of_canvas:
177
0
      return "Overlay image outside of canvas area";
178
10
    case heif_suberror_Auxiliary_image_type_unspecified:
179
10
      return "Type of auxiliary image unspecified";
180
0
    case heif_suberror_No_or_invalid_primary_item:
181
0
      return "No or invalid primary item";
182
22
    case heif_suberror_Unknown_color_profile_type:
183
22
      return "Unknown color profile type";
184
0
    case heif_suberror_Wrong_tile_image_chroma_format:
185
0
      return "Wrong tile image chroma format";
186
2
    case heif_suberror_Invalid_fractional_number:
187
2
      return "Invalid fractional number";
188
14
    case heif_suberror_Invalid_image_size:
189
14
      return "Invalid image size";
190
0
    case heif_suberror_Invalid_pixi_box:
191
0
      return "Invalid pixi box";
192
0
    case heif_suberror_Wrong_tile_image_pixel_depth:
193
0
      return "Wrong tile image pixel depth";
194
0
    case heif_suberror_Unknown_NCLX_color_primaries:
195
0
      return "Unknown NCLX color primaries";
196
0
    case heif_suberror_Unknown_NCLX_transfer_characteristics:
197
0
      return "Unknown NCLX transfer characteristics";
198
0
    case heif_suberror_Unknown_NCLX_matrix_coefficients:
199
0
      return "Unknown NCLX matrix coefficients";
200
0
    case heif_suberror_Invalid_region_data:
201
0
      return "Invalid region item data";
202
2
    case heif_suberror_No_ispe_property:
203
2
      return "Image has no 'ispe' property";
204
0
    case heif_suberror_Camera_intrinsic_matrix_undefined:
205
0
      return "Camera intrinsic matrix undefined";
206
0
    case heif_suberror_Camera_extrinsic_matrix_undefined:
207
0
      return "Camera extrinsic matrix undefined";
208
0
    case heif_suberror_Invalid_J2K_codestream:
209
0
      return "Invalid JPEG 2000 codestream";
210
0
    case heif_suberror_Decompression_invalid_data:
211
0
      return "Invalid data in generic compression inflation";
212
84
    case heif_suberror_No_moov_box:
213
84
      return "No 'moov' box";
214
0
    case heif_suberror_No_icbr_box:
215
0
      return "No 'icbr' box";
216
0
    case heif_suberror_Invalid_mini_box:
217
0
      return "Unsupported or invalid 'mini' box";
218
219
220
      // --- Memory_allocation_error ---
221
222
465
    case heif_suberror_Security_limit_exceeded:
223
465
      return "Security limit exceeded";
224
0
    case heif_suberror_Compression_initialisation_error:
225
0
      return "Compression initialisation method error";
226
227
      // --- Usage_error ---
228
229
251
    case heif_suberror_Nonexisting_item_referenced:
230
251
      return "Non-existing item ID referenced";
231
0
    case heif_suberror_Null_pointer_argument:
232
0
      return "NULL argument received";
233
0
    case heif_suberror_Nonexisting_image_channel_referenced:
234
0
      return "Non-existing image channel referenced";
235
0
    case heif_suberror_Unsupported_plugin_version:
236
0
      return "The version of the passed plugin is not supported";
237
0
    case heif_suberror_Unsupported_writer_version:
238
0
      return "The version of the passed writer is not supported";
239
0
    case heif_suberror_Unsupported_parameter:
240
0
      return "Unsupported parameter";
241
3
    case heif_suberror_Invalid_parameter_value:
242
3
      return "Invalid parameter value";
243
0
    case heif_suberror_Invalid_property:
244
0
      return "Invalid property";
245
12
    case heif_suberror_Item_reference_cycle:
246
12
      return "Image reference cycle";
247
248
      // --- Unsupported_feature ---
249
250
0
    case heif_suberror_Unsupported_codec:
251
0
      return "Unsupported codec";
252
1
    case heif_suberror_Unsupported_image_type:
253
1
      return "Unsupported image type";
254
115
    case heif_suberror_Unsupported_data_version:
255
115
      return "Unsupported data version";
256
1.65k
    case heif_suberror_Unsupported_color_conversion:
257
1.65k
      return "Unsupported color conversion";
258
3
    case heif_suberror_Unsupported_item_construction_method:
259
3
      return "Unsupported item construction method";
260
0
    case heif_suberror_Unsupported_header_compression_method:
261
0
      return "Unsupported header compression method";
262
0
    case heif_suberror_Unsupported_generic_compression_method:
263
0
      return "Unsupported generic compression method";
264
4
    case heif_suberror_Unsupported_essential_property:
265
4
      return "Unsupported essential item property";
266
267
      // --- Encoder_plugin_error --
268
269
0
    case heif_suberror_Unsupported_bit_depth:
270
0
      return "Unsupported bit depth";
271
272
      // --- Encoding_error --
273
274
0
    case heif_suberror_Cannot_write_output_data:
275
0
      return "Cannot write output data";
276
0
    case heif_suberror_Encoder_initialization:
277
0
      return "Initialization problem";
278
0
    case heif_suberror_Encoder_encoding:
279
0
      return "Encoding problem";
280
0
    case heif_suberror_Encoder_cleanup:
281
0
      return "Cleanup problem";
282
0
    case heif_suberror_Too_many_regions:
283
0
      return "Too many regions (>255) in an 'rgan' item.";
284
285
      // --- Plugin_loading_error ---
286
287
0
    case heif_suberror_Plugin_loading_error:
288
0
      return "Plugin file cannot be loaded";
289
0
    case heif_suberror_Plugin_is_not_loaded:
290
0
      return "Trying to remove a plugin that is not loaded";
291
0
    case heif_suberror_Cannot_read_plugin_directory:
292
0
      return "Error while scanning the directory for plugins";
293
178
    case heif_suberror_No_matching_decoder_installed:
294
#if ENABLE_PLUGIN_LOADING
295
      return "No decoding plugin installed for this compression format";
296
#else
297
178
      return "Support for this compression format has not been built in";
298
9.23k
#endif
299
9.23k
  }
300
301
0
  assert(false);
302
0
  return cUnknownError;
303
9.23k
}
304
305
306
heif_error Error::error_struct(ErrorBuffer* error_buffer) const
307
22.1k
{
308
22.1k
  if (error_buffer) {
309
18.5k
    if (error_code == heif_error_Ok) {
310
10.1k
      error_buffer->set_success();
311
10.1k
    }
312
8.41k
    else {
313
8.41k
      std::stringstream sstr;
314
8.41k
      sstr << get_error_string(error_code) << ": "
315
8.41k
           << get_error_string(sub_error_code);
316
8.41k
      if (!message.empty()) {
317
3.87k
        sstr << ": " << message;
318
3.87k
      }
319
320
8.41k
      error_buffer->set_error(sstr.str());
321
8.41k
    }
322
18.5k
  }
323
324
22.1k
  heif_error err;
325
22.1k
  err.code = error_code;
326
22.1k
  err.subcode = sub_error_code;
327
22.1k
  if (error_buffer) {
328
18.5k
    err.message = error_buffer->get_error();
329
18.5k
  }
330
3.65k
  else {
331
3.65k
    err.message = cUnknownError;
332
3.65k
  }
333
22.1k
  return err;
334
22.1k
}