mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-27 09:44:31 +03:00
Merge pull request #2 from radarhere/comment_correct_placement
Once comment is loaded, keep it for subsequent frames
This commit is contained in:
commit
4cdbeaf2cf
BIN
Tests/images/second_frame_comment.gif
Normal file
BIN
Tests/images/second_frame_comment.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
|
@ -837,31 +837,48 @@ def test_read_multiple_comment_blocks():
|
||||||
assert im.info["comment"] == b"Test comment 1\nTest comment 2"
|
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")
|
out = str(tmp_path / "temp.gif")
|
||||||
with Image.open("Tests/images/dispose_prev.gif") as im:
|
with Image.open("Tests/images/dispose_prev.gif") as im:
|
||||||
im.save(out, save_all=True, comment="Test")
|
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
|
|
||||||
)
|
|
||||||
|
|
||||||
|
with Image.open(out) as reread:
|
||||||
def test_write_no_comment(tmp_path):
|
for frame in ImageSequence.Iterator(reread):
|
||||||
out = str(tmp_path / "temp.gif")
|
assert frame.info["comment"] == b"Test"
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
def test_version(tmp_path):
|
def test_version(tmp_path):
|
||||||
|
|
|
@ -163,6 +163,8 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
self.__frame = -1
|
self.__frame = -1
|
||||||
self._fp.seek(self.__rewind)
|
self._fp.seek(self.__rewind)
|
||||||
self.disposal_method = 0
|
self.disposal_method = 0
|
||||||
|
if "comment" in self.info:
|
||||||
|
del self.info["comment"]
|
||||||
else:
|
else:
|
||||||
# ensure that the previous frame was loaded
|
# ensure that the previous frame was loaded
|
||||||
if self.tile and update_image:
|
if self.tile and update_image:
|
||||||
|
@ -230,7 +232,7 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
#
|
#
|
||||||
comment = b""
|
comment = b""
|
||||||
|
|
||||||
# Collect one comment block
|
# Read this comment block
|
||||||
while block:
|
while block:
|
||||||
comment += block
|
comment += block
|
||||||
block = self.data()
|
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:
|
if k in info:
|
||||||
self.info[k] = info[k]
|
self.info[k] = info[k]
|
||||||
elif k in self.info:
|
elif k in self.info:
|
||||||
|
@ -929,17 +933,18 @@ def _get_global_header(im, info):
|
||||||
# Global Color Table
|
# Global Color Table
|
||||||
_get_header_palette(palette_bytes),
|
_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"]
|
comment = info["comment"]
|
||||||
if isinstance(comment, str):
|
if isinstance(comment, str):
|
||||||
comment = comment.encode()
|
comment = comment.encode()
|
||||||
header.append(b"!" + o8(254)) # extension intro
|
|
||||||
for i in range(0, len(comment), 255):
|
for i in range(0, len(comment), 255):
|
||||||
subblock = comment[i : i + 255]
|
subblock = comment[i : i + 255]
|
||||||
header.append(o8(len(subblock)) + subblock)
|
comment_block += o8(len(subblock)) + subblock
|
||||||
header.append(o8(0))
|
|
||||||
|
|
||||||
|
comment_block += o8(0)
|
||||||
|
header.append(comment_block)
|
||||||
return header
|
return header
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user