--- /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 <e32math.h>
+
+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