1 /*
2  * Copyright (c) 2003, Javier Crespo <jcrespoc@dsland.org>
3  * Copyright (c) 2003-2007, Eric M. Johnston <emj@postal.net>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *      This product includes software developed by Eric M. Johnston.
17  * 4. Neither the name of the author nor the names of any co-contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * $Id: minolta.c,v 1.29 2007/12/15 21:01:23 ejohnst Exp $
34  *
35  */
36 
37 /*
38  * Exif tag definitions for Minolta DiMAGE maker notes.
39  * Tags deciphered by Javier Crespo <jcrespoc@dsland.org>.
40  *
41  * Mostly supported models: DiMAGE 5, 7, 7i, and 7Hi.
42  *
43  */
44 
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <math.h>
49 
50 #include "makers.h"
51 
52 
53 /* Bracketing mode. */
54 
55 static struct descrip minolta_brackmode[] = {
56 	{ 0,	"Exposure" },
57 	{ 1,	"Contrast" },
58 	{ 2,	"Saturation" },
59 	{ 3,	"Filter" },
60 	{ -1,	"Unknown" },
61 };
62 
63 
64 /* Bracketing step. */
65 
66 static struct descrip minolta_brackstep[] = {
67 	{ 0,	"1/3" },
68 	{ 1,	"1/2" },
69 	{ 2,	"1" },
70 	{ -1,	"Unknown" },
71 };
72 
73 
74 /* Sharpness. */
75 
76 static struct descrip minolta_sharp[] = {
77 	{ 0,	"Hard" },
78 	{ 1,	"Normal" },
79 	{ 2,	"Soft" },
80 	{ -1,	"Unknown" },
81 };
82 
83 
84 /* Color mode. */
85 
86 static struct descrip minolta_color[] = {
87 	{ 0,	"Natural Color" },
88 	{ 1,	"Black & White" },
89 	{ 2,	"Vivid Color" },
90 	{ 3,	"Solarization" },
91 	{ 4,	"Adobe RGB" },
92 	{ -1,	"Unknown" },
93 };
94 
95 
96 /* ISO. */
97 
98 static struct descrip minolta_iso[] = {
99 	{ 0,	"100" },
100 	{ 1,	"200" },
101 	{ 2,	"400" },
102 	{ 3,	"800" },
103 	{ 4,	"Auto" },
104 	{ -1,	"Unknown" },
105 };
106 
107 
108 /* Generic boolean. */
109 
110 static struct descrip minolta_bool[] = {
111 	{ 0,	"No" },
112 	{ 1,	"Yes" },
113 	{ -1,	"Unknown" },
114 };
115 
116 
117 /* Focus mode. */
118 
119 static struct descrip minolta_focusmode[] = {
120 	{ 0,	"Auto" },
121 	{ 1,	"Manual" },
122 	{ -1,	"Unknown" },
123 };
124 
125 
126 /* Focus area. */
127 
128 static struct descrip minolta_focusarea[] = {
129 	{ 0,	"Wide Area" },
130 	{ 1,	"Spot Focus Point" },
131 	{ -1,	"Unknown" },
132 };
133 
134 
135 /* Wide area focus zone. */
136 
137 static struct descrip minolta_widefocus[] = {
138 	{ 0,	"No Zone" },
139 	{ 1,	"Center" },
140 	{ 3,	"Left" },
141 	{ 4,	"Right" },
142 	{ -1,	"Unknown" },
143 };
144 
145 
146 /* Drive mode. */
147 
148 static struct descrip minolta_drive[] = {
149 	{ 0,	"Single Frame" },
150 	{ 1,	"Continous Advance" },
151 	{ 2,	"Self Timer" },
152 	{ 4,	"Bracketing" },
153 	{ 5,	"Interval" },
154 	{ 6,	"UHS" },
155 	{ 7,	"HS" },
156 	{ -1,	"Unknown" },
157 };
158 
159 
160 /* White balance. */
161 
162 static struct descrip minolta_whitebal[] = {
163 	{ 0,	"Auto" },
164 	{ 1,	"Daylight" },
165 	{ 2,	"Cloudy" },
166 	{ 3,	"Tungsten" },
167 	{ 5,	"Custom" },
168 	{ 7,	"Fluorescent" },
169 	{ 8,	"Fluorescent 2" },
170 	{ 11,	"Custom 2" },
171 	{ 12,	"Custom 3" },
172 	{ -1,	"Unknown" },
173 };
174 
175 
176 /* Flash mode. */
177 
178 static struct descrip minolta_flash[] = {
179 	{ 0,	"Fill Flash" },
180 	{ 1,	"Red-Eye Reduction" },
181 	{ 2,	"Rear Sync" },
182 	{ 3,	"Remote" },
183 	{ -1,	"Unknown" },
184 };
185 
186 
187 /* Capture scene. */
188 
189 static struct descrip minolta_scene[] = {
190 	{ 0,	"Normal" },
191 	{ 1,	"Portrait" },
192 	{ 2,	"Text" },
193 	{ 3,	"Night Portrait" },
194 	{ 4,	"Sunset" },
195 	{ 5,	"Sports Action" },
196 	{ -1,	"Unknown" },
197 };
198 
199 
200 /* Image quality. */
201 
202 static struct descrip minolta_quality[] = {
203 	{ 0,	"Raw" },
204 	{ 1,	"Super Fine" },
205 	{ 2,	"Fine" },
206 	{ 3,	"Standard" },
207 	{ 4,	"Economy" },
208 	{ 5,	"Extra Fine" },
209 	{ -1,	"Unknown" },
210 };
211 
212 
213 /* Exposure program. */
214 
215 static struct descrip minolta_prog[] = {
216 	{ 0,	"Program AE" },
217 	{ 1,	"Aperture Priority" },
218 	{ 2,	"Shutter Priority" },
219 	{ 3,	"Manual" },
220 	{ -1,	"Unknown" },
221 };
222 
223 
224 /*
225  * Image size.
226  * Valid only for 5 megapixel cameras (D7's), wrong for D5.
227  */
228 
229 static struct descrip minolta_size[] = {
230 	{ 0,	"2560x1920" },
231 	{ 1,	"1600x1200" },
232 	{ 2,	"1280x960" },
233 	{ 3,	"640x480" },
234 	{ -1,	"Unknown" },
235 };
236 
237 
238 /* Folder name. */
239 
240 static struct descrip minolta_folder[] = {
241 	{ 0,	"Standard" },
242 	{ 1,	"Date" },
243 	{ -1,	"Unknown" },
244 };
245 
246 
247 /* Data imprinting. */
248 
249 static struct descrip minolta_imprint[] = {
250 	{ 0,	"None" },
251 	{ 1,	"DataTime Y/M/D" },
252 	{ 2,	"DataTime M/D H:M" },
253 	{ 3,	"Text" },
254 	{ 4,	"Text + ID" },
255 	{ -1,	"Unknown" },
256 };
257 
258 
259 /* Camera model. */
260 
261 static struct descrip minolta_model[] = {
262 	{ 0,	"DiMAGE 7" },
263 	{ 1,	"DiMAGE 5" },
264 	{ 4,	"DiMAGE 7i" },
265 	{ 5,	"DiMAGE 7Hi" },
266 	{ -1,	"Unknown" },
267 };
268 
269 
270 /* Metering mode. */
271 
272 static struct descrip minolta_metermode[] = {
273 	{ 0,	"Multi-Segment" },
274 	{ 1,	"Center Weighted Average" },
275 	{ 2,	"Spot" },
276 	{ -1,	"Unknown" },
277 };
278 
279 
280 /* Maker note IFD tags. */
281 
282 static struct exiftag minolta_tags[] = {
283 	{ 0x0000, TIFF_UNDEF, 4, ED_UNK, "MinoltaMakerType",
284 	  "Minolta Maker Note Type", NULL },
285 	{ 0x0001, TIFF_UNDEF, 0, ED_UNK, "Minolta1Tag",
286 	  "Minolta Tag1 Offset", NULL },
287 	{ 0x0003, TIFF_UNDEF, 0, ED_UNK, "Minolta3Tag",
288 	  "Minolta Tag3 Offset", NULL },
289 	{ 0x0040, TIFF_LONG, 1, ED_UNK, "MinoltaCompImgSz",
290 	  "Minolta Compressed Image Size", NULL },
291 	{ 0x0088, TIFF_LONG, 1, ED_UNK, "MinoltaThumbOff",
292 	  "Minolta Thumbnail Offset", NULL },
293 	{ 0x0089, TIFF_LONG, 1, ED_UNK, "MinoltaThumbLen",
294 	  "Minolta Thumbnail Length", NULL },
295 	{ 0x0e00, TIFF_UNDEF, 0, ED_UNK, "MinoltaPIM",
296 	  "Minolta Print Image Management", NULL },
297 	{ 0xffff, TIFF_UNKN, 0, ED_UNK, "Unknown",
298 	  "Minolta Unknown", NULL },
299 };
300 
301 
302 /* Fields under tags 0x0001 and 0x0003. */
303 
304 static struct exiftag minolta_MLT0[] = {
305 	{ 1,  TIFF_LONG, 1, ED_IMG, "MinoltaExpProg",
306 	  "Exposure Program", minolta_prog },
307 	{ 2,  TIFF_LONG, 1, ED_IMG, "MinoltaFlashMode",
308 	  "Flash Mode", minolta_flash },
309 	{ 3,  TIFF_LONG, 1, ED_IMG, "MinoltaWhiteB",
310 	  "White Balance", minolta_whitebal },
311 	{ 4,  TIFF_LONG, 1, ED_UNK, "MinoltaSize",
312 	  "Image Size", minolta_size },
313 	{ 5,  TIFF_LONG, 1, ED_IMG, "MinoltaQuality",
314 	  "Image Quality", minolta_quality },
315 	{ 6,  TIFF_LONG, 1, ED_IMG, "MinoltaDriveMode",
316 	  "Drive Mode", minolta_drive },
317 	{ 7,  TIFF_LONG, 1, ED_IMG, "MinoltaMeterMode",
318 	  "Metering Mode", minolta_metermode },
319 	{ 8,  TIFF_LONG, 1, ED_UNK, "MinoltaFilmSpeed",
320 	  "Film Speed", NULL },
321 	{ 9,  TIFF_LONG, 1, ED_VRB, "MinoltaExpTime",
322 	  "Exposure Time", NULL },
323 	{ 10, TIFF_LONG, 1, ED_UNK, "MinoltaAperture",
324 	  "Lens Aperture", NULL },
325 	{ 11, TIFF_LONG, 1, ED_IMG, "MinoltaMacro",
326 	  "Macro", minolta_bool },
327 	{ 12, TIFF_LONG, 1, ED_IMG, "MinoltaDigiZoom",
328 	  "Digital Zoom", minolta_bool },
329 	{ 13, TIFF_LONG, 1, ED_UNK, "MinoltaExpComp",
330 	  "Exposure Compensation", NULL },
331 	{ 14, TIFF_LONG, 1, ED_IMG, "MinoltaBracketStep",
332 	  "Bracketing Step", minolta_brackstep },
333 	{ 16, TIFF_LONG, 1, ED_VRB, "MinoltaIntrvlTime",
334 	  "Interval Time", NULL },
335 	{ 17, TIFF_LONG, 1, ED_VRB, "MinoltaIntrvlPics",
336 	  "Interval Pics", NULL },
337 	{ 18, TIFF_LONG, 1, ED_UNK, "MinoltaFocalLen",
338 	  "Focal Length", NULL },
339 	{ 19, TIFF_LONG, 1, ED_IMG, "MinoltaFocusDist",
340 	  "Focus Distance", NULL },
341 	{ 20, TIFF_LONG, 1, ED_VRB, "MinoltaFlash",
342 	  "Flash Fired", minolta_bool },
343 	{ 21, TIFF_LONG, 1, ED_VRB, "MinoltaDate",
344 	  "Date", NULL },
345 	{ 22, TIFF_LONG, 1, ED_VRB, "MinoltaTime",
346 	  "Time", NULL },
347 	{ 23, TIFF_LONG, 1, ED_UNK, "MinoltaMaxAperture",
348 	  "Maximum Lens Aperture", NULL },
349 	{ 26, TIFF_LONG, 1, ED_VRB, "MinoltaRmbrFileNum",
350 	  "File Number Memory", minolta_bool },
351 	{ 27, TIFF_LONG, 1, ED_VRB, "MinoltaSequence",
352 	  "Sequence Number", NULL },
353 	{ 31, TIFF_LONG, 1, ED_IMG, "MinoltaSaturate",
354 	  "Saturation", NULL },
355 	{ 32, TIFF_LONG, 1, ED_IMG, "MinoltaContrast",
356 	  "Contrast", NULL },
357 	{ 33, TIFF_LONG, 1, ED_IMG, "MinoltaSharpness",
358 	  "Sharpness", minolta_sharp },
359 	{ 34, TIFF_LONG, 1, ED_IMG, "MinoltaScene",
360 	  "Scene Capture Type", minolta_scene },
361 	{ 35, TIFF_LONG, 1, ED_IMG, "MinoltaFlashComp",
362 	  "Flash Compensation", NULL },
363 	{ 36, TIFF_LONG, 1, ED_VRB, "MinoltaISO",
364 	  "ISO Speed Rating", minolta_iso },
365 	{ 37, TIFF_LONG, 1, ED_UNK, "MinoltaModel",
366 	  "Camera Model", minolta_model },
367 	{ 38, TIFF_LONG, 1, ED_VRB, "MinoltaIntervalMode",
368 	  "Interval Mode", minolta_bool },
369 	{ 39, TIFF_LONG, 1, ED_VRB, "MinoltaFolder",
370 	  "Folder Name", minolta_folder },
371 	{ 40, TIFF_LONG, 1, ED_IMG, "MinoltaColorMode",
372 	  "Color Mode", minolta_color },
373 	{ 41, TIFF_LONG, 1, ED_IMG, "MinoltaColorFilt",
374 	  "Color Warming", NULL },
375 	{ 42, TIFF_LONG, 1, ED_IMG, "MinoltaBWFilt",
376 	  "Black & White Tone", NULL },
377 	{ 43, TIFF_LONG, 1, ED_VRB, "MinoltaIntFlash",
378 	  "Internal Flash", minolta_bool },
379 	{ 45, TIFF_LONG, 1, ED_VRB, "MinoltaFocusX",
380 	  "AF Point X", NULL },
381 	{ 46, TIFF_LONG, 1, ED_VRB, "MinoltaFocusY",
382 	  "AF Point Y", NULL },
383 	{ 47, TIFF_LONG, 1, ED_VRB, "MinoltaWFocusZone",
384 	  "AF Zone", minolta_widefocus },
385 	{ 48, TIFF_LONG, 1, ED_IMG, "MinoltaFocusMode",
386 	  "Focus Mode", minolta_focusmode },
387 	{ 49, TIFF_LONG, 1, ED_IMG, "MinoltaAFArea",
388 	  "Wide Focus Area", minolta_focusarea },
389 	{ 50, TIFF_LONG, 1, ED_IMG, "MinoltaBracketMode",
390 	  "Bracketing Mode", minolta_brackmode },
391 	{ 51, TIFF_LONG, 1, ED_VRB, "MinoltaDataImprint",
392 	  "Data Imprint", minolta_imprint },
393 	{ 0xffff, TIFF_UNKN, 0, ED_UNK, "MinoltaUnknown",
394 	  "Minolta Field Unknown", NULL },
395 };
396 
397 
398 /* Stub to display unknown fields for some models. */
399 
400 static struct exiftag minolta_unkn[] = {
401 	{ 0xffff, TIFF_UNKN, 0, ED_UNK, "MinoltaUnknown",
402 	  "Minolta Field Unknown", NULL },
403 };
404 
405 
406 /*
407  * Process maker note tag 0x0001 and 0x0003 fields.
408  */
409 void
minolta_cprop(struct exifprop * prop,unsigned char * off,struct exiftags * t,struct exiftag * thetags)410 minolta_cprop(struct exifprop *prop, unsigned char *off, struct exiftags *t,
411     struct exiftag *thetags)
412 {
413 	unsigned int i, j, k;
414 	u_int32_t v;
415 	int32_t model;
416 	double d;
417 	char *valbuf;
418 	unsigned char buf[8];
419 	struct exifprop *aprop;
420 
421 	valbuf = NULL;
422 	model = -1;
423 
424 	for (i = 0; i * 4 < prop->count; i++) {
425 
426 		/*
427 		 * XXX It appears that the 7Hi oddly inserts a value at
428 		 * position 51, pushing everything down one.  We'll just
429 		 * skip #51.
430 		 */
431 
432 		if (thetags == minolta_MLT0 && i >= 51 && model == 5) {
433 			if (i == 51) continue;
434 			k = i - 1;
435 		} else
436 			k = i;
437 
438 		aprop = childprop(prop);
439 		aprop->tag = i;
440 		aprop->tagset = thetags;
441 
442 		/* Note: these are big-endian regardless. */
443 		aprop->value = exif4byte(off + (4 * i), BIG);
444 
445 		/* Lookup property name and description. */
446 
447 		for (j = 0; thetags[j].tag < EXIF_T_UNKNOWN &&
448 			thetags[j].tag != k; j++);
449 		aprop->name = thetags[j].name;
450 		aprop->descr = thetags[j].descr;
451 		aprop->lvl = thetags[j].lvl;
452 		if (thetags[j].table)
453 			aprop->str = finddescr(thetags[j].table,
454 			    (u_int16_t)aprop->value);
455 
456 		dumpprop(aprop, NULL);
457 
458 		/*
459 		 * Further process known properties.
460 		 * XXX If currently unsupported fields are implemented,
461 		 * this section will have to be specific to the set of
462 		 * tags passed in.
463 		 */
464 
465 		if (thetags != minolta_MLT0)
466 			continue;
467 
468 		if (!valbuf)
469 			exifstralloc(&valbuf, 16);
470 
471 		switch (k) {
472 
473 		/* Interval time and sequence number. */
474 
475 		case 16:
476 		case 27:
477 			aprop->value += 1;
478 			break;
479 
480 		/* Exposure and flash compensation. */
481 
482 		case 13:
483 		case 35:
484 			aprop->str = valbuf;
485 			valbuf = NULL;
486 			if (aprop->value != 6)
487 				snprintf(aprop->str, 15, "%+0.1f EV",
488 				    ((double)aprop->value - 6) / 3);
489 			else
490 				snprintf(aprop->str, 15, "Normal");
491 			break;
492 
493 		/* Camera model (saved for 7Hi stupidity). */
494 
495 		case 37:
496 			model = aprop->value;
497 			break;
498 
499 		/* Focal length. */
500 
501 		case 18:
502 			aprop->str = valbuf;
503 			valbuf = NULL;
504 			snprintf(aprop->str, 15, "%02f",
505 			    (double)aprop->value / 256);
506 			break;
507 
508 		/* Still unknown. */
509 
510 		case 28:
511 		case 29:
512 		case 30:
513 			aprop->str = valbuf;
514 			valbuf = NULL;
515 			snprintf(aprop->str, 15, "%0.6f",
516 			    (double)aprop->value / 256);
517 			break;
518 
519 		/* Film speed. */
520 
521 		case 8:
522 			aprop->str = valbuf;
523 			valbuf = NULL;
524 			v = (u_int16_t)(pow(2, ((double)aprop->value / 8) -
525 			    1) * (double)3.125);
526 			snprintf(aprop->str, 15, "%d", v);
527 			break;
528 
529 		/* Aperture and max aperture. */
530 
531 		case 10:
532 		case 23:
533 			aprop->str = valbuf;
534 			valbuf = NULL;
535 			d = pow(2, ((double)aprop->value / 16) - 0.5);
536 			snprintf(aprop->str, 15, "%0.1f", d);
537 			break;
538 
539 		/* Exposure time. */
540 
541 		case 9:
542 			aprop->str = valbuf;
543 			valbuf = NULL;
544 			d = (double)pow(2,
545 			    ((double)abs(48 - aprop->value)) / 8);
546 
547 			/* 1 sec limit. */
548 			if (aprop->value < 56)
549 				snprintf(aprop->str, 15, "%0.1f", d);
550 			else
551 				snprintf(aprop->str, 15, "1/%d",
552 				    (unsigned int)d);
553 #if 0
554 			/*
555 			 * Bulb mode D7i bug: always recorded as 30 sec in
556 			 * EXIF_T_EXPOSURE, so override.
557 			 */
558 			if (aprop->value < 32) {
559 				aprop->override = EXIF_T_EXPOSURE;
560 				aprop->lvl = ED_IMG;
561 			}
562 #endif
563 			break;
564 
565 		/* Focus distance. */
566 
567 		case 19:
568 			aprop->str = valbuf;
569 			valbuf = NULL;
570 			if (!aprop->value)
571 				strcpy(aprop->str, "Infinite");
572 			else
573 				snprintf(aprop->str, 15, "%.1f",
574 				    (float)(aprop->value / (float)1000));
575 			aprop->value /= 100;
576 			break;
577 
578 		/* Exposure program. */
579 
580 		case 1:
581 			aprop->override = EXIF_T_EXPPROG;
582 			break;
583 
584 		/* Date. */
585 
586 		case 21:
587 			aprop->str = valbuf;
588 			valbuf = NULL;
589 			byte4exif(aprop->value, buf, LITTLE);
590 			snprintf(aprop->str, 15, "%02d/%02d/%04d",
591 			    buf[0], buf[1], buf[3] << 8 | buf[2]);
592 			break;
593 
594 		/* Time. */
595 
596 		case 22:
597 			aprop->str = valbuf;
598 			valbuf = NULL;
599 			byte4exif(aprop->value, buf, LITTLE);
600 			snprintf(aprop->str, 9, "%02d:%02d:%02d",
601 			    buf[2], buf[1], buf[0]);
602 			break;
603 
604 		/* White balance. */
605 
606 		case 3:
607 			aprop->override = EXIF_T_WHITEBAL;
608 			break;
609 
610 		/* Sharpness. */
611 
612 		case 33:
613 			aprop->override = EXIF_T_SHARPNESS;
614 			break;
615 
616 		/* Metering mode. */
617 
618 		case 7:
619 			aprop->override = EXIF_T_METERMODE;
620 			break;
621 
622 		/* Saturation, contrast, & color filter. */
623 
624 		case 31:
625 		case 32:
626 			aprop->override = (i == 31 ? EXIF_T_SATURATION :
627 			    EXIF_T_CONTRAST);
628 			/* FALLTHROUGH */
629 		case 41:
630 			aprop->str = valbuf;
631 			valbuf = NULL;
632 			aprop->value -= 3;
633 			if (aprop->value)
634 				snprintf(aprop->str, 15, "%+d", aprop->value);
635 			else
636 				strcpy(aprop->str, "Normal");
637 			break;
638 
639 		/* Scene. */
640 
641 		case 34:
642 			aprop->override = EXIF_T_SCENECAPTYPE;
643 			break;
644 		}
645 	}
646 	if (valbuf)
647 		free(valbuf);
648 }
649 
650 
651 /*
652  * Make sure meaningless values are meaningless.
653  */
654 static void
minolta_naval(struct exifprop * props,struct exiftag * tags,int16_t tag)655 minolta_naval(struct exifprop *props, struct exiftag *tags, int16_t tag)
656 {
657 	struct exifprop *prop;
658 	const char *na = "n/a";
659 
660 	if (!(prop = findprop(props, tags, tag)))
661 		return;
662 
663 	free(prop->str);
664 	prop->str = NULL;
665 	exifstralloc(&prop->str, strlen(na) + 1);
666 	strcpy(prop->str, na);
667 	if (!(prop->lvl & ED_UNK))
668 		prop->lvl = ED_VRB;
669 }
670 
671 
672 /*
673  * Process Minolta maker note tags.
674  */
675 void
minolta_prop(struct exifprop * prop,struct exiftags * t)676 minolta_prop(struct exifprop *prop, struct exiftags *t)
677 {
678 	struct exiftag *fielddefs = NULL;
679 	struct exifprop *tmpprop;
680 
681 	if (debug) {
682 		static int once = 0;	/* XXX Breaks on multiple files. */
683 
684 		if (!once) {
685 			printf("Processing Minolta Maker Note\n");
686 			once = 1;
687 		}
688 		dumpprop(prop, NULL);
689 	}
690 
691 	switch (prop->tag) {
692 
693 	/* Maker note type. */
694 
695 	case 0x0000:
696 		if (prop->count < 4)
697 			break;
698 		exifstralloc(&prop->str, prop->count + 1);
699 		byte4exif(prop->value, (unsigned char *)prop->str,
700 		    t->mkrmd.order);
701 
702 		/* We recognize two types: MLT0 and mlt0. */
703 
704 		if (strcmp(prop->str, "MLT0") && strcmp(prop->str, "mlt0"))
705 			exifwarn2("Minolta maker note version not supported",
706 			    prop->str);
707 		break;
708 
709 	/*
710 	 * Various image data.
711 	 * For now, we only trust specifically-sized tags.
712 	 */
713 
714 	case 0x0001:
715 		if (prop->count != 39 * 4) {
716 			exifwarn("Minolta maker note not fully supported");
717 			fielddefs = minolta_unkn;
718 		} else
719 			fielddefs = minolta_MLT0;
720 		minolta_cprop(prop, t->mkrmd.btiff + prop->value, t, fielddefs);
721 		break;
722 
723 	case 0x0003:
724 		if (prop->count != 56 * 4 && prop->count != 57 * 4) {
725 			exifwarn("Minolta maker note not fully supported");
726 			fielddefs = minolta_unkn;
727 		} else
728 			fielddefs = minolta_MLT0;
729 		minolta_cprop(prop, t->mkrmd.btiff + prop->value, t, fielddefs);
730 		break;
731 	}
732 
733 	/* Override meaningless values. */
734 
735 	if (fielddefs) {
736 
737 		/* Drive mode (bracketing step & mode). */
738 
739 		if ((tmpprop = findprop(t->props, fielddefs, 6)))
740 			if (tmpprop->value != 4) {
741 				minolta_naval(t->props, fielddefs, 14);
742 				minolta_naval(t->props, fielddefs, 50);
743 			}
744 
745 		/* Focus mode (wide focus area, AF zone, point X & Y). */
746 
747 		if ((tmpprop = findprop(t->props, fielddefs, 48)))
748 			if (tmpprop->value == 1) {
749 				minolta_naval(t->props, fielddefs, 45);
750 				minolta_naval(t->props, fielddefs, 46);
751 				minolta_naval(t->props, fielddefs, 47);
752 				minolta_naval(t->props, fielddefs, 49);
753 			}
754 
755 		/* Flash fired (flash comp, mode, & internal flash). */
756 
757 		if ((tmpprop = findprop(t->props, fielddefs, 20)))
758 			if (tmpprop->value != 1) {
759 				minolta_naval(t->props, fielddefs, 2);
760 				minolta_naval(t->props, fielddefs, 35);
761 				minolta_naval(t->props, fielddefs, 43);
762 			}
763 
764 		/* Exposure mode (meter mode, exposure comp). */
765 
766 		if ((tmpprop = findprop(t->props, tags, EXIF_T_EXPMODE)))
767 			if (tmpprop->value == 1) {
768 				minolta_naval(t->props, fielddefs, 7);
769 				minolta_naval(t->props, fielddefs, 13);
770 			}
771 
772 		/* Exposure prog (scene capture type). */
773 
774 		if ((tmpprop = findprop(t->props, fielddefs, 1)))
775 			if (tmpprop->value != 0)
776 				minolta_naval(t->props, fielddefs, 34);
777 
778 		/* Interval mode (interval pics, time). */
779 
780 		if ((tmpprop = findprop(t->props, fielddefs, 38)))
781 			if (tmpprop->value != 1) {
782 				minolta_naval(t->props, fielddefs, 16);
783 				minolta_naval(t->props, fielddefs, 17);
784 			}
785 	}
786 }
787 
788 
789 /*
790  * Try to read a Minolta maker note IFD, which differs by model.
791  */
792 struct ifd *
minolta_ifd(u_int32_t offset,struct tiffmeta * md)793 minolta_ifd(u_int32_t offset, struct tiffmeta *md)
794 {
795 
796 	/* DiMAGE E201. */
797 
798 	if (!strcmp((const char *)(md->btiff + offset), "+M")) {
799 		exifwarn("Minolta maker note version not supported");
800 		return (NULL);
801 	}
802 
803 	/*
804 	 * Assume that if IFD num > 255 or < 2, this isn't a real IFD.
805 	 * Takes care of the unfortunate DiMAGE 2300 & EX.
806 	 */
807 
808 	if (exif2byte(md->btiff + offset, md->order) > 0xff ||
809 	    exif2byte(md->btiff + offset, md->order) < 0x02) {
810 		exifwarn("Minolta maker note version not supported");
811 		return (NULL);
812 	}
813 
814 	return (readifds(offset, minolta_tags, md));
815 }
816