From 4918a39a77237c08a0d332eb1d2b3ea93251c3da Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Fri, 24 Jul 2015 11:14:20 +0200 Subject: [PATCH 1/3] Testing that animated gif preserves all important headers --- Tests/test_file_gif.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index 70438eb03..5c83ba8e4 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -95,6 +95,21 @@ class TestFileGif(PillowTestCase): self.assertEqual(reread.n_frames, 5) + def test_headers_saving_for_animated_gifs(self): + important_headers = ['background', 'version', 'transparency', 'duration', 'loop'] + # Multiframe image + im = Image.open("Tests/images/dispose_bgnd.gif") + + out = self.tempfile('temp.gif') + im.save(out, save_all=True) + reread = Image.open(out) + + for header in important_headers: + self.assertEqual( + im.info[header], + reread.info[header] + ) + def test_palette_handling(self): # see https://github.com/python-pillow/Pillow/issues/513 From 26da91ca5679cb106134f75cd3a509f765d526aa Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 19 Aug 2015 23:51:02 +1000 Subject: [PATCH 2/3] Changed GifImagePlugin so that save_all roundtrips duration and loop --- PIL/GifImagePlugin.py | 16 ++++++++++++---- Tests/test_file_gif.py | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/PIL/GifImagePlugin.py b/PIL/GifImagePlugin.py index 08567fcd0..f03c6fdc7 100644 --- a/PIL/GifImagePlugin.py +++ b/PIL/GifImagePlugin.py @@ -24,7 +24,8 @@ # See the README file for information on usage and redistribution. # -from PIL import Image, ImageFile, ImagePalette, ImageChops, ImageSequence, _binary +from PIL import Image, ImageFile, ImagePalette, \ + ImageChops, ImageSequence, _binary __version__ = "0.9" @@ -347,7 +348,14 @@ def _save(im, fp, filename, save_all=False): # e.g. getdata(im_frame, duration=1000) if not previous: # global header - for s in getheader(im_frame, palette, im.encoderinfo)[0] + getdata(im_frame): + duration = None + if "duration" in im.info: + duration = im.info["duration"] + loop = None + if "loop" in im.info: + loop = im.info["loop"] + for s in getheader(im_frame, palette, im.encoderinfo)[0] + \ + getdata(im_frame, duration=duration, loop=loop): fp.write(s) else: # delta frame @@ -426,7 +434,7 @@ def _get_local_header(fp, im, offset, flags): else: transparent_color_exists = False - if "duration" in im.encoderinfo: + if im.encoderinfo.get("duration") != None: duration = int(im.encoderinfo["duration"] / 10) else: duration = 0 @@ -443,7 +451,7 @@ def _get_local_header(fp, im, offset, flags): o8(transparency) + # transparency index o8(0)) - if "loop" in im.encoderinfo: + if im.encoderinfo.get("loop") != None: number_of_loops = im.encoderinfo["loop"] fp.write(b"!" + o8(255) + # extension intro diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index 5c83ba8e4..bd3bf9cba 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -96,7 +96,7 @@ class TestFileGif(PillowTestCase): self.assertEqual(reread.n_frames, 5) def test_headers_saving_for_animated_gifs(self): - important_headers = ['background', 'version', 'transparency', 'duration', 'loop'] + important_headers = ['background', 'duration', 'loop'] # Multiframe image im = Image.open("Tests/images/dispose_bgnd.gif") From a86c5ec0437d17b9edd0401eba57dee62e767941 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 20 Aug 2015 06:36:16 +1000 Subject: [PATCH 3/3] Style fix --- PIL/GifImagePlugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PIL/GifImagePlugin.py b/PIL/GifImagePlugin.py index f03c6fdc7..ff38cc37c 100644 --- a/PIL/GifImagePlugin.py +++ b/PIL/GifImagePlugin.py @@ -434,7 +434,7 @@ def _get_local_header(fp, im, offset, flags): else: transparent_color_exists = False - if im.encoderinfo.get("duration") != None: + if im.encoderinfo.get("duration") is not None: duration = int(im.encoderinfo["duration"] / 10) else: duration = 0 @@ -451,7 +451,7 @@ def _get_local_header(fp, im, offset, flags): o8(transparency) + # transparency index o8(0)) - if im.encoderinfo.get("loop") != None: + if im.encoderinfo.get("loop") is not None: number_of_loops = im.encoderinfo["loop"] fp.write(b"!" + o8(255) + # extension intro