-
Bug reportDescribe the bug Re-encoding certain large JPEG images (typically stitched panoramas) with: v.write_to_buffer(".jpg")fails consistently with: VipsJpeg: out of order read at line XXXXThe images load correctly in libvips, PIL, and OpenCV, and they encode correctly to WebP and PNG. To Reproduce
width: 7527
height: 2714
format: JPEG (stitched panorama)
import io
import pyvips
from PIL import Image
path = "image.jpg"
print("---- PIL TEST ----")
try:
img = Image.open(path)
img.load()
print("PIL OK:", img.size, img.mode)
except Exception as e:
print("PIL ERROR:", e)
print("\n---- PYVIPS LOAD TEST ----")
try:
v = pyvips.Image.new_from_file(path, access="sequential")
print("pyvips OK:", v.width, v.height, v.format, v.bands)
except Exception as e:
print("pyvips LOAD ERROR:", e)
print("\n---- PYVIPS → WEBP ENCODE TEST ----")
try:
webp_bytes = v.write_to_buffer(".webp")
print("pyvips → WebP OK (bytes length:", len(webp_bytes), ")")
except Exception as e:
print("pyvips WEBP ERROR:", e)
print("\n---- PYVIPS → JPEG ENCODE TEST ----")
try:
jpeg_bytes = v.write_to_buffer(".jpg")
print("pyvips → JPEG OK (bytes length:", len(jpeg_bytes), ")")
except Exception as e:
print("pyvips JPEG ERROR:", e)
print("\n---- PYVIPS → TIFF STRICT TEST ----")
try:
v.tiffsave("test_output.tif")
print("pyvips → TIFF OK")
except Exception as e:
print("pyvips TIFF ERROR:", e)
---- PYVIPS → JPEG ENCODE TEST ----
pyvips JPEG ERROR: unable to call VipsForeignSaveJpegTarget
VipsJpeg: out of order read at line 2714
---- PYVIPS → TIFF STRICT TEST ----
pyvips TIFF ERROR: unable to call tiffsaveExpected behavior Actual behavior
VipsJpeg: out of order read at line XXXXEnvironment
Additional Information The first image saves as webp and encodes correctly. The second and third ones fail with the error above. Sizes: 1600, 800, 640. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 1 reply
-
Please can you provide a sample image that allows someone else to reproduce. Please also ensure you are using the latest versions of all dependencies, e.g. latest libvips is v8.17.3. |
Beta Was this translation helpful? Give feedback.
-
|
Hi @wallarug, When you open an image with You have: v = pyvips.Image.new_from_file(path, access="sequential")
... some time later
webp_bytes = v.write_to_buffer(".webp")
...
jpeg_bytes = v.write_to_buffer(".jpg")
...
v.tiffsave("test_output.tif")So the webp save will work, but the jpeg and tiff saves will fail, because the image has vanished by then. The fix would be to either reload the image (this is very fast), or to load once in non-sequential mode. Either this: v = pyvips.Image.new_from_file(path, access="sequential")
webp_bytes = v.write_to_buffer(".webp")
...
v = pyvips.Image.new_from_file(path, access="sequential")
jpeg_bytes = v.write_to_buffer(".jpg")
...
v = pyvips.Image.new_from_file(path, access="sequential")
v.tiffsave("test_output.tif")Or this: v = pyvips.Image.new_from_file(path)
webp_bytes = v.write_to_buffer(".webp")
...
jpeg_bytes = v.write_to_buffer(".jpg")
...
v.tiffsave("test_output.tif")Case 1) will decode the source image each time, but will save memory. Case 2) will decode the image once in the load and reuse it, but will eat a lot of memory. |
Beta Was this translation helpful? Give feedback.
-
|
As @lovell says, it'd be best to use the current versions. You can install the latest stable pyvips and libvips on windows with: That'll automatically download and use the recommended libvips binary for your platform. |
Beta Was this translation helpful? Give feedback.
-
|
Ahem, sorry, last thing, you'll find pillow and libvips are pretty similar in speed for just loading and saving files, since almost all time is spent in the image load and save libraries. You'll only start to see speed and memory differences when you use a single complex operation which benefits from threading (eg. large radius gaussian blur), or when you chain a series of operations together and libvips pipelines them. This example loads a 10k x 10k pixel RGB TIFF, trims 100 pixels of each edge, shrinks by 10%, sharpens and saves again: https://github.com/libvips/libvips/wiki/Speed-and-memory-use Pipelining makes pyvips noticeably quicker than PIL in end-to-end speed. |
Beta Was this translation helpful? Give feedback.

Hi @wallarug,
When you open an image with
access="sequential"you can only scan it once. Imagine if the image is coming over a pipe, for example --- you can get the pixels once, but then they are gone and you can't see them again.You have:
So the webp save will work, but the jpeg and tiff saves will fail, because the image has vanished by then.
The fix would be to either reload the image (this is very fast), or to load once in non-sequential mode.
Either this: