bd83411e0bee35cabbdfd2c266ea45fdf8f6daf3
[platform/upstream/libexif.git] / libexif / olympus / exif-mnote-data-olympus.c
1 /* exif-mnote-data-olympus.c
2  *
3  * Copyright (c) 2002, 2003 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
21 #include <config.h>
22 #include "exif-mnote-data-olympus.h"
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
27
28 #include <libexif/exif-utils.h>
29 #include <libexif/exif-data.h>
30
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.
35  */
36 /*#define EXIF_OVERCOME_SANYO_OFFSET_BUG */
37
38 #define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
39
40 static enum OlympusVersion
41 exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
42                 unsigned int buf_size);
43
44
45 static void
46 exif_mnote_data_olympus_clear (ExifMnoteDataOlympus *n)
47 {
48         ExifMnoteData *d = (ExifMnoteData *) n;
49         unsigned int i;
50
51         if (!n) return;
52
53         if (n->entries) {
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;
58                         }
59                 exif_mem_free (d->mem, n->entries);
60                 n->entries = NULL;
61                 n->count = 0;
62         }
63 }
64
65 static void
66 exif_mnote_data_olympus_free (ExifMnoteData *n)
67 {
68         if (!n) return;
69
70         exif_mnote_data_olympus_clear ((ExifMnoteDataOlympus *) n);
71 }
72
73 static char *
74 exif_mnote_data_olympus_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen)
75 {
76         ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
77
78         if (!d || !val) return NULL;
79         if (i > n->count -1) return NULL;
80 /*
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));
84 */
85         return mnote_olympus_entry_get_value (&n->entries[i], val, maxlen);
86 }
87
88
89
90
91 /** 
92  * @brief save the MnoteData from ne to buf
93  * 
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
97  */
98 static void
99 exif_mnote_data_olympus_save (ExifMnoteData *ne,
100                 unsigned char **buf, unsigned int *buf_size)
101 {
102         ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) ne;
103         size_t i, o, s, doff, base = 0, o2 = 6 + 2;
104         size_t datao = 0;
105         unsigned char *t;
106         size_t ts;
107
108         if (!n || !buf || !buf_size) return;
109
110         /*
111          * Allocate enough memory for all entries and the number of entries.
112          */
113         *buf_size = 6 + 2 + 2 + n->count * 12;
114         switch (n->version) {
115         case olympusV1:
116         case sanyoV1:
117         case epsonV1:
118                 *buf = exif_mem_alloc (ne->mem, *buf_size);
119                 if (!*buf) {
120                         EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
121                         return;
122                 }
123
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);
128                 datao = n->offset;
129                 break;
130
131         case olympusV2:
132                 *buf_size += 8-6 + 4;
133                 *buf = exif_mem_alloc (ne->mem, *buf_size);
134                 if (!*buf) {
135                         EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
136                         return;
137                 }
138
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) ?
143                         ('I' << 8) | 'I' :
144                         ('M' << 8) | 'M'));
145                 exif_set_short (*buf + 10, n->order, (ExifShort) 3);
146                 o2 += 4;
147                 break;
148
149         case nikonV1: 
150                 base = MNOTE_NIKON1_TAG_BASE;
151
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 */
155                 *buf_size -= 8 + 2;
156         /* Fall through to nikonV2 handler */
157         case nikonV2: 
158         /* Write out V0 files in V2 format */
159         case nikonV0: 
160                 *buf_size += 8 + 2;
161                 *buf_size += 4; /* Next IFD pointer */
162                 *buf = exif_mem_alloc (ne->mem, *buf_size);
163                 if (!*buf) {
164                         EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
165                         return;
166                 }
167
168                 /* Write the header and the number of entries. */
169                 strcpy ((char *)*buf, "Nikon");
170                 (*buf)[6] = n->version;
171
172                 if (n->version != nikonV1) {
173                         exif_set_short (*buf + 10, n->order, (ExifShort) (
174                                 (n->order == EXIF_BYTE_ORDER_INTEL) ?
175                                 ('I' << 8) | 'I' :
176                                 ('M' << 8) | 'M'));
177                         exif_set_short (*buf + 12, n->order, (ExifShort) 0x2A);
178                         exif_set_long (*buf + 14, n->order, (ExifShort) 8);
179                         o2 += 2 + 8;
180                 }
181                 datao -= 10;
182                 /* Reset next IFD pointer */
183                 exif_set_long (*buf + o2 + 2 + n->count * 12, n->order, 0);
184                 break;
185
186         default:
187                 return;
188         }
189
190         exif_set_short (*buf + o2, n->order, (ExifShort) n->count);
191         o2 += 2;
192
193         /* Save each entry */
194         for (i = 0; i < n->count; i++) {
195                 o = o2 + i * 12;
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);
202                 o += 8;
203                 s = exif_format_get_size (n->entries[i].format) *
204                                                 n->entries[i].components;
205                 if (s > 65536) {
206                         /* Corrupt data: EXIF data size is limited to the
207                          * maximum size of a JPEG segment (64 kb).
208                          */
209                         continue;
210                 }
211                 if (s > 4) {
212                         doff = *buf_size;
213                         ts = *buf_size + s;
214                         t = exif_mem_realloc (ne->mem, *buf,
215                                                  sizeof (char) * ts);
216                         if (!t) {
217                                 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", ts);
218                                 return;
219                         }
220                         *buf = t;
221                         *buf_size = ts;
222                         exif_set_long (*buf + o, n->order, datao + doff);
223                 } else
224                         doff = o;
225
226                 /* Write the data. */
227                 if (n->entries[i].data) {
228                         memcpy (*buf + doff, n->entries[i].data, s);
229                 } else {
230                         /* Most certainly damaged input file */
231                         memset (*buf + doff, 0, s);
232                 }
233         }
234 }
235
236 static void
237 exif_mnote_data_olympus_load (ExifMnoteData *en,
238                               const unsigned char *buf, unsigned int buf_size)
239 {
240         ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en;
241         ExifShort c;
242         size_t i, tcount, o, o2, datao = 6, base = 0;
243
244         if (!n || !buf || !buf_size) {
245                 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
246                           "ExifMnoteDataOlympus", "Short MakerNote");
247                 return;
248         }
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");
253                 return;
254         }
255
256         /*
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.
260          *
261          * Sanyo format is identical and uses identical tags except that
262          * header starts with "SANYO".
263          *
264          * Epson format is identical and uses identical tags except that
265          * header starts with "EPSON".
266          *
267          * Nikon headers start with "Nikon" (6 bytes including '\0'), 
268          * version number (1 or 2).
269          * 
270          * Version 1 continues with 0, 1, 0, number_of_tags,
271          * or just with number_of_tags (models D1H, D1X...).
272          * 
273          * Version 2 continues with an unknown byte (0 or 10),
274          * two unknown bytes (0), "MM" or "II", another byte 0 and 
275          * lastly 0x2A.
276          */
277         n->version = exif_mnote_data_olympus_identify_variant(buf+o2, buf_size-o2);
278         switch (n->version) {
279         case olympusV1:
280         case sanyoV1:
281         case epsonV1:
282                 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
283                         "Parsing Olympus/Sanyo/Epson maker note v1...");
284
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;
290                 o2 += 8;
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;
295                         } else {
296                                 n->order = EXIF_BYTE_ORDER_INTEL;
297                         }
298                 }
299                 break;
300
301         case olympusV2:
302                 /* Olympus S760, S770 */
303                 datao = o2;
304                 o2 += 8;
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]);
309
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;
314
315                 /* The number of entries is at position 8+4. */
316                 o2 += 4;
317                 break;
318
319         case nikonV1:
320                 o2 += 6;
321                 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
322                         "Parsing Nikon maker note v1 (0x%02x, %02x, %02x, "
323                         "%02x)...",
324                         buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]);
325
326                 /* Skip version number */
327                 o2 += 1;
328
329                 /* Skip an unknown byte (00 or 0A). */
330                 o2 += 1;
331
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;
338                         } else {
339                                 n->order = EXIF_BYTE_ORDER_INTEL;
340                         }
341                 }
342                 break;
343
344         case nikonV2:
345                 o2 += 6;
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]);
352
353                 /* Skip version number */
354                 o2 += 1;
355
356                 /* Skip an unknown byte (00 or 0A). */
357                 o2 += 1;
358
359                 /* Skip 2 unknown bytes (00 00). */
360                 o2 += 2;
361
362                 /*
363                  * Byte order. From here the data offset
364                  * gets calculated.
365                  */
366                 datao = o2;
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;
371                 else {
372                         exif_log (en->log, EXIF_LOG_CODE_DEBUG,
373                                 "ExifMnoteDataOlympus", "Unknown "
374                                 "byte order '%c%c'", buf[o2],
375                                 buf[o2 + 1]);
376                         return;
377                 }
378                 o2 += 2;
379
380                 /* Skip 2 unknown bytes (00 2A). */
381                 o2 += 2;
382
383                 /* Go to where the number of entries is. */
384                 o2 = datao + exif_get_long (buf + o2, n->order);
385                 break;
386
387         case nikonV0:
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;
395                 break;
396
397         default:
398                 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
399                         "Unknown Olympus variant %i.", n->version);
400                 return;
401         }
402
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");
407                 return;
408         }
409
410         /* Read the number of tags */
411         c = exif_get_short (buf + o2, n->order);
412         o2 += 2;
413
414         /* Remove any old entries */
415         exif_mnote_data_olympus_clear (n);
416
417         /* Reserve enough space for all the possible MakerNote tags */
418         n->entries = exif_mem_alloc (en->mem, sizeof (MnoteOlympusEntry) * c);
419         if (!n->entries) {
420                 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", sizeof (MnoteOlympusEntry) * c);
421                 return;
422         }
423
424         /* Parse all c entries, storing ones that are successfully parsed */
425         tcount = 0;
426         for (i = c, o = o2; i; --i, o += 12) {
427                 size_t s;
428                 if (CHECKOVERFLOW(o, buf_size, 12)) {
429                         exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
430                                   "ExifMnoteOlympus", "Short MakerNote");
431                         break;
432                 }
433
434             n->entries[tcount].tag        = exif_get_short (buf + o, n->order) + base;
435             n->entries[tcount].format     = exif_get_short (buf + o + 2, n->order);
436             n->entries[tcount].components = exif_get_long (buf + o + 4, n->order);
437             n->entries[tcount].order      = n->order;
438
439             exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
440                       "Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
441                       mnote_olympus_tag_get_name (n->entries[tcount].tag));
442 /*          exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
443                             "0x%x %d %ld*(%d)",
444                     n->entries[tcount].tag,
445                     n->entries[tcount].format,
446                     n->entries[tcount].components,
447                     (int)exif_format_get_size(n->entries[tcount].format)); */
448
449             /* Check if we overflow the multiplication. Use buf_size as the max size for integer overflow detection,
450              * we will check the buffer sizes closer later. */
451             if (exif_format_get_size (n->entries[tcount].format) &&
452                 buf_size / exif_format_get_size (n->entries[tcount].format) < n->entries[tcount].components
453             ) {
454                 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);
455                 continue;
456             }
457             /*
458              * Size? If bigger than 4 bytes, the actual data is not
459              * in the entry but somewhere else (offset).
460              */
461             s = exif_format_get_size (n->entries[tcount].format) *
462                                          n->entries[tcount].components;
463                 n->entries[tcount].size = s;
464                 if (s) {
465                         size_t dataofs = o + 8;
466                         if (s > 4) {
467                                 /* The data in this case is merely a pointer */
468                                 dataofs = exif_get_long (buf + dataofs, n->order) + datao;
469 #ifdef EXIF_OVERCOME_SANYO_OFFSET_BUG
470                                 /* Some Sanyo models (e.g. VPC-C5, C40) suffer from a bug when
471                                  * writing the offset for the MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE
472                                  * tag in its MakerNote. The offset is actually the absolute
473                                  * position in the file instead of the position within the IFD.
474                                  */
475                             if (dataofs > (buf_size - s) && n->version == sanyoV1) {
476                                         /* fix pointer */
477                                         dataofs -= datao + 6;
478                                         exif_log (en->log, EXIF_LOG_CODE_DEBUG,
479                                                   "ExifMnoteOlympus",
480                                                   "Inconsistent thumbnail tag offset; attempting to recover");
481                             }
482 #endif
483                         }
484                         if (CHECKOVERFLOW(dataofs, buf_size, s)) {
485                                 exif_log (en->log, EXIF_LOG_CODE_DEBUG,
486                                           "ExifMnoteOlympus",
487                                           "Tag data past end of buffer (%u > %u)",
488                                           (unsigned)(dataofs + s), buf_size);
489                                 continue;
490                         }
491
492                         n->entries[tcount].data = exif_mem_alloc (en->mem, s);
493                         if (!n->entries[tcount].data) {
494                                 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", s);
495                                 continue;
496                         }
497                         memcpy (n->entries[tcount].data, buf + dataofs, s);
498                 }
499
500                 /* Tag was successfully parsed */
501                 ++tcount;
502         }
503         /* Store the count of successfully parsed tags */
504         n->count = tcount;
505 }
506
507 static unsigned int
508 exif_mnote_data_olympus_count (ExifMnoteData *n)
509 {
510         return n ? ((ExifMnoteDataOlympus *) n)->count : 0;
511 }
512
513 static unsigned int
514 exif_mnote_data_olympus_get_id (ExifMnoteData *d, unsigned int n)
515 {
516         ExifMnoteDataOlympus *note = (ExifMnoteDataOlympus *) d;
517
518         if (!note) return 0;
519         if (note->count <= n) return 0;
520         return note->entries[n].tag;
521 }
522
523 static const char *
524 exif_mnote_data_olympus_get_name (ExifMnoteData *d, unsigned int i)
525 {
526         ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
527
528         if (!n) return NULL;
529         if (i >= n->count) return NULL;
530         return mnote_olympus_tag_get_name (n->entries[i].tag);
531 }
532
533 static const char *
534 exif_mnote_data_olympus_get_title (ExifMnoteData *d, unsigned int i)
535 {
536         ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
537         
538         if (!n) return NULL;
539         if (i >= n->count) return NULL;
540         return mnote_olympus_tag_get_title (n->entries[i].tag);
541 }
542
543 static const char *
544 exif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i)
545 {
546         ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
547         
548         if (!n) return NULL;
549         if (i >= n->count) return NULL;
550         return mnote_olympus_tag_get_description (n->entries[i].tag);
551 }
552
553 static void
554 exif_mnote_data_olympus_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
555 {
556         ExifByteOrder o_orig;
557         ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
558         unsigned int i;
559
560         if (!n) return;
561
562         o_orig = n->order;
563         n->order = o;
564         for (i = 0; i < n->count; i++) {
565                 if (n->entries[i].components && (n->entries[i].size/n->entries[i].components < exif_format_get_size (n->entries[i].format)))
566                         continue;
567                 n->entries[i].order = o;
568                 exif_array_set_byte_order (n->entries[i].format, n->entries[i].data,
569                                 n->entries[i].components, o_orig, o);
570         }
571 }
572
573 static void
574 exif_mnote_data_olympus_set_offset (ExifMnoteData *n, unsigned int o)
575 {
576         if (n) ((ExifMnoteDataOlympus *) n)->offset = o;
577 }
578
579 static enum OlympusVersion
580 exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
581                 unsigned int buf_size)
582 {
583         /* Olympus, Nikon, Sanyo, Epson */
584         if (buf_size >= 8) {
585                 /* Match the terminating NUL character, too */
586                 if (!memcmp (buf, "OLYMPUS", 8))
587                            return olympusV2;
588                 else if (!memcmp (buf, "OLYMP", 6))
589                            return olympusV1;
590                 else if (!memcmp (buf, "SANYO", 6))
591                            return sanyoV1;
592                 else if (!memcmp (buf, "EPSON", 6))
593                            return epsonV1;
594                 else if (!memcmp (buf, "Nikon", 6)) {
595                         switch (buf[6]) {
596                                 case 1:  return nikonV1;
597                                 case 2:  return nikonV2;
598                                 default: return 0; /* Unrecognized Nikon variant */
599                         }
600                 }
601         }
602
603         /* Another variant of Nikon */
604         if ((buf_size >= 2) && (buf[0] == 0x00) && (buf[1] == 0x1b)) {
605                 return nikonV0;
606         }
607
608         return unrecognized;
609 }
610
611 int
612 exif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e)
613 {
614         int variant = exif_mnote_data_olympus_identify_variant(e->data, e->size);
615
616         if (variant == nikonV0) {
617                 /* This variant needs some extra checking with the Make */
618                 char value[5];
619                 ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE);
620                 variant = unrecognized;
621
622                 if (em) {
623                         const char *v = exif_entry_get_value (em, value, sizeof(value));
624                         if (v && (!strncmp (v, "Nikon", sizeof(value)) || 
625                                           !strncmp (v, "NIKON", sizeof(value)) ))
626                                 /* When saved, this variant will be written out like the
627                                  * alternative nikonV2 form above instead
628                                  */
629                                 variant = nikonV0;
630                 }
631         }
632
633         return variant;
634 }
635
636
637 ExifMnoteData *
638 exif_mnote_data_olympus_new (ExifMem *mem)
639 {
640         ExifMnoteData *d;
641
642         if (!mem) return NULL;
643         
644         d = exif_mem_alloc (mem, sizeof (ExifMnoteDataOlympus));
645         if (!d) return NULL;
646
647         exif_mnote_data_construct (d, mem);
648
649         /* Set up function pointers */
650         d->methods.free            = exif_mnote_data_olympus_free;
651         d->methods.set_byte_order  = exif_mnote_data_olympus_set_byte_order;
652         d->methods.set_offset      = exif_mnote_data_olympus_set_offset;
653         d->methods.load            = exif_mnote_data_olympus_load;
654         d->methods.save            = exif_mnote_data_olympus_save;
655         d->methods.count           = exif_mnote_data_olympus_count;
656         d->methods.get_id          = exif_mnote_data_olympus_get_id;
657         d->methods.get_name        = exif_mnote_data_olympus_get_name;
658         d->methods.get_title       = exif_mnote_data_olympus_get_title;
659         d->methods.get_description = exif_mnote_data_olympus_get_description;
660         d->methods.get_value       = exif_mnote_data_olympus_get_value;
661
662         return d;
663 }