Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check for corrupted JPEG files in Java

Tags:

java

jpeg

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

like image 279
Lorenzo Cameroni Avatar asked Apr 13 '15 15:04

Lorenzo Cameroni


2 Answers

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)
    }
}
like image 86
Joop Eggen Avatar answered Sep 28 '22 16:09

Joop Eggen


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:

  1. Link my java code to the C++ (C in your case) library using JNI (Java Native Interface).
  2. Translate the C++ library to java code.

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.

like image 38
Shar1er80 Avatar answered Sep 28 '22 17:09

Shar1er80