libvips / php-vips

php binding for libvips
MIT License
615 stars 25 forks source link

Best way to check whether an image is corrupted? #155

Closed gabrieleolmi closed 2 years ago

gabrieleolmi commented 2 years ago

I tried to thumbnail a corrupted image but vips didn't throw any exceptions. Is there any way to detect a corrupted image?

jcupitt commented 2 years ago

Hello @GabrieleOlmi,

By default, thumbnail is permissive and will try to get any image data it can.

You can set fail_on to control the types of error that will make it fail. You can use the values none (the default), truncated, error, and warning. Docs here:

https://www.libvips.org/API/current/libvips-resample.html#vips-thumbnail

Eg.:

$ head -c 20000 k2.jpg > truncated.jpg
$ vips thumbnail truncated.jpg x.jpg 200 --fail-on warning

(vips:2019997): VIPS-WARNING **: 12:47:03.592: error in tile 0 x 32

(vips:2019997): VIPS-WARNING **: 12:47:03.592: error in tile 0 x 0

(vips:2019997): VIPS-WARNING **: 12:47:03.592: error in tile 0 x 10
VipsJpeg: Premature end of input file
$ echo $?
1
$ vips thumbnail truncated.jpg x.jpg 200 

(vips:2020041): VIPS-WARNING **: 12:47:13.428: read gave 2 warnings

(vips:2020041): VIPS-WARNING **: 12:47:13.428: VipsJpeg: Premature end of JPEG file

$ echo $?
0
gabrieleolmi commented 2 years ago

Thanks, i used 'fail_on' => 'warning' as an option in the thumbnail function and now it can detect corrupted images

gabrieleolmi commented 2 years ago

@jcupitt How do i make sure that Vips\Image::thumbnail() uses the mozjpeg library to convert jpg files? Is it enough to run this docker file? https://github.com/jcupitt/docker-builds/tree/master/libvips-mozjpeg-ubuntu20.04

jcupitt commented 2 years ago

Yes, that should work. I'd tweak the dockerfile a bit for your needs, of course.

gabrieleolmi commented 2 years ago

Thanks, you would be doing me a big favor.

jcupitt commented 2 years ago

I mean: if I were you I would adjust the dockerfile a bit. I don't know what your needs are, so I can't do it.

gabrieleolmi commented 2 years ago

I took a cue from the dockerfile to install libvips with mozjpeg without using docker containers. vipsthumbnail with the mozjpeg optimizations works only from cli. When i run this php code:

$image = Vips\Image::thumbnail($inputImagePath, $width, ['height' => $height, 'crop' => 'centre', 'fail_on' => 'warning', 'optimize-scans' => true, 'trellis-quant' => true, 'quant_table' => 3]);
$image->writeToFile($outputImagePath, ['Q' => $quality, 'optimize-coding' => true, 'strip' => true, 'interlace' => true]);

libvips returns an error: Jcupitt\Vips\Exception: optional argument 'optimize-scans' does not exist I have the latest libvips and php-libvips version

jcupitt commented 2 years ago

I would guess you probably have two libvipses on your system and the webserver php is picking up the wrong one.

Getting the system php to pick up a home-made library is a little tricky (they make it like this for security). You'll probably need to set LD_LIBRARY_PATH. There's a php-vips patch that makes this a bit easier here, but no one's tested it yet:

https://github.com/libvips/php-vips/issues/140#issuecomment-1271481353

kleisauke commented 2 years ago

Was this tested with commit https://github.com/libvips/php-vips/commit/fad7f0a34ffc1bfac05d9250ecaef4b35fa75159? Otherwise, the - as a component separator doesn't work.

Also, those MozJPEG options are part of vips_jpegsave(), so they should be be moved to ->writeToFile() instead.

@@ -4,13 +4,15 @@ $image = Vips\Image::thumbnail($inputImagePath, $width, [
     'height' => $height,
     'crop' => 'centre',
     'fail_on' => 'warning',
-    'optimize-scans' => true,
-    'trellis-quant' => true,
-    'quant_table' => 3,
 ]);
 $image->writeToFile($outputImagePath, [
     'Q' => $quality,
-    'optimize-coding' => true,
+    'optimize_coding' => true,
     'strip' => true,
     'interlace' => true,
+    // MozJPEG save options
+    'optimize_scans' => true,
+    'trellis_quant' => true,
+    'overshoot_deringing' => true,
+    'quant_table' => 3,
 ]);
gabrieleolmi commented 2 years ago

LD_LIBRARY_PATH = /opt/mozjpeg/lib64

This code works:

$image = Vips\Image::thumbnail($inputImagePath, $width, ['height' => $height, 'crop' => 'centre', 'fail_on' => 'warning']);
$image->writeToFile($outputImagePath, ['Q' => $quality, 'optimize_coding' => true, 'strip' => true, 'interlace' => true, 'optimize_scans' => true, 'trellis_quant' => true, 'overshoot_deringing' => true, 'quant_table' => 3]);

The problem was the dash - you must use the underscore _ as a separator. I saw that commit too and i assumed the code worked with the -