diff options
Diffstat (limited to 'src/exif.c')
| -rw-r--r-- | src/exif.c | 239 | 
1 files changed, 158 insertions, 81 deletions
| @@ -28,16 +28,19 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  #include <stdio.h>  #include <string.h>  #include <libexif/exif-data.h> +#include <limits.h>  #include "feh.h"  #include "options.h"  #include "debug.h"  #include "exif.h" +#include "exif_canon.h"  #include "exif_nikon.h" +#include "exif_cfg.h"  /* remove all spaces on the right end of a string */ -static void exif_trim_spaces(char *str) +void exif_trim_spaces(char *str)  {    char *end; @@ -45,25 +48,27 @@ static void exif_trim_spaces(char *str)    {      if (*str != ' ')      { -      end = str+1; +      end = str + 1;      }    }    *end = '\0';  } -/* show given exif tag content */ -static void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize) -{ -  char s[MAX_EXIF_DATA]; -  if ( (d != NULL) && (buffer != NULL) && (maxsize>0) ) +/* show given exif tag content with tag name */ +void exif_get_tag(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) )    { -    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,8 +83,36 @@ static void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, un +/* show given exif tag content without tag name */ +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 - %s\n", 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) +void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsigned int maxsize)  {    ExifMnoteData *mn = NULL;     int i, num; @@ -101,6 +134,11 @@ static void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsi      /* Loop through all MakerNote tags, searching for the desired one */      for (i=0; i < num; ++i)       { +      D(("%d/%d %d 0x%2x %s; %s\n", i, num, exif_mnote_data_get_id(mn, i),  +        exif_mnote_data_get_id(mn, i), +        exif_mnote_data_get_name(mn,i),  +        exif_mnote_data_get_title(mn, i) )); +              if (exif_mnote_data_get_id(mn, i) == tag)         {          if (exif_mnote_data_get_value(mn, i, buf, sizeof(buf)))  @@ -109,6 +147,7 @@ static void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsi            exif_trim_spaces(buf);            if (*buf != '\0')            { +             D(("%s\n", buf));               snprintf(buffer, (size_t)maxsize, "%s: %s\n", exif_mnote_data_get_title(mn, i), buf);            }          } @@ -119,6 +158,70 @@ static void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsi +/* get gps coordinates if available */ +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 +239,14 @@ ExifData * exif_get_data(char *path) -/* get exif data in readable form */ + +/* get all 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]; +  unsigned short int i = 0; +      if ( (buffer == NULL) || (maxsize == 0) )    {      return; @@ -156,27 +258,14 @@ 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)); - -    /* vendor specific makernote tags */ +    /* show normal exif tags. list must be defined in exif_cfg.h  */ +    while ( (Exif_tag_list[i].ifd != EXIF_IFD_COUNT) && (i < USHRT_MAX) ) +    { +      exif_get_tag(ed, Exif_tag_list[i].ifd, Exif_tag_list[i].tag, buffer + strlen(buffer), maxsize - strlen(buffer)); +      i++;  +    } + +    /* show vendor specific makernote tags */      entry = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);      if (entry != NULL)       { @@ -184,58 +273,46 @@ void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize)        if (exif_entry_get_value(entry, buf, sizeof(buf)))         {          exif_trim_spaces(buf); -         -        /* Nikon */                                     -        if ( 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) ) +        if ( (strcmp(buf, "NIKON CORPORATION") == 0) +             || (strcmp(buf, "Nikon") == 0)  +             || (strcmp(buf, "NIKON") == 0) +           ) +        { +          /* show nikon makernote exif tags. list must be defined in exif_cfg.h  */ +          i=0; +          while ( (Exif_makernote_nikon_tag_list[i] != EXIF_NIKON_MAKERNOTE_END) && (i < USHRT_MAX) )            { -            /* 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]); -            } +            exn_get_mnote_nikon_tags(ed, Exif_makernote_nikon_tag_list[i],  +                                     buffer + strlen(buffer), maxsize - strlen(buffer)); +            i++;             } -          /* 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));          } - +        else if ( (strcmp(buf, "Canon") == 0) ) +        { +          /* show canon makernote exif tags. list must be defined in exif_cfg.h  */ +          i=0; +          while ( (Exif_makernote_canon_tag_list[i] != EXIF_CANON_MAKERNOTE_END) && (i < USHRT_MAX) ) +          { +            exc_get_mnote_canon_tags(ed, Exif_makernote_canon_tag_list[i],  +                                     buffer + strlen(buffer), maxsize - strlen(buffer)); +            i++;  +          } +         +        } +        else +        { +        }        } +            } +     +    /* show gps coordinates */ +    exif_get_gps_coords(ed, buffer + strlen(buffer), maxsize - strlen(buffer)); +    } +    }  #endif | 
