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_olympus.c,v 1.25 2005/07/24 22:56:26 alex Exp $";
11 #endif
12
13 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
14 /* Olympus camera maker-specific routines */
15 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
16 /* Most of the information coded here is due to TsuruZoh Tachibanaya */
17 /* at: */
18 /* http://www.ba.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html */
19 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
20 /* April, 2005: */
21 /* Much of the new information for later models is taken from */
22 /* information provided by a Phil Harvey (author of 'exiftool') at: */
23 /* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/index.html */
24 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include "defs.h"
30 #include "datadefs.h"
31 #include "maker_datadefs.h"
32 #include "summary.h"
33 #include "maker.h"
34 #include "misc.h"
35 #include "tags.h"
36 #include "extern.h"
37 #include "maker_extern.h"
38
39 extern struct camera_id olympus_model_id[];
40
41 /* Find the identifying number assigned to known Olympus camera */
42 /* models. This number is used to dispatch print and interpret */
43 /* routines approopriate to the current image. */
44
45 int
olympus_model_number(char * model,char * software)46 olympus_model_number(char *model,char *software)
47 {
48 struct camera_id *model_id;
49 int number = NO_MODEL;
50
51 for(model_id = &olympus_model_id[0]; model_id && model_id->name; ++model_id)
52 {
53 if(strncasecmp(model,model_id->name,model_id->namelen) == 0)
54 {
55 number = model_id->id;
56 setnoteversion(model_id->noteversion);
57 setnotetagset(model_id->notetagset); /* info only */
58 break;
59 }
60 }
61 return(number);
62 }
63
64 /* Dispatch a print routine based upon model */
65
66 void
print_olympus_makervalue(struct ifd_entry * entry_ptr,int make,int model,char * prefix)67 print_olympus_makervalue(struct ifd_entry *entry_ptr,int make, int model,
68 char *prefix)
69 {
70 int noteversion = 0;
71
72 noteversion = getnoteversion();
73
74 if(entry_ptr && (PRINT_VALUE))
75 {
76 switch(noteversion)
77 {
78 case 1:
79 print_olympus1_makervalue(entry_ptr,make,model,PREFIX);
80 olympus1_interpret_value(entry_ptr);
81 break;
82 default:
83 print_value(entry_ptr,PREFIX);
84 break;
85 }
86 }
87 }
88
89 /* Model-specific print routine for Olympus cameras. This routine is */
90 /* responsible for picking off any direct entry tags which are */
91 /* peculiar and will not be handled properly by print_value() */
92 /* (usually UNDEFINED values which fit in the 4-byte entry value). If */
93 /* there are no such entries, this function simply calls */
94 /* print_value(). */
95
96 void
print_olympus1_makervalue(struct ifd_entry * entry_ptr,int make,int model,char * prefix)97 print_olympus1_makervalue(struct ifd_entry *entry_ptr,int make, int model,
98 char *prefix)
99 {
100 if(entry_ptr)
101 {
102 switch(entry_ptr->tag)
103 {
104 default:
105 print_value(entry_ptr,PREFIX);
106 break;
107 }
108 }
109 }
110
111 /* Dispatch a routine to decode and print offset values for Olympus */
112 /* cameras. */
113 void
print_olympus_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)114 print_olympus_offset_makervalue(FILE *inptr,unsigned short byteorder,
115 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
116 struct image_summary *summary_entry,char *parent_name,char*prefix,
117 int indent,int make,int model,int at_offset)
118 {
119 int noteversion = 0;
120
121 noteversion = getnoteversion();
122
123 if(entry_ptr)
124 {
125 switch(noteversion)
126 {
127 case 1:
128 olympus1_offset_makervalue(inptr,byteorder,entry_ptr,
129 fileoffset_base,summary_entry,
130 parent_name,prefix,indent,
131 make,model,at_offset);
132 olympus1_interpret_offset_makervalue(inptr,byteorder,entry_ptr,
133 fileoffset_base);
134 break;
135 default:
136 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,
137 fileoffset_base,parent_name,prefix,indent,
138 make,model,at_offset);
139 break;
140 }
141 }
142 }
143
144 /* Model-specific routine to print UNDEFINED values found at offsets */
145 /* in OLYMPUS makernotes. */
146
147 void
olympus1_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)148 olympus1_offset_makervalue(FILE *inptr,unsigned short byteorder,
149 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
150 struct image_summary *summary_entry,char *parent_name,char*prefix,
151 int indent,int make,int model,int at_offset)
152 {
153 unsigned long value_offset,max_offset;
154 unsigned long dumplength;
155 unsigned long count;
156 unsigned short marker;
157 char *nameoftag;
158 char *fulldirname = CNULL;
159 int status = 0;
160 int chpr = 0;
161
162 if(entry_ptr)
163 {
164 nameoftag = maker_tagname(entry_ptr->tag,make,model);
165 if((PRINT_LONGNAMES))
166 {
167 fulldirname = splice(parent_name,".",nameoftag);
168 nameoftag = fulldirname;
169 }
170 value_offset = fileoffset_base + entry_ptr->value;
171 count = entry_ptr->count;
172 switch(entry_ptr->tag)
173 {
174 case 0x0209: /* CameraId */
175 if(at_offset)
176 {
177 print_tag_address(ENTRY,value_offset,indent,prefix);
178 print_makertagid(entry_ptr,MAKERTAGWIDTH," = ",make,model);
179 }
180 if((PRINT_VALUE))
181 print_ascii(inptr,entry_ptr->count,value_offset);
182 break;
183 case 0x0100: /* JPEG Thumbnail in TIFF MakerNote */
184 if(at_offset && (PRINT_SECTION))
185 {
186 print_tag_address(VALUE_AT_OFFSET,value_offset,indent,prefix);
187 chpr += printf("# Start of JPEG Thumbnail from MakerNote");
188 chpr += printf(" length %lu",count);
189 }
190 else if(!at_offset && (PRINT_VALUE))
191 {
192 if(!(PRINT_OFFSET))
193 chpr += printf("@%lu:%-9lu",value_offset,entry_ptr->count);
194 else
195 chpr += printf(":%-9lu", entry_ptr->count);
196 if(!(PRINT_VALUE_AT_OFFSET))
197 chpr += printf(" # UNDEFINED");
198 }
199 if((PRINT_SECTION) || (PRINT_SEGMENT))
200 chpr = newline(chpr);
201 marker = read_ushort(inptr,TIFF_MOTOROLA,value_offset);
202 setcharsprinted(chpr);
203 chpr = 0;
204 max_offset = process_jpeg_segments(inptr,value_offset,marker,
205 count,summary_entry,fulldirname,
206 prefix,indent+SMALLINDENT);
207 if(at_offset)
208 {
209 if((PRINT_SECTION))
210 {
211 if((status = jpeg_status(0) == JPEG_EARLY_EOI))
212 chpr = newline(chpr);
213 jpeg_status(status);
214 print_tag_address(VALUE_AT_OFFSET,value_offset + count - 1,
215 indent,"-");
216 chpr += printf("# End of JPEG Thumbnail from MakerNote");
217 if((PRINT_ENTRY) && !(PRINT_VALUE))
218 chpr = newline(chpr);
219 }
220 }
221 print_jpeg_status();
222 if(marker && summary_entry)
223 {
224 /* The new one is on the end of the chain */
225 if((summary_entry = last_summary_entry(summary_entry)))
226 {
227 summary_entry->filesubformat |= FILESUBFMT_MNOTE;
228 summary_entry->datatype = MAKER_IFD;
229 summary_entry->subfiletype = THUMBNAIL_TYPE;
230 }
231 }
232 /* make certain we're at the end */
233 clearerr(inptr);
234 fseek(inptr,value_offset + count,0);
235 break;
236 case 0x0f00: /* Data */
237 if(at_offset && (PRINT_ENTRY))
238 {
239 print_tag_address(ENTRY,value_offset,indent,prefix);
240 print_makertagid(entry_ptr,MAKERTAGWIDTH," : ",make,model);
241 chpr += printf("length %-9lu # UNDEFINED", count);
242 }
243 else if(!at_offset && (PRINT_VALUE))
244 {
245 if(!(PRINT_OFFSET))
246 chpr += printf("@%lu:%-9lu",value_offset,entry_ptr->count);
247 else
248 chpr += printf(":%-9lu", entry_ptr->count);
249 if(!(PRINT_VALUE_AT_OFFSET))
250 chpr += printf(" # UNDEFINED");
251 }
252 if(Max_undefined == 0)
253 {
254 if(chpr)
255 printred(" (not dumped, use -U)");
256 }
257 else
258 {
259 if((Max_undefined == DUMPALL) || (Max_undefined > count))
260 dumplength = count;
261 else
262 dumplength = Max_undefined;
263 chpr = newline(chpr);
264 hexdump(inptr,value_offset,count,dumplength,12,
265 indent,SUBINDENT);
266 chpr = newline(1);
267 }
268 /* make certain we're at the end */
269 fseek(inptr,value_offset + count,0);
270 break;
271 case 0x2010: /* Private IFD's all */
272 case 0x2020:
273 case 0x2030:
274 case 0x2040:
275 case 0x2050:
276 if(!at_offset && (PRINT_VALUE))
277 {
278 if(!(PRINT_OFFSET))
279 chpr += printf("@%lu",value_offset);
280 }
281 chpr = newline(chpr);
282 max_offset = entry_ptr->value + fileoffset_base + entry_ptr->count;
283 max_offset = process_private_ifd(inptr,byteorder,entry_ptr->value,
284 fileoffset_base,max_offset,entry_ptr->tag,
285 summary_entry,nameoftag,prefix,
286 make,model,indent);
287 break;
288 default:
289 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,
290 fileoffset_base,fulldirname,prefix,indent,
291 make,model,at_offset);
292 break;
293 }
294 if(fulldirname)
295 free(fulldirname);
296 }
297 setcharsprinted(chpr);
298 }
299
300 /* Olympus-specific tagnames for makernotes. */
301
302 /* The tagname routine is the first place in the code path which */
303 /* requires knowledge of the note version. If the version is not */
304 /* given in the model table (e.g. the model is unknown), then switch */
305 /* code in find_maker_scheme() should have set it. This routine */
306 /* repeats the check for non-zero noteversion and is prepared to set */
307 /* the noteversion first time through, but should never need to do */
308 /* so. Noteversion should always be non-zero; it should be set to -1 */
309 /* if generic processing is required. */
310
311 char *
maker_olympus_tagname(unsigned short tag,int model)312 maker_olympus_tagname(unsigned short tag,int model)
313 {
314 char *tagname = CNULL;
315 int noteversion = 0;
316
317 if((noteversion = getnoteversion()) == 0)
318 {
319 /* Need more model samples before it is safe to assume a */
320 /* default */
321 noteversion = 1;
322 setnoteversion(1);
323 }
324
325 /* Check specific models first */
326 switch(noteversion)
327 {
328 case 1:
329 tagname = maker_olympus1_tagname(tag,model);
330 break;
331 default:
332 break;
333 }
334 return(tagname);
335 }
336
337 char *
maker_olympus1_tagname(unsigned short tag,int model)338 maker_olympus1_tagname(unsigned short tag,int model)
339 {
340 char *tagname = CNULL;
341
342 switch(tag)
343 {
344 case 0x0100: tagname = "JpegThumbnail"; break;
345 case 0x0200: tagname = "SpecialMode"; break;
346 case 0x0201: tagname = "CompressionMode"; break; /* "Quality"? */
347 case 0x0202: tagname = "Macro"; break;
348 case 0x0203: tagname = "BWMode"; break;
349 case 0x0204: tagname = "DigitalZoom"; break;
350 case 0x0205: tagname = "FocalplaneDiagonal"; break;
351 case 0x0207: tagname = "SoftwareRelease"; break;
352 case 0x0208: tagname = "PictureInfo"; break;
353 case 0x0209: tagname = "CameraID"; break;
354 case 0x020b: tagname = "ImageWidth"; break; /* ? */
355 case 0x020c: tagname = "ImageHeight"; break; /* ? */
356 case 0x0f00: tagname = "Data"; break;
357
358
359 case 0x0300: tagname = "PrecaptureFrames"; break;
360 case 0x0302: tagname = "OneTouchWB"; break;
361
362
363 case 0x1004: tagname = "FlashMode"; break;
364 case 0x1005: tagname = "FlashDevice"; break;
365 case 0x1006: tagname = "Bracket"; break;
366 case 0x100b: tagname = "FocusMode"; break;
367 case 0x100c: tagname = "FocusDistance"; break;
368 case 0x100d: tagname = "Zoom"; break;
369 case 0x100e: tagname = "MacroFocus"; break;
370 case 0x100f: tagname = "SharpnessFactor"; break;
371 case 0x1011: tagname = "ColorMatrix"; break;
372 case 0x1012: tagname = "BlackLevel"; break;
373 case 0x1015: tagname = "WhiteBalance"; break;
374 case 0x1017: tagname = "RedBalance"; break;
375 case 0x1018: tagname = "BlueBalance"; break;
376 case 0x101a: tagname = "SerialNumber"; break;
377 case 0x1023: tagname = "FlashBias"; break;
378 case 0x1029: tagname = "Contrast"; break;
379 case 0x102a: tagname = "SharpnessFactor"; break;
380 case 0x102b: tagname = "ColorControl"; break;
381 case 0x102c: tagname = "ValidBits"; break;
382 case 0x102d: tagname = "CoringFilter"; break;
383 case 0x102e: tagname = "ImageWidth"; break;
384 case 0x102f: tagname = "ImageHeight"; break;
385 case 0x1034: tagname = "CompressionRatio"; break;
386 case 0x1035: tagname = "PreviewImageValid"; break;
387 case 0x1036: tagname = "PreviewImageOffset"; break;
388 case 0x1037: tagname = "PreviewImageLength"; break;
389
390 case 0x2010: tagname = "Equipment"; break; /* IFD */
391 case 0x2020: tagname = "CameraSettings"; break; /* IFD */
392 case 0x2030: tagname = "RawDevelopment"; break; /* IFD */
393 case 0x2040: tagname = "ImageProcessing"; break; /* IFD */
394 case 0x2050: tagname = "FocusInfo"; break; /* IFD */
395 default: break;
396 }
397 setnotetagset(1);
398 return(tagname);
399 }
400
401
402 void
olympus1_interpret_value(struct ifd_entry * entry_ptr)403 olympus1_interpret_value(struct ifd_entry *entry_ptr)
404 {
405 int chpr = 0;
406
407 if(entry_ptr && (PRINT_VALUE))
408 {
409 switch(entry_ptr->tag)
410 {
411 case 0x0201: /* Compression Mode */
412 print_startvalue();
413 /* This appears to report "compression" only, while the */
414 /* camera's "quality" setting combines compression and */
415 /* image size in incomprehensible ways. */
416 switch(entry_ptr->value)
417 {
418 case 1: chpr += printf("SQ"); break;
419 case 2: chpr += printf("HQ"); break;
420 case 3: chpr += printf("SHQ"); break;
421 case 4: chpr += printf("RAW1"); break;
422 case 6: chpr += printf("RAW2"); break;
423 case 33: chpr += printf("not compressed"); break; /* TIFF */
424 case 34: /* not sure about this one ###%%% */
425 chpr += printf("not compressed");
426 break;
427 default: printred("undefined"); break;
428 }
429 print_endvalue();
430 break;
431 case 0x0202: /* Macro */
432 print_startvalue();
433 switch(entry_ptr->value)
434 {
435 case 0: chpr += printf("Normal"); break;
436 case 1: chpr += printf("Macro"); break;
437 case 2: chpr += printf("View"); break;
438 default: printred("undefined"); break;
439 }
440 print_endvalue();
441 break;
442 default:
443 break;
444 }
445 }
446 setcharsprinted(chpr);
447 }
448
449 void
olympus1_interpret_offset_makervalue(FILE * inptr,unsigned short byteorder,struct ifd_entry * entry_ptr,unsigned long fileoffset_base)450 olympus1_interpret_offset_makervalue(FILE *inptr,unsigned short byteorder,
451 struct ifd_entry *entry_ptr,unsigned long fileoffset_base)
452 {
453 unsigned long offset,value;
454 int chpr = 0;
455
456 if((entry_ptr) && (PRINT_VALUE))
457 {
458 offset = entry_ptr->value + fileoffset_base;
459 switch(entry_ptr->tag)
460 {
461 case 0x0200: /* SpecialMode */
462 value = read_ulong(inptr,byteorder,offset);
463 print_startvalue();
464 switch(value)
465 {
466 case 0: chpr += printf("Normal"); break;
467 case 1: chpr += printf("Unkown"); break;
468 case 2: chpr += printf("Fast"); break;
469 case 3: chpr += printf("Panorama,");
470 value = read_ulong(inptr,byteorder,HERE);
471 chpr += printf("#%lu,",value);
472 value = read_ulong(inptr,byteorder,HERE);
473 switch(value)
474 {
475 case 1: chpr += printf(" Left to Right"); break;
476 case 2: chpr += printf(" Right to Left"); break;
477 case 3: chpr += printf(" Bottom to Top"); break;
478 case 4: chpr += printf(" Top to Bottom"); break;
479 default: printred(" undefined"); break;
480 }
481 break;
482 default: printred("undefined"); break;
483 }
484 print_endvalue();
485 break;
486 default:
487 break;
488 }
489 }
490 setcharsprinted(chpr);
491 }
492
493 /* ================== OLYMPUS SUBIFD ======================== */
494
495 char *
olympus_private_tagname(unsigned short tag,unsigned short subifd_ident)496 olympus_private_tagname(unsigned short tag,unsigned short subifd_ident)
497 {
498 char *tagname = CNULL;
499
500 switch(subifd_ident)
501 {
502 case 0x2010:
503 tagname = olympus_private_2010_tagname(tag);
504 break;
505 case 0x2020:
506 tagname = olympus_private_2020_tagname(tag);
507 break;
508 case 0x2030:
509 tagname = olympus_private_2030_tagname(tag);
510 break;
511 case 0x2040:
512 tagname = olympus_private_2040_tagname(tag);
513 break;
514 case 0x2050:
515 tagname = olympus_private_2050_tagname(tag);
516 break;
517 default:
518 break;
519 }
520 return(tagname);
521 }
522
523 char *
olympus_private_2010_tagname(unsigned short tag)524 olympus_private_2010_tagname(unsigned short tag)
525 {
526 char *tagname = CNULL;
527
528 switch(tag)
529 {
530 case 0x0000: tagname = "EquipmentInfoVersion"; break;
531 case 0x0100: tagname = "FirmwareVersion2"; break;
532 case 0x0101: tagname = "SerialNumber"; break;
533 case 0x0103: tagname = "FocalPlaneDiagonal"; break;
534 case 0x0104: tagname = "BodyFirmwareVersion"; break;
535 case 0x0201: tagname = "Lens"; break;
536 case 0x0202: tagname = "LensSerialNumber"; break;
537 case 0x0204: tagname = "LensFirmwareVersion"; break;
538 case 0x0206: tagname = "MaxApertureAtMaxFocal"; break;
539 case 0x0207: tagname = "MinFocalLength"; break;
540 case 0x0208: tagname = "MaxFocalLength"; break;
541 case 0x0301: tagname = "Extender"; break;
542 case 0x0302: tagname = "ExtenderSerialNumber"; break;
543 case 0x0304: tagname = "ExtenderFirmwareVersion"; break;
544 case 0x1000: tagname = "FlashType"; break;
545 case 0x1001: tagname = "FlashModel"; break;
546 case 0x1003: tagname = "FlashSerialNumber"; break;
547 case 0x1004: tagname = "FlashFirmwareVersion"; break;
548 default:
549 break;
550 }
551 return(tagname);
552 }
553
554 char *
olympus_private_2020_tagname(unsigned short tag)555 olympus_private_2020_tagname(unsigned short tag)
556 {
557 char *tagname = CNULL;
558
559 switch(tag)
560 {
561 case 0x0000: tagname = "CameraSettingsVersion"; break;
562 case 0x0100: tagname = "PreviewImageValid"; break;
563 case 0x0101: tagname = "PreviewImageOffset"; break;
564 case 0x0102: tagname = "PreviewImageLength"; break;
565 case 0x0200: tagname = "ExposureMode"; break;
566 case 0x0202: tagname = "MeteringMode"; break;
567 case 0x0300: tagname = "MacroMode"; break;
568 case 0x0301: tagname = "FocusMode"; break;
569 case 0x0302: tagname = "FocusProcess"; break;
570 case 0x0303: tagname = "AFSearch"; break;
571 case 0x0304: tagname = "AFAreas"; break;
572 case 0x0400: tagname = "FlashMode"; break;
573 case 0x0401: tagname = "FlashExposureCompensation"; break;
574 case 0x0501: tagname = "WhiteBalanceTemperature"; break;
575 case 0x0502: tagname = "WhiteBalanceBracket"; break;
576 case 0x0503: tagname = "CustomSaturation"; break;
577 case 0x0504: tagname = "ModifiedSaturation"; break;
578 case 0x0505: tagname = "ContrastSetting"; break;
579 case 0x0506: tagname = "SharpnessSetting"; break;
580 case 0x0507: tagname = "ColorSpace"; break;
581 case 0x0509: tagname = "SceneMode"; break;
582 case 0x050a: tagname = "NoiseReduction"; break;
583 case 0x050b: tagname = "DistortionCorrection"; break;
584 case 0x050c: tagname = "ShadingCompensation"; break;
585 case 0x050d: tagname = "CompressionFactor"; break;
586 case 0x050f: tagname = "Gradation"; break;
587 case 0x0600: tagname = "Sequence"; break;
588 case 0x0603: tagname = "ImageQuality2"; break;
589 default:
590 break;
591 }
592 return(tagname);
593 }
594
595 char *
olympus_private_2030_tagname(unsigned short tag)596 olympus_private_2030_tagname(unsigned short tag)
597 {
598 char *tagname = CNULL;
599
600 switch(tag)
601 {
602 case 0x0000: tagname = "RawDevVersion"; break;
603 case 0x0100: tagname = "RawDevExposureBiasValue"; break;
604 case 0x0101: tagname = "RawDevWhiteBalanceValue"; break;
605 case 0x0102: tagname = "RawDevWBFineAdjustment"; break;
606 case 0x0103: tagname = "RawDevGrayPoint"; break;
607 case 0x0104: tagname = "RawDevSaturationEmphasis"; break;
608 case 0x0105: tagname = "RawDevMemoryColorEmphasis"; break;
609 case 0x0106: tagname = "RawDevContrastValue"; break;
610 case 0x0107: tagname = "RawDevSharpnessValue"; break;
611 case 0x0108: tagname = "RawDevColorSpace"; break;
612 case 0x0109: tagname = "RawDevEngine"; break;
613 case 0x010a: tagname = "RawDevNoiseReduction"; break;
614 case 0x010b: tagname = "RawDevEditStatus"; break;
615 case 0x010c: tagname = "RawDevSettings"; break;
616 default:
617 break;
618 }
619
620 return(tagname);
621 }
622
623 char *
olympus_private_2040_tagname(unsigned short tag)624 olympus_private_2040_tagname(unsigned short tag)
625 {
626 char *tagname = CNULL;
627
628 switch(tag)
629 {
630 case 0x0000: tagname = "ImageProcessingVersion"; break;
631 case 0x0100: tagname = "RedBlueBias"; break;
632 case 0x0200: tagname = "ColorMatrix"; break;
633 case 0x0300: tagname = "SmoothingParameter1"; break;
634 case 0x0310: tagname = "SmoothingParameter2"; break;
635 case 0x0600: tagname = "SmoothingThresholds"; break;
636 case 0x0610: tagname = "SmoothingThreshold2"; break;
637 case 0x0611: tagname = "ValidBits"; break;
638 case 0x0614: tagname = "ImageWidth2"; break;
639 case 0x0615: tagname = "ImageHeight2"; break;
640 case 0x1010: tagname = "NoiseFilter2"; break;
641 case 0x1012: tagname = "ShadingCompensation2"; break;
642 default:
643 break;
644 }
645
646 return(tagname);
647 }
648
649 char *
olympus_private_2050_tagname(unsigned short tag)650 olympus_private_2050_tagname(unsigned short tag)
651 {
652 char *tagname = CNULL;
653
654 switch(tag)
655 {
656 case 0x0000: tagname = "FocusInfoVersion"; break;
657 case 0x0209: tagname = "AutoFocus?"; break;
658 case 0x0300: tagname = "ZoomPosition"; break;
659 case 0x0305: tagname = "FocusDistance"; break;
660 case 0x1201: tagname = "ExternalFlash"; break;
661 case 0x1208: tagname = "InternalFlash"; break;
662 default:
663 break;
664 }
665
666 return(tagname);
667 }
668
669 void
olympus_interpret_pe_value(struct ifd_entry * entry_ptr,unsigned short subifd_ident,char * prefix)670 olympus_interpret_pe_value(struct ifd_entry *entry_ptr,unsigned short subifd_ident,
671 char *prefix)
672 {
673 if(entry_ptr)
674 {
675 switch(subifd_ident)
676 {
677 case 0x2010:
678 olympus2010_interpret_value(entry_ptr,prefix);
679 break;
680 case 0x2020:
681 olympus2020_interpret_value(entry_ptr,prefix);
682 break;
683 case 0x2030:
684 olympus2030_interpret_value(entry_ptr,prefix);
685 break;
686 case 0x2040:
687 olympus2040_interpret_value(entry_ptr,prefix);
688 break;
689 case 0x2050:
690 olympus2050_interpret_value(entry_ptr,prefix);
691 break;
692 default:
693 break;
694 }
695 }
696 }
697
698 void
olympus2010_interpret_value(struct ifd_entry * entry_ptr,char * prefix)699 olympus2010_interpret_value(struct ifd_entry *entry_ptr,char *prefix)
700 {
701 int chpr = 0;
702
703 if(entry_ptr && (PRINT_VALUE))
704 {
705 switch(entry_ptr->tag)
706 {
707 case 0x1000:
708 print_startvalue();
709 switch(entry_ptr->value)
710 {
711 case 0: chpr += printf("None"); break;
712 case 2: chpr += printf("Simple E-System"); break;
713 case 3: chpr += printf("E-System"); break;
714 default: chpr += printf("unknown"); break;
715 }
716 print_endvalue();
717 break;
718 case 0x1001:
719 print_startvalue();
720 switch(entry_ptr->value)
721 {
722 case 1: chpr += printf("FL-20"); break;
723 case 2: chpr += printf("FL-50"); break;
724 case 3: chpr += printf("RF-11"); break;
725 case 4: chpr += printf("TF-22"); break;
726 case 5: chpr += printf("FL-36"); break;
727 default: chpr += printf("unknown"); break;
728 }
729 print_endvalue();
730 break;
731 default:
732 break;
733 }
734 }
735 setcharsprinted(chpr);
736 }
737
738
739 void
olympus2020_interpret_value(struct ifd_entry * entry_ptr,char * prefix)740 olympus2020_interpret_value(struct ifd_entry *entry_ptr,char *prefix)
741 {
742 int chpr = 0;
743
744 if(entry_ptr && (PRINT_VALUE))
745 {
746 switch(entry_ptr->tag)
747 {
748 case 0x0100:
749 print_startvalue();
750 switch(entry_ptr->value)
751 {
752 case 0: chpr += printf("No"); break;
753 case 1: chpr += printf("yes"); break;
754 default: chpr += printf("unknown"); break;
755 }
756 print_endvalue();
757 break;
758 case 0x0200:
759 print_startvalue();
760 switch(entry_ptr->value)
761 {
762 case 1: chpr += printf("Manual"); break;
763 case 3: chpr += printf("Aperture-priority"); break;
764 case 4: chpr += printf("Shutter-priority"); break;
765 case 5: chpr += printf("Program AE"); break;
766 default: chpr += printf("unknown"); break;
767 }
768 print_endvalue();
769 break;
770 case 0x0202:
771 print_startvalue();
772 switch(entry_ptr->value)
773 {
774 case 2: chpr += printf("Center Weighted"); break;
775 case 3: chpr += printf("Spot"); break;
776 case 5: chpr += printf("ESP"); break;
777 default: chpr += printf("unknown"); break;
778 }
779 print_endvalue();
780 break;
781 case 0x0300:
782 print_startvalue();
783 switch(entry_ptr->value)
784 {
785 case 0: chpr += printf("Off"); break;
786 case 1: chpr += printf("On"); break;
787 default: chpr += printf("unknown"); break;
788 }
789 print_endvalue();
790 break;
791 case 0x0301:
792 print_startvalue();
793 switch(entry_ptr->value)
794 {
795 case 0: chpr += printf("Single AF"); break;
796 case 1: chpr += printf("Sequential Shooting AF"); break;
797 case 2: chpr += printf("Continuous AF"); break;
798 case 3: chpr += printf("Multi AF"); break;
799 case 10: chpr += printf("Manual"); break;
800 default: chpr += printf("unknown"); break;
801 }
802 print_endvalue();
803 break;
804 case 0x0302:
805 print_startvalue();
806 switch(entry_ptr->value)
807 {
808 case 0: chpr += printf("AF Off"); break;
809 case 1: chpr += printf("AF On"); break;
810 default: chpr += printf("unknown"); break;
811 }
812 print_endvalue();
813 break;
814 case 0x0303:
815 print_startvalue();
816 switch(entry_ptr->value)
817 {
818 case 0: chpr += printf("Not Ready"); break;
819 case 1: chpr += printf("Ready"); break;
820 default: chpr += printf("unknown"); break;
821 }
822 print_endvalue();
823 break;
824 case 0x0504:
825 print_startvalue();
826 switch(entry_ptr->value)
827 {
828 case 0: chpr += printf("Off"); break;
829 case 1: chpr += printf("CM1 (Red Enhance)"); break;
830 case 2: chpr += printf("CM2 (Green Enhance)"); break;
831 case 3: chpr += printf("CM3 (Blue Enhance)"); break;
832 case 4: chpr += printf("CM4 (Skin Tones)"); break;
833 default: chpr += printf("unknown"); break;
834 }
835 print_endvalue();
836 break;
837 case 0x0507:
838 print_startvalue();
839 switch(entry_ptr->value)
840 {
841 case 0: chpr += printf("sRGB"); break;
842 case 1: chpr += printf("Adobe RGB"); break;
843 case 2: chpr += printf("Pro Photo RGB"); break;
844 default: chpr += printf("unknown"); break;
845 }
846 print_endvalue();
847 break;
848 case 0x0509:
849 print_startvalue();
850 switch(entry_ptr->value)
851 {
852 case 0: chpr += printf("Standard"); break;
853 case 7: chpr += printf("Sport"); break;
854 case 8: chpr += printf("Portrait"); break;
855 case 9: chpr += printf("Landscape+Portrait"); break;
856 case 10: chpr += printf("Landscape"); break;
857 case 11: chpr += printf("Night schene"); break;
858 case 17: chpr += printf("Night+Portrait"); break;
859 case 19: chpr += printf("Fireworks"); break;
860 case 20: chpr += printf("Sunset"); break;
861 case 22: chpr += printf("Macro"); break;
862 case 25: chpr += printf("Documents"); break;
863 case 26: chpr += printf("Museum"); break;
864 case 28: chpr += printf("Beach&Snow"); break;
865 case 30: chpr += printf("Candle"); break;
866 case 39: chpr += printf("High Key"); break;
867 default: chpr += printf("unknown"); break;
868 }
869 print_endvalue();
870 break;
871 case 0x050a:
872 print_startvalue();
873 switch(entry_ptr->value)
874 {
875 case 0: chpr += printf("Off"); break;
876 case 1: chpr += printf("Noise Reduction On"); break;
877 case 2: chpr += printf("Noise Filter On"); break;
878 case 3: chpr += printf("Noise Reduction + Noise Filter On"); break;
879 default: chpr += printf("unknown"); break;
880 }
881 print_endvalue();
882 break;
883 case 0x050b:
884 print_startvalue();
885 switch(entry_ptr->value)
886 {
887 case 0: chpr += printf("Off"); break;
888 case 1: chpr += printf("On"); break;
889 default: chpr += printf("unknown"); break;
890 }
891 print_endvalue();
892 break;
893 case 0x050c:
894 print_startvalue();
895 switch(entry_ptr->value)
896 {
897 case 0: chpr += printf("Off"); break;
898 case 1: chpr += printf("On"); break;
899 default: chpr += printf("unknown"); break;
900 }
901 print_endvalue();
902 break;
903 case 0x050f:
904 print_startvalue();
905 switch(entry_ptr->value)
906 {
907 case -1: chpr += printf("Low Key"); break;
908 case 0: chpr += printf("Normal"); break;
909 case 1: chpr += printf("High Key"); break;
910 default: chpr += printf("unknown"); break;
911 }
912 print_endvalue();
913 break;
914 case 0x0600:
915 chpr += printf("%#x,%#x",(unsigned short)entry_ptr->value & 0xffff,(unsigned short)((entry_ptr->value & 0xffff0000) >> 16));
916 break;
917 case 0x0603:
918 print_startvalue();
919 switch(entry_ptr->value)
920 {
921 case 1: chpr += printf("SQ"); break;
922 case 2: chpr += printf("HQ"); break;
923 case 3: chpr += printf("SHQ"); break;
924 case 4: chpr += printf("RAW1"); break;
925 case 6: chpr += printf("RAW2"); break;
926 case 33: chpr += printf("not compressed"); break;
927 case 34: /* not sure about this one ###%%% */
928 chpr += printf("not compressed");
929 break;
930 default: chpr += printf("unknown"); break;
931 }
932 print_endvalue();
933 break;
934 default:
935 break;
936 }
937 }
938 setcharsprinted(chpr);
939 }
940
941
942 void
olympus2030_interpret_value(struct ifd_entry * entry_ptr,char * prefix)943 olympus2030_interpret_value(struct ifd_entry *entry_ptr,char *prefix)
944 {
945 if(entry_ptr && (PRINT_VALUE))
946 {
947 switch(entry_ptr->tag)
948 {
949 default:
950 break;
951 }
952 }
953 }
954
955
956 void
olympus2040_interpret_value(struct ifd_entry * entry_ptr,char * prefix)957 olympus2040_interpret_value(struct ifd_entry *entry_ptr,char *prefix)
958 {
959 if(entry_ptr && (PRINT_VALUE))
960 {
961 switch(entry_ptr->tag)
962 {
963 default:
964 break;
965 }
966 }
967 }
968
969 void
olympus2050_interpret_value(struct ifd_entry * entry_ptr,char * prefix)970 olympus2050_interpret_value(struct ifd_entry *entry_ptr,char *prefix)
971 {
972 if(entry_ptr && (PRINT_VALUE))
973 {
974 switch(entry_ptr->tag)
975 {
976 default:
977 break;
978 }
979 }
980 }
981
982 /* Pick the appropriate offset value processor for Olympus private */
983 /* IFDs based upon noteversion. */
984
985 void
olympus_offset_pe_value(FILE * inptr,unsigned short byteorder,struct ifd_entry * entry_ptr,unsigned long fileoffset_base,unsigned short subifd_ident,struct image_summary * summary_entry,char * parent_name,char * prefix,int indent,int make,int model,int at_offset)986 olympus_offset_pe_value(FILE *inptr,unsigned short byteorder,
987 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
988 unsigned short subifd_ident,struct image_summary *summary_entry,
989 char *parent_name,char*prefix,
990 int indent,int make,int model,int at_offset)
991 {
992 int noteversion = 0;
993
994 noteversion = getnoteversion();
995
996 if(entry_ptr)
997 {
998 switch(noteversion)
999 {
1000 case 1:
1001 olympus1_offset_pe_value(inptr,byteorder,entry_ptr,
1002 fileoffset_base,subifd_ident,
1003 summary_entry,parent_name,prefix,
1004 indent,make,model,at_offset);
1005 olympus1_interpret_offset_pe_value(inptr,byteorder,entry_ptr,
1006 fileoffset_base,subifd_ident);
1007 break;
1008 default:
1009 print_private_offset_value(inptr,byteorder,entry_ptr,
1010 fileoffset_base,subifd_ident,
1011 parent_name,prefix,indent,
1012 make,model,at_offset);
1013 break;
1014 }
1015 }
1016 }
1017
1018 /* Pick the appropriate offset value processor for Olympus */
1019 /* noteversion 1 private IFDs, based upon the tag number of the IFD. */
1020
1021 void
olympus1_offset_pe_value(FILE * inptr,unsigned short byteorder,struct ifd_entry * entry_ptr,unsigned long fileoffset_base,unsigned short subifd_ident,struct image_summary * summary_entry,char * parent_name,char * prefix,int indent,int make,int model,int at_offset)1022 olympus1_offset_pe_value(FILE *inptr,unsigned short byteorder,
1023 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
1024 unsigned short subifd_ident,struct image_summary *summary_entry,
1025 char *parent_name,char*prefix,
1026 int indent,int make,int model,int at_offset)
1027 {
1028 if(entry_ptr)
1029 {
1030 switch(subifd_ident)
1031 {
1032 case 0x2010:
1033 olympus2010_offset_value(inptr,byteorder,entry_ptr,
1034 fileoffset_base,summary_entry,
1035 parent_name,prefix,indent,
1036 make,model,at_offset);
1037 break;
1038 case 0x2020:
1039 olympus2020_offset_value(inptr,byteorder,entry_ptr,
1040 fileoffset_base,summary_entry,
1041 parent_name,prefix,indent,
1042 make,model,at_offset);
1043 break;
1044 case 0x2030:
1045 olympus2030_offset_value(inptr,byteorder,entry_ptr,
1046 fileoffset_base,summary_entry,
1047 parent_name,prefix,indent,
1048 make,model,at_offset);
1049 break;
1050 case 0x2040:
1051 olympus2040_offset_value(inptr,byteorder,entry_ptr,
1052 fileoffset_base,summary_entry,
1053 parent_name,prefix,indent,
1054 make,model,at_offset);
1055 break;
1056 case 0x2050:
1057 olympus2050_offset_value(inptr,byteorder,entry_ptr,
1058 fileoffset_base,summary_entry,
1059 parent_name,prefix,indent,
1060 make,model,at_offset);
1061 break;
1062 default:
1063 print_private_offset_value(inptr,byteorder,entry_ptr,
1064 fileoffset_base,subifd_ident,
1065 parent_name,prefix,indent,
1066 make,model,at_offset);
1067 break;
1068 }
1069 }
1070 }
1071
1072 /* Olympus 'Equipment' IFD from Makernote (0x2010) */
1073
1074 void
olympus2010_offset_value(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)1075 olympus2010_offset_value(FILE *inptr,unsigned short byteorder,
1076 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
1077 struct image_summary *summary_entry,char *parent_name,char*prefix,
1078 int indent,int make,int model,int at_offset)
1079 {
1080 unsigned long value_offset;
1081 unsigned long count;
1082 char *nameoftag;
1083 char *fulldirname = CNULL;
1084 int chpr = 0;
1085
1086 if(entry_ptr)
1087 {
1088 nameoftag = maker_tagname(entry_ptr->tag,make,model);
1089 if((PRINT_LONGNAMES))
1090 {
1091 fulldirname = splice(parent_name,".",nameoftag);
1092 nameoftag = fulldirname;
1093 }
1094 value_offset = fileoffset_base + entry_ptr->value;
1095 count = entry_ptr->count;
1096 switch(entry_ptr->tag)
1097 {
1098 case 0x0100:
1099 case 0x0101:
1100 case 0x0102:
1101 case 0x0202:
1102 case 0x0301:
1103 case 0x0302:
1104 case 0x1003:
1105 default:
1106 print_private_offset_value(inptr,byteorder,entry_ptr,
1107 fileoffset_base,0x2010,
1108 fulldirname,prefix,indent,
1109 make,model,at_offset);
1110 break;
1111 }
1112 if(fulldirname)
1113 free(fulldirname);
1114 }
1115 setcharsprinted(chpr);
1116 }
1117
1118 /* Olympus 'CameraSettings' IFD from Makernote (0x2020) */
1119
1120 void
olympus2020_offset_value(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)1121 olympus2020_offset_value(FILE *inptr,unsigned short byteorder,
1122 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
1123 struct image_summary *summary_entry,char *parent_name,char*prefix,
1124 int indent,int make,int model,int at_offset)
1125 {
1126 static unsigned long jpegthumbnailoffset = 0UL;
1127 static unsigned long jpegthumbnailvalid = 1UL;
1128 unsigned long value_offset,max_offset;
1129 unsigned long count;
1130 unsigned short marker;
1131 char *nameoftag;
1132 char *fulldirname = CNULL;
1133 int status = 0;
1134 int chpr = 0;
1135
1136 if(entry_ptr)
1137 {
1138 nameoftag = maker_tagname(entry_ptr->tag,make,model);
1139 if((PRINT_LONGNAMES))
1140 {
1141 fulldirname = splice(parent_name,".",nameoftag);
1142 nameoftag = fulldirname;
1143 }
1144 value_offset = fileoffset_base + entry_ptr->value;
1145 count = entry_ptr->count;
1146 switch(entry_ptr->tag)
1147 {
1148 case 0x0100: /* JPEG Thumbnail valid */
1149 /* The default is 1 (valid), so this can turn off */
1150 /* processing if present and 0. Better to attempt */
1151 /* processing when invalid than miss a valid image. */
1152 jpegthumbnailvalid = value_offset;
1153 break;
1154 case 0x0101: /* JPEG Thumbnail offset */
1155 jpegthumbnailoffset = value_offset;
1156 if(!(PRINT_VALUE_AT_OFFSET))
1157 {
1158 if(!(PRINT_OFFSET))
1159 chpr += printf("@%lu",jpegthumbnailoffset);
1160 }
1161 break;
1162 case 0x0102: /* JPEG Thumbnail length */
1163 if(jpegthumbnailvalid == 0)
1164 {
1165 jpegthumbnailvalid = 0;
1166 break;
1167 }
1168 if(jpegthumbnailoffset)
1169 {
1170 count = entry_ptr->value;
1171 value_offset = jpegthumbnailoffset;
1172 jpegthumbnailoffset = 0UL;
1173 }
1174 else
1175 {
1176 printred("# Warning: no thumbnail offset");
1177 break;
1178 }
1179 indent += SMALLINDENT;
1180 if(at_offset && (PRINT_SECTION))
1181 {
1182 print_tag_address(VALUE_AT_OFFSET,value_offset,indent,prefix);
1183 chpr += printf("# Start of JPEG Thumbnail from MakerNote SubIFD");
1184 chpr += printf(" length %ld",count);
1185 }
1186 if((PRINT_SECTION) || (PRINT_SEGMENT))
1187 chpr = newline(chpr);
1188 marker = read_ushort(inptr,TIFF_MOTOROLA,value_offset);
1189 max_offset = process_jpeg_segments(inptr,value_offset,marker,
1190 count,summary_entry,fulldirname,
1191 prefix,indent+MEDIUMINDENT);
1192 if(at_offset)
1193 {
1194 if((PRINT_SECTION))
1195 {
1196 if((status = jpeg_status(0) == JPEG_EARLY_EOI))
1197 chpr = newline(chpr);
1198 jpeg_status(status);
1199 print_tag_address(VALUE_AT_OFFSET,value_offset + count - 1,
1200 indent,"-");
1201 chpr += printf("# End of JPEG Thumbnail from MakerNote SubIFD");
1202 if((PRINT_ENTRY) && !(PRINT_VALUE))
1203 chpr = newline(chpr);
1204 }
1205 }
1206 print_jpeg_status();
1207 if(marker && summary_entry)
1208 {
1209 /* The new one is on the end of the chain */
1210 if((summary_entry = last_summary_entry(summary_entry)))
1211 {
1212 summary_entry->filesubformat |= FILESUBFMT_MNOTE;
1213 summary_entry->datatype = MAKER_SUBIFD;
1214 summary_entry->subfiletype = REDUCED_RES_TYPE;
1215 }
1216 }
1217 /* make certain we're at the end */
1218 clearerr(inptr);
1219 fseek(inptr,value_offset + count,0);
1220 break;
1221 case 0x0304:
1222 case 0x0503:
1223 case 0x0505:
1224 case 0x0506:
1225 case 0x050f:
1226 default:
1227 print_private_offset_value(inptr,byteorder,entry_ptr,
1228 fileoffset_base,0x2020,
1229 fulldirname,prefix,indent,
1230 make,model,at_offset);
1231 break;
1232 }
1233 if(fulldirname)
1234 free(fulldirname);
1235 }
1236 setcharsprinted(chpr);
1237 }
1238
1239 /* Olympus 'RawDevelopment' IFD from Makernote (0x2030) */
1240
1241 void
olympus2030_offset_value(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)1242 olympus2030_offset_value(FILE *inptr,unsigned short byteorder,
1243 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
1244 struct image_summary *summary_entry,char *parent_name,char*prefix,
1245 int indent,int make,int model,int at_offset)
1246 {
1247 unsigned long value_offset;
1248 unsigned long count;
1249 char *nameoftag;
1250 char *fulldirname = CNULL;
1251 int chpr = 0;
1252
1253 if(entry_ptr)
1254 {
1255 nameoftag = maker_tagname(entry_ptr->tag,make,model);
1256 if((PRINT_LONGNAMES))
1257 {
1258 fulldirname = splice(parent_name,".",nameoftag);
1259 nameoftag = fulldirname;
1260 }
1261 value_offset = fileoffset_base + entry_ptr->value;
1262 count = entry_ptr->count;
1263 switch(entry_ptr->tag)
1264 {
1265 default:
1266 print_private_offset_value(inptr,byteorder,entry_ptr,
1267 fileoffset_base,0x2030,
1268 fulldirname,prefix,indent,
1269 make,model,at_offset);
1270 break;
1271 }
1272 if(fulldirname)
1273 free(fulldirname);
1274 }
1275 setcharsprinted(chpr);
1276 }
1277
1278 /* Olympus 'ImageProcessing' IFD from Makernote (0x2040) */
1279
1280 void
olympus2040_offset_value(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)1281 olympus2040_offset_value(FILE *inptr,unsigned short byteorder,
1282 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
1283 struct image_summary *summary_entry,char *parent_name,char*prefix,
1284 int indent,int make,int model,int at_offset)
1285 {
1286 unsigned long value_offset;
1287 unsigned long count;
1288 char *nameoftag;
1289 char *fulldirname = CNULL;
1290 int chpr = 0;
1291
1292 if(entry_ptr)
1293 {
1294 nameoftag = maker_tagname(entry_ptr->tag,make,model);
1295 if((PRINT_LONGNAMES))
1296 {
1297 fulldirname = splice(parent_name,".",nameoftag);
1298 nameoftag = fulldirname;
1299 }
1300 value_offset = fileoffset_base + entry_ptr->value;
1301 count = entry_ptr->count;
1302 switch(entry_ptr->tag)
1303 {
1304 default:
1305 print_private_offset_value(inptr,byteorder,entry_ptr,
1306 fileoffset_base,0x2040,
1307 fulldirname,prefix,indent,
1308 make,model,at_offset);
1309 break;
1310 }
1311 if(fulldirname)
1312 free(fulldirname);
1313 }
1314 setcharsprinted(chpr);
1315 }
1316
1317 /* Olympus 'FocusInfo' IFD from Makernote (0x2050) */
1318
1319 void
olympus2050_offset_value(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)1320 olympus2050_offset_value(FILE *inptr,unsigned short byteorder,
1321 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
1322 struct image_summary *summary_entry,char *parent_name,char*prefix,
1323 int indent,int make,int model,int at_offset)
1324 {
1325 unsigned long value_offset;
1326 unsigned long count;
1327 char *nameoftag;
1328 char *fulldirname = CNULL;
1329 int chpr = 0;
1330
1331 if(entry_ptr)
1332 {
1333 nameoftag = maker_tagname(entry_ptr->tag,make,model);
1334 if((PRINT_LONGNAMES))
1335 {
1336 fulldirname = splice(parent_name,".",nameoftag);
1337 nameoftag = fulldirname;
1338 }
1339 value_offset = fileoffset_base + entry_ptr->value;
1340 count = entry_ptr->count;
1341 switch(entry_ptr->tag)
1342 {
1343 default:
1344 print_private_offset_value(inptr,byteorder,entry_ptr,
1345 fileoffset_base,0x2050,
1346 fulldirname,prefix,indent,
1347 make,model,at_offset);
1348 break;
1349 }
1350 if(fulldirname)
1351 free(fulldirname);
1352 }
1353 setcharsprinted(chpr);
1354 }
1355
1356 void
olympus1_interpret_offset_pe_value(FILE * inptr,unsigned short byteorder,struct ifd_entry * entry_ptr,unsigned long fileoffset_base,unsigned short subifd_ident)1357 olympus1_interpret_offset_pe_value(FILE *inptr,unsigned short byteorder,
1358 struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
1359 unsigned short subifd_ident)
1360 {
1361 if(entry_ptr)
1362 {
1363 switch(subifd_ident)
1364 {
1365 case 0x2010:
1366 olympus2010_interpret_offset_value(inptr,byteorder,entry_ptr,fileoffset_base);
1367 break;
1368 case 0x2020:
1369 olympus2020_interpret_offset_value(inptr,byteorder,entry_ptr,fileoffset_base);
1370 break;
1371 case 0x2030:
1372 olympus2030_interpret_offset_value(inptr,byteorder,entry_ptr,fileoffset_base);
1373 break;
1374 case 0x2040:
1375 olympus2040_interpret_offset_value(inptr,byteorder,entry_ptr,fileoffset_base);
1376 break;
1377 case 0x2050:
1378 olympus2050_interpret_offset_value(inptr,byteorder,entry_ptr,fileoffset_base);
1379 break;
1380 default:
1381 break;
1382 }
1383 }
1384 }
1385
1386 void
olympus2010_interpret_offset_value(FILE * inptr,unsigned short byteorder,struct ifd_entry * entry_ptr,unsigned long fileoffset_base)1387 olympus2010_interpret_offset_value(FILE *inptr,unsigned short byteorder,
1388 struct ifd_entry *entry_ptr,unsigned long fileoffset_base)
1389 {
1390 unsigned long offset;
1391
1392 if(entry_ptr)
1393 {
1394 offset = entry_ptr->value + fileoffset_base;
1395 switch(entry_ptr->tag)
1396 {
1397 default:
1398 break;
1399 }
1400 }
1401 }
1402
1403 void
olympus2020_interpret_offset_value(FILE * inptr,unsigned short byteorder,struct ifd_entry * entry_ptr,unsigned long fileoffset_base)1404 olympus2020_interpret_offset_value(FILE *inptr,unsigned short byteorder,
1405 struct ifd_entry *entry_ptr,unsigned long fileoffset_base)
1406 {
1407 unsigned long offset;
1408
1409 if(entry_ptr)
1410 {
1411 offset = entry_ptr->value + fileoffset_base;
1412 switch(entry_ptr->tag)
1413 {
1414 default:
1415 break;
1416 }
1417 }
1418 }
1419
1420 void
olympus2030_interpret_offset_value(FILE * inptr,unsigned short byteorder,struct ifd_entry * entry_ptr,unsigned long fileoffset_base)1421 olympus2030_interpret_offset_value(FILE *inptr,unsigned short byteorder,
1422 struct ifd_entry *entry_ptr,unsigned long fileoffset_base)
1423 {
1424 unsigned long offset;
1425
1426 if(entry_ptr)
1427 {
1428 offset = entry_ptr->value + fileoffset_base;
1429 switch(entry_ptr->tag)
1430 {
1431 default:
1432 break;
1433 }
1434 }
1435 }
1436
1437 void
olympus2040_interpret_offset_value(FILE * inptr,unsigned short byteorder,struct ifd_entry * entry_ptr,unsigned long fileoffset_base)1438 olympus2040_interpret_offset_value(FILE *inptr,unsigned short byteorder,
1439 struct ifd_entry *entry_ptr,unsigned long fileoffset_base)
1440 {
1441 unsigned long offset;
1442
1443 if(entry_ptr)
1444 {
1445 offset = entry_ptr->value + fileoffset_base;
1446 switch(entry_ptr->tag)
1447 {
1448 default:
1449 break;
1450 }
1451 }
1452 }
1453
1454 void
olympus2050_interpret_offset_value(FILE * inptr,unsigned short byteorder,struct ifd_entry * entry_ptr,unsigned long fileoffset_base)1455 olympus2050_interpret_offset_value(FILE *inptr,unsigned short byteorder,
1456 struct ifd_entry *entry_ptr,unsigned long fileoffset_base)
1457 {
1458 unsigned long offset;
1459
1460 if(entry_ptr)
1461 {
1462 offset = entry_ptr->value + fileoffset_base;
1463 switch(entry_ptr->tag)
1464 {
1465 default:
1466 break;
1467 }
1468 }
1469 }
1470
1471 int
olympus_private_value_is_offset(unsigned short subifd_ident,unsigned short tag)1472 olympus_private_value_is_offset(unsigned short subifd_ident,unsigned short tag)
1473 {
1474 int is_offset = 0;
1475
1476 switch(subifd_ident)
1477 {
1478 case 0x2010: break;
1479 case 0x2020: is_offset = olympus2020_value_is_offset(tag); break;
1480 case 0x2030: break;
1481 case 0x2040: break;
1482 case 0x2050: break;
1483 default: break;
1484 }
1485 return(is_offset);
1486 }
1487
1488 int
olympus2020_value_is_offset(unsigned short tag)1489 olympus2020_value_is_offset(unsigned short tag)
1490 {
1491 int is_offset = 0;
1492
1493 switch(tag)
1494 {
1495 case 0x0100: is_offset = -1; break;
1496 case 0x0101: is_offset = 1; break;
1497 case 0x0102: is_offset = -1; break;
1498 default: break;
1499 }
1500 return(is_offset);
1501 }
1502
1503