From a5a74fecd321629f06e3517f075d3f2e18776e10 Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Sat, 20 Aug 2011 11:43:09 +0200 Subject: Added a unit test to verify that the type of an EXIF makernote tag is correctly set when extracted from an image. Currently failing (see https://bugs.launchpad.net/pyexiv2/+bug/781464). --- test/data/MD5SUMS | 1 + test/data/pentax-makernote.jpg | Bin 0 -> 47549 bytes test/exif.py | 25 ++++++++++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test/data/pentax-makernote.jpg 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 new file mode 100644 index 0000000..67638ab Binary files /dev/null and b/test/data/pentax-makernote.jpg differ diff --git a/test/exif.py b/test/exif.py index 918f100..7f45b4e 100644 --- a/test/exif.py +++ b/test/exif.py @@ -2,7 +2,7 @@ # ****************************************************************************** # -# Copyright (C) 2009-2010 Olivier Tilloy +# Copyright (C) 2009-2011 Olivier Tilloy # # This file is part of the pyexiv2 distribution. # @@ -27,6 +27,7 @@ import unittest from pyexiv2.exif import ExifTag, ExifValueError +from pyexiv2.metadata import ImageMetadata from pyexiv2.utils import make_fraction import datetime @@ -334,3 +335,25 @@ class TestExifTag(unittest.TestCase): value = '2 0 0 foo' self.failUnlessRaises(ValueError, tag._set_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') + + 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]) + -- cgit From a58c3fe66ae7f11d98e5ecfb9f6dd01f5ec1c5be Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Sat, 20 Aug 2011 11:43:50 +0200 Subject: Correctly extract the type of an EXIF tag when read from an image. --- src/exiv2wrapper.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/exiv2wrapper.cpp b/src/exiv2wrapper.cpp index ad37f57..071d916 100644 --- a/src/exiv2wrapper.cpp +++ b/src/exiv2wrapper.cpp @@ -1,6 +1,6 @@ // ***************************************************************************** /* - * Copyright (C) 2006-2010 Olivier Tilloy + * Copyright (C) 2006-2011 Olivier Tilloy * * This file is part of the pyexiv2 distribution. * @@ -553,7 +553,14 @@ ExifTag::ExifTag(const std::string& key, // (see https://bugs.launchpad.net/pyexiv2/+bug/684177). #if EXIV2_TEST_VERSION(0,21,0) Exiv2::ExifKey exifKey(key); - _type = Exiv2::TypeInfo::typeName(exifKey.defaultTypeId()); + if (_data != 0) + { + _type = _datum->typeName(); + } + else + { + _type = Exiv2::TypeInfo::typeName(exifKey.defaultTypeId()); + } _name = exifKey.tagName(); _label = exifKey.tagLabel(); _description = exifKey.tagDesc(); -- cgit From f241ae6e91572a2bcddb3a04d0937ff5ddf407c6 Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Sat, 20 Aug 2011 11:48:40 +0200 Subject: Check the integrity of the image before performing the actual test. --- test/exif.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/exif.py b/test/exif.py index 7f45b4e..5736562 100644 --- a/test/exif.py +++ b/test/exif.py @@ -30,6 +30,8 @@ from pyexiv2.exif import ExifTag, ExifValueError from pyexiv2.metadata import ImageMetadata from pyexiv2.utils import make_fraction +from testutils import CheckFileSum + import datetime @@ -348,6 +350,9 @@ class TestExifTag(unittest.TestCase): 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] -- cgit From 60d2410d5fbbfd039a418d87678a388952c4d95a Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Sat, 20 Aug 2011 11:55:08 +0200 Subject: Add some sanity checks on the types of the UserComment tags. Those tests currently fail, probably because the sample data is malformed. --- test/usercomment.py | 8 ++++++++ 1 file changed, 8 insertions(+) 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): -- cgit From 540db70d10def3cda4edd36ff175cd1af877241e Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Sat, 20 Aug 2011 12:04:56 +0200 Subject: Special case for the 'Comment' type. --- src/exiv2wrapper.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/exiv2wrapper.cpp b/src/exiv2wrapper.cpp index 071d916..0033b23 100644 --- a/src/exiv2wrapper.cpp +++ b/src/exiv2wrapper.cpp @@ -553,14 +553,14 @@ ExifTag::ExifTag(const std::string& key, // (see https://bugs.launchpad.net/pyexiv2/+bug/684177). #if EXIV2_TEST_VERSION(0,21,0) Exiv2::ExifKey exifKey(key); - if (_data != 0) + _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(); } - else - { - _type = Exiv2::TypeInfo::typeName(exifKey.defaultTypeId()); - } _name = exifKey.tagName(); _label = exifKey.tagLabel(); _description = exifKey.tagDesc(); -- cgit From 0d90a8a6a7339543b01f8548d330e279a2067ea6 Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Sat, 20 Aug 2011 12:15:11 +0200 Subject: Replicate the fix for type extraction when compiling against libexiv2 < 0.21. --- src/exiv2wrapper.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/exiv2wrapper.cpp b/src/exiv2wrapper.cpp index 0033b23..332b78f 100644 --- a/src/exiv2wrapper.cpp +++ b/src/exiv2wrapper.cpp @@ -573,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); -- cgit