protected internal virtual void writeMainQCD()
{
int mrl;
int qstyle;
float step;
System.String qType = (System.String) encSpec.qts.getDefault();
//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
float baseStep = (float) ((System.Single) encSpec.qsss.getDefault());
int gb = ((System.Int32) encSpec.gbs.getDefault());
bool isDerived = qType.Equals("derived");
bool isReversible = qType.Equals("reversible");
mrl = ((System.Int32) encSpec.dls.getDefault());
int nt = dwt.getNumTiles();
int nc = dwt.NumComps;
int tmpI;
int[] tcIdx = new int[2];
System.String tmpStr;
bool notFound = true;
for (int t = 0; t < nt && notFound; t++)
{
for (int c = 0; c < nc && notFound; c++)
{
tmpI = ((System.Int32) encSpec.dls.getTileCompVal(t, c));
tmpStr = ((System.String) encSpec.qts.getTileCompVal(t, c));
if (tmpI == mrl && tmpStr.Equals(qType))
{
tcIdx[0] = t; tcIdx[1] = c;
notFound = false;
}
}
}
if (notFound)
{
throw new System.InvalidOperationException("Default representative for quantization type " + " and number of decomposition levels not found " + " in main QCD marker segment. " + "You have found a JJ2000 bug.");
}
SubbandAn sb, csb, sbRoot = dwt.getAnSubbandTree(tcIdx[0], tcIdx[1]);
defimgn = dwt.getNomRangeBits(tcIdx[1]);
int nqcd; // Number of quantization step-size to transmit
// Get the quantization style
qstyle = (isReversible)?CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION:((isDerived)?CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED:CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED);
// QCD marker
hbuf.Write((System.Int16) CSJ2K.j2k.codestream.Markers.QCD);
// Compute the number of steps to send
switch (qstyle)
{
case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED:
nqcd = 1; // Just the LL value
break;
case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION:
case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED:
// One value per subband
nqcd = 0;
sb = sbRoot;
// Get the subband at first resolution level
sb = (SubbandAn) sb.getSubbandByIdx(0, 0);
// Count total number of subbands
for (int j = 0; j <= mrl; j++)
{
csb = sb;
while (csb != null)
{
nqcd++;
csb = (SubbandAn) csb.nextSubband();
}
// Go up one resolution level
sb = (SubbandAn) sb.NextResLevel;
}
break;
default:
throw new System.InvalidOperationException("Internal JJ2000 error");
}
// Lqcd (marker segment length (in bytes))
// Lqcd(2 bytes)+Sqcd(1)+ SPqcd (2*Nqcd)
int markSegLen = 3 + ((isReversible)?nqcd:2 * nqcd);
// Rounded to the nearest even value greater or equals
hbuf.Write((System.Int16) markSegLen);
// Sqcd
hbuf.Write((System.Byte) (qstyle + (gb << CSJ2K.j2k.codestream.Markers.SQCX_GB_SHIFT)));
// SPqcd
switch (qstyle)
{
case CSJ2K.j2k.codestream.Markers.SQCX_NO_QUANTIZATION:
sb = sbRoot;
sb = (SubbandAn) sb.getSubbandByIdx(0, 0);
// Output one exponent per subband
for (int j = 0; j <= mrl; j++)
{
csb = sb;
while (csb != null)
{
int tmp = (defimgn + csb.anGainExp);
hbuf.Write((System.Byte) (tmp << CSJ2K.j2k.codestream.Markers.SQCX_EXP_SHIFT));
csb = (SubbandAn) csb.nextSubband();
// Go up one resolution level
}
sb = (SubbandAn) sb.NextResLevel;
}
break;
case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_DERIVED:
sb = sbRoot;
sb = (SubbandAn) sb.getSubbandByIdx(0, 0);
// Calculate subband step (normalized to unit
// dynamic range)
step = baseStep / (1 << sb.level);
// Write exponent-mantissa, 16 bits
hbuf.Write((System.Int16) StdQuantizer.convertToExpMantissa(step));
break;
case CSJ2K.j2k.codestream.Markers.SQCX_SCALAR_EXPOUNDED:
sb = sbRoot;
sb = (SubbandAn) sb.getSubbandByIdx(0, 0);
// Output one step per subband
for (int j = 0; j <= mrl; j++)
{
csb = sb;
while (csb != null)
{
// Calculate subband step (normalized to unit
// dynamic range)
step = baseStep / (csb.l2Norm * (1 << csb.anGainExp));
// Write exponent-mantissa, 16 bits
hbuf.Write((System.Int16) StdQuantizer.convertToExpMantissa(step));
csb = (SubbandAn) csb.nextSubband();
}
// Go up one resolution level
sb = (SubbandAn) sb.NextResLevel;
}
break;
default:
throw new System.InvalidOperationException("Internal JJ2000 error");
}
}