public FileBitstreamReaderAgent(HeaderDecoder hd, RandomAccessIO ehs, DecoderSpecs decSpec, ParameterList pl, bool cdstrInfo, HeaderInfo hi)
: base(hd, decSpec)
{
this.pl = pl;
this.printInfo = cdstrInfo;
this.hi = hi;
System.String strInfo = "Codestream elements information in bytes " + "(offset, total length, header length):\n\n";
// Check whether quit conditiosn used
usePOCQuit = pl.getBooleanParameter("poc_quit");
// Get decoding rate
bool rateInBytes;
bool parsing = pl.getBooleanParameter("parsing");
try
{
trate = pl.getFloatParameter("rate");
if (trate == - 1)
{
trate = System.Single.MaxValue;
}
}
catch (System.FormatException e)
{
throw new System.InvalidOperationException("Invalid value in 'rate' option: " + pl.getParameter("rate"));
}
catch (System.ArgumentException e)
{
throw new System.InvalidOperationException("'rate' option is missing");
}
try
{
tnbytes = pl.getIntParameter("nbytes");
}
catch (System.FormatException e)
{
throw new System.InvalidOperationException("Invalid value in 'nbytes' option: " + pl.getParameter("nbytes"));
}
catch (System.ArgumentException e)
{
throw new System.InvalidOperationException("'nbytes' option is missing");
}
// Check that '-rate' and '-nbytes' are not used at the same time
ParameterList defaults = pl.DefaultParameterList;
if (tnbytes != defaults.getFloatParameter("nbytes"))
{
rateInBytes = true;
}
else
{
rateInBytes = false;
}
if (rateInBytes)
{
trate = tnbytes * 8f / hd.MaxCompImgWidth / hd.MaxCompImgHeight;
}
else
{
//UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
tnbytes = (int) (trate * hd.MaxCompImgWidth * hd.MaxCompImgHeight) / 8;
if (tnbytes < 0) tnbytes = int.MaxValue;
}
isTruncMode = !pl.getBooleanParameter("parsing");
// Check if quit conditions are being used
int ncbQuit;
try
{
ncbQuit = pl.getIntParameter("ncb_quit");
}
catch (System.FormatException e)
{
throw new System.InvalidOperationException("Invalid value in 'ncb_quit' option: " + pl.getParameter("ncb_quit"));
}
catch (System.ArgumentException e)
{
throw new System.InvalidOperationException("'ncb_quit' option is missing");
}
if (ncbQuit != - 1 && !isTruncMode)
{
throw new System.InvalidOperationException("Cannot use -parsing and -ncb_quit condition at " + "the same time.");
}
try
{
lQuit = pl.getIntParameter("l_quit");
}
catch (System.FormatException e)
{
throw new System.InvalidOperationException("Invalid value in 'l_quit' option: " + pl.getParameter("l_quit"));
}
catch (System.ArgumentException e)
{
throw new System.InvalidOperationException("'l_quit' option is missing");
}
// initializations
in_Renamed = ehs;
pktDec = new PktDecoder(decSpec, hd, ehs, this, isTruncMode, ncbQuit);
tileParts = new int[nt];
totTileLen = new int[nt];
tilePartLen = new int[nt][];
tilePartNum = new int[nt][];
firstPackOff = new int[nt][];
tilePartsRead = new int[nt];
totTileHeadLen = new int[nt];
tilePartHeadLen = new int[nt][];
nBytes = new int[nt];
baknBytes = new int[nt];
hd.nTileParts = new int[nt];
// CONVERSION PROBLEM?
//this.isTruncMode = isTruncMode;
int t = 0, pos, tp = 0, tptot = 0;
// Keeps main header's length, takes file format overhead into account
int cdstreamStart = hd.mainHeadOff; // Codestream offset in the file
mainHeadLen = in_Renamed.Pos - cdstreamStart;
headLen = mainHeadLen;
// If ncb and lbody quit conditions are used, headers are not counted
if (ncbQuit == - 1)
{
anbytes = mainHeadLen;
}
else
{
anbytes = 0;
}
strInfo += ("Main header length : " + cdstreamStart + ", " + mainHeadLen + ", " + mainHeadLen + "\n");
// If cannot even read the first tile-part
if (anbytes > tnbytes)
{
throw new System.InvalidOperationException("Requested bitrate is too small.");
}
// Read all tile-part headers from all tiles.
int tilePartStart;
bool rateReached = false;
int mdl;
//int numtp = 0;
totAllTileLen = 0;
remainingTileParts = nt; // at least as many tile-parts as tiles
int maxTP = nt; // If maximum 1 tile part per tile specified
try
{
while (remainingTileParts != 0)
{
tilePartStart = in_Renamed.Pos;
// Read tile-part header
try
{
t = readTilePartHeader();
if (isEOCFound)
{
// Some tiles are missing but the
// codestream is OK
break;
}
tp = tilePartsRead[t];
if (isPsotEqualsZero)
{
// Psot may equals zero for the
// last tile-part: it is assumed that this tile-part
// contain all data until EOC
tilePartLen[t][tp] = in_Renamed.length() - 2 - tilePartStart;
}
}
catch (System.IO.EndOfStreamException e)
{
firstPackOff[t][tp] = in_Renamed.length();
throw e;
}
pos = in_Renamed.Pos;
// In truncation mode, if target decoding rate is reached in
// tile-part header, skips the tile-part and stop reading
// unless the ncb and lbody quit condition is in use
if (isTruncMode && ncbQuit == - 1)
{
if ((pos - cdstreamStart) > tnbytes)
{
firstPackOff[t][tp] = in_Renamed.length();
rateReached = true;
break;
}
}
// Set tile part position and header length
firstPackOff[t][tp] = pos;
tilePartHeadLen[t][tp] = (pos - tilePartStart);
strInfo += ("Tile-part " + tp + " of tile " + t + " : " + tilePartStart + ", " + tilePartLen[t][tp] + ", " + tilePartHeadLen[t][tp] + "\n");
// Update length counters
totTileLen[t] += tilePartLen[t][tp];
totTileHeadLen[t] += tilePartHeadLen[t][tp];
totAllTileLen += tilePartLen[t][tp];
if (isTruncMode)
{
if (anbytes + tilePartLen[t][tp] > tnbytes)
{
anbytes += tilePartHeadLen[t][tp];
headLen += tilePartHeadLen[t][tp];
rateReached = true;
nBytes[t] += (tnbytes - anbytes);
break;
}
else
{
anbytes += tilePartHeadLen[t][tp];
headLen += tilePartHeadLen[t][tp];
nBytes[t] += (tilePartLen[t][tp] - tilePartHeadLen[t][tp]);
}
}
else
{
if (anbytes + tilePartHeadLen[t][tp] > tnbytes)
{
break;
}
else
{
anbytes += tilePartHeadLen[t][tp];
headLen += tilePartHeadLen[t][tp];
}
}
// If this is first tile-part, remember header length
if (tptot == 0)
firstTilePartHeadLen = tilePartHeadLen[t][tp];
// Go to the beginning of next tile part
tilePartsRead[t]++;
in_Renamed.seek(tilePartStart + tilePartLen[t][tp]);
remainingTileParts--;
maxTP--;
tptot++;
// If Psot of the current tile-part was equal to zero, it is
// assumed that it contains all data until the EOC marker
if (isPsotEqualsZero)
{
if (remainingTileParts != 0)
{
FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Some tile-parts have not " + "been found. The codestream may be corrupted.");
}
break;
}
}
}
catch (System.IO.EndOfStreamException e)
{
if (printInfo)
{
FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo);
}
FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Codestream truncated in tile " + t);
// Set specified rate to end of file if valid
int fileLen = in_Renamed.length();
if (fileLen < tnbytes)
{
tnbytes = fileLen;
trate = tnbytes * 8f / hd.MaxCompImgWidth / hd.MaxCompImgHeight;
}
// Bit-rate allocation
if (!isTruncMode)
{
allocateRate();
}
// Update 'res' value once all tile-part headers are read
if (pl.getParameter("res") == null)
{
targetRes = decSpec.dls.Min;
}
else
{
try
{
targetRes = pl.getIntParameter("res");
if (targetRes < 0)
{
throw new System.ArgumentException("Specified negative " + "resolution level " + "index: " + targetRes);
}
}
catch (System.FormatException f)
{
throw new System.ArgumentException("Invalid resolution level " + "index ('-res' option) " + pl.getParameter("res"));
}
}
// Verify reduction in resolution level
mdl = decSpec.dls.Min;
if (targetRes > mdl)
{
FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Specified resolution level (" + targetRes + ") is larger" + " than the maximum value. Setting it to " + mdl + " (maximum value)");
targetRes = mdl;
}
// Backup nBytes
for (int tIdx = 0; tIdx < nt; tIdx++)
{
baknBytes[tIdx] = nBytes[tIdx];
}
return ;
}
remainingTileParts = 0;
// Update 'res' value once all tile-part headers are read
if (pl.getParameter("res") == null)
{
targetRes = decSpec.dls.Min;
}
else
{
try
{
targetRes = pl.getIntParameter("res");
if (targetRes < 0)
{
throw new System.ArgumentException("Specified negative " + "resolution level index: " + targetRes);
}
}
catch (System.FormatException e)
{
throw new System.ArgumentException("Invalid resolution level " + "index ('-res' option) " + pl.getParameter("res"));
}
}
// Verify reduction in resolution level
mdl = decSpec.dls.Min;
if (targetRes > mdl)
{
FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Specified resolution level (" + targetRes + ") is larger" + " than the maximum possible. Setting it to " + mdl + " (maximum possible)");
targetRes = mdl;
}
if (printInfo)
{
FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.INFO, strInfo);
}
// Check presence of EOC marker is decoding rate not reached or if
// this marker has not been found yet
if (!isEOCFound && !isPsotEqualsZero)
{
try
{
if (!rateReached && !isPsotEqualsZero && in_Renamed.readShort() != CSJ2K.j2k.codestream.Markers.EOC)
{
FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "EOC marker not found. " + "Codestream is corrupted.");
}
}
catch (System.IO.EndOfStreamException e)
{
FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "EOC marker is missing");
}
}
// Bit-rate allocation
if (!isTruncMode)
{
allocateRate();
}
else
{
// Take EOC into account if rate is not reached
if (in_Renamed.Pos >= tnbytes)
anbytes += 2;
}
// Backup nBytes
for (int tIdx = 0; tIdx < nt; tIdx++)
{
baknBytes[tIdx] = nBytes[tIdx];
if (printInfo)
{
FacilityManager.getMsgLogger().println("" + hi.toStringTileHeader(tIdx, tilePartLen[tIdx].Length), 2, 2);
}
}
}