Skip to content

"ValueError: tile cannot extend outside image" for JPEG files exported from macOS Photos app #9204

Description

@gcox

What did you do?

I'm using Pillow indirectly through another framework that, when encountering a multi-frame image, iterates over the frames in the image, seeks to each one, and creates a copy of each for further processing using img.copy().

I found that an exception is thrown when processing certain jpeg images. Specifically, when a photo has been exported from the macOS Photos app and the output width was limited to something smaller than the original image.

When exporting images as JPEG from the Photos app, it produces files that include two frames:

  • Frame 0: Mode = RGB
  • Frame 1: Mode = L

For the example image, the original size of the image was 3024x4032.

When exporting and keeping the original size, the two frames are:

  • Frame 0: Mode = RGB, Size = 3024x4032
  • Frame 1: Mode = L, Size = 1512x2016

For the example image, I exported it with a custom width of 1024, and the two frames in the resulting image are:

  • Frame 0: Mode = RGB, Size = 1024x1366
  • Frame 1: Mode = L, Size = 1512x2016

It seems that frame 1 being larger than frame 0 is a problem.

What did you expect to happen?

No exception to be thrown when iterating over the individual frames, seeking to them, and calling img.copy()

What actually happened?

An exception is thrown when calling im.copy() after seeking to the second frame *if the second frame's dimensions are larger than the first frame's.

What are your OS, Python and Pillow versions?

  • OS: macOS 15.6.1
  • Python: 3.12.11 - 3.13.7 (all I've tried)
  • Pillow: 11.3+

Reproduction

  • Copy the example image at the bottom into Tests/images as jpeg_tile_error.jpeg
  • Add and run the following test case.
  • An exception is thrown when calling im.copy() on the second frame.
TEST_FILE = "Tests/images/jpeg_tile_error.jpeg"

@skip_unless_feature("jpg")
class TestFileJpegTileError:
    def test_copy(self) -> None:
        # Test img.copy()
        with Image.open(TEST_FILE) as im:
            assert isinstance(im, JpegImagePlugin.JpegImageFile)
            if hasattr(im, "n_frames") and im.n_frames > 1:
                for i in range(im.n_frames):
                    im.seek(i)
                    print(f"Frame {i}, size: {im.size}, mode: {im.mode}, format: {im.format}, get_format_mimetype: {im.get_format_mimetype()}")
                    im_copy = im.copy()
Example Image (jpeg_tile_error.jpeg)

Image

Activity

  1. changed the title [-]"ValueError: tile cannot extend outside image" for JPEG files exported from macOS Photos app.[/-] [+]"ValueError: tile cannot extend outside image" for JPEG files exported from macOS Photos app[/+] on Sep 13, 2025
  2. radarhere commented on Sep 14, 2025

    @radarhere
    Member

    Hi. I tried following your instructions to generate a new image with the problem, but couldn't. Are you able to create an image that we can include in our test suite, and distribute under the Pillow license, that is as small as you can make it? 0.5mb is a bit large.

  3. gcox commented on Sep 14, 2025

    @gcox
    Author

    @radarhere Yes. I cropped the original, and exported with a width of 56. Here you go:

    Size: 15 KB
    Dimensions (Frame 0): 56x70
    Dimensions (Frame 1): 349x434

    Image

  4. radarhere commented on Sep 15, 2025

    @radarhere
    Member

    Thanks. I've created #9208 to resolve this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions