1 /* exif-mnote-data-olympus.c
3 * Copyright © 2002, 2003 Lutz Mueller <lutz@users.sourceforge.net>
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.
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.
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., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 #include "exif-mnote-data-olympus.h"
28 #include <libexif/exif-utils.h>
29 #include <libexif/exif-data.h>
34 exif_mnote_data_olympus_clear (ExifMnoteDataOlympus *n)
41 for (i = 0; i < n->count; i++)
42 if (n->entries[i].data) {
43 free (n->entries[i].data);
44 n->entries[i].data = NULL;
53 exif_mnote_data_olympus_free (ExifMnoteData *n)
57 exif_mnote_data_olympus_clear ((ExifMnoteDataOlympus *) n);
61 exif_mnote_data_olympus_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen)
63 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
66 if (n->count <= i) return NULL;
67 return mnote_olympus_entry_get_value (&n->entries[i], val, maxlen);
71 exif_mnote_data_olympus_save (ExifMnoteData *ne,
72 unsigned char **buf, unsigned int *buf_size)
74 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) ne;
75 unsigned int i, o, s, doff, base = 0, o2 = 6;
78 if (!n || !buf || !buf_size) return;
81 * Allocate enough memory for all entries and the number of entries.
83 *buf_size = 6 + 2 + 2 + n->count * 12;
86 *buf = malloc (*buf_size);
88 memset (*buf, 0, *buf_size);
90 /* Write the header and the number of entries. */
91 strcpy (*buf, "OLYMP");
95 case 1: /* Nikon v1 */
96 base = MNOTE_NIKON1_TAG_BASE;
99 case 2: /* Nikon v2 */
101 *buf = malloc (*buf_size);
103 memset (*buf, 0, *buf_size);
105 /* Write the header and the number of entries. */
106 strcpy (*buf, "Nikon");
107 (*buf)[6] = n->version;
108 o2 += 2; *buf_size += 2;
109 if (n->version == 2) {
110 exif_set_short (*buf + 10, n->order, (ExifShort) ((n->order == EXIF_BYTE_ORDER_INTEL) ? 'II' : 'MM'));
111 exif_set_short (*buf + 12, n->order, (ExifShort) 0x2A);
112 exif_set_long (*buf + 14, n->order, (ExifShort) 8);
119 exif_set_short (*buf + o2, n->order, (ExifShort) n->count);
122 /* Save each entry */
123 for (i = 0; i < n->count; i++) {
125 exif_set_short (*buf + o + 0, n->order,
126 (ExifShort) (n->entries[i].tag - base));
127 exif_set_short (*buf + o + 2, n->order,
128 (ExifShort) n->entries[i].format);
129 exif_set_long (*buf + o + 4, n->order,
130 n->entries[i].components);
132 s = exif_format_get_size (n->entries[i].format) *
133 n->entries[i].components;
137 *buf = realloc (*buf, *buf_size);
139 exif_set_long (*buf + o, n->order, datao + doff);
143 /* Write the data. */
144 if (n->entries[i].data) {
145 memcpy (*buf + doff, n->entries[i].data, s);
147 /* Most certainly damaged input file */
148 memset (*buf + doff, 0, s);
154 exif_mnote_data_olympus_load (ExifMnoteData *en,
155 const unsigned char *buf, unsigned int buf_size)
157 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en;
159 unsigned int i, s, o, o2, datao = 6, base = 0;
161 if (!n || !buf) return;
163 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
164 "Trying to parse Olympus/Nikon maker note...");
167 * Olympus headers start with "OLYMP" and need to have at least
168 * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the
169 * number of entries, and 12 for one entry.
171 * Nikon v1 headers start with "Nikon", 0, 1, 0, number_of_tags,
172 * or just with number_of_tags (models D1H, D1X...).
173 * Nikon v2 headers start with "Nikon", 0, 2, 0, 0, 0, "MM", 0, 0x2A
174 * or "Nikon", 0, 2, 0, 0, 0, "II", 0x2A, 0.
176 if (buf_size - n->offset < 22) return;
177 if (!memcmp (buf + 6 + n->offset, "OLYMP", 5)) {
178 o2 = 6 + n->offset + 8 + 2;
179 c = exif_get_short (buf + 6 + n->offset + 8, n->order);
181 } else if (!memcmp (buf + 6 + n->offset, "Nikon", 5)) {
182 o2 = 6 + n->offset + 8 + 2;
184 if (!memcmp(buf + o2 - 4, "\2\0\0\0II\x2A\0", 8)) {
185 n->order = EXIF_BYTE_ORDER_INTEL;
186 o2 += exif_get_long(buf + o2 + 4, n->order);
188 } else if (!memcmp(buf + o2 - 4, "\2\0\0\0MM\0\x2A", 8)) {
189 n->order = EXIF_BYTE_ORDER_MOTOROLA;
190 o2 += exif_get_long(buf + o2 + 4, n->order);
192 } else if (!memcmp(buf + o2 - 4, "\1\0", 2)) {
194 base = MNOTE_NIKON1_TAG_BASE;
199 if (o2 + 2 > buf_size) return;
200 c = exif_get_short (buf + o2, n->order);
202 } else if (!memcmp (buf + 6 + n->offset, "\0\x1b", 2)) {
204 c = exif_get_short (buf + o2, n->order);
211 /* Read the number of entries and remove old ones. */
212 exif_mnote_data_olympus_clear (n);
214 n->entries = malloc (sizeof (MnoteOlympusEntry) * c);
215 memset (n->entries, 0, sizeof (MnoteOlympusEntry) * c);
217 /* Parse the entries */
218 for (i = 0; i < c; i++) {
220 if (o + 12 > buf_size) return;
223 n->entries[i].tag = exif_get_short (buf + o, n->order) + base;
224 n->entries[i].format = exif_get_short (buf + o + 2, n->order);
225 n->entries[i].components = exif_get_long (buf + o + 4, n->order);
226 n->entries[i].order = n->order;
228 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
229 "Loading entry 0x%x ('%s')...", n->entries[i].tag,
230 mnote_olympus_tag_get_name (n->entries[i].tag));
233 * Size? If bigger than 4 bytes, the actual data is not
234 * in the entry but somewhere else (offset).
236 s = exif_format_get_size (n->entries[i].format) *
237 n->entries[i].components;
240 if (s > 4) o = exif_get_long (buf + o, n->order) + datao;
241 if (o + s > buf_size) continue;
244 n->entries[i].data = malloc (s);
245 if (!n->entries[i].data) continue;
246 n->entries[i].size = s;
247 memcpy (n->entries[i].data, buf + o, s);
252 exif_mnote_data_olympus_count (ExifMnoteData *n)
254 return n ? ((ExifMnoteDataOlympus *) n)->count : 0;
258 exif_mnote_data_olympus_get_name (ExifMnoteData *d, unsigned int i)
260 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
263 if (i >= n->count) return NULL;
264 return mnote_olympus_tag_get_title (n->entries[i].tag);
268 exif_mnote_data_olympus_get_title (ExifMnoteData *d, unsigned int i)
270 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
273 if (i >= n->count) return NULL;
274 return mnote_olympus_tag_get_title (n->entries[i].tag);
278 exif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i)
280 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
283 if (i >= n->count) return NULL;
284 return mnote_olympus_tag_get_title (n->entries[i].tag);
288 exif_mnote_data_olympus_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
290 ExifByteOrder o_orig;
291 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
303 for (i = 0; i < n->count; i++) {
304 n->entries[i].order = o;
305 fs = exif_format_get_size (n->entries[i].format);
306 switch (n->entries[i].format) {
307 case EXIF_FORMAT_SHORT:
308 for (i = 0; i < n->entries[i].components; i++) {
309 s = exif_get_short (n->entries[i].data + (i*fs),
311 exif_set_short (n->entries[i].data + (i * fs),
315 case EXIF_FORMAT_LONG:
316 for (i = 0; i < n->entries[i].components; i++) {
317 l = exif_get_long (n->entries[i].data + (i*fs),
319 exif_set_long (n->entries[i].data + (i * fs),
323 case EXIF_FORMAT_RATIONAL:
324 for (i = 0; i < n->entries[i].components; i++) {
325 r = exif_get_rational (n->entries[i].data +
327 exif_set_rational (n->entries[i].data +
331 case EXIF_FORMAT_SLONG:
332 for (i = 0; i < n->entries[i].components; i++) {
333 sl = exif_get_slong (n->entries[i].data +
335 exif_set_slong (n->entries[i].data +
339 case EXIF_FORMAT_SRATIONAL:
340 for (i = 0; i < n->entries[i].components; i++) {
341 sr = exif_get_srational (n->entries[i].data +
343 exif_set_srational (n->entries[i].data +
347 case EXIF_FORMAT_UNDEFINED:
348 case EXIF_FORMAT_BYTE:
349 case EXIF_FORMAT_ASCII:
358 exif_mnote_data_olympus_set_offset (ExifMnoteData *n, unsigned int o)
360 if (n) ((ExifMnoteDataOlympus *) n)->offset = o;
364 exif_mnote_data_olympus_new (void)
368 n = malloc (sizeof (ExifMnoteDataOlympus));
370 memset (n, 0, sizeof (ExifMnoteDataOlympus));
372 exif_mnote_data_construct (n);
374 /* Set up the function pointers */
375 n->methods.free = exif_mnote_data_olympus_free;
376 n->methods.set_byte_order = exif_mnote_data_olympus_set_byte_order;
377 n->methods.set_offset = exif_mnote_data_olympus_set_offset;
378 n->methods.load = exif_mnote_data_olympus_load;
379 n->methods.save = exif_mnote_data_olympus_save;
380 n->methods.count = exif_mnote_data_olympus_count;
381 n->methods.get_name = exif_mnote_data_olympus_get_name;
382 n->methods.get_title = exif_mnote_data_olympus_get_title;
383 n->methods.get_description = exif_mnote_data_olympus_get_description;
384 n->methods.get_value = exif_mnote_data_olympus_get_value;