4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Sangchul Lee <sc11.lee@samsung.com>
8 * This library is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU Lesser General Public License as published by the
10 * Free Software Foundation; either version 2.1 of the License, or (at your option)
13 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 * License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, write to the Free Software Foundation, Inc., 51
20 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "mnote-samsung-entry.h"
31 #include <libexif/exif-format.h>
32 #include <libexif/exif-utils.h>
33 #include <libexif/exif-entry.h>
34 #include <libexif/i18n.h>
36 #define CF(format,target,v,maxlen) \
38 if (format != target) { \
39 snprintf (v, maxlen, \
40 _("Invalid format '%s', " \
42 exif_format_get_name (format), \
43 exif_format_get_name (target)); \
48 #define CF2(format,target1,target2,v,maxlen) \
50 if ((format != target1) && (format != target2)) { \
51 snprintf (v, maxlen, \
52 _("Invalid format '%s', " \
53 "expected '%s' or '%s'."), \
54 exif_format_get_name (format), \
55 exif_format_get_name (target1), \
56 exif_format_get_name (target2)); \
61 #define CC(number,target,v,maxlen) \
63 if (number != target) { \
64 snprintf (v, maxlen, \
65 _("Invalid number of components (%i, " \
66 "expected %i)."), (int) number, (int) target); \
71 #define CC2(number,t1,t2,v,maxlen) \
73 if ((number < t1) || (number > t2)) { \
74 snprintf (v, maxlen, \
75 _("Invalid number of components (%i, " \
76 "expected %i or %i)."), (int) number, \
77 (int) t1, (int) t2); \
90 #ifndef NO_VERBOSE_TAG_DATA
91 { MNOTE_SAMSUNG_TAG_MNOTE_VERSION, EXIF_FORMAT_UNDEFINED,
92 { {0x30313030, N_("MakerNote Version")},
94 { MNOTE_SAMSUNG_TAG_DEVICE_ID, EXIF_FORMAT_LONG,
95 { {0x00001000, N_("Compact")},
96 {0x00002000, N_("DSLR")},
97 {0x00003000, N_("Camcorder")},
99 { MNOTE_SAMSUNG_TAG_SERIAL_NUM, EXIF_FORMAT_ASCII,
101 { MNOTE_SAMSUNG_TAG_FAVOR_TAGGING, EXIF_FORMAT_LONG,
102 { {0x00000000, N_("Bad")},
103 {0x00000001, N_("Good")},
105 { MNOTE_SAMSUNG_TAG_SRW_COMPRESS, EXIF_FORMAT_LONG,
106 { {0x00000000, N_("Uncompressed Mode")},
107 {0x00000001, N_("Lossless Compression Mode (Type 1)")},
108 {0x00000002, N_("Lossless Compression Mode (Type 2)")},
110 { MNOTE_SAMSUNG_TAG_COLOR_SPACE, EXIF_FORMAT_LONG,
111 { {0x00000001, N_("sRGB (Standard RGB)")},
112 {0x0000FFFF, N_("Adobe RGB (Adobe RGB)")},
114 { MNOTE_SAMSUNG_TAG_SCENE_RESULT, EXIF_FORMAT_LONG,
115 { {0x00000000, N_("Smart")},
116 {0x00000001, N_("Portrait")},
117 {0x00000002, N_("Night")},
118 {0x00000003, N_("Night Portrait")},
119 {0x00000004, N_("Backlight")},
120 {0x00000005, N_("Backlight Portrait")},
121 {0x00000006, N_("Macro")},
122 {0x00000007, N_("White")},
123 {0x00000008, N_("Landscape")},
124 {0x00000009, N_("Macro Text")},
125 {0x0000000A, N_("BLSunset")},
126 {0x0000000B, N_("Bluesky")},
127 {0x0000000C, N_("Macro Portrait")},
128 {0x0000000D, N_("Natural Green")},
129 {0x0000000E, N_("Color")},
130 {0x0000000F, N_("Color Hidden")},
131 {0x00000010, N_("Tripod")},
132 {0x00000011, N_("Action")},
134 { MNOTE_SAMSUNG_TAG_FACE_DETECTION, EXIF_FORMAT_LONG,
135 { {0x00000000, N_("FALSE")},
136 {0x00000001, N_("TRUE")},
138 { MNOTE_SAMSUNG_TAG_FACE_RECOG, EXIF_FORMAT_LONG,
139 { {0x00000000, N_("FALSE")},
140 {0x00000001, N_("TRUE")},
144 { 0, 0, { { 0, NULL } } }
147 static const struct {
155 #ifndef NO_VERBOSE_TAG_DATA
156 { MNOTE_SAMSUNG_SUBTAG_MODEL_ID_CLASS, EXIF_FORMAT_UNDEFINED,
157 { {0x1, N_("Essential")},
158 {0x2, N_("PlusOnel")},
159 {0x3, N_("Intelligent")},
161 {0x5, N_("Wannabe")},
162 {0x6, N_("Expertise")},
168 { MNOTE_SAMSUNG_SUBTAG_MODEL_ID_DEVEL, EXIF_FORMAT_UNDEFINED,
173 { MNOTE_SAMSUNG_SUBTAG_COLOR_ID, EXIF_FORMAT_SHORT,
174 { {0x0000, N_("Red")},
175 {0x0100, N_("Yellow")},
176 {0x0200, N_("Green")},
177 {0x0300, N_("Blue")},
178 {0x0400, N_("Magenta")},
179 {0x0500, N_("Black")},
180 {0x0600, N_("Gray")},
181 {0x0700, N_("Un-classification")},
184 { 0, 0, { { 0, NULL } } }
188 /*for setting data in an entry*/
189 void mnote_samsung_entry_set_value_by_index (MnoteSamsungEntry *entry, int index)
195 for (i = 0; (items[i].tag != entry->tag); i++);
196 exif_set_long(v, entry->order,(ExifLong)items[i].elem[index].index);
199 void mnote_samsung_entry_set_value_by_subtag (MnoteSamsungEntry *entry, MnoteSamsungSubTag stag1, int sindex1, MnoteSamsungSubTag stag2, int sindex2, ExifShort sval)
207 case MNOTE_SAMSUNG_TAG_MODEL_ID:
209 for(i = 0 ; (subitems[i].tag != stag1) ; i++);
210 result |= subitems[i].elem[sindex1].index;
212 for(i = 0 ; (subitems[i].tag != stag2) ; i++);
213 result |= subitems[i].elem[sindex2].index;
216 exif_set_long(v, entry->order, result);
219 case MNOTE_SAMSUNG_TAG_COLOR_INFO:
221 for(i = 0 ; (subitems[i].tag != stag1) ; i++);
222 result |= subitems[i].elem[sindex1].index;
225 exif_set_long(v, entry->order, result);
229 fprintf (stdout,_("inappropriate using mnote_samsung_entry_set_value_by_subtag - %i bytes"), entry->size);
236 void mnote_samsung_entry_set_value_by_string (MnoteSamsungEntry *entry, unsigned char* string, unsigned int len)
238 /* for MNOTE_TAG_SERIAL_NUM */
243 for (i = 0; (items[i].tag != entry->tag); i++);
244 if(items[i].elem[0].string == NULL)
245 strncpy(v, string, len);
248 char *mnote_samsung_entry_get_value (const MnoteSamsungEntry *entry, char *v, unsigned int maxlen)
252 size_t v1_maxlen= sizeof(v1);
254 ExifShort vs = 0,vs1 = 0;
264 memset (v, 0, maxlen);
267 if ((!entry->data) && (entry->components > 0))
270 switch (entry->tag) {
272 case MNOTE_SAMSUNG_TAG_MNOTE_VERSION:
273 CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
274 CC (entry->components, 4, v, maxlen);
275 vl = exif_get_long (entry->data, entry->order);
276 snprintf (v, maxlen, _("Samsung MakerNote Version: %li"), (long int)vl);
279 case MNOTE_SAMSUNG_TAG_DEVICE_ID:
280 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
281 CC (entry->components, 1, v, maxlen);
282 vl = exif_get_long (entry->data, entry->order);
284 for (i = 0; (items[i].tag != entry->tag); i++);
286 snprintf (v, maxlen, _("Internal error (unknown value %li)"),(long int) vl);
289 CF (entry->format, items[i].fmt, v, maxlen);
291 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
292 if (items[i].elem[j].index != vl) {
293 snprintf (v, maxlen, _("Unknown value %li"), (long int)vl);
297 snprintf (v, maxlen, _("Device ID: %s"), _(items[i].elem[j].string));
300 case MNOTE_SAMSUNG_TAG_MODEL_ID:
301 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
302 CC (entry->components, 1, v, maxlen);
303 vl = exif_get_long (entry->data, entry->order);
304 c = vl >> 24; /* Class info */
305 c1 = vl >> 20; /* Development info */
307 vs = (ExifShort)(0x0000FFFF & vl); /* PID */
309 for (i = 0; (subitems[i].tag != MNOTE_SAMSUNG_SUBTAG_MODEL_ID_CLASS); i++);
310 CF (EXIF_FORMAT_UNDEFINED, subitems[i].fmt, v, maxlen);
312 for (j = 0; subitems[i].elem[j].string && (subitems[i].elem[j].index < c); j++);
313 if (subitems[i].elem[j].index != c ) {
314 snprintf (v, maxlen, _("Unknown Class info value %d in MNOTE_SAMSUNG_TAG_MODEL_ID"), c);
317 snprintf (v, maxlen, _("Model ID: ClassInfo=%s, "), _(subitems[i].elem[j].string));
319 for (i = 0; (subitems[i].tag != MNOTE_SAMSUNG_SUBTAG_MODEL_ID_DEVEL); i++);
320 CF (EXIF_FORMAT_UNDEFINED, subitems[i].fmt, v, maxlen);
322 for (j = 0; subitems[i].elem[j].string && (subitems[i].elem[j].index < c1); j++);
323 if (subitems[i].elem[j].index != c1 ) {
324 snprintf (v, maxlen, _("Unknown Development info. value %d in MNOTE_SAMSUNG_TAG_MODEL_ID"), c1);
327 snprintf (v1, v1_maxlen, _("DevelopmentInfo=%s, PID=%d"), _(subitems[i].elem[j].string), vs);
328 strncat (v, v1, strlen(v1));
332 case MNOTE_SAMSUNG_TAG_COLOR_INFO:
333 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
334 CC (entry->components, 2, v, maxlen);
335 vl = exif_get_long (entry->data, entry->order);
336 vs = vl >> 16; /* Color ID */
337 vs1 = (ExifShort)(0x0000FFFF & vl); /* Color Score */
339 for (i = 0; (subitems[i].tag != MNOTE_SAMSUNG_SUBTAG_COLOR_ID); i++);
340 CF (EXIF_FORMAT_SHORT, subitems[i].fmt, v, maxlen);
342 for (j = 0; subitems[i].elem[j].string && (subitems[i].elem[j].index < vs); j++);
343 if (subitems[i].elem[j].index != vs ) {
344 snprintf (v, maxlen, _("Unknown Color ID value %d in MNOTE_SAMSUNG_TAG_COLOR_INFO"), vs);
347 snprintf (v, maxlen, _("Color Info: ColorID=%s, ColorScore=0x%x"), _(subitems[i].elem[j].string), vs1);
350 case MNOTE_SAMSUNG_TAG_SERIAL_NUM:
351 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
352 strncpy (v1, (char *)entry->data, MIN(v1_maxlen, entry->size));
353 snprintf(v, maxlen, _("Serial Number: %s"), _(v1));
356 case MNOTE_SAMSUNG_TAG_IMAGE_COUNT:
357 case MNOTE_SAMSUNG_TAG_GPS_INFO01:
358 case MNOTE_SAMSUNG_TAG_GPS_INFO02:
359 case MNOTE_SAMSUNG_TAG_PREVIEW_IMAGE:
360 case MNOTE_SAMSUNG_TAG_FAVOR_TAGGING:
361 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
362 CC (entry->components, 1, v, maxlen);
363 vl = exif_get_long (entry->data, entry->order);
365 for (i = 0; (items[i].tag != entry->tag); i++);
368 snprintf (v, maxlen, _("Internal error (unknown value %li)"), (long int)vl);
371 CF (entry->format, items[i].fmt, v, maxlen);
373 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
374 if (items[i].elem[j].index != vl) {
375 snprintf (v, maxlen, _("Unknown value %li"),(long int) vl);
378 snprintf(v, maxlen, _("Favorite Tagging: %s"), _(items[i].elem[j].string));
381 case MNOTE_SAMSUNG_TAG_SRW_COMPRESS:
382 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
383 CC (entry->components, 1, v, maxlen);
384 vl = exif_get_long (entry->data, entry->order);
386 for (i = 0; (items[i].tag != entry->tag); i++);
389 snprintf (v, maxlen, _("Internal error (unknown value %li)"), (long int)vl);
392 CF (entry->format, items[i].fmt, v, maxlen);
394 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
395 if (items[i].elem[j].index != vl) {
396 snprintf (v, maxlen, _("Unknown value %li"),(long int) vl);
399 snprintf(v, maxlen, _("SRW Compression: %s"), _(items[i].elem[j].string));
402 case MNOTE_SAMSUNG_TAG_COLOR_SPACE:
403 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
404 CC (entry->components, 1, v, maxlen);
405 vl = exif_get_long (entry->data, entry->order);
407 for (i = 0; (items[i].tag != entry->tag); i++);
410 snprintf (v, maxlen, _("Internal error (unknown value %li)"),(long int) vl);
413 CF (entry->format, items[i].fmt, v, maxlen);
415 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
416 if (items[i].elem[j].index != vl) {
417 snprintf (v, maxlen, _("Unknown value %li"),(long int) vl);
420 snprintf(v, maxlen, _("Color Space: %s"), _(items[i].elem[j].string));
423 case MNOTE_SAMSUNG_TAG_AE:
424 case MNOTE_SAMSUNG_TAG_AF:
425 case MNOTE_SAMSUNG_TAG_AWB01:
426 case MNOTE_SAMSUNG_TAG_AWB02:
427 case MNOTE_SAMSUNG_TAG_IPC:
428 case MNOTE_SAMSUNG_TAG_SCENE_RESULT:
429 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
430 CC (entry->components, 1, v, maxlen);
431 vl = exif_get_long (entry->data, entry->order);
433 for (i = 0; (items[i].tag != entry->tag); i++);
436 snprintf (v, maxlen, _("Internal error (unknown value %li)"), (long int) vl);
439 CF (entry->format, items[i].fmt, v, maxlen);
441 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
442 if (items[i].elem[j].index != vl) {
443 snprintf (v, maxlen, _("Unknown value %li"), (long int) vl);
446 snprintf(v, maxlen, _("Scene Result: %s"), _(items[i].elem[j].string));
449 case MNOTE_SAMSUNG_TAG_SADEBUG_INFO01:
450 case MNOTE_SAMSUNG_TAG_SADEBUG_INFO02:
451 case MNOTE_SAMSUNG_TAG_FACE_DETECTION:
452 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
453 CC (entry->components, 1, v, maxlen);
454 vl = exif_get_long (entry->data, entry->order);
456 for (i = 0; (items[i].tag != entry->tag); i++);
459 snprintf (v, maxlen, _("Internal error (unknown value %li)"), (long int) vl);
462 CF (entry->format, items[i].fmt, v, maxlen);
464 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
465 if (items[i].elem[j].index != vl) {
466 snprintf (v, maxlen, _("Unknown value %li"), (long int) vl);
469 snprintf(v, maxlen, _("Face Detection: %s"), _(items[i].elem[j].string));
472 case MNOTE_SAMSUNG_TAG_FACE_FEAT01:
473 case MNOTE_SAMSUNG_TAG_FACE_FEAT02:
474 case MNOTE_SAMSUNG_TAG_FACE_RECOG:
475 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
476 CC (entry->components, 1, v, maxlen);
477 vl = exif_get_long (entry->data, entry->order);
479 for (i = 0; (items[i].tag != entry->tag); i++);
482 snprintf (v, maxlen, _("Internal error (unknown value %li)"),(long int) vl);
485 CF (entry->format, items[i].fmt, v, maxlen);
487 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
488 if (items[i].elem[j].index != vl) {
489 snprintf (v, maxlen, _("Unknown value %li"), (long int)vl);
492 snprintf(v, maxlen, _("Face Recognition: %s"), _(items[i].elem[j].string));
496 case MNOTE_SAMSUNG_TAG_LENS_INFO:
497 case MNOTE_SAMSUNG_TAG_THIRDPARTY:
501 switch (entry->format) {
502 case EXIF_FORMAT_ASCII:
503 strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
505 case EXIF_FORMAT_SHORT:
506 CC (entry->components, 1, v, maxlen);
507 vs = exif_get_short (entry->data, entry->order);
508 snprintf (v, maxlen, "%hu", vs);
510 case EXIF_FORMAT_LONG:
511 CC (entry->components, 1, v, maxlen);
512 vl = exif_get_long (entry->data, entry->order);
513 snprintf (v, maxlen, "%li", (long int) vl);
515 case EXIF_FORMAT_RATIONAL:
516 CC (entry->components, 1, v, maxlen);
517 vr = exif_get_rational (entry->data, entry->order);
518 if (!vr.denominator) {
519 strncpy (v, _("Infinite"), maxlen);
521 r = (double)vr.numerator / vr.denominator;
522 snprintf (v, maxlen, "%2.3f", r);
525 case EXIF_FORMAT_SRATIONAL:
526 CC (entry->components, 1, v, maxlen);
527 vsr = exif_get_srational (entry->data, entry->order);
528 if (!vsr.denominator) {
529 strncpy (v, _("Infinite"), maxlen);
531 r = (double)vsr.numerator / vsr.denominator;
532 snprintf (v, maxlen, "%2.3f", r);
535 case EXIF_FORMAT_UNDEFINED:
537 snprintf (v, maxlen, _("%i bytes unknown data: "),
539 for (i = 0; i < (int)entry->size; i++) {
540 sprintf (buf, "%02x", entry->data[i]);
541 strncat (v, buf, maxlen - strlen (v));