View Source

Decoding a JP2 that contains an embedded ICC profile with OpenJPEG 1.5 (command-line tool) results in a degraded output image. Original test data [here|^|].

h2.Source image
We're starting with the image below, which is a losslessly compressed JP2 that was created from a source TIFF using Aware's encoder:


Below is a summary of the image's main characteristics (extracted with ExifTool 8.99):
File Name : target.jp2
File Type : JP2
Image Height : 303
Image Width : 437
Number Of Components : 3
Bits Per Component : 8 Bits, Unsigned
Compression : JPEG 2000
Color Spec Method : Restricted ICC
Profile Description : eciRGB v2

Note that the image contains an embedded ICC profile, which I'll get back to later.

h2. Decoding the image
So let's decode this back to TIFF using the latest version (1.5.0) of OpenJPEG. I used following command line:

{{j2k_to_image -i target.jp2 -o target_oj.tif}}

This is what the resulting image looks like (not a pretty sight):


Although the visual check really says enough, I also used ImageMagick's compare tool to count the number of pixels tht are changed, relative to the source image. For this I used the following command (note I used the upstream source TIFF from which the JP2 was created rather than the actualJP2 as a reference; this is because I encountered problems getting the latest version of IM to work with JPEG 2000, don't ask why!):

{{compare -metric AE -verbose target.tif target_oj.tif diff.tif}}

red: 132411
green: 132411
blue: 132411
all: 132411
I.e. all pixels have been changed.

As a control, I repeated the same conversion in Irfanview, which resulted in this:


Again I counted the number of changed pixels:

{{compare -metric AE -verbose target.tif target_iv.tif diff.tif}}

red: 0
green: 0
blue: 0
all: 0
I.e. all pixel values are unchanged relative to the source image (note that neither OpenJEG nor IrfanViewpreserved the ICC profile, although this isn't really important here).

h2. Behaviour without embedded ICC profile
As I was wondering whether the embedded ICC might have anything to do with these results, I also created a version of the JP2 with the ICC profile removed, and then decoded the image with OpenJPEG again:

{{j2k_to_image -i target_noICC.jp2 -o target_noICC_oj.tif}}

Here's the resulting image:


Now that looks more like it! So let's compare the pixel values again:

{{compare -metric AE -verbose target.tif target_noICC_oj.tif diff.tif}}

red: 0
green: 0
blue: 0
all: 0
I.e. all pixel values are unchanged relative to the source image!

So apparently something goes wrong when OpenJPEG tries to decode a JP2 whose colour space is defined by an ICC profile. This results in a degraded output image where the pixel values of the original source image are not preserved.

h2. Test data

h3. Download link


h3. Upstream source image

h3. JP2 source images
target.jp2 - created from target.tif
target_noICC.jp2 - same, without ICC profile

h3. Decoded images
target_oj.tif - decoded from target.jp2 using OpenJPEG
target_iv.tif - decoded from target.jp2 using IrfanView
target_noICC_oj.tif - decoded from target_noICC.jp2 using OpenJPEG

h2. System information
OS Name: Microsoft Windows XP Professional
OS Version: 5.1.2600 Service Pack 3 Build 2600
OS Configuration: Member Workstation
OS Build Type: Multiprocessor Free
System type: X86-based PC
Processor(s): 1 Processor(s) Installed.
[01]: x86 Family 15 Model 6 Stepping 5 GenuineIntel ~2992 Mhz
BIOS Version: HPQOEM - 20070413
Total Physical Memory: 999 MB
Available Physical Memory: 138 MB
Virtual Memory: Max Size: 2,048 MB

h2. Update
The December 2012 Windows binaries of OpenJPEG 2.0 show the same behaviour (using {{opj_decompress}}).