Jacco
Jacco

Reputation: 23799

Efficiently detect corrupted jpeg file?

Is there an efficient way of detecting if a jpeg file is corrupted?

Background info:
  solutions needs to work from within a php script
  the jpeg files are on disk
  manual checking is no option (user uploaded data)

I know that imagecreatefromjpeg(string $filename); can do it. But it is quite slow at doing so.

Does anybody know a faster/more efficient solutions?

Upvotes: 21

Views: 17139

Answers (8)

Tom
Tom

Reputation: 3044

Just a small note- how to get jpeginfo for Windows (64 bit)? There are no win32/win64 binaries on author's github but you can do this:

1) grab jpeginfo.exe from this archive: https://github.com/MoserMichael/cstuff/raw/master/img-archive/img-archive.zip

2) grab cygwin1.dll from this archive: ftp://mirror.internode.on.net/pub/cygwin/x86/release/cygwin64/cygwin64-2.6.0-1.tar.xz

Test it from commandline if it works: jpeginfo --help. If there is info- it works just fine.

How to test jpeginfo output?

jpeginfo returns 0 if the file is ok but it returns 1 not only when it's not but also when it found something it doesn't understand. Then it generates a message like this:

Warning: unknown JFIF revision number 2.01 1280 x 720 24bit JFIF N 122550 [WARNING]

On corrupted files it returns 1 and message like this:

1328 x 2048 24bit JFIF N 1310080 Premature end of JPEG file [WARNING]

Therefore you might want to test the actual output not only return code.

Upvotes: 1

skiptracing
skiptracing

Reputation: 1

Please try it

<?php
$img = $_GET['img'];
$str_exec = 'jpeginfo -c /chroot/home/www/html/media/'.$img;
$result = exec($str_exec);
if(strpos($result, 'ERROR'))
{
    echo 'ERROR';
}
else
{
    echo 'OK';
}
?>

Upvotes: 0

T-prod
T-prod

Reputation: 191

I have an other solution with a simply getimagesize()

if(!getimagesize($image_url)) echo 'Image is corrupt or not readable';

Upvotes: -3

Travis
Travis

Reputation: 497

FYI -- I've used the method above (jpeg_file_is_complete) to test JPEGs which I know are corrupt (when I load them in a browser, for example, the bottom is gray -- i.e., the image is "cut off"). Anyhow, when I ran the above test on that image it DID NOT detect it as corrupt.

So far, using imagecreatefromjpeg() works, but is not very fast. I found that using jpeginfo works as well to detect these types of corrupt images, and is FASTER than imagecreatefromjpeg (I ran a benchmark in my PHP using microtime()).

Upvotes: 7

Stefan V
Stefan V

Reputation: 33

Solution:

I found the perfect tool for what I needed:

http://www.thomasbarker.co.uk/2011/05/29/corrupt-jpeg-checkertool-for-finding-corrupt-jpeg-image-files/

Searches recursively through a directory and finds any corrupted JPEGS. Looks like you can use as many CPUs as you like to do it also.

Worked for me.

Upvotes: -1

fireweasel
fireweasel

Reputation: 349

My simplest (and fastest) solution:


function jpeg_file_is_complete($path) {
    if (!is_resource($file = fopen($path, 'rb'))) {
        return FALSE;
    }
    // check for the existence of the EOI segment header at the end of the file
    if (0 !== fseek($file, -2, SEEK_END) || "\xFF\xD9" !== fread($file, 2)) {
        fclose($file);
        return FALSE;
    }
    fclose($file);
    return TRUE;
}

function jpeg_file_is_corrupted($path) {
    return !jpeg_file_is_complete($path);
}

Note: This only detects a corrupted file structure, but does NOT detect corrupted image data.

Upvotes: 9

mloskot
mloskot

Reputation: 38940

You may also try to generate file hash based on MD5 and use it as checksum to validate JPEG data on various steps. For example, after read from file, then after transfer, etc.

Upvotes: -1

Pat
Pat

Reputation: 36702

From the command line you can use jpeginfo to find out if a jpeg file is OK or not.

$ jpeginfo -c test.jpeg

test.jpeg 260 x 264 24bit JFIF N 15332 [OK]

It should be trivial to call jpeginfo from php.

Upvotes: 18

Related Questions