views:

1688

answers:

4

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?

+4  A: 

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.

Pat
note the remark from the OP about slow: forking an external process and process the return is possibly even slower than imagecreatefromjpeg()!
Wimmer
You might be right, I have no idea how slow imagecreatefromjpeg is. I suppose the only way to find it to benchmark both.
Pat
+1  A: 

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.

fireweasel
I will take a look at that, thanks
Jacco
A: 

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.

mloskot
+1  A: 

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()).

-T

Travis
thanks, checking the jpeg_file_is_complete() functionality was still on my list of things to do. saves me the time :)
Jacco
A quick follow-up. I've been successfully using "jpeginfo" to test JPGs and it has worked great. It's fast and does not give false positives.
Travis