From 46801fee8de26f4e0af2ed294c3a4f7fc1c45ca3 Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Tue, 28 Feb 2012 22:34:51 +0100 Subject: test file with some exif data added --- config.mk | 2 +- test/ok/jpg_exif | Bin 0 -> 9821 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 test/ok/jpg_exif diff --git a/config.mk b/config.mk index 501ec89..d6a5a4f 100644 --- a/config.mk +++ b/config.mk @@ -21,7 +21,7 @@ curl ?= 1 debug ?= 0 help ?= 0 xinerama ?= 1 -exif ?= 0 +exif ?= 1 ifeq (${curl},1) CFLAGS += -DHAVE_LIBCURL diff --git a/test/ok/jpg_exif b/test/ok/jpg_exif new file mode 100644 index 0000000..34c3846 Binary files /dev/null and b/test/ok/jpg_exif differ -- cgit v1.2.3 From fe9a16bce3f06d45acf103fc4439c1af2dc4ac6c Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Tue, 28 Feb 2012 22:37:22 +0100 Subject: test case adapted to new testfile --- test/list/filename_recursive | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/list/filename_recursive b/test/list/filename_recursive index d4d27dd..6e2de8a 100644 --- a/test/list/filename_recursive +++ b/test/list/filename_recursive @@ -1,6 +1,7 @@ NUM FORMAT WIDTH HEIGHT PIXELS SIZE ALPHA FILENAME 1 gif 16 16 256 953 - test/ok/gif 2 jpeg 16 16 256 354 - test/ok/jpg -3 png 16 16 256 403 X test/ok/png -4 pnm 16 16 256 269 - test/ok/pnm -5 png 16 16 256 403 X test/ok/recursive/png +3 jpeg 16 16 256 9k - test/ok/jpg_exif +4 png 16 16 256 403 X test/ok/png +5 pnm 16 16 256 269 - test/ok/pnm +6 png 16 16 256 403 X test/ok/recursive/png -- cgit v1.2.3 From bb3c9d3571e43f913c6f659fefd9cd34971fd004 Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Tue, 28 Feb 2012 22:34:51 +0100 Subject: test file with some exif data added --- config.mk | 2 +- test/ok/jpg_exif | Bin 0 -> 9821 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 test/ok/jpg_exif diff --git a/config.mk b/config.mk index 501ec89..d6a5a4f 100644 --- a/config.mk +++ b/config.mk @@ -21,7 +21,7 @@ curl ?= 1 debug ?= 0 help ?= 0 xinerama ?= 1 -exif ?= 0 +exif ?= 1 ifeq (${curl},1) CFLAGS += -DHAVE_LIBCURL diff --git a/test/ok/jpg_exif b/test/ok/jpg_exif new file mode 100644 index 0000000..34c3846 Binary files /dev/null and b/test/ok/jpg_exif differ -- cgit v1.2.3 From 1c89da1269089d98529a6635c36d014da1b08eb4 Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Tue, 28 Feb 2012 22:37:22 +0100 Subject: test case adapted to new testfile --- test/list/filename_recursive | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/list/filename_recursive b/test/list/filename_recursive index d4d27dd..6e2de8a 100644 --- a/test/list/filename_recursive +++ b/test/list/filename_recursive @@ -1,6 +1,7 @@ NUM FORMAT WIDTH HEIGHT PIXELS SIZE ALPHA FILENAME 1 gif 16 16 256 953 - test/ok/gif 2 jpeg 16 16 256 354 - test/ok/jpg -3 png 16 16 256 403 X test/ok/png -4 pnm 16 16 256 269 - test/ok/pnm -5 png 16 16 256 403 X test/ok/recursive/png +3 jpeg 16 16 256 9k - test/ok/jpg_exif +4 png 16 16 256 403 X test/ok/png +5 pnm 16 16 256 269 - test/ok/pnm +6 png 16 16 256 403 X test/ok/recursive/png -- cgit v1.2.3 From 9e1bbf874500e99506baffec3c6b54ed04e60a2f Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Fri, 16 Mar 2012 22:20:58 +0100 Subject: - exif handling changed - gps info added if available --- src/exif.c | 252 ++++++++++++++++++++++++++++++++++++++++----------------- src/exif.h | 5 +- src/exif_cfg.h | 61 ++++++++++++++ src/imlib.c | 10 +-- 4 files changed, 250 insertions(+), 78 deletions(-) create mode 100644 src/exif_cfg.h diff --git a/src/exif.c b/src/exif.c index dcf2a88..6f6440f 100644 --- a/src/exif.c +++ b/src/exif.c @@ -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 diff --git a/src/exif.h b/src/exif.h index 4d72a57..5d7def4 100644 --- a/src/exif.h +++ b/src/exif.h @@ -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 + +#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 + +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 -- cgit v1.2.3 From e401bd9c78a82b8290ec524e56b7c832631725e6 Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Wed, 21 Mar 2012 19:47:15 +0100 Subject: 1. Own module for nikon maker notes 2. Support for AFInfo2 --- src/exif.c | 99 +++++---------------- src/exif.h | 5 ++ src/exif_nikon.c | 265 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/exif_nikon.h | 14 +-- 4 files changed, 296 insertions(+), 87 deletions(-) create mode 100644 src/exif_nikon.c diff --git a/src/exif.c b/src/exif.c index 6f6440f..91e1735 100644 --- a/src/exif.c +++ b/src/exif.c @@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include #include "feh.h" #include "options.h" @@ -36,15 +37,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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) +void exif_trim_spaces(char *str) { char *end; @@ -52,20 +47,21 @@ static void exif_trim_spaces(char *str) { if (*str != ' ') { - end = str+1; + end = str + 1; } } *end = '\0'; } + /* show given exif tag content with tag name */ -static void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize) +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) ) + if ( (d != NULL) && (buffer != NULL) && (maxsize > 0) ) { entry = exif_content_get_entry(d->ifd[ifd], tag); if (entry != NULL) @@ -87,12 +83,12 @@ 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) +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) ) + if ( (d != NULL) && (buffer != NULL) && (maxsize > 0) ) { entry = exif_content_get_entry(d->ifd[ifd], tag); if (entry != NULL) @@ -104,7 +100,7 @@ static void exif_get_tag_content(ExifData *d, ExifIfd ifd, ExifTag tag, char* bu exif_trim_spaces(s); if (*s != '\0') { - D(("%s", exif_tag_get_name_in_ifd(tag,ifd), s)); + D(("%s - %s\n", exif_tag_get_name_in_ifd(tag,ifd), s)); snprintf(buffer, (size_t)maxsize, "%s", s); } } @@ -115,7 +111,7 @@ static void exif_get_tag_content(ExifData *d, ExifIfd ifd, ExifTag tag, char* bu /* 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; @@ -137,6 +133,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))) @@ -145,6 +146,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); } } @@ -155,63 +157,8 @@ 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) +void exif_get_gps_coords(ExifData * ed, char *buffer, unsigned int maxsize) { char buf[EXIF_STD_BUF_LEN]; @@ -297,7 +244,7 @@ void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize) { ExifEntry *entry = NULL; char buf[EXIF_STD_BUF_LEN]; - int i = 0; + unsigned short int i = 0; if ( (buffer == NULL) || (maxsize == 0) ) { @@ -310,14 +257,14 @@ void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize) } else { - /* normal exif tags */ - while ( Exif_tag_list[i].ifd != EXIF_IFD_COUNT ) + /* 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++; } - /* vendor specific makernote tags */ + /* show vendor specific makernote tags */ entry = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE); if (entry != NULL) { @@ -332,14 +279,14 @@ void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize) ) { /* this is a nikon camera */ - exif_get_mnote_nikon_tags(ed, buffer + strlen(buffer), maxsize - strlen(buffer)); + exn_get_mnote_nikon_tags(ed, buffer + strlen(buffer), maxsize - strlen(buffer)); } } } - /* gps info */ + /* show gps coordinates */ exif_get_gps_coords(ed, buffer + strlen(buffer), maxsize - strlen(buffer)); } diff --git a/src/exif.h b/src/exif.h index 5d7def4..79187f4 100644 --- a/src/exif.h +++ b/src/exif.h @@ -31,6 +31,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define EXIF_MAX_DATA 1024 #define EXIF_STD_BUF_LEN 128 +extern void exif_trim_spaces(char *str); +extern void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize); +extern void exif_get_tag_content(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize); +extern void exif_get_mnote_tag(ExifData *d, unsigned int tag, char* buffer, unsigned int maxsize); +extern void exif_get_gps_coords(ExifData * ed, char *buffer, unsigned int maxsize); extern ExifData * exif_get_data(char *path); extern void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize); diff --git a/src/exif_nikon.c b/src/exif_nikon.c new file mode 100644 index 0000000..d9e83a1 --- /dev/null +++ b/src/exif_nikon.c @@ -0,0 +1,265 @@ +/* exif_nikon.c + +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. + +*/ + +#ifdef HAVE_LIBEXIF + +#include +#include +#include + +#include "feh.h" +#include "debug.h" +#include "exif.h" +#include "exif_nikon.h" + + +/* Flash control mode */ +/* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#FlashControlMode */ +#define EXN_FLASH_CONTROL_MODES_MAX 9 +char *EXN_NikonFlashControlModeValues[EXN_FLASH_CONTROL_MODES_MAX] = {"Off", + "iTTL-BL", "iTTL", "Auto Aperture", + "Automatic", "GN (distance priority)", + "Manual", "Repeating Flash", + "N/A" /* "N/A" is not a nikon setting */ + }; + +#define EXN_FLASH_CONTROL_MODE_MASK 0x7F + + +/* AFInfo2 */ +/* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#AFInfo2 */ +#define EXN_CONTRAST_DETECT_AF_MAX 2 +char *EXN_NikonContrastDetectAF[EXN_CONTRAST_DETECT_AF_MAX] = {"Off", "On"}; + +/* AFArea Mode for ContrastDetectAF Off */ +#define EXN_AF_AREA_MODE_P_MAX 13 +char *EXN_NikonAFAreaModePhase[EXN_AF_AREA_MODE_P_MAX] = { + "Single Area", "Dynamic Area", "Dynamic Area (closest subject)", + "Group Dynamic ", "Dynamic Area (9 points) ", "Dynamic Area (21 points)", + "Dynamic Area (51 points) ", "Dynamic Area (51 points, 3D-tracking)", + "Auto-area", "Dynamic Area (3D-tracking)", "Single Area (wide)", + "Dynamic Area (wide)", "Dynamic Area (wide, 3D-tracking)"}; + +/* AFArea Mode for ContrastDetectAF On */ +#define EXN_AF_AREA_MODE_C_MAX 5 +char *EXN_NikonAFAreaModeContr[EXN_AF_AREA_MODE_C_MAX] = { + "Contrast-detect", + "Contrast-detect (normal area)", + "Contrast-detect (wide area)", + "Contrast-detect (face priority)", + "Contrast-detect (subject tracking)"}; + +#define EXN_PHASE_DETECT_AF_MAX 4 +char *EXN_NikonPhaseDetectAF[EXN_PHASE_DETECT_AF_MAX] = {"Off", "On (51-point)", + "On (11-point)", "On (39-point)"}; + +/* PrimaryAFPoint and AFPointsUsed only valid with PhaseDetectAF == On */ + +#define EXN_PRIM_AF_PT_51_MAX 52 +char * EXN_Prim_AF_Pt_51[EXN_PRIM_AF_PT_51_MAX] = {"(none)", "C6 (Center)", "B6", "A5", + "D6", "E5", "C7", "B7", "A6", "D7", "E6", "C5", "B5", "A4", "D5", "E4", "C8", "B8", + "A7", "D8", "E7", "C9", "B9", "A8", "D9", "E8", "C10", "B10", "A9", "D10", "E9", + "C11", "B11", "D11", "C4", "B4", "A3", "D4", "E3", "C3", "B3", "A2", "D3", "E2", + "C2", "B2", "A1", "D2", "E1", "C1", "B1", "D1"}; + +#define EXN_PRIM_AF_PT_11_MAX 12 +char * EXN_Prim_AF_Pt_11[EXN_PRIM_AF_PT_11_MAX] = {"(none)", "Center", "Top", "Bottom", + "Mid-left", "Upper-left", "Lower-left", "Far Left", "Mid-right", "Upper-right", + "Lower-right", "Far Right"}; + +#define EXN_PRIM_AF_PT_39_MAX 40 +char * EXN_Prim_AF_Pt_39[EXN_PRIM_AF_PT_39_MAX] = {"(none)", "C6 (Center)", "B6", "A2", + "D6", "E2", "C7", "B7", "A3", "D7", "E3", "C5", "B5", "A1", "D5", "E1", "C8", "B8", + "D8", "C9", "B9", "D9", "C10", "B10", "D10", "C11", "B11", "D11", "C4", "B4", "D4", + "C3", "B3", "D3", "C2", "B2", "D2", "C1", "B1", "D1"}; + + +static void exn_get_prim_af_pt(unsigned int phasedetectaf, + unsigned int primafpt, + char * buffer, + unsigned int maxsize); + + + + +static void exn_get_prim_af_pt(unsigned int phasedetectaf, + unsigned int primafpt, + char * buffer, + unsigned int maxsize) +{ + + switch(phasedetectaf) + { + case 0: + { + /* phasedetect not used. should not happen */ + snprintf(buffer, maxsize, "FAIL"); + return; + } + break; + case 1: + { + /* 51 pt */ + if ( primafpt < EXN_PRIM_AF_PT_51_MAX ) + { + snprintf(buffer, maxsize, "%s", EXN_Prim_AF_Pt_51[primafpt]); + } + return; + } + break; + case 2: + { + /* 11 pt */ + if ( primafpt < EXN_PRIM_AF_PT_11_MAX ) + { + snprintf(buffer, maxsize, "%s", EXN_Prim_AF_Pt_11[primafpt]); + } + return; + } + break; + case 3: + { + /* 39 pt */ + if ( primafpt < EXN_PRIM_AF_PT_39_MAX ) + { + snprintf(buffer, maxsize, "%s", EXN_Prim_AF_Pt_39[primafpt]); + } + return; + } + break; + default: + { + snprintf(buffer, maxsize, "?"); + return; + } + break; + + } + +} + + + +/* get interesting nikon maker note tags in readable form */ +void exn_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; + unsigned int contrastdetectaf = 0; + unsigned int afareamode = 0; + unsigned int phasedetectaf = 0; + unsigned int primaryafpoint = 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)); + + /* AFInfo2 */ + /* libexif does not support AFInfo2 183 yet. so we have to parse the debug data :-( */ + buf[0] = '\0'; + exif_get_mnote_tag(ed, 183, buf, sizeof(buf)); + sscanf(buf, "(null): %u bytes unknown data: 303130%02X%02X%02X%02X%02X", &length, &version, + &contrastdetectaf, + &afareamode, + &phasedetectaf, + &primaryafpoint + ); + + + if ( ((length == 30) && (version == '0')) + && (contrastdetectaf < EXN_CONTRAST_DETECT_AF_MAX) + && (phasedetectaf < EXN_PHASE_DETECT_AF_MAX) + + ) + { + if ( (contrastdetectaf != 0) && (afareamode < EXN_AF_AREA_MODE_C_MAX) ) + { + /* Contrast AF (live view) */ + snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), + "ContrastDetectAF: %s; AFAreaMode: %s\n", + EXN_NikonContrastDetectAF[contrastdetectaf], + EXN_NikonAFAreaModeContr[afareamode]); + + } + else if ( (phasedetectaf != 0) && (afareamode < EXN_AF_AREA_MODE_P_MAX) ) + { + /* Phase AF */ + buf[0] = '\0'; + exn_get_prim_af_pt(phasedetectaf, primaryafpoint, buf, EXIF_STD_BUF_LEN); + + snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), + "PhaseDetectAF: %s; AreaMode: %s; PrimaryAFPoint: %s\n", + EXN_NikonPhaseDetectAF[phasedetectaf], + EXN_NikonAFAreaModePhase[afareamode], + buf + ); + } + + } + + return; +} + +#endif diff --git a/src/exif_nikon.h b/src/exif_nikon.h index e2baf0d..f12b5ce 100644 --- a/src/exif_nikon.h +++ b/src/exif_nikon.h @@ -26,16 +26,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef EXIF_NIKON_H #define EXIF_NIKON_H -/* Flash control mode */ -/* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#FlashControlMode */ -#define EXN_FLASH_CONTROL_MODES_MAX 9 -char *EXN_NikonFlashControlModeValues[EXN_FLASH_CONTROL_MODES_MAX] = {"Off", - "iTTL-BL", "iTTL", "Auto Aperture", - "Automatic", "GN (distance priority)", - "Manual", "Repeating Flash", - "N/A" /* "N/A" is not a nikon setting */ - }; - -#define EXN_FLASH_CONTROL_MODE_MASK 0x7F +#include + +extern void exn_get_mnote_nikon_tags(ExifData *ed, char * buffer, unsigned int maxsize); #endif -- cgit v1.2.3 From cc6de20061eaa7172aa0184e03df947da14d713e Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Thu, 22 Mar 2012 19:00:30 +0100 Subject: Nikon makernote parts changed --- src/exif.c | 11 +++- src/exif_cfg.h | 21 +++++++- src/exif_nikon.c | 161 +++++++++++++++++++++++++++++++++++-------------------- src/exif_nikon.h | 2 +- 4 files changed, 133 insertions(+), 62 deletions(-) diff --git a/src/exif.c b/src/exif.c index 91e1735..ed18eb5 100644 --- a/src/exif.c +++ b/src/exif.c @@ -279,7 +279,16 @@ void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize) ) { /* this is a nikon camera */ - exn_get_mnote_nikon_tags(ed, buffer + strlen(buffer), maxsize - strlen(buffer)); + + /* 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) ) + { + exn_get_mnote_nikon_tags(ed, Exif_makernote_nikon_tag_list[i], + buffer + strlen(buffer), maxsize - strlen(buffer)); + i++; + } + } } diff --git a/src/exif_cfg.h b/src/exif_cfg.h index c828f43..5ceb357 100644 --- a/src/exif_cfg.h +++ b/src/exif_cfg.h @@ -34,8 +34,8 @@ typedef struct 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}, @@ -58,4 +58,23 @@ const t_EXIF_INFO Exif_tag_list [] = {EXIF_IFD_COUNT, 0} /* end marker */ }; + +#define EXIF_NIKON_MAKERNOTE_END 0 /* end marker: if 0 used as a tag we must find something else */ + +/* show these nikon makernote tags */ +const unsigned int Exif_makernote_nikon_tag_list [] = +{ + 8, /* Flash Setting */ + 9, /* Flash Mode */ + 24, /* Flash exposure bracket value */ + 135, /* Flash used */ + 168, /* Flash info: control mode */ + + 132, /* Lens */ + 171, /* Digital Vari-Program */ + 183, /* AFInfo2 */ + + EXIF_NIKON_MAKERNOTE_END /* end marker */ +}; + #endif diff --git a/src/exif_nikon.c b/src/exif_nikon.c index d9e83a1..42f1137 100644 --- a/src/exif_nikon.c +++ b/src/exif_nikon.c @@ -100,10 +100,12 @@ static void exn_get_prim_af_pt(unsigned int phasedetectaf, unsigned int primafpt, char * buffer, unsigned int maxsize); - - - +static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int maxsize); +static void exn_get_mnote_nikon_183(ExifData *ed, char * buffer, unsigned int maxsize); + + +/* get primary AF point */ static void exn_get_prim_af_pt(unsigned int phasedetectaf, unsigned int primafpt, char * buffer, @@ -162,59 +164,46 @@ static void exn_get_prim_af_pt(unsigned int phasedetectaf, -/* get interesting nikon maker note tags in readable form */ -void exn_get_mnote_nikon_tags(ExifData *ed, char * buffer, unsigned int maxsize) +/* get nikon Flash info: control mode (168) info */ +static void exn_get_mnote_nikon_168(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; - unsigned int contrastdetectaf = 0; - unsigned int afareamode = 0; - unsigned int phasedetectaf = 0; - unsigned int primaryafpoint = 0; + unsigned int exn_fcm = (EXN_FLASH_CONTROL_MODES_MAX-1); /* default to N/A */ + /* libexif does not support flash info 168 yet. so we have to parse the debug data :-( */ 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) ) + 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 */ + ) + ) { - /* 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]); - } + 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)); +} + + + +/* get nikon AFInfo2 (183) info */ +static void exn_get_mnote_nikon_183(ExifData *ed, char * buffer, unsigned int maxsize) +{ + char buf[EXIF_STD_BUF_LEN]; + unsigned int contrastdetectaf = 0; + unsigned int afareamode = 0; + unsigned int phasedetectaf = 0; + unsigned int primaryafpoint = 0; + unsigned int version = 0; + unsigned int length = 0; /* AFInfo2 */ /* libexif does not support AFInfo2 183 yet. so we have to parse the debug data :-( */ @@ -231,34 +220,88 @@ void exn_get_mnote_nikon_tags(ExifData *ed, char * buffer, unsigned int maxsize) if ( ((length == 30) && (version == '0')) && (contrastdetectaf < EXN_CONTRAST_DETECT_AF_MAX) && (phasedetectaf < EXN_PHASE_DETECT_AF_MAX) - - ) + ) { if ( (contrastdetectaf != 0) && (afareamode < EXN_AF_AREA_MODE_C_MAX) ) { /* Contrast AF (live view) */ snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), - "ContrastDetectAF: %s; AFAreaMode: %s\n", - EXN_NikonContrastDetectAF[contrastdetectaf], - EXN_NikonAFAreaModeContr[afareamode]); - + "ContrastDetectAF: %s; AFAreaMode: %s\n", + EXN_NikonContrastDetectAF[contrastdetectaf], + EXN_NikonAFAreaModeContr[afareamode]); + } else if ( (phasedetectaf != 0) && (afareamode < EXN_AF_AREA_MODE_P_MAX) ) { /* Phase AF */ buf[0] = '\0'; exn_get_prim_af_pt(phasedetectaf, primaryafpoint, buf, EXIF_STD_BUF_LEN); - + snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), - "PhaseDetectAF: %s; AreaMode: %s; PrimaryAFPoint: %s\n", - EXN_NikonPhaseDetectAF[phasedetectaf], - EXN_NikonAFAreaModePhase[afareamode], - buf - ); + "PhaseDetectAF: %s; AreaMode: %s; PrimaryAFPoint: %s\n", + EXN_NikonPhaseDetectAF[phasedetectaf], + EXN_NikonAFAreaModePhase[afareamode], + buf + ); } + + } +} + + + +/* get interesting nikon maker note tags in readable form */ +void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, unsigned int maxsize) +{ + char buf[EXIF_STD_BUF_LEN]; + + buf[0] = '\0'; + exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buf, sizeof(buf)); + exif_trim_spaces(buf); + + switch(tag) + { + /* show only if flash was used */ + case 8: /* Flash Setting */ + case 9: /* Flash Mode */ + case 24: /* Flash exposure bracket value */ + case 135: /* Flash used */ + { + if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) ) + { + /* show extended flash info only if flash was fired */ + exif_get_mnote_tag(ed, tag, buffer + strlen(buffer), maxsize - strlen(buffer)); + } + } + break; + case 168: + { + /* Flash info: control mode */ + if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) ) + { + /* show extended flash info only if flash was fired */ + exn_get_mnote_nikon_168(ed, buffer + strlen(buffer), maxsize - strlen(buffer)); + } + } + break; + + case 183: + { + /* AFInfo 2 */ + exn_get_mnote_nikon_183(ed, buffer + strlen(buffer), maxsize - strlen(buffer)); + } + break; + + default: + { + /* normal makernote tags without special treatment */ + exif_get_mnote_tag(ed, tag, buffer + strlen(buffer), maxsize - strlen(buffer)); + } + break; } + return; } diff --git a/src/exif_nikon.h b/src/exif_nikon.h index f12b5ce..16e8fb9 100644 --- a/src/exif_nikon.h +++ b/src/exif_nikon.h @@ -28,6 +28,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include -extern void exn_get_mnote_nikon_tags(ExifData *ed, char * buffer, unsigned int maxsize); +extern void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, unsigned int maxsize); #endif -- cgit v1.2.3 From 3c284dc81dcb26249114b7ecf32ed0000f492b8b Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Thu, 22 Mar 2012 19:44:32 +0100 Subject: Support for Active D-Lightning --- src/exif_cfg.h | 1 + src/exif_nikon.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/exif_cfg.h b/src/exif_cfg.h index 5ceb357..390c1ad 100644 --- a/src/exif_cfg.h +++ b/src/exif_cfg.h @@ -72,6 +72,7 @@ const unsigned int Exif_makernote_nikon_tag_list [] = 132, /* Lens */ 171, /* Digital Vari-Program */ + 34, /* ActiveD-Lighting */ 183, /* AFInfo2 */ EXIF_NIKON_MAKERNOTE_END /* end marker */ diff --git a/src/exif_nikon.c b/src/exif_nikon.c index 42f1137..753a8bf 100644 --- a/src/exif_nikon.c +++ b/src/exif_nikon.c @@ -100,6 +100,7 @@ static void exn_get_prim_af_pt(unsigned int phasedetectaf, unsigned int primafpt, char * buffer, unsigned int maxsize); +static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int maxsize); static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int maxsize); static void exn_get_mnote_nikon_183(ExifData *ed, char * buffer, unsigned int maxsize); @@ -164,6 +165,63 @@ static void exn_get_prim_af_pt(unsigned int phasedetectaf, +/* get ActiveD-Lighting (34) info */ +static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int maxsize) +{ + char buf[EXIF_STD_BUF_LEN]; + unsigned int data = 0; + char *answer; + + buf[0] = '\0'; + exif_get_mnote_tag(ed, 34, buf, sizeof(buf)); + sscanf(buf, "(null): %u", &data); + + switch(data) + { + case 0: + { + answer = "Off"; + } + break; + case 1: + { + answer = "Low"; + } + break; + case 3: + { + answer = "Normal"; + } + break; + case 5: + { + answer = "High"; + } + break; + case 7: + { + answer = "Extra High"; + } + break; + case 65535: + { + answer = "Auto"; + } + break; + default: + { + answer = "N/A"; /* this is not a nikon value */ + } + + } + + snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "Active D-Lightning: %s\n", + answer); + +} + + + /* get nikon Flash info: control mode (168) info */ static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int maxsize) { @@ -274,6 +332,13 @@ void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, uns } } break; + + case 34: + { + /* ActiveD-Lighting */ + exn_get_mnote_nikon_34(ed, buffer + strlen(buffer), maxsize - strlen(buffer)); + } + break; case 168: { -- cgit v1.2.3 From 10b7b1e3e10ba650b240a742947cb6850bbadd23 Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Sat, 24 Mar 2012 14:41:15 +0100 Subject: Support for Canon Exif makernote tags --- .gitignore | 3 ++- src/exif.c | 23 ++++++++++++++++----- src/exif_canon.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/exif_canon.h | 33 ++++++++++++++++++++++++++++++ src/exif_cfg.h | 20 ++++++++++++++++++- src/exif_nikon.c | 23 ++++++++++----------- 6 files changed, 143 insertions(+), 20 deletions(-) create mode 100644 src/exif_canon.c create mode 100644 src/exif_canon.h diff --git a/.gitignore b/.gitignore index 559c5ab..bbfa508 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ /src/*.inc /src/feh /man/*.1 -*~ \ No newline at end of file +*~ +core diff --git a/src/exif.c b/src/exif.c index ed18eb5..a30b2ef 100644 --- a/src/exif.c +++ b/src/exif.c @@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "options.h" #include "debug.h" #include "exif.h" +#include "exif_canon.h" #include "exif_nikon.h" #include "exif_cfg.h" @@ -239,7 +240,7 @@ 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; @@ -272,14 +273,12 @@ void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize) if (exif_entry_get_value(entry, buf, sizeof(buf))) { exif_trim_spaces(buf); - + if ( (strcmp(buf, "NIKON CORPORATION") == 0) || (strcmp(buf, "Nikon") == 0) || (strcmp(buf, "NIKON") == 0) ) { - /* this is a nikon camera */ - /* 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) ) @@ -290,7 +289,21 @@ void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize) } } - + 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 + { + } } } diff --git a/src/exif_canon.c b/src/exif_canon.c new file mode 100644 index 0000000..8801899 --- /dev/null +++ b/src/exif_canon.c @@ -0,0 +1,61 @@ +/* exif_canon.c + +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. + +*/ + +#ifdef HAVE_LIBEXIF + +#include +#include + +#include "feh.h" +#include "debug.h" +#include "exif.h" +#include "exif_canon.h" + + + +/* get interesting canon maker note tags in readable form */ +void exc_get_mnote_canon_tags(ExifData *ed, unsigned int tag, char * buffer, unsigned int maxsize) +{ + /* char buf[EXIF_STD_BUF_LEN]; + + buf[0] = '\0'; + exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buf, sizeof(buf)); + exif_trim_spaces(buf); */ + + switch(tag) + { + default: + { + /* normal makernote tags without special treatment */ + exif_get_mnote_tag(ed, tag, buffer, maxsize); + } + break; + } + + + return; +} + +#endif diff --git a/src/exif_canon.h b/src/exif_canon.h new file mode 100644 index 0000000..d8682c3 --- /dev/null +++ b/src/exif_canon.h @@ -0,0 +1,33 @@ +/* exif_canon.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_CANON_H +#define EXIF_CANON_H + +#include + +extern void exc_get_mnote_canon_tags(ExifData *ed, unsigned int tag, char * buffer, unsigned int maxsize); + +#endif diff --git a/src/exif_cfg.h b/src/exif_cfg.h index 390c1ad..31acc50 100644 --- a/src/exif_cfg.h +++ b/src/exif_cfg.h @@ -30,7 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. typedef struct { - ExifIfd ifd; /* section */ + ExifIfd ifd; /* section */ ExifTag tag; /* tag */ } t_EXIF_INFO; @@ -59,6 +59,9 @@ const t_EXIF_INFO Exif_tag_list [] = }; + +/* Nikon */ + #define EXIF_NIKON_MAKERNOTE_END 0 /* end marker: if 0 used as a tag we must find something else */ /* show these nikon makernote tags */ @@ -78,4 +81,19 @@ const unsigned int Exif_makernote_nikon_tag_list [] = EXIF_NIKON_MAKERNOTE_END /* end marker */ }; + + +/* Canon */ +#define EXIF_CANON_MAKERNOTE_END 0xFFFF /* end marker: if this is used as a tag we must find something else */ + +/* show these canon makernote tags */ +const unsigned int Exif_makernote_canon_tag_list [] = +{ + 8, /* Image Number */ + 9, /* Owner Name */ + + EXIF_CANON_MAKERNOTE_END /* end marker */ +}; + + #endif diff --git a/src/exif_nikon.c b/src/exif_nikon.c index 753a8bf..f4a8eea 100644 --- a/src/exif_nikon.c +++ b/src/exif_nikon.c @@ -26,7 +26,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef HAVE_LIBEXIF #include -#include #include #include "feh.h" @@ -174,7 +173,7 @@ static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int max buf[0] = '\0'; exif_get_mnote_tag(ed, 34, buf, sizeof(buf)); - sscanf(buf, "(null): %u", &data); + sscanf(buf, "(null): %u", &data); /* not directly supported by libexif yet */ switch(data) { @@ -215,8 +214,7 @@ static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int max } - snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "Active D-Lightning: %s\n", - answer); + snprintf(buffer, maxsize, "Active D-Lightning: %s\n", answer); } @@ -244,8 +242,7 @@ static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int ma ) ) { - snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), "NikonFlashControlMode: %s\n", - EXN_NikonFlashControlModeValues[exn_fcm]); + snprintf(buffer, maxsize, "NikonFlashControlMode: %s\n", EXN_NikonFlashControlModeValues[exn_fcm]); } } @@ -283,7 +280,7 @@ static void exn_get_mnote_nikon_183(ExifData *ed, char * buffer, unsigned int ma if ( (contrastdetectaf != 0) && (afareamode < EXN_AF_AREA_MODE_C_MAX) ) { /* Contrast AF (live view) */ - snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), + snprintf(buffer, maxsize, "ContrastDetectAF: %s; AFAreaMode: %s\n", EXN_NikonContrastDetectAF[contrastdetectaf], EXN_NikonAFAreaModeContr[afareamode]); @@ -295,7 +292,7 @@ static void exn_get_mnote_nikon_183(ExifData *ed, char * buffer, unsigned int ma buf[0] = '\0'; exn_get_prim_af_pt(phasedetectaf, primaryafpoint, buf, EXIF_STD_BUF_LEN); - snprintf(buffer + strlen(buffer), maxsize - strlen(buffer), + snprintf(buffer, maxsize, "PhaseDetectAF: %s; AreaMode: %s; PrimaryAFPoint: %s\n", EXN_NikonPhaseDetectAF[phasedetectaf], EXN_NikonAFAreaModePhase[afareamode], @@ -328,7 +325,7 @@ void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, uns if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) ) { /* show extended flash info only if flash was fired */ - exif_get_mnote_tag(ed, tag, buffer + strlen(buffer), maxsize - strlen(buffer)); + exif_get_mnote_tag(ed, tag, buffer, maxsize); } } break; @@ -336,7 +333,7 @@ void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, uns case 34: { /* ActiveD-Lighting */ - exn_get_mnote_nikon_34(ed, buffer + strlen(buffer), maxsize - strlen(buffer)); + exn_get_mnote_nikon_34(ed, buffer, maxsize); } break; @@ -346,7 +343,7 @@ void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, uns if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) ) { /* show extended flash info only if flash was fired */ - exn_get_mnote_nikon_168(ed, buffer + strlen(buffer), maxsize - strlen(buffer)); + exn_get_mnote_nikon_168(ed, buffer, maxsize); } } break; @@ -354,14 +351,14 @@ void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, uns case 183: { /* AFInfo 2 */ - exn_get_mnote_nikon_183(ed, buffer + strlen(buffer), maxsize - strlen(buffer)); + exn_get_mnote_nikon_183(ed, buffer, maxsize); } break; default: { /* normal makernote tags without special treatment */ - exif_get_mnote_tag(ed, tag, buffer + strlen(buffer), maxsize - strlen(buffer)); + exif_get_mnote_tag(ed, tag, buffer, maxsize); } break; } -- cgit v1.2.3 From 586c49b3cc178c1b454749ba1bc76b5814f93737 Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Fri, 21 Dec 2012 22:01:42 +0100 Subject: Some more nikon exif features: - ISO - Whitebalance - PictureControlData - Flash output power --- src/exif_cfg.h | 11 +++++- src/exif_nikon.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 4 deletions(-) diff --git a/src/exif_cfg.h b/src/exif_cfg.h index 31acc50..a3344bc 100644 --- a/src/exif_cfg.h +++ b/src/exif_cfg.h @@ -36,6 +36,7 @@ typedef struct /* show these standard tags. section must be given first, than the tag itself */ +/* definition: http://libexif.sourceforge.net/api/exif-tag_8h.html */ const t_EXIF_INFO Exif_tag_list [] = { {EXIF_IFD_0, EXIF_TAG_MAKE}, @@ -67,15 +68,21 @@ const t_EXIF_INFO Exif_tag_list [] = /* show these nikon makernote tags */ const unsigned int Exif_makernote_nikon_tag_list [] = { + + 6, 8, /* Flash Setting */ 9, /* Flash Mode */ 24, /* Flash exposure bracket value */ 135, /* Flash used */ 168, /* Flash info: control mode */ - + + 2, /* ISO. Has some more info than EXIF_TAG_ISO_SPEED_RATINGS but also fails on Lo.1 */ + 5, /* White Balance */ 132, /* Lens */ 171, /* Digital Vari-Program */ - 34, /* ActiveD-Lighting */ + 34, /* Active D-Lighting */ + + 35, /* PictureControlData */ 183, /* AFInfo2 */ EXIF_NIKON_MAKERNOTE_END /* end marker */ diff --git a/src/exif_nikon.c b/src/exif_nikon.c index f4a8eea..21a2f08 100644 --- a/src/exif_nikon.c +++ b/src/exif_nikon.c @@ -95,11 +95,20 @@ char * EXN_Prim_AF_Pt_39[EXN_PRIM_AF_PT_39_MAX] = {"(none)", "C6 (Center)", "B6" "C3", "B3", "D3", "C2", "B2", "D2", "C1", "B1", "D1"}; +#define EXN_PIC_CTRL_ADJ_MAX 3 +char * EXN_Pic_Ctrl_Adj[EXN_PIC_CTRL_ADJ_MAX] = {"Default Settings", + "Quick Adjust", + "Full Control"}; + + + static void exn_get_prim_af_pt(unsigned int phasedetectaf, unsigned int primafpt, char * buffer, unsigned int maxsize); +static void exn_get_flash_output(unsigned int flashoutput, char * buffer, unsigned int maxsize); static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int maxsize); +static void exn_get_mnote_nikon_35(ExifData *ed, char * buffer, unsigned int maxsize); static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int maxsize); static void exn_get_mnote_nikon_183(ExifData *ed, char * buffer, unsigned int maxsize); @@ -164,6 +173,32 @@ static void exn_get_prim_af_pt(unsigned int phasedetectaf, +/* get flash output power (for FlashInfo010x) */ +static void exn_get_flash_output(unsigned int flashoutput, char * buffer, unsigned int maxsize) +{ + + if ( flashoutput == 0 ) + { + /* full power */ + snprintf(buffer, maxsize, "Full"); + } + else + { + if ( (flashoutput % 6) == 0 ) + { + /* value is a power of 2 */ + snprintf(buffer, maxsize, "1/%d", 1<<(flashoutput/6)); + } + else + { + /* something uneven...ugly. maybe introduce pow() function from libm later */ + snprintf(buffer, maxsize, "1/2^(%f)", ((float)flashoutput)/6.0); + } + } +} + + + /* get ActiveD-Lighting (34) info */ static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int maxsize) { @@ -220,6 +255,63 @@ static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int max +/* get nikon PictureControlData (35) info */ +static void exn_get_mnote_nikon_35(ExifData *ed, char * buffer, unsigned int maxsize) +{ + char buf[EXIF_STD_BUF_LEN]; + char picturecontrolname[EXIF_STD_BUF_LEN]; + char picturecontrolbase[EXIF_STD_BUF_LEN]; + unsigned int version = 0; + unsigned int length = 0; + unsigned int piccontroladj = 0; + unsigned int piccontrolquickadj = 0; + unsigned int sharpness = 0; + unsigned int contrast = 0; + unsigned int brightness = 0; + unsigned int saturation = 0; + unsigned int hueadjustment = 0; + unsigned int i, j; + + /* libexif does not support PictureControlData 35 yet. so we have to parse the debug data :-( */ + buf[0] = '\0'; + exif_get_mnote_tag(ed, 35, buf, sizeof(buf)); + + sscanf(buf, "(null): %u bytes unknown data: 303130%02X%40s%40s%*8s%02X%02X%02X%02X%02X%02X%02X", + &length, &version, &picturecontrolname[0], &picturecontrolbase[0], + &piccontroladj, &piccontrolquickadj, + &sharpness, &contrast, &brightness, &saturation, &hueadjustment + ); + + /* printf("--%s %d-%d-\n", buf, version, piccontroladj); */ + + for ( i=0; i<40; i++ ) + { + sscanf(&picturecontrolname[2*i], "%2X", &j); + picturecontrolname[i] = j; + sscanf(&picturecontrolbase[2*i], "%2X", &j); + picturecontrolbase[i] = j; + + } + exif_trim_spaces(picturecontrolname); + exif_trim_spaces(picturecontrolbase); + + if ( ((length == 58) && (version == '0')) + && (piccontroladj < EXN_PIC_CTRL_ADJ_MAX) + + ) + { + snprintf(buffer, maxsize, + "PictCtrlData: Name: %s; Base: %s; CtrlAdj: %s; Quick: %d; Shrp: %d; Contr: %d; Brght: %d; Sat: %d; Hue: %d\n", + picturecontrolname, picturecontrolbase, + EXN_Pic_Ctrl_Adj[piccontroladj], piccontrolquickadj, + sharpness, contrast, brightness, saturation, hueadjustment); + } + +} + + + + /* get nikon Flash info: control mode (168) info */ static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int maxsize) { @@ -227,11 +319,13 @@ static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int ma unsigned int version = 0; unsigned int length = 0; unsigned int exn_fcm = (EXN_FLASH_CONTROL_MODES_MAX-1); /* default to N/A */ + unsigned int flashoutput = 0; + unsigned int externalflashflags = 0; /* 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); + sscanf(buf, "(null): %u bytes unknown data: 303130%02X%*8s%02X%02X%02X", &length, &version, &externalflashflags, &exn_fcm, &flashoutput); exn_fcm = exn_fcm & EXN_FLASH_CONTROL_MODE_MASK; if ( (exn_fcm < EXN_FLASH_CONTROL_MODES_MAX) @@ -242,7 +336,16 @@ static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int ma ) ) { - snprintf(buffer, maxsize, "NikonFlashControlMode: %s\n", EXN_NikonFlashControlModeValues[exn_fcm]); + + buf[0] = '\0'; + exn_get_flash_output(flashoutput, buf, EXIF_STD_BUF_LEN); + snprintf(buffer, maxsize, "NikonFlashControlMode: %s (Power: %s)\n", EXN_NikonFlashControlModeValues[exn_fcm], buf); + + /* External Flash Flags. Not as useful as expected. Not used (yet). */ + /* if ( (externalflashflags & (1<<2)) ) -> Bounce Flash */ + /* if ( (externalflashflags & (1<<4)) ) -> Wide Flash Adapter */ + /* if ( (externalflashflags & (1<<5)) ) -> Dome Diffusor */ + } } @@ -336,6 +439,13 @@ void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, uns exn_get_mnote_nikon_34(ed, buffer, maxsize); } break; + + case 35: + { + /* PictureControlData */ + exn_get_mnote_nikon_35(ed, buffer, maxsize); + } + break; case 168: { -- cgit v1.2.3 From 008ab7fc0f43161e0eedfddbaa80fe28c4f9ff13 Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Fri, 4 Jan 2013 00:09:31 +0100 Subject: Workaround for broken Flash Exposure Compensation --- src/exif_cfg.h | 2 +- src/exif_nikon.c | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/exif_cfg.h b/src/exif_cfg.h index a3344bc..a961147 100644 --- a/src/exif_cfg.h +++ b/src/exif_cfg.h @@ -72,8 +72,8 @@ const unsigned int Exif_makernote_nikon_tag_list [] = 6, 8, /* Flash Setting */ 9, /* Flash Mode */ - 24, /* Flash exposure bracket value */ 135, /* Flash used */ + 18, /* Flash Exposure Comp */ 168, /* Flash info: control mode */ 2, /* ISO. Has some more info than EXIF_TAG_ISO_SPEED_RATINGS but also fails on Lo.1 */ diff --git a/src/exif_nikon.c b/src/exif_nikon.c index 21a2f08..7ee6e86 100644 --- a/src/exif_nikon.c +++ b/src/exif_nikon.c @@ -107,6 +107,7 @@ static void exn_get_prim_af_pt(unsigned int phasedetectaf, char * buffer, unsigned int maxsize); static void exn_get_flash_output(unsigned int flashoutput, char * buffer, unsigned int maxsize); +static void exn_get_mnote_nikon_18(ExifData *ed, char * buffer, unsigned int maxsize); static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int maxsize); static void exn_get_mnote_nikon_35(ExifData *ed, char * buffer, unsigned int maxsize); static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int maxsize); @@ -199,6 +200,23 @@ static void exn_get_flash_output(unsigned int flashoutput, char * buffer, unsign +/* get ActiveD-Lighting (18) info */ +static void exn_get_mnote_nikon_18(ExifData *ed, char * buffer, unsigned int maxsize) +{ + + char buf[EXIF_STD_BUF_LEN]; + float data = 0; + + buf[0] = '\0'; + exif_get_mnote_tag(ed, 18, buf, sizeof(buf)); + + sscanf(buf, "Flash Exposure Compensation: %f", &data); /* libexif buggy here. fix conversion */ + + snprintf(buffer, maxsize, "FlashExposureCompensation: %.1f\n", ((float)((signed char)round(data*6.0))) / 6.0 ); +} + + + /* get ActiveD-Lighting (34) info */ static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int maxsize) { @@ -321,13 +339,16 @@ static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int ma unsigned int exn_fcm = (EXN_FLASH_CONTROL_MODES_MAX-1); /* default to N/A */ unsigned int flashoutput = 0; unsigned int externalflashflags = 0; + unsigned int flashcompensation = 0; /* 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%*8s%02X%02X%02X", &length, &version, &externalflashflags, &exn_fcm, &flashoutput); + sscanf(buf, "(null): %u bytes unknown data: 303130%02X%*8s%02X%02X%02X%02X", &length, &version, &externalflashflags, &exn_fcm, &flashoutput, &flashcompensation); exn_fcm = exn_fcm & EXN_FLASH_CONTROL_MODE_MASK; + /* printf("%s - %d %d %d %d\n", buf, externalflashflags, exn_fcm, flashoutput, (signed char)flashcompensation); */ + if ( (exn_fcm < EXN_FLASH_CONTROL_MODES_MAX) && ( ((length == 22) && (version == '3')) /* Nikon FlashInfo0103 */ || ((length == 22) && (version == '4')) /* Nikon FlashInfo0104 */ @@ -422,7 +443,7 @@ void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, uns /* show only if flash was used */ case 8: /* Flash Setting */ case 9: /* Flash Mode */ - case 24: /* Flash exposure bracket value */ + case 27: /* Flash exposure bracket value */ case 135: /* Flash used */ { if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) ) @@ -433,6 +454,16 @@ void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, uns } break; + case 18: /* FlashExposureComp */ + { + if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) ) + { + /* show only if flash was fired */ + exn_get_mnote_nikon_18(ed, buffer, maxsize); + } + } + break; + case 34: { /* ActiveD-Lighting */ -- cgit v1.2.3 From 57719cc56157d31b69c2176921f77389e18f698f Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Fri, 4 Jan 2013 00:28:29 +0100 Subject: Flash Exposure Compensation (Nikon) --- src/exif_nikon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/exif_nikon.c b/src/exif_nikon.c index 7ee6e86..a223043 100644 --- a/src/exif_nikon.c +++ b/src/exif_nikon.c @@ -212,7 +212,7 @@ static void exn_get_mnote_nikon_18(ExifData *ed, char * buffer, unsigned int max sscanf(buf, "Flash Exposure Compensation: %f", &data); /* libexif buggy here. fix conversion */ - snprintf(buffer, maxsize, "FlashExposureCompensation: %.1f\n", ((float)((signed char)round(data*6.0))) / 6.0 ); + snprintf(buffer, maxsize, "FlashExposureCompensation: %+.1f EV\n", ((float)((signed char)round(data*6.0))) / 6.0 ); } -- cgit v1.2.3 From 38c3c37b5c45691211ed62e40a6c5f503b054335 Mon Sep 17 00:00:00 2001 From: Dennis Real Date: Fri, 4 Jan 2013 00:40:07 +0100 Subject: Removed flash exposure bracket value --- src/exif_nikon.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/exif_nikon.c b/src/exif_nikon.c index a223043..c058d8c 100644 --- a/src/exif_nikon.c +++ b/src/exif_nikon.c @@ -443,7 +443,6 @@ void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, uns /* show only if flash was used */ case 8: /* Flash Setting */ case 9: /* Flash Mode */ - case 27: /* Flash exposure bracket value */ case 135: /* Flash used */ { if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) ) -- cgit v1.2.3