--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/tsimageutils/src/tsgraphicfilescalinghandler.cpp Fri Sep 17 08:32:18 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 <bitmaptransforms.h>
+#include <imageconversion.h>
+
+#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<CBitmapRotator::TRotationAngle>( 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;
+ }