1 /* exif_nikon.c
2
3 Copyright (C) 2012 Dennis Real.
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to
7 deal in the Software without restriction, including without limitation the
8 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 sell copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies of the Software and its documentation and acknowledgment shall be
14 given in the documentation and software packages that this Software was
15 used.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 */
25
26 #ifdef HAVE_LIBEXIF
27
28 #include <stdio.h>
29 #include <libexif/exif-data.h>
30
31 #include "feh.h"
32 #include "debug.h"
33 #include "exif.h"
34 #include "exif_nikon.h"
35
36
37 /* Flash control mode */
38 /* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#FlashControlMode */
39 #define EXN_FLASH_CONTROL_MODES_MAX 9
40 char *EXN_NikonFlashControlModeValues[EXN_FLASH_CONTROL_MODES_MAX] = {"Off",
41 "iTTL-BL", "iTTL", "Auto Aperture",
42 "Automatic", "GN (distance priority)",
43 "Manual", "Repeating Flash",
44 "N/A" /* "N/A" is not a nikon setting */
45 };
46
47 #define EXN_FLASH_CONTROL_MODE_MASK 0x7F
48
49
50 /* AFInfo2 */
51 /* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#AFInfo2 */
52 #define EXN_CONTRAST_DETECT_AF_MAX 2
53 char *EXN_NikonContrastDetectAF[EXN_CONTRAST_DETECT_AF_MAX] = {"Off", "On"};
54
55 /* AFArea Mode for ContrastDetectAF Off */
56 #define EXN_AF_AREA_MODE_P_MAX 13
57 char *EXN_NikonAFAreaModePhase[EXN_AF_AREA_MODE_P_MAX] = {
58 "Single Area", "Dynamic Area", "Dynamic Area (closest subject)",
59 "Group Dynamic ", "Dynamic Area (9 points) ", "Dynamic Area (21 points)",
60 "Dynamic Area (51 points) ", "Dynamic Area (51 points, 3D-tracking)",
61 "Auto-area", "Dynamic Area (3D-tracking)", "Single Area (wide)",
62 "Dynamic Area (wide)", "Dynamic Area (wide, 3D-tracking)"};
63
64 /* AFArea Mode for ContrastDetectAF On */
65 #define EXN_AF_AREA_MODE_C_MAX 5
66 char *EXN_NikonAFAreaModeContr[EXN_AF_AREA_MODE_C_MAX] = {
67 "Contrast-detect",
68 "Contrast-detect (normal area)",
69 "Contrast-detect (wide area)",
70 "Contrast-detect (face priority)",
71 "Contrast-detect (subject tracking)"};
72
73 #define EXN_PHASE_DETECT_AF_MAX 4
74 char *EXN_NikonPhaseDetectAF[EXN_PHASE_DETECT_AF_MAX] = {"Off", "On (51-point)",
75 "On (11-point)", "On (39-point)"};
76
77 /* PrimaryAFPoint and AFPointsUsed only valid with PhaseDetectAF == On */
78
79 #define EXN_PRIM_AF_PT_51_MAX 52
80 char * EXN_Prim_AF_Pt_51[EXN_PRIM_AF_PT_51_MAX] = {"(none)", "C6 (Center)", "B6", "A5",
81 "D6", "E5", "C7", "B7", "A6", "D7", "E6", "C5", "B5", "A4", "D5", "E4", "C8", "B8",
82 "A7", "D8", "E7", "C9", "B9", "A8", "D9", "E8", "C10", "B10", "A9", "D10", "E9",
83 "C11", "B11", "D11", "C4", "B4", "A3", "D4", "E3", "C3", "B3", "A2", "D3", "E2",
84 "C2", "B2", "A1", "D2", "E1", "C1", "B1", "D1"};
85
86 #define EXN_PRIM_AF_PT_11_MAX 12
87 char * EXN_Prim_AF_Pt_11[EXN_PRIM_AF_PT_11_MAX] = {"(none)", "Center", "Top", "Bottom",
88 "Mid-left", "Upper-left", "Lower-left", "Far Left", "Mid-right", "Upper-right",
89 "Lower-right", "Far Right"};
90
91 #define EXN_PRIM_AF_PT_39_MAX 40
92 char * EXN_Prim_AF_Pt_39[EXN_PRIM_AF_PT_39_MAX] = {"(none)", "C6 (Center)", "B6", "A2",
93 "D6", "E2", "C7", "B7", "A3", "D7", "E3", "C5", "B5", "A1", "D5", "E1", "C8", "B8",
94 "D8", "C9", "B9", "D9", "C10", "B10", "D10", "C11", "B11", "D11", "C4", "B4", "D4",
95 "C3", "B3", "D3", "C2", "B2", "D2", "C1", "B1", "D1"};
96
97
98 #define EXN_PIC_CTRL_ADJ_MAX 3
99 char * EXN_Pic_Ctrl_Adj[EXN_PIC_CTRL_ADJ_MAX] = {"Default Settings",
100 "Quick Adjust",
101 "Full Control"};
102
103
104
105 static void exn_get_prim_af_pt(unsigned int phasedetectaf,
106 unsigned int primafpt,
107 char * buffer,
108 unsigned int maxsize);
109 static void exn_get_flash_output(unsigned int flashoutput, char * buffer, unsigned int maxsize);
110 static void exn_get_mnote_nikon_18(ExifData *ed, char * buffer, unsigned int maxsize);
111 static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int maxsize);
112 static void exn_get_mnote_nikon_35(ExifData *ed, char * buffer, unsigned int maxsize);
113 static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int maxsize);
114 static void exn_get_mnote_nikon_183(ExifData *ed, char * buffer, unsigned int maxsize);
115
116
117
118 /* get primary AF point */
exn_get_prim_af_pt(unsigned int phasedetectaf,unsigned int primafpt,char * buffer,unsigned int maxsize)119 static void exn_get_prim_af_pt(unsigned int phasedetectaf,
120 unsigned int primafpt,
121 char * buffer,
122 unsigned int maxsize)
123 {
124
125 switch(phasedetectaf)
126 {
127 case 0:
128 {
129 /* phasedetect not used. should not happen */
130 snprintf(buffer, maxsize, "FAIL");
131 return;
132 }
133 break;
134 case 1:
135 {
136 /* 51 pt */
137 if ( primafpt < EXN_PRIM_AF_PT_51_MAX )
138 {
139 snprintf(buffer, maxsize, "%s", EXN_Prim_AF_Pt_51[primafpt]);
140 }
141 return;
142 }
143 break;
144 case 2:
145 {
146 /* 11 pt */
147 if ( primafpt < EXN_PRIM_AF_PT_11_MAX )
148 {
149 snprintf(buffer, maxsize, "%s", EXN_Prim_AF_Pt_11[primafpt]);
150 }
151 return;
152 }
153 break;
154 case 3:
155 {
156 /* 39 pt */
157 if ( primafpt < EXN_PRIM_AF_PT_39_MAX )
158 {
159 snprintf(buffer, maxsize, "%s", EXN_Prim_AF_Pt_39[primafpt]);
160 }
161 return;
162 }
163 break;
164 default:
165 {
166 snprintf(buffer, maxsize, "?");
167 return;
168 }
169 break;
170
171 }
172
173 }
174
175
176
177 /* get flash output power (for FlashInfo010x) */
exn_get_flash_output(unsigned int flashoutput,char * buffer,unsigned int maxsize)178 static void exn_get_flash_output(unsigned int flashoutput, char * buffer, unsigned int maxsize)
179 {
180
181 if ( flashoutput == 0 )
182 {
183 /* full power */
184 snprintf(buffer, maxsize, "Full");
185 }
186 else
187 {
188 if ( (flashoutput % 6) == 0 )
189 {
190 /* value is a power of 2 */
191 snprintf(buffer, maxsize, "1/%d", 1<<(flashoutput/6));
192 }
193 else
194 {
195 /* something uneven...ugly. maybe introduce pow() function from libm later */
196 snprintf(buffer, maxsize, "1/2^(%f)", ((float)flashoutput)/6.0);
197 }
198 }
199 }
200
201
202
203 /* get ActiveD-Lighting (18) info */
exn_get_mnote_nikon_18(ExifData * ed,char * buffer,unsigned int maxsize)204 static void exn_get_mnote_nikon_18(ExifData *ed, char * buffer, unsigned int maxsize)
205 {
206
207 char buf[EXIF_STD_BUF_LEN];
208 float data = 0;
209
210 buf[0] = '\0';
211 exif_get_mnote_tag(ed, 18, buf, sizeof(buf));
212
213 sscanf(buf, "Flash Exposure Compensation: %f", &data); /* libexif buggy here. fix conversion */
214
215 snprintf(buffer, maxsize, "FlashExposureCompensation: %+.1f EV\n", ((float)((signed char)round(data*6.0))) / 6.0 );
216 }
217
218
219
220 /* get ActiveD-Lighting (34) info */
exn_get_mnote_nikon_34(ExifData * ed,char * buffer,unsigned int maxsize)221 static void exn_get_mnote_nikon_34(ExifData *ed, char * buffer, unsigned int maxsize)
222 {
223 char buf[EXIF_STD_BUF_LEN];
224 unsigned int data = 0;
225 char *answer;
226
227 buf[0] = '\0';
228 exif_get_mnote_tag(ed, 34, buf, sizeof(buf));
229 sscanf(buf, "(null): %u", &data); /* not directly supported by libexif yet */
230
231 switch(data)
232 {
233 case 0:
234 {
235 answer = "Off";
236 }
237 break;
238 case 1:
239 {
240 answer = "Low";
241 }
242 break;
243 case 3:
244 {
245 answer = "Normal";
246 }
247 break;
248 case 5:
249 {
250 answer = "High";
251 }
252 break;
253 case 7:
254 {
255 answer = "Extra High";
256 }
257 break;
258 case 65535:
259 {
260 answer = "Auto";
261 }
262 break;
263 default:
264 {
265 answer = "N/A"; /* this is not a nikon value */
266 }
267
268 }
269
270 snprintf(buffer, maxsize, "Active D-Lightning: %s\n", answer);
271
272 }
273
274
275
276 /* get nikon PictureControlData (35) info */
exn_get_mnote_nikon_35(ExifData * ed,char * buffer,unsigned int maxsize)277 static void exn_get_mnote_nikon_35(ExifData *ed, char * buffer, unsigned int maxsize)
278 {
279 char buf[EXIF_STD_BUF_LEN];
280 char picturecontrolname[EXIF_STD_BUF_LEN];
281 char picturecontrolbase[EXIF_STD_BUF_LEN];
282 unsigned int version = 0;
283 unsigned int length = 0;
284 unsigned int piccontroladj = 0;
285 unsigned int piccontrolquickadj = 0;
286 unsigned int sharpness = 0;
287 unsigned int contrast = 0;
288 unsigned int brightness = 0;
289 unsigned int saturation = 0;
290 unsigned int hueadjustment = 0;
291 unsigned int i, j;
292
293 /* libexif does not support PictureControlData 35 yet. so we have to parse the debug data :-( */
294 buf[0] = '\0';
295 exif_get_mnote_tag(ed, 35, buf, sizeof(buf));
296
297 sscanf(buf, "(null): %u bytes unknown data: 303130%02X%40s%40s%*8s%02X%02X%02X%02X%02X%02X%02X",
298 &length, &version, &picturecontrolname[0], &picturecontrolbase[0],
299 &piccontroladj, &piccontrolquickadj,
300 &sharpness, &contrast, &brightness, &saturation, &hueadjustment
301 );
302
303 /* printf("--%s %d-%d-\n", buf, version, piccontroladj); */
304
305 for ( i=0; i<40; i++ )
306 {
307 sscanf(&picturecontrolname[2*i], "%2X", &j);
308 picturecontrolname[i] = j;
309 sscanf(&picturecontrolbase[2*i], "%2X", &j);
310 picturecontrolbase[i] = j;
311
312 }
313 exif_trim_spaces(picturecontrolname);
314 exif_trim_spaces(picturecontrolbase);
315
316 if ( ((length == 58) && (version == '0'))
317 && (piccontroladj < EXN_PIC_CTRL_ADJ_MAX)
318
319 )
320 {
321 snprintf(buffer, maxsize,
322 "PictCtrlData: Name: %s; Base: %s; CtrlAdj: %s; Quick: %d; Shrp: %d; Contr: %d; Brght: %d; Sat: %d; Hue: %d\n",
323 picturecontrolname, picturecontrolbase,
324 EXN_Pic_Ctrl_Adj[piccontroladj], piccontrolquickadj,
325 sharpness, contrast, brightness, saturation, hueadjustment);
326 }
327
328 }
329
330
331
332
333 /* get nikon Flash info: control mode (168) info */
exn_get_mnote_nikon_168(ExifData * ed,char * buffer,unsigned int maxsize)334 static void exn_get_mnote_nikon_168(ExifData *ed, char * buffer, unsigned int maxsize)
335 {
336 char buf[EXIF_STD_BUF_LEN];
337 unsigned int version = 0;
338 unsigned int length = 0;
339 unsigned int exn_fcm = (EXN_FLASH_CONTROL_MODES_MAX-1); /* default to N/A */
340 unsigned int flashoutput = 0;
341 unsigned int externalflashflags = 0;
342 unsigned int flashcompensation = 0;
343
344 /* libexif does not support flash info 168 yet. so we have to parse the debug data :-( */
345 buf[0] = '\0';
346 exif_get_mnote_tag(ed, 168, buf, sizeof(buf));
347 sscanf(buf, "(null): %u bytes unknown data: 303130%02X%*8s%02X%02X%02X%02X", &length, &version, &externalflashflags, &exn_fcm, &flashoutput, &flashcompensation);
348 exn_fcm = exn_fcm & EXN_FLASH_CONTROL_MODE_MASK;
349
350 /* printf("%s - %d %d %d %d\n", buf, externalflashflags, exn_fcm, flashoutput, (signed char)flashcompensation); */
351
352 if ( (exn_fcm < EXN_FLASH_CONTROL_MODES_MAX)
353 && ( ((length == 22) && (version == '3')) /* Nikon FlashInfo0103 */
354 || ((length == 22) && (version == '4')) /* Nikon FlashInfo0104 */
355 || ((length == 21) && (version == '2')) /* Nikon FlashInfo0102 */
356 || ((length == 19) && (version == '0')) /* Nikon FlashInfo0100 */
357 )
358 )
359 {
360
361 buf[0] = '\0';
362 exn_get_flash_output(flashoutput, buf, EXIF_STD_BUF_LEN);
363 snprintf(buffer, maxsize, "NikonFlashControlMode: %s (Power: %s)\n", EXN_NikonFlashControlModeValues[exn_fcm], buf);
364
365 /* External Flash Flags. Not as useful as expected. Not used (yet). */
366 /* if ( (externalflashflags & (1<<2)) ) -> Bounce Flash */
367 /* if ( (externalflashflags & (1<<4)) ) -> Wide Flash Adapter */
368 /* if ( (externalflashflags & (1<<5)) ) -> Dome Diffusor */
369
370 }
371
372 }
373
374
375
376 /* get nikon AFInfo2 (183) info */
exn_get_mnote_nikon_183(ExifData * ed,char * buffer,unsigned int maxsize)377 static void exn_get_mnote_nikon_183(ExifData *ed, char * buffer, unsigned int maxsize)
378 {
379 char buf[EXIF_STD_BUF_LEN];
380 unsigned int contrastdetectaf = 0;
381 unsigned int afareamode = 0;
382 unsigned int phasedetectaf = 0;
383 unsigned int primaryafpoint = 0;
384 unsigned int version = 0;
385 unsigned int length = 0;
386
387 /* AFInfo2 */
388 /* libexif does not support AFInfo2 183 yet. so we have to parse the debug data :-( */
389 buf[0] = '\0';
390 exif_get_mnote_tag(ed, 183, buf, sizeof(buf));
391 sscanf(buf, "(null): %u bytes unknown data: 303130%02X%02X%02X%02X%02X", &length, &version,
392 &contrastdetectaf,
393 &afareamode,
394 &phasedetectaf,
395 &primaryafpoint
396 );
397
398
399 if ( ((length == 30) && (version == '0'))
400 && (contrastdetectaf < EXN_CONTRAST_DETECT_AF_MAX)
401 && (phasedetectaf < EXN_PHASE_DETECT_AF_MAX)
402 )
403 {
404 if ( (contrastdetectaf != 0) && (afareamode < EXN_AF_AREA_MODE_C_MAX) )
405 {
406 /* Contrast AF (live view) */
407 snprintf(buffer, maxsize,
408 "ContrastDetectAF: %s; AFAreaMode: %s\n",
409 EXN_NikonContrastDetectAF[contrastdetectaf],
410 EXN_NikonAFAreaModeContr[afareamode]);
411
412 }
413 else if ( (phasedetectaf != 0) && (afareamode < EXN_AF_AREA_MODE_P_MAX) )
414 {
415 /* Phase AF */
416 buf[0] = '\0';
417 exn_get_prim_af_pt(phasedetectaf, primaryafpoint, buf, EXIF_STD_BUF_LEN);
418
419 snprintf(buffer, maxsize,
420 "PhaseDetectAF: %s; AreaMode: %s; PrimaryAFPoint: %s\n",
421 EXN_NikonPhaseDetectAF[phasedetectaf],
422 EXN_NikonAFAreaModePhase[afareamode],
423 buf
424 );
425 }
426
427 }
428 }
429
430
431
432 /* get interesting nikon maker note tags in readable form */
exn_get_mnote_nikon_tags(ExifData * ed,unsigned int tag,char * buffer,unsigned int maxsize)433 void exn_get_mnote_nikon_tags(ExifData *ed, unsigned int tag, char * buffer, unsigned int maxsize)
434 {
435 char buf[EXIF_STD_BUF_LEN];
436
437 buf[0] = '\0';
438 exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buf, sizeof(buf));
439 exif_trim_spaces(buf);
440
441 switch(tag)
442 {
443 /* show only if flash was used */
444 case 8: /* Flash Setting */
445 case 9: /* Flash Mode */
446 case 135: /* Flash used */
447 {
448 if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) )
449 {
450 /* show extended flash info only if flash was fired */
451 exif_get_mnote_tag(ed, tag, buffer, maxsize);
452 }
453 }
454 break;
455
456 case 18: /* FlashExposureComp */
457 {
458 if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) )
459 {
460 /* show only if flash was fired */
461 exn_get_mnote_nikon_18(ed, buffer, maxsize);
462 }
463 }
464 break;
465
466 case 34:
467 {
468 /* ActiveD-Lighting */
469 exn_get_mnote_nikon_34(ed, buffer, maxsize);
470 }
471 break;
472
473 case 35:
474 {
475 /* PictureControlData */
476 exn_get_mnote_nikon_35(ed, buffer, maxsize);
477 }
478 break;
479
480 case 168:
481 {
482 /* Flash info: control mode */
483 if ( !(strcmp("Flash: Flash did not fire\n", buf) == 0) )
484 {
485 /* show extended flash info only if flash was fired */
486 exn_get_mnote_nikon_168(ed, buffer, maxsize);
487 }
488 }
489 break;
490
491 case 183:
492 {
493 /* AFInfo 2 */
494 exn_get_mnote_nikon_183(ed, buffer, maxsize);
495 }
496 break;
497
498 default:
499 {
500 /* normal makernote tags without special treatment */
501 exif_get_mnote_tag(ed, tag, buffer, maxsize);
502 }
503 break;
504 }
505
506
507 return;
508 }
509
510 #endif
511