summaryrefslogtreecommitdiff
path: root/src/libexif/exif-content.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexif/exif-content.c')
-rw-r--r--src/libexif/exif-content.c111
1 files changed, 98 insertions, 13 deletions
diff --git a/src/libexif/exif-content.c b/src/libexif/exif-content.c
index 39d73ad..c763751 100644
--- a/src/libexif/exif-content.c
+++ b/src/libexif/exif-content.c
@@ -1,6 +1,6 @@
/* exif-content.c
*
- * Copyright © 2001 Lutz Müller <lutz@users.sourceforge.net>
+ * Copyright (c) 2001 Lutz Mueller <lutz@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,12 +21,15 @@
#include <config.h>
#include <libexif/exif-content.h>
+#include <libexif/exif-system.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
+/* unused constant
+ * static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
+ */
struct _ExifContentPrivate
{
@@ -120,7 +123,7 @@ exif_content_dump (ExifContent *content, unsigned int indent)
if (!content)
return;
- printf ("%sDumping exif content (%i entries)...\n", buf,
+ printf ("%sDumping exif content (%u entries)...\n", buf,
content->count);
for (i = 0; i < content->count; i++)
exif_entry_dump (content->entries[i], indent + 1);
@@ -129,6 +132,7 @@ exif_content_dump (ExifContent *content, unsigned int indent)
void
exif_content_add_entry (ExifContent *c, ExifEntry *entry)
{
+ ExifEntry **entries;
if (!c || !c->priv || !entry || entry->parent) return;
/* One tag can only be added once to an IFD. */
@@ -140,19 +144,20 @@ exif_content_add_entry (ExifContent *c, ExifEntry *entry)
return;
}
+ entries = exif_mem_realloc (c->priv->mem,
+ c->entries, sizeof (ExifEntry*) * (c->count + 1));
+ if (!entries) return;
entry->parent = c;
- c->entries = exif_mem_realloc (c->priv->mem,
- c->entries, sizeof (ExifEntry) * (c->count + 1));
- if (!c->entries) return;
- c->entries[c->count] = entry;
+ entries[c->count++] = entry;
+ c->entries = entries;
exif_entry_ref (entry);
- c->count++;
}
void
exif_content_remove_entry (ExifContent *c, ExifEntry *e)
{
unsigned int i;
+ ExifEntry **t, *temp;
if (!c || !c->priv || !e || (e->parent != c)) return;
@@ -161,13 +166,26 @@ exif_content_remove_entry (ExifContent *c, ExifEntry *e)
if (i == c->count) return;
/* Remove the entry */
- memmove (&c->entries[i], &c->entries[i + 1],
- sizeof (ExifEntry) * (c->count - i - 1));
- c->count--;
+ temp = c->entries[c->count-1];
+ if (c->count > 1) {
+ t = exif_mem_realloc (c->priv->mem, c->entries,
+ sizeof(ExifEntry*) * (c->count - 1));
+ if (!t) {
+ return;
+ }
+ c->entries = t;
+ c->count--;
+ if (i != c->count) { /* we deallocated the last slot already */
+ memmove (&t[i], &t[i + 1], sizeof (ExifEntry*) * (c->count - i - 1));
+ t[c->count-1] = temp;
+ }
+ } else {
+ exif_mem_free (c->priv->mem, c->entries);
+ c->entries = NULL;
+ c->count = 0;
+ }
e->parent = NULL;
exif_entry_unref (e);
- c->entries = exif_mem_realloc (c->priv->mem, c->entries,
- sizeof(ExifEntry) * c->count);
}
ExifEntry *
@@ -207,3 +225,70 @@ exif_content_log (ExifContent *content, ExifLog *log)
content->priv->log = log;
exif_log_ref (log);
}
+
+ExifIfd
+exif_content_get_ifd (ExifContent *c)
+{
+ if (!c || !c->parent) return EXIF_IFD_COUNT;
+
+ return
+ ((c)->parent->ifd[EXIF_IFD_0] == (c)) ? EXIF_IFD_0 :
+ ((c)->parent->ifd[EXIF_IFD_1] == (c)) ? EXIF_IFD_1 :
+ ((c)->parent->ifd[EXIF_IFD_EXIF] == (c)) ? EXIF_IFD_EXIF :
+ ((c)->parent->ifd[EXIF_IFD_GPS] == (c)) ? EXIF_IFD_GPS :
+ ((c)->parent->ifd[EXIF_IFD_INTEROPERABILITY] == (c)) ? EXIF_IFD_INTEROPERABILITY :
+ EXIF_IFD_COUNT;
+}
+
+static void
+fix_func (ExifEntry *e, void *UNUSED(data))
+{
+ exif_entry_fix (e);
+}
+
+void
+exif_content_fix (ExifContent *c)
+{
+ ExifIfd ifd = exif_content_get_ifd (c);
+ ExifDataType dt;
+ ExifTag t;
+ ExifEntry *e;
+
+ if (!c) return;
+
+ dt = exif_data_get_data_type (c->parent);
+
+ /* First of all, fix all existing entries. */
+ exif_content_foreach_entry (c, fix_func, NULL);
+
+ /*
+ * Then check for existing tags that are not allowed and for
+ * non-existing mandatory tags.
+ */
+ for (t = 0; t <= 0xffff; t++) {
+ switch (exif_tag_get_support_level_in_ifd (t, ifd, dt)) {
+ case EXIF_SUPPORT_LEVEL_MANDATORY:
+ if (exif_content_get_entry (c, t)) break;
+ exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content",
+ "Tag '%s' is mandatory in IFD '%s' and has therefore been added.",
+ exif_tag_get_name_in_ifd (t, ifd), exif_ifd_get_name (ifd));
+ e = exif_entry_new ();
+ exif_content_add_entry (c, e);
+ exif_entry_initialize (e, t);
+ exif_entry_unref (e);
+ break;
+ case EXIF_SUPPORT_LEVEL_NOT_RECORDED:
+ e = exif_content_get_entry (c, t);
+ if (!e) break;
+ exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content",
+ "Tag '%s' is not recorded in IFD '%s' and has therefore been "
+ "removed.", exif_tag_get_name_in_ifd (t, ifd),
+ exif_ifd_get_name (ifd));
+ exif_content_remove_entry (c, e);
+ break;
+ case EXIF_SUPPORT_LEVEL_OPTIONAL:
+ default:
+ break;
+ }
+ }
+}