imagehandlinglib/Src/CIHLBitmapProcessor.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 26 Jan 2010 15:18:05 +0200
changeset 0 2014ca87e772
permissions -rw-r--r--
Revision: 201004

/*
* Copyright (c) 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:  Implementation of scaling processor
*              : using MIHLBitmap type bitmaps.
*
*/



// INCLUDE FILES
#include "CIHLBitmapProcessor.h"

#include "CIHLScaler.h"
#include "CIHLBitmap.h"
#include "IHLImplementationIds.h"
#include "IHLDebugPrint.h" // Debug print

#include <IHLInterfaceIds.h>
#include <fbs.h> // CFbsBitmap
#include <bitdev.h> // CFbsBitmapDevice, CFbsBitGc

// Private namespace for constants and functions
namespace
	{
	// Panic function
    _LIT( KIHLPanicString, "IHLBitmapProcessor" );
    void Panic( TInt aPanicCode ) { User::Panic( KIHLPanicString, aPanicCode ); }
	}

// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
//
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
CIHLBitmapProcessor::CIHLBitmapProcessor()
:CActive( CActive::EPriorityStandard )
    {
	CActiveScheduler::Add( this );
    }

// -----------------------------------------------------------------------------
//
// Two-phased constructor.
// -----------------------------------------------------------------------------
CIHLBitmapProcessor* CIHLBitmapProcessor::NewL( const TUint32 aOptions )
    {
    CIHLBitmapProcessor* self = new( ELeave ) CIHLBitmapProcessor();
    CleanupStack::PushL( self );
    self->ConstructL( aOptions );
	CleanupStack::Pop(); // self
    return self;
    }

// -----------------------------------------------------------------------------
//
// Symbian constructor can leave.
// -----------------------------------------------------------------------------
void CIHLBitmapProcessor::ConstructL( const TUint32 aOptions )
	{
	iScaler = CIHLScaler::NewL( aOptions );
	}

// -----------------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------------
CIHLBitmapProcessor::~CIHLBitmapProcessor()
    {
	Cancel();
	delete iScaler;
    }

// -----------------------------------------------------------------------------
// CIHLBitmapProcessor::Type
// -----------------------------------------------------------------------------
TIHLInterfaceType CIHLBitmapProcessor::Type() const
	{
	return TIHLInterfaceType( KIHLInterfaceIdBitmapProcessor, KIHLImplementationIdBitmapProcessor );
	}

// -----------------------------------------------------------------------------
// CIHLBitmapProcessor::Process
// -----------------------------------------------------------------------------
TInt CIHLBitmapProcessor::Process( TRequestStatus& aStatus,
									const MIHLBitmap& aSrcBitmap,
									const TRect& aSrcRect,
									MIHLBitmap& aDstBitmap,
									const TRect& aDstRect )
	{
	if( IsBusy() )
		{
		return KErrNotReady;
		}

	// Check bitmaps (no checking of masks is needed)
	const CFbsBitmap& srcBitmap = aSrcBitmap.Bitmap();
	const CFbsBitmap& dstBitmap = aDstBitmap.Bitmap();
	if( !srcBitmap.Handle() ||
		!iScaler->IsValidRect( srcBitmap.SizeInPixels(), aSrcRect ) ||
		!dstBitmap.Handle() ||
		!iScaler->IsValidRect( dstBitmap.SizeInPixels(), aDstRect ) )
		{
		return KErrArgument;
		}

    IHL_DEBUG1( KIHLDebug, "IHL - CIHLBitmapProcessor - Start asynchronous bitmap processing" );

	// Set references to member data
	iSrcBitmap = &aSrcBitmap;
	iSrcRect = aSrcRect;
	iDstBitmap = static_cast<CIHLBitmap*>( &aDstBitmap ); //lint !e826
	iDstRect = aDstRect;

	// Start processing
	iProcessorStatus = &aStatus;
	*iProcessorStatus = KRequestPending;

	iProcessorState = EProcessBitmap;
	SelfComplete();
	return KErrNone;
	}

// -----------------------------------------------------------------------------
// CIHLBitmapProcessor::IsBusy
// -----------------------------------------------------------------------------
TBool CIHLBitmapProcessor::IsBusy() const
	{
	return ( iProcessorState != EInactive );
	}

// -----------------------------------------------------------------------------
// CIHLBitmapProcessor::CancelProcess
// -----------------------------------------------------------------------------
void CIHLBitmapProcessor::CancelProcess()
	{
    IHL_DEBUG1( KIHLDebug, "IHL - CIHLBitmapProcessor - Process cancelled" );

	Cancel();
	}

// -----------------------------------------------------------------------------
// CIHLBitmapProcessor::SetFilter
// -----------------------------------------------------------------------------
void CIHLBitmapProcessor::SetFilter( MIHFilter* /*aFilter*/ )
	{
	// Not in use
	}

// -----------------------------------------------------------------------------
// CIHLBitmapProcessor::DoCancel
// -----------------------------------------------------------------------------
void CIHLBitmapProcessor::DoCancel()
	{
	iScaler->CancelProcess();
	iProcessorState = EInactive;
	RequestComplete( KErrCancel );
	}

// -----------------------------------------------------------------------------
// CIHLBitmapProcessor::RunL
// -----------------------------------------------------------------------------
void CIHLBitmapProcessor::RunL()
	{
	User::LeaveIfError( iStatus.Int() );

	switch( iProcessorState )
		{
		case EProcessBitmap:
			{
			ProcessBitmapL();
			if( iDstBitmap->Mask().Handle() )
				{
				iProcessorState = EProcessMask;
				}
			else
				{
				// Destination has no mask -> finish process
				iProcessorState = EFinish;
				}
			break;
			}
		case EProcessMask:
			{
			ProcessMaskL();
			iProcessorState = EFinish;
			break;
			}
		case EFinish:
			{
            IHL_DEBUG1( KIHLDebug, "IHL - CIHLBitmapProcessor - Process complete!" );

			iProcessorState = EInactive;
			RequestComplete( KErrNone );
			break;
			}
		default:
			{
			Panic( KErrTotalLossOfPrecision );
			}
		}
	}

// -----------------------------------------------------------------------------
// CIHLBitmapProcessor::RunError
// -----------------------------------------------------------------------------
TInt CIHLBitmapProcessor::RunError( TInt aError )
	{
    IHL_DEBUG2( KIHLDebug, "IHL - CIHLBitmapProcessor - Processing error: %d", aError );

	iProcessorState = EInactive;
	RequestComplete( aError );
	return KErrNone;
	}

// -----------------------------------------------------------------------------
// CIHLBitmapProcessor::ProcessBitmapL
// -----------------------------------------------------------------------------
void CIHLBitmapProcessor::ProcessBitmapL()
	{
	User::LeaveIfError( iScaler->Scale( iStatus,
										iSrcBitmap->Bitmap(),
										iSrcRect,
										iDstBitmap->BitmapModifyable(),
										iDstRect ) );
	SetActive();
	}

// -----------------------------------------------------------------------------
// CIHLBitmapProcessor::ProcessMaskL
// -----------------------------------------------------------------------------
void CIHLBitmapProcessor::ProcessMaskL()
	{
	if( iSrcBitmap->Mask().Handle() )
		{
		User::LeaveIfError( iScaler->Scale( iStatus,
											iSrcBitmap->Mask(),
											iSrcRect,
											iDstBitmap->MaskModifyable(),
											iDstRect ) );
		SetActive();
		}
	else
		{
		// No source bitmap where mask can be copied
		// -> clear destination mask at given rectangle
		CFbsBitGc* bitGc;
		CFbsBitmapDevice* bitDev = CFbsBitmapDevice::NewL(
										&(iDstBitmap->BitmapModifyable()) );
		CleanupStack::PushL( bitDev );
		User::LeaveIfError( bitDev->CreateContext( bitGc ) );
		CleanupStack::PushL( bitGc );

		bitGc->SetPenColor( KRgbWhite ); // white is non-transparent
		bitGc->SetBrushColor( KRgbWhite );
		bitGc->SetBrushStyle( CGraphicsContext::ESolidBrush );
		bitGc->DrawRect( iDstRect );

		CleanupStack::PopAndDestroy( 2 ); // bitGc, bitDev
		}
	}

// -----------------------------------------------------------------------------
// CIHLBitmapProcessor::SelfComplete
// -----------------------------------------------------------------------------
void CIHLBitmapProcessor::SelfComplete()
	{
	SetActive();
	iStatus = KRequestPending;
	TRequestStatus* status = &iStatus;
	User::RequestComplete( status, KErrNone );
	}

// -----------------------------------------------------------------------------
// CIHLBitmapProcessor::RequestComplete
// -----------------------------------------------------------------------------
void CIHLBitmapProcessor::RequestComplete( TInt aReason )
	{
	ASSERT( iProcessorStatus );
	User::RequestComplete( iProcessorStatus, aReason );
	}

//  End of File