diff options
| author | Dennis Real <github@tildepipe.org> | 2012-03-21 19:47:15 +0100 | 
|---|---|---|
| committer | Dennis Real <github@tildepipe.org> | 2012-03-21 19:47:15 +0100 | 
| commit | e401bd9c78a82b8290ec524e56b7c832631725e6 (patch) | |
| tree | ec3203018c9dd2edb0d6cf2971c16b6b43c2fbfe /src | |
| parent | 39cbd1ed2b6693beea5e974a6ae83207c6e9a826 (diff) | |
1. Own module for nikon maker notes
2. Support for AFInfo2
Diffstat (limited to 'src')
| -rw-r--r-- | src/exif.c | 99 | ||||
| -rw-r--r-- | src/exif.h | 5 | ||||
| -rw-r--r-- | src/exif_nikon.c | 265 | ||||
| -rw-r--r-- | src/exif_nikon.h | 14 | 
4 files changed, 296 insertions, 87 deletions
| @@ -28,6 +28,7 @@ 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" @@ -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));    } @@ -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 <stdio.h> +#include <string.h> +#include <libexif/exif-data.h> + +#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 <libexif/exif-data.h> + +extern void exn_get_mnote_nikon_tags(ExifData *ed, char * buffer, unsigned int maxsize);  #endif | 
