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_casio.c,v 1.19 2005/07/24 22:56:26 alex Exp $";
11 #endif
12
13 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
14 /* Casio camera maker-specific routines. */
15 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
16 /* Most of the information coded here is due to Eckhard Henkel */
17 /* (eckhard.henkel@t-online.de) as shown by TsuruZoh Tachibanaya at: */
18 /* http://www.ba.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html */
19 /* (now found at: */
20 /* http://landscapeimage.com/ThumbHTML/help/exif_file_format.html) */
21 /* Additional information: */
22 /* http://www.dicasoft.de/casiomn.htm */
23
24 /* EP-600 info: (added Jan 05) */
25 /* evan@ozhiker.com */
26 /* http://www.ozhiker.com/electronics/pjmt/jpeg_info/casio_mn.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
43 extern struct camera_id casio_model_id[];
44
45 int
casio_model_number(char * model,char * software)46 casio_model_number(char *model,char *software)
47 {
48 struct camera_id *model_id;
49 int number = NO_MODEL;
50
51 for(model_id = &casio_model_id[0]; model_id && model_id->name; ++model_id)
52 {
53 if(strncasecmp(model,model_id->name,model_id->namelen) == 0)
54 {
55 number = model_id->id;
56 setnoteversion(model_id->noteversion);
57 setnotetagset(model_id->notetagset); /* info only */
58 break;
59 }
60 }
61 return(number);
62 }
63
64 /* Determine and set note version from detected scheme. */
65 /* Notes with ID scheme use noteversion 2 */
66 /* Notes with Plain use noteversion 1 */
67
68 int
set_casio_noteversion()69 set_casio_noteversion()
70 {
71 struct maker_scheme *scheme;
72 int noteversion = 0;
73 int tagset = 0;
74
75 scheme = retrieve_makerscheme();
76 if(scheme->note_version <= 0)
77 {
78 noteversion = -1;
79 tagset = -1;
80 switch(scheme->scheme_type)
81 {
82 case HAS_ID_SCHEME: /* "QVC" */
83 tagset = 2;
84 noteversion = 2;
85 break;
86 case PLAIN_IFD_SCHEME:
87 tagset = 1;
88 noteversion = 1;
89 break;
90 case UNKNOWN_SCHEME:
91 break;
92 default:
93 break;
94 }
95 setnotetagset(tagset);
96 setnoteversion(noteversion);
97 }
98 else
99 noteversion = scheme->note_version;
100 return(noteversion);
101 }
102
103
104 /* Dispatch a Casio print routine based upon noteversion */
105
106 void
print_casio_makervalue(struct ifd_entry * entry_ptr,int make,int model,char * prefix)107 print_casio_makervalue(struct ifd_entry *entry_ptr,int make, int model,
108 char *prefix)
109 {
110 int noteversion = 0;
111
112 noteversion = getnoteversion();
113
114 if(entry_ptr && (PRINT_VALUE))
115 {
116 switch(noteversion)
117 {
118 case 2:
119 print_casio1_makervalue(entry_ptr,make,model,prefix);
120 casio2_interpret_value(entry_ptr);
121 break;
122 case 1:
123 print_casio1_makervalue(entry_ptr,make,model,prefix);
124 casio1_interpret_value(entry_ptr);
125 break;
126 default:
127 print_value(entry_ptr,PREFIX);
128 break;
129 }
130 }
131 }
132
133 /* Model-specific print routine for Casio cameras. This routine is */
134 /* responsible for picking off any direct entry tags which are */
135 /* peculiar and will not be handled properly by print_value() */
136 /* (usually UNDEFINED values which fit in the 4-byte entry value). If */
137 /* there are no such entries, this function simply calls */
138 /* print_value(). */
139
140 void
print_casio1_makervalue(struct ifd_entry * entry_ptr,int make,int model,char * prefix)141 print_casio1_makervalue(struct ifd_entry *entry_ptr,int make, int model,
142 char *prefix)
143 {
144 if(entry_ptr && (PRINT_VALUE))
145 {
146 switch(entry_ptr->tag)
147 {
148 default:
149 print_value(entry_ptr,PREFIX);
150 break;
151 }
152 }
153 }
154
155
156 /* Dispatch a routine to decode and print offset values for Casio */
157 /* cameras. */
158
159 void
print_casio_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)160 print_casio_offset_makervalue(FILE *inptr,unsigned short byteorder,
161 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
162 struct image_summary *summary_entry,char *parent_name,char*prefix,
163 int indent,int make,int model,int at_offset)
164 {
165 int noteversion = 0;
166
167 noteversion = getnoteversion();
168
169 if(entry_ptr)
170 {
171 switch(noteversion)
172 {
173 case 1:
174 casio1_offset_makervalue(inptr,byteorder,entry_ptr,
175 fileoffset_base,summary_entry,
176 parent_name,prefix,indent,
177 make,model,at_offset);
178 break;
179 case 2:
180 casio2_offset_makervalue(inptr,byteorder,entry_ptr,
181 fileoffset_base,summary_entry,
182 parent_name,prefix,indent,
183 make,model,at_offset);
184 break;
185 default:
186 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,
187 fileoffset_base,parent_name,prefix,
188 indent,make,model,at_offset);
189 break;
190 }
191 }
192 }
193
194 /* Model-specific routine to print UNDEFINED values found at offsets */
195 /* in Casio makernotes. */
196
197 void
casio1_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)198 casio1_offset_makervalue(FILE *inptr,unsigned short byteorder,
199 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
200 struct image_summary *summary_entry,char *parent_name,char*prefix,
201 int indent,int make,int model,int at_offset)
202 {
203 char *nameoftag;
204 unsigned long value_offset,current_offset;
205 unsigned long count;
206 int chpr = 0;
207 char *fulldirname = NULL;
208
209 if(entry_ptr)
210 {
211 value_offset = fileoffset_base + entry_ptr->value;
212 nameoftag = maker_tagname(entry_ptr->tag,make,model);
213 fulldirname = splice(parent_name,".",nameoftag);
214 count = entry_ptr->count;
215
216 switch(entry_ptr->tag)
217 {
218 case 0x0e00: /* PrintIM (Epson Print Image matching) */
219 if(!at_offset && (PRINT_VALUE))
220 {
221 if(!(PRINT_OFFSET))
222 {
223 chpr += printf("@%lu:%lu",value_offset,count);
224 chpr = newline(chpr);
225 }
226 }
227 current_offset = ftell(inptr);
228 if(process_pim(inptr,byteorder,entry_ptr->value,fileoffset_base,
229 count,nameoftag,parent_name,prefix,indent) == 0)
230 {
231 /* At least one QV4000 image uses a PIM offset */
232 /* relative to the entry address, even though */
233 /* other entries in the note are TIFF-relative; */
234 /* check for a PIM entry at that location if the */
235 /* previous one failed. GROSS HACK! */
236 fileoffset_base = current_offset - 12;
237 PUSHCOLOR(HI_BLACK);
238 chpr += printf(" checking for entry-relative offset bug");
239 POPCOLOR();
240 if(process_pim(inptr,byteorder,entry_ptr->value,fileoffset_base,
241 count,nameoftag,parent_name,
242 prefix,indent))
243 {
244 if(!(PRINT_SECTION))
245 {
246 chpr = newline(chpr);
247 printred("# WARNING:");
248 }
249 PUSHCOLOR(HI_BLACK);
250 chpr += printf(" %s data found at offset %lu - ",nameoftag,
251 entry_ptr->value + fileoffset_base);
252 printred("start offset is incorrect!");
253 POPCOLOR();
254 if(!(PRINT_SECTION))
255 {
256 chpr = newline(chpr);
257 print_filename();
258 if((PRINT_TAGINFO))
259 {
260 if((PRINT_LONGNAMES))
261 chpr += printf("%s.",fulldirname);
262 chpr += printf("%-*.*s",MAKERTAGWIDTH,MAKERTAGWIDTH,nameoftag);
263 }
264 if((PRINT_VALUE))
265 chpr += printf(" = @%lu:%lu",entry_ptr->value + fileoffset_base,
266 count);
267 }
268 }
269 }
270 break;
271 default:
272 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,
273 fileoffset_base,fulldirname,prefix,indent,
274 make,model,at_offset);
275 break;
276 }
277 if(fulldirname)
278 free(fulldirname);
279 }
280 setcharsprinted(chpr);
281 }
282
283 void
casio2_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)284 casio2_offset_makervalue(FILE *inptr,unsigned short byteorder,
285 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
286 struct image_summary *summary_entry,char *parent_name,char*prefix,
287 int indent,int make,int model,int at_offset)
288 {
289 unsigned long value_offset,current_offset;
290 unsigned long count;
291 unsigned short marker;
292 char *nameoftag;
293 char *fulldirname = NULL;
294 unsigned long max_offset = 0;
295 int status = 0;
296 int chpr = 0;
297
298 if(entry_ptr)
299 {
300 nameoftag = maker_tagname(entry_ptr->tag,make,model);
301 fulldirname = splice(parent_name,".",nameoftag);
302 value_offset = fileoffset_base + entry_ptr->value;
303 count = entry_ptr->count;
304
305 switch(entry_ptr->tag)
306 {
307 case 0x0004: /* JpegThumbnailOffset */
308 /* When this tag is present, the 0x2000 tag is */
309 /* present as well. Both entries point to the same */
310 /* thumbnail, so just print values for length and */
311 /* offset tags, and display the thumbnail on the */
312 /* (self-contained) 0x2000 tag */
313 if(!at_offset && (PRINT_VALUE))
314 {
315 if(!(PRINT_OFFSET))
316 chpr += printf("@%lu",value_offset);
317 }
318 break;
319 case 0x2000: /* JpegThumbnail */
320 if(at_offset && (PRINT_SECTION))
321 {
322 print_tag_address(SECTION,value_offset,indent,prefix);
323 chpr += printf("# Start of JPEG Thumbnail from MakerNote");
324 chpr += printf(" length %ld",count);
325 }
326 else if(!at_offset && (PRINT_VALUE))
327 {
328 if(!(PRINT_OFFSET))
329 chpr += printf("@%lu:%lu",value_offset,entry_ptr->count);
330 else
331 chpr += printf("length %lu", entry_ptr->count);
332 }
333 if((PRINT_SECTION) || (PRINT_SEGMENT))
334 chpr = newline(chpr);
335 marker = read_ushort(inptr,TIFF_MOTOROLA,value_offset);
336 max_offset = process_jpeg_segments(inptr,value_offset,marker,
337 count,summary_entry,fulldirname,
338 prefix,indent+SMALLINDENT);
339 if(at_offset)
340 {
341 if((PRINT_SECTION))
342 {
343 if((status = jpeg_status(0) == JPEG_EARLY_EOI))
344 chpr = newline(chpr);
345 jpeg_status(status);
346 print_tag_address(VALUE_AT_OFFSET,value_offset + count - 1,
347 indent,prefix);
348 chpr += printf("# End of JPEG Thumbnail from MakerNote");
349 if((PRINT_ENTRY) && !(PRINT_VALUE))
350 chpr = newline(chpr);
351 }
352 }
353 print_jpeg_status();
354 if(marker && summary_entry)
355 {
356 /* The new one is on the end of the chain */
357 if((summary_entry = last_summary_entry(summary_entry)))
358 {
359 summary_entry->filesubformat |= FILESUBFMT_MNOTE;
360 summary_entry->datatype = MAKER_IFD;
361 summary_entry->subfiletype = THUMBNAIL_TYPE;
362 }
363 }
364 /* make certain we're at the end */
365 clearerr(inptr);
366 fseek(inptr,value_offset + count,0);
367 break;
368 case 0x0e00: /* PrintIM (Epson Print Image matching) */
369 nameoftag = maker_tagname(entry_ptr->tag,make,model);
370 if(!at_offset && (PRINT_VALUE))
371 {
372 if(!(PRINT_OFFSET))
373 chpr += printf("@%lu",value_offset);
374 }
375 current_offset = ftell(inptr);
376 if(process_pim(inptr,byteorder,entry_ptr->value,fileoffset_base,
377 entry_ptr->count,nameoftag,parent_name,prefix,indent) == 0)
378 {
379 /* At least one QV4000 image uses a PIM offset */
380 /* relative to the entry address, even though */
381 /* other entries in the note are TIFF-relative; */
382 /* check for a PIM entry at that location if the */
383 /* previous one failed. GROSS HACK! */
384 fileoffset_base = current_offset - 12;
385 PUSHCOLOR(HI_BLACK);
386 /* We've already seen an error message */
387 chpr += printf(" checking for entry-relative offset bug");
388 POPCOLOR();
389 if(process_pim(inptr,byteorder,entry_ptr->value,fileoffset_base,
390 entry_ptr->count,nameoftag,parent_name,
391 prefix,indent))
392 {
393 if(!(PRINT_OFFSET))
394 {
395 chpr = newline(chpr);
396 chpr += printf("# WARNING:");
397 }
398 PUSHCOLOR(HI_BLACK);
399 chpr += printf(" PrintImage data found at offset %lu - ",
400 entry_ptr->value + fileoffset_base);
401 printred("start offset is incorrect!");
402 POPCOLOR();
403 if(!(PRINT_SECTION))
404 {
405 chpr = newline(chpr);
406 print_tag_address(VALUE_AT_OFFSET,entry_ptr->value + fileoffset_base,
407 indent,"-");
408 if((PRINT_TAGINFO))
409 {
410 if((PRINT_LONGNAMES))
411 chpr += printf("%s.",fulldirname);
412 chpr += printf("%-*.*s",MAKERTAGWIDTH,MAKERTAGWIDTH,nameoftag);
413 }
414 if((PRINT_VALUE))
415 chpr += printf(" = @%lu",entry_ptr->value + fileoffset_base);
416 }
417 }
418 }
419 break;
420 default:
421 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,
422 fileoffset_base,fulldirname,prefix,indent,
423 make,model,at_offset);
424 break;
425 }
426 if(fulldirname)
427 free(fulldirname);
428 }
429 setcharsprinted(chpr);
430 }
431
432
433 /* Casio-specific tagnames for makernotes. */
434
435 /* The tagname routine is the first place in the code path which */
436 /* requires knowledge of the note version. If the version is not */
437 /* given in the model table (e.g. the model is unknown), then switch */
438 /* code in find_maker_scheme() should have set it. This routine */
439 /* repeats the check for non-zero noteversion and is prepared to set */
440 /* the noteversion first time through, but should never need to do */
441 /* so. Noteversion should always be non-zero; it should be set to -1 */
442 /* if generic processing is required. */
443
444 char *
maker_casio_tagname(unsigned short tag,int model)445 maker_casio_tagname(unsigned short tag,int model)
446 {
447 char *tagname = (char *)0;
448 int noteversion = 0;
449
450 if((noteversion = getnoteversion()) == 0)
451 {
452 noteversion = set_casio_noteversion();
453 setnoteversion(noteversion);
454 }
455
456 /* Check noteversions first */
457 switch(noteversion)
458 {
459 case 1:
460 tagname = maker_casio1_tagname(tag,model);
461 break;
462 case 2:
463 tagname = maker_casio2_tagname(tag,model);
464 break;
465 default:
466 break;
467 }
468
469 /* If no version-specific tag is found, check "generic" tags */
470 if(tagname == NULL)
471 {
472 switch(tag)
473 {
474 case 0x0e00: tagname = "PrintIM"; break;
475 default: break;
476 }
477 }
478 return(tagname);
479 }
480
481
482 char *
maker_casio1_tagname(unsigned short tag,int model)483 maker_casio1_tagname(unsigned short tag,int model)
484 {
485 char *tagname = CNULL;
486
487 switch(tag)
488 {
489 case 0x0001: tagname = "RecordingMode"; break;
490 case 0x0002: tagname = "Quality"; break;
491 case 0x0003: tagname = "FocusingMode"; break;
492 case 0x0004: tagname = "FlashMode"; break;
493 case 0x0005: tagname = "FlashIntensity"; break;
494 case 0x0006: tagname = "ObjectDistance"; break;
495 case 0x0007: tagname = "WhiteBalance"; break;
496 case 0x000a: tagname = "DigitalZoom"; break;
497 case 0x000b: tagname = "Sharpness"; break;
498 case 0x000c: tagname = "Contrast"; break;
499 case 0x000d: tagname = "Saturation"; break;
500 case 0x0014: tagname = "CCDSensitivity"; break;
501 default: break;
502 }
503 setnotetagset(1);
504 return(tagname);
505 }
506
507
508 char *
maker_casio2_tagname(unsigned short tag,int model)509 maker_casio2_tagname(unsigned short tag,int model)
510 {
511 char *tagname = CNULL;
512
513 /* This is the same as Asahi/Pentax note version 2 */
514 switch(tag)
515 {
516 case 0x0002: tagname = "JpegThumbnailDimensions"; break;
517 case 0x0003: tagname = "JpegThumbnailLength"; break;
518 case 0x0004: tagname = "JpegThumbnailOffset"; break;
519 case 0x0008: tagname = "QualityMode"; break;
520 case 0x0009: tagname = "ImageSize"; break;
521 case 0x000D: tagname = "FocusMode"; break;
522 case 0x0014: tagname = "IsoSensitivity"; break;
523 case 0x0019: tagname = "WhiteBalance"; break;
524 case 0x001D: tagname = "FocalLength"; break; /* units .1mm */
525 case 0x001F: tagname = "Saturation"; break;
526 case 0x0020: tagname = "Contrast"; break;
527 case 0x0021: tagname = "Sharpness"; break;
528 case 0x2000: tagname = "JpegThumbnail"; break;
529 case 0x2011: tagname = "WhiteBalanceBias"; break;
530 case 0x2012: tagname = "WhiteBalance"; break;
531 case 0x2022: tagname = "ObjectDistance"; break;
532 case 0x2034: tagname = "FlashDistance"; break;
533 case 0x3000: tagname = "RecordMode"; break;
534 case 0x3001: tagname = "SelfTimer?"; break;
535 case 0x3002: tagname = "Quality"; break;
536 case 0x3003: tagname = "FocusMode"; break;
537 case 0x3006: tagname = "TimeZone"; break;
538 case 0x3007: tagname = "BestshotMode"; break;
539 case 0x3014: tagname = "CCDSensitivity"; break;
540 case 0x3015: tagname = "ColorMode"; break;
541 case 0x3016: tagname = "Enhancement"; break;
542 case 0x3017: tagname = "Filter"; break;
543 default: break;
544 }
545 setnotetagset(2);
546 return(tagname);
547 }
548
549 /* Report the "meaning" of tag values found directly in a Casio */
550 /* MakerNote IFD entry (not at an offset). */
551
552 void
casio1_interpret_value(struct ifd_entry * entry_ptr)553 casio1_interpret_value(struct ifd_entry *entry_ptr)
554 {
555 int chpr = 0;
556
557 if(entry_ptr && (PRINT_VALUE))
558 {
559 switch(entry_ptr->tag)
560 {
561 case 0x0001: /* RecordingMode */
562 print_startvalue();
563 switch(entry_ptr->value)
564 {
565 case 1: chpr += printf("Single Shutter"); break;
566 case 2: chpr += printf("Panorama"); break;
567 case 3: chpr += printf("Night Scene"); break;
568 case 4: chpr += printf("Portrait"); break;
569 case 5: chpr += printf("Landscape"); break;
570 default: printred("undefined"); break;
571 }
572 print_endvalue();
573 break;
574 case 0x0002: /* Quality */
575 print_startvalue();
576 switch(entry_ptr->value)
577 {
578 case 1: chpr += printf("Economy"); break;
579 case 2: chpr += printf("Normal"); break;
580 case 3: chpr += printf("Fine"); break;
581 default: printred("undefined"); break;
582 }
583 print_endvalue();
584 break;
585 case 0x0003: /* Focusing Mode */
586 print_startvalue();
587 switch(entry_ptr->value)
588 {
589 case 2: chpr += printf("Macro"); break;
590 case 3: chpr += printf("Auto"); break;
591 case 4: chpr += printf("Manual"); break;
592 case 5: chpr += printf("Infinity"); break;
593 default: printred("undefined"); break;
594 }
595 print_endvalue();
596 break;
597 case 0x0004: /* Flash Mode */
598 print_startvalue();
599 switch(entry_ptr->value)
600 {
601 case 1: chpr += printf("Auto"); break;
602 case 2: chpr += printf("On"); break;
603 case 3: chpr += printf("Off"); break;
604 case 4: chpr += printf("Redeye"); break;
605 default: printred("undefined"); break;
606 }
607 print_endvalue();
608 break;
609 case 0x0005: /* Flash Intensity */
610 print_startvalue();
611 switch(entry_ptr->value)
612 {
613 case 11: chpr += printf("Weak"); break;
614 case 13: chpr += printf("Normal"); break;
615 case 15: chpr += printf("Strong"); break;
616 default: printred("undefined"); }
617 break;
618 case 0x0006: /* Object Distance */
619 PUSHCOLOR(UNCERTAIN_COLOR);
620 chpr += printf(" mm");
621 POPCOLOR();
622 break;
623 case 0x0007: /* White Balance */
624 print_startvalue();
625 switch(entry_ptr->value)
626 {
627 case 1: chpr += printf("Auto"); break;
628 case 2: chpr += printf("Tungsten"); break;
629 case 3: chpr += printf("Daylight"); break;
630 case 4: chpr += printf("Fluorescent"); break;
631 case 5: chpr += printf("Shade"); break;
632 case 129: chpr += printf("Manual"); break;
633 default: printred("undefined"); break;
634 }
635 print_endvalue();
636 break;
637 case 0x000a: /* Digital Zoom */
638 print_startvalue();
639 switch(entry_ptr->value)
640 {
641 case 0x10000: chpr += printf("Off"); break;
642 case 0x10001: chpr += printf("On"); break;
643 default: printred("undefined"); break;
644 }
645 print_endvalue();
646 break;
647 case 0x000b: /* Sharpness */
648 print_startvalue();
649 switch(entry_ptr->value)
650 {
651 case 0: chpr += printf("Normal"); break;
652 case 1: chpr += printf("Soft"); break;
653 case 2: chpr += printf("Hard"); break;
654 default: printred("undefined"); break;
655 }
656 print_endvalue();
657 break;
658 case 0x000c: /* Contrast */
659 print_startvalue();
660 switch(entry_ptr->value)
661 {
662 case 0: chpr += printf("Normal"); break;
663 case 1: chpr += printf("Low"); break;
664 case 2: chpr += printf("High"); break;
665 default: printred("undefined"); break;
666 }
667 print_endvalue();
668 break;
669 case 0x000d: /* Saturation */
670 print_startvalue();
671 switch(entry_ptr->value)
672 {
673 case 0: chpr += printf("Normal"); break;
674 case 1: chpr += printf("Low"); break;
675 case 2: chpr += printf("High"); break;
676 default: printred("undefined"); break;
677 }
678 print_endvalue();
679 break;
680 default:
681 break;
682 }
683 }
684 setcharsprinted(chpr);
685 }
686
687 void
casio2_interpret_value(struct ifd_entry * entry_ptr)688 casio2_interpret_value(struct ifd_entry *entry_ptr)
689 {
690 int chpr = 0;
691
692 if(entry_ptr && (PRINT_VALUE))
693 {
694 switch(entry_ptr->tag)
695 {
696 case 0x0002: /* ThumbnailDimensions" */
697 chpr += printf(" pixels");
698 break;
699 case 0x0008: /* QualityMode" */
700 print_startvalue();
701 switch(entry_ptr->value)
702 {
703 case 1: chpr += printf("Fine"); break;
704 case 2: chpr += printf("Super Fine"); break;
705 default: chpr += printf("unknown"); break;
706 }
707 print_endvalue();
708 break;
709 case 0x0009: /* ImageSize" */
710 print_startvalue();
711 switch(entry_ptr->value)
712 {
713 case 1: chpr += printf("640x480"); break;
714 case 4: chpr += printf("1600x1200"); break;
715 case 5: chpr += printf("2048x1536"); break;
716 case 20: chpr += printf("2288x1712"); break;
717 case 21: chpr += printf("2592x1944"); break;
718 case 22: chpr += printf("2304x1728"); break;
719 case 36: chpr += printf("3008x2008"); break;
720 default: chpr += printf("unknown"); break;
721 }
722 print_endvalue();
723 break;
724 case 0x000D: /* FocusMode" */
725 print_startvalue();
726 switch(entry_ptr->value)
727 {
728 case 1: chpr += printf("Normal"); break;
729 case 2: chpr += printf("Macro"); break;
730 default: chpr += printf("unknown"); break;
731 }
732 print_endvalue();
733 break;
734 case 0x0014: /* IsoSensitivity" */
735 print_startvalue();
736 switch(entry_ptr->value)
737 {
738 case 3: chpr += printf("50"); break;
739 case 4: chpr += printf("64"); break;
740 case 6: chpr += printf("100"); break;
741 case 9: chpr += printf("200"); break;
742 default: chpr += printf("unknown"); break;
743 }
744 print_endvalue();
745 break;
746 case 0x0019: /* WhiteBalance" */
747 print_startvalue();
748 switch(entry_ptr->value)
749 {
750 case 1: chpr += printf("Fine"); break;
751 case 2: chpr += printf("Shade"); break;
752 case 3: chpr += printf("Tungsten"); break;
753 case 4: chpr += printf("Fluorescent"); break;
754 case 5: chpr += printf("Manual"); break;
755 default: chpr += printf("unknown"); break;
756 }
757 print_endvalue();
758 break;
759 /* rational? case 0x001D: tagname = "FocalLength"; break; units .1mm */
760 case 0x001F: /* Saturation" */
761 print_startvalue();
762 switch(entry_ptr->value)
763 {
764 case 0: chpr += printf("-1"); break;
765 case 1: chpr += printf("Normal"); break;
766 case 2: chpr += printf("+1"); break;
767 default: chpr += printf("unknown"); break;
768 }
769 print_endvalue();
770 break;
771 case 0x0020: /* Contrast" */
772 print_startvalue();
773 switch(entry_ptr->value)
774 {
775 case 0: chpr += printf("-1"); break;
776 case 1: chpr += printf("Normal"); break;
777 case 2: chpr += printf("+1"); break;
778 default: chpr += printf("unknown"); break;
779 }
780 print_endvalue();
781 break;
782 case 0x0021: /* Sharpness" */
783 print_startvalue();
784 switch(entry_ptr->value)
785 {
786 case 0: chpr += printf("-1"); break;
787 case 1: chpr += printf("Normal"); break;
788 case 2: chpr += printf("+1"); break;
789 default: chpr += printf("unknown"); break;
790 }
791 print_endvalue();
792 break;
793 case 0x2012: /* WhiteBalance" */
794 print_startvalue();
795 switch(entry_ptr->value)
796 {
797 case 0: chpr += printf("Manual"); break;
798 case 1: chpr += printf("Auto"); break;
799 case 4: chpr += printf("Flash"); break;
800 case 12: chpr += printf("Flash"); break;
801 default: chpr += printf("unknown"); break;
802 }
803 print_endvalue();
804 break;
805 case 0x2022: /* ObjectDistance" */
806 chpr += printf("mm");
807 break;
808 case 0x2034: /* FlashDistance" */
809 #if 0
810 Off?
811 if(entry_ptr->value == 0)
812 {
813 print_startvalue();
814 chpr += printf("Off");
815 print_endvalue();
816 }
817 #endif
818 break;
819 case 0x3000: /* RecordMode" */
820 print_startvalue();
821 switch(entry_ptr->value)
822 {
823 case 2: chpr += printf("Normal"); break;
824 default: chpr += printf("unknown"); break;
825 }
826 print_endvalue();
827 break;
828 case 0x3001: /* SelfTimer?" */
829 print_startvalue();
830 switch(entry_ptr->value)
831 {
832 case 1: chpr += printf("Off"); break;
833 default: chpr += printf("unknown"); break;
834 }
835 print_endvalue();
836 break;
837 case 0x3002: /* Quality" */
838 print_startvalue();
839 switch(entry_ptr->value)
840 {
841 case 1: chpr += printf("Economy"); break;
842 case 2: chpr += printf("Normal"); break;
843 case 3: chpr += printf("Fine"); break;
844 default: chpr += printf("unknown"); break;
845 }
846 print_endvalue();
847 break;
848 case 0x3003: /* FocusMode" */
849 print_startvalue();
850 switch(entry_ptr->value)
851 {
852 case 1: chpr += printf("Fixed"); break;
853 case 3: chpr += printf("Single-Area Auto"); break;
854 case 6: chpr += printf("Multi-Area Auto"); break;
855 default: chpr += printf("unknown"); break;
856 }
857 print_endvalue();
858 break;
859 case 0x3007: /* BestshotMode" */
860 print_startvalue();
861 switch(entry_ptr->value)
862 {
863 case 0: chpr += printf("Off"); break;
864 default: chpr += printf("unknown"); break;
865 }
866 print_endvalue();
867 break;
868 case 0x3015: /* ColorMode" */
869 #if 0
870 Off???
871 print_startvalue();
872 switch(entry_ptr->value)
873 {
874 case 0: chpr += printf("Off"); break;
875 default: chpr += printf("unknown"); break;
876 }
877 print_endvalue();
878 #endif
879 break;
880 case 0x3016: /* Enhancement" */
881 print_startvalue();
882 switch(entry_ptr->value)
883 {
884 case 0: chpr += printf("Off"); break;
885 default: chpr += printf("unknown"); break;
886 }
887 print_endvalue();
888 break;
889 case 0x3017: /* Filter" */
890 print_startvalue();
891 switch(entry_ptr->value)
892 {
893 case 0: chpr += printf("Off"); break;
894 default: chpr += printf("unknown"); break;
895 }
896 print_endvalue();
897 break;
898 default: break;
899 }
900 }
901 setcharsprinted(chpr);
902 }
903
904 /* Some makernotes record offsets as LONG values rather than simply */
905 /* using UNDEFINED with a size; the same technique used for */
906 /* the ExifIFDPointer itself, or JpegInterchangeFormat, etc. */
907 /* This routine hardcodes such tags so that the print_makerentry() */
908 /* routine will present them as offsets. */
909
910 int
maker_casio_value_is_offset(struct ifd_entry * entry_ptr,int model)911 maker_casio_value_is_offset(struct ifd_entry *entry_ptr,int model)
912 {
913 int is_offset = 0;
914 int noteversion = 0;
915
916 if(entry_ptr)
917 {
918 noteversion = getnoteversion();
919 switch(noteversion)
920 {
921 case 2:
922 switch(entry_ptr->tag)
923 {
924 case 0x0004: is_offset = 1; break;
925 default: break;
926 }
927 break;
928 default:
929 break;
930 }
931 }
932 return(is_offset);
933 }
934