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