+2010-10-07 Dan Fandrich <dan@coneharvesters.com>
+
+ * Refactored MakerNote detection code to put detection of each type
+ into the module handling that type
+
+2010-09-23 Dan Fandrich <dan@coneharvesters.com>
+
+ * exif_entry_dump() now displays the correct tag name for GPS tags by
+ taking the IFD into account when looking up the name. Fixes
+ bug #3073307.
+
+2010-08-11 Dan Fandrich <dan@coneharvesters.com>
+
+ * Removed redundant sentence. Fixes Ubuntu bug #197306
+
+2010-07-23 Dan Fandrich <dan@coneharvesters.com>
+
+ * Canon EOS 5D Mark II writes Aperture values as invalid values
+ 0x80000000/1 which makes pow() throw floating-point exceptions
+
2010-06-16 Dan Fandrich <dan@coneharvesters.com>
* po/da.po: Updated Danish translation by Joe Hansen
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)
{
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__ */
EXIF_DATA_TYPE_MAKER_NOTE_FUJI = 6
} ExifDataTypeMakerNote;
-static ExifDataTypeMakerNote
-exif_data_get_type_maker_note (ExifData *d)
-{
- ExifEntry *e, *em;
- char value[1024];
-
- if (!d)
- return EXIF_DATA_TYPE_MAKER_NOTE_NONE;
-
- e = exif_data_get_entry (d, EXIF_TAG_MAKER_NOTE);
- if (!e)
- return EXIF_DATA_TYPE_MAKER_NOTE_NONE;
-
- /* Olympus & Nikon & Sanyo */
- if ((e->size >= 8) && ( !memcmp (e->data, "OLYMP", 6) ||
- !memcmp (e->data, "OLYMPUS", 8) ||
- !memcmp (e->data, "SANYO", 6) ||
- !memcmp (e->data, "EPSON", 6) ||
- !memcmp (e->data, "Nikon", 6)))
- return EXIF_DATA_TYPE_MAKER_NOTE_OLYMPUS;
-
- em = exif_data_get_entry (d, EXIF_TAG_MAKE);
- if (!em)
- return EXIF_DATA_TYPE_MAKER_NOTE_NONE;
-
- /* Canon */
- if (!strcmp (exif_entry_get_value (em, value, sizeof (value)), "Canon"))
- return EXIF_DATA_TYPE_MAKER_NOTE_CANON;
-
- /* Pentax & some variant of Nikon */
- if ((e->size >= 2) && (e->data[0] == 0x00) && (e->data[1] == 0x1b)) {
- if (!strncasecmp (
- exif_entry_get_value (em, value, sizeof(value)),
- "Nikon", 5))
- return EXIF_DATA_TYPE_MAKER_NOTE_NIKON;
- else
- return EXIF_DATA_TYPE_MAKER_NOTE_PENTAX;
- }
- if ((e->size >= 8) && !memcmp (e->data, "AOC", 4)) {
- return EXIF_DATA_TYPE_MAKER_NOTE_PENTAX;
- }
- if ((e->size >= 8) && !memcmp (e->data, "QVC", 4)) {
- return EXIF_DATA_TYPE_MAKER_NOTE_CASIO;
- }
- if ((e->size >= 12) && !memcmp (e->data, "FUJIFILM", 8)) {
- return EXIF_DATA_TYPE_MAKER_NOTE_FUJI;
- }
-
- return EXIF_DATA_TYPE_MAKER_NOTE_NONE;
-}
-
/*! If MakerNote is recognized, load it.
*
* \param[in,out] data #ExifData
static void
interpret_maker_note(ExifData *data, const unsigned char *d, unsigned int ds)
{
- switch (exif_data_get_type_maker_note (data)) {
- case EXIF_DATA_TYPE_MAKER_NOTE_OLYMPUS:
- case EXIF_DATA_TYPE_MAKER_NOTE_NIKON:
+ int mnoteid;
+ ExifEntry* e = exif_data_get_entry (data, EXIF_TAG_MAKER_NOTE);
+ if (!e)
+ return;
+
+ 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);
- break;
- case EXIF_DATA_TYPE_MAKER_NOTE_PENTAX:
- case EXIF_DATA_TYPE_MAKER_NOTE_CASIO:
- data->priv->md = exif_mnote_data_pentax_new (data->priv->mem);
- break;
- case EXIF_DATA_TYPE_MAKER_NOTE_CANON:
+
+ } 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);
- break;
- case EXIF_DATA_TYPE_MAKER_NOTE_FUJI:
+
+ } 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);
- break;
- default:
- break;
+
+ /* 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);
}
/*
/*! Return the tag ID given its unique textual name.
*
* \param[in] name tag name
- * \return tag ID
+ * \return tag ID, or 0 if tag not found
+ * \note The tag not found value cannot be distinguished from a legitimate
+ * tag number 0.
*/
ExifTag exif_tag_from_name (const char *name);
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)
{
#define __MNOTE_FUJI_CONTENT_H__
#include <libexif/exif-mnote-data.h>
-
-typedef struct _ExifMnoteDataFuji ExifMnoteDataFuji;
-
#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;
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__ */
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 */
+ /* Fall through to nikonV2 handler */
case nikonV2:
*buf_size += 8 + 2;
*buf_size += 4; /* Next IFD pointer */
if (n) ((ExifMnoteDataOlympus *) n)->offset = o;
}
+int
+exif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e)
+{
+ /* Olympus, Nikon, Sanyo, Epson */
+ if (e->size >= 8) {
+ /* Match the terminating NUL character, too */
+ if (!memcmp (e->data, "OLYMPUS", 8))
+ return olympusV2;
+ else if (!memcmp (e->data, "OLYMP", 6))
+ return olympusV1;
+ else if (!memcmp (e->data, "SANYO", 6))
+ return sanyoV1;
+ else if (!memcmp (e->data, "EPSON", 6))
+ return epsonV1;
+ else if (!memcmp (e->data, "Nikon", 6)) {
+ switch (e->data[6]) {
+ case 1: return nikonV1;
+ case 2: return nikonV2;
+ default: return 0; /* Unrecognized Nikon variant */
+ }
+ }
+ }
+
+ /* Another variant of Nikon */
+ if ((e->size >= 2) && (e->data[0] == 0x00) && (e->data[1] == 0x1b)) {
+ char value[5];
+ ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE);
+
+ 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
+ */
+ return nikonV2;
+ }
+ }
+
+ return 0;
+}
+
+
ExifMnoteData *
exif_mnote_data_olympus_new (ExifMem *mem)
{
#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 {
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__ */
}
}
+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)
{
#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 };
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__ */