aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-08 16:01:05 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-08 16:01:05 +0000
commit75d1a629c40ea6cbf38c30e394b98efdeb25a737 (patch)
tree2ae62feee162969a870e440544b9e48ce221c31a
parente4175f8393fb98b852234304b756a25c045f5b0f (diff)
parent4d201c8e365b56e6559d71d8c96749676a6ca99c (diff)
downloadlibexif-aml_tz2_305400100.tar.gz
Change-Id: Iaac7efdf866a643f8a27c00dc1d6f81070ef2f27
-rw-r--r--Android.bp60
-rw-r--r--METADATA3
-rw-r--r--README.android1
-rw-r--r--libexif/canon/Makefile-files7
-rw-r--r--libexif/canon/exif-mnote-data-canon.c407
-rw-r--r--libexif/canon/exif-mnote-data-canon.h58
-rw-r--r--libexif/canon/mnote-canon-entry.c762
-rw-r--r--libexif/canon/mnote-canon-entry.h44
-rw-r--r--libexif/canon/mnote-canon-tag.c201
-rw-r--r--libexif/canon/mnote-canon-tag.h59
-rw-r--r--libexif/exif-data.c30
-rw-r--r--libexif/fuji/Makefile-files7
-rw-r--r--libexif/fuji/exif-mnote-data-fuji.c363
-rw-r--r--libexif/fuji/exif-mnote-data-fuji.h53
-rw-r--r--libexif/fuji/mnote-fuji-entry.c306
-rw-r--r--libexif/fuji/mnote-fuji-entry.h45
-rw-r--r--libexif/fuji/mnote-fuji-tag.c105
-rw-r--r--libexif/fuji/mnote-fuji-tag.h92
-rw-r--r--libexif/olympus/Makefile-files7
-rw-r--r--libexif/olympus/exif-mnote-data-olympus.c678
-rw-r--r--libexif/olympus/exif-mnote-data-olympus.h67
-rw-r--r--libexif/olympus/mnote-olympus-entry.c827
-rw-r--r--libexif/olympus/mnote-olympus-entry.h43
-rw-r--r--libexif/olympus/mnote-olympus-tag.c230
-rw-r--r--libexif/olympus/mnote-olympus-tag.h229
-rw-r--r--libexif/pentax/Makefile-files7
-rw-r--r--libexif/pentax/exif-mnote-data-pentax.c464
-rw-r--r--libexif/pentax/exif-mnote-data-pentax.h59
-rw-r--r--libexif/pentax/mnote-pentax-entry.c469
-rw-r--r--libexif/pentax/mnote-pentax-entry.h43
-rw-r--r--libexif/pentax/mnote-pentax-tag.c175
-rw-r--r--libexif/pentax/mnote-pentax-tag.h153
-rw-r--r--libexif_blacklist.txt (renamed from libexif_blocklist.txt)0
33 files changed, 6001 insertions, 53 deletions
diff --git a/Android.bp b/Android.bp
index 2d60fc8..1db830f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -16,54 +16,8 @@
// WARNING: this makefile builds a shared library. Do not ever make it build
// a static library or otherwise statically link libexif with your code.
-package {
- default_applicable_licenses: ["external_libexif_license"],
-}
-
-// Added automatically by a large-scale-change that took the approach of
-// 'apply every license found to every target'. While this makes sure we respect
-// every license restriction, it may not be entirely correct.
-//
-// e.g. GPL in an MIT project might only apply to the contrib/ directory.
-//
-// Please consider splitting the single license below into multiple licenses,
-// taking care not to lose any license_kind information, and overriding the
-// default license using the 'licenses: [...]' property on targets as needed.
-//
-// For unused files, consider creating a 'fileGroup' with "//visibility:private"
-// to attach the license to, and including a comment whether the files may be
-// used in the current project.
-//
-// large-scale-change included anything that looked like it might be a license
-// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc.
-//
-// Please consider removing redundant or irrelevant files from 'license_text:'.
-// See: http://go/android-license-faq
-license {
- name: "external_libexif_license",
- visibility: [":__subpackages__"],
- license_kinds: [
- "SPDX-license-identifier-Apache-2.0",
- "SPDX-license-identifier-BSD",
- "SPDX-license-identifier-FSFAP",
- "SPDX-license-identifier-GPL",
- "SPDX-license-identifier-LGPL",
- "SPDX-license-identifier-LGPL-2.1",
- "SPDX-license-identifier-LGPL-3.0",
- "SPDX-license-identifier-MIT",
- "legacy_notice",
- "legacy_permissive",
- "legacy_unencumbered",
- ],
- license_text: [
- "COPYING",
- "NOTICE",
- ],
-}
-
cc_library_shared {
name: "libexif",
- host_supported: true,
vendor_available: true,
vndk: {
enabled: true,
@@ -82,6 +36,18 @@ cc_library_shared {
"libexif/exif-mnote-data.c",
"libexif/exif-tag.c",
"libexif/exif-utils.c",
+ "libexif/canon/exif-mnote-data-canon.c",
+ "libexif/canon/mnote-canon-entry.c",
+ "libexif/canon/mnote-canon-tag.c",
+ "libexif/olympus/exif-mnote-data-olympus.c",
+ "libexif/olympus/mnote-olympus-tag.c",
+ "libexif/olympus/mnote-olympus-entry.c",
+ "libexif/fuji/exif-mnote-data-fuji.c",
+ "libexif/fuji/mnote-fuji-entry.c",
+ "libexif/fuji/mnote-fuji-tag.c",
+ "libexif/pentax/exif-mnote-data-pentax.c",
+ "libexif/pentax/mnote-pentax-entry.c",
+ "libexif/pentax/mnote-pentax-tag.c",
],
shared_libs: [
@@ -104,7 +70,7 @@ cc_library_shared {
sanitize: {
integer_overflow: true,
- blocklist: "libexif_blocklist.txt",
+ blacklist: "libexif_blacklist.txt",
},
}
diff --git a/METADATA b/METADATA
deleted file mode 100644
index 6d8601b..0000000
--- a/METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-third_party {
- license_type: RESTRICTED
-}
diff --git a/README.android b/README.android
index 7d0393c..e207a69 100644
--- a/README.android
+++ b/README.android
@@ -3,4 +3,3 @@ Note:
- do not statically link to it
- do not upgrade to LGPLv3
-- Much of EXIF reading capability removed to reduce library scope
diff --git a/libexif/canon/Makefile-files b/libexif/canon/Makefile-files
new file mode 100644
index 0000000..ef7ee2b
--- /dev/null
+++ b/libexif/canon/Makefile-files
@@ -0,0 +1,7 @@
+# -*- Makefile -*-
+noinst_LTLIBRARIES += libmnote-canon.la
+libmnote_canon_la_SOURCES = \
+ canon/exif-mnote-data-canon.c canon/exif-mnote-data-canon.h \
+ canon/mnote-canon-entry.c canon/mnote-canon-entry.h \
+ canon/mnote-canon-tag.c canon/mnote-canon-tag.h
+libmnote_canon_la_LIBADD = $(LTLIBINTL)
diff --git a/libexif/canon/exif-mnote-data-canon.c b/libexif/canon/exif-mnote-data-canon.c
new file mode 100644
index 0000000..3a0778c
--- /dev/null
+++ b/libexif/canon/exif-mnote-data-canon.c
@@ -0,0 +1,407 @@
+/* exif-mnote-data-canon.c
+ *
+ * Copyright (c) 2002, 2003 Lutz Mueller <lutz@users.sourceforge.net>
+ * Copyright (c) 2003 Matthieu Castet <mat-c@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+#include "exif-mnote-data-canon.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libexif/exif-byte-order.h>
+#include <libexif/exif-utils.h>
+#include <libexif/exif-data.h>
+
+#define DEBUG
+
+#define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
+
+static void
+exif_mnote_data_canon_clear (ExifMnoteDataCanon *n)
+{
+ ExifMnoteData *d = (ExifMnoteData *) n;
+ unsigned int i;
+
+ if (!n) return;
+
+ if (n->entries) {
+ for (i = 0; i < n->count; i++)
+ if (n->entries[i].data) {
+ exif_mem_free (d->mem, n->entries[i].data);
+ n->entries[i].data = NULL;
+ }
+ exif_mem_free (d->mem, n->entries);
+ n->entries = NULL;
+ n->count = 0;
+ }
+}
+
+static void
+exif_mnote_data_canon_free (ExifMnoteData *n)
+{
+ if (!n) return;
+
+ exif_mnote_data_canon_clear ((ExifMnoteDataCanon *) n);
+}
+
+static void
+exif_mnote_data_canon_get_tags (ExifMnoteDataCanon *dc, unsigned int n,
+ unsigned int *m, unsigned int *s)
+{
+ unsigned int from = 0, to;
+
+ if (!dc || !m) return;
+ for (*m = 0; *m < dc->count; (*m)++) {
+ to = from + mnote_canon_entry_count_values (&dc->entries[*m]);
+ if (to > n) {
+ if (s) *s = n - from;
+ break;
+ }
+ from = to;
+ }
+}
+
+static char *
+exif_mnote_data_canon_get_value (ExifMnoteData *note, unsigned int n, char *val, unsigned int maxlen)
+{
+ ExifMnoteDataCanon *dc = (ExifMnoteDataCanon *) note;
+ unsigned int m, s;
+
+ if (!dc) return NULL;
+ exif_mnote_data_canon_get_tags (dc, n, &m, &s);
+ if (m >= dc->count) return NULL;
+ return mnote_canon_entry_get_value (&dc->entries[m], s, val, maxlen);
+}
+
+static void
+exif_mnote_data_canon_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
+{
+ ExifByteOrder o_orig;
+ ExifMnoteDataCanon *n = (ExifMnoteDataCanon *) d;
+ unsigned int i;
+
+ if (!n) return;
+
+ o_orig = n->order;
+ n->order = o;
+ for (i = 0; i < n->count; i++) {
+ n->entries[i].order = o;
+ exif_array_set_byte_order (n->entries[i].format, n->entries[i].data,
+ n->entries[i].components, o_orig, o);
+ }
+}
+
+static void
+exif_mnote_data_canon_set_offset (ExifMnoteData *n, unsigned int o)
+{
+ if (n) ((ExifMnoteDataCanon *) n)->offset = o;
+}
+
+static void
+exif_mnote_data_canon_save (ExifMnoteData *ne,
+ unsigned char **buf, unsigned int *buf_size)
+{
+ ExifMnoteDataCanon *n = (ExifMnoteDataCanon *) ne;
+ size_t i, o, s, doff;
+ unsigned char *t;
+ size_t ts;
+
+ if (!n || !buf || !buf_size) return;
+
+ /*
+ * Allocate enough memory for all entries and the number
+ * of entries.
+ */
+ *buf_size = 2 + n->count * 12 + 4;
+ *buf = exif_mem_alloc (ne->mem, sizeof (char) * *buf_size);
+ if (!*buf) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteCanon", *buf_size);
+ return;
+ }
+
+ /* Save the number of entries */
+ exif_set_short (*buf, n->order, (ExifShort) n->count);
+
+ /* Save each entry */
+ for (i = 0; i < n->count; i++) {
+ o = 2 + i * 12;
+ exif_set_short (*buf + o + 0, n->order, (ExifShort) n->entries[i].tag);
+ exif_set_short (*buf + o + 2, n->order, (ExifShort) n->entries[i].format);
+ exif_set_long (*buf + o + 4, n->order,
+ n->entries[i].components);
+ o += 8;
+ s = exif_format_get_size (n->entries[i].format) *
+ n->entries[i].components;
+ if (s > 65536) {
+ /* Corrupt data: EXIF data size is limited to the
+ * maximum size of a JPEG segment (64 kb).
+ */
+ continue;
+ }
+ if (s > 4) {
+ ts = *buf_size + s;
+
+ /* Ensure even offsets. Set padding bytes to 0. */
+ if (s & 1) ts += 1;
+ t = exif_mem_realloc (ne->mem, *buf,
+ sizeof (char) * ts);
+ if (!t) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteCanon", ts);
+ return;
+ }
+ *buf = t;
+ *buf_size = ts;
+ doff = *buf_size - s;
+ if (s & 1) { doff--; *(*buf + *buf_size - 1) = '\0'; }
+ exif_set_long (*buf + o, n->order, n->offset + doff);
+ } else
+ doff = o;
+
+ /*
+ * Write the data. Fill unneeded bytes with 0. Do not
+ * crash if data is NULL.
+ */
+ if (!n->entries[i].data) memset (*buf + doff, 0, s);
+ else memcpy (*buf + doff, n->entries[i].data, s);
+ if (s < 4) memset (*buf + doff + s, 0, (4 - s));
+ }
+}
+
+/* XXX
+ * FIXME: exif_mnote_data_canon_load() may fail and there is no
+ * semantics to express that.
+ * See bug #1054323 for details, especially the comment by liblit
+ * after it has supposedly been fixed:
+ *
+ * https://sourceforge.net/tracker/?func=detail&aid=1054323&group_id=12272&atid=112272
+ * Unfortunately, the "return" statements aren't commented at
+ * all, so it isn't trivial to find out what is a normal
+ * return, and what is a reaction to an error condition.
+ */
+
+static void
+exif_mnote_data_canon_load (ExifMnoteData *ne,
+ const unsigned char *buf, unsigned int buf_size)
+{
+ ExifMnoteDataCanon *n = (ExifMnoteDataCanon *) ne;
+ ExifShort c;
+ size_t i, tcount, o, datao;
+
+ if (!n || !buf || !buf_size) {
+ exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteCanon", "Short MakerNote");
+ return;
+ }
+ datao = 6 + n->offset;
+
+ if (CHECKOVERFLOW(datao, buf_size, 2)) {
+ exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteCanon", "Short MakerNote");
+ return;
+ }
+
+ /* Read the number of tags */
+ c = exif_get_short (buf + datao, n->order);
+ datao += 2;
+
+ /* Remove any old entries */
+ exif_mnote_data_canon_clear (n);
+
+ /* Reserve enough space for all the possible MakerNote tags */
+ n->entries = exif_mem_alloc (ne->mem, sizeof (MnoteCanonEntry) * c);
+ if (!n->entries) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteCanon", sizeof (MnoteCanonEntry) * c);
+ return;
+ }
+
+ /* Parse the entries */
+ tcount = 0;
+ for (i = c, o = datao; i; --i, o += 12) {
+ size_t s;
+
+ memset(&n->entries[tcount], 0, sizeof(MnoteCanonEntry));
+ if (CHECKOVERFLOW(o,buf_size,12)) {
+ exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteCanon", "Short MakerNote");
+ break;
+ }
+
+ n->entries[tcount].tag = exif_get_short (buf + o, n->order);
+ n->entries[tcount].format = exif_get_short (buf + o + 2, n->order);
+ n->entries[tcount].components = exif_get_long (buf + o + 4, n->order);
+ n->entries[tcount].order = n->order;
+
+ exif_log (ne->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteCanon",
+ "Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
+ mnote_canon_tag_get_name (n->entries[tcount].tag));
+
+ /* Check if we overflow the multiplication. Use buf_size as the max size for integer overflow detection,
+ * we will check the buffer sizes closer later. */
+ if ( exif_format_get_size (n->entries[tcount].format) &&
+ buf_size / exif_format_get_size (n->entries[tcount].format) < n->entries[tcount].components
+ ) {
+ exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteCanon", "Tag size overflow detected (%u * %lu)", exif_format_get_size (n->entries[tcount].format), n->entries[tcount].components);
+ continue;
+ }
+
+ /*
+ * Size? If bigger than 4 bytes, the actual data is not
+ * in the entry but somewhere else (offset).
+ */
+ s = exif_format_get_size (n->entries[tcount].format) *
+ n->entries[tcount].components;
+ n->entries[tcount].size = s;
+ if (!s) {
+ exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteCanon",
+ "Invalid zero-length tag size");
+ continue;
+
+ } else {
+ size_t dataofs = o + 8;
+ if (s > 4) dataofs = exif_get_long (buf + dataofs, n->order) + 6;
+
+ if (CHECKOVERFLOW(dataofs, buf_size, s)) {
+ exif_log (ne->log, EXIF_LOG_CODE_DEBUG,
+ "ExifMnoteCanon",
+ "Tag data past end of buffer (%zu > %u)",
+ dataofs + s, buf_size);
+ continue;
+ }
+
+ n->entries[tcount].data = exif_mem_alloc (ne->mem, s);
+ if (!n->entries[tcount].data) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteCanon", s);
+ continue;
+ }
+ memcpy (n->entries[tcount].data, buf + dataofs, s);
+ }
+
+ /* Tag was successfully parsed */
+ ++tcount;
+ }
+ /* Store the count of successfully parsed tags */
+ n->count = tcount;
+}
+
+static unsigned int
+exif_mnote_data_canon_count (ExifMnoteData *n)
+{
+ ExifMnoteDataCanon *dc = (ExifMnoteDataCanon *) n;
+ unsigned int i, c;
+
+ for (i = c = 0; dc && (i < dc->count); i++)
+ c += mnote_canon_entry_count_values (&dc->entries[i]);
+ return c;
+}
+
+static unsigned int
+exif_mnote_data_canon_get_id (ExifMnoteData *d, unsigned int i)
+{
+ ExifMnoteDataCanon *dc = (ExifMnoteDataCanon *) d;
+ unsigned int m;
+
+ if (!dc) return 0;
+ exif_mnote_data_canon_get_tags (dc, i, &m, NULL);
+ if (m >= dc->count) return 0;
+ return dc->entries[m].tag;
+}
+
+static const char *
+exif_mnote_data_canon_get_name (ExifMnoteData *note, unsigned int i)
+{
+ ExifMnoteDataCanon *dc = (ExifMnoteDataCanon *) note;
+ unsigned int m, s;
+
+ if (!dc) return NULL;
+ exif_mnote_data_canon_get_tags (dc, i, &m, &s);
+ if (m >= dc->count) return NULL;
+ return mnote_canon_tag_get_name_sub (dc->entries[m].tag, s, dc->options);
+}
+
+static const char *
+exif_mnote_data_canon_get_title (ExifMnoteData *note, unsigned int i)
+{
+ ExifMnoteDataCanon *dc = (ExifMnoteDataCanon *) note;
+ unsigned int m, s;
+
+ if (!dc) return NULL;
+ exif_mnote_data_canon_get_tags (dc, i, &m, &s);
+ if (m >= dc->count) return NULL;
+ return mnote_canon_tag_get_title_sub (dc->entries[m].tag, s, dc->options);
+}
+
+static const char *
+exif_mnote_data_canon_get_description (ExifMnoteData *note, unsigned int i)
+{
+ ExifMnoteDataCanon *dc = (ExifMnoteDataCanon *) note;
+ unsigned int m;
+
+ if (!dc) return NULL;
+ exif_mnote_data_canon_get_tags (dc, i, &m, NULL);
+ if (m >= dc->count) return NULL;
+ return mnote_canon_tag_get_description (dc->entries[m].tag);
+}
+
+int
+exif_mnote_data_canon_identify (const ExifData *ed, const ExifEntry *e)
+{
+ char value[8];
+ ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE);
+ if (!em)
+ return 0;
+ return !strcmp (exif_entry_get_value (em, value, sizeof (value)), "Canon");
+}
+
+ExifMnoteData *
+exif_mnote_data_canon_new (ExifMem *mem, ExifDataOption o)
+{
+ ExifMnoteData *d;
+ ExifMnoteDataCanon *dc;
+
+ if (!mem) return NULL;
+
+ d = exif_mem_alloc (mem, sizeof (ExifMnoteDataCanon));
+ if (!d)
+ return NULL;
+
+ memset(d, 0, sizeof(ExifMnoteDataCanon));
+
+ exif_mnote_data_construct (d, mem);
+
+ /* Set up function pointers */
+ d->methods.free = exif_mnote_data_canon_free;
+ d->methods.set_byte_order = exif_mnote_data_canon_set_byte_order;
+ d->methods.set_offset = exif_mnote_data_canon_set_offset;
+ d->methods.load = exif_mnote_data_canon_load;
+ d->methods.save = exif_mnote_data_canon_save;
+ d->methods.count = exif_mnote_data_canon_count;
+ d->methods.get_id = exif_mnote_data_canon_get_id;
+ d->methods.get_name = exif_mnote_data_canon_get_name;
+ d->methods.get_title = exif_mnote_data_canon_get_title;
+ d->methods.get_description = exif_mnote_data_canon_get_description;
+ d->methods.get_value = exif_mnote_data_canon_get_value;
+
+ dc = (ExifMnoteDataCanon*)d;
+ dc->options = o;
+ return d;
+}
diff --git a/libexif/canon/exif-mnote-data-canon.h b/libexif/canon/exif-mnote-data-canon.h
new file mode 100644
index 0000000..2a1cc87
--- /dev/null
+++ b/libexif/canon/exif-mnote-data-canon.h
@@ -0,0 +1,58 @@
+/* exif-mnote-data-canon.h
+ *
+ * Copyright (c) 2002, 2003 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EXIF_MNOTE_DATA_CANON_H__
+#define __EXIF_MNOTE_DATA_CANON_H__
+
+#include <libexif/exif-byte-order.h>
+#include <libexif/exif-mnote-data.h>
+#include <libexif/exif-mnote-data-priv.h>
+#include <libexif/exif-mem.h>
+#include <libexif/exif-data.h>
+
+typedef struct _ExifMnoteDataCanon ExifMnoteDataCanon;
+
+#include <libexif/canon/mnote-canon-entry.h>
+
+struct _ExifMnoteDataCanon {
+ ExifMnoteData parent;
+
+ MnoteCanonEntry *entries;
+ unsigned int count;
+
+ ExifByteOrder order;
+ unsigned int offset;
+
+ ExifDataOption options;
+};
+
+/*! Detect if MakerNote is recognized as one handled by the Canon module.
+ *
+ * \param[in] ed image #ExifData to identify as as a Canon type
+ * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but
+ * duplicated here for convenience
+ * \return 0 if not recognized, nonzero if recognized. The specific nonzero
+ * value returned may identify a subtype unique within this module.
+ */
+int exif_mnote_data_canon_identify (const ExifData *ed, const ExifEntry *e);
+
+ExifMnoteData *exif_mnote_data_canon_new (ExifMem *mem, ExifDataOption o);
+
+#endif /* __EXIF_MNOTE_DATA_CANON_H__ */
diff --git a/libexif/canon/mnote-canon-entry.c b/libexif/canon/mnote-canon-entry.c
new file mode 100644
index 0000000..b92f69c
--- /dev/null
+++ b/libexif/canon/mnote-canon-entry.c
@@ -0,0 +1,762 @@
+/* mnote-canon-entry.c
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ * Copyright (c) 2003 Matthieu Castet <mat-c@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "mnote-canon-entry.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <libexif/exif-format.h>
+#include <libexif/exif-utils.h>
+#include <libexif/i18n.h>
+
+/* #define DEBUG */
+
+#define CF(format,target,v,maxlen) \
+{ \
+ if (format != target) { \
+ snprintf (v, maxlen, \
+ _("Invalid format '%s', " \
+ "expected '%s'."), \
+ exif_format_get_name (format), \
+ exif_format_get_name (target)); \
+ break; \
+ } \
+}
+
+#define CC(number,target,v,maxlen) \
+{ \
+ if (number != target) { \
+ snprintf (v, maxlen, \
+ _("Invalid number of components (%i, " \
+ "expected %i)."), (int) number, (int) target); \
+ break; \
+ } \
+}
+#define CC2(number,t1,t2,v,maxlen) \
+{ \
+ if ((number != t1) && (number != t2)) { \
+ snprintf (v, maxlen, \
+ _("Invalid number of components (%i, " \
+ "expected %i or %i)."), (int) number, \
+ (int) t1, (int) t2); \
+ break; \
+ } \
+}
+
+#define UNDEFINED 0xFF
+
+static const struct canon_entry_table_t {
+ unsigned int subtag;
+ ExifShort value;
+ const char *name;
+} entries_settings_1 [] = {
+#ifndef NO_VERBOSE_TAG_DATA
+ { 0, 1, N_("Macro")},
+ { 0, 2, N_("Normal")},
+ { 2, 1, N_("Economy")},
+ { 2, 2, N_("Normal")},
+ { 2, 3, N_("Fine")},
+ { 2, 4, N_("RAW")},
+ { 2, 5, N_("Superfine")},
+ { 3, 0, N_("Off")},
+ { 3, 1, N_("Auto")},
+ { 3, 2, N_("On")},
+ { 3, 3, N_("Red-eye reduction")},
+ { 3, 4, N_("Slow synchro")},
+ { 3, 5, N_("Auto, red-eye reduction")},
+ { 3, 6, N_("On, red-eye reduction")},
+ { 3, 16, N_("External flash")},
+ { 4, 0, N_("Single")},
+ { 4, 1, N_("Continuous")},
+ { 4, 2, N_("Movie")},
+ { 4, 3, N_("Continuous, speed priority")},
+ { 4, 4, N_("Continuous, low")},
+ { 4, 5, N_("Continuous, high")},
+ { 6, 0, N_("One-shot AF")},
+ { 6, 1, N_("AI servo AF")},
+ { 6, 2, N_("AI focus AF")},
+ { 6, 3, N_("Manual focus")},
+ { 6, 4, N_("Single")},
+ { 6, 5, N_("Continuous")},
+ { 6, 6, N_("Manual focus")},
+ { 6, 16, N_("Pan focus")},
+ { 8, 1, N_("JPEG")},
+ { 8, 2, N_("CRW+THM")},
+ { 8, 3, N_("AVI+THM")},
+ { 8, 4, N_("TIF")},
+ { 8, 5, N_("TIF+JPEG")},
+ { 8, 6, N_("CR2")},
+ { 8, 7, N_("CR2+JPEG")},
+ { 9, 0, N_("Large")},
+ { 9, 1, N_("Medium")},
+ { 9, 2, N_("Small")},
+ { 9, 5, N_("Medium 1")},
+ { 9, 6, N_("Medium 2")},
+ { 9, 7, N_("Medium 3")},
+ { 9, 8, N_("Postcard")},
+ { 9, 9, N_("Widescreen")},
+ {10, 0, N_("Full auto")},
+ {10, 1, N_("Manual")},
+ {10, 2, N_("Landscape")},
+ {10, 3, N_("Fast shutter")},
+ {10, 4, N_("Slow shutter")},
+ {10, 5, N_("Night")},
+ {10, 6, N_("Grayscale")},
+ {10, 7, N_("Sepia")},
+ {10, 8, N_("Portrait")},
+ {10, 9, N_("Sports")},
+ {10, 10, N_("Macro")},
+ {10, 11, N_("Black & white")},
+ {10, 12, N_("Pan focus")},
+ {10, 13, N_("Vivid")},
+ {10, 14, N_("Neutral")},
+ {10, 15, N_("Flash off")},
+ {10, 16, N_("Long shutter")},
+ {10, 17, N_("Super macro")},
+ {10, 18, N_("Foliage")},
+ {10, 19, N_("Indoor")},
+ {10, 20, N_("Fireworks")},
+ {10, 21, N_("Beach")},
+ {10, 22, N_("Underwater")},
+ {10, 23, N_("Snow")},
+ {10, 24, N_("Kids & pets")},
+ {10, 25, N_("Night snapshot")},
+ {10, 26, N_("Digital macro")},
+ {10, 27, N_("My colors")},
+ {10, 28, N_("Still image")},
+ {10, 30, N_("Color accent")},
+ {10, 31, N_("Color swap")},
+ {10, 32, N_("Aquarium")},
+ {10, 33, N_("ISO 3200")},
+ {11, 0, N_("None")},
+ {11, 1, N_("2x")},
+ {11, 2, N_("4x")},
+ {11, 3, N_("Other")},
+ {12, 0x0000, N_("Normal")},
+ {12, 0x0001, N_("High")},
+ {12, 0xffff, N_("Low")},
+ {13, 0x0000, N_("Normal")},
+ {13, 0x0001, N_("High")},
+ {13, 0xffff, N_("Low")},
+ {14, 0x0000, N_("Normal")},
+ {14, 0x0001, N_("High")},
+ {14, 0xffff, N_("Low")},
+ {15, 14, N_("Auto high")},
+ {15, 15, N_("Auto")},
+ {15, 16, N_("50")},
+ {15, 17, N_("100")},
+ {15, 18, N_("200")},
+ {15, 19, N_("400")},
+ {15, 20, N_("800")},
+ {16, 0, N_("Default")},
+ {16, 1, N_("Spot")},
+ {16, 2, N_("Average")},
+ {16, 3, N_("Evaluative")},
+ {16, 4, N_("Partial")},
+ {16, 5, N_("Center-weighted average")},
+ {17, 0, N_("Manual")},
+ {17, 1, N_("Auto")},
+ {17, 2, N_("Not known")},
+ {17, 3, N_("Macro")},
+ {17, 4, N_("Very close")},
+ {17, 5, N_("Close")},
+ {17, 6, N_("Middle range")},
+ {17, 7, N_("Far range")},
+ {17, 8, N_("Pan focus")},
+ {17, 9, N_("Super macro")},
+ {17, 10, N_("Infinity")},
+ {18, 0x2005, N_("Manual AF point selection")},
+ {18, 0x3000, N_("None (MF)")},
+ {18, 0x3001, N_("Auto-selected")},
+ {18, 0x3002, N_("Right")},
+ {18, 0x3003, N_("Center")},
+ {18, 0x3004, N_("Left")},
+ {18, 0x4001, N_("Auto AF point selection")},
+ {19, 0, N_("Easy shooting")},
+ {19, 1, N_("Program")},
+ {19, 2, N_("Tv-priority")},
+ {19, 3, N_("Av-priority")},
+ {19, 4, N_("Manual")},
+ {19, 5, N_("A-DEP")},
+ {19, 6, N_("M-DEP")},
+ {21, 1, N_("Canon EF 50mm f/1.8")},
+ {21, 2, N_("Canon EF 28mm f/2.8")},
+ {21, 4, N_("Sigma UC Zoom 35-135mm f/4-5.6")},
+ {21, 6, N_("Tokina AF193-2 19-35mm f/3.5-4.5")},
+ {21, 7, N_("Canon EF 100-300mm F5.6L")},
+ {21, 10, N_("Sigma 50mm f/2.8 EX or 28mm f/1.8")},
+ {21, 11, N_("Canon EF 35mm f/2")},
+ {21, 13, N_("Canon EF 15mm f/2.8")},
+ {21, 21, N_("Canon EF 80-200mm f/2.8L")},
+ {21, 22, N_("Tokina AT-X280AF PRO 28-80mm F2.8 Aspherical")},
+ {21, 26, N_("Cosina 100mm f/3.5 Macro AF")},
+ {21, 28, N_("Tamron AF Aspherical 28-200mm f/3.8-5.6")},
+ {21, 29, N_("Canon EF 50mm f/1.8 MkII")},
+ {21, 31, N_("Tamron SP AF 300mm f/2.8 LD IF")},
+ {21, 32, N_("Canon EF 24mm f/2.8 or Sigma 15mm f/2.8 EX Fisheye")},
+ {21, 37, N_("Canon EF 35-80mm f/4-5.6")},
+ {21, 39, N_("Canon EF 75-300mm f/4-5.6")},
+ {21, 40, N_("Canon EF 28-80mm f/3.5-5.6")},
+ {21, 43, N_("Canon EF 28-105mm f/4-5.6")},
+ {21, 45, N_("Canon EF-S 18-55mm f/3.5-5.6")},
+ {21, 52, N_("Canon EF-S 18-55mm f/3.5-5.6 IS II")},
+ {21, 124, N_("Canon MP-E 65mm f/2.8 1-5x Macro Photo")},
+ {21, 125, N_("Canon TS-E 24mm f/3.5L")},
+ {21, 126, N_("Canon TS-E 45mm f/2.8")},
+ {21, 127, N_("Canon TS-E 90mm f/2.8")},
+ {21, 130, N_("Canon EF 50mm f/1.0L")},
+ {21, 131, N_("Sigma 17-35mm f2.8-4 EX Aspherical HSM")},
+ {21, 134, N_("Canon EF 600mm f/4L IS")},
+ {21, 135, N_("Canon EF 200mm f/1.8L")},
+ {21, 136, N_("Canon EF 300mm f/2.8L")},
+ {21, 137, N_("Canon EF 85mm f/1.2L")},
+ {21, 139, N_("Canon EF 400mm f/2.8L")},
+ {21, 141, N_("Canon EF 500mm f/4.5L")},
+ {21, 142, N_("Canon EF 300mm f/2.8L IS")},
+ {21, 143, N_("Canon EF 500mm f/4L IS")},
+ {21, 149, N_("Canon EF 100mm f/2")},
+ {21, 150, N_("Sigma 20mm EX f/1.8")},
+ {21, 151, N_("Canon EF 200mm f/2.8L")},
+ {21, 152, N_("Sigma 10-20mm F4-5.6 or 12-24mm f/4.5-5.6 or 14mm f/2.8")},
+ {21, 153, N_("Canon EF 35-350mm f/3.5-5.6L")},
+ {21, 155, N_("Canon EF 85mm f/1.8 USM")},
+ {21, 156, N_("Canon EF 28-105mm f/3.5-4.5 USM")},
+ {21, 160, N_("Canon EF 20-35mm f/3.5-4.5 USM")},
+ {21, 161, N_("Canon EF 28-70mm f/2.8L or Sigma 24-70mm EX f/2.8")},
+ {21, 165, N_("Canon EF 70-200mm f/2.8 L")},
+ {21, 166, N_("Canon EF 70-200mm f/2.8 L + x1.4")},
+ {21, 167, N_("Canon EF 70-200mm f/2.8 L + x2")},
+ {21, 168, N_("Canon EF 28mm f/1.8 USM")},
+ {21, 169, N_("Sigma 15-30mm f/3.5-4.5 EX DG Aspherical")},
+ {21, 170, N_("Canon EF 200mm f/2.8L II")},
+ {21, 173, N_("Canon EF 180mm Macro f/3.5L or Sigma 180mm EX HSM Macro f/3.5")},
+ {21, 174, N_("Canon EF 135mm f/2L")},
+ {21, 176, N_("Canon EF 24-85mm f/3.5-4.5 USM")},
+ {21, 177, N_("Canon EF 300mm f/4L IS")},
+ {21, 178, N_("Canon EF 28-135mm f/3.5-5.6 IS")},
+ {21, 180, N_("Canon EF 35mm f/1.4L")},
+ {21, 181, N_("Canon EF 100-400mm f/4.5-5.6L IS + x1.4")},
+ {21, 182, N_("Canon EF 100-400mm f/4.5-5.6L IS + x2")},
+ {21, 183, N_("Canon EF 100-400mm f/4.5-5.6L IS")},
+ {21, 184, N_("Canon EF 400mm f/2.8L + x2")},
+ {21, 186, N_("Canon EF 70-200mm f/4L")},
+ {21, 190, N_("Canon EF 100mm f/2.8 Macro")},
+ {21, 191, N_("Canon EF 400mm f/4 DO IS")},
+ {21, 197, N_("Canon EF 75-300mm f/4-5.6 IS")},
+ {21, 198, N_("Canon EF 50mm f/1.4")},
+ {21, 202, N_("Canon EF 28-80 f/3.5-5.6 USM IV")},
+ {21, 211, N_("Canon EF 28-200mm f/3.5-5.6")},
+ {21, 213, N_("Canon EF 90-300mm f/4.5-5.6")},
+ {21, 214, N_("Canon EF-S 18-55mm f/3.5-4.5 USM")},
+ {21, 224, N_("Canon EF 70-200mm f/2.8L IS USM")},
+ {21, 225, N_("Canon EF 70-200mm f/2.8L IS USM + x1.4")},
+ {21, 226, N_("Canon EF 70-200mm f/2.8L IS USM + x2")},
+ {21, 229, N_("Canon EF 16-35mm f/2.8L")},
+ {21, 230, N_("Canon EF 24-70mm f/2.8L")},
+ {21, 231, N_("Canon EF 17-40mm f/4L")},
+ {21, 232, N_("Canon EF 70-300mm f/4.5-5.6 DO IS USM")},
+ {21, 234, N_("Canon EF-S 17-85mm f4-5.6 IS USM")},
+ {21, 235, N_("Canon EF-S10-22mm F3.5-4.5 USM")},
+ {21, 236, N_("Canon EF-S60mm F2.8 Macro USM")},
+ {21, 237, N_("Canon EF 24-105mm f/4L IS")},
+ {21, 238, N_("Canon EF 70-300mm F4-5.6 IS USM")},
+ {21, 241, N_("Canon EF 50mm F1.2L USM")},
+ {21, 242, N_("Canon EF 70-200mm f/4L IS USM")},
+ {21, 251, N_("Canon EF 70-200mm f/2.8L IS II USM")},
+ {28, 0, N_("Manual")},
+ {28, 1, N_("TTL")},
+ {28, 2, N_("A-TTL")},
+ {28, 3, N_("E-TTL")},
+ {28, 4, N_("FP sync enabled")},
+ {28, 7, N_("2nd-curtain sync used")},
+ {28, 11, N_("FP sync used")},
+ {28, 13, N_("Internal")},
+ {28, 14, N_("External")},
+ {31, 0, N_("Single")},
+ {31, 1, N_("Continuous")},
+ {32, 0, N_("Normal AE")},
+ {32, 1, N_("Exposure compensation")},
+ {32, 2, N_("AE lock")},
+ {32, 3, N_("AE lock + exposure compensation")},
+ {32, 4, N_("No AE")},
+ {33, 0, N_("Off")},
+ {33, 1, N_("On")},
+ {33, 2, N_("On, shot only")},
+ {39, 0, N_("Off")},
+ {39, 1, N_("Vivid")},
+ {39, 2, N_("Neutral")},
+ {39, 3, N_("Smooth")},
+ {39, 4, N_("Sepia")},
+ {39, 5, N_("Black & white")},
+ {39, 6, N_("Custom")},
+ {39, 100, N_("My color data")},
+ {40, 0, N_("Off")},
+ {40, 0x0500, N_("Full")},
+ {40, 0x0502, N_("2/3")},
+ {40, 0x0504, N_("1/3")},
+#endif
+ { 0, 0, NULL}
+},
+entries_focal_length [] = {
+#ifndef NO_VERBOSE_TAG_DATA
+ {0, 1, N_("Fixed")},
+ {0, 2, N_("Zoom")},
+#endif
+ {0, 0, NULL}
+},
+entries_settings_2 [] = {
+#ifndef NO_VERBOSE_TAG_DATA
+ { 6, 0, N_("Auto")},
+ { 6, 1, N_("Sunny")},
+ { 6, 2, N_("Cloudy")},
+ { 6, 3, N_("Tungsten")},
+ { 6, 4, N_("Fluorescent")},
+ { 6, 5, N_("Flash")},
+ { 6, 6, N_("Custom")},
+ { 6, 7, N_("Black & white")},
+ { 6, 8, N_("Shade")},
+ { 6, 9, N_("Manual temperature (Kelvin)")},
+ { 6, 10, N_("PC set 1")},
+ { 6, 11, N_("PC set 2")},
+ { 6, 12, N_("PC set 3")},
+ { 6, 14, N_("Daylight fluorescent")},
+ { 6, 15, N_("Custom 1")},
+ { 6, 16, N_("Custom 2")},
+ { 6, 17, N_("Underwater")},
+ { 7, 0, N_("Off")},
+ { 7, 1, N_("Night scene")},
+ { 7, 2, N_("On")},
+ { 7, 3, N_("None")},
+ { 13, 0x3000, N_("None (MF)")},
+ { 13, 0x3001, N_("Right")},
+ { 13, 0x3002, N_("Center")},
+ { 13, 0x3003, N_("Center-right")},
+ { 13, 0x3004, N_("Left")},
+ { 13, 0x3005, N_("Left-right")},
+ { 13, 0x3006, N_("Left-center")},
+ { 13, 0x3007, N_("All")},
+ { 15, 0, N_("Off")},
+ { 15, 1, N_("On (shot 1)")},
+ { 15, 2, N_("On (shot 2)")},
+ { 15, 3, N_("On (shot 3)")},
+ { 15, 0xffff, N_("On")},
+ { 25, 248, N_("EOS high-end")},
+ { 25, 250, N_("Compact")},
+ { 25, 252, N_("EOS mid-range")},
+ { 26, 0, N_("None")},
+ { 26, 1, N_("Rotate 90 CW")},
+ { 26, 2, N_("Rotate 180")},
+ { 26, 3, N_("Rotate 270 CW")},
+ { 26, 0xffff, N_("Rotated by software")},
+ { 27, 0, N_("Off")},
+ { 27, 1, N_("On")},
+ { 32, 0, N_("Off")},
+ { 32, 0x0014, N_("1/3")},
+ { 32, 0x008c, N_("2/3")},
+ { 32, 0x07d0, N_("Full")},
+#endif
+ {0, 0, NULL}
+},
+entries_panorama [] = {
+#ifndef NO_VERBOSE_TAG_DATA
+ {0, 0, N_("Left to right")},
+ {0, 1, N_("Right to left")},
+ {0, 2, N_("Bottom to top")},
+ {0, 3, N_("Top to bottom")},
+ {0, 4, N_("2x2 matrix (clockwise)")},
+#endif
+ {0, 0, NULL}
+},
+color_information [] = {
+#ifndef NO_VERBOSE_TAG_DATA
+ {0, 0, N_("Standard")},
+ {0, 1, N_("Manual")},
+ {0, 2, N_("Custom")},
+ {2, 0, N_("N/A")},
+ {2, 1, N_("Lowest")},
+ {2, 2, N_("Low")},
+ {2, 3, N_("Standard")},
+ {2, 4, N_("High")},
+ {2, 5, N_("Highest")},
+ {7, 0, N_("Auto")},
+ {7, 1, N_("Daylight")},
+ {7, 2, N_("Cloudy")},
+ {7, 3, N_("Tungsten")},
+ {7, 4, N_("Fluorescent")},
+ {7, 5, N_("Flash")},
+ {7, 6, N_("Custom")},
+ {7, 7, N_("Black & white")},
+ {7, 8, N_("Shade")},
+ {7, 9, N_("Manual temperature (Kelvin)")},
+ {7, 10, N_("PC set 1")},
+ {7, 11, N_("PC set 2")},
+ {7, 12, N_("PC set 3")},
+ {7, 14, N_("Daylight fluorescent")},
+ {7, 15, N_("Custom 1")},
+ {7, 16, N_("Custom 2")},
+ {7, 17, N_("Underwater")},
+ {9, 0x00, N_("None")},
+ {9, 0x01, N_("Standard")},
+ {9, 0x02, N_("Set 1")},
+ {9, 0x03, N_("Set 2")},
+ {9, 0x04, N_("Set 3")},
+ {9, 0x21, N_("User def. 1")},
+ {9, 0x22, N_("User def. 2")},
+ {9, 0x23, N_("User def. 3")},
+ {9, 0x41, N_("External 1")},
+ {9, 0x42, N_("External 2")},
+ {9, 0x43, N_("External 3")},
+ {9, 0x81, N_("Standard")},
+ {9, 0x82, N_("Portrait")},
+ {9, 0x83, N_("Landscape")},
+ {9, 0x84, N_("Neutral")},
+ {9, 0x85, N_("Faithful")},
+ {9, 0x86, N_("Monochrome")},
+#endif
+ {0, 0, NULL}
+};
+
+static void
+canon_search_table_value (const struct canon_entry_table_t table[],
+ unsigned int t, ExifShort vs, char *val, unsigned int maxlen)
+{
+ unsigned int j;
+
+ /* Search the table for the first matching subtag and value. */
+ for (j = 0; table[j].name && ((table[j].subtag < t) ||
+ ((table[j].subtag == t) && table[j].value <= vs)); j++) {
+ if ((table[j].subtag == t) && (table[j].value == vs)) {
+ break;
+ }
+ }
+ if ((table[j].subtag == t) && (table[j].value == vs) && table[j].name) {
+ /* Matching subtag and value found. */
+ strncpy (val, _(table[j].name), maxlen);
+ } else {
+ /* No matching subtag and/or value found. */
+ snprintf (val, maxlen, "0x%04x", vs);
+ }
+}
+
+static void
+canon_search_table_bitfield (const struct canon_entry_table_t table[],
+ unsigned int t, ExifShort vs, char *val, unsigned int maxlen)
+{
+ unsigned int j;
+
+ /* Search the table for the first matching subtag. */
+ for (j = 0; table[j].name && (table[j].subtag <= t); j++) {
+ if (table[j].subtag == t) {
+ break;
+ }
+ }
+ if ((table[j].subtag == t) && table[j].name) {
+ unsigned int i, bit, lastbit = 0;
+
+ /*
+ * Search the table for the last matching bit, because
+ * that one needs no additional comma appended.
+ */
+ for (i = j; table[i].name && (table[i].subtag == t); i++) {
+ bit = table[i].value;
+ if ((vs >> bit) & 1) {
+ lastbit = bit;
+ }
+ }
+ /* Search the table for all matching bits. */
+ for (i = j; table[i].name && (table[i].subtag == t); i++) {
+ bit = table[i].value;
+ if ((vs >> bit) & 1) {
+ strncat(val, _(table[i].name), maxlen - strlen (val));
+ if (bit != lastbit)
+ strncat (val, _(", "), maxlen - strlen (val));
+ }
+ }
+ } else {
+ /* No matching subtag found. */
+ snprintf (val, maxlen, "0x%04x", vs);
+ }
+}
+
+unsigned int
+mnote_canon_entry_count_values (const MnoteCanonEntry *entry)
+{
+ unsigned int val;
+
+ if (!entry) return 0;
+
+ switch (entry->tag) {
+ case MNOTE_CANON_TAG_FOCAL_LENGTH:
+ case MNOTE_CANON_TAG_PANORAMA:
+ return entry->components;
+ case MNOTE_CANON_TAG_SETTINGS_1:
+ case MNOTE_CANON_TAG_SETTINGS_2:
+ case MNOTE_CANON_TAG_CUSTOM_FUNCS:
+ case MNOTE_CANON_TAG_COLOR_INFORMATION:
+ if (entry->format != EXIF_FORMAT_SHORT) return 0;
+
+ val = exif_get_short (entry->data, entry->order);
+ /* val is buffer size, i.e. # of values plus 1 */
+ return MIN (entry->size - 2, val) / 2;
+ default:
+ return 1;
+ }
+}
+
+/*
+ * For reference, see Exif 2.1 specification (Appendix C),
+ * or http://en.wikipedia.org/wiki/APEX_system
+ */
+static double
+apex_value_to_aperture (double x)
+{
+ return pow (2, x / 2.);
+}
+
+static double
+apex_value_to_shutter_speed(double x)
+{
+ return 1.0 / pow (2, x);
+}
+
+static double
+apex_value_to_iso_speed (double x)
+{
+ return 3.125 * pow (2, x);
+}
+
+char *
+mnote_canon_entry_get_value (const MnoteCanonEntry *entry, unsigned int t, char *val, unsigned int maxlen)
+{
+ char buf[128];
+ ExifLong vl;
+ ExifShort vs, n;
+ unsigned char *data;
+ double d;
+
+ if (!entry)
+ return NULL;
+
+ data = entry->data;
+
+ memset (val, 0, maxlen);
+ maxlen--;
+
+ switch (entry->tag) {
+ case MNOTE_CANON_TAG_SETTINGS_1:
+ CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
+ n = exif_get_short (data, entry->order) / 2;
+ if (t >= n) return NULL;
+ CC (entry->components, n, val, maxlen);
+ vs = exif_get_short (data + 2 + t * 2, entry->order);
+ switch (t) {
+ case 1:
+ if (!vs) {
+ strncpy(val, _("Off"), maxlen);
+ break;
+ }
+ snprintf (val, maxlen, _("%i (ms)"), vs * 100);
+ break;
+ case 15:
+ if (((vs & 0xC000) == 0x4000) && (vs != 0x7FFF)) {
+ /* Canon S3 IS - directly specified value */
+ snprintf (val, maxlen, "%i", vs & ~0x4000);
+ } else {
+ /* Standard Canon - index into lookup table */
+ canon_search_table_value (entries_settings_1, t, vs, val, maxlen);
+ }
+ break;
+ case 22:
+ case 23:
+ case 24:
+ snprintf (val, maxlen, "%u", vs);
+ break;
+ case 25:
+ case 26:
+ snprintf (val, maxlen, "%.2f", apex_value_to_aperture (vs / 32.0));
+ break;
+ case 28:
+ canon_search_table_bitfield(entries_settings_1, t, vs, val, maxlen);
+ break;
+ case 34:
+ snprintf (val, maxlen, "%.2f", vs / 10.0);
+ break;
+ case 35:
+ case 36:
+ snprintf (val, maxlen, "%u", vs);
+ break;
+ default:
+ canon_search_table_value (entries_settings_1, t, vs, val, maxlen);
+ }
+ break;
+
+ case MNOTE_CANON_TAG_FOCAL_LENGTH:
+ CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
+ vs = exif_get_short (data + t * 2, entry->order);
+ switch (t) {
+ case 1:
+ snprintf (val, maxlen, "%u", vs);
+ break;
+ case 2:
+ case 3:
+ snprintf (val, maxlen, _("%.2f mm"), vs * 25.4 / 1000);
+ break;
+ default:
+ canon_search_table_value (entries_focal_length, t, vs, val, maxlen);
+ }
+ break;
+
+ case MNOTE_CANON_TAG_SETTINGS_2:
+ CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
+ n = exif_get_short (data, entry->order) / 2;
+ if (t >= n) return NULL;
+ CC (entry->components, n, val, maxlen);
+ vs = exif_get_short (data + 2 + t * 2, entry->order);
+ switch (t) {
+ case 0:
+ snprintf (val, maxlen, "%.3f", pow (2, (ExifSShort)vs / 32.0));
+ break;
+ case 1:
+ snprintf (val, maxlen, "%.0f", apex_value_to_iso_speed ((ExifSShort)vs / 32.0));
+ break;
+ case 2:
+ case 5:
+ case 14:
+ case 16:
+ snprintf (val, maxlen, _("%.2f EV"), (ExifSShort)vs / 32.0);
+ break;
+ case 3:
+ case 20:
+ snprintf (val, maxlen, "%.2f", apex_value_to_aperture (vs / 32.0));
+ break;
+ case 4:
+ case 21:
+ d = apex_value_to_shutter_speed ((ExifSShort)vs / 32.0);
+ if (d < 1)
+ snprintf (val, maxlen, _("1/%i"),(int)(1.0 / d));
+ else
+ snprintf (val, maxlen, "%i", (int) d);
+ break;
+ case 8:
+ snprintf (val, maxlen, "%u", vs);
+ break;
+ case 12:
+ snprintf (val, maxlen, "%.2f", vs / 32.0);
+ break;
+ case 18:
+ case 19:
+ snprintf (val, maxlen, _("%u mm"), vs);
+ break;
+ case 28:
+ if ((ExifSShort)vs <= 0) {
+ strncpy(val, _("Off"), maxlen);
+ break;
+ }
+ snprintf (val, maxlen, _("%i (ms)"), vs * 100);
+ break;
+ default:
+ canon_search_table_value (entries_settings_2, t, vs, val, maxlen);
+ }
+ break;
+
+ case MNOTE_CANON_TAG_PANORAMA:
+ CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
+ vs = exif_get_short (data + t * 2, entry->order);
+ canon_search_table_value (entries_panorama, t, vs, val, maxlen);
+ break;
+
+ case MNOTE_CANON_TAG_OWNER:
+ CC (entry->components, 32, val, maxlen);
+ /* Fall through; ImageType can have many sizes */
+ case MNOTE_CANON_TAG_IMAGE_TYPE:
+ CF (entry->format, EXIF_FORMAT_ASCII, val, maxlen);
+ strncpy (val, (char *)data, MIN (entry->size, maxlen));
+ break;
+
+ case MNOTE_CANON_TAG_FIRMWARE:
+ CF (entry->format, EXIF_FORMAT_ASCII, val, maxlen);
+/* CC2 (entry->components, 24, 32, val, maxlen); Can also be 22 */
+ strncpy (val, (char *)data, MIN (entry->size, maxlen));
+ break;
+
+ case MNOTE_CANON_TAG_IMAGE_NUMBER:
+ CF (entry->format, EXIF_FORMAT_LONG, val, maxlen);
+ CC (entry->components, 1, val, maxlen);
+ vl = exif_get_long (data, entry->order);
+ snprintf (val, maxlen, "%03lu-%04lu",
+ (unsigned long) vl/10000,
+ (unsigned long) vl%10000);
+ break;
+
+ case MNOTE_CANON_TAG_SERIAL_NUMBER:
+ CF (entry->format, EXIF_FORMAT_LONG, val, maxlen);
+ CC (entry->components, 1, val, maxlen);
+ vl = exif_get_long (data, entry->order);
+ snprintf (val, maxlen, "%04X-%05d", (int)vl>>16,(int)vl&0xffff);
+ break;
+
+ case MNOTE_CANON_TAG_CUSTOM_FUNCS:
+ CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
+ n = exif_get_short (data, entry->order) / 2;
+ if (t >= n) return NULL;
+ CC (entry->components, n, val, maxlen);
+ vs = exif_get_short (data + 2 + t * 2, entry->order);
+ snprintf (buf, sizeof (buf), "%u", vs);
+ strncat (val, buf, maxlen - strlen (val));
+ break;
+
+ case MNOTE_CANON_TAG_COLOR_INFORMATION:
+ CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
+ n = exif_get_short (data, entry->order) / 2;
+ if (t >= n) return NULL;
+ CC (entry->components, n, val, maxlen);
+ vs = exif_get_short (data + 2 + t * 2, entry->order);
+ canon_search_table_value (color_information, t, vs, val, maxlen);
+ break;
+
+ default:
+#ifdef DEBUG
+ {
+ int i;
+ if (entry->format == EXIF_FORMAT_SHORT)
+ for(i=0;i<entry->components;i++) {
+ vs = exif_get_short (data, entry->order);
+ data+=2;
+ printf ("Value%d=%d\n", i, vs);
+ }
+ else if (entry->format == EXIF_FORMAT_LONG)
+ for(i=0;i<entry->components;i++) {
+ vl = exif_get_long (data, entry->order);
+ data+=4;
+ printf ("Value%d=%d\n", i, vs);
+ }
+ else if (entry->format == EXIF_FORMAT_ASCII)
+ strncpy (val, data, MIN (entry->size, maxlen));
+ }
+#endif
+ break;
+ }
+ return val;
+}
diff --git a/libexif/canon/mnote-canon-entry.h b/libexif/canon/mnote-canon-entry.h
new file mode 100644
index 0000000..a4d4499
--- /dev/null
+++ b/libexif/canon/mnote-canon-entry.h
@@ -0,0 +1,44 @@
+/* mnote-canon-entry.h
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MNOTE_CANON_ENTRY_H__
+#define __MNOTE_CANON_ENTRY_H__
+
+#include <libexif/exif-format.h>
+#include <libexif/exif-byte-order.h>
+#include <libexif/canon/mnote-canon-tag.h>
+
+typedef struct _MnoteCanonEntry MnoteCanonEntry;
+
+struct _MnoteCanonEntry {
+ MnoteCanonTag tag;
+ ExifFormat format;
+ unsigned long components;
+
+ unsigned char *data;
+ unsigned int size;
+
+ ExifByteOrder order;
+};
+
+unsigned int mnote_canon_entry_count_values (const MnoteCanonEntry *);
+char *mnote_canon_entry_get_value (const MnoteCanonEntry *, unsigned int t, char *val, unsigned int maxlen);
+
+#endif /* __MNOTE_CANON_ENTRY_H__ */
diff --git a/libexif/canon/mnote-canon-tag.c b/libexif/canon/mnote-canon-tag.c
new file mode 100644
index 0000000..3cacfa6
--- /dev/null
+++ b/libexif/canon/mnote-canon-tag.c
@@ -0,0 +1,201 @@
+/* mnote-canon-tag.c
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+#include "mnote-canon-tag.h"
+
+#include <stdlib.h>
+
+#include <libexif/i18n.h>
+
+static const struct {
+ MnoteCanonTag tag;
+ const char *name;
+ const char *title;
+ const char *description;
+} table[] = {
+#ifndef NO_VERBOSE_TAG_STRINGS
+ {MNOTE_CANON_TAG_SETTINGS_1, "Settings1", N_("Settings (First Part)"), ""},
+ {MNOTE_CANON_TAG_FOCAL_LENGTH, "FocalLength", N_("Focal Length"), ""},
+ {MNOTE_CANON_TAG_SETTINGS_2, "Settings2", N_("Settings (Second Part)"), ""},
+ {MNOTE_CANON_TAG_PANORAMA, "Panorama", N_("Panorama"), ""},
+ {MNOTE_CANON_TAG_IMAGE_TYPE, "ImageType", N_("Image Type"), ""},
+ {MNOTE_CANON_TAG_FIRMWARE, "FirmwareVersion", N_("Firmware Version"), ""},
+ {MNOTE_CANON_TAG_IMAGE_NUMBER, "ImageNumber", N_("Image Number"), ""},
+ {MNOTE_CANON_TAG_OWNER, "OwnerName", N_("Owner Name"), ""},
+ {MNOTE_CANON_TAG_COLOR_INFORMATION, "ColorInformation", N_("Color Information"), ""},
+ {MNOTE_CANON_TAG_SERIAL_NUMBER, "SerialNumber", N_("Serial Number"), ""},
+ {MNOTE_CANON_TAG_CUSTOM_FUNCS, "CustomFunctions", N_("Custom Functions"), ""},
+#endif
+ {0, NULL, NULL, NULL}
+};
+
+static const struct {
+ MnoteCanonTag tag;
+ unsigned int subtag;
+ const char *name;
+} table_sub[] = {
+#ifndef NO_VERBOSE_TAG_STRINGS
+ {MNOTE_CANON_TAG_SETTINGS_1, 0, N_("Macro Mode")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 1, N_("Self-timer")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 2, N_("Quality")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 3, N_("Flash Mode")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 4, N_("Drive Mode")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 6, N_("Focus Mode")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 8, N_("Record Mode")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 9, N_("Image Size")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 10, N_("Easy Shooting Mode")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 11, N_("Digital Zoom")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 12, N_("Contrast")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 13, N_("Saturation")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 14, N_("Sharpness")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 15, N_("ISO")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 16, N_("Metering Mode")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 17, N_("Focus Range")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 18, N_("AF Point")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 19, N_("Exposure Mode")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 21, N_("Lens Type")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 22, N_("Long Focal Length of Lens")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 23, N_("Short Focal Length of Lens")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 24, N_("Focal Units per mm")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 25, N_("Maximal Aperture")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 26, N_("Minimal Aperture")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 27, N_("Flash Activity")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 28, N_("Flash Details")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 31, N_("Focus Mode")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 32, N_("AE Setting")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 33, N_("Image Stabilization")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 34, N_("Display Aperture")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 35, N_("Zoom Source Width")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 36, N_("Zoom Target Width")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 39, N_("Photo Effect")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 40, N_("Manual Flash Output")},
+ {MNOTE_CANON_TAG_SETTINGS_1, 41, N_("Color Tone")},
+ {MNOTE_CANON_TAG_FOCAL_LENGTH, 0, N_("Focal Type")},
+ {MNOTE_CANON_TAG_FOCAL_LENGTH, 1, N_("Focal Length")},
+ {MNOTE_CANON_TAG_FOCAL_LENGTH, 2, N_("Focal Plane X Size")},
+ {MNOTE_CANON_TAG_FOCAL_LENGTH, 3, N_("Focal Plane Y Size")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 0, N_("Auto ISO")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 1, N_("Shot ISO")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 2, N_("Measured EV")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 3, N_("Target Aperture")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 4, N_("Target Exposure Time")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 5, N_("Exposure Compensation")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 6, N_("White Balance")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 7, N_("Slow Shutter")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 8, N_("Sequence Number")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 12, N_("Flash Guide Number")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 13, N_("AF Point")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 14, N_("Flash Exposure Compensation")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 15, N_("AE Bracketing")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 16, N_("AE Bracket Value")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 18, N_("Focus Distance Upper")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 19, N_("Focus Distance Lower")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 20, N_("FNumber")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 21, N_("Exposure Time")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 23, N_("Bulb Duration")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 25, N_("Camera Type")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 26, N_("Auto Rotate")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 27, N_("ND Filter")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 28, N_("Self-timer")},
+ {MNOTE_CANON_TAG_SETTINGS_2, 32, N_("Manual Flash Output")},
+ {MNOTE_CANON_TAG_PANORAMA, 2, N_("Panorama Frame")},
+ {MNOTE_CANON_TAG_PANORAMA, 5, N_("Panorama Direction")},
+ {MNOTE_CANON_TAG_COLOR_INFORMATION, 0, N_("Tone Curve")},
+ {MNOTE_CANON_TAG_COLOR_INFORMATION, 2, N_("Sharpness Frequency")},
+ {MNOTE_CANON_TAG_COLOR_INFORMATION, 7, N_("White Balance")},
+ {MNOTE_CANON_TAG_COLOR_INFORMATION, 9, N_("Picture Style")},
+#endif
+ {0, 0, NULL}
+};
+
+const char *
+mnote_canon_tag_get_name (MnoteCanonTag t)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ if (table[i].tag == t) return table[i].name; /* do not translate */
+ return NULL;
+}
+
+const char *
+mnote_canon_tag_get_name_sub (MnoteCanonTag t, unsigned int s, ExifDataOption o)
+{
+ unsigned int i;
+ int tag_found = 0;
+
+ for (i = 0; i < sizeof (table_sub) / sizeof (table_sub[0]); i++) {
+ if (table_sub[i].tag == t) {
+ if (table_sub[i].subtag == s)
+ return table_sub[i].name;
+ tag_found = 1;
+ }
+ }
+ if (!tag_found || !(o & EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS))
+ return mnote_canon_tag_get_name (t);
+ else
+ return NULL;
+}
+
+const char *
+mnote_canon_tag_get_title (MnoteCanonTag t)
+{
+ unsigned int i;
+
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ if (table[i].tag == t) return (_(table[i].title));
+ return NULL;
+}
+
+const char *
+mnote_canon_tag_get_title_sub (MnoteCanonTag t, unsigned int s, ExifDataOption o)
+{
+ unsigned int i;
+ int tag_found = 0;
+
+ for (i = 0; i < sizeof (table_sub) / sizeof (table_sub[0]); i++) {
+ if (table_sub[i].tag == t) {
+ if (table_sub[i].subtag == s)
+ return _(table_sub[i].name);
+ tag_found = 1;
+ }
+ }
+ if (!tag_found || !(o & EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS))
+ return mnote_canon_tag_get_title (t);
+ else
+ return NULL;
+}
+
+const char *
+mnote_canon_tag_get_description (MnoteCanonTag t)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ if (table[i].tag == t) {
+ if (!table[i].description || !*table[i].description)
+ return "";
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ return _(table[i].description);
+ }
+ return NULL;
+}
diff --git a/libexif/canon/mnote-canon-tag.h b/libexif/canon/mnote-canon-tag.h
new file mode 100644
index 0000000..0c7d9aa
--- /dev/null
+++ b/libexif/canon/mnote-canon-tag.h
@@ -0,0 +1,59 @@
+/* mnote-canon-tag.h
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MNOTE_CANON_TAG_H__
+#define __MNOTE_CANON_TAG_H__
+
+#include <libexif/exif-data.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+enum _MnoteCanonTag {
+ MNOTE_CANON_TAG_UNKNOWN_0 = 0x0,
+ MNOTE_CANON_TAG_SETTINGS_1 = 0x1,
+ MNOTE_CANON_TAG_FOCAL_LENGTH = 0x2,
+ MNOTE_CANON_TAG_UNKNOWN_3 = 0x3,
+ MNOTE_CANON_TAG_SETTINGS_2 = 0x4,
+ MNOTE_CANON_TAG_PANORAMA = 0x5,
+ MNOTE_CANON_TAG_IMAGE_TYPE = 0x6,
+ MNOTE_CANON_TAG_FIRMWARE = 0x7,
+ MNOTE_CANON_TAG_IMAGE_NUMBER = 0x8,
+ MNOTE_CANON_TAG_OWNER = 0x9,
+ MNOTE_CANON_TAG_UNKNOWN_10 = 0xa,
+ MNOTE_CANON_TAG_SERIAL_NUMBER = 0xc,
+ MNOTE_CANON_TAG_UNKNOWN_13 = 0xd,
+ MNOTE_CANON_TAG_CUSTOM_FUNCS = 0xf,
+ MNOTE_CANON_TAG_COLOR_INFORMATION = 0xa0
+};
+typedef enum _MnoteCanonTag MnoteCanonTag;
+
+const char *mnote_canon_tag_get_name (MnoteCanonTag);
+const char *mnote_canon_tag_get_name_sub (MnoteCanonTag, unsigned int, ExifDataOption);
+const char *mnote_canon_tag_get_title (MnoteCanonTag);
+const char *mnote_canon_tag_get_title_sub (MnoteCanonTag, unsigned int, ExifDataOption);
+const char *mnote_canon_tag_get_description (MnoteCanonTag);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MNOTE_CANON_TAG_H__ */
diff --git a/libexif/exif-data.c b/libexif/exif-data.c
index 3ad2bb4..5a7763b 100644
--- a/libexif/exif-data.c
+++ b/libexif/exif-data.c
@@ -30,6 +30,11 @@
#include <libexif/i18n.h>
#include <libexif/exif-system.h>
+#include <libexif/canon/exif-mnote-data-canon.h>
+#include <libexif/fuji/exif-mnote-data-fuji.h>
+#include <libexif/olympus/exif-mnote-data-olympus.h>
+#include <libexif/pentax/exif-mnote-data-pentax.h>
+
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
@@ -744,8 +749,29 @@ interpret_maker_note(ExifData *data, const unsigned char *d, unsigned int ds)
if (!e)
return;
- /** Maker note detection removed **/
-
+ if ((mnoteid = exif_mnote_data_olympus_identify (data, e)) != 0) {
+ exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG,
+ "ExifData", "Olympus MakerNote variant type %d", mnoteid);
+ data->priv->md = exif_mnote_data_olympus_new (data->priv->mem);
+
+ } else if ((mnoteid = exif_mnote_data_canon_identify (data, e)) != 0) {
+ exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG,
+ "ExifData", "Canon MakerNote variant type %d", mnoteid);
+ data->priv->md = exif_mnote_data_canon_new (data->priv->mem, data->priv->options);
+
+ } else if ((mnoteid = exif_mnote_data_fuji_identify (data, e)) != 0) {
+ exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG,
+ "ExifData", "Fuji MakerNote variant type %d", mnoteid);
+ data->priv->md = exif_mnote_data_fuji_new (data->priv->mem);
+
+ /* NOTE: Must do Pentax detection last because some of the
+ * heuristics are pretty general. */
+ } else if ((mnoteid = exif_mnote_data_pentax_identify (data, e)) != 0) {
+ exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG,
+ "ExifData", "Pentax MakerNote variant type %d", mnoteid);
+ data->priv->md = exif_mnote_data_pentax_new (data->priv->mem);
+ }
+
/*
* If we are able to interpret the maker note, do so.
*/
diff --git a/libexif/fuji/Makefile-files b/libexif/fuji/Makefile-files
new file mode 100644
index 0000000..3a520b3
--- /dev/null
+++ b/libexif/fuji/Makefile-files
@@ -0,0 +1,7 @@
+# -*- Makefile -*-
+noinst_LTLIBRARIES += libmnote-fuji.la
+libmnote_fuji_la_SOURCES = \
+ fuji/mnote-fuji-entry.c fuji/mnote-fuji-entry.h \
+ fuji/exif-mnote-data-fuji.c fuji/exif-mnote-data-fuji.h \
+ fuji/mnote-fuji-tag.c fuji/mnote-fuji-tag.h
+libmnote_fuji_la_LIBADD = $(LTLIBINTL)
diff --git a/libexif/fuji/exif-mnote-data-fuji.c b/libexif/fuji/exif-mnote-data-fuji.c
new file mode 100644
index 0000000..ce70bb6
--- /dev/null
+++ b/libexif/fuji/exif-mnote-data-fuji.c
@@ -0,0 +1,363 @@
+/* exif-mnote-data-fuji.c
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#include <config.h>
+#include <libexif/exif-byte-order.h>
+#include <libexif/exif-utils.h>
+
+#include "exif-mnote-data-fuji.h"
+
+#define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
+
+struct _MNoteFujiDataPrivate {
+ ExifByteOrder order;
+};
+
+static void
+exif_mnote_data_fuji_clear (ExifMnoteDataFuji *n)
+{
+ ExifMnoteData *d = (ExifMnoteData *) n;
+ unsigned int i;
+
+ if (!n) return;
+
+ if (n->entries) {
+ for (i = 0; i < n->count; i++)
+ if (n->entries[i].data) {
+ exif_mem_free (d->mem, n->entries[i].data);
+ n->entries[i].data = NULL;
+ }
+ exif_mem_free (d->mem, n->entries);
+ n->entries = NULL;
+ n->count = 0;
+ }
+}
+
+static void
+exif_mnote_data_fuji_free (ExifMnoteData *n)
+{
+ if (!n) return;
+
+ exif_mnote_data_fuji_clear ((ExifMnoteDataFuji *) n);
+}
+
+static char *
+exif_mnote_data_fuji_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen)
+{
+ ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d;
+
+ if (!d || !val) return NULL;
+ if (i > n->count -1) return NULL;
+/*
+ exif_log (d->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataFuji",
+ "Querying value for tag '%s'...",
+ mnote_fuji_tag_get_name (n->entries[i].tag));
+*/
+ return mnote_fuji_entry_get_value (&n->entries[i], val, maxlen);
+}
+
+static void
+exif_mnote_data_fuji_save (ExifMnoteData *ne, unsigned char **buf,
+ unsigned int *buf_size)
+{
+ ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) ne;
+ size_t i, o, s, doff;
+ unsigned char *t;
+ size_t ts;
+
+ if (!n || !buf || !buf_size) return;
+
+ /*
+ * Allocate enough memory for all entries and the number
+ * of entries.
+ */
+ *buf_size = 8 + 4 + 2 + n->count * 12 + 4;
+ *buf = exif_mem_alloc (ne->mem, *buf_size);
+ if (!*buf) {
+ *buf_size = 0;
+ return;
+ }
+
+ /*
+ * Header: "FUJIFILM" and 4 bytes offset to the first entry.
+ * As the first entry will start right thereafter, the offset is 12.
+ */
+ memcpy (*buf, "FUJIFILM", 8);
+ exif_set_long (*buf + 8, n->order, 12);
+
+ /* Save the number of entries */
+ exif_set_short (*buf + 8 + 4, n->order, (ExifShort) n->count);
+
+ /* Save each entry */
+ for (i = 0; i < n->count; i++) {
+ o = 8 + 4 + 2 + i * 12;
+ exif_set_short (*buf + o + 0, n->order, (ExifShort) n->entries[i].tag);
+ exif_set_short (*buf + o + 2, n->order, (ExifShort) n->entries[i].format);
+ exif_set_long (*buf + o + 4, n->order, n->entries[i].components);
+ o += 8;
+ s = exif_format_get_size (n->entries[i].format) *
+ n->entries[i].components;
+ if (s > 65536) {
+ /* Corrupt data: EXIF data size is limited to the
+ * maximum size of a JPEG segment (64 kb).
+ */
+ continue;
+ }
+ if (s > 4) {
+ ts = *buf_size + s;
+
+ /* Ensure even offsets. Set padding bytes to 0. */
+ if (s & 1) ts += 1;
+ t = exif_mem_realloc (ne->mem, *buf, ts);
+ if (!t) {
+ return;
+ }
+ *buf = t;
+ *buf_size = ts;
+ doff = *buf_size - s;
+ if (s & 1) { doff--; *(*buf + *buf_size - 1) = '\0'; }
+ exif_set_long (*buf + o, n->order, doff);
+ } else
+ doff = o;
+
+ /*
+ * Write the data. Fill unneeded bytes with 0. Do not
+ * crash if data is NULL.
+ */
+ if (!n->entries[i].data) memset (*buf + doff, 0, s);
+ else memcpy (*buf + doff, n->entries[i].data, s);
+ }
+}
+
+static void
+exif_mnote_data_fuji_load (ExifMnoteData *en,
+ const unsigned char *buf, unsigned int buf_size)
+{
+ ExifMnoteDataFuji *n = (ExifMnoteDataFuji*) en;
+ ExifLong c;
+ size_t i, tcount, o, datao;
+
+ if (!n || !buf || !buf_size) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteDataFuji", "Short MakerNote");
+ return;
+ }
+ datao = 6 + n->offset;
+ if (CHECKOVERFLOW(datao, buf_size, 12)) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteDataFuji", "Short MakerNote");
+ return;
+ }
+
+ n->order = EXIF_BYTE_ORDER_INTEL;
+ datao += exif_get_long (buf + datao + 8, EXIF_BYTE_ORDER_INTEL);
+ if (CHECKOVERFLOW(datao, buf_size, 2)) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteDataFuji", "Short MakerNote");
+ return;
+ }
+
+ /* Read the number of tags */
+ c = exif_get_short (buf + datao, EXIF_BYTE_ORDER_INTEL);
+ datao += 2;
+
+ /* Remove any old entries */
+ exif_mnote_data_fuji_clear (n);
+
+ /* Reserve enough space for all the possible MakerNote tags */
+ n->entries = exif_mem_alloc (en->mem, sizeof (MnoteFujiEntry) * c);
+ if (!n->entries) {
+ EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteDataFuji", sizeof (MnoteFujiEntry) * c);
+ return;
+ }
+
+ /* Parse all c entries, storing ones that are successfully parsed */
+ tcount = 0;
+ for (i = c, o = datao; i; --i, o += 12) {
+ size_t s;
+
+ memset(&n->entries[tcount], 0, sizeof(MnoteFujiEntry));
+ if (CHECKOVERFLOW(o, buf_size, 12)) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteDataFuji", "Short MakerNote");
+ break;
+ }
+
+ n->entries[tcount].tag = exif_get_short (buf + o, n->order);
+ n->entries[tcount].format = exif_get_short (buf + o + 2, n->order);
+ n->entries[tcount].components = exif_get_long (buf + o + 4, n->order);
+ n->entries[tcount].order = n->order;
+
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataFuji",
+ "Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
+ mnote_fuji_tag_get_name (n->entries[tcount].tag));
+
+ /* Check if we overflow the multiplication. Use buf_size as the max size for integer overflow detection,
+ * we will check the buffer sizes closer later. */
+ if ( exif_format_get_size (n->entries[tcount].format) &&
+ buf_size / exif_format_get_size (n->entries[tcount].format) < n->entries[tcount].components
+ ) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteDataFuji", "Tag size overflow detected (%u * %lu)", exif_format_get_size (n->entries[tcount].format), n->entries[tcount].components);
+ continue;
+ }
+
+ /*
+ * Size? If bigger than 4 bytes, the actual data is not
+ * in the entry but somewhere else (offset).
+ */
+ s = exif_format_get_size (n->entries[tcount].format) * n->entries[tcount].components;
+ n->entries[tcount].size = s;
+ if (s) {
+ size_t dataofs = o + 8;
+ if (s > 4)
+ /* The data in this case is merely a pointer */
+ dataofs = exif_get_long (buf + dataofs, n->order) + 6 + n->offset;
+ if (CHECKOVERFLOW(dataofs, buf_size, s)) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteDataFuji", "Tag data past end of "
+ "buffer (%zu >= %u)", dataofs + s, buf_size);
+ continue;
+ }
+
+ n->entries[tcount].data = exif_mem_alloc (en->mem, s);
+ if (!n->entries[tcount].data) {
+ EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteDataFuji", s);
+ continue;
+ }
+ memcpy (n->entries[tcount].data, buf + dataofs, s);
+ }
+
+ /* Tag was successfully parsed */
+ ++tcount;
+ }
+ /* Store the count of successfully parsed tags */
+ n->count = tcount;
+}
+
+static unsigned int
+exif_mnote_data_fuji_count (ExifMnoteData *n)
+{
+ return n ? ((ExifMnoteDataFuji *) n)->count : 0;
+}
+
+static unsigned int
+exif_mnote_data_fuji_get_id (ExifMnoteData *d, unsigned int n)
+{
+ ExifMnoteDataFuji *note = (ExifMnoteDataFuji *) d;
+
+ if (!note) return 0;
+ if (note->count <= n) return 0;
+ return note->entries[n].tag;
+}
+
+static const char *
+exif_mnote_data_fuji_get_name (ExifMnoteData *d, unsigned int i)
+{
+ ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d;
+
+ if (!n) return NULL;
+ if (i >= n->count) return NULL;
+ return mnote_fuji_tag_get_name (n->entries[i].tag);
+}
+
+static const char *
+exif_mnote_data_fuji_get_title (ExifMnoteData *d, unsigned int i)
+{
+ ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d;
+
+ if (!n) return NULL;
+ if (i >= n->count) return NULL;
+ return mnote_fuji_tag_get_title (n->entries[i].tag);
+}
+
+static const char *
+exif_mnote_data_fuji_get_description (ExifMnoteData *d, unsigned int i)
+{
+ ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d;
+
+ if (!n) return NULL;
+ if (i >= n->count) return NULL;
+ return mnote_fuji_tag_get_description (n->entries[i].tag);
+}
+
+static void
+exif_mnote_data_fuji_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
+{
+ ExifByteOrder o_orig;
+ ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d;
+ unsigned int i;
+
+ if (!n) return;
+
+ o_orig = n->order;
+ n->order = o;
+ for (i = 0; i < n->count; i++) {
+ n->entries[i].order = o;
+ exif_array_set_byte_order (n->entries[i].format, n->entries[i].data,
+ n->entries[i].components, o_orig, o);
+ }
+}
+
+static void
+exif_mnote_data_fuji_set_offset (ExifMnoteData *n, unsigned int o)
+{
+ if (n) ((ExifMnoteDataFuji *) n)->offset = o;
+}
+
+int
+exif_mnote_data_fuji_identify (const ExifData *ed, const ExifEntry *e)
+{
+ return ((e->size >= 12) && !memcmp (e->data, "FUJIFILM", 8));
+}
+
+ExifMnoteData *
+exif_mnote_data_fuji_new (ExifMem *mem)
+{
+ ExifMnoteData *d;
+
+ if (!mem) return NULL;
+
+ d = exif_mem_alloc (mem, sizeof (ExifMnoteDataFuji));
+ if (!d) return NULL;
+
+ memset(d, 0, sizeof(ExifMnoteDataFuji));
+
+ exif_mnote_data_construct (d, mem);
+
+ /* Set up function pointers */
+ d->methods.free = exif_mnote_data_fuji_free;
+ d->methods.set_byte_order = exif_mnote_data_fuji_set_byte_order;
+ d->methods.set_offset = exif_mnote_data_fuji_set_offset;
+ d->methods.load = exif_mnote_data_fuji_load;
+ d->methods.save = exif_mnote_data_fuji_save;
+ d->methods.count = exif_mnote_data_fuji_count;
+ d->methods.get_id = exif_mnote_data_fuji_get_id;
+ d->methods.get_name = exif_mnote_data_fuji_get_name;
+ d->methods.get_title = exif_mnote_data_fuji_get_title;
+ d->methods.get_description = exif_mnote_data_fuji_get_description;
+ d->methods.get_value = exif_mnote_data_fuji_get_value;
+
+ return d;
+}
diff --git a/libexif/fuji/exif-mnote-data-fuji.h b/libexif/fuji/exif-mnote-data-fuji.h
new file mode 100644
index 0000000..2a7cd3e
--- /dev/null
+++ b/libexif/fuji/exif-mnote-data-fuji.h
@@ -0,0 +1,53 @@
+/* exif-mnote-data-fuji.h
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MNOTE_FUJI_CONTENT_H__
+#define __MNOTE_FUJI_CONTENT_H__
+
+#include <libexif/exif-mnote-data.h>
+#include <libexif/exif-mnote-data-priv.h>
+#include <libexif/exif-data.h>
+#include <libexif/fuji/mnote-fuji-entry.h>
+
+typedef struct _ExifMnoteDataFuji ExifMnoteDataFuji;
+
+struct _ExifMnoteDataFuji {
+ ExifMnoteData parent;
+
+ MnoteFujiEntry *entries;
+ unsigned int count;
+
+ ExifByteOrder order;
+ unsigned int offset;
+};
+
+/*! Detect if MakerNote is recognized as one handled by the Fuji module.
+ *
+ * \param[in] ed image #ExifData to identify as as a Fuji type
+ * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but
+ * duplicated here for convenience
+ * \return 0 if not recognized, nonzero if recognized. The specific nonzero
+ * value returned may identify a subtype unique within this module.
+ */
+int exif_mnote_data_fuji_identify (const ExifData *ed, const ExifEntry *e);
+
+ExifMnoteData *exif_mnote_data_fuji_new (ExifMem *);
+
+#endif /* __MNOTE_FUJI_CONTENT_H__ */
diff --git a/libexif/fuji/mnote-fuji-entry.c b/libexif/fuji/mnote-fuji-entry.c
new file mode 100644
index 0000000..0ca1634
--- /dev/null
+++ b/libexif/fuji/mnote-fuji-entry.c
@@ -0,0 +1,306 @@
+/* mnote-fuji-entry.c
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <config.h>
+
+#include <libexif/i18n.h>
+
+#include "mnote-fuji-entry.h"
+
+#define CF(format,target,v,maxlen) \
+{ \
+ if (format != target) { \
+ snprintf (v, maxlen, \
+ _("Invalid format '%s', " \
+ "expected '%s'."), \
+ exif_format_get_name (format), \
+ exif_format_get_name (target)); \
+ break; \
+ } \
+}
+
+#define CC(number,target,v,maxlen) \
+{ \
+ if (number != target) { \
+ snprintf (v, maxlen, \
+ _("Invalid number of components (%i, " \
+ "expected %i)."), (int) number, (int) target); \
+ break; \
+ } \
+}
+
+static const struct {
+ ExifTag tag;
+ struct {
+ int index;
+ const char *string;
+ } elem[22];
+} items[] = {
+#ifndef NO_VERBOSE_TAG_DATA
+ { MNOTE_FUJI_TAG_SHARPNESS,
+ { {1, N_("Softest")},
+ {2, N_("Soft")},
+ {3, N_("Normal")},
+ {4, N_("Hard")},
+ {5, N_("Hardest")},
+ {0x0082, N_("Medium soft")},
+ {0x0084, N_("Medium hard")},
+ {0x8000, N_("Film simulation mode")},
+ {0xFFFF, N_("Off")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_WHITE_BALANCE,
+ { {0, N_("Auto")},
+ {0x100, N_("Daylight")},
+ {0x200, N_("Cloudy")},
+ {0x300, N_("Daylight fluorescent")},
+ {0x301, N_("Day white fluorescent")},
+ {0x302, N_("White fluorescent")},
+ {0x400, N_("Incandescent")},
+ {0x500, N_("Flash")},
+ {0xF00, N_("Custom")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_COLOR,
+ { {0, N_("Standard")},
+ {0x0080, N_("Medium high")},
+ {0x0100, N_("High")},
+ {0x0180, N_("Medium low")},
+ {0x0200, N_("Original")},
+ {0x0300, N_("Black & white")},
+ {0x8000, N_("Film simulation mode")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_TONE,
+ { {0, N_("Standard")},
+ {0x0080, N_("Medium hard")},
+ {0x0100, N_("Hard")},
+ {0x0180, N_("Medium soft")},
+ {0x0200, N_("Original")},
+ {0x8000, N_("Film simulation mode")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_FLASH_MODE,
+ { {0, N_("Auto")},
+ {1, N_("On")},
+ {2, N_("Off")},
+ {3, N_("Red-eye reduction")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_MACRO,
+ { {0, N_("Off")},
+ {1, N_("On")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_FOCUS_MODE,
+ { {0, N_("Auto")},
+ {1, N_("Manual")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_SLOW_SYNC,
+ { {0, N_("Off")},
+ {1, N_("On")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_PICTURE_MODE,
+ { {0, N_("Auto")},
+ {1, N_("Portrait")},
+ {2, N_("Landscape")},
+ {4, N_("Sports")},
+ {5, N_("Night")},
+ {6, N_("Program AE")},
+ {7, N_("Natural photo")},
+ {8, N_("Vibration reduction")},
+ {0x000A, N_("Sunset")},
+ {0x000B, N_("Museum")},
+ {0x000C, N_("Party")},
+ {0x000D, N_("Flower")},
+ {0x000E, N_("Text")},
+ {0x000F, N_("NP & flash")},
+ {0x0010, N_("Beach")},
+ {0x0011, N_("Snow")},
+ {0x0012, N_("Fireworks")},
+ {0x0013, N_("Underwater")},
+ {0x0100, N_("Aperture priority AE")},
+ {0x0200, N_("Shutter priority AE")},
+ {0x0300, N_("Manual exposure")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_CONT_TAKING,
+ { {0, N_("Off")},
+ {1, N_("On")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_FINEPIX_COLOR,
+ { {0x00, N_("F-Standard")},
+ {0x10, N_("F-Chrome")},
+ {0x30, N_("F-B&W")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_BLUR_CHECK,
+ { {0, N_("No blur")},
+ {1, N_("Blur warning")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_FOCUS_CHECK,
+ { {0, N_("Focus good")},
+ {1, N_("Out of focus")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_AUTO_EXPOSURE_CHECK,
+ { {0, N_("AE good")},
+ {1, N_("Over exposed")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_DYNAMIC_RANGE,
+ { {1, N_("Standard")},
+ {3, N_("Wide")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_FILM_MODE,
+ { {0, N_("F0/Standard")},
+ {0x0100, N_("F1/Studio portrait")},
+ {0x0110, N_("F1a/Professional portrait")},
+ {0x0120, N_("F1b/Professional portrait")},
+ {0x0130, N_("F1c/Professional portrait")},
+ {0x0200, N_("F2/Fujichrome")},
+ {0x0300, N_("F3/Studio portrait Ex")},
+ {0x0400, N_("F4/Velvia")},
+ {0, NULL}}},
+ { MNOTE_FUJI_TAG_DYNAMIC_RANGE_SETTING,
+ { {0, N_("Auto (100-400%)")},
+ {1, N_("RAW")},
+ {0x0100, N_("Standard (100%)")},
+ {0x0200, N_("Wide1 (230%)")},
+ {0x0201, N_("Wide2 (400%)")},
+ {0x8000, N_("Film simulation mode")},
+ {0, NULL}}},
+#endif
+ {0, {{0, NULL}}}
+};
+
+
+char *
+mnote_fuji_entry_get_value (MnoteFujiEntry *entry,
+ char *val, unsigned int maxlen)
+{
+ ExifLong vl;
+ ExifSLong vsl;
+ ExifShort vs, vs2;
+ ExifRational vr;
+ ExifSRational vsr;
+ int i, j;
+
+ if (!entry) return (NULL);
+
+ memset (val, 0, maxlen);
+ maxlen--;
+
+ switch (entry->tag) {
+ case MNOTE_FUJI_TAG_VERSION:
+ CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
+ CC (entry->components, 4, val, maxlen);
+ memcpy (val, entry->data, MIN(maxlen, entry->size));
+ break;
+ case MNOTE_FUJI_TAG_SHARPNESS:
+ case MNOTE_FUJI_TAG_WHITE_BALANCE:
+ case MNOTE_FUJI_TAG_COLOR:
+ case MNOTE_FUJI_TAG_TONE:
+ case MNOTE_FUJI_TAG_FLASH_MODE:
+ case MNOTE_FUJI_TAG_MACRO:
+ case MNOTE_FUJI_TAG_FOCUS_MODE:
+ case MNOTE_FUJI_TAG_SLOW_SYNC:
+ case MNOTE_FUJI_TAG_PICTURE_MODE:
+ case MNOTE_FUJI_TAG_CONT_TAKING:
+ case MNOTE_FUJI_TAG_FINEPIX_COLOR:
+ case MNOTE_FUJI_TAG_BLUR_CHECK:
+ case MNOTE_FUJI_TAG_FOCUS_CHECK:
+ case MNOTE_FUJI_TAG_AUTO_EXPOSURE_CHECK:
+ case MNOTE_FUJI_TAG_DYNAMIC_RANGE:
+ case MNOTE_FUJI_TAG_FILM_MODE:
+ case MNOTE_FUJI_TAG_DYNAMIC_RANGE_SETTING:
+ CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
+ CC (entry->components, 1, val, maxlen);
+ vs = exif_get_short (entry->data, entry->order);
+
+ /* search the tag */
+ for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++);
+ if (!items[i].tag) {
+ snprintf (val, maxlen,
+ _("Internal error (unknown value %i)"), vs);
+ break;
+ }
+
+ /* find the value */
+ for (j = 0; items[i].elem[j].string &&
+ (items[i].elem[j].index < vs); j++);
+ if (items[i].elem[j].index != vs) {
+ snprintf (val, maxlen,
+ _("Internal error (unknown value %i)"), vs);
+ break;
+ }
+ strncpy (val, _(items[i].elem[j].string), maxlen);
+ break;
+ case MNOTE_FUJI_TAG_FOCUS_POINT:
+ CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
+ CC (entry->components, 2, val, maxlen);
+ vs = exif_get_short (entry->data, entry->order);
+ vs2 = exif_get_short (entry->data+2, entry->order);
+ snprintf (val, maxlen, "%i, %i", vs, vs2);
+ break;
+ case MNOTE_FUJI_TAG_MIN_FOCAL_LENGTH:
+ case MNOTE_FUJI_TAG_MAX_FOCAL_LENGTH:
+ CF (entry->format, EXIF_FORMAT_RATIONAL, val, maxlen);
+ CC (entry->components, 1, val, maxlen);
+ vr = exif_get_rational (entry->data, entry->order);
+ if (!vr.denominator) break;
+ snprintf (val, maxlen, _("%2.2f mm"), (double) vr.numerator /
+ vr.denominator);
+ break;
+
+ default:
+ switch (entry->format) {
+ case EXIF_FORMAT_ASCII:
+ strncpy (val, (char *)entry->data, MIN(maxlen, entry->size));
+ break;
+ case EXIF_FORMAT_SHORT:
+ vs = exif_get_short (entry->data, entry->order);
+ snprintf (val, maxlen, "%i", vs);
+ break;
+ case EXIF_FORMAT_LONG:
+ vl = exif_get_long (entry->data, entry->order);
+ snprintf (val, maxlen, "%lu", (long unsigned) vl);
+ break;
+ case EXIF_FORMAT_SLONG:
+ vsl = exif_get_slong (entry->data, entry->order);
+ snprintf (val, maxlen, "%li", (long int) vsl);
+ break;
+ case EXIF_FORMAT_RATIONAL:
+ vr = exif_get_rational (entry->data, entry->order);
+ if (!vr.denominator) break;
+ snprintf (val, maxlen, "%2.4f", (double) vr.numerator /
+ vr.denominator);
+ break;
+ case EXIF_FORMAT_SRATIONAL:
+ vsr = exif_get_srational (entry->data, entry->order);
+ if (!vsr.denominator) break;
+ snprintf (val, maxlen, "%2.4f", (double) vsr.numerator /
+ vsr.denominator);
+ break;
+ case EXIF_FORMAT_UNDEFINED:
+ default:
+ snprintf (val, maxlen, _("%i bytes unknown data"),
+ entry->size);
+ break;
+ }
+ break;
+ }
+
+ return (val);
+}
diff --git a/libexif/fuji/mnote-fuji-entry.h b/libexif/fuji/mnote-fuji-entry.h
new file mode 100644
index 0000000..a8395c5
--- /dev/null
+++ b/libexif/fuji/mnote-fuji-entry.h
@@ -0,0 +1,45 @@
+/* mnote-fuji-entry.h
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MNOTE_FUJI_ENTRY_H__
+#define __MNOTE_FUJI_ENTRY_H__
+
+#include <libexif/exif-format.h>
+#include <libexif/fuji/mnote-fuji-tag.h>
+
+typedef struct _MnoteFujiEntry MnoteFujiEntry;
+typedef struct _MnoteFujiEntryPrivate MnoteFujiEntryPrivate;
+
+#include <libexif/fuji/exif-mnote-data-fuji.h>
+
+struct _MnoteFujiEntry {
+ MnoteFujiTag tag;
+ ExifFormat format;
+ unsigned long components;
+
+ unsigned char *data;
+ unsigned int size;
+
+ ExifByteOrder order;
+};
+
+char *mnote_fuji_entry_get_value (MnoteFujiEntry *entry, char *val, unsigned int maxlen);
+
+#endif /* __MNOTE_FUJI_ENTRY_H__ */
diff --git a/libexif/fuji/mnote-fuji-tag.c b/libexif/fuji/mnote-fuji-tag.c
new file mode 100644
index 0000000..3b80597
--- /dev/null
+++ b/libexif/fuji/mnote-fuji-tag.c
@@ -0,0 +1,105 @@
+/* mnote-fuji-tag.c
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+
+#include <config.h>
+#include <libexif/i18n.h>
+
+#include "mnote-fuji-tag.h"
+
+
+static const struct {
+ MnoteFujiTag tag;
+ const char *name;
+ const char *title;
+ const char *description;
+} table[] = {
+#ifndef NO_VERBOSE_TAG_STRINGS
+ {MNOTE_FUJI_TAG_VERSION, "Version", N_("Maker Note Version"), ""},
+ {MNOTE_FUJI_TAG_SERIAL_NUMBER, "SerialNumber", N_("Serial Number"), N_("This number is unique and based on the date of manufacture.")},
+ {MNOTE_FUJI_TAG_QUALITY, "Quality", N_("Quality"), ""},
+ {MNOTE_FUJI_TAG_SHARPNESS, "Sharpness", N_("Sharpness"), ""},
+ {MNOTE_FUJI_TAG_WHITE_BALANCE, "WhiteBalance", N_("White Balance"), ""},
+ {MNOTE_FUJI_TAG_COLOR, "ChromaticitySaturation", N_("Chromaticity Saturation"), ""},
+ {MNOTE_FUJI_TAG_TONE, "Contrast", N_("Contrast"), ""},
+ {MNOTE_FUJI_TAG_FLASH_MODE, "FlashMode", N_("Flash Mode"), ""},
+ {MNOTE_FUJI_TAG_FLASH_STRENGTH, "FlashStrength", N_("Flash Firing Strength Compensation"), ""},
+ {MNOTE_FUJI_TAG_MACRO, "MacroMode", N_("Macro Mode"), ""},
+ {MNOTE_FUJI_TAG_FOCUS_MODE, "FocusingMode", N_("Focusing Mode"), ""},
+ {MNOTE_FUJI_TAG_FOCUS_POINT, "FocusPoint", N_("Focus Point"), ""},
+ {MNOTE_FUJI_TAG_SLOW_SYNC, "SlowSynchro", N_("Slow Synchro Mode"), ""},
+ {MNOTE_FUJI_TAG_PICTURE_MODE, "PictureMode", N_("Picture Mode"), ""},
+ {MNOTE_FUJI_TAG_CONT_TAKING, "ContinuousTaking", N_("Continuous Taking"), ""},
+ {MNOTE_FUJI_TAG_SEQUENCE_NUMBER, "ContinuousSequence", N_("Continuous Sequence Number"), ""},
+ {MNOTE_FUJI_TAG_FINEPIX_COLOR, "FinePixColor", N_("FinePix Color"), ""},
+ {MNOTE_FUJI_TAG_BLUR_CHECK, "BlurCheck", N_("Blur Check"), ""},
+ {MNOTE_FUJI_TAG_FOCUS_CHECK, "AutoFocusCheck", N_("Auto Focus Check"), ""},
+ {MNOTE_FUJI_TAG_AUTO_EXPOSURE_CHECK, "AutoExposureCheck", N_("Auto Exposure Check"), ""},
+ {MNOTE_FUJI_TAG_DYNAMIC_RANGE, "DynamicRange", N_("Dynamic Range"), ""},
+ {MNOTE_FUJI_TAG_FILM_MODE, "FilmMode", N_("Film Simulation Mode"), ""},
+ {MNOTE_FUJI_TAG_DYNAMIC_RANGE_SETTING, "DRangeMode", N_("Dynamic Range Wide Mode"), ""},
+ {MNOTE_FUJI_TAG_DEV_DYNAMIC_RANGE_SETTING, "DevDRangeMode", N_("Development Dynamic Range Wide Mode"), ""},
+ {MNOTE_FUJI_TAG_MIN_FOCAL_LENGTH, "MinFocalLen", N_("Minimum Focal Length"), ""},
+ {MNOTE_FUJI_TAG_MAX_FOCAL_LENGTH, "MaxFocalLen", N_("Maximum Focal Length"), ""},
+ {MNOTE_FUJI_TAG_MAX_APERT_AT_MIN_FOC, "MaxApertAtMinFoc", N_("Maximum Aperture at Minimum Focal"), ""},
+ {MNOTE_FUJI_TAG_MAX_APERT_AT_MAX_FOC, "MaxApertAtMaxFoc", N_("Maximum Aperture at Maximum Focal"), ""},
+ {MNOTE_FUJI_TAG_FILE_SOURCE, "FileSource", N_("File Source"), ""},
+ {MNOTE_FUJI_TAG_ORDER_NUMBER, "OrderNumber", N_("Order Number"), ""},
+ {MNOTE_FUJI_TAG_FRAME_NUMBER, "FrameNumber", N_("Frame Number"), ""},
+#endif
+ {0, NULL, NULL, NULL}
+};
+
+const char *
+mnote_fuji_tag_get_name (MnoteFujiTag t)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ if (table[i].tag == t) return (table[i].name);
+ return NULL;
+}
+
+const char *
+mnote_fuji_tag_get_title (MnoteFujiTag t)
+{
+ unsigned int i;
+
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ if (table[i].tag == t) return (_(table[i].title));
+ return NULL;
+}
+
+const char *
+mnote_fuji_tag_get_description (MnoteFujiTag t)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ if (table[i].tag == t) {
+ if (!table[i].description || !*table[i].description)
+ return "";
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ return _(table[i].description);
+ }
+ return NULL;
+}
diff --git a/libexif/fuji/mnote-fuji-tag.h b/libexif/fuji/mnote-fuji-tag.h
new file mode 100644
index 0000000..1d250e4
--- /dev/null
+++ b/libexif/fuji/mnote-fuji-tag.h
@@ -0,0 +1,92 @@
+/* mnote-fuji-tag.h
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MNOTE_FUJI_TAG_H__
+#define __MNOTE_FUJI_TAG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <libexif/exif-data.h>
+
+enum _MnoteFujiTag {
+ MNOTE_FUJI_TAG_VERSION = 0x0000,
+ MNOTE_FUJI_TAG_SERIAL_NUMBER = 0x0010,
+ MNOTE_FUJI_TAG_QUALITY = 0x1000,
+ MNOTE_FUJI_TAG_SHARPNESS = 0x1001,
+ MNOTE_FUJI_TAG_WHITE_BALANCE = 0x1002,
+ MNOTE_FUJI_TAG_COLOR = 0x1003,
+ MNOTE_FUJI_TAG_TONE = 0x1004,
+ MNOTE_FUJI_TAG_UNKNOWN_1006 = 0x1006,
+ MNOTE_FUJI_TAG_UNKNOWN_1007 = 0x1007,
+ MNOTE_FUJI_TAG_UNKNOWN_1008 = 0x1008,
+ MNOTE_FUJI_TAG_UNKNOWN_1009 = 0x1009,
+ MNOTE_FUJI_TAG_UNKNOWN_100A = 0x100A,
+ MNOTE_FUJI_TAG_UNKNOWN_100B = 0x100B,
+ MNOTE_FUJI_TAG_FLASH_MODE = 0x1010,
+ MNOTE_FUJI_TAG_FLASH_STRENGTH = 0x1011,
+ MNOTE_FUJI_TAG_MACRO = 0x1020,
+ MNOTE_FUJI_TAG_FOCUS_MODE = 0x1021,
+ MNOTE_FUJI_TAG_UNKNOWN_1022 = 0x1022,
+ MNOTE_FUJI_TAG_FOCUS_POINT = 0x1023,
+ MNOTE_FUJI_TAG_UNKNOWN_1024 = 0x1024,
+ MNOTE_FUJI_TAG_UNKNOWN_1025 = 0x1025,
+ MNOTE_FUJI_TAG_SLOW_SYNC = 0x1030,
+ MNOTE_FUJI_TAG_PICTURE_MODE = 0x1031,
+ MNOTE_FUJI_TAG_UNKNOWN_1032 = 0x1032,
+ MNOTE_FUJI_TAG_CONT_TAKING = 0x1100,
+ MNOTE_FUJI_TAG_SEQUENCE_NUMBER = 0x1101,
+ MNOTE_FUJI_TAG_UNKNOWN_1200 = 0x1200,
+ MNOTE_FUJI_TAG_FINEPIX_COLOR = 0x1210,
+ MNOTE_FUJI_TAG_BLUR_CHECK = 0x1300,
+ MNOTE_FUJI_TAG_FOCUS_CHECK = 0x1301,
+ MNOTE_FUJI_TAG_AUTO_EXPOSURE_CHECK = 0x1302,
+ MNOTE_FUJI_TAG_UNKNOWN_1303 = 0x1303,
+ MNOTE_FUJI_TAG_DYNAMIC_RANGE = 0x1400,
+ MNOTE_FUJI_TAG_FILM_MODE = 0x1401,
+ MNOTE_FUJI_TAG_DYNAMIC_RANGE_SETTING = 0x1402,
+ MNOTE_FUJI_TAG_DEV_DYNAMIC_RANGE_SETTING= 0x1403,
+ MNOTE_FUJI_TAG_MIN_FOCAL_LENGTH = 0x1404,
+ MNOTE_FUJI_TAG_MAX_FOCAL_LENGTH = 0x1405,
+ MNOTE_FUJI_TAG_MAX_APERT_AT_MIN_FOC = 0x1406,
+ MNOTE_FUJI_TAG_MAX_APERT_AT_MAX_FOC = 0x1407,
+ MNOTE_FUJI_TAG_UNKNOWN_1408 = 0x1408,
+ MNOTE_FUJI_TAG_UNKNOWN_1409 = 0x1409,
+ MNOTE_FUJI_TAG_UNKNOWN_140A = 0x140A,
+ MNOTE_FUJI_TAG_UNKNOWN_1410 = 0x1410,
+ MNOTE_FUJI_TAG_UNKNOWN_1421 = 0x1421,
+ MNOTE_FUJI_TAG_UNKNOWN_4100 = 0x4100,
+ MNOTE_FUJI_TAG_UNKNOWN_4800 = 0x4800,
+ MNOTE_FUJI_TAG_FILE_SOURCE = 0x8000,
+ MNOTE_FUJI_TAG_ORDER_NUMBER = 0x8002,
+ MNOTE_FUJI_TAG_FRAME_NUMBER = 0x8003,
+};
+typedef enum _MnoteFujiTag MnoteFujiTag;
+
+const char *mnote_fuji_tag_get_name (MnoteFujiTag tag);
+const char *mnote_fuji_tag_get_title (MnoteFujiTag tag);
+const char *mnote_fuji_tag_get_description (MnoteFujiTag tag);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MNOTE_FUJI_TAG_H__ */
diff --git a/libexif/olympus/Makefile-files b/libexif/olympus/Makefile-files
new file mode 100644
index 0000000..b7b6b30
--- /dev/null
+++ b/libexif/olympus/Makefile-files
@@ -0,0 +1,7 @@
+# -*- Makefile -*-
+noinst_LTLIBRARIES += libmnote-olympus.la
+libmnote_olympus_la_SOURCES = \
+ olympus/mnote-olympus-entry.c olympus/mnote-olympus-entry.h \
+ olympus/exif-mnote-data-olympus.c olympus/exif-mnote-data-olympus.h \
+ olympus/mnote-olympus-tag.c olympus/mnote-olympus-tag.h
+libmnote_olympus_la_LIBADD = $(LTLIBINTL)
diff --git a/libexif/olympus/exif-mnote-data-olympus.c b/libexif/olympus/exif-mnote-data-olympus.c
new file mode 100644
index 0000000..f11616c
--- /dev/null
+++ b/libexif/olympus/exif-mnote-data-olympus.c
@@ -0,0 +1,678 @@
+/* exif-mnote-data-olympus.c
+ *
+ * Copyright (c) 2002, 2003 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+#include "exif-mnote-data-olympus.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <libexif/exif-utils.h>
+#include <libexif/exif-data.h>
+
+#define DEBUG
+
+/* Uncomment this to fix a problem with Sanyo MakerNotes. It's probably best
+ * not to in most cases because it seems to only affect the thumbnail tag
+ * which is duplicated in IFD 1, and fixing the offset could actually cause
+ * problems with other software that expects the broken form.
+ */
+/*#define EXIF_OVERCOME_SANYO_OFFSET_BUG */
+
+#define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
+
+static enum OlympusVersion
+exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
+ unsigned int buf_size);
+
+
+static void
+exif_mnote_data_olympus_clear (ExifMnoteDataOlympus *n)
+{
+ ExifMnoteData *d = (ExifMnoteData *) n;
+ unsigned int i;
+
+ if (!n) return;
+
+ if (n->entries) {
+ for (i = 0; i < n->count; i++)
+ if (n->entries[i].data) {
+ exif_mem_free (d->mem, n->entries[i].data);
+ n->entries[i].data = NULL;
+ }
+ exif_mem_free (d->mem, n->entries);
+ n->entries = NULL;
+ n->count = 0;
+ }
+}
+
+static void
+exif_mnote_data_olympus_free (ExifMnoteData *n)
+{
+ if (!n) return;
+
+ exif_mnote_data_olympus_clear ((ExifMnoteDataOlympus *) n);
+}
+
+static char *
+exif_mnote_data_olympus_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen)
+{
+ ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
+
+ if (!d || !val) return NULL;
+ if (i > n->count -1) return NULL;
+/*
+ exif_log (d->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
+ "Querying value for tag '%s'...",
+ mnote_olympus_tag_get_name (n->entries[i].tag));
+*/
+ return mnote_olympus_entry_get_value (&n->entries[i], val, maxlen);
+}
+
+
+
+
+/**
+ * @brief save the MnoteData from ne to buf
+ *
+ * @param ne extract the data from this structure
+ * @param *buf write the mnoteData to this buffer (buffer will be allocated)
+ * @param buf_size the size of the buffer
+ */
+static void
+exif_mnote_data_olympus_save (ExifMnoteData *ne,
+ unsigned char **buf, unsigned int *buf_size)
+{
+ ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) ne;
+ size_t i, o, s, doff, base = 0, o2 = 6 + 2;
+ size_t datao = 0;
+ unsigned char *t;
+ size_t ts;
+
+ if (!n || !buf || !buf_size) return;
+
+ /*
+ * Allocate enough memory for all entries and the number of entries.
+ */
+ *buf_size = 6 + 2 + 2 + n->count * 12;
+ switch (n->version) {
+ case olympusV1:
+ case sanyoV1:
+ case epsonV1:
+ *buf = exif_mem_alloc (ne->mem, *buf_size);
+ if (!*buf) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
+ return;
+ }
+
+ /* Write the header and the number of entries. */
+ strcpy ((char *)*buf, n->version==sanyoV1?"SANYO":
+ (n->version==epsonV1?"EPSON":"OLYMP"));
+ exif_set_short (*buf + 6, n->order, (ExifShort) 1);
+ datao = n->offset;
+ break;
+
+ case olympusV2:
+ *buf_size += 8-6 + 4;
+ *buf = exif_mem_alloc (ne->mem, *buf_size);
+ if (!*buf) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
+ return;
+ }
+
+ /* Write the header and the number of entries. */
+ strcpy ((char *)*buf, "OLYMPUS");
+ exif_set_short (*buf + 8, n->order, (ExifShort) (
+ (n->order == EXIF_BYTE_ORDER_INTEL) ?
+ ('I' << 8) | 'I' :
+ ('M' << 8) | 'M'));
+ exif_set_short (*buf + 10, n->order, (ExifShort) 3);
+ o2 += 4;
+ break;
+
+ case nikonV1:
+ base = MNOTE_NIKON1_TAG_BASE;
+
+ /* v1 has offsets based to main IFD, not makernote IFD */
+ datao += n->offset + 10;
+ /* subtract the size here, so the increment in the next case will not harm us */
+ *buf_size -= 8 + 2;
+ /* Fall through to nikonV2 handler */
+ case nikonV2:
+ /* Write out V0 files in V2 format */
+ case nikonV0:
+ *buf_size += 8 + 2;
+ *buf_size += 4; /* Next IFD pointer */
+ *buf = exif_mem_alloc (ne->mem, *buf_size);
+ if (!*buf) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size);
+ return;
+ }
+
+ /* Write the header and the number of entries. */
+ strcpy ((char *)*buf, "Nikon");
+ (*buf)[6] = n->version;
+
+ if (n->version != nikonV1) {
+ exif_set_short (*buf + 10, n->order, (ExifShort) (
+ (n->order == EXIF_BYTE_ORDER_INTEL) ?
+ ('I' << 8) | 'I' :
+ ('M' << 8) | 'M'));
+ exif_set_short (*buf + 12, n->order, (ExifShort) 0x2A);
+ exif_set_long (*buf + 14, n->order, (ExifShort) 8);
+ o2 += 2 + 8;
+ }
+ datao -= 10;
+ /* Reset next IFD pointer */
+ exif_set_long (*buf + o2 + 2 + n->count * 12, n->order, 0);
+ break;
+
+ default:
+ return;
+ }
+
+ exif_set_short (*buf + o2, n->order, (ExifShort) n->count);
+ o2 += 2;
+
+ /* Save each entry */
+ for (i = 0; i < n->count; i++) {
+ o = o2 + i * 12;
+ exif_set_short (*buf + o + 0, n->order,
+ (ExifShort) (n->entries[i].tag - base));
+ exif_set_short (*buf + o + 2, n->order,
+ (ExifShort) n->entries[i].format);
+ exif_set_long (*buf + o + 4, n->order,
+ n->entries[i].components);
+ o += 8;
+ s = exif_format_get_size (n->entries[i].format) *
+ n->entries[i].components;
+ if (s > 65536) {
+ /* Corrupt data: EXIF data size is limited to the
+ * maximum size of a JPEG segment (64 kb).
+ */
+ continue;
+ }
+ if (s > 4) {
+ doff = *buf_size;
+ ts = *buf_size + s;
+ t = exif_mem_realloc (ne->mem, *buf,
+ sizeof (char) * ts);
+ if (!t) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", ts);
+ return;
+ }
+ *buf = t;
+ *buf_size = ts;
+ exif_set_long (*buf + o, n->order, datao + doff);
+ } else
+ doff = o;
+
+ /* Write the data. */
+ if (n->entries[i].data) {
+ memcpy (*buf + doff, n->entries[i].data, s);
+ } else {
+ /* Most certainly damaged input file */
+ memset (*buf + doff, 0, s);
+ }
+ }
+}
+
+static void
+exif_mnote_data_olympus_load (ExifMnoteData *en,
+ const unsigned char *buf, unsigned int buf_size)
+{
+ ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en;
+ ExifShort c;
+ size_t i, tcount, o, o2, datao = 6, base = 0;
+
+ if (!n || !buf || !buf_size) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteDataOlympus", "Short MakerNote");
+ return;
+ }
+ o2 = 6 + n->offset; /* Start of interesting data */
+
+ if (CHECKOVERFLOW(o2,buf_size,10)) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteDataOlympus", "Short MakerNote");
+ return;
+ }
+
+ /*
+ * Olympus headers start with "OLYMP" and need to have at least
+ * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the
+ * number of entries, and 12 for one entry.
+ *
+ * Sanyo format is identical and uses identical tags except that
+ * header starts with "SANYO".
+ *
+ * Epson format is identical and uses identical tags except that
+ * header starts with "EPSON".
+ *
+ * Nikon headers start with "Nikon" (6 bytes including '\0'),
+ * version number (1 or 2).
+ *
+ * Version 1 continues with 0, 1, 0, number_of_tags,
+ * or just with number_of_tags (models D1H, D1X...).
+ *
+ * Version 2 continues with an unknown byte (0 or 10),
+ * two unknown bytes (0), "MM" or "II", another byte 0 and
+ * lastly 0x2A.
+ */
+ n->version = exif_mnote_data_olympus_identify_variant(buf+o2, buf_size-o2);
+ switch (n->version) {
+ case olympusV1:
+ case sanyoV1:
+ case epsonV1:
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
+ "Parsing Olympus/Sanyo/Epson maker note v1...");
+
+ /* The number of entries is at position 8. */
+ if (buf[o2 + 6] == 1)
+ n->order = EXIF_BYTE_ORDER_INTEL;
+ else if (buf[o2 + 6 + 1] == 1)
+ n->order = EXIF_BYTE_ORDER_MOTOROLA;
+ o2 += 8;
+ if (o2 + 2 > buf_size) return;
+ c = exif_get_short (buf + o2, n->order);
+ if ((!(c & 0xFF)) && (c > 0x500)) {
+ if (n->order == EXIF_BYTE_ORDER_INTEL) {
+ n->order = EXIF_BYTE_ORDER_MOTOROLA;
+ } else {
+ n->order = EXIF_BYTE_ORDER_INTEL;
+ }
+ }
+ break;
+
+ case olympusV2:
+ /* Olympus S760, S770 */
+ datao = o2;
+ o2 += 8;
+
+ if (CHECKOVERFLOW(o2,buf_size,4)) return;
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
+ "Parsing Olympus maker note v2 (0x%02x, %02x, %02x, %02x)...",
+ buf[o2], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]);
+
+ if ((buf[o2] == 'I') && (buf[o2 + 1] == 'I'))
+ n->order = EXIF_BYTE_ORDER_INTEL;
+ else if ((buf[o2] == 'M') && (buf[o2 + 1] == 'M'))
+ n->order = EXIF_BYTE_ORDER_MOTOROLA;
+
+ /* The number of entries is at position 8+4. */
+ o2 += 4;
+ break;
+
+ case nikonV1:
+ o2 += 6;
+ if (o2 >= buf_size) return;
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
+ "Parsing Nikon maker note v1 (0x%02x, %02x, %02x, "
+ "%02x, %02x, %02x, %02x, %02x)...",
+ buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
+ buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
+
+ /* Skip version number */
+ o2 += 1;
+
+ /* Skip an unknown byte (00 or 0A). */
+ o2 += 1;
+
+ base = MNOTE_NIKON1_TAG_BASE;
+ /* Fix endianness, if needed */
+ if (o2 + 2 > buf_size) return;
+ c = exif_get_short (buf + o2, n->order);
+ if ((!(c & 0xFF)) && (c > 0x500)) {
+ if (n->order == EXIF_BYTE_ORDER_INTEL) {
+ n->order = EXIF_BYTE_ORDER_MOTOROLA;
+ } else {
+ n->order = EXIF_BYTE_ORDER_INTEL;
+ }
+ }
+ break;
+
+ case nikonV2:
+ o2 += 6;
+ if (o2 >= buf_size) return;
+ if (CHECKOVERFLOW(o2,buf_size,12)) return;
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
+ "Parsing Nikon maker note v2 (0x%02x, %02x, %02x, "
+ "%02x, %02x, %02x, %02x, %02x)...",
+ buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
+ buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
+
+ /* Skip version number */
+ o2 += 1;
+
+ /* Skip an unknown byte (00 or 0A). */
+ o2 += 1;
+
+ /* Skip 2 unknown bytes (00 00). */
+ o2 += 2;
+
+ /*
+ * Byte order. From here the data offset
+ * gets calculated.
+ */
+ datao = o2;
+ if (o2 >= buf_size) return;
+ if (!strncmp ((char *)&buf[o2], "II", 2))
+ n->order = EXIF_BYTE_ORDER_INTEL;
+ else if (!strncmp ((char *)&buf[o2], "MM", 2))
+ n->order = EXIF_BYTE_ORDER_MOTOROLA;
+ else {
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG,
+ "ExifMnoteDataOlympus", "Unknown "
+ "byte order '%c%c'", buf[o2],
+ buf[o2 + 1]);
+ return;
+ }
+ o2 += 2;
+
+ /* Skip 2 unknown bytes (00 2A). */
+ o2 += 2;
+
+ /* Go to where the number of entries is. */
+ if (o2 + 4 > buf_size) return;
+ o2 = datao + exif_get_long (buf + o2, n->order);
+ break;
+
+ case nikonV0:
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
+ "Parsing Nikon maker note v0 (0x%02x, %02x, %02x, "
+ "%02x, %02x, %02x, %02x, %02x)...",
+ buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
+ buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
+ /* 00 1b is # of entries in Motorola order - the rest should also be in MM order */
+ n->order = EXIF_BYTE_ORDER_MOTOROLA;
+ break;
+
+ default:
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
+ "Unknown Olympus variant %i.", n->version);
+ return;
+ }
+
+ /* Sanity check the offset */
+
+ if (CHECKOVERFLOW(o2,buf_size,2)) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteOlympus", "Short MakerNote");
+ return;
+ }
+
+ /* Read the number of tags */
+ c = exif_get_short (buf + o2, n->order);
+ o2 += 2;
+
+ /* Remove any old entries */
+ exif_mnote_data_olympus_clear (n);
+
+ /* Reserve enough space for all the possible MakerNote tags */
+ n->entries = exif_mem_alloc (en->mem, sizeof (MnoteOlympusEntry) * c);
+ if (!n->entries) {
+ EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", sizeof (MnoteOlympusEntry) * c);
+ return;
+ }
+
+ /* Parse all c entries, storing ones that are successfully parsed */
+ tcount = 0;
+ for (i = c, o = o2; i; --i, o += 12) {
+ size_t s;
+
+ memset(&n->entries[tcount], 0, sizeof(MnoteOlympusEntry));
+ if (CHECKOVERFLOW(o, buf_size, 12)) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteOlympus", "Short MakerNote");
+ break;
+ }
+
+ n->entries[tcount].tag = exif_get_short (buf + o, n->order) + base;
+ n->entries[tcount].format = exif_get_short (buf + o + 2, n->order);
+ n->entries[tcount].components = exif_get_long (buf + o + 4, n->order);
+ n->entries[tcount].order = n->order;
+
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
+ "Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
+ mnote_olympus_tag_get_name (n->entries[tcount].tag));
+/* exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus",
+ "0x%x %d %ld*(%d)",
+ n->entries[tcount].tag,
+ n->entries[tcount].format,
+ n->entries[tcount].components,
+ (int)exif_format_get_size(n->entries[tcount].format)); */
+
+ /* Check if we overflow the multiplication. Use buf_size as the max size for integer overflow detection,
+ * we will check the buffer sizes closer later. */
+ if (exif_format_get_size (n->entries[tcount].format) &&
+ buf_size / exif_format_get_size (n->entries[tcount].format) < n->entries[tcount].components
+ ) {
+ 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);
+ continue;
+ }
+
+ /*
+ * Size? If bigger than 4 bytes, the actual data is not
+ * in the entry but somewhere else (offset).
+ */
+ s = exif_format_get_size (n->entries[tcount].format) *
+ n->entries[tcount].components;
+ n->entries[tcount].size = s;
+ if (s) {
+ size_t dataofs = o + 8;
+ if (s > 4) {
+ /* The data in this case is merely a pointer */
+ dataofs = exif_get_long (buf + dataofs, n->order) + datao;
+#ifdef EXIF_OVERCOME_SANYO_OFFSET_BUG
+ /* Some Sanyo models (e.g. VPC-C5, C40) suffer from a bug when
+ * writing the offset for the MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE
+ * tag in its MakerNote. The offset is actually the absolute
+ * position in the file instead of the position within the IFD.
+ */
+ if (dataofs > (buf_size - s) && n->version == sanyoV1) {
+ /* fix pointer */
+ dataofs -= datao + 6;
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG,
+ "ExifMnoteOlympus",
+ "Inconsistent thumbnail tag offset; attempting to recover");
+ }
+#endif
+ }
+ if (CHECKOVERFLOW(dataofs, buf_size, s)) {
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG,
+ "ExifMnoteOlympus",
+ "Tag data past end of buffer (%zu > %u)",
+ dataofs + s, buf_size);
+ continue;
+ }
+
+ n->entries[tcount].data = exif_mem_alloc (en->mem, s);
+ if (!n->entries[tcount].data) {
+ EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", s);
+ continue;
+ }
+ memcpy (n->entries[tcount].data, buf + dataofs, s);
+ }
+
+ /* Tag was successfully parsed */
+ ++tcount;
+ }
+ /* Store the count of successfully parsed tags */
+ n->count = tcount;
+}
+
+static unsigned int
+exif_mnote_data_olympus_count (ExifMnoteData *n)
+{
+ return n ? ((ExifMnoteDataOlympus *) n)->count : 0;
+}
+
+static unsigned int
+exif_mnote_data_olympus_get_id (ExifMnoteData *d, unsigned int n)
+{
+ ExifMnoteDataOlympus *note = (ExifMnoteDataOlympus *) d;
+
+ if (!note) return 0;
+ if (note->count <= n) return 0;
+ return note->entries[n].tag;
+}
+
+static const char *
+exif_mnote_data_olympus_get_name (ExifMnoteData *d, unsigned int i)
+{
+ ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
+
+ if (!n) return NULL;
+ if (i >= n->count) return NULL;
+ return mnote_olympus_tag_get_name (n->entries[i].tag);
+}
+
+static const char *
+exif_mnote_data_olympus_get_title (ExifMnoteData *d, unsigned int i)
+{
+ ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
+
+ if (!n) return NULL;
+ if (i >= n->count) return NULL;
+ return mnote_olympus_tag_get_title (n->entries[i].tag);
+}
+
+static const char *
+exif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i)
+{
+ ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
+
+ if (!n) return NULL;
+ if (i >= n->count) return NULL;
+ return mnote_olympus_tag_get_description (n->entries[i].tag);
+}
+
+static void
+exif_mnote_data_olympus_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
+{
+ ExifByteOrder o_orig;
+ ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d;
+ unsigned int i;
+
+ if (!n) return;
+
+ o_orig = n->order;
+ n->order = o;
+ for (i = 0; i < n->count; i++) {
+ n->entries[i].order = o;
+ exif_array_set_byte_order (n->entries[i].format, n->entries[i].data,
+ n->entries[i].components, o_orig, o);
+ }
+}
+
+static void
+exif_mnote_data_olympus_set_offset (ExifMnoteData *n, unsigned int o)
+{
+ if (n) ((ExifMnoteDataOlympus *) n)->offset = o;
+}
+
+static enum OlympusVersion
+exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
+ unsigned int buf_size)
+{
+ /* Olympus, Nikon, Sanyo, Epson */
+ if (buf_size >= 8) {
+ /* Match the terminating NUL character, too */
+ if (!memcmp (buf, "OLYMPUS", 8))
+ return olympusV2;
+ else if (!memcmp (buf, "OLYMP", 6))
+ return olympusV1;
+ else if (!memcmp (buf, "SANYO", 6))
+ return sanyoV1;
+ else if (!memcmp (buf, "EPSON", 6))
+ return epsonV1;
+ else if (!memcmp (buf, "Nikon", 6)) {
+ switch (buf[6]) {
+ case 1: return nikonV1;
+ case 2: return nikonV2;
+ default: return 0; /* Unrecognized Nikon variant */
+ }
+ }
+ }
+
+ /* Another variant of Nikon */
+ if ((buf_size >= 2) && (buf[0] == 0x00) && (buf[1] == 0x1b)) {
+ return nikonV0;
+ }
+
+ return unrecognized;
+}
+
+int
+exif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e)
+{
+ int variant = exif_mnote_data_olympus_identify_variant(e->data, e->size);
+
+ if (variant == nikonV0) {
+ /* This variant needs some extra checking with the Make */
+ char value[5];
+ ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE);
+ variant = unrecognized;
+
+ if (em) {
+ const char *v = exif_entry_get_value (em, value, sizeof(value));
+ if (v && (!strncmp (v, "Nikon", sizeof(value)) ||
+ !strncmp (v, "NIKON", sizeof(value)) ))
+ /* When saved, this variant will be written out like the
+ * alternative nikonV2 form above instead
+ */
+ variant = nikonV0;
+ }
+ }
+
+ return variant;
+}
+
+
+ExifMnoteData *
+exif_mnote_data_olympus_new (ExifMem *mem)
+{
+ ExifMnoteData *d;
+
+ if (!mem) return NULL;
+
+ d = exif_mem_alloc (mem, sizeof (ExifMnoteDataOlympus));
+ if (!d) return NULL;
+
+ memset(d, 0, sizeof(ExifMnoteDataOlympus));
+
+ exif_mnote_data_construct (d, mem);
+
+ /* Set up function pointers */
+ d->methods.free = exif_mnote_data_olympus_free;
+ d->methods.set_byte_order = exif_mnote_data_olympus_set_byte_order;
+ d->methods.set_offset = exif_mnote_data_olympus_set_offset;
+ d->methods.load = exif_mnote_data_olympus_load;
+ d->methods.save = exif_mnote_data_olympus_save;
+ d->methods.count = exif_mnote_data_olympus_count;
+ d->methods.get_id = exif_mnote_data_olympus_get_id;
+ d->methods.get_name = exif_mnote_data_olympus_get_name;
+ d->methods.get_title = exif_mnote_data_olympus_get_title;
+ d->methods.get_description = exif_mnote_data_olympus_get_description;
+ d->methods.get_value = exif_mnote_data_olympus_get_value;
+
+ return d;
+}
diff --git a/libexif/olympus/exif-mnote-data-olympus.h b/libexif/olympus/exif-mnote-data-olympus.h
new file mode 100644
index 0000000..d08b0f4
--- /dev/null
+++ b/libexif/olympus/exif-mnote-data-olympus.h
@@ -0,0 +1,67 @@
+/* mnote-olympus-data.h
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MNOTE_OLYMPUS_CONTENT_H__
+#define __MNOTE_OLYMPUS_CONTENT_H__
+
+#include <libexif/exif-mnote-data-priv.h>
+#include <libexif/olympus/mnote-olympus-entry.h>
+#include <libexif/exif-byte-order.h>
+#include <libexif/exif-data.h>
+#include <libexif/exif-mem.h>
+
+enum OlympusVersion {
+ unrecognized = 0,
+ nikonV1 = 1,
+ nikonV2 = 2,
+ olympusV1 = 3,
+ olympusV2 = 4,
+ sanyoV1 = 5,
+ epsonV1 = 6,
+ nikonV0 = 7
+};
+
+
+typedef struct _ExifMnoteDataOlympus ExifMnoteDataOlympus;
+
+struct _ExifMnoteDataOlympus {
+ ExifMnoteData parent;
+
+ MnoteOlympusEntry *entries;
+ unsigned int count;
+
+ ExifByteOrder order;
+ unsigned int offset;
+ enum OlympusVersion version;
+};
+
+/*! Detect if MakerNote is recognized as one handled by the Olympus module.
+ *
+ * \param[in] ed image #ExifData to identify as as an Olympus type
+ * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but
+ * duplicated here for convenience
+ * \return 0 if not recognized, nonzero if recognized. The specific nonzero
+ * value returned may identify a subtype unique within this module.
+ */
+int exif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e);
+
+ExifMnoteData *exif_mnote_data_olympus_new (ExifMem *);
+
+#endif /* __MNOTE_OLYMPUS_CONTENT_H__ */
diff --git a/libexif/olympus/mnote-olympus-entry.c b/libexif/olympus/mnote-olympus-entry.c
new file mode 100644
index 0000000..96c919d
--- /dev/null
+++ b/libexif/olympus/mnote-olympus-entry.c
@@ -0,0 +1,827 @@
+/* mnote-olympus-entry.c
+ *
+ * Copyright (c) 2002-2009 Lutz Mueller <lutz@users.sourceforge.net> et. al.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+#include "mnote-olympus-entry.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libexif/exif-format.h>
+#include <libexif/exif-utils.h>
+#include <libexif/exif-entry.h>
+#include <libexif/i18n.h>
+
+#define CF(format,target,v,maxlen) \
+{ \
+ if (format != target) { \
+ snprintf (v, maxlen, \
+ _("Invalid format '%s', " \
+ "expected '%s'."), \
+ exif_format_get_name (format), \
+ exif_format_get_name (target)); \
+ break; \
+ } \
+}
+
+#define CF2(format,target1,target2,v,maxlen) \
+{ \
+ if ((format != target1) && (format != target2)) { \
+ snprintf (v, maxlen, \
+ _("Invalid format '%s', " \
+ "expected '%s' or '%s'."), \
+ exif_format_get_name (format), \
+ exif_format_get_name (target1), \
+ exif_format_get_name (target2)); \
+ break; \
+ } \
+}
+
+#define CC(number,target,v,maxlen) \
+{ \
+ if (number != target) { \
+ snprintf (v, maxlen, \
+ _("Invalid number of components (%i, " \
+ "expected %i)."), (int) number, (int) target); \
+ break; \
+ } \
+}
+
+#define CC2(number,t1,t2,v,maxlen) \
+{ \
+ if ((number < t1) || (number > t2)) { \
+ snprintf (v, maxlen, \
+ _("Invalid number of components (%i, " \
+ "expected %i or %i)."), (int) number, \
+ (int) t1, (int) t2); \
+ break; \
+ } \
+}
+
+#define R2L(n) ((n).denominator ? (long)(n).numerator/(n).denominator : 0L)
+#define R2D(n) ((n).denominator ? (double)(n).numerator/(n).denominator : 0.0)
+
+static const struct {
+ ExifTag tag;
+ ExifFormat fmt;
+ struct {
+ int index;
+ const char *string;
+ } elem[24];
+} items[] = {
+#ifndef NO_VERBOSE_TAG_DATA
+ { MNOTE_NIKON_TAG_LENSTYPE, EXIF_FORMAT_BYTE,
+ { {0, N_("AF non D lens")},
+ {1, N_("Manual")},
+ {2, N_("AF-D or AF-S lens")},
+ {6, N_("AF-D G lens")},
+ {10, N_("AF-D VR lens")},
+ {14, N_("AF-D G VR lens")},
+ {0, NULL}}},
+ { MNOTE_NIKON_TAG_FLASHUSED, EXIF_FORMAT_BYTE,
+ { {0, N_("Flash did not fire")},
+ {4, N_("Flash unit unknown")},
+ {7, N_("Flash is external")},
+ {9, N_("Flash is on camera")},
+ {0, NULL}}},
+ { MNOTE_NIKON1_TAG_QUALITY, EXIF_FORMAT_SHORT,
+ { {1, N_("VGA basic")},
+ {2, N_("VGA normal")},
+ {3, N_("VGA fine")},
+ {4, N_("SXGA basic")},
+ {5, N_("SXGA normal")},
+ {6, N_("SXGA fine")},
+ {10, N_("2 Mpixel basic")},
+ {11, N_("2 Mpixel normal")},
+ {12, N_("2 Mpixel fine")},
+ {0, NULL}}},
+ { MNOTE_NIKON1_TAG_COLORMODE, EXIF_FORMAT_SHORT,
+ { {1, N_("Color")},
+ {2, N_("Monochrome")},
+ {0, NULL}}},
+ { MNOTE_NIKON1_TAG_IMAGEADJUSTMENT, EXIF_FORMAT_SHORT,
+ { {0, N_("Normal")},
+ {1, N_("Bright+")},
+ {2, N_("Bright-")},
+ {3, N_("Contrast+")},
+ {4, N_("Contrast-")},
+ {0, NULL}}},
+ { MNOTE_NIKON1_TAG_CCDSENSITIVITY, EXIF_FORMAT_SHORT,
+ { {0, N_("ISO 80")},
+ {2, N_("ISO 160")},
+ {4, N_("ISO 320")},
+ {5, N_("ISO 100")},
+ {0, NULL}}},
+ { MNOTE_NIKON1_TAG_WHITEBALANCE, EXIF_FORMAT_SHORT,
+ { {0, N_("Auto")},
+ {1, N_("Preset")},
+ {2, N_("Daylight")},
+ {3, N_("Incandescence")},
+ {4, N_("Fluorescence")},
+ {5, N_("Cloudy")},
+ {6, N_("SpeedLight")},
+ {0, NULL}}},
+ { MNOTE_NIKON1_TAG_CONVERTER, EXIF_FORMAT_SHORT,
+ { {0, N_("No fisheye")},
+ {1, N_("Fisheye on")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_QUALITY, EXIF_FORMAT_SHORT,
+ { {1, N_("Normal, SQ")},
+ {2, N_("Normal, HQ")},
+ {3, N_("Normal, SHQ")},
+ {4, N_("Normal, RAW")},
+ {5, N_("Normal, SQ1")},
+ {6, N_("Normal, SQ2")},
+ {7, N_("Normal, super high")},
+ {17, N_("Normal, standard")},
+ {0x101, N_("Fine, SQ")},
+ {0x102, N_("Fine, HQ")},
+ {0x103, N_("Fine, SHQ")},
+ {0x104, N_("Fine, RAW")},
+ {0x105, N_("Fine, SQ1")},
+ {0x106, N_("Fine, SQ2")},
+ {0x107, N_("Fine, super high")},
+ {0x201, N_("Super fine, SQ")},
+ {0x202, N_("Super fine, HQ")},
+ {0x203, N_("Super fine, SHQ")},
+ {0x204, N_("Super fine, RAW")},
+ {0x205, N_("Super fine, SQ1")},
+ {0x206, N_("Super fine, SQ2")},
+ {0x207, N_("Super fine, super high")},
+ {0x211, N_("Super fine, high")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_MACRO, EXIF_FORMAT_SHORT,
+ { {0, N_("No")},
+ {1, N_("Yes")},
+ {2, N_("Super macro")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_BWMODE, EXIF_FORMAT_SHORT,
+ { {0, N_("No")},
+ {1, N_("Yes")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_ONETOUCHWB, EXIF_FORMAT_SHORT,
+ { {0, N_("Off")},
+ {1, N_("On")},
+ {2, N_("On (Preset)")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_FLASHMODE, EXIF_FORMAT_SHORT,
+ { {0, N_("Auto")},
+ {1, N_("Red-eye reduction")},
+ {2, N_("Fill")},
+ {3, N_("Off")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_FLASHDEVICE, EXIF_FORMAT_SHORT,
+ { {0, N_("None")},
+ {1, N_("Internal")},
+ {4, N_("External")},
+ {5, N_("Internal + external")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_FOCUSRANGE, EXIF_FORMAT_SHORT,
+ { {0, N_("Normal")},
+ {1, N_("Macro")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_MANFOCUS, EXIF_FORMAT_SHORT,
+ { {0, N_("Auto")},
+ {1, N_("Manual")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_SHARPNESS, EXIF_FORMAT_SHORT,
+ { {0, N_("Normal")},
+ {1, N_("Hard")},
+ {2, N_("Soft")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE, EXIF_FORMAT_SHORT,
+ { {0, N_("No")},
+ {1, N_("Yes")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_CONTRAST, EXIF_FORMAT_SHORT,
+ { {0, N_("Hard")},
+ {1, N_("Normal")},
+ {2, N_("Soft")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID, EXIF_FORMAT_LONG,
+ { {0, N_("No")},
+ {1, N_("Yes")},
+ {0, NULL}}},
+ { MNOTE_OLYMPUS_TAG_CCDSCANMODE, EXIF_FORMAT_SHORT,
+ { {0, N_("Interlaced")},
+ {1, N_("Progressive")},
+ {0, NULL}}},
+
+ { MNOTE_SANYO_TAG_SEQUENTIALSHOT, EXIF_FORMAT_SHORT,
+ { {0, N_("None")},
+ {1, N_("Standard")},
+ {2, N_("Best")},
+ {3, N_("Adjust exposure")},
+ {0, NULL}}},
+ { MNOTE_SANYO_TAG_FOCUSMODE, EXIF_FORMAT_SHORT,
+ { {1, N_("Spot focus")},
+ {2, N_("Normal focus")},
+ {0, NULL}}},
+ { MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE, EXIF_FORMAT_SHORT,
+ { {0, N_("Record while down")},
+ {1, N_("Press start, press stop")},
+ {0, NULL}}},
+ { MNOTE_SANYO_TAG_RESAVED, EXIF_FORMAT_SHORT,
+ { {0, N_("No")},
+ {1, N_("Yes")},
+ {0, NULL}}},
+ { MNOTE_SANYO_TAG_CCDSENSITIVITY, EXIF_FORMAT_SHORT,
+ { {0, N_("Auto")},
+ {1, N_("ISO 50")},
+ {3, N_("ISO 100")},
+ {4, N_("ISO 200")},
+ {5, N_("ISO 400")},
+ {0, NULL}}},
+ { MNOTE_SANYO_TAG_SCENESELECT, EXIF_FORMAT_SHORT,
+ { {0, N_("Off")},
+ {1, N_("Sport")},
+ {2, N_("TV")},
+ {3, N_("Night")},
+ {4, N_("User 1")},
+ {5, N_("User 2")},
+ {6, N_("Lamp")},
+ {0, NULL}}},
+ { MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL, EXIF_FORMAT_SHORT,
+ { {0, N_("5 frames/sec")},
+ {1, N_("10 frames/sec")},
+ {2, N_("15 frames/sec")},
+ {3, N_("20 frames/sec")},
+ {0, NULL}}},
+#endif
+ { 0, 0, { { 0, NULL } } }
+};
+
+char *
+mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *v, unsigned int maxlen)
+{
+ char buf[30];
+ ExifLong vl;
+ ExifShort vs = 0;
+ ExifSShort vss = 0;
+ ExifRational vr, vr2;
+ ExifSRational vsr;
+ int i, j;
+ double r, b;
+
+ if (!entry)
+ return (NULL);
+
+ memset (v, 0, maxlen);
+ maxlen--;
+
+ if ((!entry->data) && (entry->components > 0))
+ return (v);
+
+ if ((!entry->data) && (entry->size > 0))
+ return NULL; /* internal inconsistency error */
+
+ switch (entry->tag) {
+
+ /* Nikon */
+ case MNOTE_NIKON_TAG_FIRMWARE:
+ CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
+ CC (entry->components, 4, v, maxlen);
+ vl = exif_get_long (entry->data, entry->order);
+ if ((vl & 0xF0F0F0F0) == 0x30303030) {
+ memcpy (v, entry->data, MIN (maxlen, 4));
+ } else {
+ snprintf (v, maxlen, "%04lx", (long unsigned int) vl);
+ }
+ break;
+ case MNOTE_NIKON_TAG_ISO:
+ CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
+ CC (entry->components, 2, v, maxlen);
+ /*vs = exif_get_short (entry->data, entry->order);*/
+ vs = exif_get_short (entry->data + 2, entry->order);
+ snprintf (v, maxlen, "ISO %hd", vs);
+ break;
+ case MNOTE_NIKON_TAG_ISO2:
+ CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
+ CC (entry->components, 2, v, maxlen);
+ /*vs = exif_get_short (entry->data, entry->order);*/
+ vs = exif_get_short (entry->data + 2, entry->order);
+ snprintf (v, maxlen, "ISO2 %hd", vs);
+ break;
+ case MNOTE_NIKON_TAG_QUALITY:
+ case MNOTE_NIKON_TAG_COLORMODE:
+ case MNOTE_NIKON_TAG_COLORMODE1:
+ case MNOTE_NIKON_TAG_WHITEBALANCE:
+ case MNOTE_NIKON_TAG_SHARPENING:
+ case MNOTE_NIKON_TAG_FOCUSMODE:
+ case MNOTE_NIKON_TAG_FLASHSETTING:
+ case MNOTE_NIKON_TAG_ISOSELECTION:
+ case MNOTE_NIKON_TAG_FLASHMODE:
+ case MNOTE_NIKON_TAG_IMAGEADJUSTMENT:
+ case MNOTE_NIKON_TAG_ADAPTER:
+ case MNOTE_NIKON_TAG_SATURATION2:
+ case MNOTE_EPSON_TAG_SOFTWARE:
+ CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
+ memcpy(v, entry->data, MIN (maxlen, entry->size));
+ break;
+ case MNOTE_NIKON_TAG_TOTALPICTURES:
+ case MNOTE_EPSON_TAG_IMAGE_WIDTH:
+ case MNOTE_EPSON_TAG_IMAGE_HEIGHT:
+ CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
+ CC (entry->components, 1, v, maxlen);
+ vl = exif_get_long (entry->data, entry->order);
+ snprintf (v, maxlen, "%lu", (long unsigned int) vl );
+ break;
+ case MNOTE_NIKON_TAG_LENS_FSTOPS:
+ case MNOTE_NIKON_TAG_EXPOSUREDIFF: {
+ unsigned char a,b,c,d;
+ CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
+ CC (entry->components, 4, v, maxlen);
+ vl = exif_get_long (entry->data, entry->order);
+ a = (vl>>24)&0xff; b = (vl>>16)&0xff; c = (vl>>8)&0xff; d = (vl)&0xff;
+ snprintf (v, maxlen, "%.1f", c?(float)a*((float)b/(float)c):0 );
+ break;
+ }
+ case MNOTE_NIKON_TAG_FLASHEXPCOMPENSATION:
+ case MNOTE_NIKON_TAG_FLASHEXPOSUREBRACKETVAL:
+ CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
+ CC (entry->components, 4, v, maxlen);
+ vl = exif_get_long (entry->data, entry->order);
+ snprintf (v, maxlen, "%.1f", ((long unsigned int) vl>>24)/6.0 );
+ break;
+ case MNOTE_NIKON_TAG_SATURATION:
+ case MNOTE_NIKON_TAG_WHITEBALANCEFINE:
+ case MNOTE_NIKON_TAG_HUE:
+ case MNOTE_OLYMPUS_TAG_SENSORTEMPERATURE:
+ case MNOTE_OLYMPUS_TAG_LENSTEMPERATURE:
+ CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen);
+ CC (entry->components, 1, v, maxlen);
+ vs = exif_get_short (entry->data, entry->order);
+ snprintf (v, maxlen, "%hd", vs);
+ break;
+ case MNOTE_NIKON_TAG_WHITEBALANCERB:
+ CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
+ CC (entry->components, 4, v, maxlen);
+ vr = exif_get_rational (entry->data, entry->order);
+ r = R2D(vr);
+ vr = exif_get_rational (entry->data+8, entry->order);
+ b = R2D(vr);
+ snprintf (v, maxlen, _("Red Correction %f, blue Correction %f"), r,b);
+ break;
+ case MNOTE_NIKON_TAG_MANUALFOCUSDISTANCE:
+ CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
+ CC (entry->components, 1, v, maxlen);
+ vr = exif_get_rational (entry->data, entry->order);
+ if (!vr.numerator || !vr.denominator) {
+ strncpy (v, _("No manual focus selection"), maxlen);
+ } else {
+ r = R2D(vr);
+ snprintf (v, maxlen, _("%2.2f meters"), r);
+ }
+ break;
+ case MNOTE_NIKON_TAG_SENSORPIXELSIZE:
+ CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
+ CC (entry->components, 2, v, maxlen);
+ vr = exif_get_rational (entry->data, entry->order);
+ vr2 = exif_get_rational (entry->data+8, entry->order);
+ r = R2D(vr);
+ b = R2D(vr2);
+ snprintf (v, maxlen, "%2.2f x %2.2f um", r, b);
+ break;
+ case MNOTE_NIKON_TAG_BRACKETING:
+ CF2 (entry->format, EXIF_FORMAT_BYTE, EXIF_FORMAT_SHORT, v, maxlen);
+ CC (entry->components, 1, v, maxlen);
+ if (EXIF_FORMAT_SHORT == entry->format) {
+ vs = exif_get_short (entry->data, entry->order);
+ } else {
+ vs = entry->data[0];
+ }
+ snprintf (v, maxlen, "%hd", vs);
+ break;
+ case MNOTE_NIKON_TAG_AFFOCUSPOSITION:
+ CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
+ CC (entry->components, 4, v, maxlen);
+ switch ( *( entry->data+1) ) {
+ case 0: strncpy (v, _("AF position: center"), maxlen); break;
+ case 1: strncpy (v, _("AF position: top"), maxlen); break;
+ case 2: strncpy (v, _("AF position: bottom"), maxlen); break;
+ case 3: strncpy (v, _("AF position: left"), maxlen); break;
+ case 4: strncpy (v, _("AF position: right"), maxlen); break;
+ case 5: strncpy (v, _("AF position: upper-left"), maxlen); break;
+ case 6: strncpy (v, _("AF position: upper-right"), maxlen); break;
+ case 7: strncpy (v, _("AF position: lower-left"), maxlen); break;
+ case 8: strncpy (v, _("AF position: lower-right"), maxlen); break;
+ case 9: strncpy (v, _("AF position: far left"), maxlen); break;
+ case 10: strncpy (v, _("AF position: far right"), maxlen); break;
+ default: strncpy (v, _("Unknown AF position"), maxlen);
+ }
+ break;
+ case MNOTE_OLYMPUS_TAG_FLASHDEVICE:
+ CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
+ CC (entry->components, 2, v, maxlen);
+ vs = exif_get_short(entry->data, entry->order);
+ /* search for the tag */
+ for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++)
+ ;
+ if (!items[i].tag) {
+ snprintf (v, maxlen, _("Internal error (unknown value %hi)"), vs);
+ break;
+ }
+ CF (entry->format, items[i].fmt, v, maxlen);
+ /* find the value */
+ for (j = 0; items[i].elem[j].string &&
+ (items[i].elem[j].index < vs); j++);
+ if (items[i].elem[j].index != vs) {
+ snprintf (v, maxlen, _("Unknown value %hi"), vs);
+ break;
+ }
+ strncpy (v, _(items[i].elem[j].string), maxlen);
+ break;
+ case MNOTE_OLYMPUS_TAG_DIGIZOOM:
+ if (entry->format == EXIF_FORMAT_RATIONAL) {
+ CC (entry->components, 1, v, maxlen);
+ vr = exif_get_rational (entry->data, entry->order);
+ if (!vr.numerator || !vr.denominator) {
+ strncpy (v, _("None"), maxlen);
+ } else {
+ r = R2D(vr);
+ snprintf (v, maxlen, "%2.2f", r);
+ }
+ break;
+ }
+ /* fall through to handle SHORT version of this tag */
+ case MNOTE_NIKON_TAG_LENSTYPE:
+ case MNOTE_NIKON_TAG_FLASHUSED:
+ case MNOTE_NIKON1_TAG_QUALITY:
+ case MNOTE_NIKON1_TAG_COLORMODE:
+ case MNOTE_NIKON1_TAG_IMAGEADJUSTMENT:
+ case MNOTE_NIKON1_TAG_CCDSENSITIVITY:
+ case MNOTE_NIKON1_TAG_WHITEBALANCE:
+ case MNOTE_NIKON1_TAG_CONVERTER:
+ case MNOTE_OLYMPUS_TAG_QUALITY:
+ case MNOTE_OLYMPUS_TAG_MACRO:
+ case MNOTE_OLYMPUS_TAG_BWMODE:
+ case MNOTE_OLYMPUS_TAG_ONETOUCHWB:
+ case MNOTE_OLYMPUS_TAG_FLASHMODE:
+ case MNOTE_OLYMPUS_TAG_FOCUSRANGE:
+ case MNOTE_OLYMPUS_TAG_MANFOCUS:
+ case MNOTE_OLYMPUS_TAG_SHARPNESS:
+ case MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE:
+ case MNOTE_OLYMPUS_TAG_CONTRAST:
+ case MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID:
+ case MNOTE_OLYMPUS_TAG_CCDSCANMODE:
+ case MNOTE_SANYO_TAG_SEQUENTIALSHOT:
+ case MNOTE_SANYO_TAG_FOCUSMODE:
+ case MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE:
+ case MNOTE_SANYO_TAG_RESAVED:
+ case MNOTE_SANYO_TAG_CCDSENSITIVITY:
+ case MNOTE_SANYO_TAG_SCENESELECT:
+ case MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL:
+ CC (entry->components, 1, v, maxlen);
+ switch (entry->format) {
+ case EXIF_FORMAT_BYTE:
+ case EXIF_FORMAT_UNDEFINED:
+ vs = entry->data[0];
+ break;
+ case EXIF_FORMAT_SHORT:
+ vs = exif_get_short(entry->data, entry->order);
+ break;
+ default:
+ vs = 0;
+ break;
+ }
+ /* search for the tag */
+ for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++)
+ ;
+ if (!items[i].tag) {
+ snprintf (v, maxlen, _("Internal error (unknown value %hi)"), vs);
+ break;
+ }
+ CF (entry->format, items[i].fmt, v, maxlen);
+ /* find the value */
+ for (j = 0; items[i].elem[j].string &&
+ (items[i].elem[j].index < vs); j++);
+ if (items[i].elem[j].index != vs) {
+ snprintf (v, maxlen, _("Unknown value %hi"), vs);
+ break;
+ }
+ strncpy (v, _(items[i].elem[j].string), maxlen);
+ break;
+ case MNOTE_OLYMPUS_TAG_NOISEREDUCTION:
+ case MNOTE_SANYO_TAG_WIDERANGE:
+ case MNOTE_SANYO_TAG_COLORADJUSTMENTMODE:
+ case MNOTE_SANYO_TAG_QUICKSHOT:
+ case MNOTE_SANYO_TAG_VOICEMEMO:
+ case MNOTE_SANYO_TAG_FLICKERREDUCE:
+ case MNOTE_SANYO_TAG_OPTICALZOOM:
+ case MNOTE_SANYO_TAG_DIGITALZOOM:
+ case MNOTE_SANYO_TAG_LIGHTSOURCESPECIAL:
+ CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
+ CC (entry->components, 1, v, maxlen);
+ vs = exif_get_short (entry->data, entry->order);
+ switch (vs) {
+ case 0:
+ strncpy (v, _("Off"), maxlen);
+ break;
+ case 1:
+ strncpy (v, _("On"), maxlen);
+ break;
+ default:
+ sprintf (buf, _("Unknown %hu"), vs);
+ strncat (v, buf, maxlen - strlen (v));
+ break;
+ }
+ break;
+ case MNOTE_SANYO_TAG_SELFTIMER:
+ CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
+ CC (entry->components, 1, v, maxlen);
+ vs = exif_get_short (entry->data, entry->order);
+ switch (vs) {
+ case 0:
+ strncpy (v, _("Off"), maxlen);
+ break;
+ case 1:
+ strncpy (v, _("On"), maxlen);
+ break;
+ case 2:
+ strncpy (v, _("2 sec."), maxlen);
+ break;
+ default:
+ sprintf (buf, _("Unknown %hu"), vs);
+ strncat (v, buf, maxlen - strlen (v));
+ break;
+ }
+ break;
+ case MNOTE_NIKON_TAG_LENS:
+ CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
+ CC (entry->components, 4, v, maxlen);
+ {
+ double c,d;
+ unsigned long a,b;
+ vr = exif_get_rational (entry->data, entry->order);
+ a = R2L(vr);
+ vr = exif_get_rational (entry->data+8, entry->order);
+ b = R2L(vr);
+ vr = exif_get_rational (entry->data+16, entry->order);
+ c = R2D(vr);
+ vr = exif_get_rational (entry->data+24, entry->order);
+ d = R2D(vr);
+ snprintf (v, maxlen, "%ld-%ldmm 1:%3.1f - %3.1f",a,b,c,d);
+ }
+ break;
+
+ /* Olympus */
+ case MNOTE_OLYMPUS_TAG_MODE:
+ CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
+ CC (entry->components, 3, v, maxlen);
+ vl = exif_get_long (entry->data, entry->order);
+ switch (vl) {
+ case 0:
+ strncpy (v, _("Normal"), maxlen);
+ break;
+ case 1:
+ strncpy (v, _("Unknown"), maxlen);
+ break;
+ case 2:
+ strncpy (v, _("Fast"), maxlen);
+ break;
+ case 3:
+ strncpy (v, _("Panorama"), maxlen);
+ break;
+ default:
+ snprintf (v, maxlen, "%li", (long int) vl);
+ }
+ vl = exif_get_long (entry->data + 4, entry->order);
+ snprintf (buf, sizeof (buf), "/%li/", (long int) vl);
+ strncat (v, buf, maxlen - strlen (v));
+ vl = exif_get_long (entry->data + 8, entry->order);
+ switch (vl) {
+ case 1:
+ strncat (v, _("Left to right"), maxlen - strlen (v));
+ break;
+ case 2:
+ strncat (v, _("Right to left"), maxlen - strlen (v));
+ break;
+ case 3:
+ strncat (v, _("Bottom to top"), maxlen - strlen (v));
+ break;
+ case 4:
+ strncat (v, _("Top to bottom"), maxlen - strlen (v));
+ break;
+ default:
+ snprintf (buf, sizeof (buf), "%li",
+ (long int) vl);
+ strncat (v, buf, maxlen - strlen (v));
+ }
+ break;
+ case MNOTE_OLYMPUS_TAG_LENSDISTORTION:
+ if (entry->format == EXIF_FORMAT_SHORT) {
+ /* Epson uses a single SHORT here */
+ CC (entry->components, 1, v, maxlen);
+ vs = exif_get_short (entry->data, entry->order);
+ sprintf (buf, "%hu", vs);
+ strncat (v, buf, maxlen - strlen (v));
+ } else {
+ /* Others use an array of SSHORT here */
+ CC (entry->components, 6, v, maxlen);
+ CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen);
+ for (i=0; i < (int)entry->components; ++i) {
+ vss = exif_get_sshort (entry->data+2*i, entry->order);
+ sprintf (buf, "%hd ", vss);
+ strncat (v, buf, maxlen - strlen (v));
+ }
+ }
+ break;
+ case MNOTE_OLYMPUS_TAG_COLORCONTROL:
+ CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
+ CC (entry->components, 6, v, maxlen);
+ for (i=0; i < (int)entry->components; ++i) {
+ vs = exif_get_short (entry->data+2*i, entry->order);
+ sprintf (buf, "%hu ", vs);
+ strncat (v, buf, maxlen - strlen (v));
+ }
+ break;
+ case MNOTE_OLYMPUS_TAG_VERSION:
+ CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
+ CC2 (entry->components, 5, 8, v, maxlen);
+ strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
+ break;
+ case MNOTE_OLYMPUS_TAG_SERIALNUMBER2:
+ CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
+ strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
+ break;
+ case MNOTE_OLYMPUS_TAG_INFO:
+ CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
+ CC2 (entry->components, 52, 60, v, maxlen);
+ strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
+ break;
+ case MNOTE_OLYMPUS_TAG_ID:
+ CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
+ CC (entry->components, 32, v, maxlen);
+ strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
+ break;
+ case MNOTE_OLYMPUS_TAG_UNKNOWN_4:
+ CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
+ CC (entry->components, 30, v, maxlen);
+ for (i=0; i < (int)entry->components; ++i) {
+ vl = exif_get_long (entry->data+4*i, entry->order);
+ sprintf (buf, "%lu ", (unsigned long)vl);
+ strncat (v, buf, maxlen - strlen (v));
+ }
+ break;
+ case MNOTE_OLYMPUS_TAG_FOCUSDIST:
+ CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
+ CC (entry->components, 1, v, maxlen);
+ vr = exif_get_rational (entry->data, entry->order);
+ if (!vr.numerator || !vr.denominator) {
+ strncpy (v, _("Unknown"), maxlen);
+ }
+ else {
+ unsigned long tmp = vr.numerator / vr.denominator;
+ snprintf (v, maxlen, "%li mm", tmp);
+ }
+ break;
+ case MNOTE_OLYMPUS_TAG_WBALANCE:
+ CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
+ CC (entry->components, 2, v, maxlen);
+ vs = exif_get_short (entry->data, entry->order);
+ switch (vs) {
+ case 1:
+ strncpy (v, _("Automatic"), maxlen);
+ break;
+ case 2:
+ {
+ ExifShort v2 = exif_get_short (entry->data + 2, entry->order);
+ unsigned long colorTemp = 0;
+ switch (v2) {
+ case 2:
+ colorTemp = 3000;
+ break;
+ case 3:
+ colorTemp = 3700;
+ break;
+ case 4:
+ colorTemp = 4000;
+ break;
+ case 5:
+ colorTemp = 4500;
+ break;
+ case 6:
+ colorTemp = 5500;
+ break;
+ case 7:
+ colorTemp = 6500;
+ break;
+ case 9:
+ colorTemp = 7500;
+ break;
+ }
+ if (colorTemp) {
+ snprintf (v, maxlen, _("Manual: %liK"), colorTemp);
+ }
+ else {
+ strncpy (v, _("Manual: unknown"), maxlen);
+ }
+
+ }
+ break;
+ case 3:
+ strncpy (v, _("One-touch"), maxlen);
+ break;
+ default:
+ strncpy (v, _("Unknown"), maxlen);
+ break;
+ }
+ break;
+ case MNOTE_OLYMPUS_TAG_REDBALANCE:
+ case MNOTE_OLYMPUS_TAG_BLUEBALANCE:
+ CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
+ CC (entry->components, 2, v, maxlen);
+ vs = exif_get_short (entry->data, entry->order);
+ snprintf (v, maxlen, "%hu ", vs);
+ vs = exif_get_short (entry->data + 2, entry->order);
+ sprintf (buf, "%hu", vs);
+ strncat (v, buf, maxlen - strlen (v));
+ break;
+ case MNOTE_OLYMPUS_TAG_BLACKLEVEL:
+ case MNOTE_NIKON_TAG_IMAGEBOUNDARY:
+ CC (entry->components, 4, v, maxlen);
+ /* Fall through to COLORMATRIX */
+ case MNOTE_OLYMPUS_TAG_COLORMATRIX:
+ CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
+ if (entry->tag == MNOTE_OLYMPUS_TAG_COLORMATRIX)
+ CC (entry->components, 9, v, maxlen);
+ for (i=0; i < (int)entry->components; ++i) {
+ vs = exif_get_short (entry->data+2*i, entry->order);
+ sprintf (buf, "%hu ", vs);
+ strncat (v, buf, maxlen - strlen (v));
+ }
+ break;
+ case MNOTE_NIKON1_TAG_FOCUS:
+ case MNOTE_NIKON_TAG_DIGITALZOOM:
+ case MNOTE_NIKON1_TAG_DIGITALZOOM:
+ case MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL:
+ CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
+ /* Fall through to default handler for display */
+ default:
+ switch (entry->format) {
+ case EXIF_FORMAT_ASCII:
+ strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
+ break;
+ case EXIF_FORMAT_SHORT:
+ CC (entry->components, 1, v, maxlen);
+ vs = exif_get_short (entry->data, entry->order);
+ snprintf (v, maxlen, "%hu", vs);
+ break;
+ case EXIF_FORMAT_LONG:
+ CC (entry->components, 1, v, maxlen);
+ vl = exif_get_long (entry->data, entry->order);
+ snprintf (v, maxlen, "%li", (long int) vl);
+ break;
+ case EXIF_FORMAT_RATIONAL:
+ CC (entry->components, 1, v, maxlen);
+ vr = exif_get_rational (entry->data, entry->order);
+ if (!vr.denominator) {
+ strncpy (v, _("Infinite"), maxlen);
+ } else {
+ r = R2D(vr);
+ snprintf (v, maxlen, "%2.3f", r);
+ }
+ break;
+ case EXIF_FORMAT_SRATIONAL:
+ CC (entry->components, 1, v, maxlen);
+ vsr = exif_get_srational (entry->data, entry->order);
+ if (!vsr.denominator) {
+ strncpy (v, _("Infinite"), maxlen);
+ } else {
+ r = R2D(vsr);
+ snprintf (v, maxlen, "%2.3f", r);
+ }
+ break;
+ case EXIF_FORMAT_UNDEFINED:
+ default:
+ snprintf (v, maxlen, _("%i bytes unknown data: "),
+ entry->size);
+ for (i = 0; i < (int)entry->size; i++) {
+ sprintf (buf, "%02x", entry->data[i]);
+ strncat (v, buf, maxlen - strlen (v));
+ }
+ break;
+ }
+ break;
+ }
+
+ return (v);
+}
diff --git a/libexif/olympus/mnote-olympus-entry.h b/libexif/olympus/mnote-olympus-entry.h
new file mode 100644
index 0000000..f1b0a98
--- /dev/null
+++ b/libexif/olympus/mnote-olympus-entry.h
@@ -0,0 +1,43 @@
+/* mnote-olympus-entry.h
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MNOTE_OLYMPUS_ENTRY_H__
+#define __MNOTE_OLYMPUS_ENTRY_H__
+
+#include <libexif/exif-format.h>
+#include <libexif/exif-byte-order.h>
+#include <libexif/olympus/mnote-olympus-tag.h>
+
+typedef struct _MnoteOlympusEntry MnoteOlympusEntry;
+
+struct _MnoteOlympusEntry {
+ MnoteOlympusTag tag;
+ ExifFormat format;
+ unsigned long components;
+
+ unsigned char *data;
+ unsigned int size;
+
+ ExifByteOrder order;
+};
+
+char *mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *val, unsigned int maxlen);
+
+#endif /* __MNOTE_OLYMPUS_ENTRY_H__ */
diff --git a/libexif/olympus/mnote-olympus-tag.c b/libexif/olympus/mnote-olympus-tag.c
new file mode 100644
index 0000000..3810352
--- /dev/null
+++ b/libexif/olympus/mnote-olympus-tag.c
@@ -0,0 +1,230 @@
+/* mnote-olympus-tag.c:
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+#include "mnote-olympus-tag.h"
+
+#include <libexif/i18n.h>
+#include <libexif/exif-utils.h>
+
+#include <stdlib.h>
+
+static const struct {
+ MnoteOlympusTag tag;
+ const char *name;
+ const char *title;
+ const char *description;
+} table[] = {
+#ifndef NO_VERBOSE_TAG_STRINGS
+ /* Nikon v2 */
+ {MNOTE_NIKON_TAG_FIRMWARE, "Firmware", N_("Firmware Version"), ""},
+ {MNOTE_NIKON_TAG_ISO, "ISO", N_("ISO Setting"), ""},
+ {MNOTE_NIKON_TAG_COLORMODE1, "ColorMode1", N_("Color Mode (?)"), ""},
+ {MNOTE_NIKON_TAG_QUALITY, "Quality", N_("Quality"), ""},
+ {MNOTE_NIKON_TAG_WHITEBALANCE, "WhiteBalance", N_("White Balance"), ""},
+ {MNOTE_NIKON_TAG_SHARPENING, "Sharpening", N_("Image Sharpening"), ""},
+ {MNOTE_NIKON_TAG_FOCUSMODE, "FocusMode", N_("Focus Mode"), ""},
+ {MNOTE_NIKON_TAG_FLASHSETTING, "FlashSetting", N_("Flash Setting"), ""},
+ {MNOTE_NIKON_TAG_FLASHMODE, "FlashMode", N_("Flash Mode"), ""},
+ {MNOTE_NIKON_TAG_WHITEBALANCEFINE,"WhiteBalanceFine",N_("White Balance Fine Adjustment"), ""},
+ {MNOTE_NIKON_TAG_WHITEBALANCERB, "WhiteBalanceRB", N_("White Balance RB"), ""},
+ {MNOTE_NIKON_TAG_UNKNOWN_0X000D, NULL, NULL, NULL},
+ {MNOTE_NIKON_TAG_ISOSELECTION, "ISOSelection", N_("ISO Selection"), ""},
+ {MNOTE_NIKON_TAG_PREVIEWIMAGE_IFD_POINTER, "PreviewImage", N_("Preview Image IFD"), N_("Offset of the preview image directory (IFD) inside the file.")},
+ {MNOTE_NIKON_TAG_EXPOSUREDIFF, "ExposureDiff", N_("Exposurediff ?"), ""},
+ {MNOTE_NIKON_TAG_FLASHEXPCOMPENSATION, "FlashExpCompensation", N_("Flash Exposure Compensation"), ""},
+ {MNOTE_NIKON_TAG_ISO2, "ISO", N_("ISO Setting"), ""},
+ {MNOTE_NIKON_TAG_IMAGEBOUNDARY, "ImageBoundary", N_("Image Boundary"), ""},
+ {MNOTE_NIKON_TAG_UNKNOWN_0X0017, NULL, NULL, NULL},
+ {MNOTE_NIKON_TAG_FLASHEXPOSUREBRACKETVAL, "FlashExposureBracketVal", N_("Flash Exposure Bracket Value"), ""},
+ {MNOTE_NIKON_TAG_EXPOSUREBRACKETVAL, "ExposureBracketVal", N_("Exposure Bracket Value"), ""},
+ {MNOTE_NIKON_TAG_IMAGEADJUSTMENT, "ImageAdjustment", N_("Image Adjustment"), ""},
+ {MNOTE_NIKON_TAG_TONECOMPENSATION, "ToneCompensation", N_("Tone Compensation"), ""},
+ {MNOTE_NIKON_TAG_ADAPTER, "Adapter", N_("Adapter"), ""},
+ {MNOTE_NIKON_TAG_LENSTYPE, "LensType", N_("Lens Type"), ""},
+ {MNOTE_NIKON_TAG_LENS, "Lens", N_("Lens"), ""},
+ {MNOTE_NIKON_TAG_MANUALFOCUSDISTANCE, "ManualFocusDistance", N_("Manual Focus Distance"), ""},
+ {MNOTE_NIKON_TAG_DIGITALZOOM, "DigitalZoom", N_("Digital Zoom"), ""},
+ {MNOTE_NIKON_TAG_FLASHUSED, "FlashUsed", N_("Flash Used"), ""},
+ {MNOTE_NIKON_TAG_AFFOCUSPOSITION, "AFFocusPosition", N_("AF Focus Position"), ""},
+ {MNOTE_NIKON_TAG_BRACKETING, "Bracketing", N_("Bracketing"), ""},
+ {MNOTE_NIKON_TAG_UNKNOWN_0X008A, NULL, NULL, NULL},
+ {MNOTE_NIKON_TAG_LENS_FSTOPS, "LensFStops", N_("Lens F Stops"), ""},
+ {MNOTE_NIKON_TAG_CURVE, "Curve,", N_("Contrast Curve"), ""},
+ {MNOTE_NIKON_TAG_COLORMODE, "ColorMode,", N_("Color Mode"), ""},
+ {MNOTE_NIKON_TAG_LIGHTTYPE, "LightType,", N_("Light Type"), ""},
+ {MNOTE_NIKON_TAG_UNKNOWN_0X0091, NULL, NULL, NULL},
+ {MNOTE_NIKON_TAG_HUE, "Hue", N_("Hue Adjustment"), ""},
+ {MNOTE_NIKON_TAG_SATURATION, "Saturation", N_("Saturation"), ""},
+ {MNOTE_NIKON_TAG_NOISEREDUCTION, "NoiseReduction,", N_("Noise Reduction"), ""},
+ {MNOTE_NIKON_TAG_UNKNOWN_0X0097, NULL, NULL, NULL},
+ {MNOTE_NIKON_TAG_UNKNOWN_0X0098, NULL, NULL, NULL},
+ {MNOTE_NIKON_TAG_SENSORPIXELSIZE, "SensorPixelSize", N_("Sensor Pixel Size"), ""},
+ {MNOTE_NIKON_TAG_UNKNOWN_0X009B, NULL, NULL, NULL},
+ {MNOTE_NIKON_TAG_SERIALNUMBER, "SerialNumber", N_("Serial Number"), ""},
+ {MNOTE_NIKON_TAG_IMAGE_DATASIZE, "ImageDataSize", N_("Image Data Size"), N_("Size of compressed image data in bytes.")},
+ {MNOTE_NIKON_TAG_UNKNOWN_0X00A3, NULL, NULL, NULL},
+ {MNOTE_NIKON_TAG_TOTALPICTURES, "TotalPictures,", N_("Total Number of Pictures Taken"), ""},
+ {MNOTE_NIKON_TAG_UNKNOWN_0X00A8, NULL, NULL, NULL},
+ {MNOTE_NIKON_TAG_OPTIMIZATION, "Optimization,", N_("Optimize Image"), ""},
+ {MNOTE_NIKON_TAG_SATURATION, "Saturation", N_("Saturation"), ""},
+ {MNOTE_NIKON_TAG_VARIPROGRAM, "VariProgram", N_("Vari Program"), ""},
+ {MNOTE_NIKON_TAG_CAPTUREEDITORDATA, "CaptureEditorData", N_("Capture Editor Data"), ""},
+ {MNOTE_NIKON_TAG_CAPTUREEDITORVER, "CaptureEditorVer", N_("Capture Editor Version"), ""},
+ {MNOTE_NIKON_TAG_UNKNOWN_0X0E0E, NULL, NULL, NULL},
+ {MNOTE_NIKON_TAG_UNKNOWN_0X0E10, NULL, NULL, NULL},
+ {MNOTE_NIKON1_TAG_UNKNOWN_0X0002, NULL, NULL, NULL},
+ {MNOTE_NIKON1_TAG_QUALITY, "Quality", N_("Quality"), ""},
+ {MNOTE_NIKON1_TAG_COLORMODE, "ColorMode,", N_("Color Mode"), ""},
+ {MNOTE_NIKON1_TAG_IMAGEADJUSTMENT, "ImageAdjustment", N_("Image Adjustment"), ""},
+ {MNOTE_NIKON1_TAG_CCDSENSITIVITY, "CCDSensitivity", N_("CCD Sensitivity"), ""},
+ {MNOTE_NIKON1_TAG_WHITEBALANCE, "WhiteBalance", N_("White Balance"), ""},
+ {MNOTE_NIKON1_TAG_FOCUS, "Focus", N_("Focus"), ""},
+ {MNOTE_NIKON1_TAG_UNKNOWN_0X0009, NULL, NULL, NULL},
+ {MNOTE_NIKON1_TAG_DIGITALZOOM, "DigitalZoom", N_("Digital Zoom"), ""},
+ {MNOTE_NIKON1_TAG_CONVERTER, "Converter", N_("Converter"), ""},
+
+ /* Olympus & some Sanyo */
+ {MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE, "ThumbnailImage", N_("Thumbnail Image"), ""},
+ {MNOTE_OLYMPUS_TAG_MODE, "Mode", N_("Speed/Sequence/Panorama Direction"), ""},
+ {MNOTE_OLYMPUS_TAG_QUALITY, "Quality", N_("Quality"), ""},
+ {MNOTE_OLYMPUS_TAG_MACRO, "Macro", N_("Macro"), ""},
+ {MNOTE_OLYMPUS_TAG_BWMODE, "BWMode", N_("Black & White Mode"), ""},
+ {MNOTE_OLYMPUS_TAG_DIGIZOOM, "DigiZoom", N_("Digital Zoom"), ""},
+ {MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL, "FocalPlaneDiagonal", N_("Focal Plane Diagonal"), ""},
+ {MNOTE_OLYMPUS_TAG_LENSDISTORTION, "LensDistortionParams", N_("Lens Distortion Parameters"), ""},
+ {MNOTE_OLYMPUS_TAG_VERSION, "FirmwareVersion", N_("Firmware Version"), ""},
+ {MNOTE_OLYMPUS_TAG_INFO, "Info", N_("Info"), ""},
+ {MNOTE_OLYMPUS_TAG_ID, "CameraID", N_("Camera ID"), ""},
+ {MNOTE_OLYMPUS_TAG_PRECAPTUREFRAMES, "PreCaptureFrames", N_("Precapture Frames"), ""},
+ {MNOTE_OLYMPUS_TAG_WHITEBOARD, "WhiteBoard", N_("White Board"), ""},
+ {MNOTE_OLYMPUS_TAG_ONETOUCHWB, "OneTouchWB", N_("One Touch White Balance"), ""},
+ {MNOTE_OLYMPUS_TAG_WHITEBALANCEBRACKET, "WhiteBalanceBracket", N_("White Balance Bracket"), ""},
+ {MNOTE_OLYMPUS_TAG_WHITEBALANCEBIAS, "WhiteBalanceBias", N_("White Balance Bias"), ""},
+ {MNOTE_OLYMPUS_TAG_DATADUMP, "DataDump", N_("Data Dump"), NULL},
+ {MNOTE_OLYMPUS_TAG_UNKNOWN_4, NULL, NULL, NULL},
+ {MNOTE_OLYMPUS_TAG_SHUTTERSPEED, "ShutterSpeed", N_("Shutter Speed"), ""},
+ {MNOTE_OLYMPUS_TAG_ISOVALUE, "ISOValue", N_("ISO Value"), ""},
+ {MNOTE_OLYMPUS_TAG_APERTUREVALUE, "ApertureValue", N_("Aperture Value"), ""},
+ {MNOTE_OLYMPUS_TAG_BRIGHTNESSVALUE, "BrightnessValue", N_("Brightness Value"), ""},
+ {MNOTE_OLYMPUS_TAG_FLASHMODE, "FlashMode", N_("Flash Mode"), ""},
+ {MNOTE_OLYMPUS_TAG_FLASHDEVICE, "FlashDevice", N_("Flash Device"), ""},
+ {MNOTE_OLYMPUS_TAG_EXPOSURECOMP, "ExposureCompensation", N_("Exposure Compensation"), ""},
+ {MNOTE_OLYMPUS_TAG_SENSORTEMPERATURE, "SensorTemperature", N_("Sensor Temperature"), ""},
+ {MNOTE_OLYMPUS_TAG_LENSTEMPERATURE, "LensTemperature", N_("Lens Temperature"), ""},
+ {MNOTE_OLYMPUS_TAG_LIGHTCONDITION, "LightCondition", N_("Light Condition"), ""},
+ {MNOTE_OLYMPUS_TAG_FOCUSRANGE, "FocusRange", N_("Focus Range"), ""},
+ {MNOTE_OLYMPUS_TAG_MANFOCUS, "FocusMode", N_("Focus Mode"), "Automatic or manual focusing mode"},
+ {MNOTE_OLYMPUS_TAG_FOCUSDIST, "ManualFocusDistance", N_("Manual Focus Distance"), ""},
+ {MNOTE_OLYMPUS_TAG_ZOOMSTEPCOUNT, "ZoomStepCount", N_("Zoom Step Count"), ""},
+ {MNOTE_OLYMPUS_TAG_FOCUSSTEPCOUNT, "FocusStepCount", N_("Focus Step Count"), ""},
+ {MNOTE_OLYMPUS_TAG_SHARPNESS, "Sharpness", N_("Sharpness Setting"), ""},
+ {MNOTE_OLYMPUS_TAG_FLASHCHARGELEVEL, "FlashChargeLevel", N_("Flash Charge Level"), ""},
+ {MNOTE_OLYMPUS_TAG_COLORMATRIX, "ColorMatrix", N_("Color Matrix"), ""},
+ {MNOTE_OLYMPUS_TAG_BLACKLEVEL, "BlackLevel", N_("Black Level"), ""},
+ {MNOTE_OLYMPUS_TAG_WBALANCE, "WhiteBalance", N_("White Balance Setting"), ""},
+ {MNOTE_OLYMPUS_TAG_REDBALANCE, "RedBalance", N_("Red Balance"), ""},
+ {MNOTE_OLYMPUS_TAG_BLUEBALANCE, "BlueBalance", N_("Blue Balance"), ""},
+ {MNOTE_OLYMPUS_TAG_COLORMATRIXNUMBER, "ColorMatrixNumber", N_("Color Matrix Number"), ""},
+ {MNOTE_OLYMPUS_TAG_SERIALNUMBER2, "SerialNumber", N_("Serial Number"), ""},
+ {MNOTE_OLYMPUS_TAG_FLASHEXPOSURECOMP, "FlashExposureComp", N_("Flash Exposure Comp"), ""},
+ {MNOTE_OLYMPUS_TAG_INTERNALFLASHTABLE, "InternalFlashTable", N_("Internal Flash Table"), ""},
+ {MNOTE_OLYMPUS_TAG_EXTERNALFLASHGVALUE, "ExternalFlashGValue", N_("External Flash G Value"), ""},
+ {MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE, "ExternalFlashBounce", N_("External Flash Bounce"), ""},
+ {MNOTE_OLYMPUS_TAG_EXTERNALFLASHZOOM, "ExternalFlashZoom", N_("External Flash Zoom"), ""},
+ {MNOTE_OLYMPUS_TAG_EXTERNALFLASHMODE, "ExternalFlashMode", N_("External Flash Mode"), ""},
+ {MNOTE_OLYMPUS_TAG_CONTRAST, "Contrast", N_("Contrast Setting"), ""},
+ {MNOTE_OLYMPUS_TAG_SHARPNESSFACTOR, "SharpnessFactor", N_("Sharpness Factor"), ""},
+ {MNOTE_OLYMPUS_TAG_COLORCONTROL, "ColorControl", N_("Color Control"), ""},
+ {MNOTE_OLYMPUS_TAG_IMAGEWIDTH, "OlympusImageWidth", N_("Olympus Image Width"), ""},
+ {MNOTE_OLYMPUS_TAG_IMAGEHEIGHT, "OlympusImageHeight", N_("Olympus Image Height"), ""},
+ {MNOTE_OLYMPUS_TAG_SCENEDETECT, "SceneDetect", N_("Scene Detect"), ""},
+ {MNOTE_OLYMPUS_TAG_COMPRESSIONRATIO, "CompressionRatio", N_("Compression Ratio"), ""},
+ {MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID, "PreviewImageValid", N_("Preview Image Valid"), ""},
+ {MNOTE_OLYMPUS_TAG_AFRESULT, "AFResult", N_("AF Result"), ""},
+ {MNOTE_OLYMPUS_TAG_CCDSCANMODE, "CCDScanMode", N_("CCD Scan Mode"), ""},
+ {MNOTE_OLYMPUS_TAG_NOISEREDUCTION, "NoiseReduction", N_("Noise Reduction"), ""},
+ {MNOTE_OLYMPUS_TAG_INFINITYLENSSTEP, "InfinityLensStep", N_("Infinity Lens Step"), ""},
+ {MNOTE_OLYMPUS_TAG_NEARLENSSTEP, "NearLensStep", N_("Near Lens Step"), ""},
+ {MNOTE_OLYMPUS_TAG_LIGHTVALUECENTER, "LightValueCenter", N_("Light Value Center"), ""},
+ {MNOTE_OLYMPUS_TAG_LIGHTVALUEPERIPHERY, "LightValuePeriphery", N_("Light Value Periphery"), ""},
+
+ /* Sanyo */
+ {MNOTE_SANYO_TAG_SEQUENTIALSHOT, "SequentialShot", N_("Sequential Shot"), ""},
+ {MNOTE_SANYO_TAG_WIDERANGE, "WideRange", N_("Wide Range"), ""},
+ {MNOTE_SANYO_TAG_COLORADJUSTMENTMODE, "ColorAdjustmentMode", N_("Color Adjustment Mode"), ""},
+ {MNOTE_SANYO_TAG_FOCUSMODE, "FocusMode", N_("Focus Mode"), ""},
+ {MNOTE_SANYO_TAG_QUICKSHOT, "QuickShot", N_("Quick Shot"), ""},
+ {MNOTE_SANYO_TAG_SELFTIMER, "SelfTimer", N_("Self-timer"), ""},
+ {MNOTE_SANYO_TAG_VOICEMEMO, "VoiceMemo", N_("Voice Memo"), ""},
+ {MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE, "RecordShutterRelease", N_("Record Shutter Release"), ""},
+ {MNOTE_SANYO_TAG_FLICKERREDUCE, "FlickerReduce", N_("Flicker Reduce"), ""},
+ {MNOTE_SANYO_TAG_OPTICALZOOM, "OpticalZoom", N_("Optical Zoom"), ""},
+ {MNOTE_SANYO_TAG_DIGITALZOOM, "DigitalZoom", N_("Digital Zoom"), ""},
+ {MNOTE_SANYO_TAG_LIGHTSOURCESPECIAL, "LightSourceSpecial", N_("Light Source Special"), ""},
+ {MNOTE_SANYO_TAG_RESAVED, "Resaved", N_("Resaved"), ""},
+ {MNOTE_SANYO_TAG_CCDSENSITIVITY, "CCDSensitivity", N_("CCD Sensitivity"), ""},
+ {MNOTE_SANYO_TAG_SCENESELECT, "SceneSelect", N_("Scene Select"), ""},
+ {MNOTE_SANYO_TAG_MANUALFOCUSDISTANCE, "ManualFocusDistance", N_("Manual Focus Distance"), ""},
+ {MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL, "SequenceShotInterval", N_("Sequence Shot Interval"), ""},
+
+ /* Epson */
+ {MNOTE_EPSON_TAG_IMAGE_WIDTH, "EpsonImageWidth", N_("Epson Image Width"), ""},
+ {MNOTE_EPSON_TAG_IMAGE_HEIGHT, "EpsonImageHeight", N_("Epson Image Height"), ""},
+ {MNOTE_EPSON_TAG_SOFTWARE, "EpsonSoftware", N_("Epson Software Version"), ""},
+#endif
+ {0, NULL, NULL, NULL}
+};
+
+const char *
+mnote_olympus_tag_get_name (MnoteOlympusTag t)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ if (table[i].tag == t) return (table[i].name);
+ return NULL;
+}
+
+const char *
+mnote_olympus_tag_get_title (MnoteOlympusTag t)
+{
+ unsigned int i;
+
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ if (table[i].tag == t) return (_(table[i].title));
+ return NULL;
+}
+
+const char *
+mnote_olympus_tag_get_description (MnoteOlympusTag t)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ if (table[i].tag == t) {
+ if (!table[i].description || !*table[i].description)
+ return "";
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ return _(table[i].description);
+ }
+ return NULL;
+}
diff --git a/libexif/olympus/mnote-olympus-tag.h b/libexif/olympus/mnote-olympus-tag.h
new file mode 100644
index 0000000..2c3de82
--- /dev/null
+++ b/libexif/olympus/mnote-olympus-tag.h
@@ -0,0 +1,229 @@
+/* mnote-olympus-tag.h
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MNOTE_OLYMPUS_TAG_H__
+#define __MNOTE_OLYMPUS_TAG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+enum _MnoteOlympusTag {
+
+ /* Nikon v.2 */
+ MNOTE_NIKON_TAG_FIRMWARE = 0x0001,
+ MNOTE_NIKON_TAG_ISO = 0x0002,
+ MNOTE_NIKON_TAG_COLORMODE1 = 0x0003,
+ MNOTE_NIKON_TAG_QUALITY = 0x0004,
+ MNOTE_NIKON_TAG_WHITEBALANCE = 0x0005,
+ MNOTE_NIKON_TAG_SHARPENING = 0x0006,
+ MNOTE_NIKON_TAG_FOCUSMODE = 0x0007,
+ MNOTE_NIKON_TAG_FLASHSETTING = 0x0008,
+ MNOTE_NIKON_TAG_FLASHMODE = 0x0009,
+ MNOTE_NIKON_TAG_WHITEBALANCEFINE = 0x000b,
+ MNOTE_NIKON_TAG_WHITEBALANCERB = 0x000c,
+ MNOTE_NIKON_TAG_UNKNOWN_0X000D = 0x000d,
+ MNOTE_NIKON_TAG_EXPOSUREDIFF = 0x000e,
+ MNOTE_NIKON_TAG_ISOSELECTION = 0x000f,
+ MNOTE_NIKON_TAG_PREVIEWIMAGE_IFD_POINTER= 0x0011,
+ MNOTE_NIKON_TAG_FLASHEXPCOMPENSATION = 0x0012,
+ MNOTE_NIKON_TAG_ISO2 = 0x0013,
+ MNOTE_NIKON_TAG_IMAGEBOUNDARY = 0x0016,
+ MNOTE_NIKON_TAG_UNKNOWN_0X0017 = 0x0017,
+ MNOTE_NIKON_TAG_FLASHEXPOSUREBRACKETVAL = 0x0018,
+ MNOTE_NIKON_TAG_EXPOSUREBRACKETVAL = 0x0019,
+ MNOTE_NIKON_TAG_IMAGEADJUSTMENT = 0x0080,
+ MNOTE_NIKON_TAG_TONECOMPENSATION = 0x0081,
+ MNOTE_NIKON_TAG_ADAPTER = 0x0082,
+ MNOTE_NIKON_TAG_LENSTYPE = 0x0083,
+ MNOTE_NIKON_TAG_LENS = 0x0084,
+ MNOTE_NIKON_TAG_MANUALFOCUSDISTANCE = 0x0085,
+ MNOTE_NIKON_TAG_DIGITALZOOM = 0x0086,
+ MNOTE_NIKON_TAG_FLASHUSED = 0x0087,
+ MNOTE_NIKON_TAG_AFFOCUSPOSITION = 0x0088,
+ MNOTE_NIKON_TAG_BRACKETING = 0x0089,
+ MNOTE_NIKON_TAG_UNKNOWN_0X008A = 0x008a,
+ MNOTE_NIKON_TAG_LENS_FSTOPS = 0x008b,
+ MNOTE_NIKON_TAG_CURVE = 0x008c,
+ MNOTE_NIKON_TAG_COLORMODE = 0x008d,
+ MNOTE_NIKON_TAG_LIGHTTYPE = 0x0090,
+ MNOTE_NIKON_TAG_UNKNOWN_0X0091 = 0x0091,
+ MNOTE_NIKON_TAG_HUE = 0x0092,
+ MNOTE_NIKON_TAG_SATURATION = 0x0094,
+ MNOTE_NIKON_TAG_NOISEREDUCTION = 0x0095,
+ MNOTE_NIKON_TAG_UNKNOWN_0X0097 = 0x0097,
+ MNOTE_NIKON_TAG_UNKNOWN_0X0098 = 0x0098,
+ MNOTE_NIKON_TAG_SENSORPIXELSIZE = 0x009a,
+ MNOTE_NIKON_TAG_UNKNOWN_0X009B = 0x009b,
+ MNOTE_NIKON_TAG_SERIALNUMBER = 0x00a0,
+ MNOTE_NIKON_TAG_IMAGE_DATASIZE = 0x00a2,
+ MNOTE_NIKON_TAG_UNKNOWN_0X00A3 = 0x00a3,
+ MNOTE_NIKON_TAG_TOTALPICTURES = 0x00a7,
+ MNOTE_NIKON_TAG_UNKNOWN_0X00A8 = 0x00a8,
+ MNOTE_NIKON_TAG_OPTIMIZATION = 0x00a9,
+ MNOTE_NIKON_TAG_SATURATION2 = 0x00aa,
+ MNOTE_NIKON_TAG_VARIPROGRAM = 0x00ab,
+ MNOTE_NIKON_TAG_CAPTUREEDITORDATA = 0x0e01,
+ MNOTE_NIKON_TAG_CAPTUREEDITORVER = 0x0e09,
+ MNOTE_NIKON_TAG_UNKNOWN_0X0E0E = 0x0e0e,
+ MNOTE_NIKON_TAG_UNKNOWN_0X0E10 = 0x0e10,
+
+ /* Nikon v1: real values + our proprietary base to distinguish from v2 */
+ MNOTE_NIKON1_TAG_BASE = 0x8000,
+ MNOTE_NIKON1_TAG_UNKNOWN_0X0002 = 0x0002 + MNOTE_NIKON1_TAG_BASE,
+ MNOTE_NIKON1_TAG_QUALITY = 0x0003 + MNOTE_NIKON1_TAG_BASE,
+ MNOTE_NIKON1_TAG_COLORMODE = 0x0004 + MNOTE_NIKON1_TAG_BASE,
+ MNOTE_NIKON1_TAG_IMAGEADJUSTMENT = 0x0005 + MNOTE_NIKON1_TAG_BASE,
+ MNOTE_NIKON1_TAG_CCDSENSITIVITY = 0x0006 + MNOTE_NIKON1_TAG_BASE,
+ MNOTE_NIKON1_TAG_WHITEBALANCE = 0x0007 + MNOTE_NIKON1_TAG_BASE,
+ MNOTE_NIKON1_TAG_FOCUS = 0x0008 + MNOTE_NIKON1_TAG_BASE,
+ MNOTE_NIKON1_TAG_UNKNOWN_0X0009 = 0x0009 + MNOTE_NIKON1_TAG_BASE,
+ MNOTE_NIKON1_TAG_DIGITALZOOM = 0x000a + MNOTE_NIKON1_TAG_BASE,
+ MNOTE_NIKON1_TAG_CONVERTER = 0x000b + MNOTE_NIKON1_TAG_BASE,
+
+ /* Olympus and some Sanyo */
+ MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE = 0x0100,
+ MNOTE_OLYMPUS_TAG_MODE = 0x0200,
+ MNOTE_OLYMPUS_TAG_QUALITY = 0x0201,
+ MNOTE_OLYMPUS_TAG_MACRO = 0x0202,
+ MNOTE_OLYMPUS_TAG_BWMODE = 0x0203,
+ MNOTE_OLYMPUS_TAG_DIGIZOOM = 0x0204,
+ MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL = 0x0205,
+ MNOTE_OLYMPUS_TAG_LENSDISTORTION = 0x0206,
+ MNOTE_OLYMPUS_TAG_VERSION = 0x0207,
+ MNOTE_OLYMPUS_TAG_INFO = 0x0208,
+ MNOTE_OLYMPUS_TAG_ID = 0x0209,
+ MNOTE_OLYMPUS_TAG_PRECAPTUREFRAMES = 0x0300,
+ MNOTE_OLYMPUS_TAG_WHITEBOARD = 0x0301,
+ MNOTE_OLYMPUS_TAG_ONETOUCHWB = 0x0302,
+ MNOTE_OLYMPUS_TAG_WHITEBALANCEBRACKET = 0x0303,
+ MNOTE_OLYMPUS_TAG_WHITEBALANCEBIAS = 0x0304,
+ MNOTE_OLYMPUS_TAG_DATADUMP = 0x0f00,
+ MNOTE_OLYMPUS_TAG_UNKNOWN_4 = 0x0f04,
+ MNOTE_OLYMPUS_TAG_SHUTTERSPEED = 0x1000,
+ MNOTE_OLYMPUS_TAG_ISOVALUE = 0x1001,
+ MNOTE_OLYMPUS_TAG_APERTUREVALUE = 0x1002,
+ MNOTE_OLYMPUS_TAG_BRIGHTNESSVALUE = 0x1003,
+ MNOTE_OLYMPUS_TAG_FLASHMODE = 0x1004,
+ MNOTE_OLYMPUS_TAG_FLASHDEVICE = 0x1005,
+ MNOTE_OLYMPUS_TAG_EXPOSURECOMP = 0x1006,
+ MNOTE_OLYMPUS_TAG_SENSORTEMPERATURE = 0x1007,
+ MNOTE_OLYMPUS_TAG_LENSTEMPERATURE = 0x1008,
+ MNOTE_OLYMPUS_TAG_LIGHTCONDITION = 0x1009,
+ MNOTE_OLYMPUS_TAG_FOCUSRANGE = 0x100a,
+ MNOTE_OLYMPUS_TAG_MANFOCUS = 0x100b,
+ MNOTE_OLYMPUS_TAG_FOCUSDIST = 0x100c,
+ MNOTE_OLYMPUS_TAG_ZOOMSTEPCOUNT = 0x100d,
+ MNOTE_OLYMPUS_TAG_FOCUSSTEPCOUNT = 0x100e,
+ MNOTE_OLYMPUS_TAG_SHARPNESS = 0x100f,
+ MNOTE_OLYMPUS_TAG_FLASHCHARGELEVEL = 0x1010,
+ MNOTE_OLYMPUS_TAG_COLORMATRIX = 0x1011,
+ MNOTE_OLYMPUS_TAG_BLACKLEVEL = 0x1012,
+ MNOTE_OLYMPUS_TAG_WBALANCE = 0x1015,
+ MNOTE_OLYMPUS_TAG_REDBALANCE = 0x1017,
+ MNOTE_OLYMPUS_TAG_BLUEBALANCE = 0x1018,
+ MNOTE_OLYMPUS_TAG_COLORMATRIXNUMBER = 0x1019,
+ MNOTE_OLYMPUS_TAG_SERIALNUMBER2 = 0x101a,
+ MNOTE_OLYMPUS_TAG_FLASHEXPOSURECOMP = 0x1023,
+ MNOTE_OLYMPUS_TAG_INTERNALFLASHTABLE = 0x1024,
+ MNOTE_OLYMPUS_TAG_EXTERNALFLASHGVALUE = 0x1025,
+ MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE = 0x1026,
+ MNOTE_OLYMPUS_TAG_EXTERNALFLASHZOOM = 0x1027,
+ MNOTE_OLYMPUS_TAG_EXTERNALFLASHMODE = 0x1028,
+ MNOTE_OLYMPUS_TAG_CONTRAST = 0x1029,
+ MNOTE_OLYMPUS_TAG_SHARPNESSFACTOR = 0x102a,
+ MNOTE_OLYMPUS_TAG_COLORCONTROL = 0x102b,
+ MNOTE_OLYMPUS_TAG_IMAGEWIDTH = 0x102e,
+ MNOTE_OLYMPUS_TAG_IMAGEHEIGHT = 0x102f,
+ MNOTE_OLYMPUS_TAG_SCENEDETECT = 0x1030,
+ MNOTE_OLYMPUS_TAG_COMPRESSIONRATIO = 0x1034,
+ MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID = 0x1035,
+ MNOTE_OLYMPUS_TAG_AFRESULT = 0x1038,
+ MNOTE_OLYMPUS_TAG_CCDSCANMODE = 0x1039,
+ MNOTE_OLYMPUS_TAG_NOISEREDUCTION = 0x103a,
+ MNOTE_OLYMPUS_TAG_INFINITYLENSSTEP = 0x103b,
+ MNOTE_OLYMPUS_TAG_NEARLENSSTEP = 0x103c,
+ MNOTE_OLYMPUS_TAG_LIGHTVALUECENTER = 0x103d,
+ MNOTE_OLYMPUS_TAG_LIGHTVALUEPERIPHERY = 0x103e,
+
+ /* Epson */
+ MNOTE_EPSON_TAG_IMAGE_WIDTH = 0x020b,
+ MNOTE_EPSON_TAG_IMAGE_HEIGHT = 0x020c,
+ MNOTE_EPSON_TAG_SOFTWARE = 0x020d,
+
+ /* Sanyo */
+ MNOTE_SANYO_TAG_SEQUENTIALSHOT = 0x020e,
+ MNOTE_SANYO_TAG_WIDERANGE = 0x020f,
+ MNOTE_SANYO_TAG_COLORADJUSTMENTMODE = 0x0210,
+ MNOTE_SANYO_TAG_FOCUSMODE = 0x0212,
+ MNOTE_SANYO_TAG_QUICKSHOT = 0x0213,
+ MNOTE_SANYO_TAG_SELFTIMER = 0x0214,
+ MNOTE_SANYO_TAG_VOICEMEMO = 0x0216,
+ MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE = 0x0217,
+ MNOTE_SANYO_TAG_FLICKERREDUCE = 0x0218,
+ MNOTE_SANYO_TAG_OPTICALZOOM = 0x0219,
+ MNOTE_SANYO_TAG_CCDSENSITIVITY = 0x021a,
+ MNOTE_SANYO_TAG_DIGITALZOOM = 0x021b,
+ MNOTE_SANYO_TAG_LIGHTSOURCESPECIAL = 0x021d,
+ MNOTE_SANYO_TAG_RESAVED = 0x021e,
+ MNOTE_SANYO_TAG_SCENESELECT = 0x021f,
+ MNOTE_SANYO_TAG_MANUALFOCUSDISTANCE = 0x0223,
+ MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL = 0x0224,
+};
+typedef enum _MnoteOlympusTag MnoteOlympusTag;
+
+/* Don't use these definitions. They are here for compatibility only. */
+#define MNOTE_OLYMPUS_TAG_UNKNOWN_1 MNOTE_OLYMPUS_TAG_BWMODE
+#define MNOTE_OLYMPUS_TAG_UNKNOWN_2 MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL
+#define MNOTE_OLYMPUS_TAG_UNKNOWN_3 MNOTE_OLYMPUS_TAG_LENSDISTORTION
+#define MNOTE_OLYMPUS_TAG_UNKNOWN_5 MNOTE_OLYMPUS_TAG_DATADUMP
+#define MNOTE_NIKON_TAG_PREVIEWIMAGE MNOTE_NIKON_TAG_PREVIEWIMAGE_IFD_POINTER
+
+/*! Return a textual name of the given tag within the Olympus-style MakerNote.
+ * The name is a short, unique, non-localized text string containing only
+ * US-ASCII alphanumeric characters.
+ *
+ * \param[in] tag Olympus-style MakerNote tag
+ * \return textual name of the tag, or NULL if the tag is unknown
+ */
+const char *mnote_olympus_tag_get_name (MnoteOlympusTag tag);
+
+/*! Return a textual title of the given tag within the Olympus-style MakerNote.
+ * The title is a short, localized description of the tag.
+ *
+ * \param[in] tag Olympus-style MakerNote tag
+ * \return textual title of the tag, or NULL if the tag is unknown
+ */
+const char *mnote_olympus_tag_get_title (MnoteOlympusTag tag);
+
+/*! Return a verbose textual description of the given tag within the
+ * Olympus-style MakerNote.
+ * The description is a verbose, localized description of the tag.
+ *
+ * \param[in] tag EXIF tag
+ * \return textual description of the tag, or NULL if the tag is unknown
+ */
+const char *mnote_olympus_tag_get_description (MnoteOlympusTag tag);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MNOTE_OLYMPUS_TAG_H__ */
diff --git a/libexif/pentax/Makefile-files b/libexif/pentax/Makefile-files
new file mode 100644
index 0000000..bcc0ac5
--- /dev/null
+++ b/libexif/pentax/Makefile-files
@@ -0,0 +1,7 @@
+# -*- Makefile -*-
+noinst_LTLIBRARIES += libmnote-pentax.la
+libmnote_pentax_la_SOURCES = \
+ pentax/mnote-pentax-entry.c pentax/mnote-pentax-entry.h \
+ pentax/exif-mnote-data-pentax.c pentax/exif-mnote-data-pentax.h \
+ pentax/mnote-pentax-tag.c pentax/mnote-pentax-tag.h
+libmnote_pentax_la_LIBADD = $(LTLIBINTL)
diff --git a/libexif/pentax/exif-mnote-data-pentax.c b/libexif/pentax/exif-mnote-data-pentax.c
new file mode 100644
index 0000000..3676563
--- /dev/null
+++ b/libexif/pentax/exif-mnote-data-pentax.c
@@ -0,0 +1,464 @@
+/* exif-mnote-data-pentax.c
+ *
+ * Copyright (c) 2002, 2003 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "exif-mnote-data-pentax.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <libexif/exif-byte-order.h>
+#include <libexif/exif-utils.h>
+
+#define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
+
+static void
+exif_mnote_data_pentax_clear (ExifMnoteDataPentax *n)
+{
+ ExifMnoteData *d = (ExifMnoteData *) n;
+ unsigned int i;
+
+ if (!n) return;
+
+ if (n->entries) {
+ for (i = 0; i < n->count; i++)
+ if (n->entries[i].data) {
+ exif_mem_free (d->mem, n->entries[i].data);
+ n->entries[i].data = NULL;
+ }
+ exif_mem_free (d->mem, n->entries);
+ n->entries = NULL;
+ n->count = 0;
+ }
+}
+
+static void
+exif_mnote_data_pentax_free (ExifMnoteData *n)
+{
+ if (!n) return;
+
+ exif_mnote_data_pentax_clear ((ExifMnoteDataPentax *) n);
+}
+
+static char *
+exif_mnote_data_pentax_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen)
+{
+ ExifMnoteDataPentax *n = (ExifMnoteDataPentax *) d;
+
+ if (!n) return NULL;
+ if (n->count <= i) return NULL;
+ return mnote_pentax_entry_get_value (&n->entries[i], val, maxlen);
+}
+
+/**
+ * @brief save the MnoteData from ne to buf
+ *
+ * @param ne extract the data from this structure
+ * @param *buf write the mnoteData to this buffer (buffer will be allocated)
+ * @param buf_size the final size of the buffer
+ */
+static void
+exif_mnote_data_pentax_save (ExifMnoteData *ne,
+ unsigned char **buf, unsigned int *buf_size)
+{
+ ExifMnoteDataPentax *n = (ExifMnoteDataPentax *) ne;
+ size_t i,
+ base = 0, /* internal MakerNote tag number offset */
+ o2 = 4 + 2; /* offset to first tag entry, past header */
+ size_t datao = n->offset; /* this MakerNote style uses offsets
+ based on main IFD, not makernote IFD */
+
+ if (!n || !buf || !buf_size) return;
+
+ /*
+ * Allocate enough memory for header, the number of entries, entries,
+ * and next IFD pointer
+ */
+ *buf_size = o2 + 2 + n->count * 12 + 4;
+ switch (n->version) {
+ case casioV2:
+ base = MNOTE_PENTAX2_TAG_BASE;
+ *buf = exif_mem_alloc (ne->mem, *buf_size);
+ if (!*buf) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", *buf_size);
+ return;
+ }
+ /* Write the magic header */
+ strcpy ((char *)*buf, "QVC");
+ exif_set_short (*buf + 4, n->order, (ExifShort) 0);
+
+ break;
+
+ case pentaxV3:
+ base = MNOTE_PENTAX2_TAG_BASE;
+ *buf = exif_mem_alloc (ne->mem, *buf_size);
+ if (!*buf) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", *buf_size);
+ return;
+ }
+
+ /* Write the magic header */
+ strcpy ((char *)*buf, "AOC");
+ exif_set_short (*buf + 4, n->order, (ExifShort) (
+ (n->order == EXIF_BYTE_ORDER_INTEL) ?
+ ('I' << 8) | 'I' :
+ ('M' << 8) | 'M'));
+ break;
+
+ case pentaxV2:
+ base = MNOTE_PENTAX2_TAG_BASE;
+ *buf = exif_mem_alloc (ne->mem, *buf_size);
+ if (!*buf) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", *buf_size);
+ return;
+ }
+
+ /* Write the magic header */
+ strcpy ((char *)*buf, "AOC");
+ exif_set_short (*buf + 4, n->order, (ExifShort) 0);
+ break;
+
+ case pentaxV1:
+ /* It looks like this format doesn't have a magic header as
+ * such, just has a fixed number of entries equal to 0x001b */
+ *buf_size -= 6;
+ o2 -= 6;
+ *buf = exif_mem_alloc (ne->mem, *buf_size);
+ if (!*buf) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", *buf_size);
+ return;
+ }
+ break;
+
+ default:
+ /* internal error */
+ return;
+ }
+
+ /* Write the number of entries. */
+ exif_set_short (*buf + o2, n->order, (ExifShort) n->count);
+ o2 += 2;
+
+ /* Save each entry */
+ for (i = 0; i < n->count; i++) {
+ size_t doff; /* offset to current data portion of tag */
+ size_t s;
+ unsigned char *t;
+ size_t o = o2 + i * 12; /* current offset into output buffer */
+ exif_set_short (*buf + o + 0, n->order,
+ (ExifShort) (n->entries[i].tag - base));
+ exif_set_short (*buf + o + 2, n->order,
+ (ExifShort) n->entries[i].format);
+ exif_set_long (*buf + o + 4, n->order,
+ n->entries[i].components);
+ o += 8;
+ s = exif_format_get_size (n->entries[i].format) *
+ n->entries[i].components;
+ if (s > 65536) {
+ /* Corrupt data: EXIF data size is limited to the
+ * maximum size of a JPEG segment (64 kb).
+ */
+ continue;
+ }
+ if (s > 4) {
+ size_t ts = *buf_size + s;
+ doff = *buf_size;
+ t = exif_mem_realloc (ne->mem, *buf,
+ sizeof (char) * ts);
+ if (!t) {
+ EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", ts);
+ return;
+ }
+ *buf = t;
+ *buf_size = ts;
+ exif_set_long (*buf + o, n->order, datao + doff);
+ } else
+ doff = o;
+
+ /* Write the data. */
+ if (n->entries[i].data) {
+ memcpy (*buf + doff, n->entries[i].data, s);
+ } else {
+ /* Most certainly damaged input file */
+ memset (*buf + doff, 0, s);
+ }
+ }
+
+ /* Sanity check the buffer size */
+ if (*buf_size < (o2 + n->count * 12 + 4)) {
+ exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifMnoteDataPentax",
+ "Buffer overflow");
+ }
+
+ /* Reset next IFD pointer */
+ exif_set_long (*buf + o2 + n->count * 12, n->order, 0);
+}
+
+static void
+exif_mnote_data_pentax_load (ExifMnoteData *en,
+ const unsigned char *buf, unsigned int buf_size)
+{
+ ExifMnoteDataPentax *n = (ExifMnoteDataPentax *) en;
+ size_t i, tcount, o, datao, base = 0;
+ ExifShort c;
+
+ if (!n || !buf || !buf_size) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteDataPentax", "Short MakerNote");
+ return;
+ }
+ datao = 6 + n->offset;
+ if (CHECKOVERFLOW(datao, buf_size, 8)) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteDataPentax", "Short MakerNote");
+ return;
+ }
+
+ /* Detect variant of Pentax/Casio MakerNote found */
+ if (!memcmp(buf + datao, "AOC", 4)) {
+ if ((buf[datao + 4] == 'I') && (buf[datao + 5] == 'I')) {
+ n->version = pentaxV3;
+ n->order = EXIF_BYTE_ORDER_INTEL;
+ } else if ((buf[datao + 4] == 'M') && (buf[datao + 5] == 'M')) {
+ n->version = pentaxV3;
+ n->order = EXIF_BYTE_ORDER_MOTOROLA;
+ } else {
+ /* Uses Casio v2 tags */
+ n->version = pentaxV2;
+ }
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataPentax",
+ "Parsing Pentax maker note v%d...", (int)n->version);
+ datao += 4 + 2;
+ base = MNOTE_PENTAX2_TAG_BASE;
+ } else if (!memcmp(buf + datao, "QVC", 4)) {
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataPentax",
+ "Parsing Casio maker note v2...");
+ n->version = casioV2;
+ base = MNOTE_CASIO2_TAG_BASE;
+ datao += 4 + 2;
+ } else {
+ /* probably assert(!memcmp(buf + datao, "\x00\x1b", 2)) */
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataPentax",
+ "Parsing Pentax maker note v1...");
+ n->version = pentaxV1;
+ }
+
+ /* Read the number of tags */
+ c = exif_get_short (buf + datao, n->order);
+ datao += 2;
+
+ /* Remove any old entries */
+ exif_mnote_data_pentax_clear (n);
+
+ /* Reserve enough space for all the possible MakerNote tags */
+ n->entries = exif_mem_alloc (en->mem, sizeof (MnotePentaxEntry) * c);
+ if (!n->entries) {
+ EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteDataPentax", sizeof (MnotePentaxEntry) * c);
+ return;
+ }
+
+ /* Parse all c entries, storing ones that are successfully parsed */
+ tcount = 0;
+ for (i = c, o = datao; i; --i, o += 12) {
+ size_t s;
+
+ memset(&n->entries[tcount], 0, sizeof(MnotePentaxEntry));
+ if (CHECKOVERFLOW(o,buf_size,12)) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteDataPentax", "Short MakerNote");
+ break;
+ }
+
+ n->entries[tcount].tag = exif_get_short (buf + o + 0, n->order) + base;
+ n->entries[tcount].format = exif_get_short (buf + o + 2, n->order);
+ n->entries[tcount].components = exif_get_long (buf + o + 4, n->order);
+ n->entries[tcount].order = n->order;
+
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnotePentax",
+ "Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
+ mnote_pentax_tag_get_name (n->entries[tcount].tag));
+
+ /* Check if we overflow the multiplication. Use buf_size as the max size for integer overflow detection,
+ * we will check the buffer sizes closer later. */
+ if ( exif_format_get_size (n->entries[tcount].format) &&
+ buf_size / exif_format_get_size (n->entries[tcount].format) < n->entries[tcount].components
+ ) {
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
+ "ExifMnoteDataPentax", "Tag size overflow detected (%u * %lu)", exif_format_get_size (n->entries[tcount].format), n->entries[tcount].components);
+ break;
+ }
+
+ /*
+ * Size? If bigger than 4 bytes, the actual data is not
+ * in the entry but somewhere else (offset).
+ */
+ s = exif_format_get_size (n->entries[tcount].format) *
+ n->entries[tcount].components;
+ n->entries[tcount].size = s;
+ if (s) {
+ size_t dataofs = o + 8;
+ if (s > 4)
+ /* The data in this case is merely a pointer */
+ dataofs = exif_get_long (buf + dataofs, n->order) + 6;
+ if (CHECKOVERFLOW(dataofs, buf_size, s)) {
+ exif_log (en->log, EXIF_LOG_CODE_DEBUG,
+ "ExifMnoteDataPentax", "Tag data past end "
+ "of buffer (%zu > %u)", dataofs + s, buf_size);
+ continue;
+ }
+
+ n->entries[tcount].data = exif_mem_alloc (en->mem, s);
+ if (!n->entries[tcount].data) {
+ EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteDataPentax", s);
+ continue;
+ }
+ memcpy (n->entries[tcount].data, buf + dataofs, s);
+ }
+
+ /* Tag was successfully parsed */
+ ++tcount;
+ }
+ /* Store the count of successfully parsed tags */
+ n->count = tcount;
+}
+
+static unsigned int
+exif_mnote_data_pentax_count (ExifMnoteData *n)
+{
+ return n ? ((ExifMnoteDataPentax *) n)->count : 0;
+}
+
+static unsigned int
+exif_mnote_data_pentax_get_id (ExifMnoteData *d, unsigned int n)
+{
+ ExifMnoteDataPentax *note = (ExifMnoteDataPentax *) d;
+
+ if (!note) return 0;
+ if (note->count <= n) return 0;
+ return note->entries[n].tag;
+}
+
+static const char *
+exif_mnote_data_pentax_get_name (ExifMnoteData *d, unsigned int n)
+{
+ ExifMnoteDataPentax *note = (ExifMnoteDataPentax *) d;
+
+ if (!note) return NULL;
+ if (note->count <= n) return NULL;
+ return mnote_pentax_tag_get_name (note->entries[n].tag);
+}
+
+static const char *
+exif_mnote_data_pentax_get_title (ExifMnoteData *d, unsigned int n)
+{
+ ExifMnoteDataPentax *note = (ExifMnoteDataPentax *) d;
+
+ if (!note) return NULL;
+ if (note->count <= n) return NULL;
+ return mnote_pentax_tag_get_title (note->entries[n].tag);
+}
+
+static const char *
+exif_mnote_data_pentax_get_description (ExifMnoteData *d, unsigned int n)
+{
+ ExifMnoteDataPentax *note = (ExifMnoteDataPentax *) d;
+
+ if (!note) return NULL;
+ if (note->count <= n) return NULL;
+ return mnote_pentax_tag_get_description (note->entries[n].tag);
+}
+
+static void
+exif_mnote_data_pentax_set_offset (ExifMnoteData *d, unsigned int o)
+{
+ if (d) ((ExifMnoteDataPentax *) d)->offset = o;
+}
+
+static void
+exif_mnote_data_pentax_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
+{
+ ExifByteOrder o_orig;
+ ExifMnoteDataPentax *n = (ExifMnoteDataPentax *) d;
+ unsigned int i;
+
+ if (!n) return;
+
+ o_orig = n->order;
+ n->order = o;
+ for (i = 0; i < n->count; i++) {
+ n->entries[i].order = o;
+ exif_array_set_byte_order (n->entries[i].format, n->entries[i].data,
+ n->entries[i].components, o_orig, o);
+ }
+}
+
+int
+exif_mnote_data_pentax_identify (const ExifData *ed, const ExifEntry *e)
+{
+ if ((e->size >= 8) && !memcmp (e->data, "AOC", 4)) {
+ if (((e->data[4] == 'I') && (e->data[5] == 'I')) ||
+ ((e->data[4] == 'M') && (e->data[5] == 'M')))
+ return pentaxV3;
+ else
+ /* Uses Casio v2 tags */
+ return pentaxV2;
+ }
+
+ if ((e->size >= 8) && !memcmp (e->data, "QVC", 4))
+ return casioV2;
+
+ /* This isn't a very robust test, so make sure it's done last */
+ /* Maybe we should additionally check for a make of Asahi or Pentax */
+ if ((e->size >= 2) && (e->data[0] == 0x00) && (e->data[1] == 0x1b))
+ return pentaxV1;
+
+ return 0;
+}
+
+ExifMnoteData *
+exif_mnote_data_pentax_new (ExifMem *mem)
+{
+ ExifMnoteData *d;
+
+ if (!mem) return NULL;
+
+ d = exif_mem_alloc (mem, sizeof (ExifMnoteDataPentax));
+ if (!d) return NULL;
+
+ memset(d, 0, sizeof(ExifMnoteDataPentax));
+
+ exif_mnote_data_construct (d, mem);
+
+ /* Set up function pointers */
+ d->methods.free = exif_mnote_data_pentax_free;
+ d->methods.set_byte_order = exif_mnote_data_pentax_set_byte_order;
+ d->methods.set_offset = exif_mnote_data_pentax_set_offset;
+ d->methods.load = exif_mnote_data_pentax_load;
+ d->methods.save = exif_mnote_data_pentax_save;
+ d->methods.count = exif_mnote_data_pentax_count;
+ d->methods.get_id = exif_mnote_data_pentax_get_id;
+ d->methods.get_name = exif_mnote_data_pentax_get_name;
+ d->methods.get_title = exif_mnote_data_pentax_get_title;
+ d->methods.get_description = exif_mnote_data_pentax_get_description;
+ d->methods.get_value = exif_mnote_data_pentax_get_value;
+
+ return d;
+}
diff --git a/libexif/pentax/exif-mnote-data-pentax.h b/libexif/pentax/exif-mnote-data-pentax.h
new file mode 100644
index 0000000..da9f79a
--- /dev/null
+++ b/libexif/pentax/exif-mnote-data-pentax.h
@@ -0,0 +1,59 @@
+/* exif-mnote-data-pentax.h
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EXIF_MNOTE_DATA_PENTAX_H__
+#define __EXIF_MNOTE_DATA_PENTAX_H__
+
+#include <libexif/exif-byte-order.h>
+#include <libexif/exif-mnote-data.h>
+#include <libexif/exif-mnote-data-priv.h>
+#include <libexif/pentax/mnote-pentax-entry.h>
+#include <libexif/exif-data.h>
+#include <libexif/exif-mem.h>
+
+enum PentaxVersion {pentaxV1 = 1, pentaxV2 = 2, pentaxV3 = 3, casioV2 = 4 };
+
+typedef struct _ExifMnoteDataPentax ExifMnoteDataPentax;
+
+struct _ExifMnoteDataPentax {
+ ExifMnoteData parent;
+
+ MnotePentaxEntry *entries;
+ unsigned int count;
+
+ ExifByteOrder order;
+ unsigned int offset;
+
+ enum PentaxVersion version;
+};
+
+/*! Detect if MakerNote is recognized as one handled by the Pentax module.
+ *
+ * \param[in] ed image #ExifData to identify as as a Pentax type
+ * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but
+ * duplicated here for convenience
+ * \return 0 if not recognized, nonzero if recognized. The specific nonzero
+ * value returned may identify a subtype unique within this module.
+ */
+int exif_mnote_data_pentax_identify (const ExifData *ed, const ExifEntry *e);
+
+ExifMnoteData *exif_mnote_data_pentax_new (ExifMem *);
+
+#endif /* __EXIF_MNOTE_DATA_PENTAX_H__ */
diff --git a/libexif/pentax/mnote-pentax-entry.c b/libexif/pentax/mnote-pentax-entry.c
new file mode 100644
index 0000000..dcb1560
--- /dev/null
+++ b/libexif/pentax/mnote-pentax-entry.c
@@ -0,0 +1,469 @@
+/* mnote-pentax-entry.c
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+#include "mnote-pentax-entry.h"
+
+#include <libexif/i18n.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libexif/exif-format.h>
+#include <libexif/exif-utils.h>
+#include <libexif/exif-entry.h>
+
+
+#define CF(format,target,v,maxlen) \
+{ \
+ if (format != target) { \
+ snprintf (v, maxlen, \
+ _("Invalid format '%s', " \
+ "expected '%s'."), \
+ exif_format_get_name (format), \
+ exif_format_get_name (target)); \
+ break; \
+ } \
+}
+
+#define CC(number,target,v,maxlen) \
+{ \
+ if (number != target) { \
+ snprintf (v, maxlen, \
+ _("Invalid number of components (%i, " \
+ "expected %i)."), (int) number, (int) target); \
+ break; \
+ } \
+}
+
+#define CC2(number,t1,t2,v,maxlen) \
+{ \
+ if ((number != t1) && (number != t2)) { \
+ snprintf (v, maxlen, \
+ _("Invalid number of components (%i, " \
+ "expected %i or %i)."), (int) number, \
+ (int) t1, (int) t2); \
+ break; \
+ } \
+}
+
+static const struct {
+ ExifTag tag;
+ struct {
+ int index;
+ const char *string;
+ } elem[33];
+} items[] = {
+#ifndef NO_VERBOSE_TAG_DATA
+ { MNOTE_PENTAX_TAG_MODE,
+ { {0, N_("Auto")},
+ {1, N_("Night scene")},
+ {2, N_("Manual")},
+ {4, N_("Multi-exposure")},
+ {0, NULL}}},
+ { MNOTE_PENTAX_TAG_QUALITY,
+ { {0, N_("Good")},
+ {1, N_("Better")},
+ {2, N_("Best")},{0,NULL}}},
+ { MNOTE_PENTAX_TAG_FOCUS,
+ { {2, N_("Custom")},
+ {3, N_("Auto")},
+ {0, NULL}}},
+ { MNOTE_PENTAX_TAG_FLASH,
+ { {1, N_("Auto")},
+ {2, N_("Flash on")},
+ {4, N_("Flash off")},
+ {6, N_("Red-eye reduction")},
+ {0, NULL}}},
+ { MNOTE_PENTAX_TAG_WHITE_BALANCE,
+ { {0, N_("Auto")},
+ {1, N_("Daylight")},
+ {2, N_("Shade")},
+ {3, N_("Tungsten")},
+ {4, N_("Fluorescent")},
+ {5, N_("Manual")},
+ {0, NULL}}},
+ { MNOTE_PENTAX_TAG_SHARPNESS,
+ { {0, N_("Normal")},
+ {1, N_("Soft")},
+ {2, N_("Hard")},
+ {0, NULL}}},
+ { MNOTE_PENTAX_TAG_CONTRAST,
+ { {0, N_("Normal")},
+ {1, N_("Low")},
+ {2, N_("High")},
+ {0, NULL}}},
+ { MNOTE_PENTAX_TAG_SATURATION,
+ { {0, N_("Normal")},
+ {1, N_("Low")},
+ {2, N_("High")},
+ {0, NULL}}},
+ { MNOTE_PENTAX_TAG_ISO_SPEED,
+ { {10, N_("100")},
+ {16, N_("200")},
+ {100, N_("100")},
+ {200, N_("200")},
+ { 0, NULL}}},
+ { MNOTE_PENTAX_TAG_COLOR,
+ { {1, N_("Full")},
+ {2, N_("Black & white")},
+ {3, N_("Sepia")},
+ {0, NULL}}},
+ { MNOTE_PENTAX2_TAG_MODE,
+ { {0, N_("Auto")},
+ {1, N_("Night scene")},
+ {2, N_("Manual")},
+ {4, N_("Multi-exposure")},
+ {0, NULL}}},
+ { MNOTE_PENTAX2_TAG_QUALITY,
+ { {0, N_("Good")},
+ {1, N_("Better")},
+ {2, N_("Best")},
+ {3, N_("TIFF")},
+ {4, N_("RAW")},
+ {0, NULL}}},
+ { MNOTE_PENTAX2_TAG_IMAGE_SIZE,
+ { {0, "640x480"},
+ {1, N_("Full")},
+ {2, "1024x768"},
+ {3, "1280x960"},
+ {4, "1600x1200"},
+ {5, "2048x1536"},
+ {8, N_("2560x1920 or 2304x1728")},
+ {9, "3072x2304"},
+ {10, "3264x2448"},
+ {19, "320x240"},
+ {20, "2288x1712"},
+ {21, "2592x1944"},
+ {22, N_("2304x1728 or 2592x1944")},
+ {23, "3056x2296"},
+ {25, N_("2816x2212 or 2816x2112")},
+ {27, "3648x2736"},
+ {36, "3008x2008"},
+ {0, NULL}}},
+ { MNOTE_PENTAX2_TAG_PICTURE_MODE,
+ { {0, N_("Program")},
+ {2, N_("Program AE")},
+ {3, N_("Manual")},
+ {5, N_("Portrait")},
+ {6, N_("Landscape")},
+ {8, N_("Sport")},
+ {9, N_("Night scene")},
+ {11, N_("Soft")},
+ {12, N_("Surf & snow")},
+ {13, N_("Sunset or candlelight")},
+ {14, N_("Autumn")},
+ {15, N_("Macro")},
+ {17, N_("Fireworks")},
+ {18, N_("Text")},
+ {19, N_("Panorama")},
+ {30, N_("Self portrait")},
+ {31, N_("Illustrations")},
+ {33, N_("Digital filter")},
+ {37, N_("Museum")},
+ {38, N_("Food")},
+ {40, N_("Green mode")},
+ {49, N_("Light pet")},
+ {50, N_("Dark pet")},
+ {51, N_("Medium pet")},
+ {53, N_("Underwater")},
+ {54, N_("Candlelight")},
+ {55, N_("Natural skin tone")},
+ {56, N_("Synchro sound record")},
+ {58, N_("Frame composite")},
+ {0, NULL}}},
+ { MNOTE_PENTAX2_TAG_FLASH_MODE,
+ { {0x0000, N_("Auto, did not fire")},
+ {0x0001, N_("Off")},
+ {0x0003, N_("Auto, did not fire, red-eye reduction")},
+ {0x0100, N_("Auto, fired")},
+ {0x0102, N_("On")},
+ {0x0103, N_("Auto, fired, red-eye reduction")},
+ {0x0104, N_("On, red-eye reduction")},
+ {0x0105, N_("On, wireless")},
+ {0x0108, N_("On, soft")},
+ {0x0109, N_("On, slow-sync")},
+ {0x010a, N_("On, slow-sync, red-eye reduction")},
+ {0x010b, N_("On, trailing-curtain sync")},
+ {0, NULL}}},
+ { MNOTE_PENTAX2_TAG_FOCUS_MODE,
+ { {0, N_("Normal")},
+ {1, N_("Macro")},
+ {2, N_("Infinity")},
+ {3, N_("Manual")},
+ {5, N_("Pan focus")},
+ {16, N_("AF-S")},
+ {17, N_("AF-C")},
+ {0, NULL}}},
+ { MNOTE_PENTAX2_TAG_AFPOINT_SELECTED,
+ { {1, N_("Upper-left")},
+ {2, N_("Top")},
+ {3, N_("Upper-right")},
+ {4, N_("Left")},
+ {5, N_("Mid-left")},
+ {6, N_("Center")},
+ {7, N_("Mid-right")},
+ {8, N_("Right")},
+ {9, N_("Lower-left")},
+ {10, N_("Bottom")},
+ {11, N_("Lower-right")},
+ {0xfffe, N_("Fixed center")},
+ {0xffff, N_("Auto")},
+ {0, NULL}}},
+ { MNOTE_PENTAX2_TAG_AUTO_AFPOINT,
+ { {0, N_("Multiple")},
+ {1, N_("Top-left")},
+ {2, N_("Top-center")},
+ {3, N_("Top-right")},
+ {4, N_("Left")},
+ {5, N_("Center")},
+ {6, N_("Right")},
+ {7, N_("Bottom-left")},
+ {8, N_("Bottom-center")},
+ {9, N_("Bottom-right")},
+ {0xffff, N_("None")},
+ {0, NULL}}},
+ { MNOTE_PENTAX2_TAG_WHITE_BALANCE,
+ { {0, N_("Auto")},
+ {1, N_("Daylight")},
+ {2, N_("Shade")},
+ {3, N_("Fluorescent")},
+ {4, N_("Tungsten")},
+ {5, N_("Manual")},
+ {6, N_("Daylight fluorescent")},
+ {7, N_("Day white fluorescent")},
+ {8, N_("White fluorescent")},
+ {9, N_("Flash")},
+ {10, N_("Cloudy")},
+ {0xfffe, N_("Unknown")},
+ {0xffff, N_("User selected")},
+ {0, NULL}}},
+ {MNOTE_CASIO2_TAG_BESTSHOT_MODE,
+ { {0, N_("Off")},
+ {1, N_("On")},
+ {0, NULL}}},
+#endif
+ {0, {{0, NULL}}}
+};
+
+/* Two-component values */
+static const struct {
+ ExifTag tag;
+ struct {
+ int index1, index2;
+ const char *string;
+ } elem[39];
+} items2[] = {
+#ifndef NO_VERBOSE_TAG_DATA
+ { MNOTE_PENTAX2_TAG_IMAGE_SIZE,
+ { {0, 0, "2304x1728"},
+ {4, 0, "1600x1200"},
+ {5, 0, "2048x1536"},
+ {8, 0, "2560x1920"},
+ {34, 0, "1536x1024"},
+ {36, 0, N_("3008x2008 or 3040x2024")},
+ {37, 0, "3008x2000"},
+ {35, 1, "2400x1600"},
+ {32, 2, "960x480"},
+ {33, 2, "1152x768"},
+ {34, 2, "1536x1024"},
+ {0, 0, NULL}}},
+ { MNOTE_PENTAX2_TAG_PICTURE_MODE,
+ { {0, 0, N_("Auto")},
+ {5, 0, N_("Portrait")},
+ {53, 0, N_("Underwater")},
+ {255, 0, N_("Digital filter?")},
+ {5, 1, N_("Portrait")},
+ {9, 1, N_("Night scene")},
+ {13, 1, N_("Candlelight")},
+ {15, 1, N_("Macro")},
+ {53, 1, N_("Underwater")},
+ {0, 2, N_("Program AE")},
+ {5, 2, N_("Portrait")},
+ {6, 2, N_("Landscape")},
+ {0, 0, NULL}}},
+#endif
+ {0, {{0, 0, NULL}}}
+};
+
+char *
+mnote_pentax_entry_get_value (MnotePentaxEntry *entry,
+ char *val, unsigned int maxlen)
+{
+ ExifLong vl;
+ ExifShort vs, vs2;
+ int i = 0, j = 0;
+
+ if (!entry) return (NULL);
+
+ memset (val, 0, maxlen);
+ maxlen--;
+
+ switch (entry->tag) {
+ case MNOTE_PENTAX_TAG_MODE:
+ case MNOTE_PENTAX_TAG_QUALITY:
+ case MNOTE_PENTAX_TAG_FOCUS:
+ case MNOTE_PENTAX_TAG_FLASH:
+ case MNOTE_PENTAX_TAG_WHITE_BALANCE:
+ case MNOTE_PENTAX_TAG_SHARPNESS:
+ case MNOTE_PENTAX_TAG_CONTRAST:
+ case MNOTE_PENTAX_TAG_SATURATION:
+ case MNOTE_PENTAX_TAG_ISO_SPEED:
+ case MNOTE_PENTAX_TAG_COLOR:
+ case MNOTE_PENTAX2_TAG_MODE:
+ case MNOTE_PENTAX2_TAG_QUALITY:
+ case MNOTE_PENTAX2_TAG_FLASH_MODE:
+ case MNOTE_PENTAX2_TAG_FOCUS_MODE:
+ case MNOTE_PENTAX2_TAG_AFPOINT_SELECTED:
+ case MNOTE_PENTAX2_TAG_AUTO_AFPOINT:
+ case MNOTE_PENTAX2_TAG_WHITE_BALANCE:
+ case MNOTE_PENTAX2_TAG_PICTURE_MODE:
+ case MNOTE_PENTAX2_TAG_IMAGE_SIZE:
+ case MNOTE_CASIO2_TAG_BESTSHOT_MODE:
+ CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
+ CC2 (entry->components, 1, 2, val, maxlen);
+ if (entry->components == 1) {
+ vs = exif_get_short (entry->data, entry->order);
+
+ /* search the tag */
+ for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++);
+ if (!items[i].tag) {
+ snprintf (val, maxlen,
+ _("Internal error (unknown value %i)"), vs);
+ break;
+ }
+
+ /* find the value */
+ for (j = 0; items[i].elem[j].string &&
+ (items[i].elem[j].index < vs); j++);
+ if (items[i].elem[j].index != vs) {
+ snprintf (val, maxlen,
+ _("Internal error (unknown value %i)"), vs);
+ break;
+ }
+ strncpy (val, _(items[i].elem[j].string), maxlen);
+ } else {
+ /* Two-component values */
+ CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
+ CC2 (entry->components, 1, 2, val, maxlen);
+ vs = exif_get_short (entry->data, entry->order);
+ vs2 = exif_get_short (entry->data+2, entry->order) << 16;
+
+ /* search the tag */
+ for (i = 0; (items2[i].tag && items2[i].tag != entry->tag); i++);
+ if (!items2[i].tag) {
+ snprintf (val, maxlen,
+ _("Internal error (unknown value %i %i)"), vs, vs2);
+ break;
+ }
+
+ /* find the value */
+ for (j = 0; items2[i].elem[j].string && ((items2[i].elem[j].index2 < vs2)
+ || ((items2[i].elem[j].index2 == vs2) && (items2[i].elem[j].index1 < vs))); j++);
+ if ((items2[i].elem[j].index1 != vs) || (items2[i].elem[j].index2 != vs2)) {
+ snprintf (val, maxlen,
+ _("Internal error (unknown value %i %i)"), vs, vs2);
+ break;
+ }
+ strncpy (val, _(items2[i].elem[j].string), maxlen);
+ }
+ break;
+
+ case MNOTE_PENTAX_TAG_ZOOM:
+ CF (entry->format, EXIF_FORMAT_LONG, val, maxlen);
+ CC (entry->components, 1, val, maxlen);
+ vl = exif_get_long (entry->data, entry->order);
+ snprintf (val, maxlen, "%li", (long int) vl);
+ break;
+ case MNOTE_PENTAX_TAG_PRINTIM:
+ CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
+ CC (entry->components, 124, val, maxlen);
+ snprintf (val, maxlen, _("%i bytes unknown data"),
+ entry->size);
+ break;
+ case MNOTE_PENTAX_TAG_TZ_CITY:
+ case MNOTE_PENTAX_TAG_TZ_DST:
+ CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
+ CC (entry->components, 4, val, maxlen);
+ strncpy (val, (char*)entry->data, MIN(maxlen, entry->size));
+ break;
+ case MNOTE_PENTAX2_TAG_DATE:
+ CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
+ CC (entry->components, 4, val, maxlen);
+ /* Note: format is UNDEFINED, not SHORT -> order is fixed: MOTOROLA */
+ vs = exif_get_short (entry->data, EXIF_BYTE_ORDER_MOTOROLA);
+ snprintf (val, maxlen, "%i:%02i:%02i", vs, entry->data[2], entry->data[3]);
+ break;
+ case MNOTE_PENTAX2_TAG_TIME:
+ CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
+ CC2 (entry->components, 3, 4, val, maxlen);
+ snprintf (val, maxlen, "%02i:%02i:%02i", entry->data[0], entry->data[1], entry->data[2]);
+ break;
+ default:
+ switch (entry->format) {
+ case EXIF_FORMAT_ASCII:
+ strncpy (val, (char *)entry->data, MIN(maxlen, entry->size));
+ break;
+ case EXIF_FORMAT_SHORT:
+ {
+ const unsigned char *data = entry->data;
+ size_t k, len = strlen(val), sizeleft;
+
+ sizeleft = entry->size;
+ for(k=0; k<entry->components; k++) {
+ if (sizeleft < 2)
+ break;
+ vs = exif_get_short (data, entry->order);
+ snprintf (val+len, maxlen-len, "%i ", vs);
+ len = strlen(val);
+ data += 2;
+ sizeleft -= 2;
+ }
+ }
+ break;
+ case EXIF_FORMAT_LONG:
+ {
+ const unsigned char *data = entry->data;
+ size_t k, len = strlen(val), sizeleft;
+
+ sizeleft = entry->size;
+ for(k=0; k<entry->components; k++) {
+ if (sizeleft < 4)
+ break;
+ vl = exif_get_long (data, entry->order);
+ snprintf (val+len, maxlen-len, "%li", (long int) vl);
+ len = strlen(val);
+ data += 4;
+ sizeleft -= 4;
+ }
+ }
+ break;
+ case EXIF_FORMAT_UNDEFINED:
+ default:
+ snprintf (val, maxlen, _("%i bytes unknown data"),
+ entry->size);
+ break;
+ }
+ break;
+ }
+
+ return val;
+}
diff --git a/libexif/pentax/mnote-pentax-entry.h b/libexif/pentax/mnote-pentax-entry.h
new file mode 100644
index 0000000..4547ec3
--- /dev/null
+++ b/libexif/pentax/mnote-pentax-entry.h
@@ -0,0 +1,43 @@
+/* mnote-pentax-entry.h
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MNOTE_PENTAX_ENTRY_H__
+#define __MNOTE_PENTAX_ENTRY_H__
+
+#include <libexif/exif-format.h>
+#include <libexif/exif-byte-order.h>
+#include <libexif/pentax/mnote-pentax-tag.h>
+
+typedef struct _MnotePentaxEntry MnotePentaxEntry;
+
+struct _MnotePentaxEntry {
+ MnotePentaxTag tag;
+ ExifFormat format;
+ unsigned long components;
+
+ unsigned char *data;
+ unsigned int size;
+
+ ExifByteOrder order;
+};
+
+char *mnote_pentax_entry_get_value (MnotePentaxEntry *entry, char *val, unsigned int maxlen);
+
+#endif /* __MNOTE_PENTAX_ENTRY_H__ */
diff --git a/libexif/pentax/mnote-pentax-tag.c b/libexif/pentax/mnote-pentax-tag.c
new file mode 100644
index 0000000..740f135
--- /dev/null
+++ b/libexif/pentax/mnote-pentax-tag.c
@@ -0,0 +1,175 @@
+/* mnote-pentax-tag.c:
+ *
+ * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+#include "mnote-pentax-tag.h"
+
+#include <stdlib.h>
+
+#include <libexif/i18n.h>
+
+static const struct {
+ MnotePentaxTag tag;
+ const char *name;
+ const char *title;
+ const char *description;
+} table[] = {
+#ifndef NO_VERBOSE_TAG_STRINGS
+ {MNOTE_PENTAX_TAG_MODE, "Mode", N_("Capture Mode"), ""},
+ {MNOTE_PENTAX_TAG_QUALITY, "Quality", N_("Quality Level"), ""},
+ {MNOTE_PENTAX_TAG_FOCUS, "Focus", N_("Focus Mode"), ""},
+ {MNOTE_PENTAX_TAG_FLASH, "Flash", N_("Flash Mode"), ""},
+ {MNOTE_PENTAX_TAG_UNKNOWN_05, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_UNKNOWN_06, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_WHITE_BALANCE, "WhiteBalance", N_("White Balance"), ""},
+ {MNOTE_PENTAX_TAG_UNKNOWN_08, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_UNKNOWN_09, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_ZOOM, "Zoom", N_("Zoom"), NULL},
+ {MNOTE_PENTAX_TAG_SHARPNESS, "Sharpness", N_("Sharpness"), ""},
+ {MNOTE_PENTAX_TAG_CONTRAST, "Contrast", N_("Contrast"), ""},
+ {MNOTE_PENTAX_TAG_SATURATION, "Saturation", N_("Saturation"), ""},
+ {MNOTE_PENTAX_TAG_UNKNOWN_14, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_UNKNOWN_15, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_UNKNOWN_16, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_UNKNOWN_17, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_UNKNOWN_18, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_UNKNOWN_19, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_ISO_SPEED, "ISOSpeed", N_("ISO Speed"), ""},
+ {MNOTE_PENTAX_TAG_UNKNOWN_21, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_COLOR, "Color", N_("Colors"), ""},
+ {MNOTE_PENTAX_TAG_UNKNOWN_24, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_UNKNOWN_25, NULL, NULL, NULL},
+ {MNOTE_PENTAX_TAG_PRINTIM, "PrintIM", N_("PrintIM Settings"), ""},
+ {MNOTE_PENTAX_TAG_TZ_CITY, "TimeZone", N_("Time Zone"), ""},
+ {MNOTE_PENTAX_TAG_TZ_DST, "DaylightSavings", N_("Daylight Savings"), ""},
+
+ {MNOTE_PENTAX2_TAG_MODE, "Mode", N_("Capture Mode"), ""},
+ {MNOTE_PENTAX2_TAG_PREVIEW_SIZE, "PentaxPreviewSize", N_("Preview Size"), ""},
+ {MNOTE_PENTAX2_TAG_PREVIEW_LENGTH, "PentaxPreviewLength", N_("Preview Length"), ""},
+ {MNOTE_PENTAX2_TAG_PREVIEW_START, "PentaxPreviewStart", N_("Preview Start"), ""},
+ {MNOTE_PENTAX2_TAG_MODEL_ID, "ModelID", N_("Model Identification"), ""},
+ {MNOTE_PENTAX2_TAG_DATE, "Date", N_("Date"), ""},
+ {MNOTE_PENTAX2_TAG_TIME, "Time", N_("Time"), ""},
+ {MNOTE_PENTAX2_TAG_QUALITY, "Quality", N_("Quality Level"), ""},
+ {MNOTE_PENTAX2_TAG_IMAGE_SIZE, "ImageSize", N_("Image Size"), ""},
+ {MNOTE_PENTAX2_TAG_PICTURE_MODE, "PictureMode", N_("Picture Mode"), ""},
+ {MNOTE_PENTAX2_TAG_FLASH_MODE, "FlashMode", N_("Flash Mode"), ""},
+ {MNOTE_PENTAX2_TAG_FOCUS_MODE, "FocusMode", N_("Focus Mode"), ""},
+ {MNOTE_PENTAX2_TAG_AFPOINT_SELECTED, "AFPointSelected", N_("AF Point Selected"), ""},
+ {MNOTE_PENTAX2_TAG_AUTO_AFPOINT, "AutoAFPoint", N_("Auto AF Point"), ""},
+ {MNOTE_PENTAX2_TAG_FOCUS_POSITION, "FocusPosition", N_("Focus Position"), ""},
+ {MNOTE_PENTAX2_TAG_EXPOSURE_TIME, "ExposureTime", N_("Exposure Time"), ""},
+ {MNOTE_PENTAX2_TAG_FNUMBER, "FNumber", N_("F-Number"), ""},
+ {MNOTE_PENTAX2_TAG_ISO, "ISO", N_("ISO Number"), ""},
+ {MNOTE_PENTAX2_TAG_EXPOSURE_COMPENSATION, "ExposureCompensation", N_("Exposure Compensation"), ""},
+ {MNOTE_PENTAX2_TAG_METERING_MODE, "MeteringMode", N_("Metering Mode"), ""},
+ {MNOTE_PENTAX2_TAG_AUTO_BRACKETING, "AutoBracketing", N_("Auto Bracketing"), ""},
+ {MNOTE_PENTAX2_TAG_WHITE_BALANCE, "WhiteBalance", N_("White Balance"), ""},
+ {MNOTE_PENTAX2_TAG_WHITE_BALANCE_MODE, "WhiteBalanceMode", N_("White Balance Mode"), ""},
+ {MNOTE_PENTAX2_TAG_BLUE_BALANCE, "BlueBalance", N_("Blue Balance"), ""},
+ {MNOTE_PENTAX2_TAG_RED_BALANCE, "RedBalance", N_("Red Balance"), ""},
+ {MNOTE_PENTAX2_TAG_FOCAL_LENGTH, "FocalLength", N_("Focal Length"), ""},
+ {MNOTE_PENTAX2_TAG_DIGITAL_ZOOM, "DigitalZoom", N_("Digital Zoom"), ""},
+ {MNOTE_PENTAX2_TAG_SATURATION, "Saturation", N_("Saturation"), ""},
+ {MNOTE_PENTAX2_TAG_CONTRAST, "Contrast", N_("Contrast"), ""},
+ {MNOTE_PENTAX2_TAG_SHARPNESS, "Sharpness", N_("Sharpness"), ""},
+ {MNOTE_PENTAX2_TAG_WORLDTIME_LOCATION, "WorldTimeLocation", N_("World Time Location"), ""},
+ {MNOTE_PENTAX2_TAG_HOMETOWN_CITY, "HometownCity", N_("Hometown City"), ""},
+ {MNOTE_PENTAX2_TAG_DESTINATION_CITY, "DestinationCity", N_("Destination City"), ""},
+ {MNOTE_PENTAX2_TAG_HOMETOWN_DST, "HometownDST,", N_("Hometown DST"), N_("Home Daylight Savings Time")},
+ {MNOTE_PENTAX2_TAG_DESTINATION_DST, "DestinationDST", N_("Destination DST"), N_("Destination Daylight Savings Time")},
+ {MNOTE_PENTAX2_TAG_FRAME_NUMBER, "FrameNumber", N_("Frame Number"), ""},
+ {MNOTE_PENTAX2_TAG_IMAGE_PROCESSING, "ImageProcessing", N_("Image Processing"), ""},
+ {MNOTE_PENTAX2_TAG_PICTURE_MODE2, "PictureMode2", N_("Picture Mode (2)"), ""},
+ {MNOTE_PENTAX2_TAG_DRIVE_MODE, "DriveMode", N_("Drive Mode"), ""},
+ {MNOTE_PENTAX2_TAG_COLOR_SPACE, "ColorSpace", N_("Color Space"), ""},
+ {MNOTE_PENTAX2_TAG_IMAGE_AREA_OFFSET, "ImageAreaOffset", N_("Image Area Offset"), ""},
+ {MNOTE_PENTAX2_TAG_RAW_IMAGE_SIZE, "RawImageSize", N_("Raw Image Size"), ""},
+ {MNOTE_PENTAX2_TAG_AFPOINTS_USED, "AfPointsUsed,", N_("Autofocus Points Used"), ""},
+ {MNOTE_PENTAX2_TAG_LENS_TYPE, "LensType", N_("Lens Type"), ""},
+ {MNOTE_PENTAX2_TAG_CAMERA_TEMPERATURE, "CameraTemperature", N_("Camera Temperature"), ""},
+ {MNOTE_PENTAX2_TAG_NOISE_REDUCTION, "NoiseReduction", N_("Noise Reduction"), ""},
+ {MNOTE_PENTAX2_TAG_FLASH_EXPOSURE_COMP, "FlashExposureComp", N_("Flash Exposure Compensation"), ""},
+ {MNOTE_PENTAX2_TAG_IMAGE_TONE, "ImageTone", N_("Image Tone"), ""},
+ {MNOTE_PENTAX2_TAG_SHAKE_REDUCTION_INFO, "ShakeReductionInfo,", N_("Shake Reduction Info"), ""},
+ {MNOTE_PENTAX2_TAG_BLACK_POINT, "BlackPoint", N_("Black Point"), ""},
+ {MNOTE_PENTAX2_TAG_WHITE_POINT, "WhitePoint", N_("White Point"), ""},
+ {MNOTE_PENTAX2_TAG_AE_INFO, "AEInfo", N_("AE Info"), ""},
+ {MNOTE_PENTAX2_TAG_LENS_INFO, "LensInfo", N_("Lens Info"), ""},
+ {MNOTE_PENTAX2_TAG_FLASH_INFO, "FlashInfo", N_("Flash Info"), ""},
+ {MNOTE_PENTAX2_TAG_CAMERA_INFO, "CameraInfo", N_("Camera Info"), ""},
+ {MNOTE_PENTAX2_TAG_BATTERY_INFO, "BatteryInfo", N_("Battery Info"), ""},
+ {MNOTE_PENTAX2_TAG_HOMETOWN_CITY_CODE, "HometownCityCode", N_("Hometown City Code"), ""},
+ {MNOTE_PENTAX2_TAG_DESTINATION_CITY_CODE, "DestinationCityCode", N_("Destination City Code"), ""},
+
+ {MNOTE_CASIO2_TAG_PREVIEW_START, "CasioPreviewStart", N_("Preview Start"), ""},
+ {MNOTE_CASIO2_TAG_WHITE_BALANCE_BIAS, "WhiteBalanceBias", N_("White Balance Bias"), ""},
+ {MNOTE_CASIO2_TAG_WHITE_BALANCE, "WhiteBalance", N_("White Balance"), ""},
+ {MNOTE_CASIO2_TAG_OBJECT_DISTANCE, "ObjectDistance", N_("Object Distance"), N_("Distance of photographed object in millimeters.")},
+ {MNOTE_CASIO2_TAG_FLASH_DISTANCE, "FlashDistance", N_("Flash Distance"), ""},
+ {MNOTE_CASIO2_TAG_RECORD_MODE, "RecordMode", N_("Record Mode"), ""},
+ {MNOTE_CASIO2_TAG_SELF_TIMER, "SelfTimer", N_("Self-timer"), ""},
+ {MNOTE_CASIO2_TAG_QUALITY, "CasioQuality", N_("Quality Level"), ""},
+ {MNOTE_CASIO2_TAG_FOCUS_MODE, "CasioFocusMode", N_("Focus Mode"), ""},
+ {MNOTE_CASIO2_TAG_TIME_ZONE, "TimeZone", N_("Time Zone"), ""},
+ {MNOTE_CASIO2_TAG_BESTSHOT_MODE, "BestshotMode", N_("Bestshot Mode"), ""},
+ {MNOTE_CASIO2_TAG_CCS_ISO_SENSITIVITY, "CCSISOSensitivity", N_("CCS ISO Sensitivity"), ""},
+ {MNOTE_CASIO2_TAG_COLOR_MODE, "ColorMode", N_("Color Mode"), ""},
+ {MNOTE_CASIO2_TAG_ENHANCEMENT, "Enhancement", N_("Enhancement"), ""},
+ {MNOTE_CASIO2_TAG_FINER, "Finer", N_("Finer"), ""},
+#endif
+ {0, NULL, NULL, NULL}
+};
+
+const char *
+mnote_pentax_tag_get_name (MnotePentaxTag t)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ if (table[i].tag == t) return (table[i].name);
+ return NULL;
+}
+
+const char *
+mnote_pentax_tag_get_title (MnotePentaxTag t)
+{
+ unsigned int i;
+
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ if (table[i].tag == t) return (_(table[i].title));
+ return NULL;
+}
+
+const char *
+mnote_pentax_tag_get_description (MnotePentaxTag t)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
+ if (table[i].tag == t) {
+ if (!table[i].description || !*table[i].description)
+ return "";
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ return _(table[i].description);
+ }
+ return NULL;
+}
diff --git a/libexif/pentax/mnote-pentax-tag.h b/libexif/pentax/mnote-pentax-tag.h
new file mode 100644
index 0000000..51b2aec
--- /dev/null
+++ b/libexif/pentax/mnote-pentax-tag.h
@@ -0,0 +1,153 @@
+/* mnote-pentax-tag.h
+ *
+ * Copyright (c) 2002, 2003 Lutz Mueller <lutz@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MNOTE_PENTAX_TAG_H__
+#define __MNOTE_PENTAX_TAG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * Missing features which are probably in the unknowns somewhere ...
+ * 1/ AF Area (Wide, Spot, Free)
+ * 2/ AE Metering (Multi segment, Centre-weighted, Spot)
+ * 3/
+ */
+
+enum _MnotePentaxTag {
+ MNOTE_PENTAX_TAG_MODE = 0x0001,
+ MNOTE_PENTAX_TAG_QUALITY = 0x0002,
+ MNOTE_PENTAX_TAG_FOCUS = 0x0003,
+ MNOTE_PENTAX_TAG_FLASH = 0x0004,
+ MNOTE_PENTAX_TAG_UNKNOWN_05 = 0x0005,
+ MNOTE_PENTAX_TAG_UNKNOWN_06 = 0x0006,
+ MNOTE_PENTAX_TAG_WHITE_BALANCE = 0x0007,
+ MNOTE_PENTAX_TAG_UNKNOWN_08 = 0x0008,
+ MNOTE_PENTAX_TAG_UNKNOWN_09 = 0x0009,
+ MNOTE_PENTAX_TAG_ZOOM = 0x000a,
+ MNOTE_PENTAX_TAG_SHARPNESS = 0x000b,
+ MNOTE_PENTAX_TAG_CONTRAST = 0x000c,
+ MNOTE_PENTAX_TAG_SATURATION = 0x000d,
+ MNOTE_PENTAX_TAG_UNKNOWN_14 = 0x000e,
+ MNOTE_PENTAX_TAG_UNKNOWN_15 = 0x000f,
+ MNOTE_PENTAX_TAG_UNKNOWN_16 = 0x0010,
+ MNOTE_PENTAX_TAG_UNKNOWN_17 = 0x0011,
+ MNOTE_PENTAX_TAG_UNKNOWN_18 = 0x0012,
+ MNOTE_PENTAX_TAG_UNKNOWN_19 = 0x0013,
+ MNOTE_PENTAX_TAG_ISO_SPEED = 0x0014,
+ MNOTE_PENTAX_TAG_UNKNOWN_21 = 0x0015,
+ MNOTE_PENTAX_TAG_COLOR = 0x0017,
+ MNOTE_PENTAX_TAG_UNKNOWN_24 = 0x0018,
+ MNOTE_PENTAX_TAG_UNKNOWN_25 = 0x0019,
+ MNOTE_PENTAX_TAG_PRINTIM = 0x0e00,
+ MNOTE_PENTAX_TAG_TZ_CITY = 0x1000,
+ MNOTE_PENTAX_TAG_TZ_DST = 0x1001,
+
+ /* Pentax v2, v3: real values + our proprietary base to distinguish from v1 */
+ MNOTE_PENTAX2_TAG_BASE = 0x4000,
+ MNOTE_PENTAX2_TAG_MODE = 0x0001 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_PREVIEW_SIZE = 0x0002 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_PREVIEW_LENGTH = 0x0003 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_PREVIEW_START = 0x0004 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_MODEL_ID = 0x0005 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_DATE = 0x0006 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_TIME = 0x0007 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_QUALITY = 0x0008 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_IMAGE_SIZE = 0x0009 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_PICTURE_MODE = 0x000b + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_FLASH_MODE = 0x000c + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_FOCUS_MODE = 0x000d + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_AFPOINT_SELECTED = 0x000e + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_AUTO_AFPOINT = 0x000f + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_FOCUS_POSITION = 0x0010 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_EXPOSURE_TIME = 0x0012 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_FNUMBER = 0x0013 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_ISO = 0x0014 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_EXPOSURE_COMPENSATION = 0x0016 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_METERING_MODE = 0x0017 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_AUTO_BRACKETING = 0x0018 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_WHITE_BALANCE = 0x0019 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_WHITE_BALANCE_MODE= 0x001a + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_BLUE_BALANCE = 0x001b + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_RED_BALANCE = 0x001c + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_FOCAL_LENGTH = 0x001d + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_DIGITAL_ZOOM = 0x001e + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_SATURATION = 0x001f + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_CONTRAST = 0x0020 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_SHARPNESS = 0x0021 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_WORLDTIME_LOCATION = 0x0022 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_HOMETOWN_CITY = 0x0023 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_DESTINATION_CITY = 0x0024 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_HOMETOWN_DST = 0x0025 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_DESTINATION_DST = 0x0026 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_FRAME_NUMBER = 0x0029 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_IMAGE_PROCESSING = 0x0032 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_PICTURE_MODE2 = 0x0033 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_DRIVE_MODE = 0x0034 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_COLOR_SPACE = 0x0037 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_IMAGE_AREA_OFFSET = 0x0038 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_RAW_IMAGE_SIZE = 0x0039 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_AFPOINTS_USED = 0x003c + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_LENS_TYPE = 0x003f + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_CAMERA_TEMPERATURE = 0x0047 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_NOISE_REDUCTION = 0x0049 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_FLASH_EXPOSURE_COMP = 0x004d + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_IMAGE_TONE = 0x004f + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_SHAKE_REDUCTION_INFO = 0x005c + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_BLACK_POINT = 0x0200 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_WHITE_POINT = 0x0201 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_AE_INFO = 0x0206 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_LENS_INFO = 0x0207 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_FLASH_INFO = 0x0208 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_CAMERA_INFO = 0x0215 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_BATTERY_INFO = 0x0216 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_HOMETOWN_CITY_CODE = 0x1000 + MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_PENTAX2_TAG_DESTINATION_CITY_CODE = 0x1001 + MNOTE_PENTAX2_TAG_BASE,
+
+ /* Casio v2: some Casio v2 tags match Pentax v2 tags */
+ MNOTE_CASIO2_TAG_BASE = MNOTE_PENTAX2_TAG_BASE,
+ MNOTE_CASIO2_TAG_PREVIEW_START = 0x2000 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_WHITE_BALANCE_BIAS = 0x2011 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_WHITE_BALANCE = 0x2012 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_OBJECT_DISTANCE = 0x2022 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_FLASH_DISTANCE = 0x2034 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_RECORD_MODE = 0x3000 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_SELF_TIMER = 0x3001 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_QUALITY = 0x3002 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_FOCUS_MODE = 0x3003 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_TIME_ZONE = 0x3006 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_BESTSHOT_MODE = 0x3007 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_CCS_ISO_SENSITIVITY = 0x3014 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_COLOR_MODE = 0x3015 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_ENHANCEMENT = 0x3016 + MNOTE_CASIO2_TAG_BASE,
+ MNOTE_CASIO2_TAG_FINER = 0x3017 + MNOTE_CASIO2_TAG_BASE
+};
+typedef enum _MnotePentaxTag MnotePentaxTag;
+
+const char *mnote_pentax_tag_get_name (MnotePentaxTag tag);
+const char *mnote_pentax_tag_get_title (MnotePentaxTag tag);
+const char *mnote_pentax_tag_get_description (MnotePentaxTag tag);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MNOTE_PENTAX_TAG_H__ */
diff --git a/libexif_blocklist.txt b/libexif_blacklist.txt
index 2c838a7..2c838a7 100644
--- a/libexif_blocklist.txt
+++ b/libexif_blacklist.txt