diff -r 000000000000 -r 469c91dae73b imagingmodules/jp2kcodec/Src/JP2KSubband.cpp --- /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 +#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; + }