private void buildAndWriteLayers()
{
int nPrec = 0;
int maxBytes, actualBytes;
float rdThreshold;
SubbandAn sb;
//float threshold;
BitOutputBuffer hBuff = null;
byte[] bBuff = null;
int[] tileLengths; // Length of each tile
int tmp;
bool sopUsed; // Should SOP markers be used ?
bool ephUsed; // Should EPH markers be used ?
int nc = src.NumComps;
int nt = src.getNumTiles();
int mrl;
#if DO_TIMING
long stime = 0L;
stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
#endif
// Start with the maximum slope
rdThreshold = maxSlope;
tileLengths = new int[nt];
actualBytes = 0;
// +------------------------------+
// | First we build the layers |
// +------------------------------+
// Bitstream is simulated to know tile length
for (int l = 0; l < num_Layers; l++)
{
//loop on layers
maxBytes = layers[l].maxBytes;
if (layers[l].optimize)
{
rdThreshold = optimizeBitstreamLayer(l, rdThreshold, maxBytes, actualBytes);
}
else
{
if (l <= 0 || l >= num_Layers - 1)
{
throw new System.ArgumentException("The first and the" + " last layer " + "thresholds" + " must be optimized");
}
rdThreshold = estimateLayerThreshold(maxBytes, layers[l - 1]);
}
for (int t = 0; t < nt; t++)
{
//loop on tiles
if (l == 0)
{
// Tile header
headEnc.reset();
headEnc.encodeTilePartHeader(0, t);
tileLengths[t] += headEnc.Length;
}
for (int c = 0; c < nc; c++)
{
//loop on components
// set boolean sopUsed here (SOP markers)
sopUsed = ((System.String) encSpec.sops.getTileDef(t)).ToUpper().Equals("on".ToUpper());
// set boolean ephUsed here (EPH markers)
ephUsed = ((System.String) encSpec.ephs.getTileDef(t)).ToUpper().Equals("on".ToUpper());
// Go to LL band
sb = src.getAnSubbandTree(t, c);
mrl = sb.resLvl + 1;
while (sb.subb_LL != null)
{
sb = sb.subb_LL;
}
for (int r = 0; r < mrl; r++)
{
// loop on resolution levels
nPrec = numPrec[t][c][r].x * numPrec[t][c][r].y;
for (int p = 0; p < nPrec; p++)
{
// loop on precincts
findTruncIndices(l, c, r, t, sb, rdThreshold, p);
hBuff = pktEnc.encodePacket(l + 1, c, r, t, cblks[t][c][r], truncIdxs[t][l][c][r], hBuff, bBuff, p);
if (pktEnc.PacketWritable)
{
tmp = bsWriter.writePacketHead(hBuff.Buffer, hBuff.Length, true, sopUsed, ephUsed);
tmp += bsWriter.writePacketBody(pktEnc.LastBodyBuf, pktEnc.LastBodyLen, true, pktEnc.ROIinPkt, pktEnc.ROILen);
actualBytes += tmp;
tileLengths[t] += tmp;
}
} // End loop on precincts
sb = sb.parentband;
} // End loop on resolution levels
} // End loop on components
} // end loop on tiles
layers[l].rdThreshold = rdThreshold;
layers[l].actualBytes = actualBytes;
} // end loop on layers
#if DO_TIMING
buildTime += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime;
stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
#endif
// +--------------------------------------------------+
// | Write tiles according to their Progression order |
// +--------------------------------------------------+
// Reset the packet encoder before writing all packets
pktEnc.reset();
Progression[] prog; // Progression(s) in each tile
int cs, ce, rs, re, lye;
int[] mrlc = new int[nc];
for (int t = 0; t < nt; t++)
{
//loop on tiles
//int[][] lysA; // layer index start for each component and
// resolution level
int[][] lys = new int[nc][];
for (int c = 0; c < nc; c++)
{
mrlc[c] = src.getAnSubbandTree(t, c).resLvl;
lys[c] = new int[mrlc[c] + 1];
}
// Tile header
headEnc.reset();
headEnc.encodeTilePartHeader(tileLengths[t], t);
bsWriter.commitBitstreamHeader(headEnc);
prog = (Progression[]) encSpec.pocs.getTileDef(t);
for (int prg = 0; prg < prog.Length; prg++)
{
// Loop on progression
lye = prog[prg].lye;
cs = prog[prg].cs;
ce = prog[prg].ce;
rs = prog[prg].rs;
re = prog[prg].re;
switch (prog[prg].type)
{
case CSJ2K.j2k.codestream.ProgressionType.RES_LY_COMP_POS_PROG:
writeResLyCompPos(t, rs, re, cs, ce, lys, lye);
break;
case CSJ2K.j2k.codestream.ProgressionType.LY_RES_COMP_POS_PROG:
writeLyResCompPos(t, rs, re, cs, ce, lys, lye);
break;
case CSJ2K.j2k.codestream.ProgressionType.POS_COMP_RES_LY_PROG:
writePosCompResLy(t, rs, re, cs, ce, lys, lye);
break;
case CSJ2K.j2k.codestream.ProgressionType.COMP_POS_RES_LY_PROG:
writeCompPosResLy(t, rs, re, cs, ce, lys, lye);
break;
case CSJ2K.j2k.codestream.ProgressionType.RES_POS_COMP_LY_PROG:
writeResPosCompLy(t, rs, re, cs, ce, lys, lye);
break;
default:
throw new System.InvalidOperationException("Unsupported bit stream progression type");
} // switch on progression
// Update next first layer index
for (int c = cs; c < ce; c++)
for (int r = rs; r < re; r++)
{
if (r > mrlc[c])
continue;
lys[c][r] = lye;
}
} // End loop on progression
} // End loop on tiles
#if DO_TIMING
writeTime += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime;
#endif
}