mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 09:57:43 +03:00 
			
		
		
		
	Merge pull request #832 from hugovk/IptcImagePlugin
Tests for IptcImagePlugin.py
This commit is contained in:
		
						commit
						ed3016a08a
					
				| 
						 | 
					@ -21,7 +21,8 @@ __version__ = "0.3"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PIL import Image, ImageFile, _binary
 | 
					from PIL import Image, ImageFile, _binary
 | 
				
			||||||
import os, tempfile
 | 
					import os
 | 
				
			||||||
 | 
					import tempfile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
i8 = _binary.i8
 | 
					i8 = _binary.i8
 | 
				
			||||||
i16 = _binary.i16be
 | 
					i16 = _binary.i16be
 | 
				
			||||||
| 
						 | 
					@ -35,17 +36,20 @@ COMPRESSION = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PAD = o8(0) * 4
 | 
					PAD = o8(0) * 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Helpers
 | 
					# Helpers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def i(c):
 | 
					def i(c):
 | 
				
			||||||
    return i32((PAD + c)[-4:])
 | 
					    return i32((PAD + c)[-4:])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def dump(c):
 | 
					def dump(c):
 | 
				
			||||||
    for i in c:
 | 
					    for i in c:
 | 
				
			||||||
        print("%02x" % i8(i), end=' ')
 | 
					        print("%02x" % i8(i), end=' ')
 | 
				
			||||||
    print()
 | 
					    print()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##
 | 
					##
 | 
				
			||||||
# Image plugin for IPTC/NAA datastreams.  To read IPTC/NAA fields
 | 
					# Image plugin for IPTC/NAA datastreams.  To read IPTC/NAA fields
 | 
				
			||||||
# from TIFF and JPEG files, use the <b>getiptcinfo</b> function.
 | 
					# from TIFF and JPEG files, use the <b>getiptcinfo</b> function.
 | 
				
			||||||
| 
						 | 
					@ -84,35 +88,13 @@ class IptcImageFile(ImageFile.ImageFile):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return tag, size
 | 
					        return tag, size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _is_raw(self, offset, size):
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
        # check if the file can be mapped
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # DISABLED: the following only slows things down...
 | 
					 | 
				
			||||||
        return 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.fp.seek(offset)
 | 
					 | 
				
			||||||
        t, sz = self.field()
 | 
					 | 
				
			||||||
        if sz != size[0]:
 | 
					 | 
				
			||||||
            return 0
 | 
					 | 
				
			||||||
        y = 1
 | 
					 | 
				
			||||||
        while True:
 | 
					 | 
				
			||||||
            self.fp.seek(sz, 1)
 | 
					 | 
				
			||||||
            t, s = self.field()
 | 
					 | 
				
			||||||
            if t != (8, 10):
 | 
					 | 
				
			||||||
                break
 | 
					 | 
				
			||||||
            if s != sz:
 | 
					 | 
				
			||||||
                return 0
 | 
					 | 
				
			||||||
            y += 1
 | 
					 | 
				
			||||||
        return y == size[1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _open(self):
 | 
					    def _open(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # load descriptive fields
 | 
					        # load descriptive fields
 | 
				
			||||||
        while True:
 | 
					        while True:
 | 
				
			||||||
            offset = self.fp.tell()
 | 
					            offset = self.fp.tell()
 | 
				
			||||||
            tag, size = self.field()
 | 
					            tag, size = self.field()
 | 
				
			||||||
            if not tag or tag == (8,10):
 | 
					            if not tag or tag == (8, 10):
 | 
				
			||||||
                break
 | 
					                break
 | 
				
			||||||
            if size:
 | 
					            if size:
 | 
				
			||||||
                tagdata = self.fp.read(size)
 | 
					                tagdata = self.fp.read(size)
 | 
				
			||||||
| 
						 | 
					@ -129,10 +111,10 @@ class IptcImageFile(ImageFile.ImageFile):
 | 
				
			||||||
            # print tag, self.info[tag]
 | 
					            # print tag, self.info[tag]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # mode
 | 
					        # mode
 | 
				
			||||||
        layers = i8(self.info[(3,60)][0])
 | 
					        layers = i8(self.info[(3, 60)][0])
 | 
				
			||||||
        component = i8(self.info[(3,60)][1])
 | 
					        component = i8(self.info[(3, 60)][1])
 | 
				
			||||||
        if (3,65) in self.info:
 | 
					        if (3, 65) in self.info:
 | 
				
			||||||
            id = i8(self.info[(3,65)][0])-1
 | 
					            id = i8(self.info[(3, 65)][0])-1
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            id = 0
 | 
					            id = 0
 | 
				
			||||||
        if layers == 1 and not component:
 | 
					        if layers == 1 and not component:
 | 
				
			||||||
| 
						 | 
					@ -143,20 +125,16 @@ class IptcImageFile(ImageFile.ImageFile):
 | 
				
			||||||
            self.mode = "CMYK"[id]
 | 
					            self.mode = "CMYK"[id]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # size
 | 
					        # size
 | 
				
			||||||
        self.size = self.getint((3,20)), self.getint((3,30))
 | 
					        self.size = self.getint((3, 20)), self.getint((3, 30))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # compression
 | 
					        # compression
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            compression = COMPRESSION[self.getint((3,120))]
 | 
					            compression = COMPRESSION[self.getint((3, 120))]
 | 
				
			||||||
        except KeyError:
 | 
					        except KeyError:
 | 
				
			||||||
            raise IOError("Unknown IPTC image compression")
 | 
					            raise IOError("Unknown IPTC image compression")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # tile
 | 
					        # tile
 | 
				
			||||||
        if tag == (8,10):
 | 
					        if tag == (8, 10):
 | 
				
			||||||
            if compression == "raw" and self._is_raw(offset, self.size):
 | 
					 | 
				
			||||||
                self.tile = [(compression, (offset, size + 5, -1),
 | 
					 | 
				
			||||||
                             (0, 0, self.size[0], self.size[1]))]
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
            self.tile = [("iptc", (compression, offset),
 | 
					            self.tile = [("iptc", (compression, offset),
 | 
				
			||||||
                         (0, 0, self.size[0], self.size[1]))]
 | 
					                         (0, 0, self.size[0], self.size[1]))]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -200,14 +178,17 @@ class IptcImageFile(ImageFile.ImageFile):
 | 
				
			||||||
                im.load()
 | 
					                im.load()
 | 
				
			||||||
                self.im = im.im
 | 
					                self.im = im.im
 | 
				
			||||||
        finally:
 | 
					        finally:
 | 
				
			||||||
            try: os.unlink(outfile)
 | 
					            try:
 | 
				
			||||||
            except: pass
 | 
					                os.unlink(outfile)
 | 
				
			||||||
 | 
					            except:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Image.register_open("IPTC", IptcImageFile)
 | 
					Image.register_open("IPTC", IptcImageFile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Image.register_extension("IPTC", ".iim")
 | 
					Image.register_extension("IPTC", ".iim")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##
 | 
					##
 | 
				
			||||||
# Get IPTC information from TIFF, JPEG, or IPTC file.
 | 
					# Get IPTC information from TIFF, JPEG, or IPTC file.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					@ -230,11 +211,11 @@ def getiptcinfo(im):
 | 
				
			||||||
        # extract the IPTC/NAA resource
 | 
					        # extract the IPTC/NAA resource
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            app = im.app["APP13"]
 | 
					            app = im.app["APP13"]
 | 
				
			||||||
            if app[:14] == "Photoshop 3.0\x00":
 | 
					            if app[:14] == b"Photoshop 3.0\x00":
 | 
				
			||||||
                app = app[14:]
 | 
					                app = app[14:]
 | 
				
			||||||
                # parse the image resource block
 | 
					                # parse the image resource block
 | 
				
			||||||
                offset = 0
 | 
					                offset = 0
 | 
				
			||||||
                while app[offset:offset+4] == "8BIM":
 | 
					                while app[offset:offset+4] == b"8BIM":
 | 
				
			||||||
                    offset += 4
 | 
					                    offset += 4
 | 
				
			||||||
                    # resource code
 | 
					                    # resource code
 | 
				
			||||||
                    code = JpegImagePlugin.i16(app, offset)
 | 
					                    code = JpegImagePlugin.i16(app, offset)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								Tests/images/iptc.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/iptc.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 20 KiB  | 
							
								
								
									
										79
									
								
								Tests/test_file_iptc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								Tests/test_file_iptc.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,79 @@
 | 
				
			||||||
 | 
					from helper import unittest, PillowTestCase, lena
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from PIL import Image, IptcImagePlugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_FILE = "Tests/images/iptc.jpg"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestFileIptc(PillowTestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Helpers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def dummy_IptcImagePlugin(self):
 | 
				
			||||||
 | 
					        # Create an IptcImagePlugin object without initializing it
 | 
				
			||||||
 | 
					        class FakeImage:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					        im = FakeImage()
 | 
				
			||||||
 | 
					        im.__class__ = IptcImagePlugin.IptcImageFile
 | 
				
			||||||
 | 
					        return im
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_getiptcinfo_jpg_none(self):
 | 
				
			||||||
 | 
					        # Arrange
 | 
				
			||||||
 | 
					        im = lena()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Act
 | 
				
			||||||
 | 
					        iptc = IptcImagePlugin.getiptcinfo(im)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Assert
 | 
				
			||||||
 | 
					        self.assertIsNone(iptc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_getiptcinfo_jpg_found(self):
 | 
				
			||||||
 | 
					        # Arrange
 | 
				
			||||||
 | 
					        im = Image.open(TEST_FILE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Act
 | 
				
			||||||
 | 
					        iptc = IptcImagePlugin.getiptcinfo(im)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Assert
 | 
				
			||||||
 | 
					        self.assertIsInstance(iptc, dict)
 | 
				
			||||||
 | 
					        self.assertEqual(iptc[(2, 90)], b"Budapest")
 | 
				
			||||||
 | 
					        self.assertEqual(iptc[(2, 101)], b"Hungary")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_i(self):
 | 
				
			||||||
 | 
					        # Arrange
 | 
				
			||||||
 | 
					        c = b"a"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Act
 | 
				
			||||||
 | 
					        ret = IptcImagePlugin.i(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Assert
 | 
				
			||||||
 | 
					        self.assertEqual(ret, 97)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_dump(self):
 | 
				
			||||||
 | 
					        # Arrange
 | 
				
			||||||
 | 
					        c = b"abc"
 | 
				
			||||||
 | 
					        # Temporarily redirect stdout
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            from cStringIO import StringIO
 | 
				
			||||||
 | 
					        except ImportError:
 | 
				
			||||||
 | 
					            from io import StringIO
 | 
				
			||||||
 | 
					        import sys
 | 
				
			||||||
 | 
					        old_stdout = sys.stdout
 | 
				
			||||||
 | 
					        sys.stdout = mystdout = StringIO()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Act
 | 
				
			||||||
 | 
					        IptcImagePlugin.dump(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Reset stdout
 | 
				
			||||||
 | 
					        sys.stdout = old_stdout
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Assert
 | 
				
			||||||
 | 
					        self.assertEqual(mystdout.getvalue(), "61 62 63 \n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    unittest.main()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# End of file
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user