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

libexif Generated by doxygen