imagingmodules/jp2kcodec/Src/JP2KEntropyDecoder.cpp
changeset 0 469c91dae73b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KEntropyDecoder.cpp	Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1857 @@
+/*
+* Copyright (c) 2003, 2004 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Entropy decoder functionality..
+*
+*/
+
+
+// INCLUDE FILES
+#include "JP2KCodeBlock.h"
+#include "JP2KTileInfo.h"
+#include "JP2KImageInfo.h"
+#include "JP2KEntropyDecoder.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES  
+
+// CONSTANTS
+
+// Mq decoder state information, all of the 47 states contain
+// the probability estimate of LPS in hexadecimal, the next
+// mps state index, the next lps state index and the flag
+// indicating a mps switch.
+const TUint32 KMqQeStates[KNumberOriginalMQEntries] =  {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};
+
+const TInt32 KMqMpsStates[KNumberOriginalMQEntries] =  {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};
+
+const TInt32 KMqLpsStates[KNumberOriginalMQEntries] =  {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};
+
+const TInt32 KMqSwitchFlagStates[KNumberOriginalMQEntries] =  {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};
+
+// MQCoder initial states
+const TInt32 KMqInitStates[KNumberContexts] = {46,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// J2KEntropyStream::ReadByteFromStream
+// Read a byte from the input stream
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+TUint8 J2KEntropyStream::ReadByteFromStream()
+    {
+    if ( iPosition < iNumBytes )
+        {
+        return ( TUint8 )iBuffer[iPosition++];
+        }
+    else
+        {
+        // 0xFF to represent EOF
+        return ( 0xFF );   
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// J2KEntropyStream::ReadBitFromStream
+// Read a bit from the input stream
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+TUint8 J2KEntropyStream::ReadBitFromStream() 
+    {
+    if ( iTinyBufferPos == 0 )
+        {
+        // Input the byte buffer
+        iTinyBuffer = ReadByteFromStream();
+
+        if ( iDelayedFF )
+            {
+            iTinyBufferPos = 7;
+            }
+        else
+            {
+            iTinyBufferPos = 8;
+            }
+
+        if ( iTinyBuffer != 0xFF ) // No bit-stuffing needed
+            {
+            iDelayedFF = 0;
+            }
+        else  // We need to do bit stuffing on next byte
+            {
+            iDelayedFF = 1;
+            }
+        }
+
+    return (TUint8)( ( iTinyBuffer >> ( --iTinyBufferPos ) ) & 0x01 );
+    }
+
+// -----------------------------------------------------------------------------
+// J2KEntropyStream::CheckPrediction
+// Check a prediction termination for raw coding
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+TEntropyErrorState J2KEntropyStream::CheckPrediction()
+    {
+    // Error resilient sequence in last byte
+    TInt32 errorResSeq = 0; 
+ 
+    // If tiny buffer is empty and equal to 0xFF, 
+    // get the next byte for error resilience marker
+    if ( iTinyBufferPos == 0 && iTinyBuffer == 0xFF ) 
+        {
+        iTinyBuffer = ReadByteFromStream();
+        iTinyBufferPos = 7;
+        }
+  
+    // Search for the error resilience marker
+    if ( iTinyBufferPos > 0 ) 
+        {
+        // Get the error resilience sequence
+        errorResSeq = iTinyBuffer & ( ( 1 << iTinyBufferPos ) - 1 );
+
+        // Compare the read error resilience marker to the constant 01010101 byte
+        if ( errorResSeq != ( KErrorResilienceTermination >> ( 8 - iTinyBufferPos ) ) ) 
+            {
+            return EEntropyCodingError;
+            }
+        }
+  
+    // If we are not at the end of this stream, 
+    // next byte should be smaller than 0x80.
+    if ( iPosition < iNumBytes )
+        {
+        if ( iTinyBuffer == 0xFF && iTinyBufferPos == 1 ) 
+            {
+            if ( ReadByteFromStream() >= 0x80 ) 
+                {
+                return EEntropyCodingError;
+                }
+            }
+        else 
+            {
+            if ( ReadByteFromStream() != 0xFF ) 
+                {
+                return EEntropyCodingError;
+                }
+            }
+        }
+
+    // No error detected
+    return ENoError;
+    }
+
+// -----------------------------------------------------------------------------
+// J2KEntropyStream::ResetInputStream
+// Reset the input stream
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KEntropyStream::ResetInputStream()
+    {
+    // Initialize the stream parameters. Note that stream->position is not reset here,
+    // it is reset only when the stream is created for the first time.
+    iTinyBuffer = 0;
+    iTinyBufferPos = 0;
+    iDelayedFF = 0;
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// Destructor
+J2KMQCoder::~J2KMQCoder()
+    {
+    iOriginalStates.ResetAndDestroy();
+    iContextList.ResetAndDestroy();
+    }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::MqByteIn
+// Read a byte from the input stream
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::MqByteIn()
+    {
+    if ( !iMarker )
+        {
+        if ( iB == 0xff )
+            {
+            iB = iInputStream.ReadByteFromStream();
+
+            if ( iB > 0x8f )
+                {
+                iMarker = 1;
+                iCT = 8;
+                }
+            else
+                {
+                iC += 0xFE00 - ( iB << 9 );
+                iCT = 7;
+                }
+            }
+        else
+            {
+            iB = iInputStream.ReadByteFromStream();
+            iC += 0xFF00 - ( iB << 8 );
+            iCT = 8;
+            }   
+        }
+    else
+        {
+        iCT = 8;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::MqDecodeSymbol
+// Decode the symbol
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+TUint8 J2KMQCoder::MqDecodeSymbol( TInt32 aContextIndex )
+    {
+    // Set the current context to point to the right place in the context list
+    iCurrentContext = iContextList[aContextIndex];
+    iCurrentState = iCurrentContext->iState;
+
+    iA -= iCurrentState->iQe;
+
+    // Decision returned ( i.e. decoded symbol )
+    TInt32 decision = 0;  
+    if ( ( iC >> 16 ) < iA )  // Chigh >= A
+        {
+        MpsExchange( decision );
+        }
+    else   // lps exchange
+        {
+        LpsExchange( decision );
+        }
+
+    // Return decision 
+    return (TUint8)decision;   
+    }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::MqInitDecoder
+// Initialize the MQCoder
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::MqInitDecoder()
+    {
+    iMarker = 0;
+    iB = iInputStream.ReadByteFromStream();
+
+    // Software conventions decoder initialization 
+    iC = ( iB ^ 0xFF ) << 16;
+    MqByteIn();
+  
+    iC <<= 7;
+    iCT -= 7;
+    iA = 0x8000;
+    }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::MqCheckPrediction
+// Check the prediction termination
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+TEntropyErrorState J2KMQCoder::MqCheckPrediction()
+    {
+    // If no marker was found, B should be == 0xFF and counter zero, 
+    // otherwise there is an error
+    if ( !iMarker && ( iCT != 0 || iB != 0xFF ) ) 
+        {
+        return EEntropyCodingError;
+        }
+  
+    // If counter CT is 1, no need to check any further
+    if ( iCT == 1 )
+        {
+        return ENoError;
+        }
+  
+    // If counter CT is zero, then next byte must be larger than 0x8F, if the terminating
+    // marker has not been reached yet
+    if ( iCT == 0 )  
+        {
+        if ( !iMarker ) 
+            {
+            // Get next byte and check that it is larger than 0x8F
+            iB = iInputStream.ReadByteFromStream();
+            if ( iB <= 0x8F )
+                {
+                return EEntropyCodingError;
+                }
+            }
+        // Set the counter back to 8
+        iCT = 8;
+        }
+
+    // Number of bits that where added in the termination process
+    // Compute the number of bits, k for error resilience information
+    TUint32 k = (TUint32)( iCT - 1 );
+  
+    // Check for a coded LPS.
+    TUint32 q = 0x8000 >> k;
+  
+    // Check that we can decode an LPS interval of probability 'q'
+    iA -= q;
+    if ( ( iC >> 16 ) < iA )   // software convention
+        {
+        // MPS interval was decoded, thus error occured
+        return EEntropyCodingError;
+        }
+ 
+    // Check for coded LPS interval.
+    iA = q;
+
+    do  // Renormalization
+        {
+        if ( iCT == 0 )
+            {
+            MqByteIn();
+            }
+
+        iA <<= 1;
+        iC <<= 1;
+        iCT--;
+
+        } while ( iA < 0x8000 );
+  
+    // No error was found
+    return ENoError;
+    }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::ResetMqContexts
+// Reset the MQCoder context list to the original state
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::ResetMqContexts()
+    {
+    // Reset all context states to initial states and set the mps
+    // of every context to 0.
+    for ( TInt32 i = KNumberContexts - 1; i >= 0; i-- )
+        {
+        iContextList[i]->iState = iOriginalStates[KMqInitStates[i]];
+        iContextList[i]->iMPS = 0;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::ResetMQDecoder
+// Initialze MQCoder and reset the context
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::ResetMQDecoder( TInt32 aSegmentLength )
+    {
+    // Reset all contexts ( states and mps )
+    ResetMqContexts();              
+    iInputStream.ResetInputStream();
+    iInputStream.iPosition = 0;
+    iInputStream.iNumBytes = aSegmentLength;
+    MqInitDecoder();
+    }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::InitializeOrigMqTable
+// Initialize MQCoder original states table
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::InitializeOrigMqTable()
+    {
+    for ( TUint8 i = 0; i < KNumberOriginalMQEntries; i++ )
+        {
+        iOriginalStates[i]->iQe = KMqQeStates[i];
+        iOriginalStates[i]->iNextMPS = iOriginalStates[KMqMpsStates[i]];
+        iOriginalStates[i]->iNextLPS = iOriginalStates[KMqLpsStates[i]];
+        iOriginalStates[i]->iSwitchFlag = KMqSwitchFlagStates[i];
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::ReNormalize
+// Renormalize 
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::ReNormalize()
+    {
+    do
+        {
+        if ( iCT == 0 )
+            {
+            MqByteIn();
+            }
+
+        iA <<= 1;
+        iC <<= 1;
+        --iCT;
+        } while ( !( iA & 0x8000 ) );
+    }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::MpsExchange
+// MPS exchange
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::MpsExchange( TInt32& aD )
+    {
+    aD = iCurrentContext->iMPS;
+    if ( !( iA & 0x8000 ) )
+        {
+        if ( iA < iCurrentState->iQe )
+            {
+            aD ^= 1;
+            if ( iCurrentState->iSwitchFlag )
+                {
+                iCurrentContext->iMPS ^= 1;
+                }
+
+            iCurrentContext->iState = iCurrentState->iNextLPS;
+            }
+        else
+            {
+            iCurrentContext->iState = iCurrentState->iNextMPS;
+            }
+
+        ReNormalize();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// J2KMQCoder::LpsExchange
+// LPS exchange
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+void J2KMQCoder::LpsExchange( TInt32& aD )
+    {
+    iC -= iA << 16;
+    aD = iCurrentContext->iMPS;
+    if ( iA < iCurrentState->iQe )
+        {
+        iCurrentContext->iState = iCurrentState->iNextMPS;
+        }
+    else
+        {
+        aD ^= 1;
+        if ( iCurrentState->iSwitchFlag )
+            {
+            iCurrentContext->iMPS ^= 1;
+            }
+
+        iCurrentContext->iState = iCurrentState->iNextLPS;
+        }
+    iA = iCurrentState->iQe;
+    ReNormalize(  );
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJ2kEntropyDecoder* CJ2kEntropyDecoder::NewL( CJ2kImageInfo& aImageInfo )
+    {
+    CJ2kEntropyDecoder *self = new ( ELeave ) CJ2kEntropyDecoder;
+
+    CleanupStack::PushL( self );
+    self->ConstructL( aImageInfo );
+    CleanupStack::Pop();
+
+    return self;
+    }
+
+// Destructor
+CJ2kEntropyDecoder::~CJ2kEntropyDecoder()
+    {  
+    delete iMRLutBuf;
+    iMRLutBuf = 0;
+
+    delete iSCLutBuf;
+    iSCLutBuf = 0;
+  
+    delete iZcLutLL;
+    iZcLutLL = 0;
+
+    delete iZcLutHL;
+    iZcLutHL = 0;
+
+    delete iZcLutHH;
+    iZcLutHH = 0;
+    
+    TJ2kUtils::Free2DArray( iData );
+    User::Free( iStates );
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::SetNewSizeL
+// Set the size of internal buffer and other control data
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::SetNewSizeL( const TSize& aSize )
+    {
+    if ( aSize.iWidth <= iCurrentSize.iWidth &&
+         aSize.iHeight <= iCurrentSize.iHeight )
+        {
+        return;
+        }
+    else
+        {
+        iCurrentSize = aSize;
+
+        TJ2kUtils::Free2DArray( iData );
+        iData = 0;
+        iData = TJ2kUtils::Alloc2DArrayL( iCurrentSize.iHeight, iCurrentSize.iWidth );
+
+        iMaxBlockWidth = (TUint8)( iCurrentSize.iWidth );
+
+        // We can compute some parameters for entropy decoding here not to compute them for every pass!!!
+        iBlockDataWidth        = iMaxBlockWidth;
+        iStateWidth            = iMaxBlockWidth + 2;
+        iStateSize             = ( iCurrentSize.iHeight + 2 ) * ( iCurrentSize.iWidth + 2 );
+        iDataSamplesPerStripe  = iBlockDataWidth * KStripeHeight;
+        iStateSamplesPerStripe = iStateWidth * KStripeHeight;
+
+        TInt16* ptrTemp = STATIC_CAST( TInt16*, User::ReAlloc( iStates, iStateSize * sizeof( TInt16 ) ) );
+        if ( !ptrTemp )
+            {
+            User::Leave( KErrNoMemory );
+            }
+        iStates = ptrTemp;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::SetCurrentZCLUT
+// Set the current pointer to point to the right LUT depending on  the current subband
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::SetCurrentZCLUT( TUint8 aBandIndex )
+    {
+    if ( aBandIndex == 1 )
+        {
+        // For HL band
+        iCurrentZcLutPtr = (TUint8*)iZcLutHL->Des().Ptr();
+        }
+    else if ( aBandIndex == 3 )
+        {
+        // For HH band
+        iCurrentZcLutPtr = (TUint8*)iZcLutHH->Des().Ptr();
+        }
+    else 
+        {
+        // For LL and LH band
+        iCurrentZcLutPtr = (TUint8*)iZcLutLL->Des().Ptr();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::DecodeCodeblock
+// Decode the coded codeblock
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::DecodeCodeblock( CJ2kCodeBlock& aCodeblock, TUint8 aCblkStyle, 
+                                          TUint8 aMagBits )
+    {
+    TInt32 startBitplane = 0;     // The bitplane where coding starts
+    TInt32 endBitplane = 0;       // The last coded bitplane
+    TInt32 terminationLength = 0;
+    TUint8 tempPassIndex = 0;
+    TUint8 passIndex = 0;
+
+    iMQDecoder.iInputStream.iBuffer = CONST_CAST( TUint8*, aCodeblock.Data() );
+    TSize codeBlockSize = aCodeblock.CodeBlockCanvas().Size();
+
+    iVerticalCausalContextUsed     = ( ( aCblkStyle & EVerticalStripe ) != 0 );
+    iResetContexts                 = ( ( aCblkStyle & EResetContext ) != 0 );
+    iPredictableTerminationUsed    = ( ( aCblkStyle & EPredictableTermination ) != 0 );
+    TUint8 terminateEachPass       = ( ( aCblkStyle & ETermination ) != 0 );
+    TUint8 segmentationSymbolsUsed = ( ( aCblkStyle & ESegmentationSymbols ) != 0 );
+    TUint8 arithmeticBypass        = ( ( aCblkStyle & EArithmeticBypass ) != 0 );
+    aCodeblock.ResetPassIndex();
+  
+  
+    // Initialize the stream and the mq coder for this code block:
+    // also set mq coder's stream to point to aCodeblock's stream 
+    if ( !arithmeticBypass && !terminateEachPass )  // No termination
+        {
+        iMQDecoder.ResetMQDecoder( aCodeblock.DataLength() );
+        }
+    else
+        {
+        // Compute the length of the first terminated segment. If we are 
+        // terminating on each pass, terminated lengths are equal to 
+        // codeblock lengths. On the other hand if we are using arithmetic
+        // bypass ( without terminating each pass ), the first termination length
+        // is the codeblock lengths summed up to the point where we have last AC
+        // pass before first raw coding pass.
+
+        if ( terminateEachPass )
+            {
+            terminationLength = aCodeblock.CblkLength( (TUint16)passIndex++ );
+            }
+        else  // AC bypass without termination on each pass
+            {
+            // Loop adding codeblock lengths until enough passes have been consumed 
+            while ( ( tempPassIndex < KFirstBypassTermIndex ) && ( passIndex <= aCodeblock.LastPass() ) )
+                {
+                tempPassIndex = (TUint8)( tempPassIndex + aCodeblock.PassesPerSegment( passIndex ) );
+                terminationLength = (TUint32)( terminationLength + aCodeblock.CblkLength( passIndex++ ) );
+                }
+            }
+
+        // Now initialize the iMQDecoder with the right terminated length
+        iMQDecoder.ResetMQDecoder( terminationLength );
+        }
+  
+    // Initialize data array 
+    for ( TInt i = codeBlockSize.iHeight - 1; i >= 0; i-- )
+        {
+        Mem::FillZ( iData[i], codeBlockSize.iWidth * sizeof( TPrecInt ) );
+        }
+  
+    // Initialize iStates array
+    Mem::FillZ( iStates, iStateSize * sizeof( TInt16 ) );
+  
+    // Compute different bitplanes; empty bitplanes tells how many bitplanes are 
+    // empty in this codeblock compared to the whole subband, iStartBitplane gives
+    // the index of the first bitplane to be coded for this block and iEndBitplane
+    // is the index of the last bitplane coded for this codeblock.
+  
+    // Compute coded block's magnitude bits 
+    aMagBits = (TUint8)( aMagBits - aCodeblock.EmptyBitplanes() );
+    startBitplane = ( KImplementationPrecision - 2 ) - aCodeblock.EmptyBitplanes();
+    endBitplane = startBitplane - aMagBits;
+ 
+    // Compute the number of stripes for this codeblock 
+    iNumStripes = (TUint16)( ( codeBlockSize.iHeight + KStripeHeight - 1 ) / KStripeHeight );
+    iBlockWidth = codeBlockSize.iWidth;
+
+    // Compute the last stripe's height once, 
+    // so that we don't have to compute it for all passes!
+    iLastStripeHeight = codeBlockSize.iHeight - ( iNumStripes - 1 ) * KStripeHeight;
+
+    iCurrentBitplane = (TUint8)( startBitplane );
+
+    // First do only the normalization pass 
+    iTerminateThisPass = ( terminateEachPass || ( iCurrentBitplane == endBitplane ) );
+
+    CleanupPass( segmentationSymbolsUsed );
+
+    aCodeblock.IncrementPassIndex();
+
+    iCurrentBitplane--;
+  
+    // Then repeat the three passes: significance, refinement and normalization 
+    // for the remaining bitplanes.
+    while ( aCodeblock.PassIndex() <= aCodeblock.LastPass() )
+        {
+        // Significance pass, terminate only if terminating after each pass
+        iTerminateThisPass = terminateEachPass;
+
+        if ( ( arithmeticBypass == 0 ) || ( aCodeblock.PassIndex() < KFirstLazyPassIndex ) )
+            {
+            if ( terminateEachPass )  // if last pass was terminated, initialize MQ-coder
+                {
+                // Update the number of available TUint8s for this terminated sequence
+                iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex++ );
+                iMQDecoder.MqInitDecoder();
+                }
+
+            SignificancePass();
+            }
+        else
+            {
+            // if we are here, then the previous pass was terminated
+            if ( terminateEachPass )
+                {
+                // Update the number of available bytes for this terminated sequence 
+                iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex++ );
+                }
+            else  // AC bypass without termination on each pass 
+                {
+                // Here we have two cases:
+                // 1. If this codeblock length is for this pass only, then for the terminated length 
+                //    we have to add the next pass codeblock length also. 
+                // 2. This codeblock length is for both this pass ( significance ) and the next pass 
+                //    ( refinement ). Terminated length is equal to the CblkLength[iPassIndex].
+                if ( aCodeblock.PassesPerSegment( passIndex ) == 2 )
+                    {
+                    iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex++ );
+                    }
+                else
+                    {
+                    iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex ) + 
+                                                         aCodeblock.CblkLength( (TUint16)( passIndex + 1 ) );
+                    passIndex += 2;
+                    }
+                }
+            iMQDecoder.iInputStream.ResetInputStream();
+            LazySignificancePass();
+            }
+    
+        aCodeblock.IncrementPassIndex();
+        if ( aCodeblock.PassIndex() > aCodeblock.LastPass() )
+            {
+            // We have fully decoded this codeblock
+            return;
+            }
+    
+        // Magnitude refinement pass, terminate if raw coding or termination after each pass
+        iTerminateThisPass = ( terminateEachPass || ( arithmeticBypass && ( aCodeblock.PassIndex() > 
+                                                                            KFirstLazyPassIndex ) ) );
+
+        if ( arithmeticBypass == 0 || ( aCodeblock.PassIndex() < KFirstLazyPassIndex ) )
+            {
+            if ( terminateEachPass ) // if previous pass was terminated, initialize MQ-coder 
+                {
+                // Update the number of available bytes for this terminated sequence
+                iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex++ );
+                iMQDecoder.MqInitDecoder();
+                }
+
+            RefinementPass();
+            }
+        else
+            {
+            if ( terminateEachPass )  // if previous pass was terminated
+                {
+                // Update the number of available bytes for this terminated sequence
+                iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex++ );
+                iMQDecoder.iInputStream.ResetInputStream();
+                }
+
+            LazyRefinementPass();
+            }
+    
+        aCodeblock.IncrementPassIndex();
+        if ( aCodeblock.PassIndex() > aCodeblock.LastPass() )
+            {
+            // We have fully decoded this codeblock
+            return;
+            }
+    
+        // Cleanup pass, terminate if coding raw, termination after each pass, last bitplane
+        // before starting raw coding or last bitplane in this codeblock.
+        iTerminateThisPass = ( terminateEachPass || ( iCurrentBitplane == endBitplane ) || 
+                             ( arithmeticBypass && ( aCodeblock.PassIndex() >= KFirstLazyPassIndex ) ) );
+    
+        // If last ( AC ) pass was terminated, initialize MQ-coder
+        if ( terminateEachPass || ( arithmeticBypass && ( aCodeblock.PassIndex() > KFirstLazyPassIndex ) ) )
+            {
+            // Update the number of available bytes for this terminated sequence
+            iMQDecoder.iInputStream.iNumBytes += aCodeblock.CblkLength( passIndex++ );
+            iMQDecoder.MqInitDecoder();
+            }
+
+        CleanupPass( segmentationSymbolsUsed );
+    
+        aCodeblock.IncrementPassIndex();
+        if ( aCodeblock.PassIndex() > aCodeblock.LastPass() )
+            {
+            // We have fully decoded this codeblock
+            return;
+            }
+
+        // move onto next bitplane
+        if ( iCurrentBitplane == 0 )  // This might happen with 16-bit and ROI
+            {
+            // We have fully decoded this codeblock
+            return;
+            }
+
+        iCurrentBitplane--;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::ConstructL( CJ2kImageInfo& aImageInfo )
+    {
+    iCurrentSize = aImageInfo.MaxBlockSize();
+
+    for ( TUint16 i = 0; i < KNumberContexts; i++ )
+        {
+        J2KEntropyContexts *context = new ( ELeave ) J2KEntropyContexts;
+        CleanupStack::PushL( context );
+        User::LeaveIfError( iMQDecoder.iContextList.Append( context ) );
+        CleanupStack::Pop(1);
+        }
+
+    for ( TUint16 ii = 0; ii < KNumberOriginalMQEntries; ii++ )
+        {
+        J2KEntropyStates *state = new ( ELeave ) J2KEntropyStates;
+        CleanupStack::PushL( state );
+        User::LeaveIfError( iMQDecoder.iOriginalStates.Append( state ) );
+        CleanupStack::Pop(1);
+        }
+
+    // Allocate memory for the SC Look up table
+    iSCLutBuf = HBufC8::NewL( KLutSize );
+    iSCLut = CONST_CAST( TUint8*, iSCLutBuf->Des().Ptr() );
+
+    // Allocate memory for the MR Look up table
+    iMRLutBuf = HBufC8::NewL( KLutSize );
+    iMRLut = CONST_CAST( TUint8*, iMRLutBuf->Des().Ptr() );
+
+    // Allocate memory for the Zero coding Look up table
+    iZcLutLL = HBufC8::NewL( ( 1 << KZcLutBits ) );
+    iZcLutHL = HBufC8::NewL( ( 1 << KZcLutBits ) );
+    iZcLutHH = HBufC8::NewL( ( 1 << KZcLutBits ) );
+
+    iData = TJ2kUtils::Alloc2DArrayL( iCurrentSize.iHeight, iCurrentSize.iWidth );
+
+    iMaxBlockWidth = (TUint16)( iCurrentSize.iWidth );
+
+    // We can compute some parameters for entropy decoding here not to compute them for every pass!!!
+    iBlockDataWidth        = iMaxBlockWidth;
+    iStateWidth            = iMaxBlockWidth + 2;
+    iStateSize             = ( iCurrentSize.iHeight + 2 ) * ( iCurrentSize.iWidth + 2 );
+    iDataSamplesPerStripe  = iBlockDataWidth * KStripeHeight;
+    iStateSamplesPerStripe = iStateWidth * KStripeHeight;
+
+    iStates = STATIC_CAST( TInt16*, User::AllocL( iStateSize * sizeof( TInt16 ) ) );
+
+    // Initialization of the MQ tables needed since
+    // the original table could not be used as it was constant!
+    iMQDecoder.InitializeOrigMqTable();
+
+    iMaxBitDepth = 0;
+    for ( TUint16 iii = 0; iii < aImageInfo.NumOfComponents(); ++iii )
+        {
+        iMaxBitDepth = Max( iMaxBitDepth, aImageInfo.DepthOfComponent( iii ) );
+        }
+
+    // Initialize ZC lookup table
+    InitializeZCLut();
+
+    // Initialize SC/MR lookup table
+    InitializeScMrLut();
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::InitializeZCLut
+// Initialize ZC lookup table
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::InitializeZCLut()
+    {
+    // Create pointers for all the ZC LUT's
+    TUint8* iZcLutLLPtr = CONST_CAST( TUint8*, iZcLutLL->Des().Ptr() );
+    TUint8* iZcLutHLPtr = CONST_CAST( TUint8*, iZcLutHL->Des().Ptr() );
+    TUint8* iZcLutHHPtr = CONST_CAST( TUint8*, iZcLutHH->Des().Ptr() );
+
+    TInt32 ctxt = 0; 
+    TUint16 sh = 0;     // horizontal sum
+    TUint16 sv = 0;     // vertical sum
+    TUint16 sd = 0;     // diagonal sum
+
+    for ( TUint16 i = 0; i <= KZcMask; i++ )
+        {
+        sh = (TUint16)( ( ( i >> KPositionRight ) & 1 ) + ( ( i >> KPositionLeft ) & 1 ) );
+        sv = (TUint16)( ( ( i >> KPositionDown ) & 1 ) + ( ( i >> KPositionUp ) & 1 ) );
+        sd = (TUint16)( ( ( i >> KPositionUpperLeft ) & 1 ) + ( ( i >> KPositionUpperRight ) & 1 ) + 
+                      ( ( i >> KPositionLowerLeft ) & 1 ) + ( ( i >> KPositionLowerRight ) & 1 ) );
+
+        if ( sh == 2 )
+            {
+            ctxt = 10;
+            }
+        else if ( sh == 1 )
+            {
+            if ( sv )
+                {
+                ctxt = 9;
+                }
+            else if ( sd )
+                {
+                ctxt = 8;
+                }
+            else
+                {
+                ctxt = 7;
+                }
+            }
+        else
+            {
+            if ( sv )
+                {
+                ctxt = 4 + sv;
+                }
+            else
+                {
+                ctxt = 2 + ( ( sd > 2 ) ? 2 : sd );
+                }
+            }
+
+        iZcLutLLPtr[i] = (TUint8) ctxt;
+
+
+        if ( sv == 2 )
+            {
+            ctxt = 10;
+            }
+        else if ( sv == 1 )
+            {
+            if ( sh )
+                {
+                ctxt = 9;
+                }
+            else if ( sd )
+                {
+                ctxt = 8;
+                }
+            else
+                {
+                ctxt = 7;
+                }
+            }
+        else
+            {
+            if ( sh )
+                {
+                ctxt = 4 + sh;
+                }
+            else
+                {
+                ctxt = 2 + ( ( sd > 2 ) ? 2 : sd );
+                }
+            }
+
+        iZcLutHLPtr[i] = (TUint8) ctxt;
+    
+        if ( sd >= 3 )
+            {
+            ctxt = 10;
+            }
+        else if ( sd == 2 )
+            {
+            if ( ( sv + sh ) >= 1 )
+                {
+                ctxt = 9;
+                }
+            else
+                {
+                ctxt = 8;
+                }
+            }
+        else if ( sd == 1 )
+            {
+            ctxt = 5 + ( ( ( sv + sh ) > 2 ) ? 2 : ( sv + sh ) );
+            }
+        else
+            {
+            ctxt = 2 + ( ( ( sv + sh ) > 2 ) ? 2 : ( sv + sh ) );
+            }
+    
+        iZcLutHHPtr[i] = (TUint8) ctxt;
+        } 
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::InitializeScMrLut
+// Initialize SC/MR lookup table
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::InitializeScMrLut()
+    {
+    TInt32 ctxt = 0; 
+    TInt32 vpos = 0;    // vert +
+    TInt32 vneg = 0;    // vert -
+    TInt32 hpos = 0;    // hor +
+    TInt32 hneg = 0;    // hor -
+    TInt32 hc = 0;      // horizontal contribution
+    TInt32 vc = 0;      // vertical contribution
+    TInt16 predict = 0; // the xor bit for differentiating states. ( positioned at the 6th bit )
+
+    for ( TUint8 i = 0; i < 16; i++ )
+        {
+        vpos = i & 1;
+        vneg = ( i >> 1 ) & 1;
+        hpos = ( i >> 2 ) & 1;
+        hneg = ( i >> 3 ) & 1;
+        hc = hpos - hneg;
+        vc = vpos - vneg;
+        predict = 0;
+        if ( hc < 0 )
+            {
+            predict = 1;
+            hc = -hc;
+            vc = -vc;
+            }
+        if ( hc == 0 )
+            {
+            if ( vc < 0 )
+                {
+                predict = 1;
+                vc = -vc;
+                }
+            ctxt = 11 + vc;
+            }
+        else
+            {
+            ctxt = 14 + vc;
+            }
+
+        iSCLut[i] = (TUint8) ( ctxt | ( predict << KPredictionBit ) );
+        }
+    iMRLut[0] = 16;
+    iMRLut[1] = 17;
+    iMRLut[2] = 18;
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::GetCausal
+// Get the casual
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::GetCausal( TPrecInt*& aDataCol, TInt16*& aStateCol )
+    {
+    TInt32 vpos = 0;
+    TInt32 vneg = 0;
+    TUint16 state = 0;
+    TInt16 causalityMask = 0;
+
+    aDataCol--;
+    for ( TInt32 col = iStateWidth; col > 0; col-- )
+        {
+        state = *aStateCol;
+        vpos = 0;
+        vneg = 0;
+        if ( ( ( state >> KPositionDown ) & 1 ) == 1 )
+            {
+            if ( ( ( state >> KPositionUp ) & 1 ) == 1 )
+                {
+                if ( col < iStateWidth )
+                    {
+                    if ( *aDataCol >= 0 )
+                        {
+                        vneg = 1;
+                        }
+                    else
+                        {
+                        vpos = 1;
+                        }
+                    }
+                }
+            else
+                { 
+                vpos = 1;
+                vneg = 1;
+                }
+            }
+        causalityMask = (TInt16)( ~( ( KStateDown| KStateLowerLeft | KStateLowerRight ) | 
+                                     ( vneg << KPositionVerNeg ) | ( vpos << KPositionVerPos ) ) );
+
+        ( *aStateCol ) &= causalityMask;
+        aDataCol++;
+        aStateCol++;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::DecodeSignificance
+// Decode the significance bit
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::DecodeSignificance( TPrecInt*& aDataValue, TInt16*& aStateValue, TPrecInt aMask )
+    {
+    TUint32 state = *aStateValue;
+    TInt32 context = state & KZcMask;
+    if ( ( state & KStateSignificant ) == 0 && context > 0 )
+        { 
+        if ( iMQDecoder.MqDecodeSymbol( iCurrentZcLutPtr[context] ) != 0 )
+            {
+            TUint32 ctxt = iSCLut[( state >> KScShift ) & KScLutMask];
+            TInt32 symbol = iMQDecoder.MqDecodeSymbol( ( ctxt & KScLutMask ) ) ^ ( ( ctxt >> KPredictionBit ) & 1 );
+            *aDataValue = ( symbol << KSignShift ) | aMask;
+            *aStateValue |= KStateSignificant | KStateVisited;
+            UpdateSignificance( aStateValue, symbol );
+            }
+        else
+            {
+            ( *aStateValue ) |= KStateVisited;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::DecodeRawSignificance
+// Decode the lazy significance bit
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::DecodeRawSignificance( TPrecInt*& aDataValue, TInt16*& aStateValue, TPrecInt aMask )
+    {
+    TInt32 state = *aStateValue;
+    if ( ( state & KStateSignificant ) == 0 && ( state & KZcMask ) > 0 )
+        { 
+        if ( iMQDecoder.iInputStream.ReadBitFromStream() )
+            {
+            TInt32 symbol = iMQDecoder.iInputStream.ReadBitFromStream();
+            *aDataValue = ( symbol << KSignShift ) | aMask;
+            *aStateValue |= KStateSignificant | KStateVisited;
+            UpdateSignificance( aStateValue, symbol );
+            }
+        else
+            {
+            ( *aStateValue ) |= KStateVisited;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::DecodeRefinement
+// Decode the refinement bit
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::DecodeRefinement( TPrecInt*& aDataValue, TInt16*& aStateValue, 
+                                           TPrecInt aMask, TInt32 aResetMask )
+    {
+    TInt32 state = *aStateValue;
+    if ( ( state & ( KStateSignificant | KStateVisited ) ) == KStateSignificant )
+        {
+        TInt16 mrContext = (TInt16)( state & KStatePreviousMR );
+        TInt32 ctxt = 0;
+        if ( mrContext )
+            {
+            ctxt = 2;
+            }
+        else
+            {
+            if ( ( state & KZcMask ) == 0 )
+                {
+                ctxt = 0;
+                }
+            else
+                {
+                ctxt = 1;
+                }
+            } 
+        TInt32 symbol = iMQDecoder.MqDecodeSymbol( iMRLut[ctxt] );
+        ( *aDataValue ) &= aResetMask;
+        ( *aDataValue ) |= ( symbol << iCurrentBitplane ) | aMask;
+        ( *aStateValue ) |= KStatePreviousMR;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::DecodeRawRefinement
+// Decode the lazy refinement bit
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::DecodeRawRefinement( TPrecInt*& aDataValue, TInt16*& aStateValue, 
+                                              TPrecInt aMask, TInt32 aResetMask )
+    {
+    if ( ( ( *aStateValue ) & ( KStateSignificant | KStateVisited ) ) == KStateSignificant )
+        {
+        TInt32 symbol = iMQDecoder.iInputStream.ReadBitFromStream();
+        ( *aDataValue ) &= aResetMask;
+        ( *aDataValue ) |= ( symbol << iCurrentBitplane ) | aMask;
+        ( *aStateValue ) |= KStatePreviousMR;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::DecodeNormalization
+// Perform the normalization
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::DecodeNormalization( TPrecInt*& aDataValue, TInt16*& aStateValue, 
+                                              TPrecInt aMask, TInt32& aZCValue )
+    {
+    TUint32 state = *aStateValue;
+    if ( state < (TUint32)KStateVisited )
+        {
+        TInt32 symbol = 0;
+        TUint32 ctxt = 0;
+        if ( aZCValue == 1 )
+            {
+            ( *aStateValue ) &= ~KStateVisited;
+            if ( iMQDecoder.MqDecodeSymbol( iCurrentZcLutPtr[state & KZcMask] ) != 0 )
+                {
+                ctxt = iSCLut[( state >> KScShift ) & KScLutMask];
+                symbol = iMQDecoder.MqDecodeSymbol( ( ctxt & KScLutMask ) ) ^( ( ctxt >> KPredictionBit ) & 1 );
+                ( *aDataValue ) = ( symbol << KSignShift ) | aMask;
+                ( *aStateValue ) |= KStateSignificant;
+                UpdateSignificance( aStateValue, symbol );
+                aZCValue = 1;
+                }
+            }
+        else
+            {
+            ctxt = iSCLut[( state >> KScShift ) & KScLutMask];
+            symbol = iMQDecoder.MqDecodeSymbol( ( ctxt & KScLutMask ) ) ^ ( ( ctxt >> KPredictionBit ) & 1 );
+            ( *aDataValue ) = ( symbol << KSignShift ) | aMask;
+            ( *aStateValue ) |= KStateSignificant; \
+            UpdateSignificance( aStateValue, symbol );
+            aZCValue = 1; 
+            }
+        } 
+    else
+        {
+        ( *aStateValue ) &= ( ~KStateVisited );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::UpdateSignificance
+// Update the significance
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::UpdateSignificance( TInt16*& aStateValue, TInt32 aSymbol )
+    {
+    TInt16* u = ( aStateValue ) - ( iStateWidth );
+    TInt16* d = ( aStateValue ) + ( iStateWidth );
+    u[-1] |= KStateLowerRight;
+    u[1] |= KStateLowerLeft;
+    d[-1] |= KStateUpperRight;
+    d[1] |= KStateUpperLeft;
+
+    if ( aSymbol != 0 )
+        {
+        aStateValue[-1] |= KStateRight | KStateHorNegative;
+        aStateValue[1] |= KStateLeft | KStateHorNegative;
+        *d |= KStateUp | KStateVerNegative;
+        *u |= KStateDown | KStateVerNegative;
+        }
+    else
+        {
+        aStateValue[-1] |= KStateRight | KStateHorPositive;
+        aStateValue[1] |= KStateLeft | KStateHorPositive;
+        *d |= KStateUp | KStateVerPositive;
+        *u |= KStateDown | KStateVerPositive;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::SignificancePass
+// Perform the significance pass
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::SignificancePass()
+    {
+    // Mask for the current bitplane is actually also an approximation of the 
+    // lower bitplanes, i.e. mask might be 00001100 for the fourth bitplane instead
+    // of 00001000, thus the data will be increased by the current bitplane and
+    // half of the sum of the lower bitplanes.
+    TPrecInt mask = ( 1 << iCurrentBitplane ) | ( 1 << ( iCurrentBitplane - 1 ) );
+  
+    TPrecInt* dataRow = &( iData[0][0] );
+    TInt16*   stateRow = CONST_CAST( TInt16*, GetFirstStateRow(  ) );
+
+    TPrecInt* dataCol = 0;
+    TPrecInt* dataValue = 0; 
+    TInt16*   stateCol = 0;
+    TInt16*   stateValue = 0;
+    
+    // Column index in the stripe
+    TInt32 col = 0; 
+    TInt32 row = 0;
+
+    // Code stripe by stripe
+    for ( TInt32 s = iNumStripes - 1; s > 0; s-- )
+        {
+        // If using stripe causal context formation, reset necessary bits
+        // in state of first line in next stripe ( not on last
+        // stripe ).
+        if ( iVerticalCausalContextUsed )
+            {
+            dataCol = dataRow + 2 * iBlockDataWidth;
+            stateCol = stateRow + iStateSamplesPerStripe - iStateWidth - 1;
+            GetCausal( dataCol, stateCol );
+            }
+  
+        dataCol = dataRow;
+        stateCol = stateRow;
+    
+        // Scan column by column in each stripe
+        for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+            {
+            stateValue = stateCol;
+            dataValue = dataCol;
+
+            for ( row = KStripeHeight; row > 0; row-- )
+                {
+                DecodeSignificance( dataValue, stateValue, mask );
+                dataValue += iBlockDataWidth;
+                stateValue += iStateWidth;
+                }
+            }
+
+        dataRow += iDataSamplesPerStripe;
+        stateRow += iStateSamplesPerStripe;
+        }
+
+    // Deal with the last stripe separately
+    dataCol = dataRow;
+    stateCol = stateRow;
+    
+    // Scan column by column in each stripe
+    for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+        {
+        stateValue = stateCol;
+        dataValue = dataCol;
+
+        for ( row = iLastStripeHeight; row > 0; row-- )
+            {
+            DecodeSignificance( dataValue, stateValue, mask );
+            if ( row > 1 )
+                {
+                dataValue += iBlockDataWidth;
+                }
+            stateValue += iStateWidth;
+            }
+        }
+
+    // If there is predictable termination, check for errors
+    if ( iTerminateThisPass && iPredictableTerminationUsed )
+        {
+        iErrorState = iMQDecoder.MqCheckPrediction();
+        }
+  
+    // Reset the MQ context states if we need to
+    if ( iResetContexts )
+        {
+        iMQDecoder.ResetMqContexts();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::LazySignificancePass
+// Perform the lazy significance pass
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::LazySignificancePass()
+    {
+    // Mask for the current bitplane 
+    TPrecInt mask = ( 1 << iCurrentBitplane ) | ( 1 << ( iCurrentBitplane - 1 ) );
+  
+    TPrecInt* dataRow = &( iData[0][0] );
+    TInt16*   stateRow = CONST_CAST( TInt16*, GetFirstStateRow() );
+    TPrecInt* dataCol = 0;
+    TPrecInt* dataValue = 0; 
+    TInt16* stateCol = 0;
+    TInt16* stateValue = 0;
+
+    // Column index in the stripe
+    TInt32 col = 0; 
+    TInt32 row = 0;
+
+    for ( TInt32 s = iNumStripes - 1; s > 0; s-- )
+        {
+        // If using stripe causal context formation, reset necessary bits
+        // in state of first line in next stripe ( not on last
+        // stripe ).
+        if ( iVerticalCausalContextUsed )
+            {
+            dataCol = dataRow + 2 * iBlockDataWidth;
+            stateCol = stateRow + iStateSamplesPerStripe - iStateWidth - 1;
+            GetCausal( dataCol, stateCol );
+            }
+
+        // Scan column by column in each stripe
+        dataCol = dataRow;
+        stateCol = stateRow;
+    
+        // Scan column by column in each stripe 
+        for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+            {
+            stateValue = stateCol;
+            dataValue = dataCol;
+
+            for ( row = KStripeHeight; row > 0; row-- )
+                {
+                DecodeRawSignificance( dataValue, stateValue, mask );
+                dataValue += iBlockDataWidth;
+                stateValue += iStateWidth;
+                }
+            }
+        dataRow += iDataSamplesPerStripe;
+        stateRow += iStateSamplesPerStripe;
+        }
+
+    // Deal with the last stripe separately
+    // Scan column by column in each stripe
+    dataCol = dataRow;
+    stateCol = stateRow;
+  
+    // Line index
+    TInt32 l = 0;
+    
+    // Scan column by column in each stripe 
+    for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+        {
+        stateValue = stateCol;
+        dataValue = dataCol;
+
+        l = iLastStripeHeight;
+        DecodeRawSignificance( dataValue, stateValue, mask );
+        if ( --l <= 0 )
+            {
+            continue;   //lint !e960    Continue is OK, no need to go end of for.
+            }
+    
+        dataValue += iBlockDataWidth;
+        stateValue += iStateWidth;
+        DecodeRawSignificance( dataValue, stateValue, mask );
+        if ( --l <= 0 )
+            {
+            continue;   //lint !e960    Continue is OK, no need to go end of for.
+            }
+    
+        dataValue += iBlockDataWidth;
+        stateValue += iStateWidth;
+        DecodeRawSignificance( dataValue, stateValue, mask );
+        if ( --l <= 0 )
+            {
+            continue;   //lint !e960    Continue is OK, no need to go end of for.
+            }
+    
+        dataValue += iBlockDataWidth;
+        stateValue += iStateWidth;
+        DecodeRawSignificance( dataValue, stateValue, mask );
+
+        }
+  
+    // If there is predictable termination, check for errors 
+    if ( iTerminateThisPass && iPredictableTerminationUsed )
+        {
+        iErrorState = iMQDecoder.iInputStream.CheckPrediction();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::RefinementPass
+// Perform the refinement pass
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::RefinementPass()
+    {
+    // To reset the effects of the approximation done in significance and
+    // normalization passes we have the resetmask.
+    TInt32 resetMask = ( -1 ) << ( iCurrentBitplane + 1 );
+    TUint32 mask = ( ( TUint32 )( 1 << iCurrentBitplane ) ) >> 1;
+  
+    TPrecInt* dataRow = &( iData[0][0] );
+    TInt16*   stateRow = CONST_CAST( TInt16*, GetFirstStateRow() );
+
+    TPrecInt* dataCol = 0;
+    TPrecInt* dataValue = 0; 
+    TInt16* stateCol = 0;
+    TInt16* stateValue = 0;
+
+    // Column index in the stripe
+    TInt32 col = 0; 
+    TInt32 row = 0;
+  
+    // Code stripe by stripe 
+    for ( TInt32 s = iNumStripes - 1; s > 0; s-- )
+        {
+        // If using stripe causal context formation, reset necessary bits
+        // in state of first line in next stripe ( not on last
+        // stripe ).
+        if ( iVerticalCausalContextUsed )
+            {
+            dataCol = dataRow + 2 * iBlockDataWidth;
+            stateCol = stateRow + iStateSamplesPerStripe - iStateWidth - 1;
+            GetCausal( dataCol, stateCol );
+            }
+    
+        // Scan column by column in each stripe
+        dataCol = dataRow;
+        stateCol = stateRow;
+    
+        // Scan column by column in each stripe
+        for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+            {
+            dataValue  = dataCol;
+            stateValue = stateCol;
+
+            for ( row = KStripeHeight; row > 0; row-- )
+                {
+                DecodeRefinement( dataValue, stateValue, mask, resetMask );
+                dataValue += iBlockDataWidth;
+                stateValue += iStateWidth;
+                }
+            }
+        dataRow += iDataSamplesPerStripe;
+        stateRow += iStateSamplesPerStripe;
+        }
+
+    // Deal with the last stripe separately
+    // Scan column by column in each stripe
+    dataCol = dataRow;
+    stateCol = stateRow;
+  
+    // Scan column by column in the last stripe
+    for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+        {
+        dataValue  = dataCol;
+        stateValue = stateCol;
+
+        for ( row = iLastStripeHeight; row > 0; row-- )
+            {
+            DecodeRefinement( dataValue, stateValue, mask, resetMask );
+            if ( row > 1 )
+                {
+                dataValue += iBlockDataWidth;
+                }
+            stateValue += iStateWidth;
+            }
+        }
+  
+    // If there is predictable termination, check for errors 
+    if ( iTerminateThisPass && iPredictableTerminationUsed )
+        {
+        iErrorState = iMQDecoder.MqCheckPrediction();
+        }
+  
+    // Reset the MQ context states if we need to
+    if ( iResetContexts )
+        {
+        iMQDecoder.ResetMqContexts();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::LazyRefinementPass
+// Perform the lazy refinement pass
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::LazyRefinementPass()
+    {  
+    TInt32 resetMask = ( -1 ) << ( iCurrentBitplane + 1 );
+    TUint32 mask = ( ( TUint32 )( 1 << iCurrentBitplane ) ) >> 1;
+    TPrecInt* dataRow = &( iData[0][0] );
+    TInt16*   stateRow = CONST_CAST( TInt16*, GetFirstStateRow() );
+    TPrecInt* dataCol = 0;
+    TPrecInt* dataValue = 0; 
+    TInt16* stateCol = 0;
+    TInt16* stateValue = 0;
+
+    // Column index in the stripe
+    TInt32 col = 0; 
+    TInt32 row = 0;
+
+    // Code stripe by stripe
+    for ( TInt32 s = iNumStripes - 1; s > 0; s-- )
+        {
+        // If using stripe causal context formation, reset necessary bits
+        // in state of first line in next stripe ( not on last
+        // stripe ).
+        if ( iVerticalCausalContextUsed )
+            {
+            dataCol = dataRow + 2 * iBlockDataWidth;
+            stateCol = stateRow + iStateSamplesPerStripe - iStateWidth - 1;
+            GetCausal( dataCol, stateCol );
+            }
+    
+        // Scan column by column in each stripe
+        dataCol = dataRow;
+        stateCol = stateRow;
+    
+        // Scan column by column in each stripe
+        for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+            {
+            dataValue  = dataCol;
+            stateValue = stateCol;
+            for ( row = KStripeHeight; row > 0; row-- )
+                {
+                DecodeRawRefinement( dataValue, stateValue, mask, resetMask );
+                dataValue += iBlockDataWidth;
+                stateValue += iStateWidth;
+                }
+            }
+        dataRow += iDataSamplesPerStripe;
+        stateRow += iStateSamplesPerStripe;
+        }
+
+    // Deal with the last stripe separately
+    // Scan column by column in each stripe
+    dataCol = dataRow;
+    stateCol = stateRow;
+  
+    // Scan column by column in each stripe
+    for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+        {
+        dataValue  = dataCol;
+        stateValue = stateCol;
+
+        for ( row = iLastStripeHeight; row > 0; row-- )
+            {
+            DecodeRawRefinement( dataValue, stateValue, mask, resetMask );
+            dataValue += iBlockDataWidth;
+            stateValue += iStateWidth;
+            }
+        stateValue = stateCol;
+        dataValue = dataCol;
+        }
+  
+    // If there is predictable termination, check for errors
+    if ( iTerminateThisPass && iPredictableTerminationUsed )
+        {
+        iErrorState = iMQDecoder.iInputStream.CheckPrediction();
+        }
+
+    // Because this is always terminated, reset stream
+    iMQDecoder.iInputStream.ResetInputStream();
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::CleanupPass
+// Perform the cleanup pass
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kEntropyDecoder::CleanupPass( TUint8 aSegSymbols )
+    {
+    TInt32 zcCoding = 0;
+
+    // Symbol to be coded 
+    TInt32 symbol = 0;   
+  
+    TPrecInt mask = ( 1 << iCurrentBitplane ) | ( 1 << ( iCurrentBitplane - 1 ) );
+  
+    TPrecInt* dataRow = &( iData[0][0] );
+    TInt16* stateRow = CONST_CAST( TInt16*, GetFirstStateRow() );
+    TPrecInt* dataCol = 0;
+    TPrecInt* dataValue = 0; 
+    TInt16* stateCol = 0;
+    TInt16* stateValue = 0;
+
+    // Column index in the stripe
+    TInt32 col = 0; 
+    TInt32 row = 0;
+
+    // Code stripe by stripe
+    for ( TInt32 s = iNumStripes - 1; s > 0; s-- )
+        {
+        // If using stripe causal context formation, reset necessary bits
+        // in state of first line in next stripe 
+        if ( iVerticalCausalContextUsed )
+            {
+            dataCol = dataRow + 2 * iBlockDataWidth;
+            stateCol = stateRow + iStateSamplesPerStripe - iStateWidth - 1;
+            GetCausal( dataCol, stateCol );
+            }
+    
+        // Scan column by column in each stripe
+        dataCol = dataRow;
+        stateCol = stateRow;
+    
+        for ( col = iBlockWidth; col > 0; col--, dataCol++, stateCol++ )
+            {
+            stateValue = stateCol;
+            dataValue = dataCol;
+
+            // If sample is insignificant and not yet visited in the
+            // current bitplane, then apply the normalization pass
+            if ( ( *stateValue == 0 ) &&
+                ( stateValue += iStateWidth, ( *stateValue ) == 0 ) &&    //lint !e960    Comma is OK.
+                ( stateValue += iStateWidth, ( *stateValue ) == 0 ) &&    //lint !e960    Comma is OK.
+                ( stateValue += iStateWidth, ( *stateValue ) == 0 ) )      //lint !e960    Comma is OK.
+                {
+                // Use RLC
+                if ( iMQDecoder.MqDecodeSymbol( KRlcContext ) != 0 ) //some sample( s ) not zero
+                    {
+                    // Decode the symbol most significant bit first 
+                    symbol  = (TUint8)( iMQDecoder.MqDecodeSymbol( KUniformContext ) << 1 );    // MSB 
+                    symbol |= (TUint8)( iMQDecoder.MqDecodeSymbol( KUniformContext ) & 0x01 );  // LSB
+          
+                    // Update data and state pointers
+                    stateValue = stateCol + symbol * iStateWidth;
+                    dataValue  = dataCol + symbol * iBlockDataWidth;
+
+                    // Set zcCoding flag to zero 
+                    zcCoding = 0;
+                    row = KStripeHeight - symbol;
+                    }
+                else // All samples zero 
+                    {
+                    // Move to next column
+                    continue;   //lint !e960    Continue is OK, no need to go end of for.
+                    }
+                }
+            else  // No RLC used 
+                {
+                stateValue = stateCol;
+
+                // Set zcCoding flag to one
+                zcCoding = 1;
+                row = KStripeHeight;
+                }
+
+            for ( ; row > 0; row-- )
+                {
+                DecodeNormalization( dataValue, stateValue, mask, zcCoding );
+                dataValue += iBlockDataWidth;
+                stateValue += iStateWidth;
+                }
+            }
+        dataRow += iDataSamplesPerStripe;
+        stateRow += iStateSamplesPerStripe;
+        }
+  
+    // Deal with last stripe separately
+    // Scan column by column in each stripe
+    dataCol = dataRow;
+    stateCol = stateRow;
+  
+    // Scan column by column in each stripe
+    for ( col = iBlockWidth; col > 0; col--, stateCol++, dataCol++ )
+        {
+        stateValue = stateCol;
+        dataValue = dataCol;
+
+        // If sample is insignificant and not yet visited in the
+        // current bitplane, then apply the normalization pass
+        if( ( iLastStripeHeight == KStripeHeight ) && ( *stateValue ==0 ) &&
+           ( stateValue += iStateWidth, ( *stateValue ) == 0 ) &&    //lint !e960    Comma is OK.
+           ( stateValue += iStateWidth, ( *stateValue ) == 0 ) &&    //lint !e960    Comma is OK.
+           ( stateValue += iStateWidth, ( *stateValue ) == 0 ) )      //lint !e960    Comma is OK.
+            {
+            // Use RLC:
+            if ( iMQDecoder.MqDecodeSymbol( KRlcContext ) != 0 )  //some sample( s ) not zero
+                {
+                // Decode the symbol most significant bit first
+                symbol  = ( TUint8 )( iMQDecoder.MqDecodeSymbol( KUniformContext ) << 1 );   // MSB 
+                symbol |= ( TUint8 )( iMQDecoder.MqDecodeSymbol( KUniformContext ) & 0x01 ); // LSB 
+        
+                // Update data and state pointers 
+                stateValue = stateCol + symbol * iStateWidth;
+                dataValue  = dataCol + symbol * iBlockDataWidth;
+
+                // Set zcCoding flag to zero
+                zcCoding = 0;
+                row = KStripeHeight - symbol;
+                }
+            else   // All samples zero
+                {
+                // Move to next column
+                continue;      //lint !e960    Continue is OK, no need to go end of for.
+                }
+            }
+        else  // No RLC used 
+            {
+            row = iLastStripeHeight;
+            stateValue = stateCol;
+
+            // Set zcCoding flag to one 
+            zcCoding = 1;
+            }
+
+        for ( ; row > 0; row-- )
+            {
+            DecodeNormalization( dataValue, stateValue, mask, zcCoding );
+            if ( row > 1 )
+                {
+                dataValue += iBlockDataWidth;
+                }
+            stateValue += iStateWidth;
+            }
+        }
+  
+    // Decode a segment marker if we need to
+    if ( aSegSymbols )
+        {
+        symbol  = (TUint8)( iMQDecoder.MqDecodeSymbol( KUniformContext ) << 3 );
+        symbol |= (TUint8)( iMQDecoder.MqDecodeSymbol( KUniformContext ) << 2 );
+        symbol |= (TUint8)( iMQDecoder.MqDecodeSymbol( KUniformContext ) << 1 );
+        symbol |= (TUint8)( iMQDecoder.MqDecodeSymbol( KUniformContext ) );
+
+        if ( symbol != KSegmentationMarker )
+            {
+            iErrorState = EEntropyCodingError;
+            }
+        } 
+  
+    // If there is predictable termination, check for errors 
+    if ( iTerminateThisPass && iPredictableTerminationUsed )
+        {
+        iErrorState = iMQDecoder.MqCheckPrediction();
+        }
+  
+    // Reset the MQ context states if we need to
+    if ( iResetContexts )
+        {
+        iMQDecoder.ResetMqContexts();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kEntropyDecoder::GetFirstStateRow
+// Get the first state row
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+const TInt16* CJ2kEntropyDecoder::GetFirstStateRow() const
+    {
+    return iStates + ( iStateWidth + 1 );
+    }
+