Home | History | Annotate | Download | only in olympus
      1 /* exif-mnote-data-olympus.c
      2  *
      3  * Copyright (c) 2002, 2003 Lutz Mueller <lutz (at) 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 #define DEBUG
     32 
     33 /* Uncomment this to fix a problem with Sanyo MakerNotes. It's probably best
     34  * not to in most cases because it seems to only affect the thumbnail tag
     35  * which is duplicated in IFD 1, and fixing the offset could actually cause
     36  * problems with other software that expects the broken form.
     37  */
     38 /*#define EXIF_OVERCOME_SANYO_OFFSET_BUG */
     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 ((o2 + 10 < o2) || (o2 + 10 < 10) || (o2 + 10 > buf_size)) {
    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 		if (o2 + 2 > buf_size) return;
    292 		c = exif_get_short (buf + o2, n->order);
    293 		if ((!(c & 0xFF)) && (c > 0x500)) {
    294 			if (n->order == EXIF_BYTE_ORDER_INTEL) {
    295 				n->order = EXIF_BYTE_ORDER_MOTOROLA;
    296 			} else {
    297 				n->order = EXIF_BYTE_ORDER_INTEL;
    298 			}
    299 		}
    300 		break;
    301 
    302 	case olympusV2:
    303 		/* Olympus S760, S770 */
    304 		datao = o2;
    305 		o2 += 8;
    306 		exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
    307 			"Parsing Olympus maker note v2 (0x%02x, %02x, %02x, %02x)...",
    308 			buf[o2], 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 		if (o2 >= buf_size) return;
    322 		exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
    323 			"Parsing Nikon maker note v1 (0x%02x, %02x, %02x, "
    324 			"%02x, %02x, %02x, %02x, %02x)...",
    325 			buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
    326 			buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
    327 
    328 		/* Skip version number */
    329 		o2 += 1;
    330 
    331 		/* Skip an unknown byte (00 or 0A). */
    332 		o2 += 1;
    333 
    334 		base = MNOTE_NIKON1_TAG_BASE;
    335 		/* Fix endianness, if needed */
    336 		if (o2 + 2 > buf_size) return;
    337 		c = exif_get_short (buf + o2, n->order);
    338 		if ((!(c & 0xFF)) && (c > 0x500)) {
    339 			if (n->order == EXIF_BYTE_ORDER_INTEL) {
    340 				n->order = EXIF_BYTE_ORDER_MOTOROLA;
    341 			} else {
    342 				n->order = EXIF_BYTE_ORDER_INTEL;
    343 			}
    344 		}
    345 		break;
    346 
    347 	case nikonV2:
    348 		o2 += 6;
    349 		if (o2 >= buf_size) return;
    350 		exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
    351 			"Parsing Nikon maker note v2 (0x%02x, %02x, %02x, "
    352 			"%02x, %02x, %02x, %02x, %02x)...",
    353 			buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
    354 			buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
    355 
    356 		/* Skip version number */
    357 		o2 += 1;
    358 
    359 		/* Skip an unknown byte (00 or 0A). */
    360 		o2 += 1;
    361 
    362 		/* Skip 2 unknown bytes (00 00). */
    363 		o2 += 2;
    364 
    365 		/*
    366 		 * Byte order. From here the data offset
    367 		 * gets calculated.
    368 		 */
    369 		datao = o2;
    370 		if (o2 >= buf_size) return;
    371 		if (!strncmp ((char *)&buf[o2], "II", 2))
    372 			n->order = EXIF_BYTE_ORDER_INTEL;
    373 		else if (!strncmp ((char *)&buf[o2], "MM", 2))
    374 			n->order = EXIF_BYTE_ORDER_MOTOROLA;
    375 		else {
    376 			exif_log (en->log, EXIF_LOG_CODE_DEBUG,
    377 				"ExifMnoteDataOlympus", "Unknown "
    378 				"byte order '%c%c'", buf[o2],
    379 				buf[o2 + 1]);
    380 			return;
    381 		}
    382 		o2 += 2;
    383 
    384 		/* Skip 2 unknown bytes (00 2A). */
    385 		o2 += 2;
    386 
    387 		/* Go to where the number of entries is. */
    388 		if (o2 + 4 > buf_size) return;
    389 		o2 = datao + exif_get_long (buf + o2, n->order);
    390 		break;
    391 
    392 	case nikonV0:
    393 		exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
    394 			"Parsing Nikon maker note v0 (0x%02x, %02x, %02x, "
    395 			"%02x, %02x, %02x, %02x, %02x)...",
    396 			buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
    397 			buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
    398 		/* 00 1b is # of entries in Motorola order - the rest should also be in MM order */
    399 		n->order = EXIF_BYTE_ORDER_MOTOROLA;
    400 		break;
    401 
    402 	default:
    403 		exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
    404 			"Unknown Olympus variant %i.", n->version);
    405 		return;
    406 	}
    407 
    408 	/* Sanity check the offset */
    409 	if ((o2 + 2 < o2) || (o2 + 2 < 2) || (o2 + 2 > buf_size)) {
    410 		exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
    411 			  "ExifMnoteOlympus", "Short MakerNote");
    412 		return;
    413 	}
    414 
    415 	/* Read the number of tags */
    416 	c = exif_get_short (buf + o2, n->order);
    417 	o2 += 2;
    418 
    419 	/* Remove any old entries */
    420 	exif_mnote_data_olympus_clear (n);
    421 
    422 	/* Reserve enough space for all the possible MakerNote tags */
    423 	n->entries = exif_mem_alloc (en->mem, sizeof (MnoteOlympusEntry) * c);
    424 	if (!n->entries) {
    425 		EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", sizeof (MnoteOlympusEntry) * c);
    426 		return;
    427 	}
    428 
    429 	/* Parse all c entries, storing ones that are successfully parsed */
    430 	tcount = 0;
    431 	for (i = c, o = o2; i; --i, o += 12) {
    432 		size_t s;
    433 		if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) {
    434 			exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
    435 				  "ExifMnoteOlympus", "Short MakerNote");
    436 			break;
    437 		}
    438 
    439 	    n->entries[tcount].tag        = exif_get_short (buf + o, n->order) + base;
    440 	    n->entries[tcount].format     = exif_get_short (buf + o + 2, n->order);
    441 	    n->entries[tcount].components = exif_get_long (buf + o + 4, n->order);
    442 	    n->entries[tcount].order      = n->order;
    443 
    444 	    exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
    445 		      "Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
    446 		      mnote_olympus_tag_get_name (n->entries[tcount].tag));
    447 /*	    exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
    448 			    "0x%x %d %ld*(%d)",
    449 		    n->entries[tcount].tag,
    450 		    n->entries[tcount].format,
    451 		    n->entries[tcount].components,
    452 		    (int)exif_format_get_size(n->entries[tcount].format)); */
    453 
    454 	    /*
    455 	     * Size? If bigger than 4 bytes, the actual data is not
    456 	     * in the entry but somewhere else (offset).
    457 	     */
    458 	    s = exif_format_get_size (n->entries[tcount].format) *
    459 		   			 n->entries[tcount].components;
    460 		n->entries[tcount].size = s;
    461 		if (s) {
    462 			size_t dataofs = o + 8;
    463 			if (s > 4) {
    464 				/* The data in this case is merely a pointer */
    465 				dataofs = exif_get_long (buf + dataofs, n->order) + datao;
    466 #ifdef EXIF_OVERCOME_SANYO_OFFSET_BUG
    467 				/* Some Sanyo models (e.g. VPC-C5, C40) suffer from a bug when
    468 				 * writing the offset for the MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE
    469 				 * tag in its MakerNote. The offset is actually the absolute
    470 				 * position in the file instead of the position within the IFD.
    471 				 */
    472 			    if (dataofs + s > buf_size && n->version == sanyoV1) {
    473 					/* fix pointer */
    474 					dataofs -= datao + 6;
    475 					exif_log (en->log, EXIF_LOG_CODE_DEBUG,
    476 						  "ExifMnoteOlympus",
    477 						  "Inconsistent thumbnail tag offset; attempting to recover");
    478 			    }
    479 #endif
    480 			}
    481 			if ((dataofs + s < dataofs) || (dataofs + s < s) ||
    482 			    (dataofs + s > buf_size)) {
    483 				exif_log (en->log, EXIF_LOG_CODE_DEBUG,
    484 					  "ExifMnoteOlympus",
    485 					  "Tag data past end of buffer (%zu > %u)",
    486 					  dataofs + s, buf_size);
    487 				continue;
    488 			}
    489 
    490 			n->entries[tcount].data = exif_mem_alloc (en->mem, s);
    491 			if (!n->entries[tcount].data) {
    492 				EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", s);
    493 				continue;
    494 			}
    495 			memcpy (n->entries[tcount].data, buf + dataofs, s);
    496 		}
    497 
    498 		/* Tag was successfully parsed */
    499 		++tcount;
    500 	}
    501 	/* Store the count of successfully parsed tags */
    502 	n->count = tcount;
    503 }
    504 
    505 static unsigned int
    506 exif_mnote_data_olympus_count (ExifMnoteData *n)
    507 {
    508 	return n ? ((ExifMnoteDataOlympus *) n)->count : 0;
    509 }
    510 
    511 static unsigned int
    512 exif_mnote_data_olympus_get_id (ExifMnoteData *d, unsigned int n)
    513 {
    514 	ExifMnoteDataOlympus *note = (ExifMnoteDataOlympus *) d;
    515 
    516 	if (!note) return 0;
    517 	if (note->count <= n) return 0;
    518 	return note->entries[n].tag;
    519 }
    520 
    521 static const char *
    522 exif_mnote_data_olympus_get_name (ExifMnoteData *d, unsigned int i)
    523 {
    524 	ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
    525 
    526 	if (!n) return NULL;
    527 	if (i >= n->count) return NULL;
    528 	return mnote_olympus_tag_get_name (n->entries[i].tag);
    529 }
    530 
    531 static const char *
    532 exif_mnote_data_olympus_get_title (ExifMnoteData *d, unsigned int i)
    533 {
    534 	ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
    535 
    536 	if (!n) return NULL;
    537 	if (i >= n->count) return NULL;
    538         return mnote_olympus_tag_get_title (n->entries[i].tag);
    539 }
    540 
    541 static const char *
    542 exif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i)
    543 {
    544 	ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
    545 
    546 	if (!n) return NULL;
    547 	if (i >= n->count) return NULL;
    548         return mnote_olympus_tag_get_description (n->entries[i].tag);
    549 }
    550 
    551 static void
    552 exif_mnote_data_olympus_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
    553 {
    554 	ExifByteOrder o_orig;
    555 	ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
    556 	unsigned int i;
    557 
    558 	if (!n) return;
    559 
    560 	o_orig = n->order;
    561 	n->order = o;
    562 	for (i = 0; i < n->count; i++) {
    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 }
    660