diff --git a/Tests/test_file_gif.py b/Tests/test_file_gif.py index 3c2fab722..1bd772dc6 100644 --- a/Tests/test_file_gif.py +++ b/Tests/test_file_gif.py @@ -813,6 +813,29 @@ def test_zero_comment_subblocks(): assert_image_equal_tofile(im, TEST_GIF) +def test_write_comment(tmp_path): + out = str(tmp_path / "temp.gif") + with Image.open("Tests/images/multiple_comments.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/multiple_comments.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): out = str(tmp_path / "temp.gif") diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index 9b34a3b0e..4d785d834 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -715,15 +715,6 @@ def _write_local_header(fp, im, offset, flags): + o8(0) ) - if "comment" in im.encoderinfo and 1 <= len(im.encoderinfo["comment"]): - fp.write(b"!" + o8(254)) # extension intro - comment = im.encoderinfo["comment"] - if isinstance(comment, str): - comment = comment.encode() - for i in range(0, len(comment), 255): - subblock = comment[i : i + 255] - fp.write(o8(len(subblock)) + subblock) - fp.write(o8(0)) if "loop" in im.encoderinfo: number_of_loops = im.encoderinfo["loop"] fp.write( @@ -929,7 +920,7 @@ def _get_global_header(im, info): palette_bytes = _get_palette_bytes(im) color_table_size = _get_color_table_size(palette_bytes) - return [ + header = [ b"GIF" # signature + version # version + o16(im.size[0]) # canvas width @@ -943,6 +934,18 @@ def _get_global_header(im, info): _get_header_palette(palette_bytes), ] + 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)) + + return header + def _write_frame_data(fp, im_frame, offset, params): try: