From 6c654b384a0d2106295490bd4b023431a3b411bd Mon Sep 17 00:00:00 2001 From: Lutz Mueller Date: Sun, 26 Oct 2003 23:30:27 +0100 Subject: [PATCH] 2003-10-26 Lutz Mueller * 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. --- ChangeLog | 6 ++ libexif/Makefile.am | 6 +- libexif/canon/exif-mnote-data-canon.c | 103 ++++++++---------------------- libexif/canon/exif-mnote-data-canon.h | 3 +- libexif/exif-content.c | 26 ++++---- libexif/exif-data.c | 64 +++++++++++-------- libexif/exif-mnote-data-priv.h | 7 +- libexif/exif-mnote-data.c | 14 ++++ libexif/olympus/exif-mnote-data-olympus.c | 19 +++++- libexif/olympus/exif-mnote-data-olympus.h | 3 +- libexif/pentax/exif-mnote-data-pentax.c | 19 +++++- libexif/pentax/exif-mnote-data-pentax.h | 3 +- test/Makefile.am | 15 ++--- test/test-mnote.c | 51 +++++++++++++++ 14 files changed, 199 insertions(+), 140 deletions(-) create mode 100644 test/test-mnote.c diff --git a/ChangeLog b/ChangeLog index 5a1747e..4938078 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2003-10-26 Lutz Mueller + * 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 + * configure.in * Makefile.am: Remove PO_DIRS. Otherwise, automake complains about po and intl not being in SUBDIRS diff --git a/libexif/Makefile.am b/libexif/Makefile.am index 484953d..3851e1b 100644 --- a/libexif/Makefile.am +++ b/libexif/Makefile.am @@ -23,9 +23,9 @@ libexif_la_SOURCES = \ exif-utils.c \ i18n.h libexif_la_LIBADD = -lm \ - canon/libmnote-canon.a \ - olympus/libmnote-olympus.a \ - pentax/libmnote-pentax.a + canon/libmnote-canon.la \ + olympus/libmnote-olympus.la \ + pentax/libmnote-pentax.la libexifincludedir = $(includedir)/libexif libexifinclude_HEADERS = \ diff --git a/libexif/canon/exif-mnote-data-canon.c b/libexif/canon/exif-mnote-data-canon.c index 63e2e8a..a06e94b 100644 --- a/libexif/canon/exif-mnote-data-canon.c +++ b/libexif/canon/exif-mnote-data-canon.c @@ -30,7 +30,7 @@ #include #include -/* #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;jorder); + 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; diff --git a/libexif/canon/exif-mnote-data-canon.h b/libexif/canon/exif-mnote-data-canon.h index 03d1670..a8938de 100644 --- a/libexif/canon/exif-mnote-data-canon.h +++ b/libexif/canon/exif-mnote-data-canon.h @@ -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__ */ diff --git a/libexif/exif-content.c b/libexif/exif-content.c index 2cfcde0..fbbbe49 100644 --- a/libexif/exif-content.c +++ b/libexif/exif-content.c @@ -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 * diff --git a/libexif/exif-data.c b/libexif/exif-data.c index 809d83f..1bb9e87 100644 --- a/libexif/exif-data.c +++ b/libexif/exif-data.c @@ -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); } } diff --git a/libexif/exif-mnote-data-priv.h b/libexif/exif-mnote-data-priv.h index cc5379b..2cc6480 100644 --- a/libexif/exif-mnote-data-priv.h +++ b/libexif/exif-mnote-data-priv.h @@ -26,6 +26,7 @@ extern "C" { #endif /* __cplusplus */ #include +#include 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 } diff --git a/libexif/exif-mnote-data.c b/libexif/exif-mnote-data.c index fe8cba1..cd69a63 100644 --- a/libexif/exif-mnote-data.c +++ b/libexif/exif-mnote-data.c @@ -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) { diff --git a/libexif/olympus/exif-mnote-data-olympus.c b/libexif/olympus/exif-mnote-data-olympus.c index 3f7238e..13fccc8 100644 --- a/libexif/olympus/exif-mnote-data-olympus.c +++ b/libexif/olympus/exif-mnote-data-olympus.c @@ -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; diff --git a/libexif/olympus/exif-mnote-data-olympus.h b/libexif/olympus/exif-mnote-data-olympus.h index ba4fb5d..db7a516 100644 --- a/libexif/olympus/exif-mnote-data-olympus.h +++ b/libexif/olympus/exif-mnote-data-olympus.h @@ -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__ */ diff --git a/libexif/pentax/exif-mnote-data-pentax.c b/libexif/pentax/exif-mnote-data-pentax.c index c978dfc..bd1e40a 100644 --- a/libexif/pentax/exif-mnote-data-pentax.c +++ b/libexif/pentax/exif-mnote-data-pentax.c @@ -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; diff --git a/libexif/pentax/exif-mnote-data-pentax.h b/libexif/pentax/exif-mnote-data-pentax.h index e92601f..c24021c 100644 --- a/libexif/pentax/exif-mnote-data-pentax.h +++ b/libexif/pentax/exif-mnote-data-pentax.h @@ -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__ */ diff --git a/test/Makefile.am b/test/Makefile.am index 997fe51..c1691a1 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -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 index 0000000..9790403 --- /dev/null +++ b/test/test-mnote.c @@ -0,0 +1,51 @@ +#include + +#include +#include + +#include + +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); +} -- 2.7.4