--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingmodules/jp2kcodec/Src/JP2KSubband.cpp Thu Dec 17 09:22:31 2009 +0200
@@ -0,0 +1,661 @@
+/*
+* 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: JP2KSubband class used to collect the subband related
+* information such as list of packets and list of subbands.
+*
+*/
+
+
+// INCLUDE FILES
+#include <icl/imagecodec.h>
+#include "JP2KImageUtils.h"
+#include "JP2KFormat.h"
+#include "JP2KStreamReader.h"
+#include "JP2KTileInfo.h"
+#include "JP2KImageInfo.h"
+#include "JP2KCodec.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 ===============================
+
+// Destructor
+CJ2kSubband::~CJ2kSubband()
+ {
+ iPacketList.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::BuildSubbandTreeL
+// Static method to set up the tree structure of the DWT subbands.
+// ( other items were commented in a header ).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubband::BuildSubbandTreeL( TUint8 aMaxLevel, CJ2kComponentInfo& aComponent )
+ {
+ CJ2kSubband *root = CJ2kSubbandLL::NewLC();
+ root->iLevel = 0;
+
+ // The root subband, LLO, original image
+ root->iResLevel = (TUint8)( aMaxLevel + 1 );
+ root->iSubbandCanvas = aComponent.ComponentCanvas();
+ root->iHighPassFirst = TPoint( root->iSubbandCanvas.iTl.iX % 2,
+ root->iSubbandCanvas.iTl.iY % 2 );
+ CJ2kSubband *start = root;
+ CJ2kSubband *tmpLL = 0;
+ CJ2kSubband *tmpHL = 0;
+ CJ2kSubband *tmpLH = 0;
+ CJ2kSubband *tmpHH = 0;
+
+ for ( TUint8 index = 1; index <= aMaxLevel; ++index )
+ {
+ // Must be built in the following order - LL, HL, LH, and HH
+ // where all of them share the same parent - next lower LL
+ // but only the LL subband can be further sub-divided into
+ // lower resolution subband
+ // create LL subband
+ TUint8 highPassFirstX = (TUint8)( start->iHighPassFirst.iX );
+ TUint8 highPassFirstY = (TUint8)( start->iHighPassFirst.iY );
+
+ tmpLL = CJ2kSubbandLL::NewLC();
+ tmpLL->iLevel = index;
+ tmpLL->iResLevel = (TUint8)( aMaxLevel - index + 1 );
+
+ tmpLL->iSubbandCanvas.iTl = TPoint( (TUint32)( start->iSubbandCanvas.iTl.iX + 1 ) >> 1,
+ (TUint32)( start->iSubbandCanvas.iTl.iY + 1 ) >> 1 );
+
+ tmpLL->iSubbandCanvas.SetWidth( ( start->iSubbandCanvas.Width() + ( 1-highPassFirstX ) ) / 2 );
+
+ tmpLL->iSubbandCanvas.SetHeight( ( start->iSubbandCanvas.Height() + ( 1-highPassFirstY ) ) / 2 );
+
+ tmpLL->iHighPassFirst = TPoint( tmpLL->iSubbandCanvas.iTl.iX % 2,
+ tmpLL->iSubbandCanvas.iTl.iY % 2 );
+ start->AddChildL( tmpLL );
+ CleanupStack::Pop();
+
+ // Create HL subband
+ tmpHL = CJ2kSubbandNLL::NewLC();
+ tmpHL->iType = EBandHL;
+ tmpHL->iLevel = index;
+ tmpHL->iGain = 1;
+ tmpHL->iResLevel = tmpLL->iResLevel;
+ tmpHL->iSubbandCanvas.iTl = TPoint( (TUint32)start->iSubbandCanvas.iTl.iX >> 1,
+ (TUint32)( start->iSubbandCanvas.iTl.iY + 1 ) >> 1 );
+ tmpHL->iSubbandCanvas.SetWidth( ( start->iSubbandCanvas.Width() + highPassFirstX ) / 2 );
+ tmpHL->iSubbandCanvas.SetHeight( tmpLL->iSubbandCanvas.Height() );
+ tmpHL->iSubbandOrigin.iX = start->iSubbandOrigin.iX + ( ( start->iSubbandCanvas.Width() + ( 1-highPassFirstX ) ) / 2 );
+ tmpHL->iSubbandOrigin.iY = start->iSubbandOrigin.iY;
+ start->AddChildL( tmpHL );
+ CleanupStack::Pop();
+
+ // Create LH subband
+ tmpLH = CJ2kSubbandNLL::NewLC();
+ tmpLH->iType = EBandLH;
+ tmpLH->iLevel = index;
+ tmpLH->iGain = 1;
+ tmpLH->iResLevel = tmpLL->iResLevel;
+ tmpLH->iSubbandCanvas.iTl = TPoint( (TUint32)( start->iSubbandCanvas.iTl.iX + 1 ) >> 1,
+ (TUint32)start->iSubbandCanvas.iTl.iY >> 1 );
+ tmpLH->iSubbandCanvas.SetWidth( tmpLL->iSubbandCanvas.Width() );
+
+ tmpLH->iSubbandCanvas.SetHeight( ( start->iSubbandCanvas.Height() + highPassFirstY ) / 2 );
+ tmpLH->iSubbandOrigin.iX = start->iSubbandOrigin.iX;
+
+ tmpLH->iSubbandOrigin.iY = start->iSubbandOrigin.iY + ( ( start->iSubbandCanvas.Height() + ( 1-highPassFirstY ) ) / 2 );
+ start->AddChildL( tmpLH );
+ CleanupStack::Pop();
+
+ // Create HH subband
+ tmpHH = CJ2kSubbandNLL::NewLC();
+ tmpHH->iType = EBandHH;
+ tmpHH->iLevel = index;
+ tmpHH->iGain = 2;
+ tmpHH->iResLevel = tmpLL->iResLevel;
+ tmpHH->iSubbandCanvas.iTl = TPoint( ( TUint32 )start->iSubbandCanvas.iTl.iX >> 1,
+ ( TUint32 )start->iSubbandCanvas.iTl.iY >> 1 );
+ tmpHH->iSubbandCanvas.SetWidth( tmpHL->iSubbandCanvas.Width() );
+ tmpHH->iSubbandCanvas.SetHeight( tmpLH->iSubbandCanvas.Height() );
+ tmpHH->iSubbandOrigin.iX = tmpHL->iSubbandOrigin.iX;
+ tmpHH->iSubbandOrigin.iY = tmpLH->iSubbandOrigin.iY;
+ start->AddChildL( tmpHH );
+ CleanupStack::Pop();
+
+ start = start->ChildAt( EBandLL );
+ }
+
+ // The lowest resolution must be 0, so reset
+ // the resolution of NLL from 1 to 0.
+ start->iResLevel = 0;
+
+ CleanupStack::Pop();
+ return root;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::BuildPacketsL
+// Build the possible packets that may be in the subband
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSubband::BuildPacketsL( CJ2kComponentInfo& aComponent, HBufC8 *aPrecinctSiz, TUint16 aLayer )
+ {
+ CJ2kSubband *subband = 0;
+ CJ2kPacket *packet = 0;
+ TUint16 packetIndex = 0;
+ TUint16 xIndex = 0;
+ TUint16 yIndex = 0;
+ TInt denom = 0;
+ TInt ppx = 0;
+ TInt ppy = 0;
+ TInt ppxL = 0;
+ TInt ppyL = 0;
+ TInt32 trx0 = 0;
+ TInt32 try0 = 0;
+ TInt32 trx1 = 0;
+ TInt32 try1 = 0;
+ TInt32 n = 0;
+ TInt32 m = 0;
+ TInt32 nOrig = 0;
+ TInt32 mOrig = 0;
+ TInt32 xCoord = 0;
+ TInt32 yCoord = 0;
+ TInt32 numOfPackets = 0;
+ TInt32 tmpX = 0;
+ TInt32 tmpY = 0;
+ TSize cblkSize( 0, 0 );
+ TSize tmpSize( 0, 0 );
+
+ const TSize &compSize = aComponent.CodeBlockSize();
+ TInt compSizeLogWidth = TJ2kUtils::Log2( compSize.iWidth );
+ TInt compSizeLogHeight = TJ2kUtils::Log2( compSize.iHeight );
+
+ for ( TUint8 resLevel = 0; resLevel <= aComponent.Levels(); ++resLevel )
+ {
+ subband = SubbandAt( resLevel );
+ numOfPackets = aComponent.NumOfPackets( resLevel );
+ if ( numOfPackets )
+ {
+ do
+ {
+ for ( packetIndex = 0; packetIndex < numOfPackets; ++packetIndex )
+ {
+ CJ2kPacket *packet = new ( ELeave ) CJ2kPacket( aLayer ); //lint !e578 must be declared also earlier.
+ CleanupStack::PushL( packet );
+
+ User::LeaveIfError( subband->iPacketList.Append( packet ) );
+ CleanupStack::Pop( 1 );
+
+ if ( subband->iType == EBandLL || subband->iType == EBandHL )
+ {
+ subband->iPacketList[packetIndex]->BuildInclusiveInfoL();
+ }
+ }
+ subband = subband->NextSubbandRaster();
+ } while ( subband );
+
+ // Set to the default
+ ppx = ppy = 15;
+
+ if ( aPrecinctSiz )
+ {
+ ppxL = ( *aPrecinctSiz )[resLevel] & 0x0f;
+ ppyL = ( ( *aPrecinctSiz )[resLevel] & 0xf0 ) >> 4;
+ }
+ else
+ {
+ ppxL = ppyL = 15;
+ }
+
+ if ( ppxL != 15 || ppyL != 15 )
+ {
+ ppx = ( resLevel ) ? ppxL - 1 : ppxL;
+ ppy = ( resLevel ) ? ppyL - 1 : ppyL;
+ cblkSize.iWidth = ( compSizeLogWidth < ppx ) ? compSize.iWidth : 1 << ppx;
+ cblkSize.iHeight = ( compSizeLogHeight < ppy ) ? compSize.iHeight : 1 << ppy;
+ }
+ else
+ {
+ cblkSize = compSize;
+ }
+
+ denom = 1 << ( aComponent.Levels() - resLevel );
+
+ trx0 = TJ2kUtils::Ceil( aComponent.ComponentCanvas().iTl.iX, denom );
+ try0 = TJ2kUtils::Ceil( aComponent.ComponentCanvas().iTl.iY, denom );
+ trx1 = TJ2kUtils::Ceil( aComponent.ComponentCanvas().iBr.iX, denom );
+ try1 = TJ2kUtils::Ceil( aComponent.ComponentCanvas().iBr.iY, denom );
+
+ nOrig = ( trx0 / ( 1 << ppxL ) ) * ( 1 << ppxL );
+ mOrig = ( try0 / ( 1 << ppyL ) ) * ( 1 << ppyL );
+
+ // First subband at this resolution level
+ // at r = 0, it will be nLL
+ // at r > 0, it will be ( n-r+1 )HL
+
+ tmpSize = aComponent.PrecinctSizeAt( resLevel );
+ tmpX = 1 << ppx;
+ tmpY = 1 << ppy;
+ subband = SubbandAt( resLevel );
+ do
+ {
+ if ( subband->SubbandCanvasSize().iWidth > 0 &&
+ subband->SubbandCanvasSize().iHeight > 0 )
+ {
+ n = nOrig;
+ m = mOrig;
+
+ if ( subband->iType != EBandLL )
+ {
+ n /= 2;
+ m /= 2;
+ }
+
+ yCoord = m;
+ for ( yIndex = 0; yIndex < tmpSize.iHeight; ++yIndex )
+ {
+ xCoord = n;
+ for ( xIndex = 0; xIndex < tmpSize.iWidth; ++xIndex )
+ {
+ // Reuse the variables trx0, trx1, try0, try1
+ trx0 = Max( subband->SubbandCanvas().iTl.iX, xCoord );
+ try0 = Max( subband->SubbandCanvas().iTl.iY, yCoord );
+ trx1 = Min( xCoord + tmpX, subband->SubbandCanvas().iBr.iX ) - trx0;
+ try1 = Min( yCoord + tmpY, subband->SubbandCanvas().iBr.iY ) - try0;
+
+ if ( trx1 > 0 && try1 > 0 )
+ {
+ packetIndex = ( TUint16 )( yIndex * tmpSize.iWidth + xIndex );
+ packet = subband->iPacketList[packetIndex];
+ packet->SetPacketCanvas( trx0, try0, trx1, try1 );
+ packet->SetNumOfBlocks( cblkSize );
+ packet->BuildCodeBlocksL( xCoord, yCoord, cblkSize );
+ }
+ xCoord += tmpX;
+ } // end of xIndex
+ yCoord += tmpY;
+ } // end of yIndex
+ } // precinct size is greater than 0
+ subband = subband->NextSubbandRaster();
+ } while ( subband );
+ } // num of packets is greater than 0
+ } // end of resolution level
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::LRCPProgressionL
+// At each subband, parse the bitstream with LRCP progression order
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kSubband::LRCPProgressionL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent )
+ {
+ TUint8 incomplete = EFalse;
+ TUint16 marker = 0;
+ const TJ2kStreamReader& reader = aTile.StreamReader();
+ while ( iLastPacket < iPacketList.Count() )
+ {
+ if ( aTile.IsPOC() )
+ {
+ marker = PtrReadUtil::ReadBigEndianUint16( reader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ break; //lint !e960 Break is OK.
+ }
+ }
+
+ incomplete = iPacketList[iLastPacket]->ReadPacketHeaderL( aTile, aComponent, *this );
+ if ( incomplete )
+ {
+ // Underflow
+ break; //lint !e960 Break is OK.
+ }
+ if ( iPacketList[iLastPacket]->IsBodyIncomplete() )
+ {
+ incomplete = iPacketList[iLastPacket]->ReadPacketBodyL( aTile, aComponent, *this );
+ if ( incomplete )
+ {
+ // Underflow
+ break; //lint !e960 Break is OK.
+ }
+ }
+ iPacketList[iLastPacket]->ResetInternalFlags();
+ ++iLastPacket;
+ }
+
+ if ( !incomplete && iLastPacket == iPacketList.Count() )
+ {
+ // Reset it back to 0 for the next layer
+ iLastPacket = 0;
+ }
+
+ return incomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::RPCLProgressionL
+// At each subband, parse the bitstream with RPCL progression order
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kSubband::RPCLProgressionL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent )
+ {
+ TUint8 incomplete = EFalse;
+ TUint16 numOfLayers = aTile.NumOfLayersPOC();
+ TUint16 marker = 0;
+ const TJ2kStreamReader& reader = aTile.StreamReader();
+ while ( aTile.LastLayerProcessed() < numOfLayers )
+ {
+ if ( iPacketList.Count() )
+ {
+ if ( aTile.IsPOC() )
+ {
+ marker = PtrReadUtil::ReadBigEndianUint16( reader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ break; //lint !e960 Break is OK.
+ }
+ }
+
+ incomplete = iPacketList[iLastPacket]->ReadPacketHeaderL( aTile, aComponent, *this );
+ if ( incomplete )
+ {
+ // Underflow
+ break; //lint !e960 Break is OK.
+ }
+ if ( iPacketList[iLastPacket]->IsBodyIncomplete() )
+ {
+ incomplete = iPacketList[iLastPacket]->ReadPacketBodyL( aTile, aComponent, *this );
+ if ( incomplete )
+ {
+ // Underflow
+ break; //lint !e960 Break is OK.
+ }
+ }
+ iPacketList[iLastPacket]->ResetInternalFlags();
+ }
+ aTile.IncrementLastLayerProcessed();
+ }
+
+ if ( !incomplete && aTile.LastLayerProcessed() == numOfLayers )
+ {
+ aTile.ResetLastLayerProcessed();
+ ++iLastPacket;
+ if ( iLastPacket == iPacketList.Count() )
+ {
+ iLastPacket = 0;
+ }
+ }
+ return incomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::CPRLProgressionL
+// At each subband, parse the bitstream with CPRL progression order.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint8 CJ2kSubband::CPRLProgressionL( CJ2kTileInfo& aTile, CJ2kComponentInfo& aComponent )
+ {
+ TUint8 incomplete = EFalse;
+ TUint16 numOfLayers = aTile.NumOfLayersPOC();
+ TUint16 marker = 0;
+ const TJ2kStreamReader& reader = aTile.StreamReader();
+ while ( aTile.LastLayerProcessed() < numOfLayers )
+ {
+ if ( iPacketList.Count() )
+ {
+ if ( aTile.IsPOC() )
+ {
+ marker = PtrReadUtil::ReadBigEndianUint16( reader.iPtr );
+ if ( marker == KSOT || marker == KEOC )
+ {
+ break; //lint !e960 Break is OK.
+ }
+ }
+
+ incomplete = iPacketList[iLastPacket]->ReadPacketHeaderL( aTile, aComponent, *this );
+ if ( incomplete )
+ {
+ // Underflow
+ break; //lint !e960 Break is OK.
+ }
+ if ( iPacketList[iLastPacket]->IsBodyIncomplete() )
+ {
+ incomplete = iPacketList[iLastPacket]->ReadPacketBodyL( aTile, aComponent, *this );
+ if ( incomplete )
+ {
+ // Underflow
+ break; //lint !e960 Break is OK.
+ }
+ }
+ iPacketList[iLastPacket]->ResetInternalFlags();
+ }
+ aTile.IncrementLastLayerProcessed();
+ }
+
+ if ( !incomplete && aTile.LastLayerProcessed() == numOfLayers )
+ {
+ aTile.ResetLastLayerProcessed();
+ ++iLastPacket;
+ if ( iLastPacket == iPacketList.Count() )
+ {
+ iLastPacket = 0;
+ }
+ }
+ return incomplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::ChildAt
+// Get the child subband at specific index
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubband::ChildAt( TInt /*aBand*/ )
+ {
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::NextSubbandRaster
+// Get the sibling subband
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubband::NextSubbandRaster()
+ {
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SubbandAt
+// Get the subband at specific resolution level
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubband::SubbandAt( TUint8 /*aResLevel*/ )
+ {
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::AddChildL
+// Add the child subband into the list of child subbands ( No-op )
+// -----------------------------------------------------------------------------
+//
+void CJ2kSubband::AddChildL( CJ2kSubband* /*aChild*/ )
+ { }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::SubbandTreeIndex
+// Get the subband tree index
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUint16 CJ2kSubband::SubbandTreeIndex() const
+ {
+ TUint16 bandIndex = 0;
+ if ( iResLevel )
+ {
+ bandIndex = ( TUint16 )( ( iResLevel - 1 ) * 3 + iType );
+ }
+
+ return bandIndex;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubband::CJ2kSubband
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband::CJ2kSubband() :
+ iPacketList( 1 )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubbandLL::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJ2kSubbandLL* CJ2kSubbandLL::NewLC()
+ {
+ CJ2kSubbandLL* self = new ( ELeave ) CJ2kSubbandLL();
+
+ CleanupStack::PushL( self );
+ self->iType = EBandLL;
+
+ return self;
+ }
+
+// Destructor
+CJ2kSubbandLL::~CJ2kSubbandLL()
+ {
+ iChildList.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubbandLL::ChildAt
+// Get the child subband at specific index
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubbandLL::ChildAt( TInt aBand )
+ {
+ if ( iChildList.Count() > 0 )
+ {
+ return iChildList[aBand];
+ }
+
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubbandLL::SubbandAt
+// Get the subband at specific resolution level
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubbandLL::SubbandAt( TUint8 aResLevel )
+ {
+ if ( iResLevel > aResLevel )
+ {
+ return ChildAt( EBandLL )->SubbandAt( aResLevel );
+ }
+ if ( iResLevel == 0 && aResLevel == 0 )
+ {
+ return this;
+ }
+ else
+ {
+ return Parent()->ChildAt( EBandHL );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubbandLL::AddChildL
+// Add the child subband into the list of child subbands
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CJ2kSubbandLL::AddChildL( CJ2kSubband* aChild )
+ {
+ aChild->SetParent( this );
+ User::LeaveIfError( iChildList.Append( aChild ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubbandNLL::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CJ2kSubbandNLL* CJ2kSubbandNLL::NewLC()
+ {
+ CJ2kSubbandNLL* self = new ( ELeave ) CJ2kSubbandNLL();
+ CleanupStack::PushL( self );
+ return self;
+ }
+
+// Destructor
+CJ2kSubbandNLL::~CJ2kSubbandNLL()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CJ2kSubbandNLL::NextSubbandRaster
+// Get the sibling subband
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CJ2kSubband* CJ2kSubbandNLL::NextSubbandRaster()
+ {
+ CJ2kSubband *nextSubband = 0;
+ switch ( iType )
+ {
+ case EBandHL:
+ {
+ nextSubband = Parent()->ChildAt( EBandLH );
+ break;
+ }
+ case EBandLH:
+ {
+ nextSubband = Parent()->ChildAt( EBandHH );
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return nextSubband;
+ }