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; +		} +	} +}  | 
