private void readTilePkts(int t)
{
pktHL = new List<int>(10);
// Number of layers
int nl = ((System.Int32) decSpec.nls.getTileDef(t));
// If packed packet headers was used, get the packet headers for this
// tile
if (((System.Boolean) decSpec.pphs.getTileDef(t)))
{
// Gets packed headers as separate input stream
System.IO.MemoryStream pphbais = hd.getPackedPktHead(t);
// Restarts PktDecoder instance
cbI = pktDec.restart(this.nc, mdl, nl, cbI, true, pphbais);
}
else
{
// Restarts PktDecoder instance
cbI = pktDec.restart(this.nc, mdl, nl, cbI, false, null);
}
// Reads packets of the tile according to the progression order
int[][] pocSpec = ((int[][]) decSpec.pcs.getTileDef(t));
int nChg = (pocSpec == null)?1:pocSpec.Length;
// Create an array containing information about changes (progression
// order type, layers index start, layer index end, resolution level
// start, resolution level end, component index start, component index
// end). There is one row per progresion order
int[][] change = new int[nChg][];
for (int i = 0; i < nChg; i++)
{
change[i] = new int[6];
}
int idx = 0; // Index of the current progression order
change[0][1] = 0; // layer start
if (pocSpec == null)
{
change[idx][0] = ((System.Int32) decSpec.pos.getTileDef(t));
// Progression type found in COx marker segments
change[idx][1] = nl; // Layer index end
change[idx][2] = 0; // resolution level start
change[idx][3] = decSpec.dls.getMaxInTile(t) + 1; // res. level end
change[idx][4] = 0; // Component index start
change[idx][5] = this.nc; // Component index end
}
else
{
for (idx = 0; idx < nChg; idx++)
{
change[idx][0] = pocSpec[idx][5];
change[idx][1] = pocSpec[idx][2]; // layer end
change[idx][2] = pocSpec[idx][0]; // res. lev. start
change[idx][3] = pocSpec[idx][3]; // res. lev. end
change[idx][4] = pocSpec[idx][1]; // Comp. index start
change[idx][5] = pocSpec[idx][4]; // Comp. index end
}
}
// Seeks to the first packet of the first tile-part
try
{
// If in truncation mode, the first tile-part may be beyond the
// target decoding rate. In this case, the offset of the first
// packet is not defined.
if (isTruncMode && firstPackOff == null || firstPackOff[t] == null)
{
return ;
}
in_Renamed.seek(firstPackOff[t][0]);
}
catch (System.IO.EndOfStreamException e)
{
FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Codestream truncated in tile " + t);
return ;
}
curTilePart = 0;
// Start and end indexes for layers, resolution levels and components.
int lye, ress, rese, comps, compe;
bool status = false;
int nb = nBytes[t];
int[][] lys = new int[this.nc][];
for (int c = 0; c < this.nc; c++)
{
lys[c] = new int[((System.Int32) decSpec.dls.getTileCompVal(t, c)) + 1];
}
try
{
for (int chg = 0; chg < nChg; chg++)
{
lye = change[chg][1];
ress = change[chg][2];
rese = change[chg][3];
comps = change[chg][4];
compe = change[chg][5];
switch (change[chg][0])
{
case CSJ2K.j2k.codestream.ProgressionType.LY_RES_COMP_POS_PROG:
status = readLyResCompPos(lys, lye, ress, rese, comps, compe);
break;
case CSJ2K.j2k.codestream.ProgressionType.RES_LY_COMP_POS_PROG:
status = readResLyCompPos(lys, lye, ress, rese, comps, compe);
break;
case CSJ2K.j2k.codestream.ProgressionType.RES_POS_COMP_LY_PROG:
status = readResPosCompLy(lys, lye, ress, rese, comps, compe);
break;
case CSJ2K.j2k.codestream.ProgressionType.POS_COMP_RES_LY_PROG:
status = readPosCompResLy(lys, lye, ress, rese, comps, compe);
break;
case CSJ2K.j2k.codestream.ProgressionType.COMP_POS_RES_LY_PROG:
status = readCompPosResLy(lys, lye, ress, rese, comps, compe);
break;
default:
throw new System.ArgumentException("Not recognized " + "progression type");
}
// Update next first layer index
for (int c = comps; c < compe; c++)
{
if (c >= lys.Length)
continue;
for (int r = ress; r < rese; r++)
{
if (r >= lys[c].Length)
continue;
lys[c][r] = lye;
}
}
if (status || usePOCQuit)
{
break;
}
}
}
catch (System.IO.EndOfStreamException e)
{
// Should never happen. Truncated codestream are normally found by
// the class constructor
throw e;
}
// In truncation mode, update the number of read bytes
if (isTruncMode)
{
anbytes += nb - nBytes[t];
// If truncation rate is reached
if (status)
{
nBytes[t] = 0;
}
}
else if (nBytes[t] < (totTileLen[t] - totTileHeadLen[t]))
{
// In parsing mode, if there is not enough rate to entirely read the
// tile. Then, parses the bit stream so as to create a virtual
// layer-resolution-component progressive bit stream that will be
// truncated and decoded afterwards.
CBlkInfo cb;
// Systematicaly reject all remaining code-blocks if one
// code-block, at least, is refused.
bool reject;
// Stop reading any data from the bit stream
bool stopCount = false;
// Length of each packet's head (in an array)
int[] pktHeadLen = new int[pktHL.Count];
for (int i = pktHL.Count - 1; i >= 0; i--)
{
pktHeadLen[i] = ((System.Int32) pktHL[i]);
}
// Parse each code-block, layer per layer until nBytes[t] is
// reached
reject = false;
for (int l = 0; l < nl; l++)
{
// layers
if (cbI == null)
continue;
int nc = cbI.Length;
int mres = 0;
for (int c = 0; c < nc; c++)
{
if (cbI[c] != null && cbI[c].Length > mres)
mres = cbI[c].Length;
}
for (int r = 0; r < mres; r++)
{
// resolutions
int msub = 0;
for (int c = 0; c < nc; c++)
{
if (cbI[c] != null && cbI[c][r] != null && cbI[c][r].Length > msub)
msub = cbI[c][r].Length;
}
for (int s = 0; s < msub; s++)
{
// subbands
// Only LL subband resolution level 0
if (r == 0 && s != 0)
{
continue;
}
else if (r != 0 && s == 0)
{
// No LL subband in resolution level > 0
continue;
}
int mnby = 0;
for (int c = 0; c < nc; c++)
{
if (cbI[c] != null && cbI[c][r] != null && cbI[c][r][s] != null && cbI[c][r][s].Length > mnby)
mnby = cbI[c][r][s].Length;
}
for (int m = 0; m < mnby; m++)
{
int mnbx = 0;
for (int c = 0; c < nc; c++)
{
if (cbI[c] != null && cbI[c][r] != null && cbI[c][r][s] != null && cbI[c][r][s][m] != null && cbI[c][r][s][m].Length > mnbx)
mnbx = cbI[c][r][s][m].Length;
}
for (int n = 0; n < mnbx; n++)
{
for (int c = 0; c < nc; c++)
{
if (cbI[c] == null || cbI[c][r] == null || cbI[c][r][s] == null || cbI[c][r][s][m] == null || cbI[c][r][s][m][n] == null)
{
continue;
}
cb = cbI[c][r][s][m][n];
// If no code-block has been refused until
// now
if (!reject)
{
// Rate is to low to allow reading of
// packet's head
if (nBytes[t] < pktHeadLen[cb.pktIdx[l]])
{
// Stop parsing
stopCount = true;
// Reject all next
// code-blocks
reject = true;
}
else
{
// Rate is enough to read packet's
// head
if (!stopCount)
{
//If parsing was not stopped
//Takes into account packet's
//head length
nBytes[t] -= pktHeadLen[cb.pktIdx[l]];
anbytes += pktHeadLen[cb.pktIdx[l]];
// Set packet's head length to
// 0, so that it won't be
// taken into account next
// time
pktHeadLen[cb.pktIdx[l]] = 0;
}
}
}
// Code-block has no data in this layer
if (cb.len[l] == 0)
{
continue;
}
// Accepts code-block if length is enough,
// if this code-block was not refused in a
// previous layer and if no code-block was
// refused in current component
if (cb.len[l] < nBytes[t] && !reject)
{
nBytes[t] -= cb.len[l];
anbytes += cb.len[l];
}
else
{
// Refuses code-block
// Forgets code-block's data
cb.len[l] = cb.off[l] = cb.ntp[l] = 0;
// Refuses all other code-block in
// current and next component
reject = true;
}
} // End loop on components
} // End loop on horiz. code-blocks
} // End loop on vert. code-blocks
} // End loop on subbands
} // End loop on resolutions
} // End loop on layers
}
else
{
// No parsing for this tile, adds tile's body to the total
// number of read bytes.
anbytes += totTileLen[t] - totTileHeadLen[t];
if (t < getNumTiles() - 1)
{
nBytes[t + 1] += nBytes[t] - (totTileLen[t] - totTileHeadLen[t]);
}
}
}