phonebookui/Phonebook2/ccapplication/ccapp/ccapputil/src/ccappimagedecoding.cpp
branchRCL_3
changeset 3 04ab22b956c2
child 15 e8e3147d53eb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/ccapplication/ccapp/ccapputil/src/ccappimagedecoding.cpp	Fri Feb 19 22:40:27 2010 +0200
@@ -0,0 +1,268 @@
+/*
+* Copyright (c) 2008-2008 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:  Implementation of the utility class for asynchronously decoding the header thumbnail image
+*
+*/
+
+#include "ccappimagedecoding.h"
+#include <bitmaptransforms.h>
+#include <Pbk2PresentationUtils.h>
+#include <imageconversion.h>
+
+namespace{
+
+const TInt KDelay = 500000; // 0.5s
+
+inline TSize ScaledLoadSize( const TSize& aOriginalSize, TInt aScaleFactor )
+    {
+    // Divide original size with scalefactor
+    // Round always up if result is not integer
+    return TSize( aOriginalSize.iWidth / aScaleFactor + ( aOriginalSize.iWidth % aScaleFactor ? 1 : 0 ),
+               aOriginalSize.iHeight / aScaleFactor + ( aOriginalSize.iHeight % aScaleFactor ? 1 : 0 ) );
+    }
+} // namespace
+
+// ---------------------------------------------------------------------------
+// Two-phase construction
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CCCAppImageDecoding* CCCAppImageDecoding::NewL(
+        MCCAppImageDecodingObserver& aObserver,
+        RFs& aFs,
+        HBufC8* aBitmapData, 
+        HBufC* aImageFile)
+    {
+    CCCAppImageDecoding* self = new (ELeave) CCCAppImageDecoding(
+            aObserver, aFs, aBitmapData, aImageFile);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);    
+    
+    self->iBitmapData = aBitmapData;   // take ownship
+    self->iImageFullName = aImageFile;  // take ownship
+
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// First phase (C++) constructor
+// ---------------------------------------------------------------------------
+//
+inline CCCAppImageDecoding::CCCAppImageDecoding(
+        MCCAppImageDecodingObserver& aObserver,
+        RFs& aFs,
+        HBufC8* aBitmapData, 
+        HBufC* aImageFile) : 
+CActive( CActive::EPriorityStandard ), 
+iObserver(aObserver), 
+iFs(aFs)
+    { 
+    CActiveScheduler::Add(this); 
+    }
+
+// ---------------------------------------------------------------------------
+// Second phase (C++) constructor
+// ---------------------------------------------------------------------------
+//
+inline void CCCAppImageDecoding::ConstructL()
+    {
+    User::LeaveIfError( iTimer.CreateLocal() );
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CCCAppImageDecoding::~CCCAppImageDecoding()
+    {
+    Cancel();
+    if (iImgDecoder)
+        {
+        iImgDecoder->Cancel();
+        delete iImgDecoder;
+        }
+    if (iBitmapScaler)
+        {
+        iBitmapScaler->Cancel();
+        delete iBitmapScaler;
+        }
+    delete iBitmap;
+    delete iBitmapData;
+    delete iImageFullName;
+    iTimer.Close();
+    }
+
+// ---------------------------------------------------------------------------
+// Starts the decoding process
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CCCAppImageDecoding::StartL( const TSize& aImageSize )
+    {
+    Cancel();
+    iDecoderState = ECcaConvertThumbnailImage;
+    iBitmapSize = aImageSize;
+    CreateBitmapL();
+    }
+
+// ---------------------------------------------------------------------------
+// Called by the active object framework when the decoding (request) is
+// completed.
+// ---------------------------------------------------------------------------
+//
+void CCCAppImageDecoding::RunL() 
+    {
+    User::LeaveIfError( iStatus.Int() );
+    switch ( iDecoderState )
+	    {
+	    case ECcaConvertThumbnailImage:
+	    	{
+	        iDecoderState = ECcaScaleThumbnail;
+	        CropBitmapL();
+	        ScaleBitmapL();
+	        break;
+	    	}
+	
+	    case ECcaScaleThumbnail:
+	    	{
+	    	if ( iImageFullName )
+	    		{
+	            iDecoderState = ECcaReadImageFromFile;
+	            SetPriority( EPriorityIdle );
+	            iTimer.After( iStatus, KDelay ); 
+	            SetActive();
+	    		}
+	    	// don't break here
+	    	}
+	    	
+	    case ECcaScaleImage:
+	    	{
+	        // Ownership of the bitmap is transferred
+	        iObserver.BitmapReadyL( iBitmap );
+	        iBitmap = NULL;
+	        delete iBitmapScaler;
+	        iBitmapScaler = NULL;
+	        delete iImgDecoder;
+	        iImgDecoder = NULL;
+	        break;
+	    	}
+	        
+	    case ECcaReadImageFromFile:
+	    	{
+	    	if ( iImageFullName )
+	    		{
+	            iDecoderState = ECcaConvertImageFromFile;
+	            CreateBitmapL();
+	    		}
+	    	break;
+	    	}
+	         
+	    case ECcaConvertImageFromFile:
+	    	{
+	        iDecoderState = ECcaScaleImage;
+	        SetPriority( EPriorityStandard );
+            CropBitmapL();
+	        ScaleBitmapL();
+	        break;
+	    	}
+	        
+	    default:
+	        break;
+	    }
+    }
+// ---------------------------------------------------------------------------
+// Called when the decoding (request) is cancelled for some reason.
+// ---------------------------------------------------------------------------
+//
+void CCCAppImageDecoding::DoCancel()
+    { 
+    if (iImgDecoder)
+        {
+        iImgDecoder->Cancel();
+        delete iImgDecoder;
+        iImgDecoder = NULL;
+        }
+    if ( iBitmapScaler )
+        {
+        iBitmapScaler->Cancel();
+        delete iBitmapScaler;
+        iBitmapScaler = NULL;
+        }
+    iTimer.Cancel();
+    }
+
+void CCCAppImageDecoding::CropBitmapL()
+    {
+    TSize dummy;
+    Pbk2PresentationImageUtils::CropImageL(
+            *iBitmap, 
+            Pbk2PresentationImageUtils::ELandscapeCropping, 
+            dummy );
+    }
+
+void CCCAppImageDecoding::ScaleBitmapL()
+    {   
+    iBitmapScaler = CBitmapScaler::NewL();
+    iBitmapScaler->Scale( &iStatus, *iBitmap, iBitmapSize );
+    SetActive();
+    }
+
+void CCCAppImageDecoding::CreateBitmapL()
+    {
+    TInt initDecoder( KErrGeneral );
+    if ( iDecoderState == ECcaConvertThumbnailImage && iBitmapData )
+        {
+        iImgDecoder = CImageDecoder::DataNewL( iFs, *iBitmapData, CImageDecoder::EOptionAlwaysThread );
+        initDecoder = KErrNone;
+        }
+    else if ( iDecoderState == ECcaConvertImageFromFile && iImageFullName )
+        {
+        // leaaves if file doesn't exist
+        TRAP ( initDecoder, iImgDecoder = CImageDecoder::FileNewL( iFs, *iImageFullName, CImageDecoder::EOptionAlwaysThread ) );
+        }
+    if ( initDecoder )
+        {
+        delete iBitmapScaler;
+        iBitmapScaler = NULL;
+        delete iImgDecoder;
+        iImgDecoder = NULL;
+        return;
+        }
+    
+   if ( !iBitmap )
+       {
+       const TFrameInfo info = iImgDecoder->FrameInfo();
+	   // calculate size for the bitmap
+       const TSize size( iBitmapSize );
+       TSize loadSize( info.iOverallSizeInPixels );
+       
+       for( TInt i = 1 ; i < 9 ; i = i * 2 )
+           {
+		   // we can use scalers 1:1 1:2 1:4 1:8
+           TSize calcSize( ScaledLoadSize( info.iOverallSizeInPixels, i ) );
+           if( calcSize.iHeight < size.iHeight ||
+               calcSize.iWidth < size.iWidth )
+               {
+               break;
+               }
+           loadSize = calcSize;
+           }
+       
+       iBitmap = new ( ELeave ) CFbsBitmap;
+       User::LeaveIfError( iBitmap->Create( loadSize, info.iFrameDisplayMode ));
+       }
+ 
+    iStatus = KRequestPending;
+    iImgDecoder->Convert( &iStatus, *iBitmap );
+    SetActive();
+    }