imagingmodules/jp2kcodec/Src/JP2KPacket.cpp
changeset 0 469c91dae73b
child 4 3993b8f65362
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KPacket.cpp	Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,1430 @@
+/*
+* 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:  JP2KPacket class used to collect packet related
+*                information such as tag tree and list of codeblocks.
+*
+*/
+
+
+// INCLUDE FILES
+#include <icl/imagecodec.h>
+#include "JP2KImageUtils.h"
+#include "JP2KStreamReader.h"
+#include "JP2KTileInfo.h"
+#include "JP2KImageInfo.h"
+#include "JP2KCodeBlock.h"
+#include "JP2KPacket.h"
+#include "JP2KSubband.h"
+#include "JP2KComponentInfo.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES  
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::CJ2kPacket
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJ2kPacket::CJ2kPacket( TUint16 aLayer ) : 
+    iTagTreeLevel(1),
+    iLayer(aLayer), 
+    iCodeBlockList(1)
+    {
+    }
+
+// Destructor
+CJ2kPacket::~CJ2kPacket()
+    {
+    delete iIncluded;
+    iIncluded = 0;
+
+    delete iTagTreeInfo;
+    iTagTreeInfo = 0;
+
+    delete iIncTagTreeValue;
+    iIncTagTreeValue = 0;
+
+    delete iIncTagTreeState;
+    iIncTagTreeState = 0;
+
+    delete iMsbTagTreeValue;
+    iMsbTagTreeValue = 0;
+
+    delete iMsbTagTreeState;
+    iMsbTagTreeState = 0;
+
+    iCodeBlockList.ResetAndDestroy();
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetPacketCanvas
+// Set the canvas of the packet
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::SetPacketCanvas( TInt32 aX, TInt32 aY, TInt32 aWidth, TInt32 aHeight )
+    {
+    iPacketCanvas.iTl = TPoint( aX, aY );
+    iPacketCanvas.SetWidth( aWidth );
+    iPacketCanvas.SetHeight( aHeight );
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetNumOfBlocks
+// Set the number of blocks
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::SetNumOfBlocks( TSize& aCodeBlock )
+    {
+    TInt32 x0 = TJ2kUtils::Floor( iPacketCanvas.iTl.iX, aCodeBlock.iWidth ) * aCodeBlock.iWidth;
+    TInt32 y0 = TJ2kUtils::Floor( iPacketCanvas.iTl.iY, aCodeBlock.iHeight ) * aCodeBlock.iHeight;
+    TInt32 x1 = TJ2kUtils::Ceil( iPacketCanvas.iTl.iX + iPacketCanvas.Width(), aCodeBlock.iWidth ) * aCodeBlock.iWidth;
+    TInt32 y1 = TJ2kUtils::Ceil( iPacketCanvas.iTl.iY + iPacketCanvas.Height(), aCodeBlock.iHeight ) * aCodeBlock.iHeight;
+    iCodeBlockSize.iWidth  = ( x1 - x0 ) / aCodeBlock.iWidth;
+    iCodeBlockSize.iHeight = ( y1 - y0 ) / aCodeBlock.iHeight;
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::BuildInclusiveInfoL
+// Build the inclusive information of the packet
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::BuildInclusiveInfoL()
+    {
+    TInt entries = ( iLayer % 8 ) ? ( ( iLayer / 8 ) + 1 ) : ( iLayer / 8 );
+    iIncluded = HBufC8::NewMaxL( entries );
+    iIncluded->Des().FillZ();
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::BuildCodeBlocksL
+// Build the codeblocks in the packet
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::BuildCodeBlocksL( TInt32 aX, TInt32 aY, TSize& aCodeBlock )
+    {
+    TUint16 numOfBlocks = NumOfBlocks();
+
+    if ( numOfBlocks )
+        {
+        BuildTagtreeL();
+
+        TInt32 x0 = 0;
+        TInt32 y0 = 0;
+        TInt32 x1 = 0;
+        TInt32 y1 = 0;
+        TInt32 origX = aX;
+        TUint16 index = 0;
+
+        while ( index < numOfBlocks )
+            {
+            x0 = Max( aX, iPacketCanvas.iTl.iX );
+            y0 = Max( aY, iPacketCanvas.iTl.iY );
+            x1 = Min( aX + aCodeBlock.iWidth, iPacketCanvas.iTl.iX + iPacketCanvas.Width() ) - x0;
+            y1 = Min( aY + aCodeBlock.iHeight, iPacketCanvas.iTl.iY + iPacketCanvas.Height() ) - y0;
+            if ( x1 > 0 && y1 > 0 )
+                {
+                CJ2kCodeBlock *block = new ( ELeave ) CJ2kCodeBlock;
+                CleanupStack::PushL( block );
+                User::LeaveIfError( iCodeBlockList.Append( block ) );
+                CleanupStack::Pop( 1 );
+                iCodeBlockList[index]->SetCodeBlockCanvas( x0, y0, x1, y1 );
+
+                // Initialize the codeblock
+                iCodeBlockList[index]->InitializeL( iLayer );
+                ++index;
+                }
+
+            aX += aCodeBlock.iWidth;
+            if ( aX >= iPacketCanvas.iTl.iX + iPacketCanvas.Width() )
+                {
+                aX = origX;
+                aY += aCodeBlock.iHeight;
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadPacketHeaderL
+// Read the packet header
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadPacketHeaderL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent, CJ2kSubband& aSubband )
+    {
+    if ( IsIncludedL( aTile.LastLayerProcessed() ) )
+        {
+        return EFalse;
+        }
+
+    TUint8 incomplete = ETrue;
+    if ( LastCodeBlockProcessed() == 0 )
+        {
+        if ( ReadSOP_EPHMarker( aComponent, aTile ) )
+            {
+            return incomplete;
+            }
+        }
+
+    TJ2kStreamReader& reader = CONST_CAST( TJ2kStreamReader&, aTile.StreamReader() );
+    TUint8 *rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
+
+    if ( !StartReadBit( aTile ) )
+        {
+        TUint8 bit = 0;
+
+        if ( LastCodeBlockProcessed() == 0 )
+            {
+            if ( !IsRecoverFromIncomplete() )
+                {
+                ReadBit( bit, aTile );
+                if ( bit == 0 )
+                    {
+                    // Empty packet
+                    incomplete = EFalse;
+                    }
+                }
+            }
+
+        if ( incomplete )
+            {
+            // Packet header has not been processed yet
+            if ( !IsHeader() )
+                {
+                TUint8 isBackup = IsBackupNeeded( aTile );
+
+                CJ2kSubband *subband = &aSubband;
+                if ( subband->SubbandResLevel() > 0 )
+                    {
+                    if ( subband->LastSubbandProcessed() == CJ2kSubband::EBandLL )
+                        {
+                        subband->SetLastSubbandProcessed( CJ2kSubband::EBandHL );
+                        }
+                    else
+                        {
+                        // Move to last subband processed
+                        while ( subband->SubbandType() != aSubband.LastSubbandProcessed() )
+                            {
+                            subband = subband->NextSubbandRaster();
+                            }
+                        }
+                    }
+
+                TUint16 bandIndex = 0;
+                TUint16 cbIndex = 0;
+                TUint16 cbYIndex = 0;
+                TUint16 xIndex = 0;
+                TUint16 yIndex = 0;
+                TUint16 incValue = 0;
+                TUint16 msbValue = 0;
+                TUint16 index = 0;
+                TUint16 layer = aTile.LastLayerProcessed();
+                TUint16 numPass = 0;
+                TUint16 codePass = 0;
+                TUint16 numSegment = 0;
+                TUint8  recoverIncTag = 0;
+                TUint8  recoverMsbTag = 0;
+                TUint8  firstRecovery = ETrue;
+                TUint8  recoverData = 0;
+                TUint8  recoverPos = 0;
+                TUint8  recoverNextPos = 0;
+                TUint8  origPassIndex = 0;
+                TUint8  origLengthBits = 0;
+                TInt8   origLastPass = 0;
+                TUint32 origDataLength = 0;
+
+                HBufC16 *recoverIncTagTreeValue = 0;
+                HBufC16 *recoverIncTagTreeState = 0;
+                HBufC16 *recoverMsbTagTreeValue = 0;
+                HBufC16 *recoverMsbTagTreeState = 0;
+
+                if ( IsRecoverFromIncomplete() )
+                    {
+                    recoverData = reader.iData;
+                    recoverPos = reader.iPos;
+                    recoverNextPos = reader.iNextPos;
+                    }
+
+                CJ2kPacket *packet = CONST_CAST( CJ2kPacket*, &subband->PacketAt( aSubband.LastPacketProcessed() ) );
+                CJ2kCodeBlock *codeBlock;
+                incomplete = EFalse;
+                do
+                    {
+                    if ( aComponent.QuantizationStyle() != 1 )
+                        {
+                        bandIndex = subband->SubbandTreeIndex();
+                        }
+                    
+                    for ( yIndex = 0; yIndex < packet->NumOfBlocksY(); ++yIndex )
+                        {
+                        cbYIndex = (TUint16)( yIndex * packet->NumOfBlocksX() );
+                        for ( xIndex = 0; xIndex < packet->NumOfBlocksX(); ++xIndex )
+                            {
+                            cbIndex = (TUint16)( cbYIndex + xIndex );
+                            if ( cbIndex < packet->LastCodeBlockProcessed() ||
+                                ( packet->IsMatch() && cbIndex == packet->LastCodeBlockProcessed() ) )
+                                {
+                                // Has been processed, skip to the next codeblock
+                                continue;   //lint !e960    Using continue saves a lot of code here.
+                                }
+                            else
+                                {
+                                packet->ResetMatch();
+                                recoverIncTag = recoverMsbTag = EFalse;
+                                codeBlock = CONST_CAST( CJ2kCodeBlock*, &packet->CodeBlockAt( cbIndex ) );
+
+                                TPtr16 numSegPtr = codeBlock->iNumSegment->Des();
+
+                                origPassIndex = codeBlock->iPassIndex;
+                                origLastPass  = codeBlock->iLastPass;
+                                if ( codeBlock->iLastPass < 0 && codeBlock->iPassIndex == 0 )
+                                    {
+                                    if ( isBackup )
+                                        {
+                                        packet->BackupIncTagtreeL( recoverIncTagTreeValue, recoverIncTagTreeState );
+                                        recoverIncTag = ETrue;
+                                        }
+                                    msbValue = (TUint16)0;
+                                    incomplete = packet->DecodeIncTagtree( aTile, xIndex, yIndex, incValue );
+                                    if ( !incomplete )
+                                        {
+                                        if ( incValue <= layer )
+                                            {
+                                            if ( isBackup )
+                                                {
+                                                packet->BackupMsbTagtreeL( recoverMsbTagTreeValue, recoverMsbTagTreeState );
+                                                recoverMsbTag = ETrue;
+                                                }
+                                            incomplete = packet->DecodeMsbTagtree( aTile, xIndex, yIndex, msbValue );
+                                            }
+                                        else
+                                            {
+                                            packet->SetLastCodeBlockProcessed( cbIndex );
+                                            firstRecovery  = EFalse;
+                                            recoverData    = reader.iData;
+                                            recoverPos     = reader.iPos;
+                                            recoverNextPos = reader.iNextPos;
+                                            recoverIncTag = recoverMsbTag = EFalse;
+                                            rollbackPtr   =  CONST_CAST( TUint8*, reader.iPtr );
+
+                                            // Move on to the next codeblock
+                                            continue;   //lint !e960    Using continue saves a lot of code here.
+                                            }
+                                        }
+
+                                    if ( incomplete )
+                                        {
+                                        // Underflow, should backup the iterator position
+                                        if ( cbIndex > packet->LastCodeBlockProcessed() )
+                                            {
+                                            // Next read should match the codeblock index
+                                            packet->SetMatch();
+                                            }
+                                        
+                                        if ( !firstRecovery )
+                                            {
+                                            SetRecoverFromIncomplete();
+                                            reader.iData    = recoverData;
+                                            reader.iPos     = recoverPos;
+                                            reader.iNextPos = recoverNextPos;
+                                            }
+                                        else
+                                            {
+                                            if ( IsRecoverFromIncomplete() )
+                                                {
+                                                reader.iData    = recoverData;
+                                                reader.iPos     = recoverPos;
+                                                reader.iNextPos = recoverNextPos;
+                                                }
+                                            }
+                                        
+                                        if ( isBackup )
+                                            {
+                                            if ( recoverIncTag )
+                                                {
+                                                packet->RestoreIncTagtree( recoverIncTagTreeValue, recoverIncTagTreeState );
+                                                }
+                                            if ( recoverMsbTag )
+                                                {
+                                                packet->RestoreMsbTagtree( recoverMsbTagTreeValue, recoverMsbTagTreeState );
+                                                }
+                                            // Release memory
+                                            packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState, 
+                                                                       recoverMsbTagTreeValue, recoverMsbTagTreeState );
+                                            }
+                                        reader.iPtr = rollbackPtr;
+
+                                        // Return from the packet header decoding
+                                        return incomplete;
+                                        }
+
+                                    codeBlock->iLastPass = 0;
+                                    numSegPtr[layer] = 1;
+
+                                    codeBlock->iEmptyBitplane = (TUint8)msbValue;
+
+                                    if ( aComponent.RoiShift() > 0 )
+                                        {
+                                        numPass = (TUint16)( ( aComponent.MagnitudeBits( bandIndex ) + aComponent.RoiShift() ) * 3 + 1 );
+                                        }
+                                    else
+                                        {
+                                        numPass = (TUint16)( ( aComponent.MagnitudeBits( bandIndex ) - msbValue  ) * 3 + 1 );
+                                        }
+
+                                    if ( codeBlock->iDataSize == 0 || codeBlock->iDataSize->Length() < numPass )
+                                        {
+                                        if ( codeBlock->iDataSize == 0 )
+                                            {
+                                            codeBlock->iDataSize = HBufC16::NewMaxL( numPass );
+                                            codeBlock->iDataSize->Des().FillZ();
+                                            codeBlock->iPassesPerSegment = HBufC16::NewMaxL( numPass );
+                                            codeBlock->iPassesPerSegment->Des().FillZ();
+                                            }
+                                        else
+                                            {
+                                            incValue = ( TUint16 )( numPass - codeBlock->iDataSize->Length() );
+                                            codeBlock->iDataSize = codeBlock->iDataSize->ReAllocL( numPass );
+                                            codeBlock->iPassesPerSegment = codeBlock->iPassesPerSegment->ReAllocL( numPass );
+                                            while ( incValue-- )
+                                                {
+                                                codeBlock->iDataSize->Des().Append( 0 );
+                                                codeBlock->iPassesPerSegment->Des().Append( 0 );
+                                                }
+                                            }
+                                        }
+                                    }
+                                else
+                                    {
+                                    incomplete = ReadBit( bit, aTile );
+                                    if ( incomplete )
+                                        {
+                                        // Underflow, should backup the iterator position
+                                        if ( cbIndex > packet->LastCodeBlockProcessed() )
+                                            {
+                                            // Next read should match the codeblock index
+                                            packet->SetMatch();
+                                            }
+                                        
+                                        if ( !firstRecovery )
+                                            {
+                                            SetRecoverFromIncomplete();
+                                            reader.iData = recoverData;
+                                            reader.iPos = recoverPos;
+                                            reader.iNextPos = recoverNextPos;
+                                            }
+                                        else
+                                            {
+                                            if ( IsRecoverFromIncomplete() )
+                                                {
+                                                reader.iData    = recoverData;
+                                                reader.iPos     = recoverPos;
+                                                reader.iNextPos = recoverNextPos;
+                                                }
+                                            }
+                                        
+                                        if ( isBackup )
+                                            {
+                                            // Release memory
+                                            packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState, 
+                                                                       recoverMsbTagTreeValue, recoverMsbTagTreeState );
+                                            }
+                                        reader.iPtr = rollbackPtr;
+
+                                        // Return from the packet header decoding
+                                        return incomplete;
+                                        }
+
+                                    numSegPtr[layer] = bit;
+
+                                    if ( bit == 0 )
+                                        {
+                                        packet->SetLastCodeBlockProcessed( cbIndex );
+                                        firstRecovery  = EFalse;
+                                        recoverData = reader.iData;
+                                        recoverPos  = reader.iPos;
+                                        recoverNextPos = reader.iNextPos;
+                                        recoverIncTag = recoverMsbTag = EFalse;
+                                        rollbackPtr   =  CONST_CAST( TUint8*, reader.iPtr );
+
+                                        // Move on to the next codeblock
+                                        continue;   //lint !e960    Using continue saves a lot of code here.
+                                        }
+                                    }
+
+                                incomplete = ReadBit( bit, aTile );
+                                codePass = (TUint16)0;
+                                if ( !incomplete )
+                                    {
+                                    if ( bit ) // 1
+                                        {
+                                        incomplete = ReadBit( bit, aTile );
+                                        if ( !incomplete )
+                                            {
+                                            if ( bit ) // 11
+                                                {
+                                                incomplete = ReadBits( bit, 2, aTile );
+                                                if ( !incomplete )
+                                                    {
+                                                    if ( bit == 0x03 ) // 1111
+                                                        {
+                                                        incomplete = ReadBits( bit, 5, aTile );
+                                                        if ( !incomplete )
+                                                            {
+                                                            if ( bit == 0x1f ) // 1111 11111
+                                                                {
+                                                                incomplete = ReadBits( bit, 7, aTile );
+                                                                if ( !incomplete )
+                                                                    {
+                                                                    codePass = (TUint16)( 0x25 + bit );
+                                                                    }
+                                                                }
+                                                            else
+                                                                {
+                                                                // 1111 XXXXX, at least one of them is not 1
+                                                                codePass = (TUint16)( 6 + bit );
+                                                                }
+                                                            }
+                                                        }
+                                                    else
+                                                        {
+                                                        // 11XX
+                                                        codePass = (TUint16)( 3 + bit );
+                                                        }
+                                                    }
+                                                }
+                                            else
+                                                {
+                                                // 10
+                                                codePass = 2;
+                                                }
+                                            }
+                                        }
+                                    else
+                                        {
+                                        // 0
+                                        codePass = 1;
+                                        }
+                                    }
+
+                                if ( incomplete )
+                                    {
+                                    // Underflow, restore the original codeblock information
+                                    codeBlock->iPassIndex = origPassIndex;
+                                    codeBlock->iLastPass = origLastPass;
+
+                                    // Underflow, should backup the iterator position
+                                    if ( cbIndex > packet->LastCodeBlockProcessed() )
+                                        {
+                                        // Next read should match the codeblock index
+                                        packet->SetMatch();
+                                        }
+                                    
+                                    if ( !firstRecovery )
+                                        {
+                                        SetRecoverFromIncomplete();
+                                        reader.iData = recoverData;
+                                        reader.iPos = recoverPos;
+                                        reader.iNextPos = recoverNextPos;
+                                        }                                    
+                                    else
+                                        {
+                                        if ( IsRecoverFromIncomplete() )
+                                            {
+                                            reader.iData = recoverData;
+                                            reader.iPos  = recoverPos;
+                                            reader.iNextPos = recoverNextPos;
+                                            }
+                                        }
+
+                                    if ( isBackup )
+                                        {
+                                        if ( recoverIncTag )
+                                            {
+                                            packet->RestoreIncTagtree( recoverIncTagTreeValue, 
+                                                                       recoverIncTagTreeState );
+                                            }
+                                        if ( recoverMsbTag )
+                                            {
+                                            packet->RestoreMsbTagtree( recoverMsbTagTreeValue, 
+                                                                       recoverMsbTagTreeState );
+                                            }
+                                        // Release memory
+                                        packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState, 
+                                                                   recoverMsbTagTreeValue, recoverMsbTagTreeState );
+                                        }
+                                    reader.iPtr = rollbackPtr;
+                                    
+                                    // Return from the packet header decoding
+                                    return incomplete;
+                                    }
+
+                                if ( codeBlock->iPassIndex == 0 )
+                                    {
+                                    codeBlock->iLastPass = -1;
+                                    }
+
+                                numSegment = 1;
+
+                                if ( aComponent.IsTermination() )
+                                    {
+                                    numSegment = codePass;
+                                    }
+                                else if ( aComponent.IsACByPass() )
+                                    {
+                                    if ( ( codeBlock->iLastPass + codePass ) >= KFirstLazyPassIndex )
+                                        {
+                                        for ( index = 1; index < codePass; ++index )
+                                            {
+                                            if ( ( index + codeBlock->iLastPass ) >= KFirstLazyPassIndex )
+                                                {
+                                                if ( ( ( index + codeBlock->iLastPass ) % 3 ) != 1 )
+                                                    {
+                                                    ++numSegment;
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+
+                                numSegPtr[layer] = numSegment;   //lint !e961    no else is needed here at the end of if...else if
+
+                                origLengthBits = codeBlock->iLengthBits;
+                                origDataLength = codeBlock->iDataLength;
+                                incomplete = ReadBit( bit, aTile );
+                                if ( !incomplete )
+                                    {
+                                    // Skip all 1 bits
+                                    while ( bit )
+                                        {
+                                        ++codeBlock->iLengthBits;
+                                        incomplete = ReadBit( bit, aTile );
+                                        if ( incomplete )
+                                            {
+                                            // Underflow
+                                            // Set bit to zero to break from the while-loop
+                                            bit = 0;
+                                            }
+                                        }
+                                    }
+
+                                if ( !incomplete )
+                                    {
+                                    TUint8 bits = 0;
+                                    TUint32 tmpBits = 0;
+                                    TPtr16 numPassesPerSegPtr = codeBlock->iPassesPerSegment->Des();
+                                    TPtr16 numDataSizePtr = codeBlock->iDataSize->Des();
+
+                                    if ( numSegment == 1 )
+                                        {
+                                        bits = (TUint8)( codeBlock->iLengthBits + TJ2kUtils::Log2( codePass ) );
+
+                                        incomplete = ReadBits( tmpBits, bits, aTile );
+                                        if ( !incomplete )
+                                            {
+                                            numPassesPerSegPtr[codeBlock->iPassIndex] = codePass;
+                                            numDataSizePtr[codeBlock->iPassIndex++] = (TUint16)tmpBits;
+
+                                            codeBlock->iDataLength += tmpBits;
+                                            codeBlock->iLastPass = (TUint8)( codeBlock->iLastPass + codePass );
+                                            if ( tmpBits > 0 )
+                                                {
+                                                SetBodyIncomplete();
+                                                }
+                                            }
+                                        }
+                                    else
+                                        {
+                                        TUint16 totalCodePass = codePass;
+                                        TUint16 tmpCodePass;
+                                        for ( index = 0; index < numSegment; ++index )
+                                            {
+                                            if ( aComponent.IsTermination() )
+                                                {
+                                                tmpCodePass = 1;
+                                                }
+                                            else
+                                                {
+                                                if ( codeBlock->iLastPass < KFirstLazyPassIndex )
+                                                    {
+                                                    tmpCodePass = (TUint16)( KFirstLazyPassIndex - ( TInt )codeBlock->iLastPass );
+                                                    }
+                                                else
+                                                    {
+                                                    tmpCodePass = (TUint16)( ( codeBlock->iLastPass % 3 ) ? 1 : ( ( totalCodePass > 1 ) ? 2 : 1 ) );
+                                                    }
+                                                }
+                                            bits = (TUint8)( codeBlock->iLengthBits + TJ2kUtils::Log2( tmpCodePass ) );
+                                            incomplete = ReadBits( tmpBits, bits, aTile );
+                                            if ( !incomplete )
+                                                {
+                                                numPassesPerSegPtr[codeBlock->iPassIndex] = tmpCodePass;
+                                                numDataSizePtr[codeBlock->iPassIndex++] = (TUint16)tmpBits;
+
+                                                codeBlock->iDataLength += tmpBits;
+                                                codeBlock->iLastPass = (TUint8)( codeBlock->iLastPass + tmpCodePass );
+                                                totalCodePass = (TUint16)( totalCodePass - tmpCodePass );
+                                                if ( tmpBits > 0 )
+                                                    {
+                                                    SetBodyIncomplete();
+                                                    }
+                                                }
+                                            else
+                                                {
+                                                index = numSegment;     // break from the for-loop
+                                                }
+                                            }
+                                        }
+                                    }
+
+                                if ( incomplete )
+                                    {
+                                    // Underflow, restore the original codeblock information
+                                    codeBlock->iPassIndex = origPassIndex;
+                                    codeBlock->iLastPass = origLastPass;
+                                    codeBlock->iLengthBits = origLengthBits;
+                                    codeBlock->iDataLength = origDataLength;
+
+                                    // Underflow, should backup the iterator position
+                                    if ( cbIndex > packet->LastCodeBlockProcessed() )
+                                        {
+                                        // Next read should match the codeblock index
+                                        packet->SetMatch();
+                                        }
+                                    
+                                    if ( !firstRecovery )
+                                        {
+                                        SetRecoverFromIncomplete();
+                                        reader.iData = recoverData;
+                                        reader.iPos = recoverPos;
+                                        reader.iNextPos = recoverNextPos;
+                                        }
+                                    else
+                                        {
+                                        if ( IsRecoverFromIncomplete() )
+                                            {
+                                            reader.iData = recoverData;
+                                            reader.iPos = recoverPos;
+                                            reader.iNextPos = recoverNextPos;
+                                            }
+                                        }
+                                    
+                                    if ( isBackup )
+                                        {
+                                        if ( recoverIncTag )
+                                            {
+                                            packet->RestoreIncTagtree( recoverIncTagTreeValue, 
+                                                                       recoverIncTagTreeState );
+                                            }
+                                        if ( recoverMsbTag )
+                                            {
+                                            packet->RestoreMsbTagtree( recoverMsbTagTreeValue, 
+                                                                       recoverMsbTagTreeState );
+                                            }
+
+                                        // Release memory
+                                        packet->FreeBackupTagtree( recoverIncTagTreeValue, 
+                                                                   recoverIncTagTreeState, 
+                                                                   recoverMsbTagTreeValue, 
+                                                                   recoverMsbTagTreeState );
+                                        }
+                                    reader.iPtr = rollbackPtr;
+                                    
+                                    // Return from the packet header decoding
+                                    return incomplete;
+                                    }
+
+                                }
+
+                            packet->SetLastCodeBlockProcessed( cbIndex );
+                            firstRecovery  = EFalse;
+                            recoverData = reader.iData;
+                            recoverPos = reader.iPos;
+                            recoverNextPos = reader.iNextPos;
+                            recoverIncTag = recoverMsbTag = EFalse;
+                            rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
+                            } // end of xIndex
+                        } // end of yIndex
+
+                    packet->SetLastCodeBlockProcessed( 0 );
+                    packet->ResetMatch();
+                    ResetRecoverFromIncomplete();
+                    subband = subband->NextSubbandRaster();
+                    if ( subband )
+                        {
+                        if ( isBackup )
+                            {
+                            // Sibling may have different tag tree level, so release memory here
+                            packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState, 
+                                                       recoverMsbTagTreeValue, recoverMsbTagTreeState );
+                            }
+                        packet = CONST_CAST( CJ2kPacket*, &subband->PacketAt( aSubband.LastPacketProcessed() ) );
+                        aSubband.SetLastSubbandProcessed( (TUint8)subband->SubbandType() );
+                        }
+
+                    } while ( subband );
+
+                if ( !incomplete )
+                    {
+                    // Packet header has been completely processed
+                    SetHeader();
+                    SetIncluded( aTile.LastLayerProcessed() );
+                    AlignReader( aTile );
+                    aSubband.SetLastSubbandProcessed( CJ2kSubband::EBandLL );
+                    }
+                if ( isBackup )
+                    {
+                    // Release memory
+                    packet->FreeBackupTagtree( recoverIncTagTreeValue, recoverIncTagTreeState, 
+                                               recoverMsbTagTreeValue, recoverMsbTagTreeState );
+                    }
+                }
+            else
+                {
+                // Packet has been processed
+                reader.iPtr = rollbackPtr;
+                }
+            }
+
+        if ( !incomplete )
+            {
+            if ( aComponent.IsEPHMarkerUsed() )
+                {
+                ReadEPHMarker( aTile );
+                }
+            }
+        }
+    return incomplete;
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadPacketBodyL
+// Read the packet body
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadPacketBodyL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent, CJ2kSubband& aSubband )
+    {
+    TUint8 incomplete = EFalse;
+    if ( LastCodeBlockProcessed() == 0 )
+        {
+        if ( ReadSOP_EPHMarker( aComponent, aTile, EFalse ) )
+            {
+            return ETrue;
+            }
+        }
+
+    TJ2kStreamReader& reader = CONST_CAST( TJ2kStreamReader&, aTile.StreamReader() );
+
+    // Packet body has not been processed yet
+    if ( !IsBody() )
+        {
+        SetBodyIncomplete();
+
+        CJ2kSubband *subband = &aSubband;
+        if ( subband->SubbandResLevel() > 0 )
+            {
+            if ( subband->LastSubbandProcessed() == CJ2kSubband::EBandLL )
+                {
+                subband->SetLastSubbandProcessed( CJ2kSubband::EBandHL );
+                }
+            else
+                {
+                // Move to last subband processed
+                while ( subband->SubbandType() != aSubband.LastSubbandProcessed() )
+                    {
+                    subband = subband->NextSubbandRaster();
+                    }
+                }
+            }
+        TUint16 xIndex = 0;
+        TUint16 yIndex = 0;
+        TUint16 cbIndex = 0;
+        TUint16 cbYIndex = 0;
+        TUint16 index = 0;
+        TUint16 cblkLength = 0;
+        TUint16 layer = aTile.LastLayerProcessed();
+        TInt32  totalLength = 0;
+        TUint8 *rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
+        
+        CJ2kPacket *packet = CONST_CAST( CJ2kPacket*, &subband->PacketAt( aSubband.LastPacketProcessed() ) );
+        CJ2kCodeBlock *codeBlock = 0;
+        do
+            {
+        
+            for ( yIndex = 0; yIndex < packet->NumOfBlocksY(); ++yIndex )
+                {
+                cbYIndex = (TUint16)( yIndex * packet->NumOfBlocksX() );
+                for ( xIndex = 0; xIndex < packet->NumOfBlocksX(); ++xIndex )
+                    {
+                    cbIndex = (TUint16)( cbYIndex + xIndex );
+                    if ( cbIndex < packet->LastCodeBlockProcessed() ||
+                        ( packet->IsMatch() && cbIndex == packet->LastCodeBlockProcessed() ) )
+                        {
+                        // Has been processed, skip to the next codeblock
+                        continue;   //lint !e960    Using continue saves a lot of code here.
+                        }
+                    else
+                        {
+                        packet->ResetMatch();
+                        codeBlock = CONST_CAST( CJ2kCodeBlock*, &packet->CodeBlockAt( cbIndex ) );
+                        
+                        if ( ( *codeBlock->iNumSegment )[layer] > 0 )
+                            {
+                            TUint tempLength = 0;
+                            TUint8 skip = 0;
+                            
+                            if ( !aTile.IsSpeedup() )
+                            {
+                                // If this resolution level is not required in decoding, skip storing the data to save memory
+                                if ( aTile.LastLevelProcessed() > (TUint8)( aTile.NumOfLevelsPOC() - aTile.ImageInfo().LevelDrop() ) )
+                                    skip = 1;
+                            }
+                            
+                            tempLength = codeBlock->iDataLength;
+                            
+                            if ( tempLength )
+                                {
+                                // Find out which segment has been processed
+                                totalLength = codeBlock->iDataLength - tempLength;
+                                    {
+                                    for ( index = 1; index <= ( *codeBlock->iNumSegment )[layer]; ++index )
+                                        {
+                                        totalLength -= ( *codeBlock->iDataSize )[codeBlock->iPassIndex - index];
+                                        if ( totalLength <= 0 )
+                                            {
+                                            break;   //lint !e960    break usage saves code here.
+                                            }
+                                        }
+                                    }
+                                }
+                            else
+                                {
+                                index = ( *codeBlock->iNumSegment )[layer];
+                                }
+
+                            for ( ; index > 0; --index )
+                                {
+                                cblkLength = ( *codeBlock->iDataSize )[codeBlock->iPassIndex - index];
+                                if ( ( reader.iPtrEnd - reader.iPtr ) < cblkLength )
+                                    {
+                                    // Underflow, rollback the iterator position
+                                    reader.iPtr = rollbackPtr;
+                                    incomplete = ETrue;
+                                    if ( cbIndex > packet->LastCodeBlockProcessed() )
+                                        {
+                                        // Next read should match the codeblock index
+                                        packet->SetMatch();
+                                        }
+
+                                    return incomplete;
+                                    }
+                                else
+                                    {
+                                    
+                                        // Store data only if the resolution level is not skipped
+                                        if( !skip )
+                                        {
+                                    	    TPtr8 data = codeBlock->DataL()->Des();
+	                                        data.Append( reader.iPtr, cblkLength );
+                                        }
+                                    
+                                    reader.iPtr += cblkLength;
+                                    }
+                                // Save the iterator position
+                                rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
+                                }
+                            }
+                        }
+                    packet->SetLastCodeBlockProcessed( cbIndex );
+
+                    // Save the iterator position
+                    rollbackPtr = CONST_CAST( TUint8*, reader.iPtr );
+                    } // end of xIndex
+                } // end of yIndex
+
+            packet->SetLastCodeBlockProcessed( 0 );
+            packet->ResetMatch();
+            subband = subband->NextSubbandRaster();
+            if ( subband )
+                {
+                packet = CONST_CAST( CJ2kPacket*, &subband->PacketAt( aSubband.LastPacketProcessed() ) );
+                aSubband.SetLastSubbandProcessed( (TUint8)subband->SubbandType() );
+                }
+
+            } while ( subband );
+
+        SetBody();
+        ResetBodyIncomplete();
+        aSubband.SetLastSubbandProcessed( CJ2kSubband::EBandLL );
+        }
+
+    return incomplete;
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ResetInternalFlags
+// Reset the internal flags
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::ResetInternalFlags()
+    {
+    ResetHeader();
+    ResetBody();
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::BuildTagtreeL
+// Build the tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::BuildTagtreeL()
+    {
+    TUint32 width  = iCodeBlockSize.iWidth;
+    TUint32 height = iCodeBlockSize.iHeight;
+
+    while ( width != 1 || height != 1 )
+        {
+        width  = ( width + 1 ) >> 1;
+        height = ( height + 1 ) >> 1;
+        ++iTagTreeLevel;
+        }
+
+    TInt size = 0;
+    TInt sizeIndex = 0;
+    width = iCodeBlockSize.iWidth;
+    height = iCodeBlockSize.iHeight;
+
+    iTagTreeInfo = HBufC16::NewMaxL( iTagTreeLevel + 1 );
+    TPtr16 tmpPtr = ( iTagTreeInfo->Des() );
+    tmpPtr[0] = (TUint16)sizeIndex;
+
+    for ( TUint8 index = 0; index < iTagTreeLevel; ++index )
+        {
+        size = width * height;
+        sizeIndex += size;
+        tmpPtr[index + 1] = (TUint16)sizeIndex;
+        }
+
+    TChar fillChar( 0xffff );
+
+    iIncTagTreeValue = HBufC16::NewMaxL( sizeIndex );
+    iIncTagTreeValue->Des().Fill( fillChar, iIncTagTreeValue->Length() );
+    iIncTagTreeState = HBufC16::NewMaxL( sizeIndex );
+    iIncTagTreeState->Des().FillZ();
+
+    iMsbTagTreeValue = HBufC16::NewMaxL( sizeIndex );
+    iMsbTagTreeValue->Des().Fill( fillChar, iIncTagTreeValue->Length() );
+    iMsbTagTreeState = HBufC16::NewMaxL( sizeIndex );
+    iMsbTagTreeState->Des().FillZ();
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::DecodeIncTagtree
+// Decode the included tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::DecodeIncTagtree( CJ2kTileInfo& aTile, TUint32 aWidth, TUint32 aHeight, TUint16& aValue )
+    {
+    TUint8 bit = 2;
+    TInt16 parentState = 0;
+    TUint8 contCoding = 1;
+    TUint16 idx = 0;
+    TUint16 layer = (TUint16)( aTile.LastLayerProcessed() + 1 );
+
+    for ( TInt16 index = TInt16( iTagTreeLevel - 1 ); index >= 0; --index )
+        {
+        idx = (TUint16)( ( aHeight >> index ) * ( (TUint32)( iCodeBlockSize.iWidth + ( 1 << index ) - 1 ) >> index ) + ( aWidth >> index ) );
+        if ( ( IncTagState( index, idx ) < parentState ) && IncTagValue( index, idx ) == 0xffff )
+            {
+            SetIncTagState( index, idx, (TUint16)( parentState - contCoding ) );
+            }
+
+        while ( contCoding && IncTagState( index, idx ) < layer && IncTagValue( index, idx ) == 0xffff )
+            {
+            if ( ReadBit( bit, aTile ) )
+                {
+                return ETrue;
+                }
+
+            if ( bit == 1 )
+                {
+                SetIncTagValue( index, idx, IncTagState( index, idx ) );
+                }
+            IncrementIncTagState( index, idx );
+            }
+        parentState = IncTagState( index, idx );
+        if ( bit == 0 || IncTagValue( index, idx ) == 0xffff )
+            {
+            contCoding = 0;
+            }
+        }
+    aValue = IncTagValue( 0, idx );
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::DecodeMsbTagtree
+// Decode the msb tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::DecodeMsbTagtree( CJ2kTileInfo& aTile, TUint32 aWidth, TUint32 aHeight, TUint16& aValue )
+    {
+    TUint8 bit = 2;
+    TInt16 parentState = 0;
+    TUint8 contCoding = 1;
+    TUint16 idx = 0;
+    TUint16 layer = 0xffff;
+
+    for ( TInt16 index = (TUint16)( iTagTreeLevel - 1 ); index >= 0; --index )
+        {
+        idx = (TUint16)( ( aHeight >> index ) * ( (TUint32)( iCodeBlockSize.iWidth + ( 1 << index ) - 1 ) >> index ) + ( aWidth >> index ) );
+
+        if ( ( MsbTagState( index, idx ) < parentState ) && MsbTagValue( index, idx ) == 0xffff )
+            {
+            SetMsbTagState( index, idx, (TUint16)( ( parentState - contCoding ) ) );
+            }
+
+        while ( contCoding && MsbTagState( index, idx ) < layer && MsbTagValue( index, idx ) == 0xffff )
+            {
+            if ( ReadBit( bit, aTile ) )
+                {
+                return ETrue;
+                }
+
+            if ( bit == 1 )
+                {
+                SetMsbTagValue( index, idx, MsbTagState( index, idx ) );
+                }
+            IncrementMsbTagState( index, idx );
+            }
+        parentState = MsbTagState( index, idx );
+        if ( bit == 0 || MsbTagValue( index, idx ) == 0xffff )
+            {
+            contCoding = 0;
+            }
+        }
+    aValue = MsbTagValue( 0, idx );
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::BackupIncTagtreeL
+// Backup the included tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::BackupIncTagtreeL( HBufC16*& aTagValue, HBufC16*& aTagState )
+    {
+    if ( aTagValue && aTagState )
+        {
+        if ( aTagValue->Des().MaxLength() < iIncTagTreeValue->Length() )
+            {
+            aTagValue = aTagValue->ReAllocL( iIncTagTreeValue->Length() );
+            }
+        if ( aTagState->Des().MaxLength() < iIncTagTreeState->Length() )
+            {
+            aTagState = aTagState->ReAllocL( iIncTagTreeState->Length() );
+            }
+        }
+    else
+        {
+        aTagValue = HBufC16::NewMaxLC( iIncTagTreeValue->Length() );
+        aTagState = HBufC16::NewMaxLC( iIncTagTreeState->Length() );
+        }
+    *aTagValue = *iIncTagTreeValue;
+    *aTagState = *iIncTagTreeState;
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::BackupMsbTagtreeL
+// Backup the msb tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::BackupMsbTagtreeL( HBufC16*& aTagValue, HBufC16*& aTagState )
+    {
+    if ( aTagValue && aTagState )
+        {
+        if ( aTagValue->Des().MaxLength() < iMsbTagTreeValue->Length() )
+            {
+            aTagValue = aTagValue->ReAllocL( iMsbTagTreeValue->Length() );
+            }
+        if ( aTagState->Des().MaxLength() < iMsbTagTreeState->Length() )
+            {
+            aTagState = aTagState->ReAllocL( iMsbTagTreeState->Length() );
+            }
+        }
+    else
+        {
+        aTagValue = HBufC16::NewMaxLC( iMsbTagTreeValue->Length() );
+        aTagState = HBufC16::NewMaxLC( iMsbTagTreeState->Length() );
+        }
+    *aTagValue = *iMsbTagTreeValue;
+    *aTagState = *iMsbTagTreeState;
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::RestoreIncTagtree
+// Restore the included tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::RestoreIncTagtree( HBufC16 *aTagValue, HBufC16 *aTagState )
+    {
+    *iIncTagTreeValue = *aTagValue;
+    *iIncTagTreeState = *aTagState;
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::RestoreMsbTagtree
+// Restore the msb tag tree
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::RestoreMsbTagtree( HBufC16 *aTagValue, HBufC16 *aTagState )
+    {
+    *iMsbTagTreeValue = *aTagValue;
+    *iMsbTagTreeState = *aTagState;
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::FreeBackupTagtree
+// Release the temporary backup memory
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::FreeBackupTagtree( HBufC16*& aIncTagValue, HBufC16*& aIncTagState,
+                                    HBufC16*& aMsbTagValue, HBufC16*& aMsbTagState )
+    {
+    TInt count = 0;
+    if ( aIncTagValue )
+        {
+        delete aIncTagValue;
+        aIncTagValue = 0;
+        ++count;
+        }
+    if ( aIncTagState )
+        {
+        delete aIncTagState;
+        aIncTagState = 0;
+        ++count;
+        }
+    if ( aMsbTagValue )
+        {
+        delete aMsbTagValue;
+        aMsbTagValue = 0;
+        ++count;
+        }
+    if ( aMsbTagState )
+        {
+        delete aMsbTagState;
+        aMsbTagState = 0;
+        ++count;
+        }
+    CleanupStack::Pop( count );
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IsIncludedL
+// Is the layer has been included in previous packet
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::IsIncludedL( TUint16 aLayer )
+    {
+    TInt entries = ( iLayer % 8 ) ? ( ( iLayer / 8 ) + 1 ) : ( iLayer / 8 );
+    if ( iIncluded == 0 || iIncluded->Des().MaxLength() < entries )
+        {
+        if ( iIncluded )
+            {
+            TInt diff = entries - iIncluded->Length();
+            iIncluded = iIncluded->ReAllocL( entries );
+            while ( diff-- )
+                {
+                iIncluded->Des().Append( (TUint8)0 );
+                }
+            }
+        else
+            {
+            iIncluded = HBufC8::NewMaxL( entries );
+            iIncluded->Des().FillZ();
+            }
+        }
+    return IncludedAt( aLayer );
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IncludedAt
+// Get the inclusive information at specific layer
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::IncludedAt( TUint16 aLayer ) const
+    {
+    TInt entry = aLayer / 8;
+    TInt bit   = aLayer % 8;
+    return (TUint8)( ( iIncluded->Des() )[entry] & ( 0x01 << bit ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::SetIncluded
+// Set the inclusive information at specific layer
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::SetIncluded( TUint16 aLayer )
+    {
+    TInt entry = aLayer / 8;
+    TInt bit   = aLayer % 8;
+    TPtr8 tmpPtr = iIncluded->Des();
+    tmpPtr[entry] |= ( 0x01 << bit );
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::IsBackupNeeded
+// Is tag tree backup is required for underflow recovery
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::IsBackupNeeded( CJ2kTileInfo& aTile )
+    {
+    return !( aTile.IsPPT() || aTile.ImageInfo().IsPPM() );
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::StartReadBit
+// Read a bit from the packet header stream
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::StartReadBit( CJ2kTileInfo& aTile )
+    {
+    return ( !IsRecoverFromIncomplete() ) ?
+        aTile.PacketHeaderReader().StartReadBit() : 
+        (TUint8)EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadBit
+// Read a bit from the packet header stream
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadBit( TUint8& aBit, CJ2kTileInfo& aTile )
+    {
+    return aTile.PacketHeaderReader().ReadBit( aBit );
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadBits
+// Read some bits from the packet header stream
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadBits( TUint8& aBit, TUint8 aBitLen, CJ2kTileInfo& aTile )
+    {
+    return aTile.PacketHeaderReader().ReadBits( aBit, aBitLen );
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadBits
+// Read some bits from the packet header stream
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadBits( TUint32& aBit, TUint8 aBitLen, CJ2kTileInfo& aTile )
+    {
+    return aTile.PacketHeaderReader().ReadBits( aBit, aBitLen );
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::AlignReader
+// Align the stream to the next byte boundary if necessary
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kPacket::AlignReader( CJ2kTileInfo& aTile )
+    {
+    aTile.PacketHeaderReader().AlignReader();
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadSOPMarker
+// Try to consume the SOP marker if there is one
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadSOPMarker( CJ2kTileInfo& aTile )
+    {
+    // SOP may be inside the CodeStream only
+    return CONST_CAST( TJ2kStreamReader&, aTile.StreamReader() ).ReadSOPMarker();
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadEPHMarker
+// Try to consume the EPH marker if there is one
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadEPHMarker( CJ2kTileInfo& aTile )
+    {
+    // EPH may be inside PPT or PPM or CodeStream
+    return aTile.PacketHeaderReader().ReadEPHMarker();
+    }
+
+// -----------------------------------------------------------------------------
+// CJ2kPacket::ReadSOP_EPHMarker
+// Try to re-align stream to next byte boundary if necessary,
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kPacket::ReadSOP_EPHMarker( CJ2kComponentInfo& aComponent, CJ2kTileInfo& aTile, TBool aSOP )
+    {
+    TJ2kStreamReader& reader = CONST_CAST( TJ2kStreamReader&, aTile.StreamReader() );
+
+    TUint8 incomplete = reader.TryReAlignReader();
+    incomplete = reader.TryReadEPHMarker();
+
+    if ( !incomplete && aSOP && aComponent.IsSOPMarkerUsed() && ( !IsHeader() || !IsBody() ) )
+        {
+        incomplete = ReadSOPMarker( aTile );
+        }
+
+    return incomplete;
+    }