python-3.xpython-imaging-librarytruncated

How to detect if my image is truncated and load it thread-safely?


I have an image processing function which makes an image's thumbnail and gets its width and height. I set LOAD_TRUNCATED_IMAGE = True to load truncated image.

    from PIL import Image, ImageFile

    ImageFile.LOAD_TRUNCATED_IMAGES = True
    try:
        image = Image.open(buffer)
        image = image.convert('RGB')
        ...

    finally:
        ImageFile.LOAD_TRUNCATED_IMAGES = False

But because it's working on multi-thread, that global variable(LOAD_TRUNCATED_IMAGE) does not seem like thread-safe and sometimes fail to load truncated images and raise OSError.

What I want to do is

  1. load truncated image thread safely.
  2. raise OSError to alert the image is truncated.

Is there any way to solve these problem?

I saw related PIL github issue and found that the only way is try-catch. So it would be nice if I can find another way to detect image truncation with or without PIL.


Solution

  • You don't mention the type of your images:


    I can't get near a computer to test, but this should show the last 2 bytes of a JPEG in a BytesIO are ff d9

    from PIL import Image
    from io import BytesIO
    
    # Create black image
    im = Image.new("RGB",(64,48))
    
    # Put into a BytesIO
    bytes = BytesIO()
    im.save(bytes, format="JPEG")
    
    # Check last 2 bytes
    buff = bytes.getbuffer()
    print(buff[-2:].hex())
    

    And likewise for PNG:

    from PIL import Image
    from io import BytesIO
    
    im = Image.new("RGB",(64,48))
    
    bytes = BytesIO()
    im.save(bytes, format="PNG")
    buff = bytes.getbuffer()
    print(buff[-8:].hex())
    

    Alternatively, you can upload a JPEG/PNG to hexed.it and inspect the last few bytes.