public virtual CBlkWTData getNextInternCodeBlock(int c, CBlkWTData cblk)
{
int mi, i, j, k, wrap;
int ulx, uly, w, h;
DataBlkInt mask = roiMask; // local copy of mask
int[] maskData; // local copy of mask data
int[] data; // local copy of quantized data
int tmp;
int bitMask = 0x7FFFFFFF;
SubbandAn root, sb;
int maxBits = 0; // local copy
bool roiInTile;
bool sbInMask;
int nROIcoeff = 0;
// Get codeblock's data from quantizer
cblk = src.getNextCodeBlock(c, cblk);
// If there is no ROI in the image, or if we already got all
// code-blocks
if (!roi || cblk == null)
{
return cblk;
}
data = (int[]) cblk.Data;
sb = cblk.sb;
ulx = cblk.ulx;
uly = cblk.uly;
w = cblk.w;
h = cblk.h;
sbInMask = (sb.resLvl <= useStartLevel);
// Check that there is an array for the mask and set it to zero
maskData = mask.DataInt; // local copy of mask data
if (maskData == null || w * h > maskData.Length)
{
maskData = new int[w * h];
mask.DataInt = maskData;
}
else
{
for (i = w * h - 1; i >= 0; i--)
maskData[i] = 0;
}
mask.ulx = ulx;
mask.uly = uly;
mask.w = w;
mask.h = h;
// Get ROI mask from generator
root = src.getAnSubbandTree(tIdx, c);
maxBits = maxMagBits[tIdx][c];
roiInTile = mg.getROIMask(mask, root, maxBits, c);
// If there is no ROI in this tile, return the code-block untouched
if (!roiInTile && (!sbInMask))
{
cblk.nROIbp = 0;
return cblk;
}
// Update field containing the number of ROI magnitude bit-planes
cblk.nROIbp = cblk.magbits;
// If the entire subband belongs to the ROI mask, The code-block is
// set to belong entirely to the ROI with the highest scaling value
if (sbInMask)
{
// Scale the wmse so that instead of scaling the coefficients, the
// wmse is scaled.
//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'"
cblk.wmseScaling *= (float) (1 << (maxBits << 1));
cblk.nROIcoeff = w * h;
return cblk;
}
// In 'block aligned' mode, the code-block is set to belong entirely
// to the ROI with the highest scaling value if one coefficient, at
// least, belongs to the ROI
if (blockAligned)
{
wrap = cblk.scanw - w;
mi = h * w - 1;
i = cblk.offset + cblk.scanw * (h - 1) + w - 1;
int nroicoeff = 0;
for (j = h; j > 0; j--)
{
for (k = w - 1; k >= 0; k--, i--, mi--)
{
if (maskData[mi] != 0)
{
nroicoeff++;
}
}
i -= wrap;
}
if (nroicoeff != 0)
{
// Include the subband
//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'"
cblk.wmseScaling *= (float) (1 << (maxBits << 1));
cblk.nROIcoeff = w * h;
}
return cblk;
}
// Scale background coefficients
bitMask = (((1 << cblk.magbits) - 1) << (31 - cblk.magbits));
wrap = cblk.scanw - w;
mi = h * w - 1;
i = cblk.offset + cblk.scanw * (h - 1) + w - 1;
for (j = h; j > 0; j--)
{
for (k = w; k > 0; k--, i--, mi--)
{
tmp = data[i];
if (maskData[mi] != 0)
{
// ROI coeff. We need to erase fractional bits to ensure
// that they do not conflict with BG coeffs. This is only
// strictly necessary for ROI coeffs. which non-fractional
// magnitude is zero, but much better BG quality can be
// achieved if done if reset to zero since coding zeros is
// much more efficient (the entropy coder knows nothing
// about ROI and cannot avoid coding the ROI fractional
// bits, otherwise this would not be necessary).
data[i] = (unchecked((int) 0x80000000) & tmp) | (tmp & bitMask);
nROIcoeff++;
}
else
{
// BG coeff. it is not necessary to erase fractional bits
data[i] = (unchecked((int) 0x80000000) & tmp) | ((tmp & 0x7FFFFFFF) >> maxBits);
}
}
i -= wrap;
}
// Modify the number of significant bit-planes in the code-block
cblk.magbits += maxBits;
// Store the number of ROI coefficients present in the code-block
cblk.nROIcoeff = nROIcoeff;
return cblk;
}