1 /* exif-mnote-data-olympus.c
3 * Copyright (c) 2002, 2003 Lutz Mueller <lutz@users.sourceforge.net>
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.
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.
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.
22 #include "exif-mnote-data-olympus.h"
28 #include <libexif/exif-utils.h>
29 #include <libexif/exif-data.h>
33 /* Uncomment this to fix a problem with Sanyo MakerNotes. It's probably best
34 * not to in most cases because it seems to only affect the thumbnail tag
35 * which is duplicated in IFD 1, and fixing the offset could actually cause
36 * problems with other software that expects the broken form.
38 /*#define EXIF_OVERCOME_SANYO_OFFSET_BUG */
40 #define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
42 static enum OlympusVersion
43 exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
44 unsigned int buf_size);
48 exif_mnote_data_olympus_clear (ExifMnoteDataOlympus *n)
50 ExifMnoteData *d = (ExifMnoteData *) n;
56 for (i = 0; i < n->count; i++)
57 if (n->entries[i].data) {
58 exif_mem_free (d->mem, n->entries[i].data);
59 n->entries[i].data = NULL;
61 exif_mem_free (d->mem, n->entries);
68 exif_mnote_data_olympus_free (ExifMnoteData *n)
72 exif_mnote_data_olympus_clear ((ExifMnoteDataOlympus *) n);
76 exif_mnote_data_olympus_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen)
78 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
80 if (!d || !val) return NULL;
81 if (i > n->count -1) return NULL;
83 exif_log (d->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
84 "Querying value for tag '%s'...",
85 mnote_olympus_tag_get_name (n->entries[i].tag));
87 return mnote_olympus_entry_get_value (&n->entries[i], val, maxlen);
94 * @brief save the MnoteData from ne to buf
96 * @param ne extract the data from this structure
97 * @param *buf write the mnoteData to this buffer (buffer will be allocated)
98 * @param buf_size the size of the buffer
101 exif_mnote_data_olympus_save (ExifMnoteData *ne,
102 unsigned char **buf, unsigned int *buf_size)
104 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) ne;
105 size_t i, o, s, doff, base = 0, o2 = 6 + 2;
110 if (!n || !buf || !buf_size) return;
113 * Allocate enough memory for all entries and the number of entries.
115 *buf_size = 6 + 2 + 2 + n->count * 12;
116 switch (n->version) {
120 *buf = exif_mem_alloc (ne->mem, *buf_size);
122 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
126 /* Write the header and the number of entries. */
127 strcpy ((char *)*buf, n->version==sanyoV1?"SANYO":
128 (n->version==epsonV1?"EPSON":"OLYMP"));
129 exif_set_short (*buf + 6, n->order, (ExifShort) 1);
134 *buf_size += 8-6 + 4;
135 *buf = exif_mem_alloc (ne->mem, *buf_size);
137 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
141 /* Write the header and the number of entries. */
142 strcpy ((char *)*buf, "OLYMPUS");
143 exif_set_short (*buf + 8, n->order, (ExifShort) (
144 (n->order == EXIF_BYTE_ORDER_INTEL) ?
147 exif_set_short (*buf + 10, n->order, (ExifShort) 3);
152 base = MNOTE_NIKON1_TAG_BASE;
154 /* v1 has offsets based to main IFD, not makernote IFD */
155 datao += n->offset + 10;
156 /* subtract the size here, so the increment in the next case will not harm us */
158 /* Fall through to nikonV2 handler */
160 /* Write out V0 files in V2 format */
163 *buf_size += 4; /* Next IFD pointer */
164 *buf = exif_mem_alloc (ne->mem, *buf_size);
166 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
170 /* Write the header and the number of entries. */
171 strcpy ((char *)*buf, "Nikon");
172 (*buf)[6] = n->version;
174 if (n->version != nikonV1) {
175 exif_set_short (*buf + 10, n->order, (ExifShort) (
176 (n->order == EXIF_BYTE_ORDER_INTEL) ?
179 exif_set_short (*buf + 12, n->order, (ExifShort) 0x2A);
180 exif_set_long (*buf + 14, n->order, (ExifShort) 8);
184 /* Reset next IFD pointer */
185 exif_set_long (*buf + o2 + 2 + n->count * 12, n->order, 0);
192 exif_set_short (*buf + o2, n->order, (ExifShort) n->count);
195 /* Save each entry */
196 for (i = 0; i < n->count; i++) {
198 exif_set_short (*buf + o + 0, n->order,
199 (ExifShort) (n->entries[i].tag - base));
200 exif_set_short (*buf + o + 2, n->order,
201 (ExifShort) n->entries[i].format);
202 exif_set_long (*buf + o + 4, n->order,
203 n->entries[i].components);
205 s = exif_format_get_size (n->entries[i].format) *
206 n->entries[i].components;
208 /* Corrupt data: EXIF data size is limited to the
209 * maximum size of a JPEG segment (64 kb).
216 t = exif_mem_realloc (ne->mem, *buf,
219 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", ts);
224 exif_set_long (*buf + o, n->order, datao + doff);
228 /* Write the data. */
229 if (n->entries[i].data) {
230 memcpy (*buf + doff, n->entries[i].data, s);
232 /* Most certainly damaged input file */
233 memset (*buf + doff, 0, s);
239 exif_mnote_data_olympus_load (ExifMnoteData *en,
240 const unsigned char *buf, unsigned int buf_size)
242 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en;
244 size_t i, tcount, o, o2, datao = 6, base = 0;
246 if (!n || !buf || !buf_size) {
247 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
248 "ExifMnoteDataOlympus", "Short MakerNote");
251 o2 = 6 + n->offset; /* Start of interesting data */
252 if (CHECKOVERFLOW(o2,buf_size,10)) {
253 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
254 "ExifMnoteDataOlympus", "Short MakerNote");
259 * Olympus headers start with "OLYMP" and need to have at least
260 * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the
261 * number of entries, and 12 for one entry.
263 * Sanyo format is identical and uses identical tags except that
264 * header starts with "SANYO".
266 * Epson format is identical and uses identical tags except that
267 * header starts with "EPSON".
269 * Nikon headers start with "Nikon" (6 bytes including '\0'),
270 * version number (1 or 2).
272 * Version 1 continues with 0, 1, 0, number_of_tags,
273 * or just with number_of_tags (models D1H, D1X...).
275 * Version 2 continues with an unknown byte (0 or 10),
276 * two unknown bytes (0), "MM" or "II", another byte 0 and
279 n->version = exif_mnote_data_olympus_identify_variant(buf+o2, buf_size-o2);
280 switch (n->version) {
284 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
285 "Parsing Olympus/Sanyo/Epson maker note v1...");
287 /* The number of entries is at position 8. */
288 if (buf[o2 + 6] == 1)
289 n->order = EXIF_BYTE_ORDER_INTEL;
290 else if (buf[o2 + 6 + 1] == 1)
291 n->order = EXIF_BYTE_ORDER_MOTOROLA;
293 if (o2 + 2 > buf_size) return;
294 c = exif_get_short (buf + o2, n->order);
295 if ((!(c & 0xFF)) && (c > 0x500)) {
296 if (n->order == EXIF_BYTE_ORDER_INTEL) {
297 n->order = EXIF_BYTE_ORDER_MOTOROLA;
299 n->order = EXIF_BYTE_ORDER_INTEL;
305 /* Olympus S760, S770 */
308 if (CHECKOVERFLOW(o2,buf_size,4)) return;
309 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
310 "Parsing Olympus maker note v2 (0x%02x, %02x, %02x, %02x)...",
311 buf[o2], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]);
313 if ((buf[o2] == 'I') && (buf[o2 + 1] == 'I'))
314 n->order = EXIF_BYTE_ORDER_INTEL;
315 else if ((buf[o2] == 'M') && (buf[o2 + 1] == 'M'))
316 n->order = EXIF_BYTE_ORDER_MOTOROLA;
318 /* The number of entries is at position 8+4. */
324 if (o2 >= buf_size) return;
325 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
326 "Parsing Nikon maker note v1 (0x%02x, %02x, %02x, "
327 "%02x, %02x, %02x, %02x, %02x)...",
328 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
329 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
331 /* Skip version number */
334 /* Skip an unknown byte (00 or 0A). */
337 base = MNOTE_NIKON1_TAG_BASE;
338 /* Fix endianness, if needed */
339 if (o2 + 2 > buf_size) return;
340 c = exif_get_short (buf + o2, n->order);
341 if ((!(c & 0xFF)) && (c > 0x500)) {
342 if (n->order == EXIF_BYTE_ORDER_INTEL) {
343 n->order = EXIF_BYTE_ORDER_MOTOROLA;
345 n->order = EXIF_BYTE_ORDER_INTEL;
352 if (CHECKOVERFLOW(o2,buf_size,12)) return;
353 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
354 "Parsing Nikon maker note v2 (0x%02x, %02x, %02x, "
355 "%02x, %02x, %02x, %02x, %02x)...",
356 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
357 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
359 /* Skip version number */
362 /* Skip an unknown byte (00 or 0A). */
365 /* Skip 2 unknown bytes (00 00). */
369 * Byte order. From here the data offset
373 if (o2 >= buf_size) return;
374 if (!strncmp ((char *)&buf[o2], "II", 2))
375 n->order = EXIF_BYTE_ORDER_INTEL;
376 else if (!strncmp ((char *)&buf[o2], "MM", 2))
377 n->order = EXIF_BYTE_ORDER_MOTOROLA;
379 exif_log (en->log, EXIF_LOG_CODE_DEBUG,
380 "ExifMnoteDataOlympus", "Unknown "
381 "byte order '%c%c'", buf[o2],
387 /* Skip 2 unknown bytes (00 2A). */
390 /* Go to where the number of entries is. */
391 if (o2 + 4 > buf_size) return;
392 o2 = datao + exif_get_long (buf + o2, n->order);
396 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
397 "Parsing Nikon maker note v0 (0x%02x, %02x, %02x, "
398 "%02x, %02x, %02x, %02x, %02x)...",
399 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
400 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
401 /* 00 1b is # of entries in Motorola order - the rest should also be in MM order */
402 n->order = EXIF_BYTE_ORDER_MOTOROLA;
406 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
407 "Unknown Olympus variant %i.", n->version);
411 /* Sanity check the offset */
412 if (CHECKOVERFLOW(o2,buf_size,2)) {
413 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
414 "ExifMnoteOlympus", "Short MakerNote");
418 /* Read the number of tags */
419 c = exif_get_short (buf + o2, n->order);
422 /* Remove any old entries */
423 exif_mnote_data_olympus_clear (n);
425 /* Reserve enough space for all the possible MakerNote tags */
426 n->entries = exif_mem_alloc (en->mem, sizeof (MnoteOlympusEntry) * c);
428 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", sizeof (MnoteOlympusEntry) * c);
432 /* Parse all c entries, storing ones that are successfully parsed */
434 for (i = c, o = o2; i; --i, o += 12) {
436 if (CHECKOVERFLOW(o, buf_size, 12)) {
437 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
438 "ExifMnoteOlympus", "Short MakerNote");
442 n->entries[tcount].tag = exif_get_short (buf + o, n->order) + base;
443 n->entries[tcount].format = exif_get_short (buf + o + 2, n->order);
444 n->entries[tcount].components = exif_get_long (buf + o + 4, n->order);
445 n->entries[tcount].order = n->order;
447 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
448 "Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
449 mnote_olympus_tag_get_name (n->entries[tcount].tag));
450 /* exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
452 n->entries[tcount].tag,
453 n->entries[tcount].format,
454 n->entries[tcount].components,
455 (int)exif_format_get_size(n->entries[tcount].format)); */
457 /* Check if we overflow the multiplication. Use buf_size as the max size for integer overflow detection,
458 * we will check the buffer sizes closer later. */
459 if (exif_format_get_size (n->entries[tcount].format) &&
460 buf_size / exif_format_get_size (n->entries[tcount].format) < n->entries[tcount].components
462 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifMnoteOlympus", "Tag size overflow detected (%u * %lu)", exif_format_get_size (n->entries[tcount].format), n->entries[tcount].components);
466 * Size? If bigger than 4 bytes, the actual data is not
467 * in the entry but somewhere else (offset).
469 s = exif_format_get_size (n->entries[tcount].format) *
470 n->entries[tcount].components;
471 n->entries[tcount].size = s;
473 size_t dataofs = o + 8;
475 /* The data in this case is merely a pointer */
476 dataofs = exif_get_long (buf + dataofs, n->order) + datao;
477 #ifdef EXIF_OVERCOME_SANYO_OFFSET_BUG
478 /* Some Sanyo models (e.g. VPC-C5, C40) suffer from a bug when
479 * writing the offset for the MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE
480 * tag in its MakerNote. The offset is actually the absolute
481 * position in the file instead of the position within the IFD.
483 if (dataofs > (buf_size - s) && n->version == sanyoV1) {
485 dataofs -= datao + 6;
486 exif_log (en->log, EXIF_LOG_CODE_DEBUG,
488 "Inconsistent thumbnail tag offset; attempting to recover");
492 if (CHECKOVERFLOW(dataofs, buf_size, s)) {
493 exif_log (en->log, EXIF_LOG_CODE_DEBUG,
495 "Tag data past end of buffer (%u > %u)",
496 dataofs + s, buf_size);
500 n->entries[tcount].data = exif_mem_alloc (en->mem, s);
501 if (!n->entries[tcount].data) {
502 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", s);
505 memcpy (n->entries[tcount].data, buf + dataofs, s);
508 /* Tag was successfully parsed */
511 /* Store the count of successfully parsed tags */
516 exif_mnote_data_olympus_count (ExifMnoteData *n)
518 return n ? ((ExifMnoteDataOlympus *) n)->count : 0;
522 exif_mnote_data_olympus_get_id (ExifMnoteData *d, unsigned int n)
524 ExifMnoteDataOlympus *note = (ExifMnoteDataOlympus *) d;
527 if (note->count <= n) return 0;
528 return note->entries[n].tag;
532 exif_mnote_data_olympus_get_name (ExifMnoteData *d, unsigned int i)
534 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
537 if (i >= n->count) return NULL;
538 return mnote_olympus_tag_get_name (n->entries[i].tag);
542 exif_mnote_data_olympus_get_title (ExifMnoteData *d, unsigned int i)
544 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
547 if (i >= n->count) return NULL;
548 return mnote_olympus_tag_get_title (n->entries[i].tag);
552 exif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i)
554 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
557 if (i >= n->count) return NULL;
558 return mnote_olympus_tag_get_description (n->entries[i].tag);
562 exif_mnote_data_olympus_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
564 ExifByteOrder o_orig;
565 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
572 for (i = 0; i < n->count; i++) {
573 n->entries[i].order = o;
574 exif_array_set_byte_order (n->entries[i].format, n->entries[i].data,
575 n->entries[i].components, o_orig, o);
580 exif_mnote_data_olympus_set_offset (ExifMnoteData *n, unsigned int o)
582 if (n) ((ExifMnoteDataOlympus *) n)->offset = o;
585 static enum OlympusVersion
586 exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
587 unsigned int buf_size)
589 /* Olympus, Nikon, Sanyo, Epson */
591 /* Match the terminating NUL character, too */
592 if (!memcmp (buf, "OLYMPUS", 8))
594 else if (!memcmp (buf, "OLYMP", 6))
596 else if (!memcmp (buf, "SANYO", 6))
598 else if (!memcmp (buf, "EPSON", 6))
600 else if (!memcmp (buf, "Nikon", 6)) {
602 case 1: return nikonV1;
603 case 2: return nikonV2;
604 default: return 0; /* Unrecognized Nikon variant */
609 /* Another variant of Nikon */
610 if ((buf_size >= 2) && (buf[0] == 0x00) && (buf[1] == 0x1b)) {
618 exif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e)
620 int variant = exif_mnote_data_olympus_identify_variant(e->data, e->size);
622 if (variant == nikonV0) {
623 /* This variant needs some extra checking with the Make */
625 ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE);
626 variant = unrecognized;
629 const char *v = exif_entry_get_value (em, value, sizeof(value));
630 if (v && (!strncmp (v, "Nikon", sizeof(value)) ||
631 !strncmp (v, "NIKON", sizeof(value)) ))
632 /* When saved, this variant will be written out like the
633 * alternative nikonV2 form above instead
644 exif_mnote_data_olympus_new (ExifMem *mem)
648 if (!mem) return NULL;
650 d = exif_mem_alloc (mem, sizeof (ExifMnoteDataOlympus));
653 exif_mnote_data_construct (d, mem);
655 /* Set up function pointers */
656 d->methods.free = exif_mnote_data_olympus_free;
657 d->methods.set_byte_order = exif_mnote_data_olympus_set_byte_order;
658 d->methods.set_offset = exif_mnote_data_olympus_set_offset;
659 d->methods.load = exif_mnote_data_olympus_load;
660 d->methods.save = exif_mnote_data_olympus_save;
661 d->methods.count = exif_mnote_data_olympus_count;
662 d->methods.get_id = exif_mnote_data_olympus_get_id;
663 d->methods.get_name = exif_mnote_data_olympus_get_name;
664 d->methods.get_title = exif_mnote_data_olympus_get_title;
665 d->methods.get_description = exif_mnote_data_olympus_get_description;
666 d->methods.get_value = exif_mnote_data_olympus_get_value;