I need a fast Java way to check if a JPEG file is valid or if it's a truncated / corrupted image.
I tried to do it in a couple of ways:
using the javax.ImageIO library
public boolean check(File image) throws IOException {
    try {
        BufferedImage bi = ImageIO.read(image);
        bi.flush();
    } catch (IIOException e) {
        return false;
    }
    return true;
}
but it can detect only few corrupted files of the ones I have tested and it's very slow (on my PC around 1 image / second).
Apache Commons Imaging library
public boolean check(File image) throws IOException {
    JpegImageParser parser = new JpegImageParser();
    ByteSourceFile bs = new ByteSourceFile(image);
    try {
        BufferedImage bi = parser.getBufferedImage(bs, null);
        bi.flush();
        return true;
    } catch (ImageReadException e) {
        return false;
    }
}
This code can detect all the corrupted images I've tested, but the performances are very poor (on my PC less than 1 image / second).
I'm looking for a Java alternative to the UNIX program jpeginfo which is roughly 10 times faster (on my PC around 10 images / second).
I took a look at the JPEG format, and to my understanding a final EOI (end-of-image) segment of two bytes (FF D9) should be last.
boolean jpegEnded(String path) throws IOException {
    try (RandomAccessFile fh = new RandomAccessFile(path, "r")) {
        long length = fh.length();
        if (length < 10L) { // Or whatever
            return false;
        }
        fh.seek(length - 2);
        byte[] eoi = new byte[2];
        fh.readFully(eoi);
        return eoi[0] == -1 && eoi[1] == -39; // FF D9 (first falsely -23)
    }
}
                        Probably not the best of answers, but...
The jpeginfo program you mentioned is in C. So that brings back memories of when I wanted to use code written by the Navy (That was in C++) in a Java application that I was developing.
I had two options:
Option 1 proved to be difficult to me as I need to pass an object into the library and get object(S) back from the library which forced me to do option 2 (Also, because of deadline scheduling).
So in you're case, because I don't know of any other libraries in Java that would meet your requirements, I would suggest these 2 options, or possibly build your own parser.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With