corrade-vassal – Rev 1
?pathlinks?
/*
* CVS identifier:
*
* $Id: StdQuantizer.java,v 1.14 2001/09/20 12:41:52 grosbois Exp $
*
* Class: StdQuantizer
*
* Description: Scalar deadzone quantizer of integer or float
* data.
*
* Mergerd from StdQuantizerInt and
* StdQuantizerFloat from Joel Askelof.
*
*
* COPYRIGHT:
*
* This software module was originally developed by Raphaël Grosbois and
* Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
* Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
* Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
* Centre France S.A) in the course of development of the JPEG2000
* standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
* software module is an implementation of a part of the JPEG 2000
* Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
* Systems AB and Canon Research Centre France S.A (collectively JJ2000
* Partners) agree not to assert against ISO/IEC and users of the JPEG
* 2000 Standard (Users) any of their rights under the copyright, not
* including other intellectual property rights, for this software module
* with respect to the usage by ISO/IEC and Users of this software module
* or modifications thereof for use in hardware or software products
* claiming conformance to the JPEG 2000 Standard. Those intending to use
* this software module in hardware or software products are advised that
* their use may infringe existing patents. The original developers of
* this software module, JJ2000 Partners and ISO/IEC assume no liability
* for use of this software module or modifications thereof. No license
* or right to this software module is granted for non JPEG 2000 Standard
* conforming products. JJ2000 Partners have full right to use this
* software module for his/her own purpose, assign or donate this
* software module to any third party and to inhibit third parties from
* using this software module for non JPEG 2000 Standard conforming
* products. This copyright notice must be included in all copies or
* derivative works of this software module.
*
* Copyright (c) 1999/2000 JJ2000 Partners.
* */
using System;
using CSJ2K.j2k.codestream.writer;
using CSJ2K.j2k.wavelet.analysis;
using CSJ2K.j2k.quantization;
using CSJ2K.j2k.wavelet;
using CSJ2K.j2k.encoder;
using CSJ2K.j2k.image;
using CSJ2K.j2k;
namespace CSJ2K.j2k.quantization.quantizer
{
/// <summary> This class implements scalar quantization of integer or floating-point
/// valued source data. The source data is the wavelet transformed image data
/// and the output is the quantized wavelet coefficients represented in
/// sign-magnitude (see below).
///
/// <p>Sign magnitude representation is used (instead of two's complement) for
/// the output data. The most significant bit is used for the sign (0 if
/// positive, 1 if negative). Then the magnitude of the quantized coefficient
/// is stored in the next M most significat bits. The rest of the bits (least
/// significant bits) can contain a fractional value of the quantized
/// coefficient. This fractional value is not to be coded by the entropy
/// coder. However, it can be used to compute rate-distortion measures with
/// greater precision.</p>
///
/// <p>The value of M is determined for each subband as the sum of the number
/// of guard bits G and the nominal range of quantized wavelet coefficients in
/// the corresponding subband (Rq), minus 1:</p>
///
/// <p>M = G + Rq -1</p>
///
/// <p>The value of G should be the same for all subbands. The value of Rq
/// depends on the quantization step size, the nominal range of the component
/// before the wavelet transform and the analysis gain of the subband (see
/// Subband).</p>
///
/// <p>The blocks of data that are requested should not cross subband
/// boundaries.</p>
///
/// </summary>
/// <seealso cref="Subband">
///
/// </seealso>
/// <seealso cref="Quantizer">
///
/// </seealso>
public class StdQuantizer:Quantizer
{
/// <summary> Returns the quantization type spec object associated to the quantizer.
///
/// </summary>
/// <returns> The quantization type spec
///
/// </returns>
virtual public QuantTypeSpec QuantTypeSpec
{
get
{
return qts;
}
}
/// <summary>The number of mantissa bits for the quantization steps </summary>
public const int QSTEP_MANTISSA_BITS = 11;
/// <summary>The number of exponent bits for the quantization steps </summary>
// NOTE: formulas in 'convertFromExpMantissa()' and
// 'convertToExpMantissa()' methods do not support more than 5 bits.
public const int QSTEP_EXPONENT_BITS = 5;
/// <summary>The maximum value of the mantissa for the quantization steps </summary>
//UPGRADE_NOTE: Final was removed from the declaration of 'QSTEP_MAX_MANTISSA '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
public static readonly int QSTEP_MAX_MANTISSA = (1 << QSTEP_MANTISSA_BITS) - 1;
/// <summary>The maximum value of the exponent for the quantization steps </summary>
//UPGRADE_NOTE: Final was removed from the declaration of 'QSTEP_MAX_EXPONENT '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
public static readonly int QSTEP_MAX_EXPONENT = (1 << QSTEP_EXPONENT_BITS) - 1;
/// <summary>Natural log of 2, used as a convenience variable </summary>
private static double log2 = System.Math.Log(2);
/// <summary>The quantization type specifications </summary>
private QuantTypeSpec qts;
/// <summary>The quantization step size specifications </summary>
private QuantStepSizeSpec qsss;
/// <summary>The guard bits specifications </summary>
private GuardBitsSpec gbs;
/// <summary>The 'CBlkWTDataFloat' object used to request data, used when
/// quantizing floating-point data.
/// </summary>
// This variable makes the class thread unsafe, but it avoids allocating
// new objects for code-block that is quantized.
private CBlkWTDataFloat infblk;
/// <summary> Initializes the source of wavelet transform coefficients. The
/// constructor takes information on whether the quantizer is in
/// reversible, derived or expounded mode. If the quantizer is reversible
/// the value of 'derived' is ignored. If the source data is not integer
/// (int) then the quantizer can not be reversible.
///
/// <p>After initializing member attributes, getAnSubbandTree is called for
/// all components setting the 'stepWMSE' for all subbands in the current
/// tile.</p>
///
/// </summary>
/// <param name="src">The source of wavelet transform coefficients.
///
/// </param>
/// <param name="encSpec">The encoder specifications
///
/// </param>
public StdQuantizer(CBlkWTDataSrc src, EncoderSpecs encSpec):base(src)
{
qts = encSpec.qts;
qsss = encSpec.qsss;
gbs = encSpec.gbs;
}
/// <summary> Returns the number of guard bits used by this quantizer in the given
/// tile-component.
///
/// </summary>
/// <param name="t">Tile index
///
/// </param>
/// <param name="c">Component index
///
/// </param>
/// <returns> The number of guard bits
///
/// </returns>
public override int getNumGuardBits(int t, int c)
{
return ((System.Int32) gbs.getTileCompVal(t, c));
}
/// <summary> Returns true if the quantized data is reversible, for the specified
/// tile-component. For the quantized data to be reversible it is necessary
/// and sufficient that the quantization is reversible.
///
/// </summary>
/// <param name="t">The tile to test for reversibility
///
/// </param>
/// <param name="c">The component to test for reversibility
///
/// </param>
/// <returns> True if the quantized data is reversible, false if not.
///
/// </returns>
public override bool isReversible(int t, int c)
{
return qts.isReversible(t, c);
}
/// <summary> Returns true if given tile-component uses derived quantization step
/// sizes.
///
/// </summary>
/// <param name="t">Tile index
///
/// </param>
/// <param name="c">Component index
///
/// </param>
/// <returns> True if derived
///
/// </returns>
public override bool isDerived(int t, int c)
{
return qts.isDerived(t, c);
}
/// <summary> Returns the next code-block in the current tile for the specified
/// component, as a copy (see below). The order in which code-blocks are
/// returned is not specified. However each code-block is returned only
/// once and all code-blocks will be returned if the method is called 'N'
/// times, where 'N' is the number of code-blocks in the tile. After all
/// the code-blocks have been returned for the current tile calls to this
/// method will return 'null'.
///
/// <p>When changing the current tile (through 'setTile()' or 'nextTile()')
/// this method will always return the first code-block, as if this method
/// was never called before for the new current tile.</p>
///
/// <p>The data returned by this method is always a copy of the
/// data. Therfore it can be modified "in place" without any problems after
/// being returned. The 'offset' of the returned data is 0, and the 'scanw'
/// is the same as the code-block width. See the 'CBlkWTData' class.</p>
///
/// <p>The 'ulx' and 'uly' members of the returned 'CBlkWTData' object
/// contain the coordinates of the top-left corner of the block, with
/// respect to the tile, not the subband.</p>
///
/// </summary>
/// <param name="c">The component for which to return the next code-block.
///
/// </param>
/// <param name="cblk">If non-null this object will be used to return the new
/// code-block. If null a new one will be allocated and returned. If the
/// "data" array of the object is non-null it will be reused, if possible,
/// to return the data.
///
/// </param>
/// <returns> The next code-block in the current tile for component 'n', or
/// null if all code-blocks for the current tile have been returned.
///
/// </returns>
/// <seealso cref="CBlkWTData">
///
/// </seealso>
public override CBlkWTData getNextCodeBlock(int c, CBlkWTData cblk)
{
return getNextInternCodeBlock(c, cblk);
}
/// <summary> Returns the next code-block in the current tile for the specified
/// component. The order in which code-blocks are returned is not
/// specified. However each code-block is returned only once and all
/// code-blocks will be returned if the method is called 'N' times, where
/// 'N' is the number of code-blocks in the tile. After all the code-blocks
/// have been returned for the current tile calls to this method will
/// return 'null'.
///
/// <p>When changing the current tile (through 'setTile()' or 'nextTile()')
/// this method will always return the first code-block, as if this method
/// was never called before for the new current tile.</p>
///
/// <p>The data returned by this method can be the data in the internal
/// buffer of this object, if any, and thus can not be modified by the
/// caller. The 'offset' and 'scanw' of the returned data can be
/// arbitrary. See the 'CBlkWTData' class.</p>
///
/// <p>The 'ulx' and 'uly' members of the returned 'CBlkWTData' object
/// contain the coordinates of the top-left corner of the block, with
/// respect to the tile, not the subband.</p>
///
/// </summary>
/// <param name="c">The component for which to return the next code-block.
///
/// </param>
/// <param name="cblk">If non-null this object will be used to return the new
/// code-block. If null a new one will be allocated and returned. If the
/// "data" array of the object is non-null it will be reused, if possible,
/// to return the data.
///
/// </param>
/// <returns> The next code-block in the current tile for component 'n', or
/// null if all code-blocks for the current tile have been returned.
///
/// </returns>
/// <seealso cref="CBlkWTData">
///
/// </seealso>
public override CBlkWTData getNextInternCodeBlock(int c, CBlkWTData cblk)
{
// NOTE: this method is declared final since getNextCodeBlock() relies
// on this particular implementation
int k, j;
int tmp, shiftBits, jmin;
int w, h;
int[] outarr;
float[] infarr = null;
CBlkWTDataFloat infblk;
float invstep; // The inverse of the quantization step size
bool intq; // flag for quantizig ints
SubbandAn sb;
float stepUDR; // The quantization step size (for a dynamic
// range of 1, or unit)
int g = ((System.Int32) gbs.getTileCompVal(tIdx, c));
// Are we quantizing ints or floats?
intq = (src.getDataType(tIdx, c) == DataBlk.TYPE_INT);
// Check that we have an output object
if (cblk == null)
{
cblk = new CBlkWTDataInt();
}
// Cache input float code-block
infblk = this.infblk;
// Get data to quantize. When quantizing int data 'cblk' is used to
// get the data to quantize and to return the quantized data as well,
// that's why 'getNextCodeBlock()' is used. This can not be done when
// quantizing float data because of the different data types, that's
// why 'getNextInternCodeBlock()' is used in that case.
if (intq)
{
// Source data is int
cblk = src.getNextCodeBlock(c, cblk);
if (cblk == null)
{
return null; // No more code-blocks in current tile for comp.
}
// Input and output arrays are the same (for "in place" quant.)
outarr = (int[]) cblk.Data;
}
else
{
// Source data is float
// Can not use 'cblk' to get float data, use 'infblk'
infblk = (CBlkWTDataFloat) src.getNextInternCodeBlock(c, infblk);
if (infblk == null)
{
// Release buffer from infblk: this enables to garbage collect
// the big buffer when we are done with last code-block of
// component.
this.infblk.Data = null;
return null; // No more code-blocks in current tile for comp.
}
this.infblk = infblk; // Save local cache
infarr = (float[]) infblk.Data;
// Get output data array and check that there is memory to put the
// quantized coeffs in
outarr = (int[]) cblk.Data;
if (outarr == null || outarr.Length < infblk.w * infblk.h)
{
outarr = new int[infblk.w * infblk.h];
cblk.Data = outarr;
}
cblk.m = infblk.m;
cblk.n = infblk.n;
cblk.sb = infblk.sb;
cblk.ulx = infblk.ulx;
cblk.uly = infblk.uly;
cblk.w = infblk.w;
cblk.h = infblk.h;
cblk.wmseScaling = infblk.wmseScaling;
cblk.offset = 0;
cblk.scanw = cblk.w;
}
// Cache width, height and subband of code-block
w = cblk.w;
h = cblk.h;
sb = cblk.sb;
if (isReversible(tIdx, c))
{
// Reversible only for int data
cblk.magbits = g - 1 + src.getNomRangeBits(c) + sb.anGainExp;
shiftBits = 31 - cblk.magbits;
// Update the convertFactor field
cblk.convertFactor = (1 << shiftBits);
// Since we used getNextCodeBlock() to get the int data then
// 'offset' is 0 and 'scanw' is the width of the code-block The
// input and output arrays are the same (i.e. "in place")
for (j = w * h - 1; j >= 0; j--)
{
tmp = (outarr[j] << shiftBits);
outarr[j] = ((tmp < 0)?(1 << 31) | (- tmp):tmp);
}
}
else
{
// Non-reversible, use step size
//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) qsss.getTileCompVal(tIdx, c));
// Calculate magnitude bits and quantization step size
if (isDerived(tIdx, c))
{
//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'"
cblk.magbits = g - 1 + sb.level - (int) System.Math.Floor(System.Math.Log(baseStep) / log2);
stepUDR = baseStep / (1 << sb.level);
}
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'"
cblk.magbits = g - 1 - (int) System.Math.Floor(System.Math.Log(baseStep / (sb.l2Norm * (1 << sb.anGainExp))) / log2);
stepUDR = baseStep / (sb.l2Norm * (1 << sb.anGainExp));
}
shiftBits = 31 - cblk.magbits;
// Calculate step that decoder will get and use that one.
stepUDR = convertFromExpMantissa(convertToExpMantissa(stepUDR));
invstep = 1.0f / ((1L << (src.getNomRangeBits(c) + sb.anGainExp)) * stepUDR);
// Normalize to magnitude bits (output fractional point)
invstep *= (1 << (shiftBits - src.getFixedPoint(c)));
// Update convertFactor and stepSize fields
cblk.convertFactor = invstep;
cblk.stepSize = ((1L << (src.getNomRangeBits(c) + sb.anGainExp)) * stepUDR);
if (intq)
{
// Quantizing int data
// Since we used getNextCodeBlock() to get the int data then
// 'offset' is 0 and 'scanw' is the width of the code-block
// The input and output arrays are the same (i.e. "in place")
for (j = w * h - 1; j >= 0; j--)
{
//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'"
tmp = (int) (outarr[j] * invstep);
outarr[j] = ((tmp < 0)?(1 << 31) | (- tmp):tmp);
}
}
else
{
// Quantizing float data
for (j = w * h - 1, k = infblk.offset + (h - 1) * infblk.scanw + w - 1, jmin = w * (h - 1); j >= 0; jmin -= w)
{
for (; j >= jmin; k--, j--)
{
//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'"
tmp = (int) (infarr[k] * invstep);
outarr[j] = ((tmp < 0)?(1 << 31) | (- tmp):tmp);
}
// Jump to beggining of previous line in input
k -= (infblk.scanw - w);
}
}
}
// Return the quantized code-block
return cblk;
}
/// <summary> Calculates the parameters of the SubbandAn objects that depend on the
/// Quantizer. The 'stepWMSE' field is calculated for each subband which is
/// a leaf in the tree rooted at 'sb', for the specified component. The
/// subband tree 'sb' must be the one for the component 'n'.
///
/// </summary>
/// <param name="sb">The root of the subband tree.
///
/// </param>
/// <param name="c">The component index
///
/// </param>
/// <seealso cref="SubbandAn.stepWMSE">
///
/// </seealso>
protected internal override void calcSbParams(SubbandAn sb, int c)
{
float baseStep;
if (sb.stepWMSE > 0f)
// parameters already calculated
return ;
if (!sb.isNode)
{
if (isReversible(tIdx, c))
{
//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'"
sb.stepWMSE = (float) System.Math.Pow(2, - (src.getNomRangeBits(c) << 1)) * sb.l2Norm * sb.l2Norm;
}
else
{
//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'"
baseStep = (float) ((System.Single) qsss.getTileCompVal(tIdx, c));
if (isDerived(tIdx, c))
{
//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'"
sb.stepWMSE = baseStep * baseStep * (float) System.Math.Pow(2, (sb.anGainExp - sb.level) << 1) * sb.l2Norm * sb.l2Norm;
}
else
{
sb.stepWMSE = baseStep * baseStep;
}
}
}
else
{
calcSbParams((SubbandAn) sb.LL, c);
calcSbParams((SubbandAn) sb.HL, c);
calcSbParams((SubbandAn) sb.LH, c);
calcSbParams((SubbandAn) sb.HH, c);
sb.stepWMSE = 1f; // Signal that we already calculated this branch
}
}
/// <summary> Converts the floating point value to its exponent-mantissa
/// representation. The mantissa occupies the 11 least significant bits
/// (bits 10-0), and the exponent the previous 5 bits (bits 15-11).
///
/// </summary>
/// <param name="step">The quantization step, normalized to a dynamic range of 1.
///
/// </param>
/// <returns> The exponent mantissa representation of the step.
///
/// </returns>
public static int convertToExpMantissa(float step)
{
int exp;
//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'"
exp = (int) System.Math.Ceiling((- System.Math.Log(step)) / log2);
if (exp > QSTEP_MAX_EXPONENT)
{
// If step size is too small for exponent representation, use the
// minimum, which is exponent QSTEP_MAX_EXPONENT and mantissa 0.
return (QSTEP_MAX_EXPONENT << QSTEP_MANTISSA_BITS);
}
// NOTE: this formula does not support more than 5 bits for the
// exponent, otherwise (-1<<exp) might overflow (the - is used to be
// able to represent 2**31)
//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'"
return (exp << QSTEP_MANTISSA_BITS) | ((int) (((- step) * (- 1 << exp) - 1f) * (1 << QSTEP_MANTISSA_BITS) + 0.5f));
}
/// <summary> Converts the exponent-mantissa representation to its floating-point
/// value. The mantissa occupies the 11 least significant bits (bits 10-0),
/// and the exponent the previous 5 bits (bits 15-11).
///
/// </summary>
/// <param name="ems">The exponent-mantissa representation of the step.
///
/// </param>
/// <returns> The floating point representation of the step, normalized to a
/// dynamic range of 1.
///
/// </returns>
private static float convertFromExpMantissa(int ems)
{
// NOTE: this formula does not support more than 5 bits for the
// exponent, otherwise (-1<<exp) might overflow (the - is used to be
// able to represent 2**31)
//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'"
return (- 1f - ((float) (ems & QSTEP_MAX_MANTISSA)) / ((float) (1 << QSTEP_MANTISSA_BITS))) / (float) (- 1 << ((ems >> QSTEP_MANTISSA_BITS) & QSTEP_MAX_EXPONENT));
}
/// <summary> Returns the maximum number of magnitude bits in any subband of the
/// current tile.
///
/// </summary>
/// <param name="c">the component number
///
/// </param>
/// <returns> The maximum number of magnitude bits in all subbands of the
/// current tile.
///
/// </returns>
public override int getMaxMagBits(int c)
{
Subband sb = getAnSubbandTree(tIdx, c);
if (isReversible(tIdx, c))
{
return getMaxMagBitsRev(sb, c);
}
else
{
if (isDerived(tIdx, c))
{
return getMaxMagBitsDerived(sb, tIdx, c);
}
else
{
return getMaxMagBitsExpounded(sb, tIdx, c);
}
}
}
/// <summary> Returns the maximum number of magnitude bits in any subband of the
/// current tile if reversible quantization is used
///
/// </summary>
/// <param name="sb">The root of the subband tree of the current tile
///
/// </param>
/// <param name="c">the component number
///
/// </param>
/// <returns> The highest number of magnitude bit-planes
///
/// </returns>
private int getMaxMagBitsRev(Subband sb, int c)
{
int tmp, max = 0;
int g = ((System.Int32) gbs.getTileCompVal(tIdx, c));
if (!sb.isNode)
return g - 1 + src.getNomRangeBits(c) + sb.anGainExp;
max = getMaxMagBitsRev(sb.LL, c);
tmp = getMaxMagBitsRev(sb.LH, c);
if (tmp > max)
max = tmp;
tmp = getMaxMagBitsRev(sb.HL, c);
if (tmp > max)
max = tmp;
tmp = getMaxMagBitsRev(sb.HH, c);
if (tmp > max)
max = tmp;
return max;
}
/// <summary> Returns the maximum number of magnitude bits in any subband in the
/// given tile-component if derived quantization is used
///
/// </summary>
/// <param name="sb">The root of the subband tree of the tile-component
///
/// </param>
/// <param name="t">Tile index
///
/// </param>
/// <param name="c">Component index
///
/// </param>
/// <returns> The highest number of magnitude bit-planes
///
/// </returns>
private int getMaxMagBitsDerived(Subband sb, int t, int c)
{
int tmp, max = 0;
int g = ((System.Int32) gbs.getTileCompVal(t, c));
if (!sb.isNode)
{
//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) qsss.getTileCompVal(t, c));
//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'"
return g - 1 + sb.level - (int) System.Math.Floor(System.Math.Log(baseStep) / log2);
}
max = getMaxMagBitsDerived(sb.LL, t, c);
tmp = getMaxMagBitsDerived(sb.LH, t, c);
if (tmp > max)
max = tmp;
tmp = getMaxMagBitsDerived(sb.HL, t, c);
if (tmp > max)
max = tmp;
tmp = getMaxMagBitsDerived(sb.HH, t, c);
if (tmp > max)
max = tmp;
return max;
}
/// <summary> Returns the maximum number of magnitude bits in any subband in the
/// given tile-component if expounded quantization is used
///
/// </summary>
/// <param name="sb">The root of the subband tree of the tile-component
///
/// </param>
/// <param name="t">Tile index
///
/// </param>
/// <param name="c">Component index
///
/// </param>
/// <returns> The highest number of magnitude bit-planes
///
/// </returns>
private int getMaxMagBitsExpounded(Subband sb, int t, int c)
{
int tmp, max = 0;
int g = ((System.Int32) gbs.getTileCompVal(t, c));
if (!sb.isNode)
{
//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) qsss.getTileCompVal(t, c));
//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'"
return g - 1 - (int) System.Math.Floor(System.Math.Log(baseStep / (((SubbandAn) sb).l2Norm * (1 << sb.anGainExp))) / log2);
}
max = getMaxMagBitsExpounded(sb.LL, t, c);
tmp = getMaxMagBitsExpounded(sb.LH, t, c);
if (tmp > max)
max = tmp;
tmp = getMaxMagBitsExpounded(sb.HL, t, c);
if (tmp > max)
max = tmp;
tmp = getMaxMagBitsExpounded(sb.HH, t, c);
if (tmp > max)
max = tmp;
return max;
}
}
}
Generated by GNU Enscript 1.6.5.90.