2009-09-30 23:50:03 +00:00
/ *
* CVS identifier :
*
* $ Id : MQDecoder . java , v 1.32 2001 / 10 / 17 16 : 58 : 00 grosbois Exp $
*
* Class : MQDecoder
*
* Description : Class that encodes a number of bits using the
* MQ arithmetic decoder
*
*
*
* COPYRIGHT :
*
* This software module was originally developed by Rapha <EFBFBD> l Grosbois and
* Diego Santa Cruz ( Swiss Federal Institute of Technology - EPFL ) ; Joel
* Askel <EFBFBD> f ( Ericsson Radio Systems AB ) ; and Bertrand Berthelot , David
* Bouchard , F <EFBFBD> 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.entropy.decoder ;
using CSJ2K.j2k.entropy ;
using CSJ2K.j2k.io ;
using CSJ2K.j2k.util ;
namespace CSJ2K.j2k.entropy.decoder
{
/// <summary> This class implements the MQ arithmetic decoder. It is implemented using
/// the software conventions decoder for better performance (i.e. execution
/// time performance). The initial states for each context of the MQ-coder are
/// specified in the constructor.
///
/// </summary>
// A trick to test for increased speed: merge the Qe and mPS into 1 thing by
// using the sign bit of Qe to signal mPS (positive-or-0 is 0, negative is 1),
// and doubling the Qe, nMPS and nLPS tables. This gets rid of the swicthLM
// table since it can be integrated as special cases in the doubled nMPS and
// nLPS tables. See the JPEG book, chapter 13. The decoded decision can be
// calculated as (q>>>31).
public class MQDecoder
{
/// <summary> Returns the number of contexts in the arithmetic coder.
///
/// </summary>
/// <returns> The number of contexts
///
/// </returns>
virtual public int NumCtxts
{
get
{
return I . Length ;
}
}
/// <summary> Returns the underlying 'ByteInputBuffer' from where the MQ coded input
/// bytes are read.
///
/// </summary>
/// <returns> The underlying ByteInputBuffer.
///
/// </returns>
virtual public ByteInputBuffer ByteInputBuffer
{
get
{
return in_Renamed ;
}
}
/// <summary>The data structures containing the probabilities for the LPS </summary>
//UPGRADE_NOTE: Final was removed from the declaration of 'qe'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly uint [ ] qe = new uint [ ] { 0x5601 , 0x3401 , 0x1801 , 0x0ac1 , 0x0521 , 0x0221 , 0x5601 , 0x5401 , 0x4801 , 0x3801 , 0x3001 , 0x2401 , 0x1c01 , 0x1601 , 0x5601 , 0x5401 , 0x5101 , 0x4801 , 0x3801 , 0x3401 , 0x3001 , 0x2801 , 0x2401 , 0x2201 , 0x1c01 , 0x1801 , 0x1601 , 0x1401 , 0x1201 , 0x1101 , 0x0ac1 , 0x09c1 , 0x08a1 , 0x0521 , 0x0441 , 0x02a1 , 0x0221 , 0x0141 , 0x0111 , 0x0085 , 0x0049 , 0x0025 , 0x0015 , 0x0009 , 0x0005 , 0x0001 , 0x5601 } ;
/// <summary>The indexes of the next MPS </summary>
//UPGRADE_NOTE: Final was removed from the declaration of 'nMPS'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int [ ] nMPS = new int [ ] { 1 , 2 , 3 , 4 , 5 , 38 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 29 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 45 , 46 } ;
/// <summary>The indexes of the next LPS </summary>
//UPGRADE_NOTE: Final was removed from the declaration of 'nLPS'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int [ ] nLPS = new int [ ] { 1 , 6 , 9 , 12 , 29 , 33 , 6 , 14 , 14 , 14 , 17 , 18 , 20 , 21 , 14 , 14 , 15 , 16 , 17 , 18 , 19 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 46 } ;
/// <summary>Whether LPS and MPS should be switched </summary>
//UPGRADE_NOTE: Final was removed from the declaration of 'switchLM'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal static readonly int [ ] switchLM = new int [ ] { 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
/// <summary>The ByteInputBuffer used to read the compressed bit stream. </summary>
internal ByteInputBuffer in_Renamed ;
/// <summary>The current most probable signal for each context </summary>
internal int [ ] mPS ;
/// <summary>The current index of each context </summary>
internal int [ ] I ;
/// <summary>The current bit code </summary>
internal uint c ;
/// <summary>The bit code counter </summary>
internal uint cT ;
/// <summary>The current interval </summary>
internal uint a ;
/// <summary>The last byte read </summary>
internal uint b ;
/// <summary>Flag indicating if a marker has been found </summary>
internal bool markerFound ;
/// <summary>The initial state of each context </summary>
//UPGRADE_NOTE: Final was removed from the declaration of 'initStates '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
internal int [ ] initStates ;
/// <summary> Instantiates a new MQ-decoder, with the specified number of contexts
/// and initial states. The compressed bytestream is read from the
/// 'iStream' object.
///
/// </summary>
/// <param name="iStream">the stream that contains the coded bits
///
/// </param>
/// <param name="nrOfContexts">The number of contexts used
///
/// </param>
/// <param name="initStates">The initial state for each context. A reference is
/// kept to this array to reinitialize the contexts whenever 'reset()' or
/// 'resetCtxts()' is called.
///
/// </param>
public MQDecoder ( ByteInputBuffer iStream , int nrOfContexts , int [ ] initStates )
{
in_Renamed = iStream ;
// Default initialization of the statistics bins is MPS=0 and
// I=0
I = new int [ nrOfContexts ] ;
mPS = new int [ nrOfContexts ] ;
// Save the initial states
this . initStates = initStates ;
// Initialize
init ( ) ;
// Set the contexts
resetCtxts ( ) ;
}
/// <summary> Decodes 'n' symbols from the bit stream using the same context
/// 'ctxt'. If possible the MQ-coder speedup mode will be used to speed up
/// decoding. The speedup mode is used if Q (the LPS probability for 'ctxt'
/// is low enough) and the A and C registers permit decoding several MPS
/// symbols without renormalization.
///
/// <P>Speedup mode should be used when decoding long runs of MPS with high
/// probability with the same context.
///
/// <P>This methiod will return the decoded symbols differently if speedup
/// mode was used or not. If true is returned, then speedup mode was used
/// and the 'n' decoded symbols are all the same and it is returned ain
/// bits[0] only. If false is returned then speedup mode was not used, the
/// decoded symbols are probably not all the same and they are returned in
/// bits[0], bits[1], ... bits[n-1].
///
/// </summary>
/// <param name="bits">The array where to put the decoded symbols. Must be of
/// length 'n' or more.
///
/// </param>
/// <param name="ctxt">The context to use in decoding the symbols.
///
/// </param>
/// <param name="n">The number of symbols to decode.
///
/// </param>
/// <returns> True if speedup mode was used, false if not. If speedup mode
/// was used then all the decoded symbols are the same and its value is
/// returned in 'bits[0]' only (not in bits[1], bits[2], etc.).
///
/// </returns>
internal bool fastDecodeSymbols ( int [ ] bits , int ctxt , uint n )
{
uint q ; // LPS probability for context
int idx ; // Index of current state
uint la ; // cache for A register
int i ; // counter
idx = I [ ctxt ] ;
q = qe [ idx ] ;
// This is a first attempt to implement speedup mode, it is probably
// not the most efficient way of doing it.
if ( ( q < 0x4000 ) & & ( n < = ( a - ( c > > 16 ) - 1 ) / q ) & & ( n < = ( a - 0x8000 ) / q + 1 ) )
{
// Q is small enough. There will be no modification of C that
// affects decoding, and Q can be substracted from A several
// times. We will decode all MPS.
a - = n * q ;
if ( a > = 0x8000 )
{
// No renormalization needed
bits [ 0 ] = mPS [ ctxt ] ;
return true ; // Done, used speedup mode
}
else
{
// renormalization needed
I [ ctxt ] = nMPS [ idx ] ;
// Renormalize (MPS: no need for while loop)
if ( cT = = 0 )
byteIn ( ) ;
a < < = 1 ;
c < < = 1 ;
cT - - ;
// End renormalization
bits [ 0 ] = mPS [ ctxt ] ;
return true ; // Done, used speedup mode
}
}
else
{
// Normal mode
la = a ; // cache A register
for ( i = 0 ; i < n ; i + + )
{
la - = q ;
if ( ( c > > 16 ) < la )
{
if ( la > = 0x8000 )
{
bits [ i ] = mPS [ ctxt ] ;
}
else
{
// -- MPS Exchange
if ( la > = q )
{
bits [ i ] = mPS [ ctxt ] ;
idx = nMPS [ idx ] ;
q = qe [ idx ] ;
// I[ctxt] set at end of loop
// -- Renormalize (MPS: no need for while loop)
if ( cT = = 0 )
byteIn ( ) ;
la < < = 1 ;
c < < = 1 ;
cT - - ;
// -- End renormalization
}
else
{
bits [ i ] = 1 - mPS [ ctxt ] ;
if ( switchLM [ idx ] = = 1 )
mPS [ ctxt ] = 1 - mPS [ ctxt ] ;
idx = nLPS [ idx ] ;
q = qe [ idx ] ;
// I[ctxt] set at end of loop
// -- Renormalize
do
{
if ( cT = = 0 )
byteIn ( ) ;
la < < = 1 ;
c < < = 1 ;
cT - - ;
}
while ( la < 0x8000 ) ;
// -- End renormalization
}
// -- End MPS Exchange
}
}
else
{
c - = ( la < < 16 ) ;
// -- LPS Exchange
if ( la < q )
{
la = q ;
bits [ i ] = mPS [ ctxt ] ;
idx = nMPS [ idx ] ;
q = qe [ idx ] ;
// I[ctxt] set at end of loop
// -- Renormalize (MPS: no need for while loop)
if ( cT = = 0 )
byteIn ( ) ;
la < < = 1 ;
c < < = 1 ;
cT - - ;
// -- End renormalization
}
else
{
la = q ;
bits [ i ] = 1 - mPS [ ctxt ] ;
if ( switchLM [ idx ] = = 1 )
mPS [ ctxt ] = 1 - mPS [ ctxt ] ;
idx = nLPS [ idx ] ;
q = qe [ idx ] ;
// I[ctxt] set at end of loop
// -- Renormalize
do
{
if ( cT = = 0 )
byteIn ( ) ;
la < < = 1 ;
c < < = 1 ;
cT - - ;
}
while ( la < 0x8000 ) ;
// -- End renormalization
}
// -- End LPS Exchange
}
}
a = la ; // save cached A register
I [ ctxt ] = idx ; // save current index for context
return false ; // done, did not use speedup mode
} // End normal mode
}
/// <summary> This function performs the arithmetic decoding. The function receives
/// an array in which to put the decoded symbols and an array of contexts
/// with which to decode them.
///
/// <P>Each context has a current MPS and an index describing what the
/// current probability is for the LPS. Each bit is decoded and if the
/// probability of the LPS exceeds .5, the MPS and LPS are switched.
///
/// </summary>
/// <param name="bits">The array where to place the decoded symbols. It should be
/// long enough to contain 'n' elements.
///
/// </param>
/// <param name="cX">The context to use in decoding each symbol.
///
/// </param>
/// <param name="n">The number of symbols to decode
///
/// </param>
public void decodeSymbols ( int [ ] bits , int [ ] cX , int n )
{
uint q ;
int ctxt ;
uint la ; // cache for A register value
int index ;
int i ;
// NOTE: (a < 0x8000) is equivalent to ((a & 0x8000)==0)
// since 'a' is always less than or equal to 0xFFFF
// NOTE: conditional exchange guarantees that A for MPS is
// always greater than 0x4000 (i.e. 0.375)
// => one renormalization shift is enough for MPS
// => no need to do a renormalization while loop for MPS
for ( i = 0 ; i < n ; i + + )
{
ctxt = cX [ i ] ;
index = I [ ctxt ] ;
q = qe [ index ] ;
a - = q ;
if ( ( c > > 16 ) < a )
{
if ( a > = 0x8000 )
{
bits [ i ] = mPS [ ctxt ] ;
}
else
{
la = a ;
// -- MPS Exchange
if ( la > = q )
{
bits [ i ] = mPS [ ctxt ] ;
I [ ctxt ] = nMPS [ index ] ;
// -- Renormalize (MPS: no need for while loop)
if ( cT = = 0 )
byteIn ( ) ;
la < < = 1 ;
c < < = 1 ;
cT - - ;
// -- End renormalization
}
else
{
bits [ i ] = 1 - mPS [ ctxt ] ;
if ( switchLM [ index ] = = 1 )
mPS [ ctxt ] = 1 - mPS [ ctxt ] ;
I [ ctxt ] = nLPS [ index ] ;
// -- Renormalize
do
{
if ( cT = = 0 )
byteIn ( ) ;
la < < = 1 ;
c < < = 1 ;
cT - - ;
}
while ( la < 0x8000 ) ;
// -- End renormalization
}
// -- End MPS Exchange
a = la ;
}
}
else
{
la = a ;
c - = ( la < < 16 ) ;
// -- LPS Exchange
if ( la < q )
{
la = q ;
bits [ i ] = mPS [ ctxt ] ;
I [ ctxt ] = nMPS [ index ] ;
// -- Renormalize (MPS: no need for while loop)
if ( cT = = 0 )
byteIn ( ) ;
la < < = 1 ;
c < < = 1 ;
cT - - ;
// -- End renormalization
}
else
{
la = q ;
bits [ i ] = 1 - mPS [ ctxt ] ;
if ( switchLM [ index ] = = 1 )
mPS [ ctxt ] = 1 - mPS [ ctxt ] ;
I [ ctxt ] = nLPS [ index ] ;
// -- Renormalize
do
{
if ( cT = = 0 )
byteIn ( ) ;
la < < = 1 ;
c < < = 1 ;
cT - - ;
}
while ( la < 0x8000 ) ;
// -- End renormalization
}
// -- End LPS Exchange
a = la ;
}
}
}
/// <summary> Arithmetically decodes one symbol from the bit stream with the given
/// context and returns its decoded value.
///
/// <P>Each context has a current MPS and an index describing what the
/// current probability is for the LPS. Each bit is encoded and if the
/// probability of the LPS exceeds .5, the MPS and LPS are switched.
///
/// </summary>
/// <param name="context">The context to use in decoding the symbol
///
/// </param>
/// <returns> The decoded symbol, 0 or 1.
///
/// </returns>
public int decodeSymbol ( int context )
{
uint q ;
uint la ;
int index ;
int decision ;
index = I [ context ] ;
q = qe [ index ] ;
// NOTE: (a < 0x8000) is equivalent to ((a & 0x8000)==0)
// since 'a' is always less than or equal to 0xFFFF
// NOTE: conditional exchange guarantees that A for MPS is
// always greater than 0x4000 (i.e. 0.375)
// => one renormalization shift is enough for MPS
// => no need to do a renormalization while loop for MPS
a - = q ;
if ( ( c > > 16 ) < a )
{
if ( a > = 0x8000 )
{
decision = mPS [ context ] ;
}
else
{
la = a ;
// -- MPS Exchange
if ( la > = q )
{
decision = mPS [ context ] ;
I [ context ] = nMPS [ index ] ;
// -- Renormalize (MPS: no need for while loop)
if ( cT = = 0 )
byteIn ( ) ;
la < < = 1 ;
c < < = 1 ;
cT - - ;
// -- End renormalization
}
else
{
decision = 1 - mPS [ context ] ;
if ( switchLM [ index ] = = 1 )
mPS [ context ] = 1 - mPS [ context ] ;
I [ context ] = nLPS [ index ] ;
// -- Renormalize
do
{
if ( cT = = 0 )
byteIn ( ) ;
la < < = 1 ;
c < < = 1 ;
cT - - ;
}
while ( la < 0x8000 ) ;
// -- End renormalization
}
// -- End MPS Exchange
a = la ;
}
}
else
{
la = a ;
c - = ( la < < 16 ) ;
// -- LPS Exchange
if ( la < q )
{
la = q ;
decision = mPS [ context ] ;
I [ context ] = nMPS [ index ] ;
// -- Renormalize (MPS: no need for while loop)
if ( cT = = 0 )
byteIn ( ) ;
la < < = 1 ;
c < < = 1 ;
cT - - ;
// -- End renormalization
}
else
{
la = q ;
decision = 1 - mPS [ context ] ;
if ( switchLM [ index ] = = 1 )
mPS [ context ] = 1 - mPS [ context ] ;
I [ context ] = nLPS [ index ] ;
// -- Renormalize
do
{
if ( cT = = 0 )
byteIn ( ) ;
la < < = 1 ;
c < < = 1 ;
cT - - ;
}
while ( la < 0x8000 ) ;
// -- End renormalization
}
// -- End LPS Exchange
a = la ;
}
return decision ;
}
/// <summary> Checks for past errors in the decoding process using the predictable
/// error resilient termination. This works only if the encoder used the
/// predictable error resilient MQ termination, otherwise it reports wrong
/// results. If an error is detected it means that the MQ bit stream has
/// been wrongly decoded or that the MQ terminated segment length is too
/// long. If no errors are detected it does not necessarily mean that the
/// MQ bit stream has been correctly decoded.
///
/// </summary>
/// <returns> True if errors are found, false otherwise.
///
/// </returns>
public virtual bool checkPredTerm ( )
{
int k ; // Number of bits that where added in the termination process
uint q ;
// 1) if everything has been OK, 'b' must be 0xFF if a terminating
// marker has not yet been found
if ( b ! = 0xFF & & ! markerFound )
return true ;
// 2) if cT is not 0, we must have already reached the terminating
// marker
if ( cT ! = 0 & & ! markerFound )
return true ;
// 3) If cT is 1 there where no spare bits at the encoder, this is all
// that we can check
if ( cT = = 1 )
return false ;
// 4) if cT is 0, then next byte must be the second byte of a
// terminating marker (i.e. larger than 0x8F) if the terminating
// marker has not been reached yet
if ( cT = = 0 )
{
if ( ! markerFound )
{
// Get next byte and check
b = ( uint ) in_Renamed . read ( ) & 0xFF ;
if ( b < = 0x8F )
return true ;
}
// Adjust cT for last byte
cT = 8 ;
}
// 5) Now we can calculate the number 'k' of bits having error
// resilience information, which is the number of bits left to
// normalization in the C register, minus 1.
k = ( int ) ( cT - 1 ) ;
// 6) The predictable termination policy is as if an LPS interval was
// coded that caused a renormalization of 'k' bits, before the
// termination marker started
// We first check if an LPS is decoded, that causes a renormalization
// of 'k' bits. Worst case is smallest LPS probability 'q' that causes
// a renormalization of 'k' bits.
q = ( ( uint ) 0x8000 ) > > k ;
// Check that we can decode an LPS interval of probability 'q'
a - = q ;
if ( ( c > > 16 ) < a )
{
// Error: MPS interval decoded
return true ;
}
// OK: LPS interval decoded
c - = ( a < < 16 ) ;
// -- LPS Exchange
// Here 'a' can not be smaller than 'q' because the minimum value
// for 'a' is 0x8000-0x4000=0x4000 and 'q' is set to a value equal
// to or smaller than that.
a = q ;
// -- Renormalize
do
{
if ( cT = = 0 )
byteIn ( ) ;
a < < = 1 ;
c < < = 1 ;
cT - - ;
}
while ( a < 0x8000 ) ;
// -- End renormalization
// -- End LPS Exchange
// 7) Everything seems OK, we have checked the C register for the LPS
// symbols and ensured that it is followed by bits synthetized by the
// termination marker.
return false ;
}
/// <summary> This function gets one byte of compressed bits from the in-stream. the
/// byte is added to c. If the byte is 0xFF and the next byte is greater
/// than 0x8F, the byte after 0xFF is a marker.
///
/// </summary>
private void byteIn ( )
{
if ( ! markerFound )
{
if ( b = = 0xFF )
{
b = ( ( uint ) in_Renamed . read ( ) ) & 0xFF ; // Convert EOFs (-1) to 0xFF
if ( b > 0x8F )
{
markerFound = true ;
// software-convention decoder: c unchanged
cT = 8 ;
}
else
{
c + = 0xFE00 - ( b < < 9 ) ;
cT = 7 ;
}
}
else
{
b = ( ( uint ) in_Renamed . read ( ) ) & 0xFF ; // Convert EOFs (-1) to 0xFF
c + = 0xFF00 - ( b < < 8 ) ;
cT = 8 ;
}
}
else
{
// software-convention decoder: c unchanged
cT = 8 ;
}
}
/// <summary> Resets a context to the original probability distribution.
///
/// </summary>
/// <param name="c">The number of the context (it starts at 0).
///
/// </param>
public void resetCtxt ( int c )
{
I [ c ] = initStates [ c ] ;
mPS [ c ] = 0 ;
}
/// <summary> Resets a context to the original probability distribution. The original
/// probability distribution depends on the actual implementation of the
/// arithmetic coder or decoder.
///
/// </summary>
/// <param name="c">The index of the context (it starts at 0).
///
/// </param>
public void resetCtxts ( )
{
2010-08-06 03:11:08 +00:00
Array . Copy ( initStates , 0 , I , 0 , I . Length ) ;
2009-09-30 23:50:03 +00:00
ArrayUtil . intArraySet ( mPS , 0 ) ;
}
/// <summary> Resets the MQ decoder to start a new segment. This is like recreating a
/// new MQDecoder object with new input data.
///
/// </summary>
/// <param name="buf">The byte array containing the MQ encoded data. If null the
/// current byte array is assumed.
///
/// </param>
/// <param name="off">The index of the first element in 'buf' to be decoded. If
/// negative the byte just after the previous segment is assumed, only
/// valid if 'buf' is null.
///
/// </param>
/// <param name="len">The number of bytes in 'buf' to be decoded. Any subsequent
/// bytes are taken to be 0xFF.
///
/// </param>
public void nextSegment ( byte [ ] buf , int off , int len )
{
// Set the new input
in_Renamed . setByteArray ( buf , off , len ) ;
// Reinitialize MQ
init ( ) ;
}
/// <summary> Initializes the state of the MQ coder, without modifying the current
/// context states. It sets the registers (A,C,B) and the "marker found"
/// state to the initial state, to start the decoding of a new segment.
///
/// <P>To have a complete reset of the MQ (as if a new MQDecoder object was
/// created) 'resetCtxts()' should be called after this method.
///
/// </summary>
private void init ( )
{
// --- INITDEC
markerFound = false ;
// Read first byte
b = ( ( uint ) in_Renamed . read ( ) ) & 0xFF ;
// Software conventions decoder
c = ( b ^ 0xFF ) < < 16 ;
byteIn ( ) ;
c = c < < 7 ;
cT = cT - 7 ;
a = 0x8000 ;
// End of INITDEC ---
}
}
}