/src/libexif/libexif/exif-data.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* exif-data.c |
2 | | * |
3 | | * Copyright (c) 2001 Lutz Mueller <lutz@users.sourceforge.net> |
4 | | * |
5 | | * This library is free software; you can redistribute it and/or |
6 | | * modify it under the terms of the GNU Lesser General Public |
7 | | * License as published by the Free Software Foundation; either |
8 | | * version 2 of the License, or (at your option) any later version. |
9 | | * |
10 | | * This library is distributed in the hope that it will be useful, |
11 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | | * Lesser General Public License for more details. |
14 | | * |
15 | | * You should have received a copy of the GNU Lesser General Public |
16 | | * License along with this library; if not, write to the |
17 | | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | | * Boston, MA 02110-1301 USA. |
19 | | * |
20 | | * SPDX-License-Identifier: LGPL-2.0-or-later |
21 | | */ |
22 | | |
23 | | #include <config.h> |
24 | | |
25 | | #include <libexif/exif-mnote-data.h> |
26 | | #include <libexif/exif-data.h> |
27 | | #include <libexif/exif-ifd.h> |
28 | | #include <libexif/exif-mnote-data-priv.h> |
29 | | #include <libexif/exif-utils.h> |
30 | | #include <libexif/exif-loader.h> |
31 | | #include <libexif/exif-log.h> |
32 | | #include <libexif/i18n.h> |
33 | | #include <libexif/exif-system.h> |
34 | | |
35 | | /*#include <libexif/apple/exif-mnote-data-apple.h>*/ |
36 | | #include <libexif/canon/exif-mnote-data-canon.h> |
37 | | #include <libexif/fuji/exif-mnote-data-fuji.h> |
38 | | #include <libexif/olympus/exif-mnote-data-olympus.h> |
39 | | #include <libexif/pentax/exif-mnote-data-pentax.h> |
40 | | |
41 | | #include <math.h> |
42 | | #include <stdlib.h> |
43 | | #include <stdio.h> |
44 | | #include <string.h> |
45 | | |
46 | | #undef JPEG_MARKER_SOI |
47 | 2.31k | #define JPEG_MARKER_SOI 0xd8 |
48 | | #undef JPEG_MARKER_APP0 |
49 | | #define JPEG_MARKER_APP0 0xe0 |
50 | | #undef JPEG_MARKER_APP1 |
51 | 1.42k | #define JPEG_MARKER_APP1 0xe1 |
52 | | |
53 | 5.06M | #define CHECKOVERFLOW(offset,datasize,structsize) (( (offset) >= (datasize)) || ((structsize) > (datasize)) || ((offset) > (datasize) - (structsize) )) |
54 | | |
55 | | static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; |
56 | | |
57 | | struct _ExifDataPrivate |
58 | | { |
59 | | ExifByteOrder order; |
60 | | |
61 | | ExifMnoteData *md; |
62 | | |
63 | | ExifLog *log; |
64 | | ExifMem *mem; |
65 | | |
66 | | unsigned int ref_count; |
67 | | |
68 | | /* Temporarily used while loading data */ |
69 | | unsigned int offset_mnote; |
70 | | |
71 | | ExifDataOption options; |
72 | | ExifDataType data_type; |
73 | | }; |
74 | | |
75 | | static void * |
76 | | exif_data_alloc (ExifData *data, unsigned int i) |
77 | 89.1k | { |
78 | 89.1k | void *d; |
79 | | |
80 | 89.1k | if (!data || !i) |
81 | 0 | return NULL; |
82 | | |
83 | 89.1k | d = exif_mem_alloc (data->priv->mem, i); |
84 | 89.1k | if (d) |
85 | 89.1k | return d; |
86 | | |
87 | 0 | EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", i); |
88 | 0 | return NULL; |
89 | 89.1k | } |
90 | | |
91 | | ExifMnoteData * |
92 | | exif_data_get_mnote_data (ExifData *d) |
93 | 30.6k | { |
94 | 30.6k | return (d && d->priv) ? d->priv->md : NULL; |
95 | 30.6k | } |
96 | | |
97 | | ExifData * |
98 | | exif_data_new (void) |
99 | 10.3k | { |
100 | 10.3k | ExifMem *mem = exif_mem_new_default (); |
101 | 10.3k | ExifData *d = exif_data_new_mem (mem); |
102 | | |
103 | 10.3k | exif_mem_unref (mem); |
104 | | |
105 | 10.3k | return d; |
106 | 10.3k | } |
107 | | |
108 | | ExifData * |
109 | | exif_data_new_mem (ExifMem *mem) |
110 | 20.3k | { |
111 | 20.3k | ExifData *data; |
112 | 20.3k | unsigned int i; |
113 | | |
114 | 20.3k | if (!mem) |
115 | 0 | return NULL; |
116 | | |
117 | 20.3k | data = exif_mem_alloc (mem, sizeof (ExifData)); |
118 | 20.3k | if (!data) |
119 | 0 | return (NULL); |
120 | 20.3k | data->priv = exif_mem_alloc (mem, sizeof (ExifDataPrivate)); |
121 | 20.3k | if (!data->priv) { |
122 | 0 | exif_mem_free (mem, data); |
123 | 0 | return (NULL); |
124 | 0 | } |
125 | 20.3k | data->priv->ref_count = 1; |
126 | | |
127 | 20.3k | data->priv->mem = mem; |
128 | 20.3k | exif_mem_ref (mem); |
129 | | |
130 | 121k | for (i = 0; i < EXIF_IFD_COUNT; i++) { |
131 | 101k | data->ifd[i] = exif_content_new_mem (data->priv->mem); |
132 | 101k | if (!data->ifd[i]) { |
133 | 0 | exif_data_free (data); |
134 | 0 | return (NULL); |
135 | 0 | } |
136 | 101k | data->ifd[i]->parent = data; |
137 | 101k | } |
138 | | |
139 | | /* Default options */ |
140 | 20.3k | #ifndef NO_VERBOSE_TAG_STRINGS |
141 | | /* |
142 | | * When the tag list is compiled away, setting this option prevents |
143 | | * any tags from being loaded |
144 | | */ |
145 | 20.3k | exif_data_set_option (data, EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS); |
146 | 20.3k | #endif |
147 | 20.3k | exif_data_set_option (data, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION); |
148 | | |
149 | | /* Default data type: none */ |
150 | 20.3k | exif_data_set_data_type (data, EXIF_DATA_TYPE_COUNT); |
151 | | |
152 | 20.3k | return (data); |
153 | 20.3k | } |
154 | | |
155 | | ExifData * |
156 | | exif_data_new_from_data (const unsigned char *data, unsigned int size) |
157 | 10.3k | { |
158 | 10.3k | ExifData *edata; |
159 | | |
160 | 10.3k | edata = exif_data_new (); |
161 | 10.3k | exif_data_load_data (edata, data, size); |
162 | 10.3k | return (edata); |
163 | 10.3k | } |
164 | | |
165 | | static int |
166 | | exif_data_load_data_entry (ExifData *data, ExifEntry *entry, |
167 | | const unsigned char *d, |
168 | | unsigned int size, unsigned int offset) |
169 | 1.26M | { |
170 | 1.26M | unsigned int s, doff; |
171 | | |
172 | 1.26M | entry->tag = exif_get_short (d + offset + 0, data->priv->order); |
173 | 1.26M | entry->format = exif_get_short (d + offset + 2, data->priv->order); |
174 | 1.26M | entry->components = exif_get_long (d + offset + 4, data->priv->order); |
175 | | |
176 | | /* FIXME: should use exif_tag_get_name_in_ifd here but entry->parent |
177 | | * has not been set yet |
178 | | */ |
179 | 1.26M | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
180 | 1.26M | "Loading entry 0x%x ('%s')...", entry->tag, |
181 | 1.26M | exif_tag_get_name (entry->tag)); |
182 | | |
183 | | /* {0,1,2,4,8} x { 0x00000000 .. 0xffffffff } |
184 | | * -> { 0x000000000 .. 0x7fffffff8 } */ |
185 | 1.26M | s = exif_format_get_size(entry->format) * entry->components; |
186 | 1.26M | if ((s < entry->components) || (s == 0)){ |
187 | 1.11M | return 0; |
188 | 1.11M | } |
189 | | |
190 | | /* |
191 | | * Size? If bigger than 4 bytes, the actual data is not |
192 | | * in the entry but somewhere else (offset). |
193 | | */ |
194 | 153k | if (s > 4) |
195 | 128k | doff = exif_get_long (d + offset + 8, data->priv->order); |
196 | 25.3k | else |
197 | 25.3k | doff = offset + 8; |
198 | | |
199 | | /* Sanity checks */ |
200 | 153k | if (doff >= size) { |
201 | 64.4k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
202 | 64.4k | "Tag starts past end of buffer (%u > %u)", doff, size); |
203 | 64.4k | return 0; |
204 | 64.4k | } |
205 | | |
206 | 89.3k | if (s > size - doff) { |
207 | 13.8k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
208 | 13.8k | "Tag data goes past end of buffer (%u > %u)", doff+s, size); |
209 | 13.8k | return 0; |
210 | 13.8k | } |
211 | | |
212 | 75.5k | entry->data = exif_data_alloc (data, s); |
213 | 75.5k | if (entry->data) { |
214 | 75.5k | entry->size = s; |
215 | 75.5k | memcpy (entry->data, d + doff, s); |
216 | 75.5k | } else { |
217 | 0 | EXIF_LOG_NO_MEMORY(data->priv->log, "ExifData", s); |
218 | 0 | return 0; |
219 | 0 | } |
220 | | |
221 | | /* If this is the MakerNote, remember the offset */ |
222 | 75.5k | if (entry->tag == EXIF_TAG_MAKER_NOTE) { |
223 | 17.9k | if (!entry->data) { |
224 | 0 | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
225 | 0 | "MakerNote found with empty data"); |
226 | 17.9k | } else if (entry->size > 6) { |
227 | 15.9k | exif_log (data->priv->log, |
228 | 15.9k | EXIF_LOG_CODE_DEBUG, "ExifData", |
229 | 15.9k | "MakerNote found (%02x %02x %02x %02x " |
230 | 15.9k | "%02x %02x %02x...).", |
231 | 15.9k | entry->data[0], entry->data[1], entry->data[2], |
232 | 15.9k | entry->data[3], entry->data[4], entry->data[5], |
233 | 15.9k | entry->data[6]); |
234 | 15.9k | } |
235 | 17.9k | data->priv->offset_mnote = doff; |
236 | 17.9k | } |
237 | 75.5k | return 1; |
238 | 75.5k | } |
239 | | |
240 | | static void |
241 | | exif_data_save_data_entry (ExifData *data, ExifEntry *e, |
242 | | unsigned char **d, unsigned int *ds, |
243 | | unsigned int offset) |
244 | 71.6k | { |
245 | 71.6k | unsigned int doff, s; |
246 | 71.6k | unsigned int ts; |
247 | | |
248 | 71.6k | if (!data || !data->priv) |
249 | 0 | return; |
250 | | |
251 | | /* |
252 | | * Each entry is 12 bytes long. The memory for the entry has |
253 | | * already been allocated. |
254 | | */ |
255 | 71.6k | exif_set_short (*d + 6 + offset + 0, |
256 | 71.6k | data->priv->order, (ExifShort) e->tag); |
257 | 71.6k | exif_set_short (*d + 6 + offset + 2, |
258 | 71.6k | data->priv->order, (ExifShort) e->format); |
259 | | |
260 | 71.6k | if (!(data->priv->options & EXIF_DATA_OPTION_DONT_CHANGE_MAKER_NOTE)) { |
261 | | /* If this is the maker note tag, update it. */ |
262 | 71.6k | if ((e->tag == EXIF_TAG_MAKER_NOTE) && data->priv->md) { |
263 | | /* TODO: this is using the wrong ExifMem to free e->data */ |
264 | 7.09k | exif_mem_free (data->priv->mem, e->data); |
265 | 7.09k | e->data = NULL; |
266 | 7.09k | e->size = 0; |
267 | 7.09k | exif_mnote_data_set_offset (data->priv->md, *ds - 6); |
268 | 7.09k | exif_mnote_data_save (data->priv->md, &e->data, &e->size); |
269 | 7.09k | e->components = e->size; |
270 | 7.09k | if (exif_format_get_size (e->format) != 1) { |
271 | | /* e->format is taken from input code, |
272 | | * but we need to make sure it is a 1 byte |
273 | | * entity due to the multiplication below. */ |
274 | 1.58k | e->format = EXIF_FORMAT_UNDEFINED; |
275 | 1.58k | } |
276 | 7.09k | } |
277 | 71.6k | } |
278 | | |
279 | 71.6k | exif_set_long (*d + 6 + offset + 4, |
280 | 71.6k | data->priv->order, e->components); |
281 | | |
282 | | /* |
283 | | * Size? If bigger than 4 bytes, the actual data is not in |
284 | | * the entry but somewhere else. |
285 | | */ |
286 | | /* we usually have only 64kb datablock, so add a safety bound to avoid overflows */ |
287 | 71.6k | if (e->components > 65536) { |
288 | 154 | exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", _("Overflow in components detected.")); |
289 | 154 | return; |
290 | 154 | } |
291 | 71.4k | s = exif_format_get_size (e->format) * e->components; |
292 | 71.4k | if (s > 4) { |
293 | 33.9k | unsigned char *t; |
294 | 33.9k | doff = *ds - 6; |
295 | 33.9k | ts = *ds + s; |
296 | | |
297 | | /* |
298 | | * According to the TIFF specification, |
299 | | * the offset must be an even number. If we need to introduce |
300 | | * a padding byte, we set it to 0. |
301 | | */ |
302 | 33.9k | if (s & 1) |
303 | 1.98k | ts++; |
304 | 33.9k | t = exif_mem_realloc (data->priv->mem, *d, ts); |
305 | 33.9k | if (!t) { |
306 | 0 | EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", ts); |
307 | 0 | return; |
308 | 0 | } |
309 | 33.9k | *d = t; |
310 | 33.9k | *ds = ts; |
311 | 33.9k | exif_set_long (*d + 6 + offset + 8, data->priv->order, doff); |
312 | 33.9k | if (s & 1) |
313 | 1.98k | *(*d + *ds - 1) = '\0'; |
314 | | |
315 | 33.9k | } else |
316 | 37.5k | doff = offset + 8; |
317 | | |
318 | | /* Write the data. Fill unneeded bytes with 0. Do not crash with |
319 | | * e->data is NULL */ |
320 | 71.4k | if (e->data) { |
321 | 71.3k | unsigned int len = s; |
322 | 71.3k | if (e->size < s) len = e->size; |
323 | 71.3k | memcpy (*d + 6 + doff, e->data, len); |
324 | 71.3k | } else { |
325 | 69 | memset (*d + 6 + doff, 0, s); |
326 | 69 | } |
327 | 71.4k | if (s < 4) |
328 | 20.5k | memset (*d + 6 + doff + s, 0, (4 - s)); |
329 | 71.4k | } |
330 | | |
331 | | static void |
332 | | exif_data_load_data_thumbnail (ExifData *data, const unsigned char *d, |
333 | | unsigned int ds, ExifLong o, ExifLong s) |
334 | 4.36k | { |
335 | | /* Sanity checks */ |
336 | 4.36k | if (o >= ds) { |
337 | 0 | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Bogus thumbnail offset (%u).", o); |
338 | 0 | return; |
339 | 0 | } |
340 | 4.36k | if (CHECKOVERFLOW(o,ds,s)) { |
341 | 1.05k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Bogus thumbnail size (%u), max would be %u.", s, ds-o); |
342 | 1.05k | return; |
343 | 1.05k | } |
344 | 3.30k | if (data->data) |
345 | 2.64k | exif_mem_free (data->priv->mem, data->data); |
346 | 3.30k | if (!(data->data = exif_data_alloc (data, s))) { |
347 | 0 | EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", s); |
348 | 0 | data->size = 0; |
349 | 0 | return; |
350 | 0 | } |
351 | 3.30k | data->size = s; |
352 | 3.30k | memcpy (data->data, d + o, s); |
353 | 3.30k | } |
354 | | |
355 | | #undef CHECK_REC |
356 | 71.6M | #define CHECK_REC(i) \ |
357 | 71.6M | if ((i) == ifd) { \ |
358 | 34.5M | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, \ |
359 | 34.5M | "ExifData", "Recursive entry in IFD " \ |
360 | 34.5M | "'%s' detected. Skipping...", \ |
361 | 34.5M | exif_ifd_get_name (i)); \ |
362 | 34.5M | break; \ |
363 | 37.1M | } \ |
364 | 37.1M | if (data->ifd[(i)]->count) { \ |
365 | 19.1k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, \ |
366 | 19.1k | "ExifData", "Attempt to load IFD " \ |
367 | 19.1k | "'%s' multiple times detected. " \ |
368 | 19.1k | "Skipping...", \ |
369 | 19.1k | exif_ifd_get_name (i)); \ |
370 | 19.1k | break; \ |
371 | 19.1k | } |
372 | | |
373 | | /*! Calculate the recursion cost added by one level of IFD loading. |
374 | | * |
375 | | * The work performed is related to the cost in the exponential relation |
376 | | * work=1.1**cost |
377 | | */ |
378 | | static unsigned int |
379 | | level_cost(unsigned int n) |
380 | 37.1M | { |
381 | 37.1M | static const double log_1_1 = 0.09531017980432493; |
382 | | |
383 | | /* Adding 0.1 protects against the case where n==1 */ |
384 | 37.1M | return ceil(log(n + 0.1)/log_1_1); |
385 | 37.1M | } |
386 | | |
387 | | /*! Load data for an IFD. |
388 | | * |
389 | | * \param[in,out] data #ExifData |
390 | | * \param[in] ifd IFD to load |
391 | | * \param[in] d pointer to buffer containing raw IFD data |
392 | | * \param[in] ds size of raw data in buffer at \c d |
393 | | * \param[in] offset offset into buffer at \c d at which IFD starts |
394 | | * \param[in] recursion_cost factor indicating how expensive this recursive |
395 | | * call could be |
396 | | */ |
397 | | static void |
398 | | exif_data_load_data_content (ExifData *data, ExifIfd ifd, |
399 | | const unsigned char *d, |
400 | | unsigned int ds, unsigned int offset, unsigned int recursion_cost) |
401 | 37.1M | { |
402 | 37.1M | ExifLong o, thumbnail_offset = 0, thumbnail_length = 0; |
403 | 37.1M | ExifShort n; |
404 | 37.1M | ExifEntry *entry; |
405 | 37.1M | unsigned int i; |
406 | 37.1M | ExifTag tag; |
407 | | |
408 | 37.1M | if (!data || !data->priv) |
409 | 0 | return; |
410 | | |
411 | | /* check for valid ExifIfd enum range */ |
412 | 37.1M | if ((((int)ifd) < 0) || ( ((int)ifd) >= EXIF_IFD_COUNT)) |
413 | 0 | return; |
414 | | |
415 | 37.1M | if (recursion_cost > 170) { |
416 | | /* |
417 | | * recursion_cost is a logarithmic-scale indicator of how expensive this |
418 | | * recursive call might end up being. It is an indicator of the depth of |
419 | | * recursion as well as the potential for worst-case future recursive |
420 | | * calls. Since it's difficult to tell ahead of time how often recursion |
421 | | * will occur, this assumes the worst by assuming every tag could end up |
422 | | * causing recursion. |
423 | | * The value of 170 was chosen to limit typical EXIF structures to a |
424 | | * recursive depth of about 6, but pathological ones (those with very |
425 | | * many tags) to only 2. |
426 | | */ |
427 | 34.6M | exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", |
428 | 34.6M | "Deep/expensive recursion detected!"); |
429 | 34.6M | return; |
430 | 34.6M | } |
431 | | |
432 | | /* Read the number of entries */ |
433 | 2.53M | if (CHECKOVERFLOW(offset, ds, 2)) { |
434 | 1.48k | exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", |
435 | 1.48k | "Tag data past end of buffer (%u+2 > %u)", offset, ds); |
436 | 1.48k | return; |
437 | 1.48k | } |
438 | 2.53M | n = exif_get_short (d + offset, data->priv->order); |
439 | 2.53M | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
440 | 2.53M | "Loading %hu entries...", n); |
441 | 2.53M | offset += 2; |
442 | | |
443 | | /* Check if we have enough data. */ |
444 | 2.53M | if (CHECKOVERFLOW(offset, ds, 12*n)) { |
445 | 2.43M | n = (ds - offset) / 12; |
446 | 2.43M | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
447 | 2.43M | "Short data; only loading %hu entries...", n); |
448 | 2.43M | } |
449 | | |
450 | 120M | for (i = 0; i < n; i++) { |
451 | | |
452 | 117M | tag = exif_get_short (d + offset + 12 * i, data->priv->order); |
453 | 117M | switch (tag) { |
454 | 1.27M | case EXIF_TAG_EXIF_IFD_POINTER: |
455 | 36.2M | case EXIF_TAG_GPS_INFO_IFD_POINTER: |
456 | 71.6M | case EXIF_TAG_INTEROPERABILITY_IFD_POINTER: |
457 | 71.6M | case EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH: |
458 | 71.6M | case EXIF_TAG_JPEG_INTERCHANGE_FORMAT: |
459 | 71.6M | o = exif_get_long (d + offset + 12 * i + 8, |
460 | 71.6M | data->priv->order); |
461 | 71.6M | if (o >= ds) { |
462 | 19.6k | exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", |
463 | 19.6k | "Tag data past end of buffer (%u > %u)", offset+2, ds); |
464 | 19.6k | if (recursion_cost > 0) |
465 | 12.9k | return; |
466 | 6.72k | break; |
467 | 19.6k | } |
468 | | /* FIXME: IFD_POINTER tags aren't marked as being in a |
469 | | * specific IFD, so exif_tag_get_name_in_ifd won't work |
470 | | */ |
471 | 71.6M | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
472 | 71.6M | "Sub-IFD entry 0x%x ('%s') at %u.", tag, |
473 | 71.6M | exif_tag_get_name(tag), o); |
474 | 71.6M | switch (tag) { |
475 | 1.27M | case EXIF_TAG_EXIF_IFD_POINTER: |
476 | 1.27M | CHECK_REC (EXIF_IFD_EXIF) |
477 | 1.25M | exif_data_load_data_content (data, EXIF_IFD_EXIF, d, ds, o, |
478 | 1.25M | recursion_cost + level_cost(n)); |
479 | 1.25M | break; |
480 | 35.0M | case EXIF_TAG_GPS_INFO_IFD_POINTER: |
481 | 35.0M | CHECK_REC (EXIF_IFD_GPS) |
482 | 17.8M | exif_data_load_data_content (data, EXIF_IFD_GPS, d, ds, o, |
483 | 17.8M | recursion_cost + level_cost(n)); |
484 | 17.8M | break; |
485 | 35.3M | case EXIF_TAG_INTEROPERABILITY_IFD_POINTER: |
486 | 35.3M | CHECK_REC (EXIF_IFD_INTEROPERABILITY) |
487 | 17.9M | exif_data_load_data_content (data, EXIF_IFD_INTEROPERABILITY, d, ds, o, |
488 | 17.9M | recursion_cost + level_cost(n)); |
489 | 17.9M | break; |
490 | 13.3k | case EXIF_TAG_JPEG_INTERCHANGE_FORMAT: |
491 | 13.3k | thumbnail_offset = o; |
492 | 13.3k | if (thumbnail_offset && thumbnail_length) |
493 | 1.89k | exif_data_load_data_thumbnail (data, d, |
494 | 1.89k | ds, thumbnail_offset, |
495 | 1.89k | thumbnail_length); |
496 | 13.3k | break; |
497 | 9.69k | case EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH: |
498 | 9.69k | thumbnail_length = o; |
499 | 9.69k | if (thumbnail_offset && thumbnail_length) |
500 | 2.47k | exif_data_load_data_thumbnail (data, d, |
501 | 2.47k | ds, thumbnail_offset, |
502 | 2.47k | thumbnail_length); |
503 | 9.69k | break; |
504 | 0 | default: |
505 | 0 | return; |
506 | 71.6M | } |
507 | 71.6M | break; |
508 | 71.6M | default: |
509 | | |
510 | | /* |
511 | | * If we don't know the tag, don't fail. It could be that new |
512 | | * versions of the standard have defined additional tags. Note that |
513 | | * 0 is a valid tag in the GPS IFD. |
514 | | */ |
515 | 46.0M | if (!exif_tag_get_name_in_ifd (tag, ifd)) { |
516 | | |
517 | | /* |
518 | | * Special case: Tag and format 0. That's against specification |
519 | | * (at least up to 2.2). But Photoshop writes it anyways. |
520 | | */ |
521 | 44.8M | if (!memcmp (d + offset + 12 * i, "\0\0\0\0", 4)) { |
522 | 962k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
523 | 962k | "Skipping empty entry at position %u in '%s'.", i, |
524 | 962k | exif_ifd_get_name (ifd)); |
525 | 962k | break; |
526 | 962k | } |
527 | 43.8M | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
528 | 43.8M | "Unknown tag 0x%04x (entry %u in '%s'). Please report this tag " |
529 | 43.8M | "to <libexif-devel@lists.sourceforge.net>.", tag, i, |
530 | 43.8M | exif_ifd_get_name (ifd)); |
531 | 43.8M | if (data->priv->options & EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS) |
532 | 43.8M | break; |
533 | 43.8M | } |
534 | 1.26M | entry = exif_entry_new_mem (data->priv->mem); |
535 | 1.26M | if (!entry) { |
536 | 0 | exif_log (data->priv->log, EXIF_LOG_CODE_NO_MEMORY, "ExifData", |
537 | 0 | "Could not allocate memory"); |
538 | 0 | return; |
539 | 0 | } |
540 | 1.26M | if (exif_data_load_data_entry (data, entry, d, ds, |
541 | 1.26M | offset + 12 * i)) |
542 | 75.5k | exif_content_add_entry (data->ifd[ifd], entry); |
543 | 1.26M | exif_entry_unref (entry); |
544 | 1.26M | break; |
545 | 117M | } |
546 | 117M | } |
547 | 2.53M | } |
548 | | |
549 | | static int |
550 | | cmp_func (const unsigned char *p1, const unsigned char *p2, ExifByteOrder o) |
551 | 102k | { |
552 | 102k | ExifShort tag1 = exif_get_short (p1, o); |
553 | 102k | ExifShort tag2 = exif_get_short (p2, o); |
554 | | |
555 | 102k | return (tag1 < tag2) ? -1 : (tag1 > tag2) ? 1 : 0; |
556 | 102k | } |
557 | | |
558 | | static int |
559 | | cmp_func_intel (const void *elem1, const void *elem2) |
560 | 100k | { |
561 | 100k | return cmp_func ((const unsigned char *) elem1, |
562 | 100k | (const unsigned char *) elem2, EXIF_BYTE_ORDER_INTEL); |
563 | 100k | } |
564 | | |
565 | | static int |
566 | | cmp_func_motorola (const void *elem1, const void *elem2) |
567 | 2.00k | { |
568 | 2.00k | return cmp_func ((const unsigned char *) elem1, |
569 | 2.00k | (const unsigned char *) elem2, EXIF_BYTE_ORDER_MOTOROLA); |
570 | 2.00k | } |
571 | | |
572 | | static void |
573 | | exif_data_save_data_content (ExifData *data, ExifContent *ifd, |
574 | | unsigned char **d, unsigned int *ds, |
575 | | unsigned int offset) |
576 | 20.6k | { |
577 | 20.6k | unsigned int j, n_ptr = 0, n_thumb = 0; |
578 | 20.6k | ExifIfd i; |
579 | 20.6k | unsigned char *t; |
580 | 20.6k | unsigned int ts; |
581 | | |
582 | 20.6k | if (!data || !data->priv || !ifd || !d || !ds) |
583 | 0 | return; |
584 | | |
585 | 42.2k | for (i = 0; i < EXIF_IFD_COUNT; i++) |
586 | 42.2k | if (ifd == data->ifd[i]) |
587 | 20.6k | break; |
588 | 20.6k | if (i == EXIF_IFD_COUNT) |
589 | 0 | return; /* error */ |
590 | | |
591 | | /* |
592 | | * Check if we need some extra entries for pointers or the thumbnail. |
593 | | */ |
594 | 20.6k | switch (i) { |
595 | 10.3k | case EXIF_IFD_0: |
596 | | |
597 | | /* |
598 | | * The pointer to IFD_EXIF is in IFD_0. The pointer to |
599 | | * IFD_INTEROPERABILITY is in IFD_EXIF. |
600 | | */ |
601 | 10.3k | if (data->ifd[EXIF_IFD_EXIF]->count || |
602 | 10.3k | data->ifd[EXIF_IFD_INTEROPERABILITY]->count) |
603 | 8.77k | n_ptr++; |
604 | | |
605 | | /* The pointer to IFD_GPS is in IFD_0. */ |
606 | 10.3k | if (data->ifd[EXIF_IFD_GPS]->count) |
607 | 693 | n_ptr++; |
608 | | |
609 | 10.3k | break; |
610 | 432 | case EXIF_IFD_1: |
611 | 432 | if (data->size) |
612 | 432 | n_thumb = 2; |
613 | 432 | break; |
614 | 8.77k | case EXIF_IFD_EXIF: |
615 | 8.77k | if (data->ifd[EXIF_IFD_INTEROPERABILITY]->count) |
616 | 387 | n_ptr++; |
617 | 9.85k | default: |
618 | 9.85k | break; |
619 | 20.6k | } |
620 | | |
621 | | /* |
622 | | * Allocate enough memory for all entries |
623 | | * and the number of entries. |
624 | | */ |
625 | 20.6k | ts = *ds + (2 + (ifd->count + n_ptr + n_thumb) * 12 + 4); |
626 | 20.6k | t = exif_mem_realloc (data->priv->mem, *d, ts); |
627 | 20.6k | if (!t) { |
628 | 0 | EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", ts); |
629 | 0 | return; |
630 | 0 | } |
631 | 20.6k | *d = t; |
632 | 20.6k | *ds = ts; |
633 | | |
634 | | /* Save the number of entries */ |
635 | 20.6k | exif_set_short (*d + 6 + offset, data->priv->order, |
636 | 20.6k | (ExifShort) (ifd->count + n_ptr + n_thumb)); |
637 | 20.6k | offset += 2; |
638 | | |
639 | | /* |
640 | | * Save each entry. Make sure that no memcpys from NULL pointers are |
641 | | * performed |
642 | | */ |
643 | 20.6k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
644 | 20.6k | "Saving %i entries (IFD '%s', offset: %i)...", |
645 | 20.6k | ifd->count, exif_ifd_get_name (i), offset); |
646 | 92.2k | for (j = 0; j < ifd->count; j++) { |
647 | 71.6k | if (ifd->entries[j]) { |
648 | 71.6k | exif_data_save_data_entry (data, ifd->entries[j], d, ds, |
649 | 71.6k | offset + 12 * j); |
650 | 71.6k | } |
651 | 71.6k | } |
652 | | |
653 | 20.6k | offset += 12 * ifd->count; |
654 | | |
655 | | /* Now save special entries. */ |
656 | 20.6k | switch (i) { |
657 | 10.3k | case EXIF_IFD_0: |
658 | | |
659 | | /* |
660 | | * The pointer to IFD_EXIF is in IFD_0. |
661 | | * However, the pointer to IFD_INTEROPERABILITY is in IFD_EXIF, |
662 | | * therefore, if IFD_INTEROPERABILITY is not empty, we need |
663 | | * IFD_EXIF even if latter is empty. |
664 | | */ |
665 | 10.3k | if (data->ifd[EXIF_IFD_EXIF]->count || |
666 | 10.3k | data->ifd[EXIF_IFD_INTEROPERABILITY]->count) { |
667 | 8.77k | exif_set_short (*d + 6 + offset + 0, data->priv->order, |
668 | 8.77k | EXIF_TAG_EXIF_IFD_POINTER); |
669 | 8.77k | exif_set_short (*d + 6 + offset + 2, data->priv->order, |
670 | 8.77k | EXIF_FORMAT_LONG); |
671 | 8.77k | exif_set_long (*d + 6 + offset + 4, data->priv->order, |
672 | 8.77k | 1); |
673 | 8.77k | exif_set_long (*d + 6 + offset + 8, data->priv->order, |
674 | 8.77k | *ds - 6); |
675 | 8.77k | exif_data_save_data_content (data, |
676 | 8.77k | data->ifd[EXIF_IFD_EXIF], d, ds, *ds - 6); |
677 | 8.77k | offset += 12; |
678 | 8.77k | } |
679 | | |
680 | | /* The pointer to IFD_GPS is in IFD_0, too. */ |
681 | 10.3k | if (data->ifd[EXIF_IFD_GPS]->count) { |
682 | 693 | exif_set_short (*d + 6 + offset + 0, data->priv->order, |
683 | 693 | EXIF_TAG_GPS_INFO_IFD_POINTER); |
684 | 693 | exif_set_short (*d + 6 + offset + 2, data->priv->order, |
685 | 693 | EXIF_FORMAT_LONG); |
686 | 693 | exif_set_long (*d + 6 + offset + 4, data->priv->order, |
687 | 693 | 1); |
688 | 693 | exif_set_long (*d + 6 + offset + 8, data->priv->order, |
689 | 693 | *ds - 6); |
690 | 693 | exif_data_save_data_content (data, |
691 | 693 | data->ifd[EXIF_IFD_GPS], d, ds, *ds - 6); |
692 | 693 | offset += 12; |
693 | 693 | } |
694 | | |
695 | 10.3k | break; |
696 | 8.77k | case EXIF_IFD_EXIF: |
697 | | |
698 | | /* |
699 | | * The pointer to IFD_INTEROPERABILITY is in IFD_EXIF. |
700 | | * See note above. |
701 | | */ |
702 | 8.77k | if (data->ifd[EXIF_IFD_INTEROPERABILITY]->count) { |
703 | 387 | exif_set_short (*d + 6 + offset + 0, data->priv->order, |
704 | 387 | EXIF_TAG_INTEROPERABILITY_IFD_POINTER); |
705 | 387 | exif_set_short (*d + 6 + offset + 2, data->priv->order, |
706 | 387 | EXIF_FORMAT_LONG); |
707 | 387 | exif_set_long (*d + 6 + offset + 4, data->priv->order, |
708 | 387 | 1); |
709 | 387 | exif_set_long (*d + 6 + offset + 8, data->priv->order, |
710 | 387 | *ds - 6); |
711 | 387 | exif_data_save_data_content (data, |
712 | 387 | data->ifd[EXIF_IFD_INTEROPERABILITY], d, ds, |
713 | 387 | *ds - 6); |
714 | 387 | offset += 12; |
715 | 387 | } |
716 | | |
717 | 8.77k | break; |
718 | 432 | case EXIF_IFD_1: |
719 | | |
720 | | /* |
721 | | * Information about the thumbnail (if any) is saved in |
722 | | * IFD_1. |
723 | | */ |
724 | 432 | if (data->size) { |
725 | | |
726 | | /* EXIF_TAG_JPEG_INTERCHANGE_FORMAT */ |
727 | 432 | exif_set_short (*d + 6 + offset + 0, data->priv->order, |
728 | 432 | EXIF_TAG_JPEG_INTERCHANGE_FORMAT); |
729 | 432 | exif_set_short (*d + 6 + offset + 2, data->priv->order, |
730 | 432 | EXIF_FORMAT_LONG); |
731 | 432 | exif_set_long (*d + 6 + offset + 4, data->priv->order, |
732 | 432 | 1); |
733 | 432 | exif_set_long (*d + 6 + offset + 8, data->priv->order, |
734 | 432 | *ds - 6); |
735 | 432 | ts = *ds + data->size; |
736 | 432 | t = exif_mem_realloc (data->priv->mem, *d, ts); |
737 | 432 | if (!t) { |
738 | 0 | EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", |
739 | 0 | ts); |
740 | 0 | return; |
741 | 0 | } |
742 | 432 | *d = t; |
743 | 432 | *ds = ts; |
744 | 432 | memcpy (*d + *ds - data->size, data->data, data->size); |
745 | 432 | offset += 12; |
746 | | |
747 | | /* EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH */ |
748 | 432 | exif_set_short (*d + 6 + offset + 0, data->priv->order, |
749 | 432 | EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH); |
750 | 432 | exif_set_short (*d + 6 + offset + 2, data->priv->order, |
751 | 432 | EXIF_FORMAT_LONG); |
752 | 432 | exif_set_long (*d + 6 + offset + 4, data->priv->order, |
753 | 432 | 1); |
754 | 432 | exif_set_long (*d + 6 + offset + 8, data->priv->order, |
755 | 432 | data->size); |
756 | 432 | offset += 12; |
757 | 432 | } |
758 | | |
759 | 432 | break; |
760 | 1.08k | default: |
761 | 1.08k | break; |
762 | 20.6k | } |
763 | | |
764 | | /* Sort the directory according to TIFF specification */ |
765 | 20.6k | qsort (*d + 6 + offset - (ifd->count + n_ptr + n_thumb) * 12, |
766 | 20.6k | (ifd->count + n_ptr + n_thumb), 12, |
767 | 20.6k | (data->priv->order == EXIF_BYTE_ORDER_INTEL) ? cmp_func_intel : cmp_func_motorola); |
768 | | |
769 | | /* Correctly terminate the directory */ |
770 | 20.6k | if (i == EXIF_IFD_0 && (data->ifd[EXIF_IFD_1]->count || |
771 | 10.3k | data->size)) { |
772 | | |
773 | | /* |
774 | | * We are saving IFD 0. Tell where IFD 1 starts and save |
775 | | * IFD 1. |
776 | | */ |
777 | 432 | exif_set_long (*d + 6 + offset, data->priv->order, *ds - 6); |
778 | 432 | exif_data_save_data_content (data, data->ifd[EXIF_IFD_1], d, ds, |
779 | 432 | *ds - 6); |
780 | 432 | } else |
781 | 20.2k | exif_set_long (*d + 6 + offset, data->priv->order, 0); |
782 | 20.6k | } |
783 | | |
784 | | typedef enum { |
785 | | EXIF_DATA_TYPE_MAKER_NOTE_NONE = 0, |
786 | | EXIF_DATA_TYPE_MAKER_NOTE_CANON = 1, |
787 | | EXIF_DATA_TYPE_MAKER_NOTE_OLYMPUS = 2, |
788 | | EXIF_DATA_TYPE_MAKER_NOTE_PENTAX = 3, |
789 | | EXIF_DATA_TYPE_MAKER_NOTE_NIKON = 4, |
790 | | EXIF_DATA_TYPE_MAKER_NOTE_CASIO = 5, |
791 | | EXIF_DATA_TYPE_MAKER_NOTE_FUJI = 6 |
792 | | } ExifDataTypeMakerNote; |
793 | | |
794 | | /*! If MakerNote is recognized, load it. |
795 | | * |
796 | | * \param[in,out] data #ExifData |
797 | | * \param[in] d pointer to raw EXIF data |
798 | | * \param[in] ds length of data at d |
799 | | */ |
800 | | static void |
801 | | interpret_maker_note(ExifData *data, const unsigned char *d, unsigned int ds) |
802 | 15.5k | { |
803 | 15.5k | int mnoteid; |
804 | 15.5k | ExifEntry* e = exif_data_get_entry (data, EXIF_TAG_MAKER_NOTE); |
805 | 15.5k | if (!e) |
806 | 1.53k | return; |
807 | | |
808 | 14.0k | if ((mnoteid = exif_mnote_data_olympus_identify (data, e)) != 0) { |
809 | 7.19k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, |
810 | 7.19k | "ExifData", "Olympus MakerNote variant type %d", mnoteid); |
811 | 7.19k | data->priv->md = exif_mnote_data_olympus_new (data->priv->mem); |
812 | | |
813 | 7.19k | } else if ((mnoteid = exif_mnote_data_canon_identify (data, e)) != 0) { |
814 | 2.17k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, |
815 | 2.17k | "ExifData", "Canon MakerNote variant type %d", mnoteid); |
816 | 2.17k | data->priv->md = exif_mnote_data_canon_new (data->priv->mem, data->priv->options); |
817 | | |
818 | 4.68k | } else if ((mnoteid = exif_mnote_data_fuji_identify (data, e)) != 0) { |
819 | 1.89k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, |
820 | 1.89k | "ExifData", "Fuji MakerNote variant type %d", mnoteid); |
821 | 1.89k | data->priv->md = exif_mnote_data_fuji_new (data->priv->mem); |
822 | | |
823 | | /* NOTE: Must do Pentax detection last because some of the |
824 | | * heuristics are pretty general. */ |
825 | 2.79k | } else if ((mnoteid = exif_mnote_data_pentax_identify (data, e)) != 0) { |
826 | 2.40k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, |
827 | 2.40k | "ExifData", "Pentax MakerNote variant type %d", mnoteid); |
828 | 2.40k | data->priv->md = exif_mnote_data_pentax_new (data->priv->mem); |
829 | 2.40k | } |
830 | | /* Marcus: disabled until apple makernote can also be saved |
831 | | else if ((mnoteid = exif_mnote_data_apple_identify (data, e)) != 0) { |
832 | | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, |
833 | | "ExifData", "Apple MakerNote variant type %d", mnoteid); |
834 | | data->priv->md = exif_mnote_data_apple_new (data->priv->mem); |
835 | | } |
836 | | */ |
837 | | |
838 | | /* |
839 | | * If we are able to interpret the maker note, do so. |
840 | | */ |
841 | 14.0k | if (data->priv->md) { |
842 | 13.6k | exif_mnote_data_log (data->priv->md, data->priv->log); |
843 | 13.6k | exif_mnote_data_set_byte_order (data->priv->md, |
844 | 13.6k | data->priv->order); |
845 | 13.6k | exif_mnote_data_set_offset (data->priv->md, |
846 | 13.6k | data->priv->offset_mnote); |
847 | 13.6k | exif_mnote_data_load (data->priv->md, d, ds); |
848 | 13.6k | } |
849 | 14.0k | } |
850 | | |
851 | 62 | #define LOG_TOO_SMALL \ |
852 | 62 | exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", \ |
853 | 62 | _("Size of data too small to allow for EXIF data.")) |
854 | | |
855 | | void |
856 | | exif_data_load_data (ExifData *data, const unsigned char *d_orig, |
857 | | unsigned int ds) |
858 | 20.3k | { |
859 | 20.3k | unsigned int l; |
860 | 20.3k | ExifLong offset; |
861 | 20.3k | ExifShort n; |
862 | 20.3k | const unsigned char *d = d_orig; |
863 | 20.3k | unsigned int len, fullds; |
864 | | |
865 | 20.3k | if (!data || !data->priv || !d || !ds) |
866 | 0 | return; |
867 | | |
868 | 20.3k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
869 | 20.3k | "Parsing %i byte(s) EXIF data...\n", ds); |
870 | | |
871 | | /* |
872 | | * It can be that the data starts with the EXIF header. If it does |
873 | | * not, search the EXIF marker. |
874 | | */ |
875 | 20.3k | if (ds < 6) { |
876 | 13 | LOG_TOO_SMALL; |
877 | 13 | return; |
878 | 13 | } |
879 | 20.2k | if (!memcmp (d, ExifHeader, 6)) { |
880 | 19.8k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
881 | 19.8k | "Found EXIF header at start."); |
882 | 19.8k | } else { |
883 | 2.36k | while (ds >= 3) { |
884 | 2.88k | while (ds && (d[0] == 0xff)) { |
885 | 555 | d++; |
886 | 555 | ds--; |
887 | 555 | } |
888 | | |
889 | | /* JPEG_MARKER_SOI */ |
890 | 2.32k | if (ds && d[0] == JPEG_MARKER_SOI) { |
891 | 892 | d++; |
892 | 892 | ds--; |
893 | 892 | continue; |
894 | 892 | } |
895 | | |
896 | | /* JPEG_MARKER_APP1 */ |
897 | 1.43k | if (ds && d[0] == JPEG_MARKER_APP1) { |
898 | | /* |
899 | | * Verify the exif header |
900 | | * (offset 3, length 6). |
901 | | * FF E1 NN NN EXIFHEADER |
902 | | * ^^ d points here currently |
903 | | */ |
904 | 735 | if ((ds >= 9) && !memcmp (d+3, ExifHeader, 6)) |
905 | 140 | break; |
906 | | /* fallthrough */ |
907 | 735 | } |
908 | | /* Skip irrelevant APP markers. The branch for APP1 must come before this, |
909 | | otherwise this code block will cause APP1 to be skipped. This code path |
910 | | is only relevant for files that are nonconformant to the EXIF |
911 | | specification. For conformant files, the APP1 code path above will be |
912 | | taken. */ |
913 | 1.29k | if (ds >= 3 && d[0] >= 0xe0 && d[0] <= 0xef) { /* JPEG_MARKER_APPn */ |
914 | 1.12k | d++; |
915 | 1.12k | ds--; |
916 | 1.12k | l = (((unsigned int)d[0]) << 8) | d[1]; |
917 | 1.12k | if (l > ds) |
918 | 77 | return; |
919 | 1.04k | d += l; |
920 | 1.04k | ds -= l; |
921 | 1.04k | continue; |
922 | 1.12k | } |
923 | | |
924 | | /* Unknown marker or data. Give up. */ |
925 | 172 | exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, |
926 | 172 | "ExifData", _("EXIF marker not found.")); |
927 | 172 | return; |
928 | 1.29k | } |
929 | 178 | if (ds < 3) { |
930 | 38 | LOG_TOO_SMALL; |
931 | 38 | return; |
932 | 38 | } |
933 | 140 | d++; |
934 | 140 | ds--; |
935 | 140 | len = (((unsigned int)d[0]) << 8) | d[1]; |
936 | 140 | if (len > ds) { |
937 | 72 | exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, |
938 | 72 | "ExifData", _("Read length %d is longer than data length %d."), len, ds); |
939 | 72 | return; |
940 | 72 | } |
941 | 68 | if (len < 2) { |
942 | 7 | exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, |
943 | 7 | "ExifData", _("APP Tag too short.")); |
944 | 7 | return; |
945 | 7 | } |
946 | 61 | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
947 | 61 | "We have to deal with %i byte(s) of EXIF data.", |
948 | 61 | len); |
949 | 61 | d += 2; |
950 | 61 | ds = len - 2; /* we do not want the full rest size, but only the size of the tag */ |
951 | 61 | } |
952 | | |
953 | | /* |
954 | | * Verify the exif header |
955 | | * (offset 2, length 6). |
956 | | */ |
957 | 19.9k | if (ds < 6) { |
958 | 11 | LOG_TOO_SMALL; |
959 | 11 | return; |
960 | 11 | } |
961 | 19.9k | if (memcmp (d, ExifHeader, 6)) { |
962 | 0 | exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, |
963 | 0 | "ExifData", _("EXIF header not found.")); |
964 | 0 | return; |
965 | 0 | } |
966 | | |
967 | 19.9k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
968 | 19.9k | "Found EXIF header."); |
969 | | |
970 | | /* Sanity check the data length */ |
971 | 19.9k | if (ds < 14) |
972 | 49 | return; |
973 | | |
974 | | /* The JPEG APP1 section can be no longer than 64 KiB (including a |
975 | | 16-bit length), so cap the data length to protect against overflow |
976 | | in future offset calculations */ |
977 | 19.8k | fullds = ds; |
978 | 19.8k | if (ds > 0xfffe) |
979 | 496 | ds = 0xfffe; |
980 | | |
981 | | /* Byte order (offset 6, length 2) */ |
982 | 19.8k | if (!memcmp (d + 6, "II", 2)) |
983 | 16.6k | data->priv->order = EXIF_BYTE_ORDER_INTEL; |
984 | 3.21k | else if (!memcmp (d + 6, "MM", 2)) |
985 | 3.08k | data->priv->order = EXIF_BYTE_ORDER_MOTOROLA; |
986 | 127 | else { |
987 | 127 | exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, |
988 | 127 | "ExifData", _("Unknown encoding.")); |
989 | 127 | return; |
990 | 127 | } |
991 | | |
992 | | /* Fixed value */ |
993 | 19.7k | if (exif_get_short (d + 8, data->priv->order) != 0x002a) |
994 | 42 | return; |
995 | | |
996 | | /* IFD 0 offset */ |
997 | 19.7k | offset = exif_get_long (d + 10, data->priv->order); |
998 | 19.7k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
999 | 19.7k | "IFD 0 at %i.", (int) offset); |
1000 | | |
1001 | | /* ds is restricted to 16 bit above, so offset is restricted too, and offset+8 should not overflow. */ |
1002 | 19.7k | if (offset > ds || offset + 6 + 2 > ds) |
1003 | 127 | return; |
1004 | | |
1005 | | /* Parse the actual exif data (usually offset 14 from start) */ |
1006 | 19.5k | exif_data_load_data_content (data, EXIF_IFD_0, d + 6, ds - 6, offset, 0); |
1007 | | |
1008 | | /* IFD 1 offset */ |
1009 | 19.5k | n = exif_get_short (d + 6 + offset, data->priv->order); |
1010 | | /* offset < 2<<16, n is 16 bit at most, so this op will not overflow */ |
1011 | 19.5k | if (offset + 6 + 2 + 12 * n + 4 > ds) |
1012 | 3.98k | return; |
1013 | | |
1014 | 15.5k | offset = exif_get_long (d + 6 + offset + 2 + 12 * n, data->priv->order); |
1015 | 15.5k | if (offset) { |
1016 | 15.2k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
1017 | 15.2k | "IFD 1 at %i.", (int) offset); |
1018 | | |
1019 | | /* Sanity check. ds is ensured to be above 6 above, offset is 16bit */ |
1020 | 15.2k | if (offset > ds - 6) { |
1021 | 3.23k | exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, |
1022 | 3.23k | "ExifData", "Bogus offset of IFD1."); |
1023 | 12.0k | } else { |
1024 | 12.0k | exif_data_load_data_content (data, EXIF_IFD_1, d + 6, ds - 6, offset, 0); |
1025 | 12.0k | } |
1026 | 15.2k | } |
1027 | | |
1028 | | /* |
1029 | | * If we got an EXIF_TAG_MAKER_NOTE, try to interpret it. Some |
1030 | | * cameras use pointers in the maker note tag that point to the |
1031 | | * space between IFDs. Here is the only place where we have access |
1032 | | * to that data. |
1033 | | */ |
1034 | 15.5k | interpret_maker_note(data, d, fullds); |
1035 | | |
1036 | | /* Fixup tags if requested */ |
1037 | 15.5k | if (data->priv->options & EXIF_DATA_OPTION_FOLLOW_SPECIFICATION) |
1038 | 15.5k | exif_data_fix (data); |
1039 | 15.5k | } |
1040 | | |
1041 | | void |
1042 | | exif_data_save_data (ExifData *data, unsigned char **d, unsigned int *ds) |
1043 | 10.3k | { |
1044 | 10.3k | if (ds) |
1045 | 10.3k | *ds = 0; /* This means something went wrong */ |
1046 | | |
1047 | 10.3k | if (!data || !d || !ds) |
1048 | 0 | return; |
1049 | | |
1050 | | /* Header */ |
1051 | 10.3k | *ds = 14; |
1052 | 10.3k | *d = exif_data_alloc (data, *ds); |
1053 | 10.3k | if (!*d) { |
1054 | 0 | *ds = 0; |
1055 | 0 | return; |
1056 | 0 | } |
1057 | 10.3k | memcpy (*d, ExifHeader, 6); |
1058 | | |
1059 | | /* Order (offset 6) */ |
1060 | 10.3k | if (data->priv->order == EXIF_BYTE_ORDER_INTEL) { |
1061 | 9.44k | memcpy (*d + 6, "II", 2); |
1062 | 9.44k | } else { |
1063 | 917 | memcpy (*d + 6, "MM", 2); |
1064 | 917 | } |
1065 | | |
1066 | | /* Fixed value (2 bytes, offset 8) */ |
1067 | 10.3k | exif_set_short (*d + 8, data->priv->order, 0x002a); |
1068 | | |
1069 | | /* |
1070 | | * IFD 0 offset (4 bytes, offset 10). |
1071 | | * We will start 8 bytes after the |
1072 | | * EXIF header (2 bytes for order, another 2 for the test, and |
1073 | | * 4 bytes for the IFD 0 offset make 8 bytes together). |
1074 | | */ |
1075 | 10.3k | exif_set_long (*d + 10, data->priv->order, 8); |
1076 | | |
1077 | | /* Now save IFD 0. IFD 1 will be saved automatically. */ |
1078 | 10.3k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
1079 | 10.3k | "Saving IFDs..."); |
1080 | 10.3k | exif_data_save_data_content (data, data->ifd[EXIF_IFD_0], d, ds, |
1081 | 10.3k | *ds - 6); |
1082 | 10.3k | exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", |
1083 | 10.3k | "Saved %i byte(s) EXIF data.", *ds); |
1084 | 10.3k | } |
1085 | | |
1086 | | ExifData * |
1087 | | exif_data_new_from_file (const char *path) |
1088 | 0 | { |
1089 | 0 | ExifData *edata; |
1090 | 0 | ExifLoader *loader; |
1091 | |
|
1092 | 0 | loader = exif_loader_new (); |
1093 | 0 | exif_loader_write_file (loader, path); |
1094 | 0 | edata = exif_loader_get_data (loader); |
1095 | 0 | exif_loader_unref (loader); |
1096 | |
|
1097 | 0 | return (edata); |
1098 | 0 | } |
1099 | | |
1100 | | void |
1101 | | exif_data_ref (ExifData *data) |
1102 | 0 | { |
1103 | 0 | if (!data) |
1104 | 0 | return; |
1105 | | |
1106 | 0 | data->priv->ref_count++; |
1107 | 0 | } |
1108 | | |
1109 | | void |
1110 | | exif_data_unref (ExifData *data) |
1111 | 20.3k | { |
1112 | 20.3k | if (!data) |
1113 | 0 | return; |
1114 | | |
1115 | 20.3k | data->priv->ref_count--; |
1116 | 20.3k | if (!data->priv->ref_count) |
1117 | 20.3k | exif_data_free (data); |
1118 | 20.3k | } |
1119 | | |
1120 | | void |
1121 | | exif_data_free (ExifData *data) |
1122 | 20.3k | { |
1123 | 20.3k | unsigned int i; |
1124 | 20.3k | ExifMem *mem = (data && data->priv) ? data->priv->mem : NULL; |
1125 | | |
1126 | 20.3k | if (!data) |
1127 | 0 | return; |
1128 | | |
1129 | 121k | for (i = 0; i < EXIF_IFD_COUNT; i++) { |
1130 | 101k | if (data->ifd[i]) { |
1131 | 101k | exif_content_unref (data->ifd[i]); |
1132 | 101k | data->ifd[i] = NULL; |
1133 | 101k | } |
1134 | 101k | } |
1135 | | |
1136 | 20.3k | if (data->data) { |
1137 | 658 | exif_mem_free (mem, data->data); |
1138 | 658 | data->data = NULL; |
1139 | 658 | } |
1140 | | |
1141 | 20.3k | if (data->priv) { |
1142 | 20.3k | if (data->priv->log) { |
1143 | 0 | exif_log_unref (data->priv->log); |
1144 | 0 | data->priv->log = NULL; |
1145 | 0 | } |
1146 | 20.3k | if (data->priv->md) { |
1147 | 13.6k | exif_mnote_data_unref (data->priv->md); |
1148 | 13.6k | data->priv->md = NULL; |
1149 | 13.6k | } |
1150 | 20.3k | exif_mem_free (mem, data->priv); |
1151 | 20.3k | exif_mem_free (mem, data); |
1152 | 20.3k | } |
1153 | | |
1154 | 20.3k | exif_mem_unref (mem); |
1155 | 20.3k | } |
1156 | | |
1157 | | void |
1158 | | exif_data_dump (ExifData *data) |
1159 | 0 | { |
1160 | 0 | unsigned int i; |
1161 | |
|
1162 | 0 | if (!data) |
1163 | 0 | return; |
1164 | | |
1165 | 0 | for (i = 0; i < EXIF_IFD_COUNT; i++) { |
1166 | 0 | if (data->ifd[i] && data->ifd[i]->count) { |
1167 | 0 | printf ("Dumping IFD '%s'...\n", |
1168 | 0 | exif_ifd_get_name (i)); |
1169 | 0 | exif_content_dump (data->ifd[i], 0); |
1170 | 0 | } |
1171 | 0 | } |
1172 | |
|
1173 | 0 | if (data->data) { |
1174 | 0 | printf ("%i byte(s) thumbnail data available: ", data->size); |
1175 | 0 | if (data->size >= 4) { |
1176 | 0 | printf ("0x%02x 0x%02x ... 0x%02x 0x%02x\n", |
1177 | 0 | data->data[0], data->data[1], |
1178 | 0 | data->data[data->size - 2], |
1179 | 0 | data->data[data->size - 1]); |
1180 | 0 | } |
1181 | 0 | } |
1182 | 0 | } |
1183 | | |
1184 | | ExifByteOrder |
1185 | | exif_data_get_byte_order (ExifData *data) |
1186 | 323k | { |
1187 | 323k | if (!data) |
1188 | 0 | return (0); |
1189 | | |
1190 | 323k | return (data->priv->order); |
1191 | 323k | } |
1192 | | |
1193 | | void |
1194 | | exif_data_foreach_content (ExifData *data, ExifDataForeachContentFunc func, |
1195 | | void *user_data) |
1196 | 46.2k | { |
1197 | 46.2k | unsigned int i; |
1198 | | |
1199 | 46.2k | if (!data || !func) |
1200 | 0 | return; |
1201 | | |
1202 | 277k | for (i = 0; i < EXIF_IFD_COUNT; i++) |
1203 | 231k | func (data->ifd[i], user_data); |
1204 | 46.2k | } |
1205 | | |
1206 | | typedef struct _ByteOrderChangeData ByteOrderChangeData; |
1207 | | struct _ByteOrderChangeData { |
1208 | | ExifByteOrder old, new; |
1209 | | }; |
1210 | | |
1211 | | static void |
1212 | | entry_set_byte_order (ExifEntry *e, void *data) |
1213 | 0 | { |
1214 | 0 | ByteOrderChangeData *d = data; |
1215 | |
|
1216 | 0 | if (!e) |
1217 | 0 | return; |
1218 | | |
1219 | 0 | exif_array_set_byte_order (e->format, e->data, e->components, d->old, d->new); |
1220 | 0 | } |
1221 | | |
1222 | | static void |
1223 | | content_set_byte_order (ExifContent *content, void *data) |
1224 | 0 | { |
1225 | 0 | exif_content_foreach_entry (content, entry_set_byte_order, data); |
1226 | 0 | } |
1227 | | |
1228 | | void |
1229 | | exif_data_set_byte_order (ExifData *data, ExifByteOrder order) |
1230 | 0 | { |
1231 | 0 | ByteOrderChangeData d; |
1232 | |
|
1233 | 0 | if (!data || (order == data->priv->order)) |
1234 | 0 | return; |
1235 | | |
1236 | 0 | d.old = data->priv->order; |
1237 | 0 | d.new = order; |
1238 | 0 | exif_data_foreach_content (data, content_set_byte_order, &d); |
1239 | 0 | data->priv->order = order; |
1240 | 0 | if (data->priv->md) |
1241 | 0 | exif_mnote_data_set_byte_order (data->priv->md, order); |
1242 | 0 | } |
1243 | | |
1244 | | void |
1245 | | exif_data_log (ExifData *data, ExifLog *log) |
1246 | 9.94k | { |
1247 | 9.94k | unsigned int i; |
1248 | | |
1249 | 9.94k | if (!data || !data->priv) |
1250 | 0 | return; |
1251 | 9.94k | exif_log_unref (data->priv->log); |
1252 | 9.94k | data->priv->log = log; |
1253 | 9.94k | exif_log_ref (log); |
1254 | | |
1255 | 59.6k | for (i = 0; i < EXIF_IFD_COUNT; i++) |
1256 | 49.7k | exif_content_log (data->ifd[i], log); |
1257 | 9.94k | } |
1258 | | |
1259 | | /* Used internally within libexif */ |
1260 | | ExifLog *exif_data_get_log (ExifData *); |
1261 | | ExifLog * |
1262 | | exif_data_get_log (ExifData *data) |
1263 | 126k | { |
1264 | 126k | if (!data || !data->priv) |
1265 | 0 | return NULL; |
1266 | 126k | return data->priv->log; |
1267 | 126k | } |
1268 | | |
1269 | | static const struct { |
1270 | | ExifDataOption option; |
1271 | | const char *name; |
1272 | | const char *description; |
1273 | | } exif_data_option[] = { |
1274 | | {EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS, N_("Ignore unknown tags"), |
1275 | | N_("Ignore unknown tags when loading EXIF data.")}, |
1276 | | {EXIF_DATA_OPTION_FOLLOW_SPECIFICATION, N_("Follow specification"), |
1277 | | N_("Add, correct and remove entries to get EXIF data that follows " |
1278 | | "the specification.")}, |
1279 | | {EXIF_DATA_OPTION_DONT_CHANGE_MAKER_NOTE, N_("Do not change maker note"), |
1280 | | N_("When loading and resaving Exif data, save the maker note unmodified." |
1281 | | " Be aware that the maker note can get corrupted.")}, |
1282 | | {0, NULL, NULL} |
1283 | | }; |
1284 | | |
1285 | | const char * |
1286 | | exif_data_option_get_name (ExifDataOption o) |
1287 | 0 | { |
1288 | 0 | unsigned int i; |
1289 | |
|
1290 | 0 | for (i = 0; exif_data_option[i].name; i++) |
1291 | 0 | if (exif_data_option[i].option == o) |
1292 | 0 | break; |
1293 | 0 | return _(exif_data_option[i].name); |
1294 | 0 | } |
1295 | | |
1296 | | const char * |
1297 | | exif_data_option_get_description (ExifDataOption o) |
1298 | 0 | { |
1299 | 0 | unsigned int i; |
1300 | |
|
1301 | 0 | for (i = 0; exif_data_option[i].description; i++) |
1302 | 0 | if (exif_data_option[i].option == o) |
1303 | 0 | break; |
1304 | 0 | return _(exif_data_option[i].description); |
1305 | 0 | } |
1306 | | |
1307 | | void |
1308 | | exif_data_set_option (ExifData *d, ExifDataOption o) |
1309 | 40.6k | { |
1310 | 40.6k | if (!d) |
1311 | 0 | return; |
1312 | | |
1313 | 40.6k | d->priv->options |= o; |
1314 | 40.6k | } |
1315 | | |
1316 | | void |
1317 | | exif_data_unset_option (ExifData *d, ExifDataOption o) |
1318 | 0 | { |
1319 | 0 | if (!d) |
1320 | 0 | return; |
1321 | | |
1322 | 0 | d->priv->options &= ~o; |
1323 | 0 | } |
1324 | | |
1325 | | static void |
1326 | | fix_func (ExifContent *c, void *UNUSED(data)) |
1327 | 129k | { |
1328 | 129k | switch (exif_content_get_ifd (c)) { |
1329 | 25.9k | case EXIF_IFD_1: |
1330 | 25.9k | if (c->parent->data) |
1331 | 1.01k | exif_content_fix (c); |
1332 | 24.9k | else if (c->count) { |
1333 | 2.07k | exif_log (c->parent->priv->log, EXIF_LOG_CODE_DEBUG, "exif-data", |
1334 | 2.07k | "No thumbnail but entries on thumbnail. These entries have been " |
1335 | 2.07k | "removed."); |
1336 | 6.82k | while (c->count) { |
1337 | 4.75k | unsigned int cnt = c->count; |
1338 | 4.75k | exif_content_remove_entry (c, c->entries[c->count - 1]); |
1339 | 4.75k | if (cnt == c->count) { |
1340 | | /* safety net */ |
1341 | 0 | exif_log (c->parent->priv->log, EXIF_LOG_CODE_DEBUG, "exif-data", |
1342 | 0 | "failed to remove last entry from entries."); |
1343 | 0 | c->count--; |
1344 | 0 | } |
1345 | 4.75k | } |
1346 | 2.07k | } |
1347 | 25.9k | break; |
1348 | 103k | default: |
1349 | 103k | exif_content_fix (c); |
1350 | 129k | } |
1351 | 129k | } |
1352 | | |
1353 | | void |
1354 | | exif_data_fix (ExifData *d) |
1355 | 25.9k | { |
1356 | 25.9k | exif_data_foreach_content (d, fix_func, NULL); |
1357 | 25.9k | } |
1358 | | |
1359 | | void |
1360 | | exif_data_set_data_type (ExifData *d, ExifDataType dt) |
1361 | 20.3k | { |
1362 | 20.3k | if (!d || !d->priv) |
1363 | 0 | return; |
1364 | | |
1365 | 20.3k | d->priv->data_type = dt; |
1366 | 20.3k | } |
1367 | | |
1368 | | ExifDataType |
1369 | | exif_data_get_data_type (ExifData *d) |
1370 | 214k | { |
1371 | 214k | return (d && d->priv) ? d->priv->data_type : EXIF_DATA_TYPE_UNKNOWN; |
1372 | 214k | } |