1 /* mnote-olympus-entry.c 2 * 3 * Copyright (c) 2002-2009 Lutz Mueller <lutz (at) users.sourceforge.net> et. al. 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-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 CF2(format,target1,target2,v,maxlen) \ 46 { \ 47 if ((format != target1) && (format != target2)) { \ 48 snprintf (v, maxlen, \ 49 _("Invalid format '%s', " \ 50 "expected '%s' or '%s'."), \ 51 exif_format_get_name (format), \ 52 exif_format_get_name (target1), \ 53 exif_format_get_name (target2)); \ 54 break; \ 55 } \ 56 } 57 58 #define CC(number,target,v,maxlen) \ 59 { \ 60 if (number != target) { \ 61 snprintf (v, maxlen, \ 62 _("Invalid number of components (%i, " \ 63 "expected %i)."), (int) number, (int) target); \ 64 break; \ 65 } \ 66 } 67 68 #define CC2(number,t1,t2,v,maxlen) \ 69 { \ 70 if ((number < t1) || (number > t2)) { \ 71 snprintf (v, maxlen, \ 72 _("Invalid number of components (%i, " \ 73 "expected %i or %i)."), (int) number, \ 74 (int) t1, (int) t2); \ 75 break; \ 76 } \ 77 } 78 79 #define R2L(n) ((n).denominator ? (long)(n).numerator/(n).denominator : 0L) 80 #define R2D(n) ((n).denominator ? (double)(n).numerator/(n).denominator : 0.0) 81 82 static const struct { 83 ExifTag tag; 84 ExifFormat fmt; 85 struct { 86 int index; 87 const char *string; 88 } elem[24]; 89 } items[] = { 90 #ifndef NO_VERBOSE_TAG_DATA 91 { MNOTE_NIKON_TAG_LENSTYPE, EXIF_FORMAT_BYTE, 92 { {0, N_("AF non D lens")}, 93 {1, N_("Manual")}, 94 {2, N_("AF-D or AF-S lens")}, 95 {6, N_("AF-D G lens")}, 96 {10, N_("AF-D VR lens")}, 97 {14, N_("AF-D G VR lens")}, 98 {0, NULL}}}, 99 { MNOTE_NIKON_TAG_FLASHUSED, EXIF_FORMAT_BYTE, 100 { {0, N_("Flash did not fire")}, 101 {4, N_("Flash unit unknown")}, 102 {7, N_("Flash is external")}, 103 {9, N_("Flash is on camera")}, 104 {0, NULL}}}, 105 { MNOTE_NIKON1_TAG_QUALITY, EXIF_FORMAT_SHORT, 106 { {1, N_("VGA basic")}, 107 {2, N_("VGA normal")}, 108 {3, N_("VGA fine")}, 109 {4, N_("SXGA basic")}, 110 {5, N_("SXGA normal")}, 111 {6, N_("SXGA fine")}, 112 {10, N_("2 Mpixel basic")}, 113 {11, N_("2 Mpixel normal")}, 114 {12, N_("2 Mpixel fine")}, 115 {0, NULL}}}, 116 { MNOTE_NIKON1_TAG_COLORMODE, EXIF_FORMAT_SHORT, 117 { {1, N_("Color")}, 118 {2, N_("Monochrome")}, 119 {0, NULL}}}, 120 { MNOTE_NIKON1_TAG_IMAGEADJUSTMENT, EXIF_FORMAT_SHORT, 121 { {0, N_("Normal")}, 122 {1, N_("Bright+")}, 123 {2, N_("Bright-")}, 124 {3, N_("Contrast+")}, 125 {4, N_("Contrast-")}, 126 {0, NULL}}}, 127 { MNOTE_NIKON1_TAG_CCDSENSITIVITY, EXIF_FORMAT_SHORT, 128 { {0, N_("ISO 80")}, 129 {2, N_("ISO 160")}, 130 {4, N_("ISO 320")}, 131 {5, N_("ISO 100")}, 132 {0, NULL}}}, 133 { MNOTE_NIKON1_TAG_WHITEBALANCE, EXIF_FORMAT_SHORT, 134 { {0, N_("Auto")}, 135 {1, N_("Preset")}, 136 {2, N_("Daylight")}, 137 {3, N_("Incandescence")}, 138 {4, N_("Fluorescence")}, 139 {5, N_("Cloudy")}, 140 {6, N_("SpeedLight")}, 141 {0, NULL}}}, 142 { MNOTE_NIKON1_TAG_CONVERTER, EXIF_FORMAT_SHORT, 143 { {0, N_("No fisheye")}, 144 {1, N_("Fisheye on")}, 145 {0, NULL}}}, 146 { MNOTE_OLYMPUS_TAG_QUALITY, EXIF_FORMAT_SHORT, 147 { {1, N_("Normal, SQ")}, 148 {2, N_("Normal, HQ")}, 149 {3, N_("Normal, SHQ")}, 150 {4, N_("Normal, RAW")}, 151 {5, N_("Normal, SQ1")}, 152 {6, N_("Normal, SQ2")}, 153 {7, N_("Normal, super high")}, 154 {17, N_("Normal, standard")}, 155 {0x101, N_("Fine, SQ")}, 156 {0x102, N_("Fine, HQ")}, 157 {0x103, N_("Fine, SHQ")}, 158 {0x104, N_("Fine, RAW")}, 159 {0x105, N_("Fine, SQ1")}, 160 {0x106, N_("Fine, SQ2")}, 161 {0x107, N_("Fine, super high")}, 162 {0x201, N_("Super fine, SQ")}, 163 {0x202, N_("Super fine, HQ")}, 164 {0x203, N_("Super fine, SHQ")}, 165 {0x204, N_("Super fine, RAW")}, 166 {0x205, N_("Super fine, SQ1")}, 167 {0x206, N_("Super fine, SQ2")}, 168 {0x207, N_("Super fine, super high")}, 169 {0x211, N_("Super fine, high")}, 170 {0, NULL}}}, 171 { MNOTE_OLYMPUS_TAG_MACRO, EXIF_FORMAT_SHORT, 172 { {0, N_("No")}, 173 {1, N_("Yes")}, 174 {2, N_("Super macro")}, 175 {0, NULL}}}, 176 { MNOTE_OLYMPUS_TAG_BWMODE, EXIF_FORMAT_SHORT, 177 { {0, N_("No")}, 178 {1, N_("Yes")}, 179 {0, NULL}}}, 180 { MNOTE_OLYMPUS_TAG_ONETOUCHWB, EXIF_FORMAT_SHORT, 181 { {0, N_("Off")}, 182 {1, N_("On")}, 183 {2, N_("On (Preset)")}, 184 {0, NULL}}}, 185 { MNOTE_OLYMPUS_TAG_FLASHMODE, EXIF_FORMAT_SHORT, 186 { {0, N_("Auto")}, 187 {1, N_("Red-eye reduction")}, 188 {2, N_("Fill")}, 189 {3, N_("Off")}, 190 {0, NULL}}}, 191 { MNOTE_OLYMPUS_TAG_FLASHDEVICE, EXIF_FORMAT_SHORT, 192 { {0, N_("None")}, 193 {1, N_("Internal")}, 194 {4, N_("External")}, 195 {5, N_("Internal + external")}, 196 {0, NULL}}}, 197 { MNOTE_OLYMPUS_TAG_FOCUSRANGE, EXIF_FORMAT_SHORT, 198 { {0, N_("Normal")}, 199 {1, N_("Macro")}, 200 {0, NULL}}}, 201 { MNOTE_OLYMPUS_TAG_MANFOCUS, EXIF_FORMAT_SHORT, 202 { {0, N_("Auto")}, 203 {1, N_("Manual")}, 204 {0, NULL}}}, 205 { MNOTE_OLYMPUS_TAG_SHARPNESS, EXIF_FORMAT_SHORT, 206 { {0, N_("Normal")}, 207 {1, N_("Hard")}, 208 {2, N_("Soft")}, 209 {0, NULL}}}, 210 { MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE, EXIF_FORMAT_SHORT, 211 { {0, N_("No")}, 212 {1, N_("Yes")}, 213 {0, NULL}}}, 214 { MNOTE_OLYMPUS_TAG_CONTRAST, EXIF_FORMAT_SHORT, 215 { {0, N_("Hard")}, 216 {1, N_("Normal")}, 217 {2, N_("Soft")}, 218 {0, NULL}}}, 219 { MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID, EXIF_FORMAT_LONG, 220 { {0, N_("No")}, 221 {1, N_("Yes")}, 222 {0, NULL}}}, 223 { MNOTE_OLYMPUS_TAG_CCDSCANMODE, EXIF_FORMAT_SHORT, 224 { {0, N_("Interlaced")}, 225 {1, N_("Progressive")}, 226 {0, NULL}}}, 227 228 { MNOTE_SANYO_TAG_SEQUENTIALSHOT, EXIF_FORMAT_SHORT, 229 { {0, N_("None")}, 230 {1, N_("Standard")}, 231 {2, N_("Best")}, 232 {3, N_("Adjust exposure")}, 233 {0, NULL}}}, 234 { MNOTE_SANYO_TAG_FOCUSMODE, EXIF_FORMAT_SHORT, 235 { {1, N_("Spot focus")}, 236 {2, N_("Normal focus")}, 237 {0, NULL}}}, 238 { MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE, EXIF_FORMAT_SHORT, 239 { {0, N_("Record while down")}, 240 {1, N_("Press start, press stop")}, 241 {0, NULL}}}, 242 { MNOTE_SANYO_TAG_RESAVED, EXIF_FORMAT_SHORT, 243 { {0, N_("No")}, 244 {1, N_("Yes")}, 245 {0, NULL}}}, 246 { MNOTE_SANYO_TAG_CCDSENSITIVITY, EXIF_FORMAT_SHORT, 247 { {0, N_("Auto")}, 248 {1, N_("ISO 50")}, 249 {3, N_("ISO 100")}, 250 {4, N_("ISO 200")}, 251 {5, N_("ISO 400")}, 252 {0, NULL}}}, 253 { MNOTE_SANYO_TAG_SCENESELECT, EXIF_FORMAT_SHORT, 254 { {0, N_("Off")}, 255 {1, N_("Sport")}, 256 {2, N_("TV")}, 257 {3, N_("Night")}, 258 {4, N_("User 1")}, 259 {5, N_("User 2")}, 260 {6, N_("Lamp")}, 261 {0, NULL}}}, 262 { MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL, EXIF_FORMAT_SHORT, 263 { {0, N_("5 frames/sec")}, 264 {1, N_("10 frames/sec")}, 265 {2, N_("15 frames/sec")}, 266 {3, N_("20 frames/sec")}, 267 {0, NULL}}}, 268 #endif 269 { 0, 0, { { 0, NULL } } } 270 }; 271 272 char * 273 mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *v, unsigned int maxlen) 274 { 275 char buf[30]; 276 ExifLong vl; 277 ExifShort vs = 0; 278 ExifSShort vss = 0; 279 ExifRational vr, vr2; 280 ExifSRational vsr; 281 int i, j; 282 double r, b; 283 284 if (!entry) 285 return (NULL); 286 287 memset (v, 0, maxlen); 288 maxlen--; 289 290 if ((!entry->data) && (entry->components > 0)) 291 return (v); 292 293 if ((!entry->data) && (entry->size > 0)) 294 return NULL; /* internal inconsistency error */ 295 296 switch (entry->tag) { 297 298 /* Nikon */ 299 case MNOTE_NIKON_TAG_FIRMWARE: 300 CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen); 301 CC (entry->components, 4, v, maxlen); 302 vl = exif_get_long (entry->data, entry->order); 303 if ((vl & 0xF0F0F0F0) == 0x30303030) { 304 memcpy (v, entry->data, MIN (maxlen, 4)); 305 } else { 306 snprintf (v, maxlen, "%04lx", (long unsigned int) vl); 307 } 308 break; 309 case MNOTE_NIKON_TAG_ISO: 310 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); 311 CC (entry->components, 2, v, maxlen); 312 /*vs = exif_get_short (entry->data, entry->order);*/ 313 vs = exif_get_short (entry->data + 2, entry->order); 314 snprintf (v, maxlen, "ISO %hd", vs); 315 break; 316 case MNOTE_NIKON_TAG_ISO2: 317 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); 318 CC (entry->components, 2, v, maxlen); 319 /*vs = exif_get_short (entry->data, entry->order);*/ 320 vs = exif_get_short (entry->data + 2, entry->order); 321 snprintf (v, maxlen, "ISO2 %hd", vs); 322 break; 323 case MNOTE_NIKON_TAG_QUALITY: 324 case MNOTE_NIKON_TAG_COLORMODE: 325 case MNOTE_NIKON_TAG_COLORMODE1: 326 case MNOTE_NIKON_TAG_WHITEBALANCE: 327 case MNOTE_NIKON_TAG_SHARPENING: 328 case MNOTE_NIKON_TAG_FOCUSMODE: 329 case MNOTE_NIKON_TAG_FLASHSETTING: 330 case MNOTE_NIKON_TAG_ISOSELECTION: 331 case MNOTE_NIKON_TAG_FLASHMODE: 332 case MNOTE_NIKON_TAG_IMAGEADJUSTMENT: 333 case MNOTE_NIKON_TAG_ADAPTER: 334 case MNOTE_NIKON_TAG_SATURATION2: 335 case MNOTE_EPSON_TAG_SOFTWARE: 336 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen); 337 memcpy(v, entry->data, MIN (maxlen, entry->size)); 338 break; 339 case MNOTE_NIKON_TAG_TOTALPICTURES: 340 case MNOTE_EPSON_TAG_IMAGE_WIDTH: 341 case MNOTE_EPSON_TAG_IMAGE_HEIGHT: 342 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen); 343 CC (entry->components, 1, v, maxlen); 344 vl = exif_get_long (entry->data, entry->order); 345 snprintf (v, maxlen, "%lu", (long unsigned int) vl ); 346 break; 347 case MNOTE_NIKON_TAG_LENS_FSTOPS: 348 case MNOTE_NIKON_TAG_EXPOSUREDIFF: { 349 unsigned char a,b,c,d; 350 CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen); 351 CC (entry->components, 4, v, maxlen); 352 vl = exif_get_long (entry->data, entry->order); 353 a = (vl>>24)&0xff; b = (vl>>16)&0xff; c = (vl>>8)&0xff; d = (vl)&0xff; 354 snprintf (v, maxlen, "%.1f", c?(float)a*((float)b/(float)c):0 ); 355 break; 356 } 357 case MNOTE_NIKON_TAG_FLASHEXPCOMPENSATION: 358 case MNOTE_NIKON_TAG_FLASHEXPOSUREBRACKETVAL: 359 CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen); 360 CC (entry->components, 4, v, maxlen); 361 vl = exif_get_long (entry->data, entry->order); 362 snprintf (v, maxlen, "%.1f", ((long unsigned int) vl>>24)/6.0 ); 363 break; 364 case MNOTE_NIKON_TAG_SATURATION: 365 case MNOTE_NIKON_TAG_WHITEBALANCEFINE: 366 case MNOTE_NIKON_TAG_HUE: 367 case MNOTE_OLYMPUS_TAG_SENSORTEMPERATURE: 368 case MNOTE_OLYMPUS_TAG_LENSTEMPERATURE: 369 CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen); 370 CC (entry->components, 1, v, maxlen); 371 vs = exif_get_short (entry->data, entry->order); 372 snprintf (v, maxlen, "%hd", vs); 373 break; 374 case MNOTE_NIKON_TAG_WHITEBALANCERB: 375 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen); 376 CC (entry->components, 4, v, maxlen); 377 vr = exif_get_rational (entry->data, entry->order); 378 r = R2D(vr); 379 vr = exif_get_rational (entry->data+8, entry->order); 380 b = R2D(vr); 381 snprintf (v, maxlen, _("Red Correction %f, blue Correction %f"), r,b); 382 break; 383 case MNOTE_NIKON_TAG_MANUALFOCUSDISTANCE: 384 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen); 385 CC (entry->components, 1, v, maxlen); 386 vr = exif_get_rational (entry->data, entry->order); 387 if (!vr.numerator || !vr.denominator) { 388 strncpy (v, _("No manual focus selection"), maxlen); 389 } else { 390 r = R2D(vr); 391 snprintf (v, maxlen, _("%2.2f meters"), r); 392 } 393 break; 394 case MNOTE_NIKON_TAG_SENSORPIXELSIZE: 395 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen); 396 CC (entry->components, 2, v, maxlen); 397 vr = exif_get_rational (entry->data, entry->order); 398 vr2 = exif_get_rational (entry->data+8, entry->order); 399 r = R2D(vr); 400 b = R2D(vr2); 401 snprintf (v, maxlen, "%2.2f x %2.2f um", r, b); 402 break; 403 case MNOTE_NIKON_TAG_BRACKETING: 404 CF2 (entry->format, EXIF_FORMAT_BYTE, EXIF_FORMAT_SHORT, v, maxlen); 405 CC (entry->components, 1, v, maxlen); 406 if (EXIF_FORMAT_SHORT == entry->format) { 407 vs = exif_get_short (entry->data, entry->order); 408 } else { 409 vs = entry->data[0]; 410 } 411 snprintf (v, maxlen, "%hd", vs); 412 break; 413 case MNOTE_NIKON_TAG_AFFOCUSPOSITION: 414 CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen); 415 CC (entry->components, 4, v, maxlen); 416 switch ( *( entry->data+1) ) { 417 case 0: strncpy (v, _("AF position: center"), maxlen); break; 418 case 1: strncpy (v, _("AF position: top"), maxlen); break; 419 case 2: strncpy (v, _("AF position: bottom"), maxlen); break; 420 case 3: strncpy (v, _("AF position: left"), maxlen); break; 421 case 4: strncpy (v, _("AF position: right"), maxlen); break; 422 case 5: strncpy (v, _("AF position: upper-left"), maxlen); break; 423 case 6: strncpy (v, _("AF position: upper-right"), maxlen); break; 424 case 7: strncpy (v, _("AF position: lower-left"), maxlen); break; 425 case 8: strncpy (v, _("AF position: lower-right"), maxlen); break; 426 case 9: strncpy (v, _("AF position: far left"), maxlen); break; 427 case 10: strncpy (v, _("AF position: far right"), maxlen); break; 428 default: strncpy (v, _("Unknown AF position"), maxlen); 429 } 430 break; 431 case MNOTE_OLYMPUS_TAG_FLASHDEVICE: 432 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); 433 CC (entry->components, 2, v, maxlen); 434 vs = exif_get_short(entry->data, entry->order); 435 /* search for the tag */ 436 for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++) 437 ; 438 if (!items[i].tag) { 439 snprintf (v, maxlen, _("Internal error (unknown value %hi)"), vs); 440 break; 441 } 442 CF (entry->format, items[i].fmt, v, maxlen); 443 /* find the value */ 444 for (j = 0; items[i].elem[j].string && 445 (items[i].elem[j].index < vs); j++); 446 if (items[i].elem[j].index != vs) { 447 snprintf (v, maxlen, _("Unknown value %hi"), vs); 448 break; 449 } 450 strncpy (v, _(items[i].elem[j].string), maxlen); 451 break; 452 case MNOTE_OLYMPUS_TAG_DIGIZOOM: 453 if (entry->format == EXIF_FORMAT_RATIONAL) { 454 CC (entry->components, 1, v, maxlen); 455 vr = exif_get_rational (entry->data, entry->order); 456 if (!vr.numerator || !vr.denominator) { 457 strncpy (v, _("None"), maxlen); 458 } else { 459 r = R2D(vr); 460 snprintf (v, maxlen, "%2.2f", r); 461 } 462 break; 463 } 464 /* fall through to handle SHORT version of this tag */ 465 case MNOTE_NIKON_TAG_LENSTYPE: 466 case MNOTE_NIKON_TAG_FLASHUSED: 467 case MNOTE_NIKON1_TAG_QUALITY: 468 case MNOTE_NIKON1_TAG_COLORMODE: 469 case MNOTE_NIKON1_TAG_IMAGEADJUSTMENT: 470 case MNOTE_NIKON1_TAG_CCDSENSITIVITY: 471 case MNOTE_NIKON1_TAG_WHITEBALANCE: 472 case MNOTE_NIKON1_TAG_CONVERTER: 473 case MNOTE_OLYMPUS_TAG_QUALITY: 474 case MNOTE_OLYMPUS_TAG_MACRO: 475 case MNOTE_OLYMPUS_TAG_BWMODE: 476 case MNOTE_OLYMPUS_TAG_ONETOUCHWB: 477 case MNOTE_OLYMPUS_TAG_FLASHMODE: 478 case MNOTE_OLYMPUS_TAG_FOCUSRANGE: 479 case MNOTE_OLYMPUS_TAG_MANFOCUS: 480 case MNOTE_OLYMPUS_TAG_SHARPNESS: 481 case MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE: 482 case MNOTE_OLYMPUS_TAG_CONTRAST: 483 case MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID: 484 case MNOTE_OLYMPUS_TAG_CCDSCANMODE: 485 case MNOTE_SANYO_TAG_SEQUENTIALSHOT: 486 case MNOTE_SANYO_TAG_FOCUSMODE: 487 case MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE: 488 case MNOTE_SANYO_TAG_RESAVED: 489 case MNOTE_SANYO_TAG_CCDSENSITIVITY: 490 case MNOTE_SANYO_TAG_SCENESELECT: 491 case MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL: 492 CC (entry->components, 1, v, maxlen); 493 switch (entry->format) { 494 case EXIF_FORMAT_BYTE: 495 case EXIF_FORMAT_UNDEFINED: 496 vs = entry->data[0]; 497 break; 498 case EXIF_FORMAT_SHORT: 499 vs = exif_get_short(entry->data, entry->order); 500 break; 501 default: 502 vs = 0; 503 break; 504 } 505 /* search for the tag */ 506 for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++) 507 ; 508 if (!items[i].tag) { 509 snprintf (v, maxlen, _("Internal error (unknown value %hi)"), vs); 510 break; 511 } 512 CF (entry->format, items[i].fmt, v, maxlen); 513 /* find the value */ 514 for (j = 0; items[i].elem[j].string && 515 (items[i].elem[j].index < vs); j++); 516 if (items[i].elem[j].index != vs) { 517 snprintf (v, maxlen, _("Unknown value %hi"), vs); 518 break; 519 } 520 strncpy (v, _(items[i].elem[j].string), maxlen); 521 break; 522 case MNOTE_OLYMPUS_TAG_NOISEREDUCTION: 523 case MNOTE_SANYO_TAG_WIDERANGE: 524 case MNOTE_SANYO_TAG_COLORADJUSTMENTMODE: 525 case MNOTE_SANYO_TAG_QUICKSHOT: 526 case MNOTE_SANYO_TAG_VOICEMEMO: 527 case MNOTE_SANYO_TAG_FLICKERREDUCE: 528 case MNOTE_SANYO_TAG_OPTICALZOOM: 529 case MNOTE_SANYO_TAG_DIGITALZOOM: 530 case MNOTE_SANYO_TAG_LIGHTSOURCESPECIAL: 531 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); 532 CC (entry->components, 1, v, maxlen); 533 vs = exif_get_short (entry->data, entry->order); 534 switch (vs) { 535 case 0: 536 strncpy (v, _("Off"), maxlen); 537 break; 538 case 1: 539 strncpy (v, _("On"), maxlen); 540 break; 541 default: 542 sprintf (buf, _("Unknown %hu"), vs); 543 strncat (v, buf, maxlen - strlen (v)); 544 break; 545 } 546 break; 547 case MNOTE_SANYO_TAG_SELFTIMER: 548 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); 549 CC (entry->components, 1, v, maxlen); 550 vs = exif_get_short (entry->data, entry->order); 551 switch (vs) { 552 case 0: 553 strncpy (v, _("Off"), maxlen); 554 break; 555 case 1: 556 strncpy (v, _("On"), maxlen); 557 break; 558 case 2: 559 strncpy (v, _("2 sec."), maxlen); 560 break; 561 default: 562 sprintf (buf, _("Unknown %hu"), vs); 563 strncat (v, buf, maxlen - strlen (v)); 564 break; 565 } 566 break; 567 case MNOTE_NIKON_TAG_LENS: 568 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen); 569 CC (entry->components, 4, v, maxlen); 570 { 571 double c,d; 572 unsigned long a,b; 573 vr = exif_get_rational (entry->data, entry->order); 574 a = R2L(vr); 575 vr = exif_get_rational (entry->data+8, entry->order); 576 b = R2L(vr); 577 vr = exif_get_rational (entry->data+16, entry->order); 578 c = R2D(vr); 579 vr = exif_get_rational (entry->data+24, entry->order); 580 d = R2D(vr); 581 snprintf (v, maxlen, "%ld-%ldmm 1:%3.1f - %3.1f",a,b,c,d); 582 } 583 break; 584 585 /* Olympus */ 586 case MNOTE_OLYMPUS_TAG_MODE: 587 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen); 588 CC (entry->components, 3, v, maxlen); 589 vl = exif_get_long (entry->data, entry->order); 590 switch (vl) { 591 case 0: 592 strncpy (v, _("Normal"), maxlen); 593 break; 594 case 1: 595 strncpy (v, _("Unknown"), maxlen); 596 break; 597 case 2: 598 strncpy (v, _("Fast"), maxlen); 599 break; 600 case 3: 601 strncpy (v, _("Panorama"), maxlen); 602 break; 603 default: 604 snprintf (v, maxlen, "%li", (long int) vl); 605 } 606 vl = exif_get_long (entry->data + 4, entry->order); 607 snprintf (buf, sizeof (buf), "/%li/", (long int) vl); 608 strncat (v, buf, maxlen - strlen (v)); 609 vl = exif_get_long (entry->data + 8, entry->order); 610 switch (vl) { 611 case 1: 612 strncat (v, _("Left to right"), maxlen - strlen (v)); 613 break; 614 case 2: 615 strncat (v, _("Right to left"), maxlen - strlen (v)); 616 break; 617 case 3: 618 strncat (v, _("Bottom to top"), maxlen - strlen (v)); 619 break; 620 case 4: 621 strncat (v, _("Top to bottom"), maxlen - strlen (v)); 622 break; 623 default: 624 snprintf (buf, sizeof (buf), "%li", 625 (long int) vl); 626 strncat (v, buf, maxlen - strlen (v)); 627 } 628 break; 629 case MNOTE_OLYMPUS_TAG_LENSDISTORTION: 630 if (entry->format == EXIF_FORMAT_SHORT) { 631 /* Epson uses a single SHORT here */ 632 CC (entry->components, 1, v, maxlen); 633 vs = exif_get_short (entry->data, entry->order); 634 sprintf (buf, "%hu", vs); 635 strncat (v, buf, maxlen - strlen (v)); 636 } else { 637 /* Others use an array of SSHORT here */ 638 CC (entry->components, 6, v, maxlen); 639 CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen); 640 for (i=0; i < (int)entry->components; ++i) { 641 vss = exif_get_sshort (entry->data+2*i, entry->order); 642 sprintf (buf, "%hd ", vss); 643 strncat (v, buf, maxlen - strlen (v)); 644 } 645 } 646 break; 647 case MNOTE_OLYMPUS_TAG_COLORCONTROL: 648 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); 649 CC (entry->components, 6, v, maxlen); 650 for (i=0; i < (int)entry->components; ++i) { 651 vs = exif_get_short (entry->data+2*i, entry->order); 652 sprintf (buf, "%hu ", vs); 653 strncat (v, buf, maxlen - strlen (v)); 654 } 655 break; 656 case MNOTE_OLYMPUS_TAG_VERSION: 657 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen); 658 CC2 (entry->components, 5, 8, v, maxlen); 659 strncpy (v, (char *)entry->data, MIN (maxlen, entry->size)); 660 break; 661 case MNOTE_OLYMPUS_TAG_SERIALNUMBER2: 662 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen); 663 strncpy (v, (char *)entry->data, MIN (maxlen, entry->size)); 664 break; 665 case MNOTE_OLYMPUS_TAG_INFO: 666 CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen); 667 CC2 (entry->components, 52, 60, v, maxlen); 668 strncpy (v, (char *)entry->data, MIN (maxlen, entry->size)); 669 break; 670 case MNOTE_OLYMPUS_TAG_ID: 671 CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen); 672 CC (entry->components, 32, v, maxlen); 673 strncpy (v, (char *)entry->data, MIN (maxlen, entry->size)); 674 break; 675 case MNOTE_OLYMPUS_TAG_UNKNOWN_4: 676 CF (entry->format, EXIF_FORMAT_LONG, v, maxlen); 677 CC (entry->components, 30, v, maxlen); 678 for (i=0; i < (int)entry->components; ++i) { 679 vl = exif_get_long (entry->data+4*i, entry->order); 680 sprintf (buf, "%lu ", (unsigned long)vl); 681 strncat (v, buf, maxlen - strlen (v)); 682 } 683 break; 684 case MNOTE_OLYMPUS_TAG_FOCUSDIST: 685 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen); 686 CC (entry->components, 1, v, maxlen); 687 vr = exif_get_rational (entry->data, entry->order); 688 if (!vr.numerator || !vr.denominator) { 689 strncpy (v, _("Unknown"), maxlen); 690 } 691 else { 692 unsigned long tmp = vr.numerator / vr.denominator; 693 snprintf (v, maxlen, "%li mm", tmp); 694 } 695 break; 696 case MNOTE_OLYMPUS_TAG_WBALANCE: 697 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); 698 CC (entry->components, 2, v, maxlen); 699 vs = exif_get_short (entry->data, entry->order); 700 switch (vs) { 701 case 1: 702 strncpy (v, _("Automatic"), maxlen); 703 break; 704 case 2: 705 { 706 ExifShort v2 = exif_get_short (entry->data + 2, entry->order); 707 unsigned long colorTemp = 0; 708 switch (v2) { 709 case 2: 710 colorTemp = 3000; 711 break; 712 case 3: 713 colorTemp = 3700; 714 break; 715 case 4: 716 colorTemp = 4000; 717 break; 718 case 5: 719 colorTemp = 4500; 720 break; 721 case 6: 722 colorTemp = 5500; 723 break; 724 case 7: 725 colorTemp = 6500; 726 break; 727 case 9: 728 colorTemp = 7500; 729 break; 730 } 731 if (colorTemp) { 732 snprintf (v, maxlen, _("Manual: %liK"), colorTemp); 733 } 734 else { 735 strncpy (v, _("Manual: unknown"), maxlen); 736 } 737 738 } 739 break; 740 case 3: 741 strncpy (v, _("One-touch"), maxlen); 742 break; 743 default: 744 strncpy (v, _("Unknown"), maxlen); 745 break; 746 } 747 break; 748 case MNOTE_OLYMPUS_TAG_REDBALANCE: 749 case MNOTE_OLYMPUS_TAG_BLUEBALANCE: 750 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); 751 CC (entry->components, 2, v, maxlen); 752 vs = exif_get_short (entry->data, entry->order); 753 snprintf (v, maxlen, "%hu ", vs); 754 vs = exif_get_short (entry->data + 2, entry->order); 755 sprintf (buf, "%hu", vs); 756 strncat (v, buf, maxlen - strlen (v)); 757 break; 758 case MNOTE_OLYMPUS_TAG_BLACKLEVEL: 759 case MNOTE_NIKON_TAG_IMAGEBOUNDARY: 760 CC (entry->components, 4, v, maxlen); 761 /* Fall through to COLORMATRIX */ 762 case MNOTE_OLYMPUS_TAG_COLORMATRIX: 763 CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); 764 if (entry->tag == MNOTE_OLYMPUS_TAG_COLORMATRIX) 765 CC (entry->components, 9, v, maxlen); 766 for (i=0; i < (int)entry->components; ++i) { 767 vs = exif_get_short (entry->data+2*i, entry->order); 768 sprintf (buf, "%hu ", vs); 769 strncat (v, buf, maxlen - strlen (v)); 770 } 771 break; 772 case MNOTE_NIKON1_TAG_FOCUS: 773 case MNOTE_NIKON_TAG_DIGITALZOOM: 774 case MNOTE_NIKON1_TAG_DIGITALZOOM: 775 case MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL: 776 CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen); 777 /* Fall through to default handler for display */ 778 default: 779 switch (entry->format) { 780 case EXIF_FORMAT_ASCII: 781 strncpy (v, (char *)entry->data, MIN (maxlen, entry->size)); 782 break; 783 case EXIF_FORMAT_SHORT: 784 CC (entry->components, 1, v, maxlen); 785 vs = exif_get_short (entry->data, entry->order); 786 snprintf (v, maxlen, "%hu", vs); 787 break; 788 case EXIF_FORMAT_LONG: 789 CC (entry->components, 1, v, maxlen); 790 vl = exif_get_long (entry->data, entry->order); 791 snprintf (v, maxlen, "%li", (long int) vl); 792 break; 793 case EXIF_FORMAT_RATIONAL: 794 CC (entry->components, 1, v, maxlen); 795 vr = exif_get_rational (entry->data, entry->order); 796 if (!vr.denominator) { 797 strncpy (v, _("Infinite"), maxlen); 798 } else { 799 r = R2D(vr); 800 snprintf (v, maxlen, "%2.3f", r); 801 } 802 break; 803 case EXIF_FORMAT_SRATIONAL: 804 CC (entry->components, 1, v, maxlen); 805 vsr = exif_get_srational (entry->data, entry->order); 806 if (!vsr.denominator) { 807 strncpy (v, _("Infinite"), maxlen); 808 } else { 809 r = R2D(vsr); 810 snprintf (v, maxlen, "%2.3f", r); 811 } 812 break; 813 case EXIF_FORMAT_UNDEFINED: 814 default: 815 snprintf (v, maxlen, _("%i bytes unknown data: "), 816 entry->size); 817 for (i = 0; i < (int)entry->size; i++) { 818 sprintf (buf, "%02x", entry->data[i]); 819 strncat (v, buf, maxlen - strlen (v)); 820 } 821 break; 822 } 823 break; 824 } 825 826 return (v); 827 } 828