Skip to content

Commit 22d9095

Browse files
committed
Correct placement of GIF comment
Place GIF comment after Global Color table. Should go after "NETSCAPE" looping extension after pull #6211.
1 parent c4325c8 commit 22d9095

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

Tests/test_file_gif.py

+23
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,29 @@ def test_zero_comment_subblocks():
813813
assert_image_equal_tofile(im, TEST_GIF)
814814

815815

816+
def test_write_comment(tmp_path):
817+
out = str(tmp_path / "temp.gif")
818+
with Image.open("Tests/images/multiple_comments.gif") as im:
819+
im.save(out, save_all=True, comment="Test")
820+
with Image.open(out) as reread:
821+
# Comments written should appear only in first frame
822+
assert reread.info["comment"] == b"Test"
823+
for i, frame in enumerate(ImageSequence.Iterator(reread)):
824+
assert (i == 0 and frame.info["comment"] == b"Test" or
825+
i != 0 and "comment" not in frame.info)
826+
827+
828+
def test_write_no_comment(tmp_path):
829+
out = str(tmp_path / "temp.gif")
830+
with Image.open("Tests/images/multiple_comments.gif") as im:
831+
# Empty comment="" arg should suppress all comments
832+
im.save(out, save_all=True, comment="")
833+
with Image.open(out) as reread:
834+
assert "comment" not in reread.info
835+
for frame in ImageSequence.Iterator(reread):
836+
assert "comment" not in frame.info
837+
838+
816839
def test_version(tmp_path):
817840
out = str(tmp_path / "temp.gif")
818841

src/PIL/GifImagePlugin.py

+13-10
Original file line numberDiff line numberDiff line change
@@ -715,15 +715,6 @@ def _write_local_header(fp, im, offset, flags):
715715
+ o8(0)
716716
)
717717

718-
if "comment" in im.encoderinfo and 1 <= len(im.encoderinfo["comment"]):
719-
fp.write(b"!" + o8(254)) # extension intro
720-
comment = im.encoderinfo["comment"]
721-
if isinstance(comment, str):
722-
comment = comment.encode()
723-
for i in range(0, len(comment), 255):
724-
subblock = comment[i : i + 255]
725-
fp.write(o8(len(subblock)) + subblock)
726-
fp.write(o8(0))
727718
if "loop" in im.encoderinfo:
728719
number_of_loops = im.encoderinfo["loop"]
729720
fp.write(
@@ -929,7 +920,7 @@ def _get_global_header(im, info):
929920
palette_bytes = _get_palette_bytes(im)
930921
color_table_size = _get_color_table_size(palette_bytes)
931922

932-
return [
923+
header = [
933924
b"GIF" # signature
934925
+ version # version
935926
+ o16(im.size[0]) # canvas width
@@ -943,6 +934,18 @@ def _get_global_header(im, info):
943934
_get_header_palette(palette_bytes),
944935
]
945936

937+
if "comment" in info and len(info["comment"]):
938+
comment = info["comment"]
939+
if isinstance(comment, str):
940+
comment = comment.encode()
941+
header.append(b"!" + o8(254)) # extension intro
942+
for i in range(0, len(comment), 255):
943+
subblock = comment[i : i + 255]
944+
header.append(o8(len(subblock)) + subblock)
945+
header.append(o8(0))
946+
947+
return header
948+
946949

947950
def _write_frame_data(fp, im_frame, offset, params):
948951
try:

0 commit comments

Comments
 (0)