utils/tsimageutils/src/tsgraphicfilescalinghandler.cpp
changeset 121 0b3699f6c654
--- /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;
+    }