Added support for Epson MakerNotes, which have the identical
[platform/upstream/libexif.git] / libexif / olympus / mnote-olympus-entry.c
1 /* mnote-olympus-entry.c
2  *
3  * Copyright (c) 2002 Lutz Mueller <lutz@users.sourceforge.net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <config.h>
22 #include "mnote-olympus-entry.h"
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include <libexif/exif-format.h>
29 #include <libexif/exif-utils.h>
30 #include <libexif/exif-entry.h>
31 #include <libexif/i18n.h>
32
33 #define CF(format,target,v,maxlen)                              \
34 {                                                               \
35         if (format != target) {                                 \
36                 snprintf (v, maxlen,                            \
37                         _("Invalid format '%s', "               \
38                         "expected '%s'."),                      \
39                         exif_format_get_name (format),          \
40                         exif_format_get_name (target));         \
41                 break;                                          \
42         }                                                       \
43 }
44
45 #define CF2(format,target1,target2,v,maxlen)                    \
46 {                                                               \
47         if ((format != target1) && (format != target2)) {       \
48                 snprintf (v, maxlen,                            \
49                         _("Invalid format '%s', "               \
50                         "expected '%s' or '%s'."),              \
51                         exif_format_get_name (format),          \
52                         exif_format_get_name (target1),         \
53                         exif_format_get_name (target2));        \
54                 break;                                          \
55         }                                                       \
56 }
57
58 #define CC(number,target,v,maxlen)                                      \
59 {                                                                       \
60         if (number != target) {                                         \
61                 snprintf (v, maxlen,                                    \
62                         _("Invalid number of components (%i, "          \
63                         "expected %i)."), (int) number, (int) target);  \
64                 break;                                                  \
65         }                                                               \
66 }
67
68 #define CC2(number,t1,t2,v,maxlen)                                      \
69 {                                                                       \
70         if ((number < t1) || (number > t2)) {                           \
71                 snprintf (v, maxlen,                                    \
72                         _("Invalid number of components (%i, "          \
73                         "expected %i or %i)."), (int) number,           \
74                         (int) t1, (int) t2);                            \
75                 break;                                                  \
76         }                                                               \
77 }
78
79 static const struct {
80         ExifTag tag;
81     ExifFormat fmt;
82         struct {
83                 int index;
84                 const char *string;
85         } elem[10];
86 } items[] = {
87 #ifndef NO_VERBOSE_TAG_DATA
88   { MNOTE_NIKON_TAG_LENSTYPE, EXIF_FORMAT_BYTE,
89     { {0, N_("AF non D Lens")},
90       {1, N_("Manual")},
91       {2, N_("AF-D or AF-S Lens")},
92       {6, N_("AF-D G Lens")},
93       {10, N_("AF-D VR Lens")},
94       {0, NULL}}},
95   { MNOTE_NIKON_TAG_FLASHUSED, EXIF_FORMAT_BYTE,
96     { {0, N_("Flash did not fire")},
97       {4, N_("Flash unit unknown")},
98       {7, N_("Flash is external")},
99       {9, N_("Flash is on Camera")},
100       {0, NULL}}},
101   { MNOTE_NIKON1_TAG_QUALITY, EXIF_FORMAT_SHORT,
102     { {1, N_("VGA Basic")},
103       {2, N_("VGA Normal")},
104       {3, N_("VGA Fine")},
105       {4, N_("SXGA Basic")},
106       {5, N_("SXGA Normal")},
107       {6, N_("SXGA Fine")},
108       {10, N_("2 MPixel Basic")},
109       {11, N_("2 MPixel Normal")},
110       {12, N_("2 MPixel Fine")},
111       {0, NULL}}},
112   { MNOTE_NIKON1_TAG_COLORMODE, EXIF_FORMAT_SHORT,
113     { {1, N_("Color")},
114       {2, N_("Monochrome")},
115       {0, NULL}}},
116   { MNOTE_NIKON1_TAG_IMAGEADJUSTMENT, EXIF_FORMAT_SHORT,
117     { {0, N_("Normal")},
118       {1, N_("Bright+")},
119       {2, N_("Bright-")},
120       {3, N_("Contrast+")},
121       {4, N_("Contrast-")},
122       {0, NULL}}},
123   { MNOTE_NIKON1_TAG_CCDSENSITIVITY, EXIF_FORMAT_SHORT,
124     { {0, N_("ISO80")},
125       {2, N_("ISO160")},
126       {4, N_("ISO320")},
127       {5, N_("ISO100")},
128       {0, NULL}}},
129   { MNOTE_NIKON1_TAG_WHITEBALANCE, EXIF_FORMAT_SHORT,
130     { {0, N_("Auto")},
131       {1, N_("Preset")},
132       {2, N_("Daylight")},
133       {3, N_("Incandescence")},
134       {4, N_("Fluorescence")},
135       {5, N_("Cloudy")},
136       {6, N_("SpeedLight")},
137       {0, NULL}}},
138   { MNOTE_NIKON1_TAG_CONVERTER, EXIF_FORMAT_SHORT,
139     { {0, N_("No Fisheye")},
140       {1, N_("Fisheye On")},
141       {0, NULL}}},
142   { MNOTE_OLYMPUS_TAG_QUALITY, EXIF_FORMAT_SHORT,
143     { {1, N_("SQ")},
144       {2, N_("HQ")},
145       {3, N_("SHQ")},
146       {4, N_("RAW")},
147       {5, N_("SQ1")},
148       {6, N_("SQ2")},
149       {17, N_("Standard")},
150       {529, N_("High")},
151       {0, NULL}}},
152   { MNOTE_OLYMPUS_TAG_MACRO, EXIF_FORMAT_SHORT,
153     { {0, N_("No")},
154       {1, N_("Yes")},
155       {2, N_("Super Macro")},
156       {0, NULL}}},
157   { MNOTE_OLYMPUS_TAG_BWMODE, EXIF_FORMAT_SHORT,
158     { {0, N_("No")},
159       {1, N_("Yes")},
160       {0, NULL}}},
161   { MNOTE_OLYMPUS_TAG_ONETOUCHWB, EXIF_FORMAT_SHORT,
162     { {0, N_("Off")},
163       {1, N_("On")},
164       {2, N_("On (Preset)")},
165       {0, NULL}}},
166   { MNOTE_OLYMPUS_TAG_FLASHMODE, EXIF_FORMAT_SHORT,
167     { {0, N_("Auto")},
168       {1, N_("Red-eye reduction")},
169       {2, N_("Fill")},
170       {3, N_("Off")},
171       {0, NULL}}},
172   { MNOTE_OLYMPUS_TAG_FLASHDEVICE, EXIF_FORMAT_SHORT,
173     { {0, N_("None")},
174       {1, N_("Internal")},
175       {4, N_("External")},
176       {5, N_("Internal + External")},
177       {0, NULL}}},
178   { MNOTE_OLYMPUS_TAG_FOCUSRANGE, EXIF_FORMAT_SHORT,
179     { {0, N_("Normal")},
180       {1, N_("Macro")},
181       {0, NULL}}},
182   { MNOTE_OLYMPUS_TAG_MANFOCUS, EXIF_FORMAT_SHORT,
183     { {0, N_("Auto")},
184       {1, N_("Manual")},
185       {0, NULL}}},
186   { MNOTE_OLYMPUS_TAG_SHARPNESS, EXIF_FORMAT_SHORT,
187     { {0, N_("Normal")},
188       {1, N_("Hard")},
189       {2, N_("Soft")},
190       {0, NULL}}},
191   { MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE, EXIF_FORMAT_SHORT,
192     { {0, N_("No")},
193       {1, N_("Yes")},
194       {0, NULL}}},
195   { MNOTE_OLYMPUS_TAG_CONTRAST, EXIF_FORMAT_SHORT,
196     { {0, N_("Hard")},
197       {1, N_("Normal")},
198       {2, N_("Soft")},
199       {0, NULL}}},
200   { MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID, EXIF_FORMAT_LONG,
201     { {0, N_("No")},
202       {1, N_("Yes")},
203       {0, NULL}}},
204   { MNOTE_OLYMPUS_TAG_CCDSCANMODE, EXIF_FORMAT_SHORT,
205     { {0, N_("Interlaced")},
206       {1, N_("Progressive")},
207       {0, NULL}}},
208   { MNOTE_SANYO_TAG_SEQUENTIALSHOT, EXIF_FORMAT_SHORT,
209     { {0, N_("None")},
210       {1, N_("Standard")},
211       {2, N_("Best")},
212       {3, N_("Adjust Exposure")},
213       {0, NULL}}},
214   { MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE, EXIF_FORMAT_SHORT,
215     { {0, N_("Record while down")},
216       {1, N_("Press start, press stop")},
217       {0, NULL}}},
218   { MNOTE_SANYO_TAG_RESAVED, EXIF_FORMAT_SHORT,
219     { {0, N_("No")},
220       {1, N_("Yes")},
221       {0, NULL}}},
222   { MNOTE_SANYO_TAG_SCENESELECT, EXIF_FORMAT_SHORT,
223     { {0, N_("Off")},
224       {1, N_("Sport")},
225       {2, N_("TV")},
226       {3, N_("Night")},
227       {4, N_("User 1")},
228       {5, N_("User 2")},
229       {6, N_("Lamp")},
230       {0, NULL}}},
231   { MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL, EXIF_FORMAT_SHORT,
232     { {0, N_("5 frames/sec")},
233       {1, N_("10 frames/sec")},
234       {2, N_("15 frames/sec")},
235       {3, N_("20 frames/sec")},
236       {0, NULL}}},
237 #endif
238   { 0, 0, { { 0, NULL } } }
239 };
240
241 char *
242 mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *v, unsigned int maxlen)
243 {
244         char         buf[30];
245         ExifLong     vl;
246         ExifShort    vs = 0;
247         ExifSShort   vss = 0;
248         ExifRational vr, vr2;
249         ExifSRational vsr;
250         int          i, j;
251         double       r, b;
252
253         if (!entry)
254                 return (NULL);
255
256         memset (v, 0, maxlen);
257         maxlen--;
258
259         if ((!entry->data) && (entry->components > 0)) 
260                 return (v);
261
262         switch (entry->tag) {
263         
264         /* Nikon */
265         case MNOTE_NIKON_TAG_FIRMWARE:
266                 CF (entry->format,  EXIF_FORMAT_UNDEFINED, v, maxlen);
267                 CC (entry->components, 4, v, maxlen);
268                 vl = exif_get_long (entry->data, entry->order);
269                 if ((vl & 0xF0F0F0F0) == 0x30303030) {
270                         memcpy (v, entry->data, MIN (maxlen, 4));
271                 } else {
272                         snprintf (v, maxlen, "%04lx", (long unsigned int) vl);
273                 }
274                 break;
275         case MNOTE_NIKON_TAG_ISO:
276                 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
277                 CC (entry->components, 2, v, maxlen);
278                 //vs = exif_get_short (entry->data, entry->order);
279                 vs = exif_get_short (entry->data + 2, entry->order);
280                 snprintf (v, maxlen, "ISO %hd", vs);
281                 break;
282         case MNOTE_NIKON_TAG_ISO2:
283                 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
284                 CC (entry->components, 2, v, maxlen);
285                 //vs = exif_get_short (entry->data, entry->order);
286                 vs = exif_get_short (entry->data + 2, entry->order);
287                 snprintf (v, maxlen, "ISO2 %hd", vs);
288                 break;
289         case MNOTE_NIKON_TAG_QUALITY:
290                 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
291                 //CC (entry->components, 8, v, maxlen);
292                 //vl =  exif_get_long (entry->data  , entry->order);
293                 //printf("-> 0x%04x\n",entry->data);
294                 //printf("-> 0x%s<\n",entry->data - 0);
295                 memcpy(v, entry->data, MIN(maxlen, entry->size));
296                 //snprintf (v, maxlen, "%s<",  ( entry->data - 9  );
297                 break;
298         case MNOTE_NIKON_TAG_COLORMODE:
299         case MNOTE_NIKON_TAG_COLORMODE1:
300         case MNOTE_NIKON_TAG_WHITEBALANCE:
301         case MNOTE_NIKON_TAG_SHARPENING:
302         case MNOTE_NIKON_TAG_FOCUSMODE:
303         case MNOTE_NIKON_TAG_FLASHSETTING:
304         case MNOTE_NIKON_TAG_ISOSELECTION:
305         case MNOTE_NIKON_TAG_FLASHMODE:
306         case MNOTE_NIKON_TAG_IMAGEADJUSTMENT:
307         case MNOTE_NIKON_TAG_ADAPTER:
308         case MNOTE_NIKON_TAG_SATURATION2:
309         case MNOTE_EPSON_TAG_OEM_MODEL:
310                 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
311                 memcpy(v, entry->data, MIN (maxlen, entry->size));
312                 break;
313         case MNOTE_NIKON_TAG_TOTALPICTURES:
314         case MNOTE_EPSON_TAG_IMAGE_WIDTH:
315         case MNOTE_EPSON_TAG_IMAGE_HEIGHT:
316                 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
317                 CC (entry->components, 1, v, maxlen);
318                 vl =  exif_get_long (entry->data, entry->order);
319                 snprintf (v, maxlen, "%lu",  (long unsigned int) vl );
320                 break;
321         case MNOTE_NIKON_TAG_LENS_FSTOPS:
322         case MNOTE_NIKON_TAG_EXPOSUREDIFF: {
323                 unsigned char a,b,c,d;
324                 CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
325                 CC (entry->components, 4, v, maxlen);
326                 vl =  exif_get_long (entry->data, entry->order);
327                 a = (vl>>24)&0xff; b = (vl>>16)&0xff; c = (vl>>8)&0xff; d = (vl)&0xff;
328                 snprintf (v, maxlen, "%.1f",  c?(float)a*((float)b/(float)c):0 );
329                 break;
330         }
331         case MNOTE_NIKON_TAG_FLASHEXPCOMPENSATION:
332         case MNOTE_NIKON_TAG_FLASHEXPOSUREBRACKETVAL:
333                 CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
334                 CC (entry->components, 4, v, maxlen);
335                 vl =  exif_get_long (entry->data, entry->order);
336                 snprintf (v, maxlen, "%.1f",  ((long unsigned int) vl>>24)/6.0 );
337                 break;
338         case MNOTE_NIKON_TAG_SATURATION:
339         case MNOTE_NIKON_TAG_WHITEBALANCEFINE:
340         case MNOTE_NIKON_TAG_HUE:
341         case MNOTE_OLYMPUS_TAG_SENSORTEMPERATURE:
342         case MNOTE_OLYMPUS_TAG_LENSTEMPERATURE:
343                 CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen);
344                 CC (entry->components, 1, v, maxlen);
345                 vs = exif_get_short (entry->data, entry->order);
346                 snprintf (v, maxlen, "%hd", vs);
347                 break;
348         case MNOTE_NIKON_TAG_WHITEBALANCERB:
349                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
350                 CC (entry->components, 4, v, maxlen);
351                 vr = exif_get_rational (entry->data, entry->order);
352                 r = (double)vr.numerator / vr.denominator;
353                 vr = exif_get_rational (entry->data+8, entry->order);
354                 b = (double)vr.numerator / vr.denominator;
355                 //printf("numerator %li, denominator %li\n", vr.numerator, vr.denominator);
356                 snprintf (v, maxlen, _("Red Correction %f, Blue Correction %f"), r,b);
357                 break;
358         case MNOTE_NIKON_TAG_MANUALFOCUSDISTANCE:
359                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
360                 CC (entry->components, 1, v, maxlen);
361                 vr = exif_get_rational (entry->data, entry->order);
362                 if (vr.numerator) {
363                         r = (double)vr.numerator / vr.denominator;
364                         snprintf (v, maxlen, _("%2.2f meters"), r);
365                 } else {
366                         strncpy (v, _("No manual focus selection"), maxlen);
367                 }
368                 break;
369         case MNOTE_NIKON_TAG_SENSORPIXELSIZE:
370                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
371                 CC (entry->components, 2, v, maxlen);
372                 vr = exif_get_rational (entry->data, entry->order);
373                 vr2 = exif_get_rational (entry->data+8, entry->order);
374                 r = (double)vr.numerator / vr.denominator;
375                 b = (double)vr2.numerator / vr2.denominator;
376                 snprintf (v, maxlen, "%2.2f x %2.2f um", r, b);
377                 break;
378         case MNOTE_NIKON_TAG_BRACKETING:
379                 CF2 (entry->format, EXIF_FORMAT_BYTE, EXIF_FORMAT_SHORT, v, maxlen);
380                 CC (entry->components, 1, v, maxlen);
381                 if (EXIF_FORMAT_SHORT == entry->format) {
382                         vs = exif_get_short (entry->data, entry->order);
383                 } else {
384                         vs = entry->data[0];
385                 }
386                 snprintf (v, maxlen, "%hd", vs);
387                 break;
388         case MNOTE_NIKON_TAG_AFFOCUSPOSITION:
389                 CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
390                 CC (entry->components, 4, v, maxlen);
391                 switch (  *( entry->data+1)  ) {
392                         case  0: strncpy (v, _("AF Position: Center"), maxlen); break;
393                         case  1: strncpy (v, _("AF Position: Top"), maxlen); break;
394                         case  2: strncpy (v, _("AF Position: Bottom"), maxlen); break;
395                         case  3: strncpy (v, _("AF Position: Left"), maxlen); break;
396                         case  4: strncpy (v, _("AF Position: Right"), maxlen); break;
397                         case  5: strncpy (v, _("AF Position: Upper-left"), maxlen); break;
398                         case  6: strncpy (v, _("AF Position: Upper-right"), maxlen); break;
399                         case  7: strncpy (v, _("AF Position: Lower-left"), maxlen); break;
400                         case  8: strncpy (v, _("AF Position: Lower-right"), maxlen); break;
401                         case  9: strncpy (v, _("AF Position: Far Left"), maxlen); break;
402                         case  10: strncpy (v, _("AF Position: Far Right"), maxlen); break;
403                         default: strncpy (v, _("Unknown AF Position"), maxlen);
404                 }     
405                 break;
406         case MNOTE_OLYMPUS_TAG_FLASHDEVICE:
407                 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
408                 CC (entry->components, 2, v, maxlen);
409                 vs = exif_get_short(entry->data, entry->order);
410                 /* search for the tag */
411                 for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++)
412                         ;
413                 if (!items[i].tag) {
414                         snprintf (v, maxlen, _("Internal error (unknown value %hi)"), vs);
415                         break;
416                 }
417                 CF (entry->format, items[i].fmt, v, maxlen);
418                 /* find the value */
419                 for (j = 0; items[i].elem[j].string &&
420                             (items[i].elem[j].index < vs); j++);
421                 if (items[i].elem[j].index != vs) {
422                         snprintf (v, maxlen, _("Unknown value %hi"), vs);
423                         break;
424                 }
425                 strncpy (v, _(items[i].elem[j].string), maxlen);
426                 break;
427         case MNOTE_OLYMPUS_TAG_DIGIZOOM:
428                 if (entry->format == EXIF_FORMAT_RATIONAL) {
429                         CC (entry->components, 1, v, maxlen);
430                         vr = exif_get_rational (entry->data, entry->order);
431                         r = (double)vr.numerator / vr.denominator;
432                         if (!vr.numerator) {
433                                 strncpy (v, _("None"), maxlen);
434                         } else {
435                                 snprintf (v, maxlen, "%2.2f", r);
436                         }
437                         break;
438                 }
439                 /* fall through to handle SHORT version of this tag */
440         case MNOTE_NIKON_TAG_LENSTYPE:
441         case MNOTE_NIKON_TAG_FLASHUSED:
442         case MNOTE_NIKON1_TAG_QUALITY:
443         case MNOTE_NIKON1_TAG_COLORMODE:
444         case MNOTE_NIKON1_TAG_IMAGEADJUSTMENT:
445         case MNOTE_NIKON1_TAG_CCDSENSITIVITY:
446         case MNOTE_NIKON1_TAG_WHITEBALANCE:
447         case MNOTE_NIKON1_TAG_CONVERTER:
448         case MNOTE_OLYMPUS_TAG_QUALITY:
449         case MNOTE_OLYMPUS_TAG_MACRO:
450         case MNOTE_OLYMPUS_TAG_BWMODE:
451         case MNOTE_OLYMPUS_TAG_ONETOUCHWB:
452         case MNOTE_OLYMPUS_TAG_FLASHMODE:
453         case MNOTE_OLYMPUS_TAG_FOCUSRANGE:
454         case MNOTE_OLYMPUS_TAG_MANFOCUS:
455         case MNOTE_OLYMPUS_TAG_SHARPNESS:
456         case MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE:
457         case MNOTE_OLYMPUS_TAG_CONTRAST:
458         case MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID:
459         case MNOTE_OLYMPUS_TAG_CCDSCANMODE:
460         case MNOTE_SANYO_TAG_SEQUENTIALSHOT:
461         case MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE:
462         case MNOTE_SANYO_TAG_RESAVED:
463         case MNOTE_SANYO_TAG_SCENESELECT:
464         case MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL:
465                 CC (entry->components, 1, v, maxlen);
466                 switch (entry->format) {
467                 case EXIF_FORMAT_BYTE:
468                 case EXIF_FORMAT_UNDEFINED:
469                         vs = entry->data[0];
470                         break;
471                 case EXIF_FORMAT_SHORT:
472                         vs = exif_get_short(entry->data, entry->order);
473                         break;
474                 default:
475                         vs = 0;
476                         break;
477                 }
478                 /* search for the tag */
479                 for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++)
480                         ;
481                 if (!items[i].tag) {
482                         snprintf (v, maxlen, _("Internal error (unknown value %hi)"), vs);
483                         break;
484                 }
485                 CF (entry->format, items[i].fmt, v, maxlen);
486                 /* find the value */
487                 for (j = 0; items[i].elem[j].string &&
488                             (items[i].elem[j].index < vs); j++);
489                 if (items[i].elem[j].index != vs) {
490                         snprintf (v, maxlen, _("Unknown value %hi"), vs);
491                         break;
492                 }
493                 strncpy (v, _(items[i].elem[j].string), maxlen);
494                 break;
495         case MNOTE_OLYMPUS_TAG_NOISEREDUCTION:
496         case MNOTE_SANYO_TAG_WIDERANGE:
497         case MNOTE_SANYO_TAG_COLORADJUSTMENTMODE:
498         case MNOTE_SANYO_TAG_QUICKSHOT:
499         case MNOTE_SANYO_TAG_SELFTIMER:
500         case MNOTE_SANYO_TAG_VOICEMEMO:
501         case MNOTE_SANYO_TAG_FLICKERREDUCE:
502         case MNOTE_SANYO_TAG_OPTICALZOOM:
503         case MNOTE_SANYO_TAG_DIGITALZOOM:
504         case MNOTE_SANYO_TAG_LIGHTSOURCESPECIAL:
505                 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
506                 CC (entry->components, 1, v, maxlen);
507                 vs = exif_get_short (entry->data, entry->order);
508                 switch (vs) {
509                 case 0:
510                         strncpy (v, _("Off"), maxlen);
511                         break;
512                 case 1:
513                         strncpy (v, _("On"), maxlen);
514                         break;
515                 default:
516                         strncpy (v, _("Unknown"), maxlen);
517                         break;
518                 }
519                 break;
520         case MNOTE_NIKON_TAG_LENS:
521                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
522                 CC (entry->components, 4, v, maxlen);
523                 {
524                         double c,d;
525                         unsigned long a,b;
526                         vr = exif_get_rational (entry->data, entry->order);
527                         a = vr.numerator / vr.denominator;
528                         vr = exif_get_rational (entry->data+8, entry->order);
529                         b = vr.numerator / vr.denominator;
530                         vr = exif_get_rational (entry->data+16, entry->order);
531                         c = (double)vr.numerator / vr.denominator;
532                         vr = exif_get_rational (entry->data+24, entry->order);
533                         d = (double)vr.numerator / vr.denominator;
534                         //printf("numerator %li, denominator %li\n", vr.numerator, vr.denominator);
535                         snprintf (v, maxlen, "%ld-%ldmm 1:%3.1f - %3.1f",a,b,c,d);
536                 }
537                 break;
538
539         /* Olympus */
540         case MNOTE_OLYMPUS_TAG_MODE:
541                 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
542                 CC (entry->components, 3, v, maxlen);
543                 vl = exif_get_long (entry->data, entry->order);
544                 switch (vl) {
545                 case 0:
546                         strncpy (v, _("normal"), maxlen);
547                         break;
548                 case 1:
549                         strncpy (v, _("unknown"), maxlen);
550                         break;
551                 case 2:
552                         strncpy (v, _("fast"), maxlen);
553                         break;
554                 case 3:
555                         strncpy (v, _("panorama"), maxlen);
556                         break;
557                 default:
558                         snprintf (v, maxlen, _("%li"), (long int) vl);
559                 }
560                 vl = exif_get_long (entry->data + 4, entry->order);
561                 snprintf (buf, sizeof (buf), "/%li/", (long int) vl);
562                 strncat (v, buf, maxlen - strlen (v));
563                 vl = exif_get_long (entry->data + 8, entry->order);
564                 switch (vl) {
565                 case 1:
566                         strncat (v, _("left to right"), maxlen - strlen (v));
567                         break;
568                 case 2:
569                         strncat (v, _("right to left"), maxlen - strlen (v));
570                         break;
571                 case 3:
572                         strncat (v, _("bottom to top"), maxlen - strlen (v));
573                         break;
574                 case 4:
575                         strncat (v, _("top to bottom"), maxlen - strlen (v));
576                         break;
577                 default:
578                         snprintf (buf, sizeof (buf), _("%li"),
579                                   (long int) vl);
580                         strncat (v, buf, maxlen - strlen (v));
581                 }
582                 break;
583         case MNOTE_OLYMPUS_TAG_LENSDISTORTION:
584                 if (entry->format == EXIF_FORMAT_SHORT) {
585                         /* Epson uses a single SHORT here */
586                         CC (entry->components, 1, v, maxlen);
587                         vs = exif_get_short (entry->data, entry->order);
588                         sprintf (buf, "%hu", vs);
589                         strncat (v, buf, maxlen - strlen (v));
590                 } else {
591                         /* Others use an array of SSHORT here */
592                         CC (entry->components, 6, v, maxlen);
593                         CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen);
594                         for (i=0; i < (int)entry->components; ++i) {
595                                 vss = exif_get_sshort (entry->data+2*i, entry->order);
596                                 sprintf (buf, "%hd ", vss);
597                                 strncat (v, buf, maxlen - strlen (v));
598                         }
599                 }
600                 break;
601         case MNOTE_OLYMPUS_TAG_COLORCONTROL:
602                 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
603                 CC (entry->components, 6, v, maxlen);
604                 for (i=0; i < (int)entry->components; ++i) {
605                         vs = exif_get_short (entry->data+2*i, entry->order);
606                         sprintf (buf, "%hu ", vs);
607                         strncat (v, buf, maxlen - strlen (v));
608                 }
609                 break;
610         case MNOTE_OLYMPUS_TAG_VERSION:
611                 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
612                 CC2 (entry->components, 5, 8, v, maxlen);
613                 strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
614                 break;
615         case MNOTE_OLYMPUS_TAG_SERIALNUMBER2:
616                 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
617                 strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
618                 break;
619         case MNOTE_OLYMPUS_TAG_INFO:
620                 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
621                 CC2 (entry->components, 52, 60, v, maxlen);
622                 strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
623                 break;
624         case MNOTE_OLYMPUS_TAG_ID:
625                 CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
626                 CC (entry->components, 32, v, maxlen);
627                 strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
628                 break;
629         case MNOTE_OLYMPUS_TAG_UNKNOWN_4:
630                 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
631                 CC (entry->components, 30, v, maxlen);
632                 /* TODO: display me */
633                 break;
634         case MNOTE_OLYMPUS_TAG_FOCUSDIST:
635                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
636                 CC (entry->components, 1, v, maxlen);
637                 vr = exif_get_rational (entry->data, entry->order);
638                 if (vr.numerator == 0) {
639                         strncpy (v, _("Unknown"), maxlen);
640                 }
641                 else {
642                         unsigned long tmp = vr.numerator / vr.denominator;
643                         /* printf("numerator %li, denominator %li\n", vr.numerator, vr.denominator); */
644                         snprintf (v, maxlen, "%li mm", tmp);
645                 }
646                 break;
647         case MNOTE_OLYMPUS_TAG_WBALANCE:
648                 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
649                 CC (entry->components, 2, v, maxlen);
650                 vs = exif_get_short (entry->data, entry->order);
651                 switch (vs) {
652                 case 1:
653                         strncpy (v, _("Automatic"), maxlen);
654                         break;
655                 case 2:
656                         {
657                                 ExifShort v2 = exif_get_short (entry->data + 2, entry->order);
658                                 unsigned long colorTemp = 0;
659                                 switch (v2) {
660                                 case 2:
661                                         colorTemp = 3000;
662                                         break;
663                                 case 3:
664                                         colorTemp = 3700;
665                                         break;
666                                 case 4:
667                                         colorTemp = 4000;
668                                         break;
669                                 case 5:
670                                         colorTemp = 4500;
671                                         break;
672                                 case 6:
673                                         colorTemp = 5500;
674                                         break;
675                                 case 7:
676                                         colorTemp = 6500;
677                                         break;
678                                 case 9:
679                                         colorTemp = 7500;
680                                         break;
681                                 }
682                                 if (colorTemp) {
683                                         snprintf (v, maxlen, _("Manual: %liK"), colorTemp);
684                                 }
685                                 else {
686                                         strncpy (v, _("Manual: Unknown"), maxlen);
687                                 }
688
689                         }
690                         break;
691                 case 3:
692                         strncpy (v, _("One-touch"), maxlen);
693                         break;
694                 default:
695                         strncpy (v, _("Unknown"), maxlen);
696                         break;
697                 }
698                 break;
699         case MNOTE_OLYMPUS_TAG_REDBALANCE:
700         case MNOTE_OLYMPUS_TAG_BLUEBALANCE:
701                 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
702                 CC (entry->components, 2, v, maxlen);
703                 vs = exif_get_short (entry->data, entry->order);
704                 snprintf (v, maxlen, "%hu ", vs);
705                 vs = exif_get_short (entry->data + 2, entry->order);
706                 sprintf (buf, "%hu", vs);
707                 strncat (v, buf, maxlen - strlen (v));
708                 break;
709         case MNOTE_OLYMPUS_TAG_BLACKLEVEL:
710         case MNOTE_NIKON_TAG_IMAGEBOUNDARY:
711                 CC (entry->components, 4, v, maxlen);
712                 /* Fall through to COLORMATRIX */
713         case MNOTE_OLYMPUS_TAG_COLORMATRIX:
714                 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
715                 if (entry->tag == MNOTE_OLYMPUS_TAG_COLORMATRIX)
716                         CC (entry->components, 9, v, maxlen);
717                 for (i=0; i < (int)entry->components; ++i) {
718                         vs = exif_get_short (entry->data+2*i, entry->order);
719                         sprintf (buf, "%hu ", vs);
720                         strncat (v, buf, maxlen - strlen (v));
721                 }
722                 break;
723         case MNOTE_NIKON1_TAG_FOCUS:
724         case MNOTE_NIKON_TAG_DIGITALZOOM:
725         case MNOTE_NIKON1_TAG_DIGITALZOOM:
726         case MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL:
727                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
728                 /* Fall through to default handler for display */
729         default:
730                 switch (entry->format) {
731                 case EXIF_FORMAT_ASCII:
732                         strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
733                         break;
734                 case EXIF_FORMAT_SHORT:
735                         CC (entry->components, 1, v, maxlen);
736                         vs = exif_get_short (entry->data, entry->order);
737                         snprintf (v, maxlen, "%hu", vs);
738                         break;
739                 case EXIF_FORMAT_LONG:
740                         CC (entry->components, 1, v, maxlen);
741                         vl = exif_get_long (entry->data, entry->order);
742                         snprintf (v, maxlen, "%li", (long int) vl);
743                         break;
744                 case EXIF_FORMAT_RATIONAL:
745                         CC (entry->components, 1, v, maxlen);
746                         vr = exif_get_rational (entry->data, entry->order);
747                         if (!vr.denominator) {
748                                 strncpy (v, _("Infinite"), maxlen);
749                         } else {
750                                 r = (double)vr.numerator / vr.denominator;
751                                 snprintf (v, maxlen, "%2.3f", r);
752                         }
753                         break;
754                 case EXIF_FORMAT_SRATIONAL:
755                         CC (entry->components, 1, v, maxlen);
756                         vsr = exif_get_srational (entry->data, entry->order);
757                         if (!vsr.denominator) {
758                                 strncpy (v, _("Infinite"), maxlen);
759                         } else {
760                                 r = (double)vsr.numerator / vsr.denominator;
761                                 snprintf (v, maxlen, "%2.3f", r);
762                         }
763                         break;
764                 case EXIF_FORMAT_UNDEFINED:
765                 default:
766                         snprintf (v, maxlen, _("%i bytes unknown data: "),
767                                   entry->size);
768                         for (i = 0; i < (int)entry->size; i++) {
769                                 sprintf (buf, "%02x", entry->data[i]);
770                                 strncat (v, buf, maxlen - strlen (v));
771                         }
772                         break;
773                 }
774                 break;
775         }
776
777         return (v);
778 }