X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=libexif%2Fexif-content.c;h=6d6c589d07b89fc42c994d6b2ef1c0d0e53b7486;hb=18fd0ff7408961416a3077071320d95c66873b5d;hp=c763751b7ca7f74c4f5425047917c917e7d0f96d;hpb=4e85db22d4812cc72069ed681f7a004f926d59c1;p=platform%2Fupstream%2Flibexif.git diff --git a/libexif/exif-content.c b/libexif/exif-content.c index c763751..6d6c589 100644 --- a/libexif/exif-content.c +++ b/libexif/exif-content.c @@ -14,8 +14,8 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. */ #include @@ -162,8 +162,12 @@ exif_content_remove_entry (ExifContent *c, ExifEntry *e) if (!c || !c->priv || !e || (e->parent != c)) return; /* Search the entry */ - for (i = 0; i < c->count; i++) if (c->entries[i] == e) break; - if (i == c->count) return; + for (i = 0; i < c->count; i++) + if (c->entries[i] == e) + break; + + if (i == c->count) + return; /* Remove the entry */ temp = c->entries[c->count-1]; @@ -232,9 +236,9 @@ exif_content_get_ifd (ExifContent *c) if (!c || !c->parent) return EXIF_IFD_COUNT; return + ((c)->parent->ifd[EXIF_IFD_EXIF] == (c)) ? EXIF_IFD_EXIF : ((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; @@ -246,29 +250,71 @@ fix_func (ExifEntry *e, void *UNUSED(data)) exif_entry_fix (e); } +/*! + * Check if this entry is unknown and if so, delete it. + * \note Be careful calling this function in a loop. Deleting an entry from + * an ExifContent changes the index of subsequent entries, as well as the + * total size of the entries array. + */ +static void +remove_not_recorded (ExifEntry *e, void *UNUSED(data)) +{ + ExifIfd ifd = exif_entry_get_ifd(e) ; + ExifContent *c = e->parent; + ExifDataType dt = exif_data_get_data_type (c->parent); + ExifTag t = e->tag; + + if (exif_tag_get_support_level_in_ifd (t, ifd, dt) == + EXIF_SUPPORT_LEVEL_NOT_RECORDED) { + exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content", + "Tag 0x%04x is not recorded in IFD '%s' and has therefore been " + "removed.", t, exif_ifd_get_name (ifd)); + exif_content_remove_entry (c, e); + } + +} + void exif_content_fix (ExifContent *c) { ExifIfd ifd = exif_content_get_ifd (c); ExifDataType dt; - ExifTag t; ExifEntry *e; + unsigned int i, num; - if (!c) return; + if (!c) + return; dt = exif_data_get_data_type (c->parent); - /* First of all, fix all existing entries. */ + /* + * 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. + * Go through each tag and if it's not recorded, remove it. If one + * is removed, exif_content_foreach_entry() will skip the next entry, + * so if this happens do the loop again from the beginning to ensure + * they're all checked. This could be avoided if we stop relying on + * exif_content_foreach_entry but loop intelligently here. */ - 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; + do { + num = c->count; + exif_content_foreach_entry (c, remove_not_recorded, NULL); + } while (num != c->count); + + /* + * Then check for non-existing mandatory tags and create them if needed + */ + num = exif_tag_table_count(); + for (i = 0; i < num; ++i) { + const ExifTag t = exif_tag_table_get_tag (i); + if (exif_tag_get_support_level_in_ifd (t, ifd, dt) == + EXIF_SUPPORT_LEVEL_MANDATORY) { + if (exif_content_get_entry (c, t)) + /* This tag already exists */ + continue; 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)); @@ -276,19 +322,6 @@ exif_content_fix (ExifContent *c) 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; } } }