imageeditorengine/filters/FilterFrame/Src/CFilterFrame.cpp
author Mikael Laine <mikael.laine@ixonos.com>
Fri, 29 Jan 2010 13:53:17 +0200
changeset 1 edfc90759b9f
permissions -rw-r--r--
Committing the Image Editor package under the Eclipse Public License

/*
* 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 <fbs.h>
#include <e32math.h>
#include "CFilterFrame.h"

const TInt KScaleBits = 12;

EXPORT_C TInt CFilterFrame::Create()
	{
	CFilterFrame* ptr = NULL;
	TRAPD( error, ptr = NewL(); );
	if( error != KErrNone )
		{
		ptr = NULL;
		}
	return (TInt)((MImageFilter*)ptr);
	}



CFilterFrame* CFilterFrame::NewL()
	{
	CFilterFrame* self = new( ELeave )CFilterFrame();
	CleanupStack::PushL( self );
	self->ConstructL();
	CleanupStack::Pop( self );
	return self;
	}



CFilterFrame::~CFilterFrame()
	{
	delete[] iData;
	}



CFilterFrame::CFilterFrame()
	{

	}



void CFilterFrame::ConstructL()
	{

	}



TRect CFilterFrame::Rect()
	{
	return iChild->Rect();
	}

TReal CFilterFrame::Scale()
	{
	return iChild->Scale();
	}

TSize CFilterFrame::ViewPortSize()
{
    return iChild->ViewPortSize();
}

TBlock * CFilterFrame::GetBlockL ( const TRect & aRect )
{
    TBlock * pB = iChild->GetBlockL (aRect);
    if (!pB) return NULL;
    TUint32 * pD = pB->iData;

    for (TInt i = pB->iRect.iTl.iY; i < pB->iRect.iBr.iY; ++i)
    {

        TInt y = ((i - iOffset.iY) * iScale.iY) >> KScaleBits;

        for (TInt j = pB->iRect.iTl.iX; j < pB->iRect.iBr.iX; ++j, ++pD)
        {

	        TInt x = ((j - iOffset.iX) * iScale.iX) >> KScaleBits;

	        if ( x >= 0 && x < iSize.iWidth && y >= 0 && y < iSize.iHeight )
	        {
	            TUint32 pixel = *pD;
		        TUint32 frame = iData[y * iSize.iWidth + x];
		        TUint8 alpha = (TUint8)(iData[y * iSize.iWidth + x] >> 24);

		        if (alpha == 255)
		        {
			        *pD = frame;
		        }
		        else 
		        {
		            TInt cc1 = (frame & 0xff00ff) * alpha + (pixel & 0xff00ff) * (255 - alpha);
		            TInt cc2 = (frame & 0xff00) * alpha + (pixel & 0xff00) * (255 - alpha);
		            *pD = (( cc1 >> 8 ) & 0xff00ff) + ((cc2 >> 8) & 0xff00);
		        }
	        }
        }
    }
    return pB;
}



void CFilterFrame::SetParent( MImageFilter* aParent )
	{
	iParent = aParent;
	}




void CFilterFrame::SetChild( MImageFilter* aChild )
	{
	iChild = aChild;
	}



TInt CFilterFrame::CmdL( const TDesC16& aCmd )
{
	TLex lex (aCmd);

	//	Handle parameters
	while ( !lex.Eos() )
	{
		TPtrC token = lex.NextToken();

		if ( token.Compare( _L("file") ) == 0 )
		{
			TPtrC namec = lex.NextToken();
			TPtrC name (namec.Ptr() + 1, namec.Length() - 2);
			iFile.Copy (name);
		}
		else if( token.Compare( _L("frame") ) == 0 )
		{
			lex.Inc ();
			lex.Val( iFrameInd );
		}
		else if( token.Compare( _L("mask") ) == 0 )
		{
			lex.Inc();
			lex.Val( iMaskInd );
		}
		else if( token.Compare( _L("load") ) == 0 )
		{
			LoadFrameL();
            iOrigRect = iChild->Rect();
            TReal relscale = iChild->Scale();
            iOrigRect.iTl.iX = (TInt)((iOrigRect.iTl.iX / relscale) + 0.5);
            iOrigRect.iTl.iY = (TInt)((iOrigRect.iTl.iY / relscale) + 0.5);
            iOrigRect.iBr.iX = (TInt)((iOrigRect.iBr.iX / relscale) + 0.5);
            iOrigRect.iBr.iY = (TInt)((iOrigRect.iBr.iY / relscale) + 0.5);
		}
	}
    
    TReal relscale = iChild->Scale();
	TRect rect = iChild->Rect();
    rect.iTl.iX = (TInt)((rect.iTl.iX / relscale) + 0.5);
    rect.iTl.iY = (TInt)((rect.iTl.iY / relscale) + 0.5);
    rect.iBr.iX = (TInt)((rect.iBr.iX / relscale) + 0.5);
    rect.iBr.iY = (TInt)((rect.iBr.iY / relscale) + 0.5);
    
    TRect framerect;
    framerect.iTl.iX = ((rect.iTl.iX - iOrigRect.iTl.iX) * (iSize.iWidth - 1)) / iOrigRect.Width();
    framerect.iTl.iY = ((rect.iTl.iY - iOrigRect.iTl.iY) * (iSize.iHeight - 1)) / iOrigRect.Height();
    framerect.iBr.iX = ((rect.iBr.iX - iOrigRect.iTl.iX) * (iSize.iWidth - 1)) / iOrigRect.Width();
    framerect.iBr.iY = ((rect.iBr.iY - iOrigRect.iTl.iY) * (iSize.iHeight - 1)) / iOrigRect.Height();

	rect = iChild->Rect();
    iScale.iX = (framerect.Width() << KScaleBits) / rect.Width();
	iScale.iY = (framerect.Height() << KScaleBits) / rect.Height();

    iOffset.iX = (TInt)(iOrigRect.iTl.iX * relscale + 0.5);
    iOffset.iY = (TInt)(iOrigRect.iTl.iY * relscale + 0.5);

    return 0;
}

const char* CFilterFrame::Type()
	{
	return "frame";
	}

void CFilterFrame::LoadFrameL()
{

	CFbsBitmap * frame = new (ELeave) CFbsBitmap;
	CleanupStack::PushL (frame);
	User::LeaveIfError ( frame->Load (iFile, iFrameInd) );

	CFbsBitmap * mask = new (ELeave) CFbsBitmap;
	CleanupStack::PushL (mask);
	User::LeaveIfError ( mask->Load (iFile, iMaskInd) );

	//	Get frame size
	iSize = frame->SizeInPixels();

	//	Create frame buffer
	delete iData;
	iData = NULL;
	iData = new (ELeave) TUint32 [iSize.iWidth * iSize.iHeight];

	//	Copy frame data
	frame->LockHeapLC();

	TInt wsf = frame->ScanLineLength (iSize.iWidth, frame->DisplayMode());
	TInt wsm = mask->ScanLineLength (iSize.iWidth, mask->DisplayMode());

	TUint8 * pfos = (TUint8 *)frame->DataAddress();
	TUint8 * pmos = (TUint8 *)mask->DataAddress();
	for ( TInt i = 0, k = 0; i < iSize.iHeight; ++i )
	{
		TUint8 * pd = pfos;
		pfos += wsf;

		TUint8 * pm = pmos;
		pmos += wsm;

		for ( TInt j = 0; j < iSize.iWidth; ++j )
		{
			iData[k++] = (TUint32)(*pd  | (*(pd + 1) << 8) | (*(pd + 2) << 16) | (*pm++ << 24));
			pd += 3;
		}
	}

	CleanupStack::PopAndDestroy(3); // LockHeapLC, mask, frame
}

	
#if !defined(EKA2)
GLDEF_C TInt E32Dll( TDllReason )
    {
    return KErrNone;
    }	
#endif