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 
68 static 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_("Day white 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 */
268 static 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 
307 char *
mnote_pentax_entry_get_value(MnotePentaxEntry * entry,char * val,unsigned int maxlen)308 mnote_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