private DataBlk invRCT(DataBlk blk, int c)
{
// If the component number is three or greater, return original data
if (c >= 3 && c < NumComps)
{
// Requesting a component whose index is greater than 3
return src.getInternCompData(blk, c);
}
// If asking a component for the first time for this block,
// do transform for the 3 components
else if ((outdata[c] == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly)
|| (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h))
{
int k, k0, k1, k2, mink, i;
int w = blk.w; //width of output block
int h = blk.h; //height of ouput block
//Reference to output block data array
outdata[c] = (int[])blk.Data;
//Create data array of blk if necessary
if (outdata[c] == null || outdata[c].Length != h * w)
{
outdata[c] = new int[h * w];
blk.Data = outdata[c];
}
outdata[(c + 1) % 3] = new int[outdata[c].Length];
outdata[(c + 2) % 3] = new int[outdata[c].Length];
if (block0 == null || block0.DataType != DataBlk.TYPE_INT) block0 = new DataBlkInt();
if (block1 == null || block1.DataType != DataBlk.TYPE_INT) block1 = new DataBlkInt();
if (block2 == null || block2.DataType != DataBlk.TYPE_INT) block2 = new DataBlkInt();
block0.w = block1.w = block2.w = blk.w;
block0.h = block1.h = block2.h = blk.h;
block0.ulx = block1.ulx = block2.ulx = blk.ulx;
block0.uly = block1.uly = block2.uly = blk.uly;
int[] data0, data1, data2; // input data arrays
// Fill in buffer blocks (to be read only)
// Returned blocks may have different size and position
block0 = (DataBlkInt)src.getInternCompData(block0, 0);
data0 = (int[])block0.Data;
block1 = (DataBlkInt)src.getInternCompData(block1, 1);
data1 = (int[])block1.Data;
block2 = (DataBlkInt)src.getInternCompData(block2, 2);
data2 = (int[])block2.Data;
// Set the progressiveness of the output data
blk.progressive = block0.progressive || block1.progressive || block2.progressive;
blk.offset = 0;
blk.scanw = w;
// set attributes of the DataBlk used for buffering
dbi.progressive = blk.progressive;
dbi.ulx = blk.ulx;
dbi.uly = blk.uly;
dbi.w = blk.w;
dbi.h = blk.h;
// Perform conversion
// Initialize general indexes
k = w * h - 1;
k0 = block0.offset + (h - 1) * block0.scanw + w - 1;
k1 = block1.offset + (h - 1) * block1.scanw + w - 1;
k2 = block2.offset + (h - 1) * block2.scanw + w - 1;
for (i = h - 1; i >= 0; i--)
{
for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
{
outdata[1][k] = (data0[k0] - ((data1[k1] + data2[k2]) >> 2));
outdata[0][k] = data2[k2] + outdata[1][k];
outdata[2][k] = data1[k1] + outdata[1][k];
}
// Jump to beggining of previous line in input
k0 -= (block0.scanw - w);
k1 -= (block1.scanw - w);
k2 -= (block2.scanw - w);
}
outdata[c] = null;
}
else if ((c >= 0) && (c < 3))
{
//Asking for the 2nd or 3rd block component
blk.Data = outdata[c];
blk.progressive = dbi.progressive;
blk.offset = (blk.uly - dbi.uly) * dbi.w + blk.ulx - dbi.ulx;
blk.scanw = dbi.w;
outdata[c] = null;
}
else
{
// Requesting a non valid component index
throw new System.ArgumentException();
}
return blk;
}