diff -r 8ee96d21d9bf -r 7e0eff37aedb gssettingsuis/Gs/GSBackgroundImage/Src/GsAsyncImageHandling.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gssettingsuis/Gs/GSBackgroundImage/Src/GsAsyncImageHandling.cpp Wed Sep 01 12:20:44 2010 +0100 @@ -0,0 +1,445 @@ +/* +* Copyright (c) 2005-2007 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: +* +*/ + + +// INCLUDE FILES +#include "gsasyncimagehandling.h" +#include +#include +#include +#include +#include + +#include "mgsasyncimagehandlingobserver.h" +#include "GsLogger.h" + +#include +#include +#include + +//_LIT( KGSWelcomeNoteImgPath, "c:\\private\\100058ec\\welcomeimage.mbm"); + +const TInt KGSVTStillImageWidth = 176; +const TInt KGSVTStillImageHeight = 144; + + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------------------------- +// CGSAsyncImageHandling::CGSAsyncImageHandling +// C++ constructor. +// +// --------------------------------------------------------------------------- +// +CGSAsyncImageHandling::CGSAsyncImageHandling( RFs& aFs, + MGSAsyncImageHandlingObserver* aObserver, + const TDesC& aDestinationPath ) + : CActive( EPriorityNormal ), + iObserver( aObserver ), + iFs( aFs ), + iDestinationPath( aDestinationPath ) + + { + CActiveScheduler::Add( this ); + } + + +// --------------------------------------------------------------------------- +// CGSAsyncImageHandling::NewL() +// C++ constructor. +// +// --------------------------------------------------------------------------- +// +EXPORT_C CGSAsyncImageHandling* CGSAsyncImageHandling::NewL( RFs& aFs, + MGSAsyncImageHandlingObserver* aObserver, + const TDesC& aDestinationPath ) + { + CGSAsyncImageHandling* self = + new( ELeave ) CGSAsyncImageHandling( aFs, aObserver, + aDestinationPath ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + + return self; + } + + +// ----------------------------------------------------------------------------- +// CGSAsyncImageHandling::ConstructL +// Symbian 2nd phase constructor can leave. +// +// ----------------------------------------------------------------------------- +// +void CGSAsyncImageHandling::ConstructL() + { + iStartupRepository = CRepository::NewL( KCRUidStartupConf ); + iBitmapScaler = CBitmapScaler::NewL(); + } + + +// --------------------------------------------------------------------------- +// CGSAsyncImageHandling::~CGSAsyncImageHandling +// destructor. +// +// --------------------------------------------------------------------------- +// +CGSAsyncImageHandling::~CGSAsyncImageHandling() + { + Cancel(); + + if ( iStartupRepository ) + { + delete iStartupRepository; + } + + if( iDecoder ) + { + delete iDecoder; + } + + if ( iBitmapScaler ) + { + delete iBitmapScaler; + } + + if ( iBitmap ) + { + delete iBitmap; + } + } + +// --------------------------------------------------------------------------- +// CGSAsyncImageHandling::ProcessImageL +// +// Processing the image asynchronously +// --------------------------------------------------------------------------- +// +void CGSAsyncImageHandling::ProcessImageL( const TDesC& aFileName, + TInt aScreenWidth, + TInt aScreenHeight, + TGSBgImageType aBgImageType ) + { +__GSLOGSTRING1( "[CGSAsyncImageHandling] process image %S", &aFileName ); + + TInt frameNumber = 0; //for JPEG & bmp images + iBgImageType = aBgImageType; + + // make sure there is no memory leaks because of iBitmap and iDimmedBmp + if (iBitmap) + { + delete iBitmap; + iBitmap = NULL; + } + iBitmap = new(ELeave) CFbsBitmap; + + // Loading image from file into CFbsBitmap + CImageDecoder::GetMimeTypeFileL( iFs, aFileName, iMimeString ); + iDecoder = CImageDecoder::FileNewL( iFs, aFileName, + CImageDecoder::EOptionNone ); + + TFrameInfo frameInfo = iDecoder->FrameInfo(); + TSize imgSize = frameInfo.iOverallSizeInPixels; + + + TDisplayMode displayMode = GetDisplayMode( frameInfo ); + + TSize screenSize( aScreenWidth, aScreenHeight ); + TSize loadSize( CalculateLoadSize( frameInfo, screenSize ) ); + iScaleSize = loadSize; + + iBitmap->Reset(); + User::LeaveIfError( iBitmap->Create( imgSize, displayMode ) ); + iDecoder->Convert( &iStatus, *iBitmap, frameNumber ); + + if ( aBgImageType == EGSWelcomeNoteImage ) + { + iState = EGSWelcomeConversion; + } + else if ( aBgImageType == EGSVtStillImage ) + { + iState = EGSVTConversion; + } + + SetActive(); + } + +// --------------------------------------------------------------------------- +// CGSAsyncImageHandling::GetDisplayMode +// +// Dithers the image to attain the required dithering according to the display +// mode settings +// --------------------------------------------------------------------------- +// +TDisplayMode CGSAsyncImageHandling::GetDisplayMode( const TFrameInfo& aFrameInfo ) + { + if( aFrameInfo.iFlags & TFrameInfo::ECanDither ) + { + if( aFrameInfo.iFrameDisplayMode < EColor64K ) + { + return aFrameInfo.iFrameDisplayMode; + } + else + { + return EColor64K; + } + } + else + { + return aFrameInfo.iFrameDisplayMode; + } + } + + +// ----------------------------------------------------------------------------- +// CGSAsyncImageHandling::RunL +// +// +// --------------------------------------------------------------------------- +// +void CGSAsyncImageHandling::RunL() + { + if( iStatus.Int() == KErrNone ) + { + switch( iState ) + { + case EGSWelcomeConversion: + iBitmapScaler->Scale(&iStatus, *iBitmap, iScaleSize, ETrue ); + iState = EGSWelcomeScaling; + SetActive(); + break; + + case EGSWelcomeScaling: + { + TInt err = iBitmap->Save( iDestinationPath ); + iStartupRepository->Set( KStartupWelcomeNoteImage, + iDestinationPath ); + + //raising completion event + iObserver->ImageHandlingCompleteL( iStatus.Int() ); + Cancel(); + } + break; + + case EGSVTConversion: + iBitmapScaler->Scale(&iStatus, *iBitmap, iScaleSize, ETrue ); + iState = EGSVTScaling; + SetActive(); + break; + + case EGSVTScaling: + SaveVTStillImageL(); + iObserver->ImageHandlingCompleteL( iStatus.Int() ); + Cancel(); + break; + + default: + break; + } + } + else + { + iObserver->ImageHandlingCompleteL( iStatus.Int() ); + Cancel(); + } + } + +// ----------------------------------------------------------------------------- +// CGSAsyncImageHandling::DoCancel +// +// +// --------------------------------------------------------------------------- +// +void CGSAsyncImageHandling::DoCancel() + { + if ( iDecoder ) + { + iDecoder->Cancel(); + } + + if ( iBitmapScaler ) + { + iBitmapScaler->Cancel(); + } + + delete iDecoder; + iDecoder = NULL; + } + +// ----------------------------------------------------------------------------- +// CGSAsyncImageHandling::RunError +// +// +// --------------------------------------------------------------------------- +// +TInt CGSAsyncImageHandling::RunError( TInt aError ) + { + TRAP_IGNORE( iObserver->ImageHandlingCompleteL( aError ) ); + DoCancel(); + return aError; + } + +// ---------------------------------------------------------------------------- +// TSize CGSAsyncImageHandling::CalculateLoadSize +// +// Calculates the load size +// ---------------------------------------------------------------------------- +// +TSize CGSAsyncImageHandling::CalculateLoadSize( TFrameInfo& aFrameInfo, + const TSize aScreenSize ) + { + TReal perfectAspect = ( TReal )( + ( TReal )aScreenSize.iWidth/ + ( TReal )aScreenSize.iHeight ); + TReal aspect = ( TReal )( + ( TReal )aFrameInfo.iFrameCoordsInPixels.Width()/ + ( TReal )aFrameInfo.iFrameCoordsInPixels.Height() ); + TSize size( aScreenSize.iWidth, aScreenSize.iHeight ); + TSize cropsize( aScreenSize.iWidth, aScreenSize.iHeight ); + + TAknWindowLineLayout layout = AknLayout::wallpaper_pane(); + if( aFrameInfo.iFrameCoordsInPixels.Width() > aScreenSize.iWidth || + aFrameInfo.iFrameCoordsInPixels.Height() > aScreenSize.iHeight ) + { + //calculating dynamically range for image aspect ratio close to screen + TReal maxAspect = ((TReal)aScreenSize.iWidth/(TReal)aScreenSize.iHeight) + 0.12; + TReal minAspect = ((TReal)aScreenSize.iWidth/(TReal)aScreenSize.iHeight) - 0.12; + + if (aspect >= minAspect && aspect <= maxAspect ) + { + if( aspect < perfectAspect ) + { + size.iWidth = aScreenSize.iWidth; + size.iHeight = (TInt)((TReal)aScreenSize.iWidth/ + (TReal)aFrameInfo.iFrameCoordsInPixels.Width()* + (TReal)aFrameInfo.iFrameCoordsInPixels.Height()); + } + else + { + size.iWidth = (TInt)((TReal)aScreenSize.iHeight/ + (TReal)aFrameInfo.iFrameCoordsInPixels.Height()* + (TReal)aFrameInfo.iFrameCoordsInPixels.Width()); + size.iHeight = aScreenSize.iHeight; + } + if (size.iWidth > aScreenSize.iWidth) + { + cropsize.iWidth = aScreenSize.iWidth; + } + else + { + cropsize.iWidth = size.iWidth; + } + if (size.iHeight > aScreenSize.iHeight) + { + cropsize.iHeight = aScreenSize.iHeight; + } + else + { + cropsize.iHeight = size.iHeight; + } + } + else + { + // Scale and maintain aspect ratio + if( aspect < perfectAspect ) + { + if (aFrameInfo.iFrameCoordsInPixels.Height() > aScreenSize.iHeight) + { + size.iWidth = (TInt)((TReal)aScreenSize.iHeight/ + (TReal)aFrameInfo.iFrameCoordsInPixels.Height()* + (TReal)aFrameInfo.iFrameCoordsInPixels.Width()); + size.iHeight = aScreenSize.iHeight; + } + } + else + { + if (aFrameInfo.iFrameCoordsInPixels.Width() > aScreenSize.iWidth) + { + size.iWidth = aScreenSize.iWidth; + size.iHeight = (TInt)((TReal)aScreenSize.iWidth/ + (TReal)aFrameInfo.iFrameCoordsInPixels.Width()* + (TReal)aFrameInfo.iFrameCoordsInPixels.Height()); + } + } + } + } + + return size; + } + +// ----------------------------------------------------------------------------- +// CGSAsyncImageHandling::SaveVTStillImageL +// +// +// --------------------------------------------------------------------------- +// +void CGSAsyncImageHandling::SaveVTStillImageL() + { + //creating new and merging + const TSize KStillImageSize( KGSVTStillImageWidth, KGSVTStillImageHeight ); + + CFbsBitmap* newBitmap = new ( ELeave ) CFbsBitmap; + CleanupStack::PushL( newBitmap ); + + User::LeaveIfError( + newBitmap->Create( KStillImageSize, iBitmap->DisplayMode() ) ); + + CFbsBitmapDevice* device = CFbsBitmapDevice::NewL( newBitmap ); + CleanupStack::PushL( device ); + + CFbsBitGc* context = NULL; + User::LeaveIfError( device->CreateContext( context ) ); + User::LeaveIfNull( context ); + + context->SetPenStyle( CGraphicsContext::ENullPen ); + context->SetBrushColor( TRgb( 0, 0, 0 ) ); // black color + context->SetBrushStyle( CGraphicsContext::ESolidBrush ); + context->Clear(); + + const TSize scaledImageSize( iBitmap->SizeInPixels() ); + + TInt xPos = ( KStillImageSize.iWidth - scaledImageSize.iWidth ) / 2; + TInt yPos = ( KStillImageSize.iHeight - scaledImageSize.iHeight ) / 2; + + context->BitBlt( TPoint( xPos, yPos ), iBitmap ); + + delete context; + CleanupStack::PopAndDestroy( device ); + + //saving bitmap + CPhCltImageHandler* phCltImageHandler = CPhCltImageHandler::NewL(); + CleanupStack::PushL( phCltImageHandler ); + + // Acquires ownership of *imageParams + // Bad naming for create-function CPhCltBaseImageParamsL(). + CPhCltImageParams* imageParams = phCltImageHandler-> + CPhCltBaseImageParamsL( EPhCltTypeVTStill ); + CleanupStack::PushL( imageParams ); + TInt ret = newBitmap->Handle(); + imageParams->AddImageL( ret ); + phCltImageHandler->SaveImages( *imageParams ); + CleanupStack::PopAndDestroy( imageParams ); + CleanupStack::PopAndDestroy( phCltImageHandler ); + + delete iBitmap; + iBitmap = NULL; + + CleanupStack::PopAndDestroy( newBitmap ); + } + + +// End of File