Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use libjpeg to read JPEGs with an alpha channel?

There seems to be some debate about whether JPEGs with alpha channels are valid or not. The answer I had always understood to be correct is that in the JPEG FAQ, which is essentially "No". (This is reiterated in another question on Stack Overflow.)

However, Java's JPEGImageWriter in Sun's ImageIO library will happily write and read grayscale and RGB images with an alpha channel, even though there are virtually no applications on Linux I've tried so far that will load such JPEGs correctly. This has been reported in the past as a bug, but Sun's response is that these are valid files:

This is not an Image I/O bug, but rather a deficiency in the other applications the submitter mentions. The IIO JPEGImageWriter is able to write images with a color model that contains an alpha channel (referred to in the IJG native source code as the "NIFTY" color spaces, such as RGBA, YCbCrA, etc.), but many applications are not aware of these color spaces. So even though these images written by the IIO JPEG writer are compliant with the JPEG specification (which is blind to the various color space possiblities), some applications may not recognize color spaces that contain an alpha channel and may throw an error or render a corrupted image, as the submitter describes.

Developers wishing to maintain compatibility with these other alpha-unaware applications should write images that do not contain an alpha channel (such as TYPE_INT_RGB). Developers who want the capability of writing/reading an image containing an alpha channel in the JPEG format can do so using the Image I/O API, but need to be aware that many native applications out there are not quite compliant with the YCbCrA and RGBA formats.

For more information, see the Image I/O JPEG Metadata Format Specification and Usage Notes: http://java.sun.com/j2se/1.4.1/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html

Closing as "not a bug". xxxxx@xxxxx 2003-03-24

I'm working with a Java application that creates files like these, and want to write some C code that will load these as fast as possible. (Essentially the problem is that the Java ImageIO library is remarkably slow at decompressing these files, and we would like to replace the loader with native code via JNI that improves this - it's a performance bottleneck at the moment.)

There are some example files here - apologies to anyone who's coulrophobic:

  • http://mythic-beasts.com/~mark/example-jpegs/

And here you can see the results of trying to view the grayscale+alpha and RGB+alpha images with various bit of Linux software that I believe use libjpeg:

grayscale image with alpha channel view with various programs http://mythic-beasts.com/~mark/all-alpha-bridges.png

RGB image with alpha channel view with various programs
(source: mark at mythic-beasts.com)

So it looks as if the color space is just being misinterpreted in each case. The only allowed values in jpeglib.h are:

/* Known color spaces. */

typedef enum {
        JCS_UNKNOWN,            /* error/unspecified */
        JCS_GRAYSCALE,          /* monochrome */
        JCS_RGB,                /* red/green/blue */
        JCS_YCbCr,              /* Y/Cb/Cr (also known as YUV) */
        JCS_CMYK,               /* C/M/Y/K */
        JCS_YCCK                /* Y/Cb/Cr/K */
} J_COLOR_SPACE;

... which doesn't look promising.

If I load these images with a slightly modified version of example.c from libjpeg, the values of cinfo.jpeg_color_space and cinfo.out_color_space for each image after reading the header are as follows:

gray-normal.jpg: jpeg_color_space is JCS_GRAYSCALE, out_color_space is JCS_GRAYSCALE
gray-alpha.jpg: jpeg_color_space is JCS_CMYK, out_color_space is JCS_CMYK

rgb-normal.jpg: jpeg_color_space is JCS_YCbCr, out_color_space is JCS_RGB
rgb-alpha.jpg: jpeg_color_space is JCS_CMYK, out_color_space is JCS_CMYK

So, my questions are:

  • Can libjpeg be used to correctly read these files?
  • If not, is there an alternative C library I can use which will cope with them?

Obviously there are at least two other solutions to the more general problem:

  1. Change the software to output normal JPEGs + a PNG file representing the alpha channel
  2. Somehow improve the performance of Sun's ImageIO

... but the first would involve a lot of code changes, and it's not clear how to go about the latter. In any case, I think that the question of how to use libjpeg to load such files is likely to be one of more general interest.

Any suggestions would be much appreciated.

like image 973
Mark Longair Avatar asked Jun 02 '11 09:06

Mark Longair


1 Answers

Even if you store your images as 4 channel jpeg images, there's no standardized way I know of how to specify the color format in the jpeg file.

The JFIF standard assumes YCbCr.

like image 154
onemasse Avatar answered Sep 30 '22 02:09

onemasse