summaryrefslogtreecommitdiff
path: root/src/exif_nikon.c
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2012-04-04 21:24:12 +0200
committerDaniel Friesel <derf@finalrewind.org>2012-04-04 21:24:12 +0200
commitbb954ff134e4299d4251e0376363271c3feccc56 (patch)
tree2bf3d2dde7dc56aad24a222f611e6622a01b84db /src/exif_nikon.c
parent82a976e0909e02ba8c25e4fd10d0e56a3e5c13ca (diff)
Lots of EXIF mode fixes and improvements by Dennis Real (closes #87)
Squashed commit of the following: commit 58dd2e303c5ee380527d92a3fa3d6baeeacb50a1 Merge: cf6f032 82a976e Author: Dennis Real <github@tildepipe.org> Date: Sat Mar 31 18:43:47 2012 +0200 Merge branch 'master' of git://github.com/derf/feh commit cf6f0320c15abd753951990a963d5c94b180bbde Merge: 10b7b1e 877e634 Author: Dennis Real <github@tildepipe.org> Date: Sun Mar 25 19:07:30 2012 +0200 Merge branch 'master' of git://github.com/derf/feh commit 10b7b1e3e10ba650b240a742947cb6850bbadd23 Author: Dennis Real <github@tildepipe.org> Date: Sat Mar 24 14:41:15 2012 +0100 Support for Canon Exif makernote tags commit 3c284dc81dcb26249114b7ecf32ed0000f492b8b Author: Dennis Real <github@tildepipe.org> Date: Thu Mar 22 19:44:32 2012 +0100 Support for Active D-Lightning commit ad5aea8cb853cc9d1b322c69f4812ad0bcb08ef3 Merge: cc6de20 9c43b64 Author: Dennis Real <github@tildepipe.org> Date: Thu Mar 22 19:01:38 2012 +0100 Merge remote branch 'upstream/master' commit cc6de20061eaa7172aa0184e03df947da14d713e Author: Dennis Real <github@tildepipe.org> Date: Thu Mar 22 19:00:30 2012 +0100 Nikon makernote parts changed commit e401bd9c78a82b8290ec524e56b7c832631725e6 Author: Dennis Real <github@tildepipe.org> Date: Wed Mar 21 19:47:15 2012 +0100 1. Own module for nikon maker notes 2. Support for AFInfo2 commit 39cbd1ed2b6693beea5e974a6ae83207c6e9a826 Merge: 9e1bbf8 a100123 Author: Dennis Real <github@tildepipe.org> Date: Fri Mar 16 22:22:28 2012 +0100 Merge remote branch 'upstream/master' commit 9e1bbf874500e99506baffec3c6b54ed04e60a2f Author: Dennis Real <github@tildepipe.org> Date: Fri Mar 16 22:20:58 2012 +0100 - exif handling changed - gps info added if available commit 8e96382805eb77a82209df9d71dbf9c0dd1c4cdb Merge: 77fa5ac 29cd868 Author: Dennis Real <github@tildepipe.org> Date: Fri Mar 16 19:13:47 2012 +0100 Merge branch 'master' of git://github.com/derf/feh commit 77fa5aca182435f2771511832ea198d027393ceb Merge: 93a90e6 3b2756b Author: Dennis Real <github@tildepipe.org> Date: Wed Mar 7 17:18:07 2012 +0100 Merge branch 'master' of git://github.com/derf/feh commit 93a90e60d0cf093ca71c34f4f5dbfde974f433f0 Merge: a81465d 52d5da9 Author: Dennis Real <github@tildepipe.org> Date: Tue Mar 6 21:42:40 2012 +0100 Merge branch 'master' of git://github.com/derf/feh commit a81465d019593cfd1e506eb66f20f6b5e10488f3 Merge: a19e50d 31afac4 Author: Dennis Real <github@tildepipe.org> Date: Mon Mar 5 17:23:40 2012 +0100 Merge branch 'master' of git://github.com/derf/feh commit a19e50deb749c5188bdbc75a5c1cd6ab1f3f3a3a Merge: 1c89da1 fe9a16b Author: Dennis Real <github@tildepipe.org> Date: Sun Mar 4 15:35:45 2012 +0100 Merge branch 'master' of ssh://github.com/reald/feh commit 1c89da1269089d98529a6635c36d014da1b08eb4 Author: Dennis Real <github@tildepipe.org> Date: Tue Feb 28 22:37:22 2012 +0100 test case adapted to new testfile commit bb3c9d3571e43f913c6f659fefd9cd34971fd004 Author: Dennis Real <github@tildepipe.org> Date: Tue Feb 28 22:34:51 2012 +0100 test file with some exif data added commit fe9a16bce3f06d45acf103fc4439c1af2dc4ac6c Author: Dennis Real <github@tildepipe.org> Date: Tue Feb 28 22:37:22 2012 +0100 test case adapted to new testfile commit e0bedc0438cf4ab4eafe43afca0886ad63591560 Merge: 46801fe 69ecc5c Author: Dennis Real <github@tildepipe.org> Date: Tue Feb 28 22:36:08 2012 +0100 Merge remote branch 'upstream/master' commit 46801fee8de26f4e0af2ed294c3a4f7fc1c45ca3 Author: Dennis Real <github@tildepipe.org> Date: Tue Feb 28 22:34:51 2012 +0100 test file with some exif data added
Diffstat (limited to 'src/exif_nikon.c')
-rw-r--r--src/exif_nikon.c370
1 files changed, 370 insertions, 0 deletions
diff --git a/src/exif_nikon.c b/src/exif_nikon.c
new file mode 100644
index 0000000..f4a8eea
--- /dev/null
+++ b/src/exif_nikon.c
@@ -0,0 +1,370 @@
+/* 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 <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_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);
+
+
+
+/* get primary AF point */
+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 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); /* not directly supported by libexif yet */
+
+ 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, maxsize, "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)
+{
+ char buf[EXIF_STD_BUF_LEN];
+ unsigned int version = 0;
+ unsigned int length = 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_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, maxsize, "NikonFlashControlMode: %s\n", EXN_NikonFlashControlModeValues[exn_fcm]);
+ }
+
+}
+
+
+
+/* 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 :-( */
+ 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, maxsize,
+ "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, maxsize,
+ "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, maxsize);
+ }
+ }
+ break;
+
+ case 34:
+ {
+ /* ActiveD-Lighting */
+ exn_get_mnote_nikon_34(ed, buffer, maxsize);
+ }
+ 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, maxsize);
+ }
+ }
+ break;
+
+ case 183:
+ {
+ /* AFInfo 2 */
+ exn_get_mnote_nikon_183(ed, buffer, maxsize);
+ }
+ break;
+
+ default:
+ {
+ /* normal makernote tags without special treatment */
+ exif_get_mnote_tag(ed, tag, buffer, maxsize);
+ }
+ break;
+ }
+
+
+ return;
+}
+
+#endif