From 300e25c15c61025221ca170683a4c6776558b6aa Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 6 Sep 2017 13:14:39 +1000 Subject: [PATCH 1/3] Removed duplicate code --- PIL/GdImageFile.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/PIL/GdImageFile.py b/PIL/GdImageFile.py index 09ab5ec6964..5b7dc3d7683 100644 --- a/PIL/GdImageFile.py +++ b/PIL/GdImageFile.py @@ -25,16 +25,9 @@ from . import ImageFile, ImagePalette from ._binary import i16be as i16 -from ._util import isPath __version__ = "0.1" -try: - import builtins -except ImportError: - import __builtin__ - builtins = __builtin__ - ## # Image plugin for the GD uncompressed format. Note that this format @@ -78,13 +71,7 @@ def open(fp, mode="r"): if mode != "r": raise ValueError("bad mode") - if isPath(fp): - filename = fp - fp = builtins.open(fp, "rb") - else: - filename = "" - try: - return GdImageFile(fp, filename) + return GdImageFile(fp) except SyntaxError: raise IOError("cannot identify this image file") From e190e8ae9d422045cd57c19fed74efcdaf41ff0d Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 6 Sep 2017 13:14:47 +1000 Subject: [PATCH 2/3] Corrected info key --- PIL/GdImageFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PIL/GdImageFile.py b/PIL/GdImageFile.py index 5b7dc3d7683..645aae6e348 100644 --- a/PIL/GdImageFile.py +++ b/PIL/GdImageFile.py @@ -51,7 +51,7 @@ def _open(self): # transparency index tindex = i16(s[5:7]) if tindex < 256: - self.info["transparent"] = tindex + self.info["transparency"] = tindex self.palette = ImagePalette.raw("RGB", s[7:]) From d1bbb7881fbec0c5621b5081db4117da81b329fe Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sun, 17 Sep 2017 20:15:59 +1000 Subject: [PATCH 3/3] Added GD tests --- PIL/GdImageFile.py | 18 ++++++++++++------ Tests/images/hopper.gd | Bin 0 -> 17421 bytes Tests/test_file_gd.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 Tests/images/hopper.gd create mode 100644 Tests/test_file_gd.py diff --git a/PIL/GdImageFile.py b/PIL/GdImageFile.py index 645aae6e348..2ca1e821854 100644 --- a/PIL/GdImageFile.py +++ b/PIL/GdImageFile.py @@ -24,7 +24,7 @@ from . import ImageFile, ImagePalette -from ._binary import i16be as i16 +from ._binary import i8, i16be as i16, i32be as i32 __version__ = "0.1" @@ -43,19 +43,25 @@ class GdImageFile(ImageFile.ImageFile): def _open(self): # Header - s = self.fp.read(775) + s = self.fp.read(1037) + + if not i16(s[:2]) in [65534, 65535]: + raise SyntaxError("Not a valid GD 2.x .gd file") self.mode = "L" # FIXME: "P" - self.size = i16(s[0:2]), i16(s[2:4]) + self.size = i16(s[2:4]), i16(s[4:6]) + + trueColor = i8(s[6]) + trueColorOffset = 2 if trueColor else 0 # transparency index - tindex = i16(s[5:7]) + tindex = i32(s[7+trueColorOffset:7+trueColorOffset+4]) if tindex < 256: self.info["transparency"] = tindex - self.palette = ImagePalette.raw("RGB", s[7:]) + self.palette = ImagePalette.raw("XBGR", s[7+trueColorOffset+4:7+trueColorOffset+4+256*4]) - self.tile = [("raw", (0, 0)+self.size, 775, ("L", 0, -1))] + self.tile = [("raw", (0, 0)+self.size, 7+trueColorOffset+4+256*4, ("L", 0, 1))] def open(fp, mode="r"): diff --git a/Tests/images/hopper.gd b/Tests/images/hopper.gd new file mode 100644 index 0000000000000000000000000000000000000000..82d2408f93ef67c49ca6e7b09e00cfd9b040bac4 GIT binary patch literal 17421 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�<#b*Cc>oIKGFfE?U-<>R!pc6gWDuqOpV>V=-tzmgB)1 zIw4JX;SoK$D)5E>_hG~>5#UQeOKG*^fKTfNMxzn zlj(?m$@l!MB!H4;ieiBOt0((893goABu>2?u!}c$zgAVoI~_9rg)3gn2Wzf9Rd5Ke zG;rI=sooP}$VV*3!+xZH^eM^xlBxU?awezYVS*JMr*GJl7{H`o@C08})S)p3JOK@F zOZ7(>D9{$Ky&wx+q^=hnAb@ll+}$Tc+g0Ev!~S&acq5Rk2R4C|417tj^g`3prv}5) zwNj@a6*Z%>8r_hxV<44ZkNQf(K-rZR5mG7_?ajHa53VWA06!? zIXnOoE+30xlk21fA7Utxhp)wsWotdbfB3s$QWpeLUf*|6&xk?=Yn65Z#R{0xiD;?h zNT@?v+Xmp1|9SX(@EM!u?>}$NjhT<6^9us#B7Nc^P4Xx^uH@X~qkuz8kEbKcAUM}t z3IOm09{PQ)40CFzSV%&d3=W`Ek%qLu%61wTrOB|L9|sD3V9@$sM^yP=SUP+RE=e!= z&l_BYk0=_XA9Du?7uEtlt8wXZ`ezkNbzpKK@UJoWzkq?GzB>Qk=XrZq3-$3l8;UCV zpBhetp`g~*0sCP-p0K1-^V8$Tqd)!&;qJV$3m1;;&&kOdle53`hWBHv@uspu|16Pm zZ|UxNbCm-P9aP`Y-BWABbSlI@`{AEHd+o#5KKS>a{wfS40wjr&qvI4FBJOcK{=Oi? z>5V@;YuA}`cgo$RWk<&3**RuuGd`j>G5nvLJc^q}=8=`nx5hLczOd}p zg{4Q1j2Qz5bar;`zaY?u)W=|f>ng!eRayC+|JftBc*7MOW*Pu5QVtH3t@`#z)Ui)* zUETl7tsnmR=AYLL`t74{Ui-(B-98JS=2IK!g@I0yW_#&eJ?f7O_*@shNWZb>_^^3r z%gQ7IM>>xj*}rrt5)uTcaR}L;o?TF-S65xxef$^yvxvkC zWi&wIjRa8QtHO=5)z$m7GK|0hj~s*JQF1a@2R429;s1X4uXn%u=$A|1z4>nH@u!+z z`}Z4YKi!U}iB3=_Xy6-^q0rwO{*rwhg_tP$KFB~_ReHLFt_6F1h}gl==IUy?Y`~fD zg5y!~G84bLyu`QY$6XN3Q3x4;K~ARy_FLHH}M|B`p? z=~bApJYw(-30pEBzT-nU$Rt!x!%|61VGQaIZkvDg{xh#Xu6y#c4?o?%cGIlkhra#d zpJ%tc_wOg4eC?+vf4YWDAh#nCBnK$<_4U!wZ<63>5+p6XjkZVtETltN0gyKw#(x?i z8F_>CN`p+mKLaGqeB{*EQ@=i$zF}a8sw!S}(uIE#z*IdJiTJsa$`D0AC~IxX`g(8r z5tMXh7)X_$R}4buJDeST4l-mi`VyRn=aCZMDu+Yy(@3Uor48%PXGV_ literal 0 HcmV?d00001 diff --git a/Tests/test_file_gd.py b/Tests/test_file_gd.py new file mode 100644 index 00000000000..326b0c4b27d --- /dev/null +++ b/Tests/test_file_gd.py @@ -0,0 +1,28 @@ +from helper import unittest, PillowTestCase + +from PIL import GdImageFile + +import io + +TEST_GD_FILE = "Tests/images/hopper.gd" + + +class TestFileGd(PillowTestCase): + + def test_sanity(self): + im = GdImageFile.open(TEST_GD_FILE) + self.assertEqual(im.size, (128, 128)) + self.assertEqual(im.format, "GD") + + def test_bad_mode(self): + self.assertRaises(ValueError, + GdImageFile.open, TEST_GD_FILE, 'bad mode') + + def test_invalid_file(self): + invalid_file = "Tests/images/flower.jpg" + + self.assertRaises(IOError, GdImageFile.open, invalid_file) + + +if __name__ == '__main__': + unittest.main()