Fetching contributors…
Cannot retrieve contributors at this time
63 lines (51 sloc) 4.54 KB


This is another version of the "JJ2000" package, which provides an API for reading and writing JPEG-2000 encoded image data in Java. It is based on the "JAI" branch of the code, but with the JAI dependencies removed so it can be compiled as a standalone package again. The box model has been drastically simplified replacing the very heavy one dating from the JAI code, and simpler classes for reading/writing JPX images have been introduced, that focus on reading/writing to InputStream and OutputStream wherever possible rather than to a File or IIOImage.

How to build

Download and run "ant". The jar "target/jj2000.jar" contains the API code, the "target/test.jar" is a standalone Jar for testing (run "java -jar target/test.jar" for help). There are no external dependencies

How to read a JP2 or JPX image

This will create a PNM from a grayscale or RGB image.

import com.github.jpeg2000.*;

J2KFile file = new J2KFile(); BEBufferedRandomAccessFile(infile, "r", 8192));
J2KReader iin = new J2KReader(file);
OutputStream out = new BufferedOutputStream(new FileOutputStream(outfile));
if (iin.getNumComponents() == 1) {
    out.write(("P5 "+iin.getWidth()+" "+iin.getHeight()+" 255\n").getBytes("ISO-8859-1"));
} else if (iin.getNumComponents() == 3) {
    out.write(("P6 "+iin.getWidth()+" "+iin.getHeight()+" 255\n").getBytes("ISO-8859-1"));
int c;
while (( >= 0) {

How to write a JP2 file

This will create a JP2 from a grayscale or RGB image.

import com.github.jpeg2000.*;

BufferedImage image = ...
J2KWriter writer = new J2KWriter();
writer.setCompressionRatio(8, false);
writer.setSource(image, 256);
writer.write(new FileOutputStream("out.jp2"));


The JJ2000 portion of the code is covered under the JJ2000 license. The JAI portions of the code have mostly been removed, although some contributions to the main body of the API may remain: they are covered under a modified BSD license. The BFO contributions (mainly in com.github.jpeg2000, but again with some contributions to the main body of the API) are licensed under the same modified BSD license.

History (which may be wrong)

The JJ2000 package was originally written by a team from Swiss Federal Institute of Technology-EPFL, Ericsson Radio Systems AB and Canon Research Centre France S.A during 1999-2000 as part of the development of the original JPEG2000 specification. The source code was made available at and the final release there was version 5.1 (this site disappeared around 2010; an archive version is available at

The code was then adopted by Sun as part of their JAI project (Java Advanced Imaging). It was hosted at, with changes made by Sun to fit into their JAI architecture. This eventually shut down too (disappearing completely in 2016 after a long period of bitrot) and the code was migrated to Github and in April 2010, where this fork came from. The JAI project is still active.

The original pre-JAI code from JJ2000 also moved, to From there it was copied to Github at, and probably elsewhere too.

The two codebases diverged slightly; the "ucar" build (derived from the original JJ2000 codebase) had issues with failing to read the last tile from JP2 streams where the number of tiles was listed as one less than required; common in many of our test files. This has been Patched. The "jai" build had issues with an integer overflow, usually causing black blobs on the image. This has also been Patched, although at the time of writing the pull request has not been merged, because maven.

Although the two packages are largely identical in terms of API and functionality, we have found the "JAI" branch to use less memory overall for the kind of files where this is an issue (large, high resolution, single tile images - the differences seems to stem from the changes in jj2000.j2k.codestream.reader.FileBitstreamReaderAgent). So we've chosen to base this branch on that version.