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_leica.c,v 1.9 2005/07/24 22:56:26 alex Exp $";
11 #endif
12 
13 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
14 /* Leica camera maker-specific routines                               */
15 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
16 /* This information is from a page by Johannes Tschebisch at:         */
17 /* http://www.jojotsch.de/downloads/jojothumb/beispiele/              */
18 /*                             html_exif/bilder/leica-digilux4.3.html */
19 /*                                                                    */
20 /* Note that the tags are identical to the fujifilm tags, the format  */
21 /* is the same wierd format as the fuji, and the note even begins     */
22 /* with the string "FUJIFILM".                                        */
23 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
24 
25 #include <stdio.h>
26 #include <string.h>
27 #include "defs.h"
28 #include "datadefs.h"
29 #include "maker_datadefs.h"
30 #include "summary.h"
31 #include "maker.h"
32 #include "misc.h"
33 #include "tags.h"
34 #include "maker_extern.h"
35 #include "extern.h"
36 
37 extern struct camera_id leica_model_id[];
38 
39 /* Find the identifying number assigned to known Leica camera         */
40 /* models. This number is used to dispatch print and interpret        */
41 /* routines approopriate to the current image.                        */
42 
43 int
leica_model_number(char * model,char * software)44 leica_model_number(char *model,char *software)
45 {
46     struct camera_id *model_id;
47     int number = NO_MODEL;
48 
49     for(model_id = &leica_model_id[0]; model_id && model_id->name; ++model_id)
50     {
51         if(strncasecmp(model,model_id->name,model_id->namelen) == 0)
52         {
53             number = model_id->id;
54             setnoteversion(model_id->noteversion);
55             setnotetagset(model_id->notetagset);    /* info only      */
56             break;
57         }
58     }
59     return(number);
60 }
61 
62 
63 /* Dispatch a print routine for direct values in Leica cameras,       */
64 /* based upon model                                                   */
65 
66 void
print_leica_makervalue(struct ifd_entry * entry_ptr,int make,int model,char * prefix)67 print_leica_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_leica1_makervalue(entry_ptr,make,model,PREFIX);
80                 leica1_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 Leica 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_leica1_makervalue(struct ifd_entry * entry_ptr,int make,int model,char * prefix)97 print_leica1_makervalue(struct ifd_entry *entry_ptr,int make,int model,
98                     char *prefix)
99 {
100     if(entry_ptr && (PRINT_VALUE))
101     {
102         switch(entry_ptr->tag)
103         {
104             default:
105                 print_value(entry_ptr,PREFIX);
106                 break;
107         }
108     }
109 }
110 
111 
112 /* Dispatch a routine to decode and print offset values for Leica     */
113 /* cameras.                                                           */
114 
115 void
print_leica_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)116 print_leica_offset_makervalue(FILE *inptr,unsigned short byteorder,
117     struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
118     struct image_summary *summary_entry,char *parent_name,char *prefix,
119     int indent,int make,int model,int at_offset)
120 {
121     int noteversion = 0;
122 
123     noteversion = getnoteversion();
124     if(entry_ptr)
125     {
126         switch(noteversion)
127         {
128             case 1:
129                 leica1_offset_makervalue(inptr,byteorder,entry_ptr,
130                                             fileoffset_base,summary_entry,
131                                             parent_name,prefix,indent,
132                                             make,model,at_offset);
133                 break;
134             default:
135                 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,
136                                     fileoffset_base,parent_name,prefix,
137                                     indent,make,model,at_offset);
138                 break;
139         }
140     }
141 }
142 
143 /* Model-specific routine to print UNDEFINED values found at offsets  */
144 /* in Leica makernotes.                                               */
145 
146 void
leica1_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)147 leica1_offset_makervalue(FILE *inptr,unsigned short byteorder,
148     struct ifd_entry *entry_ptr,unsigned long fileoffset_base,
149     struct image_summary *summary_entry,char *parent_name,char *prefix,
150     int indent,int make,int model,int at_offset)
151 {
152     if(entry_ptr)
153     {
154         switch(entry_ptr->tag)
155         {
156             default:
157                 print_generic_offset_makervalue(inptr,byteorder,entry_ptr,
158                                     fileoffset_base,parent_name,prefix,
159                                     indent,make,model,at_offset);
160                 break;
161         }
162     }
163 }
164 
165 
166 /* Leica-specific tagnames for makernotes.                            */
167 
168 char *
maker_leica_tagname(unsigned short tag,int model)169 maker_leica_tagname(unsigned short tag,int model)
170 {
171     char *tagname = CNULL;
172     int noteversion = 0;
173 
174     /* Should have to do this only once, and only for unrecognized    */
175     /* models. If the model is recognized (or the user has forced a   */
176     /* noteversion) noteversion will already be set.                  */
177     if((noteversion = getnoteversion()) == 0)
178     {
179         /* Need more model samples before it is safe to assume a      */
180         /* default                                                    */
181         noteversion = 1;
182         setnoteversion(1);
183     }
184 
185     switch(noteversion)
186     {
187         case 1:
188             tagname = maker_leica1_tagname(tag,model);
189             break;
190         default:
191             break;
192     }
193 
194     /* If no model-specific tag is found, check "generic" tags        */
195     if(tagname == NULL)
196     {
197         switch(tag)
198         {
199             case 0x0e00: tagname = "PrintIM"; break;
200             default: break;
201         }
202     }
203     return(tagname);
204 }
205 
206 
207 char *
maker_leica1_tagname(unsigned short tag,int model)208 maker_leica1_tagname(unsigned short tag,int model)
209 {
210     char *tagname = CNULL;
211 
212     switch(tag)
213     {
214         case 0x0000: tagname = "Version"; break;
215         case 0x1000: tagname = "Quality"; break;
216         case 0x1001: tagname = "Sharpness"; break;
217         case 0x1002: tagname = "WhiteBalance"; break;
218         case 0x1003: tagname = "Color"; break;
219         case 0x1004: tagname = "Tone"; break;
220         case 0x1010: tagname = "FlashMode"; break;
221         case 0x1011: tagname = "FlashStrength"; break;
222         case 0x1020: tagname = "Macro"; break;
223         case 0x1021: tagname = "FocusMode"; break;
224         case 0x1030: tagname = "SlowSync"; break;
225         case 0x1031: tagname = "PictureMode"; break;
226         case 0x1100: tagname = "ContTake-Bracket"; break;
227         case 0x1300: tagname = "BlurWarning"; break;
228         case 0x1301: tagname = "FocusWarning"; break;
229         case 0x1302: tagname = "AEWarning"; break;
230         default: break;
231     }
232     setnotetagset(1);
233     return(tagname);
234 }
235 
236 
237 /* Report the "meaning" of tag values found at offsets in a Leica     */
238 /* MakerNote IFD entry (not at an offset).                            */
239 
240 void
leica1_interpret_value(struct ifd_entry * entry_ptr)241 leica1_interpret_value(struct ifd_entry *entry_ptr)
242 {
243     int chpr = 0;
244 
245     if(entry_ptr && (PRINT_VALUE))
246     {
247         switch(entry_ptr->tag)
248         {
249             case 0x1001:    /* Sharpness */
250                 print_startvalue();
251                 switch(entry_ptr->value)
252                 {
253                     case 1: chpr += printf("Soft"); break;
254                     case 2: chpr += printf("Soft"); break;
255                     case 3: chpr += printf("Normal"); break;
256                     case 4: chpr += printf("Hard"); break;
257                     case 5: chpr += printf("Hard"); break;
258                     default: printred("undefined"); break;
259                 }
260                 print_endvalue();
261                 break;
262             case 0x1002:    /* White Balance */
263                 print_startvalue();
264                 /* I think we're looking at a bit mask here, but I have   */
265                 /* no way to check; this is the way Tachibanaya           */
266                 /* characterizes it.                                      */
267                 switch(entry_ptr->value)
268                 {
269                     case 0: chpr += printf("Auto"); break;
270                     case 256: chpr += printf("Daylight"); break;
271                     case 512: chpr += printf("Cloudy"); break;
272                     case 768:   /* ???? */ chpr += printf("DaylightColor-Fluorescent"); break;
273                     case 769:   /* ???? */ chpr += printf("DaywhiteColor-Fluorescent"); break;
274                     case 770:   /* ???? */ chpr += printf("White-Fluorescent"); break;
275                     case 1024: chpr += printf("Incandescent"); break;
276                     case 3840: chpr += printf("Custom"); break;
277                     default: printred("undefined"); break;
278                 }
279                 print_endvalue();
280                 break;
281             case 0x1003:    /* Color Saturation */
282                 print_startvalue();
283                 switch(entry_ptr->value)
284                 {
285                     case 0: chpr += printf("Standard"); break;
286                     case 256: chpr += printf("High"); break;
287                     case 512: chpr += printf("Low"); break;
288                     default: printred("undefined"); break;
289                 }
290                 print_endvalue();
291                 break;
292             case 0x1004:    /* Tone */
293                 print_startvalue();
294                 switch(entry_ptr->value)
295                 {
296                     case 0: chpr += printf("Standard"); break;
297                     case 256: chpr += printf("High"); break;
298                     case 512: chpr += printf("Low"); break;
299                     default: printred("undefined"); break;
300                 }
301                 print_endvalue();
302                 break;
303             case 0x1010:    /* Flash Mode */
304                 print_startvalue();
305                 switch(entry_ptr->value)
306                 {
307                     case 0: chpr += printf("Auto"); break;
308                     case 1: chpr += printf("On"); break;
309                     case 2: chpr += printf("Off"); break;
310                     case 3: chpr += printf("Redeye"); break;
311                     default: printred("undefined"); break;
312                 }
313                 print_endvalue();
314                 break;
315             case 0x1020:    /* Macro Mode */
316                 print_startvalue();
317                 switch(entry_ptr->value)
318                 {
319                     case 0: chpr += printf("Off"); break;
320                     case 1: chpr += printf("On"); break;
321                     default: printred("undefined"); break;
322                 }
323                 print_endvalue();
324                 break;
325             case 0x1021:    /* Focusing Mode */
326                 print_startvalue();
327                 switch(entry_ptr->value)
328                 {
329                     case 0: chpr += printf("Auto"); break;
330                     case 1: chpr += printf("Manual"); break;
331                     default: printred("undefined"); break;
332                 }
333                 print_endvalue();
334                 break;
335             case 0x1030:    /* Slow Sync */
336                 print_startvalue();
337                 switch(entry_ptr->value)
338                 {
339                     case 0: chpr += printf("Off"); break;
340                     case 1: chpr += printf("On"); break;
341                     default: printred("undefined"); break;
342                 }
343                 print_endvalue();
344                 break;
345             case 0x1031:    /* Picture Mode */
346                 print_startvalue();
347                 switch(entry_ptr->value)
348                 {
349                     case 0: chpr += printf("Auto"); break;
350                     case 1: chpr += printf("Portrait"); break;
351                     case 2: chpr += printf("Landscape"); break;
352                     case 4: chpr += printf("Sports"); break;
353                     case 5: chpr += printf("Night"); break;
354                     case 6: chpr += printf("Program Normal"); break;
355                     case 256: chpr += printf("Aperture Priority"); break;
356                     case 512: chpr += printf("Shutter Priority"); break;
357                     case 768: chpr += printf("Manual"); break;
358                     default: printred("undefined");
359                 }
360                 print_endvalue();
361                 break;
362             case 0x1100:    /* Continuous Take/Bracket */
363                 print_startvalue();
364                 switch(entry_ptr->value)
365                 {
366                     case 0: chpr += printf("Off"); break;
367                     case 1: chpr += printf("On"); break;
368                     default: printred("undefined"); break;
369                 }
370                 print_endvalue();
371                 break;
372             case 0x1300:    /* Blur Warning */
373                 print_startvalue();
374                 switch(entry_ptr->value)
375                 {
376                     case 0: chpr += printf("Ok"); break;
377                     case 1: chpr += printf("Blurred"); break;
378                     default: printred("undefined"); break;
379                 }
380                 print_endvalue();
381                 break;
382             case 0x1301:    /* Focus Warning */
383                 print_startvalue();
384                 switch(entry_ptr->value)
385                 {
386                     case 0: chpr += printf("Ok"); break;
387                     case 1: chpr += printf("Out of focus"); break;
388                     default: printred("undefined"); break;
389                 }
390                 print_endvalue();
391                 break;
392             case 0x1302:    /* AE Warning */
393                 print_startvalue();
394                 switch(entry_ptr->value)
395                 {
396                     case 0: chpr += printf("Ok"); break;
397                     case 1: chpr += printf("Overexposed"); break;
398                     default: printred("undefined"); break;
399                 }
400                 print_endvalue();
401                 break;
402             default:
403                 break;
404         }
405     }
406     setcharsprinted(chpr);
407 }
408 
409 /* ID "Leica" tags 0x01-0x2c,0x4449; similar to Panasonic (matches types) (check exiftool)
410    Plain (R9 DMR) tags 0x01-0x10
411    */
412