diff -r 57d4cdd99204 -r edfc90759b9f imageeditorengine/filters/FilterScale/Src/CFilterScale.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imageeditorengine/filters/FilterScale/Src/CFilterScale.cpp Fri Jan 29 13:53:17 2010 +0200 @@ -0,0 +1,242 @@ +/* +* Copyright (c) 2010 Ixonos Plc. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the "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: +* Ixonos Plc +* +* Description: +* +*/ + + +#include "CFilterScale.h" +#include + +const TInt KScaleBits = 12; + +EXPORT_C TInt CFilterScale::Create() + { + CFilterScale* ptr = NULL; + TRAPD( error, ptr = NewL(); ); + if( error != KErrNone ) + { + ptr = NULL; + } + return (TInt)((MImageFilter*)ptr); + } + + + +CFilterScale* CFilterScale::NewL() + { + CFilterScale* self = new( ELeave )CFilterScale(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + + +CFilterScale::~CFilterScale() + { + } + + + +CFilterScale::CFilterScale() + { + iScale = (1 << KScaleBits); + iRelScale = 1.0; + } + + + +void CFilterScale::ConstructL() + { + + } + + + +TRect CFilterScale::Rect() + { + if ( iRect == TRect(0,0,0,0) ) + { + return iChild->Rect(); + } + else + { + return iRect; + } + } + +TReal CFilterScale::Scale() + { + return iRelScale; + } + + +TSize CFilterScale::ViewPortSize() +{ + return iChild->ViewPortSize(); +} + +TBlock * CFilterScale::GetBlockL ( const TRect & aRect ) +{ + // Get the block to be scaled + TRect rect; + rect.iTl.iX = iOrigo.iX + (((aRect.iTl.iX * iScale) >> KScaleBits)); + rect.iTl.iY = iOrigo.iY + (((aRect.iTl.iY * iScale) >> KScaleBits)); + rect.iBr.iX = iOrigo.iX + (((aRect.iBr.iX * iScale) >> KScaleBits)) + 1; + rect.iBr.iY = iOrigo.iY + (((aRect.iBr.iY * iScale) >> KScaleBits)) + 1; + + TBlock * pSource = iChild->GetBlockL(rect); + if (!pSource) return NULL; + + // Create the scaled block + TBlock * pDest = new (ELeave) TBlock (aRect); + TUint32 * pD = pDest->iData; + + rect = iChild->Rect(); + + for (TInt i = aRect.iTl.iY; i < aRect.iBr.iY; ++i) + { + + TInt y = iOrigo.iY + ((i * iScale) >> KScaleBits); + if ((y < rect.iTl.iY) || (y >= rect.iBr.iY)) + { + pD += pDest->iWidth; + continue; + } + + for (TInt j = aRect.iTl.iX; j < aRect.iBr.iX; ++j, ++pD) + { + + TInt x = iOrigo.iX + ((j * iScale) >> KScaleBits); + if ((x < rect.iTl.iX) || (x >= rect.iBr.iX)) + { + continue; + } + + if ( (x >= pSource->iRect.iTl.iX) && (x < pSource->iRect.iBr.iX) && + (y >= pSource->iRect.iTl.iY) && (y < pSource->iRect.iBr.iY) ) + { + *pD = *(pSource->iData + (y - pSource->iRect.iTl.iY) * pSource->iWidth + (x - pSource->iRect.iTl.iX)); + } + } + } + + delete pSource; + pSource = NULL; + + // Return scaled block + return pDest; +} + + + +void CFilterScale::SetParent( MImageFilter* aParent ) + { + iParent = aParent; + } + + + +void CFilterScale::SetChild( MImageFilter* aChild ) + { + iChild = aChild; + } + + + +TInt CFilterScale::CmdL( const TDesC16& aCmd ) + { + + TLex lex( aCmd ); + + while( ! lex.Eos() ) + { + TPtrC token = lex.NextToken(); + if( token.Compare( _L("zoom") ) == 0 ) + { + lex.Inc(); + lex.Val( iZoom ); + } + else if( token.Compare( _L("x") ) == 0 ) + { + lex.Inc(); + lex.Val( iPosition.iX ); + } + else if( token.Compare( _L("y") ) == 0 ) + { + lex.Inc(); + lex.Val( iPosition.iY ); + } + } + + // Get source and target sizes + TRect rect = iChild->Rect(); + TSize srcsize; + srcsize.iWidth = rect.iBr.iX - rect.iTl.iX; + srcsize.iHeight = rect.iBr.iY - rect.iTl.iY; + + rect = iParent->Rect(); + TSize tgtsize; + tgtsize.iWidth = rect.iBr.iX - rect.iTl.iX; + tgtsize.iHeight = rect.iBr.iY - rect.iTl.iY; + + // Compute aspect ratio of the source + TInt ars = (srcsize.iWidth << KScaleBits) / srcsize.iHeight; + + // Compute aspect ratio of the target + TInt art = (tgtsize.iWidth << KScaleBits) / tgtsize.iHeight; + + // Select scale so that aspect ratio is preserved + if ( ars >= art ) + { + iScale = (srcsize.iWidth << KScaleBits) / tgtsize.iWidth; + iRelScale = (TReal)tgtsize.iWidth / (TReal)srcsize.iWidth; + iOrigo.iX = iChild->Rect().iTl.iX; + TInt h = (srcsize.iWidth << KScaleBits) / art; + iOrigo.iY = iChild->Rect().iTl.iY + (srcsize.iHeight - h) / 2; + } + else + { + iScale = (srcsize.iHeight << KScaleBits) / tgtsize.iHeight; + iRelScale = (TReal)tgtsize.iHeight / (TReal)srcsize.iHeight; + iOrigo.iY = iChild->Rect().iTl.iY; + TInt w = (srcsize.iHeight * art) >> KScaleBits; + iOrigo.iX = iChild->Rect().iTl.iX + (srcsize.iWidth - w) / 2 ; + } + + rect = iChild->Rect(); + iRect.iTl.iX = ((rect.iTl.iX * iScale) >> KScaleBits); + iRect.iTl.iY = ((rect.iTl.iY * iScale) >> KScaleBits); + iRect.iBr.iX = ((rect.iBr.iX * iScale) >> KScaleBits); + iRect.iBr.iY = ((rect.iBr.iY * iScale) >> KScaleBits); + return 0; + } + + + +const char* CFilterScale::Type() + { + return "scale"; + } + + +#if !defined(EKA2) +GLDEF_C TInt E32Dll( TDllReason ) + { + return KErrNone; + } +#endif