public override void initialize()
{
int n, i, l;
int ho; // The header overhead (in bytes)
float np; // The number of pixels divided by the number of bits per byte
double ls; // Step for log-scale
double basebytes;
int lastbytes, newbytes, nextbytes;
int loopnlyrs;
int minlsz; // The minimum allowable number of bytes in a layer
int totenclength;
int maxpkt;
int numTiles = src.getNumTiles();
int numComps = src.NumComps;
int numLvls;
int avgPktLen;
#if DO_TIMING
long stime = 0L;
#endif
// Start by getting all the code-blocks, we need this in order to have
// an idea of the total encoded bitrate.
getAllCodeBlocks();
#if DO_TIMING
stime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
#endif
// Now get the total encoded length
totenclength = RDSlopesRates[0]; // all the encoded data
// Make a rough estimation of the packet head overhead, as 2 bytes per
// packet in average (plus EPH / SOP) , and add that to the total
// encoded length
for (int t = 0; t < numTiles; t++)
{
avgPktLen = 2;
// Add SOP length if set
if (((System.String) encSpec.sops.getTileDef(t)).ToUpper().Equals("on".ToUpper()))
{
avgPktLen += CSJ2K.j2k.codestream.Markers.SOP_LENGTH;
}
// Add EPH length if set
if (((System.String) encSpec.ephs.getTileDef(t)).ToUpper().Equals("on".ToUpper()))
{
avgPktLen += CSJ2K.j2k.codestream.Markers.EPH_LENGTH;
}
for (int c = 0; c < numComps; c++)
{
numLvls = src.getAnSubbandTree(t, c).resLvl + 1;
if (!src.precinctPartitionUsed(c, t))
{
// Precinct partition is not used so there is only
// one packet per resolution level/layer
totenclength += num_Layers * avgPktLen * numLvls;
}
else
{
// Precinct partition is used so for each
// component/tile/resolution level, we get the maximum
// number of packets
for (int rl = 0; rl < numLvls; rl++)
{
maxpkt = numPrec[t][c][rl].x * numPrec[t][c][rl].y;
totenclength += num_Layers * avgPktLen * maxpkt;
}
}
} // End loop on components
} // End loop on tiles
// If any layer specifies more than 'totenclength' as its target
// length then 'totenclength' is used. This is to prevent that
// estimated layers get excessively large target lengths due to an
// excessively large target bitrate. At the end the last layer is set
// to the target length corresponding to the overall target
// bitrate. Thus, 'totenclength' can not limit the total amount of
// encoded data, as intended.
ho = headEnc.Length;
np = src.ImgWidth * src.ImgHeight / 8f;
// SOT marker must be taken into account
for (int t = 0; t < numTiles; t++)
{
headEnc.reset();
headEnc.encodeTilePartHeader(0, t);
ho += headEnc.Length;
}
layers = new EBCOTLayer[num_Layers];
for (n = num_Layers - 1; n >= 0; n--)
{
layers[n] = new EBCOTLayer();
}
minlsz = 0; // To keep compiler happy
for (int t = 0; t < numTiles; t++)
{
for (int c = 0; c < numComps; c++)
{
numLvls = src.getAnSubbandTree(t, c).resLvl + 1;
if (!src.precinctPartitionUsed(c, t))
{
// Precinct partition is not used
minlsz += MIN_AVG_PACKET_SZ * numLvls;
}
else
{
// Precinct partition is used
for (int rl = 0; rl < numLvls; rl++)
{
maxpkt = numPrec[t][c][rl].x * numPrec[t][c][rl].y;
minlsz += MIN_AVG_PACKET_SZ * maxpkt;
}
}
} // End loop on components
} // End loop on tiles
// Initialize layers
n = 0;
i = 0;
lastbytes = 0;
while (n < num_Layers - 1)
{
// At an optimized layer
basebytes = System.Math.Floor(lyrSpec.getTargetBitrate(i) * np);
if (i < lyrSpec.NOptPoints - 1)
{
//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'"
nextbytes = (int) (lyrSpec.getTargetBitrate(i + 1) * np);
// Limit target length to 'totenclength'
if (nextbytes > totenclength)
nextbytes = totenclength;
}
else
{
nextbytes = 1;
}
loopnlyrs = lyrSpec.getExtraLayers(i) + 1;
ls = System.Math.Exp(System.Math.Log((double) nextbytes / basebytes) / loopnlyrs);
layers[n].optimize = true;
for (l = 0; l < loopnlyrs; l++)
{
//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'"
newbytes = (int) basebytes - lastbytes - ho;
if (newbytes < minlsz)
{
// Skip layer (too small)
basebytes *= ls;
num_Layers--;
continue;
}
//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'"
lastbytes = (int) basebytes - ho;
layers[n].maxBytes = lastbytes;
basebytes *= ls;
n++;
}
i++; // Goto next optimization point
}
// Ensure minimum size of last layer (this one determines overall
// bitrate)
n = num_Layers - 2;
//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'"
nextbytes = (int) (lyrSpec.TotBitrate * np) - ho;
newbytes = nextbytes - ((n >= 0)?layers[n].maxBytes:0);
while (newbytes < minlsz)
{
if (num_Layers == 1)
{
if (newbytes <= 0)
{
throw new System.ArgumentException("Overall target bitrate too " + "low, given the current " + "bit stream header overhead");
}
break;
}
// Delete last layer
num_Layers--;
n--;
newbytes = nextbytes - ((n >= 0)?layers[n].maxBytes:0);
}
// Set last layer to the overall target bitrate
n++;
layers[n].maxBytes = nextbytes;
layers[n].optimize = true;
// Re-initialize progression order changes if needed Default values
Progression[] prog1; // prog2 removed
prog1 = (Progression[]) encSpec.pocs.getDefault();
int nValidProg = prog1.Length;
for (int prg = 0; prg < prog1.Length; prg++)
{
if (prog1[prg].lye > num_Layers)
{
prog1[prg].lye = num_Layers;
}
}
if (nValidProg == 0)
{
throw new System.InvalidOperationException("Unable to initialize rate allocator: No " + "default progression type has been defined.");
}
// Tile specific values
for (int t = 0; t < numTiles; t++)
{
if (encSpec.pocs.isTileSpecified(t))
{
prog1 = (Progression[]) encSpec.pocs.getTileDef(t);
nValidProg = prog1.Length;
for (int prg = 0; prg < prog1.Length; prg++)
{
if (prog1[prg].lye > num_Layers)
{
prog1[prg].lye = num_Layers;
}
}
if (nValidProg == 0)
{
throw new System.InvalidOperationException("Unable to initialize rate allocator:" + " No default progression type has been " + "defined for tile " + t);
}
}
} // End loop on tiles
#if DO_TIMING
initTime += (System.DateTime.Now.Ticks - 621355968000000000) / 10000 - stime;
#endif
}