1548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/* exif-mnote-data-olympus.c
2548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *
3548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Copyright (c) 2002, 2003 Lutz Mueller <lutz@users.sourceforge.net>
4548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *
5548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * This library is free software; you can redistribute it and/or
6548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * modify it under the terms of the GNU Lesser General Public
7548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * License as published by the Free Software Foundation; either
8548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * version 2 of the License, or (at your option) any later version.
9548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *
10548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * This library is distributed in the hope that it will be useful,
11548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * but WITHOUT ANY WARRANTY; without even the implied warranty of
12548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Lesser General Public License for more details.
14548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *
15548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * You should have received a copy of the GNU Lesser General Public
16548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * License along with this library; if not, write to the
17548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * Boston, MA  02110-1301  USA.
19548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */
20548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
21548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <config.h>
22548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include "exif-mnote-data-olympus.h"
23548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
24548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <stdlib.h>
25548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <string.h>
26548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <stdio.h>
27548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
28548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <libexif/exif-utils.h>
29548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#include <libexif/exif-data.h>
30548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
31548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#define DEBUG
32548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
33548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/* Uncomment this to fix a problem with Sanyo MakerNotes. It's probably best
34548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * not to in most cases because it seems to only affect the thumbnail tag
35548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * which is duplicated in IFD 1, and fixing the offset could actually cause
36548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * problems with other software that expects the broken form.
37548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */
38548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/*#define EXIF_OVERCOME_SANYO_OFFSET_BUG */
39548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
40548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic enum OlympusVersion
41548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_identify_variant (const unsigned char *buf,
42548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		unsigned int buf_size);
43548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
44548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
45548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void
46548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_clear (ExifMnoteDataOlympus *n)
47548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
48548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMnoteData *d = (ExifMnoteData *) n;
49548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	unsigned int i;
50548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
51548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!n) return;
52548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
53548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (n->entries) {
54548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		for (i = 0; i < n->count; i++)
55548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			if (n->entries[i].data) {
56548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				exif_mem_free (d->mem, n->entries[i].data);
57548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				n->entries[i].data = NULL;
58548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			}
59548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_mem_free (d->mem, n->entries);
60548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		n->entries = NULL;
61548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		n->count = 0;
62548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
63548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
64548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
65548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void
66548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_free (ExifMnoteData *n)
67548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
68548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!n) return;
69548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
70548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_mnote_data_olympus_clear ((ExifMnoteDataOlympus *) n);
71548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
72548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
73548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic char *
74548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen)
75548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
76548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
77548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
78548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!d || !val) return NULL;
79548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (i > n->count -1) return NULL;
80548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/*
81548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_log (d->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
82548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		  "Querying value for tag '%s'...",
83548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		  mnote_olympus_tag_get_name (n->entries[i].tag));
84548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen*/
85548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return mnote_olympus_entry_get_value (&n->entries[i], val, maxlen);
86548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
87548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
88548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
89548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
90548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
91548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/**
92548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * @brief save the MnoteData from ne to buf
93548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen *
94548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * @param ne extract the data from this structure
95548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * @param *buf write the mnoteData to this buffer (buffer will be allocated)
96548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen * @param buf_size the size of the buffer
97548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen */
98548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void
99548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_save (ExifMnoteData *ne,
100548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		unsigned char **buf, unsigned int *buf_size)
101548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
102548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) ne;
103548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	size_t i, o, s, doff, base = 0, o2 = 6 + 2;
104548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	size_t datao = 0;
105548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	unsigned char *t;
106548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	size_t ts;
107548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
108548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!n || !buf || !buf_size) return;
109548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
110548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/*
111548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * Allocate enough memory for all entries and the number of entries.
112548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 */
113548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	*buf_size = 6 + 2 + 2 + n->count * 12;
114548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	switch (n->version) {
115548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case olympusV1:
116548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case sanyoV1:
117548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case epsonV1:
118548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		*buf = exif_mem_alloc (ne->mem, *buf_size);
119548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (!*buf) {
120548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
121548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			return;
122548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
123548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
124548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Write the header and the number of entries. */
125548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		strcpy ((char *)*buf, n->version==sanyoV1?"SANYO":
126548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					(n->version==epsonV1?"EPSON":"OLYMP"));
127548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_set_short (*buf + 6, n->order, (ExifShort) 1);
128548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		datao = n->offset;
129548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		break;
130548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
131548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case olympusV2:
132548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		*buf_size += 8-6 + 4;
133548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		*buf = exif_mem_alloc (ne->mem, *buf_size);
134548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (!*buf) {
135548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
136548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			return;
137548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
138548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
139548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Write the header and the number of entries. */
140548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		strcpy ((char *)*buf, "OLYMPUS");
141548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_set_short (*buf + 8, n->order, (ExifShort) (
142548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			(n->order == EXIF_BYTE_ORDER_INTEL) ?
143548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			('I' << 8) | 'I' :
144548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			('M' << 8) | 'M'));
145548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_set_short (*buf + 10, n->order, (ExifShort) 3);
146548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 4;
147548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		break;
148548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
149548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case nikonV1:
150548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		base = MNOTE_NIKON1_TAG_BASE;
151548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
152548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* v1 has offsets based to main IFD, not makernote IFD */
153548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		datao += n->offset + 10;
154548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* subtract the size here, so the increment in the next case will not harm us */
155548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		*buf_size -= 8 + 2;
156548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Fall through to nikonV2 handler */
157548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case nikonV2:
158548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Write out V0 files in V2 format */
159548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case nikonV0:
160548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		*buf_size += 8 + 2;
161548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		*buf_size += 4; /* Next IFD pointer */
162548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		*buf = exif_mem_alloc (ne->mem, *buf_size);
163548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (!*buf) {
164548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
165548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			return;
166548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
167548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
168548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Write the header and the number of entries. */
169548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		strcpy ((char *)*buf, "Nikon");
170548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		(*buf)[6] = n->version;
171548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
172548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (n->version != nikonV1) {
173548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			exif_set_short (*buf + 10, n->order, (ExifShort) (
174548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				(n->order == EXIF_BYTE_ORDER_INTEL) ?
175548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				('I' << 8) | 'I' :
176548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				('M' << 8) | 'M'));
177548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			exif_set_short (*buf + 12, n->order, (ExifShort) 0x2A);
178548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			exif_set_long (*buf + 14, n->order, (ExifShort) 8);
179548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			o2 += 2 + 8;
180548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
181548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		datao -= 10;
182548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Reset next IFD pointer */
183548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_set_long (*buf + o2 + 2 + n->count * 12, n->order, 0);
184548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		break;
185548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
186548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	default:
187548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return;
188548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
189548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
190548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_set_short (*buf + o2, n->order, (ExifShort) n->count);
191548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	o2 += 2;
192548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
193548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Save each entry */
194548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	for (i = 0; i < n->count; i++) {
195548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o = o2 + i * 12;
196548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_set_short (*buf + o + 0, n->order,
197548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				(ExifShort) (n->entries[i].tag - base));
198548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_set_short (*buf + o + 2, n->order,
199548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				(ExifShort) n->entries[i].format);
200548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_set_long  (*buf + o + 4, n->order,
201548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				n->entries[i].components);
202548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o += 8;
203548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		s = exif_format_get_size (n->entries[i].format) *
204548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen						n->entries[i].components;
205548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (s > 65536) {
206548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			/* Corrupt data: EXIF data size is limited to the
207548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			 * maximum size of a JPEG segment (64 kb).
208548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			 */
209548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			continue;
210548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
211548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (s > 4) {
212548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			doff = *buf_size;
213548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			ts = *buf_size + s;
214548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			t = exif_mem_realloc (ne->mem, *buf,
215548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen						 sizeof (char) * ts);
216548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			if (!t) {
217548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", ts);
218548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				return;
219548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			}
220548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			*buf = t;
221548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			*buf_size = ts;
222548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			exif_set_long (*buf + o, n->order, datao + doff);
223548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		} else
224548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			doff = o;
225548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
226548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Write the data. */
227548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (n->entries[i].data) {
228548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			memcpy (*buf + doff, n->entries[i].data, s);
229548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		} else {
230548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			/* Most certainly damaged input file */
231548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			memset (*buf + doff, 0, s);
232548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
233548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
234548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
235548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
236548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void
237548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_load (ExifMnoteData *en,
238548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			      const unsigned char *buf, unsigned int buf_size)
239548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
240548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en;
241548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifShort c;
242548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	size_t i, tcount, o, o2, datao = 6, base = 0;
243548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
244548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!n || !buf || !buf_size) {
245548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
246548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			  "ExifMnoteDataOlympus", "Short MakerNote");
247548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return;
248548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
249548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	o2 = 6 + n->offset; /* Start of interesting data */
250548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if ((o2 + 10 < o2) || (o2 + 10 < 10) || (o2 + 10 > buf_size)) {
251548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
252548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			  "ExifMnoteDataOlympus", "Short MakerNote");
253548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return;
254548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
255548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
256548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/*
257548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * Olympus headers start with "OLYMP" and need to have at least
258548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the
259548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * number of entries, and 12 for one entry.
260548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 *
261548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * Sanyo format is identical and uses identical tags except that
262548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * header starts with "SANYO".
263548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 *
264548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * Epson format is identical and uses identical tags except that
265548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * header starts with "EPSON".
266548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 *
267548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * Nikon headers start with "Nikon" (6 bytes including '\0'),
268548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * version number (1 or 2).
269548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 *
270548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * Version 1 continues with 0, 1, 0, number_of_tags,
271548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * or just with number_of_tags (models D1H, D1X...).
272548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 *
273548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * Version 2 continues with an unknown byte (0 or 10),
274548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * two unknown bytes (0), "MM" or "II", another byte 0 and
275548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 * lastly 0x2A.
276548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	 */
277548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	n->version = exif_mnote_data_olympus_identify_variant(buf+o2, buf_size-o2);
278548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	switch (n->version) {
279548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case olympusV1:
280548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case sanyoV1:
281548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case epsonV1:
282548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
283548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			"Parsing Olympus/Sanyo/Epson maker note v1...");
284548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
285548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* The number of entries is at position 8. */
286548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (buf[o2 + 6] == 1)
287548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			n->order = EXIF_BYTE_ORDER_INTEL;
288548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		else if (buf[o2 + 6 + 1] == 1)
289548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			n->order = EXIF_BYTE_ORDER_MOTOROLA;
290548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 8;
291548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (o2 + 2 > buf_size) return;
292548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		c = exif_get_short (buf + o2, n->order);
293548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if ((!(c & 0xFF)) && (c > 0x500)) {
294548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			if (n->order == EXIF_BYTE_ORDER_INTEL) {
295548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				n->order = EXIF_BYTE_ORDER_MOTOROLA;
296548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			} else {
297548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				n->order = EXIF_BYTE_ORDER_INTEL;
298548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			}
299548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
300548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		break;
301548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
302548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case olympusV2:
303548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Olympus S760, S770 */
304548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		datao = o2;
305548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 8;
306548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
307548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			"Parsing Olympus maker note v2 (0x%02x, %02x, %02x, %02x)...",
308548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			buf[o2], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]);
309548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
310548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if ((buf[o2] == 'I') && (buf[o2 + 1] == 'I'))
311548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			n->order = EXIF_BYTE_ORDER_INTEL;
312548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		else if ((buf[o2] == 'M') && (buf[o2 + 1] == 'M'))
313548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			n->order = EXIF_BYTE_ORDER_MOTOROLA;
314548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
315548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* The number of entries is at position 8+4. */
316548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 4;
317548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		break;
318548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
319548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case nikonV1:
320548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 6;
321548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (o2 >= buf_size) return;
322548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
323548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			"Parsing Nikon maker note v1 (0x%02x, %02x, %02x, "
324548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			"%02x, %02x, %02x, %02x, %02x)...",
325548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
326548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
327548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
328548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Skip version number */
329548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 1;
330548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
331548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Skip an unknown byte (00 or 0A). */
332548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 1;
333548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
334548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		base = MNOTE_NIKON1_TAG_BASE;
335548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Fix endianness, if needed */
336548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (o2 + 2 > buf_size) return;
337548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		c = exif_get_short (buf + o2, n->order);
338548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if ((!(c & 0xFF)) && (c > 0x500)) {
339548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			if (n->order == EXIF_BYTE_ORDER_INTEL) {
340548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				n->order = EXIF_BYTE_ORDER_MOTOROLA;
341548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			} else {
342548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				n->order = EXIF_BYTE_ORDER_INTEL;
343548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			}
344548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
345548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		break;
346548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
347548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case nikonV2:
348548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 6;
349548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (o2 >= buf_size) return;
350548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
351548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			"Parsing Nikon maker note v2 (0x%02x, %02x, %02x, "
352548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			"%02x, %02x, %02x, %02x, %02x)...",
353548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
354548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
355548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
356548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Skip version number */
357548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 1;
358548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
359548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Skip an unknown byte (00 or 0A). */
360548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 1;
361548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
362548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Skip 2 unknown bytes (00 00). */
363548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 2;
364548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
365548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/*
366548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		 * Byte order. From here the data offset
367548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		 * gets calculated.
368548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		 */
369548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		datao = o2;
370548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (o2 >= buf_size) return;
371548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (!strncmp ((char *)&buf[o2], "II", 2))
372548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			n->order = EXIF_BYTE_ORDER_INTEL;
373548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		else if (!strncmp ((char *)&buf[o2], "MM", 2))
374548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			n->order = EXIF_BYTE_ORDER_MOTOROLA;
375548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		else {
376548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			exif_log (en->log, EXIF_LOG_CODE_DEBUG,
377548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				"ExifMnoteDataOlympus", "Unknown "
378548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				"byte order '%c%c'", buf[o2],
379548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				buf[o2 + 1]);
380548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			return;
381548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
382548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 2;
383548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
384548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Skip 2 unknown bytes (00 2A). */
385548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 += 2;
386548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
387548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Go to where the number of entries is. */
388548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (o2 + 4 > buf_size) return;
389548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		o2 = datao + exif_get_long (buf + o2, n->order);
390548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		break;
391548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
392548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	case nikonV0:
393548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
394548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			"Parsing Nikon maker note v0 (0x%02x, %02x, %02x, "
395548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			"%02x, %02x, %02x, %02x, %02x)...",
396548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
397548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
398548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* 00 1b is # of entries in Motorola order - the rest should also be in MM order */
399548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		n->order = EXIF_BYTE_ORDER_MOTOROLA;
400548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		break;
401548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
402548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	default:
403548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
404548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			"Unknown Olympus variant %i.", n->version);
405548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return;
406548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
407548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
408548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Sanity check the offset */
409548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if ((o2 + 2 < o2) || (o2 + 2 < 2) || (o2 + 2 > buf_size)) {
410548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
411548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			  "ExifMnoteOlympus", "Short MakerNote");
412548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return;
413548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
414548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
415548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Read the number of tags */
416548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	c = exif_get_short (buf + o2, n->order);
417548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	o2 += 2;
418548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
419548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Remove any old entries */
420548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_mnote_data_olympus_clear (n);
421548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
422548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Reserve enough space for all the possible MakerNote tags */
423548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	n->entries = exif_mem_alloc (en->mem, sizeof (MnoteOlympusEntry) * c);
424548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!n->entries) {
425548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", sizeof (MnoteOlympusEntry) * c);
426548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return;
427548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
428548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
429548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Parse all c entries, storing ones that are successfully parsed */
430548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	tcount = 0;
431548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	for (i = c, o = o2; i; --i, o += 12) {
432548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		size_t s;
433548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) {
434548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
435548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				  "ExifMnoteOlympus", "Short MakerNote");
436548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			break;
437548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
438548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
439548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	    n->entries[tcount].tag        = exif_get_short (buf + o, n->order) + base;
440548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	    n->entries[tcount].format     = exif_get_short (buf + o + 2, n->order);
441548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	    n->entries[tcount].components = exif_get_long (buf + o + 4, n->order);
442548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	    n->entries[tcount].order      = n->order;
443548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
444548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	    exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
445548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		      "Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
446548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		      mnote_olympus_tag_get_name (n->entries[tcount].tag));
447548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen/*	    exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
448548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			    "0x%x %d %ld*(%d)",
449548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		    n->entries[tcount].tag,
450548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		    n->entries[tcount].format,
451548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		    n->entries[tcount].components,
452548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		    (int)exif_format_get_size(n->entries[tcount].format)); */
453548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
454548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	    /*
455548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	     * Size? If bigger than 4 bytes, the actual data is not
456548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	     * in the entry but somewhere else (offset).
457548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	     */
458548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	    s = exif_format_get_size (n->entries[tcount].format) *
459548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		   			 n->entries[tcount].components;
460548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		n->entries[tcount].size = s;
461548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (s) {
462548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			size_t dataofs = o + 8;
463548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			if (s > 4) {
464548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				/* The data in this case is merely a pointer */
465548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				dataofs = exif_get_long (buf + dataofs, n->order) + datao;
466548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#ifdef EXIF_OVERCOME_SANYO_OFFSET_BUG
467548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				/* Some Sanyo models (e.g. VPC-C5, C40) suffer from a bug when
468548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				 * writing the offset for the MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE
469548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				 * tag in its MakerNote. The offset is actually the absolute
470548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				 * position in the file instead of the position within the IFD.
471548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				 */
472548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			    if (dataofs + s > buf_size && n->version == sanyoV1) {
473548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					/* fix pointer */
474548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					dataofs -= datao + 6;
475548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					exif_log (en->log, EXIF_LOG_CODE_DEBUG,
476548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen						  "ExifMnoteOlympus",
477548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen						  "Inconsistent thumbnail tag offset; attempting to recover");
478548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			    }
479548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen#endif
480548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			}
481548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			if ((dataofs + s < dataofs) || (dataofs + s < s) ||
482548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			    (dataofs + s > buf_size)) {
483548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				exif_log (en->log, EXIF_LOG_CODE_DEBUG,
484548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					  "ExifMnoteOlympus",
485548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					  "Tag data past end of buffer (%u > %u)",
486548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					  dataofs + s, buf_size);
487548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				continue;
488548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			}
489548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
490548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			n->entries[tcount].data = exif_mem_alloc (en->mem, s);
491548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			if (!n->entries[tcount].data) {
492548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", s);
493548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				continue;
494548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			}
495548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			memcpy (n->entries[tcount].data, buf + dataofs, s);
496548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
497548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
498548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Tag was successfully parsed */
499548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		++tcount;
500548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
501548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Store the count of successfully parsed tags */
502548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	n->count = tcount;
503548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
504548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
505548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic unsigned int
506548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_count (ExifMnoteData *n)
507548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
508548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return n ? ((ExifMnoteDataOlympus *) n)->count : 0;
509548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
510548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
511548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic unsigned int
512548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_get_id (ExifMnoteData *d, unsigned int n)
513548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
514548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMnoteDataOlympus *note = (ExifMnoteDataOlympus *) d;
515548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
516548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!note) return 0;
517548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (note->count <= n) return 0;
518548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return note->entries[n].tag;
519548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
520548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
521548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic const char *
522548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_get_name (ExifMnoteData *d, unsigned int i)
523548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
524548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
525548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
526548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!n) return NULL;
527548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (i >= n->count) return NULL;
528548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return mnote_olympus_tag_get_name (n->entries[i].tag);
529548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
530548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
531548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic const char *
532548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_get_title (ExifMnoteData *d, unsigned int i)
533548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
534548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
535548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
536548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!n) return NULL;
537548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (i >= n->count) return NULL;
538548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen        return mnote_olympus_tag_get_title (n->entries[i].tag);
539548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
540548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
541548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic const char *
542548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i)
543548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
544548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
545548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
546548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!n) return NULL;
547548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (i >= n->count) return NULL;
548548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen        return mnote_olympus_tag_get_description (n->entries[i].tag);
549548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
550548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
551548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void
552548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
553548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
554548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifByteOrder o_orig;
555548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
556548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	unsigned int i;
557548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
558548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!n) return;
559548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
560548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	o_orig = n->order;
561548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	n->order = o;
562548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	for (i = 0; i < n->count; i++) {
563548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		n->entries[i].order = o;
564548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		exif_array_set_byte_order (n->entries[i].format, n->entries[i].data,
565548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				n->entries[i].components, o_orig, o);
566548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
567548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
568548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
569548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic void
570548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_set_offset (ExifMnoteData *n, unsigned int o)
571548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
572548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (n) ((ExifMnoteDataOlympus *) n)->offset = o;
573548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
574548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
575548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenstatic enum OlympusVersion
576548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_identify_variant (const unsigned char *buf,
577548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		unsigned int buf_size)
578548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
579548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Olympus, Nikon, Sanyo, Epson */
580548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (buf_size >= 8) {
581548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* Match the terminating NUL character, too */
582548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (!memcmp (buf, "OLYMPUS", 8))
583548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			   return olympusV2;
584548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		else if (!memcmp (buf, "OLYMP", 6))
585548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			   return olympusV1;
586548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		else if (!memcmp (buf, "SANYO", 6))
587548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			   return sanyoV1;
588548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		else if (!memcmp (buf, "EPSON", 6))
589548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			   return epsonV1;
590548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		else if (!memcmp (buf, "Nikon", 6)) {
591548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			switch (buf[6]) {
592548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				case 1:  return nikonV1;
593548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				case 2:  return nikonV2;
594548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				default: return 0; /* Unrecognized Nikon variant */
595548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			}
596548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
597548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
598548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
599548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Another variant of Nikon */
600548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if ((buf_size >= 2) && (buf[0] == 0x00) && (buf[1] == 0x1b)) {
601548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		return nikonV0;
602548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
603548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
604548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return unrecognized;
605548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
606548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
607548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenint
608548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e)
609548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
610548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	int variant = exif_mnote_data_olympus_identify_variant(e->data, e->size);
611548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
612548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (variant == nikonV0) {
613548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		/* This variant needs some extra checking with the Make */
614548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		char value[5];
615548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE);
616548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		variant = unrecognized;
617548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
618548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		if (em) {
619548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			const char *v = exif_entry_get_value (em, value, sizeof(value));
620548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen			if (v && (!strncmp (v, "Nikon", sizeof(value)) ||
621548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen					  !strncmp (v, "NIKON", sizeof(value)) ))
622548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				/* When saved, this variant will be written out like the
623548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				 * alternative nikonV2 form above instead
624548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				 */
625548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen				variant = nikonV0;
626548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen		}
627548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	}
628548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
629548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return variant;
630548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
631548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
632548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
633548dde4863e9a2315e3f327efe63ff55949addb8Marco NelissenExifMnoteData *
634548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissenexif_mnote_data_olympus_new (ExifMem *mem)
635548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen{
636548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	ExifMnoteData *d;
637548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
638548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!mem) return NULL;
639548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
640548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d = exif_mem_alloc (mem, sizeof (ExifMnoteDataOlympus));
641548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	if (!d) return NULL;
642548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
643548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	exif_mnote_data_construct (d, mem);
644548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
645548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	/* Set up function pointers */
646548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d->methods.free            = exif_mnote_data_olympus_free;
647548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d->methods.set_byte_order  = exif_mnote_data_olympus_set_byte_order;
648548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d->methods.set_offset      = exif_mnote_data_olympus_set_offset;
649548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d->methods.load            = exif_mnote_data_olympus_load;
650548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d->methods.save            = exif_mnote_data_olympus_save;
651548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d->methods.count           = exif_mnote_data_olympus_count;
652548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d->methods.get_id          = exif_mnote_data_olympus_get_id;
653548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d->methods.get_name        = exif_mnote_data_olympus_get_name;
654548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d->methods.get_title       = exif_mnote_data_olympus_get_title;
655548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d->methods.get_description = exif_mnote_data_olympus_get_description;
656548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	d->methods.get_value       = exif_mnote_data_olympus_get_value;
657548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen
658548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen	return d;
659548dde4863e9a2315e3f327efe63ff55949addb8Marco Nelissen}
660