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