/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 | } |