phonebookui/Phonebook2/ccapplication/ccapp/ccapputil/src/ccappimagedecoding.cpp
branchRCL_3
changeset 3 04ab22b956c2
child 6 e8e3147d53eb
equal deleted inserted replaced
0:e686773b3f54 3:04ab22b956c2
       
     1 /*
       
     2 * Copyright (c) 2008-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:  Implementation of the utility class for asynchronously decoding the header thumbnail image
       
    15 *
       
    16 */
       
    17 
       
    18 #include "ccappimagedecoding.h"
       
    19 #include <bitmaptransforms.h>
       
    20 #include <Pbk2PresentationUtils.h>
       
    21 #include <imageconversion.h>
       
    22 
       
    23 namespace{
       
    24 
       
    25 const TInt KDelay = 500000; // 0.5s
       
    26 
       
    27 inline TSize ScaledLoadSize( const TSize& aOriginalSize, TInt aScaleFactor )
       
    28     {
       
    29     // Divide original size with scalefactor
       
    30     // Round always up if result is not integer
       
    31     return TSize( aOriginalSize.iWidth / aScaleFactor + ( aOriginalSize.iWidth % aScaleFactor ? 1 : 0 ),
       
    32                aOriginalSize.iHeight / aScaleFactor + ( aOriginalSize.iHeight % aScaleFactor ? 1 : 0 ) );
       
    33     }
       
    34 } // namespace
       
    35 
       
    36 // ---------------------------------------------------------------------------
       
    37 // Two-phase construction
       
    38 // ---------------------------------------------------------------------------
       
    39 //
       
    40 EXPORT_C CCCAppImageDecoding* CCCAppImageDecoding::NewL(
       
    41         MCCAppImageDecodingObserver& aObserver,
       
    42         RFs& aFs,
       
    43         HBufC8* aBitmapData, 
       
    44         HBufC* aImageFile)
       
    45     {
       
    46     CCCAppImageDecoding* self = new (ELeave) CCCAppImageDecoding(
       
    47             aObserver, aFs, aBitmapData, aImageFile);
       
    48     CleanupStack::PushL(self);
       
    49     self->ConstructL();
       
    50     CleanupStack::Pop(self);    
       
    51     
       
    52     self->iBitmapData = aBitmapData;   // take ownship
       
    53     self->iImageFullName = aImageFile;  // take ownship
       
    54 
       
    55     return self;
       
    56     }
       
    57 
       
    58 // ---------------------------------------------------------------------------
       
    59 // First phase (C++) constructor
       
    60 // ---------------------------------------------------------------------------
       
    61 //
       
    62 inline CCCAppImageDecoding::CCCAppImageDecoding(
       
    63         MCCAppImageDecodingObserver& aObserver,
       
    64         RFs& aFs,
       
    65         HBufC8* aBitmapData, 
       
    66         HBufC* aImageFile) : 
       
    67 CActive( CActive::EPriorityStandard ), 
       
    68 iObserver(aObserver), 
       
    69 iFs(aFs)
       
    70     { 
       
    71     CActiveScheduler::Add(this); 
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 // Second phase (C++) constructor
       
    76 // ---------------------------------------------------------------------------
       
    77 //
       
    78 inline void CCCAppImageDecoding::ConstructL()
       
    79     {
       
    80     User::LeaveIfError( iTimer.CreateLocal() );
       
    81     }
       
    82 
       
    83 // ---------------------------------------------------------------------------
       
    84 // Destructor
       
    85 // ---------------------------------------------------------------------------
       
    86 //
       
    87 CCCAppImageDecoding::~CCCAppImageDecoding()
       
    88     {
       
    89     Cancel();
       
    90     if (iImgDecoder)
       
    91         {
       
    92         iImgDecoder->Cancel();
       
    93         delete iImgDecoder;
       
    94         }
       
    95     if (iBitmapScaler)
       
    96         {
       
    97         iBitmapScaler->Cancel();
       
    98         delete iBitmapScaler;
       
    99         }
       
   100     delete iBitmap;
       
   101     delete iBitmapData;
       
   102     delete iImageFullName;
       
   103     iTimer.Close();
       
   104     }
       
   105 
       
   106 // ---------------------------------------------------------------------------
       
   107 // Starts the decoding process
       
   108 // ---------------------------------------------------------------------------
       
   109 //
       
   110 EXPORT_C void CCCAppImageDecoding::StartL( const TSize& aImageSize )
       
   111     {
       
   112     Cancel();
       
   113     iDecoderState = ECcaConvertThumbnailImage;
       
   114     iBitmapSize = aImageSize;
       
   115     CreateBitmapL();
       
   116     }
       
   117 
       
   118 // ---------------------------------------------------------------------------
       
   119 // Called by the active object framework when the decoding (request) is
       
   120 // completed.
       
   121 // ---------------------------------------------------------------------------
       
   122 //
       
   123 void CCCAppImageDecoding::RunL() 
       
   124     {
       
   125     User::LeaveIfError( iStatus.Int() );
       
   126     switch ( iDecoderState )
       
   127 	    {
       
   128 	    case ECcaConvertThumbnailImage:
       
   129 	    	{
       
   130 	        iDecoderState = ECcaScaleThumbnail;
       
   131 	        CropBitmapL();
       
   132 	        ScaleBitmapL();
       
   133 	        break;
       
   134 	    	}
       
   135 	
       
   136 	    case ECcaScaleThumbnail:
       
   137 	    	{
       
   138 	    	if ( iImageFullName )
       
   139 	    		{
       
   140 	            iDecoderState = ECcaReadImageFromFile;
       
   141 	            SetPriority( EPriorityIdle );
       
   142 	            iTimer.After( iStatus, KDelay ); 
       
   143 	            SetActive();
       
   144 	    		}
       
   145 	    	// don't break here
       
   146 	    	}
       
   147 	    	
       
   148 	    case ECcaScaleImage:
       
   149 	    	{
       
   150 	        // Ownership of the bitmap is transferred
       
   151 	        iObserver.BitmapReadyL( iBitmap );
       
   152 	        iBitmap = NULL;
       
   153 	        delete iBitmapScaler;
       
   154 	        iBitmapScaler = NULL;
       
   155 	        delete iImgDecoder;
       
   156 	        iImgDecoder = NULL;
       
   157 	        break;
       
   158 	    	}
       
   159 	        
       
   160 	    case ECcaReadImageFromFile:
       
   161 	    	{
       
   162 	    	if ( iImageFullName )
       
   163 	    		{
       
   164 	            iDecoderState = ECcaConvertImageFromFile;
       
   165 	            CreateBitmapL();
       
   166 	    		}
       
   167 	    	break;
       
   168 	    	}
       
   169 	         
       
   170 	    case ECcaConvertImageFromFile:
       
   171 	    	{
       
   172 	        iDecoderState = ECcaScaleImage;
       
   173 	        SetPriority( EPriorityStandard );
       
   174             CropBitmapL();
       
   175 	        ScaleBitmapL();
       
   176 	        break;
       
   177 	    	}
       
   178 	        
       
   179 	    default:
       
   180 	        break;
       
   181 	    }
       
   182     }
       
   183 // ---------------------------------------------------------------------------
       
   184 // Called when the decoding (request) is cancelled for some reason.
       
   185 // ---------------------------------------------------------------------------
       
   186 //
       
   187 void CCCAppImageDecoding::DoCancel()
       
   188     { 
       
   189     if (iImgDecoder)
       
   190         {
       
   191         iImgDecoder->Cancel();
       
   192         delete iImgDecoder;
       
   193         iImgDecoder = NULL;
       
   194         }
       
   195     if ( iBitmapScaler )
       
   196         {
       
   197         iBitmapScaler->Cancel();
       
   198         delete iBitmapScaler;
       
   199         iBitmapScaler = NULL;
       
   200         }
       
   201     iTimer.Cancel();
       
   202     }
       
   203 
       
   204 void CCCAppImageDecoding::CropBitmapL()
       
   205     {
       
   206     TSize dummy;
       
   207     Pbk2PresentationImageUtils::CropImageL(
       
   208             *iBitmap, 
       
   209             Pbk2PresentationImageUtils::ELandscapeCropping, 
       
   210             dummy );
       
   211     }
       
   212 
       
   213 void CCCAppImageDecoding::ScaleBitmapL()
       
   214     {   
       
   215     iBitmapScaler = CBitmapScaler::NewL();
       
   216     iBitmapScaler->Scale( &iStatus, *iBitmap, iBitmapSize );
       
   217     SetActive();
       
   218     }
       
   219 
       
   220 void CCCAppImageDecoding::CreateBitmapL()
       
   221     {
       
   222     TInt initDecoder( KErrGeneral );
       
   223     if ( iDecoderState == ECcaConvertThumbnailImage && iBitmapData )
       
   224         {
       
   225         iImgDecoder = CImageDecoder::DataNewL( iFs, *iBitmapData, CImageDecoder::EOptionAlwaysThread );
       
   226         initDecoder = KErrNone;
       
   227         }
       
   228     else if ( iDecoderState == ECcaConvertImageFromFile && iImageFullName )
       
   229         {
       
   230         // leaaves if file doesn't exist
       
   231         TRAP ( initDecoder, iImgDecoder = CImageDecoder::FileNewL( iFs, *iImageFullName, CImageDecoder::EOptionAlwaysThread ) );
       
   232         }
       
   233     if ( initDecoder )
       
   234         {
       
   235         delete iBitmapScaler;
       
   236         iBitmapScaler = NULL;
       
   237         delete iImgDecoder;
       
   238         iImgDecoder = NULL;
       
   239         return;
       
   240         }
       
   241     
       
   242    if ( !iBitmap )
       
   243        {
       
   244        const TFrameInfo info = iImgDecoder->FrameInfo();
       
   245 	   // calculate size for the bitmap
       
   246        const TSize size( iBitmapSize );
       
   247        TSize loadSize( info.iOverallSizeInPixels );
       
   248        
       
   249        for( TInt i = 1 ; i < 9 ; i = i * 2 )
       
   250            {
       
   251 		   // we can use scalers 1:1 1:2 1:4 1:8
       
   252            TSize calcSize( ScaledLoadSize( info.iOverallSizeInPixels, i ) );
       
   253            if( calcSize.iHeight < size.iHeight ||
       
   254                calcSize.iWidth < size.iWidth )
       
   255                {
       
   256                break;
       
   257                }
       
   258            loadSize = calcSize;
       
   259            }
       
   260        
       
   261        iBitmap = new ( ELeave ) CFbsBitmap;
       
   262        User::LeaveIfError( iBitmap->Create( loadSize, info.iFrameDisplayMode ));
       
   263        }
       
   264  
       
   265     iStatus = KRequestPending;
       
   266     iImgDecoder->Convert( &iStatus, *iBitmap );
       
   267     SetActive();
       
   268     }