riscv64: Update config.sub and config.guess
[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                 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");
432                         break;
433                 }
434
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;
439
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",
444                             "0x%x %d %ld*(%d)",
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)); */
449
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
454             ) {
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);
456                 continue;
457             }
458             /*
459              * Size? If bigger than 4 bytes, the actual data is not
460              * in the entry but somewhere else (offset).
461              */
462             s = exif_format_get_size (n->entries[tcount].format) *
463                                          n->entries[tcount].components;
464                 n->entries[tcount].size = s;
465                 if (s) {
466                         size_t dataofs = o + 8;
467                         if (s > 4) {
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.
475                                  */
476                             if (dataofs > (buf_size - s) && n->version == sanyoV1) {
477                                         /* fix pointer */
478                                         dataofs -= datao + 6;
479                                         exif_log (en->log, EXIF_LOG_CODE_DEBUG,
480                                                   "ExifMnoteOlympus",
481                                                   "Inconsistent thumbnail tag offset; attempting to recover");
482                             }
483 #endif
484                         }
485                         if (CHECKOVERFLOW(dataofs, buf_size, s)) {
486                                 exif_log (en->log, EXIF_LOG_CODE_DEBUG,
487                                           "ExifMnoteOlympus",
488                                           "Tag data past end of buffer (%u > %u)",
489                                           (unsigned)(dataofs + s), buf_size);
490                                 continue;
491                         }
492
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);
496                                 continue;
497                         }
498                         memcpy (n->entries[tcount].data, buf + dataofs, s);
499                 }
500
501                 /* Tag was successfully parsed */
502                 ++tcount;
503         }
504         /* Store the count of successfully parsed tags */
505         n->count = tcount;
506 }
507
508 static unsigned int
509 exif_mnote_data_olympus_count (ExifMnoteData *n)
510 {
511         return n ? ((ExifMnoteDataOlympus *) n)->count : 0;
512 }
513
514 static unsigned int
515 exif_mnote_data_olympus_get_id (ExifMnoteData *d, unsigned int n)
516 {
517         ExifMnoteDataOlympus *note = (ExifMnoteDataOlympus *) d;
518
519         if (!note) return 0;
520         if (note->count <= n) return 0;
521         return note->entries[n].tag;
522 }
523
524 static const char *
525 exif_mnote_data_olympus_get_name (ExifMnoteData *d, unsigned int i)
526 {
527         ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
528
529         if (!n) return NULL;
530         if (i >= n->count) return NULL;
531         return mnote_olympus_tag_get_name (n->entries[i].tag);
532 }
533
534 static const char *
535 exif_mnote_data_olympus_get_title (ExifMnoteData *d, unsigned int i)
536 {
537         ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
538         
539         if (!n) return NULL;
540         if (i >= n->count) return NULL;
541         return mnote_olympus_tag_get_title (n->entries[i].tag);
542 }
543
544 static const char *
545 exif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i)
546 {
547         ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
548         
549         if (!n) return NULL;
550         if (i >= n->count) return NULL;
551         return mnote_olympus_tag_get_description (n->entries[i].tag);
552 }
553
554 static void
555 exif_mnote_data_olympus_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
556 {
557         ExifByteOrder o_orig;
558         ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
559         unsigned int i;
560
561         if (!n) return;
562
563         o_orig = n->order;
564         n->order = o;
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)))
567                         continue;
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);
571         }
572 }
573
574 static void
575 exif_mnote_data_olympus_set_offset (ExifMnoteData *n, unsigned int o)
576 {
577         if (n) ((ExifMnoteDataOlympus *) n)->offset = o;
578 }
579
580 static enum OlympusVersion
581 exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
582                 unsigned int buf_size)
583 {
584         /* Olympus, Nikon, Sanyo, Epson */
585         if (buf_size >= 8) {
586                 /* Match the terminating NUL character, too */
587                 if (!memcmp (buf, "OLYMPUS", 8))
588                            return olympusV2;
589                 else if (!memcmp (buf, "OLYMP", 6))
590                            return olympusV1;
591                 else if (!memcmp (buf, "SANYO", 6))
592                            return sanyoV1;
593                 else if (!memcmp (buf, "EPSON", 6))
594                            return epsonV1;
595                 else if (!memcmp (buf, "Nikon", 6)) {
596                         switch (buf[6]) {
597                                 case 1:  return nikonV1;
598                                 case 2:  return nikonV2;
599                                 default: return 0; /* Unrecognized Nikon variant */
600                         }
601                 }
602         }
603
604         /* Another variant of Nikon */
605         if ((buf_size >= 2) && (buf[0] == 0x00) && (buf[1] == 0x1b)) {
606                 return nikonV0;
607         }
608
609         return unrecognized;
610 }
611
612 int
613 exif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e)
614 {
615         int variant = exif_mnote_data_olympus_identify_variant(e->data, e->size);
616
617         if (variant == nikonV0) {
618                 /* This variant needs some extra checking with the Make */
619                 char value[5];
620                 ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE);
621                 variant = unrecognized;
622
623                 if (em) {
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
629                                  */
630                                 variant = nikonV0;
631                 }
632         }
633
634         return variant;
635 }
636
637
638 ExifMnoteData *
639 exif_mnote_data_olympus_new (ExifMem *mem)
640 {
641         ExifMnoteData *d;
642
643         if (!mem) return NULL;
644         
645         d = exif_mem_alloc (mem, sizeof (ExifMnoteDataOlympus));
646         if (!d) return NULL;
647
648         exif_mnote_data_construct (d, mem);
649
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;
662
663         return d;
664 }