From: Dan F. <dfa...@us...> - 2009-09-27 05:49:53
|
Update of /cvsroot/libexif/libexif/libexif In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv19315/libexif Modified Files: exif-content.c exif-tag.c exif-tag.h Log Message: Sped up exif_content_fix() considerably by splitting the one giant loop into two much smaller & faster loops. Index: exif-tag.h =================================================================== RCS file: /cvsroot/libexif/libexif/libexif/exif-tag.h,v retrieving revision 1.24 retrieving revision 1.25 diff -u -p -d -r1.24 -r1.25 --- exif-tag.h 23 Jan 2009 00:06:36 -0000 1.24 +++ exif-tag.h 27 Sep 2009 04:48:56 -0000 1.25 @@ -259,6 +259,19 @@ const char *exif_tag_get_title /*! \deprecated Use #exif_tag_get_description_in_ifd instead */ const char *exif_tag_get_description (ExifTag tag); + +/* For now, do not use these functions. */ + +/*! \internal */ +ExifTag exif_tag_table_get_tag (unsigned int n); + +/*! \internal */ +const char *exif_tag_table_get_name (unsigned int n); + +/*! \internal */ +unsigned int exif_tag_table_count (void); + + /* Don't use these definitions. They are here for compatibility only. */ /*! \deprecated Use EXIF_TAG_PRINT_IMAGE_MATCHING instead. */ Index: exif-tag.c =================================================================== RCS file: /cvsroot/libexif/libexif/libexif/exif-tag.c,v retrieving revision 1.54 retrieving revision 1.55 diff -u -p -d -r1.54 -r1.55 --- exif-tag.c 23 Jan 2009 00:06:36 -0000 1.54 +++ exif-tag.c 27 Sep 2009 04:48:56 -0000 1.55 @@ -857,15 +857,6 @@ static const struct { /* For now, do not use these functions. */ -/*! \internal */ -ExifTag exif_tag_table_get_tag (unsigned int n); - -/*! \internal */ -const char *exif_tag_table_get_name (unsigned int n); - -/*! \internal */ -unsigned int exif_tag_table_count (void); - ExifTag exif_tag_table_get_tag (unsigned int n) { Index: exif-content.c =================================================================== RCS file: /cvsroot/libexif/libexif/libexif/exif-content.c,v retrieving revision 1.31 retrieving revision 1.32 diff -u -p -d -r1.31 -r1.32 --- exif-content.c 23 Sep 2009 18:00:15 -0000 1.31 +++ exif-content.c 27 Sep 2009 04:48:56 -0000 1.32 @@ -246,31 +246,71 @@ fix_func (ExifEntry *e, void *UNUSED(dat 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; ExifEntry *e; - unsigned int i; + 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 do the loop again from the beginning if this happens to ensure + * they're all checked. This could be avoided if we stop relying on + * exif_content_foreach_entry. */ - for (i = 0; i <= 0xffff; i++) { - /* Index using an int because t might only be 16 bits */ - const ExifTag t = (ExifTag) i; - 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)); @@ -278,20 +318,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: - case EXIF_SUPPORT_LEVEL_UNKNOWN: - default: - break; } } } |