From: Jan P. <pa...@us...> - 2007-05-15 18:23:36
|
Update of /cvsroot/libexif/libexif/libexif In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv3381 Modified Files: exif-entry.c exif-tag.c exif-tag.h exif-utils.c exif-utils.h Log Message: Windows XP Explorer writes Title, Comment, Author, Metadata, Keywords, and Subject metadata into proprietary UTF16-encoded tags 0x9c9b-0x9c9f in IFD0. We now recognize them, exif_entry_get_value returns their value converted to UTF8. BTW, Explorer corrupts makernote using offsets relative to IFD0... Index: exif-utils.h =================================================================== RCS file: /cvsroot/libexif/libexif/libexif/exif-utils.h,v retrieving revision 1.15 retrieving revision 1.16 diff -u -p -d -r1.15 -r1.16 --- exif-utils.h 3 Oct 2006 19:41:36 -0000 1.15 +++ exif-utils.h 15 May 2007 18:23:28 -0000 1.16 @@ -65,6 +65,8 @@ void exif_set_rational (unsigned char * void exif_set_srational (unsigned char *b, ExifByteOrder order, ExifSRational value); +void exif_convert_utf16_to_utf8 (char *out, const unsigned short *in, int maxlen); + /* Please do not use this function outside of the library. */ void exif_array_set_byte_order (ExifFormat, unsigned char *, unsigned int, ExifByteOrder o_orig, ExifByteOrder o_new); Index: exif-tag.h =================================================================== RCS file: /cvsroot/libexif/libexif/libexif/exif-tag.h,v retrieving revision 1.14 retrieving revision 1.15 diff -u -p -d -r1.14 -r1.15 --- exif-tag.h 30 Apr 2005 00:55:42 -0000 1.14 +++ exif-tag.h 15 May 2007 18:23:28 -0000 1.15 @@ -107,6 +107,11 @@ typedef enum { EXIF_TAG_SUB_SEC_TIME = 0x9290, EXIF_TAG_SUB_SEC_TIME_ORIGINAL = 0x9291, EXIF_TAG_SUB_SEC_TIME_DIGITIZED = 0x9292, + EXIF_TAG_XP_TITLE = 0x9c9b, + EXIF_TAG_XP_COMMENT = 0x9c9c, + EXIF_TAG_XP_AUTHOR = 0x9c9d, + EXIF_TAG_XP_KEYWORDS = 0x9c9e, + EXIF_TAG_XP_SUBJECT = 0x9c9f, EXIF_TAG_FLASH_PIX_VERSION = 0xa000, EXIF_TAG_COLOR_SPACE = 0xa001, EXIF_TAG_PIXEL_X_DIMENSION = 0xa002, Index: exif-tag.c =================================================================== RCS file: /cvsroot/libexif/libexif/libexif/exif-tag.c,v retrieving revision 1.30 retrieving revision 1.31 diff -u -p -d -r1.30 -r1.31 --- exif-tag.c 13 Feb 2006 07:31:52 -0000 1.30 +++ exif-tag.c 15 May 2007 18:23:28 -0000 1.31 @@ -486,6 +486,16 @@ static struct { N_("A tag used to record fractions of seconds for the " "<DateTimeDigitized> tag."), { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_XP_TITLE, "XPTitle", N_("XP Title"), "", + { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_XP_COMMENT, "XPComment", N_("XP Comment"), "", + { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_XP_AUTHOR, "XPAuthor", N_("XP Author"), "", + { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_XP_KEYWORDS, "XPKeywords", N_("XP Keywords"), "", + { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_XP_SUBJECT, "XPSubject", N_("XP Subject"), "", + { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, {EXIF_TAG_FLASH_PIX_VERSION, "FlashPixVersion", "FlashPixVersion", N_("The FlashPix format version supported by a FPXR file."), { ESL_NNNN, ESL_NNNN, ESL_MMMM, ESL_NNNN, ESL_NNNN } }, Index: exif-utils.c =================================================================== RCS file: /cvsroot/libexif/libexif/libexif/exif-utils.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -p -d -r1.11 -r1.12 --- exif-utils.c 31 Mar 2005 12:24:31 -0000 1.11 +++ exif-utils.c 15 May 2007 18:23:28 -0000 1.12 @@ -212,3 +212,40 @@ exif_set_srational (unsigned char *buf, exif_set_slong (buf, order, value.numerator); exif_set_slong (buf + 4, order, value.denominator); } + +void +exif_convert_utf16_to_utf8 (char *out, const unsigned short *in, int maxlen) +{ + /* This function converts rather UCS2 than UTF16 to UTF8 */ + if (maxlen <= 0) { + return; + } + while (*in) { + if (*in < 0x80) { + if (maxlen > 1) { + *out++ = (char)*in++; + maxlen--; + } else { + break; + } + } else if (*in < 0x800) { + if (maxlen > 2) { + *out++ = ((*in >> 6) & 0x1F) | 0xC0; + *out++ = (*in++ & 0x3F) | 0x80; + maxlen -= 2; + } else { + break; + } + } else { + if (maxlen > 2) { + *out++ = ((*in >> 12) & 0x0F) | 0xE0; + *out++ = ((*in >> 6) & 0x3F) | 0x80; + *out++ = (*in++ & 0x3F) | 0x80; + maxlen -= 3; + } else { + break; + } + } + } + *out = 0; +} \ No newline at end of file Index: exif-entry.c =================================================================== RCS file: /cvsroot/libexif/libexif/libexif/exif-entry.c,v retrieving revision 1.100 retrieving revision 1.101 diff -u -p -d -r1.100 -r1.101 --- exif-entry.c 13 May 2007 19:24:01 -0000 1.100 +++ exif-entry.c 15 May 2007 18:23:28 -0000 1.101 @@ -711,16 +711,16 @@ exif_entry_get_value (ExifEntry *e, char (float) v_rat.denominator); break; case EXIF_TAG_APERTURE_VALUE: - case EXIF_TAG_MAX_APERTURE_VALUE: + case EXIF_TAG_MAX_APERTURE_VALUE: CF (e, EXIF_FORMAT_RATIONAL, val, maxlen); CC (e, 1, val, maxlen); v_rat = exif_get_rational (e->data, o); if (!v_rat.denominator) return val; - d = (double) v_rat.numerator / (double) v_rat.denominator; - snprintf (val, maxlen, _("%.02f EV"), d); - snprintf (b, sizeof (b), _(" (f/%.01f)"), pow (2, d / 2.)); - if (maxlen > strlen (val) + strlen (b)) - strncat (val, b, maxlen - strlen (val) - 1); + d = (double) v_rat.numerator / (double) v_rat.denominator; + snprintf (val, maxlen, _("%.02f EV"), d); + snprintf (b, sizeof (b), _(" (f/%.01f)"), pow (2, d / 2.)); + if (maxlen > strlen (val) + strlen (b)) + strncat (val, b, maxlen - strlen (val) - 1); break; case EXIF_TAG_FOCAL_LENGTH: CF (e, EXIF_FORMAT_RATIONAL, val, maxlen); @@ -785,8 +785,8 @@ exif_entry_get_value (ExifEntry *e, char CC (e, 1, val, maxlen); v_srat = exif_get_srational (e->data, o); if (!v_srat.denominator) return val; - d = (double) v_srat.numerator / (double) v_srat.denominator; - snprintf (val, maxlen, _("%.02f EV"), d); + d = (double) v_srat.numerator / (double) v_srat.denominator; + snprintf (val, maxlen, _("%.02f EV"), d); snprintf (b, sizeof (b), " (APEX: %i)", (int) pow (sqrt(2), d)); if (maxlen > strlen (val) + strlen (b)) strncat (val, b, maxlen - strlen (val) - 1); @@ -804,13 +804,13 @@ exif_entry_get_value (ExifEntry *e, char CF (e, EXIF_FORMAT_SRATIONAL, val, maxlen); CC (e, 1, val, maxlen); v_srat = exif_get_srational (e->data, o); - if (!v_srat.denominator) return val; - d = (double) v_srat.numerator / (double) v_srat.denominator; - snprintf (val, maxlen, _("%.02f EV"), d); - snprintf (b, sizeof (b), _(" (%.02f cd/m^2)"), - 1. / (M_PI * 0.3048 * 0.3048) * pow (2, d)); - if (maxlen > strlen (val) + strlen (b)) - strncat (val, b, maxlen - strlen (val) - 1); + if (!v_srat.denominator) return val; + d = (double) v_srat.numerator / (double) v_srat.denominator; + snprintf (val, maxlen, _("%.02f EV"), d); + snprintf (b, sizeof (b), _(" (%.02f cd/m^2)"), + 1. / (M_PI * 0.3048 * 0.3048) * pow (2, d)); + if (maxlen > strlen (val) + strlen (b)) + strncat (val, b, maxlen - strlen (val) - 1); break; case EXIF_TAG_FILE_SOURCE: CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen); @@ -843,8 +843,8 @@ exif_entry_get_value (ExifEntry *e, char CC (e, 1, val, maxlen); v_srat = exif_get_srational (e->data, o); if (!v_srat.denominator) return val; - d = (double) v_srat.numerator / (double) v_srat.denominator; - snprintf (val, maxlen, _("%.02f EV"), d); + d = (double) v_srat.numerator / (double) v_srat.denominator; + snprintf (val, maxlen, _("%.02f EV"), d); break; case EXIF_TAG_YCBCR_SUB_SAMPLING: CF (e, EXIF_FORMAT_SHORT, val, maxlen); @@ -967,7 +967,15 @@ exif_entry_get_value (ExifEntry *e, char snprintf (val, maxlen, "%i", v_short); else strncpy (val, _(list[i].strings[j]), maxlen - 1); - break; + break; + case EXIF_TAG_XP_TITLE: + case EXIF_TAG_XP_COMMENT: + case EXIF_TAG_XP_AUTHOR: + case EXIF_TAG_XP_KEYWORDS: + case EXIF_TAG_XP_SUBJECT: + /* Warning! The texts are converted from UTF16 to UTF8 */ + exif_convert_utf16_to_utf8(val, (unsigned short*)e->data, MIN(maxlen, e->size)); + break; case EXIF_TAG_INTEROPERABILITY_VERSION: if (e->format == EXIF_FORMAT_UNDEFINED) { strncpy (val, (char *) e->data, MIN (maxlen, e->size)); |