| scyjdv 2004-10-25, 11:31 am |
| Hi,
I've tried decompressing JPEG-compressed raster data using both
javax.imageio.plugins.jpeg.* (together with the general javax.imageio.* infrastructure) and the IJG jpeglib C code, but both of these keep swapping RGB band ordering of my images to BGR ordering.
The only way I've found to work around this is to specify
JPEGImageReadParam.setSourceBands([b,g,r]), where b, g, and r correspond to the band offsets for blue, green, and red bands. Just to give a bit of context, I've also implemented JPEG compression, which is how I get the raster data to be compressed in the first place. During the JPEG compression process I specify a ComponentSampleModel with the band offsets [r,g,b]. I know that the JPEG compression works correctly, because the compressed data can be viewed in a standard browser with the correct colors.
My questions: Is the color swapping in JPEG decompression a known issue? Why does JPEG decompression keep reversing the bands internally? Is it something with my usage of the API? Is my workaround valid, or does it just "cure the symptoms" without fixing the underlying problem?
If anyone can please help me out in getting to the bottom of this, I would really appreciate it.
Thanks,
C.
(My decompression code is below. Just before I call this function, I write the data in bis to a file and successfully display it in a standard browser with correct colors, so I am assuming that my compress function is correct and I therefore have not included the compression code. )
public static void decompress(BinaryInputStream bis, BinaryOutputStream bos)
{
ImageReadParam ep = null;
ImageReader imread = null;
ImageInputStream iis = null;
JPEGEncodeParam ep1 = null;
JPEGQTable[] qtbl_new = null;
JPEGHuffmanTable[] dchuff = null;
JPEGHuffmanTable[] achuff = null;
byte[] outBuffer = null;
int numBands = 3; //hard coded for clarity
int method = JPEG_FULL; //hard coded for clarity, but actually the swapping occurs for both full and abbreviated formats.
try
{
Iterator readers = ImageIO.getImageReadersByFormatName("jpeg");
imread = (ImageReader)readers.next();
ep = imread.getDefaultReadParam();
iis = ImageIO.createImageInputStream(bis);
imread.setInput(iis, true);
qtbl_new = new JPEGQTable[numBands];
dchuff = new JPEGHuffmanTable[numBands];
achuff = new JPEGHuffmanTable[numBands];
double scquality = (double)quality/100.0;
scquality = jpegQualityScaling(scquality);
if ((method == JPEG_ABBREV))
{
for (int z = 0; z < numBands; z++)
{
qtbl_new[z] = JPEGQTable.K2Chrominance.getScaledInstance((float) scquality, true);
dchuff[z] = JPEGHuffmanTable.StdDCChrominance;
achuff[z] = JPEGHuffmanTable.StdACChrominance;
}
((JPEGImageReadParam)ep).setDecodeTables(qtbl_new, dchuff, achuff);
}
int[] bandOffsets = null;
bandOffsets = new int[numBands];
int ii = numBands-1;
for(int i=0; i < numBands; i++)
{
if (numBands == 3)
{
bandOffsets = ii;
ii = ii - 1;
}
else
{
bandOffsets = i;
}
}
((JPEGImageReadParam)ep).setSourceBands(bandOffsets);
BufferedImage decompIm = imread.read(0, ep);
Raster decompRaster = decompIm.getData();
//... snipped irrelevant processing of Raster.
}
catch (Exception ex)
{
try
{
iis.close();
}
catch (Exception ex1)
{
}
qtbl_new = null;
achuff = null;
dchuff = null;
outBuffer = null;
}
} |