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