3
3
# ******************************************************************************
5
# Copyright (C) 2009-2011 Olivier Tilloy <olivier@tilloy.net>
5
# Copyright (C) 2009-2010 Olivier Tilloy <olivier@tilloy.net>
7
7
# This file is part of the pyexiv2 distribution.
29
29
from pyexiv2.exif import ExifTag, ExifValueError
30
from pyexiv2.metadata import ImageMetadata
31
from pyexiv2.utils import make_fraction
30
from pyexiv2.utils import Rational, Fraction
39
35
class TestExifTag(unittest.TestCase):
83
79
'2009:03:01 12:54:28')
84
80
self.assertEqual(tag._convert_to_string(datetime.date(2009, 03, 01)),
85
81
'2009:03:01 00:00:00')
86
self.assertEqual(tag._convert_to_string(datetime.datetime(1899, 12, 31, 23, 59, 59)),
87
'1899:12:31 23:59:59')
88
self.assertEqual(tag._convert_to_string(datetime.date(1899, 12, 31)),
89
'1899:12:31 00:00:00')
91
83
# Valid values: dates
92
84
tag = ExifTag('Exif.GPSInfo.GPSDateStamp')
93
85
self.assertEqual(tag.type, 'Ascii')
94
86
self.assertEqual(tag._convert_to_string(datetime.date(2009, 03, 01)),
96
self.assertEqual(tag._convert_to_string(datetime.date(1899, 12, 31)),
99
89
# Valid values: strings
100
90
tag = ExifTag('Exif.Image.Copyright')
145
135
tag = ExifTag('Exif.Photo.UserComment')
146
136
self.assertEqual(tag.type, 'Comment')
147
137
self.assertEqual(tag._convert_to_python('A comment'), 'A comment')
148
for charset in ('Ascii', 'Jis', 'Unicode', 'Undefined', 'InvalidCharsetId'):
149
self.assertEqual(tag._convert_to_python('charset="%s" A comment' % charset), 'A comment')
150
for charset in ('Ascii', 'Jis', 'Undefined', 'InvalidCharsetId'):
151
self.failIfEqual(tag._convert_to_python('charset="%s" déjà vu' % charset), u'déjà vu')
153
139
def test_convert_to_string_comment(self):
156
142
self.assertEqual(tag.type, 'Comment')
157
143
self.assertEqual(tag._convert_to_string('A comment'), 'A comment')
158
144
self.assertEqual(tag._convert_to_string(u'A comment'), 'A comment')
159
charsets = ('Ascii', 'Jis', 'Unicode', 'Undefined')
160
for charset in charsets:
161
tag.raw_value = 'charset="%s" foo' % charset
162
self.assertEqual(tag._convert_to_string('A comment'),
163
'charset="%s" A comment' % charset)
164
self.assertEqual(tag._convert_to_string('déjà vu'), 'déjà vu')
167
147
self.failUnlessRaises(ExifValueError, tag._convert_to_string, None)
271
251
tag = ExifTag('Exif.Image.XResolution')
272
252
self.assertEqual(tag.type, 'Rational')
273
self.assertEqual(tag._convert_to_python('5/3'), make_fraction(5, 3))
253
self.assertEqual(tag._convert_to_python('5/3'), Rational(5, 3))
276
256
self.failUnlessRaises(ExifValueError, tag._convert_to_python, 'invalid')
283
263
tag = ExifTag('Exif.Image.XResolution')
284
264
self.assertEqual(tag.type, 'Rational')
285
self.assertEqual(tag._convert_to_string(make_fraction(5, 3)), '5/3')
265
self.assertEqual(tag._convert_to_string(Rational(5, 3)), '5/3')
266
if Fraction is not None:
267
self.assertEqual(tag._convert_to_string(Fraction('1.6')), '8/5')
288
270
self.failUnlessRaises(ExifValueError, tag._convert_to_string, 'invalid')
289
271
self.failUnlessRaises(ExifValueError,
290
tag._convert_to_string, make_fraction(-5, 3))
272
tag._convert_to_string, Rational(-5, 3))
292
274
def test_convert_to_python_srational(self):
294
276
tag = ExifTag('Exif.Image.BaselineExposure')
295
277
self.assertEqual(tag.type, 'SRational')
296
self.assertEqual(tag._convert_to_python('5/3'), make_fraction(5, 3))
297
self.assertEqual(tag._convert_to_python('-5/3'), make_fraction(-5, 3))
278
self.assertEqual(tag._convert_to_python('5/3'), Rational(5, 3))
279
self.assertEqual(tag._convert_to_python('-5/3'), Rational(-5, 3))
300
282
self.failUnlessRaises(ExifValueError, tag._convert_to_python, 'invalid')
306
288
tag = ExifTag('Exif.Image.BaselineExposure')
307
289
self.assertEqual(tag.type, 'SRational')
308
self.assertEqual(tag._convert_to_string(make_fraction(5, 3)), '5/3')
309
self.assertEqual(tag._convert_to_string(make_fraction(-5, 3)), '-5/3')
290
self.assertEqual(tag._convert_to_string(Rational(5, 3)), '5/3')
291
self.assertEqual(tag._convert_to_string(Rational(-5, 3)), '-5/3')
292
if Fraction is not None:
293
self.assertEqual(tag._convert_to_string(Fraction('1.6')), '8/5')
294
self.assertEqual(tag._convert_to_string(Fraction('-1.6')), '-8/5')
312
297
self.failUnlessRaises(ExifValueError, tag._convert_to_string, 'invalid')
336
321
def test_set_raw_value_invalid(self):
337
322
tag = ExifTag('Exif.GPSInfo.GPSVersionID')
338
323
value = '2 0 0 foo'
339
self.failUnlessRaises(ValueError, setattr, tag, 'raw_value', value)
341
def test_makernote_types(self):
342
# Makernote tags not attached to an image have an Undefined type by
343
# default. When read from an existing image though, their type should be
344
# correctly set (see https://bugs.launchpad.net/pyexiv2/+bug/781464).
345
tag1 = ExifTag('Exif.Pentax.PreviewResolution')
346
tag1.raw_value = '640 480'
347
self.assertEqual(tag1.type, 'Undefined')
348
self.failUnlessRaises(ValueError, getattr, tag1, 'value')
349
tag2 = ExifTag('Exif.Pentax.CameraInfo')
350
tag2.raw_value = '76830 20070527 2 1 4228109'
351
self.assertEqual(tag2.type, 'Undefined')
352
self.failUnlessRaises(ValueError, getattr, tag2, 'value')
354
filepath = testutils.get_absolute_file_path(os.path.join('data', 'pentax-makernote.jpg'))
355
checksum = '646804b309a4a2d31feafe9bffc5d7f0'
356
self.assert_(testutils.CheckFileSum(filepath, checksum))
357
metadata = ImageMetadata(filepath)
359
tag1 = metadata[tag1.key]
360
self.assertEqual(tag1.type, 'Short')
361
self.assertEqual(tag1.value, [640, 480])
362
tag2 = metadata[tag2.key]
363
self.assertEqual(tag2.type, 'Long')
364
self.assertEqual(tag2.value, [76830L, 20070527L, 2L, 1L, 4228109L])
324
self.failUnlessRaises(ValueError, tag._set_raw_value, value)