private void initSubbandsFields(int t, int c, Subband sb)
{
int cbw = cblks.getCBlkWidth(ModuleSpec.SPEC_TILE_COMP, t, c);
int cbh = cblks.getCBlkHeight(ModuleSpec.SPEC_TILE_COMP, t, c);
if (!sb.isNode)
{
// Code-blocks dimension
int ppx, ppy;
int ppxExp, ppyExp, cbwExp, cbhExp;
ppx = pss.getPPX(t, c, sb.resLvl);
ppy = pss.getPPY(t, c, sb.resLvl);
if (ppx != CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE || ppy != CSJ2K.j2k.codestream.Markers.PRECINCT_PARTITION_DEF_SIZE)
{
ppxExp = MathUtil.log2(ppx);
ppyExp = MathUtil.log2(ppy);
cbwExp = MathUtil.log2(cbw);
cbhExp = MathUtil.log2(cbh);
// Precinct partition is used
switch (sb.resLvl)
{
case 0:
sb.nomCBlkW = (cbwExp < ppxExp?(1 << cbwExp):(1 << ppxExp));
sb.nomCBlkH = (cbhExp < ppyExp?(1 << cbhExp):(1 << ppyExp));
break;
default:
sb.nomCBlkW = (cbwExp < ppxExp - 1?(1 << cbwExp):(1 << (ppxExp - 1)));
sb.nomCBlkH = (cbhExp < ppyExp - 1?(1 << cbhExp):(1 << (ppyExp - 1)));
break;
}
}
else
{
sb.nomCBlkW = cbw;
sb.nomCBlkH = cbh;
}
// Number of code-blocks
if (sb.numCb == null)
sb.numCb = new Coord();
if (sb.w != 0 && sb.h != 0)
{
int acb0x = cb0x;
int acb0y = cb0y;
int tmp;
// Project code-block partition origin to subband. Since the
// origin is always 0 or 1, it projects to the low-pass side
// (throught the ceil operator) as itself (i.e. no change) and
// to the high-pass side (through the floor operator) as 0,
// always.
switch (sb.sbandIdx)
{
case Subband.WT_ORIENT_LL:
// No need to project since all low-pass => nothing to do
break;
case Subband.WT_ORIENT_HL:
acb0x = 0;
break;
case Subband.WT_ORIENT_LH:
acb0y = 0;
break;
case Subband.WT_ORIENT_HH:
acb0x = 0;
acb0y = 0;
break;
default:
throw new System.InvalidOperationException("Internal JJ2000 error");
}
if (sb.ulcx - acb0x < 0 || sb.ulcy - acb0y < 0)
{
throw new System.ArgumentException("Invalid code-blocks " + "partition origin or " + "image offset in the " + "reference grid.");
}
// NOTE: when calculating "floor()" by integer division the
// dividend and divisor must be positive, we ensure that by
// adding the divisor to the dividend and then substracting 1
// to the result of the division
tmp = sb.ulcx - acb0x + sb.nomCBlkW;
sb.numCb.x = (tmp + sb.w - 1) / sb.nomCBlkW - (tmp / sb.nomCBlkW - 1);
tmp = sb.ulcy - acb0y + sb.nomCBlkH;
sb.numCb.y = (tmp + sb.h - 1) / sb.nomCBlkH - (tmp / sb.nomCBlkH - 1);
}
else
{
sb.numCb.x = sb.numCb.y = 0;
}
}
else
{
initSubbandsFields(t, c, sb.LL);
initSubbandsFields(t, c, sb.HL);
initSubbandsFields(t, c, sb.LH);
initSubbandsFields(t, c, sb.HH);
}
}