2003-10-26 Lutz Mueller <lutz@users.sourceforge.net>
authorLutz Mueller <lutz.s.mueller@gmail.com>
Sun, 26 Oct 2003 22:30:27 +0000 (23:30 +0100)
committerLutz Mueller <lutz.s.mueller@gmail.com>
Sun, 26 Oct 2003 22:30:27 +0000 (23:30 +0100)
* test/test-mnote.c: New.
* libexif: The code now both compiles and doesn't crash,
  but at least the canon maker note still doesn't get parsed.

14 files changed:
ChangeLog
libexif/Makefile.am
libexif/canon/exif-mnote-data-canon.c
libexif/canon/exif-mnote-data-canon.h
libexif/exif-content.c
libexif/exif-data.c
libexif/exif-mnote-data-priv.h
libexif/exif-mnote-data.c
libexif/olympus/exif-mnote-data-olympus.c
libexif/olympus/exif-mnote-data-olympus.h
libexif/pentax/exif-mnote-data-pentax.c
libexif/pentax/exif-mnote-data-pentax.h
test/Makefile.am
test/test-mnote.c [new file with mode: 0644]

index 5a1747e..4938078 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2003-10-26  Lutz Mueller <lutz@users.sourceforge.net>
 
+       * test/test-mnote.c: New.
+       * libexif: The code now both compiles and doesn't crash,
+         but at least the canon maker note still doesn't get parsed.
+
+2003-10-26  Lutz Mueller <lutz@users.sourceforge.net>
+
        * configure.in
        * Makefile.am: Remove PO_DIRS. Otherwise, automake complains about
          po and intl not being in SUBDIRS
index 484953d..3851e1b 100644 (file)
@@ -23,9 +23,9 @@ libexif_la_SOURCES =          \
        exif-utils.c            \
        i18n.h
 libexif_la_LIBADD = -lm                \
-       canon/libmnote-canon.         \
-       olympus/libmnote-olympus.     \
-       pentax/libmnote-pentax.a
+       canon/libmnote-canon.la         \
+       olympus/libmnote-olympus.la     \
+       pentax/libmnote-pentax.la
 
 libexifincludedir = $(includedir)/libexif
 libexifinclude_HEADERS =       \
index 63e2e8a..a06e94b 100644 (file)
@@ -30,7 +30,7 @@
 #include <libexif/exif-utils.h>
 #include <libexif/exif-data.h>
 
-/* #define DEBUG */
+#define DEBUG
 
 static void
 exif_mnote_data_canon_free (ExifMnoteData *n)
@@ -63,6 +63,18 @@ exif_mnote_data_canon_get_value (ExifMnoteData *note, unsigned int n)
 }
 
 static void
+exif_mnote_data_canon_set_byte_order (ExifMnoteData *n, ExifByteOrder o)
+{
+       if (n) ((ExifMnoteDataCanon *) n)->order = 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_load_entry_with_exif (ExifMnoteDataCanon *note,
                                             MnoteCanonEntry *entry,
                                             const unsigned char *d,
@@ -108,53 +120,11 @@ exif_mnote_data_canon_load_entry_with_exif (ExifMnoteDataCanon *note,
 }
 
 static void
-exif_mnote_data_canon_load_entry (ExifMnoteDataCanon *note,
-                                   MnoteCanonEntry *entry,
-                                   const unsigned char *d,
-                                   unsigned int size, unsigned int offset)
-{
-        unsigned int s, doff;
-
-        entry->tag        = exif_get_short (d + offset + 0, note->order);
-        entry->format     = exif_get_short (d + offset + 2, note->order);
-        entry->components = exif_get_long  (d + offset + 4, note->order);
-
-        /*
-         * Size? If bigger than 4 bytes, the actual data is not
-         * in the entry but somewhere else (offset).
-         */
-        s = exif_format_get_size (entry->format) * entry->components;
-        if (!s)
-                return;
-        if (s > 4)
-                /* FIXME works on g3, but other should send exif data... */
-               doff = exif_get_long (d + offset + 8, note->order)-0x3B0 ;
-        else
-                doff = offset + 8;
-
-#ifdef DEBUG
-                printf ("Comp %x %d %d %x %x\n",doff, s,size,d[doff],d[doff+1]);
-#endif
-        /* Sanity check */
-        if (size < doff + s)
-                return;
-        entry->data = malloc (sizeof (char) * s);
-        if (!entry->data)
-                return;
-        entry->size = s;
-        memcpy (entry->data, d + doff, s);
-
-}
-
-static void
 exif_mnote_data_canon_load (ExifMnoteData *ne,
        const unsigned char *buf, unsigned int buf_size)
 {
        ExifMnoteDataCanon *data = (ExifMnoteDataCanon *) ne;
-
        const unsigned char *d = buf;
-       ExifData *ed = NULL;
-       ExifEntry *e = NULL;
        ExifShort n;
        unsigned int i;
        unsigned int size = buf_size;
@@ -165,25 +135,11 @@ exif_mnote_data_canon_load (ExifMnoteData *ne,
        if (!buf || !buf_size)
                return;
 
-       /* If we got EXIF data, go to the MakerNote tag. */
-       ed = exif_data_new_from_data (buf, size);
-       if (ed) {
-               e = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF],
-                                           EXIF_TAG_MAKER_NOTE);
-               if (e)
-               {
-                       d = e->data;
-                       size = e->size;
-#ifdef DEBUG
-                       printf ("Exif data\n");
-#endif
-               }
-       }
-
 #ifdef DEBUG
-       printf ("Parsing %i byte(s) Mnote data...\n", size);
+       printf ("Parsing %i byte(s) data at offset %i...\n", size,
+               data->offset);
 #endif
-#ifdef DEBUG
+#if 0
         int j;
         for (j=0;j<size;j++)
         {
@@ -195,37 +151,29 @@ exif_mnote_data_canon_load (ExifMnoteData *ne,
 #endif
 
        /* Read the number of entries */
-       n = exif_get_short (d ,data->order);
+       n = exif_get_short (buf + 6 + data->offset, data->order);
 #ifdef DEBUG
        printf ("Loading %i entries...\n", n);
 #endif
-       d+=2;
-       size-=2;
+       d += 2;
+       size -= 2;
 
-       if ( 12 * n > size )
-               return;
+       if (12 * n > size) return;
 
        for (i = 0; i < n; i++) {
 
                tag = exif_get_short (d + 12 * i, data->order);
 #ifdef DEBUG
                printf ("Loading entry '%s' (%i of %i)...\n",
-                       exif_mnote_data_canon_tag_get_name (tag), i + 1, n);
+                       mnote_canon_tag_get_name (tag), i + 1, n);
 #endif
                data->count++;
                data->entries = realloc (data->entries,
                                sizeof (MnoteCanonEntry) * data->count);
-               if (e) /* we have exif data */
-                       exif_mnote_data_canon_load_entry_with_exif (data,
+               exif_mnote_data_canon_load_entry_with_exif (data,
                                &data->entries[data->count - 1],
                                d, size, 12 * i, buf, buf_size);
-               else
-                       exif_mnote_data_canon_load_entry (data,
-                               &data->entries[data->count - 1],
-                               d, size, 12 * i);
        }
-       exif_data_unref (ed);
-
 }
 
 static unsigned int
@@ -264,19 +212,20 @@ exif_mnote_data_canon_get_description (ExifMnoteData *note, unsigned int i)
 }
 
 ExifMnoteData *
-exif_mnote_data_canon_new (ExifByteOrder order)
+exif_mnote_data_canon_new (void)
 {
        ExifMnoteData *d;
 
        d = malloc (sizeof (ExifMnoteDataCanon));
        if (!d) return NULL;
-
-       ((ExifMnoteDataCanon *) d)->order = order;
+       memset (d, 0, sizeof (ExifMnoteDataCanon));
 
        exif_mnote_data_construct (d);
 
        /* 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.count           = exif_mnote_data_canon_count;
        d->methods.get_name        = exif_mnote_data_canon_get_name;
index 03d1670..a8938de 100644 (file)
@@ -36,8 +36,9 @@ struct _ExifMnoteDataCanon {
        unsigned int count;
 
        ExifByteOrder order;
+       unsigned int offset;
 };
 
-ExifMnoteData *exif_mnote_data_canon_new (ExifByteOrder);
+ExifMnoteData *exif_mnote_data_canon_new (void);
 
 #endif /* __EXIF_MNOTE_DATA_CANON_H__ */
index 2cfcde0..fbbbe49 100644 (file)
@@ -115,25 +115,23 @@ exif_content_add_entry (ExifContent *content, ExifEntry *entry)
 }
 
 void
-exif_content_remove_entry (ExifContent *content, ExifEntry *entry)
+exif_content_remove_entry (ExifContent *c, ExifEntry *e)
 {
        unsigned int i;
 
-       if (entry->parent != content)
-               return;
-
-       for (i = 0; i < content->count; i++)
-               if (content->entries[i] == entry)
-                       break;
-       if (i == content->count)
-               return;
+       if (!c || !e) return;
+       if (e->parent != c) return;
 
-       memmove (&content->entries[i], &content->entries[i + 1],
-                sizeof (ExifEntry) * (content->count - i - 1));
-       content->count--;
+       /* Search the entry */
+       for (i = 0; i < c->count; i++) if (c->entries[i] == e) break;
+       if (i == c->count) return;
 
-       entry->parent = NULL;
-       exif_entry_unref (entry);
+       /* Remove the entry */
+       memmove (&c->entries[i], &c->entries[i + 1],
+                sizeof (ExifEntry) * (c->count - i - 1));
+       c->count--;
+       e->parent = NULL;
+       exif_entry_unref (e);
 }
 
 ExifEntry *
index 809d83f..1bb9e87 100644 (file)
@@ -50,8 +50,17 @@ struct _ExifDataPrivate
        ExifMnoteData *md;
 
        unsigned int ref_count;
+
+       /* Temporarily used while loading data */
+       unsigned int offset_mnote;
 };
 
+ExifMnoteData *
+exif_data_get_mnote_data (ExifData *d)
+{
+       return (d && d->priv) ? d->priv->md : NULL;
+}
+
 ExifData *
 exif_data_new (void)
 {
@@ -124,6 +133,10 @@ exif_data_load_data_entry (ExifData *data, ExifEntry *entry,
                return;
        entry->size = s;
        memcpy (entry->data, d + doff, s);
+
+       /* If this is the MakerNote, remember the offset */
+       if (entry->tag == EXIF_TAG_MAKER_NOTE)
+               data->priv->offset_mnote = doff;
 }
 
 static void
@@ -484,22 +497,22 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
        ExifShort n;
        ExifEntry *e, *em;
        const unsigned char *d = d_orig;
-       unsigned int size = ds_orig, len;
+       unsigned int ds = ds_orig, len;
 
        if (!data)
                return;
-       if (!d || !size)
+       if (!d || !ds)
                return;
 
 #ifdef DEBUG
-       printf ("Parsing %i byte(s) EXIF data...\n", size);
+       printf ("Parsing %i byte(s) EXIF data...\n", ds);
 #endif
 
        /*
         * It can be that the data starts with the EXIF header. If it does
         * not, search the EXIF marker.
         */
-       if (size < 6) {
+       if (ds < 6) {
 #ifdef DEBUG
                printf ("Size too small.\n");
 #endif
@@ -515,27 +528,27 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
                        "0x%x...\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6]);
 #endif
                while (1) {
-                       while ((d[0] == 0xff) && size) {
+                       while ((d[0] == 0xff) && ds) {
                                d++;
-                               size--;
+                               ds--;
                        }
 
                        /* JPEG_MARKER_SOI */
                        if (d[0] == JPEG_MARKER_SOI) {
                                d++;
-                               size--;
+                               ds--;
                                continue;
                        }
 
                        /* JPEG_MARKER_APP0 */
                        if (d[0] == JPEG_MARKER_APP0) {
                                d++;
-                               size--;
+                               ds--;
                                l = (d[0] << 8) | d[1];
-                               if (l > size)
+                               if (l > ds)
                                        return;
                                d += l;
-                               size -= l;
+                               ds -= l;
                                continue;
                        }
 
@@ -550,8 +563,8 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
                        return;
                }
                d++;
-               size--;
-               if (size < 2) {
+               ds--;
+               if (ds < 2) {
 #ifdef DEBUG
                        printf ("Size too small.\n");
 #endif
@@ -562,14 +575,14 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
                printf ("We have to deal with %i byte(s) of EXIF data.\n", len);
 #endif
                d += 2;
-               size -= 2;
+               ds -= 2;
        }
 
        /*
         * Verify the exif header
         * (offset 2, length 6).
         */
-       if (size < 6) {
+       if (ds < 6) {
 #ifdef DEBUG
                printf ("Size too small.\n");
 #endif
@@ -587,7 +600,7 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
 #endif
 
        /* Byte order (offset 6, length 2) */
-       if (size < 12)
+       if (ds < 12)
                return;
        if (!memcmp (d + 6, "II", 2))
                data->priv->order = EXIF_BYTE_ORDER_INTEL;
@@ -608,7 +621,7 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
 
        /* Parse the actual exif data (offset 14) */
        exif_data_load_data_content (data, data->ifd[EXIF_IFD_0], d + 6,
-                                    size - 6, offset);
+                                    ds - 6, offset);
 
        /* IFD 1 offset */
        n = exif_get_short (d + 6 + offset, data->priv->order);
@@ -619,7 +632,7 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
 #endif
 
                /* Sanity check. */
-               if (offset > size - 6) {
+               if (offset > ds - 6) {
 #ifdef DEBUG
                        printf ("Bogus offset!\n");
 #endif
@@ -627,7 +640,7 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
                }
 
                exif_data_load_data_content (data, data->ifd[EXIF_IFD_1], d + 6,
-                                            size - 6, offset);
+                                            ds - 6, offset);
        }
 
        /*
@@ -641,14 +654,12 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
 
            /* Olympus */
            if ((e->size >= 5) && (!memcmp (e->data, "OLYMP", 5)))
-               data->priv->md = exif_mnote_data_olympus_new (
-                                               data->priv->order);
+               data->priv->md = exif_mnote_data_olympus_new ();
 
            /* Pentax */
            else if ((e->size >= 2) && (e->data[0] == 0x00)
                                    && (e->data[1] == 0x1b))
-               data->priv->md = exif_mnote_data_pentax_new (
-                                               data->priv->order);
+               data->priv->md = exif_mnote_data_pentax_new ();
 
            else {
                em = exif_data_get_entry (data, EXIF_TAG_MAKE);
@@ -656,8 +667,7 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
 
                    /* Canon */
                    if (!strcmp (exif_entry_get_value (em), "Canon"))
-                       data->priv->md = exif_mnote_data_canon_new (
-                                                       data->priv->order);
+                       data->priv->md = exif_mnote_data_canon_new ();
                }
            }
 
@@ -667,7 +677,11 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
             * pointers after this function here returns.
             */
            if (data->priv->md) {
-               exif_mnote_data_load (data->priv->md, d_orig, ds_orig);
+               exif_mnote_data_set_byte_order (data->priv->md,
+                                               data->priv->order);
+               exif_mnote_data_set_offset (data->priv->md,
+                                           data->priv->offset_mnote);
+               exif_mnote_data_load (data->priv->md, d, ds);
                exif_data_remove_entry (data, EXIF_TAG_MAKER_NOTE);
            }
        }
index cc5379b..2cc6480 100644 (file)
@@ -26,6 +26,7 @@ extern "C" {
 #endif /* __cplusplus */
 
 #include <libexif/exif-mnote-data.h>
+#include <libexif/exif-byte-order.h>
 
 typedef struct _ExifMnoteDataMethods ExifMnoteDataMethods;
 struct _ExifMnoteDataMethods {
@@ -36,6 +37,8 @@ struct _ExifMnoteDataMethods {
        /* Modification */
        void (* save) (ExifMnoteData *, unsigned char **, unsigned int *);
        void (* load) (ExifMnoteData *, const unsigned char *, unsigned int);
+       void (* set_offset)     (ExifMnoteData *, unsigned int);
+       void (* set_byte_order) (ExifMnoteData *, ExifByteOrder);
 
        /* Query */
        unsigned int (* count)           (ExifMnoteData *);
@@ -54,7 +57,9 @@ struct _ExifMnoteData
        ExifMnoteDataPriv *priv;
 };
 
-void exif_mnote_data_construct (ExifMnoteData *);
+void exif_mnote_data_construct      (ExifMnoteData *);
+void exif_mnote_data_set_byte_order (ExifMnoteData *, ExifByteOrder);
+void exif_mnote_data_set_offset     (ExifMnoteData *, unsigned int);
 
 #ifdef __cplusplus
 }
index fe8cba1..cd69a63 100644 (file)
@@ -86,6 +86,20 @@ exif_mnote_data_save (ExifMnoteData *d, unsigned char **buf,
        d->methods.save (d, buf, buf_size);
 }
 
+void
+exif_mnote_data_set_byte_order (ExifMnoteData *d, ExifByteOrder o)
+{
+       if (!d || !d->methods.set_byte_order) return;
+       d->methods.set_byte_order (d, o);
+}
+
+void
+exif_mnote_data_set_offset (ExifMnoteData *d, unsigned int o)
+{
+       if (!d || !d->methods.set_offset) return;
+       d->methods.set_offset (d, o);
+}
+
 unsigned int
 exif_mnote_data_count (ExifMnoteData *d)
 {
index 3f7238e..13fccc8 100644 (file)
@@ -223,20 +223,33 @@ exif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i)
         return mnote_olympus_tag_get_title (n->entries[i].tag);
 }
 
+static void
+exif_mnote_data_olympus_set_byte_order (ExifMnoteData *n, ExifByteOrder o)
+{
+       if (n) ((ExifMnoteDataOlympus *) n)->order = o;
+}
+
+static void
+exif_mnote_data_olympus_set_offset (ExifMnoteData *n, unsigned int o)
+{
+       if (n) ((ExifMnoteDataOlympus *) n)->offset = o;
+}
+
 ExifMnoteData *
-exif_mnote_data_olympus_new (ExifByteOrder order)
+exif_mnote_data_olympus_new (void)
 {
        ExifMnoteData *n;
 
        n = malloc (sizeof (ExifMnoteDataOlympus));
        if (!n) return NULL;
        memset (n, 0, sizeof (ExifMnoteDataOlympus));
-       exif_mnote_data_construct (n);
 
-       ((ExifMnoteDataOlympus *) n)->order = order;
+       exif_mnote_data_construct (n);
 
        /* Set up the function pointers */
        n->methods.free            = exif_mnote_data_olympus_free;
+       n->methods.set_byte_order  = exif_mnote_data_olympus_set_byte_order;
+       n->methods.set_offset      = exif_mnote_data_olympus_set_offset;
        n->methods.load            = exif_mnote_data_olympus_load;
        n->methods.count           = exif_mnote_data_olympus_count;
        n->methods.get_name        = exif_mnote_data_olympus_get_name;
index ba4fb5d..db7a516 100644 (file)
@@ -34,8 +34,9 @@ struct _ExifMnoteDataOlympus {
        unsigned int count;
 
        ExifByteOrder order;
+       unsigned int offset;
 };
 
-ExifMnoteData *exif_mnote_data_olympus_new (ExifByteOrder);
+ExifMnoteData *exif_mnote_data_olympus_new (void);
 
 #endif /* __MNOTE_OLYMPUS_CONTENT_H__ */
index c978dfc..bd1e40a 100644 (file)
@@ -161,20 +161,33 @@ exif_mnote_data_pentax_get_description (ExifMnoteData *d, unsigned int n)
        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)
+{
+       if (d) ((ExifMnoteDataPentax *) d)->order = o;
+}
+
 ExifMnoteData *
-exif_mnote_data_pentax_new (ExifByteOrder order)
+exif_mnote_data_pentax_new (void)
 {
        ExifMnoteData *n;
 
        n = malloc (sizeof (ExifMnoteDataPentax));
        if (!n) return NULL;
        memset (n, 0, sizeof (ExifMnoteDataPentax));
-       exif_mnote_data_construct (n);
 
-       ((ExifMnoteDataPentax *) n)->order = order;
+       exif_mnote_data_construct (n);
 
        /* Set up function pointers */
        n->methods.free            = exif_mnote_data_pentax_free;
+       n->methods.set_byte_order  = exif_mnote_data_pentax_set_byte_order;
+       n->methods.set_offset      = exif_mnote_data_pentax_set_offset;
        n->methods.load            = exif_mnote_data_pentax_load;
        n->methods.count           = exif_mnote_data_pentax_count;
        n->methods.get_name        = exif_mnote_data_pentax_get_name;
index e92601f..c24021c 100644 (file)
@@ -35,8 +35,9 @@ struct _ExifMnoteDataPentax {
        unsigned int count;
 
        ExifByteOrder order;
+       unsigned int offset;
 };
 
-ExifMnoteData *exif_mnote_data_pentax_new (ExifByteOrder);
+ExifMnoteData *exif_mnote_data_pentax_new (void);
 
 #endif /* __EXIF_MNOTE_DATA_PENTAX_H__ */
index 997fe51..c1691a1 100644 (file)
@@ -3,15 +3,8 @@ INCLUDES =                             \
        -I$(top_srcdir)intl             \
        -I$(top_srcdir) 
 
-noinst_PROGRAMS =      \
-       test-mem        \
-       test-tree
+noinst_PROGRAMS = test-mem test-tree test-mnote
 
-test_tree_LDADD =              \
-       ../libjpeg/libjpeg.la   \
-       ../libexif/libexif.la   \
-       $(INTLLIBS)
-
-test_mem_LDADD =               \
-       ../libexif/libexif.la   \
-       $(INTLLIBS)
+test_tree_LDADD = ../libjpeg/libjpeg.la        ../libexif/libexif.la $(INTLLIBS)
+test_mem_LDADD = ../libexif/libexif.la $(INTLLIBS)
+test_mnote_LDADD = ../libexif/libexif.la $(INTLLIBS)
diff --git a/test/test-mnote.c b/test/test-mnote.c
new file mode 100644 (file)
index 0000000..9790403
--- /dev/null
@@ -0,0 +1,51 @@
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <libexif/exif-data.h>
+
+int
+main (int argc, char **argv)
+{
+       ExifData *d;
+       ExifMnoteData *md;
+       unsigned int c, i;
+       char *v;
+
+       if (argc <= 1) {
+               fprintf (stderr, "You need to supply a filename!\n");
+               return 1;
+       }
+
+       fprintf (stdout, "Loading '%s'...\n", argv[1]);
+       d = exif_data_new_from_file (argv[1]);
+       if (!d) {
+               fprintf (stderr, "Could not load data from '%s'!\n", argv[1]);
+               return 1;
+       }
+
+       fprintf (stdout, "Parsing maker note...\n");
+       md = exif_data_get_mnote_data (d);
+       if (!md) {
+               fprintf (stderr, "Could not parse maker note!\n");
+               exif_data_unref (d);
+               return 1;
+       }
+
+       c = exif_mnote_data_count (md);
+       for (i = 0; i < c; i++) {
+               fprintf (stdout, "%s", exif_mnote_data_get_name (md, i));
+               fprintf (stdout, "  Title: %s",
+                        exif_mnote_data_get_title (md, i));
+               fprintf (stdout, "  Description: %s",
+                        exif_mnote_data_get_description (md, i));
+               v = exif_mnote_data_get_value (md, i);
+               if (v) {
+                       fprintf (stdout, "  Value: '%s'", v);
+                       free (v);
+               }
+       }
+
+       exif_data_unref (d);
+}