utils/tsimageutils/src/tsgraphicfilescalinghandler.cpp
changeset 124 e36b2f4799c0
parent 121 0b3699f6c654
equal deleted inserted replaced
121:0b3699f6c654 124:e36b2f4799c0
     1 /*
       
     2  * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Nokia Corporation - initial contribution.
       
    11  *
       
    12  * Contributors:
       
    13  *
       
    14  * Description :
       
    15  *
       
    16  */
       
    17 #include <bitmaptransforms.h>
       
    18 #include <imageconversion.h>
       
    19 
       
    20 #include "tsgraphicfilescalinghandler.h"
       
    21 // -----------------------------------------------------------------------------
       
    22 /**
       
    23  * Private constructor.
       
    24  * Parameters - the same meaning as in appropriate NewL/NewLC functions.
       
    25  */
       
    26 CTsGraphicFileScalingHandler::CTsGraphicFileScalingHandler(
       
    27                                 MImageReadyCallBack &aNotify,
       
    28                                 const TSize &aNewSize,
       
    29                                 TKindOfScaling aKindOfScaling,
       
    30                                 TInt aRotation )
       
    31 :
       
    32     CActive( EPriorityNormal ),
       
    33     iNotify( aNotify ),
       
    34     iNewSize( aNewSize ),
       
    35     iKindOfScaling( aKindOfScaling ),
       
    36     iRotation( aRotation ),
       
    37     iCurrentOperation( ENone )
       
    38     {
       
    39     CActiveScheduler::Add(this);
       
    40     }
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 /**
       
    44 * Destructor.
       
    45 */
       
    46 CTsGraphicFileScalingHandler::~CTsGraphicFileScalingHandler()
       
    47     {
       
    48     Cancel();
       
    49     delete iInputBitmap;
       
    50     delete iOutputBitmap;
       
    51     delete iImageDecoder;
       
    52     delete iBitmapScaler;
       
    53     delete iBitmapRotator;
       
    54     }
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 /**
       
    58  * Constructors for activation graphic file scaling.
       
    59  * aNotify        - reference to observer implementation.
       
    60  * aFs            - reference to file server session.
       
    61  * aFileName      - path to graphic file.
       
    62  * aMimeType      - mime type of graphic file.
       
    63  * aNewSize       - new size of output graphic file.
       
    64  * aKindOfScaling - kind of graphic file scaling described above.
       
    65  * aRotation - requested rotation angle
       
    66  */
       
    67 CTsGraphicFileScalingHandler* CTsGraphicFileScalingHandler::NewL(
       
    68                                                 MImageReadyCallBack &aNotify,
       
    69                                                 RFs &aFs,
       
    70                                                 const TDesC &aFileName,
       
    71                                                 const TDesC8& aMimeType,
       
    72                                                 const TSize &aNewSize,
       
    73                                                 TKindOfScaling aKindOfScaling,
       
    74                                                 TInt aRotation
       
    75                                                 )
       
    76     {
       
    77     CTsGraphicFileScalingHandler *self = 
       
    78                             CTsGraphicFileScalingHandler::NewLC(aNotify,
       
    79                                                                 aFs,
       
    80                                                                 aFileName,
       
    81                                                                 aMimeType,
       
    82                                                                 aNewSize,
       
    83                                                                 aKindOfScaling,
       
    84                                                                 aRotation );
       
    85     CleanupStack::Pop( self );
       
    86     return self;
       
    87     }
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 /**
       
    91  * Constructors for activation graphic file scaling.
       
    92  * aNotify        - reference to observer implementation.
       
    93  * aFs            - reference to file server session.
       
    94  * aFileName      - path to graphic file.
       
    95  * aMimeType      - mime type of graphic file.
       
    96  * aNewSize       - new size of output graphic file.
       
    97  * aKindOfScaling - kind of graphic file scaling described above.
       
    98  * aRotation - requested rotation angle
       
    99  */
       
   100 CTsGraphicFileScalingHandler* CTsGraphicFileScalingHandler::NewLC(
       
   101                                                 MImageReadyCallBack &aNotify,
       
   102                                                 RFs &aFs,
       
   103                                                 const TDesC &aFileName,
       
   104                                                 const TDesC8& aMimeType,
       
   105                                                 const TSize &aNewSize,
       
   106                                                 TKindOfScaling aKindOfScaling,
       
   107                                                 TInt aRotation )
       
   108     {
       
   109     CTsGraphicFileScalingHandler *self = 
       
   110                     new (ELeave) CTsGraphicFileScalingHandler( aNotify,
       
   111                                                                aNewSize,
       
   112                                                                aKindOfScaling,
       
   113                                                                aRotation );
       
   114 
       
   115     CleanupStack::PushL( self );
       
   116     self->ConstructL( aFs, aFileName, aMimeType );
       
   117     return self;
       
   118     }
       
   119 
       
   120 // -----------------------------------------------------------------------------
       
   121 /**
       
   122  * Functions construct active objest instance and made asynchronous operation/s.
       
   123  * Parameters - the same meaning as in appropriate NewL/NewLC functions.
       
   124  */
       
   125 void CTsGraphicFileScalingHandler::ConstructL( RFs &aFs, 
       
   126                                                const TDesC &aFileName, 
       
   127                                                const TDesC8& aMimeType )
       
   128     {
       
   129     if( 0 == aFileName.Length()
       
   130          || EFalse == aFs.IsValidName( aFileName ) )
       
   131         {
       
   132         User::Leave( KErrPathNotFound );
       
   133         }
       
   134 
       
   135     if( 0 == aMimeType.Length() )
       
   136         {
       
   137         User::Leave( KErrBadName );
       
   138         }
       
   139 
       
   140     if( 0 >= iNewSize.iWidth || 0 >= iNewSize.iHeight )
       
   141         {
       
   142         User::Leave(KErrCorrupt);
       
   143         }
       
   144     iInputBitmap = new(ELeave)CFbsBitmap();
       
   145     DecodingOperationL( aFs, aFileName, aMimeType );
       
   146     SetActive();
       
   147     }
       
   148 
       
   149 // -----------------------------------------------------------------------------
       
   150 /**
       
   151  * Exported from dll constructors for activation graphic file scaling.
       
   152  * aNotify         - reference to observer implementation.
       
   153  * aInputFbsBitmap - reference to pattern CFbsBitmap.
       
   154  * aNewSize        - new size of output graphic file.
       
   155  * aKindOfScaling  - kind of graphic file scaling described above.
       
   156  * aRotation - requested rotation angle
       
   157  */
       
   158 CTsGraphicFileScalingHandler* CTsGraphicFileScalingHandler::NewL(
       
   159                                         MImageReadyCallBack &aNotify,
       
   160                                         const CFbsBitmap &aInputFbsBitmap,
       
   161                                         const TSize &aNewSize,
       
   162                                         TKindOfScaling aKindOfScaling,
       
   163                                         TInt aRotation)
       
   164 
       
   165 {
       
   166     CTsGraphicFileScalingHandler *self = 
       
   167                             CTsGraphicFileScalingHandler::NewLC( aNotify,
       
   168                                                                  aInputFbsBitmap,
       
   169                                                                  aNewSize,
       
   170                                                                  aKindOfScaling,
       
   171                                                                 aRotation );
       
   172     CleanupStack::Pop( self );
       
   173     return self;
       
   174 }
       
   175 
       
   176 // -----------------------------------------------------------------------------
       
   177 /**
       
   178  * Exported from dll constructors for activation graphic file scaling.
       
   179  * aNotify         - reference to observer implementation.
       
   180  * aInputFbsBitmap - reference to pattern CFbsBitmap.
       
   181  * aNewSize        - new size of output graphic file.
       
   182  * aKindOfScaling  - kind of graphic file scaling described above.
       
   183  * aRotation - requested rotation angle
       
   184  */
       
   185 CTsGraphicFileScalingHandler* CTsGraphicFileScalingHandler::NewLC(
       
   186                                             MImageReadyCallBack &aNotify,
       
   187                                             const CFbsBitmap &aInputFbsBitmap,
       
   188                                             const TSize &aNewSize,
       
   189                                             TKindOfScaling aKindOfScaling,
       
   190                                             TInt aRotation)
       
   191     {
       
   192     CTsGraphicFileScalingHandler *self = 
       
   193                             new (ELeave) CTsGraphicFileScalingHandler(
       
   194                                                                aNotify,
       
   195                                                                aNewSize,
       
   196                                                                aKindOfScaling,
       
   197                                                                aRotation );
       
   198     CleanupStack::PushL( self );
       
   199     self->ConstructL( aInputFbsBitmap );
       
   200     return self;
       
   201     }
       
   202 
       
   203 // -----------------------------------------------------------------------------
       
   204 /**
       
   205  * Functions construct active objest instance and made asynchronous operation/s.
       
   206  * Parameters - the same meaning as in appropriate NewL/NewLC functions.
       
   207  */
       
   208 void CTsGraphicFileScalingHandler::ConstructL( const CFbsBitmap &aInputFbsBitmap )
       
   209     {
       
   210     if( 0 >= iNewSize.iWidth || 0 >= iNewSize.iHeight)
       
   211         {
       
   212         User::Leave( KErrCorrupt );
       
   213         }
       
   214 
       
   215     iInputBitmap = new(ELeave)CFbsBitmap();
       
   216     User::LeaveIfError( iInputBitmap->Duplicate( aInputFbsBitmap.Handle() ) );
       
   217 
       
   218     IsSupportedRotationMode() ? RotationOperationL() : ScalingOperationL();
       
   219     SetActive();
       
   220     }
       
   221 
       
   222 // -----------------------------------------------------------------------------
       
   223 /**
       
   224  * Cancels the wait for completion of an outstanding request.
       
   225  */
       
   226 void CTsGraphicFileScalingHandler::DoCancel()
       
   227     {
       
   228     switch(iCurrentOperation)
       
   229         {
       
   230     case EConvertBitmapFromFile:
       
   231         iImageDecoder->Cancel();
       
   232         break;
       
   233     case EScale:
       
   234         iBitmapScaler->Cancel();
       
   235         break;
       
   236         }
       
   237     iNotify.ImageReadyCallBack( KErrCancel, 0 );
       
   238     }
       
   239 
       
   240 // -----------------------------------------------------------------------------
       
   241 /**
       
   242  * Handles an active object’s request completion event.
       
   243  */
       
   244 void CTsGraphicFileScalingHandler::RunL()
       
   245     {
       
   246     User::LeaveIfError(iStatus.Int());
       
   247 
       
   248     switch (iCurrentOperation)
       
   249         {
       
   250     case EConvertBitmapFromFile:
       
   251             delete iImageDecoder;
       
   252             iImageDecoder = 0;
       
   253             
       
   254             IsSupportedRotationMode() ? RotationOperationL() : ScalingOperationL();
       
   255             SetActive();
       
   256             break;
       
   257     
       
   258     case ERotate:
       
   259             delete iBitmapRotator;
       
   260             iBitmapRotator = 0;
       
   261             
       
   262             ScalingOperationL();
       
   263             SetActive();
       
   264             break;
       
   265     
       
   266     case EScale:
       
   267             iCurrentOperation = ENone;
       
   268             delete iBitmapScaler;
       
   269             iBitmapScaler = 0;
       
   270             delete iInputBitmap;
       
   271             iInputBitmap = 0;
       
   272             if (iKindOfScaling == CTsGraphicFileScalingHandler::EKeepAspectRatioByExpanding) 
       
   273                 {
       
   274                 User::LeaveIfError(iOutputBitmap->Resize(iNewSize));
       
   275                 }
       
   276             iNotify.ImageReadyCallBack(iStatus.Int(), iOutputBitmap);
       
   277             break;
       
   278         
       
   279         }
       
   280     }
       
   281 
       
   282 // -----------------------------------------------------------------------------
       
   283 /**
       
   284  * Action to made before decoding graphic file operation.
       
   285  * Parameters - the same meaning as in appropriate NewL/NewLC functions.
       
   286  */
       
   287 void CTsGraphicFileScalingHandler::DecodingOperationL( RFs &aFs, 
       
   288                                                        const TDesC &aFileName, 
       
   289                                                        const TDesC8& aMimeType )
       
   290     {
       
   291     // convert *.png to bitmap
       
   292     iImageDecoder = CImageDecoder::FileNewL( aFs, aFileName, aMimeType );
       
   293     const TFrameInfo frameInfo( iImageDecoder->FrameInfo( 0 ) );
       
   294     iInputBitmap->Reset();
       
   295     User::LeaveIfError( iInputBitmap->Create(frameInfo.iOverallSizeInPixels, 
       
   296                                              frameInfo.iFrameDisplayMode ) );
       
   297     iImageDecoder->Convert( &iStatus, *iInputBitmap, 0 );
       
   298     iCurrentOperation = EConvertBitmapFromFile;
       
   299     }
       
   300 
       
   301 // -----------------------------------------------------------------------------
       
   302 /**
       
   303  * Action to made before scaling graphic file operation.
       
   304  */
       
   305 void CTsGraphicFileScalingHandler::ScalingOperationL()
       
   306     {
       
   307     iBitmapScaler = CBitmapScaler::NewL();
       
   308     iBitmapScaler->SetQualityAlgorithm( CBitmapScaler::EMaximumQuality );
       
   309     FixForDisplayModeNotSupportedByScalingOperation();
       
   310     iOutputBitmap = new (ELeave)CFbsBitmap();
       
   311     User::LeaveIfError(iOutputBitmap->Create( NewSizeToScalingOperation(), 
       
   312                                               iInputBitmap->DisplayMode() ) );
       
   313     iBitmapScaler->Scale( &iStatus, *iInputBitmap, *iOutputBitmap, EFalse );
       
   314     iCurrentOperation = EScale;
       
   315     }
       
   316 
       
   317 // -----------------------------------------------------------------------------
       
   318 // -----------------------------------------------------------------------------
       
   319 //
       
   320 void CTsGraphicFileScalingHandler::RotationOperationL()
       
   321     {
       
   322     const CBitmapRotator::TRotationAngle rotation =
       
   323         static_cast<CBitmapRotator::TRotationAngle>( RotationMode() );
       
   324     iBitmapRotator = CBitmapRotator::NewL();
       
   325     iBitmapRotator->Rotate( &iStatus, 
       
   326                             *iInputBitmap, 
       
   327                             rotation );
       
   328     iCurrentOperation = ERotate;
       
   329     }
       
   330 
       
   331 // -----------------------------------------------------------------------------
       
   332 //
       
   333 TInt CTsGraphicFileScalingHandler::RotationMode()const
       
   334     {
       
   335     const TInt rotation(iRotation%360);
       
   336     TInt retVal(CBitmapRotator::EMirrorHorizontalAxis);
       
   337     if( 270 <= rotation )
       
   338         {
       
   339         retVal = CBitmapRotator::ERotation270DegreesClockwise;
       
   340         }
       
   341     else if( 180 <= rotation )
       
   342         {
       
   343         retVal = CBitmapRotator::ERotation180DegreesClockwise;
       
   344         }
       
   345     else if( 90 <= rotation )
       
   346         {
       
   347         retVal = CBitmapRotator::ERotation90DegreesClockwise;
       
   348         }
       
   349     return retVal;
       
   350     }
       
   351 
       
   352 // -----------------------------------------------------------------------------
       
   353 TBool CTsGraphicFileScalingHandler::IsSupportedRotationMode() const
       
   354     {
       
   355     TBool retVal(EFalse);
       
   356     switch( RotationMode() )
       
   357         {
       
   358         case CBitmapRotator::ERotation90DegreesClockwise:
       
   359         case CBitmapRotator::ERotation180DegreesClockwise:
       
   360         case CBitmapRotator::ERotation270DegreesClockwise:
       
   361             retVal = ETrue;
       
   362             break;
       
   363         }
       
   364     return retVal;
       
   365     }
       
   366 // -----------------------------------------------------------------------------
       
   367 /**
       
   368  * Fix for TDisplayMode == EColor16MAP not supported by scaling operation!
       
   369  * ! ! ! ADD OTHER NOT SUPPORTED DISPLAY MODES ! ! !
       
   370  */
       
   371 void CTsGraphicFileScalingHandler::FixForDisplayModeNotSupportedByScalingOperation()
       
   372     {
       
   373     if (EColor16MAP == iInputBitmap->DisplayMode()) 
       
   374         {
       
   375         iInputBitmap->SetDisplayMode(EColor16MA);
       
   376         }
       
   377     }
       
   378 
       
   379 // -----------------------------------------------------------------------------
       
   380 /**
       
   381  * Algorithm to determine output bitmap (returned in ImageReadyCallBack) size
       
   382  * after scaling operation.
       
   383  */
       
   384 TSize CTsGraphicFileScalingHandler::NewSizeToScalingOperation()
       
   385     {
       
   386     TSize originalSize = iInputBitmap->SizeInPixels();
       
   387     float widthFactor = iNewSize.iWidth / (float)originalSize.iWidth;
       
   388     float heightFactor = iNewSize.iHeight / (float)originalSize.iHeight;
       
   389     TSize retSize(iNewSize);
       
   390 
       
   391     if(CTsGraphicFileScalingHandler::EKeepAspectRatio == iKindOfScaling) 
       
   392        {
       
   393        retSize = (widthFactor < heightFactor) ?
       
   394                  TSize(iNewSize.iWidth, widthFactor * originalSize.iHeight) :
       
   395                  TSize(heightFactor * originalSize.iWidth, iNewSize.iHeight);
       
   396        } 
       
   397     else if (CTsGraphicFileScalingHandler::EKeepAspectRatioByExpanding == iKindOfScaling) 
       
   398        {
       
   399        retSize = (widthFactor < heightFactor) ?
       
   400                  TSize(heightFactor * originalSize.iWidth, iNewSize.iHeight) :
       
   401                  TSize(iNewSize.iWidth, widthFactor * originalSize.iHeight);
       
   402        }
       
   403     return retSize;
       
   404     }
       
   405 // -----------------------------------------------------------------------------
       
   406 /**
       
   407  * Handles a leave occurring in the request completion event handler RunL().
       
   408  */
       
   409 TInt CTsGraphicFileScalingHandler::RunError( TInt aError )
       
   410     {
       
   411     iNotify.ImageReadyCallBack( aError, 0 );
       
   412     return KErrNone;
       
   413     }