diff options
Diffstat (limited to 'src/libexif/exif-content.c')
-rw-r--r-- | src/libexif/exif-content.c | 111 |
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; + } + } +} |