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: interpret.c,v 1.18 2005/07/24 21:26:04 alex Exp $";
11 #endif
12 
13 #include <stdio.h>
14 
15 #include "defs.h"
16 #include "datadefs.h"
17 #include "summary.h"
18 #include "maker.h"
19 #include "misc.h"
20 #include "tags.h"
21 #include "extern.h"
22 #include "ciff.h"
23 
24 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
25 /* This file contains the functions which interpret and print         */
26 /* "meaningful" descriptions for values found in TIFF and EXIF ifds.  */
27 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
28 
29 
30 
31 static void print_aperture(FILE *,unsigned short,unsigned long);
32 static void print_brightness(FILE *,unsigned short,unsigned long);
33 static void print_shutterspeed(FILE *,unsigned short,unsigned long);
34 
35 static void print_capturetype(unsigned long);
36 static void print_colorspace(unsigned long);
37 static void print_componentsconfig(unsigned long);
38 static void print_compression(unsigned long);
39 static void print_contrast(unsigned long);
40 static void print_custom(unsigned long);
41 static void print_epfpresunit(unsigned long);
42 static void print_epcfapattern(unsigned long,unsigned long);
43 static void print_offset_epcfapattern(FILE *,struct ifd_entry *,
44                                                     unsigned long);
45 static void print_exposuremode(unsigned long);
46 static void print_exposureprogram(unsigned long);
47 static void print_filesource(unsigned long source);
48 static void print_flash(unsigned long flash);
49 static void print_gaincontrol(unsigned long);
50 static void print_jpegproc(unsigned long);
51 static void print_lightsource(unsigned long);
52 static void print_meteringmode(unsigned long);
53 static void print_newsubfiletype(unsigned long);
54 static void print_oldsubfiletype(unsigned long);
55 static void print_orientation(unsigned long);
56 static void print_photometric(unsigned long,int);
57 static void print_planarconfig(unsigned long);
58 static void print_resunit(unsigned long);
59 static void print_saturation(unsigned long);
60 static void print_scenetype(unsigned long type);
61 static void print_sensingmethod(unsigned long);
62 static void print_sharpness(unsigned long);
63 static void print_subjectdistancerange(unsigned long);
64 static void print_whitebalance(unsigned long);
65 static void print_ycbcrpositioning(unsigned long);
66 
67 static void print_35mmfocallength();
68 
69 void
interpret_value(struct ifd_entry * entry_ptr,struct image_summary * summary_entry)70 interpret_value(struct ifd_entry *entry_ptr,struct image_summary *summary_entry)
71 {
72     switch(entry_ptr->tag)
73     {
74         case TIFFTAG_Compression:
75             print_compression(entry_ptr->value);
76             break;
77         case TIFFTAG_PhotometricInterpretation:
78             print_photometric(entry_ptr->value,summary_entry->fileformat);
79             break;
80         case TIFFTAG_Orientation:
81             print_orientation(entry_ptr->value);
82             break;
83         case TIFFTAG_ResolutionUnit:
84         case EXIFTAG_FocalPlaneResolutionUnit:
85             print_resunit(entry_ptr->value);
86             break;
87         case TIFFEPTAG_FocalPlaneResolutionUnit:
88             print_epfpresunit(entry_ptr->value);
89             break;
90         case EXIFTAG_ColorSpace:
91             print_colorspace(entry_ptr->value);
92             break;
93         case EXIFTAG_MeteringMode:
94             print_meteringmode(entry_ptr->value);
95             break;
96         case TIFFEPTAG_CFAPattern:
97             print_epcfapattern(entry_ptr->value,entry_ptr->count);
98             break;
99         case TIFFEPTAG_SensingMethod:
100         case EXIFTAG_SensingMethod:
101             print_sensingmethod(entry_ptr->value);
102             break;
103         case EXIFTAG_ExposureProgram:
104             print_exposureprogram(entry_ptr->value);
105             break;
106         case EXIFTAG_ComponentsConfiguration:
107             print_componentsconfig(entry_ptr->value);
108             break;
109         case TIFFTAG_OldSubFileType:
110             print_oldsubfiletype(entry_ptr->value);
111             break;
112         case TIFFTAG_NewSubFileType:
113             print_newsubfiletype(entry_ptr->value);
114             break;
115         case TIFFTAG_PlanarConfiguration:
116             print_planarconfig(entry_ptr->value);
117             break;
118         case TIFFTAG_JpegProc:
119             print_jpegproc(entry_ptr->value);
120             break;
121         case TIFFTAG_YcbCrPositioning:
122             print_ycbcrpositioning(entry_ptr->value);
123             break;
124         case EXIFTAG_LightSource:
125             print_lightsource(entry_ptr->value);
126             break;
127         case EXIFTAG_Flash:
128             print_flash(entry_ptr->value);
129             break;
130         case  EXIFTAG_FileSource:
131             print_filesource(entry_ptr->value);
132             break;
133         case  EXIFTAG_SceneType:
134             print_scenetype(entry_ptr->value);
135             break;
136         case EXIFTAG_ExifCustomRendered:
137             print_custom(entry_ptr->value);
138             break;
139         case EXIFTAG_ExifExposureMode:
140             print_exposuremode(entry_ptr->value);
141             break;
142         case EXIFTAG_ExifWhiteBalance:
143             print_whitebalance(entry_ptr->value);
144             break;
145         case EXIFTAG_ExifDigitalZoomRatio:
146             /* Nothing to do                                          */
147             break;
148         case EXIFTAG_ExifFocalLengthIn35mmFilm:
149             print_35mmfocallength();
150             break;
151         case EXIFTAG_ExifSceneCaptureType:
152             print_capturetype(entry_ptr->value);
153             break;
154         case EXIFTAG_ExifGainControl:
155             print_gaincontrol(entry_ptr->value);
156             break;
157         case EXIFTAG_ExifContrast:
158             print_contrast(entry_ptr->value);
159             break;
160         case EXIFTAG_ExifSaturation:
161             print_saturation(entry_ptr->value);
162             break;
163         case EXIFTAG_ExifSharpness:
164             print_sharpness(entry_ptr->value);
165             break;
166         case EXIFTAG_ExifSubjectDistanceRange:
167             print_subjectdistancerange(entry_ptr->value);
168             break;
169         case EXIFTAG_ExifImageUniqueId:
170             /* Nothing to do                                          */
171             break;
172         default:
173             break;
174     }
175 }
176 
177 void
interpret_offset_value(FILE * inptr,struct ifd_entry * entry_ptr,unsigned short byteorder,unsigned long fileoffset_base)178 interpret_offset_value(FILE *inptr,struct ifd_entry *entry_ptr,unsigned short byteorder,
179                                                            unsigned long fileoffset_base)
180 {
181     unsigned long offset;
182     int chpr = 0;
183 
184     switch(entry_ptr->tag)
185     {
186         case TIFFEPTAG_CFAPattern:
187             print_offset_epcfapattern(inptr,entry_ptr,fileoffset_base);
188             break;
189         case EXIFTAG_ExposureTime:
190             setcharsprinted(printf(" sec"));
191             break;
192         case EXIFTAG_ShutterSpeedValue:
193             chpr += printf(" APEX");
194             offset = entry_ptr->value + fileoffset_base;
195             print_shutterspeed(inptr,byteorder,offset);
196             break;
197         case EXIFTAG_ApertureValue:
198         case EXIFTAG_MaxApertureValue:
199         case EXIFTAG_FNumber:
200             chpr += printf(" APEX");
201             offset = entry_ptr->value + fileoffset_base;
202             print_aperture(inptr,byteorder,offset);
203             break;
204         case EXIFTAG_BrightnessValue:
205             chpr += printf(" APEX");
206             offset = entry_ptr->value + fileoffset_base;
207             print_brightness(inptr,byteorder,offset);
208             break;
209         case EXIFTAG_FocalLength:
210             chpr += printf(" mm");
211             break;
212         case EXIFTAG_SubjectDistance:
213             chpr += printf(" meters");
214             break;
215         case EXIFTAG_ExposureBiasValue:
216             chpr += printf(" APEX");
217             break;
218     }
219     setcharsprinted(chpr);
220 }
221 
222 void
print_compression(unsigned long compvalue)223 print_compression(unsigned long compvalue)
224 {
225     char *compstr;
226     int chpr = 0;
227 
228     if((compstr = tiff_compression_string(compvalue)))
229     {
230         print_startvalue();
231         chpr += printf("%s",compstr);
232         print_endvalue();
233     }
234     setcharsprinted(chpr);
235 }
236 
237 void
print_photometric(unsigned long metric,int fileformat)238 print_photometric(unsigned long metric,int fileformat)
239 {
240     int chpr = 0;
241 
242     switch(fileformat)
243     {
244         case FILEFMT_ORF1:
245         case FILEFMT_ORF2:
246             print_startvalue();
247             switch(metric)
248             {
249                 case 1: chpr += printf("CFA 16 bit"); break;
250                 case 2: chpr += printf("CFA 12 bit"); break;
251                 default: chpr += printf("undefined"); break;
252             }
253             print_endvalue();
254             break;
255         default:
256             print_startvalue();
257             switch(metric)
258             {
259                 case 0: chpr += printf("MINISWHITE"); break;
260                 case 1: chpr += printf("MINISBLACK"); break;
261                 case 2: chpr += printf("RGB"); break;
262                 case 3: chpr += printf("Palette"); break;
263                 case 4: chpr += printf("Transparency Mask"); break;
264                 case 5: chpr += printf("Separated"); break;
265                 case 6: chpr += printf("YCbCr"); break;
266                 case 8: chpr += printf("CIELAB"); break;
267                 case 10: chpr += printf("ITULAB"); break;
268                 case 32803: chpr += printf("CFA"); break;    /* TIFFEP, DNG */
269                 case 32844: chpr += printf("CIE Log2(L)"); break;
270                 case 32845: chpr += printf("CIE Log2(L) (u',v')"); break;
271                 case 34892: chpr += printf("LinearRaw"); break;
272                 default: chpr += printf("undefined"); break;
273             }
274             print_endvalue();
275             break;
276     }
277     setcharsprinted(chpr);
278 }
279 
280 void
print_orientation(unsigned long value)281 print_orientation(unsigned long value)
282 {
283     int chpr = 0;
284 
285     print_startvalue();
286     switch(value)
287     {
288         case 1: chpr += printf("0,0 is top left"); break;
289         case 2: chpr += printf("0,0 is top right"); break;
290         case 3: chpr += printf("0,0 is bottom right"); break;
291         case 4: chpr += printf("0,0 is bottom left"); break;
292         case 5: chpr += printf("0,0 is left top"); break;
293         case 6: chpr += printf("0,0 is right top"); break;
294         case 7: chpr += printf("0,0 is right bottom"); break;
295         case 8: chpr += printf("0,0 is left bottom"); break;
296         default: chpr += printf("undefined"); break;
297     }
298     print_endvalue();
299     setcharsprinted(chpr);
300 }
301 
302 void
print_resunit(unsigned long unit)303 print_resunit(unsigned long unit)
304 {
305     int chpr = 0;
306 
307     print_startvalue();
308     switch(unit)
309     {
310         case 1: chpr += printf("no units"); break;
311         case 2: chpr += printf("pixels per inch"); break;
312         case 3: chpr += printf("pixels per cm"); break;
313         default: chpr += printf("undefined"); break;
314     }
315     print_endvalue();
316     setcharsprinted(chpr);
317 }
318 
319 void
print_epfpresunit(unsigned long unit)320 print_epfpresunit(unsigned long unit)
321 {
322     int chpr = 0;
323 
324     print_startvalue();
325     switch(unit)
326     {
327         case 1: chpr += printf("no units"); break;
328         case 2: chpr += printf("per meter"); break;
329         case 3: chpr += printf("per cm"); break;
330         case 4: chpr += printf("per mm"); break;
331         case 5: chpr += printf("per um"); break;
332         default: chpr += printf("undefined"); break;
333     }
334     print_endvalue();
335     setcharsprinted(chpr);
336 }
337 
338 void
print_epcfapattern(unsigned long value,unsigned long count)339 print_epcfapattern(unsigned long value,unsigned long count)
340 {
341     unsigned char *p;
342     int i;
343     int chpr = 0;
344 
345     p = (unsigned char *)&value;
346     print_startvalue();
347     for(i = 0; i < count; ++i)
348     {
349         if(i)
350         {
351             putchar(',');
352             ++chpr;
353         }
354         putcolorchar((unsigned short)*p++ & 0xff);
355     }
356     print_endvalue();
357     setcharsprinted(chpr);
358 }
359 
360 void
print_offset_epcfapattern(FILE * inptr,struct ifd_entry * entry_ptr,unsigned long fileoffset_base)361 print_offset_epcfapattern(FILE *inptr,struct ifd_entry *entry_ptr,
362                                     unsigned long fileoffset_base)
363 {
364     unsigned long offset;
365     unsigned short p;
366     int i;
367     int chpr = 0;
368 
369     if(inptr)
370     {
371         offset = entry_ptr->value + fileoffset_base;
372         print_startvalue();
373         for(i = 0; i < entry_ptr->count; ++i)
374         {
375             p = read_ubyte(inptr,offset++);
376             if(i)
377             {
378                 putchar(',');
379                 ++chpr;
380             }
381             putcolorchar(p & 0xff);
382         }
383         print_endvalue();
384     }
385     setcharsprinted(chpr);
386 }
387 
388 void
print_colorspace(unsigned long space)389 print_colorspace(unsigned long space)
390 {
391     int chpr = 0;
392 
393     print_startvalue();
394     if(space == 1)
395         chpr += printf("sRGB");
396     else if(space == 0xffff)
397         chpr += printf("uncalibrated");
398     else
399         chpr += printf("reserved");
400     print_endvalue();
401     setcharsprinted(chpr);
402 }
403 
404 void
print_meteringmode(unsigned long mode)405 print_meteringmode(unsigned long mode)
406 {
407     int chpr = 0;
408 
409     print_startvalue();
410     switch(mode)
411     {
412         case 0: chpr += printf("unknown"); break;
413         case 1: chpr += printf("Average"); break;
414         case 2: chpr += printf("Center Weighted Average"); break;
415         case 3: chpr += printf("Spot"); break;
416         case 4: chpr += printf("Multi Spot"); break;
417         case 5: chpr += printf("Pattern"); break;
418         case 6: chpr += printf("Partial"); break;
419         default: if(mode < 255) chpr += printf("reserved");
420             else chpr += printf("other"); break;
421     }
422     print_endvalue();
423     setcharsprinted(chpr);
424 }
425 
426 
427 void
print_sensingmethod(unsigned long method)428 print_sensingmethod(unsigned long method)
429 {
430     int chpr = 0;
431 
432     print_startvalue();
433     switch(method)
434     {
435         case 0: chpr += printf("Not defined"); break;
436         case 1: chpr += printf("Monochrome area sensor"); break;
437         case 2: chpr += printf("One-chip color area sensor"); break;
438         case 3: chpr += printf("Two-chip color area sensor"); break;
439         case 4: chpr += printf("Three-chip color area sensor"); break;
440         case 5: chpr += printf("Color sequential area sensor"); break;
441         case 7: chpr += printf("Trilinear sensor"); break;
442         case 8: chpr += printf("Color sequential linear sensor"); break;
443         default: chpr += printf("reserved"); break;
444     }
445     print_endvalue();
446     setcharsprinted(chpr);
447 }
448 
449 void
print_exposureprogram(unsigned long program)450 print_exposureprogram(unsigned long program)
451 {
452     int chpr = 0;
453 
454     print_startvalue();
455     switch(program)
456     {
457         case 0: chpr += printf("Not defined"); break;
458         case 1: chpr += printf("Manual"); break;
459         case 2: chpr += printf("Normal"); break;
460         case 3: chpr += printf("Aperture Priority"); break;
461         case 4: chpr += printf("Shutter Priority"); break;
462         case 5: chpr += printf("Creative Program"); break;
463         case 6: chpr += printf("Action Program"); break;
464         case 7: chpr += printf("Portrait Mode"); break;
465         case 8: chpr += printf("Landscape Mode"); break;
466         default:
467             if(program < 255)
468                 printf("reserved");
469             break;
470     }
471     print_endvalue();
472     setcharsprinted(chpr);
473 }
474 
475 void
print_componentsconfig(unsigned long components)476 print_componentsconfig(unsigned long components)
477 {
478     char *comp = (char *)&components;
479     int i;
480     int chpr = 0;
481 
482     print_startvalue();
483     for(i = 0; i < 4; ++i)
484     {
485         switch(*comp++)
486         {
487         case 1: putchar('Y'); break;
488         case 2: putchar('C'); putchar('b'); break;
489         case 3: putchar('C'); putchar('r'); break;
490         case 4: putchar('R'); break;
491         case 5: putchar('G'); break;
492         case 6: putchar('B'); break;
493         case 0: break;
494         default:
495             putchar('.');
496             break;
497         }
498         ++chpr;
499     }
500     print_endvalue();
501     setcharsprinted(chpr);
502 }
503 
504 
505 void
print_newsubfiletype(unsigned long type)506 print_newsubfiletype(unsigned long type)
507 {
508     int chpr = 0;
509 
510     print_startvalue();
511     switch(type)
512     {
513         case 0: chpr += printf("primary"); break;
514         case 1: chpr += printf("thumbnail"); break;
515         case 2: chpr += printf("page"); break;
516         case 4: chpr += printf("mask"); break;
517         default: chpr += printf("unknown"); break;
518     }
519     print_endvalue();
520     setcharsprinted(chpr);
521 }
522 
523 
524 void
print_oldsubfiletype(unsigned long type)525 print_oldsubfiletype(unsigned long type)
526 {
527     int chpr = 0;
528 
529     print_startvalue();
530     if(type == 1)
531         chpr += printf("primary");
532     else if(type == 2)
533         chpr += printf("thumbnail");
534     else
535         chpr += printf("unknown");
536     print_endvalue();
537     setcharsprinted(chpr);
538 }
539 
540 void
print_planarconfig(unsigned long config)541 print_planarconfig(unsigned long config)
542 {
543     int chpr = 0;
544 
545     print_startvalue();
546     if(config == 1)
547         chpr += printf("chunky/contig");
548     else if(config == 2)
549         chpr += printf("planar/separate");
550     else
551         chpr += printf("unknown");
552     print_endvalue();
553     setcharsprinted(chpr);
554 }
555 
556 void
print_jpegproc(unsigned long process)557 print_jpegproc(unsigned long process)
558 {
559     int chpr = 0;
560 
561     print_startvalue();
562     if(process == 1)
563         chpr += printf("baseline");
564     else if(process == 14)
565         chpr += printf("lossless");
566     else
567         chpr += printf("unknown");
568     print_endvalue();
569     setcharsprinted(chpr);
570 }
571 
572 void
print_ycbcrpositioning(unsigned long position)573 print_ycbcrpositioning(unsigned long position)
574 {
575     int chpr = 0;
576 
577     print_startvalue();
578     if(position == 1)
579         chpr += printf("centered");
580     else if(position == 2)
581         chpr += printf("co-sited");
582     else
583         chpr += printf("unknown");
584     print_endvalue();
585     setcharsprinted(chpr);
586 }
587 
588 void
print_lightsource(unsigned long source)589 print_lightsource(unsigned long source)
590 {
591     int chpr = 0;
592 
593     print_startvalue();
594     switch(source)
595     {
596         case 0: chpr += printf("unknown"); break;
597         case 1: chpr += printf("Daylight"); break;
598         case 2: chpr += printf("Fluorescent"); break;
599         case 3: chpr += printf("Tungsten"); break;
600         case 4: chpr += printf("Flash"); break;
601         case 9: chpr += printf("Fine weather"); break;
602         case 10: chpr += printf("Cloudy weather"); break;
603         case 11: chpr += printf("Shade"); break;
604         case 12: chpr += printf("Daylight fluorescent"); break;
605         case 13: chpr += printf("Day white fluorescent"); break;
606         case 14: chpr += printf("Cool white fluorescent"); break;
607         case 15: chpr += printf("Fluorescent"); break;
608         case 17: chpr += printf("Standard light A"); break;
609         case 18: chpr += printf("Standard light B"); break;
610         case 19: chpr += printf("Standard light C"); break;
611         case 20: chpr += printf("D65"); break;
612         case 21: chpr += printf("D55"); break;
613         case 22: chpr += printf("D75"); break;
614         case 23: chpr += printf("D50"); break;
615         case 24: chpr += printf("ISO studio tungsten"); break;
616         case 25: chpr += printf("Other light source"); break;
617         default:
618                 chpr += printf("reserved");
619             break;
620     }
621     print_endvalue();
622     setcharsprinted(chpr);
623 }
624 
625 void
print_flash(unsigned long flash)626 print_flash(unsigned long flash)
627 {
628     unsigned long bits;
629     int chpr = 0;
630 
631     print_startvalue();
632     bits = flash & 0x1;
633     if(bits != 0)
634         chpr += printf("flash fired");
635     else
636         chpr += printf("no flash");    /* there will be more          */
637     bits = (flash & 0x6) >> 1;
638     switch(bits)    /* return detection                               */
639     {
640         case 2: chpr += printf(" - return not detected"); break;
641         case 3: chpr += printf(" - return detected"); break;
642         default: break;
643     }
644     bits = (flash & 0x18) >> 3; /* flash mode                         */
645     switch(bits)
646     {
647         case 1: chpr += printf(" - compulsory"); break;
648         case 2: chpr += printf(" - suppressed"); break;
649         case 3: chpr += printf(" - auto"); break;
650         default: break;
651     }
652     bits = (flash & 0x20) >> 5; /* flash function                     */
653     if(bits != 0)
654         chpr += printf(" - no flash function present");
655     bits = (flash & 0x40) >> 6; /* red-eye                            */
656     if(bits != 0)
657         chpr += printf(" - no red-eye function present");
658     print_endvalue();
659     setcharsprinted(chpr);
660 }
661 
662 void
print_filesource(unsigned long source)663 print_filesource(unsigned long source)
664 {
665     int chpr = 0;
666 
667     print_startvalue();
668     switch(source)
669     {
670         case 0: chpr += printf("not specified"); break;
671         case 1: chpr += printf("scanner - transparent"); break;
672         case 2: chpr += printf("scanner - reflex"); break;
673         case 3: chpr += printf("DSC"); break;
674         default: chpr += printf("undefined");
675     }
676     print_endvalue();
677     setcharsprinted(chpr);
678 }
679 
680 void
print_scenetype(unsigned long type)681 print_scenetype(unsigned long type)
682 {
683     int chpr = 0;
684 
685     print_startvalue();
686     if(type == 1)
687         chpr += printf("direct photo");
688     else
689         chpr += printf("not direct photo");
690     print_endvalue();
691     setcharsprinted(chpr);
692 }
693 
694 void
print_custom(unsigned long rendered)695 print_custom(unsigned long rendered)
696 {
697     int chpr = 0;
698 
699     print_startvalue();
700     if(rendered == 0)
701         chpr += printf("Normal");
702     else if(rendered == 1)
703         chpr += printf("Custom");
704     else
705         chpr += printf("reserved");
706     print_endvalue();
707     setcharsprinted(chpr);
708 }
709 
710 void
print_exposuremode(unsigned long mode)711 print_exposuremode(unsigned long mode)
712 {
713     int chpr = 0;
714 
715     print_startvalue();
716     switch(mode)
717     {
718         case 0: chpr += printf("Auto"); break;
719         case 1: chpr += printf("Manual"); break;
720         case 2: chpr += printf("Auto Bracket"); break;
721         default: chpr += printf("???"); break;
722     }
723     print_endvalue();
724     setcharsprinted(chpr);
725 }
726 
727 void
print_whitebalance(unsigned long mode)728 print_whitebalance(unsigned long mode)
729 {
730     int chpr = 0;
731 
732     print_startvalue();
733     switch(mode)
734     {
735         case 0: chpr += printf("Auto"); break;
736         case 1: chpr += printf("Manual"); break;
737         default: chpr += printf("???"); break;
738     }
739     print_endvalue();
740     setcharsprinted(chpr);
741 }
742 
743 void
print_35mmfocallength()744 print_35mmfocallength()
745 {
746     /* %%%### */
747     printf("mm");
748     setcharsprinted(2);
749 }
750 
751 void
print_capturetype(unsigned long type)752 print_capturetype(unsigned long type)
753 {
754     int chpr = 0;
755 
756     print_startvalue();
757     switch(type)
758     {
759         case 0: chpr += printf("Standard"); break;
760         case 1: chpr += printf("Landscape"); break;
761         case 2: chpr += printf("Portrait"); break;
762         case 3: chpr += printf("Night Scene"); break;
763         default: chpr += printf("reserved"); break;
764     }
765     print_endvalue();
766     setcharsprinted(chpr);
767 }
768 
769 void
print_gaincontrol(unsigned long type)770 print_gaincontrol(unsigned long type)
771 {
772     int chpr = 0;
773 
774     print_startvalue();
775     switch(type)
776     {
777         case 0: chpr += printf("None"); break;
778         case 1: chpr += printf("Low gain up"); break;
779         case 2: chpr += printf("High gain up"); break;
780         case 3: chpr += printf("Low gain down"); break;
781         case 4: chpr += printf("Hign gain down"); break;
782         default: chpr += printf("reserved"); break;
783     }
784     print_endvalue();
785     setcharsprinted(chpr);
786 }
787 
788 void
print_contrast(unsigned long contrast)789 print_contrast(unsigned long contrast)
790 {
791     int chpr = 0;
792 
793     print_startvalue();
794     switch(contrast)
795     {
796         case 0: chpr += printf("Normal"); break;
797         case 1: chpr += printf("Soft"); break;
798         case 2: chpr += printf("Hard"); break;
799         default: chpr += printf("???"); break;
800     }
801     print_endvalue();
802     setcharsprinted(chpr);
803 }
804 
805 void
print_saturation(unsigned long saturation)806 print_saturation(unsigned long saturation)
807 {
808     int chpr = 0;
809 
810     print_startvalue();
811     switch(saturation)
812     {
813         case 0: chpr += printf("Normal"); break;
814         case 1: chpr += printf("Low"); break;
815         case 2: chpr += printf("High"); break;
816         default: chpr += printf("???"); break;
817     }
818     print_endvalue();
819     setcharsprinted(chpr);
820 }
821 
822 void
print_sharpness(unsigned long sharpness)823 print_sharpness(unsigned long sharpness)
824 {
825     int chpr = 0;
826 
827     print_startvalue();
828     switch(sharpness)
829     {
830         case 0: chpr += printf("Normal"); break;
831         case 1: chpr += printf("Soft"); break;
832         case 2: chpr += printf("Hard"); break;
833         default: chpr += printf("???"); break;
834     }
835     print_endvalue();
836     setcharsprinted(chpr);
837 }
838 
839 void
print_subjectdistancerange(unsigned long range)840 print_subjectdistancerange(unsigned long range)
841 {
842     int chpr = 0;
843 
844     print_startvalue();
845     switch(range)
846     {
847         case 0: chpr += printf("???"); break;
848         case 1: chpr += printf("Macro"); break;
849         case 2: chpr += printf("Close view"); break;
850         case 3: chpr += printf("Distant view"); break;
851         default: chpr += printf("???"); break;
852     }
853     print_endvalue();
854     setcharsprinted(chpr);
855 }
856 
857 #include <math.h>
858 
859 void
print_aperture(FILE * inptr,unsigned short byteorder,unsigned long offset)860 print_aperture(FILE *inptr,unsigned short byteorder,unsigned long offset)
861 {
862     double aperture_value,fnumber;
863     unsigned long num,denom;
864     int chpr = 0;
865 
866     num = read_ulong(inptr,byteorder,offset);
867     denom = read_ulong(inptr,byteorder,HERE);
868     aperture_value = (double)((double)num/(double)denom);
869     fnumber = pow(2.0,aperture_value/2.0);
870     print_startvalue();
871     chpr += printf("f%.1f",fnumber);
872     print_endvalue();
873     setcharsprinted(chpr);
874 }
875 
876 void
print_shutterspeed(FILE * inptr,unsigned short byteorder,unsigned long offset)877 print_shutterspeed(FILE *inptr,unsigned short byteorder,unsigned long offset)
878 {
879     double speed_value,exptime;
880     long num,denom;
881     int chpr = 0;
882 
883     num = read_ulong(inptr,byteorder,offset);
884     denom = read_ulong(inptr,byteorder,HERE);
885     speed_value = (double)((double)num/(double)denom);
886     exptime = pow(2.0,-speed_value);
887     print_startvalue();
888     chpr += printf("%g sec",exptime);
889     print_endvalue();
890     setcharsprinted(chpr);
891 }
892 
893 void
print_brightness(FILE * inptr,unsigned short byteorder,unsigned long offset)894 print_brightness(FILE *inptr,unsigned short byteorder,unsigned long offset)
895 {
896     double brightness_value,brightness;
897     long num,denom;
898     int chpr = 0;
899 
900     num = read_ulong(inptr,byteorder,offset);
901     denom = read_ulong(inptr,byteorder,HERE);
902     brightness_value = (double)((double)num/(double)denom);
903     brightness = pow(2.0,brightness_value);
904     print_startvalue();
905     chpr += printf("%.3g foot lambert",brightness);
906     print_endvalue();
907     setcharsprinted(chpr);
908 }
909