Home | History | Annotate | Download | only in pentax
      1 /* mnote-pentax-entry.c
      2  *
      3  * Copyright (c) 2002 Lutz Mueller <lutz (at) 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 	ExifTag 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 	ExifTag 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 *
    308 mnote_pentax_entry_get_value (MnotePentaxEntry *entry,
    309 			      char *val, unsigned int maxlen)
    310 {
    311 	ExifLong vl;
    312 	ExifShort vs, vs2;
    313 	int i = 0, j = 0;
    314 
    315 	if (!entry) return (NULL);
    316 
    317 	memset (val, 0, maxlen);
    318 	maxlen--;
    319 
    320 	switch (entry->tag) {
    321 	  case MNOTE_PENTAX_TAG_MODE:
    322 	  case MNOTE_PENTAX_TAG_QUALITY:
    323 	  case MNOTE_PENTAX_TAG_FOCUS:
    324 	  case MNOTE_PENTAX_TAG_FLASH:
    325 	  case MNOTE_PENTAX_TAG_WHITE_BALANCE:
    326 	  case MNOTE_PENTAX_TAG_SHARPNESS:
    327 	  case MNOTE_PENTAX_TAG_CONTRAST:
    328 	  case MNOTE_PENTAX_TAG_SATURATION:
    329 	  case MNOTE_PENTAX_TAG_ISO_SPEED:
    330 	  case MNOTE_PENTAX_TAG_COLOR:
    331 	  case MNOTE_PENTAX2_TAG_MODE:
    332 	  case MNOTE_PENTAX2_TAG_QUALITY:
    333 	  case MNOTE_PENTAX2_TAG_FLASH_MODE:
    334 	  case MNOTE_PENTAX2_TAG_FOCUS_MODE:
    335 	  case MNOTE_PENTAX2_TAG_AFPOINT_SELECTED:
    336 	  case MNOTE_PENTAX2_TAG_AUTO_AFPOINT:
    337 	  case MNOTE_PENTAX2_TAG_WHITE_BALANCE:
    338 	  case MNOTE_PENTAX2_TAG_PICTURE_MODE:
    339 	  case MNOTE_PENTAX2_TAG_IMAGE_SIZE:
    340 	  case MNOTE_CASIO2_TAG_BESTSHOT_MODE:
    341 		CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
    342 		CC2 (entry->components, 1, 2, val, maxlen);
    343 		if (entry->components == 1) {
    344 			vs = exif_get_short (entry->data, entry->order);
    345 
    346 			/* search the tag */
    347 			for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++);
    348 			if (!items[i].tag) {
    349 				snprintf (val, maxlen,
    350 					  _("Internal error (unknown value %i)"), vs);
    351 			  	break;
    352 			}
    353 
    354 			/* find the value */
    355 			for (j = 0; items[i].elem[j].string &&
    356 			    (items[i].elem[j].index < vs); j++);
    357 			if (items[i].elem[j].index != vs) {
    358 				snprintf (val, maxlen,
    359 					  _("Internal error (unknown value %i)"), vs);
    360 				break;
    361 			}
    362 			strncpy (val, _(items[i].elem[j].string), maxlen);
    363 		} else {
    364 			/* Two-component values */
    365 			CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen);
    366 			CC2 (entry->components, 1, 2, val, maxlen);
    367 			vs = exif_get_short (entry->data, entry->order);
    368 			vs2 = exif_get_short (entry->data+2, entry->order) << 16;
    369 
    370 			/* search the tag */
    371 			for (i = 0; (items2[i].tag && items2[i].tag != entry->tag); i++);
    372 			if (!items2[i].tag) {
    373 				snprintf (val, maxlen,
    374 					  _("Internal error (unknown value %i %i)"), vs, vs2);
    375 			  	break;
    376 			}
    377 
    378 			/* find the value */
    379 			for (j = 0; items2[i].elem[j].string && ((items2[i].elem[j].index2 < vs2)
    380 				|| ((items2[i].elem[j].index2 == vs2) && (items2[i].elem[j].index1 < vs))); j++);
    381 			if ((items2[i].elem[j].index1 != vs) || (items2[i].elem[j].index2 != vs2)) {
    382 				snprintf (val, maxlen,
    383 					  _("Internal error (unknown value %i %i)"), vs, vs2);
    384 				break;
    385 			}
    386 			strncpy (val, _(items2[i].elem[j].string), maxlen);
    387 		}
    388 		break;
    389 
    390 	case MNOTE_PENTAX_TAG_ZOOM:
    391 		CF (entry->format, EXIF_FORMAT_LONG, val, maxlen);
    392 		CC (entry->components, 1, val, maxlen);
    393 		vl = exif_get_long (entry->data, entry->order);
    394 		snprintf (val, maxlen, "%li", (long int) vl);
    395 		break;
    396 	case MNOTE_PENTAX_TAG_PRINTIM:
    397 		CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
    398 		CC (entry->components, 124, val, maxlen);
    399 		snprintf (val, maxlen, _("%i bytes unknown data"),
    400 			entry->size);
    401 		break;
    402 	case MNOTE_PENTAX_TAG_TZ_CITY:
    403 	case MNOTE_PENTAX_TAG_TZ_DST:
    404 		CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
    405 		CC (entry->components, 4, val, maxlen);
    406 		strncpy (val, (char*)entry->data, MIN(maxlen, entry->size));
    407 		break;
    408 	case MNOTE_PENTAX2_TAG_DATE:
    409 		CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
    410 		CC (entry->components, 4, val, maxlen);
    411 		/* Note: format is UNDEFINED, not SHORT -> order is fixed: MOTOROLA */
    412 		vs = exif_get_short (entry->data, EXIF_BYTE_ORDER_MOTOROLA);
    413 		snprintf (val, maxlen, "%i:%02i:%02i", vs, entry->data[2], entry->data[3]);
    414 		break;
    415 	case MNOTE_PENTAX2_TAG_TIME:
    416 		CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen);
    417 		CC2 (entry->components, 3, 4, val, maxlen);
    418 		snprintf (val, maxlen, "%02i:%02i:%02i", entry->data[0], entry->data[1], entry->data[2]);
    419 		break;
    420 	default:
    421 		switch (entry->format) {
    422 		case EXIF_FORMAT_ASCII:
    423 		  strncpy (val, (char *)entry->data, MIN(maxlen, entry->size));
    424 		  break;
    425 		case EXIF_FORMAT_SHORT:
    426 		  {
    427 			const unsigned char *data = entry->data;
    428 		  	size_t k, len = strlen(val);
    429 		  	for(k=0; k<entry->components; k++) {
    430 				vs = exif_get_short (data, entry->order);
    431 				snprintf (val+len, maxlen-len, "%i ", vs);
    432 				len = strlen(val);
    433 				data += 2;
    434 			}
    435 		  }
    436 		  break;
    437 		case EXIF_FORMAT_LONG:
    438 		  {
    439 			const unsigned char *data = entry->data;
    440 		  	size_t k, len = strlen(val);
    441 		  	for(k=0; k<entry->components; k++) {
    442 				vl = exif_get_long (data, entry->order);
    443 				snprintf (val+len, maxlen-len, "%li", (long int) vl);
    444 				len = strlen(val);
    445 				data += 4;
    446 			}
    447 		  }
    448 		  break;
    449 		case EXIF_FORMAT_UNDEFINED:
    450 		default:
    451 		  snprintf (val, maxlen, _("%i bytes unknown data"),
    452 			  entry->size);
    453 		  break;
    454 		}
    455 		break;
    456 	}
    457 
    458 	return (val);
    459 }
    460