Prevent crashes on too many unknown bytes:
[platform/upstream/libexif.git] / libexif / olympus / mnote-olympus-entry.c
1 /* mnote-olympus-entry.c
2  *
3  * Copyright © 2002 Lutz Müller <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., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <config.h>
22 #include "mnote-olympus-entry.h"
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include <libexif/exif-format.h>
29 #include <libexif/exif-utils.h>
30 #include <libexif/exif-entry.h>
31 #include <libexif/i18n.h>
32
33 #define CF(format,target,v,maxlen)                              \
34 {                                                               \
35         if (format != target) {                                 \
36                 snprintf (v, maxlen,                            \
37                         _("Invalid format '%s', "               \
38                         "expected '%s'."),                      \
39                         exif_format_get_name (format),          \
40                         exif_format_get_name (target));         \
41                 break;                                          \
42         }                                                       \
43 }
44
45 #define CC(number,target,v,maxlen)                                      \
46 {                                                                       \
47         if (number != target) {                                         \
48                 snprintf (v, maxlen,                                    \
49                         _("Invalid number of components (%i, "          \
50                         "expected %i)."), (int) number, (int) target);  \
51                 break;                                                  \
52         }                                                               \
53 }
54
55 #undef  MIN
56 #define MIN(a, b)  (((a) < (b)) ? (a) : (b))
57
58 static struct {
59         ExifTag tag;
60     ExifFormat fmt;
61         struct {
62                 int index;
63                 const char *string;
64         } elem[10];
65 } items[] = {
66   { MNOTE_NIKON_TAG_LENSTYPE, EXIF_FORMAT_BYTE,
67     { {0, N_("AF non D Lens")},
68       {1, N_("Manual")},
69       {2, N_("AF-D or AF-S Lens")},
70       {6, N_("AF-D G Lens")},
71       {10, N_("AF-D VR Lens")},
72       {0, NULL}}},
73   { MNOTE_NIKON_TAG_FLASHUSED, EXIF_FORMAT_BYTE,
74     { {0, N_("Flash did not fire")},
75       {4, N_("Flash unit unknown")},
76       {7, N_("Flash is external")},
77       {9, N_("Flash is on Camera")},
78       {0, NULL}}},
79   { MNOTE_NIKON1_TAG_QUALITY, EXIF_FORMAT_SHORT,
80     { {1, N_("VGA Basic")},
81       {2, N_("VGA Normal")},
82       {3, N_("VGA Fine")},
83       {4, N_("SXGA Basic")},
84       {5, N_("SXGA Normal")},
85       {6, N_("SXGA Fine")},
86       {10, N_("2 MPixel Basic")},
87       {11, N_("2 MPixel Normal")},
88       {12, N_("2 MPixel Fine")},
89       {0, NULL}}},
90   { MNOTE_NIKON1_TAG_COLORMODE, EXIF_FORMAT_SHORT,
91     { {1, N_("Color")},
92       {2, N_("Monochrome")},
93       {0, NULL}}},
94   { MNOTE_NIKON1_TAG_IMAGEADJUSTMENT, EXIF_FORMAT_SHORT,
95     { {0, N_("Normal")},
96       {1, N_("Bright+")},
97       {2, N_("Bright-")},
98       {3, N_("Contrast+")},
99       {4, N_("Contrast-")},
100       {0, NULL}}},
101   { MNOTE_NIKON1_TAG_CCDSENSITIVITY, EXIF_FORMAT_SHORT,
102     { {0, N_("ISO80")},
103       {2, N_("ISO160")},
104       {4, N_("ISO320")},
105       {5, N_("ISO100")},
106       {0, NULL}}},
107   { MNOTE_NIKON1_TAG_WHITEBALANCE, EXIF_FORMAT_SHORT,
108     { {0, N_("Auto")},
109       {1, N_("Preset")},
110       {2, N_("Daylight")},
111       {3, N_("Incandescense")},
112       {4, N_("Fluorescence")},
113       {5, N_("Cloudy")},
114       {6, N_("SpeedLight")},
115       {0, NULL}}},
116   { MNOTE_NIKON1_TAG_CONVERTER, EXIF_FORMAT_SHORT,
117     { {0, N_("No Fisheye")},
118       {1, N_("Fisheye On")},
119       {0, NULL}}},
120   { MNOTE_OLYMPUS_TAG_QUALITY, EXIF_FORMAT_SHORT,
121     { {1, N_("SQ")},
122       {2, N_("HQ")},
123       {3, N_("SHQ")},
124       {0, NULL}}},
125   { MNOTE_OLYMPUS_TAG_MACRO, EXIF_FORMAT_SHORT,
126     { {0, N_("No")},
127       {1, N_("Yes")},
128       {0, NULL}}},
129   { MNOTE_OLYMPUS_TAG_DIGIZOOM, EXIF_FORMAT_SHORT,
130     { {0, N_("1x")},
131       {2, N_("2x")},
132       {0, NULL}}},
133   { MNOTE_OLYMPUS_TAG_FLASHMODE, EXIF_FORMAT_SHORT,
134     { {0, N_("Auto")},
135       {1, N_("Red-eye reduction")},
136       {2, N_("Fill")},
137       {3, N_("Off")},
138       {0, NULL}}},
139   { MNOTE_OLYMPUS_TAG_SHARPNESS, EXIF_FORMAT_SHORT,
140     { {0, N_("Normal")},
141       {1, N_("Hard")},
142       {2, N_("Soft")},
143       {0, NULL}}},
144   { MNOTE_OLYMPUS_TAG_CONTRAST, EXIF_FORMAT_SHORT,
145     { {0, N_("Hard")},
146       {1, N_("Normal")},
147       {2, N_("Soft")},
148       {0, NULL}}},
149   { MNOTE_OLYMPUS_TAG_MANFOCUS, EXIF_FORMAT_SHORT,
150     { {0, N_("No")},
151       {1, N_("Yes")},
152       {0, NULL}}},
153   { 0, }
154 };
155
156 char *
157 mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *v, unsigned int maxlen)
158 {
159         char         buf[32];
160         ExifLong     vl;
161         ExifShort    vs = 0;
162         ExifRational vr;
163         int          i, j;
164         double       r, b;
165
166         if (!entry)
167                 return (NULL);
168
169         memset (v, 0, maxlen);
170         maxlen--;
171
172         if ((!entry->data) && (entry->components > 0)) return (v);
173
174         switch (entry->tag) {
175         
176         /* Nikon */
177         case MNOTE_NIKON_TAG_FIRMWARE:
178                 CF (entry->format,  EXIF_FORMAT_UNDEFINED, v, maxlen);
179                 CC (entry->components, 4, v, maxlen);
180                 vl = exif_get_long (entry->data, entry->order);
181                 if ((vl & 0xF0F0F0F0) == 0x30303030) {
182                         memcpy (v, entry->data, MIN (maxlen, 4));
183                 } else {
184                         snprintf (v, maxlen, "%04lx", vl);
185                 }
186                 break;
187         case MNOTE_NIKON_TAG_ISO:
188                 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
189                 CC (entry->components, 2, v, maxlen);
190                 //vs = exif_get_short (entry->data, entry->order);
191                 vs = exif_get_short (entry->data + 2, entry->order);
192                 snprintf (v, maxlen, "ISO %hd", vs);
193                 break;
194         case MNOTE_NIKON_TAG_ISO2:
195                 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
196                 CC (entry->components, 2, v, maxlen);
197                 //vs = exif_get_short (entry->data, entry->order);
198                 vs = exif_get_short (entry->data + 2, entry->order);
199                 snprintf (v, maxlen, "ISO2 %hd", vs);
200                 break;
201         case MNOTE_NIKON_TAG_QUALITY:
202                 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
203                 //CC (entry->components, 8, v, maxlen);
204                 //vl =  exif_get_long (entry->data  , entry->order);
205                 //printf("-> 0x%04x\n",entry->data);
206                 //printf("-> 0x%s<\n",entry->data - 0);
207                 memcpy(v, entry->data ,entry->components);
208                 //snprintf (v, maxlen, "%s<",  ( entry->data - 9  );
209                 break;
210         case MNOTE_NIKON_TAG_COLORMODE:
211         case MNOTE_NIKON_TAG_COLORMODE1:
212         case MNOTE_NIKON_TAG_WHITEBALANCE:
213         case MNOTE_NIKON_TAG_SHARPENING:
214         case MNOTE_NIKON_TAG_FOCUSMODE:
215         case MNOTE_NIKON_TAG_FLASHSETTING:
216         case MNOTE_NIKON_TAG_ISOSELECTION:
217         case MNOTE_NIKON_TAG_FLASHMODE:
218         case MNOTE_NIKON_TAG_IMAGEADJUSTMENT:
219         case MNOTE_NIKON_TAG_ADAPTER:
220                 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
221                 memcpy(v, entry->data, MIN (maxlen, entry->components));
222                 break;
223         case MNOTE_NIKON_TAG_TOTALPICTURES:
224                 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
225                 CC (entry->components, 1, v, maxlen);
226                 vl =  exif_get_long (entry->data, entry->order);
227                 snprintf (v, maxlen, "%lu",  vl );
228                 break;
229         case MNOTE_NIKON_TAG_WHITEBALANCEFINE:
230                 CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen);
231                 CC (entry->components, 1, v, maxlen);
232                 vs = exif_get_short (entry->data, entry->order);
233                 snprintf (v, maxlen, "%hd", vs);
234                 break;
235         case MNOTE_NIKON_TAG_WHITEBALANCERB:
236                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
237                 CC (entry->components, 4, v, maxlen);
238                 vr = exif_get_rational (entry->data, entry->order);
239                 r = (double)vr.numerator / vr.denominator;
240                 vr = exif_get_rational (entry->data+8, entry->order);
241                 b = (double)vr.numerator / vr.denominator;
242                 //printf("numerator %li, denominator %li\n", vr.numerator, vr.denominator);
243                 snprintf (v, maxlen, "Red Correction %f, Blue Correction %f", r,b);
244                 break;
245         case MNOTE_NIKON_TAG_MANUALFOCUSDISTANCE:
246                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
247                 CC (entry->components, 1, v, maxlen);
248                 vr = exif_get_rational (entry->data, entry->order);
249                 if (vr.numerator) {
250                         r = (double)vr.numerator / vr.denominator;
251                         snprintf (v, maxlen, "%2.2f meters", r);
252                 } else {
253                         strncpy (v, _("No manual focus selection"), maxlen);
254                 }
255                 break;
256         case MNOTE_NIKON_TAG_DIGITALZOOM:
257         case MNOTE_NIKON1_TAG_DIGITALZOOM:
258                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
259                 CC (entry->components, 1, v, maxlen);
260                 vr = exif_get_rational (entry->data, entry->order);
261                 r = (double)vr.numerator / vr.denominator;
262                 snprintf (v, maxlen, "%2.2f", r);
263                 break;
264         case MNOTE_NIKON_TAG_AFFOCUSPOSITION:
265                 CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
266                 CC (entry->components, 4, v, maxlen);
267                 switch (  *( entry->data+1)  ) {
268                         case  0: strncpy (v, "AF Position: Center", maxlen); break;
269                         case  1: strncpy (v, "AF Position: Top", maxlen); break;
270                         case  2: strncpy (v, "AF Position: Bottom", maxlen); break;
271                         case  3: strncpy (v, "AF Position: Left", maxlen); break;
272                         case  4: strncpy (v, "AF Position: Right", maxlen); break;
273                         default: strncpy (v, "Unknown AF Position", maxlen);
274                 }     
275                 break;
276         case MNOTE_OLYMPUS_TAG_DIGIZOOM:
277                 if (entry->format == EXIF_FORMAT_RATIONAL) {
278                         CC (entry->components, 1, v, maxlen);
279                         vr = exif_get_rational (entry->data, entry->order);
280                         r = (double)vr.numerator / vr.denominator;
281                         if (!vr.numerator) {
282                                 strncpy (v, _("None"), maxlen);
283                         } else {
284                                 snprintf (v, maxlen, "%2.2f", r);
285                         }
286                         break;
287                 }
288                 /* fall through to handle SHORT version of this tag */
289         case MNOTE_NIKON_TAG_LENSTYPE:
290         case MNOTE_NIKON_TAG_FLASHUSED:
291         case MNOTE_NIKON1_TAG_QUALITY:
292         case MNOTE_NIKON1_TAG_COLORMODE:
293         case MNOTE_NIKON1_TAG_IMAGEADJUSTMENT:
294         case MNOTE_NIKON1_TAG_CCDSENSITIVITY:
295         case MNOTE_NIKON1_TAG_WHITEBALANCE:
296         case MNOTE_NIKON1_TAG_CONVERTER:
297         case MNOTE_OLYMPUS_TAG_QUALITY:
298         case MNOTE_OLYMPUS_TAG_MACRO:
299         case MNOTE_OLYMPUS_TAG_FLASHMODE:
300         case MNOTE_OLYMPUS_TAG_SHARPNESS:
301         case MNOTE_OLYMPUS_TAG_CONTRAST:
302         case MNOTE_OLYMPUS_TAG_MANFOCUS:
303                 /* search the tag */
304                 for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++);
305                 if (!items[i].tag) {
306                         strncpy (v, "Internal error", maxlen);
307                         break;
308                 }
309                 CF (entry->format, items[i].fmt, v, maxlen);
310                 CC (entry->components, 1, v, maxlen);
311                 switch (entry->format) {
312                 case EXIF_FORMAT_BYTE:
313                 case EXIF_FORMAT_UNDEFINED:
314                         vs = entry->data[0];
315                         break;
316                 case EXIF_FORMAT_SHORT:
317                         vs = exif_get_short(entry->data, entry->order);
318                         break;
319                 default:
320                         vs = 0;
321                         break;
322                 }
323                 /* find the value */
324                 for (j = 0; items[i].elem[j].string &&
325                             (items[i].elem[j].index < vs); j++);
326                 if (items[i].elem[j].index != vs) {
327                         snprintf (v, maxlen, "Unknown value %hi", vs);
328                         break;
329                 }
330                 strncpy (v, items[i].elem[j].string, maxlen);
331                 break;
332
333         case MNOTE_NIKON_TAG_LENS:
334                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
335                 CC (entry->components, 4, v, maxlen);
336                 {
337                         double c,d;
338                         unsigned long a,b;
339                         vr = exif_get_rational (entry->data, entry->order);
340                         a = vr.numerator / vr.denominator;
341                         vr = exif_get_rational (entry->data+8, entry->order);
342                         b = vr.numerator / vr.denominator;
343                         vr = exif_get_rational (entry->data+16, entry->order);
344                         c = (double)vr.numerator / vr.denominator;
345                         vr = exif_get_rational (entry->data+24, entry->order);
346                         d = (double)vr.numerator / vr.denominator;
347                         //printf("numerator %li, denominator %li\n", vr.numerator, vr.denominator);
348                         snprintf (v, maxlen, "%ld-%ldmm 1:%3.1f - %3.1f",a,b,c,d);
349                 }
350                 break;
351         case MNOTE_NIKON1_TAG_FOCUS:
352                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
353                 CC (entry->components, 1, v, maxlen);
354                 vr = exif_get_rational (entry->data, entry->order);
355                 if (!vr.denominator) {
356                         strncpy (v, _("Infinite"), maxlen);
357                 } else {
358                         r = (double)vr.numerator / vr.denominator;
359                         snprintf (v, maxlen, "%2.2f", r);
360                 }
361                 break;
362
363         /* Olympus */
364         case MNOTE_OLYMPUS_TAG_MODE:
365                 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
366                 CC (entry->components, 3, v, maxlen);
367                 vl = exif_get_long (entry->data, entry->order);
368                 switch (vl) {
369                 case 0:
370                         strncpy (v, _("normal"), maxlen);
371                         break;
372                 case 1:
373                         strncpy (v, _("unknown"), maxlen);
374                         break;
375                 case 2:
376                         strncpy (v, _("fast"), maxlen);
377                         break;
378                 case 3:
379                         strncpy (v, _("panorama"), maxlen);
380                         break;
381                 default:
382                         snprintf (v, maxlen, _("%li"), vl);
383                 }
384                 vl = exif_get_long (entry->data + 4, entry->order);
385                 snprintf (buf, sizeof (buf), "/%li/", vl);
386                 strncat (v, buf, maxlen - strlen (v));
387                 vl = exif_get_long (entry->data + 4, entry->order);
388                 switch (vl) {
389                 case 1:
390                         strncat (v, _("left to right"), maxlen - strlen (v));
391                         break;
392                 case 2:
393                         strncat (v, _("right to left"), maxlen - strlen (v));
394                         break;
395                 case 3:
396                         strncat (v, _("bottom to top"), maxlen - strlen (v));
397                         break;
398                 case 4:
399                         strncat (v, _("top to bottom"), maxlen - strlen (v));
400                         break;
401                 default:
402                         snprintf (buf, sizeof (buf), _("%li"), vl);
403                         strncat (v, buf, maxlen - strlen (v));
404                 }
405                 break;
406         case MNOTE_OLYMPUS_TAG_UNKNOWN_1:
407                 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
408                 CC (entry->components, 1, v, maxlen);
409                 strncpy (v, _("Unknown tag."), maxlen);
410                 break;
411         case MNOTE_OLYMPUS_TAG_UNKNOWN_2:
412                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
413                 CC (entry->components, 1, v, maxlen);
414                 break;
415         case MNOTE_OLYMPUS_TAG_UNKNOWN_3:
416                 CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen);
417                 CC (entry->components, 1, v, maxlen);
418                 break;
419         case MNOTE_OLYMPUS_TAG_VERSION:
420                 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
421                 CC (entry->components, 5, v, maxlen);
422                 strncpy (v, entry->data, MIN (maxlen, entry->size));
423                 break;
424         case MNOTE_OLYMPUS_TAG_INFO:
425                 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen);
426                 CC (entry->components, 52, v, maxlen);
427                 break;
428         case MNOTE_OLYMPUS_TAG_ID:
429                 CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen);
430                 CC (entry->components, 32, v, maxlen);
431                 strncpy (v, entry->data, MIN (maxlen, entry->size));
432                 break;
433         case MNOTE_OLYMPUS_TAG_UNKNOWN_4:
434                 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen);
435                 CC (entry->components, 30, v, maxlen);
436                 break;
437         case MNOTE_OLYMPUS_TAG_FOCUSDIST:
438                 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen);
439                 CC (entry->components, 1, v, maxlen);
440                 vr = exif_get_rational (entry->data, entry->order);
441                 if (vr.numerator == 0) {
442                         strncpy (v, _("Unknown"), maxlen);
443                 }
444                 else {
445                         unsigned long tmp = vr.numerator / vr.denominator;
446                         /* printf("numerator %li, denominator %li\n", vr.numerator, vr.denominator); */
447                         snprintf (v, maxlen, "%li mm", tmp);
448                 }
449                 break;
450         case MNOTE_OLYMPUS_TAG_WBALANCE:
451                 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen);
452                 CC (entry->components, 2, v, maxlen);
453                 vs = exif_get_short (entry->data, entry->order);
454                 switch (vs) {
455                 case 1:
456                         strncpy (v, _("Automatic"), maxlen);
457                         break;
458                 case 2:
459                         {
460                                 ExifShort v2 = exif_get_short (entry->data + 2, entry->order);
461                                 unsigned long colorTemp = 0;
462                                 switch (v2) {
463                                 case 2:
464                                         colorTemp = 3000;
465                                         break;
466                                 case 3:
467                                         colorTemp = 3700;
468                                         break;
469                                 case 4:
470                                         colorTemp = 4000;
471                                         break;
472                                 case 5:
473                                         colorTemp = 4500;
474                                         break;
475                                 case 6:
476                                         colorTemp = 5500;
477                                         break;
478                                 case 7:
479                                         colorTemp = 6500;
480                                         break;
481                                 case 9:
482                                         colorTemp = 7500;
483                                         break;
484                                 }
485                                 if (colorTemp) {
486                                         snprintf (v, maxlen, "Manual: %liK", colorTemp);
487                                 }
488                                 else {
489                                         strncpy (v, _("Manual: Unknown"), maxlen);
490                                 }
491
492                         }
493                         break;
494                 case 3:
495                         strncpy (v, _("One-touch"), maxlen);
496                         break;
497                 default:
498                         strncpy (v, _("Unknown"), maxlen);
499                         break;
500                 }
501                 break;
502         default:
503                 switch (entry->format) {
504                 case EXIF_FORMAT_ASCII:
505                         strncpy (v, entry->data,
506                                  MIN (maxlen, entry->components));
507                         break;
508                 case EXIF_FORMAT_SHORT:
509                         vs = exif_get_short (entry->data, entry->order);
510                         snprintf (v, maxlen, "%hi", vs);
511                         break;
512                 case EXIF_FORMAT_LONG:
513                         vl = exif_get_long (entry->data, entry->order);
514                         snprintf (v, maxlen, "%li", vl);
515                         break;
516                 case EXIF_FORMAT_UNDEFINED:
517                 default:
518                         snprintf (v, maxlen, "%li bytes unknown data:",
519                                   entry->size);
520                         for (i = 0; i < entry->size; i++) {
521                                 sprintf (buf, " %02x", entry->data[i]);
522                                 strncat (v, buf, maxlen - strlen (v));
523                         }
524                         break;
525                 }
526                 break;
527         }
528
529         return (v);
530 }