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 |