diff options
| author | Dennis Real <github@tildepipe.org> | 2012-03-16 22:20:58 +0100 | 
|---|---|---|
| committer | Dennis Real <github@tildepipe.org> | 2012-03-16 22:20:58 +0100 | 
| commit | 9e1bbf874500e99506baffec3c6b54ed04e60a2f (patch) | |
| tree | f8d384ded578b95dce53cc58c5c0cc0315d730d0 /src | |
| parent | 8e96382805eb77a82209df9d71dbf9c0dd1c4cdb (diff) | |
- exif handling changed
- gps info added if available
Diffstat (limited to 'src')
| -rw-r--r-- | src/exif.c | 252 | ||||
| -rw-r--r-- | src/exif.h | 5 | ||||
| -rw-r--r-- | src/exif_cfg.h | 61 | ||||
| -rw-r--r-- | src/imlib.c | 10 | 
4 files changed, 250 insertions, 78 deletions
| @@ -34,7 +34,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #include "debug.h"  #include "exif.h"  #include "exif_nikon.h" +#include "exif_cfg.h" +static void exif_trim_spaces(char *str); +static void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize); +static void exif_get_tag_content(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize); +static void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsigned int maxsize); +static void exif_get_mnote_nikon_tags(ExifData *ed, char * buffer, unsigned int maxsize); +static void exif_get_gps_coords(ExifData * ed, char *buffer, unsigned int maxsize);  /* remove all spaces on the right end of a string */  static void exif_trim_spaces(char *str) @@ -52,18 +59,19 @@ static void exif_trim_spaces(char *str)  } -/* show given exif tag content */ +/* show given exif tag content with tag name */  static void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize)  { -  char s[MAX_EXIF_DATA]; - +  char s[EXIF_MAX_DATA]; +  ExifEntry *entry = NULL; +      if ( (d != NULL) && (buffer != NULL) && (maxsize>0) )    { -    ExifEntry *entry = exif_content_get_entry(d->ifd[ifd], tag); +    entry = exif_content_get_entry(d->ifd[ifd], tag);      if (entry != NULL)       {        /* Get the contents of the tag in human-readable form */ -      exif_entry_get_value(entry, s, maxsize); +      exif_entry_get_value(entry, s, EXIF_MAX_DATA);        /* Don't bother printing it if it's entirely blank */        exif_trim_spaces(s); @@ -78,6 +86,34 @@ static void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, un +/* show given exif tag content without tag name */ +static void exif_get_tag_content(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize) +{ +  char s[EXIF_MAX_DATA]; +  ExifEntry *entry = NULL; + +  if ( (d != NULL) && (buffer != NULL) && (maxsize>0) ) +  { +    entry = exif_content_get_entry(d->ifd[ifd], tag); +    if (entry != NULL)  +    { +      /* Get the contents of the tag in human-readable form */ +      exif_entry_get_value(entry, s, EXIF_MAX_DATA); + +      /* Don't bother printing it if it's entirely blank */ +      exif_trim_spaces(s); +      if (*s != '\0') +      { +        D(("%s", exif_tag_get_name_in_ifd(tag,ifd), s)); +        snprintf(buffer, (size_t)maxsize, "%s", s); +      } +    } +  } + +} + + +  /* Show the given MakerNote tag if it exists */  static void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsigned int maxsize)  { @@ -119,6 +155,125 @@ static void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsi +/* get interesting nikon maker note tags in readable form */ +static void exif_get_mnote_nikon_tags(ExifData *ed, char * buffer, unsigned int maxsize) +{ +  char buf[EXIF_STD_BUF_LEN]; +  unsigned int exn_fcm = (EXN_FLASH_CONTROL_MODES_MAX-1); /* default to N/A */ +  unsigned int version = 0; +  unsigned int length = 0; + +  buf[0] = '\0'; +  exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buf, sizeof(buf)); +  exif_trim_spaces(buf); + +  if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) ) +  { +    /* show extended flash info if flash was fired */ +   +    /* Flash Setting */ +    exif_get_mnote_tag(ed, 8, buffer + strlen(buffer), maxsize - strlen(buffer)); +    /* Flash Mode */ +    exif_get_mnote_tag(ed, 9, buffer + strlen(buffer), maxsize - strlen(buffer)); +    /* flash exposure bracket value */ +    exif_get_mnote_tag(ed, 24, buffer + strlen(buffer), maxsize - strlen(buffer)); +    /* Flash used */ +    exif_get_mnote_tag(ed, 135, buffer + strlen(buffer), maxsize - strlen(buffer)); + +    /* Flash info: control mode. */ +    /* libexif does not support flash info 168 yet. so we have to parse the debug data :-( */ +    buf[0] = '\0'; +    exif_get_mnote_tag(ed, 168, buf, sizeof(buf)); +    sscanf(buf, "(null): %u bytes unknown data: 303130%02X%*10s%02X", &length, &version, &exn_fcm); +    exn_fcm = exn_fcm & EXN_FLASH_CONTROL_MODE_MASK; + +    if ( (exn_fcm < EXN_FLASH_CONTROL_MODES_MAX) +         && ( ((length == 22) && (version == '3'))      /* Nikon FlashInfo0103 */ +              || ((length == 22) && (version == '4'))   /* Nikon FlashInfo0104 */ +              || ((length == 21) && (version == '2'))   /* Nikon FlashInfo0102 */ +              || ((length == 19) && (version == '0'))   /* Nikon FlashInfo0100 */ +            ) +       ) +    { +      snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "NikonFlashControlMode: %s\n",  +      EXN_NikonFlashControlModeValues[exn_fcm]); +    } +  } + +  /* Lens */ +  exif_get_mnote_tag(ed, 132, buffer + strlen(buffer), maxsize - strlen(buffer)); +  /* Digital Vari-Program */ +  exif_get_mnote_tag(ed, 171, buffer + strlen(buffer), maxsize - strlen(buffer)); + +  return; +} + + + +/* get gps coordinates if available */ +static void exif_get_gps_coords(ExifData * ed, char *buffer, unsigned int maxsize) +{ +  char buf[EXIF_STD_BUF_LEN]; +   +  buf[0] = '\0'; +  exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF, buf, sizeof(buf)); +  if ( buf[0] != '\0' ) +  { +    snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "GPS: %s ", buf); +  } +  else +  { +    return; +  } + +  buf[0] = '\0'; +  exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE, buf, sizeof(buf)); +  if ( buf[0] != '\0' ) +  { +    snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "%s ", buf); +  } +  else +  { +    return; +  } + +  buf[0] = '\0'; +  exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF, buf, sizeof(buf)); +  if ( buf[0] != '\0' ) +  { +    snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), ", %s ", buf); +  } +  else +  { +    return; +  } + +  buf[0] = '\0'; +  exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE, buf, sizeof(buf)); +  if ( buf[0] != '\0' ) +  { +    snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "%s ", buf); +  } +  else +  { +    return; +  } + +  buf[0] = '\0'; +  exif_get_tag_content(ed, EXIF_IFD_GPS, EXIF_TAG_GPS_MAP_DATUM, buf, sizeof(buf)); +  if ( buf[0] != '\0' ) +  { +    snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "(%s)\n", buf); +  } +  else +  { +    return; +  } + +} + + +  /* return data structure with exif data if available */  ExifData * exif_get_data(char *path)  { @@ -136,15 +291,14 @@ ExifData * exif_get_data(char *path) +  /* get exif data in readable form */  void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize)  {    ExifEntry *entry = NULL; -  char buf[128]; -  unsigned int exn_fcm = (EXN_FLASH_CONTROL_MODES_MAX-1); /* default to N/A */ -  unsigned int version = 0; -  unsigned int length = 0; - +  char buf[EXIF_STD_BUF_LEN]; +  int i = 0; +      if ( (buffer == NULL) || (maxsize == 0) )    {      return; @@ -157,24 +311,11 @@ void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize)    else    {      /* normal exif tags */ -    exif_get_tag(ed, EXIF_IFD_0, EXIF_TAG_MAKE, buffer, maxsize); -    exif_get_tag(ed, EXIF_IFD_0, EXIF_TAG_MODEL, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buffer + strlen(buffer), maxsize - strlen(buffer)); -    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH_ENERGY, buffer + strlen(buffer), maxsize - strlen(buffer)); +    while ( Exif_tag_list[i].ifd != EXIF_IFD_COUNT ) +    { +      exif_get_tag(ed, Exif_tag_list[i].ifd, Exif_tag_list[i].tag, buffer + strlen(buffer), maxsize - strlen(buffer)); +      i++;  +    }      /* vendor specific makernote tags */      entry = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE); @@ -185,57 +326,24 @@ void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize)        {          exif_trim_spaces(buf); -        /* Nikon */                                     -        if ( strcmp(buf, "Nikon") != 0 ) +        if ( (strcmp(buf, "NIKON CORPORATION") == 0) +             || (strcmp(buf, "Nikon") == 0)  +             || (strcmp(buf, "NIKON") == 0) +           )          {            /* this is a nikon camera */ -           -          buf[0] = '\0'; -          exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buf, sizeof(buf)); -          exif_trim_spaces(buf); - -          if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) ) -          { -            /* extended flash info if it was fired */ -   -            /* Flash Setting */ -            exif_get_mnote_tag(ed, 8, buffer + strlen(buffer), maxsize - strlen(buffer)); -            /* Flash Mode */ -            exif_get_mnote_tag(ed, 9, buffer + strlen(buffer), maxsize - strlen(buffer)); -            /* flash exposure bracket value */ -            exif_get_mnote_tag(ed, 24, buffer + strlen(buffer), maxsize - strlen(buffer)); -            /* Flash used */ -            exif_get_mnote_tag(ed, 135, buffer + strlen(buffer), maxsize - strlen(buffer)); - -            /* Flash info: control mode. */ -            /* libexif does not support flash info 168 yet. so we have to parse the debug data :-( */ -            buf[0] = '\0'; -            exif_get_mnote_tag(ed, 168, buf, sizeof(buf)); -            sscanf(buf, "(null): %u bytes unknown data: 303130%02X%*10s%02X", &length, &version, &exn_fcm); -            exn_fcm = exn_fcm & EXN_FLASH_CONTROL_MODE_MASK; - -            if ( (exn_fcm < EXN_FLASH_CONTROL_MODES_MAX) -                 && ( ((length == 22) && (version == '3'))      /* Nikon FlashInfo0103 */ -                      || ((length == 22) && (version == '4'))   /* Nikon FlashInfo0104 */ -                      || ((length == 21) && (version == '2'))   /* Nikon FlashInfo0102 */ -                      || ((length == 19) && (version == '0'))   /* Nikon FlashInfo0100 */ -                    ) -               ) -            { -              snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "NikonFlashControlMode: %s\n",  -                EXN_NikonFlashControlModeValues[exn_fcm]); -            } -          } -          /* Lens */ -          exif_get_mnote_tag(ed, 132, buffer + strlen(buffer), maxsize - strlen(buffer)); -          /* Digital Vari-Program */ -          exif_get_mnote_tag(ed, 171, buffer + strlen(buffer), maxsize - strlen(buffer)); - +          exif_get_mnote_nikon_tags(ed, buffer + strlen(buffer), maxsize - strlen(buffer));          }        } +            } +     +    /* gps info */ +    exif_get_gps_coords(ed, buffer + strlen(buffer), maxsize - strlen(buffer)); +    } +    }  #endif @@ -26,7 +26,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #ifndef EXIF_H  #define EXIF_H -#define MAX_EXIF_DATA 1024 +#include <libexif/exif-data.h> + +#define EXIF_MAX_DATA 1024 +#define EXIF_STD_BUF_LEN 128  extern ExifData * exif_get_data(char *path);  extern void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize); diff --git a/src/exif_cfg.h b/src/exif_cfg.h new file mode 100644 index 0000000..c828f43 --- /dev/null +++ b/src/exif_cfg.h @@ -0,0 +1,61 @@ +/* exif_cfg.h + +Copyright (C) 2012      Dennis Real. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies of the Software and its documentation and acknowledgment shall be +given in the documentation and software packages that this Software was +used. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#ifndef EXIF_CFG_H +#define EXIF_CFG_H + +#include <libexif/exif-data.h> + +typedef struct +{ +  ExifIfd ifd; /* section */ +  ExifTag tag;  /* tag */ +} t_EXIF_INFO; + +/* show these standard tags. section must be given first, than the tag itself */ +/* note: maker note specific tags are handled directly in exif.c up to now */ +const t_EXIF_INFO Exif_tag_list [] = +{ +  {EXIF_IFD_0, EXIF_TAG_MAKE}, +  {EXIF_IFD_0, EXIF_TAG_MODEL}, +  {EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION}, +  {EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL}, +  {EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME}, +  {EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE}, +  {EXIF_IFD_EXIF, EXIF_TAG_FNUMBER}, +  {EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE}, +  {EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE}, +  {EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS}, +  {EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH}, +  {EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM}, +  {EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE}, +  {EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM}, +  {EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE}, +  {EXIF_IFD_EXIF, EXIF_TAG_FLASH}, +   +  {EXIF_IFD_COUNT, 0}	/* end marker */ +}; + +#endif diff --git a/src/imlib.c b/src/imlib.c index eda3e2a..9aa166f 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -612,7 +612,7 @@ void feh_draw_exif(winwidget w)  	int pos2 = 0;  	char info_line[256];  	char *info_buf[128]; -	char buffer[MAX_EXIF_DATA]; +	char buffer[EXIF_MAX_DATA];  	if ( (!w->file) || (!FEH_FILE(w->file->data))  			 || (!FEH_FILE(w->file->data)->filename) ) @@ -622,20 +622,20 @@ void feh_draw_exif(winwidget w)  	buffer[0] = '\0'; -	exif_get_info(FEH_FILE(w->file->data)->ed, buffer, MAX_EXIF_DATA); +	exif_get_info(FEH_FILE(w->file->data)->ed, buffer, EXIF_MAX_DATA);  	fn = feh_load_font(w);  	if (buffer == NULL)   	{ -		snprintf(buffer, MAX_EXIF_DATA, "%s", estrdup("Failed to run exif command")); +		snprintf(buffer, EXIF_MAX_DATA, "%s", estrdup("Failed to run exif command"));  		gib_imlib_get_text_size(fn, &buffer[0], NULL, &width, &height, IMLIB_TEXT_TO_RIGHT);  		no_lines = 1;  	}  	else   	{ -		while ( (no_lines < 128) && (pos < MAX_EXIF_DATA) ) +		while ( (no_lines < 128) && (pos < EXIF_MAX_DATA) )  		{  			/* max 128 lines */  			pos2 = 0; @@ -648,7 +648,7 @@ void feh_draw_exif(winwidget w)  			  }  			  else if ( buffer[pos] == '\0' )  			  { -			    pos = MAX_EXIF_DATA; /* all data seen */ +			    pos = EXIF_MAX_DATA; /* all data seen */  			    info_line[pos2] = '\0';  				}  			  else | 
