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 exif_log (d->log, EXIF_LOG_CODE_DEBUG, "MnoteDataOlympus",
68 "Querying value for tag '%s'...",
69 mnote_olympus_tag_get_name (n->entries[i].tag));
70 return mnote_olympus_entry_get_value (&n->entries[i], val, maxlen);
74 exif_mnote_data_olympus_save (ExifMnoteData *ne,
75 unsigned char **buf, unsigned int *buf_size)
77 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) ne;
78 unsigned int i, o, s, doff, base = 0, o2 = 6;
81 if (!n || !buf || !buf_size) return;
84 * Allocate enough memory for all entries and the number of entries.
86 *buf_size = 6 + 2 + 2 + n->count * 12;
89 *buf = malloc (*buf_size);
91 memset (*buf, 0, *buf_size);
93 /* Write the header and the number of entries. */
94 strcpy (*buf, "OLYMP");
98 case 1: /* Nikon v1 */
99 base = MNOTE_NIKON1_TAG_BASE;
102 case 2: /* Nikon v2 */
104 *buf = malloc (*buf_size);
106 memset (*buf, 0, *buf_size);
108 /* Write the header and the number of entries. */
109 strcpy (*buf, "Nikon");
110 (*buf)[6] = n->version;
111 o2 += 2; *buf_size += 2;
112 if (n->version == 2) {
113 exif_set_short (*buf + 10, n->order, (ExifShort) ((n->order == EXIF_BYTE_ORDER_INTEL) ? 'II' : 'MM'));
114 exif_set_short (*buf + 12, n->order, (ExifShort) 0x2A);
115 exif_set_long (*buf + 14, n->order, (ExifShort) 8);
122 exif_set_short (*buf + o2, n->order, (ExifShort) n->count);
125 /* Save each entry */
126 for (i = 0; i < n->count; i++) {
128 exif_set_short (*buf + o + 0, n->order,
129 (ExifShort) (n->entries[i].tag - base));
130 exif_set_short (*buf + o + 2, n->order,
131 (ExifShort) n->entries[i].format);
132 exif_set_long (*buf + o + 4, n->order,
133 n->entries[i].components);
135 s = exif_format_get_size (n->entries[i].format) *
136 n->entries[i].components;
140 *buf = realloc (*buf, *buf_size);
142 exif_set_long (*buf + o, n->order, datao + doff);
146 /* Write the data. */
147 if (n->entries[i].data) {
148 memcpy (*buf + doff, n->entries[i].data, s);
150 /* Most certainly damaged input file */
151 memset (*buf + doff, 0, s);
157 exif_mnote_data_olympus_load (ExifMnoteData *en,
158 const unsigned char *buf, unsigned int buf_size)
160 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en;
162 unsigned int i, s, o, o2, datao = 6, base = 0;
164 if (!n || !buf) return;
166 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
167 "Trying to parse Olympus/Nikon maker note...");
170 * Olympus headers start with "OLYMP" and need to have at least
171 * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the
172 * number of entries, and 12 for one entry.
174 * Nikon v1 headers start with "Nikon", 0, 1, 0, number_of_tags,
175 * or just with number_of_tags (models D1H, D1X...).
176 * Nikon v2 headers start with "Nikon", 0, 2, 0, 0, 0, "MM", 0, 0x2A
177 * or "Nikon", 0, 2, 0, 0, 0, "II", 0x2A, 0.
179 if (buf_size - n->offset < 22) return;
180 if (!memcmp (buf + 6 + n->offset, "OLYMP", 5)) {
181 o2 = 6 + n->offset + 8 + 2;
182 c = exif_get_short (buf + 6 + n->offset + 8, n->order);
184 } else if (!memcmp (buf + 6 + n->offset, "Nikon", 5)) {
185 o2 = 6 + n->offset + 8 + 2;
187 if (!memcmp(buf + o2 - 4, "\2\0\0\0II\x2A\0", 8)) {
188 n->order = EXIF_BYTE_ORDER_INTEL;
189 o2 += exif_get_long(buf + o2 + 4, n->order);
191 } else if (!memcmp(buf + o2 - 4, "\2\0\0\0MM\0\x2A", 8)) {
192 n->order = EXIF_BYTE_ORDER_MOTOROLA;
193 o2 += exif_get_long(buf + o2 + 4, n->order);
195 } else if (!memcmp(buf + o2 - 4, "\1\0", 2)) {
197 base = MNOTE_NIKON1_TAG_BASE;
202 if (o2 + 2 > buf_size) return;
203 c = exif_get_short (buf + o2, n->order);
205 } else if (!memcmp (buf + 6 + n->offset, "\0\x1b", 2)) {
207 c = exif_get_short (buf + o2, n->order);
214 /* Read the number of entries and remove old ones. */
215 exif_mnote_data_olympus_clear (n);
217 n->entries = malloc (sizeof (MnoteOlympusEntry) * c);
218 memset (n->entries, 0, sizeof (MnoteOlympusEntry) * c);
220 /* Parse the entries */
221 for (i = 0; i < c; i++) {
223 if (o + 12 > buf_size) return;
226 n->entries[i].tag = exif_get_short (buf + o, n->order) + base;
227 n->entries[i].format = exif_get_short (buf + o + 2, n->order);
228 n->entries[i].components = exif_get_long (buf + o + 4, n->order);
229 n->entries[i].order = n->order;
231 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
232 "Loading entry 0x%x ('%s')...", n->entries[i].tag,
233 mnote_olympus_tag_get_name (n->entries[i].tag));
236 * Size? If bigger than 4 bytes, the actual data is not
237 * in the entry but somewhere else (offset).
239 s = exif_format_get_size (n->entries[i].format) *
240 n->entries[i].components;
243 if (s > 4) o = exif_get_long (buf + o, n->order) + datao;
244 if (o + s > buf_size) continue;
247 n->entries[i].data = malloc (s);
248 if (!n->entries[i].data) continue;
249 n->entries[i].size = s;
250 memcpy (n->entries[i].data, buf + o, s);
255 exif_mnote_data_olympus_count (ExifMnoteData *n)
257 return n ? ((ExifMnoteDataOlympus *) n)->count : 0;
261 exif_mnote_data_olympus_get_name (ExifMnoteData *d, unsigned int i)
263 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
266 if (i >= n->count) return NULL;
267 return mnote_olympus_tag_get_title (n->entries[i].tag);
271 exif_mnote_data_olympus_get_title (ExifMnoteData *d, unsigned int i)
273 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
276 if (i >= n->count) return NULL;
277 return mnote_olympus_tag_get_title (n->entries[i].tag);
281 exif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i)
283 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
286 if (i >= n->count) return NULL;
287 return mnote_olympus_tag_get_title (n->entries[i].tag);
291 exif_mnote_data_olympus_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
293 ExifByteOrder o_orig;
294 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
306 for (i = 0; i < n->count; i++) {
307 n->entries[i].order = o;
308 fs = exif_format_get_size (n->entries[i].format);
309 switch (n->entries[i].format) {
310 case EXIF_FORMAT_SHORT:
311 for (i = 0; i < n->entries[i].components; i++) {
312 s = exif_get_short (n->entries[i].data + (i*fs),
314 exif_set_short (n->entries[i].data + (i * fs),
318 case EXIF_FORMAT_LONG:
319 for (i = 0; i < n->entries[i].components; i++) {
320 l = exif_get_long (n->entries[i].data + (i*fs),
322 exif_set_long (n->entries[i].data + (i * fs),
326 case EXIF_FORMAT_RATIONAL:
327 for (i = 0; i < n->entries[i].components; i++) {
328 r = exif_get_rational (n->entries[i].data +
330 exif_set_rational (n->entries[i].data +
334 case EXIF_FORMAT_SLONG:
335 for (i = 0; i < n->entries[i].components; i++) {
336 sl = exif_get_slong (n->entries[i].data +
338 exif_set_slong (n->entries[i].data +
342 case EXIF_FORMAT_SRATIONAL:
343 for (i = 0; i < n->entries[i].components; i++) {
344 sr = exif_get_srational (n->entries[i].data +
346 exif_set_srational (n->entries[i].data +
350 case EXIF_FORMAT_UNDEFINED:
351 case EXIF_FORMAT_BYTE:
352 case EXIF_FORMAT_ASCII:
361 exif_mnote_data_olympus_set_offset (ExifMnoteData *n, unsigned int o)
363 if (n) ((ExifMnoteDataOlympus *) n)->offset = o;
367 exif_mnote_data_olympus_new (void)
371 n = malloc (sizeof (ExifMnoteDataOlympus));
373 memset (n, 0, sizeof (ExifMnoteDataOlympus));
375 exif_mnote_data_construct (n);
377 /* Set up the function pointers */
378 n->methods.free = exif_mnote_data_olympus_free;
379 n->methods.set_byte_order = exif_mnote_data_olympus_set_byte_order;
380 n->methods.set_offset = exif_mnote_data_olympus_set_offset;
381 n->methods.load = exif_mnote_data_olympus_load;
382 n->methods.save = exif_mnote_data_olympus_save;
383 n->methods.count = exif_mnote_data_olympus_count;
384 n->methods.get_name = exif_mnote_data_olympus_get_name;
385 n->methods.get_title = exif_mnote_data_olympus_get_title;
386 n->methods.get_description = exif_mnote_data_olympus_get_description;
387 n->methods.get_value = exif_mnote_data_olympus_get_value;