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