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;
77 if (!n || !buf || !buf_size) return;
80 * Allocate enough memory for all entries and the number of entries.
82 *buf_size = 6 + 2 + 2 + n->count * 12;
83 *buf = malloc (*buf_size);
85 memset (*buf, 0, *buf_size);
87 /* Write the header and the number of entries. */
88 strcpy (*buf, "OLYMP");
89 exif_set_short (*buf + 8, n->order, (ExifShort) n->count);
92 for (i = 0; i < n->count; i++) {
93 o = 6 + 2 + 2 + i * 12;
94 exif_set_short (*buf + o + 0, n->order,
95 (ExifShort) n->entries[i].tag);
96 exif_set_short (*buf + o + 2, n->order,
97 (ExifShort) n->entries[i].format);
98 exif_set_long (*buf + o + 4, n->order,
99 n->entries[i].components);
101 s = exif_format_get_size (n->entries[i].format) *
102 n->entries[i].components;
105 *buf = realloc (*buf, *buf_size);
107 doff = *buf_size - s;
108 exif_set_long (*buf + o, n->order, n->offset + doff);
112 /* Write the data. */
113 memcpy (*buf + doff, n->entries[i].data, s);
118 exif_mnote_data_olympus_load (ExifMnoteData *en,
119 const unsigned char *buf, unsigned int buf_size)
121 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en;
123 unsigned int i, s, o;
125 if (!n || !buf) return;
128 * Olympus headers start with "OLYMP" and need to have at least
129 * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the
130 * number of entries, and 12 for one entry.
132 if (buf_size - n->offset < 22) return;
133 if (memcmp (buf + 6 + n->offset, "OLYMP", 5)) return;
135 /* Read the number of entries and remove old ones. */
136 c = exif_get_short (buf + 6 + n->offset + 8, n->order);
137 exif_mnote_data_olympus_clear (n);
139 n->entries = malloc (sizeof (MnoteOlympusEntry) * c);
140 memset (n->entries, 0, sizeof (MnoteOlympusEntry) * c);
142 /* Parse the entries */
143 for (i = 0; i < c; i++) {
144 o = 6 + n->offset + 8 + 2 + 12 * i;
145 if (o + 12 > buf_size) return;
148 n->entries[i].tag = exif_get_short (buf + o, n->order);
149 n->entries[i].format = exif_get_short (buf + o + 2, n->order);
150 n->entries[i].components = exif_get_long (buf + o + 4, n->order);
151 n->entries[i].order = n->order;
154 * Size? If bigger than 4 bytes, the actual data is not
155 * in the entry but somewhere else (offset).
157 s = exif_format_get_size (n->entries[i].format) *
158 n->entries[i].components;
161 if (s > 4) o = exif_get_long (buf + o, n->order) + 6;
162 if (o + s > buf_size) return;
165 n->entries[i].data = malloc (s);
166 if (!n->entries[i].data) return;
167 n->entries[i].size = s;
168 memcpy (n->entries[i].data, buf + o, s);
173 exif_mnote_data_olympus_count (ExifMnoteData *n)
175 return n ? ((ExifMnoteDataOlympus *) n)->count : 0;
179 exif_mnote_data_olympus_get_name (ExifMnoteData *d, unsigned int i)
181 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
184 if (i >= n->count) return NULL;
185 return mnote_olympus_tag_get_title (n->entries[i].tag);
189 exif_mnote_data_olympus_get_title (ExifMnoteData *d, unsigned int i)
191 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
194 if (i >= n->count) return NULL;
195 return mnote_olympus_tag_get_title (n->entries[i].tag);
199 exif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i)
201 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
204 if (i >= n->count) return NULL;
205 return mnote_olympus_tag_get_title (n->entries[i].tag);
209 exif_mnote_data_olympus_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
211 ExifByteOrder o_orig;
212 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
224 for (i = 0; i < n->count; i++) {
225 n->entries[i].order = o;
226 fs = exif_format_get_size (n->entries[i].format);
227 switch (n->entries[i].format) {
228 case EXIF_FORMAT_SHORT:
229 for (i = 0; i < n->entries[i].components; i++) {
230 s = exif_get_short (n->entries[i].data + (i*fs),
232 exif_set_short (n->entries[i].data + (i * fs),
236 case EXIF_FORMAT_LONG:
237 for (i = 0; i < n->entries[i].components; i++) {
238 l = exif_get_long (n->entries[i].data + (i*fs),
240 exif_set_long (n->entries[i].data + (i * fs),
244 case EXIF_FORMAT_RATIONAL:
245 for (i = 0; i < n->entries[i].components; i++) {
246 r = exif_get_rational (n->entries[i].data +
248 exif_set_rational (n->entries[i].data +
252 case EXIF_FORMAT_SLONG:
253 for (i = 0; i < n->entries[i].components; i++) {
254 sl = exif_get_slong (n->entries[i].data +
256 exif_set_slong (n->entries[i].data +
260 case EXIF_FORMAT_SRATIONAL:
261 for (i = 0; i < n->entries[i].components; i++) {
262 sr = exif_get_srational (n->entries[i].data +
264 exif_set_srational (n->entries[i].data +
268 case EXIF_FORMAT_UNDEFINED:
269 case EXIF_FORMAT_BYTE:
270 case EXIF_FORMAT_ASCII:
279 exif_mnote_data_olympus_set_offset (ExifMnoteData *n, unsigned int o)
281 if (n) ((ExifMnoteDataOlympus *) n)->offset = o;
285 exif_mnote_data_olympus_new (void)
289 n = malloc (sizeof (ExifMnoteDataOlympus));
291 memset (n, 0, sizeof (ExifMnoteDataOlympus));
293 exif_mnote_data_construct (n);
295 /* Set up the function pointers */
296 n->methods.free = exif_mnote_data_olympus_free;
297 n->methods.set_byte_order = exif_mnote_data_olympus_set_byte_order;
298 n->methods.set_offset = exif_mnote_data_olympus_set_offset;
299 n->methods.load = exif_mnote_data_olympus_load;
300 n->methods.save = exif_mnote_data_olympus_save;
301 n->methods.count = exif_mnote_data_olympus_count;
302 n->methods.get_name = exif_mnote_data_olympus_get_name;
303 n->methods.get_title = exif_mnote_data_olympus_get_title;
304 n->methods.get_description = exif_mnote_data_olympus_get_description;
305 n->methods.get_value = exif_mnote_data_olympus_get_value;