uiservicetab/vimpstutils/src/cvimpstimageprocessor.cpp
changeset 15 81eeb8c83ce5
parent 0 5e5d6b214f4f
equal deleted inserted replaced
0:5e5d6b214f4f 15:81eeb8c83ce5
     1 /*
       
     2 * Copyright (c) 2008 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:  Image processor  and scaler
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 #include "cvimpstimageprocessor.h"
       
    20 #include "tvimpstconsts.h"
       
    21 #include <imageconversion.h>
       
    22 #include <bitmaptransforms.h>
       
    23 #include <s32file.h>
       
    24 #include <e32cmn.h>
       
    25 #include "vimpstdebugprint.h"
       
    26 // CONSTANTS
       
    27 const TInt KChatCustomBitmapWidth =  65;
       
    28 const TInt KChatCustomBitmapHeight = 65;
       
    29 const TInt KMaxImageSize = 1800; //2k
       
    30 const TInt KMimeLength = 16;
       
    31 const TInt KScaleSize = 10;
       
    32 
       
    33 //-----------------------------------------------------------------------------
       
    34 // CCAImageLoader::CCAImageLoader
       
    35 // ( Other items commented in header )
       
    36 //-----------------------------------------------------------------------------
       
    37 CVimpstImageProcessor::CVimpstImageProcessor( MCAImageProcessObserver* aObserver )
       
    38 : CActive( CActive::EPriorityLow ),iObserver(aObserver),iScaleSize(KScaleSize)
       
    39 	    {
       
    40 	    CActiveScheduler::Add( this );
       
    41 	    }
       
    42 
       
    43 //-----------------------------------------------------------------------------
       
    44 // CVimpstImageProcessor::CVimpstImageProcessor
       
    45 // ( Other items commented in header )
       
    46 //-----------------------------------------------------------------------------
       
    47 CVimpstImageProcessor::~CVimpstImageProcessor()
       
    48     {
       
    49     iFs.Close();
       
    50 
       
    51     delete iImageDecoder;
       
    52     delete iScaler;
       
    53     delete iImageEncoder;
       
    54     if(!isBitmapReturned)
       
    55         {
       
    56         delete iBitmap;
       
    57         }
       
    58     delete iMimeType;
       
    59     }
       
    60 
       
    61 //-----------------------------------------------------------------------------
       
    62 // CVimpstImageProcessor::NewL
       
    63 // ( Other items commented in header )
       
    64 //-----------------------------------------------------------------------------
       
    65 CVimpstImageProcessor* CVimpstImageProcessor::NewL( MCAImageProcessObserver* aObserver)
       
    66     {
       
    67     CVimpstImageProcessor* self =
       
    68     new ( ELeave ) CVimpstImageProcessor(aObserver);
       
    69     CleanupStack::PushL( self );
       
    70     self->ConstructL();
       
    71     CleanupStack::Pop( self );
       
    72     return self;
       
    73     }
       
    74 
       
    75 //-----------------------------------------------------------------------------
       
    76 // CVimpstImageProcessor::ConstructL
       
    77 // ( Other items commented in header )
       
    78 //-----------------------------------------------------------------------------
       
    79 void CVimpstImageProcessor::ConstructL()
       
    80     {
       
    81     User::LeaveIfError( iFs.Connect() );
       
    82     }
       
    83 
       
    84 
       
    85 //-----------------------------------------------------------------------------
       
    86 // CVimpstImageProcessor::RunL
       
    87 // ( Other items commented in header )
       
    88 //-----------------------------------------------------------------------------
       
    89 void CVimpstImageProcessor::RunL()
       
    90     {
       
    91     TInt status = iStatus.Int();    
       
    92 
       
    93     if(!status)
       
    94         {
       
    95         switch(iProcessingState)
       
    96             {
       
    97             case EConvertImageDatatoBitmap:
       
    98                 {
       
    99                 ConvertImageToBitmapL();
       
   100                 break;
       
   101                 }
       
   102             case EScaleBitmap:
       
   103                 {
       
   104                 ScaleBitmapL();
       
   105                 break;
       
   106                 }
       
   107             case EConentFromScaledBitmap:
       
   108                 {
       
   109                 ContentFromScaledBitmapL();
       
   110                 break;
       
   111                 }
       
   112             case EProcessingComplete: 
       
   113                 {
       
   114                 if( iContent->Length() > KMaxImageSize)
       
   115                     {
       
   116                     delete iScaler;
       
   117                     iScaler = NULL;
       
   118                     delete iImageEncoder;
       
   119                     iImageEncoder = NULL;
       
   120                     delete iContent;
       
   121                     iTargetSize.SetSize( KChatCustomBitmapWidth - iScaleSize, KChatCustomBitmapHeight - iScaleSize );
       
   122                     iScaleSize += KScaleSize;
       
   123                     ScaleBitmapL();
       
   124                     }
       
   125                 else
       
   126                     {
       
   127                     CHAT_DP_FUNC_ENTER("CVimpstImageProcessor::RunL completed ");
       
   128                     CompleteRequestL();
       
   129                     }
       
   130                 break;
       
   131                 }  
       
   132             default:
       
   133                 {
       
   134                 
       
   135                 }
       
   136             }
       
   137 
       
   138         }
       
   139     else
       
   140         {
       
   141         CHAT_DP_FUNC_ENTER("CVimpstImageProcessor::RunL completed ");
       
   142         CompleteRequestL();
       
   143         }
       
   144 
       
   145     }
       
   146 //-----------------------------------------------------------------------------
       
   147 // CVimpstImageProcessor::ConvertImageToBitmapL()
       
   148 // ( Other items commented in header )
       
   149 //-----------------------------------------------------------------------------
       
   150 void CVimpstImageProcessor::ConvertImageToBitmapL()
       
   151     {
       
   152     TSize origSize( iImageDecoder->FrameInfo().iOverallSizeInPixels );
       
   153     ScaleSize( origSize, iTargetSize );
       
   154     TBool fullyScaleable( iImageDecoder->FrameInfo().iFlags & TFrameInfo::EFullyScaleable );
       
   155     TSize decodeSize( DecodeSize( origSize, iTargetSize, fullyScaleable ) );
       
   156 
       
   157     iBitmap = new (ELeave) CFbsBitmap();
       
   158     User::LeaveIfError( iBitmap->Create( decodeSize, 
       
   159             iImageDecoder->FrameInfo().iFrameDisplayMode ) );
       
   160     iImageDecoder->Convert( &iStatus, *iBitmap );
       
   161     iProcessingState = EScaleBitmap;  //  set state to next step
       
   162     if( !IsActive() )
       
   163         {
       
   164         SetActive();
       
   165         }
       
   166     }
       
   167 //-----------------------------------------------------------------------------
       
   168 // CVimpstImageProcessor::ScaleBitmapL()
       
   169 // ( Other items commented in header )
       
   170 //-----------------------------------------------------------------------------
       
   171 void CVimpstImageProcessor::ScaleBitmapL()
       
   172     {
       
   173     TSize currentSize( iBitmap ? iBitmap->SizeInPixels() : iTargetSize );
       
   174 
       
   175     if( currentSize != iTargetSize )
       
   176         {
       
   177         // bitmap exists and the size is wrong,
       
   178         // we have to scale the bitmap
       
   179         iScaler = CBitmapScaler::NewL();
       
   180         iScaler->Scale( &iStatus, *iBitmap, iTargetSize );
       
   181         iProcessingState = EConentFromScaledBitmap; //  set state to next step
       
   182         if( !IsActive() )
       
   183             {
       
   184             SetActive();
       
   185             }
       
   186         }
       
   187     else 
       
   188         { // get content from scaled bitmap
       
   189         ContentFromScaledBitmapL();
       
   190         }
       
   191 
       
   192     }
       
   193 
       
   194 //-----------------------------------------------------------------------------
       
   195 // CVimpstImageProcessor::ContentFromScaledBitmapL()
       
   196 // ( Other items commented in header )
       
   197 //-----------------------------------------------------------------------------
       
   198 void CVimpstImageProcessor::ContentFromScaledBitmapL()
       
   199     {
       
   200     iContent = NULL;
       
   201     iImageEncoder = CImageEncoder::DataNewL( iContent,*iMimeType);
       
   202     iImageEncoder->Convert( &iStatus, *iBitmap );
       
   203     iProcessingState = EProcessingComplete ; //  set state to next step
       
   204     if( !IsActive() )
       
   205         {
       
   206         SetActive();
       
   207         }
       
   208     }
       
   209 
       
   210 
       
   211 //-----------------------------------------------------------------------------
       
   212 // CVimpstImageProcessor::DoCancel
       
   213 // ( Other items commented in header )
       
   214 //-----------------------------------------------------------------------------
       
   215 void CVimpstImageProcessor::DoCancel()
       
   216     {
       
   217     ClearState();        
       
   218     }
       
   219 
       
   220 //-----------------------------------------------------------------------------
       
   221 // CVimpstImageProcessor::RunError
       
   222 // ( Other items commented in header )
       
   223 //-----------------------------------------------------------------------------
       
   224 TInt CVimpstImageProcessor::RunError( TInt aError )
       
   225     {
       
   226     if( IsActive() )
       
   227         {
       
   228         iStatus = aError;
       
   229         Cancel();
       
   230         }
       
   231 
       
   232     if( aError == KErrNoMemory )
       
   233         {
       
   234         CActiveScheduler::Current()->Error( KErrNoMemory );
       
   235         }
       
   236 
       
   237     // Clean up and reset all pending messages
       
   238     ClearState();
       
   239     TRAP_IGNORE( ResetProcessingL( aError ) );
       
   240 
       
   241     return KErrNone;    
       
   242     }
       
   243 //-----------------------------------------------------------------------------
       
   244 // CVimpstImageProcessor::StartProcessingFromDataL
       
   245 // ( Other items commented in header )
       
   246 //-----------------------------------------------------------------------------
       
   247 TInt CVimpstImageProcessor::ProcessFromDataL( const TDesC8& aImageData , const TDesC8& aMimeType)
       
   248     {
       
   249     TInt err = KErrNone;
       
   250     if ( aMimeType.Length())
       
   251         {
       
   252         // if the mimetype is passed then allocate the memory
       
   253         iMimeType = aMimeType.AllocL();
       
   254         }
       
   255     else 
       
   256         {
       
   257         // if no mimetype find the mimetype
       
   258         iMimeType = HBufC8::NewL( KMimeLength);
       
   259         TPtr8 mimePtr = iMimeType->Des();
       
   260         TRAP(err,CImageDecoder::GetMimeTypeDataL( aImageData , mimePtr ));
       
   261         if(KErrNone != err)
       
   262             {
       
   263             return err;
       
   264             }
       
   265         }  
       
   266     iImageDecoder = NULL;
       
   267     // need to check for the mimetype length, as sometimes CImageDecoder::GetMimeTypeDataL
       
   268     // is alos not able to give the mimetype
       
   269     iImageDecoder = CImageDecoder::DataNewL(iFs, aImageData , *iMimeType);
       
   270     iProcessingState = EConvertImageDatatoBitmap;
       
   271     RunL();
       
   272     return err;  
       
   273     }
       
   274 
       
   275 //-----------------------------------------------------------------------------
       
   276 // CVimpstImageProcessor::ProcessFromFileL
       
   277 // ( Other items commented in header )
       
   278 //-----------------------------------------------------------------------------
       
   279 void CVimpstImageProcessor::ProcessFromFileL( const TDesC& aFileName , const TDesC8& aMimeType)
       
   280     {
       
   281     CHAT_DP_FUNC_ENTER("CVimpstImageProcessor::ProcessFromFileL start");
       
   282     iMimeType = aMimeType.AllocL();
       
   283     iImageDecoder = NULL;
       
   284     iImageDecoder = CImageDecoder::FileNewL(iFs, aFileName, *iMimeType );
       
   285     iProcessingState = EConvertImageDatatoBitmap;
       
   286     RunL();
       
   287     CHAT_DP_FUNC_ENTER("CVimpstImageProcessor::ProcessFromFileL end ");
       
   288     }
       
   289 
       
   290 //-----------------------------------------------------------------------------
       
   291 // CVimpstImageProcessor::CancelProcessing
       
   292 // ( Other items commented in header )
       
   293 //-----------------------------------------------------------------------------
       
   294 void CVimpstImageProcessor::CancelProcessing()
       
   295     {
       
   296     if( IsActive() )
       
   297         {
       
   298         Cancel();
       
   299         }        
       
   300     }
       
   301 //-----------------------------------------------------------------------------
       
   302 // CVimpstImageProcessor::RegisterObserver
       
   303 // ( Other items commented in header )
       
   304 //-----------------------------------------------------------------------------
       
   305 void CVimpstImageProcessor::RegisterObserver( MCAImageProcessObserver* aObserver )
       
   306     {
       
   307     iObserver = aObserver;
       
   308     }
       
   309 //-----------------------------------------------------------------------------
       
   310 // CVimpstImageProcessor::GetContentData
       
   311 // ( Other items commented in header )
       
   312 //-----------------------------------------------------------------------------
       
   313 
       
   314 HBufC8* CVimpstImageProcessor::GetContentData()
       
   315     {
       
   316     return iContent;
       
   317     }
       
   318 //-----------------------------------------------------------------------------
       
   319 // CVimpstImageProcessor::Bitmap
       
   320 // ( Other items commented in header )
       
   321 //-----------------------------------------------------------------------------
       
   322 
       
   323 CFbsBitmap& CVimpstImageProcessor::Bitmap()
       
   324     {
       
   325     isBitmapReturned = ETrue;
       
   326     return *iBitmap;
       
   327     }
       
   328 //-----------------------------------------------------------------------------
       
   329 // CVimpstImageProcessor::DecodeSize
       
   330 // Scale to nearest (larger or equal) size with ratio 1:1, 1:2, 1:4 or 1:8
       
   331 //-----------------------------------------------------------------------------    
       
   332 TSize CVimpstImageProcessor::DecodeSize( const TSize& aSize, const TSize& aTargetSize,
       
   333         TBool aAnyRatio )
       
   334     {
       
   335     if( aAnyRatio || aSize == aTargetSize )
       
   336         {
       
   337         // decoder can scale to any ratio or the size is already correct
       
   338         return aTargetSize;
       
   339         }
       
   340 
       
   341     // 1:1 is always valid ratio for decode scaling
       
   342     TInt lastValidRatio( 1 );
       
   343     for( TInt ratio( KDecodeScaleRatioMin ); ratio <= KDecodeScaleRatioMax; ratio <<= 1 )
       
   344         {
       
   345         if( aSize.iWidth % ratio + aSize.iHeight % ratio == 0 )
       
   346             {
       
   347             // this ratio is valid
       
   348             if( aSize.iWidth / ratio < aTargetSize.iWidth || 
       
   349                     aSize.iHeight / ratio < aTargetSize.iHeight )
       
   350                 {
       
   351                 // the decoded size was smaller in some dimension, 
       
   352                 // the last valid ratio should be used
       
   353                 break;
       
   354                 }
       
   355 
       
   356             // this scale ratio results to greater or equal size
       
   357             lastValidRatio = ratio;
       
   358             }
       
   359         }
       
   360 
       
   361     // return the size scaled with correct ratio
       
   362     return TSize( aSize.iWidth / lastValidRatio, 
       
   363             aSize.iHeight / lastValidRatio );
       
   364     }
       
   365 
       
   366 //-----------------------------------------------------------------------------
       
   367 // CVimpstImageProcessor::ScaleSize
       
   368 // ( Other items commented in header )
       
   369 //-----------------------------------------------------------------------------
       
   370 TBool CVimpstImageProcessor::ScaleSize( const TSize& aSize, TSize& aNewSize )
       
   371     {
       
   372     if( Max( aSize.iHeight, aSize.iWidth ) > KChatCustomBitmapWidth )
       
   373         {  
       
   374         aNewSize.SetSize( KChatCustomBitmapWidth, KChatCustomBitmapHeight );
       
   375         return ETrue;
       
   376         }
       
   377 
       
   378     // old size is correct
       
   379     aNewSize = aSize;
       
   380     return EFalse;
       
   381     }
       
   382 
       
   383 //-----------------------------------------------------------------------------
       
   384 // CVimpstImageProcessor::CompleteRequestL
       
   385 // ( Other items commented in header )
       
   386 //-----------------------------------------------------------------------------
       
   387 void CVimpstImageProcessor::CompleteRequestL()
       
   388     {    
       
   389     iObserver->HandleProcessingCompleteL( iStatus.Int() );
       
   390     }
       
   391 
       
   392 
       
   393 //-----------------------------------------------------------------------------
       
   394 // CVimpstImageProcessor::ResetProcessingL
       
   395 // ( Other items commented in header )
       
   396 //-----------------------------------------------------------------------------
       
   397 void CVimpstImageProcessor::ResetProcessingL( TInt aReason )
       
   398     {
       
   399     // cancel operation
       
   400     if( IsActive() )
       
   401         {
       
   402         iStatus = aReason;
       
   403         Cancel();
       
   404         }  
       
   405     }
       
   406 
       
   407 //-----------------------------------------------------------------------------
       
   408 // CVimpstImageProcessor::ClearState
       
   409 // ( Other items commented in header )
       
   410 //-----------------------------------------------------------------------------
       
   411 void CVimpstImageProcessor::ClearState()
       
   412     {
       
   413     if( iScaler )
       
   414         {
       
   415         iScaler->Cancel();
       
   416         delete iScaler;
       
   417         iScaler = NULL;
       
   418         }
       
   419     if( iImageDecoder )
       
   420         {
       
   421         iImageDecoder->Cancel();
       
   422         delete iImageDecoder;
       
   423         iImageDecoder = NULL;
       
   424         }
       
   425     if( iImageEncoder )
       
   426         {
       
   427         iImageEncoder->Cancel();
       
   428         delete iImageEncoder;
       
   429         iImageEncoder = NULL;
       
   430         }
       
   431     if( iBitmap )
       
   432         {
       
   433         delete iBitmap;
       
   434         iBitmap = NULL;
       
   435         }
       
   436     if (iMimeType)
       
   437         {
       
   438         delete iMimeType;
       
   439         iMimeType = NULL;
       
   440         }
       
   441 
       
   442     }
       
   443 
       
   444 
       
   445 // End of file