From 3922ee3f9946a69b26c0fb1387e7f91ba4868089 Mon Sep 17 00:00:00 2001 From: Hugo Date: Wed, 1 Oct 2014 11:47:54 +0300 Subject: [PATCH 1/4] Public domain image prepared by Bob Friesenhahn using a development version of GraphicsMagick 1.2. From ftp://ftp.remotesensing.org/pub/libtiff/pics-3.8.0.tar.gz --- Tests/images/flower-minisblack-04.tif | Bin 0 -> 1905 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Tests/images/flower-minisblack-04.tif diff --git a/Tests/images/flower-minisblack-04.tif b/Tests/images/flower-minisblack-04.tif new file mode 100644 index 0000000000000000000000000000000000000000..2583c42fb9159c029504eaf54fa49c0c26fb421e GIT binary patch literal 1905 zcmY+F&u`R56vu67LobzLZvyI%LuTv*)QZ54Z6fuw_{S0sNFi%GsHY^m9&ZYTZP<7w zMU^5I;&Iyp2WafjUW*#&tx{0}p^80E9By12|k0_;HrP6(Ha9d{7Fb zIKG>(jPW$(jPpdW9>Ee&@;%E1CZ=io+B5#u)5ozWSM!9Is-Vr1(#{RSIOS=UeztRW zbLTJc01=okbE7;hm0UNZ0-g&d?rlEX+;%U2Jcb>xnCemxa@%+aljg<3TfKDbv_H_M^Y>7b>|M22*o@ER6l}4$x5n7*@g(b-G;*o~ET%l6bV1`h zyR)%%QzY#o%U2&n!R%tyf~5eT&wcQ$gy5jd(H39!w|M`i5wtfl0?x)V8>Oc6s6Ocf@McsR`T13EQbi zJL3C0zf8>!3{1Kh4T$1)YwCvXSoOpXc41cn?GwIc?&G zqK82hla`_D4YOKt^oBvG7cj9T65m#kZfgxg#a7s`TvBGNR9vhh~K;qm)xE-!M)&HNI>p6$CO` z^?+*-n8A8g)~l*nRV%Zq=@_P46E#`JpyhyvVSpnpbJ38Dk!LfzbT(_Vk^)(xiqRq( zHZVpAx`V(RRjl(z6UQ~MTO+_K7^#L!fQDF+@nEY5Im%%ljyI(fZs3CnQ8k3*URgT9 zisyk3@{k@N-Sy~%W5Do<0)>MTU>d>B(C{QUkJuJpfZ1>wk~N@ia4Z?{E8C=CHw?Uy zhB=kNL64_lZ}f8N>GZhX0xRUH+cdBl#w?m}9T0}eR}eN#&&Ik(`Hj-6Y|P0X(l767 zK&4t)4h?)q8RHE4U5;G{QXyD{Hd&353E)iiD+6Z|!*X{a0!=FW4DE-HtO53JxB&WK zNa4v#s6=4EONB}yBluQEkP>{zA|EgZ>~`OmS=yUHnNK+q09hIV0!#_P(99@+MI{4w zFMxlA7`AN5z%Xl))GtfYK}nKi=`392z4(2I5A4OSL40s823YRf7r!YTfVFQ)(xE{@4SkS$?xu4du%TTN4eVbJq^Am zVVy)TU18Du@sH;&&t09pG}F9z{G>VBouiU8zAO9cerA5A)1GTyJvS52H7^cTN6FB_ j<@xARG;=j-4V^d0P`lghd~o6f^m6q7@aUEK_=NNy!*Dci literal 0 HcmV?d00001 From 2b11052588818431bb7468a5c29c45dedfbc7c2c Mon Sep 17 00:00:00 2001 From: Hugo Date: Wed, 1 Oct 2014 11:50:34 +0300 Subject: [PATCH 2/4] Add (MM, 1, 1, 1, (4,), ()): ('L', 'L;4'), and sort list --- PIL/TiffImagePlugin.py | 47 +++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/PIL/TiffImagePlugin.py b/PIL/TiffImagePlugin.py index 50648288e..004704599 100644 --- a/PIL/TiffImagePlugin.py +++ b/PIL/TiffImagePlugin.py @@ -144,68 +144,69 @@ OPEN_INFO = { # (ByteOrder, PhotoInterpretation, SampleFormat, FillOrder, BitsPerSample, # ExtraSamples) => mode, rawmode (II, 0, 1, 1, (1,), ()): ("1", "1;I"), - (II, 0, 1, 2, (1,), ()): ("1", "1;IR"), (II, 0, 1, 1, (8,), ()): ("L", "L;I"), + (II, 0, 1, 2, (1,), ()): ("1", "1;IR"), (II, 0, 1, 2, (8,), ()): ("L", "L;IR"), (II, 0, 3, 1, (32,), ()): ("F", "F;32F"), (II, 1, 1, 1, (1,), ()): ("1", "1"), - (II, 1, 1, 2, (1,), ()): ("1", "1;R"), - (II, 1, 1, 1, (8,), ()): ("L", "L"), - (II, 1, 1, 1, (8, 8), (2,)): ("LA", "LA"), - (II, 1, 1, 2, (8,), ()): ("L", "L;R"), (II, 1, 1, 1, (12,), ()): ("I;16", "I;12"), (II, 1, 1, 1, (16,), ()): ("I;16", "I;16"), - (II, 1, 2, 1, (16,), ()): ("I;16S", "I;16S"), (II, 1, 1, 1, (32,), ()): ("I", "I;32N"), + (II, 1, 1, 1, (8, 8), (2,)): ("LA", "LA"), + (II, 1, 1, 1, (8,), ()): ("L", "L"), + (II, 1, 1, 2, (1,), ()): ("1", "1;R"), + (II, 1, 1, 2, (8,), ()): ("L", "L;R"), + (II, 1, 2, 1, (16,), ()): ("I;16S", "I;16S"), (II, 1, 2, 1, (32,), ()): ("I", "I;32S"), (II, 1, 3, 1, (32,), ()): ("F", "F;32F"), (II, 2, 1, 1, (8, 8, 8), ()): ("RGB", "RGB"), - (II, 2, 1, 2, (8, 8, 8), ()): ("RGB", "RGB;R"), (II, 2, 1, 1, (8, 8, 8, 8), ()): ("RGBA", "RGBA"), # missing ExtraSamples (II, 2, 1, 1, (8, 8, 8, 8), (0,)): ("RGBX", "RGBX"), (II, 2, 1, 1, (8, 8, 8, 8), (1,)): ("RGBA", "RGBa"), (II, 2, 1, 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"), (II, 2, 1, 1, (8, 8, 8, 8), (999,)): ("RGBA", "RGBA"), # Corel Draw 10 + (II, 2, 1, 2, (8, 8, 8), ()): ("RGB", "RGB;R"), (II, 3, 1, 1, (1,), ()): ("P", "P;1"), - (II, 3, 1, 2, (1,), ()): ("P", "P;1R"), (II, 3, 1, 1, (2,), ()): ("P", "P;2"), - (II, 3, 1, 2, (2,), ()): ("P", "P;2R"), (II, 3, 1, 1, (4,), ()): ("P", "P;4"), - (II, 3, 1, 2, (4,), ()): ("P", "P;4R"), - (II, 3, 1, 1, (8,), ()): ("P", "P"), (II, 3, 1, 1, (8, 8), (2,)): ("PA", "PA"), + (II, 3, 1, 1, (8,), ()): ("P", "P"), + (II, 3, 1, 2, (1,), ()): ("P", "P;1R"), + (II, 3, 1, 2, (2,), ()): ("P", "P;2R"), + (II, 3, 1, 2, (4,), ()): ("P", "P;4R"), (II, 3, 1, 2, (8,), ()): ("P", "P;R"), (II, 5, 1, 1, (8, 8, 8, 8), ()): ("CMYK", "CMYK"), (II, 6, 1, 1, (8, 8, 8), ()): ("YCbCr", "YCbCr"), (II, 8, 1, 1, (8, 8, 8), ()): ("LAB", "LAB"), (MM, 0, 1, 1, (1,), ()): ("1", "1;I"), - (MM, 0, 1, 2, (1,), ()): ("1", "1;IR"), (MM, 0, 1, 1, (8,), ()): ("L", "L;I"), + (MM, 0, 1, 2, (1,), ()): ("1", "1;IR"), (MM, 0, 1, 2, (8,), ()): ("L", "L;IR"), (MM, 1, 1, 1, (1,), ()): ("1", "1"), - (MM, 1, 1, 2, (1,), ()): ("1", "1;R"), - (MM, 1, 1, 1, (8,), ()): ("L", "L"), - (MM, 1, 1, 1, (8, 8), (2,)): ("LA", "LA"), - (MM, 1, 1, 2, (8,), ()): ("L", "L;R"), (MM, 1, 1, 1, (16,), ()): ("I;16B", "I;16B"), + (MM, 1, 1, 1, (4,), ()): ("L", "L;4"), + (MM, 1, 1, 1, (8, 8), (2,)): ("LA", "LA"), + (MM, 1, 1, 1, (8,), ()): ("L", "L"), + (MM, 1, 1, 2, (1,), ()): ("1", "1;R"), + (MM, 1, 1, 2, (8,), ()): ("L", "L;R"), (MM, 1, 2, 1, (16,), ()): ("I;16BS", "I;16BS"), (MM, 1, 2, 1, (32,), ()): ("I;32BS", "I;32BS"), (MM, 1, 3, 1, (32,), ()): ("F", "F;32BF"), (MM, 2, 1, 1, (8, 8, 8), ()): ("RGB", "RGB"), - (MM, 2, 1, 2, (8, 8, 8), ()): ("RGB", "RGB;R"), (MM, 2, 1, 1, (8, 8, 8, 8), (0,)): ("RGBX", "RGBX"), (MM, 2, 1, 1, (8, 8, 8, 8), (1,)): ("RGBA", "RGBa"), (MM, 2, 1, 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"), (MM, 2, 1, 1, (8, 8, 8, 8), (999,)): ("RGBA", "RGBA"), # Corel Draw 10 + (MM, 2, 1, 2, (8, 8, 8), ()): ("RGB", "RGB;R"), (MM, 3, 1, 1, (1,), ()): ("P", "P;1"), - (MM, 3, 1, 2, (1,), ()): ("P", "P;1R"), (MM, 3, 1, 1, (2,), ()): ("P", "P;2"), - (MM, 3, 1, 2, (2,), ()): ("P", "P;2R"), (MM, 3, 1, 1, (4,), ()): ("P", "P;4"), - (MM, 3, 1, 2, (4,), ()): ("P", "P;4R"), - (MM, 3, 1, 1, (8,), ()): ("P", "P"), (MM, 3, 1, 1, (8, 8), (2,)): ("PA", "PA"), + (MM, 3, 1, 1, (8,), ()): ("P", "P"), + (MM, 3, 1, 2, (1,), ()): ("P", "P;1R"), + (MM, 3, 1, 2, (2,), ()): ("P", "P;2R"), + (MM, 3, 1, 2, (4,), ()): ("P", "P;4R"), (MM, 3, 1, 2, (8,), ()): ("P", "P;R"), (MM, 5, 1, 1, (8, 8, 8, 8), ()): ("CMYK", "CMYK"), (MM, 6, 1, 1, (8, 8, 8), ()): ("YCbCr", "YCbCr"), @@ -660,7 +661,7 @@ class TiffImageFile(ImageFile.ImageFile): raise EOFError("no more images in TIFF file") if Image.DEBUG: print("Seeking to frame %s, on frame %s, __next %s, location: %s"% - (frame, self.__frame, self.__next, self.fp.tell())) + (frame, self.__frame, self.__next, self.fp.tell())) # reset python3 buffered io handle in case fp # was passed to libtiff, invalidating the buffer self.fp.tell() @@ -671,7 +672,7 @@ class TiffImageFile(ImageFile.ImageFile): self.__next = self.tag.next self.__frame += 1 self._setup() - + def _tell(self): return self.__frame From 39b30e616a5b3430a68839f2478119b37f8b5a9a Mon Sep 17 00:00:00 2001 From: Hugo Date: Wed, 1 Oct 2014 11:53:44 +0300 Subject: [PATCH 3/4] Test for 4-bit TIFF --- Tests/test_file_tiff.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py index cf809d5d0..be13522a3 100644 --- a/Tests/test_file_tiff.py +++ b/Tests/test_file_tiff.py @@ -298,6 +298,17 @@ class TestFileTiff(PillowTestCase): # Assert self.assertEqual(ret, [0, 1]) + def test_4bit(self): + # Arrange + test_file = "Tests/images/flower-minisblack-04.tif" + + # Act + im = Image.open(test_file) + + # Assert + self.assertEqual(im.size, (73, 43)) + self.assertEqual(im.mode, "L") + if __name__ == '__main__': unittest.main() From 94028f01d4ed0e542722216a4c71a61052b22d47 Mon Sep 17 00:00:00 2001 From: Hugo Date: Wed, 1 Oct 2014 12:44:10 +0300 Subject: [PATCH 4/4] flake8 --- PIL/TiffImagePlugin.py | 8 ++++---- Tests/test_file_tiff.py | 23 +++++++++-------------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/PIL/TiffImagePlugin.py b/PIL/TiffImagePlugin.py index 004704599..0ef01cb5e 100644 --- a/PIL/TiffImagePlugin.py +++ b/PIL/TiffImagePlugin.py @@ -450,10 +450,10 @@ class ImageFileDirectory(collections.MutableMapping): if size > 4: here = fp.tell() if Image.DEBUG: - print ("Tag Location: %s" %here) + print("Tag Location: %s" % here) fp.seek(i32(ifd, 8)) if Image.DEBUG: - print ("Data Location: %s" %fp.tell()) + print("Data Location: %s" % fp.tell()) data = ImageFile._safe_read(fp, size) fp.seek(here) else: @@ -660,14 +660,14 @@ class TiffImageFile(ImageFile.ImageFile): if not self.__next: raise EOFError("no more images in TIFF file") if Image.DEBUG: - print("Seeking to frame %s, on frame %s, __next %s, location: %s"% + print("Seeking to frame %s, on frame %s, __next %s, location: %s" % (frame, self.__frame, self.__next, self.fp.tell())) # reset python3 buffered io handle in case fp # was passed to libtiff, invalidating the buffer self.fp.tell() self.fp.seek(self.__next) if Image.DEBUG: - print("Loading tags, location: %s"%self.fp.tell()) + print("Loading tags, location: %s" % self.fp.tell()) self.tag.load(self.fp) self.__next = self.tag.next self.__frame += 1 diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py index be13522a3..4374f2c12 100644 --- a/Tests/test_file_tiff.py +++ b/Tests/test_file_tiff.py @@ -144,28 +144,27 @@ class TestFileTiff(PillowTestCase): def test_multipage(self): # issue #862 im = Image.open('Tests/images/multipage.tiff') - # file is a multipage tiff, 10x10 green, 10x10 red, 20x20 blue + # file is a multipage tiff: 10x10 green, 10x10 red, 20x20 blue im.seek(0) - self.assertEqual(im.size, (10,10)) - self.assertEqual(im.convert('RGB').getpixel((0,0)), (0,128,0)) + self.assertEqual(im.size, (10, 10)) + self.assertEqual(im.convert('RGB').getpixel((0, 0)), (0, 128, 0)) im.seek(1) im.load() - self.assertEqual(im.size, (10,10)) - self.assertEqual(im.convert('RGB').getpixel((0,0)), (255,0,0)) + self.assertEqual(im.size, (10, 10)) + self.assertEqual(im.convert('RGB').getpixel((0, 0)), (255, 0, 0)) im.seek(2) im.load() - self.assertEqual(im.size, (20,20)) - self.assertEqual(im.convert('RGB').getpixel((0,0)), (0,0,255)) + self.assertEqual(im.size, (20, 20)) + self.assertEqual(im.convert('RGB').getpixel((0, 0)), (0, 0, 255)) def test_multipage_last_frame(self): im = Image.open('Tests/images/multipage-lastframe.tif') im.load() - self.assertEqual(im.size, (20,20)) - self.assertEqual(im.convert('RGB').getpixel((0,0)), (0,0,255)) - + self.assertEqual(im.size, (20, 20)) + self.assertEqual(im.convert('RGB').getpixel((0, 0)), (0, 0, 255)) def test___str__(self): # Arrange @@ -199,7 +198,6 @@ class TestFileTiff(PillowTestCase): def test_load_byte(self): # Arrange - from PIL import TiffImagePlugin ifd = TiffImagePlugin.ImageFileDirectory() data = b"abc" @@ -211,7 +209,6 @@ class TestFileTiff(PillowTestCase): def test_load_string(self): # Arrange - from PIL import TiffImagePlugin ifd = TiffImagePlugin.ImageFileDirectory() data = b"abc\0" @@ -223,7 +220,6 @@ class TestFileTiff(PillowTestCase): def test_load_float(self): # Arrange - from PIL import TiffImagePlugin ifd = TiffImagePlugin.ImageFileDirectory() data = b"abcdabcd" @@ -235,7 +231,6 @@ class TestFileTiff(PillowTestCase): def test_load_double(self): # Arrange - from PIL import TiffImagePlugin ifd = TiffImagePlugin.ImageFileDirectory() data = b"abcdefghabcdefgh"