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).
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],
entry->data[6]);
data->priv->offset_mnote = doff;
}
+
+ exif_entry_fix (entry);
}
static void
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)
{
}
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];
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,
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:
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);
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) {
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;
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));
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);
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: