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_asahi.c,v 1.10 2005/07/24 22:56:26 alex Exp $";
11 #endif
12
13 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
14 /* Asahi/Pentax camera maker-specific routines */
15 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
16 /* This information is from an image by Johannes Tschebisch at: */
17 /* http://www.jojotsch.de/downloads/jojothumb/beispiele/ */
18 /* html_exif/bilder/bilder.html */
19 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
20
21 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
22 /* New info (Jan 05) from Evan Hunter: */
23 /* http://www.ozhiker.com/electronics/pjmt/jpeg_info/pentax_mn.html */
24
25 /* April 05: tagset 3 largely due to Phil Harvey's pages at: */
26 /* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/index.html */
27 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include "defs.h"
33 #include "datadefs.h"
34 #include "maker_datadefs.h"
35 #include "summary.h"
36 #include "maker.h"
37 #include "misc.h"
38 #include "tags.h"
39 #include "maker_extern.h"
40 #include "extern.h"
41
42 extern struct camera_id pentax_model_id[];
43
44 /* Find the identifying number assigned to known Asahi/Pentax camera */
45 /* models. This number is used to dispatch print and interpret */
46 /* routines approopriate to the current image. */
47
48 int
asahi_model_number(char * model,char * software)49 asahi_model_number(char *model,char *software)
50 {
51 struct camera_id *model_id;
52 int number = NO_MODEL;
53
54 for(model_id = &pentax_model_id[0]; model_id && model_id->name; ++model_id)
55 {
56 if(strncasecmp(model,model_id->name,model_id->namelen) == 0)
57 {
58 number = model_id->id;
59 setnoteversion(model_id->noteversion);
60 setnotetagset(model_id->notetagset); /* info only */
61 break;
62 }
63 }
64 return(number);
65 }
66
67 /* If an unknown model is seen, use the makernote scheme to select a */
68 /* noteversion to use */
69
70 /* There are some assumptions involved in doing this, but there seems */
71 /* sufficient difference (and distinctive difference) between */
72 /* Asahi/Pentax schemes to make this reasonable. */
73
74 /* v3 has first tag 0x01 (1 SHORT) ID scheme, "PENTAX Corporation" */
75 /* v2 has first tag 0x02 (2 SHORT) ID scheme, "Asahi Optical" */
76 /* second tag 0x02 (2 SHORT) */
77 /* v1 has first tag 0x01 (1 SHORT) ER scheme (no ID), "Asahi Optical" */
78 /* second tag 0x02 (1 SHORT) */
79
80 int
set_asahi_noteversion()81 set_asahi_noteversion()
82 {
83 struct maker_scheme *scheme;
84 int noteversion = 0;
85 int tagset = 0;
86
87 scheme = retrieve_makerscheme();
88 if(scheme->note_version <= 0)
89 {
90 switch(scheme->scheme_type)
91 {
92 case HAS_ID_SCHEME:
93 if(scheme->first_entry.tag == 0x1)
94 {
95 tagset = 3;
96 noteversion = 3;
97 }
98 else
99 {
100 tagset = 2;
101 noteversion = 2;
102 }
103 break;
104 case PLAIN_IFD_SCHEME:
105 tagset = 1;
106 noteversion = 1;
107 break;
108 }
109 setnotetagset(tagset);
110 setnoteversion(noteversion);
111 }
112 else
113 noteversion = scheme->note_version;
114 return(noteversion);
115 }
116
117 /* Dispatch print routines for direct values in Asahi/Pentax cameras, */
118 /* based upon previously set noteversion */
119
120 void
print_asahi_makervalue(struct ifd_entry * entry_ptr,int make,int model,char * prefix)121 print_asahi_makervalue(struct ifd_entry *entry_ptr,int make,int model,
122 char *prefix)
123 {
124 int noteversion = 0;
125
126 noteversion = getnoteversion();
127
128 if(entry_ptr)
129 {
130 switch(noteversion)
131 {
132 case 3:
133 print_asahi1_makervalue(entry_ptr,make,model,prefix);
134 asahi3_interpret_value(entry_ptr);
135 break;
136 case 2:
137 print_asahi1_makervalue(entry_ptr,make,model,prefix);
138 asahi2_interpret_value(entry_ptr);
139 break;
140 case 1:
141 print_asahi1_makervalue(entry_ptr,make,model,prefix);
142 asahi1_interpret_value(entry_ptr);
143 break;
144 default:
145 print_value(entry_ptr,PREFIX);
146 break;
147 }
148 }
149 }
150
151 /* Model-specific print routine for Asahi/Pentax cameras. This */
152 /* routine is responsible for picking off any direct entry tags which */
153 /* are peculiar and will not be handled properly by print_value() */
154 /* (usually UNDEFINED values which fit in the 4-byte entry value). If */
155 /* there are no such entries, this function simply calls */
156 /* print_value(). */
157
158 void
print_asahi1_makervalue(struct ifd_entry * entry_ptr,int make,int model,char * prefix)159 print_asahi1_makervalue(struct ifd_entry *entry_ptr,int make,int model,
160 char *prefix)
161 {
162 if(entry_ptr)
163 {
164 switch(entry_ptr->tag)
165 {
166 default:
167 print_value(entry_ptr,PREFIX);
168 break;
169 }
170 }
171 }
172
173
174 /* Dispatch a routine to decode and print offset values for Asahi/Pentax */
175 /* cameras. */
176
177 void
print_asahi_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)178 print_asahi_offset_makervalue(FILE *inptr,unsigned short byteorder,
179 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
180 struct image_summary *summary_entry,char *parent_name,
181 char *prefix,int indent,int make,int model,int at_offset)
182 {
183 int noteversion = 0;
184
185 noteversion = getnoteversion();
186
187 if(entry_ptr)
188 {
189 switch(noteversion)
190 {
191 case 3:
192 asahi2_offset_makervalue(inptr,byteorder,entry_ptr,
193 fileoffset_base,summary_entry,
194 parent_name,prefix,indent,
195 make,model,at_offset);
196 break;
197 case 2:
198 asahi1_offset_makervalue(inptr,byteorder,entry_ptr,
199 fileoffset_base,summary_entry,
200 parent_name,prefix,indent,
201 make,model,at_offset);
202 break;
203 case 1:
204 asahi1_offset_makervalue(inptr,byteorder,entry_ptr,
205 fileoffset_base,summary_entry,
206 parent_name,prefix,indent,
207 make,model,at_offset);
208 break;
209 default:
210 print_value(entry_ptr,PREFIX);
211 break;
212 }
213 }
214 }
215
216
217 /* Model-specific routine to print UNDEFINED values found at offsets */
218 /* in Asahi/Pentax makernotes. */
219
220 void
asahi1_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)221 asahi1_offset_makervalue(FILE *inptr,unsigned short byteorder,
222 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
223 struct image_summary *summary_entry,char *parent_name,char *prefix,
224 int indent,int make,int model,int at_offset)
225 {
226 unsigned long value_offset,max_offset;
227 unsigned short marker;
228 unsigned long count;
229 char *nameoftag;
230 char *fulldirname = CNULL;
231 int status = 0;
232 int chpr = 0;
233
234 if(inptr && entry_ptr)
235 {
236 nameoftag = maker_tagname(entry_ptr->tag,make,model);
237 fulldirname = splice(parent_name,".",nameoftag);
238 value_offset = fileoffset_base + entry_ptr->value;
239 count = entry_ptr->count;
240
241 switch(entry_ptr->tag)
242 {
243 case 0x0004: /* JpegThumbnailOffset */
244 /* These models provide the 0x2000 tag as well as the */
245 /* 0x0003/0x0004 tags. Both entries point to the same */
246 /* thumbnail, so just print values for length and */
247 /* offset tags, and display the thumbnail on the */
248 /* (self-contained) 0x2000 tag */
249 if(!at_offset && (PRINT_VALUE))
250 {
251 if(!(PRINT_OFFSET))
252 chpr += printf("@%lu",value_offset);
253 }
254 break;
255 case 0x2000: /* Jpeg Thumbnail as UNDEFINED section */
256 if(at_offset && (PRINT_SECTION))
257 {
258 print_tag_address(VALUE_AT_OFFSET,value_offset,indent,prefix);
259 chpr += printf("# Start of JPEG Thumbnail from MakerNote");
260 chpr += printf(" length %lu",count);
261 }
262 else if(!at_offset && (PRINT_VALUE))
263 {
264 if(!(PRINT_OFFSET))
265 chpr += printf("@%lu:%lu # UNDEFINED",value_offset,count);
266 }
267 if((PRINT_SECTION) || (PRINT_SEGMENT))
268 chpr = newline(chpr);
269 marker = read_ushort(inptr,TIFF_MOTOROLA,value_offset);
270 max_offset = process_jpeg_segments(inptr,value_offset,marker,
271 count,summary_entry,fulldirname,
272 prefix,indent+SMALLINDENT);
273 if(at_offset)
274 {
275 if((PRINT_SECTION))
276 {
277 if((status = jpeg_status(0) == JPEG_EARLY_EOI))
278 chpr = newline(chpr);
279 jpeg_status(status);
280 print_tag_address(VALUE_AT_OFFSET,value_offset + count - 1,
281 indent,"-");
282 chpr += printf("# End of JPEG Thumbnail from MakerNote");
283 if((PRINT_ENTRY) && !(PRINT_VALUE))
284 chpr = newline(chpr);
285 }
286 }
287 print_jpeg_status();
288 if(marker && summary_entry)
289 {
290 /* The new one is on the end of the chain */
291 if((summary_entry = last_summary_entry(summary_entry)))
292 {
293 summary_entry->filesubformat |= FILESUBFMT_MNOTE;
294 summary_entry->datatype = MAKER_IFD;
295 summary_entry->subfiletype = THUMBNAIL_TYPE;
296 }
297 }
298 /* make certain we're at the end */
299 clearerr(inptr);
300 fseek(inptr,value_offset + count,0);
301 break;
302 case 0x0e00: /* PrintIM (Epson Print Image matching) */
303 if(!at_offset && (PRINT_VALUE))
304 {
305 if(!(PRINT_OFFSET))
306 {
307 chpr += printf("@%lu:%lu",value_offset,count);
308 chpr = newline(chpr);
309 }
310 }
311 process_pim(inptr,byteorder,entry_ptr->value,fileoffset_base,
312 count,nameoftag,parent_name,prefix,indent);
313 break;
314 default:
315 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,fileoffset_base,
316 fulldirname,prefix,indent,
317 make,model,at_offset);
318 break;
319 }
320 if(fulldirname)
321 free(fulldirname);
322 }
323 setcharsprinted(chpr);
324 }
325
326 void
asahi2_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)327 asahi2_offset_makervalue(FILE *inptr,unsigned short byteorder,
328 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
329 struct image_summary *summary_entry,char *parent_name,
330 char *prefix,int indent,int make,int model,int at_offset)
331 {
332 static unsigned long jpegthumbnaillength = 0UL;
333 unsigned long value_offset,max_offset;
334 unsigned short marker;
335 unsigned long count;
336 char *nameoftag;
337 char *fulldirname = CNULL;
338 int status = 0;
339 int chpr = 0;
340
341 if(inptr && entry_ptr)
342 {
343 nameoftag = maker_tagname(entry_ptr->tag,make,model);
344 fulldirname = splice(parent_name,".",nameoftag);
345 value_offset = fileoffset_base + entry_ptr->value;
346 count = entry_ptr->count;
347
348 switch(entry_ptr->tag)
349 {
350 case 0x0003: /* JpegThumbnailLength */
351 /* Just record it */
352 jpegthumbnaillength = entry_ptr->value;
353 break;
354 case 0x0004: /* JpegThumbnailOffset */
355 if(jpegthumbnaillength)
356 {
357 count = jpegthumbnaillength;
358 jpegthumbnaillength = 0;
359 }
360 if(at_offset && (PRINT_SECTION))
361 {
362 print_tag_address(VALUE_AT_OFFSET,value_offset,indent,prefix);
363 chpr += printf("# Start of JPEG Thumbnail from MakerNote");
364 chpr += printf(" length %ld",count);
365 }
366 else if(!at_offset && (PRINT_VALUE))
367 {
368 if(!(PRINT_OFFSET))
369 chpr += printf("@%lu:%lu",value_offset,count);
370 else
371 chpr = printf("length %lu",count);
372 }
373 if((PRINT_SECTION) || (PRINT_SEGMENT))
374 chpr = newline(chpr);
375 marker = read_ushort(inptr,TIFF_MOTOROLA,value_offset);
376 max_offset = process_jpeg_segments(inptr,value_offset,marker,
377 count,summary_entry,fulldirname,
378 prefix,indent+SMALLINDENT);
379 if(at_offset)
380 {
381 if((PRINT_SECTION))
382 {
383 if((status = jpeg_status(0) == JPEG_EARLY_EOI))
384 chpr = newline(chpr);
385 jpeg_status(status);
386 print_tag_address(VALUE_AT_OFFSET,value_offset + count - 1,
387 indent,"-");
388 chpr += printf("# End of JPEG Thumbnail from MakerNote");
389 if((PRINT_ENTRY) && !(PRINT_VALUE))
390 chpr = newline(chpr);
391 }
392 }
393 print_jpeg_status();
394 if(marker && summary_entry)
395 {
396 /* The new one is on the end of the chain */
397 if((summary_entry = last_summary_entry(summary_entry)))
398 {
399 summary_entry->filesubformat |= FILESUBFMT_MNOTE;
400 summary_entry->datatype = MAKER_IFD;
401 summary_entry->subfiletype = THUMBNAIL_TYPE;
402 }
403 }
404 /* make certain we're at the end */
405 clearerr(inptr);
406 fseek(inptr,value_offset + count,0);
407 break;
408 case 0x0e00: /* PrintIM (Epson Print Image matching) */
409 if(!at_offset && (PRINT_VALUE))
410 {
411 if(!(PRINT_OFFSET))
412 chpr += printf("@%lu",value_offset);
413 }
414 process_pim(inptr,byteorder,entry_ptr->value,fileoffset_base,
415 count,nameoftag,parent_name,prefix,indent);
416 break;
417 default:
418 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,
419 fileoffset_base, fulldirname,prefix,indent,
420 make,model,at_offset);
421 break;
422 }
423 }
424 setcharsprinted(chpr);
425 }
426
427
428 /* Asahi/Pentax-specific tagnames for makernotes. */
429
430 char *
maker_asahi_tagname(unsigned short tag,int model)431 maker_asahi_tagname(unsigned short tag,int model)
432 {
433 char *tagname = (char *)0;
434 int noteversion = 0;
435
436 /* Should have to do this only once, and only for unrecognized */
437 /* models. If the model is recognized (or the user has forced a */
438 /* noteversion) noteversion will already be set. */
439 /* This should already have been done in find_maker_scheme(), but */
440 /* there is no harm in checking noteversion after retrieving it. */
441 if(((noteversion = getnoteversion()) == 0))
442 noteversion = set_asahi_noteversion();
443
444 switch(noteversion)
445 {
446 case 1:
447 tagname = maker_asahi1_tagname(tag,model);
448 break;
449 case 2:
450 tagname = maker_asahi2_tagname(tag,model);
451 break;
452 case 3:
453 tagname = maker_asahi3_tagname(tag,model);
454 break;
455 default:
456 break;
457 }
458
459 /* If no model-specific tag is found, check "generic" tags */
460 if(tagname == NULL)
461 {
462 switch(tag)
463 {
464 case 0x0e00: tagname = "PrintIM"; break;
465 default: break;
466 }
467 }
468 return(tagname);
469 }
470
471
472 char *
maker_asahi1_tagname(unsigned short tag,int model)473 maker_asahi1_tagname(unsigned short tag,int model)
474 {
475 char *tagname = CNULL;
476
477 switch(tag)
478 {
479 case 0x0001: tagname = "CaptureMode"; break;
480 case 0x0002: tagname = "Quality"; break;
481 case 0x0003: tagname = "FocusMode"; break;
482 case 0x0004: tagname = "FlashMode"; break;
483 case 0x0007: tagname = "WhiteBalance"; break;
484 case 0x000a: tagname = "DigitalZoom"; break;
485 case 0x000b: tagname = "Sharpness"; break;
486 case 0x000c: tagname = "Contrast"; break;
487 case 0x000d: tagname = "Saturation"; break;
488 case 0x0014: tagname = "ISOSpeedSetting"; break;
489 case 0x0017: tagname = "Color"; break;
490 case 0x1000: tagname = "TimeZone"; break;
491 case 0x1001: tagname = "DaylightSavings"; break;
492 }
493 setnotetagset(1);
494 return(tagname);
495 }
496
497 char *
maker_asahi2_tagname(unsigned short tag,int model)498 maker_asahi2_tagname(unsigned short tag,int model)
499 {
500 char *tagname = CNULL;
501
502 /* This is the same as Casio note version 2 */
503 switch(tag)
504 {
505 case 0x0002: tagname = "JpegThumbnailDimensions"; break;
506 case 0x0003: tagname = "JpegThumbnailLength"; break;
507 case 0x0004: tagname = "JpegThumbnailOffset"; break;
508 case 0x0008: tagname = "QualityMode"; break;
509 case 0x0009: tagname = "ImageSize"; break;
510 case 0x000D: tagname = "FocusMode"; break;
511 case 0x0014: tagname = "IsoSensitivity"; break;
512 case 0x0019: tagname = "WhiteBalance"; break;
513 case 0x001D: tagname = "FocalLength"; break; /* units .1mm */
514 case 0x001F: tagname = "Saturation"; break;
515 case 0x0020: tagname = "Contrast"; break;
516 case 0x0021: tagname = "Sharpness"; break;
517 case 0x2000: tagname = "JpegThumbnail"; break;
518 case 0x2011: tagname = "WhiteBalanceBias"; break;
519 case 0x2012: tagname = "WhiteBalance"; break;
520 case 0x2022: tagname = "ObjectDistance"; break;
521 case 0x2034: tagname = "FlashDistance"; break;
522 case 0x3000: tagname = "RecordMode"; break;
523 case 0x3001: tagname = "SelfTimer?"; break;
524 case 0x3002: tagname = "Quality"; break;
525 case 0x3003: tagname = "FocusMode"; break;
526 case 0x3006: tagname = "TimeZone"; break;
527 case 0x3007: tagname = "BestshotMode"; break;
528 case 0x3014: tagname = "CCDSensitivity"; break;
529 case 0x3015: tagname = "ColorMode"; break;
530 case 0x3016: tagname = "Enhancement"; break;
531 case 0x3017: tagname = "Filter"; break;
532 default: break;
533 }
534 setnotetagset(2);
535 return(tagname);
536 }
537
538 char *
maker_asahi3_tagname(unsigned short tag,int model)539 maker_asahi3_tagname(unsigned short tag,int model)
540 {
541 char *tagname = CNULL;
542
543 switch(tag)
544 {
545 case 0x0001: tagname = "CaptureMode"; break;
546 case 0x0002: tagname = "JpegThumbnailDimensions"; break;
547 case 0x0003: tagname = "JpegThumbnailLength"; break;
548 case 0x0004: tagname = "JpegThumbnailOffset"; break;
549 case 0x0006: tagname = "Date"; break;
550 case 0x0007: tagname = "Time"; break;
551 case 0x0008: tagname = "QualityMode"; break;
552 case 0x0009: tagname = "ImageSize"; break;
553 case 0x000B: tagname = "PictureMode"; break;
554 case 0x000D: tagname = "FocusMode"; break;
555 case 0x0014: tagname = "IsoSensitivity"; break;
556 case 0x0017: tagname = "MeteringMode"; break;
557 case 0x0019: tagname = "WhiteBalance"; break;
558 case 0x001D: tagname = "FocalLength"; break;
559 case 0x001E: tagname = "DigitalZoom"; break;
560 case 0x001F: tagname = "Saturation"; break;
561 case 0x0020: tagname = "Contrast"; break;
562 case 0x0021: tagname = "Sharpness"; break;
563 case 0x0029: tagname = "FrameNumber"; break;
564 case 0x0039: tagname = "RawImageSize"; break;
565 case 0x003F: tagname = "LensType"; break;
566 case 0x0200: tagname = "BlackPoint"; break;
567 case 0x0201: tagname = "WhitePoint"; break;
568 case 0x0402: tagname = "ToneCurve"; break;
569 case 0x0403: tagname = "ToneCurves"; break;
570 default: break;
571 }
572 setnotetagset(3);
573 return(tagname);
574 }
575
576 /* Report the "meaning" of tag values found at offsets in an */
577 /* Asahi/Pentax MakerNote IFD entry (not at an offset). */
578
579 void
asahi1_interpret_value(struct ifd_entry * entry_ptr)580 asahi1_interpret_value(struct ifd_entry *entry_ptr)
581 {
582 int chpr = 0;
583
584 if(entry_ptr && (PRINT_VALUE))
585 {
586 switch(entry_ptr->tag)
587 {
588 case 0x0001: /* CaptureMode */
589 print_startvalue();
590 switch(entry_ptr->value)
591 {
592 case 0: chpr += printf("Auto"); break;
593 case 1: chpr += printf("Night-scene"); break;
594 case 2: chpr += printf("Manual"); break;
595 case 4: chpr += printf("Multiple"); break;
596 default: break;
597 }
598 print_endvalue();
599 break;
600 case 0x0002: /* Quality */
601 print_startvalue();
602 switch(entry_ptr->value)
603 {
604 case 0: chpr += printf("Good"); break;
605 case 1: chpr += printf("Better"); break;
606 case 2: chpr += printf("Best"); break;
607 default: break;
608 }
609 print_endvalue();
610 break;
611 case 0x0003: /* Focus Mode */
612 print_startvalue();
613 switch(entry_ptr->value)
614 {
615 case 2: chpr += printf("Custom"); break;
616 case 3: chpr += printf("Auto"); break;
617 default: break;
618 }
619 print_endvalue();
620 break;
621 case 0x0004: /* Flash Mode */
622 print_startvalue();
623 switch(entry_ptr->value)
624 {
625 case 1: chpr += printf("Auto"); break;
626 case 2: chpr += printf("On"); break;
627 case 4: chpr += printf("Off"); break;
628 case 6: chpr += printf("Red-eye"); break;
629 default: break;
630 }
631 print_endvalue();
632 break;
633 case 0x0007: /* White Balance */
634 print_startvalue();
635 switch(entry_ptr->value)
636 {
637 case 0: chpr += printf("Auto"); break;
638 case 1: chpr += printf("Daylight"); break;
639 case 2: chpr += printf("Shade"); break;
640 case 3: chpr += printf("Tungsten"); break;
641 case 4: chpr += printf("Fluorescent"); break;
642 case 5: chpr += printf("Manual"); break;
643 default: break;
644 }
645 print_endvalue();
646 break;
647 case 0x000a: /* Digital Zoom */
648 if(entry_ptr->value == 0)
649 {
650 print_startvalue();
651 chpr += printf("Off");
652 print_endvalue();
653 }
654 break;
655 case 0x000b: /* Sharpness */
656 print_startvalue();
657 switch(entry_ptr->value)
658 {
659 case 0: chpr += printf("Normal"); break;
660 case 1: chpr += printf("Soft"); break;
661 case 2: chpr += printf("Hard"); break;
662 default: break;
663 }
664 print_endvalue();
665 break;
666 case 0x000c: /* Contrast */
667 print_startvalue();
668 switch(entry_ptr->value)
669 {
670 case 0: chpr += printf("Normal"); break;
671 case 1: chpr += printf("Low"); break;
672 case 2: chpr += printf("High"); break;
673 default: break;
674 }
675 print_endvalue();
676 break;
677 case 0x000d: /* Saturation */
678 print_startvalue();
679 switch(entry_ptr->value)
680 {
681 case 0: chpr += printf("Normal"); break;
682 case 1: chpr += printf("Low"); break;
683 case 2: chpr += printf("High"); break;
684 default: break;
685 }
686 print_endvalue();
687 break;
688 case 0x0014: /* ISO Speed Setting */
689 print_startvalue();
690 switch(entry_ptr->value)
691 {
692 case 10: chpr += printf("ISO 100"); break;
693 case 16: chpr += printf("ISO 200"); break;
694 case 100: chpr += printf("ISO 100"); break;
695 case 200: chpr += printf("ISO 200"); break;
696 default: break;
697 }
698 print_endvalue();
699 break;
700 case 0x0017: /* Color */
701 print_startvalue();
702 switch(entry_ptr->value)
703 {
704 case 1: chpr += printf("Normal"); break;
705 case 2: chpr += printf("Black & White"); break;
706 case 3: chpr += printf("Sepia"); break;
707 default: break;
708 }
709 print_endvalue();
710 break;
711 default:
712 break;
713 }
714 }
715 setcharsprinted(chpr);
716 }
717
718 void
asahi2_interpret_value(struct ifd_entry * entry_ptr)719 asahi2_interpret_value(struct ifd_entry *entry_ptr)
720 {
721 int chpr = 0;
722
723 if(entry_ptr && (PRINT_VALUE))
724 {
725 switch(entry_ptr->tag)
726 {
727 case 0x0002: /* ThumbnailDimensions" */
728 chpr += printf(" pixels");
729 break;
730 case 0x0008: /* QualityMode" */
731 print_startvalue();
732 switch(entry_ptr->value)
733 {
734 case 1: chpr += printf("Fine"); break;
735 case 2: chpr += printf("Super Fine"); break;
736 default: chpr += printf("unknown"); break;
737 }
738 print_endvalue();
739 break;
740 case 0x0009: /* ImageSize" */
741 print_startvalue();
742 switch(entry_ptr->value)
743 {
744 case 1: chpr += printf("640x480"); break;
745 case 4: chpr += printf("1600x1200"); break;
746 case 5: chpr += printf("2048x1536"); break;
747 case 8: chpr += printf("2560x1920"); break;
748 case 20: chpr += printf("2288x1712"); break;
749 case 21: chpr += printf("2592x1944"); break;
750 case 22: chpr += printf("2304x1728"); break;
751 case 23: chpr += printf("2296x3056"); break;
752 case 36: chpr += printf("3008x2008"); break;
753 default: chpr += printf("unknown"); break;
754 }
755 print_endvalue();
756 break;
757 case 0x000D: /* FocusMode" */
758 print_startvalue();
759 switch(entry_ptr->value)
760 {
761 case 1: chpr += printf("Normal"); break;
762 case 2: chpr += printf("Macro"); break;
763 default: chpr += printf("unknown"); break;
764 }
765 print_endvalue();
766 break;
767 case 0x0014: /* IsoSensitivity" */
768 print_startvalue();
769 switch(entry_ptr->value)
770 {
771 case 3: chpr += printf("50"); break;
772 case 4: chpr += printf("64"); break;
773 case 6: chpr += printf("100"); break;
774 case 9: chpr += printf("200"); break;
775 default: chpr += printf("unknown"); break;
776 }
777 print_endvalue();
778 break;
779 case 0x0019: /* WhiteBalance" */
780 print_startvalue();
781 switch(entry_ptr->value)
782 {
783 case 0: chpr += printf("Auto"); break;
784 case 1: chpr += printf("Daylight"); break;
785 case 2: chpr += printf("Shade"); break;
786 case 3: chpr += printf("Tungsten"); break;
787 case 4: chpr += printf("Fluorescent"); break;
788 case 5: chpr += printf("Manual"); break;
789 default: chpr += printf("unknown"); break;
790 }
791 print_endvalue();
792 break;
793 case 0x001D: chpr += printf(" x .1 mm"); break;
794 case 0x001F: /* Saturation" */
795 print_startvalue();
796 switch(entry_ptr->value)
797 {
798 case 0: chpr += printf("-1"); break;
799 case 1: chpr += printf("Normal"); break;
800 case 2: chpr += printf("+1"); break;
801 default: chpr += printf("unknown"); break;
802 }
803 print_endvalue();
804 break;
805 case 0x0020: /* Contrast" */
806 print_startvalue();
807 switch(entry_ptr->value)
808 {
809 case 0: chpr += printf("-1"); break;
810 case 1: chpr += printf("Normal"); break;
811 case 2: chpr += printf("+1"); break;
812 default: chpr += printf("unknown"); break;
813 }
814 print_endvalue();
815 break;
816 case 0x0021: /* Sharpness" */
817 print_startvalue();
818 switch(entry_ptr->value)
819 {
820 case 0: chpr += printf("-1"); break;
821 case 1: chpr += printf("Normal"); break;
822 case 2: chpr += printf("+1"); break;
823 default: chpr += printf("unknown"); break;
824 }
825 print_endvalue();
826 break;
827 case 0x2012: /* WhiteBalance" */
828 print_startvalue();
829 switch(entry_ptr->value)
830 {
831 case 0: chpr += printf("Manual"); break;
832 case 1: chpr += printf("Auto"); break;
833 case 4: chpr += printf("Flash"); break;
834 case 12: chpr += printf("Flash"); break;
835 default: chpr += printf("unknown"); break;
836 }
837 print_endvalue();
838 break;
839 case 0x2022: /* ObjectDistance" */
840 chpr += printf("mm");
841 break;
842 case 0x2034: /* FlashDistance" */
843 #if 0
844 Off?
845 if(entry_ptr->value == 0)
846 {
847 print_startvalue();
848 chpr += printf("Off");
849 print_endvalue();
850 }
851 #endif
852 break;
853 case 0x3000: /* RecordMode" */
854 print_startvalue();
855 switch(entry_ptr->value)
856 {
857 case 2: chpr += printf("Normal"); break;
858 default: chpr += printf("unknown"); break;
859 }
860 print_endvalue();
861 break;
862 case 0x3001: /* SelfTimer?" */
863 print_startvalue();
864 switch(entry_ptr->value)
865 {
866 case 1: chpr += printf("Off"); break;
867 default: chpr += printf("unknown"); break;
868 }
869 print_endvalue();
870 break;
871 case 0x3002: /* Quality" */
872 print_startvalue();
873 switch(entry_ptr->value)
874 {
875 case 1: chpr += printf("Economy"); break;
876 case 2: chpr += printf("Normal"); break;
877 case 3: chpr += printf("Fine"); break;
878 default: chpr += printf("unknown"); break;
879 }
880 print_endvalue();
881 break;
882 case 0x3003: /* FocusMode" */
883 print_startvalue();
884 switch(entry_ptr->value)
885 {
886 case 1: chpr += printf("Fixed"); break;
887 case 3: chpr += printf("Single-Area Auto"); break;
888 case 6: chpr += printf("Multi-Area Auto"); break;
889 default: chpr += printf("unknown"); break;
890 }
891 print_endvalue();
892 break;
893 case 0x3007: /* BestshotMode" */
894 print_startvalue();
895 switch(entry_ptr->value)
896 {
897 case 0: chpr += printf("Off"); break;
898 default: chpr += printf("unknown"); break;
899 }
900 print_endvalue();
901 break;
902 case 0x3015: /* ColorMode" */
903 print_startvalue();
904 switch(entry_ptr->value)
905 {
906 case 0: chpr += printf("Off*"); break;
907 default: chpr += printf("unknown"); break;
908 }
909 print_endvalue();
910 break;
911 case 0x3016: /* Enhancement" */
912 print_startvalue();
913 switch(entry_ptr->value)
914 {
915 case 0: chpr += printf("Off"); break;
916 default: chpr += printf("unknown"); break;
917 }
918 print_endvalue();
919 break;
920 case 0x3017: /* Filter" */
921 print_startvalue();
922 switch(entry_ptr->value)
923 {
924 case 0: chpr += printf("Off"); break;
925 default: chpr += printf("unknown"); break;
926 }
927 print_endvalue();
928 break;
929 default: break;
930 }
931 }
932 setcharsprinted(chpr);
933 }
934
935 void
asahi3_interpret_value(struct ifd_entry * entry_ptr)936 asahi3_interpret_value(struct ifd_entry *entry_ptr)
937 {
938 int year,month,day;
939 int chpr = 0;
940
941 if(entry_ptr && (PRINT_VALUE))
942 {
943 switch(entry_ptr->tag)
944 {
945 case 0x0001: /* CaptureMode */
946 print_startvalue();
947 switch(entry_ptr->value)
948 {
949 case 0: chpr += printf("Auto"); break;
950 case 1: chpr += printf("Night-scene"); break;
951 case 2: chpr += printf("Manual"); break;
952 case 4: chpr += printf("Multiple"); break;
953 default: break;
954 }
955 print_endvalue();
956 break;
957 case 0x0002: /* ThumbnailDimensions" */
958 chpr += printf(" pixels");
959 break;
960 case 0x0006:
961 year = ((entry_ptr->value & 0xff) << 8) | ((entry_ptr->value & 0xff00) >> 8);
962 month = ((entry_ptr->value & 0xff0000) >> 16) & 0x7f;
963 day = ((entry_ptr->value & 0xff000000) >> 24) & 0x7f;
964 chpr += printf(" = %4d:%02d:%02d",year,month,day);
965 break;
966 case 0x0008: /* QualityMode" */
967 print_startvalue();
968 switch(entry_ptr->value)
969 {
970 case 0: chpr += printf("Good"); break;
971 case 1: chpr += printf("Better"); break;
972 case 2: chpr += printf("Best"); break;
973 case 3: chpr += printf("TIFF"); break;
974 case 4: chpr += printf("RAW"); break;
975 default: chpr += printf("unknown"); break;
976 }
977 print_endvalue();
978 break;
979 case 0x0009: /* ImageSize" */
980 print_startvalue();
981 switch(entry_ptr->value)
982 {
983 case 0: chpr += printf("640x480"); break;
984 case 1: chpr += printf("Full"); break;
985 case 2: chpr += printf("1024x768"); break;
986 case 4: chpr += printf("1600x1200"); break;
987 case 5: chpr += printf("2048x1536"); break;
988 case 20: chpr += printf("2288x1712"); break;
989 case 21: chpr += printf("2592x1944"); break;
990 case 22: chpr += printf("2304x1728"); break;
991 case 36: chpr += printf("3008x2008"); break;
992 default: chpr += printf("unknown"); break;
993 }
994 print_endvalue();
995 break;
996 case 0x000D: /* FocusMode" */
997 print_startvalue();
998 switch(entry_ptr->value)
999 {
1000 case 0: chpr += printf("Normal"); break;
1001 case 1: chpr += printf("Macro(1)"); break;
1002 case 2: chpr += printf("Macro(2)"); break;
1003 case 3: chpr += printf("Infinity"); break;
1004 default: chpr += printf("unknown"); break;
1005 }
1006 print_endvalue();
1007 break;
1008 case 0x0014: /* IsoSensitivity" */
1009 print_startvalue();
1010 switch(entry_ptr->value)
1011 {
1012 case 3: chpr += printf("50"); break;
1013 case 4: chpr += printf("64"); break;
1014 case 6: chpr += printf("100"); break;
1015 case 9: chpr += printf("200"); break;
1016 case 12: chpr += printf("400"); break;
1017 case 15: chpr += printf("800"); break;
1018 case 18: chpr += printf("1600"); break;
1019 case 21: chpr += printf("3200"); break;
1020 case 50: chpr += printf("50"); break;
1021 case 100: chpr += printf("100"); break;
1022 case 200: chpr += printf("200"); break;
1023 case 400: chpr += printf("400"); break;
1024 case 800: chpr += printf("800"); break;
1025 case 1600: chpr += printf("1600"); break;
1026 case 3200: chpr += printf("3200"); break;
1027 default: chpr += printf("unknown"); break;
1028 }
1029 print_endvalue();
1030 break;
1031 case 0x0017: /* MeteringMode" */
1032 print_startvalue();
1033 switch(entry_ptr->value)
1034 {
1035 case 0: chpr += printf("Multi Segment"); break;
1036 case 1: chpr += printf("Center Weighted"); break;
1037 case 2: chpr += printf("Spot"); break;
1038 default: chpr += printf("unknown"); break;
1039 }
1040 print_endvalue();
1041 break;
1042 case 0x0019: /* WhiteBalance" */
1043 print_startvalue();
1044 switch(entry_ptr->value)
1045 {
1046 case 0: chpr += printf("Auto"); break;
1047 case 1: chpr += printf("Daylight"); break;
1048 case 2: chpr += printf("Shade"); break;
1049 case 3: chpr += printf("Fluorescent"); break;
1050 case 4: chpr += printf("Tungsten"); break;
1051 case 5: chpr += printf("Manual"); break;
1052 default: chpr += printf("unknown"); break;
1053 }
1054 print_endvalue();
1055 break;
1056 case 0x001D: chpr += printf(" x .1 mm");
1057 break;
1058
1059 case 0x001F: /* Saturation" */
1060 print_startvalue();
1061 switch(entry_ptr->value)
1062 {
1063 case 0: chpr += printf("Normal"); break;
1064 case 1: chpr += printf("Low"); break;
1065 case 2: chpr += printf("High"); break;
1066 default: chpr += printf("unknown"); break;
1067 }
1068 print_endvalue();
1069 break;
1070 case 0x0020: /* Contrast" */
1071 print_startvalue();
1072 switch(entry_ptr->value)
1073 {
1074 case 0: chpr += printf("Normal"); break;
1075 case 1: chpr += printf("Low"); break;
1076 case 0x10: chpr += printf("Low"); break;
1077 case 2: chpr += printf("High"); break;
1078 case 0x20: chpr += printf("High"); break;
1079 case 3: chpr += printf("Medium Low"); break;
1080 case 0x30: chpr += printf("Medium High"); break;
1081 default: chpr += printf("unknown"); break;
1082 }
1083 print_endvalue();
1084 break;
1085 case 0x0021: /* Sharpness" */
1086 print_startvalue();
1087 switch(entry_ptr->value)
1088 {
1089 case 0: chpr += printf("Normal"); break;
1090 case 1: chpr += printf("Soft"); break;
1091 case 0x10: chpr += printf("Soft"); break;
1092 case 2: chpr += printf("Hard"); break;
1093 case 0x20: chpr += printf("Hard"); break;
1094 case 3: chpr += printf("Medium Soft"); break;
1095 case 0x30: chpr += printf("Medium Hard"); break;
1096 default: chpr += printf("unknown"); break;
1097 }
1098 print_endvalue();
1099 break;
1100 default: break;
1101 }
1102 }
1103 setcharsprinted(chpr);
1104 }
1105
1106 /* Some makernotes record offsets as LONG values rather than simply */
1107 /* using UNDEFINED with a size; the same technique used for */
1108 /* the ExifIFDPointer itself, or JpegInterchangeFormat, etc. */
1109 /* This routine hardcodes such tags so that the print_makerentry() */
1110 /* routine will present them as offsets. */
1111
1112 /* Asahi has the unfortunate characteristic that tag numbers are */
1113 /* re-used for different purposes in the second version, and one of */
1114 /* those tags is an offset masquerading as a long. */
1115
1116 int
maker_asahi_value_is_offset(struct ifd_entry * entry_ptr,int model)1117 maker_asahi_value_is_offset(struct ifd_entry *entry_ptr,int model)
1118 {
1119 int is_offset = 0;
1120 int noteversion = 0;
1121
1122 if(entry_ptr)
1123 {
1124 noteversion = getnoteversion();
1125
1126 switch(noteversion)
1127 {
1128 case 2:
1129 switch(entry_ptr->tag)
1130 {
1131 case 0x0004: is_offset = 1; break;
1132 default: break;
1133 }
1134 break;
1135 case 3:
1136 /* A negative value here forces call of the maker offset */
1137 /* value routine, so that the routine may record */
1138 /* information it will need later; the value is not */
1139 /* treated as an offset. */
1140 switch(entry_ptr->tag)
1141 {
1142 case 0x0003: is_offset = -1; break;
1143 case 0x0004: is_offset = 1; break;
1144 default: break;
1145 }
1146 break;
1147 case 1:
1148 default:
1149 break;
1150 }
1151 }
1152
1153 return(is_offset);
1154 }
1155
1156 /*
1157 Tagset 1: 0x01-0x19,0xE00,0x1000,0x1001 330,430
1158 Tagset 2: 0x02-0x04,0x2000-0x2003,0x2011-0x2013,0x2021-0x2023,0x2031-0x2034,03000-0x3007,0x3011-0x3018
1159 (first 4 tags thumbnail, even jpeg, both methods) 330RS,430RS
1160 Tagset 3: 0x01-0x0029,0x0E00,0x002E,...,0x002A,0x002C,0x0031,0x0032 Optio550
1161 Tagset 3: 0x01-0x0029,....0x0049,0x0200-0x0216,0x03FF,0x0402 starist
1162 (CaptureMode, next 3 thumbnail, dim/length/offset), date & time (6,7)
1163 */
1164