imageeditorengine/filters/FilterScale/Src/CFilterScale.cpp
changeset 1 edfc90759b9f
--- /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