private DataBlk forwICT(DataBlk blk, int c)
{
int k, k0, k1, k2, mink, i;
int w = blk.w; //width of output block
int h = blk.h; //height of ouput block
float[] outdata; //array of output data
if (blk.DataType != DataBlk.TYPE_FLOAT)
{
if (outBlk == null || outBlk.DataType != DataBlk.TYPE_FLOAT)
{
outBlk = new DataBlkFloat();
}
outBlk.w = w;
outBlk.h = h;
outBlk.ulx = blk.ulx;
outBlk.uly = blk.uly;
blk = outBlk;
}
//Reference to output block data array
outdata = (float[]) blk.Data;
//Create data array of blk if necessary
if (outdata == null || outdata.Length < w * h)
{
outdata = new float[h * w];
blk.Data = outdata;
}
//If asking for Y, Cb or Cr do transform
if (c >= 0 && c <= 2)
{
int[] data0, data1, data2; // input data arrays
if (block0 == null)
{
block0 = new DataBlkInt();
}
if (block1 == null)
{
block1 = new DataBlkInt();
}
if (block2 == null)
{
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;
// 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;
//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;
switch (c)
{
case 0:
//RGB to Y conversion
for (i = h - 1; i >= 0; i--)
{
for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
{
outdata[k] = 0.299f * data0[k0] + 0.587f * data1[k1] + 0.114f * data2[k2];
}
// Jump to beggining of previous line in input
k0 -= (block0.scanw - w);
k1 -= (block1.scanw - w);
k2 -= (block2.scanw - w);
}
break;
case 1:
//RGB to Cb conversion
for (i = h - 1; i >= 0; i--)
{
for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
{
outdata[k] = (- 0.16875f) * data0[k0] - 0.33126f * data1[k1] + 0.5f * data2[k2];
}
// Jump to beggining of previous line in input
k0 -= (block0.scanw - w);
k1 -= (block1.scanw - w);
k2 -= (block2.scanw - w);
}
break;
case 2:
//RGB to Cr conversion
for (i = h - 1; i >= 0; i--)
{
for (mink = k - w; k > mink; k--, k0--, k1--, k2--)
{
outdata[k] = 0.5f * data0[k0] - 0.41869f * data1[k1] - 0.08131f * data2[k2];
}
// Jump to beggining of previous line in input
k0 -= (block0.scanw - w);
k1 -= (block1.scanw - w);
k2 -= (block2.scanw - w);
}
break;
}
}
else if (c >= 3)
{
// Requesting a component which is not Y, Cb or Cr =>
// just pass the data
// Variables
DataBlkInt indb = new DataBlkInt(blk.ulx, blk.uly, w, h);
int[] indata; // input data array
// Get the input data
// (returned block may be larger than requested one)
src.getInternCompData(indb, c);
indata = (int[]) indb.Data;
// Copy the data converting from int to float
k = w * h - 1;
k0 = indb.offset + (h - 1) * indb.scanw + w - 1;
for (i = h - 1; i >= 0; i--)
{
for (mink = k - w; k > mink; k--, k0--)
{
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
outdata[k] = (float) indata[k0];
}
// Jump to beggining of next line in input
k0 += indb.w - w;
}
// Set the progressivity
blk.progressive = indb.progressive;
blk.offset = 0;
blk.scanw = w;
return blk;
}
else
{
// Requesting a non valid component index
throw new System.ArgumentException();
}
return blk;
}