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>
31 /* Uncomment this to fix a problem with Sanyo MakerNotes. It's probably best
32 * not to in most cases because it seems to only affect the thumbnail tag
33 * which is duplicated in IFD 1, and fixing the offset could actually cause
34 * problems with other software that expects the broken form.
36 /*#define EXIF_OVERCOME_SANYO_OFFSET_BUG */
38 #define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
40 static enum OlympusVersion
41 exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
42 unsigned int buf_size);
46 exif_mnote_data_olympus_clear (ExifMnoteDataOlympus *n)
48 ExifMnoteData *d = (ExifMnoteData *) n;
54 for (i = 0; i < n->count; i++)
55 if (n->entries[i].data) {
56 exif_mem_free (d->mem, n->entries[i].data);
57 n->entries[i].data = NULL;
59 exif_mem_free (d->mem, n->entries);
66 exif_mnote_data_olympus_free (ExifMnoteData *n)
70 exif_mnote_data_olympus_clear ((ExifMnoteDataOlympus *) n);
74 exif_mnote_data_olympus_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen)
76 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
78 if (!d || !val) return NULL;
79 if (i > n->count -1) return NULL;
81 exif_log (d->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
82 "Querying value for tag '%s'...",
83 mnote_olympus_tag_get_name (n->entries[i].tag));
85 return mnote_olympus_entry_get_value (&n->entries[i], val, maxlen);
92 * @brief save the MnoteData from ne to buf
94 * @param ne extract the data from this structure
95 * @param *buf write the mnoteData to this buffer (buffer will be allocated)
96 * @param buf_size the size of the buffer
99 exif_mnote_data_olympus_save (ExifMnoteData *ne,
100 unsigned char **buf, unsigned int *buf_size)
102 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) ne;
103 size_t i, o, s, doff, base = 0, o2 = 6 + 2;
108 if (!n || !buf || !buf_size) return;
111 * Allocate enough memory for all entries and the number of entries.
113 *buf_size = 6 + 2 + 2 + n->count * 12;
114 switch (n->version) {
118 *buf = exif_mem_alloc (ne->mem, *buf_size);
120 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
124 /* Write the header and the number of entries. */
125 strcpy ((char *)*buf, n->version==sanyoV1?"SANYO":
126 (n->version==epsonV1?"EPSON":"OLYMP"));
127 exif_set_short (*buf + 6, n->order, (ExifShort) 1);
132 *buf_size += 8-6 + 4;
133 *buf = exif_mem_alloc (ne->mem, *buf_size);
135 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
139 /* Write the header and the number of entries. */
140 strcpy ((char *)*buf, "OLYMPUS");
141 exif_set_short (*buf + 8, n->order, (ExifShort) (
142 (n->order == EXIF_BYTE_ORDER_INTEL) ?
145 exif_set_short (*buf + 10, n->order, (ExifShort) 3);
150 base = MNOTE_NIKON1_TAG_BASE;
152 /* v1 has offsets based to main IFD, not makernote IFD */
153 datao += n->offset + 10;
154 /* subtract the size here, so the increment in the next case will not harm us */
156 /* Fall through to nikonV2 handler */
158 /* Write out V0 files in V2 format */
161 *buf_size += 4; /* Next IFD pointer */
162 *buf = exif_mem_alloc (ne->mem, *buf_size);
164 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
168 /* Write the header and the number of entries. */
169 strcpy ((char *)*buf, "Nikon");
170 (*buf)[6] = n->version;
172 if (n->version != nikonV1) {
173 exif_set_short (*buf + 10, n->order, (ExifShort) (
174 (n->order == EXIF_BYTE_ORDER_INTEL) ?
177 exif_set_short (*buf + 12, n->order, (ExifShort) 0x2A);
178 exif_set_long (*buf + 14, n->order, (ExifShort) 8);
182 /* Reset next IFD pointer */
183 exif_set_long (*buf + o2 + 2 + n->count * 12, n->order, 0);
190 exif_set_short (*buf + o2, n->order, (ExifShort) n->count);
193 /* Save each entry */
194 for (i = 0; i < n->count; i++) {
196 exif_set_short (*buf + o + 0, n->order,
197 (ExifShort) (n->entries[i].tag - base));
198 exif_set_short (*buf + o + 2, n->order,
199 (ExifShort) n->entries[i].format);
200 exif_set_long (*buf + o + 4, n->order,
201 n->entries[i].components);
203 s = exif_format_get_size (n->entries[i].format) *
204 n->entries[i].components;
206 /* Corrupt data: EXIF data size is limited to the
207 * maximum size of a JPEG segment (64 kb).
214 t = exif_mem_realloc (ne->mem, *buf,
217 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", ts);
222 exif_set_long (*buf + o, n->order, datao + doff);
226 /* Write the data. */
227 if (n->entries[i].data) {
228 memcpy (*buf + doff, n->entries[i].data, s);
230 /* Most certainly damaged input file */
231 memset (*buf + doff, 0, s);
237 exif_mnote_data_olympus_load (ExifMnoteData *en,
238 const unsigned char *buf, unsigned int buf_size)
240 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en;
242 size_t i, tcount, o, o2, datao = 6, base = 0;
244 if (!n || !buf || !buf_size) {
245 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
246 "ExifMnoteDataOlympus", "Short MakerNote");
249 o2 = 6 + n->offset; /* Start of interesting data */
250 if (CHECKOVERFLOW(o2,buf_size,10)) {
251 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
252 "ExifMnoteDataOlympus", "Short MakerNote");
257 * Olympus headers start with "OLYMP" and need to have at least
258 * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the
259 * number of entries, and 12 for one entry.
261 * Sanyo format is identical and uses identical tags except that
262 * header starts with "SANYO".
264 * Epson format is identical and uses identical tags except that
265 * header starts with "EPSON".
267 * Nikon headers start with "Nikon" (6 bytes including '\0'),
268 * version number (1 or 2).
270 * Version 1 continues with 0, 1, 0, number_of_tags,
271 * or just with number_of_tags (models D1H, D1X...).
273 * Version 2 continues with an unknown byte (0 or 10),
274 * two unknown bytes (0), "MM" or "II", another byte 0 and
277 n->version = exif_mnote_data_olympus_identify_variant(buf+o2, buf_size-o2);
278 switch (n->version) {
282 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
283 "Parsing Olympus/Sanyo/Epson maker note v1...");
285 /* The number of entries is at position 8. */
286 if (buf[o2 + 6] == 1)
287 n->order = EXIF_BYTE_ORDER_INTEL;
288 else if (buf[o2 + 6 + 1] == 1)
289 n->order = EXIF_BYTE_ORDER_MOTOROLA;
291 c = exif_get_short (buf + o2, n->order);
292 if ((!(c & 0xFF)) && (c > 0x500)) {
293 if (n->order == EXIF_BYTE_ORDER_INTEL) {
294 n->order = EXIF_BYTE_ORDER_MOTOROLA;
296 n->order = EXIF_BYTE_ORDER_INTEL;
302 /* Olympus S760, S770 */
305 if (CHECKOVERFLOW(o2,buf_size,4)) return;
306 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
307 "Parsing Olympus maker note v2 (0x%02x, %02x, %02x, %02x)...",
308 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]);
310 if ((buf[o2] == 'I') && (buf[o2 + 1] == 'I'))
311 n->order = EXIF_BYTE_ORDER_INTEL;
312 else if ((buf[o2] == 'M') && (buf[o2 + 1] == 'M'))
313 n->order = EXIF_BYTE_ORDER_MOTOROLA;
315 /* The number of entries is at position 8+4. */
321 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
322 "Parsing Nikon maker note v1 (0x%02x, %02x, %02x, "
324 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]);
326 /* Skip version number */
329 /* Skip an unknown byte (00 or 0A). */
332 base = MNOTE_NIKON1_TAG_BASE;
333 /* Fix endianness, if needed */
334 c = exif_get_short (buf + o2, n->order);
335 if ((!(c & 0xFF)) && (c > 0x500)) {
336 if (n->order == EXIF_BYTE_ORDER_INTEL) {
337 n->order = EXIF_BYTE_ORDER_MOTOROLA;
339 n->order = EXIF_BYTE_ORDER_INTEL;
346 if (CHECKOVERFLOW(o2,buf_size,12)) return;
347 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
348 "Parsing Nikon maker note v2 (0x%02x, %02x, %02x, "
349 "%02x, %02x, %02x, %02x, %02x)...",
350 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
351 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
353 /* Skip version number */
356 /* Skip an unknown byte (00 or 0A). */
359 /* Skip 2 unknown bytes (00 00). */
363 * Byte order. From here the data offset
367 if (!strncmp ((char *)&buf[o2], "II", 2))
368 n->order = EXIF_BYTE_ORDER_INTEL;
369 else if (!strncmp ((char *)&buf[o2], "MM", 2))
370 n->order = EXIF_BYTE_ORDER_MOTOROLA;
372 exif_log (en->log, EXIF_LOG_CODE_DEBUG,
373 "ExifMnoteDataOlympus", "Unknown "
374 "byte order '%c%c'", buf[o2],
380 /* Skip 2 unknown bytes (00 2A). */
383 /* Go to where the number of entries is. */
384 o2 = datao + exif_get_long (buf + o2, n->order);
388 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
389 "Parsing Nikon maker note v0 (0x%02x, %02x, %02x, "
390 "%02x, %02x, %02x, %02x, %02x)...",
391 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
392 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
393 /* 00 1b is # of entries in Motorola order - the rest should also be in MM order */
394 n->order = EXIF_BYTE_ORDER_MOTOROLA;
398 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
399 "Unknown Olympus variant %i.", n->version);
403 /* Sanity check the offset */
404 if (CHECKOVERFLOW(o2,buf_size,2)) {
405 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
406 "ExifMnoteOlympus", "Short MakerNote");
410 /* Read the number of tags */
411 c = exif_get_short (buf + o2, n->order);
414 /* Remove any old entries */
415 exif_mnote_data_olympus_clear (n);
417 /* Reserve enough space for all the possible MakerNote tags */
418 n->entries = exif_mem_alloc (en->mem, sizeof (MnoteOlympusEntry) * c);
420 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", sizeof (MnoteOlympusEntry) * c);
424 /* Parse all c entries, storing ones that are successfully parsed */
426 for (i = c, o = o2; i; --i, o += 12) {
428 memset(&n->entries[tcount], 0, sizeof(MnoteOlympusEntry));
429 if (CHECKOVERFLOW(o, buf_size, 12)) {
430 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
431 "ExifMnoteOlympus", "Short MakerNote");
435 n->entries[tcount].tag = exif_get_short (buf + o, n->order) + base;
436 n->entries[tcount].format = exif_get_short (buf + o + 2, n->order);
437 n->entries[tcount].components = exif_get_long (buf + o + 4, n->order);
438 n->entries[tcount].order = n->order;
440 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
441 "Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
442 mnote_olympus_tag_get_name (n->entries[tcount].tag));
443 /* exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
445 n->entries[tcount].tag,
446 n->entries[tcount].format,
447 n->entries[tcount].components,
448 (int)exif_format_get_size(n->entries[tcount].format)); */
450 /* Check if we overflow the multiplication. Use buf_size as the max size for integer overflow detection,
451 * we will check the buffer sizes closer later. */
452 if (exif_format_get_size (n->entries[tcount].format) &&
453 buf_size / exif_format_get_size (n->entries[tcount].format) < n->entries[tcount].components
455 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);
459 * Size? If bigger than 4 bytes, the actual data is not
460 * in the entry but somewhere else (offset).
462 s = exif_format_get_size (n->entries[tcount].format) *
463 n->entries[tcount].components;
464 n->entries[tcount].size = s;
466 size_t dataofs = o + 8;
468 /* The data in this case is merely a pointer */
469 dataofs = exif_get_long (buf + dataofs, n->order) + datao;
470 #ifdef EXIF_OVERCOME_SANYO_OFFSET_BUG
471 /* Some Sanyo models (e.g. VPC-C5, C40) suffer from a bug when
472 * writing the offset for the MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE
473 * tag in its MakerNote. The offset is actually the absolute
474 * position in the file instead of the position within the IFD.
476 if (dataofs > (buf_size - s) && n->version == sanyoV1) {
478 dataofs -= datao + 6;
479 exif_log (en->log, EXIF_LOG_CODE_DEBUG,
481 "Inconsistent thumbnail tag offset; attempting to recover");
485 if (CHECKOVERFLOW(dataofs, buf_size, s)) {
486 exif_log (en->log, EXIF_LOG_CODE_DEBUG,
488 "Tag data past end of buffer (%u > %u)",
489 (unsigned)(dataofs + s), buf_size);
493 n->entries[tcount].data = exif_mem_alloc (en->mem, s);
494 if (!n->entries[tcount].data) {
495 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", s);
498 memcpy (n->entries[tcount].data, buf + dataofs, s);
501 /* Tag was successfully parsed */
504 /* Store the count of successfully parsed tags */
509 exif_mnote_data_olympus_count (ExifMnoteData *n)
511 return n ? ((ExifMnoteDataOlympus *) n)->count : 0;
515 exif_mnote_data_olympus_get_id (ExifMnoteData *d, unsigned int n)
517 ExifMnoteDataOlympus *note = (ExifMnoteDataOlympus *) d;
520 if (note->count <= n) return 0;
521 return note->entries[n].tag;
525 exif_mnote_data_olympus_get_name (ExifMnoteData *d, unsigned int i)
527 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
530 if (i >= n->count) return NULL;
531 return mnote_olympus_tag_get_name (n->entries[i].tag);
535 exif_mnote_data_olympus_get_title (ExifMnoteData *d, unsigned int i)
537 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
540 if (i >= n->count) return NULL;
541 return mnote_olympus_tag_get_title (n->entries[i].tag);
545 exif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i)
547 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
550 if (i >= n->count) return NULL;
551 return mnote_olympus_tag_get_description (n->entries[i].tag);
555 exif_mnote_data_olympus_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
557 ExifByteOrder o_orig;
558 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
565 for (i = 0; i < n->count; i++) {
566 if (n->entries[i].components && (n->entries[i].size/n->entries[i].components < exif_format_get_size (n->entries[i].format)))
568 n->entries[i].order = o;
569 exif_array_set_byte_order (n->entries[i].format, n->entries[i].data,
570 n->entries[i].components, o_orig, o);
575 exif_mnote_data_olympus_set_offset (ExifMnoteData *n, unsigned int o)
577 if (n) ((ExifMnoteDataOlympus *) n)->offset = o;
580 static enum OlympusVersion
581 exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
582 unsigned int buf_size)
584 /* Olympus, Nikon, Sanyo, Epson */
586 /* Match the terminating NUL character, too */
587 if (!memcmp (buf, "OLYMPUS", 8))
589 else if (!memcmp (buf, "OLYMP", 6))
591 else if (!memcmp (buf, "SANYO", 6))
593 else if (!memcmp (buf, "EPSON", 6))
595 else if (!memcmp (buf, "Nikon", 6)) {
597 case 1: return nikonV1;
598 case 2: return nikonV2;
599 default: return 0; /* Unrecognized Nikon variant */
604 /* Another variant of Nikon */
605 if ((buf_size >= 2) && (buf[0] == 0x00) && (buf[1] == 0x1b)) {
613 exif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e)
615 int variant = exif_mnote_data_olympus_identify_variant(e->data, e->size);
617 if (variant == nikonV0) {
618 /* This variant needs some extra checking with the Make */
620 ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE);
621 variant = unrecognized;
624 const char *v = exif_entry_get_value (em, value, sizeof(value));
625 if (v && (!strncmp (v, "Nikon", sizeof(value)) ||
626 !strncmp (v, "NIKON", sizeof(value)) ))
627 /* When saved, this variant will be written out like the
628 * alternative nikonV2 form above instead
639 exif_mnote_data_olympus_new (ExifMem *mem)
643 if (!mem) return NULL;
645 d = exif_mem_alloc (mem, sizeof (ExifMnoteDataOlympus));
648 exif_mnote_data_construct (d, mem);
650 /* Set up function pointers */
651 d->methods.free = exif_mnote_data_olympus_free;
652 d->methods.set_byte_order = exif_mnote_data_olympus_set_byte_order;
653 d->methods.set_offset = exif_mnote_data_olympus_set_offset;
654 d->methods.load = exif_mnote_data_olympus_load;
655 d->methods.save = exif_mnote_data_olympus_save;
656 d->methods.count = exif_mnote_data_olympus_count;
657 d->methods.get_id = exif_mnote_data_olympus_get_id;
658 d->methods.get_name = exif_mnote_data_olympus_get_name;
659 d->methods.get_title = exif_mnote_data_olympus_get_title;
660 d->methods.get_description = exif_mnote_data_olympus_get_description;
661 d->methods.get_value = exif_mnote_data_olympus_get_value;