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_generic.c,v 1.40 2005/07/24 21:34:37 alex Exp $";
11 #endif
12 
13 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
14 /* "Generic" routines for makernotes which use TIFF IFD structure     */
15 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
16 
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <ctype.h>
21 
22 #include "defs.h"
23 #include "summary.h"
24 #include "maker.h"
25 #include "datadefs.h"
26 #include "maker_datadefs.h"
27 #include "camera_names.h"
28 #include "misc.h"
29 #include "tags.h"
30 #include "maker_extern.h"
31 #include "extern.h"
32 
33 /* Read a makernote at the offset given in the passed maker_entry.    */
34 
35 /* Checks for data with a TIFF IFD structure at the makernote offset, */
36 /* possibly offset by a maker name string and/or a new TIFF header    */
37 /* (e.g. some later Nikons). Notes which pass the test are scanned    */
38 /* and printed. If the note is in IFD format but the maker is         */
39 /* unknown, a "bare bones" entry will be printed, with tag numbers,   */
40 /* type, etc. If the maker is known, tag names, undefined values and  */
41 /* "interpretations" of the data may be printed. MakerNotes with      */
42 /* unknown/non-ifd structures could be dispatched to specialized      */
43 /* routines, but at this time I do not have information on any of     */
44 /* those. Unknown notes (or notes with invalid IFD entries) can be    */
45 /* dumped in hex/ascii by user option (-M). 'Undefined" data may be   */
46 /* similarly dumped by the -U option, if maker-specific routines      */
47 /* don't handle it.                                                   */
48 
49 /* The return is the offset of the end of the note; if the note       */
50 /* cannot be read, return is 0L.                                      */
51 
52 /* end_of_note: calculated from start offset and 'count' in parent    */
53 /*              entry                                                 */
54 
55 /* max_value_offset: maximum offset reached by an entry value which   */
56 /* begins within the note, as defined by the count. Used...           */
57 
58 /* max_end_offset: maximum offset reached by data referenced by any   */
59 /* entry, even if 'outside' the note                                  */
60 
61 /* value_end_offset: maximum offset reached by the current entry's    */
62 /* offset value                                                       */
63 
64 /* max_in_note_tagoffset: the starting offset of the last tag value   */
65 /* that begins within the note boundaries.                            */
66 
67 /* min_out_of_note_tagoffset: the start offset of the first tag with  */
68 /* value which starts beyond the end of the note.                     */
69 
70 /* The only rule is that thre are no rules...                         */
71 
72 unsigned long
process_makernote(FILE * inptr,unsigned short byteorder,struct ifd_entry * maker_entry,unsigned long fileoffset_base,unsigned long max_offset,struct image_summary * summary_entry,char * parent_name,int indent)73 process_makernote(FILE *inptr,unsigned short byteorder,
74                     struct ifd_entry *maker_entry,unsigned long fileoffset_base,
75                     unsigned long max_offset,struct image_summary *summary_entry,
76                     char *parent_name,int indent)
77 {
78     struct ifd_entry *entry_ptr;
79     struct maker_scheme *maker_scheme;
80     unsigned long maker_offset = 0UL;
81     unsigned long maker_count = 0UL;
82     unsigned long max_value_offset = 0UL;
83     unsigned long max_end_offset = 0UL;
84     unsigned long value_end_offset = 0UL;
85     unsigned long max_in_note_tagoffset = 0UL;
86     unsigned long min_out_of_note_tagoffset = 0UL;
87     unsigned long start_offset = 0UL;
88     unsigned long dumplength = 0UL;
89     unsigned long end_of_note = 0UL;
90     unsigned long next_ifd_offset = 0UL;
91     unsigned long current_offset;
92     unsigned long start_entry_offset;
93     unsigned long entry_offset,value_offset;
94     char *prefix,*tprefix,*swname;
95     char *nameoftag = CNULL;
96     char *fulldirname = CNULL;
97     int entry_num,num_entries,make,model;
98     int tagindent = 0;
99     int tagwidth = 0;
100     int invalid = 0;
101     int scheme_indent = 0;
102     int value_is_offset = 0;
103     int use_second_pass = 0;
104     int chpr = 0;
105 
106     if(inptr && maker_entry)
107     {
108         PUSHCOLOR(MAKER_COLOR);
109         if(summary_entry)
110             summary_entry->filesubformat |= FILESUBFMT_MNOTE;
111         /* Save these; they're in static storage in the maker_entry   */
112         /* and will be overwritten when entry reading starts.         */
113         maker_offset = maker_entry->value;
114         maker_count = maker_entry->count;
115         if(maker_count > 4UL)
116             end_of_note = maker_offset + maker_count + fileoffset_base;
117         else if(maker_count == 4UL)
118         {
119             /* special case, for certain Casio MakerNotes which use   */
120             /* 4-byte UNDEFINED as though it were a LONG offset       */
121             if(maker_entry->value_type == UNDEFINED)
122                 maker_offset = to_ulong((unsigned char *)&maker_entry->value,byteorder);
123             /* This pretty much forces maker_scheme to PLAIN          */
124             maker_count=0L;
125         }
126         else
127             goto cant_dumpit;
128 
129         /* Clear any previous scheme structure                        */
130         /* This must be done before model() number is called.         */
131         clear_makerscheme();
132         /* Get make and model from the global names saved from IFD0   */
133         /* Override real names if -m, -l, -s                          */
134         if(Use_Make_name)
135             make = maker_number(Use_Make_name);
136         else
137             make = maker_number(Make_name);
138 
139         if(Use_Software_name)
140             swname = Use_Software_name;
141         else
142             swname = Software_name;
143 
144         /* The camera-specific model number routine may fill in the   */
145         /* note_version field in the scheme structure if the model is */
146         /* recognized and has more than 1 note version. Unknown       */
147         /* models will be tested later or defaulted                   */
148         if(Use_Model_name)
149             model = model_number(make,Use_Model_name,swname);
150         else
151             model = model_number(make,Model_name,swname);
152 
153 
154         /* start_offset is where the note begins, relative to the     */
155         /* start of the file.                                         */
156         start_offset = start_entry_offset = maker_offset + fileoffset_base;
157         nameoftag = tagname(maker_entry->tag);
158         fulldirname = splice(parent_name,".",nameoftag);
159 
160         /* The MakerNote should be written within the values section  */
161         /* of the Exif ifd, but sometimes is not. 'max_offset', if    */
162         /* set, will be the end of the parent ifd (Exif). Mark it to  */
163         /* indicate that the MakerNote is out of place.               */
164         if(max_offset && (start_offset > max_offset))
165             prefix = ">";
166         else
167             prefix = "@";
168         if(PRINT_SECTION)
169         {
170             print_tag_address(SECTION,start_offset,indent,prefix);
171             chpr = printf("<%s> length %lu, ",nameoftag,
172                         maker_count ? maker_count: maker_entry->count);
173         }
174         else if(!(PRINT_VALUE_AT_OFFSET))
175         {
176             tagwidth = MAKERTAGWIDTH;
177             if(!(PRINT_LONGNAMES))
178                 tagwidth -= strlen(nameoftag) + 1;
179             /* When SECTIONS are not printed, provide these items as  */
180             /* "pseudotags".                                          */
181             if((PRINT_TAGINFO) || (PRINT_VALUE))
182                 print_tag_address(ENTRY,HERE,indent+SMALLINDENT,"*");
183             if(PRINT_TAGINFO)
184             {
185                 if((PRINT_LONGNAMES))
186                     chpr += printf("%s.",parent_name);
187                 chpr += printf("%s.",nameoftag);
188                 chpr += printf("%-*.*s",tagwidth,tagwidth,"Offset");
189             }
190             if((PRINT_VALUE))
191                 chpr += printf(" = @%lu",start_offset);
192             chpr = newline(chpr);
193             if((PRINT_TAGINFO) || (PRINT_VALUE))
194                 print_tag_address(ENTRY,HERE,indent+SMALLINDENT,"*");
195             if(PRINT_TAGINFO)
196             {
197                 if((PRINT_LONGNAMES))
198                     chpr += printf("%s.",parent_name);
199                 chpr += printf("%s.",nameoftag);
200                 chpr += printf("%-*.*s",tagwidth,tagwidth,"Length");
201             }
202             if((PRINT_VALUE))
203                 chpr += printf(" = %lu",maker_count ? maker_count: maker_entry->count);
204             chpr = newline(chpr);
205             if((PRINT_TAGINFO) || (PRINT_VALUE))
206                 print_tag_address(ENTRY,HERE,indent+SMALLINDENT,"*");
207             if(PRINT_TAGINFO)
208             {
209                 if((PRINT_LONGNAMES))
210                     chpr += printf("%s.",parent_name);
211                 chpr += printf("%s.",nameoftag);
212                 chpr += printf("%-*.*s",tagwidth,tagwidth,"Scheme");
213             }
214         }
215 
216         /* Discover, if possible, the 'scheme' by which the MakerNote */
217         /* is stored.                                                 */
218         scheme_indent = charsprinted();
219         maker_scheme = find_makerscheme(inptr,maker_offset,fileoffset_base,
220                                             byteorder,maker_count,make,model);
221 
222         /* If scheme debugging is in effect, the type info below      */
223         /* needs to be indented a bit, since the debug output splits  */
224         /* the starting <MakerNote> line.                             */
225         if(PRINT_SCHEME_DEBUG)
226             putindent(scheme_indent + chpr + 2);
227         /* Print a brief description of the scheme found. Enclose it  */
228         /* in quotes if not in a SECTION line                         */
229         if((PRINT_SECTION) || ((PRINT_VALUE) && !(PRINT_VALUE_AT_OFFSET)))
230         {
231             if(!(PRINT_SECTION))
232                 chpr += printf(" = '");
233             switch(maker_scheme->scheme_type)
234             {
235                 case HAS_ID_SCHEME:
236                     if(maker_scheme->offsets_relative_to == START_OF_NOTE)
237                         chpr += printf("Note-relative offset ");
238                     else if(maker_scheme->offsets_relative_to == START_OF_ENTRY)
239                         chpr += printf("Entry-relative offset ");
240                     chpr += printf("ID");
241                     break;
242                 case HAS_ID_PLUS_TIFFHDR_SCHEME:
243                     chpr += printf("ID+TIFFheader");
244                     break;
245                 case PLAIN_IFD_SCHEME:
246                     if(maker_scheme->offsets_relative_to == START_OF_NOTE)
247                         chpr += printf("Note-relative offset ");
248                     else if(maker_scheme->offsets_relative_to == START_OF_ENTRY)
249                         chpr += printf("Entry-relative offset ");
250                     else
251                         chpr += printf("Plain ");
252                     chpr += printf("IFD");
253                     if(maker_count == 0) /* some old Casio                */
254                         chpr += printf(" (from UNDEFINED offset)");
255                     break;
256                 /* New schemes can be added here.                         */
257                 case UNKNOWN_SCHEME:
258                 default:
259                     /* dump a couple of lines, unless user says otherwise */
260                     next_ifd_offset = 0UL;
261                     chpr += printf("unknown");
262                     if(PRINT_SECTION)
263                         chpr += printf(" scheme");
264                     if(PRINT_SECTION && !(PRINT_MAKERDUMP))
265                     {
266                         chpr = newline(1);
267                         if(maker_count < DEF_SHORTDUMP)
268                             dumplength = maker_count;
269                         else
270                             dumplength = DEF_SHORTDUMP;
271                         hexdump(inptr,start_offset,maker_count,dumplength,12,
272                                     indent,SUBINDENT);
273                         if(maker_count > dumplength)
274                         {
275                             printred(" (use -M to see more)");
276                             chpr = newline(1);
277                         }
278                     }
279                     else if((PRINT_VALUE))
280                             printf("'");
281                     chpr = newline(chpr);
282                     if(PRINT_MAKERNOTE_SCHEME)
283                         print_scheme(inptr,maker_scheme);
284                     goto dumpit;
285                     break;
286             }
287             if(!(PRINT_SECTION))
288                 chpr = printf("'");
289         }
290         else
291             chpr = newline(chpr);
292 
293         /* If printing a value in LIST mode, it's done; if in the     */
294         /* middle of a section heading in SECTION mode, there's more  */
295         /* heading to print.                                          */
296         if(PRINT_SECTION)
297             chpr += printf(" scheme,");
298         else if((PRINT_VALUE))
299             chpr = newline(chpr);
300         num_entries = maker_scheme->num_entries;
301         byteorder = maker_scheme->note_byteorder;
302         if((maker_scheme->scheme_type == HAS_ID_PLUS_TIFFHDR_SCHEME) ||
303                 (maker_scheme->offsets_relative_to == START_OF_NOTE))
304         {
305             fileoffset_base = maker_scheme->fileoffset_base;
306             start_entry_offset = fileoffset_base + maker_scheme->ifd_offset + 2;
307         }
308         else
309             start_entry_offset = start_offset + maker_scheme->ifd_offset + 2;
310         if(PRINT_SECTION)
311         {
312             chpr = printf(" %d entries starting at offset %#lx/%lu",num_entries,
313                         start_entry_offset,start_entry_offset);
314             chpr = newline(chpr);
315         }
316         if(PRINT_MAKERNOTE_SCHEME)
317             print_scheme(inptr,maker_scheme);
318 
319         if((maker_scheme->id_length > 0) && (PRINT_ENTRY))
320         {
321             print_tag_address(ENTRY,start_offset, indent,prefix);
322             extraindent(SUBINDENT);
323             if((PRINT_LONGNAMES))
324                 chpr += printf("%s.%s.",parent_name,nameoftag);
325             chpr = printf("%sId",nameoftag);
326             if((PRINT_VALUE))
327             {
328                 tagwidth = MAKERTAGWIDTH - strlen(nameoftag) - 2;
329                 putindent(tagwidth);
330                 chpr += printf(" = '%s'",maker_scheme->id);
331             }
332             chpr = newline(chpr);
333         }
334 
335         if(((maker_scheme->scheme_type == HAS_ID_PLUS_TIFFHDR_SCHEME)) &&
336                     (PRINT_SECTION))
337         {
338             print_tag_address(SECTION,fileoffset_base,indent + SMALLINDENT,prefix);
339             if(print_tiff_header(TIFF_MAGIC,maker_scheme->note_byteorder,SECTION) == 0)
340             {
341                 chpr = printf(" ifd offset = %#x/%d)",maker_scheme->ifd_offset,
342                                                     maker_scheme->ifd_offset);
343                 if(fileoffset_base)
344                 {
345                     chpr += printf(" (+ %lu = %#lx/%lu)",fileoffset_base,
346                                             fileoffset_base + maker_scheme->ifd_offset,
347                                             fileoffset_base + maker_scheme->ifd_offset);
348                 }
349             }
350             chpr = newline(chpr);
351         }
352 
353         /* At this point, the note has been "verified" to be in TIFF  */
354         /* IFD format, and can be read normally in that fashion.      */
355         /* Maker-specific information is handled in the print_maker   */
356         /* routines, according to the noteversion derived from the    */
357         /* make and model numbers.                                    */
358 
359         /* Scheme validation is not entirely robust, however, so the  */
360         /* code below bails out at the first sign of an invalid       */
361         /* entry, and hexdumps the data if wanted.                    */
362 
363         indent += SMALLINDENT;
364         current_offset = entry_offset = start_entry_offset;
365         value_is_offset = 0;
366         for(entry_num = 0; entry_num < num_entries; ++entry_num)
367         {
368             print_tag_address(ENTRY,entry_offset,indent,prefix);
369             tagindent = charsprinted();  /* in case error msg needed   */
370             entry_ptr = read_ifd_entry(inptr,byteorder,entry_offset);
371             if((entry_ptr->value_type == 0) || (entry_ptr->value_type > DOUBLE) ||
372                                                     ferror(inptr) || feof(inptr))
373             {
374                 ++invalid;
375             }
376             else
377                 invalid = 0;
378             if(maker_scheme->offsets_relative_to == START_OF_ENTRY)
379                 fileoffset_base = entry_offset;
380             entry_offset = current_offset = ftell(inptr);
381             value_offset = print_makerentry(inptr,byteorder,
382                                             entry_ptr,fileoffset_base,
383                                             summary_entry,fulldirname,
384                                             indent,make,model);
385             if(invalid > 5)
386             {
387                 if((PRINT_SECTION))
388                 {
389                     PUSHCOLOR(RED);
390                     chpr += printf(" TOO MANY INVALID ENTRIES");
391                     if((PRINT_MAKERDUMP))
392                         chpr += printf(" (hexdump follows)");
393                     else
394                         chpr += printf(" (Use -M to hex/ascii dump)");
395                     POPCOLOR();
396                     chpr = newline(chpr);
397                 }
398                 else
399                 {
400                     chpr = newline(chpr);
401                     PUSHCOLOR(RED);
402                     chpr += printf("# WARNING: TOO MANY INVALID MAKERNOTE ENTRIES");
403                     chpr += printf(" (note processing aborted)");
404                     POPCOLOR();
405                     chpr = newline(chpr);
406                 }
407                 goto dumpit;
408             }
409             if(value_offset == 0UL)
410                 value_offset = entry_offset;
411             if(end_of_note)
412             {
413                 if((value_offset < end_of_note) && (value_offset > max_value_offset))
414                     max_value_offset = value_offset;
415             }
416             else if(value_offset > max_value_offset);
417                 max_value_offset = value_offset;
418             if((is_offset(entry_ptr) || maker_value_is_offset(entry_ptr,make,model)))
419                 ++use_second_pass;
420         }
421 
422         /* Some makers write the next ifd offset as 0, as is normal   */
423         /* for an IFD. Some write nothing.                            */
424         if(maker_scheme->no_nextifd_offset)
425         {
426             next_ifd_offset = 0L;
427             if((PRINT_SECTION) && (PRINT_ENTRY))
428             {
429                 /* Since it isn't needed, just note it and move on.       */
430                 print_tag_address(SECTION,current_offset,indent,prefix);
431                 printred("no next IFD offset used");
432                 chpr = newline(1);
433             }
434         }
435         else
436         {
437             next_ifd_offset = read_ulong(inptr,byteorder,current_offset);
438             if(next_ifd_offset > 0L)
439             {
440                 /* This should not happen, of course.                     */
441                 if((PRINT_ADDRESS) && (PRINT_VALUE) && (PRINT_VALUE_AT_OFFSET))
442                 {
443                     print_tag_address(ENTRY,current_offset,indent,prefix);
444                     chpr += printf("**** next IFD offset %lu  ",next_ifd_offset);
445                     next_ifd_offset += fileoffset_base;
446                     chpr += printf("(+ %lu = %#lx/%lu)",fileoffset_base,
447                                 next_ifd_offset,next_ifd_offset);
448                     if(next_ifd_offset < ftell(inptr))
449                     {
450                         printred(" # BAD NEXT IFD OFFSET");
451                         next_ifd_offset = 0L;
452                     }
453                     chpr = newline(chpr);
454                 }
455                 else
456                     next_ifd_offset += fileoffset_base;
457             }
458             else
459             {
460                 if((PRINT_ADDRESS) && (PRINT_VALUE) && (PRINT_VALUE_AT_OFFSET))
461                 {
462                     print_tag_address(ENTRY,current_offset,indent,prefix);
463                     chpr = printf("**** next IFD offset 0");
464                     chpr = newline(chpr);
465                 }
466             }
467         }
468 
469         if(ferror(inptr))
470         {
471             chpr = printf(" READ NEXT IFD OFFSET FAILED ");
472             why(stdout);
473             clearerr(inptr);    /* keep going...                      */
474             chpr = newline(1);
475         }
476         else
477             current_offset = ftell(inptr);
478 
479         value_offset = current_offset;
480         if((max_value_offset == 0) || (current_offset > max_value_offset))
481             max_value_offset = current_offset;
482 
483         /* Make a second pass over the entries, to print values of    */
484         /* entries whose values are indirect.                         */
485         if(use_second_pass)
486         {
487 
488             if((PRINT_VALUE) && (PRINT_ADDRESS) && (PRINT_VALUE_AT_OFFSET))
489             {
490                 print_tag_address(ENTRY,value_offset,indent,prefix);
491                 chpr = printf("============= VALUES, %s ============",nameoftag);
492                 chpr = newline(chpr);
493             }
494 
495             entry_offset = start_entry_offset;
496             for(entry_num = 0; entry_num < num_entries; ++entry_num)
497             {
498                 entry_ptr = read_ifd_entry(inptr,byteorder,entry_offset);
499                 if(ferror(inptr))   /* why didn't this happen above?  */
500                     goto dumpit;
501                 if(maker_scheme->offsets_relative_to == START_OF_ENTRY)
502                     fileoffset_base = entry_offset;
503                 entry_offset = current_offset = ftell(inptr);
504                 if(is_offset(entry_ptr) || maker_value_is_offset(entry_ptr,make,model))
505                 {
506                     /* If this is negative, it is assumed to be a     */
507                     /* length value which is intended to trigger      */
508                     /* processing of the previous entry, which is an  */
509                     /* offset (usually of a thumbnail which is        */
510                     /* specified by two tags)...so use the previous   */
511                     /* value_offset. Don't violate this convention!   */
512                     if(maker_value_is_offset(entry_ptr,make,model) >= 0)
513                         value_offset = fileoffset_base + entry_ptr->value;
514                     if(Debug & 0x10)
515                         printf("SL:mvo=%lu,vo=%lu,veo=%lu, en=%lu ### prefix='%s'\n",
516                                 max_value_offset,value_offset,value_end_offset,end_of_note,prefix);
517                     if((value_type_size(entry_ptr->value_type) * entry_ptr->count) <= 4UL)
518                         value_end_offset = 0;
519                     else
520                         value_end_offset = value_offset +
521                             (value_type_size(entry_ptr->value_type) * entry_ptr->count);
522                     if(value_offset > end_of_note)
523                     {
524                         if(*prefix == '>')
525                             tprefix = "+";
526                         else
527                             tprefix = ">";
528                     }
529                     else
530                         tprefix = prefix;
531                     if(Debug & 0x10)
532                         printf("BP:mvo=%lu,vo=%lu,veo=%lu, meo=%lu, en=%lu ### prefix=%s\n",
533                                             max_value_offset,value_offset,value_end_offset,
534                                                         max_end_offset,end_of_note,prefix);
535                     if((PRINT_VALUE_AT_OFFSET))
536                     {
537                         value_end_offset =
538                             print_offset_makervalue(inptr,byteorder,entry_ptr,
539                                         fileoffset_base,summary_entry,fulldirname,
540                                                     tprefix,indent,make,model,1);
541                     }
542                     if(Debug & 0x10)
543                         printf("AP:mvo=%lu,vo=%lu,veo=%lu, meo=%lu, en=%lu ### prefix=%s\n",
544                                             max_value_offset,value_offset,value_end_offset,
545                                                         max_end_offset,end_of_note,prefix);
546                     /* If the value is a section which STARTS past    */
547                     /* the announced end of the makernote it should   */
548                     /* not be regarded as part of the makernote, and  */
549                     /* should not contribute to the offset returned   */
550                     /* from this routine.                             */
551                     if(end_of_note)
552                     {
553                         if((value_offset < end_of_note) && (value_end_offset > max_value_offset))
554                         {
555                             max_value_offset = value_end_offset;
556                             max_in_note_tagoffset = value_offset;
557                         }
558                     }
559                     else if((value_end_offset > max_value_offset))
560                             max_value_offset = value_end_offset;
561                     /* Keep track of actual maximum; tattle later     */
562                     if(value_end_offset > max_end_offset)
563                         max_end_offset = value_end_offset;
564                     if(end_of_note)
565                     {
566                         if((value_offset > end_of_note) && (min_out_of_note_tagoffset == 0))
567                             min_out_of_note_tagoffset = value_offset;
568                     }
569                     if(Debug & 0x10)
570                         printf("EL:mvo=%lu,vo=%lu,veo=%lu, meo=%lu, en=%lu ### prefix=%s\n",
571                                             max_value_offset,value_offset,value_end_offset,
572                                                         max_end_offset,end_of_note,prefix);
573                 }
574                 current_offset = ftell(inptr);
575             }
576         }
577         else if(current_offset > max_value_offset)
578             max_value_offset = current_offset;
579 
580         indent -= SMALLINDENT;
581         /* If the note is incompletely specified, point that out. If  */
582         /* IFD entries are not being printed this message is not      */
583         /* wanted.                                                    */
584         if((end_of_note && (max_value_offset < end_of_note)) &&
585                                         (PRINT_SECTION) && (PRINT_ENTRY) &&
586                                             !(LIST_MODE))
587         {
588             unsigned long printlength = 0;
589 
590             print_tag_address(ENTRY,max_value_offset - 1,indent + SMALLINDENT,
591                                                                 "*");
592             chpr = printf("---- End of values before end of %s",nameoftag);
593             chpr = newline(chpr);
594             dumplength = end_of_note - max_value_offset;
595             /* dump at least the first couple of rows, just to see... */
596             if(PRINT_MAKERDUMP)
597             {
598                 if((Max_makerdump == DUMPALL) || (Max_makerdump > dumplength))
599                     printlength = dumplength;
600                 else if(Max_makerdump > 0L)
601                     printlength = Max_makerdump;
602                 else if(Max_undefined > 0L)
603                     printlength = Max_undefined > dumplength ? Max_undefined : dumplength;
604             }
605             else    /* always print a little bit in this case         */
606             {
607                 if(dumplength > DEF_SHORTDUMP)
608                     printlength = DEF_SHORTDUMP;
609                 else
610                     printlength = dumplength;
611             }
612             hexdump(inptr,max_value_offset,dumplength,printlength,12,
613                             indent,SUBINDENT);
614             if(dumplength > printlength)
615                 printred(" (use -M to see more)");
616             chpr = newline(1);
617         }
618         else if(maker_count == 0L)
619         {
620             end_of_note = max_value_offset - 1;
621             maker_count = end_of_note - start_offset;
622             if(!(PRINT_SECTION) && !(PRINT_VALUE_AT_OFFSET) && (PRINT_ENTRY))
623             {
624                 tagwidth = MAKERTAGWIDTH;
625                 if(!(PRINT_LONGNAMES))
626                     tagwidth -= strlen(nameoftag) - 1;
627                 /* rewrite this pseudotag, since the first one was    */
628                 /* wrong                                              */
629                 chpr = newline(chpr);
630                 if((PRINT_TAGINFO) || (PRINT_VALUE))
631                     print_tag_address(ENTRY,HERE,indent+SMALLINDENT,prefix);
632                 if(PRINT_TAGINFO)
633                 {
634                     if((PRINT_LONGNAMES))
635                         chpr += printf("%s.",parent_name);
636                     chpr += printf("%s.",nameoftag);
637                     chpr += printf("%-*.*s",tagwidth,tagwidth,"Length");
638                 }
639                 if((PRINT_VALUE))
640                     chpr += printf(" = %lu",maker_count);
641             }
642         }
643         if(Debug & 0x10)
644             printf("END: mvo=%lu, en=%lu, meo=%lu\n",max_value_offset,end_of_note,max_end_offset);
645         if(end_of_note && (max_value_offset > (end_of_note + 1)) && max_in_note_tagoffset)
646         {
647             print_tag_address(SECTION,max_in_note_tagoffset,indent + SMALLINDENT,"!");
648             printred("# WARNING: values extend past end of MakerNote");
649             chpr = newline(chpr);
650         }
651         if(end_of_note && (max_end_offset > (end_of_note + 1)) && min_out_of_note_tagoffset)
652         {
653             print_tag_address(SECTION,min_out_of_note_tagoffset,indent + SMALLINDENT,"!");
654             printred("# WARNING: values referenced outside of MakerNote");
655             chpr = newline(chpr);
656         }
657 
658         print_tag_address(SECTION,end_of_note - 1,indent,prefix);
659         if(PRINT_SECTION)
660             chpr = printf("</%s>",nameoftag);
661         if(next_ifd_offset)
662         {
663             if((PRINT_SECTION))
664                 chpr += printf(" ");
665             PUSHCOLOR(RED);
666             chpr = printf("# WARNING! MakerNote has next ifd offset %lu",next_ifd_offset);
667             POPCOLOR();
668         }
669         chpr = newline(chpr);
670         POPCOLOR();
671         if(fulldirname)
672             free(fulldirname);
673         fulldirname = CNULL;
674     }
675     /* The offset passed back to the caller may be higher than the    */
676     /* offset written above for the end of the note, if values are    */
677     /* referenced past advertised end of note in a chunk that began   */
678     /* before end of note.                                            */
679     if(max_value_offset > end_of_note)
680         end_of_note = max_value_offset;
681     return(end_of_note);
682 
683 dumpit:
684     if(PRINT_MAKERDUMP)
685     {
686         /* If no specific length is given for makernote data, limit   */
687         /* the dump length to the length specified for undefined      */
688         /* data.                                                      */
689         if(Max_makerdump == DUMPALL)
690             dumplength = maker_count;
691         else if(Max_makerdump > 0L)
692         {
693             dumplength = Max_makerdump;
694             /* In case the maker_count is botched, dump as much as    */
695             /* asked                                                  */
696             if(maker_count < dumplength)
697                 maker_count = dumplength;
698         }
699         else
700             dumplength = Max_undefined;
701         if(dumplength > 0L)
702         {
703             chpr = newline(chpr);
704             hexdump(inptr,start_offset,maker_count,dumplength,12,
705                     indent,SUBINDENT);
706             chpr = newline(1);
707         }
708     }
709     if(PRINT_SECTION)
710     {
711         print_tag_address(SECTION,end_of_note - 1,indent,"-");
712         chpr = printf("</MakerNote>");
713     }
714     POPCOLOR();
715     chpr = newline(chpr);
716     clearerr(inptr);
717     if(maker_count)
718         return(end_of_note);
719     return(0L);
720 cant_dumpit:
721     clearerr(inptr);
722     chpr = printf(" INVALID MakerNote offset %lu",maker_offset);
723     chpr = newline(chpr);
724     return(0L);
725 }
726 
727 /* Return a unique number for a given maker, (assigned in "maker.h")  */
728 /* based upon a string, usually taken from a "Make" tag. This "magic  */
729 /* number" will be used to select routines to print tagnames and to   */
730 /* interpret data from MakerNotes for that maker.                     */
731 
732 int
maker_number(char * make)733 maker_number(char *make)
734 {
735     struct camera_name *maker_id;
736     int number = NO_MAKE;
737 
738     /* 'Camera_make' is a global parameter                            */
739     for(maker_id = Camera_make; maker_id && maker_id->name; ++maker_id)
740     {
741         if(strncasecmp(make,maker_id->name,maker_id->namelen) == 0)
742         {
743             number = maker_id->id;
744             break;
745         }
746     }
747     return(number);
748 }
749 
750 /* Call a maker-specific routine to assign an identifying number for  */
751 /* a specific model of a given maker's camera. The camera make is     */
752 /* identified by the number assigned by make_number(), and is used to */
753 /* dispatch the maker-specific routine, which is then free to pick an */
754 /* identifying number based upon the "Model" tag and possibly the     */
755 /* "Software" tag. The numbers are assigned in "maker.h". Model       */
756 /* numbers are used only to determine 'quirks' in some notes which    */
757 /* cannot reliably be discovered by examining the note scheme,        */
758 
759 /* The softwarename field has proven unreliable for any purpose, is   */
760 /* not used anywhere in the program (other than to print it), and     */
761 /* could disappear from these argument lists. Some image edit         */
762 /* software will change this field, some won't; in any case,          */
763 /* maker-supplied versions do not appear to tell us much.             */
764 
765 int
model_number(int make,char * modelstring,char * softwarename)766 model_number(int make,char *modelstring,char *softwarename)
767 {
768     int number = NO_MODEL;
769 
770     if(modelstring == NULL)
771         modelstring = NULLSTRING;
772     if(softwarename == NULL)
773         softwarename = NULLSTRING;
774     switch(make)
775     {
776         case MAKER_AGFA:
777             number = agfa_model_number(modelstring,softwarename);
778             break;
779         case MAKER_ASAHI:   /* PENTAX                                 */
780         case MAKER_PENTAX:  /* PENTAX                                 */
781             number = asahi_model_number(modelstring,softwarename);
782             break;
783         case MAKER_CANON:
784             number = canon_model_number(modelstring,softwarename);
785             break;
786         case MAKER_CASIO:
787             number = casio_model_number(modelstring,softwarename);
788             break;
789         case MAKER_EPSON:
790             number = epson_model_number(modelstring,softwarename);
791             break;
792         case MAKER_FUJIFILM:
793             number = fujifilm_model_number(modelstring,softwarename);
794             break;
795         case MAKER_HP:      /* proprietary makernotes                 */
796             number = hp_model_number(modelstring,softwarename);
797             break;
798         case MAKER_KODAK:   /* proprietary makernotes                 */
799             number = kodak_model_number(modelstring,softwarename);
800             break;
801         case MAKER_KONICA:  /* proprietary notes: old Konica models   */
802             number = konica_model_number(modelstring,softwarename);
803             break;
804         case MAKER_KYOCERA:
805             number = kyocera_model_number(modelstring,softwarename);
806             break;
807         case MAKER_LEICA:
808             number = leica_model_number(modelstring,softwarename);
809             break;
810         case MAKER_MINOLTA:
811             number = minolta_model_number(modelstring,softwarename);
812             break;
813         case MAKER_NIKON:
814             number = nikon_model_number(modelstring,softwarename);
815             break;
816         case MAKER_OLYMPUS:
817             number = olympus_model_number(modelstring,softwarename);
818             break;
819         case MAKER_PANASONIC:
820             number = panasonic_model_number(modelstring,softwarename);
821             break;
822         case MAKER_RICOH:    /* no or non-IFD makernote data          */
823             number = ricoh_model_number(modelstring,softwarename);
824             break;
825         case MAKER_SANYO:
826             number = sanyo_model_number(modelstring,softwarename);
827             break;
828         case MAKER_SIGMA:
829             number = sigma_model_number(modelstring,softwarename);
830             break;
831         case MAKER_SONY:    /* no makernote data                      */
832             /* DSC-V3 has makernote in IFD format, but nothing is     */
833             /* known about meaning (there are no maker-specific       */
834             /* routines here yet)                                     */
835             number = sony_model_number(modelstring,softwarename);
836             break;
837         case MAKER_TOSHIBA:
838             number = toshiba_model_number(modelstring,softwarename);
839             break;
840         case MAKER_TRAVELER:    /* proprietary makernote              */
841             number = traveler_model_number(modelstring,softwarename);
842             break;
843         default:    /* NO_MODEL                                       */
844             break;
845     }
846     return(number);
847 }
848 
849 /* ********************************************************************/
850 /* Attempt to discover the format of a MakerNote. Some notes are in   */
851 /* normal TIFF IFD format, with tags assigned by the maker, and       */
852 /* values interpreted in maker-specific ways. Some makers begin with  */
853 /* a few bytes containing an ascii string identifying the maker, with */
854 /* a normal IFD following at a specific offset. One camera I've seen  */
855 /* begins with such an ascii id, followed by an actual TIFF header,   */
856 /* with the following IFD offsets then relative to that TIFF header.  */
857 /* This latter scheme seems the most sensible, since it allows image  */
858 /* editting software to move the MakerNote with little effort, and    */
859 /* allows standard TIFF machinery to read them.                       */
860 
861 /* Within the three schemes above, all of which include the basic     */
862 /* format of a TIFF Image File Directory, makers have devised several */
863 /* ways to express their individuality.                               */
864 
865 /* The most harmless is the length of the ID string, and the          */
866 /* resulting offset from the start of the MakerNote blob to the start */
867 /* of the actual IFD. Some makers prove their independence by writing */
868 /* "offset" entries in the IFD (required when a value won't fit in    */
869 /* the 12-byte entry) relative to the start of the MakerNote or even  */
870 /* the start of the current entry. The TIFF specification requires    */
871 /* that such offsets are relative to the beginning of the last        */
872 /* in-scope TIFF header.                                              */
873 
874 /* At least one maker thumbs it's nose at the software world by       */
875 /* gratuitously changing the byte order used when writing the         */
876 /* MakerNote, compared to the remainder of the image file.            */
877 
878 /* Some makers write MakerNotes, but in a purely private, proprietary */
879 /* format.  We cannot read those, except as a blob of useless junk.   */
880 
881 /* This routine uses some simple heuristics to attempt to intuit the  */
882 /* format of a note, rather than a table of known make/model formats. */
883 /* If an Id string is found, an attempt is made to find a TIFF header */
884 /* or an apparently valid IFD. If found, the offset from the start of */
885 /* the blob is recorded, and if the byteorder is changed, that is     */
886 /* noted as well                                                      */
887 
888 /* Offset to the start of the IFD and byteorder are sufficient to     */
889 /* read the directory entries (and print them) but the reference      */
890 /* point for offsets to indirect data is difficult to determine if it */
891 /* differs from the TIFF specification. Specific information,         */
892 /* according to camera make and model, is added for cameras which are */
893 /* known to write note- or entry-relative offsets. Some cameras also  */
894 /* fail to write zeros for the "next IFD offset" normally included at */
895 /* the end of a TIFF IFD, so that fact is noted as well.              */
896 
897 /* If the note just doesn't look presentable, a (currently dummy)     */
898 /* routine can be used to check for known sports.                     */
899 
900 /* The information recorded in the maker_scheme structure at this     */
901 /* point is sufficient to read and print the structure of the note    */
902 /* (except for UNKNOWN schemes, of course). Interpreting the          */
903 /* *meaning* of the tags and values is the responsibility of          */
904 /* maker-specific routines.                                           */
905 /* ********************************************************************/
906 
907 /* ********************************************************************/
908 /* The maker_scheme structure may be of interest to maker-specific    */
909 /* routines, but is not passed around, and should not be modified     */
910 /* outside find_makerscheme. retrieve_makerscheme is provided to      */
911 /* allow a *copy* of the structure to be retrieved after it has been  */
912 /* filled.                                                            */
913 /* ********************************************************************/
914 
915 /* Allow only find_makerscheme() to muck with the original scheme.    */
916 /* Spcific routines are provided to alter note_version and/or tagset  */
917 /* from anywhere in the program, although this is not currently       */
918 /* required.                                                          */
919 
920 static struct maker_scheme maker_scheme;
921 
922 /* Clear the structure and mark it clear for process_makernote()      */
923 
924 void
clear_makerscheme()925 clear_makerscheme()
926 {
927     memset(&maker_scheme,'\0',sizeof(struct maker_scheme));
928     maker_scheme.make = -1;
929 }
930 
931 struct maker_scheme *
find_makerscheme(FILE * inptr,unsigned long note_offset,unsigned long fileoffset_base,unsigned short byteorder,unsigned long maker_size,int make,int model)932 find_makerscheme(FILE *inptr,unsigned long note_offset,
933                     unsigned long fileoffset_base,
934                     unsigned short byteorder,
935                     unsigned long maker_size,int make,int model)
936 {
937     struct ifd_entry *ifdentry;
938     int length_read,id_length,num_entries,start,maxchk_offset;
939     int tiffhdr_offset = 0;
940     unsigned long note_fileoffset = 0L;
941     unsigned long num_entry_offset = 0L;
942     unsigned long ifd_offset = 0L;
943     unsigned long scheme_type = UNKNOWN_SCHEME;
944     unsigned short alt_byteorder;
945     unsigned short note_byteorder = byteorder;
946     int chpr = 0;
947     char *id;
948 
949     if(maker_scheme.make >= 0)
950         clear_makerscheme();
951     note_fileoffset = note_offset + fileoffset_base;
952 
953     id= (char *)read_bytes(inptr,MAX_IDLEN,note_fileoffset);
954     length_read = strlen(id);
955 
956     /* check that string is printable, adjust id_length if nexessary  */
957     if(PRINT_SCHEME_DEBUG)
958     {
959         PUSHCOLOR(HI_RED);
960         PUSHCOLOR(BG_WHITE);
961         chpr = newline(1);
962         chpr += printf("Scheme debug:");
963         chpr = newline(chpr);
964         chpr += printf("Initial id length = %d, ID=",length_read);
965         chpr += print_ascii(inptr,length_read,note_fileoffset);
966         chpr += printf(" at file offset %lu",note_fileoffset);
967         chpr = newline(chpr);
968     }
969 
970     /* Check that the string is printable, and truncate at the first  */
971     /* non-printable found                                            */
972     id = check_printable(id,MAX_IDLEN);
973     id_length = strlen(id);
974     if((PRINT_SCHEME_DEBUG) && (id_length != length_read))
975     {
976         chpr += printf("\tchecked id length = %d",id_length);
977         chpr = newline(chpr);
978     }
979     switch(id_length)
980     {
981         case -1:    /* read failed                                    */
982         case 0:     /* normal or unknown                              */
983         case 1:
984         case 2:
985             /* ###% allow 1 and 2 to be checked?                      */
986             scheme_type = PLAIN_IFD_SCHEME;
987             note_byteorder = byteorder;
988 #if 0
989 /* This is unwise                                                     */
990             if(PRINT_SCHEME_DEBUG)
991             {
992                 chpr += printf(" force PLAIN IFD with no offset");
993                 chpr = newline(chpr);
994                 chpr += printf(" entry check offset 0: ");
995             }
996             num_entry_offset = note_fileoffset;
997             num_entries = read_ushort(inptr,byteorder,num_entry_offset);
998             if(((num_entries > 0) && (maker_size > 0L) &&
999                 (num_entries <= (maker_size / 12))) &&
1000                     (invalid_ifd_entry(inptr,num_entry_offset + 2,
1001                                                 maker_size,num_entries,
1002                                                         byteorder) == 0))
1003             {
1004                 if(PRINT_SCHEME_DEBUG)
1005                 {
1006                     chpr += printf(" FOUND entry, num_entries=%d",num_entries);
1007                     chpr = newline(chpr);
1008                 }
1009                 note_byteorder = byteorder;
1010             }
1011             else
1012             {
1013                 if(PRINT_SCHEME_DEBUG)
1014                 {
1015                     chpr += printf(", num_entries=%d\t(INVALID)",num_entries);
1016                     chpr = newline(chpr);
1017                     chpr += printf(" alt byteorder entry check offset 0: ");
1018                 }
1019                 if(byteorder == TIFF_MOTOROLA)
1020                     alt_byteorder = TIFF_INTEL;
1021                 else
1022                     alt_byteorder = TIFF_MOTOROLA;
1023                 num_entries = read_ushort(inptr,alt_byteorder,num_entry_offset);
1024                 if(((num_entries > 0) && (maker_size > 0L) &&
1025                     (num_entries <= (maker_size / 12))) &&
1026                     (invalid_ifd_entry(inptr,num_entry_offset + 2,maker_size,num_entries,alt_byteorder) == 0))
1027                 {
1028                     if(PRINT_SCHEME_DEBUG)
1029                     {
1030                         chpr += printf(" num_entries=%d, VALID entry found, byteorder=",num_entries);
1031                         print_byteorder(alt_byteorder,1);
1032                         chpr = newline(chpr);
1033                     }
1034                     note_byteorder = alt_byteorder;
1035                 }
1036                 else if(PRINT_SCHEME_DEBUG)
1037                 {
1038                     chpr += printf(" , num_entries=%d\t(INVALID)",num_entries);
1039                     chpr = newline(chpr);
1040                 }
1041             }
1042 #endif
1043             break;
1044         default:
1045             ifd_offset = 0L;
1046             start = ((id_length + 3) * 2) / 2;
1047             maxchk_offset = start + 8;
1048             /* look for TIFF header first.                            */
1049             /* At least one maker uses odd offsets, so we can't       */
1050             /* increment by two                                       */
1051             for( ; start < maxchk_offset; ++start)
1052             {
1053                 int print_marker = 0;
1054 
1055                 if(PRINT_SCHEME_DEBUG)
1056                 {
1057                     chpr += printf(" header check offset %d",start);
1058                     print_marker++;
1059                 }
1060 
1061                 alt_byteorder = valid_tiffhdr(inptr,note_fileoffset + start,print_marker);
1062                 if(alt_byteorder)
1063                 {
1064                     scheme_type = HAS_ID_PLUS_TIFFHDR_SCHEME;
1065                     tiffhdr_offset = start;
1066                     fileoffset_base = note_fileoffset + tiffhdr_offset;
1067                     ifd_offset = read_ulong(inptr,alt_byteorder,HERE);
1068                     note_byteorder = alt_byteorder;
1069                     if(PRINT_SCHEME_DEBUG)
1070                     {
1071                         chpr += printf(" found TIFF header af file offset %lu",fileoffset_base);
1072                         chpr = newline(chpr);
1073                         chpr += printf(" note_fileoffset = %lu, tifhdr_offset = %u, ifd_offset = %lu",
1074                                 note_fileoffset,tiffhdr_offset,ifd_offset);
1075                         chpr = newline(chpr);
1076                     }
1077                     break;
1078                 }
1079                 else if(PRINT_SCHEME_DEBUG)
1080                 {
1081                     chpr += printf("\t (NO VALID MARKER)");
1082                     chpr = newline(chpr);
1083                 }
1084             }
1085 
1086             if(ifd_offset == 0)     /* No TIFF header                 */
1087             {
1088                 start = ((id_length + 1) * 2) / 2;
1089                 for( ; start < maxchk_offset; ++start)
1090                 {
1091                     if(PRINT_SCHEME_DEBUG)
1092                         chpr += printf(" entry check offset %d",start);
1093                     num_entry_offset = note_fileoffset + start;
1094                     num_entries = read_ushort(inptr,byteorder,num_entry_offset);
1095                     if(((num_entries > 0) && (maker_size > 0L) &&
1096                         (num_entries <= (maker_size / 12))) &&
1097                             (invalid_ifd_entry(inptr,num_entry_offset + 2,
1098                                                 maker_size,num_entries,
1099                                                     byteorder) == 0))
1100                     {
1101                         if(PRINT_SCHEME_DEBUG)
1102                         {
1103                             chpr += printf(" FOUND entry, num_entries=%d",num_entries);
1104                             chpr = newline(chpr);
1105                         }
1106                         scheme_type = HAS_ID_SCHEME;
1107                         ifd_offset = start;
1108                         note_byteorder = byteorder;
1109                         break;
1110                     }
1111                     else if(PRINT_SCHEME_DEBUG)
1112                     {
1113                         chpr += printf(" , num_entries=%d\t(INVALID)",num_entries);
1114                         chpr = newline(chpr);
1115                     }
1116                 }
1117             }
1118 
1119             if(ifd_offset == 0)     /* Try the other byte order       */
1120             {
1121                 if(byteorder == TIFF_MOTOROLA)
1122                     alt_byteorder = TIFF_INTEL;
1123                 else
1124                     alt_byteorder = TIFF_MOTOROLA;
1125                 start = ((id_length + 3) * 2) / 2;
1126                 for( ; start < maxchk_offset; ++start)
1127                 {
1128                     if(PRINT_SCHEME_DEBUG)
1129                         chpr += printf(" alt byteorder entry check offset %d",start);
1130                     num_entry_offset = note_fileoffset + start;
1131                     num_entries = read_ushort(inptr,alt_byteorder,num_entry_offset);
1132                     if(((num_entries > 0) && (maker_size > 0L) &&
1133                         (num_entries <= (maker_size / 12))) &&
1134                         (invalid_ifd_entry(inptr,num_entry_offset + 2,maker_size,num_entries,alt_byteorder) == 0))
1135                     {
1136                         if(PRINT_SCHEME_DEBUG)
1137                         {
1138                             chpr += printf(" num_entries=%d, VALID entry found, byteorder=",num_entries);
1139                             print_byteorder(alt_byteorder,1);
1140                             chpr = newline(chpr);
1141                         }
1142                         note_byteorder = alt_byteorder;
1143                         scheme_type = HAS_ID_SCHEME;
1144                         ifd_offset = start;
1145                         break;
1146                     }
1147                     else if(PRINT_SCHEME_DEBUG)
1148                     {
1149                         chpr += printf(" , num_entries=%d\t(INVALID)",num_entries);
1150                         chpr = newline(chpr);
1151                     }
1152                 }
1153             }
1154             break;
1155     }
1156 
1157     if(PRINT_SCHEME_DEBUG)
1158     {
1159         chpr = newline(chpr);
1160         chpr += printf(" reading num_entries at offset %lu, byteorder=",
1161                     note_fileoffset + tiffhdr_offset + ifd_offset);
1162         print_byteorder(note_byteorder,1);
1163         chpr = newline(chpr);
1164     }
1165     if(ifd_offset >= 0)
1166     {
1167         num_entries = read_ushort(inptr,note_byteorder,note_fileoffset + tiffhdr_offset + ifd_offset);
1168         /* read and save first entry (in scheme structure) as an aid  */
1169         /* to selecting version of note processor to use for unknown  */
1170         /* models                                                     */
1171         /* ### this probably shouldn't be done until the scheme has   */
1172         /* been validated.  It's not used much anyway.                */
1173         /* ###%%% better yet, read it here and pass it to             */
1174         /* invalid_ifd_entry() rather than reading it again there.    */
1175         ifdentry = read_ifd_entry(inptr,note_byteorder,HERE);
1176         memcpy(&(maker_scheme.first_entry),ifdentry,sizeof(struct ifd_entry));
1177     }
1178     else
1179         num_entries = 0;    /* read failed */
1180 
1181     if(PRINT_SCHEME_DEBUG)
1182     {
1183         chpr += printf(" num_entries=%d",num_entries);
1184         chpr = newline(chpr);
1185     }
1186 
1187 
1188     if(((maker_size > 0L) && (num_entries > (maker_size / 12))) ||
1189         invalid_ifd_entry(inptr,note_fileoffset + tiffhdr_offset + ifd_offset + 2,
1190             maker_size,num_entries,note_byteorder))
1191     {
1192         /* Record what we know                                        */
1193         maker_scheme.make = make;
1194         maker_scheme.model = model;
1195         maker_scheme.note_version = -1;
1196         maker_scheme.scheme_type = UNKNOWN_SCHEME;
1197         maker_scheme.note_fileoffset = note_fileoffset;
1198         maker_scheme.note_length = maker_size;
1199         maker_scheme.id = id;   /* ...could be one                    */
1200         maker_scheme.id_length = id_length;
1201         maker_scheme.tiffhdr_offset = 0L;
1202         maker_scheme.ifd_offset = 0L;
1203         maker_scheme.fileoffset_base = fileoffset_base;
1204         maker_scheme.num_entries = 0;
1205         maker_scheme.offsets_relative_to = 0;
1206         maker_scheme.no_nextifd_offset = 1;
1207         maker_scheme.tiff_byteorder = byteorder;
1208         maker_scheme.note_byteorder = 0;
1209         find_maker_model(&maker_scheme,make,model);
1210         /* If find_maker_model() is changed to succeed at anything,   */
1211         /* this will have to change...                                */
1212         if(PRINT_SCHEME_DEBUG)
1213         {
1214             PUSHCOLOR(GREEN);
1215             chpr = printf(" No valid scheme found ");
1216             POPCOLOR();
1217             POPCOLOR();
1218         }
1219     }
1220     else
1221     {
1222         if(PRINT_SCHEME_DEBUG)
1223         {
1224             PUSHCOLOR(GREEN);
1225             chpr = printf(" Found valid scheme ");
1226             POPCOLOR();
1227             POPCOLOR();
1228         }
1229         /* We seem to have a winner...                                */
1230         if(scheme_type == UNKNOWN_SCHEME)
1231             maker_scheme.scheme_type = PLAIN_IFD_SCHEME;
1232         else
1233             maker_scheme.scheme_type = scheme_type;
1234         maker_scheme.make = make;
1235         maker_scheme.model = model;
1236         /* note_version may already be set by maker_number()          */
1237         maker_scheme.note_fileoffset = note_fileoffset;
1238         maker_scheme.note_length = maker_size;
1239         maker_scheme.id = id;
1240         maker_scheme.id_length = id_length;
1241         maker_scheme.ifd_offset = ifd_offset;
1242         maker_scheme.tiffhdr_offset = tiffhdr_offset;
1243         maker_scheme.num_entries = num_entries;
1244         maker_scheme.no_nextifd_offset = 0;
1245         maker_scheme.offsets_relative_to = START_OF_TIFFHEADER;
1246         maker_scheme.fileoffset_base = fileoffset_base;
1247 
1248         /* The two entries allow print_scheme() to make it plain when */
1249         /* the note byte order gratuitously differs from the rest of  */
1250         /* the file.                                                  */
1251         maker_scheme.tiff_byteorder = byteorder;
1252         maker_scheme.note_byteorder = note_byteorder;
1253 
1254         /* Maker-specific adjustments                                 */
1255         switch(make)
1256         {
1257             case MAKER_AGFA:
1258                 if((maker_scheme.note_version == 0))
1259                     setnoteversion(1);
1260                 break;
1261             case MAKER_ASAHI: /* fall through */
1262             case MAKER_PENTAX:
1263                 if(maker_scheme.scheme_type == PLAIN_IFD_SCHEME)
1264                     maker_scheme.offsets_relative_to = START_OF_ENTRY;
1265                 if((maker_scheme.note_version == 0))
1266                     (void)set_asahi_noteversion();
1267                 break;
1268             case MAKER_CANON:
1269                 if((maker_scheme.note_version == 0))
1270                     setnoteversion(1);
1271                 break;
1272             case MAKER_CASIO:
1273                 if((maker_scheme.note_version == 0))
1274                     (void)set_casio_noteversion();
1275                 break;
1276             case MAKER_EPSON:
1277                 if((maker_scheme.note_version == 0))
1278                     setnoteversion(1);
1279                 break;
1280             case MAKER_FUJIFILM:
1281                 maker_scheme.offsets_relative_to = START_OF_NOTE;
1282                 maker_scheme.fileoffset_base = note_fileoffset;
1283                 if((maker_scheme.note_version == 0))
1284                     setnoteversion(1);
1285                 break;
1286             case MAKER_HP:      /* proprietary makernote              */
1287                 if((maker_scheme.note_version == 0))
1288                     setnoteversion(-1);
1289                 break;
1290             case MAKER_KODAK:   /* proprietary makernote              */
1291                 if((maker_scheme.note_version == 0))
1292                     setnoteversion(-1);
1293                 break;
1294             case MAKER_KONICA:  /* no makernote data                  */
1295                 if((maker_scheme.note_version == 0))
1296                     setnoteversion(-1);
1297                 break;
1298             case MAKER_LEICA:
1299                 if(strncasecmp(id,"FUJIFILM",8) == 0)
1300                 {
1301                     maker_scheme.offsets_relative_to = START_OF_NOTE;
1302                     maker_scheme.fileoffset_base = note_fileoffset;
1303                     /* maker_scheme.no_nextifd_offset = 1; */
1304                 }
1305                 if((maker_scheme.note_version == 0))
1306                     setnoteversion(1);
1307                 break;
1308             case MAKER_MINOLTA:
1309                 if((maker_scheme.note_version == 0))
1310                     setnoteversion(1);
1311                 break;
1312             case MAKER_KYOCERA:
1313                 maker_scheme.offsets_relative_to = START_OF_ENTRY;
1314                 maker_scheme.no_nextifd_offset = 1;
1315                 break;
1316             case MAKER_NIKON:
1317                 if((maker_scheme.note_version == 0))
1318                     (void)set_nikon_noteversion();
1319                 break;
1320             case MAKER_OLYMPUS:
1321                 if((maker_scheme.note_version == 0))
1322                     setnoteversion(1);
1323                 break;
1324             case MAKER_PANASONIC:
1325                 maker_scheme.no_nextifd_offset = 1;
1326                 if((maker_scheme.note_version == 0))
1327                     setnoteversion(1);
1328                 break;
1329             case MAKER_TOSHIBA:
1330                 if((maker_scheme.note_version == 0))
1331                     setnoteversion(1);
1332                 maker_scheme.no_nextifd_offset = 1;
1333                 break;
1334             case MAKER_RICOH:    /* no or non-IFD makernote data      */
1335                 if((maker_scheme.note_version == 0))
1336                     setnoteversion(-1);
1337                 break;
1338             case MAKER_SANYO:
1339                 if((maker_scheme.note_version == 0))
1340                     setnoteversion(1);
1341                 break;
1342             case MAKER_SIGMA:
1343                 if(model == SIGMA_SD9)
1344                     maker_scheme.no_nextifd_offset = 1;
1345                 if((maker_scheme.note_version == 0))
1346                     setnoteversion(1);
1347                 break;
1348             case MAKER_SONY:
1349                 if((maker_scheme.note_version == 0))
1350                     setnoteversion(-1);
1351                 maker_scheme.no_nextifd_offset = 1;
1352                 break;
1353             case MAKER_TRAVELER:    /* proprietary makernote          */
1354                 if((maker_scheme.note_version == 0))
1355                     setnoteversion(-1);
1356                 break;
1357             default:
1358                 break;
1359         }
1360     }
1361     if(PRINT_SCHEME_DEBUG)
1362     {
1363         POPCOLOR();
1364         chpr = newline(chpr);
1365     }
1366     return(&maker_scheme);
1367 }
1368 
1369 /* Look up a make and model in a table of known sports. This is       */
1370 /* currently just a dummy, but might be used to handle non-ifd notes  */
1371 /* by setting a new type here and revising the generic code to        */
1372 /* dispatch a specialized routine. I have no information on such      */
1373 /* notes now.                                                         */
1374 
1375 void
find_maker_model(struct maker_scheme * maker_scheme,int make,int model)1376 find_maker_model(struct maker_scheme *maker_scheme,int make,int model)
1377 {
1378         /* do a lookup here on make and model                         */
1379         /* This should probably return a scheme structure, or some    */
1380         /* indication of success or failure, but since it's not used  */
1381         /* now (except to initialize the structure)...                */
1382 }
1383 
1384 /* Check for a valid TIFF header at the argument offset               */
1385 
1386 unsigned short
valid_tiffhdr(FILE * inptr,unsigned long offset,int print_marker)1387 valid_tiffhdr(FILE *inptr,unsigned long offset,int print_marker)
1388 {
1389     struct fileheader *header;
1390     unsigned short marker = 0;
1391     int chpr = 0;
1392 
1393     if(inptr && offset)
1394     {
1395         if(print_marker)
1396             chpr = printf(" read at offset %lu ",offset);
1397         header = read_imageheader(inptr,offset);
1398         if(header)
1399         {
1400             if(print_marker)
1401                 chpr += printf(" %#x ",header->file_marker);
1402             switch(header->probe_magic)
1403             {
1404                 case TIFF_MAGIC:
1405                     marker = header->file_marker;
1406                     break;
1407                 default:
1408                     marker = 0;
1409                     break;
1410             }
1411         }
1412     }
1413     setcharsprinted(chpr);
1414     return(marker);
1415 }
1416 
1417 /* Check for an apparently valid TIFF IFD entry at the argumrnt       */
1418 /* offset.                                                            */
1419 
1420 int
invalid_ifd_entry(FILE * inptr,unsigned long offset,unsigned long segment_size,int nentries,unsigned short byteorder)1421 invalid_ifd_entry(FILE *inptr,unsigned long offset,unsigned long segment_size,
1422                     int nentries,unsigned short byteorder)
1423 {
1424     struct ifd_entry *entry_ptr;
1425     int invalid = 0;
1426 
1427     if(inptr && offset && byteorder)
1428     {
1429         /* Read an entry at the given offset and see if has a valid   */
1430         /* type, and non-zero count.                                  */
1431         entry_ptr = read_ifd_entry(inptr,byteorder,offset);
1432         if((entry_ptr->value_type == 0) || (entry_ptr->value_type > DOUBLE) ||
1433             ferror(inptr) || feof(inptr))
1434                 ++invalid;
1435         else if(entry_ptr->count == 0)
1436                 ++invalid;
1437 
1438         /* If there is more than one entry, and the first appears     */
1439         /* valid, check the second entry.                             */
1440         /* If there is only one entry, and it appears valid, make     */
1441         /* sure that it's size fits within the note. This size check  */
1442         /* can fail on multi-entry notes when moronic makers write a  */
1443         /* thumbnail offset, then write the thumbnail outside the     */
1444         /* note...so we don't check size for multi.                   */
1445         if(nentries > 1)
1446         {
1447             if(invalid == 0)    /* double check                           */
1448             {
1449                 entry_ptr = read_ifd_entry(inptr,byteorder,HERE);
1450                 if((entry_ptr->value_type == 0) || (entry_ptr->value_type > DOUBLE) ||
1451                     ferror(inptr) || feof(inptr))
1452                         ++invalid;
1453                 else if(entry_ptr->count == 0)
1454                         ++invalid;
1455             }
1456         }
1457         else if(entry_ptr->count > segment_size)
1458             ++invalid;
1459     }
1460     else
1461         ++invalid;
1462     return(invalid);
1463 }
1464 
1465 /* Call a maker-specific routine to identify LONG values which must   */
1466 /* be interpreted as offsets.                                         */
1467 
1468 int
maker_value_is_offset(struct ifd_entry * entry,int make,int model)1469 maker_value_is_offset(struct ifd_entry *entry,int make,int model)
1470 {
1471     int is_offset = 0;
1472 
1473     if(entry)
1474     {
1475         switch(make)
1476         {
1477             case MAKER_ASAHI:
1478             case MAKER_PENTAX:
1479                 is_offset = maker_asahi_value_is_offset(entry,model);
1480                 break;
1481             case MAKER_CANON:
1482                 is_offset = maker_canon_value_is_offset(entry,model);
1483                 break;
1484             case MAKER_CASIO:
1485                 is_offset = maker_casio_value_is_offset(entry,model);
1486                 break;
1487             case MAKER_NIKON:
1488                 is_offset = maker_nikon_value_is_offset(entry,model);
1489                 break;
1490             case MAKER_MINOLTA:
1491                 is_offset = maker_minolta_value_is_offset(entry,model);
1492                 break;
1493             default:
1494                 break;
1495         }
1496     }
1497     return(is_offset);
1498 }
1499 
1500 /* Copy the argument string into static storage, stopping at any      */
1501 /* unprintable byte which may be found.                               */
1502 /* Return the null-terminated result string.                          */
1503 
1504 char *
check_printable(char * id,int maxlen)1505 check_printable(char *id, int maxlen)
1506 {
1507     static char buffer[MAX_IDLEN];
1508     char *idval,*bufval;
1509     int i = 0;
1510 
1511     memset(buffer,'\0',MAX_IDLEN);
1512     if(maxlen > MAX_IDLEN)
1513         maxlen = MAX_IDLEN;
1514     bufval = buffer;
1515 
1516     for(idval = id; idval && (i < maxlen - 1); ++idval,++bufval,++i)
1517         if(!isprint(*idval))
1518         {
1519             *bufval = '\0';
1520             break;
1521         }
1522         else
1523             *bufval = *idval;
1524     return(buffer);
1525 }
1526 
1527 /* Record the "version" of the makernote as recognized by exifprobe.  */
1528 /* Note that the version number is arbitrary and does not correspond  */
1529 /* to any manufacturer numbering scheme; it is used for internal      */
1530 /* identification in order to identify or determine which routine is  */
1531 /* to be used for each model.                                         */
1532 
1533 int option_noteversion = 0;
1534 
1535 /* This function may be called from the option processing code to     */
1536 /* allow a user to override the noteversion which would otherwise be  */
1537 /* set. This is primarily intended to permit trying an existing       */
1538 /* noteversion on an unrecognized model.                              */
1539 
1540 void
setoptionnoteversion(int note_vers)1541 setoptionnoteversion(int note_vers)
1542 {
1543     option_noteversion = note_vers;
1544 }
1545 
1546 void
setnoteversion(int note_vers)1547 setnoteversion(int note_vers)
1548 {
1549     if(option_noteversion != 0)
1550         maker_scheme.note_version = option_noteversion;
1551     else
1552         maker_scheme.note_version = note_vers;
1553 }
1554 
1555 int
getnoteversion()1556 getnoteversion()
1557 {
1558     if(option_noteversion != 0)
1559         maker_scheme.note_version = option_noteversion;
1560     return(maker_scheme.note_version);
1561 }
1562 
1563 /* Tagset number is usually the same as note version; however, some   */
1564 /* models may have fewer tagsets than note versions. The two are set  */
1565 /* separately. Tagset number is provided for info/debug only (it is   */
1566 /* not used by the selection code);                                   */
1567 
1568 void
setnotetagset(int tagset)1569 setnotetagset(int tagset)
1570 {
1571     maker_scheme.tagset = tagset;
1572 }
1573 
1574 int
getnotetagset()1575 getnotetagset()
1576 {
1577     return(maker_scheme.tagset);
1578 }
1579 
1580 /* Provide maker-specific files access to a copy of the scheme.       */
1581 
1582 struct maker_scheme *
retrieve_makerscheme()1583 retrieve_makerscheme()
1584 {
1585     static struct maker_scheme maker_scheme_copy;
1586 
1587     /* structure assignment                                           */
1588     maker_scheme_copy = maker_scheme;
1589     return(&maker_scheme_copy);
1590 }
1591