1 /*
2 * Copyright (c) 2001-2005, Eric M. Johnston <emj@postal.net>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Eric M. Johnston.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $Id: nikon.c,v 1.27 2005/01/04 23:29:31 ejohnst Exp $
33 */
34
35 /*
36 * Exif tag definitions for Nikon maker notes.
37 *
38 * Some information for Nikon D1X support obtained from JoJoThumb, version
39 * 2.7.2 (http://www.jojosoftware.de/jojothumb/).
40 *
41 * Updated with data from
42 * http://www.ozhiker.com/electronics/pjmt/jpeg_info/nikon_mn.html.
43 *
44 */
45
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49
50 #include "makers.h"
51
52
53 /* Quality. */
54
55 static struct descrip nikon_quality[] = {
56 { 1, "VGA Basic" },
57 { 2, "VGA Normal" },
58 { 3, "VGA Fine" },
59 { 4, "SXGA Basic" },
60 { 5, "SXGA Normal" },
61 { 6, "SXGA Fine" },
62 { 10, "UXGA Basic" },
63 { 11, "UXGA Normal" },
64 { 12, "UXGA Fine" },
65 { -1, "Unknown" },
66 };
67
68
69 /* Color. */
70
71 static struct descrip nikon_color[] = {
72 { 1, "Color" },
73 { 2, "Monochrome" },
74 { -1, "Unknown" },
75 };
76
77
78 /* Image adjustment. */
79
80 static struct descrip nikon_adjust[] = {
81 { 0, "Normal" },
82 { 1, "Bright(+)" },
83 { 2, "Bright(-)" },
84 { 3, "Contrast(+)" },
85 { 4, "Contrast(-)" },
86 { -1, "Unknown" },
87 };
88
89
90 /* CCD sensitivity. */
91
92 static struct descrip nikon_ccd[] = {
93 { 0, "ISO 80" },
94 { 2, "ISO 160" },
95 { 4, "ISO 320" },
96 { 5, "ISO 100" },
97 { -1, "Unknown" },
98 };
99
100
101 /* White balance. */
102
103 static struct descrip nikon_white[] = {
104 { 0, "Auto" },
105 { 1, "Preset" },
106 { 2, "Daylight" },
107 { 3, "Incandescent" },
108 { 4, "Fluorescent" },
109 { 5, "Cloudy" },
110 { 6, "Speedlight" },
111 { -1, "Unknown" },
112 };
113
114
115 /* Converter. */
116
117 static struct descrip nikon_convert[] = {
118 { 0, "None" },
119 { 2, "Fisheye" },
120 { -1, "Unknown" },
121 };
122
123
124 /* Flash. */
125
126 static struct descrip nikon_flash[] = {
127 { 0, "No" },
128 { 9, "Fired" },
129 { -1, "Unknown" },
130 };
131
132
133 /* Lens type. */
134
135 static struct descrip nikon_lenstype[] = {
136 { 6, "Nikon D Series" },
137 { 14, "Nikon G Series" },
138 { -1, "Unknown" },
139 };
140
141
142 /* Shooting mode. */
143
144 static struct descrip nikon_shoot[] = {
145 { 0, "Single Frame" },
146 { 1, "Continuous" },
147 { 2, "Timer" },
148 { 3, "Remote Timer" },
149 { 4, "Remote" },
150 { -1, "Unknown" },
151 };
152
153
154 /* Auto focus position. */
155
156 static struct descrip nikon_afpos[] = {
157 { 0, "Center" },
158 { 1, "Top" },
159 { 2, "Bottom" },
160 { 3, "Left" },
161 { 4, "Right" },
162 { -1, "Unknown" },
163 };
164
165
166 /* Auto focus mode. */
167
168 static struct descrip nikon_afmode[] = {
169 { 0, "Single Area" },
170 { 1, "Dynamic Area" },
171 { 2, "Closest Subject" },
172 { -1, "Unknown" },
173 };
174
175
176 /* Old school Nikon "lookup" maker note IFD tags. */
177
178 static struct exiftag nikon_tags0[] = {
179 { 0x0003, TIFF_SHORT, 1, ED_IMG, "NikonQuality",
180 "Image Quality", nikon_quality },
181 { 0x0004, TIFF_SHORT, 1, ED_IMG, "NikonColor",
182 "Color Mode", nikon_color },
183 { 0x0005, TIFF_SHORT, 1, ED_IMG, "NikonImgAdjust",
184 "Image Adjustment", nikon_adjust },
185 { 0x0006, TIFF_SHORT, 1, ED_IMG, "NikonCCDSensitive",
186 "CCD Sensitivity", nikon_ccd },
187 { 0x0007, TIFF_SHORT, 1, ED_IMG, "NikonWhiteBal",
188 "White Balance", nikon_white },
189 { 0x0008, TIFF_RTNL, 1, ED_UNK, "NikonFocus",
190 "Focus", NULL },
191 { 0x000a, TIFF_RTNL, 1, ED_IMG, "NikonDigiZoom",
192 "Digital Zoom", NULL },
193 { 0x000b, TIFF_SHORT, 1, ED_IMG, "NikonAdapter",
194 "Lens Adapter", nikon_convert },
195 { 0xffff, TIFF_UNKN, 0, ED_UNK, "Unknown",
196 "Nikon Unknown", NULL },
197 };
198
199
200 /* Newer Nikon ASCII maker note IFD tags. */
201
202 static struct exiftag nikon_tags1[] = {
203 { 0x0001, TIFF_UNDEF, 4, ED_VRB, "NikonVersion",
204 "Nikon Note Version", NULL },
205 { 0x0002, TIFF_SHORT, 2, ED_IMG, "NikonISOUsed",
206 "ISO Speed Used", NULL },
207 { 0x0003, TIFF_ASCII, 0, ED_IMG, "NikonColorMode1",
208 "Color Mode", NULL },
209 { 0x0004, TIFF_ASCII, 0, ED_IMG, "NikonQuality",
210 "Image Quality", NULL },
211 { 0x0005, TIFF_ASCII, 0, ED_IMG, "NikonWhiteBal",
212 "White Balance", NULL },
213 { 0x0006, TIFF_ASCII, 0, ED_IMG, "NikonImgSharp",
214 "Image Sharpening", NULL },
215 { 0x0007, TIFF_ASCII, 0, ED_IMG, "NikonFocusMode",
216 "Focus Mode", NULL },
217 { 0x0008, TIFF_ASCII, 0, ED_IMG, "NikonFlashSet",
218 "Flash Setting", NULL },
219 { 0x0009, TIFF_ASCII, 0, ED_IMG, "NikonAutoFlash",
220 "Auto Flash Mode", NULL },
221 { 0x000b, TIFF_SSHORT, 1, ED_UNK, "NikonWhiteBalBias",
222 "White Balance Bias", NULL },
223 { 0x000f, TIFF_ASCII, 0, ED_IMG, "NikonISOSelect",
224 "ISO Selection", NULL },
225 { 0x0012, TIFF_UNDEF, 4, ED_IMG, "NikonFlashComp",
226 "Flash Compensation", NULL },
227 { 0x0013, TIFF_SHORT, 2, ED_IMG, "NikonISOReq",
228 "ISO Speed Requested", NULL },
229 { 0x0018, TIFF_UNDEF, 4, ED_IMG, "NikonFlashBrackComp",
230 "Flash Bracket Compensation", NULL },
231 { 0x0019, TIFF_SRTNL, 1, ED_IMG, "NikonAEBrackComp",
232 "AE Bracket Compensation", NULL },
233 { 0x0080, TIFF_ASCII, 0, ED_IMG, "NikonImgAdjust",
234 "Image Adjustment", NULL },
235 { 0x0081, TIFF_ASCII, 0, ED_IMG, "NikonToneComp",
236 "Tone Compensation", NULL },
237 { 0x0082, TIFF_ASCII, 0, ED_IMG, "NikonLensAdapter",
238 "Lens Adapter", NULL },
239 { 0x0083, TIFF_BYTE, 1, ED_IMG, "NikonLensType",
240 "Lens Type", NULL },
241 { 0x0084, TIFF_RTNL, 4, ED_IMG, "NikonLensRange",
242 "Lens Range", NULL },
243 { 0x0085, TIFF_RTNL, 1, ED_IMG, "NikonFocusDist",
244 "Focus Distance", NULL },
245 { 0x0086, TIFF_RTNL, 1, ED_IMG, "NikonDigiZoom",
246 "Digital Zoom", NULL },
247 { 0x0087, TIFF_BYTE, 1, ED_VRB, "NikonFlashUsed",
248 "Flash Used", nikon_flash },
249 { 0x0088, TIFF_UNDEF, 4, ED_IMG, "NikonAutoFocus",
250 "Auto Focus", NULL },
251 /* Is either BYTE (D100) or SHORT (D70). */
252 { 0x0089, TIFF_UNKN, 1, ED_IMG, "NikonShootBrack",
253 "Shooting/Bracketing Mode", NULL },
254 { 0x008d, TIFF_ASCII, 0, ED_IMG, "NikonColorMode2",
255 "Color Mode", NULL },
256 { 0x008f, TIFF_ASCII, 0, ED_IMG, "NikonSceneMode",
257 "Scene Mode", NULL },
258 { 0x0090, TIFF_ASCII, 0, ED_IMG, "NikonLighting",
259 "Lighting Type", NULL },
260 { 0x0092, TIFF_SSHORT, 1, ED_UNK, "NikonHueAdjust",
261 "Hue Adjustment", NULL },
262 { 0x0094, TIFF_SSHORT, 1, ED_IMG, "NikonSaturate",
263 "Saturation", NULL },
264 { 0x0095, TIFF_ASCII, 0, ED_IMG, "NikonNoiseReduce",
265 "Noise Reduction", NULL },
266 { 0x00a0, TIFF_ASCII, 0, ED_CAM, "NikonSerial",
267 "Serial Number", NULL },
268 { 0x00a7, TIFF_LONG, 1, ED_IMG, "NikonAcuations",
269 "Camera Actuations", NULL },
270 { 0x00a9, TIFF_ASCII, 0, ED_IMG, "NikonImageOpt",
271 "Image Optimization", NULL },
272 { 0x00aa, TIFF_ASCII, 0, ED_IMG, "NikonSaturate2",
273 "Saturation 2", NULL },
274 { 0x00ab, TIFF_ASCII, 0, ED_IMG, "NikonDigiProg",
275 "Digital Vari-Program", NULL },
276 { 0xffff, TIFF_UNKN, 0, ED_UNK, "Unknown",
277 "Nikon Unknown", NULL },
278 };
279
280
281 /*
282 * Process older Nikon maker note tags.
283 */
284 static void
nikon_prop0(struct exifprop * prop,struct exiftags * t)285 nikon_prop0(struct exifprop *prop, struct exiftags *t)
286 {
287 u_int32_t a, b;
288
289 switch (prop->tag) {
290
291 /* Digital zoom. */
292
293 case 0x000a:
294 a = exif4byte(t->mkrmd.btiff + prop->value, t->mkrmd.order);
295 b = exif4byte(t->mkrmd.btiff + prop->value + 4, t->mkrmd.order);
296
297 if (!a) {
298 snprintf(prop->str, 31, "None");
299 prop->lvl = ED_VRB;
300 } else
301 snprintf(prop->str, 31, "x%.1f", (float)a / (float)b);
302 break;
303 }
304 }
305
306
307 /*
308 * Process newer Nikon maker note tags.
309 */
310 static void
nikon_prop1(struct exifprop * prop,struct exiftags * t)311 nikon_prop1(struct exifprop *prop, struct exiftags *t)
312 {
313 int i;
314 u_int32_t v[8];
315 char *c1, *c2, *c3;
316 int32_t sn, sd;
317 char buf[5];
318
319 switch (prop->tag) {
320
321 /*
322 * Nikon maker note version.
323 * XXX Note that earlier versions aren't ASCII, and that we
324 * don't handle them yet.
325 */
326
327 case 0x0001:
328 byte4exif(prop->value, (unsigned char *)buf, t->mkrmd.order);
329 buf[4] = '\0';
330 v[1] = atoi(buf + 2);
331 buf[2] = '\0';
332 v[0] = atoi(buf);
333
334 exifstralloc(&prop->str, 8);
335 snprintf(prop->str, 7, "%d.%d", v[0], v[1]);
336 break;
337
338 /*
339 * ISO values. Two shorts stuffed into the value; we only care
340 * about the second one. (First is always zero?)
341 */
342
343 case 0x0002:
344 case 0x0013:
345 /*
346 * XXX Well, this is messy. Nikon stuffs the two shorts into
347 * into the tag value, rather than referencing an offset.
348 * Byte order screws with us here... (Need to fix!)
349 */
350 if (t->mkrmd.order == LITTLE)
351 v[0] = (prop->value >> 16) & 0xffff;
352 else
353 v[0] = prop->value & 0xffff;
354
355 exifstralloc(&prop->str, 32);
356 snprintf(prop->str, 31, "%d", (u_int16_t)v[0]);
357 if (!v[0]) prop->lvl = ED_VRB;
358 break;
359
360 /* White balance. */
361
362 case 0x0005:
363 prop->override = EXIF_T_WHITEBAL;
364 break;
365
366 /* Flash [bracket] compensation. Four values here; we only know one. */
367
368 case 0x0012:
369 case 0x0018:
370 exifstralloc(&prop->str, 10);
371 snprintf(prop->str, 9, "%.1f EV",
372 (int16_t)(prop->value >> 24) / 6.0);
373 break;
374
375 /* AE bracket compensation. */
376
377 case 0x0019:
378 sn = exif4byte(t->mkrmd.btiff + prop->value, t->mkrmd.order);
379 sd = exif4byte(t->mkrmd.btiff + prop->value + 4,
380 t->mkrmd.order);
381
382 if (sn && !sd) {
383 snprintf(prop->str, 31, "n/a");
384 prop->lvl = ED_VRB;
385 } else
386 snprintf(prop->str, 31, "%.1f EV", (float)sn /
387 (float)sd);
388 break;
389
390 /* Lens type. */
391
392 case 0x0083:
393 prop->str = finddescr(nikon_lenstype,
394 (u_int16_t)((prop->value >> 24) & 0xff));
395 break;
396
397 /* Lens range. */
398
399 case 0x0084:
400 if (prop->value + prop->count * 8 >
401 (u_int32_t)(t->mkrmd.etiff - t->mkrmd.btiff))
402 break;
403
404 for (i = 0; i < 8; i++)
405 v[i] = exif4byte(t->mkrmd.btiff + prop->value + (i * 4),
406 t->mkrmd.order);
407
408 if ((v[0] && !v[1]) || (v[2] && !v[3]) ||
409 (v[4] && !v[5]) || (v[6] && !v[7])) {
410 snprintf(prop->str, 31, "n/a");
411 prop->lvl = ED_VRB;
412 break;
413 }
414
415 /* XXX Err, kind of a mess. */
416 if (v[0] == v[2] && v[1] == v[3]) {
417 if (v[4] == v[6] && v[5] == v[7]) {
418 snprintf(prop->str, 31, "%.1f mm; f/%.1f",
419 (float)v[0] / (float)v[1],
420 (float)v[4] / (float)v[5]);
421 break;
422 }
423
424 snprintf(prop->str, 31, "%.1f mm; f/%.1f - f/%.1f",
425 (float)v[0] / (float)v[1], (float)v[4] /
426 (float)v[5], (float)v[6] / (float)v[7]);
427 break;
428 }
429
430 if (v[4] == v[6] && v[5] == v[7]) {
431 snprintf(prop->str, 31, "%.1f - %.1f mm; f/%.1f",
432 (float)v[0] / (float)v[1], (float)v[2] /
433 (float)v[3], (float)v[4] / (float)v[5]);
434 break;
435 }
436
437 snprintf(prop->str, 31, "%.1f - %.1f mm; f/%.1f - f/%.1f",
438 (float)v[0] / (float)v[1], (float)v[2] / (float)v[3],
439 (float)v[4] / (float)v[5], (float)v[6] / (float)v[7]);
440 break;
441
442 /* Manual focus distance. */
443
444 case 0x0085:
445 v[0] = exif4byte(t->mkrmd.btiff + prop->value, t->mkrmd.order);
446 v[1] = exif4byte(t->mkrmd.btiff + prop->value + 4,
447 t->mkrmd.order);
448
449 if (v[0] == v[1] || (v[0] && !v[1])) {
450 snprintf(prop->str, 31, "n/a");
451 prop->lvl = ED_VRB;
452 } else
453 snprintf(prop->str, 31, "x%.1f m", (float)v[0] /
454 (float)v[1]);
455 break;
456
457 /* Digital zoom. */
458
459 case 0x0086:
460 v[0] = exif4byte(t->mkrmd.btiff + prop->value, t->mkrmd.order);
461 v[1] = exif4byte(t->mkrmd.btiff + prop->value + 4,
462 t->mkrmd.order);
463
464 if (v[0] == v[1] || !v[0] || (v[0] && !v[1])) {
465 snprintf(prop->str, 31, "None");
466 prop->lvl = ED_VRB;
467 } else
468 snprintf(prop->str, 31, "x%.1f", (float)v[0] /
469 (float)v[1]);
470 break;
471
472 /*
473 * Auto focus position.
474 * XXX Need some feedback from users here -- guessing somewhat.
475 */
476
477 case 0x0088:
478 /*
479 * An older/simpler method? (Byte 3 only.)
480 * Note that cameras using the newer method will get caught
481 * here on Single Area, Center (and just show Center).
482 */
483 if (!(prop->value & 0xffff00ff)) {
484 if (prop->str) printf("err, hello? overwriting?\n");
485 prop->str = finddescr(nikon_afpos,
486 (u_int16_t)((prop->value >> 8) & 0xff));
487 break;
488 }
489
490 /* Byte 1, mode. */
491 c1 = finddescr(nikon_afmode,
492 (u_int16_t)((prop->value >> 24) & 0xff));
493
494 /* Byte 2, area selected; byte 4, area focused. */
495 c2 = finddescr(nikon_afpos, (u_int16_t)(prop->value & 0xff));
496
497 if ((prop->value & 0xff) == ((prop->value >> 16) & 0xff)) {
498 exifstralloc(&prop->str, strlen(c1) + strlen(c2) + 3);
499 sprintf(prop->str, "%s, %s", c1, c2);
500
501 } else {
502 c3 = finddescr(nikon_afpos,
503 (u_int16_t)((prop->value >> 16) & 0xff));
504 exifstralloc(&prop->str, strlen(c1) + strlen(c2) +
505 strlen(c3) + 24);
506 sprintf(prop->str, "%s, %s Selected, %s Focused",
507 c1, c3, c2);
508 free(c3);
509 }
510 free(c1);
511 free(c2);
512 break;
513
514 /*
515 * Bracketing/shooting mode.
516 * XXX I've probably made this a lot more complicated than it
517 * needs to be. Would be nice to be able to experiment...
518 */
519
520 case 0x0089:
521 /* XXX Shouldn't be necessary. */
522 if (prop->type == TIFF_BYTE)
523 prop->value = (prop->value >> 24) & 0xff;
524 else if (prop->type == TIFF_SHORT)
525 prop->value = (prop->value >> 8) & 0xff;
526
527 /* Bits 0 & 1. */
528 c1 = finddescr(nikon_shoot, (u_int16_t)(prop->value & 0x03));
529
530 /* Bit 4 = bracketing, bit 6 = white balance bracketing. */
531 if (prop->value & 0x40) {
532 if (prop->value & 0x10)
533 c2 = "On, White Balance";
534 else
535 c2 = "Off, White Balance";
536 } else {
537 if (prop->value & 0x10)
538 c2 = "On";
539 else
540 c2 = "Off";
541 }
542
543 exifstralloc(&prop->str, strlen(c1) + strlen(c2) + 2);
544 sprintf(prop->str, "%s/%s", c1, c2);
545 free(c1);
546 break;
547
548 /* Color mode. */
549
550 case 0x008d:
551 if (!(c1 = prop->str)) break;
552
553 if (!strncmp(c1, "MODE1a", 6)) {
554 free(c1);
555 prop->str = NULL;
556 c1 = "Portrait sRGB";
557 exifstralloc(&prop->str, strlen(c1) + 1);
558 strcpy(prop->str, c1);
559 break;
560 }
561
562 if (!strncmp(c1, "MODE2", 5)) {
563 free(c1);
564 prop->str = NULL;
565 c1 = "Adobe RGB";
566 exifstralloc(&prop->str, strlen(c1) + 1);
567 strcpy(prop->str, c1);
568 break;
569 }
570
571 if (!strncmp(c1, "MODE3a", 6)) {
572 free(c1);
573 prop->str = NULL;
574 c1 = "Landscape sRGB";
575 exifstralloc(&prop->str, strlen(c1) + 1);
576 strcpy(prop->str, c1);
577 break;
578 }
579 break;
580
581 /* Saturation. (Signed, so can't just do lookup table.) */
582
583 case 0x0094:
584 c1 = NULL;
585 switch (prop->value) {
586 case -3:
587 c1 = "Black & White";
588 exifstralloc(&prop->str, strlen(c1) + 1);
589 strcpy(prop->str, c1);
590 break;
591
592 case 0:
593 c1 = "Normal";
594 exifstralloc(&prop->str, strlen(c1) + 1);
595 strcpy(prop->str, c1);
596 break;
597 }
598
599 if (!c1) {
600 prop->lvl = ED_VRB;
601 break;
602 }
603 /* FALLTHROUGH */
604
605 case 0x00aa:
606 prop->override = EXIF_T_SATURATION;
607 break;
608
609 /* Serial number. */
610
611 case 0x00a0:
612 /* Remove prefix. */
613 if (!strncmp(prop->str, "NO= ", 4))
614 memmove(prop->str, prop->str + 4,
615 strlen(prop->str + 4) + 1);
616
617 /* Remove leading whitespace. */
618 for (c1 = prop->str; *c1 && *c1 == (unsigned char)' '; c1++);
619 if (*c1 && c1 > prop->str)
620 memmove(prop->str, c1, strlen(c1) + 1);
621 break;
622 }
623 }
624
625
626 /*
627 * Process Nikon maker note tags.
628 */
629 void
nikon_prop(struct exifprop * prop,struct exiftags * t)630 nikon_prop(struct exifprop *prop, struct exiftags *t)
631 {
632 int i;
633
634 for (i = 0; prop->tagset[i].tag < EXIF_T_UNKNOWN &&
635 prop->tagset[i].tag != prop->tag; i++);
636
637 if (prop->tagset[i].type && prop->tagset[i].type != prop->type)
638 exifwarn2("field type mismatch", prop->name);
639
640 /*
641 * Check the field count.
642 * XXX For whatever the reason, Sigma doesn't follow the
643 * spec on count for FileSource.
644 */
645
646 if (prop->tagset[i].count && prop->tagset[i].count != prop->count)
647 exifwarn2("field count mismatch", prop->name);
648
649 if (prop->tagset == nikon_tags0) {
650 nikon_prop0(prop, t);
651 return;
652 }
653
654 if (prop->tagset == nikon_tags1) {
655 nikon_prop1(prop, t);
656 return;
657 }
658 }
659
660
661 /*
662 * Try to read a Nikon maker note IFD.
663 */
664 struct ifd *
nikon_ifd(u_int32_t offset,struct tiffmeta * md)665 nikon_ifd(u_int32_t offset, struct tiffmeta *md)
666 {
667 struct ifd *myifd;
668 unsigned char *b;
669
670 b = md->btiff + offset;
671
672 /*
673 * Seems that some Nikon maker notes start with an ID string and
674 * a version of some sort.
675 */
676
677 if (!strcmp((const char *)b, "Nikon")) {
678 b += 6;
679 switch (exif2byte(b, BIG)) {
680 case 0x0100:
681 readifd(offset + 8, &myifd, nikon_tags0, md);
682 return (myifd);
683
684 case 0x0200:
685 case 0x0210:
686 b += 4;
687
688 /*
689 * So, this is interesting: they've put a full-fledged
690 * TIFF header here.
691 */
692
693 /* Determine endianness of the TIFF data. */
694
695 if (!memcmp(b, "MM", 2))
696 md->order = BIG;
697 else if (!memcmp(b, "II", 2))
698 md->order = LITTLE;
699 else {
700 exifwarn("invalid Nikon TIFF header");
701 return (NULL);
702 }
703 md->btiff = b; /* Beginning of maker. */
704 b += 2;
705
706 /* Verify the TIFF header. */
707
708 if (exif2byte(b, md->order) != 42) {
709 exifwarn("invalid Nikon TIFF header");
710 return (NULL);
711 }
712 b += 2;
713
714 readifd(exif4byte(b, md->order), &myifd,
715 nikon_tags1, md);
716 return (myifd);
717
718 default:
719 exifwarn("Nikon maker note version not supported");
720 return (NULL);
721 }
722 }
723
724 /*
725 * Others are just normal IFDs.
726 */
727
728 readifd(offset, &myifd, nikon_tags1, md);
729 return (myifd);
730 }
731