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