diff options
author | Olivier Tilloy <olivier@tilloy.net> | 2011-08-22 08:31:19 +0200 |
---|---|---|
committer | Olivier Tilloy <olivier@tilloy.net> | 2011-08-22 08:31:19 +0200 |
commit | 34f55f38b2bbb18843b53c6804f4410d9a3f1dc1 (patch) | |
tree | 1a3438d7dd8cbc31139a67ec228027dc474bfdb6 | |
parent | 39ce84eb5a85f32a2f2521a7ba7d3451a1244584 (diff) | |
parent | 0d90a8a6a7339543b01f8548d330e279a2067ea6 (diff) | |
download | pyexiv2-34f55f38b2bbb18843b53c6804f4410d9a3f1dc1.tar.gz |
Correctly extract the type of an EXIF tag when read from an image.
-rw-r--r-- | src/exiv2wrapper.cpp | 16 | ||||
-rw-r--r-- | test/data/MD5SUMS | 1 | ||||
-rw-r--r-- | test/data/pentax-makernote.jpg | bin | 0 -> 47549 bytes | |||
-rw-r--r-- | test/exif.py | 28 | ||||
-rw-r--r-- | test/usercomment.py | 8 |
5 files changed, 52 insertions, 1 deletions
diff --git a/src/exiv2wrapper.cpp b/src/exiv2wrapper.cpp index ad37f57..332b78f 100644 --- a/src/exiv2wrapper.cpp +++ b/src/exiv2wrapper.cpp @@ -1,6 +1,6 @@ // ***************************************************************************** /* - * Copyright (C) 2006-2010 Olivier Tilloy <olivier@tilloy.net> + * Copyright (C) 2006-2011 Olivier Tilloy <olivier@tilloy.net> * * This file is part of the pyexiv2 distribution. * @@ -554,6 +554,13 @@ ExifTag::ExifTag(const std::string& key, #if EXIV2_TEST_VERSION(0,21,0) Exiv2::ExifKey exifKey(key); _type = Exiv2::TypeInfo::typeName(exifKey.defaultTypeId()); + // Where available, extract the type from the metadata, it is more reliable + // than static type information. The exception is for user comments, for + // which we’d rather keep the 'Comment' type instead of 'Undefined'. + if ((_data != 0) && (_type != "Comment")) + { + _type = _datum->typeName(); + } _name = exifKey.tagName(); _label = exifKey.tagLabel(); _description = exifKey.tagDesc(); @@ -566,6 +573,13 @@ ExifTag::ExifTag(const std::string& key, const uint16_t tag = _datum->tag(); const Exiv2::IfdId ifd = _datum->ifdId(); _type = Exiv2::TypeInfo::typeName(Exiv2::ExifTags::tagType(tag, ifd)); + // Where available, extract the type from the metadata, it is more reliable + // than static type information. The exception is for user comments, for + // which we’d rather keep the 'Comment' type instead of 'Undefined'. + if ((_data != 0) && (_type != "Comment")) + { + _type = _datum->typeName(); + } _name = Exiv2::ExifTags::tagName(tag, ifd); _label = Exiv2::ExifTags::tagLabel(tag, ifd); _description = Exiv2::ExifTags::tagDesc(tag, ifd); diff --git a/test/data/MD5SUMS b/test/data/MD5SUMS index c664932..c692790 100644 --- a/test/data/MD5SUMS +++ b/test/data/MD5SUMS @@ -1,5 +1,6 @@ e8525211f62a0944db9072f73750258c empty.jpg 64d4b7eab1e78f1f6bfb3c966e99eef2 exiv2-bug540.jpg +646804b309a4a2d31feafe9bffc5d7f0 pentax-makernote.jpg c066958457c685853293058f9bf129c1 smiley1.jpg ad29ac65fb6f63c8361aaed6cb02f8c7 usercomment-ascii.jpg 13b7cc09129a8677f2cf18634f5abd3c usercomment-unicode-ii.jpg diff --git a/test/data/pentax-makernote.jpg b/test/data/pentax-makernote.jpg Binary files differnew file mode 100644 index 0000000..67638ab --- /dev/null +++ b/test/data/pentax-makernote.jpg diff --git a/test/exif.py b/test/exif.py index c9cc609..2bfbc67 100644 --- a/test/exif.py +++ b/test/exif.py @@ -27,8 +27,11 @@ import unittest from pyexiv2.exif import ExifTag, ExifValueError +from pyexiv2.metadata import ImageMetadata from pyexiv2.utils import make_fraction +from testutils import CheckFileSum + import datetime @@ -334,3 +337,28 @@ class TestExifTag(unittest.TestCase): value = '2 0 0 foo' self.failUnlessRaises(ValueError, setattr, tag, 'raw_value', value) + def test_makernote_types(self): + # Makernote tags not attached to an image have an Undefined type by + # default. When read from an existing image though, their type should be + # correctly set (see https://bugs.launchpad.net/pyexiv2/+bug/781464). + tag1 = ExifTag('Exif.Pentax.PreviewResolution') + tag1.raw_value = '640 480' + self.assertEqual(tag1.type, 'Undefined') + self.failUnlessRaises(ValueError, getattr, tag1, 'value') + tag2 = ExifTag('Exif.Pentax.CameraInfo') + tag2.raw_value = '76830 20070527 2 1 4228109' + self.assertEqual(tag2.type, 'Undefined') + self.failUnlessRaises(ValueError, getattr, tag2, 'value') + + filename = 'test/data/pentax-makernote.jpg' + checksum = '646804b309a4a2d31feafe9bffc5d7f0' + self.assert_(CheckFileSum(filename, checksum)) + metadata = ImageMetadata('test/data/pentax-makernote.jpg') + metadata.read() + tag1 = metadata[tag1.key] + self.assertEqual(tag1.type, 'Short') + self.assertEqual(tag1.value, [640, 480]) + tag2 = metadata[tag2.key] + self.assertEqual(tag2.type, 'Long') + self.assertEqual(tag2.value, [76830L, 20070527L, 2L, 1L, 4228109L]) + diff --git a/test/usercomment.py b/test/usercomment.py index cc8ff1a..a9b4774 100644 --- a/test/usercomment.py +++ b/test/usercomment.py @@ -59,24 +59,28 @@ class TestUserCommentReadWrite(unittest.TestCase): def test_read_ascii(self): m = self._read_image('usercomment-ascii.jpg') tag = m['Exif.Photo.UserComment'] + self.assertEqual(tag.type, 'Comment') self.assertEqual(tag.raw_value, 'charset="Ascii" deja vu') self.assertEqual(tag.value, u'deja vu') def test_read_unicode_little_endian(self): m = self._read_image('usercomment-unicode-ii.jpg') tag = m['Exif.Photo.UserComment'] + self.assertEqual(tag.type, 'Comment') self.assertEqual(tag.raw_value, 'charset="Unicode" %s' % self._expected_raw_value('ii', 'déjà vu')) self.assertEqual(tag.value, u'déjà vu') def test_read_unicode_big_endian(self): m = self._read_image('usercomment-unicode-mm.jpg') tag = m['Exif.Photo.UserComment'] + self.assertEqual(tag.type, 'Comment') self.assertEqual(tag.raw_value, 'charset="Unicode" %s' % self._expected_raw_value('mm', 'déjà vu')) self.assertEqual(tag.value, u'déjà vu') def test_write_ascii(self): m = self._read_image('usercomment-ascii.jpg') tag = m['Exif.Photo.UserComment'] + self.assertEqual(tag.type, 'Comment') tag.value = 'foo bar' self.assertEqual(tag.raw_value, 'charset="Ascii" foo bar') self.assertEqual(tag.value, u'foo bar') @@ -84,6 +88,7 @@ class TestUserCommentReadWrite(unittest.TestCase): def test_write_unicode_over_ascii(self): m = self._read_image('usercomment-ascii.jpg') tag = m['Exif.Photo.UserComment'] + self.assertEqual(tag.type, 'Comment') tag.value = u'déjà vu' self.assertEqual(tag.raw_value, 'déjà vu') self.assertEqual(tag.value, u'déjà vu') @@ -91,6 +96,7 @@ class TestUserCommentReadWrite(unittest.TestCase): def test_write_unicode_little_endian(self): m = self._read_image('usercomment-unicode-ii.jpg') tag = m['Exif.Photo.UserComment'] + self.assertEqual(tag.type, 'Comment') tag.value = u'DÉJÀ VU' self.assertEqual(tag.raw_value, 'charset="Unicode" %s' % self._expected_raw_value('ii', 'DÉJÀ VU')) self.assertEqual(tag.value, u'DÉJÀ VU') @@ -98,6 +104,7 @@ class TestUserCommentReadWrite(unittest.TestCase): def test_write_unicode_big_endian(self): m = self._read_image('usercomment-unicode-mm.jpg') tag = m['Exif.Photo.UserComment'] + self.assertEqual(tag.type, 'Comment') tag.value = u'DÉJÀ VU' self.assertEqual(tag.raw_value, 'charset="Unicode" %s' % self._expected_raw_value('mm', 'DÉJÀ VU')) self.assertEqual(tag.value, u'DÉJÀ VU') @@ -125,6 +132,7 @@ class TestUserCommentAdd(unittest.TestCase): metadata.read() self.assert_(key in metadata.exif_keys) tag = metadata[key] + self.assertEqual(tag.type, 'Comment') self.assertEqual(tag.value, value) def test_add_comment_ascii(self): |