Skip to content

Commit c22230b

Browse files
authored
Use save parameters as encoderinfo defaults (#9001)
2 parents da10ed1 + d4162f8 commit c22230b

File tree

5 files changed

+37
-13
lines changed

5 files changed

+37
-13
lines changed

Tests/test_file_mpo.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -317,13 +317,24 @@ def test_save_all() -> None:
317317
def test_save_xmp() -> None:
318318
im = Image.new("RGB", (1, 1))
319319
im2 = Image.new("RGB", (1, 1), "#f00")
320+
321+
def roundtrip_xmp() -> list[Any]:
322+
im_reloaded = roundtrip(im, xmp=b"Default", save_all=True, append_images=[im2])
323+
xmp = [im_reloaded.info["xmp"]]
324+
im_reloaded.seek(1)
325+
return xmp + [im_reloaded.info["xmp"]]
326+
327+
# Use the save parameters for all frames by default
328+
assert roundtrip_xmp() == [b"Default", b"Default"]
329+
330+
# Specify a value for the first frame
331+
im.encoderinfo = {"xmp": b"First frame"}
332+
assert roundtrip_xmp() == [b"First frame", b"Default"]
333+
del im.encoderinfo
334+
335+
# Specify value for the second frame
320336
im2.encoderinfo = {"xmp": b"Second frame"}
321-
im_reloaded = roundtrip(im, xmp=b"First frame", save_all=True, append_images=[im2])
337+
assert roundtrip_xmp() == [b"Default", b"Second frame"]
322338

323339
# Test that encoderinfo is unchanged
324340
assert im2.encoderinfo == {"xmp": b"Second frame"}
325-
326-
assert im_reloaded.info["xmp"] == b"First frame"
327-
328-
im_reloaded.seek(1)
329-
assert im_reloaded.info["xmp"] == b"Second frame"

Tests/test_file_tiff.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -681,16 +681,21 @@ def test_rowsperstrip(self, tmp_path: Path) -> None:
681681
assert im.tag_v2[278] == 256
682682

683683
im = hopper()
684+
im.encoderinfo = {"tiffinfo": {278: 100}}
684685
im2 = Image.new("L", (128, 128))
685-
im2.encoderinfo = {"tiffinfo": {278: 256}}
686-
im.save(outfile, save_all=True, append_images=[im2])
686+
im3 = im2.copy()
687+
im3.encoderinfo = {"tiffinfo": {278: 300}}
688+
im.save(outfile, save_all=True, tiffinfo={278: 200}, append_images=[im2, im3])
687689

688690
with Image.open(outfile) as im:
689691
assert isinstance(im, TiffImagePlugin.TiffImageFile)
690-
assert im.tag_v2[278] == 128
692+
assert im.tag_v2[278] == 100
691693

692694
im.seek(1)
693-
assert im.tag_v2[278] == 256
695+
assert im.tag_v2[278] == 200
696+
697+
im.seek(2)
698+
assert im.tag_v2[278] == 300
694699

695700
def test_strip_raw(self) -> None:
696701
infile = "Tests/images/tiff_strip_raw.tif"

src/PIL/Image.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2556,8 +2556,9 @@ def save(
25562556
self.load()
25572557

25582558
save_all = params.pop("save_all", None)
2559+
self._default_encoderinfo = params
25592560
encoderinfo = getattr(self, "encoderinfo", {})
2560-
self.encoderinfo = {**encoderinfo, **params}
2561+
self._attach_default_encoderinfo(self)
25612562
self.encoderconfig: tuple[Any, ...] = ()
25622563

25632564
if format.upper() not in SAVE:
@@ -2599,6 +2600,11 @@ def save(
25992600
if open_fp:
26002601
fp.close()
26012602

2603+
def _attach_default_encoderinfo(self, im: Image) -> dict[str, Any]:
2604+
encoderinfo = getattr(self, "encoderinfo", {})
2605+
self.encoderinfo = {**im._default_encoderinfo, **encoderinfo}
2606+
return encoderinfo
2607+
26022608
def seek(self, frame: int) -> None:
26032609
"""
26042610
Seeks to the given frame in this sequence file. If you seek

src/PIL/MpoImagePlugin.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
6969
JpegImagePlugin._save(im_frame, fp, filename)
7070
offsets.append(fp.tell())
7171
else:
72+
encoderinfo = im_frame._attach_default_encoderinfo(im)
7273
im_frame.save(fp, "JPEG")
74+
im_frame.encoderinfo = encoderinfo
7375
offsets.append(fp.tell() - offsets[-1])
7476

7577
ifd = TiffImagePlugin.ImageFileDirectory_v2()

src/PIL/TiffImagePlugin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2311,8 +2311,7 @@ def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
23112311
try:
23122312
with AppendingTiffWriter(fp) as tf:
23132313
for ims in [im] + append_images:
2314-
if not hasattr(ims, "encoderinfo"):
2315-
ims.encoderinfo = {}
2314+
encoderinfo = ims._attach_default_encoderinfo(im)
23162315
if not hasattr(ims, "encoderconfig"):
23172316
ims.encoderconfig = ()
23182317
nfr = getattr(ims, "n_frames", 1)
@@ -2322,6 +2321,7 @@ def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
23222321
ims.load()
23232322
_save(ims, tf, filename)
23242323
tf.newFrame()
2324+
ims.encoderinfo = encoderinfo
23252325
finally:
23262326
im.seek(cur_idx)
23272327

0 commit comments

Comments
 (0)