1 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
2 /* EXIFPROBE - TIFF/JPEG/EXIF image file probe */
3 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
4 /* Copyright (C) 2002,2005 by Duane H. Hesser. All rights reserved. */
5 /* */
6 /* See the file LICENSE.EXIFPROBE for terms of use. */
7 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
8
9 #ifndef lint
10 static char *ModuleId = "@(#) $Id: maker_minolta.c,v 1.28 2005/07/24 21:57:28 alex Exp $";
11 #endif
12
13 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
14 /* minolta camera maker-specific routines */
15 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
16 /* Most of the information used here is due to Dalibor Jelinek at: */
17 /* http://www.dalibor.cz/minolta/makernote.htm */
18 /* */
19 /* The F100 and "X" models *appear* to use the same MakerNote tagset */
20 /* as used for Sanyo models, as decoded by John Hawkins */
21 /* http://www.exif.org/makernotes/SanyoMakerNote.html */
22 /* */
23 /* NOTE that this is guesswork. Test images I have found for these */
24 /* models appear to decode properly using the tag numbers from */
25 /* Hawkinn's Sanyo data. Send mail if you can confirm or deny. */
26 /* */
27 /* The EX model MakerNote format is indecipherable. */
28 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include "defs.h"
34 #include "datadefs.h"
35 #include "maker_datadefs.h"
36 #include "summary.h"
37 #include "maker.h"
38 #include "misc.h"
39 #include "tags.h"
40 #include "maker_extern.h"
41 #include "extern.h"
42
43 extern struct camera_id minolta_model_id[];
44
45 /* Find the identifying number assigned to known Minolta camera */
46 /* models, and record the noteversion and tagset assigned to that */
47 /* model. The noteversion is used to dispatch print and interpret */
48 /* routines approopriate to the current image. */
49
50 int
minolta_model_number(char * model,char * software)51 minolta_model_number(char *model,char *software)
52 {
53 struct camera_id *model_id;
54 int number = NO_MODEL;
55
56 for(model_id = &minolta_model_id[0]; model_id && model_id->name; ++model_id)
57 {
58 if(strncasecmp(model,model_id->name,model_id->namelen) == 0)
59 {
60 number = model_id->id;
61 setnoteversion(model_id->noteversion);
62 setnotetagset(model_id->notetagset); /* info only */
63 break;
64 }
65 }
66 return(number);
67 }
68
69
70 /* Dispatch a print routine based upon the noteversion which has been */
71 /* assigned. */
72
73 void
print_minolta_makervalue(struct ifd_entry * entry_ptr,int make,int model,char * prefix)74 print_minolta_makervalue(struct ifd_entry *entry_ptr,int make, int model,
75 char *prefix)
76 {
77 int noteversion = 0;
78
79 noteversion = getnoteversion();
80
81 if(entry_ptr && (PRINT_VALUE))
82 {
83 switch(noteversion)
84 {
85 case 1:
86 print_minolta1_makervalue(entry_ptr,make,model,prefix);
87 minolta1_interpret_value(entry_ptr,model);
88 break;
89 default:
90 print_value(entry_ptr,PREFIX);
91 break;
92 }
93 }
94 }
95
96 /* Maker-specific print routine for minolta cameras. This routine is */
97 /* responsible for picking off any direct entry tags which are */
98 /* peculiar and might not be handled properly by print_value() */
99 /* (usually UNDEFINED values which fit in the 4-byte entry value). If */
100 /* there are no such entries, this function simply calls */
101 /* print_value(). */
102
103 void
print_minolta1_makervalue(struct ifd_entry * entry_ptr,int make,int model,char * prefix)104 print_minolta1_makervalue(struct ifd_entry *entry_ptr,int make, int model,
105 char *prefix)
106 {
107 int chpr = 0;
108 if(entry_ptr && (PRINT_VALUE))
109 {
110 switch(entry_ptr->tag)
111 {
112 case 0x0040: /* ImageByteSize */
113 chpr += printf("%lu ",entry_ptr->value);
114 if(entry_ptr->count > 1)
115 {
116 printred("# BAD COUNT");
117 setcharsprinted(chpr);
118 }
119 break;
120 default:
121 print_value(entry_ptr,PREFIX);
122 break;
123 }
124 }
125 }
126
127 /* Dispatch a routine to decode and print offset values for minolta */
128 /* cameras. */
129
130 void
print_minolta_offset_makervalue(FILE * inptr,unsigned short byteorder,struct ifd_entry * entry_ptr,unsigned long fileoffset_base,struct image_summary * summary_entry,char * parent_name,char * prefix,int indent,int make,int model,int at_offset)131 print_minolta_offset_makervalue(FILE *inptr,unsigned short byteorder,
132 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
133 struct image_summary *summary_entry,char *parent_name,char*prefix,
134 int indent,int make,int model,int at_offset)
135 {
136 int noteversion = 0;
137
138
139 if(entry_ptr)
140 {
141 noteversion = getnoteversion();
142 switch(noteversion)
143 {
144 case 1:
145 minolta1_offset_makervalue(inptr,byteorder,entry_ptr,
146 fileoffset_base,summary_entry,
147 parent_name,prefix,indent,
148 make,model,at_offset);
149 minolta1_interpret_offset_makervalue(inptr,byteorder,entry_ptr,
150 fileoffset_base);
151 break;
152 default:
153 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,
154 fileoffset_base,parent_name,prefix,indent,
155 make,model,at_offset);
156 break;
157 }
158 }
159 }
160
161 /* Maker-specific routine to print UNDEFINED values found at offsets */
162 /* in minolta makernotes. One of these may be supplied for each model */
163 /* with unique UNDEFINED tags. */
164
165 void
minolta1_offset_makervalue(FILE * inptr,unsigned short byteorder,struct ifd_entry * entry_ptr,unsigned long fileoffset_base,struct image_summary * summary_entry,char * parent_name,char * prefix,int indent,int make,int model,int at_offset)166 minolta1_offset_makervalue(FILE *inptr,unsigned short byteorder,
167 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
168 struct image_summary *summary_entry,char *parent_name,char*prefix,
169 int indent,int make,int model,int at_offset)
170 {
171 static unsigned long jpegthumbnailoffset = 0UL;
172 unsigned long value_offset;
173 unsigned long dumplength;
174 unsigned long count;
175 unsigned long max_offset = 0;
176 unsigned short marker;
177 char *nameoftag,*tagprefix;
178 char *fulldirname = NULL;
179 int status = 0;
180 int chpr = 0;
181
182 if(entry_ptr)
183 {
184 nameoftag = maker_tagname(entry_ptr->tag,make,model);
185 fulldirname = splice(parent_name,".",nameoftag);
186 value_offset = fileoffset_base + entry_ptr->value;
187 count = entry_ptr->count;
188 switch(entry_ptr->tag)
189 {
190 case 0x0001: /* Camera Settings, old */
191 case 0x0003: /* Camera Settings, new */
192 if(at_offset)
193 {
194 if((PRINT_SECTION))
195 {
196 print_tag_address(SECTION,value_offset,indent,prefix);
197 chpr += printf("<%s> ",nameoftag);
198 chpr += printf("%lu entries",count / 4);
199 }
200 }
201 else if(!at_offset && (PRINT_VALUE))
202 {
203 if(!(PRINT_OFFSET))
204 chpr += printf("@%lu",value_offset);
205 }
206 if((PRINT_LONGNAMES))
207 tagprefix = fulldirname;
208 else
209 tagprefix = nameoftag;
210 max_offset = minolta_camerasetting(inptr,byteorder,model,tagprefix,
211 entry_ptr,value_offset,indent + MEDIUMINDENT);
212 if(PRINT_SECTION)
213 {
214 chpr = newline(0);
215 print_tag_address(SECTION,max_offset - 1,indent,prefix);
216 chpr += printf("</%s> ",nameoftag);
217 }
218 setcharsprinted(chpr);
219 break;
220 case 0x0040: /* ImageByteSize */
221 break; /* should have a count of 1 */
222 case 0x0088: /* JpegThumbnailOffset */
223 /* It's not magic, there's a trick to it. The offset */
224 /* length will normally be the next entry tag in the */
225 /* IFD, and this will work iff it is. Remember the */
226 /* offset and handle it when the length tag is seen. */
227 /* This is necessary because we do not save entries. */
228 jpegthumbnailoffset = value_offset;
229 if(!at_offset && (PRINT_VALUE))
230 {
231 if(!(PRINT_OFFSET))
232 chpr += printf("@%lu",jpegthumbnailoffset);
233 }
234 break;
235 case 0x0089: /* JpegThumbnailLength */
236 if(jpegthumbnailoffset == 0UL)
237 {
238 printred("# WARNING: JpegThumbnailLength encountered with 0 offset");
239 break; /* must have the offset. */
240 }
241 value_offset = jpegthumbnailoffset;
242 count = entry_ptr->value;
243 jpegthumbnailoffset = 0L;
244 /* fall through */
245 case 0x0081: /* Jpeg Thumbnail */
246 /* Minolta seems to use EITHER 0x0088/0x0089 OR */
247 /* 0x0081, not both. */
248 if(at_offset && (PRINT_SECTION))
249 {
250 print_tag_address(VALUE_AT_OFFSET,value_offset,indent,
251 prefix);
252 chpr += printf("# Start of JPEG Thumbnail from MakerNote");
253 chpr += printf(" length %lu",count);
254 }
255 else if(!at_offset && (PRINT_VALUE) && (entry_ptr->tag == 0x0081))
256 {
257 if(!(PRINT_OFFSET))
258 chpr += printf("@%lu:%lu",value_offset,count);
259 else
260 chpr = printf(":%lu",count);
261 if(!(PRINT_VALUE_AT_OFFSET))
262 chpr += printf(" # UNDEFINED");
263 }
264 if((PRINT_SECTION) || (PRINT_SEGMENT))
265 chpr = newline(chpr);
266 marker = read_ushort(inptr,TIFF_MOTOROLA,value_offset);
267 max_offset = process_jpeg_segments(inptr,value_offset,marker,
268 count,summary_entry,fulldirname,
269 prefix,indent+SMALLINDENT);
270 if(at_offset)
271 {
272 if((PRINT_SECTION))
273 {
274 if((status = jpeg_status(0) == JPEG_EARLY_EOI))
275 chpr = newline(chpr);
276 jpeg_status(status);
277 print_tag_address(VALUE_AT_OFFSET,value_offset + count - 1,
278 indent,"-");
279 chpr += printf("# End of JPEG Thumbnail from MakerNote");
280 if((PRINT_ENTRY) && !(PRINT_VALUE))
281 chpr = newline(chpr);
282 }
283 }
284 print_jpeg_status();
285 if(marker && summary_entry)
286 {
287 /* The new one is on the end of the chain */
288 if((summary_entry = last_summary_entry(summary_entry)))
289 {
290 summary_entry->filesubformat |= FILESUBFMT_MNOTE;
291 summary_entry->datatype = MAKER_IFD;
292 summary_entry->subfiletype = THUMBNAIL_TYPE;
293 }
294 }
295 /* make certain we're at the end */
296 clearerr(inptr);
297 fseek(inptr,value_offset + count,0);
298 break;
299 case 0x0e00: /* PrintIM */
300 if(!at_offset && (PRINT_VALUE))
301 {
302 if(!(PRINT_OFFSET))
303 {
304 chpr += printf("@%lu:%lu",value_offset,count);
305 chpr = newline(chpr);
306 }
307 }
308 process_pim(inptr,byteorder,entry_ptr->value,fileoffset_base,
309 count,nameoftag,parent_name,prefix,indent);
310 break;
311 case 0x0f00: /* Data */
312 if(at_offset && (PRINT_ENTRY))
313 {
314 print_tag_address(ENTRY,value_offset,indent,prefix);
315 print_makertagid(entry_ptr,23," : ",make,model);
316 chpr += printf(" length %-9lu", count);
317 if(Max_undefined == 0)
318 {
319 if(chpr)
320 printred(" (not dumped, use -U)");
321 }
322 else
323 {
324 if((Max_undefined == DUMPALL) || (Max_undefined > count))
325 dumplength = count;
326 else
327 dumplength = Max_undefined;
328 chpr = newline(chpr);
329 hexdump(inptr,value_offset,count,dumplength,12,
330 indent,SUBINDENT);
331 chpr = newline(1);
332 }
333 }
334 else if(!at_offset && (PRINT_VALUE))
335 {
336 if(!(PRINT_OFFSET))
337 chpr += printf("@%lu:%lu",value_offset,count);
338 else
339 chpr += printf(":%lu", count);
340 if(!(PRINT_VALUE_AT_OFFSET))
341 chpr += printf(" # UNDEFINED");
342 }
343 /* make certain we're at the end */
344 fseek(inptr,value_offset + count,0);
345 break;
346 default:
347 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,
348 fileoffset_base,fulldirname,prefix,indent,
349 make,model,at_offset);
350 break;
351 }
352 if(fulldirname)
353 free(fulldirname);
354 }
355 setcharsprinted(chpr);
356 }
357
358 /* Minolta-specific tagnames for makernotes. */
359 /* Minolta models sport at least 9 different MakerNote tagsets that I */
360 /* have seen. However, the various tagsets do not overlap (if a given */
361 /* tag number is used in more than 1 model, it is assigned the same */
362 /* meaning everywhere). This makes it possible to use a single */
363 /* routine for tagnames, values, interpretations, etc. */
364
365 char *
maker_minolta_tagname(unsigned short tag,int model)366 maker_minolta_tagname(unsigned short tag,int model)
367 {
368 char *tagname = (char *)0;
369 int noteversion = 0;
370
371 /* Should have to do this only once, and only for unrecognized */
372 /* models. If the model is recognized (or the user has forced a */
373 /* noteversion) noteversion will already be set. */
374 if((noteversion = getnoteversion()) == 0)
375 {
376 noteversion = 1;
377 setnoteversion(1);
378 }
379
380 switch(noteversion)
381 {
382 case 1:
383 tagname = maker_minolta1_tagname(tag,model);
384 break;
385 default:
386 break;
387 }
388
389 /* If no model-specific tag is found, check "generic" tags */
390 if(tagname == NULL)
391 {
392 switch(tag)
393 {
394 case 0x0e00: tagname = "PrintIM"; break;
395 default: break;
396 }
397 }
398 return(tagname);
399 }
400
401 /* Although several versions of Minolta MakerNotes have been seen in */
402 /* the wild, there appears to be no duplication of tag numbers (i.e. */
403 /* no tag number is used for different purposes in one note version */
404 /* than in another vesion. This makes it possible to treat the notes */
405 /* as a single version. */
406
407 /* For now... */
408
409 char *
maker_minolta1_tagname(unsigned short tag,int model)410 maker_minolta1_tagname(unsigned short tag,int model)
411 {
412 char *tagname = CNULL;
413
414 /* The Minolta MakerNote of TIFF format images have a JPEG */
415 /* thumbnail with a defective SOI marker (0x00f8). In fact, */
416 /* Minolta JPEG_SOI is often missing the high "0xff". */
417
418 if(tagname == NULL)
419 {
420 switch(tag)
421 {
422 case 0x0000: tagname = "Version"; break;
423 case 0x0001: tagname = "CameraSettings"; break;
424 case 0x0003: tagname = "CameraSettings"; break;
425 case 0x0040: tagname = "ImageByteSize"; break;
426 case 0x0081: tagname = "JpegThumbnail"; break;
427 case 0x0088: tagname = "JpegThumbnailOffset"; break;
428 case 0x0089: tagname = "JpegThumbnailLength"; break;
429 case 0x0101: tagname = "ColorMode"; break;
430 case 0x0102: tagname = "ImageQuality"; break;
431 case 0x0103: if(model == MINOLTA_DIMAGE7Hi)
432 tagname = "ImageQuality";
433 else
434 tagname = "ImageSize";
435 break;
436 /* The following tagname appears valid for at least the */
437 /* F200, thanks to Harald Puhl (h.puhl@ki-ag.com) */
438 case 0x0104: tagname = "FlashCompensation"; break;
439 case 0x0200: tagname = "SpecialMode"; break;
440
441 /* The following tag names appear valid for the F100 and "X" but */
442 /* do not appear to be used for any other Minolta model. They are */
443 /* essentially the Sanyo tag set, used here based upon guesswork; */
444 /* some Minolta and Sanyo cameras are said to use the same chip, */
445 /* and some F100 and "X" images I've seen contain almost exactly */
446 /* this set of tags (as described by John Hawkins for Sanyo */
447 /* DSC-MZ2 notes). The Quality, Macro, SpecialMode and PrintIM */
448 /* tags are reasonably certain to be correct (they "decode" */
449 /* properly). The remaining names are less certain, and no */
450 /* attempt is made to decode them in minolta1_interpret_value()/ */
451
452 case 0x0201: tagname = "Quality"; break;
453 case 0x0202: tagname = "Macro"; break;
454 case 0x0204: tagname = "DigiZoom"; break;
455 case 0x0207: tagname = "SoftwareRelease"; break;
456 case 0x0208: tagname = "PictInfo"; break;
457 case 0x0209: tagname = "CameraID"; break;
458 case 0x020e: tagname = "SeqShotMethod"; break;
459 case 0x020f: tagname = "WideRange"; break;
460 case 0x0210: tagname = "ColorAdjMode"; break;
461 case 0x0213: tagname = "QuickShot"; break;
462 case 0x0214: tagname = "SelfTimer"; break;
463 case 0x0216: tagname = "VoiceMemo"; break;
464 case 0x0217: tagname = "RecordShutterRel"; break;
465 case 0x0218: tagname = "FlickerReduce"; break;
466 case 0x0219: tagname = "OpticalZoom"; break;
467 case 0x021b: tagname = "DigitalZoom"; break;
468 case 0x021d: tagname = "LightSourceSpecial"; break;
469 case 0x021e: tagname = "Resaved"; break;
470 case 0x021f: tagname = "SceneSelect"; break;
471 case 0x0223: tagname = "ManualFocusDist"; break; /* ###%%% not seen */
472 case 0x0224: tagname = "SeqShotIntvl"; break; /* ###%%% not seen */
473 case 0x0225: tagname = "FlashMode"; break; /* ###%%% not seen */
474 case 0x0e00: tagname = "PrintIM"; break;
475 case 0x0f00: tagname = "Data"; break;
476 default: break;
477 }
478 }
479 setnotetagset(1);
480 return(tagname);
481 }
482
483
484 void
minolta1_interpret_value(struct ifd_entry * entry_ptr,int model)485 minolta1_interpret_value(struct ifd_entry *entry_ptr,int model)
486 {
487 int chpr = 0;
488
489 if(entry_ptr && (PRINT_VALUE))
490 {
491 switch(entry_ptr->tag)
492 {
493 case 0x0101: /* ColorMode */
494 print_startvalue();
495 switch(entry_ptr->value)
496 {
497 case 0: chpr += printf("Natural"); break;
498 case 1: chpr += printf("Black/White*"); break;
499 case 2: chpr += printf("Vivid"); break;
500 case 3: chpr += printf("Solarize"); break;
501 case 4: chpr += printf("Adobe RGB"); break;
502 case 9: chpr += printf("unknown"); break;
503 case 132: chpr += printf("Adobe RGB Embedded Profile"); break;
504 default: printred("undefined"); break;
505 }
506 print_endvalue();
507 break;
508 case 0x0102: /* CameraSettings ImageQuality, 7, 7Hi, F300 */
509 minolta_7Hi_botch:
510 print_startvalue();
511 switch(entry_ptr->value)
512 {
513 /* ###%%% jpeg quality/compression? check this */
514 case 0: chpr += printf("Raw"); break;
515 case 1: chpr += printf("Uncompressed"); break; /* superfine, raw? tiff? */
516 case 2: chpr += printf("Fine(1/2)"); break;
517 case 3: chpr += printf("Normal(1/3)"); break; /* ###%%% */
518 case 4: chpr += printf("Economy(1/4)"); break; /* ###%%% */
519 case 5: chpr += printf("ExtraFine(1/1)"); break;
520 default: printred("undefined"); break;
521 }
522 print_endvalue();
523 break;
524 case 0x0103: /* CameraSettings ImageSize*, 7Hi, F300 */
525 /* The 7Hi appears to get this wrong, printing the same */
526 /* value for this as for 0x0102; the F300 seems to do it */
527 /* right. The ImageSize entry in "Camera Settings" */
528 /* appears correct in both cases. For the 7Hi, it would */
529 /* be wrong to report this as image size, so just don't */
530 /* do it. */
531 if(model == MINOLTA_DIMAGE7Hi)
532 goto minolta_7Hi_botch;
533
534 print_startvalue();
535 switch(entry_ptr->value)
536 {
537 case 1: chpr += printf("1600x1200"); break;
538 case 2: chpr += printf("unknown"); break; /* 1280x960? */
539 case 3: chpr += printf("640x480"); break;
540 case 4: chpr += printf("unknown"); break;
541 case 5: chpr += printf("2560x1920"); break;
542 case 6: chpr += printf("2272x1704"); break;
543 case 7: chpr += printf("2048x1536"); break;
544 case 13: chpr += printf("3264x2448"); break;
545 default: printred("undefined"); break;
546 }
547 print_endvalue();
548 break;
549 case 0x0201: /* Quality, X, F100 */
550 print_startvalue();
551 /* ###%%% jpeg quality/compression? check this, same as 0x0102? */
552 switch(entry_ptr->value)
553 {
554 case 0: chpr += printf("Raw*"); break;
555 case 1: chpr += printf("Economy(1/8)"); break;
556 case 2: chpr += printf("Normal(1/4)"); break;
557 case 3: chpr += printf("Fine(1/2)"); break;
558 case 4: chpr += printf("Uncompressed"); break;
559 default: printred("undefined"); break;
560 }
561 print_endvalue();
562 break;
563 case 0x0202: /* Macro */
564 print_startvalue();
565 switch(entry_ptr->value)
566 {
567 case 0: chpr += printf("Normal"); break;
568 case 1: chpr += printf("Macro"); break;
569 case 2: chpr += printf("View"); break;
570 default: printred("undefined"); break;
571 }
572 print_endvalue();
573 break;
574 default:
575 break;
576 }
577 }
578 setcharsprinted(chpr);
579 }
580
581 void
minolta1_interpret_offset_makervalue(FILE * inptr,unsigned short byteorder,struct ifd_entry * entry_ptr,unsigned long fileoffset_base)582 minolta1_interpret_offset_makervalue(FILE *inptr,unsigned short byteorder,
583 struct ifd_entry *entry_ptr,unsigned long fileoffset_base)
584 {
585 unsigned long offset,value;
586 int chpr = 0;
587
588 if(entry_ptr && (PRINT_VALUE))
589 {
590 offset = entry_ptr->value + fileoffset_base;
591 switch(entry_ptr->tag)
592 {
593 case 0x0200: /* SpecialMode */
594 value = read_ulong(inptr,byteorder,offset);
595 print_startvalue();
596 switch(value)
597 {
598 case 0: chpr += printf("Normal"); break;
599 case 1: chpr += printf("Unkown"); break;
600 case 2: chpr += printf("Fast"); break;
601 case 3: chpr += printf("Panorama,");
602 value = read_ulong(inptr,byteorder,HERE);
603 chpr += printf("#%lu,",value);
604 value = read_ulong(inptr,byteorder,HERE);
605 switch(value)
606 {
607 case 1: chpr += printf(" Left to Right"); break;
608 case 2: chpr += printf(" Right to Left"); break;
609 case 3: chpr += printf(" Bottom to Top"); break;
610 case 4: chpr += printf(" Top to Bottom"); break;
611 default: printred(" undefined"); break;
612 }
613 break;
614 default: printred("undefined"); break;
615 }
616 print_endvalue();
617 break;
618 default:
619 break;
620 }
621 }
622 setcharsprinted(chpr);
623 }
624
625 /* Interpret the "Camera Settings" tag data from Minolta MakerNotes. */
626
627 #include <math.h>
628
629 unsigned long
minolta_camerasetting(FILE * inptr,unsigned short byteorder,int model,char * tagprefix,struct ifd_entry * entry_ptr,unsigned long offset,int indent)630 minolta_camerasetting(FILE *inptr,unsigned short byteorder,int model,
631 char *tagprefix,struct ifd_entry *entry_ptr,unsigned long offset,int indent)
632 {
633 unsigned long value,end_offset;
634 double fvalue;
635 int i,corr_i,entries;
636 signed char wcorr;
637 int chpr = 0;
638
639 end_offset = offset + entry_ptr->count;
640 if((PRINT_SECTION))
641 chpr += printf(" length %lu",entry_ptr->count);
642 if((PRINT_ENTRY))
643 {
644 entries = entry_ptr->count / 4;
645 for(i = 0; i < entries; ++i)
646 {
647 chpr = newline(chpr);
648 value = read_ulong(inptr,TIFF_MOTOROLA,offset);
649 print_tag_address(ENTRY,offset,indent,"@");
650 if((PRINT_TAGINFO))
651 chpr += printf("%s.",tagprefix);
652 offset += 4;
653
654 /* Very oddly new values are inserted after value 51. */
655 corr_i=i;
656 if((model != MINOLTA_DIMAGE7Hi) && (model != MINOLTA_DIMAGEA1))
657 {
658 if (i > 50)
659 corr_i++;
660 }
661 if((model != MINOLTA_DIMAGEA1) && (model != MINOLTA_DIMAGEA2) && (model != MINOLTA_DIMAGEA200))
662 {
663 if (i > 51)
664 corr_i++;
665 }
666
667 switch(corr_i)
668 {
669 case 0:
670 if((PRINT_TAGINFO))
671 chpr += printf("%02d:%-21.21s",i,"Unknown");
672 if((PRINT_VALUE))
673 chpr += printf(" = %lu",value);
674 break;
675 case 1:
676 if((PRINT_TAGINFO))
677 chpr += printf("%02d:%-21.21s",i,"ExposureMode");
678 if((PRINT_VALUE))
679 {
680 chpr += printf(" = %lu",value);
681 print_startvalue();
682 switch(value)
683 {
684 case 0: chpr += printf("Programmed Auto"); break;
685 case 1: chpr += printf("Aperture Priority Auto"); break;
686 case 2: chpr += printf("Shuttter Priority Auto"); break;
687 case 3: chpr += printf("Manual"); break;
688 default: printred("undefined"); break;
689 }
690 print_endvalue();
691 }
692 break;
693 case 2:
694 if((PRINT_TAGINFO))
695 chpr += printf("%02d:%-21.21s",i,"FlashMode");
696 if((PRINT_VALUE))
697 {
698 chpr += printf(" = %lu",value);
699 print_startvalue();
700 switch(value)
701 {
702 case 0: chpr += printf("Fill-Flash"); break;
703 case 1: chpr += printf("Red Eye Reduction"); break;
704 case 2: chpr += printf("Rear Flash Sync"); break;
705 case 3: chpr += printf("Wireless"); break;
706 default: printred("undefined"); break;
707 }
708 print_endvalue();
709 }
710 break;
711 case 3:
712 if((PRINT_TAGINFO))
713 chpr += printf("%02d:%-21.21s",i,"WhiteBalance");
714 if((PRINT_VALUE))
715 {
716 chpr += printf(" = %#lx",value);
717 print_startvalue();
718 if (value & 0x00ff0000)
719 {
720 /* New style white balance values */
721 switch(value >> 24)
722 {
723 case 0: printf("Auto"); break;
724 case 1: printf("Daylight"); break;
725 case 2: printf("Cloudy"); break;
726 case 3: printf("Incandescent"); break;
727 case 5: printf("Fluorescent"); break;
728 case 6: printf("Shadow"); break;
729 case 7: printf("Memory1"); break;
730 case 8: printf("Memory2"); break;
731 case 9: printf("Memory3"); break;
732 default: printred("unknown"); break;
733 }
734 wcorr = ((value & 0x00ffffff) >> 16) - 0x80;
735 switch(wcorr)
736 {
737 case 0: break;
738 default: printf(" %+hd", wcorr); break;
739 }
740 }
741 else
742 {
743 /* Old style white balance values */
744 switch(value)
745 {
746 case 0: chpr += printf("Auto"); break;
747 case 1: chpr += printf("Daylight"); break;
748 case 2: chpr += printf("Cloudy"); break;
749 case 3: chpr += printf("Incandescent"); break;
750 case 5: chpr += printf("Custom"); break;
751 case 7: chpr += printf("Fluorescent"); break;
752 case 8: chpr += printf("Fluorescent2"); break;
753 case 11: chpr += printf("Custom2"); break;
754 case 12: chpr += printf("Custom3"); break;
755 default: printred("unknown"); break;
756 }
757 }
758 print_endvalue();
759 }
760 break;
761 case 4:
762 if((PRINT_TAGINFO))
763 chpr += printf("%02d:%-21.21s",i,"ImageSize");
764 if((PRINT_VALUE))
765 {
766 chpr += printf(" = %lu",value);
767 print_startvalue();
768 switch(value)
769 {
770 /* ###%%% There should also be a */
771 /* 2080x1560 size, at least for the A1 */
772 case 0: switch(model)
773 {
774 case MINOLTA_DIMAGEA2:
775 chpr += printf("3264x2448");
776 break;
777 case MINOLTA_DIMAGES404:
778 case MINOLTA_DIMAGES414:
779 chpr += printf("2272x1704");
780 break;
781 case MINOLTA_DIMAGE5:
782 chpr += printf("2048x1536");
783 break;
784 case MINOLTA_DIMAGEA1:
785 case MINOLTA_DIMAGE7Hi:
786 case MINOLTA_DIMAGE7i:
787 default:
788 chpr += printf("2560x1920");
789 break;
790 }
791 break;
792 case 1: chpr += printf("1600x1200"); break;
793 case 2: chpr += printf("1280x960"); break;
794 case 3: chpr += printf("640x480"); break;
795 default: printred("undefined"); break;
796 }
797 print_endvalue();
798 }
799 break;
800 case 5:
801 if((PRINT_TAGINFO))
802 chpr += printf("%02d:%-21.21s",i,"ImageQuality");
803 if((PRINT_VALUE))
804 {
805 chpr += printf(" = %lu",value);
806 print_startvalue();
807 switch(value)
808 {
809 case 0: chpr += printf("RAW"); break;
810 case 1: chpr += printf("Super Fine"); break;
811 case 2: chpr += printf("Fine"); break;
812 case 3: chpr += printf("Standard"); break;
813 case 4: chpr += printf("Economy"); break;
814 case 5: chpr += printf("Extra Fine"); break;
815 default: printred("undefined"); break;
816 }
817 print_endvalue();
818 }
819 break;
820 case 6:
821 if((PRINT_TAGINFO))
822 chpr += printf("%02d:%-21.21s",i,"DriveMode");
823 if((PRINT_VALUE))
824 {
825 chpr += printf(" = %lu",value);
826 print_startvalue();
827 switch(value)
828 {
829 case 0: chpr += printf("Single"); break;
830 case 1: chpr += printf("Continuous"); break;
831 case 2: chpr += printf("Self Timer"); break;
832 case 4: chpr += printf("Bracketing"); break;
833 case 5: chpr += printf("Interval"); break;
834 case 6: chpr += printf("UHS Continuous"); break;
835 case 7: chpr += printf("HS Continuous"); break;
836 default: printred("undefined"); break;
837 }
838 print_endvalue();
839 }
840 break;
841 case 7:
842 if((PRINT_TAGINFO))
843 chpr += printf("%02d:%-21.21s",i,"MeteringMode");
844 if((PRINT_VALUE))
845 {
846 chpr += printf(" = %lu",value);
847 print_startvalue();
848 switch(value)
849 {
850 case 0: chpr += printf("Multi-Segment"); break;
851 case 1: chpr += printf("Center Weighted"); break;
852 case 2: chpr += printf("Spot"); break;
853 default: printred("undefined"); break;
854 }
855 print_endvalue();
856 }
857 break;
858 case 8:
859 if((PRINT_TAGINFO))
860 chpr += printf("%02d:%-21.21s",i,"CCDSentitivity");
861 if((PRINT_VALUE))
862 {
863 if(PRINT_RAW_VALUES)
864 chpr += printf(" = %lu",value);
865 fvalue = ((double)value/8.0) - 1.0;
866 chpr += printf(" = %.3g APEX",fvalue);
867 fvalue = pow(2.0,fvalue) * 3.125;
868 print_startvalue();
869 chpr += printf("%.3g ISO",fvalue);
870 print_endvalue();
871 }
872 break;
873 case 9:
874 if((PRINT_TAGINFO))
875 chpr += printf("%02d_%-21.21s",i,"ShutterSpeed");
876 if((PRINT_VALUE))
877 {
878 if(PRINT_RAW_VALUES)
879 chpr += printf(" = %lu",value);
880 if (value == 8)
881 fvalue = 30.0; /* Due to rounding error x=8 should be displayed as 30 sec. */
882 else
883 {
884 fvalue = ((double)value / 8.0) - 6.0;
885 chpr += printf(" = %.3g APEX",fvalue);
886 fvalue = pow(2.0,-fvalue);
887 }
888 print_startvalue();
889 chpr += printf("%.3g sec",fvalue);
890 print_endvalue();
891 }
892 break;
893 case 10:
894 if((PRINT_TAGINFO))
895 chpr += printf("%02d_%-21.21s",i,"Aperture");
896 if((PRINT_VALUE))
897 {
898 if(PRINT_RAW_VALUES)
899 chpr += printf(" = %lu",value);
900 fvalue = (double)value/8.0 - 1.0;
901 chpr += printf(" = %.3g APEX",fvalue);
902 fvalue = pow(2.0,fvalue/2.0);
903 print_startvalue();
904 chpr += printf("f%.2g",fvalue);
905 print_endvalue();
906 }
907 break;
908 case 11:
909 if((PRINT_TAGINFO))
910 chpr += printf("%02d_%-21.21s",i,"MacroMode");
911 if((PRINT_VALUE))
912 {
913 chpr += printf(" = %lu",value);
914 print_startvalue();
915 switch(value)
916 {
917 case 0: chpr += printf("On"); break;
918 case 1: chpr += printf("Off"); break;
919 default: printred("undefined"); break;
920 }
921 print_endvalue();
922 }
923 break;
924 case 12:
925 if((PRINT_TAGINFO))
926 chpr += printf("%02d_%-21.21s",i,"DigitalZoom");
927 if((PRINT_VALUE))
928 {
929 chpr += printf(" = %lu",value);
930 print_startvalue();
931 switch(value)
932 {
933 case 0: chpr += printf("Off"); break;
934 case 1: chpr += printf("Electronic"); break;
935 case 2: chpr += printf("2x"); break;
936 /* FIXME: http://www.dalibor.cz/minolta/makernote.htm says 2 */
937 case 0xffff: chpr += printf("2x"); break;
938 default: printred("Undefined"); break;
939 }
940 print_endvalue();
941 }
942 break;
943 case 13:
944 if((PRINT_TAGINFO))
945 chpr += printf("%02d_%-21.21s",i,"ExposureCompensation");
946 if((PRINT_VALUE))
947 {
948 chpr += printf(" = %lu",value);
949 print_startvalue();
950 chpr += printf("%g EV",(double)value/3.0 - 2);
951 print_endvalue();
952 }
953 break;
954 case 14:
955 if((PRINT_TAGINFO))
956 chpr += printf("%02d:%-21.21s",i,"BracketStep");
957 if((PRINT_VALUE))
958 {
959 chpr += printf(" = %lu",value);
960 print_startvalue();
961 switch(value)
962 {
963 case 0: chpr += printf("1/3"); break;
964 case 1: chpr += printf("2/3"); break;
965 case 2: chpr += printf("1"); break;
966 default: printred("undefined"); break;
967 }
968 print_endvalue();
969 }
970 break;
971 case 15:
972 if((PRINT_TAGINFO))
973 chpr += printf("%02d:%-21.21s",i,"Unknown");
974 if((PRINT_VALUE))
975 chpr += printf(" = %lu",value);
976 break;
977 case 16:
978 if((PRINT_TAGINFO))
979 /* FIXME: Values don't fit on A1 */
980 chpr += printf("%02d_%-21.21s",i,"IntervalLength");
981 if((PRINT_VALUE))
982 {
983 chpr += printf(" = %lu",value + 1);
984 chpr += printf(" minutes");
985 }
986 break;
987 case 17:
988 if((PRINT_TAGINFO))
989 chpr += printf("%02d:%-21.21s",i,"IntervalNumber");
990 if((PRINT_VALUE))
991 chpr += printf(" = %lu",value);
992 break;
993 case 18:
994 if((PRINT_TAGINFO))
995 chpr += printf("%02d:%-21.21s",i,"FocalLength");
996 if((PRINT_VALUE))
997 {
998 /* This value is not equal to FocalLength in public
999 EXIF as the public one is tweaked to get 7x zoom to
1000 comply with marketing specification. The real zoom
1001 is 6.51x. * 3.9333 is 35mm equivalent */
1002 chpr += printf(" = %lu",value);
1003 fvalue = (double)value/256.0;
1004 print_startvalue();
1005 chpr += printf("%g mm",fvalue);
1006 print_endvalue();
1007 }
1008 break;
1009 case 19:
1010 if((PRINT_TAGINFO))
1011 chpr += printf("%02d:%-21.21s",i,"FocalDistance");
1012 if((PRINT_VALUE))
1013 {
1014 if (value == 0)
1015 {
1016 chpr += printf(" = infinity");
1017 }
1018 else
1019 {
1020 chpr += printf(" = %lu",value);
1021 chpr += printf(" mm");
1022 }
1023 }
1024 break;
1025 case 20:
1026 if((PRINT_TAGINFO))
1027 chpr += printf("%02d:%-21.21s",i,"FlashFired");
1028 if((PRINT_VALUE))
1029 {
1030 chpr += printf(" = %lu",value);
1031 print_startvalue();
1032 if(value == 0UL)
1033 chpr += printf("No");
1034 else
1035 chpr += printf("Yes");
1036 print_endvalue();
1037 }
1038 break;
1039 case 21:
1040 if((PRINT_TAGINFO))
1041 chpr += printf("%02d:%-21.21s",i,"Date");
1042 if((PRINT_VALUE))
1043 {
1044 chpr += printf(" = %#010lx",value);
1045 print_startvalue();
1046 chpr += printf("%02ld:%02ld:%02ld",(value & 0xffff0000) >> 16,
1047 (value & 0xff00) >> 8,value & 0xff);
1048 print_endvalue();
1049 }
1050 break;
1051 case 22:
1052 if((PRINT_TAGINFO))
1053 chpr += printf("%02d:%-21.21s",i,"Time");
1054 if((PRINT_VALUE))
1055 {
1056 chpr += printf(" = %#010lx",value);
1057 print_startvalue();
1058 chpr += printf("%02ld:%02ld:%02ld",(value & 0xffff0000) >> 16,
1059 (value & 0xff00) >> 8,value & 0xff);
1060 print_endvalue();
1061 }
1062 break;
1063 case 23:
1064 if((PRINT_TAGINFO))
1065 chpr += printf("%02d_%-21.21s",i,"MaxAperture");
1066 if((PRINT_VALUE))
1067 {
1068 if(PRINT_RAW_VALUES)
1069 chpr += printf(" = %lu",value);
1070 fvalue = (double)value/8.0 - 1.0;
1071 chpr += printf(" = %.3g APEX",fvalue);
1072 fvalue = pow(2.0,fvalue/2.0);
1073 print_startvalue();
1074 chpr += printf("f%.2g",fvalue);
1075 print_endvalue();
1076 }
1077 break;
1078 case 24:
1079 if((PRINT_TAGINFO))
1080 chpr += printf("%02d:%-21.21s",i,"Unknown");
1081 if((PRINT_VALUE))
1082 chpr += printf(" = %lu",value);
1083 break;
1084 case 25:
1085 if((PRINT_TAGINFO))
1086 chpr += printf("%02d:%-21.21s",i,"Unknown");
1087 if((PRINT_VALUE))
1088 chpr += printf(" = %lu",value);
1089 break;
1090 case 26:
1091 if((PRINT_TAGINFO))
1092 chpr += printf("%02d:%-21.21s",i,"FileNumberMemory");
1093 if((PRINT_VALUE))
1094 {
1095 chpr += printf(" = %lu",value);
1096 print_startvalue();
1097 if(value == 0UL)
1098 chpr += printf("Off");
1099 else
1100 chpr += printf("On");
1101 print_endvalue();
1102 }
1103 break;
1104 case 27:
1105 if((PRINT_TAGINFO))
1106 chpr += printf("%02d:%-21.21s",i,"LastFileNumber");
1107 if((PRINT_VALUE))
1108 {
1109 chpr += printf(" = %lu",value);
1110 /* 0 if FileNumberMemory is off */
1111 if(value == 0)
1112 {
1113 print_startvalue();
1114 chpr += printf("(FileNumberMemory Off)");
1115 print_endvalue();
1116 }
1117 }
1118 break;
1119 case 28:
1120 if((PRINT_TAGINFO))
1121 chpr += printf("%02d_%-21.21s",i,"WhiteBalanceRed");
1122 if((PRINT_VALUE))
1123 {
1124 chpr += printf(" = %lu",value);
1125 print_startvalue();
1126 chpr += printf("%.3f",value/256.0);
1127 print_endvalue();
1128 }
1129 break;
1130 case 29:
1131 /* Warning! Green white balance coefficient in */
1132 /* raw file may not be equal to one and in this */
1133 /* case WB coefficients stored in raw file will */
1134 /* not match those stored here. */
1135 if((PRINT_TAGINFO))
1136 chpr += printf("%02d:%-21.21s",i,"WhiteBalanceGreen");
1137 if((PRINT_VALUE))
1138 {
1139 chpr += printf(" = %lu",value);
1140 print_startvalue();
1141 chpr += printf("%.3f",value/256.0);
1142 print_endvalue();
1143 }
1144 break;
1145 case 30:
1146 if((PRINT_TAGINFO))
1147 chpr += printf("%02d:%-21.21s",i,"WhiteBalanceBlue");
1148 if((PRINT_VALUE))
1149 {
1150 chpr += printf(" = %lu",value);
1151 print_startvalue();
1152 chpr += printf("%.3f",value/256.0);
1153 print_endvalue();
1154 }
1155 break;
1156 case 31:
1157 if((PRINT_TAGINFO))
1158 chpr += printf("%02d:%-21.21s",i,"Saturation");
1159 if((PRINT_VALUE))
1160 {
1161 chpr += printf(" = %lu",value);
1162 print_startvalue();
1163 if ((model == MINOLTA_DIMAGEA1) || (model == MINOLTA_DIMAGEA2) || (model == MINOLTA_DIMAGEA200))
1164 chpr += printf("%+ld",value-5);
1165 else
1166 chpr += printf("%+ld",value-3);
1167
1168 print_endvalue();
1169 }
1170 break;
1171 case 32:
1172 if((PRINT_TAGINFO))
1173 chpr += printf("%02d:%-21.21s",i,"Contrast");
1174 if((PRINT_VALUE))
1175 {
1176 chpr += printf(" = %lu",value);
1177 print_startvalue();
1178 if ((model == MINOLTA_DIMAGEA1) || (model == MINOLTA_DIMAGEA2) || (model == MINOLTA_DIMAGEA200))
1179 chpr += printf("%+ld",value-5);
1180 else
1181 chpr += printf("%+ld",value-3);
1182
1183 print_endvalue();
1184 }
1185 break;
1186 case 33:
1187 if((PRINT_TAGINFO))
1188 chpr += printf("%02d:%-21.21s",i,"Sharpness");
1189 if((PRINT_VALUE))
1190 {
1191 chpr += printf(" = %lu",value);
1192 print_startvalue();
1193 switch(value)
1194 {
1195 case 0: chpr += printf("Hard"); break;
1196 case 1: chpr += printf("Normal"); break;
1197 case 2: chpr += printf("Soft"); break;
1198 case 3: chpr += printf("None"); break;
1199 default: printred("undefined"); break;
1200 }
1201 print_endvalue();
1202 }
1203 break;
1204 case 34:
1205 if((PRINT_TAGINFO))
1206 chpr += printf("%02d:%-21.21s",i,"Subject Program");
1207 if((PRINT_VALUE))
1208 {
1209 chpr += printf(" = %lu",value);
1210 print_startvalue();
1211 switch(value)
1212 {
1213 case 0: chpr += printf("None"); break;
1214 case 1: chpr += printf("Portrait"); break;
1215 case 2: chpr += printf("Text"); break;
1216 case 3: chpr += printf("Night Portrait"); break;
1217 case 4: chpr += printf("Sunset"); break;
1218 case 5: chpr += printf("Sports Action"); break;
1219 default: printred("undefined"); break;
1220 }
1221 print_endvalue();
1222 }
1223 break;
1224 case 35:
1225 if((PRINT_TAGINFO))
1226 chpr += printf("%02d:%-21.21s",i,"FlashCompensation");
1227 if((PRINT_VALUE))
1228 {
1229 chpr += printf(" = %lu",value);
1230 fvalue = ((double)value - 6.0) / 3.0;
1231 print_startvalue();
1232 chpr += printf("%g EV",fvalue);
1233 print_endvalue();
1234 }
1235 break;
1236 case 36:
1237 if((PRINT_TAGINFO))
1238 chpr += printf("%02d:%-21.21s",i,"ISO Setting");
1239 if((PRINT_VALUE))
1240 {
1241 chpr += printf(" = %lu",value);
1242 print_startvalue();
1243 switch(value)
1244 {
1245 case 0: chpr += printf("100"); break;
1246 case 1: chpr += printf("200"); break;
1247 case 2: chpr += printf("200"); break;
1248 case 3: chpr += printf("800"); break;
1249 case 4: chpr += printf("Auto"); break;
1250 case 5: chpr += printf("64"); break;
1251 default: printred("undefined"); break;
1252 }
1253 print_endvalue();
1254 }
1255 break;
1256 case 37:
1257 if((PRINT_TAGINFO))
1258 chpr += printf("%02d:%-21.21s",i,"CameraModel");
1259 if((PRINT_VALUE))
1260 {
1261 chpr += printf(" = %lu",value);
1262 print_startvalue();
1263 switch(value)
1264 {
1265 case 0: chpr += printf("DiMAGE 7"); break;
1266 case 1: chpr += printf("DiMAGE 5"); break;
1267 case 2: chpr += printf("DiMAGE S304"); break;
1268 case 3: chpr += printf("DiMAGE S404"); break;
1269 case 4: chpr += printf("DiMAGE 7i"); break;
1270 case 5: chpr += printf("DiMAGE 7Hi"); break;
1271 case 6: chpr += printf("DiMAGE A1"); break;
1272 case 7: chpr += printf("DiMAGE (A2 or S414)"); break;
1273 /* A200 doesn't appear to have */
1274 /* CameraSettings */
1275 default: printred("unknown"); break;
1276 }
1277 print_endvalue();
1278 }
1279 break;
1280 case 38:
1281 if((PRINT_TAGINFO))
1282 chpr += printf("%02d:%-21.21s",i,"IntervalMode*");
1283 if((PRINT_VALUE))
1284 {
1285 chpr += printf(" = %lu",value);
1286 print_startvalue();
1287 switch(value)
1288 /* FIXME: verify it */
1289 {
1290 case 0: chpr += printf("Still Image"); break;
1291 case 1: chpr += printf("Time Lapse"); break;
1292 default: printred("undefined"); break;
1293 }
1294 print_endvalue();
1295 }
1296 break;
1297 case 39:
1298 if((PRINT_TAGINFO))
1299 chpr += printf("%02d:%-21.21s",i,"FolderName");
1300 if((PRINT_VALUE))
1301 {
1302 chpr += printf(" = %lu",value);
1303 print_startvalue();
1304 switch(value)
1305 {
1306 case 0: chpr += printf("Standard Form"); break;
1307 case 1: chpr += printf("Data Form"); break;
1308 default: printred("undefined"); break;
1309 }
1310 print_endvalue();
1311 }
1312 break;
1313 case 40:
1314 if((PRINT_TAGINFO))
1315 chpr += printf("%02d:%-21.21s",i,"ColorMode");
1316 if((PRINT_VALUE))
1317 {
1318 chpr += printf(" = %lu",value);
1319 print_startvalue();
1320 switch(value)
1321 {
1322 case 0: chpr += printf("Natural Color"); break;
1323 case 1: chpr += printf("Black and White"); break;
1324 case 2: chpr += printf("Vivid Color"); break;
1325 case 3: chpr += printf("Solarization"); break;
1326 case 4: chpr += printf("Adobe RGB"); break;
1327 case 9: chpr += printf("unknown"); break;
1328 case 132: chpr += printf("Adobe RGB Embedded Profile"); break;
1329 default: printred("undefined"); break;
1330 }
1331 print_endvalue();
1332 }
1333 break;
1334 case 41:
1335 /* FIXME: assign values */
1336 if((PRINT_TAGINFO))
1337 chpr += printf("%02d:%-21.21s",i,"ColorFilter");
1338 if((PRINT_VALUE))
1339 {
1340 chpr += printf(" = %lu",value);
1341 switch(model)
1342 {
1343 case MINOLTA_DIMAGEA2:
1344 case MINOLTA_DIMAGEA1:
1345 print_startvalue();
1346 switch(value)
1347 {
1348 case 0: chpr += printf("cool 100%%"); break;
1349 case 1: chpr += printf("cool 80%%"); break;
1350 case 2: chpr += printf("cool 60%%"); break;
1351 case 3: chpr += printf("cool 40%%"); break;
1352 case 4: chpr += printf("cool 20%%"); break;
1353 case 5: chpr += printf("no cool/warm adjustment"); break;
1354 case 6: chpr += printf("warm 20%%"); break;
1355 case 7: chpr += printf("warm 40%%"); break;
1356 case 8: chpr += printf("warm 60%%"); break;
1357 case 9: chpr += printf("warm 80%%"); break;
1358 case 10: chpr += printf("warm 100%%"); break;
1359 default: chpr += printf("undefined"); break;
1360 }
1361 print_endvalue();
1362 break;
1363 case MINOLTA_DIMAGE7Hi:
1364 case MINOLTA_DIMAGE7i:
1365 print_startvalue();
1366 switch(value)
1367 {
1368 case 0: chpr += printf("cool 100%%"); break;
1369 case 1: chpr += printf("cool 67%%"); break;
1370 case 2: chpr += printf("cool 33%%"); break;
1371 case 3: chpr += printf("no cool/warm adjustment"); break;
1372 case 4: chpr += printf("warm 33%%"); break;
1373 case 5: chpr += printf("warm 67%%"); break;
1374 case 6: chpr += printf("warm 100%%"); break;
1375 default: chpr += printf("undefined"); break;
1376 }
1377 print_endvalue();
1378 break;
1379 default:
1380 /* Print nothing unless the model is */
1381 /* known */
1382 break;
1383 }
1384 }
1385 break;
1386 case 42:
1387 /* FIXME: assign values */
1388 if((PRINT_TAGINFO))
1389 chpr += printf("%02d:%-21.21s",i,"BWFilter");
1390 if((PRINT_VALUE))
1391 chpr += printf(" = %lu",value);
1392 break;
1393 case 43:
1394 if((PRINT_TAGINFO))
1395 chpr += printf("%02d:%-21.21s",i,"InternalFlashFired");
1396 if((PRINT_VALUE))
1397 {
1398 chpr += printf(" = %lu",value);
1399 print_startvalue();
1400 switch(value)
1401 {
1402 case 0: chpr += printf("No"); break;
1403 case 1: chpr += printf("Yes"); break;
1404 default: printred("undefined"); break;
1405 }
1406 print_endvalue();
1407 }
1408 break;
1409 case 44:
1410 if((PRINT_TAGINFO))
1411 chpr += printf("%02d_%-21.21s",i,"BrightnessValue");
1412 if((PRINT_VALUE))
1413 {
1414 if(PRINT_RAW_VALUES)
1415 chpr += printf(" = %lu",value);
1416 fvalue = ((double)value/ 8.0) - 6.0;
1417 chpr += printf(" = %g APEX",fvalue);
1418 fvalue = pow(2.0,fvalue);
1419 print_startvalue();
1420 chpr += printf("%.3f foot lambert",fvalue);
1421 print_endvalue();
1422 }
1423 break;
1424 case 45:
1425 if((PRINT_TAGINFO))
1426 chpr += printf("%02d:%-21.21s",i,"SpotFocusPointX");
1427 if((PRINT_VALUE))
1428 chpr += printf(" = %lu",value);
1429 break;
1430 case 46:
1431 if((PRINT_TAGINFO))
1432 chpr += printf("%02d:%-21.21s",i,"SpotFocusPointY");
1433 if((PRINT_VALUE))
1434 chpr += printf(" = %lu",value);
1435 break;
1436 case 47:
1437 if((PRINT_TAGINFO))
1438 chpr += printf("%02d:%-21.21s",i,"WideFocusZone");
1439 if((PRINT_VALUE))
1440 {
1441 chpr += printf(" = %lu",value);
1442 print_startvalue();
1443 /* FIXME: Different for A1 */
1444 if(model == MINOLTA_DIMAGEA1)
1445 chpr += printf("Unknown");
1446 else
1447 {
1448 switch(value)
1449 {
1450 case 0: chpr += printf("no zone"); break;
1451 case 1: chpr += printf("center zone (horizontal)"); break;
1452 case 2: chpr += printf("center zone (vertical)"); break;
1453 case 3: chpr += printf("left zone"); break;
1454 case 4: chpr += printf("right zone"); break;
1455 default: printred("undefined"); break;
1456 }
1457 }
1458 print_endvalue();
1459 }
1460 break;
1461 case 48:
1462 if((PRINT_TAGINFO))
1463 chpr += printf("%02d:%-21.21s",i,"FocusMode");
1464 if((PRINT_VALUE))
1465 {
1466 chpr += printf(" = %lu",value);
1467 print_startvalue();
1468 switch(value)
1469 {
1470 case 0: chpr += printf("Auto"); break;
1471 case 1: chpr += printf("Manual"); break;
1472 default: printred("undefined"); break;
1473 }
1474 print_endvalue();
1475 }
1476 break;
1477 case 49:
1478 if((PRINT_TAGINFO))
1479 chpr += printf("%02d:%-21.21s",i,"FocusArea");
1480 if((PRINT_VALUE))
1481 {
1482 chpr += printf(" = %lu",value);
1483 print_startvalue();
1484 switch(value)
1485 {
1486 case 0: chpr += printf("Wide"); break;
1487 case 1: chpr += printf("Spot"); break;
1488 default: printred("undefined"); break;
1489 }
1490 print_endvalue();
1491 }
1492 break;
1493 case 50:
1494 if((PRINT_TAGINFO))
1495 chpr += printf("%02d:%-21.21s",i,"DECPosition");
1496 if((PRINT_VALUE))
1497 {
1498 chpr += printf(" = %lu",value);
1499 print_startvalue();
1500 switch(value)
1501 {
1502 case 0: chpr += printf("Exposure"); break;
1503 case 1: chpr += printf("Contrast"); break;
1504 case 2: chpr += printf("Saturation"); break;
1505 case 3: chpr += printf("Filter"); break;
1506 default: printred("undefined"); break;
1507 }
1508 print_endvalue();
1509 }
1510 break;
1511 case 51:
1512 if((PRINT_TAGINFO))
1513 chpr += printf("%02d:%-21.21s",i,"ColorProfileEmbedded");
1514 if((PRINT_VALUE))
1515 {
1516 chpr += printf(" = %lu",value);
1517 print_startvalue();
1518 switch(value)
1519 {
1520 case 0: chpr += printf("No"); break;
1521 case 1: chpr += printf("Yes"); break;
1522 default: printred("undefined"); break;
1523 }
1524 print_endvalue();
1525 }
1526 break;
1527 case 52:
1528 if((PRINT_TAGINFO))
1529 chpr += printf("%02d:%-21.21s",i,"AntiShake");
1530 if((PRINT_VALUE))
1531 {
1532 chpr += printf(" = %lu",value);
1533 print_startvalue();
1534 switch(value)
1535 {
1536 case 0: chpr += printf("Off"); break;
1537 case 1: chpr += printf("On"); break;
1538 default: printred("undefined"); break;
1539 }
1540 print_endvalue();
1541 }
1542 break;
1543 case 53:
1544 if((PRINT_TAGINFO))
1545 chpr += printf("%02d:%-21.21s",i,"DataImprint");
1546 if((PRINT_VALUE))
1547 {
1548 chpr += printf(" = %lu",value);
1549 print_startvalue();
1550 switch(value)
1551 {
1552 case 0: chpr += printf("None"); break;
1553 case 1: chpr += printf("YYYY/MM/DD"); break;
1554 case 2: chpr += printf("MM/DD/HR.MIN"); break;
1555 case 3: chpr += printf("Text"); break;
1556 case 4: chpr += printf("Text + Id#"); break;
1557 default: printred("undefined"); break;
1558 }
1559 print_endvalue();
1560 }
1561 break;
1562 default:
1563 if((PRINT_TAGINFO))
1564 chpr += printf("%02d:%-21.21s",i,"Unknown");
1565 if((PRINT_VALUE))
1566 chpr += printf(" = %#lx/%lu",value,value);
1567 break;
1568 }
1569 }
1570 }
1571 setcharsprinted(chpr);
1572 return(end_offset);
1573 }
1574
1575 int
maker_minolta_value_is_offset(struct ifd_entry * entry_ptr,int model)1576 maker_minolta_value_is_offset(struct ifd_entry *entry_ptr,int model)
1577 {
1578 int is_offset = 0;
1579
1580 if(entry_ptr)
1581 {
1582 switch(entry_ptr->tag)
1583 {
1584 case 0x0040: is_offset = -1; break; /* cancel */
1585 case 0x0088: is_offset = 1; break;
1586 case 0x0089: is_offset = -1; break;
1587 default: break;
1588 }
1589 }
1590 return(is_offset);
1591 }
1592
1593 /* I have seen at least 9 Minolta versions, as shown below. */
1594 /* Fortunately, some of the variations are minor, and the tagsets do */
1595 /* not overlap, so it is possible to service all of them with just */
1596 /* one tagset and one set of processing routines. The version strings */
1597 /* in the notes have no apparent meaning. */
1598
1599 /* tagsets: HEX
1600 0,1,10,20,40,81,e00 MLT0
1601 0,1,10,20,40,E00 mlt0
1602 0,3,10,20,40,88,89,E00 MLT0
1603 0,3,10,20,40,88,89,100-103 MLT0
1604 0,4,10,18,20,40,88,89,100-107,10A-10D (MRW) MLT0
1605 0,88,89,100-103,F00 MLY0
1606 0,88,89,100-103,F00,18 (MRW) MLY0
1607 0,200-21F,E00,F00 MLT0
1608 0,81,200-21F,E00,F00 MLT0
1609 */
1610