• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/minidlna/libexif-0.6.19/libexif/olympus/
1/* mnote-olympus-entry.c
2 *
3 * Copyright (c) 2002-2009 Lutz Mueller <lutz@users.sourceforge.net> et. al.
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., 51 Franklin Street, Fifth Floor,
18 * Boston, MA  02110-1301  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
79static const struct {
80	ExifTag tag;
81	ExifFormat fmt;
82	struct {
83		int index;
84		const char *string;
85	} elem[24];
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_("ISO 80")},
125      {2, N_("ISO 160")},
126      {4, N_("ISO 320")},
127      {5, N_("ISO 100")},
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_("Normal, SQ")},
144      {2, N_("Normal, HQ")},
145      {3, N_("Normal, SHQ")},
146      {4, N_("Normal, RAW")},
147      {5, N_("Normal, SQ1")},
148      {6, N_("Normal, SQ2")},
149      {7, N_("Normal, super high")},
150      {17, N_("Normal, standard")},
151      {0x101, N_("Fine, SQ")},
152      {0x102, N_("Fine, HQ")},
153      {0x103, N_("Fine, SHQ")},
154      {0x104, N_("Fine, RAW")},
155      {0x105, N_("Fine, SQ1")},
156      {0x106, N_("Fine, SQ2")},
157      {0x107, N_("Fine, super high")},
158      {0x201, N_("Super fine, SQ")},
159      {0x202, N_("Super fine, HQ")},
160      {0x203, N_("Super fine, SHQ")},
161      {0x204, N_("Super fine, RAW")},
162      {0x205, N_("Super fine, SQ1")},
163      {0x206, N_("Super fine, SQ2")},
164      {0x207, N_("Super fine, super high")},
165      {0x211, N_("Super fine, high")},
166      {0, NULL}}},
167  { MNOTE_OLYMPUS_TAG_MACRO, EXIF_FORMAT_SHORT,
168    { {0, N_("No")},
169      {1, N_("Yes")},
170      {2, N_("Super Macro")},
171      {0, NULL}}},
172  { MNOTE_OLYMPUS_TAG_BWMODE, EXIF_FORMAT_SHORT,
173    { {0, N_("No")},
174      {1, N_("Yes")},
175      {0, NULL}}},
176  { MNOTE_OLYMPUS_TAG_ONETOUCHWB, EXIF_FORMAT_SHORT,
177    { {0, N_("Off")},
178      {1, N_("On")},
179      {2, N_("On (Preset)")},
180      {0, NULL}}},
181  { MNOTE_OLYMPUS_TAG_FLASHMODE, EXIF_FORMAT_SHORT,
182    { {0, N_("Auto")},
183      {1, N_("Red-eye reduction")},
184      {2, N_("Fill")},
185      {3, N_("Off")},
186      {0, NULL}}},
187  { MNOTE_OLYMPUS_TAG_FLASHDEVICE, EXIF_FORMAT_SHORT,
188    { {0, N_("None")},
189      {1, N_("Internal")},
190      {4, N_("External")},
191      {5, N_("Internal + External")},
192      {0, NULL}}},
193  { MNOTE_OLYMPUS_TAG_FOCUSRANGE, EXIF_FORMAT_SHORT,
194    { {0, N_("Normal")},
195      {1, N_("Macro")},
196      {0, NULL}}},
197  { MNOTE_OLYMPUS_TAG_MANFOCUS, EXIF_FORMAT_SHORT,
198    { {0, N_("Auto")},
199      {1, N_("Manual")},
200      {0, NULL}}},
201  { MNOTE_OLYMPUS_TAG_SHARPNESS, EXIF_FORMAT_SHORT,
202    { {0, N_("Normal")},
203      {1, N_("Hard")},
204      {2, N_("Soft")},
205      {0, NULL}}},
206  { MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE, EXIF_FORMAT_SHORT,
207    { {0, N_("No")},
208      {1, N_("Yes")},
209      {0, NULL}}},
210  { MNOTE_OLYMPUS_TAG_CONTRAST, EXIF_FORMAT_SHORT,
211    { {0, N_("Hard")},
212      {1, N_("Normal")},
213      {2, N_("Soft")},
214      {0, NULL}}},
215  { MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID, EXIF_FORMAT_LONG,
216    { {0, N_("No")},
217      {1, N_("Yes")},
218      {0, NULL}}},
219  { MNOTE_OLYMPUS_TAG_CCDSCANMODE, EXIF_FORMAT_SHORT,
220    { {0, N_("Interlaced")},
221      {1, N_("Progressive")},
222      {0, NULL}}},
223
224  { MNOTE_SANYO_TAG_SEQUENTIALSHOT, EXIF_FORMAT_SHORT,
225    { {0, N_("None")},
226      {1, N_("Standard")},
227      {2, N_("Best")},
228      {3, N_("Adjust Exposure")},
229      {0, NULL}}},
230  { MNOTE_SANYO_TAG_FOCUSMODE, EXIF_FORMAT_SHORT,
231    { {1, N_("Spot Focus")},
232      {2, N_("Normal Focus")},
233      {0, NULL}}},
234  { MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE, EXIF_FORMAT_SHORT,
235    { {0, N_("Record while down")},
236      {1, N_("Press start, press stop")},
237      {0, NULL}}},
238  { MNOTE_SANYO_TAG_RESAVED, EXIF_FORMAT_SHORT,
239    { {0, N_("No")},
240      {1, N_("Yes")},
241      {0, NULL}}},
242  { MNOTE_SANYO_TAG_CCDSENSITIVITY, EXIF_FORMAT_SHORT,
243    { {0, N_("Auto")},
244      {1, N_("ISO 50")},
245      {3, N_("ISO 100")},
246      {4, N_("ISO 200")},
247      {5, N_("ISO 400")},
248      {0, NULL}}},
249  { MNOTE_SANYO_TAG_SCENESELECT, EXIF_FORMAT_SHORT,
250    { {0, N_("Off")},
251      {1, N_("Sport")},
252      {2, N_("TV")},
253      {3, N_("Night")},
254      {4, N_("User 1")},
255      {5, N_("User 2")},
256      {6, N_("Lamp")},
257      {0, NULL}}},
258  { MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL, EXIF_FORMAT_SHORT,
259    { {0, N_("5 frames/sec")},
260      {1, N_("10 frames/sec")},
261      {2, N_("15 frames/sec")},
262      {3, N_("20 frames/sec")},
263      {0, NULL}}},
264#endif
265  { 0, 0, { { 0, NULL } } }
266};
267
268char *
269mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *v, unsigned int maxlen)
270{
271	char         buf[30];
272	ExifLong     vl;
273	ExifShort    vs = 0;
274	ExifSShort   vss = 0;
275	ExifRational vr, vr2;
276	ExifSRational vsr;
277	int          i, j;
278	double       r, b;
279
280	if (!entry)
281		return (NULL);
282
283	memset (v, 0, maxlen);
284	maxlen--;
285
286	if ((!entry->data) && (entry->components > 0))
287		return (v);
288
289	switch (entry->tag) {
290
291	/* Nikon */
292	case MNOTE_NIKON_TAG_FIRMWARE:
293		CF (entry->format,  EXIF_FORMAT_UNDEFINED, v, maxlen);
294		CC (entry->components, 4, v, maxlen);
295		vl = exif_get_long (entry->data, entry->order);
296		if ((vl & 0xF0F0F0F0) == 0x30303030) {
297			memcpy (v, entry->data, MIN (maxlen, 4));
298		} else {
299			snprintf (v, maxlen, "%04lx", (long unsigned int) vl);
300		}
301		break;
302	case MNOTE_NIKON_TAG_ISO:
303                CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
304                CC (entry->components, 2, v, maxlen);
305                /*vs = exif_get_short (entry->data, entry->order);*/
306                vs = exif_get_short (entry->data + 2, entry->order);
307                snprintf (v, maxlen, "ISO %hd", vs);
308                break;
309	case MNOTE_NIKON_TAG_ISO2:
310                CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
311                CC (entry->components, 2, v, maxlen);
312                /*vs = exif_get_short (entry->data, entry->order);*/
313                vs = exif_get_short (entry->data + 2, entry->order);
314                snprintf (v, maxlen, "ISO2 %hd", vs);
315                break;
316	case MNOTE_NIKON_TAG_QUALITY:
317	case MNOTE_NIKON_TAG_COLORMODE:
318	case MNOTE_NIKON_TAG_COLORMODE1:
319	case MNOTE_NIKON_TAG_WHITEBALANCE:
320	case MNOTE_NIKON_TAG_SHARPENING:
321	case MNOTE_NIKON_TAG_FOCUSMODE:
322	case MNOTE_NIKON_TAG_FLASHSETTING:
323	case MNOTE_NIKON_TAG_ISOSELECTION:
324	case MNOTE_NIKON_TAG_FLASHMODE:
325	case MNOTE_NIKON_TAG_IMAGEADJUSTMENT:
326	case MNOTE_NIKON_TAG_ADAPTER:
327	case MNOTE_NIKON_TAG_SATURATION2:
328	case MNOTE_EPSON_TAG_SOFTWARE:
329		CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
330		memcpy(v, entry->data, MIN (maxlen, entry->size));
331		break;
332	case MNOTE_NIKON_TAG_TOTALPICTURES:
333	case MNOTE_EPSON_TAG_IMAGE_WIDTH:
334	case MNOTE_EPSON_TAG_IMAGE_HEIGHT:
335		CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
336		CC (entry->components, 1, v, maxlen);
337		vl =  exif_get_long (entry->data, entry->order);
338		snprintf (v, maxlen, "%lu",  (long unsigned int) vl );
339		break;
340	case MNOTE_NIKON_TAG_LENS_FSTOPS:
341	case MNOTE_NIKON_TAG_EXPOSUREDIFF: {
342		unsigned char a,b,c,d;
343		CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
344		CC (entry->components, 4, v, maxlen);
345		vl =  exif_get_long (entry->data, entry->order);
346		a = (vl>>24)&0xff; b = (vl>>16)&0xff; c = (vl>>8)&0xff; d = (vl)&0xff;
347		snprintf (v, maxlen, "%.1f",  c?(float)a*((float)b/(float)c):0 );
348		break;
349	}
350	case MNOTE_NIKON_TAG_FLASHEXPCOMPENSATION:
351	case MNOTE_NIKON_TAG_FLASHEXPOSUREBRACKETVAL:
352		CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
353		CC (entry->components, 4, v, maxlen);
354		vl =  exif_get_long (entry->data, entry->order);
355		snprintf (v, maxlen, "%.1f",  ((long unsigned int) vl>>24)/6.0 );
356		break;
357	case MNOTE_NIKON_TAG_SATURATION:
358	case MNOTE_NIKON_TAG_WHITEBALANCEFINE:
359	case MNOTE_NIKON_TAG_HUE:
360	case MNOTE_OLYMPUS_TAG_SENSORTEMPERATURE:
361	case MNOTE_OLYMPUS_TAG_LENSTEMPERATURE:
362		CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen);
363		CC (entry->components, 1, v, maxlen);
364		vs = exif_get_short (entry->data, entry->order);
365		snprintf (v, maxlen, "%hd", vs);
366		break;
367	case MNOTE_NIKON_TAG_WHITEBALANCERB:
368		CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
369		CC (entry->components, 4, v, maxlen);
370		vr = exif_get_rational (entry->data, entry->order);
371		r = (double)vr.numerator / vr.denominator;
372		vr = exif_get_rational (entry->data+8, entry->order);
373		b = (double)vr.numerator / vr.denominator;
374		snprintf (v, maxlen, _("Red Correction %f, Blue Correction %f"), r,b);
375		break;
376	case MNOTE_NIKON_TAG_MANUALFOCUSDISTANCE:
377		CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
378		CC (entry->components, 1, v, maxlen);
379		vr = exif_get_rational (entry->data, entry->order);
380		if (vr.numerator) {
381			r = (double)vr.numerator / vr.denominator;
382			snprintf (v, maxlen, _("%2.2f meters"), r);
383		} else {
384			strncpy (v, _("No manual focus selection"), maxlen);
385		}
386		break;
387	case MNOTE_NIKON_TAG_SENSORPIXELSIZE:
388		CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
389		CC (entry->components, 2, v, maxlen);
390		vr = exif_get_rational (entry->data, entry->order);
391		vr2 = exif_get_rational (entry->data+8, entry->order);
392		r = (double)vr.numerator / vr.denominator;
393		b = (double)vr2.numerator / vr2.denominator;
394		snprintf (v, maxlen, "%2.2f x %2.2f um", r, b);
395		break;
396	case MNOTE_NIKON_TAG_BRACKETING:
397		CF2 (entry->format, EXIF_FORMAT_BYTE, EXIF_FORMAT_SHORT, v, maxlen);
398		CC (entry->components, 1, v, maxlen);
399		if (EXIF_FORMAT_SHORT == entry->format) {
400			vs = exif_get_short (entry->data, entry->order);
401		} else {
402			vs = entry->data[0];
403		}
404		snprintf (v, maxlen, "%hd", vs);
405		break;
406	case MNOTE_NIKON_TAG_AFFOCUSPOSITION:
407		CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
408		CC (entry->components, 4, v, maxlen);
409		switch (  *( entry->data+1)  ) {
410		  	case  0: strncpy (v, _("AF Position: Center"), maxlen); break;
411		  	case  1: strncpy (v, _("AF Position: Top"), maxlen); break;
412		  	case  2: strncpy (v, _("AF Position: Bottom"), maxlen); break;
413		  	case  3: strncpy (v, _("AF Position: Left"), maxlen); break;
414		  	case  4: strncpy (v, _("AF Position: Right"), maxlen); break;
415			case  5: strncpy (v, _("AF Position: Upper-left"), maxlen); break;
416		  	case  6: strncpy (v, _("AF Position: Upper-right"), maxlen); break;
417		  	case  7: strncpy (v, _("AF Position: Lower-left"), maxlen); break;
418		  	case  8: strncpy (v, _("AF Position: Lower-right"), maxlen); break;
419		  	case  9: strncpy (v, _("AF Position: Far Left"), maxlen); break;
420		  	case  10: strncpy (v, _("AF Position: Far Right"), maxlen); break;
421		  	default: strncpy (v, _("Unknown AF Position"), maxlen);
422		}
423		break;
424	case MNOTE_OLYMPUS_TAG_FLASHDEVICE:
425		CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
426		CC (entry->components, 2, v, maxlen);
427		vs = exif_get_short(entry->data, entry->order);
428		/* search for the tag */
429		for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++)
430			;
431		if (!items[i].tag) {
432		  	snprintf (v, maxlen, _("Internal error (unknown value %hi)"), vs);
433		  	break;
434		}
435		CF (entry->format, items[i].fmt, v, maxlen);
436		/* find the value */
437		for (j = 0; items[i].elem[j].string &&
438			    (items[i].elem[j].index < vs); j++);
439		if (items[i].elem[j].index != vs) {
440			snprintf (v, maxlen, _("Unknown value %hi"), vs);
441			break;
442		}
443		strncpy (v, _(items[i].elem[j].string), maxlen);
444		break;
445	case MNOTE_OLYMPUS_TAG_DIGIZOOM:
446		if (entry->format == EXIF_FORMAT_RATIONAL) {
447			CC (entry->components, 1, v, maxlen);
448			vr = exif_get_rational (entry->data, entry->order);
449			r = (double)vr.numerator / vr.denominator;
450			if (!vr.numerator) {
451				strncpy (v, _("None"), maxlen);
452			} else {
453				snprintf (v, maxlen, "%2.2f", r);
454			}
455			break;
456		}
457		/* fall through to handle SHORT version of this tag */
458	case MNOTE_NIKON_TAG_LENSTYPE:
459	case MNOTE_NIKON_TAG_FLASHUSED:
460	case MNOTE_NIKON1_TAG_QUALITY:
461	case MNOTE_NIKON1_TAG_COLORMODE:
462	case MNOTE_NIKON1_TAG_IMAGEADJUSTMENT:
463	case MNOTE_NIKON1_TAG_CCDSENSITIVITY:
464	case MNOTE_NIKON1_TAG_WHITEBALANCE:
465	case MNOTE_NIKON1_TAG_CONVERTER:
466	case MNOTE_OLYMPUS_TAG_QUALITY:
467	case MNOTE_OLYMPUS_TAG_MACRO:
468	case MNOTE_OLYMPUS_TAG_BWMODE:
469	case MNOTE_OLYMPUS_TAG_ONETOUCHWB:
470	case MNOTE_OLYMPUS_TAG_FLASHMODE:
471	case MNOTE_OLYMPUS_TAG_FOCUSRANGE:
472	case MNOTE_OLYMPUS_TAG_MANFOCUS:
473	case MNOTE_OLYMPUS_TAG_SHARPNESS:
474	case MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE:
475	case MNOTE_OLYMPUS_TAG_CONTRAST:
476	case MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID:
477	case MNOTE_OLYMPUS_TAG_CCDSCANMODE:
478	case MNOTE_SANYO_TAG_SEQUENTIALSHOT:
479	case MNOTE_SANYO_TAG_FOCUSMODE:
480	case MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE:
481	case MNOTE_SANYO_TAG_RESAVED:
482	case MNOTE_SANYO_TAG_CCDSENSITIVITY:
483	case MNOTE_SANYO_TAG_SCENESELECT:
484	case MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL:
485		CC (entry->components, 1, v, maxlen);
486		switch (entry->format) {
487		case EXIF_FORMAT_BYTE:
488		case EXIF_FORMAT_UNDEFINED:
489			vs = entry->data[0];
490			break;
491		case EXIF_FORMAT_SHORT:
492			vs = exif_get_short(entry->data, entry->order);
493			break;
494		default:
495			vs = 0;
496			break;
497		}
498		/* search for the tag */
499		for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++)
500			;
501		if (!items[i].tag) {
502		  	snprintf (v, maxlen, _("Internal error (unknown value %hi)"), vs);
503		  	break;
504		}
505		CF (entry->format, items[i].fmt, v, maxlen);
506		/* find the value */
507		for (j = 0; items[i].elem[j].string &&
508			    (items[i].elem[j].index < vs); j++);
509		if (items[i].elem[j].index != vs) {
510			snprintf (v, maxlen, _("Unknown value %hi"), vs);
511			break;
512		}
513		strncpy (v, _(items[i].elem[j].string), maxlen);
514		break;
515	case MNOTE_OLYMPUS_TAG_NOISEREDUCTION:
516	case MNOTE_SANYO_TAG_WIDERANGE:
517	case MNOTE_SANYO_TAG_COLORADJUSTMENTMODE:
518	case MNOTE_SANYO_TAG_QUICKSHOT:
519	case MNOTE_SANYO_TAG_VOICEMEMO:
520	case MNOTE_SANYO_TAG_FLICKERREDUCE:
521	case MNOTE_SANYO_TAG_OPTICALZOOM:
522	case MNOTE_SANYO_TAG_DIGITALZOOM:
523	case MNOTE_SANYO_TAG_LIGHTSOURCESPECIAL:
524		CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
525		CC (entry->components, 1, v, maxlen);
526		vs = exif_get_short (entry->data, entry->order);
527		switch (vs) {
528		case 0:
529			strncpy (v, _("Off"), maxlen);
530			break;
531		case 1:
532			strncpy (v, _("On"), maxlen);
533			break;
534		default:
535			sprintf (buf, _("Unknown %hu"), vs);
536			strncat (v, buf, maxlen - strlen (v));
537			break;
538		}
539		break;
540	case MNOTE_SANYO_TAG_SELFTIMER:
541		CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
542		CC (entry->components, 1, v, maxlen);
543		vs = exif_get_short (entry->data, entry->order);
544		switch (vs) {
545		case 0:
546			strncpy (v, _("Off"), maxlen);
547			break;
548		case 1:
549			strncpy (v, _("On"), maxlen);
550			break;
551		case 2:
552			strncpy (v, _("2 sec."), maxlen);
553			break;
554		default:
555			sprintf (buf, _("Unknown %hu"), vs);
556			strncat (v, buf, maxlen - strlen (v));
557			break;
558		}
559		break;
560	case MNOTE_NIKON_TAG_LENS:
561		CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
562		CC (entry->components, 4, v, maxlen);
563		{
564			double c,d;
565			unsigned long a,b;
566			vr = exif_get_rational (entry->data, entry->order);
567			a = vr.numerator / vr.denominator;
568			vr = exif_get_rational (entry->data+8, entry->order);
569			b = vr.numerator / vr.denominator;
570			vr = exif_get_rational (entry->data+16, entry->order);
571			c = (double)vr.numerator / vr.denominator;
572			vr = exif_get_rational (entry->data+24, entry->order);
573			d = (double)vr.numerator / vr.denominator;
574			snprintf (v, maxlen, "%ld-%ldmm 1:%3.1f - %3.1f",a,b,c,d);
575		}
576		break;
577
578	/* Olympus */
579	case MNOTE_OLYMPUS_TAG_MODE:
580		CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
581		CC (entry->components, 3, v, maxlen);
582		vl = exif_get_long (entry->data, entry->order);
583		switch (vl) {
584		case 0:
585			strncpy (v, _("normal"), maxlen);
586			break;
587		case 1:
588			strncpy (v, _("unknown"), maxlen);
589			break;
590		case 2:
591			strncpy (v, _("fast"), maxlen);
592			break;
593		case 3:
594			strncpy (v, _("panorama"), maxlen);
595			break;
596		default:
597			snprintf (v, maxlen, "%li", (long int) vl);
598		}
599		vl = exif_get_long (entry->data + 4, entry->order);
600		snprintf (buf, sizeof (buf), "/%li/", (long int) vl);
601		strncat (v, buf, maxlen - strlen (v));
602		vl = exif_get_long (entry->data + 8, entry->order);
603		switch (vl) {
604		case 1:
605			strncat (v, _("left to right"), maxlen - strlen (v));
606			break;
607		case 2:
608			strncat (v, _("right to left"), maxlen - strlen (v));
609			break;
610		case 3:
611			strncat (v, _("bottom to top"), maxlen - strlen (v));
612			break;
613		case 4:
614			strncat (v, _("top to bottom"), maxlen - strlen (v));
615			break;
616		default:
617			snprintf (buf, sizeof (buf), "%li",
618				  (long int) vl);
619			strncat (v, buf, maxlen - strlen (v));
620		}
621		break;
622	case MNOTE_OLYMPUS_TAG_LENSDISTORTION:
623		if (entry->format == EXIF_FORMAT_SHORT) {
624			/* Epson uses a single SHORT here */
625			CC (entry->components, 1, v, maxlen);
626			vs = exif_get_short (entry->data, entry->order);
627			sprintf (buf, "%hu", vs);
628			strncat (v, buf, maxlen - strlen (v));
629		} else {
630			/* Others use an array of SSHORT here */
631			CC (entry->components, 6, v, maxlen);
632			CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen);
633			for (i=0; i < (int)entry->components; ++i) {
634				vss = exif_get_sshort (entry->data+2*i, entry->order);
635				sprintf (buf, "%hd ", vss);
636				strncat (v, buf, maxlen - strlen (v));
637			}
638		}
639		break;
640	case MNOTE_OLYMPUS_TAG_COLORCONTROL:
641		CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
642		CC (entry->components, 6, v, maxlen);
643		for (i=0; i < (int)entry->components; ++i) {
644			vs = exif_get_short (entry->data+2*i, entry->order);
645			sprintf (buf, "%hu ", vs);
646			strncat (v, buf, maxlen - strlen (v));
647		}
648		break;
649	case MNOTE_OLYMPUS_TAG_VERSION:
650		CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
651		CC2 (entry->components, 5, 8, v, maxlen);
652		strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
653		break;
654	case MNOTE_OLYMPUS_TAG_SERIALNUMBER2:
655		CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
656		strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
657		break;
658	case MNOTE_OLYMPUS_TAG_INFO:
659		CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
660		CC2 (entry->components, 52, 60, v, maxlen);
661		strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
662		break;
663	case MNOTE_OLYMPUS_TAG_ID:
664		CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
665		CC (entry->components, 32, v, maxlen);
666		strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
667		break;
668	case MNOTE_OLYMPUS_TAG_UNKNOWN_4:
669		CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
670		CC (entry->components, 30, v, maxlen);
671		for (i=0; i < (int)entry->components; ++i) {
672			vl = exif_get_long (entry->data+4*i, entry->order);
673			sprintf (buf, "%lu ", (unsigned long)vl);
674			strncat (v, buf, maxlen - strlen (v));
675		}
676		break;
677	case MNOTE_OLYMPUS_TAG_FOCUSDIST:
678		CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
679		CC (entry->components, 1, v, maxlen);
680		vr = exif_get_rational (entry->data, entry->order);
681		if (vr.numerator == 0) {
682			strncpy (v, _("Unknown"), maxlen);
683		}
684		else {
685			unsigned long tmp = vr.numerator / vr.denominator;
686			snprintf (v, maxlen, "%li mm", tmp);
687		}
688		break;
689	case MNOTE_OLYMPUS_TAG_WBALANCE:
690		CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
691		CC (entry->components, 2, v, maxlen);
692		vs = exif_get_short (entry->data, entry->order);
693		switch (vs) {
694		case 1:
695			strncpy (v, _("Automatic"), maxlen);
696			break;
697		case 2:
698			{
699				ExifShort v2 = exif_get_short (entry->data + 2, entry->order);
700				unsigned long colorTemp = 0;
701				switch (v2) {
702				case 2:
703					colorTemp = 3000;
704					break;
705				case 3:
706					colorTemp = 3700;
707					break;
708				case 4:
709					colorTemp = 4000;
710					break;
711				case 5:
712					colorTemp = 4500;
713					break;
714				case 6:
715					colorTemp = 5500;
716					break;
717				case 7:
718					colorTemp = 6500;
719					break;
720				case 9:
721					colorTemp = 7500;
722					break;
723				}
724				if (colorTemp) {
725					snprintf (v, maxlen, _("Manual: %liK"), colorTemp);
726				}
727				else {
728					strncpy (v, _("Manual: Unknown"), maxlen);
729				}
730
731			}
732			break;
733		case 3:
734			strncpy (v, _("One-touch"), maxlen);
735			break;
736		default:
737			strncpy (v, _("Unknown"), maxlen);
738			break;
739		}
740		break;
741	case MNOTE_OLYMPUS_TAG_REDBALANCE:
742	case MNOTE_OLYMPUS_TAG_BLUEBALANCE:
743		CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
744		CC (entry->components, 2, v, maxlen);
745		vs = exif_get_short (entry->data, entry->order);
746		snprintf (v, maxlen, "%hu ", vs);
747		vs = exif_get_short (entry->data + 2, entry->order);
748		sprintf (buf, "%hu", vs);
749		strncat (v, buf, maxlen - strlen (v));
750		break;
751	case MNOTE_OLYMPUS_TAG_BLACKLEVEL:
752	case MNOTE_NIKON_TAG_IMAGEBOUNDARY:
753		CC (entry->components, 4, v, maxlen);
754		/* Fall through to COLORMATRIX */
755	case MNOTE_OLYMPUS_TAG_COLORMATRIX:
756		CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
757		if (entry->tag == MNOTE_OLYMPUS_TAG_COLORMATRIX)
758			CC (entry->components, 9, v, maxlen);
759		for (i=0; i < (int)entry->components; ++i) {
760			vs = exif_get_short (entry->data+2*i, entry->order);
761			sprintf (buf, "%hu ", vs);
762			strncat (v, buf, maxlen - strlen (v));
763		}
764		break;
765	case MNOTE_NIKON1_TAG_FOCUS:
766	case MNOTE_NIKON_TAG_DIGITALZOOM:
767	case MNOTE_NIKON1_TAG_DIGITALZOOM:
768	case MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL:
769		CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
770		/* Fall through to default handler for display */
771	default:
772		switch (entry->format) {
773		case EXIF_FORMAT_ASCII:
774			strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
775			break;
776		case EXIF_FORMAT_SHORT:
777			CC (entry->components, 1, v, maxlen);
778			vs = exif_get_short (entry->data, entry->order);
779			snprintf (v, maxlen, "%hu", vs);
780			break;
781		case EXIF_FORMAT_LONG:
782			CC (entry->components, 1, v, maxlen);
783			vl = exif_get_long (entry->data, entry->order);
784			snprintf (v, maxlen, "%li", (long int) vl);
785			break;
786		case EXIF_FORMAT_RATIONAL:
787			CC (entry->components, 1, v, maxlen);
788			vr = exif_get_rational (entry->data, entry->order);
789			if (!vr.denominator) {
790				strncpy (v, _("Infinite"), maxlen);
791			} else {
792				r = (double)vr.numerator / vr.denominator;
793				snprintf (v, maxlen, "%2.3f", r);
794			}
795			break;
796		case EXIF_FORMAT_SRATIONAL:
797			CC (entry->components, 1, v, maxlen);
798			vsr = exif_get_srational (entry->data, entry->order);
799			if (!vsr.denominator) {
800				strncpy (v, _("Infinite"), maxlen);
801			} else {
802				r = (double)vsr.numerator / vsr.denominator;
803				snprintf (v, maxlen, "%2.3f", r);
804			}
805			break;
806		case EXIF_FORMAT_UNDEFINED:
807		default:
808			snprintf (v, maxlen, _("%i bytes unknown data: "),
809				  entry->size);
810			for (i = 0; i < (int)entry->size; i++) {
811				sprintf (buf, "%02x", entry->data[i]);
812				strncat (v, buf, maxlen - strlen (v));
813			}
814			break;
815		}
816		break;
817	}
818
819	return (v);
820}
821