• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	MnotePentaxTag 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 	MnotePentaxTag 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 	ExifSLong vsl;
313 	ExifShort vs, vs2;
314 	ExifSShort vss;
315 	int i = 0, j = 0;
316 
317 	if (!entry) return (NULL);
318 
319 	memset (val, 0, maxlen);
320 	maxlen--;
321 
322 	switch (entry->tag) {
323 	  case MNOTE_PENTAX_TAG_MODE:
324 	  case MNOTE_PENTAX_TAG_QUALITY:
325 	  case MNOTE_PENTAX_TAG_FOCUS:
326 	  case MNOTE_PENTAX_TAG_FLASH:
327 	  case MNOTE_PENTAX_TAG_WHITE_BALANCE:
328 	  case MNOTE_PENTAX_TAG_SHARPNESS:
329 	  case MNOTE_PENTAX_TAG_CONTRAST:
330 	  case MNOTE_PENTAX_TAG_SATURATION:
331 	  case MNOTE_PENTAX_TAG_ISO_SPEED:
332 	  case MNOTE_PENTAX_TAG_COLOR:
333 	  case MNOTE_PENTAX2_TAG_MODE:
334 	  case MNOTE_PENTAX2_TAG_QUALITY:
335 	  case MNOTE_PENTAX2_TAG_FLASH_MODE:
336 	  case MNOTE_PENTAX2_TAG_FOCUS_MODE:
337 	  case MNOTE_PENTAX2_TAG_AFPOINT_SELECTED:
338 	  case MNOTE_PENTAX2_TAG_AUTO_AFPOINT:
339 	  case MNOTE_PENTAX2_TAG_WHITE_BALANCE:
340 	  case MNOTE_PENTAX2_TAG_PICTURE_MODE:
341 	  case MNOTE_PENTAX2_TAG_IMAGE_SIZE:
342 	  case MNOTE_CASIO2_TAG_BESTSHOT_MODE:
343 		CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
344 		CC2 (entry->components, 1, 2, val, maxlen);
345 		if (entry->components == 1) {
346 			vs = exif_get_short (entry->data, entry->order);
347 
348 			/* search the tag */
349 			for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++);
350 			if (!items[i].tag) {
351 				snprintf (val, maxlen,
352 					  _("Internal error (unknown value %hu)"), vs);
353 			  	break;
354 			}
355 
356 			/* find the value */
357 			for (j = 0; items[i].elem[j].string &&
358 			    (items[i].elem[j].index < vs); j++);
359 			if (items[i].elem[j].index != vs) {
360 				snprintf (val, maxlen,
361 					  _("Internal error (unknown value %hu)"), vs);
362 				break;
363 			}
364 			strncpy (val, _(items[i].elem[j].string), maxlen);
365 		} else {
366 			/* Two-component values */
367 			CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
368 			CC2 (entry->components, 1, 2, val, maxlen);
369 			vs = exif_get_short (entry->data, entry->order);
370 			vs2 = ((unsigned int)exif_get_short (entry->data+2, entry->order)) << 16;
371 
372 			/* search the tag */
373 			for (i = 0; (items2[i].tag && items2[i].tag != entry->tag); i++);
374 			if (!items2[i].tag) {
375 				snprintf (val, maxlen,
376 					  _("Internal error (unknown value %hu %hu)"), vs, vs2);
377 			  	break;
378 			}
379 
380 			/* find the value */
381 			for (j = 0; items2[i].elem[j].string && ((items2[i].elem[j].index2 < vs2)
382 				|| ((items2[i].elem[j].index2 == vs2) && (items2[i].elem[j].index1 < vs))); j++);
383 			if ((items2[i].elem[j].index1 != vs) || (items2[i].elem[j].index2 != vs2)) {
384 				snprintf (val, maxlen,
385 					  _("Internal error (unknown value %hi %hi)"), vs, vs2);
386 				break;
387 			}
388 			strncpy (val, _(items2[i].elem[j].string), maxlen);
389 		}
390 		break;
391 
392 	case MNOTE_PENTAX_TAG_ZOOM:
393 		CF (entry->format, EXIF_FORMAT_LONG, val, maxlen);
394 		CC (entry->components, 1, val, maxlen);
395 		vl = exif_get_long (entry->data, entry->order);
396 		snprintf (val, maxlen, "%lu", (long unsigned) vl);
397 		break;
398 	case MNOTE_PENTAX_TAG_PRINTIM:
399 		CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
400 		CC (entry->components, 124, val, maxlen);
401 		snprintf (val, maxlen, _("%i bytes unknown data"),
402 			entry->size);
403 		break;
404 	case MNOTE_PENTAX_TAG_TZ_CITY:
405 	case MNOTE_PENTAX_TAG_TZ_DST:
406 		CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
407 		CC (entry->components, 4, val, maxlen);
408 		strncpy (val, (char*)entry->data, MIN(maxlen, entry->size));
409 		break;
410 	case MNOTE_PENTAX2_TAG_DATE:
411 		CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
412 		CC (entry->components, 4, val, maxlen);
413 		/* Note: format is UNDEFINED, not SHORT -> order is fixed: MOTOROLA */
414 		vs = exif_get_short (entry->data, EXIF_BYTE_ORDER_MOTOROLA);
415 		snprintf (val, maxlen, "%hi:%02i:%02i", vs, entry->data[2], entry->data[3]);
416 		break;
417 	case MNOTE_PENTAX2_TAG_TIME:
418 		CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
419 		CC2 (entry->components, 3, 4, val, maxlen);
420 		snprintf (val, maxlen, "%02i:%02i:%02i", entry->data[0], entry->data[1], entry->data[2]);
421 		break;
422 	default:
423 		switch (entry->format) {
424 		case EXIF_FORMAT_ASCII:
425 		  strncpy (val, (char *)entry->data, MIN(maxlen, entry->size));
426 		  break;
427 		case EXIF_FORMAT_SHORT:
428 		  {
429 			const unsigned char *data = entry->data;
430 			size_t k, len = strlen(val), sizeleft;
431 
432 			sizeleft = entry->size;
433 			for(k=0; k<entry->components; k++) {
434 				if (sizeleft < 2)
435 					break;
436 				vs = exif_get_short (data, entry->order);
437 				snprintf (val+len, maxlen-len, "%hu ", vs);
438 				len = strlen(val);
439 				data += 2;
440 				sizeleft -= 2;
441 			}
442 		  }
443 		  break;
444 		case EXIF_FORMAT_SSHORT:
445 		  {
446 			const unsigned char *data = entry->data;
447 			size_t k, len = strlen(val), sizeleft;
448 
449 			sizeleft = entry->size;
450 			for(k=0; k<entry->components; k++) {
451 				if (sizeleft < 2)
452 					break;
453 				vss = exif_get_sshort (data, entry->order);
454 				snprintf (val+len, maxlen-len, "%hi ", vss);
455 				len = strlen(val);
456 				data += 2;
457 				sizeleft -= 2;
458 			}
459 		  }
460 		  break;
461 		case EXIF_FORMAT_LONG:
462 		  {
463 			const unsigned char *data = entry->data;
464 			size_t k, len = strlen(val), sizeleft;
465 
466 			sizeleft = entry->size;
467 			for(k=0; k<entry->components; k++) {
468 				if (sizeleft < 4)
469 					break;
470 				vl = exif_get_long (data, entry->order);
471 				snprintf (val+len, maxlen-len, "%lu ", (long unsigned) vl);
472 				len = strlen(val);
473 				data += 4;
474 				sizeleft -= 4;
475 			}
476 		  }
477 		  break;
478 		case EXIF_FORMAT_SLONG:
479 		  {
480 			const unsigned char *data = entry->data;
481 			size_t k, len = strlen(val), sizeleft;
482 
483 			sizeleft = entry->size;
484 			for(k=0; k<entry->components; k++) {
485 				if (sizeleft < 4)
486 					break;
487 				vsl = exif_get_slong (data, entry->order);
488 				snprintf (val+len, maxlen-len, "%li ", (long int) vsl);
489 				len = strlen(val);
490 				data += 4;
491 				sizeleft -= 4;
492 			}
493 		  }
494 		  break;
495 		case EXIF_FORMAT_UNDEFINED:
496 		default:
497 		  snprintf (val, maxlen, _("%i bytes unknown data"),
498 			  entry->size);
499 		  break;
500 		}
501 		break;
502 	}
503 
504 	return val;
505 }
506