diff -r 000000000000 -r 469c91dae73b imagingmodules/jp2kcodec/Src/JP2KComponentInfo.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imagingmodules/jp2kcodec/Src/JP2KComponentInfo.cpp Thu Dec 17 09:22:31 2009 +0200 @@ -0,0 +1,393 @@ +/* +* 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: CJ2kComponentInfo class used to collect component related +* information such as precincts size at each resolution level and +* list of subbands. +* +*/ + + + +// INCLUDE FILES +#include "JP2KTileInfo.h" +#include "JP2KImageInfo.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 =============================== + +// ----------------------------------------------------------------------------- +// CJ2kComponentInfo::NewLC +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CJ2kComponentInfo* CJ2kComponentInfo::NewLC( CJ2kTileInfo& aTile, TUint16 aIndex ) + { + CJ2kComponentInfo* self = new ( ELeave ) CJ2kComponentInfo; + + CleanupStack::PushL(self); + self->ConstructL( aTile, aIndex ); + + return self; + } + +// Destructor +CJ2kComponentInfo::~CJ2kComponentInfo() + { + delete iRootSubband; + iRootSubband = 0; + + iPrecinctSizeList.Close(); + iGridList.Close(); + + // iExponentList and iMantissaList are not owned by this object + } + +// ----------------------------------------------------------------------------- +// CJ2kComponentInfo::LRCPProgressionL +// At each component, parse the bitstream with LRCP progression order +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint8 CJ2kComponentInfo::LRCPProgressionL( CJ2kTileInfo& aTile ) + { + TUint8 incomplete = 0; + if ( aTile.LastLevelProcessed() <= iNumOfLevels ) + { + incomplete = iRootSubband->SubbandAt( aTile.LastLevelProcessed() )->LRCPProgressionL( aTile, *this ); + } + return incomplete; + } + +// ----------------------------------------------------------------------------- +// CJ2kComponentInfo::RPCLProgressionL +// At each component, parse the bitstream with RPCL progression order +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint8 CJ2kComponentInfo::RPCLProgressionL( CJ2kTileInfo& aTile ) + { + TUint8 incomplete = 0; + TUint8 level = aTile.LastLevelProcessed(); + TUint8 diff = (TUint8)( iNumOfLevels - level ); + if ( level <= iNumOfLevels ) + { + TInt trx0 = TJ2kUtils::Ceil( iComponentCanvas.iTl.iX, 1 << diff ); + TInt try0 = TJ2kUtils::Ceil( iComponentCanvas.iTl.iY, 1 << diff ); + const TSizMarker& sizMarker = aTile.ImageInfo().SizMarker(); + + if ( ( ( aTile.LastN1Processed() % (TInt)( sizMarker.iYRsiz[aTile.LastComponentProcessed()] * iGridList[level].iHeight ) == 0) || + ( ( aTile.LastN1Processed() == aTile.TileCanvas().iTl.iY ) && + ( ( try0 << diff) % iGridList[level].iHeight ) ) ) && + ( ( aTile.LastN2Processed() % (TInt)( sizMarker.iXRsiz[aTile.LastComponentProcessed()] * iGridList[level].iWidth ) == 0) || + ( ( aTile.LastN2Processed() == aTile.TileCanvas().iTl.iX ) && + ( ( trx0 << diff ) % iGridList[level].iWidth ) ) ) ) + { + incomplete = iRootSubband->SubbandAt( level )->RPCLProgressionL( aTile, *this ); + } + } + return incomplete; + } + +// ----------------------------------------------------------------------------- +// CJ2kComponentInfo::CPRLProgressionL +// At each component, parse the bitstream with CPRL progression order +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint8 CJ2kComponentInfo::CPRLProgressionL( CJ2kTileInfo& aTile ) + { + TUint8 incomplete = 0; + TUint8 level = aTile.LastLevelProcessed(); + TUint8 diff = (TUint8)( iNumOfLevels - level ); + + if (level <= iNumOfLevels) + { + TInt trx0 = TJ2kUtils::Ceil( iComponentCanvas.iTl.iX, 1 << diff ); + TInt try0 = TJ2kUtils::Ceil( iComponentCanvas.iTl.iY, 1 << diff ); + const TSizMarker& sizMarker = aTile.ImageInfo().SizMarker(); + + if ( ( ( aTile.LastN1Processed() % (TInt)( sizMarker.iYRsiz[aTile.LastComponentProcessed()] * iGridList[level].iHeight ) == 0 ) || + ( ( aTile.LastN1Processed() == aTile.TileCanvas().iTl.iY ) && + ( ( try0 << diff) % iGridList[level].iHeight ) ) ) && + ( ( aTile.LastN2Processed() % (TInt)( sizMarker.iXRsiz[aTile.LastComponentProcessed()] * iGridList[level].iWidth ) == 0 ) || + ( ( aTile.LastN2Processed() == aTile.TileCanvas().iTl.iX ) && + ( ( trx0 << diff) % iGridList[level].iWidth ) ) ) ) + { + incomplete = iRootSubband->SubbandAt( level )->CPRLProgressionL( aTile, *this ); + } + } + return incomplete; + } + +// ----------------------------------------------------------------------------- +// CJ2kComponentInfo::SubbandAt +// Get the subband at specific resolution level +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +const CJ2kSubband* CJ2kComponentInfo::SubbandAt( TUint8 aResLevel ) const + { + return ( iRootSubband ) ? iRootSubband->SubbandAt( aResLevel ) : 0; + } + +// ----------------------------------------------------------------------------- +// CJ2kComponentInfo::NumOfPackets +// Get the number of packets at specific resolution level +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint32 CJ2kComponentInfo::NumOfPackets( TUint8 aResLevel ) const + { + return (TUint32)( iPrecinctSizeList[aResLevel].iWidth * + iPrecinctSizeList[aResLevel].iHeight ); + } + +// ----------------------------------------------------------------------------- +// CJ2kComponentInfo::Exponent +// Get the quantization exponnet value for transformation +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint8 CJ2kComponentInfo::Exponent( TUint16 aIndex ) const + { + if ( iQc & 0x01 ) + { + if ( aIndex > 0 ) + { + return (TUint8)( ( *iExponentList)[0] - ( ( aIndex - 1 ) / 3 ) ); + } + } + return ( *iExponentList )[aIndex]; + } + +// ----------------------------------------------------------------------------- +// CJ2kComponentInfo::Mantissa +// Get the quantization mantissa value for transformation +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint16 CJ2kComponentInfo::Mantissa( TUint16 aIndex ) const + { + if ( iQc & 0x01 ) + { + if ( aIndex > 0 ) + { + return ( *iMantissaList )[0]; + } + } + return ( *iMantissaList )[aIndex]; + } + +// ----------------------------------------------------------------------------- +// CJ2kComponentInfo::MagnitudeBits +// Get the magnitude bits +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint8 CJ2kComponentInfo::MagnitudeBits( TUint16 aIndex ) const + { + return (TUint8)( NumGuard() + Exponent( aIndex ) - 1 ); + } + +// ----------------------------------------------------------------------------- +// CJ2kComponentInfo::ResetLastPacketProcessed +// Reset the last packet processed +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CJ2kComponentInfo::ResetLastPacketProcessed() + { + for ( TUint8 index = 0; index <= iNumOfLevels; ++index ) + { + iRootSubband->SubbandAt( index )->ResetLastPacketProcessed(); + } + } + +// ----------------------------------------------------------------------------- +// CJ2kComponentInfo::CJ2kComponentInfo +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CJ2kComponentInfo::CJ2kComponentInfo() : + iPrecinctSizeList(4), + iGridList(4) + { + } + +// ----------------------------------------------------------------------------- +// CJ2kComponentInfo::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CJ2kComponentInfo::ConstructL( CJ2kTileInfo& aTile, TUint16 aIndex ) + { + CJ2kImageInfo& imageInfo = CONST_CAST( CJ2kImageInfo&, aTile.ImageInfo() ); + const TSizMarker& sizMarker = imageInfo.SizMarker(); + const TRect& tileCanvas = aTile.TileCanvas(); + + iComponentCanvas.iTl = TPoint( TJ2kUtils::Ceil( tileCanvas.iTl.iX, sizMarker.iXRsiz[aIndex] ), + TJ2kUtils::Ceil( tileCanvas.iTl.iY, sizMarker.iYRsiz[aIndex] ) ); + iComponentCanvas.iBr = TPoint( TJ2kUtils::Ceil( tileCanvas.iBr.iX, sizMarker.iXRsiz[aIndex] ), + TJ2kUtils::Ceil( tileCanvas.iBr.iY, sizMarker.iYRsiz[aIndex] ) ); + + if ( iComponentCanvas.Width( ) <= 0 || iComponentCanvas.Height( ) <= 0 ) + { + // Empty may be caused by subsampled + return; + } + + // Tile part COD > main header COD + TCODMarker *codMarker = aTile.TileMarker().iCod; + if ( !codMarker ) + { + codMarker = CONST_CAST( TCODMarker*, &imageInfo.MainMarker().iCod ); + } + + TCODMarker *cod = 0; + TCOCMarker *coc = 0; + + // Tile part COC > tile part COD > main header COC > main header COD + imageInfo.GetCodingStyle( cod, coc, aTile, aIndex ); + + iNumOfLevels = ( coc ) ? coc->iNumOfLevels : cod->iNumOfLevels; + iCodeBlockSiz = ( coc ) ? coc->iCodeBlockSiz : cod->iCodeBlockSiz; + iCodeBlockStyle = ( coc ) ? coc->iCodeBlockStyle : cod->iCodeBlockStyle; + iWaveletTransformation = ( coc ) ? coc->iWaveletTransformation : cod->iWaveletTransformation; + + HBufC8 *precinctSiz = ( coc ) ? coc->iPrecinctSiz : cod->iPrecinctSiz; + iCod = ( coc ) ? (TUint8)( ( codMarker->iScod & 0xfe ) | ( coc->iScoc & 0x01 ) ): cod->iScod; + + TQCDMarker *qcd = 0; + TQCCMarker *qcc = 0; + + // Tile part QCC > tile part QCD > main header QCC > main header QCD + imageInfo.GetQuantization( qcd, qcc, aTile, aIndex ); + + iQc = ( qcc ) ? qcc->iSqcc : qcd->iSqcd; + iExponentList = ( qcc ) ? qcc->iExponent : qcd->iExponent; + iMantissaList = ( qcc ) ? qcc->iMantissa : qcd->iMantissa; + + TRGNMarker *rgn = 0; + + // Tile part RGN > main header RGN + imageInfo.GetRegion( rgn, aTile, aIndex ); + iRoiShift = ( rgn ) ? rgn->iSPrgn : (TUint8)0; + + TSize& maxBlock = CONST_CAST( TSize&, imageInfo.MaxBlockSize() ); + maxBlock.iWidth = Max( maxBlock.iWidth, iCodeBlockSiz.iWidth ); + maxBlock.iHeight = Max( maxBlock.iHeight, iCodeBlockSiz.iHeight ); + + TSize precinct( 0,0 ); + TInt trx0 = 0; + TInt trx1 = 0; + TInt try0 = 0; + TInt try1 = 0; + TInt denom = 0; + TInt ppx = 15; + TInt ppy = 15; + + for ( TUint8 index = 0; index <= iNumOfLevels; ++index ) + { + // Resolution level at r = index + if ( precinctSiz ) + { + ppx = ( *precinctSiz )[index] & 0x0f; + ppy = ( ( *precinctSiz )[index] & 0xf0 ) >> 4; + } + denom = 1 << ( iNumOfLevels - index ); + + trx0 = TJ2kUtils::Ceil( iComponentCanvas.iTl.iX, denom ); + try0 = TJ2kUtils::Ceil( iComponentCanvas.iTl.iY, denom ); + trx1 = TJ2kUtils::Ceil( iComponentCanvas.iBr.iX, denom ); + try1 = TJ2kUtils::Ceil( iComponentCanvas.iBr.iY, denom ); + + if ( trx1 > trx0 ) + { + precinct.iWidth = TJ2kUtils::Ceil( trx1, 1 << ppx ) - TJ2kUtils::Floor( trx0, 1 << ppx ); + } + else + { + precinct.iWidth = 0; + } + + if ( try1 > try0 ) + { + precinct.iHeight = TJ2kUtils::Ceil( try1, 1 << ppy ) - TJ2kUtils::Floor( try0, 1 << ppy ); + } + else + { + precinct.iHeight = 0; + } + + User::LeaveIfError( iPrecinctSizeList.Append( precinct ) ); + + precinct.iWidth = 1 << ( ppx + iNumOfLevels - index ); + precinct.iHeight = 1 << ( ppy + iNumOfLevels - index ); + User::LeaveIfError( iGridList.Append( precinct ) ); + + // Calculate the minimum grid + if ( iMinGrid.iWidth == 0 || iMinGrid.iWidth > precinct.iWidth ) + { + iMinGrid.iWidth = precinct.iWidth; + } + if ( iMinGrid.iHeight == 0 || iMinGrid.iHeight > precinct.iHeight ) + { + iMinGrid.iHeight = precinct.iHeight; + } + } + + if ( imageInfo.Crop() ) + { + const TRect& crop = imageInfo.CropArea(); + + if ( !( crop.iTl.iX >= ( tileCanvas.iBr.iX - ( TInt )sizMarker.iXOsiz ) || + crop.iBr.iX < ( tileCanvas.iTl.iX - ( TInt )sizMarker.iXOsiz ) || + crop.iTl.iY >= ( tileCanvas.iBr.iY - ( TInt )sizMarker.iYOsiz ) || + crop.iBr.iY < ( tileCanvas.iTl.iY - ( TInt )sizMarker.iYOsiz ) ) ) + { + imageInfo.SetTileMask( aTile.SotMarker().iIsot, ETrue ); + } + else + { + // Current tile is not in the cropping area, + // just skip setting up the subbands and packets + return; + } + } + + // Build the associated Subband root + iRootSubband = CJ2kSubband::BuildSubbandTreeL( iNumOfLevels, *this ); + + // Build the associated Packet classes + iRootSubband->BuildPacketsL( *this, precinctSiz, codMarker->iNumOfLayers ); + } +