EXIF library (libexif) Internals 0.6.26
exif-mnote-data-olympus.c
Go to the documentation of this file.
1/* exif-mnote-data-olympus.c
2 *
3 * Copyright (c) 2002, 2003 Lutz Mueller <lutz@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 * SPDX-License-Identifier: LGPL-2.0-or-later
21 */
22
23#include <config.h>
25
26#include <stdlib.h>
27#include <string.h>
28#include <stdio.h>
29
30#include <libexif/exif-utils.h>
31#include <libexif/exif-data.h>
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#define CHECKOVERFLOW(offset,datasize,structsize) (( (offset) >= (datasize)) || ((structsize) > (datasize)) || ((offset) > (datasize) - (structsize) ))
41
42static enum OlympusVersion
43exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
44 unsigned int buf_size);
45
46
47static void
49{
51 unsigned int i;
52
53 if (!n) return;
54
55 if (n->entries) {
56 for (i = 0; i < n->count; i++)
57 if (n->entries[i].data) {
58 exif_mem_free (d->mem, n->entries[i].data);
59 n->entries[i].data = NULL;
60 }
61 exif_mem_free (d->mem, n->entries);
62 n->entries = NULL;
63 n->count = 0;
64 }
65}
66
67static void
69{
70 if (!n) return;
71
73}
74
75static char *
76exif_mnote_data_olympus_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen)
77{
79
80 if (!d || !val) return NULL;
81 if (i >= n->count) return NULL;
82/*
83 exif_log (d->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
84 "Querying value for tag '%s'...",
85 mnote_olympus_tag_get_name (n->entries[i].tag));
86*/
87 return mnote_olympus_entry_get_value (&n->entries[i], val, maxlen);
88}
89
90
91
92
100static void
102 unsigned char **buf, unsigned int *buf_size)
103{
105 size_t i, o, s, doff, base = 0, o2 = 6 + 2;
106 size_t datao = 0;
107 unsigned char *t;
108 size_t ts;
109
110 if (!n || !buf || !buf_size) return;
111
112 /*
113 * Allocate enough memory for all entries and the number of entries.
114 */
115 *buf_size = 6 + 2 + 2 + n->count * 12;
116 switch (n->version) {
117 case olympusV1:
118 case sanyoV1:
119 case epsonV1:
120 *buf = exif_mem_alloc (ne->mem, *buf_size);
121 if (!*buf) {
122 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
123 return;
124 }
125
126 /* Write the header and the number of entries. */
127 strcpy ((char *)*buf, n->version==sanyoV1?"SANYO":
128 (n->version==epsonV1?"EPSON":"OLYMP"));
129 exif_set_short (*buf + 6, n->order, (ExifShort) 1);
130 datao = n->offset;
131 break;
132
133 case olympusV2:
134 *buf_size += 8-6 + 4;
135 *buf = exif_mem_alloc (ne->mem, *buf_size);
136 if (!*buf) {
137 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
138 return;
139 }
140
141 /* Write the header and the number of entries. */
142 strcpy ((char *)*buf, "OLYMPUS");
143 exif_set_short (*buf + 8, n->order, (ExifShort) (
145 ('I' << 8) | 'I' :
146 ('M' << 8) | 'M'));
147 exif_set_short (*buf + 10, n->order, (ExifShort) 3);
148 o2 += 4;
149 break;
150
151 case nikonV1:
153
154 /* v1 has offsets based to main IFD, not makernote IFD */
155 datao += n->offset + 10;
156 /* subtract the size here, so the increment in the next case will not harm us */
157 *buf_size -= 8 + 2;
158 /* fall through */
159 /* Fall through to nikonV2 handler */
160 case nikonV2:
161 /* Write out V0 files in V2 format */
162 case nikonV0:
163 *buf_size += 8 + 2;
164 *buf_size += 4; /* Next IFD pointer */
165 *buf = exif_mem_alloc (ne->mem, *buf_size);
166 if (!*buf) {
167 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
168 return;
169 }
170
171 /* Write the header and the number of entries. */
172 strcpy ((char *)*buf, "Nikon");
173 (*buf)[6] = (unsigned char)n->version;
174
175 if (n->version != nikonV1) {
176 exif_set_short (*buf + 10, n->order, (ExifShort) (
178 ('I' << 8) | 'I' :
179 ('M' << 8) | 'M'));
180 exif_set_short (*buf + 12, n->order, (ExifShort) 0x2A);
181 exif_set_long (*buf + 14, n->order, (ExifShort) 8);
182 o2 += 2 + 8;
183 }
184 datao -= 10;
185 /* Reset next IFD pointer */
186 exif_set_long (*buf + o2 + 2 + n->count * 12, n->order, 0);
187 break;
188
189 default:
190 return;
191 }
192
193 exif_set_short (*buf + o2, n->order, (ExifShort) n->count);
194 o2 += 2;
195
196 /* Save each entry */
197 for (i = 0; i < n->count; i++) {
198 o = o2 + i * 12;
199 exif_set_short (*buf + o + 0, n->order,
200 (ExifShort) (n->entries[i].tag - base));
201 exif_set_short (*buf + o + 2, n->order,
202 (ExifShort) n->entries[i].format);
203 exif_set_long (*buf + o + 4, n->order,
204 n->entries[i].components);
205 o += 8;
207 n->entries[i].components;
208 if (s > 65536) {
209 /* Corrupt data: EXIF data size is limited to the
210 * maximum size of a JPEG segment (64 kb).
211 */
212 continue;
213 }
214 if (s > 4) {
215 doff = *buf_size;
216 ts = *buf_size + s;
217 t = exif_mem_realloc (ne->mem, *buf,
218 sizeof (char) * ts);
219 if (!t) {
220 EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", ts);
221 return;
222 }
223 *buf = t;
224 *buf_size = ts;
225 exif_set_long (*buf + o, n->order, datao + doff);
226 } else
227 doff = o;
228
229 /* Write the data. */
230 if (n->entries[i].data) {
231 memcpy (*buf + doff, n->entries[i].data, s);
232 } else {
233 /* Most certainly damaged input file */
234 memset (*buf + doff, 0, s);
235 }
236 }
237}
238
239static void
241 const unsigned char *buf, unsigned int buf_size)
242{
244 ExifShort c;
245 size_t i, tcount, o, o2, datao = 6, base = 0;
246
247 if (!n) return;
248
249 if (!buf || !buf_size) {
251 "ExifMnoteDataOlympus", "Short MakerNote");
252 return;
253 }
254 o2 = 6 + n->offset; /* Start of interesting data */
255 if (CHECKOVERFLOW(o2,buf_size,10)) {
257 "ExifMnoteDataOlympus", "Short MakerNote");
258 return;
259 }
260
261 /*
262 * Olympus headers start with "OLYMP" and need to have at least
263 * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the
264 * number of entries, and 12 for one entry.
265 *
266 * Sanyo format is identical and uses identical tags except that
267 * header starts with "SANYO".
268 *
269 * Epson format is identical and uses identical tags except that
270 * header starts with "EPSON".
271 *
272 * Nikon headers start with "Nikon" (6 bytes including '\0'),
273 * version number (1 or 2).
274 *
275 * Version 1 continues with 0, 1, 0, number_of_tags,
276 * or just with number_of_tags (models D1H, D1X...).
277 *
278 * Version 2 continues with an unknown byte (0 or 10),
279 * two unknown bytes (0), "MM" or "II", another byte 0 and
280 * lastly 0x2A.
281 */
282 n->version = exif_mnote_data_olympus_identify_variant(buf+o2, buf_size-o2);
283 switch (n->version) {
284 case olympusV1:
285 case sanyoV1:
286 case epsonV1:
287 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
288 "Parsing Olympus/Sanyo/Epson maker note v1...");
289
290 /* The number of entries is at position 8. */
291 if (buf[o2 + 6] == 1)
293 else if (buf[o2 + 6 + 1] == 1)
295 o2 += 8;
296 c = exif_get_short (buf + o2, n->order);
297 if ((!(c & 0xFF)) && (c > 0x500)) {
298 if (n->order == EXIF_BYTE_ORDER_INTEL) {
300 } else {
302 }
303 }
304 break;
305
306 case olympusV2:
307 /* Olympus S760, S770 */
308 datao = o2;
309 o2 += 8;
310 if (CHECKOVERFLOW(o2,buf_size,4)) return;
311 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
312 "Parsing Olympus maker note v2 (0x%02x, %02x, %02x, %02x)...",
313 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]);
314
315 if ((buf[o2] == 'I') && (buf[o2 + 1] == 'I'))
317 else if ((buf[o2] == 'M') && (buf[o2 + 1] == 'M'))
319
320 /* The number of entries is at position 8+4. */
321 o2 += 4;
322 break;
323
324 case nikonV1:
325 o2 += 6;
326 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
327 "Parsing Nikon maker note v1 (0x%02x, %02x, %02x, "
328 "%02x)...",
329 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]);
330
331 /* Skip version number */
332 o2 += 1;
333
334 /* Skip an unknown byte (00 or 0A). */
335 o2 += 1;
336
338 /* Fix endianness, if needed */
339 c = exif_get_short (buf + o2, n->order);
340 if ((!(c & 0xFF)) && (c > 0x500)) {
341 if (n->order == EXIF_BYTE_ORDER_INTEL) {
343 } else {
345 }
346 }
347 break;
348
349 case nikonV2:
350 o2 += 6;
351 if (CHECKOVERFLOW(o2,buf_size,12)) return;
352 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
353 "Parsing Nikon maker note v2 (0x%02x, %02x, %02x, "
354 "%02x, %02x, %02x, %02x, %02x)...",
355 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
356 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
357
358 /* Skip version number */
359 o2 += 1;
360
361 /* Skip an unknown byte (00 or 0A). */
362 o2 += 1;
363
364 /* Skip 2 unknown bytes (00 00). */
365 o2 += 2;
366
367 /*
368 * Byte order. From here the data offset
369 * gets calculated.
370 */
371 datao = o2;
372 if (!strncmp ((char *)&buf[o2], "II", 2))
374 else if (!strncmp ((char *)&buf[o2], "MM", 2))
376 else {
378 "ExifMnoteDataOlympus", "Unknown "
379 "byte order '%c%c'", buf[o2],
380 buf[o2 + 1]);
381 return;
382 }
383 o2 += 2;
384
385 /* Skip 2 unknown bytes (00 2A). */
386 o2 += 2;
387
388 /* Go to where the number of entries is. */
389 if (CHECKOVERFLOW(o2,buf_size,exif_get_long (buf + o2, n->order))) return;
390 o2 = datao + exif_get_long (buf + o2, n->order);
391 break;
392
393 case nikonV0:
394 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
395 "Parsing Nikon maker note v0 (0x%02x, %02x, %02x, "
396 "%02x, %02x, %02x, %02x, %02x)...",
397 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
398 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
399 /* 00 1b is # of entries in Motorola order - the rest should also be in MM order */
401 break;
402
403 default:
404 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
405 "Unknown Olympus variant %i.", n->version);
406 return;
407 }
408
409 /* Sanity check the offset */
410 if (CHECKOVERFLOW(o2,buf_size,2)) {
412 "ExifMnoteOlympus", "Short MakerNote");
413 return;
414 }
415
416 /* Read the number of tags */
417 c = exif_get_short (buf + o2, n->order);
418 o2 += 2;
419
420 /* Just use an arbitrary max tag limit here to avoid needing to much memory or time. There are 150 named tags currently.
421 * The format allows specifying the same range of memory as often as it can, so this multiplies quickly. */
422 if (c > 300) {
423 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifMnoteOlympus", "Too much tags (%d) in Olympus MakerNote", c);
424 return;
425 }
426
427 /* Remove any old entries */
429
430 /* Reserve enough space for all the possible MakerNote tags */
431 n->entries = exif_mem_alloc (en->mem, sizeof (MnoteOlympusEntry) * c);
432 if (!n->entries) {
433 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", sizeof (MnoteOlympusEntry) * c);
434 return;
435 }
436
437 /* Parse all c entries, storing ones that are successfully parsed */
438 tcount = 0;
439 for (i = c, o = o2; i; --i, o += 12) {
440 size_t s;
441 memset(&n->entries[tcount], 0, sizeof(MnoteOlympusEntry));
442 if (CHECKOVERFLOW(o, buf_size, 12)) {
444 "ExifMnoteOlympus", "Short MakerNote");
445 break;
446 }
447
448 n->entries[tcount].tag = exif_get_short (buf + o, n->order) + base;
449 n->entries[tcount].format = exif_get_short (buf + o + 2, n->order);
450 n->entries[tcount].components = exif_get_long (buf + o + 4, n->order);
451 n->entries[tcount].order = n->order;
452
453 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
454 "Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
456/* exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
457 "0x%x %d %ld*(%d)",
458 n->entries[tcount].tag,
459 n->entries[tcount].format,
460 n->entries[tcount].components,
461 (int)exif_format_get_size(n->entries[tcount].format)); */
462
463 /* Check if we overflow the multiplication. Use buf_size as the max size for integer overflow detection,
464 * we will check the buffer sizes closer later. */
465 if (exif_format_get_size (n->entries[tcount].format) &&
466 buf_size / exif_format_get_size (n->entries[tcount].format) < n->entries[tcount].components
467 ) {
468 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifMnoteOlympus", "Tag size overflow detected (%u * %lu)", exif_format_get_size (n->entries[tcount].format), n->entries[tcount].components);
469 continue;
470 }
471 /*
472 * Size? If bigger than 4 bytes, the actual data is not
473 * in the entry but somewhere else (offset).
474 */
475 s = exif_format_get_size (n->entries[tcount].format) *
476 n->entries[tcount].components;
477 n->entries[tcount].size = s;
478 if (s) {
479 size_t dataofs = o + 8;
480 if (s > 4) {
481 /* The data in this case is merely a pointer */
482 dataofs = exif_get_long (buf + dataofs, n->order) + datao;
483#ifdef EXIF_OVERCOME_SANYO_OFFSET_BUG
484 /* Some Sanyo models (e.g. VPC-C5, C40) suffer from a bug when
485 * writing the offset for the MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE
486 * tag in its MakerNote. The offset is actually the absolute
487 * position in the file instead of the position within the IFD.
488 */
489 if (dataofs > (buf_size - s) && n->version == sanyoV1) {
490 /* fix pointer */
491 dataofs -= datao + 6;
493 "ExifMnoteOlympus",
494 "Inconsistent thumbnail tag offset; attempting to recover");
495 }
496#endif
497 }
498 if (CHECKOVERFLOW(dataofs, buf_size, s)) {
500 "ExifMnoteOlympus",
501 "Tag data past end of buffer (%u > %u)",
502 (unsigned)(dataofs + s), buf_size);
503 continue;
504 }
505
506 n->entries[tcount].data = exif_mem_alloc (en->mem, s);
507 if (!n->entries[tcount].data) {
508 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", s);
509 continue;
510 }
511 memcpy (n->entries[tcount].data, buf + dataofs, s);
512 }
513
514 /* Tag was successfully parsed */
515 ++tcount;
516 }
517 /* Store the count of successfully parsed tags */
518 n->count = tcount;
519}
520
521static unsigned int
523{
524 return n ? ((ExifMnoteDataOlympus *) n)->count : 0;
525}
526
527static unsigned int
529{
531
532 if (!note) return 0;
533 if (note->count <= n) return 0;
534 return note->entries[n].tag;
535}
536
537static const char *
539{
541
542 if (!n) return NULL;
543 if (i >= n->count) return NULL;
545}
546
547static const char *
549{
551
552 if (!n) return NULL;
553 if (i >= n->count) return NULL;
555}
556
557static const char *
559{
561
562 if (!n) return NULL;
563 if (i >= n->count) return NULL;
565}
566
567static void
569{
570 ExifByteOrder o_orig;
572 unsigned int i;
573
574 if (!n) return;
575
576 o_orig = n->order;
577 n->order = o;
578 for (i = 0; i < n->count; i++) {
580 continue;
581 n->entries[i].order = o;
583 n->entries[i].components, o_orig, o);
584 }
585}
586
587static void
589{
590 if (n) ((ExifMnoteDataOlympus *) n)->offset = o;
591}
592
593static enum OlympusVersion
595 unsigned int buf_size)
596{
597 /* Olympus, Nikon, Sanyo, Epson */
598 if (buf_size >= 8) {
599 /* Match the terminating NUL character, too */
600 if (!memcmp (buf, "OLYMPUS", 8))
601 return olympusV2;
602 else if (!memcmp (buf, "OLYMP", 6))
603 return olympusV1;
604 else if (!memcmp (buf, "SANYO", 6))
605 return sanyoV1;
606 else if (!memcmp (buf, "EPSON", 6))
607 return epsonV1;
608 else if (!memcmp (buf, "Nikon", 6)) {
609 switch (buf[6]) {
610 case 1: return nikonV1;
611 case 2: return nikonV2;
612 default: return 0; /* Unrecognized Nikon variant */
613 }
614 }
615 }
616
617 /* Another variant of Nikon */
618 if ((buf_size >= 2) && (buf[0] == 0x00) && (buf[1] == 0x1b)) {
619 return nikonV0;
620 }
621
622 return unrecognized;
623}
624
625int
627{
629
630 if (variant == nikonV0) {
631 /* This variant needs some extra checking with the Make */
632 char value[5];
634 variant = unrecognized;
635
636 if (em) {
637 const char *v = exif_entry_get_value (em, value, sizeof(value));
638 if (v && (!strncmp (v, "Nikon", sizeof(value)) ||
639 !strncmp (v, "NIKON", sizeof(value)) ))
640 /* When saved, this variant will be written out like the
641 * alternative nikonV2 form above instead
642 */
643 variant = nikonV0;
644 }
645 }
646
647 return variant;
648}
649
650
653{
654 ExifMnoteData *d;
655
656 if (!mem) return NULL;
657
658 d = exif_mem_alloc (mem, sizeof (ExifMnoteDataOlympus));
659 if (!d) return NULL;
660
662
663 /* Set up function pointers */
675
676 return d;
677}
ExifByteOrder
Which byte order to use.
@ EXIF_BYTE_ORDER_INTEL
Little-endian byte order.
@ EXIF_BYTE_ORDER_MOTOROLA
Big-endian byte order.
Defines the ExifData type and the associated functions.
#define exif_data_get_entry(d, t)
Return an ExifEntry for the given tag if found in any IFD.
Definition exif-data.h:252
const char * exif_entry_get_value(ExifEntry *e, char *val, unsigned int maxlen)
Return a localized textual representation of the value of the EXIF entry.
Definition exif-entry.c:854
unsigned char exif_format_get_size(ExifFormat format)
Return the raw size of the given EXIF data type.
Definition exif-format.c:68
void exif_log(ExifLog *log, ExifLogCode code, const char *domain, const char *format,...)
Definition exif-log.c:137
@ EXIF_LOG_CODE_CORRUPT_DATA
Definition exif-log.h:60
@ EXIF_LOG_CODE_DEBUG
Definition exif-log.h:58
#define EXIF_LOG_NO_MEMORY(l, d, s)
Definition exif-log.h:112
void exif_mem_free(ExifMem *mem, void *d)
Definition exif-mem.c:91
void * exif_mem_alloc(ExifMem *mem, ExifLong ds)
Definition exif-mem.c:101
void * exif_mem_realloc(ExifMem *mem, void *d, ExifLong ds)
Definition exif-mem.c:111
static void exif_mnote_data_olympus_set_offset(ExifMnoteData *n, unsigned int o)
static unsigned int exif_mnote_data_olympus_count(ExifMnoteData *n)
static enum OlympusVersion exif_mnote_data_olympus_identify_variant(const unsigned char *buf, unsigned int buf_size)
static void exif_mnote_data_olympus_free(ExifMnoteData *n)
static void exif_mnote_data_olympus_load(ExifMnoteData *en, const unsigned char *buf, unsigned int buf_size)
static const char * exif_mnote_data_olympus_get_description(ExifMnoteData *d, unsigned int i)
static char * exif_mnote_data_olympus_get_value(ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen)
static void exif_mnote_data_olympus_save(ExifMnoteData *ne, unsigned char **buf, unsigned int *buf_size)
save the MnoteData from ne to buf
static void exif_mnote_data_olympus_set_byte_order(ExifMnoteData *d, ExifByteOrder o)
static void exif_mnote_data_olympus_clear(ExifMnoteDataOlympus *n)
int exif_mnote_data_olympus_identify(const ExifData *ed, const ExifEntry *e)
Detect if MakerNote is recognized as one handled by the Olympus module.
static unsigned int exif_mnote_data_olympus_get_id(ExifMnoteData *d, unsigned int n)
static const char * exif_mnote_data_olympus_get_title(ExifMnoteData *d, unsigned int i)
#define CHECKOVERFLOW(offset, datasize, structsize)
static const char * exif_mnote_data_olympus_get_name(ExifMnoteData *d, unsigned int i)
ExifMnoteData * exif_mnote_data_olympus_new(ExifMem *mem)
void exif_mnote_data_construct(ExifMnoteData *, ExifMem *mem)
@ EXIF_TAG_MAKE
Definition exif-tag.h:48
ExifLong exif_get_long(const unsigned char *buf, ExifByteOrder order)
Retrieve an ExifLong value from memory.
Definition exif-utils.c:167
ExifShort exif_get_short(const unsigned char *buf, ExifByteOrder order)
Retrieve an ExifShort value from memory.
Definition exif-utils.c:104
void exif_array_set_byte_order(ExifFormat f, unsigned char *b, unsigned int n, ExifByteOrder o_orig, ExifByteOrder o_new)
Definition exif-utils.c:28
void exif_set_long(unsigned char *b, ExifByteOrder order, ExifLong value)
Store an ExifLong value into memory in EXIF format.
Definition exif-utils.c:173
void exif_set_short(unsigned char *b, ExifByteOrder order, ExifShort value)
Store an ExifShort value into memory in EXIF format.
Definition exif-utils.c:126
EXIF data manipulation functions and types.
uint16_t ExifShort
EXIF Unsigned Short data type.
Definition exif-utils.h:50
char * mnote_olympus_entry_get_value(MnoteOlympusEntry *entry, char *v, unsigned int maxlen)
const char * mnote_olympus_tag_get_name(MnoteOlympusTag t)
Return a textual name of the given tag within the Olympus-style MakerNote.
const char * mnote_olympus_tag_get_description(MnoteOlympusTag t)
Return a verbose textual description of the given tag within the Olympus-style MakerNote.
const char * mnote_olympus_tag_get_title(MnoteOlympusTag t)
Return a textual title of the given tag within the Olympus-style MakerNote.
@ MNOTE_NIKON1_TAG_BASE
Represents the entire EXIF data found in an image.
Definition exif-data.h:48
Data found in one EXIF tag.
Definition exif-entry.h:45
unsigned char * data
Pointer to the raw EXIF data for this entry.
Definition exif-entry.h:59
unsigned int size
Number of bytes in the buffer at data.
Definition exif-entry.h:63
const char *(* get_name)(ExifMnoteData *, unsigned int)
const char *(* get_description)(ExifMnoteData *, unsigned int)
void(* load)(ExifMnoteData *, const unsigned char *, unsigned int)
char *(* get_value)(ExifMnoteData *, unsigned int, char *val, unsigned int maxlen)
unsigned int(* get_id)(ExifMnoteData *, unsigned int)
void(* save)(ExifMnoteData *, unsigned char **, unsigned int *)
unsigned int(* count)(ExifMnoteData *)
void(* set_offset)(ExifMnoteData *, unsigned int)
const char *(* get_title)(ExifMnoteData *, unsigned int)
void(* set_byte_order)(ExifMnoteData *, ExifByteOrder)
void(* free)(ExifMnoteData *)
ExifMnoteDataMethods methods

libexif Generated by doxygen