Menu

Home

StephenG

JLibJPEG is a small Java class interfacing to C code using JNI. Ut is designed to load large JPEGs as quickly as possible.

JPEG images are a major, perhaps the major, image file type used in applications. Java's standard methods for loadig a JPEG to a BufferedImage are very slow. This is particularl;y frsutrating if you want to develop applications that view the large image files from modern cameras. JLibJPEG tries to address this by providing an explicit call to load JPEGs.

JLibJPEG should work with both RGB and B&W images - it has been tested with both.

Performance tests on the developer's system using an AMD A8 APU indicate a speedup of up to a factor of ten over ImageIO for a 16Mp JPEG straight from a digital camera. The smaller the image, the less the gain. In practical terms this made the difference between a photo viewer application that could flip between images ona key stroke and one that had serious lag when images were switched.

Using JLibJPEG

Using JLIbJPEG is very simple - it's just one call to a static method. For example ;

BufferedImage bi = JLibJPEG.loadImage( "location/name.jpg" ) ;

The loadImage() method returns null if the load operation fails for any reason. No exceptions should be thrown.

Building JLibJPEG

To build JLibJPEG you first need to compile the Java file and then use that to build the C include file with javah. Finally you compile the C file with the native code. This is an example from the developer's own system :

javac JLibJPEG.java

javah -jni JLibJPEG

jar cf JLibJPEG.jar *.class

gcc -g -shared -fPIC -I/usr/lib/jvm/java-7-openjdk-amd64/include -o libJLibJPEG.so JLibJPEG.c -ljpeg

The resulting JAR and shared library files need to be on your application's classpath to use them, of course.

A test java file is also available

Under The Hood

JLibJPEG uses standard Java and C calls and invokes only one library - libjpeg. That's a standard library on Linux systems and available for most systems, including MS Windows. Most systems use the libjpeg-turbo fork in practice.

JLibJPEG exploits the fact that both libjpeg and Java's BUfferedImage class support the image format 3BYTE_BGR ( i.e. each pixel being three bytes in the order Blue, Green, Red ). Of course monochrome images are just bytes and this is also supported by BufferedImage.

The C code allows direct access to the libjpeg decoder.

Note that the Java VM has one frustration that cannot easily be avoided. To pass the decoded JPEG data to Java we must use a byte array. To safely allocate this and not risk issues with the JVM we unfortunately need to allocate the byte array through Java and Java will always ( and unavoidably ) zero every single byte when we allocate. There is no safe way around this ( although there is at least one very unsafe way around it ). This means that we're first zeroing every byte in our multi-megapixel image array and immediately writing over all those zeros when we decode the JPEG. Unless the Java VM is extended to add support for non-zering allocations at some point in the future, we're stuck with this waste of time. Despite this, JLibJPEG can still provide a considerable increase in load times, especially when coupled with libjpeg-turbo ( the Linux default ).

Project Members:


MongoDB Logo MongoDB