diff -r dbfb5e38438b -r 305818acdca4 utils/tsimageutils/src/tsgraphicfilescalinghandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils/tsimageutils/src/tsgraphicfilescalinghandler.cpp Mon Sep 13 13:26:33 2010 +0300 @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2009 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 : + * + */ +#include +#include + +#include "tsgraphicfilescalinghandler.h" +// ----------------------------------------------------------------------------- +/** + * Private constructor. + * Parameters - the same meaning as in appropriate NewL/NewLC functions. + */ +CTsGraphicFileScalingHandler::CTsGraphicFileScalingHandler( + MImageReadyCallBack &aNotify, + const TSize &aNewSize, + TKindOfScaling aKindOfScaling, + TInt aRotation ) +: + CActive( EPriorityNormal ), + iNotify( aNotify ), + iNewSize( aNewSize ), + iKindOfScaling( aKindOfScaling ), + iRotation( aRotation ), + iCurrentOperation( ENone ) + { + CActiveScheduler::Add(this); + } + +// ----------------------------------------------------------------------------- +/** +* Destructor. +*/ +CTsGraphicFileScalingHandler::~CTsGraphicFileScalingHandler() + { + Cancel(); + delete iInputBitmap; + delete iOutputBitmap; + delete iImageDecoder; + delete iBitmapScaler; + delete iBitmapRotator; + } + +// ----------------------------------------------------------------------------- +/** + * Constructors for activation graphic file scaling. + * aNotify - reference to observer implementation. + * aFs - reference to file server session. + * aFileName - path to graphic file. + * aMimeType - mime type of graphic file. + * aNewSize - new size of output graphic file. + * aKindOfScaling - kind of graphic file scaling described above. + * aRotation - requested rotation angle + */ +CTsGraphicFileScalingHandler* CTsGraphicFileScalingHandler::NewL( + MImageReadyCallBack &aNotify, + RFs &aFs, + const TDesC &aFileName, + const TDesC8& aMimeType, + const TSize &aNewSize, + TKindOfScaling aKindOfScaling, + TInt aRotation + ) + { + CTsGraphicFileScalingHandler *self = + CTsGraphicFileScalingHandler::NewLC(aNotify, + aFs, + aFileName, + aMimeType, + aNewSize, + aKindOfScaling, + aRotation ); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +/** + * Constructors for activation graphic file scaling. + * aNotify - reference to observer implementation. + * aFs - reference to file server session. + * aFileName - path to graphic file. + * aMimeType - mime type of graphic file. + * aNewSize - new size of output graphic file. + * aKindOfScaling - kind of graphic file scaling described above. + * aRotation - requested rotation angle + */ +CTsGraphicFileScalingHandler* CTsGraphicFileScalingHandler::NewLC( + MImageReadyCallBack &aNotify, + RFs &aFs, + const TDesC &aFileName, + const TDesC8& aMimeType, + const TSize &aNewSize, + TKindOfScaling aKindOfScaling, + TInt aRotation ) + { + CTsGraphicFileScalingHandler *self = + new (ELeave) CTsGraphicFileScalingHandler( aNotify, + aNewSize, + aKindOfScaling, + aRotation ); + + CleanupStack::PushL( self ); + self->ConstructL( aFs, aFileName, aMimeType ); + return self; + } + +// ----------------------------------------------------------------------------- +/** + * Functions construct active objest instance and made asynchronous operation/s. + * Parameters - the same meaning as in appropriate NewL/NewLC functions. + */ +void CTsGraphicFileScalingHandler::ConstructL( RFs &aFs, + const TDesC &aFileName, + const TDesC8& aMimeType ) + { + if( 0 == aFileName.Length() + || EFalse == aFs.IsValidName( aFileName ) ) + { + User::Leave( KErrPathNotFound ); + } + + if( 0 == aMimeType.Length() ) + { + User::Leave( KErrBadName ); + } + + if( 0 >= iNewSize.iWidth || 0 >= iNewSize.iHeight ) + { + User::Leave(KErrCorrupt); + } + iInputBitmap = new(ELeave)CFbsBitmap(); + DecodingOperationL( aFs, aFileName, aMimeType ); + SetActive(); + } + +// ----------------------------------------------------------------------------- +/** + * Exported from dll constructors for activation graphic file scaling. + * aNotify - reference to observer implementation. + * aInputFbsBitmap - reference to pattern CFbsBitmap. + * aNewSize - new size of output graphic file. + * aKindOfScaling - kind of graphic file scaling described above. + * aRotation - requested rotation angle + */ +CTsGraphicFileScalingHandler* CTsGraphicFileScalingHandler::NewL( + MImageReadyCallBack &aNotify, + const CFbsBitmap &aInputFbsBitmap, + const TSize &aNewSize, + TKindOfScaling aKindOfScaling, + TInt aRotation) + +{ + CTsGraphicFileScalingHandler *self = + CTsGraphicFileScalingHandler::NewLC( aNotify, + aInputFbsBitmap, + aNewSize, + aKindOfScaling, + aRotation ); + CleanupStack::Pop( self ); + return self; +} + +// ----------------------------------------------------------------------------- +/** + * Exported from dll constructors for activation graphic file scaling. + * aNotify - reference to observer implementation. + * aInputFbsBitmap - reference to pattern CFbsBitmap. + * aNewSize - new size of output graphic file. + * aKindOfScaling - kind of graphic file scaling described above. + * aRotation - requested rotation angle + */ +CTsGraphicFileScalingHandler* CTsGraphicFileScalingHandler::NewLC( + MImageReadyCallBack &aNotify, + const CFbsBitmap &aInputFbsBitmap, + const TSize &aNewSize, + TKindOfScaling aKindOfScaling, + TInt aRotation) + { + CTsGraphicFileScalingHandler *self = + new (ELeave) CTsGraphicFileScalingHandler( + aNotify, + aNewSize, + aKindOfScaling, + aRotation ); + CleanupStack::PushL( self ); + self->ConstructL( aInputFbsBitmap ); + return self; + } + +// ----------------------------------------------------------------------------- +/** + * Functions construct active objest instance and made asynchronous operation/s. + * Parameters - the same meaning as in appropriate NewL/NewLC functions. + */ +void CTsGraphicFileScalingHandler::ConstructL( const CFbsBitmap &aInputFbsBitmap ) + { + if( 0 >= iNewSize.iWidth || 0 >= iNewSize.iHeight) + { + User::Leave( KErrCorrupt ); + } + + iInputBitmap = new(ELeave)CFbsBitmap(); + User::LeaveIfError( iInputBitmap->Duplicate( aInputFbsBitmap.Handle() ) ); + + IsSupportedRotationMode() ? RotationOperationL() : ScalingOperationL(); + SetActive(); + } + +// ----------------------------------------------------------------------------- +/** + * Cancels the wait for completion of an outstanding request. + */ +void CTsGraphicFileScalingHandler::DoCancel() + { + switch(iCurrentOperation) + { + case EConvertBitmapFromFile: + iImageDecoder->Cancel(); + break; + case EScale: + iBitmapScaler->Cancel(); + break; + } + iNotify.ImageReadyCallBack( KErrCancel, 0 ); + } + +// ----------------------------------------------------------------------------- +/** + * Handles an active object’s request completion event. + */ +void CTsGraphicFileScalingHandler::RunL() + { + User::LeaveIfError(iStatus.Int()); + + switch (iCurrentOperation) + { + case EConvertBitmapFromFile: + delete iImageDecoder; + iImageDecoder = 0; + + IsSupportedRotationMode() ? RotationOperationL() : ScalingOperationL(); + SetActive(); + break; + + case ERotate: + delete iBitmapRotator; + iBitmapRotator = 0; + + ScalingOperationL(); + SetActive(); + break; + + case EScale: + iCurrentOperation = ENone; + delete iBitmapScaler; + iBitmapScaler = 0; + delete iInputBitmap; + iInputBitmap = 0; + if (iKindOfScaling == CTsGraphicFileScalingHandler::EKeepAspectRatioByExpanding) + { + User::LeaveIfError(iOutputBitmap->Resize(iNewSize)); + } + iNotify.ImageReadyCallBack(iStatus.Int(), iOutputBitmap); + break; + + } + } + +// ----------------------------------------------------------------------------- +/** + * Action to made before decoding graphic file operation. + * Parameters - the same meaning as in appropriate NewL/NewLC functions. + */ +void CTsGraphicFileScalingHandler::DecodingOperationL( RFs &aFs, + const TDesC &aFileName, + const TDesC8& aMimeType ) + { + // convert *.png to bitmap + iImageDecoder = CImageDecoder::FileNewL( aFs, aFileName, aMimeType ); + const TFrameInfo frameInfo( iImageDecoder->FrameInfo( 0 ) ); + iInputBitmap->Reset(); + User::LeaveIfError( iInputBitmap->Create(frameInfo.iOverallSizeInPixels, + frameInfo.iFrameDisplayMode ) ); + iImageDecoder->Convert( &iStatus, *iInputBitmap, 0 ); + iCurrentOperation = EConvertBitmapFromFile; + } + +// ----------------------------------------------------------------------------- +/** + * Action to made before scaling graphic file operation. + */ +void CTsGraphicFileScalingHandler::ScalingOperationL() + { + iBitmapScaler = CBitmapScaler::NewL(); + iBitmapScaler->SetQualityAlgorithm( CBitmapScaler::EMaximumQuality ); + FixForDisplayModeNotSupportedByScalingOperation(); + iOutputBitmap = new (ELeave)CFbsBitmap(); + User::LeaveIfError(iOutputBitmap->Create( NewSizeToScalingOperation(), + iInputBitmap->DisplayMode() ) ); + iBitmapScaler->Scale( &iStatus, *iInputBitmap, *iOutputBitmap, EFalse ); + iCurrentOperation = EScale; + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +void CTsGraphicFileScalingHandler::RotationOperationL() + { + const CBitmapRotator::TRotationAngle rotation = + static_cast( RotationMode() ); + iBitmapRotator = CBitmapRotator::NewL(); + iBitmapRotator->Rotate( &iStatus, + *iInputBitmap, + rotation ); + iCurrentOperation = ERotate; + } + +// ----------------------------------------------------------------------------- +// +TInt CTsGraphicFileScalingHandler::RotationMode()const + { + const TInt rotation(iRotation%360); + TInt retVal(CBitmapRotator::EMirrorHorizontalAxis); + if( 270 <= rotation ) + { + retVal = CBitmapRotator::ERotation270DegreesClockwise; + } + else if( 180 <= rotation ) + { + retVal = CBitmapRotator::ERotation180DegreesClockwise; + } + else if( 90 <= rotation ) + { + retVal = CBitmapRotator::ERotation90DegreesClockwise; + } + return retVal; + } + +// ----------------------------------------------------------------------------- +TBool CTsGraphicFileScalingHandler::IsSupportedRotationMode() const + { + TBool retVal(EFalse); + switch( RotationMode() ) + { + case CBitmapRotator::ERotation90DegreesClockwise: + case CBitmapRotator::ERotation180DegreesClockwise: + case CBitmapRotator::ERotation270DegreesClockwise: + retVal = ETrue; + break; + } + return retVal; + } +// ----------------------------------------------------------------------------- +/** + * Fix for TDisplayMode == EColor16MAP not supported by scaling operation! + * ! ! ! ADD OTHER NOT SUPPORTED DISPLAY MODES ! ! ! + */ +void CTsGraphicFileScalingHandler::FixForDisplayModeNotSupportedByScalingOperation() + { + if (EColor16MAP == iInputBitmap->DisplayMode()) + { + iInputBitmap->SetDisplayMode(EColor16MA); + } + } + +// ----------------------------------------------------------------------------- +/** + * Algorithm to determine output bitmap (returned in ImageReadyCallBack) size + * after scaling operation. + */ +TSize CTsGraphicFileScalingHandler::NewSizeToScalingOperation() + { + TSize originalSize = iInputBitmap->SizeInPixels(); + float widthFactor = iNewSize.iWidth / (float)originalSize.iWidth; + float heightFactor = iNewSize.iHeight / (float)originalSize.iHeight; + TSize retSize(iNewSize); + + if(CTsGraphicFileScalingHandler::EKeepAspectRatio == iKindOfScaling) + { + retSize = (widthFactor < heightFactor) ? + TSize(iNewSize.iWidth, widthFactor * originalSize.iHeight) : + TSize(heightFactor * originalSize.iWidth, iNewSize.iHeight); + } + else if (CTsGraphicFileScalingHandler::EKeepAspectRatioByExpanding == iKindOfScaling) + { + retSize = (widthFactor < heightFactor) ? + TSize(heightFactor * originalSize.iWidth, iNewSize.iHeight) : + TSize(iNewSize.iWidth, widthFactor * originalSize.iHeight); + } + return retSize; + } +// ----------------------------------------------------------------------------- +/** + * Handles a leave occurring in the request completion event handler RunL(). + */ +TInt CTsGraphicFileScalingHandler::RunError( TInt aError ) + { + iNotify.ImageReadyCallBack( aError, 0 ); + return KErrNone; + }