Merge pull request #2 from radarhere/comment_correct_placement

Once comment is loaded, keep it for subsequent frames
This commit is contained in:
Ray Gardner 2022-05-23 11:54:57 -06:00 committed by GitHub
commit 4cdbeaf2cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 27 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -837,31 +837,48 @@ def test_read_multiple_comment_blocks():
assert im.info["comment"] == b"Test comment 1\nTest comment 2"
def test_write_comment(tmp_path):
def test_empty_string_comment(tmp_path):
out = str(tmp_path / "temp.gif")
with Image.open("Tests/images/chi.gif") as im:
assert "comment" in im.info
# Empty string comment should suppress existing comment
im.save(out, save_all=True, comment="")
with Image.open(out) as reread:
for frame in ImageSequence.Iterator(reread):
assert "comment" not in frame.info
def test_retain_comment_in_subsequent_frames(tmp_path):
# Test that a comment block at the beginning is kept
with Image.open("Tests/images/chi.gif") as im:
for frame in ImageSequence.Iterator(im):
assert frame.info["comment"] == b"Created with GIMP"
with Image.open("Tests/images/second_frame_comment.gif") as im:
assert "comment" not in im.info
# Test that a comment in the middle is read
im.seek(1)
assert im.info["comment"] == b"Comment in the second frame"
# Test that it is still present in a later frame
im.seek(2)
assert im.info["comment"] == b"Comment in the second frame"
# Test that rewinding removes the comment
im.seek(0)
assert "comment" not in im.info
# Test that a saved image keeps the comment
out = str(tmp_path / "temp.gif")
with Image.open("Tests/images/dispose_prev.gif") as im:
im.save(out, save_all=True, comment="Test")
with Image.open(out) as reread:
# Comments written should appear only in first frame
assert reread.info["comment"] == b"Test"
for i, frame in enumerate(ImageSequence.Iterator(reread)):
assert (
i == 0
and frame.info["comment"] == b"Test"
or i != 0
and "comment" not in frame.info
)
def test_write_no_comment(tmp_path):
out = str(tmp_path / "temp.gif")
with Image.open("Tests/images/dispose_prev.gif") as im:
# Empty comment="" arg should suppress all comments
im.save(out, save_all=True, comment="")
with Image.open(out) as reread:
assert "comment" not in reread.info
for frame in ImageSequence.Iterator(reread):
assert "comment" not in frame.info
with Image.open(out) as reread:
for frame in ImageSequence.Iterator(reread):
assert frame.info["comment"] == b"Test"
def test_version(tmp_path):

View File

@ -163,6 +163,8 @@ class GifImageFile(ImageFile.ImageFile):
self.__frame = -1
self._fp.seek(self.__rewind)
self.disposal_method = 0
if "comment" in self.info:
del self.info["comment"]
else:
# ensure that the previous frame was loaded
if self.tile and update_image:
@ -230,7 +232,7 @@ class GifImageFile(ImageFile.ImageFile):
#
comment = b""
# Collect one comment block
# Read this comment block
while block:
comment += block
block = self.data()
@ -395,7 +397,9 @@ class GifImageFile(ImageFile.ImageFile):
)
]
for k in ["duration", "comment", "extension", "loop"]:
if info.get("comment"):
self.info["comment"] = info["comment"]
for k in ["duration", "extension", "loop"]:
if k in info:
self.info[k] = info[k]
elif k in self.info:
@ -929,17 +933,18 @@ def _get_global_header(im, info):
# Global Color Table
_get_header_palette(palette_bytes),
]
if info.get("comment"):
comment_block = b"!" + o8(254) # extension intro
if "comment" in info and len(info["comment"]):
comment = info["comment"]
if isinstance(comment, str):
comment = comment.encode()
header.append(b"!" + o8(254)) # extension intro
for i in range(0, len(comment), 255):
subblock = comment[i : i + 255]
header.append(o8(len(subblock)) + subblock)
header.append(o8(0))
comment_block += o8(len(subblock)) + subblock
comment_block += o8(0)
header.append(comment_block)
return header