Skip to content

Commit

Permalink
Handle avifDecoderCreate and avifEncoderCreate errors (#21)
Browse files Browse the repository at this point in the history
* Simplify Python code by receiving tuple from C, as per python-pillow#8740

* Use default PyTypeObject value

* Removed AVIF_TRUE

* Width and height are already set on first frame

* Removed memset

* Depth is set by avifRGBImageSetDefaults

* Replace PyObject with int

* After a failed pixel allocation, destroy non-first frame

* Added error if avifImageCreateEmpty returns NULL

* Python images cannot have negative dimensions

* Test invalid canvas dimensions

* Use boolean format argument

* Handle avifDecoderCreate and avifEncoderCreate errors

* tileRowsLog2 and tileColsLog2 are ignored if autotiling is enabled

* Only define _add_codec_specific_options if it may be used

* Test non-string advanced value

* Simplified error handling in AvifEncoderNew

* Corrected heading

---------

Co-authored-by: Andrew Murray <[email protected]>
  • Loading branch information
radarhere and radarhere authored Feb 12, 2025
1 parent e1509ee commit 0590f08
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 79 deletions.
8 changes: 7 additions & 1 deletion Tests/test_file_avif.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ def test_AvifDecoder_with_invalid_args(self) -> None:
with pytest.raises(TypeError):
_avif.AvifDecoder()

def test_invalid_dimensions(self, tmp_path: Path) -> None:
test_file = str(tmp_path / "temp.avif")
im = Image.new("RGB", (0, 0))
with pytest.raises(ValueError):
im.save(test_file)

def test_encoder_finish_none_error(
self, monkeypatch: pytest.MonkeyPatch, tmp_path: Path
) -> None:
Expand Down Expand Up @@ -461,7 +467,7 @@ def test_encoder_advanced_codec_options(
assert ctrl_buf.getvalue() != test_buf.getvalue()

@skip_unless_avif_encoder("aom")
@pytest.mark.parametrize("advanced", [{"foo": "bar"}, 1234])
@pytest.mark.parametrize("advanced", [{"foo": "bar"}, {"foo": 1234}, 1234])
def test_encoder_advanced_codec_options_invalid(
self, tmp_path: Path, advanced: dict[str, str] | int
) -> None:
Expand Down
5 changes: 3 additions & 2 deletions docs/handbook/image-file-formats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1388,7 +1388,8 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options:

**tile_rows** / **tile_cols**
For tile encoding, the (log 2) number of tile rows and columns to use.
Valid values are 0-6, default 0.
Valid values are 0-6, default 0. Ignored if "autotiling" is set to true in libavif
version **0.11.0** or greater.

**autotiling**
Split the image up to allow parallelization. Enabled automatically if "tile_rows"
Expand All @@ -1412,7 +1413,7 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options:
The XMP data to include in the saved file.

Saving sequences
~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~

When calling :py:meth:`~PIL.Image.Image.save` to write an AVIF file, by default
only the first frame of a multiframe image will be saved. If the ``save_all``
Expand Down
6 changes: 2 additions & 4 deletions src/PIL/AvifImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,9 @@ def _open(self) -> None:
)

# Get info from decoder
width, height, n_frames, mode, icc, exif, exif_orientation, xmp = (
self._size, n_frames, mode, icc, exif, exif_orientation, xmp = (
self._decoder.get_info()
)
self._size = width, height
self.n_frames = n_frames
self.is_animated = self.n_frames > 1
self._mode = mode
Expand Down Expand Up @@ -151,8 +150,6 @@ def _save(
for ims in [im] + append_images:
total += getattr(ims, "n_frames", 1)

is_single_frame = total == 1

quality = info.get("quality", 75)
if not isinstance(quality, int) or quality < 0 or quality > 100:
msg = "Invalid quality setting"
Expand Down Expand Up @@ -232,6 +229,7 @@ def _save(
frame_idx = 0
frame_duration = 0
cur_idx = im.tell()
is_single_frame = total == 1
try:
for ims in [im] + append_images:
# Get # of frames in this image
Expand Down
Loading

0 comments on commit 0590f08

Please sign in to comment.