-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
What did you do?
- Load an APNG with 3 frames with different durations (let us imagine the first frame has a duration of 1ms, the second frame has a duration of 2ms and the third frame has a duration of 3m)
- iterate through the image - looking at the duration supplied by the info dict, output will appropriately be (1ms, 2ms, 3ms)
- do the same thing, output will appropriately be (1ms, 2ms, 3ms)
- do the same thing, output will incorrectly be (3ms, 2ms, 3ms)
What did you expect to happen?
The duration value per frame should be accurate no matter how many times the image is seeked
What actually happened?
After the 2nd loop through the first frame will always have the info attributes of the last frame iterated.
What are your OS, Python and Pillow versions?
- OS: Linux
- Python: 3.12
- Pillow: 10.2.0
The problem is, afaik, specific to APNG. When seeking the Image to the first frame the PngStream goes through a "rewind", in which it assigns the rewind_state (generated on the first read of the first frame) to the current state of the object. However, the rewind state im_info is simply assigned to the current state, not copied. This means the rewind state info object is later modified inadvertently because current and rewind state share the same object.
Pillow/src/PIL/PngImagePlugin.py
Line 381 in a786a05
| self.im_info = self.rewind_state["info"] |
This should be:
self.im_info = self.rewind_state["info"].copy()