3
3
from PIL import features
4
4
from PIL ._util import py3
5
5
6
+ from collections import namedtuple
6
7
from ctypes import c_float
7
8
import io
8
9
import logging
@@ -233,13 +234,32 @@ def test_additional_metadata(self):
233
234
TiffImagePlugin .WRITE_LIBTIFF = False
234
235
235
236
def test_custom_metadata (self ):
236
- custom = {
237
- 37000 : [4 , TiffTags .SHORT ],
238
- 37001 : [4.2 , TiffTags .RATIONAL ],
239
- 37002 : ['custom tag value' , TiffTags .ASCII ],
240
- 37003 : [u'custom tag value' , TiffTags .ASCII ],
241
- 37004 : [b'custom tag value' , TiffTags .BYTE ]
242
- }
237
+ tc = namedtuple ('test_case' , 'value,type,supported_by_default' )
238
+ custom = {37000 + k : v for k , v in enumerate ([
239
+ tc (4 , TiffTags .SHORT , True ),
240
+ tc (123456789 , TiffTags .LONG , True ),
241
+ tc (- 4 , TiffTags .SIGNED_BYTE , False ),
242
+ tc (- 4 , TiffTags .SIGNED_SHORT , False ),
243
+ tc (- 123456789 , TiffTags .SIGNED_LONG , False ),
244
+ tc (TiffImagePlugin .IFDRational (4 , 7 ), TiffTags .RATIONAL , True ),
245
+ tc (4.25 , TiffTags .FLOAT , True ),
246
+ tc (4.25 , TiffTags .DOUBLE , True ),
247
+ tc ('custom tag value' , TiffTags .ASCII , True ),
248
+ tc (u'custom tag value' , TiffTags .ASCII , True ),
249
+ tc (b'custom tag value' , TiffTags .BYTE , True ),
250
+ tc ((4 , 5 , 6 ), TiffTags .SHORT , True ),
251
+ tc ((123456789 , 9 , 34 , 234 , 219387 , 92432323 ), TiffTags .LONG , True ),
252
+ tc ((- 4 , 9 , 10 ), TiffTags .SIGNED_BYTE , False ),
253
+ tc ((- 4 , 5 , 6 ), TiffTags .SIGNED_SHORT , False ),
254
+ tc ((- 123456789 , 9 , 34 , 234 , 219387 , - 92432323 ),
255
+ TiffTags .SIGNED_LONG , False ),
256
+ tc ((4.25 , 5.25 ), TiffTags .FLOAT , True ),
257
+ tc ((4.25 , 5.25 ), TiffTags .DOUBLE , True ),
258
+ # array of TIFF_BYTE requires bytes instead of tuple for backwards
259
+ # compatibility
260
+ tc (bytes ([4 ]), TiffTags .BYTE , True ),
261
+ tc (bytes ((4 , 9 , 10 )), TiffTags .BYTE , True ),
262
+ ])}
243
263
244
264
libtiff_version = TiffImagePlugin ._libtiff_version ()
245
265
@@ -260,8 +280,13 @@ def check_tags(tiffinfo):
260
280
reloaded = Image .open (out )
261
281
for tag , value in tiffinfo .items ():
262
282
reloaded_value = reloaded .tag_v2 [tag ]
263
- if isinstance (reloaded_value , TiffImagePlugin .IFDRational ):
264
- reloaded_value = float (reloaded_value )
283
+ if (
284
+ isinstance (reloaded_value , TiffImagePlugin .IFDRational )
285
+ and libtiff
286
+ ):
287
+ # libtiff does not support real RATIONALS
288
+ self .assertAlmostEqual (float (reloaded_value ), float (value ))
289
+ continue
265
290
266
291
if libtiff and isinstance (value , bytes ):
267
292
value = value .decode ()
@@ -271,12 +296,14 @@ def check_tags(tiffinfo):
271
296
# Test with types
272
297
ifd = TiffImagePlugin .ImageFileDirectory_v2 ()
273
298
for tag , tagdata in custom .items ():
274
- ifd [tag ] = tagdata [ 0 ]
275
- ifd .tagtype [tag ] = tagdata [ 1 ]
299
+ ifd [tag ] = tagdata . value
300
+ ifd .tagtype [tag ] = tagdata . type
276
301
check_tags (ifd )
277
302
278
- # Test without types
279
- check_tags ({tag : tagdata [0 ] for tag , tagdata in custom .items ()})
303
+ # Test without types. This only works for some types, int for example are
304
+ # always encoded as LONG and not SIGNED_LONG.
305
+ check_tags ({tag : tagdata .value for tag , tagdata in custom .items ()
306
+ if tagdata .supported_by_default })
280
307
TiffImagePlugin .WRITE_LIBTIFF = False
281
308
282
309
def test_int_dpi (self ):
0 commit comments