For Programmers: Free Programming Magazines  


Home > Archive > Compression > October 2004 > JPEG decompression swaps colors e.g. RGB->BGR???









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author JPEG decompression swaps colors e.g. RGB->BGR???
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;
}
}
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com