From e49e689c70eb243322e57e9213df9f804c85d762 Mon Sep 17 00:00:00 2001 From: hugovk Date: Wed, 30 Jul 2014 19:33:04 +0300 Subject: [PATCH 1/7] Add JPEG with IPTC data. My image, permission given to distribute under MIT licence --- Tests/images/iptc.jpg | Bin 0 -> 21019 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Tests/images/iptc.jpg diff --git a/Tests/images/iptc.jpg b/Tests/images/iptc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b4d49caa182b1a5db367629b2d2719db86566188 GIT binary patch literal 21019 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�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 literal 0 HcmV?d00001 From 4c5a5c1f0eddef0d384f18d46657c92e954b5075 Mon Sep 17 00:00:00 2001 From: hugovk Date: Wed, 30 Jul 2014 19:34:20 +0300 Subject: [PATCH 2/7] Tests for IptcImagePlugin.py --- Tests/test_file_iptc.py | 71 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 Tests/test_file_iptc.py diff --git a/Tests/test_file_iptc.py b/Tests/test_file_iptc.py new file mode 100644 index 000000000..4ae85c66b --- /dev/null +++ b/Tests/test_file_iptc.py @@ -0,0 +1,71 @@ +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)], "Budapest") + self.assertEqual(iptc[(2, 101)], "Hungary") + + # _FIXME: is_raw() is disabled. Should we remove it? + def test__is_raw_equal_zero(self): + # Arrange + im = self.dummy_IptcImagePlugin() + offset = 0 + size = 4 + + # Act + ret = im._is_raw(offset, size) + + # Assert + self.assertEqual(ret, 0) + + def test_i(self): + # Arrange + c = "a" + + # Act + ret = IptcImagePlugin.i(c) + + # Assert + self.assertEqual(ret, 97) + + +if __name__ == '__main__': + unittest.main() + +# End of file From 515bb6e14dc95824133cd7fac56208233880caa3 Mon Sep 17 00:00:00 2001 From: hugovk Date: Wed, 30 Jul 2014 19:39:11 +0300 Subject: [PATCH 3/7] flake8 --- PIL/IptcImagePlugin.py | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/PIL/IptcImagePlugin.py b/PIL/IptcImagePlugin.py index 85575612c..955afbbeb 100644 --- a/PIL/IptcImagePlugin.py +++ b/PIL/IptcImagePlugin.py @@ -21,7 +21,8 @@ __version__ = "0.3" from PIL import Image, ImageFile, _binary -import os, tempfile +import os +import tempfile i8 = _binary.i8 i16 = _binary.i16be @@ -35,17 +36,20 @@ COMPRESSION = { PAD = o8(0) * 4 + # # Helpers def i(c): return i32((PAD + c)[-4:]) + def dump(c): for i in c: print("%02x" % i8(i), end=' ') print() + ## # Image plugin for IPTC/NAA datastreams. To read IPTC/NAA fields # from TIFF and JPEG files, use the getiptcinfo function. @@ -112,7 +116,7 @@ class IptcImageFile(ImageFile.ImageFile): while True: offset = self.fp.tell() tag, size = self.field() - if not tag or tag == (8,10): + if not tag or tag == (8, 10): break if size: tagdata = self.fp.read(size) @@ -129,10 +133,10 @@ class IptcImageFile(ImageFile.ImageFile): # print tag, self.info[tag] # mode - layers = i8(self.info[(3,60)][0]) - component = i8(self.info[(3,60)][1]) - if (3,65) in self.info: - id = i8(self.info[(3,65)][0])-1 + layers = i8(self.info[(3, 60)][0]) + component = i8(self.info[(3, 60)][1]) + if (3, 65) in self.info: + id = i8(self.info[(3, 65)][0])-1 else: id = 0 if layers == 1 and not component: @@ -143,16 +147,16 @@ class IptcImageFile(ImageFile.ImageFile): self.mode = "CMYK"[id] # size - self.size = self.getint((3,20)), self.getint((3,30)) + self.size = self.getint((3, 20)), self.getint((3, 30)) # compression try: - compression = COMPRESSION[self.getint((3,120))] + compression = COMPRESSION[self.getint((3, 120))] except KeyError: raise IOError("Unknown IPTC image compression") # 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]))] @@ -200,14 +204,17 @@ class IptcImageFile(ImageFile.ImageFile): im.load() self.im = im.im finally: - try: os.unlink(outfile) - except: pass + try: + os.unlink(outfile) + except: + pass Image.register_open("IPTC", IptcImageFile) Image.register_extension("IPTC", ".iim") + ## # Get IPTC information from TIFF, JPEG, or IPTC file. # @@ -267,7 +274,7 @@ def getiptcinfo(im): pass if data is None: - return None # no properties + return None # no properties # create an IptcImagePlugin object without initializing it class FakeImage: @@ -282,6 +289,6 @@ def getiptcinfo(im): try: im._open() except (IndexError, KeyError): - pass # expected failure + pass # expected failure return im.info From f5440cc3e1b0523b156a98ff311af61e003e95f9 Mon Sep 17 00:00:00 2001 From: hugovk Date: Wed, 30 Jul 2014 20:43:34 +0300 Subject: [PATCH 4/7] Fixes for Python 3 --- PIL/IptcImagePlugin.py | 4 ++-- Tests/test_file_iptc.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/PIL/IptcImagePlugin.py b/PIL/IptcImagePlugin.py index 955afbbeb..a94fc7524 100644 --- a/PIL/IptcImagePlugin.py +++ b/PIL/IptcImagePlugin.py @@ -237,11 +237,11 @@ def getiptcinfo(im): # extract the IPTC/NAA resource try: app = im.app["APP13"] - if app[:14] == "Photoshop 3.0\x00": + if app[:14] == b"Photoshop 3.0\x00": app = app[14:] # parse the image resource block offset = 0 - while app[offset:offset+4] == "8BIM": + while app[offset:offset+4] == b"8BIM": offset += 4 # resource code code = JpegImagePlugin.i16(app, offset) diff --git a/Tests/test_file_iptc.py b/Tests/test_file_iptc.py index 4ae85c66b..fd68e88b6 100644 --- a/Tests/test_file_iptc.py +++ b/Tests/test_file_iptc.py @@ -38,8 +38,8 @@ class TestFileIptc(PillowTestCase): # Assert self.assertIsInstance(iptc, dict) - self.assertEqual(iptc[(2, 90)], "Budapest") - self.assertEqual(iptc[(2, 101)], "Hungary") + self.assertEqual(iptc[(2, 90)], b"Budapest") + self.assertEqual(iptc[(2, 101)], b"Hungary") # _FIXME: is_raw() is disabled. Should we remove it? def test__is_raw_equal_zero(self): @@ -56,7 +56,7 @@ class TestFileIptc(PillowTestCase): def test_i(self): # Arrange - c = "a" + c = b"a" # Act ret = IptcImagePlugin.i(c) From a0aff1a87faa72373010d0e5c71667c7dcc34e19 Mon Sep 17 00:00:00 2001 From: hugovk Date: Fri, 1 Aug 2014 11:12:47 +0300 Subject: [PATCH 5/7] Remove disabled _is_raw() --- PIL/IptcImagePlugin.py | 30 ++---------------------------- Tests/test_file_iptc.py | 13 ------------- 2 files changed, 2 insertions(+), 41 deletions(-) diff --git a/PIL/IptcImagePlugin.py b/PIL/IptcImagePlugin.py index a94fc7524..dc8607591 100644 --- a/PIL/IptcImagePlugin.py +++ b/PIL/IptcImagePlugin.py @@ -88,28 +88,6 @@ class IptcImageFile(ImageFile.ImageFile): 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): # load descriptive fields @@ -157,12 +135,8 @@ class IptcImageFile(ImageFile.ImageFile): # tile 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), - (0, 0, self.size[0], self.size[1]))] + self.tile = [("iptc", (compression, offset), + (0, 0, self.size[0], self.size[1]))] def load(self): diff --git a/Tests/test_file_iptc.py b/Tests/test_file_iptc.py index fd68e88b6..3c04b7413 100644 --- a/Tests/test_file_iptc.py +++ b/Tests/test_file_iptc.py @@ -41,19 +41,6 @@ class TestFileIptc(PillowTestCase): self.assertEqual(iptc[(2, 90)], b"Budapest") self.assertEqual(iptc[(2, 101)], b"Hungary") - # _FIXME: is_raw() is disabled. Should we remove it? - def test__is_raw_equal_zero(self): - # Arrange - im = self.dummy_IptcImagePlugin() - offset = 0 - size = 4 - - # Act - ret = im._is_raw(offset, size) - - # Assert - self.assertEqual(ret, 0) - def test_i(self): # Arrange c = b"a" From 35838da803253db7ecb5e47ae635d5dcb150ccdb Mon Sep 17 00:00:00 2001 From: hugovk Date: Fri, 1 Aug 2014 11:56:21 +0300 Subject: [PATCH 6/7] Test dump() --- Tests/test_file_iptc.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Tests/test_file_iptc.py b/Tests/test_file_iptc.py index 3c04b7413..57c2011b6 100644 --- a/Tests/test_file_iptc.py +++ b/Tests/test_file_iptc.py @@ -51,6 +51,27 @@ class TestFileIptc(PillowTestCase): # 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(), b"61 62 63 \n") + if __name__ == '__main__': unittest.main() From 805184fcbb0579589cce02e86aa3fd51ad76680d Mon Sep 17 00:00:00 2001 From: hugovk Date: Fri, 1 Aug 2014 12:11:03 +0300 Subject: [PATCH 7/7] Fi xffor Python 3 --- Tests/test_file_iptc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/test_file_iptc.py b/Tests/test_file_iptc.py index 57c2011b6..bd331e5b2 100644 --- a/Tests/test_file_iptc.py +++ b/Tests/test_file_iptc.py @@ -70,7 +70,7 @@ class TestFileIptc(PillowTestCase): sys.stdout = old_stdout # Assert - self.assertEqual(mystdout.getvalue(), b"61 62 63 \n") + self.assertEqual(mystdout.getvalue(), "61 62 63 \n") if __name__ == '__main__':