2004-09-17 Lutz Mueller <lutz@users.sourceforge.net>
authorLutz Mueller <lutz.s.mueller@gmail.com>
Fri, 17 Sep 2004 20:59:16 +0000 (22:59 +0200)
committerLutz Mueller <lutz.s.mueller@gmail.com>
Fri, 17 Sep 2004 20:59:16 +0000 (22:59 +0200)
* libexif/exif-entry.c (exif_entry_fix): New. Fixes any violations
  against the standard.

ChangeLog
libexif/exif-data.c
libexif/exif-entry.c
libexif/exif-entry.h
libexif/olympus/mnote-olympus-entry.c
libexif/pentax/mnote-pentax-entry.c

index eb77aea..68a6595 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2004-09-17  Lutz Mueller <lutz@users.sourceforge.net>
 
+       * libexif/exif-entry.c (exif_entry_fix): New. Fixes any violations
+         against the standard.
+
+2004-09-17  Lutz Mueller <lutz@users.sourceforge.net>
+
        * libexif/exif-entry.c: Kill some warnings. Read as much from the
          UserComment tag as possible (as suggested by Angela Wrobel).
 
index 1ccb9d9..bad5f72 100644 (file)
@@ -143,13 +143,15 @@ exif_data_load_data_entry (ExifData *data, ExifEntry *entry,
                return;
 
        entry->data = exif_data_alloc (data, s);
-       if (!entry->data) return;
-       entry->size = s;
-       memcpy (entry->data, d + doff, s);
+       if (entry->data) {
+               entry->size = s;
+               memcpy (entry->data, d + doff, s);
+       }
 
        /* If this is the MakerNote, remember the offset */
        if (entry->tag == EXIF_TAG_MAKER_NOTE) {
-               exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
+               if (entry->size > 6) exif_log (data->priv->log,
+                         EXIF_LOG_CODE_DEBUG, "ExifData",
                          "MakerNote found (%02x %02x %02x %02x "
                          "%02x %02x %02x...).",
                          entry->data[0], entry->data[1], entry->data[2],
@@ -157,6 +159,8 @@ exif_data_load_data_entry (ExifData *data, ExifEntry *entry,
                          entry->data[6]);
                data->priv->offset_mnote = doff;
        }
+
+       exif_entry_fix (entry);
 }
 
 static void
index 6937d39..d2a8ab5 100644 (file)
@@ -76,6 +76,25 @@ exif_entry_alloc (ExifEntry *e, unsigned int i)
        return NULL;
 }
 
+static void *
+exif_entry_realloc (ExifEntry *e, void *d_orig, unsigned int i)
+{
+       void *d;
+       ExifLog *l = NULL;
+
+       if (!i) { free (d_orig); return NULL; }
+
+       /* This is the only call to realloc in this file. */
+       d = realloc (d_orig, i);
+       if (d) return d;
+
+       if (e && e->parent && e->parent->parent)
+               l = exif_data_get_log (e->parent->parent);
+       EXIF_LOG_NO_MEMORY (l, "ExifEntry", i);
+
+       return NULL;
+}
+
 ExifEntry *
 exif_entry_new (void)
 {
@@ -123,6 +142,95 @@ exif_entry_free (ExifEntry *e)
 }
 
 void
+exif_entry_fix (ExifEntry *e)
+{
+       unsigned int i;
+
+       if (!e) return;
+
+       switch (e->tag) {
+       case EXIF_TAG_USER_COMMENT:
+
+               /* Format needs to be UNDEFINED. */
+               if (e->format != EXIF_FORMAT_UNDEFINED) {
+                       exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
+                               "Tag 'UserComment' had invalid format '%s'. "
+                               "Format has been set to 'undefined'.",
+                               exif_format_get_name (e->format));
+                       e->format = EXIF_FORMAT_UNDEFINED;
+               }
+
+               /* Some cameras fill the tag with '\0' or ' '. */
+               for (i = 0; i < e->size &&
+                           (!e->data[i] || (e->data[i] == ' ')); i++);
+               if (i && (i == e->size)) {
+                       exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
+                               "Tag 'UserComment' contained unnecessary "
+                               "data which has been removed.");
+                       free (e->data);
+                       e->data = NULL;
+                       e->size = 0;
+                       e->components = 0;
+               }
+
+               /* There need to be at least 8 bytes. */
+               if (e->size < 8) {
+                       e->data = exif_entry_realloc (e, e->data, 8 + e->size);
+                       if (!e->data) {
+                               e->size = 0;
+                               e->components = 0;
+                               return;
+                       }
+
+                       /* Assume ASCII */
+                       memmove (e->data + 8, e->data, e->size);
+                       memcpy (e->data, "ASCII\0\0\0", 8);
+                       exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
+                               "Tag 'UserComment' has been expanded to at "
+                               "least 8 bytes in order to follow the "
+                               "specification.");
+                       break;
+               }
+
+               /*
+                * If the first 8 bytes are empty and real data starts
+                * afterwards, let's assume ASCII and claim the 8 first
+                * bytes for the format specifyer.
+                */
+               if (i >= 8) {
+                       exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
+                               "Tag 'UserComment' did not start with "
+                               "format identifyer. This has been fixed.");
+                       memcpy (e->data, "ASCII\0\0\0", 8);
+               }
+
+               /* First 8 bytes need to follow the specification. */
+               if (memcmp (e->data, "ASCII\0\0\0"  , 8) &&
+                   memcmp (e->data, "UNICODE\0"    , 8) &&
+                   memcmp (e->data, "JIS\0\0\0\0\0", 8)) {
+                       e->data = exif_entry_realloc (e, e->data, 8 + e->size);
+                       if (!e->data) {
+                               e->size = 0;
+                               e->components = 0;
+                               break;
+                       }
+
+                       /* Assume ASCII */
+                       memmove (e->data + 8, e->data, e->size);
+                       memcpy (e->data, "ASCII\0\0\0", 8);
+                       exif_entry_log (e, EXIF_LOG_CODE_DEBUG,
+                               "Tag 'UserComment' did not start with "
+                               "format identifyer. This has been fixed.");
+                       break;
+               }
+
+               break;
+       default:
+               break;
+       }
+}
+
+void
 exif_entry_dump (ExifEntry *e, unsigned int indent)
 {
        char buf[1024];
index 31468b2..3cde841 100644 (file)
@@ -52,6 +52,7 @@ void        exif_entry_unref (ExifEntry *entry);
 void        exif_entry_free  (ExifEntry *entry);
 
 void        exif_entry_initialize (ExifEntry *entry, ExifTag tag);
+void        exif_entry_fix        (ExifEntry *entry);
 
 /* For your convenience */
 const char *exif_entry_get_value (ExifEntry *entry, char *val,
index 4c49800..1eff6fe 100644 (file)
@@ -189,7 +189,7 @@ mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *v, unsigned int m
                if ((vl & 0xF0F0F0F0) == 0x30303030) {
                        memcpy (v, entry->data, MIN (maxlen, 4));
                } else {
-                       snprintf (v, maxlen, "%04lx", vl);
+                       snprintf (v, maxlen, "%04lx", (long unsigned int) vl);
                }
                break;
        case MNOTE_NIKON_TAG_ISO:
@@ -232,7 +232,7 @@ mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *v, unsigned int m
                 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",  vl );
+                snprintf (v, maxlen, "%lu",  (long unsigned int) vl );
                 break;
        case MNOTE_NIKON_TAG_WHITEBALANCEFINE:
                 CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen);
@@ -387,10 +387,10 @@ mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *v, unsigned int m
                        strncpy (v, _("panorama"), maxlen);
                        break;
                default:
-                       snprintf (v, maxlen, _("%li"), vl);
+                       snprintf (v, maxlen, _("%li"), (long int) vl);
                }
                vl = exif_get_long (entry->data + 4, entry->order);
-               snprintf (buf, sizeof (buf), "/%li/", vl);
+               snprintf (buf, sizeof (buf), "/%li/", (long int) vl);
                strncat (v, buf, maxlen - strlen (v));
                vl = exif_get_long (entry->data + 4, entry->order);
                switch (vl) {
@@ -407,7 +407,8 @@ mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *v, unsigned int m
                        strncat (v, _("top to bottom"), maxlen - strlen (v));
                        break;
                default:
-                       snprintf (buf, sizeof (buf), _("%li"), vl);
+                       snprintf (buf, sizeof (buf), _("%li"),
+                                 (long int) vl);
                        strncat (v, buf, maxlen - strlen (v));
                }
                break;
@@ -520,12 +521,12 @@ mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *v, unsigned int m
                        break;
                case EXIF_FORMAT_LONG:
                        vl = exif_get_long (entry->data, entry->order);
-                       snprintf (v, maxlen, "%li", vl);
+                       snprintf (v, maxlen, "%li", (long int) vl);
                        break;
                case EXIF_FORMAT_UNDEFINED:
                default:
                        snprintf (v, maxlen, _("%li bytes unknown data: "),
-                                 entry->size);
+                                 (long int) entry->size);
                        for (i = 0; i < (int)entry->size; i++) {
                                sprintf (buf, "%02x", entry->data[i]);
                                strncat (v, buf, maxlen - strlen (v));
index 8332da6..3469f22 100644 (file)
@@ -166,7 +166,7 @@ mnote_pentax_entry_get_value (MnotePentaxEntry *entry,
                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", vl);
+               snprintf (val, maxlen, "%li", (long int) vl);
                break;
        case MNOTE_PENTAX_TAG_PRINTIM:
                CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
@@ -195,7 +195,7 @@ mnote_pentax_entry_get_value (MnotePentaxEntry *entry,
                  break;
                case EXIF_FORMAT_LONG:
                  vl = exif_get_long (entry->data, entry->order);
-                 snprintf (val, maxlen, "%li", vl);
+                 snprintf (val, maxlen, "%li", (long int) vl);
                  break;
                case EXIF_FORMAT_UNDEFINED:
                default: