private bool rawMagRefPass(DataBlk cblk, ByteToBitInput bin, int bp, int[] state, bool isterm)
{
int j, sj; // The state index for line and stripe
int k, sk; // The data index for line and stripe
int dscanw; // The data scan-width
int sscanw; // The state scan-width
int jstep; // Stripe to stripe step for 'sj'
int kstep; // Stripe to stripe step for 'sk'
int stopsk; // The loop limit on the variable sk
int csj; // Local copy (i.e. cached) of 'state[j]'
int setmask; // The mask to set lower bit-planes to 1/2 approximation
int resetmask; // The mask to reset approximation bit-planes
int sym; // The symbol to decode
int[] data; // The data buffer
int s; // The stripe index
int nstripes; // The number of stripes in the code-block
int sheight; // Height of the current stripe
bool error; // The error condition
// Initialize local variables
dscanw = cblk.scanw;
sscanw = cblk.w + 2;
jstep = sscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT / 2 - cblk.w;
kstep = dscanw * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - cblk.w;
setmask = (1 << bp) >> 1;
resetmask = (- 1) << (bp + 1);
data = (int[]) cblk.Data;
nstripes = (cblk.h + CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT - 1) / CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
// Decode stripe by stripe
sk = cblk.offset;
sj = sscanw + 1;
for (s = nstripes - 1; s >= 0; s--, sk += kstep, sj += jstep)
{
sheight = (s != 0)?CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT:cblk.h - (nstripes - 1) * CSJ2K.j2k.entropy.StdEntropyCoderOptions.STRIPE_HEIGHT;
stopsk = sk + cblk.w;
// Scan by set of 1 stripe column at a time
for (; sk < stopsk; sk++, sj++)
{
// Do half top of column
j = sj;
csj = state[j];
// If any of the two samples is significant and not yet
// visited in the current bit-plane we can not skip them
if ((((SupportClass.URShift(csj, 1)) & (~ csj)) & VSTD_MASK_R1R2) != 0)
{
k = sk;
// Scan first row
if ((csj & (STATE_SIG_R1 | STATE_VISITED_R1)) == STATE_SIG_R1)
{
// Read raw bit (no MR primative)
sym = bin.readBit();
// Update the data
data[k] &= resetmask;
data[k] |= (sym << bp) | setmask;
// No need to set STATE_PREV_MR_R1 since all magnitude
// refinement passes to follow are "raw"
}
if (sheight < 2)
continue;
// Scan second row
if ((csj & (STATE_SIG_R2 | STATE_VISITED_R2)) == STATE_SIG_R2)
{
k += dscanw;
// Read raw bit (no MR primative)
sym = bin.readBit();
// Update the data
data[k] &= resetmask;
data[k] |= (sym << bp) | setmask;
// No need to set STATE_PREV_MR_R1 since all magnitude
// refinement passes to follow are "raw"
}
}
// Do half bottom of column
if (sheight < 3)
continue;
j += sscanw;
csj = state[j];
// If any of the two samples is significant and not yet
// visited in the current bit-plane we can not skip them
if ((((SupportClass.URShift(csj, 1)) & (~ csj)) & VSTD_MASK_R1R2) != 0)
{
k = sk + (dscanw << 1);
// Scan first row
if ((csj & (STATE_SIG_R1 | STATE_VISITED_R1)) == STATE_SIG_R1)
{
// Read raw bit (no MR primative)
sym = bin.readBit();
// Update the data
data[k] &= resetmask;
data[k] |= (sym << bp) | setmask;
// No need to set STATE_PREV_MR_R1 since all magnitude
// refinement passes to follow are "raw"
}
if (sheight < 4)
continue;
// Scan second row
if ((state[j] & (STATE_SIG_R2 | STATE_VISITED_R2)) == STATE_SIG_R2)
{
k += dscanw;
// Read raw bit (no MR primative)
sym = bin.readBit();
// Update the data
data[k] &= resetmask;
data[k] |= (sym << bp) | setmask;
// No need to set STATE_PREV_MR_R1 since all magnitude
// refinement passes to follow are "raw"
}
}
}
}
error = false;
// Check the byte padding if the pass is terminated and the
// predictable termination is signaled in COx marker.
if (isterm && (options & CSJ2K.j2k.entropy.StdEntropyCoderOptions.OPT_PRED_TERM) != 0)
{
error = bin.checkBytePadding();
}
// Return error condition
return error;
}