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_canon.c,v 1.29 2005/07/24 22:56:26 alex Exp $";
11 #endif
12
13 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
14 /* Canon camera maker-specific routines */
15 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
16 /* The information coded here is derived from information provided by */
17 /* David Burren at: */
18 /* http://www.burren.cx/david/canon.html */
19
20 /* April 05: new tag information and CustomFunctions for additional */
21 /* models from Phil Harvey's exiftool pages at: */
22 /* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/index.html */
23 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29
30 #include "defs.h"
31 #include "datadefs.h"
32 #include "maker_datadefs.h"
33 #include "summary.h"
34 #include "maker.h"
35 #include "misc.h"
36 #include "tags.h"
37 #include "maker_extern.h"
38 #include "extern.h"
39
40 extern struct camera_id canon_model_id[];
41
42
43 /* Find the identifying number assigned to known Canon camera models. */
44 /* This number is used to dispatch appropriate print and interpret */
45 /* routines approopriate to the current image. */
46
47 int
canon_model_number(char * model,char * software)48 canon_model_number(char *model,char *software)
49 {
50 struct camera_id *model_id;
51 int number = NO_MODEL;
52
53 for(model_id = &canon_model_id[0]; model_id && model_id->name; ++model_id)
54 {
55 if(strncasecmp(model,model_id->name,model_id->namelen) == 0)
56 {
57 number = model_id->id;
58 setnoteversion(model_id->noteversion);
59 setnotetagset(model_id->notetagset); /* info only */
60 break;
61 }
62 }
63 return(number);
64 }
65
66 /* Dispatch a print routine based upon previously set noteversion */
67 /* Everything is (currently) mapped to one set of routines. */
68
69 void
print_canon_makervalue(struct ifd_entry * entry_ptr,int make,int model,char * prefix)70 print_canon_makervalue(struct ifd_entry *entry_ptr,int make, int model,
71 char *prefix)
72 {
73 int noteversion = 0;
74
75 noteversion = getnoteversion();
76
77 if(entry_ptr && (PRINT_VALUE))
78 {
79 switch(noteversion)
80 {
81 case 1:
82 case 2:
83 case 3:
84 case 4:
85 case 5:
86 print_canon1_makervalue(entry_ptr,make,model,prefix);
87 canon1_interpret_value(entry_ptr);
88 break;
89 default:
90 print_value(entry_ptr,PREFIX);
91 break;
92 }
93 }
94 }
95
96 /* Model-specific print routine for Canon cameras. This routine is */
97 /* responsible for picking off any direct entry tags which are */
98 /* peculiar and will 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_canon1_makervalue(struct ifd_entry * entry_ptr,int make,int model,char * prefix)104 print_canon1_makervalue(struct ifd_entry *entry_ptr,int make, int model,
105 char *prefix)
106 {
107 if(entry_ptr && (PRINT_VALUE))
108 {
109 switch(entry_ptr->tag)
110 {
111 case 0x000C: /* Camera serial number */
112 print_value(entry_ptr,PREFIX);
113 /* ###%%% */
114 /* perhaps this should be in canon1_interpret_value() */
115 (void)print_canon_serialno(entry_ptr->value);
116 break;
117 default:
118 print_value(entry_ptr,PREFIX);
119 break;
120 }
121 }
122 }
123
124 /* Canon serial numbers are encoded. It is not clear that this is */
125 /* consistent across all models, but since the "raw" value is */
126 /* displayed as well, it will do no harm to display this */
127 /* unconditionally. */
128
129 int
print_canon_serialno(unsigned long value)130 print_canon_serialno(unsigned long value)
131 {
132 unsigned long tmp;
133 int chpr = 0;
134
135 print_startvalue();
136 tmp = (value & 0xffff0000) >> 16;
137 chpr += printf("%04lX",value & 0xffff);
138 tmp = value & 0xffff;
139 chpr += printf("%05lu",value & 0xffff);
140 print_endvalue();
141 setcharsprinted(chpr);
142 return(chpr);
143 }
144
145 /* Dispatch a routine to decode and print offset values for Canon */
146 /* cameras. There is currently only one tagset, and 1 interpretation */
147 /* of each tag, except that there are 4 different varieties of custom */
148 /* functions. The canon_customfunctions() routine will do the */
149 /* selection on noteversion; everything is handled the same here. */
150
151 void
print_canon_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)152 print_canon_offset_makervalue(FILE *inptr,unsigned short byteorder,
153 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
154 struct image_summary *summary_entry,char *parent_name,
155 char *prefix,int indent,int make,int model,
156 int at_offset)
157 {
158 int noteversion = 0;
159
160 noteversion = getnoteversion();
161
162 if(entry_ptr)
163 {
164 switch(noteversion)
165 {
166 /* noteversion 1 assumes the single known tagset is */
167 /* correct, but imposes a "generic" routine for */
168 /* CustomFunctions (which presents values but interprets */
169 /* nothing) for unrecognized models or those for which no */
170 /* information is available. */
171 case 1:
172 case 2:
173 case 3:
174 case 4:
175 case 5:
176 canon1_offset_makervalue(inptr,byteorder,entry_ptr,
177 fileoffset_base,summary_entry,
178 parent_name,prefix,indent,
179 make,model,at_offset);
180 break;
181 default:
182 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,fileoffset_base,
183 parent_name,prefix,indent,
184 make,model,at_offset);
185 break;
186 }
187 }
188 }
189
190 /* Model-specific routine to print UNDEFINED values found at offsets */
191 /* in canon makernotes. */
192
193 void
canon1_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)194 canon1_offset_makervalue(FILE *inptr,unsigned short byteorder,
195 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
196 struct image_summary *summary_entry,char *parent_name,char*prefix,
197 int indent,int make,int model,int at_offset)
198 {
199 unsigned long value_offset;
200 unsigned long count;
201 unsigned long max_offset = 0;
202 unsigned long filesize = 0UL;
203 unsigned short marker;
204 char *nameoftag,*tagprefix;
205 char *fulldirname = NULL;
206 int status = 0;
207 int chpr = 0;
208
209 if(entry_ptr)
210 {
211 nameoftag = maker_tagname(entry_ptr->tag,make,model);
212 fulldirname = splice(parent_name,".",nameoftag);
213 value_offset = fileoffset_base + entry_ptr->value;
214 count = entry_ptr->count;
215 filesize = get_filesize(inptr);
216
217 switch(entry_ptr->tag)
218 {
219 case 0x0001: /* Camera Settings */
220 if(at_offset)
221 {
222 if((PRINT_SECTION))
223 {
224 print_tag_address(SECTION,value_offset,indent,prefix);
225 chpr += printf("<%s> ",nameoftag);
226 chpr += printf("%lu entries",entry_ptr->count - 1);
227 }
228 }
229 else if((PRINT_VALUE))
230 chpr += printf("\'%lu entries\'",entry_ptr->count - 1);
231 if((PRINT_LONGNAMES))
232 tagprefix = fulldirname;
233 else
234 tagprefix = nameoftag;
235 setcharsprinted(chpr);
236 chpr = 0;
237 (void)canon_camera_settings(inptr,byteorder,tagprefix,value_offset,
238 entry_ptr->count * sizeof(unsigned short),
239 indent + MEDIUMINDENT);
240 if(PRINT_SECTION)
241 {
242 print_tag_address(SECTION,value_offset + (entry_ptr->count * 2) - 1,
243 indent,prefix);
244 chpr += printf("</%s> ",nameoftag);
245 }
246 break;
247 case 0x0002: /* Focus Info */
248 if(at_offset)
249 {
250 if((PRINT_SECTION))
251 {
252 print_tag_address(SECTION,value_offset,indent,prefix);
253 chpr += printf("<%s> ",nameoftag);
254 chpr += printf("%lu entries",entry_ptr->count);
255 }
256 }
257 else if((PRINT_VALUE))
258 chpr += printf("\'%lu entries\'",entry_ptr->count);
259 if((PRINT_LONGNAMES))
260 tagprefix = fulldirname;
261 else
262 tagprefix = nameoftag;
263 setcharsprinted(chpr);
264 chpr = 0;
265 (void)canon_focusinfo(inptr,byteorder,tagprefix,value_offset,
266 entry_ptr->count * sizeof(unsigned short),
267 indent + MEDIUMINDENT);
268 if(PRINT_SECTION)
269 {
270 print_tag_address(SECTION,value_offset + (entry_ptr->count * 2) - 1,
271 indent,prefix);
272 chpr += printf("</%s> ",nameoftag);
273 }
274 break;
275 case 0x0004: /* Shot Info */
276 if(at_offset)
277 {
278 if((PRINT_SECTION))
279 {
280 print_tag_address(SECTION,value_offset,indent,prefix);
281 chpr += printf("<%s> ",nameoftag);
282 chpr += printf("%lu entries",entry_ptr->count - 1);
283 }
284 }
285 else if((PRINT_VALUE))
286 chpr += printf("\'%lu entries\'",entry_ptr->count - 1);
287 if((PRINT_LONGNAMES))
288 tagprefix = fulldirname;
289 else
290 tagprefix = nameoftag;
291 setcharsprinted(chpr);
292 chpr = 0;
293 (void)canon_shotinfo(inptr,byteorder,tagprefix,value_offset,
294 entry_ptr->count * sizeof(unsigned short),
295 indent + MEDIUMINDENT);
296 if(PRINT_SECTION)
297 {
298 print_tag_address(SECTION,value_offset + (entry_ptr->count * 2) - 1,
299 indent,prefix);
300 chpr += printf("</%s> ",nameoftag);
301 }
302 break;
303 case 0x0090: /* Custom Functions */
304 case 0x000F: /* Custom Functions */
305 if(at_offset)
306 {
307 if((PRINT_SECTION))
308 {
309 print_tag_address(SECTION,value_offset,indent,prefix);
310 chpr += printf("<%s> ",nameoftag);
311 chpr += printf("%lu entries",entry_ptr->count - 1);
312 }
313 }
314 else if((PRINT_VALUE))
315 chpr += printf("\'%lu entries\'",entry_ptr->count - 1);
316 if((PRINT_LONGNAMES))
317 tagprefix = fulldirname;
318 else
319 tagprefix = nameoftag;
320 setcharsprinted(chpr);
321 chpr = 0;
322 (void)canon_customfunctions(inptr,byteorder,tagprefix,value_offset,
323 entry_ptr->count * sizeof(unsigned short),
324 model,indent + MEDIUMINDENT);
325 if(PRINT_SECTION)
326 {
327 print_tag_address(SECTION,value_offset + (entry_ptr->count * 2) - 1,
328 indent,prefix);
329 chpr += printf("</%s> ",nameoftag);
330 }
331 break;
332 case 0x00E0: /* Sensor Info */
333 if(at_offset)
334 {
335 if((PRINT_SECTION))
336 {
337 print_tag_address(SECTION,value_offset,indent,prefix);
338 chpr += printf("<%s> ",nameoftag);
339 chpr += printf("%lu entries",entry_ptr->count - 1);
340 }
341 }
342 else if((PRINT_VALUE))
343 chpr += printf("\'%lu entries\'",entry_ptr->count - 1);
344 if((PRINT_LONGNAMES))
345 tagprefix = fulldirname;
346 else
347 tagprefix = nameoftag;
348 setcharsprinted(chpr);
349 chpr = 0;
350 (void)canon_sensorinfo(inptr,byteorder,tagprefix,value_offset,
351 entry_ptr->count * sizeof(unsigned short),
352 indent + MEDIUMINDENT);
353 if(PRINT_SECTION)
354 {
355 print_tag_address(SECTION,value_offset + (entry_ptr->count * 2) - 1,
356 indent,prefix);
357 chpr += printf("</%s> ",nameoftag);
358 }
359 break;
360 case 0x0012: /* Picture Info */
361 if(at_offset)
362 {
363 if((PRINT_SECTION))
364 {
365 print_tag_address(SECTION,value_offset,indent,prefix);
366 chpr += printf("<%s> ",nameoftag);
367 chpr += printf("%lu entries",entry_ptr->count - 1);
368 }
369 }
370 else if((PRINT_VALUE))
371 chpr += printf("\'%lu entries\'",entry_ptr->count - 1);
372 if((PRINT_LONGNAMES))
373 tagprefix = fulldirname;
374 else
375 tagprefix = nameoftag;
376 setcharsprinted(chpr);
377 chpr = 0;
378 (void)canon_pictureinfo(inptr,byteorder,tagprefix,value_offset,
379 entry_ptr->count * sizeof(unsigned short),
380 indent + MEDIUMINDENT);
381 if(PRINT_SECTION)
382 {
383 print_tag_address(SECTION,value_offset + (entry_ptr->count * 2) - 1,
384 indent,prefix);
385 chpr += printf("</%s> ",nameoftag);
386 }
387 break;
388 case 0x0081: /* JPEG image offset */
389 if(at_offset && (PRINT_SECTION))
390 {
391 print_tag_address(VALUE_AT_OFFSET,value_offset,indent,prefix);
392 chpr += printf("# Start of JPEG image from MakerNote");
393 }
394 else if(!at_offset && (PRINT_VALUE))
395 {
396 if(!(PRINT_OFFSET))
397 chpr += printf("@%lu",value_offset);
398 }
399 if((PRINT_SECTION) || (PRINT_SEGMENT))
400 chpr = newline(chpr);
401 marker = read_ushort(inptr,TIFF_MOTOROLA,value_offset);
402 max_offset = process_jpeg_segments(inptr,value_offset,marker,
403 0,summary_entry,fulldirname,
404 prefix,indent+SMALLINDENT);
405 if(at_offset)
406 {
407 if((PRINT_SECTION))
408 {
409 if(max_offset == 0UL)
410 max_offset = filesize;
411 if(max_offset)
412 {
413 if((status = jpeg_status(0)) == JPEG_EARLY_EOI)
414 chpr = newline(chpr);
415 jpeg_status(status);
416 print_tag_address(VALUE_AT_OFFSET,max_offset - 1,indent,"-");
417 chpr += printf("# End of JPEG image from MakerNote");
418 chpr += printf(" length %lu",max_offset - value_offset);
419 }
420 if(!(PRINT_VALUE) && (status == JPEG_NO_ERROR))
421 chpr = newline(chpr);
422 }
423 }
424 print_jpeg_status();
425 if(marker && summary_entry)
426 {
427 /* The new one is on the end of the chain */
428 if((summary_entry = last_summary_entry(summary_entry)))
429 {
430 summary_entry->filesubformat |= FILESUBFMT_MNOTE;
431 summary_entry->datatype = MAKER_IFD;
432 if((summary_entry->compression == JPEG_SOF_3) && (max_offset == 0))
433 summary_entry->length = filesize - value_offset;
434 }
435 }
436 clearerr(inptr);
437 break;
438 default:
439 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,fileoffset_base,
440 fulldirname,prefix,indent,
441 make,model,at_offset);
442 break;
443 }
444 if(fulldirname)
445 free(fulldirname);
446 }
447 setcharsprinted(chpr);
448 }
449
450
451 /* Canon-specific tagnames for makernotes. */
452 /* There is currently only one tagset, but there are (at least) 4 */
453 /* different sets of custom functions. */
454
455 char *
maker_canon_tagname(unsigned short tag,int model)456 maker_canon_tagname(unsigned short tag,int model)
457 {
458 char *tagname = CNULL;
459 int noteversion = 0;
460
461 /* Should have to do this only once, and only for unrecognized */
462 /* models. If the model is recognized (or the user has forced a */
463 /* noteversion) noteversion will already be set. */
464 if(((noteversion = getnoteversion()) == 0))
465 {
466 /* Assume the tagset is correct, but use the generic */
467 /* CustomFunctions routine if required (some models don't */
468 /* have custom functions) */
469 noteversion = 1;
470 setnoteversion(1);
471 }
472
473 switch(noteversion)
474 {
475 case 1:
476 case 2:
477 case 3:
478 case 4:
479 case 5:
480 tagname = maker_canon1_tagname(tag,model);
481 break;
482 default:
483 /* This essentially turns off tagname interpretation; it */
484 /* should happen only if the user has deliberately set a */
485 /* non-existent version (e.g. -1) */
486 break;
487 }
488
489 /* If no model-specific tag is found, check "generic" tags */
490 if(tagname == NULL)
491 {
492 switch(tag)
493 {
494 case 0x0e00: tagname = "PrintIM"; break;
495 default: break;
496 }
497 }
498 return(tagname);
499 }
500
501 char *
maker_canon1_tagname(unsigned short tag,int model)502 maker_canon1_tagname(unsigned short tag,int model)
503 {
504 char *tagname = CNULL;
505
506 switch(tag)
507 {
508 case 0x0001: tagname = "CameraSettings"; break;
509 case 0x0002: tagname = "FocusInfo"; break;
510 case 0x0004: tagname = "ShotInfo"; break;
511 case 0x0006: tagname = "ImageType"; break;
512 case 0x0007: tagname = "FirmwareVersion"; break;
513 case 0x0008: tagname = "ImageNumber"; break;
514 case 0x0009: tagname = "OwnerName"; break;
515 case 0x000a: tagname = "ColorInfoD30*"; break;
516 case 0x000c: tagname = "CameraSerialNo"; break;
517 case 0x000e: tagname = "FileLength"; break;
518 case 0x000f: tagname = "CustomFunctions"; break;
519 case 0x0012: tagname = "PictureInfo"; break;
520 case 0x0081: tagname = "JpegImage"; break;
521 case 0x0090: tagname = "CustomFunctions"; break;
522 case 0x0093: tagname = "FileInfo**"; break; /* exiftool shows wrong type */
523 case 0x00a0: tagname = "ColorInfo**"; break; /* exiftool - wrong # values */
524 case 0x00a9: tagname = "WhiteBalanceTable"; break;
525 case 0x00ae: tagname = "ColorTemperature"; break;
526 case 0x00b6: tagname = "PreviewImageInfo"; break;
527 case 0x00e0: tagname = "SensorInfo"; break;
528 default: break;
529 }
530 setnotetagset(1);
531 return(tagname);
532 }
533
534 /* Report the "meaning" of tag values found directly in a Canon */
535 /* MakerNote IFD entry (not at an offset). */
536
537 /* There are currently no direct entry tags for which the meaning is */
538 /* known, so this routine is null, empty, void. There are observed */
539 /* tags with unknown meaning, so this routine will be necessary. */
540
541 /* I suspect that ImageNumber could be decomposed into a DCF folder */
542 /* number and sequence number), */
543
544 void
canon1_interpret_value(struct ifd_entry * entry_ptr)545 canon1_interpret_value(struct ifd_entry *entry_ptr)
546 {
547 switch(entry_ptr->tag)
548 {
549 default: break;
550 }
551 }
552
553 /* ###%%% FIXIT: none of the routines below honor the PRINT_TAGNAMES */
554 /* or PRINT_VALUE options. */
555
556 /* Interpret the "Camera Settings" tag data from Canon MakerNotes. */
557
558 unsigned long
canon_camera_settings(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent)559 canon_camera_settings(FILE *inptr,unsigned short byteorder,char *tagprefix,
560 unsigned long offset,unsigned long dirlength,int indent)
561 {
562 unsigned long count;
563 unsigned long end_offset;
564 struct fileheader *header = NULL;
565 unsigned short length,value;
566 char *sep;
567 int i;
568 int chpr = 0;
569
570
571 end_offset = offset + dirlength;
572 length = read_ushort(inptr,byteorder,offset);
573 if(PRINT_SECTION)
574 {
575 chpr += printf(" length %lu",dirlength);
576 if(length != dirlength)
577 {
578 chpr = newline(chpr);
579 PUSHCOLOR(RED);
580 print_tag_address(SECTION,offset,indent,"@");
581 chpr += printf("# WARNING: length %u from segment does not match length %lu from directory",
582 length,dirlength);
583 POPCOLOR();
584 }
585 }
586 chpr = newline(chpr);
587 offset += 2;
588 count = (dirlength / sizeof(unsigned short)) - 1;
589
590 if((PRINT_ENTRY))
591 {
592 for(i = 1; i <= count; ++i)
593 {
594 value = read_ushort(inptr,byteorder,offset);
595 print_tag_address(ENTRY,offset,indent,"@");
596 /* tagprefix has already been adjusted according to the */
597 /* setting of PRINT_LONGNAMES. */
598 if((PRINT_TAGINFO))
599 chpr += printf("%s",tagprefix);
600 offset += 2;
601 switch(i)
602 {
603 case 1:
604 if((PRINT_TAGINFO))
605 chpr += printf(".%02d_%-23.23s",i,"MacroMode");
606 if((PRINT_VALUE))
607 {
608 chpr += printf(" = %u",value);
609 print_startvalue();
610 switch(value)
611 {
612 case 1: chpr += printf("macro"); break;
613 case 2: chpr += printf("normal"); break;
614 default: printred("undefined"); break;
615 }
616 print_endvalue();
617 }
618 break;
619 case 2:
620 if((PRINT_TAGINFO))
621 chpr += printf(".%02d_%-23.23s",i,"SelfTimer");
622 if((PRINT_VALUE))
623 {
624 chpr += printf(" = %u",value);
625 print_startvalue();
626 if(value)
627 chpr += printf(".%u sec",value); /* ###%%% ? */
628 else
629 chpr += printf("off");
630 print_endvalue();
631 }
632 break;
633 case 3:
634 if((PRINT_TAGINFO))
635 chpr += printf(".%02d_%-23.23s",i,"Quality");
636 if((PRINT_VALUE))
637 {
638 chpr += printf(" = %u",value);
639 print_startvalue();
640 switch(value)
641 {
642 case 2: chpr += printf("normal"); break;
643 case 3: chpr += printf("fine"); break;
644 case 4: header = read_imageheader(inptr,0);
645 switch(header->probe_magic)
646 {
647 case TIFF_MAGIC:
648 case PROBE_JPEGMAGIC:
649 chpr += printf("Lossless JPEG");
650 break;
651 case PROBE_CIFFMAGIC:
652 default:
653 chpr += printf("RAW");
654 break;
655 }
656 break;
657 case 5: chpr += printf("super fine"); break;
658 default: printred("unknown"); break;
659 }
660 print_endvalue();
661 }
662 break;
663 case 4:
664 if((PRINT_TAGINFO))
665 chpr += printf(".%02d_%-23.23s",i,"FlashMode");
666 if((PRINT_VALUE))
667 {
668 chpr += printf(" = %u",value);
669 print_startvalue();
670 switch(value)
671 {
672 case 0: chpr += printf("flash did not fire"); break;
673 case 1: chpr += printf("auto"); break;
674 case 2: chpr += printf("on"); break;
675 case 3: chpr += printf("redeye"); break;
676 case 4: chpr += printf("slow sync"); break;
677 case 5: chpr += printf("auto + redeye"); break;
678 case 6: chpr += printf("on + redeye"); break;
679 case 16: chpr += printf("external flash"); break;
680 default: printred("undefined"); break;
681 }
682 print_endvalue();
683 }
684 break;
685 case 5:
686 if((PRINT_TAGINFO))
687 chpr += printf(".%02d_%-23.23s",i,"ContinuousMode");
688 if((PRINT_VALUE))
689 {
690 chpr += printf(" = %u",value);
691 print_startvalue();
692 switch(value)
693 {
694 case 0: chpr += printf("single or timer"); break;
695 case 1: chpr += printf("continuous"); break;
696 default: printred("undefined"); break;
697 }
698 print_endvalue();
699 }
700 break;
701 case 6:
702 if((PRINT_TAGINFO))
703 chpr += printf(".%02d_%-23.23s",i,"Unknown");
704 if((PRINT_VALUE))
705 chpr += printf(" = %u",value);
706 break;
707 case 7:
708 if((PRINT_TAGINFO))
709 chpr += printf(".%02d_%-23.23s",i,"FocusMode");
710 if((PRINT_VALUE))
711 {
712 chpr += printf(" = %u",value);
713 print_startvalue();
714 switch(value)
715 {
716 case 0: chpr += printf("One Shot AF"); break;
717 case 1: chpr += printf("AI Servo AF"); break;
718 case 2: chpr += printf("AI Focus AF"); break;
719 case 3: chpr += printf("Manual Focus"); break;
720 case 4: chpr += printf("single"); break;
721 case 5: chpr += printf("Continuous"); break;
722 default: printred("undefined"); break;
723 }
724 print_endvalue();
725 }
726 break;
727 case 8:
728 if((PRINT_TAGINFO))
729 chpr += printf(".%02d_%-23.23s",i,"Unknown");
730 if((PRINT_VALUE))
731 chpr += printf(" = %u",value);
732 break;
733 case 9:
734 if((PRINT_TAGINFO))
735 chpr += printf(".%02d_%-23.23s",i,"Unknown");
736 if((PRINT_VALUE))
737 chpr += printf(" = %u",value);
738 break;
739 case 10:
740 if((PRINT_TAGINFO))
741 chpr += printf(".%02d_%-23.23s",i,"ImageSize");
742 if((PRINT_VALUE))
743 {
744 chpr += printf(" = %u",value);
745 print_startvalue();
746 switch(value)
747 {
748 case 0: chpr += printf("Large"); break;
749 case 1: chpr += printf("Medium"); break;
750 case 2: chpr += printf("Small"); break;
751 default: printred("undefined"); break;
752 }
753 print_endvalue();
754 }
755 break;
756 case 11:
757 if((PRINT_TAGINFO))
758 chpr += printf(".%02d_%-23.23s",i,"EasyShootMode");
759 if((PRINT_VALUE))
760 {
761 chpr += printf(" = %u",value);
762 print_startvalue();
763 switch(value)
764 {
765 case 0: chpr += printf("Full Auto"); break;
766 case 1: chpr += printf("Manual"); break;
767 case 2: chpr += printf("Landscape"); break;
768 case 3: chpr += printf("Fast Shutter"); break;
769 case 4: chpr += printf("Slow Shutter"); break;
770 case 5: chpr += printf("Night"); break;
771 case 6: chpr += printf("B & W"); break;
772 case 7: chpr += printf("Sepia"); break;
773 case 8: chpr += printf("Portrait"); break;
774 case 9: chpr += printf("Sports"); break;
775 case 10: chpr += printf("Macro/CloseUp"); break;
776 case 11: chpr += printf("Pan Focus"); break;
777 default: printred("undefined"); break;
778 }
779 print_endvalue();
780 }
781 break;
782 case 12:
783 if((PRINT_TAGINFO))
784 chpr += printf(".%02d_%-23.23s",i,"DigitalZoom");
785 if((PRINT_VALUE))
786 {
787 chpr += printf(" = %u",value);
788 print_startvalue();
789 switch(value)
790 {
791 case 0: chpr += printf("none"); break;
792 case 1: chpr += printf("2x"); break;
793 case 2: chpr += printf("4x"); break;
794 default: printred("(2 * ZoomedResBase) / ZoomedResValue**"); break;
795 }
796 print_endvalue();
797 }
798 break;
799 case 13:
800 if((PRINT_TAGINFO))
801 chpr += printf(".%02d_%-23.23s",i,"Contrast");
802 if((PRINT_VALUE))
803 {
804 chpr += printf(" = %u",value);
805 print_startvalue();
806 switch(value)
807 {
808 case 0: chpr += printf("Normal"); break;
809 case 1: chpr += printf("High"); break;
810 case 0xffff: chpr += printf("Low"); break;
811 default: printred("undefined"); break;
812 }
813 print_endvalue();
814 }
815 break;
816 case 14:
817 if((PRINT_TAGINFO))
818 chpr += printf(".%02d_%-23.23s",i,"Saturation");
819 if((PRINT_VALUE))
820 {
821 chpr += printf(" = %u",value);
822 print_startvalue();
823 switch(value)
824 {
825 case 0: chpr += printf("Normal"); break;
826 case 1: chpr += printf("High"); break;
827 case 0xffff: chpr += printf("Low"); break;
828 default: printred("undefined"); break;
829 }
830 print_endvalue();
831 }
832 break;
833 case 15:
834 if((PRINT_TAGINFO))
835 chpr += printf(".%02d_%-23.23s",i,"Sharpness");
836 if((PRINT_VALUE))
837 {
838 chpr += printf(" = %u",value);
839 print_startvalue();
840 switch(value)
841 {
842 case 0: chpr += printf("Normal"); break;
843 case 1: chpr += printf("High"); break;
844 case 0xffff: chpr += printf("Low"); break;
845 default: printred("undefined"); break;
846 }
847 print_endvalue();
848 }
849 break;
850 case 16:
851 if((PRINT_TAGINFO))
852 chpr += printf(".%02d_%-23.23s",i,"ISO");
853 if((PRINT_VALUE))
854 {
855 chpr += printf(" = %#x/%u",value,value);
856 print_startvalue();
857 switch(value)
858 {
859 case 0: chpr += printf("Use Exif ISOSpeedRating"); break;
860 case 15: chpr += printf("Auto"); break;
861 case 16: chpr += printf("50"); break;
862 case 17: chpr += printf("100"); break;
863 case 18: chpr += printf("200"); break;
864 case 19: chpr += printf("400"); break;
865 default: printred("undefined"); break;
866 }
867 print_endvalue();
868 }
869 break;
870 case 17:
871 if((PRINT_TAGINFO))
872 chpr += printf(".%02d_%-23.23s",i,"MeteringMode");
873 if((PRINT_VALUE))
874 {
875 chpr += printf(" = %u",value);
876 print_startvalue();
877 switch(value)
878 {
879 case 0: chpr += printf("Default"); break;
880 case 1: chpr += printf("Spot"); break;
881 case 3: chpr += printf("Evaluative"); break;
882 case 4: chpr += printf("Partial"); break;
883 case 5: chpr += printf("Center-weighted"); break;
884 default: printred("undefined"); break;
885 }
886 print_endvalue();
887 }
888 break;
889 case 18:
890 if((PRINT_TAGINFO))
891 chpr += printf(".%02d_%-23.23s",i,"FocusType");
892 if((PRINT_VALUE))
893 {
894 chpr += printf(" = %u",value);
895 print_startvalue();
896 switch(value)
897 {
898 case 0: chpr += printf("Manual"); break;
899 case 1: chpr += printf("Auto1"); break;
900 case 2: chpr += printf("Auto2"); break;
901 case 3: chpr += printf("Macro"); break;
902 case 7: chpr += printf("Infinity"); break;
903 case 8: chpr += printf("Locked (pan mode)"); break;
904 default: printred("undefined"); break;
905 }
906 print_endvalue();
907 }
908 break;
909 case 19:
910 if((PRINT_TAGINFO))
911 chpr += printf(".%02d_%-23.23s",i,"AFPositionSelected");
912 if((PRINT_VALUE))
913 {
914 chpr += printf(" = %#x",value);
915 print_startvalue();
916 switch(value)
917 {
918 case 0x2005: chpr += printf("Manual AF Point select"); break;
919 case 0x3000: chpr += printf("None (manual focus)"); break;
920 case 0x3001: chpr += printf("Auto-selected"); break;
921 case 0x3002: chpr += printf("Right"); break;
922 case 0x3003: chpr += printf("Center"); break;
923 case 0x3004: chpr += printf("Left"); break;
924 case 0x4001: chpr += printf("Auto AF Point select"); break;
925 default: printred("undefined");
926 }
927 print_endvalue();
928 }
929 break;
930 case 20:
931 if((PRINT_TAGINFO))
932 chpr += printf(".%02d_%-23.23s",i,"ExposureMode");
933 if((PRINT_VALUE))
934 {
935 chpr += printf(" = %u",value);
936 print_startvalue();
937 switch(value)
938 {
939 case 0: chpr += printf("Easy Shooting"); break;
940 case 1: chpr += printf("Program AE"); break;
941 case 2: chpr += printf("Shutter priority AE"); break;
942 case 3: chpr += printf("Aperture priority AE"); break;
943 case 4: chpr += printf("Manual"); break;
944 case 5: chpr += printf("Depth of field AE"); break;
945 default: printred("undefined"); break;
946 }
947 print_endvalue();
948 }
949 break;
950 case 21:
951 if((PRINT_TAGINFO))
952 chpr += printf(".%02d_%-23.23s",i,"Unknown");
953 if((PRINT_VALUE))
954 chpr += printf(" = %u",value);
955 break;
956 case 22:
957 if((PRINT_TAGINFO))
958 chpr += printf(".%02d_%-23.23s",i,"LensType");
959 if((PRINT_VALUE))
960 chpr += printf(" = %u",value);
961 /* ###%% Phil Harvey gives a massive Lens type */
962 /* table */
963 break;
964 case 23:
965 if((PRINT_TAGINFO))
966 chpr += printf(".%02d_%-23.23s",i,"FocalLength_long");
967 if((PRINT_VALUE))
968 chpr += printf(" = %u units",value);
969 break;
970 case 24:
971 if((PRINT_TAGINFO))
972 chpr += printf(".%02d_%-23.23s",i,"FocalLength_short");
973 if((PRINT_VALUE))
974 chpr += printf(" = %u units",value);
975 break;
976 case 25:
977 if((PRINT_TAGINFO))
978 chpr += printf(".%02d_%-23.23s",i,"FocalUnits*");
979 if((PRINT_VALUE))
980 {
981 if(value > 1)
982 chpr += printf(" = %u units per mm*",value);
983 else
984 chpr += printf(" = %u unit per mm",value);
985 }
986 break;
987 case 26:
988 if((PRINT_TAGINFO))
989 chpr += printf(".%02d_%-23.23s",i,"Unknown");
990 if((PRINT_VALUE))
991 chpr += printf(" = %u",value);
992 break;
993 case 27:
994 if((PRINT_TAGINFO))
995 chpr += printf(".%02d_%-23.23s",i,"Unknown");
996 if((PRINT_VALUE))
997 chpr += printf(" = %u",value);
998 break;
999 case 28:
1000 if((PRINT_TAGINFO))
1001 chpr += printf(".%02d_%-23.23s",i,"FlashActivity");
1002 if((PRINT_VALUE))
1003 {
1004 chpr += printf(" = %#x",value);
1005 print_startvalue();
1006 switch(value)
1007 {
1008 case 0: chpr += printf("did not fire"); break;
1009 case 1: chpr += printf("fired"); break;
1010 default: printred("undefined"); break;
1011 }
1012 print_endvalue();
1013 }
1014 break;
1015 case 29:
1016 if((PRINT_TAGINFO))
1017 chpr += printf(".%02d_%-23.23s",i,"FlashDetails");
1018 if((PRINT_VALUE))
1019 {
1020 chpr += printf(" = %#x",value);
1021 print_startvalue();
1022 sep = "";
1023 if(value & 0x0e)
1024 {
1025 chpr += printf("%sexternal E-TTL",sep);
1026 sep = ",";
1027 }
1028 if(value & 0x0d)
1029 {
1030 chpr += printf("%sInternal flash**",sep);
1031 sep = ",";
1032 }
1033 if(value & 0x0b)
1034 {
1035 chpr += printf("%sFP sync used",sep);
1036 sep = ",";
1037 }
1038 if(value & 0x07)
1039 {
1040 chpr += printf("%s2nd-curtain sync used",sep);
1041 sep = ",";
1042 }
1043 if(value & 0x04)
1044 {
1045 chpr += printf("%sFP sync enabled",sep);
1046 sep = ",";
1047 }
1048 if(value & 0x03)
1049 {
1050 chpr += printf("%sOn",sep);
1051 sep = ",";
1052 }
1053 print_endvalue();
1054 }
1055 break;
1056 case 30:
1057 if((PRINT_TAGINFO))
1058 chpr += printf(".%02d_%-23.23s",i,"Unknown");
1059 if((PRINT_VALUE))
1060 chpr += printf(" = %u",value);
1061 break;
1062 case 31:
1063 if((PRINT_TAGINFO))
1064 chpr += printf(".%02d_%-23.23s",i,"Unknown");
1065 if((PRINT_VALUE))
1066 chpr += printf(" = %u",value);
1067 break;
1068 case 32:
1069 if((PRINT_TAGINFO))
1070 chpr += printf(".%02d_%-23.23s",i,"FocusMode");
1071 if((PRINT_VALUE))
1072 {
1073 chpr += printf(" = %u",value);
1074 print_startvalue();
1075 switch(value)
1076 {
1077 case 0: chpr += printf("Single"); break;
1078 case 1: chpr += printf("Continuous"); break;
1079 default: printred("undefined"); break;
1080 }
1081 print_endvalue();
1082 }
1083 break;
1084 case 36:
1085 if((PRINT_TAGINFO))
1086 chpr += printf(".%02d_%-23.23s",i,"ZoomedResValue**");
1087 if((PRINT_VALUE))
1088 chpr += printf(" = %u",value);
1089 break;
1090 case 37:
1091 if((PRINT_TAGINFO))
1092 chpr += printf(".%02d_%-23.23s",i,"ZoomedResBase**");
1093 if((PRINT_VALUE))
1094 chpr += printf(" = %u",value);
1095 break;
1096 case 42:
1097 if((PRINT_TAGINFO))
1098 chpr += printf(".%02d_%-23.23s",i,"ColorTone**");
1099 if((PRINT_VALUE))
1100 chpr += printf(" = %#x/%u",value,value);
1101 break;
1102 default:
1103 if((PRINT_TAGINFO))
1104 chpr += printf(".%02d_%-23.23s",i,"undefined");
1105 if((PRINT_VALUE))
1106 chpr += printf(" = %#x/%u",value,value);
1107 break;
1108 }
1109 chpr = newline(chpr);
1110 }
1111 }
1112 setcharsprinted(chpr);
1113 return(end_offset);
1114 }
1115
1116 /* Interpret the "ShotInfo" settings in a Cannon MakerNote or */
1117 /* CIFF file */
1118
1119 unsigned long
canon_shotinfo(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent)1120 canon_shotinfo(FILE *inptr,unsigned short byteorder,char *tagprefix,
1121 unsigned long offset,unsigned long dirlength,int indent)
1122 {
1123 unsigned long count;
1124 unsigned long end_offset;
1125 unsigned short length,value;
1126 int i;
1127 int chpr = 0;
1128
1129 end_offset = offset + dirlength;
1130 length = read_ushort(inptr,byteorder,offset);
1131 if(PRINT_SECTION)
1132 {
1133 chpr += printf(" length %lu",dirlength);
1134 if(length != dirlength)
1135 {
1136 chpr = newline(chpr);
1137 PUSHCOLOR(RED);
1138 print_tag_address(SECTION,offset,indent,"@");
1139 chpr += printf("# WARNING: length %u from segment does not match length %lu from directory",
1140 length,dirlength);
1141 POPCOLOR();
1142 }
1143 }
1144 chpr = newline(chpr);
1145
1146 if((PRINT_ENTRY))
1147 {
1148 offset += 2;
1149 count = (dirlength / sizeof(unsigned short)) - 1;
1150
1151 for(i = 1; i <= count; ++i)
1152 {
1153 value = read_ushort(inptr,byteorder,offset);
1154 print_tag_address(ENTRY,offset,indent,"@");
1155 if((PRINT_TAGINFO))
1156 chpr += printf("%s",tagprefix);
1157 offset += 2;
1158 switch(i)
1159 {
1160 case 1:
1161 if((PRINT_TAGINFO))
1162 chpr += printf(".%02d_%-28.28s",i,"Unknown");
1163 if((PRINT_VALUE))
1164 chpr += printf(" = %#x%u",value,value);
1165 break;
1166 case 2:
1167 if((PRINT_TAGINFO))
1168 chpr += printf(".%02d_%-28.28s",i,"ISO");
1169 if((PRINT_VALUE))
1170 chpr += printf(" = %u",value);
1171 break;
1172 case 3:
1173 if((PRINT_TAGINFO))
1174 chpr += printf(".%02d_%-28.28s",i,"Unknown");
1175 if((PRINT_VALUE))
1176 chpr += printf(" = %#x%u",value,value);
1177 break;
1178 case 4:
1179 if((PRINT_TAGINFO))
1180 chpr += printf(".%02d_%-28.28s",i,"Unknown");
1181 if((PRINT_VALUE))
1182 chpr += printf(" = %#x%u",value,value);
1183 break;
1184 case 5:
1185 if((PRINT_TAGINFO))
1186 chpr += printf(".%02d_%-28.28s",i,"Unknown");
1187 if((PRINT_VALUE))
1188 chpr += printf(" = %#x%u",value,value);
1189 break;
1190 case 6:
1191 if((PRINT_TAGINFO))
1192 chpr += printf(".%02d_%-28.28s",i,"ExposureCompensation**");
1193 if((PRINT_VALUE))
1194 chpr += printf(" = %u",value);
1195 break;
1196 case 7:
1197 if((PRINT_TAGINFO))
1198 chpr += printf(".%02d_%-28.28s",i,"WhiteBalance");
1199 if((PRINT_VALUE))
1200 {
1201 chpr += printf(" = %u",value);
1202 print_startvalue();
1203 switch(value)
1204 {
1205 case 0: chpr += printf("Auto"); break;
1206 case 1: chpr += printf("Sunny"); break;
1207 case 2: chpr += printf("Cloudy"); break;
1208 case 3: chpr += printf("Tungsten"); break;
1209 case 4: chpr += printf("Fluorescent"); break;
1210 case 5: chpr += printf("Flash"); break;
1211 case 6: chpr += printf("Custom"); break;
1212 default: printred("undefined"); break;
1213 }
1214 print_endvalue();
1215 }
1216 break;
1217 case 8:
1218 if((PRINT_TAGINFO))
1219 chpr += printf(".%02d_%-28.28s",i,"Unknown");
1220 if((PRINT_VALUE))
1221 chpr += printf(" = %#x%u",value,value);
1222 break;
1223 case 9:
1224 if((PRINT_TAGINFO))
1225 chpr += printf(".%02d_%-28.28s",i,"SequenceNumber");
1226 if((PRINT_VALUE))
1227 chpr += printf(" = %u",value);
1228 break;
1229 case 10:
1230 if((PRINT_TAGINFO))
1231 chpr += printf(".%02d_%-28.28s",i,"Unknown");
1232 if((PRINT_VALUE))
1233 chpr += printf(" = %#x%u",value,value);
1234 break;
1235 case 11:
1236 if((PRINT_TAGINFO))
1237 chpr += printf(".%02d_%-28.28s",i,"Unknown");
1238 if((PRINT_VALUE))
1239 chpr += printf(" = %#x%u",value,value);
1240 break;
1241 case 12:
1242 if((PRINT_TAGINFO))
1243 chpr += printf(".%02d_%-28.28s",i,"Unknown");
1244 if((PRINT_VALUE))
1245 chpr += printf(" = %#x%u",value,value);
1246 break;
1247 case 13:
1248 if((PRINT_TAGINFO))
1249 chpr += printf(".%02d_%-28.28s",i,"Unknown");
1250 if((PRINT_VALUE))
1251 chpr += printf(" = %#x%u",value,value);
1252 break;
1253 case 14:
1254 if((PRINT_TAGINFO))
1255 chpr += printf(".%02d_%-28.28s",i,"AFPositionUsed");
1256 if((PRINT_VALUE))
1257 {
1258 chpr += printf(" = %#x",value);
1259 print_startvalue();
1260 if(value & 0xf000)
1261 {
1262 switch(value & 0x7)
1263 {
1264 case 0: chpr += printf("none (MF)"); break;
1265 case 1: chpr += printf("right"); break;
1266 case 2: chpr += printf("center"); break;
1267 case 3: chpr += printf("center+right"); break;
1268 case 4: chpr += printf("left"); break;
1269 case 5: chpr += printf("left+right"); break;
1270 case 6: chpr += printf("left+center"); break;
1271 case 7: chpr += printf("all"); break;
1272 default: printred("undefined"); break;
1273 }
1274 chpr += printf(" of %d points",(value & 0xf000) >> 12);
1275 }
1276 else
1277 chpr += printf("MF");
1278 print_endvalue();
1279 }
1280 break;
1281 case 15:
1282 if((PRINT_TAGINFO))
1283 chpr += printf(".%02d_%-28.28s",i,"FlashBias");
1284 if((PRINT_VALUE))
1285 {
1286 chpr += printf(" = %#x",value);
1287 print_startvalue();
1288 switch(value)
1289 {
1290 case 0xffc0: chpr += printf("-2 EV"); break;
1291 case 0xffcc: chpr += printf("-1.67 EV"); break;
1292 case 0xffd0: chpr += printf("-1.50 EV"); break;
1293 case 0xffd4: chpr += printf("-1.33 EV"); break;
1294 case 0xffe0: chpr += printf("-1 EV"); break;
1295 case 0xffec: chpr += printf("-0.67 EV"); break;
1296 case 0xfff0: chpr += printf("-0.50 EV"); break;
1297 case 0xfff4: chpr += printf("-0.33 EV"); break;
1298 case 0x0000: chpr += printf("0 EV"); break;
1299 case 0x000c: chpr += printf("+0.33 EV"); break;
1300 case 0x0010: chpr += printf("+0.50 EV"); break;
1301 case 0x0014: chpr += printf("+0.67 EV"); break;
1302 case 0x0020: chpr += printf("+1 EV"); break;
1303 case 0x002c: chpr += printf("+1.33 EV"); break;
1304 case 0x0030: chpr += printf("+1.50 EV"); break;
1305 case 0x0034: chpr += printf("+1.67 EV"); break;
1306 case 0x0040: chpr += printf("+2 EV"); break;
1307 default: printred("undefined"); break;
1308 }
1309 print_endvalue();
1310 }
1311 break;
1312 case 16:
1313 if((PRINT_TAGINFO))
1314 chpr += printf(".%02d_%-28.28s",i,"AutoExposureBracketing**");
1315 if((PRINT_VALUE))
1316 chpr += printf(" = %u",value);
1317 break;
1318 case 17:
1319 if((PRINT_TAGINFO))
1320 chpr += printf(".%02d_%-28.28s",i,"AEBracketValue**");
1321 if((PRINT_VALUE))
1322 chpr += printf(" = %u",value);
1323 break;
1324 case 18:
1325 if((PRINT_TAGINFO))
1326 chpr += printf(".%02d_%-28.28s",i,"Unknown");
1327 if((PRINT_VALUE))
1328 chpr += printf(" = %#x%u",value,value);
1329 break;
1330 case 19:
1331 if((PRINT_TAGINFO))
1332 chpr += printf(".%02d_%-28.28s",i,"FocusDistanceMax**");
1333 if((PRINT_VALUE))
1334 chpr += printf(" = %u mm",value);
1335 break;
1336 case 20:
1337 if((PRINT_TAGINFO))
1338 chpr += printf(".%02d_%-28.28s",i,"FocusDistanceMin**");
1339 if((PRINT_VALUE))
1340 chpr += printf(" = %u mm",value);
1341 break;
1342 case 21:
1343 if((PRINT_TAGINFO))
1344 chpr += printf(".%02d_%-28.28s",i,"ApertureValue**");
1345 if((PRINT_VALUE))
1346 chpr += printf(" = %u",value);
1347 break;
1348 case 22:
1349 if((PRINT_TAGINFO))
1350 chpr += printf(".%02d_%-28.28s",i,"ExposureTime**");
1351 if((PRINT_VALUE))
1352 chpr += printf(" = %u",value);
1353 break;
1354 case 24:
1355 if((PRINT_TAGINFO))
1356 chpr += printf(".%02d_%-28.28s",i,"BulbDuration**");
1357 if((PRINT_VALUE))
1358 chpr += printf(" = %u",value);
1359 break;
1360 case 27:
1361 if((PRINT_TAGINFO))
1362 chpr += printf(".%02d_%-28.28s",i,"AutoRotate**");
1363 if((PRINT_VALUE))
1364 chpr += printf(" = %u",value);
1365 break;
1366 case 29:
1367 if((PRINT_TAGINFO))
1368 chpr += printf(".%02d_%-28.28s",i,"SelfTimer2**");
1369 if((PRINT_VALUE))
1370 chpr += printf(" = %u",value);
1371 break;
1372 default:
1373 if((PRINT_TAGINFO))
1374 chpr += printf(".%02d_%-28.28s",i,"Undefined");
1375 if((PRINT_VALUE))
1376 chpr += printf(" = %#x%u",value,value);
1377 break;
1378 }
1379 chpr = newline(chpr);
1380 }
1381 }
1382 setcharsprinted(chpr);
1383 return(end_offset);
1384 }
1385
1386 /* Interpret Canon Custom Functions */
1387 unsigned long
canon_customfunctions(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int model,int indent)1388 canon_customfunctions(FILE *inptr,unsigned short byteorder,
1389 char *tagprefix,unsigned long offset,
1390 unsigned long dirlength,int model,int indent)
1391 {
1392 unsigned long max_offset;
1393 int noteversion = 0;
1394
1395 noteversion = getnoteversion();
1396
1397 switch(noteversion)
1398 {
1399 case 5: /* 20 entries (or 21,22) */
1400 max_offset = canon_customfunctions1D(inptr,byteorder,tagprefix,offset,dirlength,indent);
1401 break;
1402 case 4: /* 18 entries */
1403 max_offset = canon_customfunctions20D(inptr,byteorder,tagprefix,offset,dirlength,indent);
1404 break;
1405 case 3: /* 17 entries starting at 1*/
1406 max_offset = canon_customfunctions10D(inptr,byteorder,tagprefix,offset,dirlength,indent);
1407 break;
1408 case 2: /* 16 entries */
1409 max_offset = canon_customfunctionsD30(inptr,byteorder,tagprefix,offset,dirlength,indent);
1410 break;
1411 case 1: /* unknown customfuctions */
1412 default:
1413 max_offset = canon_customfunctions_unk(inptr,byteorder,tagprefix,offset,dirlength,indent);
1414 break;
1415 }
1416 return(max_offset);
1417 }
1418
1419 /* A "generic" version of customfunctions; just prints the data, with */
1420 /* no interpretation. */
1421
1422 unsigned long
canon_customfunctions_unk(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent)1423 canon_customfunctions_unk(FILE *inptr,unsigned short byteorder,char *tagprefix,
1424 unsigned long offset,unsigned long dirlength,int indent)
1425 {
1426 unsigned long count;
1427 unsigned long end_offset;
1428 unsigned short length,value;
1429 int i,cfn,cfv;
1430 int chpr = 0;
1431
1432 length = read_ushort(inptr,byteorder,offset);
1433 end_offset = offset + dirlength;
1434 if(PRINT_SECTION)
1435 {
1436 chpr += printf(" length %lu",dirlength);
1437 if(length != dirlength)
1438 {
1439 chpr = newline(chpr);
1440 PUSHCOLOR(RED);
1441 print_tag_address(SECTION,offset,indent,"@");
1442 chpr += printf("# WARNING: length %u from segment does not match length %lu from directory",
1443 length,dirlength);
1444 POPCOLOR();
1445 }
1446 }
1447 chpr = newline(chpr);
1448
1449 if((PRINT_ENTRY))
1450 {
1451 offset += 2;
1452 count = (dirlength / sizeof(unsigned short)) - 1;
1453 for(i = 0; i < count; ++i)
1454 {
1455 value = read_ushort(inptr,byteorder,offset);
1456 print_tag_address(ENTRY,offset,indent,"@");
1457 chpr += printf("%s",tagprefix);
1458 offset += 2;
1459 cfn = (value & 0xff00) >> 8;
1460 cfv = value & 0xff;
1461 if(PRINT_SECTION)
1462 chpr += printf("Unk.%02d: = %#x/%u",cfn,cfv,cfv);
1463 else
1464 chpr += printf("Unk.%02d = %#x/%u",cfn,cfv,cfv);
1465 chpr = newline(chpr);
1466 }
1467 }
1468 setcharsprinted(chpr);
1469 return(end_offset);
1470 }
1471
1472 /* CustomFunctions for Canon D30 */
1473
1474 unsigned long
canon_customfunctionsD30(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent)1475 canon_customfunctionsD30(FILE *inptr,unsigned short byteorder,char *tagprefix,
1476 unsigned long offset,unsigned long dirlength,int indent)
1477 {
1478 unsigned long count;
1479 unsigned long end_offset;
1480 unsigned short length,value;
1481 int i,cfn,cfv;
1482 int chpr = 0;
1483
1484 length = read_ushort(inptr,byteorder,offset);
1485 end_offset = offset + dirlength;
1486 if(PRINT_SECTION)
1487 {
1488 chpr += printf(" length %lu",dirlength);
1489 if(length != dirlength)
1490 {
1491 chpr = newline(chpr);
1492 PUSHCOLOR(RED);
1493 print_tag_address(SECTION,offset,indent,"@");
1494 chpr += printf("# WARNING: length %u from segment does not match length %lu from directory",
1495 length,dirlength);
1496 POPCOLOR();
1497 }
1498 }
1499 chpr = newline(chpr);
1500
1501 if((PRINT_ENTRY))
1502 {
1503 offset += 2;
1504 count = (dirlength / sizeof(unsigned short)) - 1;
1505 for(i = 0; i < count; ++i)
1506 {
1507 value = read_ushort(inptr,byteorder,offset);
1508 print_tag_address(ENTRY,offset,indent,"@");
1509 if((PRINT_TAGINFO))
1510 chpr += printf("%s",tagprefix);
1511 offset += 2;
1512 cfn = (value & 0xff00) >> 8;
1513 cfv = value & 0xff;
1514 switch(cfn)
1515 {
1516 case 1:
1517 if((PRINT_TAGINFO))
1518 chpr += printf("D30.%02d:%-30.30s",cfn,"LongExposureNoiseReduction");
1519 if((PRINT_VALUE))
1520 {
1521 chpr += printf(" = %u",cfv);
1522 print_startvalue();
1523 switch(cfv)
1524 {
1525 case 0: chpr += printf("Off"); break;
1526 case 1: chpr += printf("On"); break;
1527 default: printred("undefined"); break;
1528 }
1529 print_endvalue();
1530 }
1531 break;
1532 case 2:
1533 if((PRINT_TAGINFO))
1534 chpr += printf("D30.%02d_%-30.30s",cfn,"ShutterAElockButtons");
1535 if((PRINT_VALUE))
1536 {
1537 chpr += printf(" = %u",cfv);
1538 print_startvalue();
1539 switch(cfv)
1540 {
1541 case 0: chpr += printf("AF/AE lock"); break;
1542 case 1: chpr += printf("AE lock/AF"); break;
1543 case 2: chpr += printf("AF/AF lock"); break;
1544 case 3: chpr += printf("AE+release/AE+AF"); break;
1545 default: printred("undefined"); break;
1546 }
1547 print_endvalue();
1548 }
1549 break;
1550 case 3:
1551 if((PRINT_TAGINFO))
1552 chpr += printf("D30.%02d_%-30.30s",cfn,"MirrorLockup");
1553 if((PRINT_VALUE))
1554 {
1555 chpr += printf(" = %u",cfv);
1556 print_startvalue();
1557 switch(cfv)
1558 {
1559 case 0: chpr += printf("Disabled"); break;
1560 case 1: chpr += printf("Enabled"); break;
1561 default: printred("undefined"); break;
1562 }
1563 print_endvalue();
1564 }
1565 break;
1566 case 4:
1567 if((PRINT_TAGINFO))
1568 chpr += printf("D30.%02d_%-30.30s",cfn,"TvAvAndExposureLevel");
1569 if((PRINT_VALUE))
1570 {
1571 chpr += printf(" = %u",cfv);
1572 print_startvalue();
1573 switch(cfv)
1574 {
1575 case 0: chpr += printf("1/2 stop"); break;
1576 case 1: chpr += printf("1/3 stop"); break;
1577 default: printred("undefined"); break;
1578 }
1579 print_endvalue();
1580 }
1581 break;
1582 case 5:
1583 if((PRINT_TAGINFO))
1584 chpr += printf("D30.%02d_%-30.30s",cfn,"AFAssistLight");
1585 if((PRINT_VALUE))
1586 {
1587 chpr += printf(" = %u",cfv);
1588 print_startvalue();
1589 switch(cfv)
1590 {
1591 case 0: chpr += printf("On (auto)"); break;
1592 case 1: chpr += printf("Off"); break;
1593 default: printred("undefined"); break;
1594 }
1595 print_endvalue();
1596 }
1597 break;
1598 case 6:
1599 if((PRINT_TAGINFO))
1600 chpr += printf("D30.%02d_%-30.30s",cfn,"FlashSyncSpeedAv");
1601 if((PRINT_VALUE))
1602 {
1603 chpr += printf(" = %u",cfv);
1604 print_startvalue();
1605 switch(cfv)
1606 {
1607 case 0: chpr += printf("Auto"); break;
1608 case 1: chpr += printf("D30/200 (fixed)"); break;
1609 default: printred("undefined"); break;
1610 }
1611 print_endvalue();
1612 }
1613 break;
1614 case 7:
1615 if((PRINT_TAGINFO))
1616 chpr += printf("D30.%02d_%-30.30s",cfn,"AEBSequenceAutoCancellation");
1617 if((PRINT_VALUE))
1618 {
1619 chpr += printf(" = %u",cfv);
1620 print_startvalue();
1621 switch(cfv)
1622 {
1623 case 0: chpr += printf("0,-,+/Enabled"); break;
1624 case 1: chpr += printf("0,-,+/Disabled"); break;
1625 case 2: chpr += printf("-,0,+/Enabled"); break;
1626 case 3: chpr += printf("-,0,+/Disabled"); break;
1627 default: printred("undefined"); break;
1628 }
1629 print_endvalue();
1630 }
1631 break;
1632 case 8:
1633 if((PRINT_TAGINFO))
1634 chpr += printf("D30.%02d_%-30.30s",cfn,"ShutterCurtainSync");
1635 if((PRINT_VALUE))
1636 {
1637 chpr += printf(" = %u",cfv);
1638 print_startvalue();
1639 switch(cfv)
1640 {
1641 case 0: chpr += printf("D30-curtain sync"); break;
1642 case 1: chpr += printf("2nd-curtain sync"); break;
1643 default: printred("undefined"); break;
1644 }
1645 print_endvalue();
1646 }
1647 break;
1648 case 9:
1649 if((PRINT_TAGINFO))
1650 chpr += printf("D30.%02d_%-30.30s",cfn,"LensAFStopButtonFnSwitch");
1651 if((PRINT_VALUE))
1652 {
1653 chpr += printf(" = %u",cfv);
1654 print_startvalue();
1655 switch(cfv)
1656 {
1657 case 0: chpr += printf("AF Stop"); break;
1658 case 1: chpr += printf("Operate AF"); break;
1659 case 2: chpr += printf("Lock AE and start timer"); break;
1660 default: printred("undefined"); break;
1661 }
1662 print_endvalue();
1663 }
1664 break;
1665 case 10:
1666 if((PRINT_TAGINFO))
1667 chpr += printf("D30.%02d_%-30.30s",cfn,"AutoReductionOfFillFlash");
1668 if((PRINT_VALUE))
1669 {
1670 chpr += printf(" = %u",cfv);
1671 print_startvalue();
1672 switch(cfv)
1673 {
1674 case 0: chpr += printf("Enabled"); break;
1675 case 1: chpr += printf("Disabled"); break;
1676 default: printred("undefined"); break;
1677 }
1678 print_endvalue();
1679 }
1680 break;
1681 case 11:
1682 if((PRINT_TAGINFO))
1683 chpr += printf("D30.%02d_%-30.30s",cfn,"MenuButtonReturnPosition");
1684 if((PRINT_VALUE))
1685 {
1686 chpr += printf(" = %u",cfv);
1687 print_startvalue();
1688 switch(cfv)
1689 {
1690 case 0: chpr += printf("Top"); break;
1691 case 1: chpr += printf("Previous (volatile)"); break;
1692 case 2: chpr += printf("Previous"); break;
1693 default: printred("undefined"); break;
1694 }
1695 print_endvalue();
1696 }
1697 break;
1698 case 12:
1699 if((PRINT_TAGINFO))
1700 chpr += printf("D30.%02d_%-30.30s",cfn,"SETButtonFuncWhenShooting");
1701 if((PRINT_VALUE))
1702 {
1703 chpr += printf(" = %u",cfv);
1704 print_startvalue();
1705 switch(cfv)
1706 {
1707 case 0: chpr += printf("Not assigned"); break;
1708 case 1: chpr += printf("Change quality"); break;
1709 case 2: chpr += printf("Change ISO speed"); break;
1710 case 3: chpr += printf("PreviouSelect parameters"); break;
1711 default: printred("undefined"); break;
1712 }
1713 print_endvalue();
1714 }
1715 break;
1716 case 13:
1717 if((PRINT_TAGINFO))
1718 chpr += printf("D30.%02d_%-30.30s",cfn,"SensorCleaning");
1719 if((PRINT_VALUE))
1720 {
1721 chpr += printf(" = %u",cfv);
1722 print_startvalue();
1723 switch(cfv)
1724 {
1725 case 0: chpr += printf("Disabled"); break;
1726 case 1: chpr += printf("Enabled"); break;
1727 default: printred("undefined"); break;
1728 }
1729 print_endvalue();
1730 }
1731 break;
1732 case 14:
1733 if((PRINT_TAGINFO))
1734 chpr += printf("D30.%02d_%-30.30s",cfn,"SuperimposedDisplay*");
1735 if((PRINT_VALUE))
1736 {
1737 chpr += printf(" = %u",cfv);
1738 print_startvalue();
1739 switch(cfv)
1740 {
1741 case 0: chpr += printf("On"); break;
1742 case 1: chpr += printf("Off"); break;
1743 default: printred("undefined"); break;
1744 }
1745 print_endvalue();
1746 }
1747 break;
1748 case 15:
1749 if((PRINT_TAGINFO))
1750 chpr += printf("D30.%02d_%-30.30s",cfn,"ShutterReleaseNoCFCard*");
1751 if((PRINT_VALUE))
1752 {
1753 chpr += printf(" = %u",cfv);
1754 print_startvalue();
1755 switch(cfv)
1756 {
1757 case 0: chpr += printf("Yes"); break;
1758 case 1: chpr += printf("No"); break;
1759 default: printred("undefined"); break;
1760 }
1761 print_endvalue();
1762 }
1763 break;
1764 default:
1765 if((PRINT_TAGINFO))
1766 chpr += printf("D30.%02d_%-30.30s",cfn,"undefined");
1767 if((PRINT_VALUE))
1768 chpr += printf(" = %#x/%u",cfv,cfv);
1769 break;
1770 }
1771 chpr = newline(chpr);
1772 }
1773 }
1774 setcharsprinted(chpr);
1775 return(end_offset);
1776 }
1777
1778 /* CustomFunctions for Canon 10D */
1779
1780 unsigned long
canon_customfunctions10D(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent)1781 canon_customfunctions10D(FILE *inptr,unsigned short byteorder,char *tagprefix,
1782 unsigned long offset,unsigned long dirlength,int indent)
1783 {
1784 unsigned long count;
1785 unsigned long end_offset;
1786 unsigned short length,value;
1787 int i,cfn,cfv;
1788 int chpr = 0;
1789
1790 end_offset = offset + dirlength;
1791 length = read_ushort(inptr,byteorder,offset);
1792 if(PRINT_SECTION)
1793 {
1794 chpr += printf(" length %lu",dirlength);
1795 if(length != dirlength)
1796 {
1797 chpr = newline(chpr);
1798 PUSHCOLOR(RED);
1799 print_tag_address(SECTION,offset,indent,"@");
1800 chpr += printf("# WARNING: length %u from segment does not match length %lu from directory",
1801 length,dirlength);
1802 POPCOLOR();
1803 }
1804 }
1805 chpr = newline(chpr);
1806
1807 if((PRINT_ENTRY))
1808 {
1809 offset += 2;
1810 count = (dirlength / sizeof(unsigned short)) - 1;
1811
1812 for(i = 0; i < count; ++i)
1813 {
1814 value = read_ushort(inptr,byteorder,offset);
1815 print_tag_address(ENTRY,offset,indent,"@");
1816 if((PRINT_TAGINFO))
1817 chpr += printf("%s",tagprefix);
1818 offset += 2;
1819 cfn = (value & 0xff00) >> 8;
1820 cfv = value & 0xff;
1821 switch(cfn)
1822 {
1823 case 1:
1824 if((PRINT_TAGINFO))
1825 chpr += printf("10D.%02d_%-30.30s",cfn,"Set Button Function");
1826 if((PRINT_VALUE))
1827 {
1828 chpr += printf(" = %u",cfv);
1829 print_startvalue();
1830 switch(cfv)
1831 {
1832 case 0: chpr += printf("Not assigned"); break;
1833 case 1: chpr += printf("Change quality"); break;
1834 case 2: chpr += printf("Change parameters"); break;
1835 case 3: chpr += printf("Menu display"); break;
1836 case 4: chpr += printf("Image replay"); break;
1837 default: printred("undefined"); break;
1838 }
1839 print_endvalue();
1840 }
1841 break;
1842 case 2:
1843 if((PRINT_TAGINFO))
1844 chpr += printf("10D.%02d_%-30.30s",cfn,"ShutterReleaseNoCFCard");
1845 if((PRINT_VALUE))
1846 {
1847 chpr += printf(" = %u",cfv);
1848 print_startvalue();
1849 switch(cfv)
1850 {
1851 case 0: chpr += printf("Yes"); break;
1852 case 1: chpr += printf("No"); break;
1853 default: printred("undefined"); break;
1854 }
1855 print_endvalue();
1856 }
1857 break;
1858 case 3:
1859 if((PRINT_TAGINFO))
1860 chpr += printf("10D.%02d_%-30.30s",cfn,"FlashSyncSpeedAv");
1861 if((PRINT_VALUE))
1862 {
1863 chpr += printf(" = %u",cfv);
1864 print_startvalue();
1865 switch(cfv)
1866 {
1867 case 0: chpr += printf("Auto"); break;
1868 case 1: chpr += printf("1/200 (fixed)"); break;
1869 default: printred("undefined"); break;
1870 }
1871 print_endvalue();
1872 }
1873 break;
1874 case 4:
1875 if((PRINT_TAGINFO))
1876 chpr += printf("10D.%02d_%-30.30s",cfn,"ShutterAElockButtons");
1877 if((PRINT_VALUE))
1878 {
1879 chpr += printf(" = %u",cfv);
1880 print_startvalue();
1881 switch(cfv)
1882 {
1883 case 0: chpr += printf("AF/AE lock"); break;
1884 case 1: chpr += printf("AE lock/AF"); break;
1885 case 2: chpr += printf("AF/AF lock"); break;
1886 case 3: chpr += printf("AE/AF"); break;
1887 default: printred("undefined"); break;
1888 }
1889 print_endvalue();
1890 }
1891 break;
1892 case 5:
1893 if((PRINT_TAGINFO))
1894 chpr += printf("10D.%02d_%-30.30s",cfn,"AFAssistLight");
1895 if((PRINT_VALUE))
1896 {
1897 chpr += printf(" = %u",cfv);
1898 print_startvalue();
1899 switch(cfv)
1900 {
1901 case 0: chpr += printf("Emits/Fires"); break;
1902 case 1: chpr += printf("Does not emit/Fires"); break;
1903 case 2: chpr += printf("Only ext flash emits/Fires"); break;
1904 case 3: chpr += printf("Emits/Does not fire"); break;
1905 default: printred("undefined"); break;
1906 }
1907 print_endvalue();
1908 }
1909 break;
1910 case 6:
1911 if((PRINT_TAGINFO))
1912 chpr += printf("10D.%02d_%-30.30s",cfn,"ExposureLevelIncrements");
1913 if((PRINT_VALUE))
1914 {
1915 chpr += printf(" = %u",cfv);
1916 print_startvalue();
1917 switch(cfv)
1918 {
1919 case 0: chpr += printf("1/2 stop"); break;
1920 case 1: chpr += printf("1/3 stop"); break;
1921 default: printred("undefined"); break;
1922 }
1923 print_endvalue();
1924 }
1925 break;
1926 case 7:
1927 if((PRINT_TAGINFO))
1928 chpr += printf("10D.%02d_%-30.30s",cfn,"AFPointRegistration");
1929 if((PRINT_VALUE))
1930 {
1931 chpr += printf(" = %u",cfv);
1932 print_startvalue();
1933 switch(cfv)
1934 {
1935 case 0: chpr += printf("Center"); break;
1936 case 1: chpr += printf("Bottom"); break;
1937 case 2: chpr += printf("Right"); break;
1938 case 3: chpr += printf("Extreme Right"); break;
1939 case 4: chpr += printf("Automatic"); break;
1940 case 5: chpr += printf("Extreme Left"); break;
1941 case 6: chpr += printf("Left"); break;
1942 case 7: chpr += printf("Top"); break;
1943 default: printred("undefined"); break;
1944 }
1945 print_endvalue();
1946 }
1947 break;
1948 case 8:
1949 if((PRINT_TAGINFO))
1950 chpr += printf("10D.%02d_%-30.30s",cfn,"RawandJpegRecording");
1951 if((PRINT_VALUE))
1952 {
1953 chpr += printf(" = %u",cfv);
1954 print_startvalue();
1955 switch(cfv)
1956 {
1957 case 0: chpr += printf("RAW+Small/Normal"); break;
1958 case 1: chpr += printf("RAW+Small/Fine"); break;
1959 case 2: chpr += printf("RAW+Medium/Normal"); break;
1960 case 3: chpr += printf("RAW+Medium/Fine"); break;
1961 case 4: chpr += printf("RAW+Large/Normal"); break;
1962 case 5: chpr += printf("RAW+Large/Fine"); break;
1963 default: printred("undefined"); break;
1964 }
1965 print_endvalue();
1966 }
1967 break;
1968 case 9:
1969 if((PRINT_TAGINFO))
1970 chpr += printf("10D.%02d_%-30.30s",cfn,"AEBSequence");
1971 if((PRINT_VALUE))
1972 {
1973 chpr += printf(" = %u",cfv);
1974 print_startvalue();
1975 switch(cfv)
1976 {
1977 case 0: chpr += printf("0,-,+/Enabled"); break;
1978 case 1: chpr += printf("0,-,+/Disabled"); break;
1979 case 2: chpr += printf("-,0,+/Enabled"); break;
1980 case 3: chpr += printf("-,0,+/Disabled"); break;
1981 default: printred("undefined"); break;
1982 }
1983 print_endvalue();
1984 }
1985 break;
1986 case 10:
1987 if((PRINT_TAGINFO))
1988 chpr += printf("10D.%02d_%-30.30s",cfn,"SuperimposedDisplay");
1989 if((PRINT_VALUE))
1990 {
1991 chpr += printf(" = %u",cfv);
1992 print_startvalue();
1993 switch(cfv)
1994 {
1995 case 0: chpr += printf("On"); break;
1996 case 1: chpr += printf("Off"); break;
1997 default: printred("undefined"); break;
1998 }
1999 print_endvalue();
2000 }
2001 break;
2002 case 11:
2003 if((PRINT_TAGINFO))
2004 chpr += printf("10D.%02d_%-30.30s",cfn,"MenuButtonDisplayPosition");
2005 if((PRINT_VALUE))
2006 {
2007 chpr += printf(" = %u",cfv);
2008 print_startvalue();
2009 switch(cfv)
2010 {
2011 case 0: chpr += printf("Previous (volatile)"); break;
2012 case 1: chpr += printf("Previous"); break;
2013 case 2: chpr += printf("Top"); break;
2014 default: printred("undefined"); break;
2015 }
2016 print_endvalue();
2017 }
2018 break;
2019 case 12:
2020 if((PRINT_TAGINFO))
2021 chpr += printf("10D.%02d_%-30.30s",cfn,"MirrorLockup");
2022 if((PRINT_VALUE))
2023 {
2024 chpr += printf(" = %u",cfv);
2025 print_startvalue();
2026 switch(cfv)
2027 {
2028 case 0: chpr += printf("Disabled"); break;
2029 case 1: chpr += printf("Enabled"); break;
2030 default: printred("undefined"); break;
2031 }
2032 print_endvalue();
2033 }
2034 break;
2035 case 13:
2036 if((PRINT_TAGINFO))
2037 chpr += printf("10D.%02d_%-30.30s",cfn,"AssistButtonFunction");
2038 if((PRINT_VALUE))
2039 {
2040 chpr += printf(" = %u",cfv);
2041 print_startvalue();
2042 switch(cfv)
2043 {
2044 case 0: chpr += printf("Normal"); break;
2045 case 1: chpr += printf("Select home position"); break;
2046 case 2: chpr += printf("Select HP (while pressing)"); break;
2047 case 3: chpr += printf("Ax+/-(AF point by QCD)"); break;
2048 case 4: chpr += printf("FE lock"); break;
2049 default: printred("undefined"); break;
2050 }
2051 print_endvalue();
2052 }
2053 break;
2054 case 14:
2055 if((PRINT_TAGINFO))
2056 chpr += printf("10D.%02d_%-30.30s",cfn,"FillFlashAutoReduction");
2057 if((PRINT_VALUE))
2058 {
2059 chpr += printf(" = %u",cfv);
2060 print_startvalue();
2061 switch(cfv)
2062 {
2063 case 0: chpr += printf("Enabled"); break;
2064 case 1: chpr += printf("Disabled"); break;
2065 default: printred("undefined"); break;
2066 }
2067 print_endvalue();
2068 }
2069 break;
2070 case 15:
2071 if((PRINT_TAGINFO))
2072 chpr += printf("10D.%02d_%-30.30s",cfn,"ShutterCurtainSync");
2073 if((PRINT_VALUE))
2074 {
2075 chpr += printf(" = %u",cfv);
2076 print_startvalue();
2077 switch(cfv)
2078 {
2079 case 0: chpr += printf("1st-curtain sync"); break;
2080 case 1: chpr += printf("2nd-curtain sync"); break;
2081 default: printred("undefined"); break;
2082 }
2083 print_endvalue();
2084 }
2085 break;
2086 case 16:
2087 if((PRINT_TAGINFO))
2088 chpr += printf("10D.%02d_%-30.30s",cfn,"SafetyShiftInAvOrTv");
2089 if((PRINT_VALUE))
2090 {
2091 chpr += printf(" = %u",cfv);
2092 print_startvalue();
2093 switch(cfv)
2094 {
2095 case 0: chpr += printf("Disable"); break;
2096 case 1: chpr += printf("Enable"); break;
2097 default: printred("undefined"); break;
2098 }
2099 print_endvalue();
2100 }
2101 break;
2102 case 17:
2103 if((PRINT_TAGINFO))
2104 chpr += printf("10D.%02d_%-30.30s",cfn,"LensAFStopButton");
2105 if((PRINT_VALUE))
2106 {
2107 chpr += printf(" = %u",cfv);
2108 print_startvalue();
2109 switch(cfv)
2110 {
2111 case 0: chpr += printf("AF Stop"); break;
2112 case 1: chpr += printf("Operate AF"); break;
2113 case 2: chpr += printf("Lock AE and start timer"); break;
2114 default: printred("undefined"); break;
2115 }
2116 print_endvalue();
2117 }
2118 break;
2119 default:
2120 if((PRINT_TAGINFO))
2121 chpr += printf("10D.%02d_%-30.30s",cfn,"undefined");
2122 if((PRINT_VALUE))
2123 chpr += printf(" = %#x/%u",cfv,cfv);
2124 break;
2125 }
2126 chpr = newline(chpr);
2127 }
2128 }
2129 setcharsprinted(chpr);
2130 return(end_offset);
2131 }
2132
2133 /* CustomFunctions for Canon 20D */
2134
2135 unsigned long
canon_customfunctions20D(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent)2136 canon_customfunctions20D(FILE *inptr,unsigned short byteorder,char *tagprefix,
2137 unsigned long offset,unsigned long dirlength,int indent)
2138 {
2139 unsigned long count;
2140 unsigned long end_offset;
2141 unsigned short length,value;
2142 int i,cfn,cfv;
2143 int chpr = 0;
2144
2145 end_offset = offset + dirlength;
2146 length = read_ushort(inptr,byteorder,offset);
2147 if(PRINT_SECTION)
2148 {
2149 chpr += printf(" length %lu",dirlength);
2150 if(length != dirlength)
2151 {
2152 chpr = newline(chpr);
2153 PUSHCOLOR(RED);
2154 print_tag_address(SECTION,offset,indent,"@");
2155 chpr += printf("# WARNING: length %u from segment does not match length %lu from directory",
2156 length,dirlength);
2157 POPCOLOR();
2158 }
2159 }
2160 chpr = newline(chpr);
2161
2162 if((PRINT_ENTRY))
2163 {
2164 offset += 2;
2165 count = (dirlength / sizeof(unsigned short)) - 1;
2166
2167 for(i = 0; i < count; ++i)
2168 {
2169 value = read_ushort(inptr,byteorder,offset);
2170 print_tag_address(ENTRY,offset,indent,"@");
2171 if((PRINT_TAGINFO))
2172 chpr += printf("%s",tagprefix);
2173 offset += 2;
2174 cfn = (value & 0xff00) >> 8;
2175 cfv = value & 0xff;
2176 switch(cfn)
2177 {
2178 case 0:
2179 if((PRINT_TAGINFO))
2180 chpr += printf("20D.%02d_%-30.30s",cfn,"SetButtonFunctionWhenShooting");
2181 if((PRINT_VALUE))
2182 {
2183 chpr += printf(" = %u",cfv);
2184 print_startvalue();
2185 switch(cfv)
2186 {
2187 case 0: chpr += printf("(no function)"); break;
2188 case 1: chpr += printf("change quality"); break;
2189 case 2: chpr += printf("change parameters"); break;
2190 case 3: chpr += printf("menu display"); break;
2191 case 4: chpr += printf("image replay"); break;
2192 default: printred("undefined"); break;
2193 }
2194 }
2195 print_endvalue();
2196 break;
2197 case 1:
2198 if((PRINT_TAGINFO))
2199 chpr += printf("20D.%02d_%-30.30s",cfn,"LongExposureNoiseReduction");
2200 if((PRINT_VALUE))
2201 {
2202 chpr += printf(" = %u",cfv);
2203 print_startvalue();
2204 switch(cfv)
2205 {
2206 case 0: chpr += printf("Off"); break;
2207 case 1: chpr += printf("On"); break;
2208 default: printred("undefined"); break;
2209 }
2210 print_endvalue();
2211 }
2212 break;
2213 case 2:
2214 if((PRINT_TAGINFO))
2215 chpr += printf("20D.%02d_%-30.30s",cfn,"FlashSyncSpeedAv");
2216 if((PRINT_VALUE))
2217 {
2218 chpr += printf(" = %u",cfv);
2219 print_startvalue();
2220 switch(cfv)
2221 {
2222 case 0: chpr += printf("Auto"); break;
2223 case 1: chpr += printf("1/200 (fixed)"); break;
2224 default: printred("undefined"); break;
2225 }
2226 print_endvalue();
2227 }
2228 break;
2229 case 3:
2230 if((PRINT_TAGINFO))
2231 chpr += printf("20D.%02d_%-30.30s",cfn,"ShutterAElockButtons");
2232 if((PRINT_VALUE))
2233 {
2234 chpr += printf(" = %u",cfv);
2235 print_startvalue();
2236 switch(cfv)
2237 {
2238 case 0: chpr += printf("AF/AE lock"); break;
2239 case 1: chpr += printf("AE lock/AF"); break;
2240 case 2: chpr += printf("AF/AF lock"); break;
2241 case 3: chpr += printf("AE+release/AE+AF"); break;
2242 default: printred("undefined"); break;
2243 }
2244 print_endvalue();
2245 }
2246 break;
2247 case 4:
2248 if((PRINT_TAGINFO))
2249 chpr += printf("20D.%02d_%-30.30s",cfn,"AFAssistLight");
2250 if((PRINT_VALUE))
2251 {
2252 chpr += printf(" = %u",cfv);
2253 print_startvalue();
2254 switch(cfv)
2255 {
2256 case 0: chpr += printf("Emits"); break;
2257 case 1: chpr += printf("Does not emit"); break;
2258 case 2: chpr += printf("Only ext flash emits"); break;
2259 default: printred("undefined"); break;
2260 }
2261 print_endvalue();
2262 }
2263 break;
2264 case 5:
2265 if((PRINT_TAGINFO))
2266 chpr += printf("20D.%02d_%-30.30s",cfn,"ExposureLevelIncrements");
2267 if((PRINT_VALUE))
2268 {
2269 chpr += printf(" = %u",cfv);
2270 print_startvalue();
2271 switch(cfv)
2272 {
2273 case 0: chpr += printf("1/2 stop"); break;
2274 case 1: chpr += printf("1/3 stop"); break;
2275 default: printred("undefined"); break;
2276 }
2277 print_endvalue();
2278 }
2279 break;
2280 case 6:
2281 if((PRINT_TAGINFO))
2282 chpr += printf("20D.%02d_%-30.30s",cfn,"FlashFiring");
2283 if((PRINT_VALUE))
2284 {
2285 chpr += printf(" = %u",cfv);
2286 print_startvalue();
2287 switch(cfv)
2288 {
2289 case 0: chpr += printf("Fires"); break;
2290 case 1: chpr += printf("Does not fire"); break;
2291 default: printred("undefined"); break;
2292 }
2293 print_endvalue();
2294 }
2295 break;
2296 case 7:
2297 if((PRINT_TAGINFO))
2298 chpr += printf("20D.%02d_%-30.30s",cfn,"ISOSpeedExpansion");
2299 if((PRINT_VALUE))
2300 {
2301 chpr += printf(" = %u",cfv);
2302 print_startvalue();
2303 switch(cfv)
2304 {
2305 case 0: chpr += printf("Off"); break;
2306 case 1: chpr += printf("On"); break;
2307 default: printred("undefined"); break;
2308 }
2309 print_endvalue();
2310 }
2311 break;
2312 case 8:
2313 if((PRINT_TAGINFO))
2314 chpr += printf("20D.%02d_%-30.30s",cfn,"AEBSequence");
2315 if((PRINT_VALUE))
2316 {
2317 chpr += printf(" = %u",cfv);
2318 print_startvalue();
2319 switch(cfv)
2320 {
2321 case 0: chpr += printf("0,-,+/Enabled"); break;
2322 case 1: chpr += printf("0,-,+/Disabled"); break;
2323 case 2: chpr += printf("-,0,+/Enabled"); break;
2324 case 3: chpr += printf("-,0,+/Disabled"); break;
2325 default: printred("undefined"); break;
2326 }
2327 print_endvalue();
2328 }
2329 break;
2330 case 9:
2331 if((PRINT_TAGINFO))
2332 chpr += printf("20D.%02d_%-30.30s",cfn,"SuperimposedDisplay");
2333 if((PRINT_VALUE))
2334 {
2335 chpr += printf(" = %u",cfv);
2336 print_startvalue();
2337 switch(cfv)
2338 {
2339 case 0: chpr += printf("On"); break;
2340 case 1: chpr += printf("Off"); break;
2341 default: printred("undefined"); break;
2342 }
2343 print_endvalue();
2344 }
2345 break;
2346 case 10:
2347 if((PRINT_TAGINFO))
2348 chpr += printf("20D.%02d_%-30.30s",cfn,"MenuButtonDisplayPosition");
2349 if((PRINT_VALUE))
2350 {
2351 chpr += printf(" = %u",cfv);
2352 print_startvalue();
2353 switch(cfv)
2354 {
2355 case 0: chpr += printf("Top"); break;
2356 case 1: chpr += printf("Previous (volatile)"); break;
2357 case 2: chpr += printf("Previous"); break;
2358 default: printred("undefined"); break;
2359 }
2360 print_endvalue();
2361 }
2362 break;
2363 case 11:
2364 if((PRINT_TAGINFO))
2365 chpr += printf("20D.%02d_%-30.30s",cfn,"MirrorLockup");
2366 if((PRINT_VALUE))
2367 {
2368 chpr += printf(" = %u",cfv);
2369 print_startvalue();
2370 switch(cfv)
2371 {
2372 case 0: chpr += printf("Disabled"); break;
2373 case 1: chpr += printf("Enabled"); break;
2374 default: printred("undefined"); break;
2375 }
2376 print_endvalue();
2377 }
2378 break;
2379 case 12:
2380 if((PRINT_TAGINFO))
2381 chpr += printf("20D.%02d_%-30.30s",cfn,"AFPointSelectionMethod");
2382 if((PRINT_VALUE))
2383 {
2384 chpr += printf(" = %u",cfv);
2385 print_startvalue();
2386 switch(cfv)
2387 {
2388 case 0: chpr += printf("Normal"); break;
2389 case 1: chpr += printf("Multi-controller direct"); break;
2390 case 2: chpr += printf("Quick control dial direct"); break;
2391 default: printred("undefined"); break;
2392 }
2393 print_endvalue();
2394 }
2395 break;
2396 case 13:
2397 if((PRINT_TAGINFO))
2398 chpr += printf("20D.%02d_%-30.30s",cfn,"ETTLII");
2399 if((PRINT_VALUE))
2400 {
2401 chpr += printf(" = %u",cfv);
2402 print_startvalue();
2403 switch(cfv)
2404 {
2405 case 0: chpr += printf("Evaluative"); break;
2406 case 1: chpr += printf("Average"); break;
2407 default: printred("undefined"); break;
2408 }
2409 print_endvalue();
2410 }
2411 break;
2412 case 14:
2413 if((PRINT_TAGINFO))
2414 chpr += printf("20D.%02d_%-30.30s",cfn,"ShutterCurtainSync");
2415 if((PRINT_VALUE))
2416 {
2417 chpr += printf(" = %u",cfv);
2418 print_startvalue();
2419 switch(cfv)
2420 {
2421 case 0: chpr += printf("1st-curtain sync"); break;
2422 case 1: chpr += printf("2nd-curtain sync"); break;
2423 default: printred("undefined"); break;
2424 }
2425 print_endvalue();
2426 }
2427 break;
2428 case 15:
2429 if((PRINT_TAGINFO))
2430 chpr += printf("20D.%02d_%-30.30s",cfn,"SafetyShiftInAvOrTv");
2431 if((PRINT_VALUE))
2432 {
2433 chpr += printf(" = %u",cfv);
2434 print_startvalue();
2435 switch(cfv)
2436 {
2437 case 0: chpr += printf("Disable"); break;
2438 case 1: chpr += printf("Enable"); break;
2439 default: printred("undefined"); break;
2440 }
2441 print_endvalue();
2442 }
2443 break;
2444 case 16:
2445 if((PRINT_TAGINFO))
2446 chpr += printf("20D.%02d_%-30.30s",cfn,"LensAFStopButton");
2447 if((PRINT_VALUE))
2448 {
2449 chpr += printf(" = %u",cfv);
2450 print_startvalue();
2451 switch(cfv)
2452 {
2453 case 0: chpr += printf("AF Stop"); break;
2454 case 1: chpr += printf("Operate AF"); break;
2455 case 2: chpr += printf("Lock AE and start timer"); break;
2456 default: printred("undefined"); break;
2457 }
2458 print_endvalue();
2459 }
2460 break;
2461 case 17:
2462 if((PRINT_TAGINFO))
2463 chpr += printf("20D.%02d_%-30.30s",cfn,"AddOriginalDecisionData");
2464 if((PRINT_VALUE))
2465 {
2466 chpr += printf(" = %u",cfv);
2467 print_startvalue();
2468 switch(cfv)
2469 {
2470 case 0: chpr += printf("Off"); break;
2471 case 1: chpr += printf("On"); break;
2472 default: printred("undefined"); break;
2473 }
2474 print_endvalue();
2475 }
2476 break;
2477 default:
2478 if((PRINT_TAGINFO))
2479 chpr += printf("20D.%02d_%-30.30s",cfn,"undefined");
2480 if((PRINT_VALUE))
2481 chpr += printf(" = %#x/%u",cfv,cfv);
2482 break;
2483 }
2484 chpr = newline(chpr);
2485 }
2486 }
2487 setcharsprinted(chpr);
2488 return(end_offset);
2489 }
2490
2491 /* CustomFunctions for Canon 1D */
2492
2493 unsigned long
canon_customfunctions1D(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent)2494 canon_customfunctions1D(FILE *inptr,unsigned short byteorder,char *tagprefix,
2495 unsigned long offset,unsigned long dirlength,int indent)
2496 {
2497 unsigned long count;
2498 unsigned long end_offset;
2499 unsigned short length,value;
2500 int i,cfn,cfv;
2501 int chpr = 0;
2502
2503 end_offset = offset + dirlength;
2504 length = read_ushort(inptr,byteorder,offset);
2505 if(PRINT_SECTION)
2506 {
2507 chpr += printf(" length %lu",dirlength);
2508 if(length != dirlength)
2509 {
2510 chpr = newline(chpr);
2511 PUSHCOLOR(RED);
2512 print_tag_address(SECTION,offset,indent,"@");
2513 chpr += printf("# WARNING: length %u from segment does not match length %lu from directory",
2514 length,dirlength);
2515 POPCOLOR();
2516 }
2517 }
2518 chpr = newline(chpr);
2519
2520 if((PRINT_ENTRY))
2521 {
2522 offset += 2;
2523 count = (dirlength / sizeof(unsigned short)) - 1;
2524
2525 for(i = 0; i < count; ++i)
2526 {
2527 value = read_ushort(inptr,byteorder,offset);
2528 print_tag_address(ENTRY,offset,indent,"@");
2529 chpr += printf("%s",tagprefix);
2530 offset += 2;
2531 cfn = (value & 0xff00) >> 8;
2532 cfv = value & 0xff;
2533 switch(cfn)
2534 {
2535 case 0:
2536 if((PRINT_TAGINFO))
2537 chpr += printf("1D.%02d_%-30.30s",cfn,"FocusingScreen");
2538 if((PRINT_VALUE))
2539 {
2540 chpr += printf(" = %u",cfv);
2541 print_startvalue();
2542 switch(cfv)
2543 {
2544 case 0: chpr += printf("Ec-N,R"); break;
2545 case 1: chpr += printf("Ec-A,B,C,CII,CIII,D,H,I,L"); break;
2546 default: printred("undefined"); break;
2547 }
2548 print_endvalue();
2549 }
2550 break;
2551 case 1:
2552 if((PRINT_TAGINFO))
2553 chpr += printf("1D.%02d_%-30.30s",cfn,"FinderDisplayDuringExposure");
2554 if((PRINT_VALUE))
2555 {
2556 chpr += printf(" = %u",cfv);
2557 print_startvalue();
2558 switch(cfv)
2559 {
2560 case 0: chpr += printf("Off"); break;
2561 case 1: chpr += printf("On"); break;
2562 default: printred("undefined"); break;
2563 }
2564 print_endvalue();
2565 }
2566 break;
2567 case 2:
2568 if((PRINT_TAGINFO))
2569 chpr += printf("1D.%02d_%-30.30s",cfn,"ShutterReleaseNoCFCard");
2570 if((PRINT_VALUE))
2571 {
2572 chpr += printf(" = %u",cfv);
2573 print_startvalue();
2574 switch(cfv)
2575 {
2576 case 0: chpr += printf("Yes"); break;
2577 case 1: chpr += printf("No"); break;
2578 default: printred("undefined"); break;
2579 }
2580 print_endvalue();
2581 }
2582 break;
2583 case 3:
2584 if((PRINT_TAGINFO))
2585 chpr += printf("1D.%02d_%-30.30s",cfn,"ISOSpeedExpansion");
2586 if((PRINT_VALUE))
2587 {
2588 chpr += printf(" = %u",cfv);
2589 print_startvalue();
2590 switch(cfv)
2591 {
2592 case 0: chpr += printf("No"); break;
2593 case 1: chpr += printf("Yes"); break;
2594 default: printred("undefined"); break;
2595 }
2596 print_endvalue();
2597 }
2598 break;
2599 case 4:
2600 if((PRINT_TAGINFO))
2601 chpr += printf("1D.%02d_%-30.30s",cfn,"ShutterAElockButtons");
2602 if((PRINT_VALUE))
2603 {
2604 chpr += printf(" = %u",cfv);
2605 print_startvalue();
2606 switch(cfv)
2607 {
2608 case 0: chpr += printf("AF/AE lock"); break;
2609 case 1: chpr += printf("AE lock/AF"); break;
2610 case 2: chpr += printf("AF/AF lock"); break;
2611 case 3: chpr += printf("AE+release/AE+AF"); break;
2612 default: printred("undefined"); break;
2613 }
2614 print_endvalue();
2615 }
2616 break;
2617 case 5:
2618 if((PRINT_TAGINFO))
2619 chpr += printf("1D.%02d_%-30.30s",cfn,"ManualTv");
2620 if((PRINT_VALUE))
2621 {
2622 chpr += printf(" = %u",cfv);
2623 print_startvalue();
2624 switch(cfv)
2625 {
2626 case 0: chpr += printf("Tv:Main/Av:Control"); break;
2627 case 1: chpr += printf("Tv:Control/Av:Main"); break;
2628 case 2: chpr += printf("Tv:Main/Av:Main w/o lens"); break;
2629 case 3: chpr += printf("Tv:Control/Av:Main w/o lens"); break;
2630 default: printred("undefined"); break;
2631 }
2632 print_endvalue();
2633 }
2634 break;
2635 case 6:
2636 if((PRINT_TAGINFO))
2637 chpr += printf("1D.%02d_%-30.30s",cfn,"ExposureLevelIncrements");
2638 if((PRINT_VALUE))
2639 {
2640 chpr += printf(" = %u",cfv);
2641 print_startvalue();
2642 switch(cfv)
2643 {
2644 case 0: chpr += printf("1/3-Stop set, 1/3-Stop comp"); break;
2645 case 1: chpr += printf("1-Stop set, 1/3-Stop comp"); break;
2646 case 2: chpr += printf("1/2-Stop set, 1/2-Stop comp"); break;
2647 default: printred("undefined"); break;
2648 }
2649 print_endvalue();
2650 }
2651 break;
2652 case 7:
2653 if((PRINT_TAGINFO))
2654 chpr += printf("1D.%02d_%-30.30s",cfn,"USMLensElectronicMF");
2655 if((PRINT_VALUE))
2656 {
2657 chpr += printf(" = %u",cfv);
2658 print_startvalue();
2659 switch(cfv)
2660 {
2661 case 0: chpr += printf("Turns on after one-shot AF"); break;
2662 case 1: chpr += printf("Turns off after one-shot AF"); break;
2663 case 2: chpr += printf("Always off"); break;
2664 default: printred("undefined"); break;
2665 }
2666 print_endvalue();
2667 }
2668 break;
2669 case 8:
2670 if((PRINT_TAGINFO))
2671 chpr += printf("1D.%02d_%-30.30s",cfn,"LCDPanels");
2672 if((PRINT_VALUE))
2673 {
2674 chpr += printf(" = %u",cfv);
2675 print_startvalue();
2676 switch(cfv)
2677 {
2678 case 0: chpr += printf("Remaining shots/File no"); break;
2679 case 1: chpr += printf("ISO/Remaining shots"); break;
2680 case 2: chpr += printf("ISO/File no"); break;
2681 case 3: chpr += printf("Shots in folder/Remaining shots"); break;
2682 default: printred("undefined"); break;
2683 }
2684 print_endvalue();
2685 }
2686 break;
2687 case 9:
2688 if((PRINT_TAGINFO))
2689 chpr += printf("1D.%02d_%-30.30s",cfn,"AEBSequenceAutoCancellation");
2690 if((PRINT_VALUE))
2691 {
2692 chpr += printf(" = %u",cfv);
2693 print_startvalue();
2694 switch(cfv)
2695 {
2696 case 0: chpr += printf("0,-,+/Enabled"); break;
2697 case 1: chpr += printf("0,-,+/Disabled"); break;
2698 case 2: chpr += printf("-,0,+/Enabled"); break;
2699 case 3: chpr += printf("-,0,+/Disabled"); break;
2700 default: printred("undefined"); break;
2701 }
2702 print_endvalue();
2703 }
2704 break;
2705 case 10:
2706 if((PRINT_TAGINFO))
2707 chpr += printf("1D.%02d_%-30.30s",cfn,"AFPointIllumination");
2708 if((PRINT_VALUE))
2709 {
2710 chpr += printf(" = %u",cfv);
2711 print_startvalue();
2712 switch(cfv)
2713 {
2714 case 0: chpr += printf("On"); break;
2715 case 1: chpr += printf("Off"); break;
2716 case 2: chpr += printf("On without dimming"); break;
2717 case 3: chpr += printf("Brighter"); break;
2718 default: printred("undefined"); break;
2719 }
2720 print_endvalue();
2721 }
2722 break;
2723 case 11:
2724 if((PRINT_TAGINFO))
2725 chpr += printf("1D.%02d_%-30.30s",cfn,"AFPointSelection");
2726 if((PRINT_VALUE))
2727 {
2728 chpr += printf(" = %u",cfv);
2729 print_startvalue();
2730 switch(cfv)
2731 {
2732 case 0: chpr += printf("H:AF+Main, V:AF+Command"); break;
2733 case 1: chpr += printf("H:Comp+Main, V:AF+Comp+Command"); break;
2734 case 2: chpr += printf("H:Command only, V:Assist+Main"); break;
2735 case 3: chpr += printf("H:FEL_Main, V:FEL+Command"); break;
2736 default: printred("undefined"); break;
2737 }
2738 print_endvalue();
2739 }
2740 break;
2741 case 12:
2742 if((PRINT_TAGINFO))
2743 chpr += printf("1D.%02d_%-30.30s",cfn,"MirrorLockup");
2744 if((PRINT_VALUE))
2745 {
2746 chpr += printf(" = %u",cfv);
2747 print_startvalue();
2748 switch(cfv)
2749 {
2750 case 0: chpr += printf("Disabled"); break;
2751 case 1: chpr += printf("Enabled"); break;
2752 default: printred("undefined"); break;
2753 }
2754 print_endvalue();
2755 }
2756 break;
2757 case 13:
2758 if((PRINT_TAGINFO))
2759 chpr += printf("1D.%02d_%-30.30s",cfn,"AFPointSpotMetering");
2760 if((PRINT_VALUE))
2761 {
2762 chpr += printf(" = %u",cfv);
2763 print_startvalue();
2764 switch(cfv)
2765 {
2766 case 0: chpr += printf("45/Center of Point"); break;
2767 case 1: chpr += printf("11/Active AF point"); break;
2768 case 2: chpr += printf("11/Center AF point"); break;
2769 case 3: chpr += printf("9/Active af pOINT"); break;
2770 default: printred("undefined"); break;
2771 }
2772 print_endvalue();
2773 }
2774 break;
2775 case 14:
2776 if((PRINT_TAGINFO))
2777 chpr += printf("1D.%02d_%-30.30s",cfn,"FillFlashAutoReduction");
2778 if((PRINT_VALUE))
2779 {
2780 chpr += printf(" = %u",cfv);
2781 print_startvalue();
2782 switch(cfv)
2783 {
2784 case 0: chpr += printf("Enabled"); break;
2785 case 1: chpr += printf("Disabled"); break;
2786 default: printred("undefined"); break;
2787 }
2788 print_endvalue();
2789 }
2790 break;
2791 case 15:
2792 if((PRINT_TAGINFO))
2793 chpr += printf("1D.%02d_%-30.30s",cfn,"ShutterCurtainSync");
2794 if((PRINT_VALUE))
2795 {
2796 chpr += printf(" = %u",cfv);
2797 print_startvalue();
2798 switch(cfv)
2799 {
2800 case 0: chpr += printf("1st-curtain sync"); break;
2801 case 1: chpr += printf("2nd-curtain sync"); break;
2802 default: printred("undefined"); break;
2803 }
2804 print_endvalue();
2805 }
2806 break;
2807 case 16:
2808 if((PRINT_TAGINFO))
2809 chpr += printf("1D.%02d_%-30.30s",cfn,"SafetyShiftIn");
2810 if((PRINT_VALUE))
2811 {
2812 chpr += printf(" = %u",cfv);
2813 print_startvalue();
2814 switch(cfv)
2815 {
2816 case 0: chpr += printf("Disable"); break;
2817 case 1: chpr += printf("Enable"); break;
2818 default: printred("undefined"); break;
2819 }
2820 print_endvalue();
2821 }
2822 break;
2823 case 17:
2824 if((PRINT_TAGINFO))
2825 chpr += printf("1D.%02d_%-30.30s",cfn,"AF Point Activation Area");
2826 if((PRINT_VALUE))
2827 {
2828 chpr += printf(" = %u",cfv);
2829 print_startvalue();
2830 switch(cfv)
2831 {
2832 case 0: chpr += printf("Single AF point"); break;
2833 case 1: chpr += printf("Expanded (7 AF points)"); break;
2834 case 2: chpr += printf("Auto expanded (max 13)"); break;
2835 default: printred("undefined"); break;
2836 }
2837 print_endvalue();
2838 }
2839 break;
2840 case 18:
2841 if((PRINT_TAGINFO))
2842 chpr += printf("1D.%02d_%-30.30s",cfn,"SwitchToRegisteredAFPoint");
2843 if((PRINT_VALUE))
2844 {
2845 chpr += printf(" = %u",cfv);
2846 print_startvalue();
2847 switch(cfv)
2848 {
2849 case 0: chpr += printf("AF + assist"); break;
2850 case 1: chpr += printf("Assist"); break;
2851 case 2: chpr += printf("Only while pressing Assist"); break;
2852 default: printred("undefined"); break;
2853 }
2854 print_endvalue();
2855 }
2856 break;
2857 case 19:
2858 if((PRINT_TAGINFO))
2859 chpr += printf("1D.%02d_%-30.30s",cfn,"Lens AF Stop Button");
2860 if((PRINT_VALUE))
2861 {
2862 chpr += printf(" = %u",cfv);
2863 print_startvalue();
2864 switch(cfv)
2865 {
2866 case 0: chpr += printf("AF Stop"); break;
2867 case 1: chpr += printf("AF Start"); break;
2868 case 2: chpr += printf("AE Lock whuile metering"); break;
2869 case 3: chpr += printf("AF Point: M > Auto, Auto > Center"); break;
2870 case 4: chpr += printf("AF Mode: oneshot/servo"); break;
2871 case 5: chpr += printf("IS Start"); break;
2872 default: printred("undefined"); break;
2873 }
2874 print_endvalue();
2875 }
2876 break;
2877 case 20:
2878 if((PRINT_TAGINFO))
2879 chpr += printf("1D.%02d_%-30.30s",cfn,"AIServoTrackingSensitivity");
2880 if((PRINT_VALUE))
2881 {
2882 chpr += printf(" = %u",cfv);
2883 print_startvalue();
2884 switch(cfv)
2885 {
2886 case 0: chpr += printf("Standard"); break;
2887 case 1: chpr += printf("Slow"); break;
2888 case 2: chpr += printf("Moderately slow"); break;
2889 case 3: chpr += printf("Moderately fast"); break;
2890 case 4: chpr += printf("Fast"); break;
2891 default: printred("undefined"); break;
2892 }
2893 print_endvalue();
2894 }
2895 break;
2896 default:
2897 if((PRINT_TAGINFO))
2898 chpr += printf("1D.%02d_%-30.30s",cfn,"undefined");
2899 if((PRINT_VALUE))
2900 chpr += printf(" = %#x/%u",cfv,cfv);
2901 break;
2902 }
2903 chpr = newline(chpr);
2904 }
2905 }
2906 setcharsprinted(chpr);
2907 return(end_offset);
2908 }
2909
2910 unsigned long
canon_sensorinfo(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent)2911 canon_sensorinfo(FILE *inptr,unsigned short byteorder,char *tagprefix,
2912 unsigned long offset,unsigned long dirlength,int indent)
2913 {
2914 unsigned long count;
2915 unsigned long end_offset;
2916 unsigned short length,value;
2917 int i;
2918 int chpr = 0;
2919
2920 end_offset = offset + dirlength;
2921 length = read_ushort(inptr,byteorder,offset);
2922 if(PRINT_SECTION)
2923 {
2924 chpr += printf(" length %lu",dirlength);
2925 if(length != dirlength)
2926 {
2927 chpr = newline(chpr);
2928 PUSHCOLOR(RED);
2929 print_tag_address(SECTION,offset,indent,"@");
2930 chpr += printf("# WARNING: length %u from segment does not match length %lu from directory",
2931 length,dirlength);
2932 POPCOLOR();
2933 }
2934 }
2935 chpr = newline(chpr);
2936
2937 if((PRINT_ENTRY))
2938 {
2939 offset += 2;
2940 count = (dirlength / sizeof(unsigned short)) - 1;
2941
2942 for(i = 1; i <= count; ++i)
2943 {
2944 value = read_ushort(inptr,byteorder,offset);
2945 print_tag_address(ENTRY,offset,indent,"@");
2946 if((PRINT_TAGINFO))
2947 chpr += printf("%s",tagprefix);
2948 offset += 2;
2949 switch(i)
2950 {
2951 case 1:
2952 if((PRINT_TAGINFO))
2953 chpr += printf(".%02d_%-26.26s",i,"SensorWidth");
2954 if((PRINT_VALUE))
2955 chpr += printf(" = %u",value);
2956 break;
2957 case 2:
2958 if((PRINT_TAGINFO))
2959 chpr += printf(".%02d_%-26.26s",i,"SensorHeight");
2960 if((PRINT_VALUE))
2961 chpr += printf(" = %u",value);
2962 break;
2963 case 3:
2964 if((PRINT_TAGINFO))
2965 chpr += printf(".%02d_%-26.26s",i,"Unknown");
2966 if((PRINT_VALUE))
2967 chpr += printf(" = %u",value);
2968 break;
2969 case 4:
2970 if((PRINT_TAGINFO))
2971 chpr += printf(".%02d_%-26.26s",i,"Unknown");
2972 if((PRINT_VALUE))
2973 chpr += printf(" = %u",value);
2974 break;
2975 case 5:
2976 if((PRINT_TAGINFO))
2977 chpr += printf(".%02d_%-26.26s",i,"SensorLeftBorder");
2978 if((PRINT_VALUE))
2979 chpr += printf(" = %u",value);
2980 break;
2981 case 6:
2982 if((PRINT_TAGINFO))
2983 chpr += printf(".%02d_%-26.26s",i,"SensorTopBorder");
2984 if((PRINT_VALUE))
2985 chpr += printf(" = %u",value);
2986 break;
2987 case 7:
2988 if((PRINT_TAGINFO))
2989 chpr += printf(".%02d_%-26.26s",i,"SensorRightBorder");
2990 if((PRINT_VALUE))
2991 chpr += printf(" = %u",value);
2992 break;
2993 case 8:
2994 if((PRINT_TAGINFO))
2995 chpr += printf(".%02d_%-26.26s",i,"SensorBottomBorder");
2996 if((PRINT_VALUE))
2997 chpr += printf(" = %u",value);
2998 break;
2999 default:
3000 if((PRINT_TAGINFO))
3001 chpr += printf(".%02d_%-26.26s",i,"Undefined");
3002 if((PRINT_VALUE))
3003 chpr += printf(" = %#x%u",value,value);
3004 break;
3005 }
3006 chpr = newline(chpr);
3007 }
3008 }
3009 setcharsprinted(chpr);
3010 return(end_offset);
3011 }
3012
3013
3014 /* not a directory; an array of shorts used as rationals */
3015 unsigned long
canon_whitebalancetable(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent)3016 canon_whitebalancetable(FILE *inptr,unsigned short byteorder,char *tagprefix,
3017 unsigned long offset,unsigned long dirlength,int indent)
3018 {
3019 unsigned long count;
3020 unsigned long end_offset;
3021 unsigned short length;
3022 unsigned short num,denom;
3023 float value;
3024 int i;
3025 int chpr = 0;
3026
3027 end_offset = offset + dirlength;
3028 length = read_ushort(inptr,byteorder,offset);
3029 if(PRINT_SECTION)
3030 {
3031 chpr += printf(" length %lu",dirlength);
3032 if(length != dirlength)
3033 {
3034 chpr = newline(chpr);
3035 PUSHCOLOR(RED);
3036 print_tag_address(SECTION,offset,indent,"@");
3037 chpr += printf("# WARNING: length %u from segment does not match length %lu from directory",
3038 length,dirlength);
3039 POPCOLOR();
3040 }
3041 chpr = newline(chpr);
3042 }
3043
3044 if((PRINT_ENTRY))
3045 {
3046 offset += 2;
3047 count = (dirlength - 2) / sizeof(float);
3048
3049 for(i = 0; i < count; ++i)
3050 {
3051 num = read_ushort(inptr,byteorder,offset);
3052 denom = read_ushort(inptr,byteorder,offset+2);
3053 value = (float)num / (float)denom;
3054 print_tag_address(ENTRY,offset,indent,"@");
3055 if((PRINT_TAGINFO))
3056 chpr += printf("%s",tagprefix);
3057 switch(i)
3058 {
3059 case 0:
3060 if((PRINT_TAGINFO))
3061 chpr += printf(".%02d_%-22.22s",i,"RedBalanceAuto");
3062 if((PRINT_VALUE))
3063 chpr += printf(" = %f",value);
3064 break;
3065 case 1:
3066 if((PRINT_TAGINFO))
3067 chpr += printf(".%02d_%-22.22s",i,"BlueBalanceAuto");
3068 if((PRINT_VALUE))
3069 chpr += printf(" = %f",value);
3070 break;
3071 case 2:
3072 if((PRINT_TAGINFO))
3073 chpr += printf(".%02d_%-22.22s",i,"RedBalanceDaylight");
3074 if((PRINT_VALUE))
3075 chpr += printf(" = %f",value);
3076 break;
3077 case 3:
3078 if((PRINT_TAGINFO))
3079 chpr += printf(".%02d_%-22.22s",i,"BlueBalanceDaylight");
3080 if((PRINT_VALUE))
3081 chpr += printf(" = %f",value);
3082 break;
3083 case 4:
3084 if((PRINT_TAGINFO))
3085 chpr += printf(".%02d_%-22.22s",i,"RedBalanceCloudy");
3086 if((PRINT_VALUE))
3087 chpr += printf(" = %f",value);
3088 break;
3089 case 5:
3090 if((PRINT_TAGINFO))
3091 chpr += printf(".%02d_%-22.22s",i,"BlueBalanceCloudy");
3092 if((PRINT_VALUE))
3093 chpr += printf(" = %f",value);
3094 break;
3095 case 6:
3096 if((PRINT_TAGINFO))
3097 chpr += printf(".%02d_%-22.22s",i,"RedBalanceTungsten");
3098 if((PRINT_VALUE))
3099 chpr += printf(" = %f",value);
3100 break;
3101 case 7:
3102 if((PRINT_TAGINFO))
3103 chpr += printf(".%02d_%-22.22s",i,"BlueBalanceTungsten");
3104 if((PRINT_VALUE))
3105 chpr += printf(" = %f",value);
3106 break;
3107 case 8:
3108 if((PRINT_TAGINFO))
3109 chpr += printf(".%02d_%-22.22s",i,"RedBalanceFluorescent");
3110 if((PRINT_VALUE))
3111 chpr += printf(" = %f",value);
3112 break;
3113 case 9:
3114 if((PRINT_TAGINFO))
3115 chpr += printf(".%02d_%-22.22s",i,"BlueBalanceFluorescent");
3116 if((PRINT_VALUE))
3117 chpr += printf(" = %f",value);
3118 break;
3119 case 10:
3120 if((PRINT_TAGINFO))
3121 chpr += printf(".%02d_%-22.22s",i,"RedBalanceFlash");
3122 if((PRINT_VALUE))
3123 chpr += printf(" = %f",value);
3124 break;
3125 case 11:
3126 if((PRINT_TAGINFO))
3127 chpr += printf(".%02d_%-22.22s",i,"BlueBalanceFlash");
3128 if((PRINT_VALUE))
3129 chpr += printf(" = %f",value);
3130 break;
3131 case 12:
3132 if((PRINT_TAGINFO))
3133 chpr += printf(".%02d_%-22.22s",i,"RedBalanceCustom");
3134 if((PRINT_VALUE))
3135 chpr += printf(" = %f",value);
3136 break;
3137 case 13:
3138 if((PRINT_TAGINFO))
3139 chpr += printf(".%02d_%-22.22s",i,"BlueBalanceCustom");
3140 if((PRINT_VALUE))
3141 chpr += printf(" = %f",value);
3142 break;
3143 case 14:
3144 if((PRINT_TAGINFO))
3145 chpr += printf(".%02d_%-22.22s",i,"RedBalanceB&W");
3146 if((PRINT_VALUE))
3147 chpr += printf(" = %f",value);
3148 break;
3149 case 15:
3150 if((PRINT_TAGINFO))
3151 chpr += printf(".%02d_%-22.22s",i,"BlueBalanceB&W");
3152 if((PRINT_VALUE))
3153 chpr += printf(" = %f",value);
3154 break;
3155 case 16:
3156 if((PRINT_TAGINFO))
3157 chpr += printf(".%02d_%-22.22s",i,"RedBalanceShade");
3158 if((PRINT_VALUE))
3159 chpr += printf(" = %f",value);
3160 break;
3161 case 17:
3162 if((PRINT_TAGINFO))
3163 chpr += printf(".%02d_%-22.22s",i,"BlueBalanceShade");
3164 if((PRINT_VALUE))
3165 chpr += printf(" = %f",value);
3166 break;
3167 default:
3168 if((PRINT_TAGINFO))
3169 chpr += printf(".%02d_%-22.22s",i,"Undefined");
3170 if((PRINT_VALUE))
3171 chpr += printf(" = %f",value);
3172 break;
3173 }
3174 offset += 4;
3175 chpr = newline(chpr);
3176 }
3177 }
3178 setcharsprinted(chpr);
3179 return(end_offset);
3180 }
3181
3182 /* pictureinfo appears to be treated as a directory, except that the */
3183 /* 'length' which should appear at the beginning of a ciff-style */
3184 /* directory often does not agree with the length passed from the */
3185 /* parent. */
3186
3187 unsigned long
canon_pictureinfo(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent)3188 canon_pictureinfo(FILE *inptr,unsigned short byteorder,char *tagprefix,
3189 unsigned long offset,unsigned long dirlength,int indent)
3190 {
3191 unsigned long count;
3192 unsigned long end_offset;
3193 unsigned short value,length;
3194 int i;
3195 int chpr = 0;
3196
3197 end_offset = offset + dirlength;
3198 length = read_ushort(inptr,byteorder,offset);
3199 if(PRINT_SECTION)
3200 {
3201 chpr += printf(" length %lu",dirlength);
3202 if(length != dirlength)
3203 {
3204 chpr = newline(chpr);
3205 PUSHCOLOR(RED);
3206 print_tag_address(SECTION,offset,indent,"@");
3207 chpr += printf("# WARNING: length %u from segment does not match length %lu from directory",
3208 length,dirlength);
3209 POPCOLOR();
3210 }
3211 }
3212 chpr = newline(chpr);
3213
3214 if((PRINT_ENTRY))
3215 {
3216 offset += 2;
3217 count = (dirlength / sizeof(unsigned short)) - 1;
3218
3219 for(i = 1; i <= count; ++i)
3220 {
3221 value = read_ushort(inptr,byteorder,offset);
3222 print_tag_address(ENTRY,offset,indent,"@");
3223 if((PRINT_TAGINFO))
3224 chpr += printf("%s",tagprefix);
3225 offset += 2;
3226 switch(i)
3227 {
3228 case 1:
3229 if((PRINT_TAGINFO))
3230 chpr += printf(".%02d_%-22.22s",i,"Unknown");
3231 if((PRINT_VALUE))
3232 chpr += printf(" = %u",value);
3233 break;
3234 case 2:
3235 if((PRINT_TAGINFO))
3236 chpr += printf(".%02d_%-22.22s",i,"ImageWidth");
3237 if((PRINT_VALUE))
3238 chpr += printf(" = %u",value);
3239 break;
3240 case 3:
3241 if((PRINT_TAGINFO))
3242 chpr += printf(".%02d_%-22.22s",i,"ImageHeight");
3243 if((PRINT_VALUE))
3244 chpr += printf(" = %u",value);
3245 break;
3246 case 4:
3247 if((PRINT_TAGINFO))
3248 chpr += printf(".%02d_%-22.22s",i,"ImageWidthAsShot");
3249 if((PRINT_VALUE))
3250 chpr += printf(" = %u",value);
3251 break;
3252 case 5:
3253 if((PRINT_TAGINFO))
3254 chpr += printf(".%02d_%-22.22s",i,"ImageHeightAsShot");
3255 if((PRINT_VALUE))
3256 chpr += printf(" = %u",value);
3257 break;
3258 case 22:
3259 if((PRINT_TAGINFO))
3260 chpr += printf(".%02d_%-22.22s",i,"AFPointsUsed");
3261 if((PRINT_VALUE))
3262 chpr += printf(" = %u",value);
3263 break;
3264 default:
3265 if((PRINT_TAGINFO))
3266 chpr += printf(".%02d_%-22.22s",i,"Undefined");
3267 if((PRINT_VALUE))
3268 chpr += printf(" = %#x%u",value,value);
3269 break;
3270 }
3271 chpr = newline(chpr);
3272 }
3273 }
3274 setcharsprinted(chpr);
3275 return(end_offset);
3276 }
3277
3278 /* Currently identified only in CIFF files */
3279
3280 unsigned long
canon_imageinfo(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent,struct image_summary * summary_entry)3281 canon_imageinfo(FILE *inptr,unsigned short byteorder,char *tagprefix,
3282 unsigned long offset,unsigned long dirlength,int indent,
3283 struct image_summary *summary_entry)
3284 {
3285 unsigned long count,value;
3286 unsigned long end_offset;
3287 float fvalue;
3288 int i;
3289 int chpr = 0;
3290
3291 if(PRINT_SECTION)
3292 {
3293 chpr += printf(" length %lu",dirlength);
3294 chpr = newline(chpr);
3295 }
3296
3297 /* NOTE that imageinfo is not treated as a directory; there is no */
3298 /* 2-byte count at the beginning. */
3299
3300 end_offset = offset + dirlength;
3301 count = (dirlength / sizeof(unsigned long));
3302
3303 /* Must always do the processing, in order to pick up the image */
3304 /* width and height for the summary, even if nothing is to be */
3305 /* printed */
3306 for(i = 0; i < count; ++i)
3307 {
3308 value = read_ulong(inptr,byteorder,offset);
3309 print_tag_address(ENTRY,offset,indent + MEDIUMINDENT,"@");
3310 if((PRINT_ENTRY))
3311 {
3312 if((PRINT_TAGINFO))
3313 chpr += printf("%s",tagprefix);
3314 }
3315 offset += 4;
3316 switch(i)
3317 {
3318 case 0:
3319 if((PRINT_TAGINFO))
3320 chpr += printf(".%02d_%-22.22s",i,"ImageWidth");
3321 if((PRINT_VALUE))
3322 chpr += printf(" = %lu",value);
3323 if(summary_entry)
3324 summary_entry->pixel_width = value;
3325 break;
3326 case 1:
3327 if((PRINT_TAGINFO))
3328 chpr += printf(".%02d_%-22.22s",i,"ImageHeight");
3329 if((PRINT_VALUE))
3330 chpr += printf(" = %lu",value);
3331 if(summary_entry)
3332 summary_entry->pixel_height = value;
3333 break;
3334 case 2:
3335 fvalue = to_float(value);
3336 if((PRINT_TAGINFO))
3337 chpr += printf(".%02d_%-22.22s",i,"PixelAspectRatio");
3338 if((PRINT_VALUE))
3339 chpr += printf(" = %lu",value);
3340 break;
3341 case 3:
3342 if((PRINT_TAGINFO))
3343 chpr += printf(".%02d_%-22.22s",i,"Rotation");
3344 if((PRINT_VALUE))
3345 chpr += printf(" = %lu",value);
3346 break;
3347 case 4:
3348 if((PRINT_TAGINFO))
3349 chpr += printf(".%02d_%-22.22s",i,"ComponentBitDepth");
3350 if((PRINT_VALUE))
3351 chpr += printf(" = %lu",value);
3352 break;
3353 case 5:
3354 if((PRINT_TAGINFO))
3355 chpr += printf(".%02d_%-22.22s",i,"ColorBitDepth");
3356 if((PRINT_VALUE))
3357 chpr += printf(" = %lu",value);
3358 break;
3359 case 6:
3360 if((PRINT_TAGINFO))
3361 chpr += printf(".%02d_%-22.22s",i,"ColorBW");
3362 if((PRINT_VALUE))
3363 {
3364 chpr += printf(" = %#lx/%lu",value,value);
3365 if((value & 0xff) == 1)
3366 chpr += printf(" = color");
3367 else
3368 chpr += printf(" = greyscale");
3369 if(((value & 0xff00) >> 8) == 1)
3370 chpr += printf(" = \'pixel ratio postproc reqd\'");
3371 }
3372 break;
3373 default:
3374 if((PRINT_TAGINFO))
3375 chpr += printf(".%02d_%-22.22s",i,"Undefined");
3376 if((PRINT_VALUE))
3377 chpr += printf(" = %#lx/%lu",value,value);
3378 break;
3379 }
3380 chpr = newline(chpr);
3381 }
3382 setcharsprinted(chpr);
3383 return(end_offset);
3384 }
3385
3386 /* Currently identified only in CIFF files */
3387
3388 unsigned long
canon_exposureinfo(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent,struct image_summary * summary_entry)3389 canon_exposureinfo(FILE *inptr,unsigned short byteorder,char *tagprefix,
3390 unsigned long offset,unsigned long dirlength,int indent,
3391 struct image_summary *summary_entry)
3392 {
3393 unsigned long count,value;
3394 unsigned long end_offset;
3395 float fvalue;
3396 int i;
3397 int chpr = 0;
3398
3399 if(PRINT_SECTION)
3400 {
3401 chpr += printf(" length %lu",dirlength);
3402 chpr = newline(chpr);
3403 }
3404
3405 /* NOTE that exposureinfo is not treated as a directory; there is */
3406 /* no 2-byte count at the beginning. */
3407
3408 end_offset = offset + dirlength;
3409 count = (dirlength / sizeof(unsigned long));
3410
3411 for(i = 0; i < count; ++i)
3412 {
3413 value = read_ulong(inptr,byteorder,offset);
3414 print_tag_address(ENTRY,offset,indent,"@");
3415 if((PRINT_ENTRY))
3416 {
3417 if((PRINT_TAGINFO))
3418 chpr += printf("%s",tagprefix);
3419 }
3420 offset += 4;
3421 switch(i)
3422 {
3423 case 0:
3424 fvalue = to_float(value);
3425 if((PRINT_TAGINFO))
3426 chpr += printf(".%02d_%-22.22s",i,"ExposureCompensation");
3427 if((PRINT_VALUE))
3428 chpr += printf(" = %f",fvalue);
3429 break;
3430 case 1:
3431 fvalue = to_float(value);
3432 if((PRINT_TAGINFO))
3433 chpr += printf(".%02d_%-22.22s",i,"Tv");
3434 if((PRINT_VALUE))
3435 chpr += printf(" = %f",fvalue);
3436 break;
3437 case 2:
3438 fvalue = to_float(value);
3439 if((PRINT_TAGINFO))
3440 chpr += printf(".%02d_%-22.22s",i,"Av");
3441 if((PRINT_VALUE))
3442 chpr += printf(" = %f",fvalue);
3443 break;
3444 default:
3445 fvalue = to_float(value);
3446 if((PRINT_TAGINFO))
3447 chpr += printf(".%02d_%-22.22s",i,"Undefined");
3448 if((PRINT_VALUE))
3449 chpr += printf(" = %f",fvalue);
3450 break;
3451 }
3452 chpr = newline(chpr);
3453 }
3454 setcharsprinted(chpr);
3455 return(end_offset);
3456 }
3457
3458
3459 unsigned long
canon_focusinfo(FILE * inptr,unsigned short byteorder,char * tagprefix,unsigned long offset,unsigned long dirlength,int indent)3460 canon_focusinfo(FILE *inptr,unsigned short byteorder,char *tagprefix,
3461 unsigned long offset,unsigned long dirlength,int indent)
3462 {
3463 unsigned long count;
3464 unsigned long end_offset;
3465 unsigned short value;
3466 int i;
3467 int chpr = 0;
3468
3469 if(PRINT_SECTION)
3470 chpr += printf(" length %lu",dirlength);
3471 chpr = newline(chpr);
3472
3473 /* NOTE that focallength is not treated as a directory; there is */
3474 /* no 2-byte count at the beginning. */
3475
3476 end_offset = offset + dirlength;
3477 count = (dirlength / sizeof(unsigned short));
3478
3479 for(i = 0; i < count; ++i)
3480 {
3481 value = read_ushort(inptr,byteorder,offset);
3482 print_tag_address(ENTRY,offset,indent,"@");
3483 if((PRINT_ENTRY))
3484 {
3485 if((PRINT_TAGINFO))
3486 chpr += printf("%s",tagprefix);
3487 }
3488 offset += 2;
3489 switch(i)
3490 {
3491 case 0:
3492 if((PRINT_TAGINFO))
3493 chpr += printf(".%02d_%-22.22s",i,"unknown");
3494 if((PRINT_VALUE))
3495 chpr += printf(" = %u",value);
3496 break;
3497 case 1:
3498 if((PRINT_TAGINFO))
3499 chpr += printf(".%02d_%-22.22s",i,"FocalLength");
3500 if((PRINT_VALUE))
3501 chpr += printf(" = %u",value);
3502 break;
3503 case 2:
3504 if((PRINT_TAGINFO))
3505 chpr += printf(".%02d_%-22.22s",i,"FocalPlaneXSize");
3506 if((PRINT_VALUE))
3507 chpr += printf(" = %u",value);
3508 break;
3509 case 3:
3510 if((PRINT_TAGINFO))
3511 chpr += printf(".%02d_%-22.22s",i,"FocalPlaneYSize");
3512 if((PRINT_VALUE))
3513 chpr += printf(" = %u",value);
3514 break;
3515 default:
3516 if((PRINT_TAGINFO))
3517 chpr += printf(".%02d_%-22.22s",i,"Undefined");
3518 if((PRINT_VALUE))
3519 chpr += printf(" = %#x%u",value,value);
3520 break;
3521 }
3522 chpr = newline(chpr);
3523 }
3524 setcharsprinted(chpr);
3525 return(end_offset);
3526 }
3527
3528 /* Some makernotes record offsets as LONG values rather than simply */
3529 /* using UNDEFINED with a size; the same technique used for */
3530 /* the ExifIFDPointer itself, or JpegInterchangeFormat, etc. */
3531 /* This routine hardcodes such tags so that the print_makerentry() */
3532 /* routine will present them as offsets. */
3533
3534 int
maker_canon_value_is_offset(struct ifd_entry * entry_ptr,int model)3535 maker_canon_value_is_offset(struct ifd_entry *entry_ptr,int model)
3536 {
3537 int is_offset = 0;
3538 int noteversion = 0;
3539
3540 if(entry_ptr)
3541 {
3542 noteversion = getnoteversion();
3543 switch(noteversion)
3544 {
3545 default:
3546 switch(entry_ptr->tag)
3547 {
3548 case 0x0081: is_offset = 1; break;
3549 default: break;
3550 }
3551 break;
3552 }
3553 }
3554 return(is_offset);
3555 }
3556
3557 /*
3558 <0xc5d9=50649> = 2 compression=6 CR2 RGB (Ifd 2)
3559
3560 <0xc5d8=50648> = 0 compression=6 primary? (biggest) CR2 Ifd 3
3561 <0xc5e0=50656> = 1 CR2 Ifd 3
3562 <0xc640-50752> = offset to 3 shorts (EOS 350D) CR2 Ifd 3
3563 <0xc640-50752> = offset to 3 shorts (EOS-1Ds Mark II) CR2 Ifd 3 2,1680,1748 (e0=3)
3564 */
3565