1/* mnote-pentax-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., 51 Franklin Street, Fifth Floor,
18 * Boston, MA  02110-1301  USA.
19 */
20
21#include <config.h>
22#include "mnote-pentax-entry.h"
23
24#include <libexif/i18n.h>
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include <libexif/exif-format.h>
31#include <libexif/exif-utils.h>
32#include <libexif/exif-entry.h>
33
34
35#define CF(format,target,v,maxlen)                              \
36{                                                               \
37	if (format != target) {                                 \
38		snprintf (v, maxlen,	                        \
39			_("Invalid format '%s', "               \
40			"expected '%s'."),                      \
41			exif_format_get_name (format),          \
42			exif_format_get_name (target));         \
43		break;                                          \
44	}                                                       \
45}
46
47#define CC(number,target,v,maxlen)                                      \
48{                                                                       \
49	if (number != target) {                                         \
50		snprintf (v, maxlen,                                    \
51			_("Invalid number of components (%i, "          \
52			"expected %i)."), (int) number, (int) target);  \
53		break;                                                  \
54	}                                                               \
55}
56
57#define CC2(number,t1,t2,v,maxlen)                                      \
58{                                                                       \
59	if ((number != t1) && (number != t2)) {                         \
60		snprintf (v, maxlen,                                    \
61			_("Invalid number of components (%i, "          \
62			"expected %i or %i)."), (int) number,		\
63			(int) t1, (int) t2);  				\
64		break;                                                  \
65	}                                                               \
66}
67
68static const struct {
69	ExifTag tag;
70	struct {
71		int index;
72		const char *string;
73	} elem[33];
74} items[] = {
75#ifndef NO_VERBOSE_TAG_DATA
76  { MNOTE_PENTAX_TAG_MODE,
77    { {0, N_("Auto")},
78      {1, N_("Night-scene")},
79      {2, N_("Manual")},
80      {4, N_("Multi-exposure")},
81      {0, NULL}}},
82  { MNOTE_PENTAX_TAG_QUALITY,
83    { {0, N_("Good")},
84      {1, N_("Better")},
85      {2, N_("Best")},{0,NULL}}},
86  { MNOTE_PENTAX_TAG_FOCUS,
87    { {2, N_("Custom")},
88      {3, N_("Auto")},
89      {0, NULL}}},
90  { MNOTE_PENTAX_TAG_FLASH,
91    { {1, N_("Auto")},
92      {2, N_("Flash on")},
93      {4, N_("Flash off")},
94      {6, N_("Red-eye Reduction")},
95      {0, NULL}}},
96  { MNOTE_PENTAX_TAG_WHITE_BALANCE,
97    { {0, N_("Auto")},
98      {1, N_("Daylight")},
99      {2, N_("Shade")},
100      {3, N_("Tungsten")},
101      {4, N_("Fluorescent")},
102      {5, N_("Manual")},
103      {0, NULL}}},
104  { MNOTE_PENTAX_TAG_SHARPNESS,
105    { {0, N_("Normal")},
106      {1, N_("Soft")},
107      {2, N_("Hard")},
108      {0, NULL}}},
109  { MNOTE_PENTAX_TAG_CONTRAST,
110    { {0, N_("Normal")},
111      {1, N_("Low")},
112      {2, N_("High")},
113      {0, NULL}}},
114  { MNOTE_PENTAX_TAG_SATURATION,
115    { {0, N_("Normal")},
116      {1, N_("Low")},
117      {2, N_("High")},
118      {0, NULL}}},
119  { MNOTE_PENTAX_TAG_ISO_SPEED,
120    { {10,  N_("100")},
121      {16,  N_("200")},
122      {100, N_("100")},
123      {200, N_("200")},
124      { 0,  NULL}}},
125  { MNOTE_PENTAX_TAG_COLOR,
126    { {1, N_("Full")},
127      {2, N_("Black & White")},
128      {3, N_("Sepia")},
129      {0, NULL}}},
130  { MNOTE_PENTAX2_TAG_MODE,
131    { {0, N_("Auto")},
132      {1, N_("Night-scene")},
133      {2, N_("Manual")},
134      {4, N_("Multi-exposure")},
135      {0, NULL}}},
136  { MNOTE_PENTAX2_TAG_QUALITY,
137    { {0, N_("Good")},
138      {1, N_("Better")},
139      {2, N_("Best")},
140      {3, N_("TIFF")},
141      {4, N_("RAW")},
142      {0, NULL}}},
143  { MNOTE_PENTAX2_TAG_IMAGE_SIZE,
144    { {0, "640x480"},
145      {1, N_("Full")},
146      {2, "1024x768"},
147      {3, "1280x960"},
148      {4, "1600x1200"},
149      {5, "2048x1536"},
150      {8, N_("2560x1920 or 2304x1728")},
151      {9, "3072x2304"},
152      {10, "3264x2448"},
153      {19, "320x240"},
154      {20, "2288x1712"},
155      {21, "2592x1944"},
156      {22, N_("2304x1728 or 2592x1944")},
157      {23, "3056x2296"},
158      {25, N_("2816x2212 or 2816x2112")},
159      {27, "3648x2736"},
160      {36, "3008x2008"},
161      {0, NULL}}},
162  { MNOTE_PENTAX2_TAG_PICTURE_MODE,
163    { {0, N_("Program")},
164      {2, N_("Program AE")},
165      {3, N_("Manual")},
166      {5, N_("Portrait")},
167      {6, N_("Landscape")},
168      {8, N_("Sport")},
169      {9, N_("Night Scene")},
170      {11, N_("Soft")},
171      {12, N_("Surf & Snow")},
172      {13, N_("Sunset or Candlelight")},
173      {14, N_("Autumn")},
174      {15, N_("Macro")},
175      {17, N_("Fireworks")},
176      {18, N_("Text")},
177      {19, N_("Panorama")},
178      {30, N_("Self Portrait")},
179      {31, N_("Illustrations")},
180      {33, N_("Digital Filter")},
181      {37, N_("Museum")},
182      {38, N_("Food")},
183      {40, N_("Green Mode")},
184      {49, N_("Light Pet")},
185      {50, N_("Dark Pet")},
186      {51, N_("Medium Pet")},
187      {53, N_("Underwater")},
188      {54, N_("Candlelight")},
189      {55, N_("Natural Skin Tone")},
190      {56, N_("Synchro Sound Record")},
191      {58, N_("Frame Composite")},
192      {0, NULL}}},
193  { MNOTE_PENTAX2_TAG_FLASH_MODE,
194    { {0x0000, N_("Auto, Did not fire")},
195      {0x0001, N_("Off")},
196      {0x0003, N_("Auto, Did not fire, Red-eye reduction")},
197      {0x0100, N_("Auto, Fired")},
198      {0x0102, N_("On")},
199      {0x0103, N_("Auto, Fired, Red-eye reduction")},
200      {0x0104, N_("On, Red-eye reduction")},
201      {0x0105, N_("On, Wireless")},
202      {0x0108, N_("On, Soft")},
203      {0x0109, N_("On, Slow-sync")},
204      {0x010a, N_("On, Slow-sync, Red-eye reduction")},
205      {0x010b, N_("On, Trailing-curtain Sync")},
206      {0, NULL}}},
207  { MNOTE_PENTAX2_TAG_FOCUS_MODE,
208    { {0, N_("Normal")},
209      {1, N_("Macro")},
210      {2, N_("Infinity")},
211      {3, N_("Manual")},
212      {5, N_("Pan Focus")},
213      {16, N_("AF-S")},
214      {17, N_("AF-C")},
215      {0, NULL}}},
216  { MNOTE_PENTAX2_TAG_AFPOINT_SELECTED,
217    { {1, N_("Upper-left")},
218      {2, N_("Top")},
219      {3, N_("Upper-right")},
220      {4, N_("Left")},
221      {5, N_("Mid-left")},
222      {6, N_("Center")},
223      {7, N_("Mid-right")},
224      {8, N_("Right")},
225      {9, N_("Lower-left")},
226      {10, N_("Bottom")},
227      {11, N_("Lower-right")},
228      {0xfffe, N_("Fixed Center")},
229      {0xffff, N_("Auto")},
230      {0, NULL}}},
231  { MNOTE_PENTAX2_TAG_AUTO_AFPOINT,
232    { {0, N_("Multiple")},
233      {1, N_("Top-left")},
234      {2, N_("Top-center")},
235      {3, N_("Top-right")},
236      {4, N_("Left")},
237      {5, N_("Center")},
238      {6, N_("Right")},
239      {7, N_("Bottom-left")},
240      {8, N_("Bottom-center")},
241      {9, N_("Bottom-right")},
242      {0xffff, N_("None")},
243      {0, NULL}}},
244  { MNOTE_PENTAX2_TAG_WHITE_BALANCE,
245    { {0, N_("Auto")},
246      {1, N_("Daylight")},
247      {2, N_("Shade")},
248      {3, N_("Fluorescent")},
249      {4, N_("Tungsten")},
250      {5, N_("Manual")},
251      {6, N_("Daylight Fluorescent")},
252      {7, N_("Daywhite Fluorescent")},
253      {8, N_("White Fluorescent")},
254      {9, N_("Flash")},
255      {10, N_("Cloudy")},
256      {0xfffe, N_("Unknown")},
257      {0xffff, N_("User Selected")},
258      {0, NULL}}},
259  {MNOTE_CASIO2_TAG_BESTSHOT_MODE,
260    { {0, N_("Off")},
261      {1, N_("On")},
262      {0, NULL}}},
263#endif
264  {0, {{0, NULL}}}
265};
266
267/* Two-component values */
268static const struct {
269	ExifTag tag;
270	struct {
271		int index1, index2;
272		const char *string;
273	} elem[39];
274} items2[] = {
275#ifndef NO_VERBOSE_TAG_DATA
276  { MNOTE_PENTAX2_TAG_IMAGE_SIZE,
277    { {0, 0, "2304x1728"},
278      {4, 0, "1600x1200"},
279      {5, 0, "2048x1536"},
280      {8, 0, "2560x1920"},
281      {34, 0, "1536x1024"},
282      {36, 0, N_("3008x2008 or 3040x2024")},
283      {37, 0, "3008x2000"},
284      {35, 1, "2400x1600"},
285      {32, 2, "960x480"},
286      {33, 2, "1152x768"},
287      {34, 2, "1536x1024"},
288      {0,  0, NULL}}},
289  { MNOTE_PENTAX2_TAG_PICTURE_MODE,
290    { {0,   0, N_("Auto")},
291      {5,   0, N_("Portrait")},
292      {53,  0, N_("Underwater")},
293      {255, 0, N_("Digital Filter?")},
294      {5,   1, N_("Portrait")},
295      {9,   1, N_("Night Scene")},
296      {13,  1, N_("Candlelight")},
297      {15,  1, N_("Macro")},
298      {53,  1, N_("Underwater")},
299      {0,   2, N_("Program AE")},
300      {5,   2, N_("Portrait")},
301      {6,   2, N_("Landscape")},
302      {0,   0, NULL}}},
303#endif
304  {0, {{0, 0, NULL}}}
305};
306
307char *
308mnote_pentax_entry_get_value (MnotePentaxEntry *entry,
309			      char *val, unsigned int maxlen)
310{
311	ExifLong vl;
312	ExifShort vs, vs2;
313	int i = 0, j = 0;
314
315	if (!entry) return (NULL);
316
317	memset (val, 0, maxlen);
318	maxlen--;
319
320	switch (entry->tag) {
321	  case MNOTE_PENTAX_TAG_MODE:
322	  case MNOTE_PENTAX_TAG_QUALITY:
323	  case MNOTE_PENTAX_TAG_FOCUS:
324	  case MNOTE_PENTAX_TAG_FLASH:
325	  case MNOTE_PENTAX_TAG_WHITE_BALANCE:
326	  case MNOTE_PENTAX_TAG_SHARPNESS:
327	  case MNOTE_PENTAX_TAG_CONTRAST:
328	  case MNOTE_PENTAX_TAG_SATURATION:
329	  case MNOTE_PENTAX_TAG_ISO_SPEED:
330	  case MNOTE_PENTAX_TAG_COLOR:
331	  case MNOTE_PENTAX2_TAG_MODE:
332	  case MNOTE_PENTAX2_TAG_QUALITY:
333	  case MNOTE_PENTAX2_TAG_FLASH_MODE:
334	  case MNOTE_PENTAX2_TAG_FOCUS_MODE:
335	  case MNOTE_PENTAX2_TAG_AFPOINT_SELECTED:
336	  case MNOTE_PENTAX2_TAG_AUTO_AFPOINT:
337	  case MNOTE_PENTAX2_TAG_WHITE_BALANCE:
338	  case MNOTE_PENTAX2_TAG_PICTURE_MODE:
339	  case MNOTE_PENTAX2_TAG_IMAGE_SIZE:
340	  case MNOTE_CASIO2_TAG_BESTSHOT_MODE:
341		CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
342		CC2 (entry->components, 1, 2, val, maxlen);
343		if (entry->components == 1) {
344			vs = exif_get_short (entry->data, entry->order);
345
346			/* search the tag */
347			for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++);
348			if (!items[i].tag) {
349				snprintf (val, maxlen,
350					  _("Internal error (unknown value %i)"), vs);
351			  	break;
352			}
353
354			/* find the value */
355			for (j = 0; items[i].elem[j].string &&
356			    (items[i].elem[j].index < vs); j++);
357			if (items[i].elem[j].index != vs) {
358				snprintf (val, maxlen,
359					  _("Internal error (unknown value %i)"), vs);
360				break;
361			}
362			strncpy (val, _(items[i].elem[j].string), maxlen);
363		} else {
364			/* Two-component values */
365			CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
366			CC2 (entry->components, 1, 2, val, maxlen);
367			vs = exif_get_short (entry->data, entry->order);
368			vs2 = exif_get_short (entry->data+2, entry->order) << 16;
369
370			/* search the tag */
371			for (i = 0; (items2[i].tag && items2[i].tag != entry->tag); i++);
372			if (!items2[i].tag) {
373				snprintf (val, maxlen,
374					  _("Internal error (unknown value %i %i)"), vs, vs2);
375			  	break;
376			}
377
378			/* find the value */
379			for (j = 0; items2[i].elem[j].string && ((items2[i].elem[j].index2 < vs2)
380				|| ((items2[i].elem[j].index2 == vs2) && (items2[i].elem[j].index1 < vs))); j++);
381			if ((items2[i].elem[j].index1 != vs) || (items2[i].elem[j].index2 != vs2)) {
382				snprintf (val, maxlen,
383					  _("Internal error (unknown value %i %i)"), vs, vs2);
384				break;
385			}
386			strncpy (val, _(items2[i].elem[j].string), maxlen);
387		}
388		break;
389
390	case MNOTE_PENTAX_TAG_ZOOM:
391		CF (entry->format, EXIF_FORMAT_LONG, val, maxlen);
392		CC (entry->components, 1, val, maxlen);
393		vl = exif_get_long (entry->data, entry->order);
394		snprintf (val, maxlen, "%li", (long int) vl);
395		break;
396	case MNOTE_PENTAX_TAG_PRINTIM:
397		CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
398		CC (entry->components, 124, val, maxlen);
399		snprintf (val, maxlen, _("%i bytes unknown data"),
400			entry->size);
401		break;
402	case MNOTE_PENTAX_TAG_TZ_CITY:
403	case MNOTE_PENTAX_TAG_TZ_DST:
404		CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
405		CC (entry->components, 4, val, maxlen);
406		strncpy (val, (char*)entry->data, MIN(maxlen, entry->size));
407		break;
408	case MNOTE_PENTAX2_TAG_DATE:
409		CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
410		CC (entry->components, 4, val, maxlen);
411		/* Note: format is UNDEFINED, not SHORT -> order is fixed: MOTOROLA */
412		vs = exif_get_short (entry->data, EXIF_BYTE_ORDER_MOTOROLA);
413		snprintf (val, maxlen, "%i:%02i:%02i", vs, entry->data[2], entry->data[3]);
414		break;
415	case MNOTE_PENTAX2_TAG_TIME:
416		CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
417		CC2 (entry->components, 3, 4, val, maxlen);
418		snprintf (val, maxlen, "%02i:%02i:%02i", entry->data[0], entry->data[1], entry->data[2]);
419		break;
420	default:
421		switch (entry->format) {
422		case EXIF_FORMAT_ASCII:
423		  strncpy (val, (char *)entry->data, MIN(maxlen, entry->size));
424		  break;
425		case EXIF_FORMAT_SHORT:
426		  {
427			const unsigned char *data = entry->data;
428		  	size_t k, len = strlen(val);
429		  	for(k=0; k<entry->components; k++) {
430				vs = exif_get_short (data, entry->order);
431				snprintf (val+len, maxlen-len, "%i ", vs);
432				len = strlen(val);
433				data += 2;
434			}
435		  }
436		  break;
437		case EXIF_FORMAT_LONG:
438		  {
439			const unsigned char *data = entry->data;
440		  	size_t k, len = strlen(val);
441		  	for(k=0; k<entry->components; k++) {
442				vl = exif_get_long (data, entry->order);
443				snprintf (val+len, maxlen-len, "%li", (long int) vl);
444				len = strlen(val);
445				data += 4;
446			}
447		  }
448		  break;
449		case EXIF_FORMAT_UNDEFINED:
450		default:
451		  snprintf (val, maxlen, _("%i bytes unknown data"),
452			  entry->size);
453		  break;
454		}
455		break;
456	}
457
458	return (val);
459}
460