diff -r 61bc0f252b2b -r bac7acad7cb3 camerauis/cameraapp/generic/src/CamBurstThumbnailGridSizer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/camerauis/cameraapp/generic/src/CamBurstThumbnailGridSizer.cpp Wed Sep 01 12:30:54 2010 +0100 @@ -0,0 +1,332 @@ +/* +* Copyright (c) 2007-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: Class used to for resizing burst mode thumbnails* +*/ + + + +// INCLUDE FILES +#include +#include + +#include "CamBurstThumbnailGridSizer.h" +#include "camlogging.h" + + + + + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// Symbian 2 phase constructor <> +// ----------------------------------------------------------------------------- +// +CScaleTask* +CScaleTask::NewL( const CFbsBitmap& aBitmap, + const TSize& aSize, + TInt32 aInfo ) + { + CScaleTask* self = new (ELeave) CScaleTask( aSize, aInfo ); + CleanupStack::PushL( self ); + self->ConstructL( aBitmap ); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CScaleTask destructor <> +// ----------------------------------------------------------------------------- +// +CScaleTask::~CScaleTask() + { + delete iSrc; + iSrc = NULL; + } + +// ----------------------------------------------------------------------------- +// CScaleTask constructor <> +// ----------------------------------------------------------------------------- +// +CScaleTask::CScaleTask( const TSize& aSize, + TInt32 aInfo ) + : iSize ( aSize ), + iInfo ( aInfo ) + { + } + +// ----------------------------------------------------------------------------- +// CScaleTask::ConstructL +// ----------------------------------------------------------------------------- +// +void +CScaleTask::ConstructL( const CFbsBitmap& aBitmap ) + { + iSrc = new (ELeave) CFbsBitmap; + User::LeaveIfError( iSrc->Duplicate( aBitmap.Handle() ) ); + } + + + +// ----------------------------------------------------------------------------- +// CCamThumbnailGridSizer::CCamThumbnailGridSizer +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CCamThumbnailGridSizer::CCamThumbnailGridSizer( MBitmapScaler* aObserver, TSize& aSize ) + : CActive( EPriorityStandard ), + iThumbSize( aSize ) + { + iObserver = aObserver; + CActiveScheduler::Add(this); + } + +// ----------------------------------------------------------------------------- +// CCamThumbnailGridSizer::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CCamThumbnailGridSizer::ConstructL() + { + iScaler = CBitmapScaler::NewL(); + } + +// ----------------------------------------------------------------------------- +// CCamThumbnailGridSizer::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CCamThumbnailGridSizer* CCamThumbnailGridSizer::NewL( MBitmapScaler* aObserver, TSize& aSize ) + { + CCamThumbnailGridSizer* self = new( ELeave ) CCamThumbnailGridSizer( aObserver, aSize ); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + + return self; + } + + +// ----------------------------------------------------------------------------- +// Destructor +// ----------------------------------------------------------------------------- +// +CCamThumbnailGridSizer::~CCamThumbnailGridSizer() + { + PRINT( _L("Camera => ~CCamThumbnailGridSizer") ); + Cancel(); + delete iScaler; + + // Delete any intermediate temporary bitmap + delete iTmpBitmap; + + // Cancel all pending scaling operations + iScaleTaskArray.ResetAndDestroy(); + PRINT( _L("Camera <= ~CCamThumbnailGridSizer") ); + } + +// ----------------------------------------------------------------------------- +// CCamThumbnailGridSizer::SetSize +// ----------------------------------------------------------------------------- +// +void CCamThumbnailGridSizer::SetSize( const TSize aThumbSize ) + { + PRINT2( _L("Camera == CCamThumbnailGridSizer::SetSize width = %d, height = %d"), aThumbSize.iWidth, aThumbSize.iHeight ); + iThumbSize.iWidth = aThumbSize.iWidth; + iThumbSize.iHeight = aThumbSize.iHeight; + } + +// ----------------------------------------------------------------------------- +// CCamThumbnailGridSizer::StartScaleL +// ----------------------------------------------------------------------------- +// +void CCamThumbnailGridSizer::StartScaleL( const CFbsBitmap& aSrc ) + { + PRINT( _L("Camera == CCamThumbnailGridSizer::StartScaleL") ); + // Forward request on with default destination size + StartScaleL( aSrc, iThumbSize, 0 ); + } + + +// ----------------------------------------------------------------------------- +// CCamThumbnailGridSizer::StartScaleL +// Allows specifying of specific size to go to where required. +// ----------------------------------------------------------------------------- +// +void CCamThumbnailGridSizer::StartScaleL( const CFbsBitmap& aSrc, TSize& aSize, TInt32 aInfo ) + { + PRINT3(_L("Camera => CCamThumbnailGridSizer::StartScaleL size %d x %d info 0x%x"), aSize.iWidth, aSize.iHeight, aInfo ); + + // Add it to the queue of things to scale + CScaleTask* task = CScaleTask::NewL( aSrc, aSize, aInfo ); + CleanupStack::PushL( task ); + User::LeaveIfError( iScaleTaskArray.Append( task ) ); // takes ownership of "task" + CleanupStack::Pop( task ); + + StartScaleL( task ); + PRINT ( _L("Camera <= CCamThumbnailGridSizer::StartScaleL") ); + } + +// ----------------------------------------------------------------------------- +// CCamThumbnailGridSizer::StartScaleL +// Allows specifying of specific sizing task to start +// ----------------------------------------------------------------------------- +// +void CCamThumbnailGridSizer::StartScaleL( CScaleTask* aTask ) + { + PRINT( _L("Camera => CCamThumbnailGridSizer::StartScaleL task") ); + // If scaling not currently underway, start it. + // If scaler is busy, it will be started when current operation completes. + if ( !IsActive() ) + { + // Check that we don't have any temporary images floating around + if ( iTmpBitmap ) + { + delete iTmpBitmap; + iTmpBitmap = NULL; + } + + TSize trgSize( aTask->Size() ); + const TSize& bmpSize( aTask->Bitmap()->SizeInPixels() ); + TRect srcRect( bmpSize ); + + TReal bmpRatio( TReal( bmpSize.iWidth ) / TReal( bmpSize.iHeight ) ); + TReal trgRatio( TReal( trgSize.iWidth ) / TReal( trgSize.iHeight ) ); + + PRINT2( _L("Camera <> CCamThumbnailGridSizer - source size(%d,%d)"), + bmpSize.iWidth, bmpSize.iHeight ); + + PRINT2( _L("Camera <> CCamThumbnailGridSizer - target size(%d,%d)"), + trgSize.iWidth, trgSize.iHeight ); + + if( bmpRatio > trgRatio ) + { + // Thumbnail aspect ratio is wider than the target size. + // Scale initially to a size wider than target and then crop. + trgSize.iWidth = Max( trgSize.iHeight * bmpRatio, 1 ); + } + if( bmpRatio < trgRatio ) + { + // Thumbnail aspect ratio is wider than the target size. + // Scale initially to a size higher than target and then crop. + trgSize.iHeight = Max( trgSize.iWidth * bmpRatio, 1 ); + } + + PRINT2( _L("Camera <> CCamThumbnailGridSizer - intermediate size(%d,%d)"), + trgSize.iWidth, trgSize.iHeight ); + + + // Create a temporary bitmap + iTmpBitmap = new ( ELeave ) CFbsBitmap(); + iTmpBitmap->Create( trgSize, aTask->Bitmap()->DisplayMode() ); + + + // Start the scaling operation + iScaler->Scale( &iStatus, + const_cast(*aTask->Bitmap()), + *iTmpBitmap, + ETrue ); + SetActive(); + } + PRINT( _L("Camera <= CCamThumbnailGridSizer::StartScaleL task") ); + } + +// ----------------------------------------------------------------------------- +// CCamThumbnailGridSizer::DoCancel +// ----------------------------------------------------------------------------- +// +void CCamThumbnailGridSizer::DoCancel() + { + PRINT( _L("Camera => CCamThumbnailGridSizer::DoCancel") ); + iScaler->Cancel(); + + // Delete any intermediate temporary bitmap + if ( iTmpBitmap ) + { + delete iTmpBitmap; + iTmpBitmap = NULL; + } + + // Cancel all pending scaling operations + iScaleTaskArray.ResetAndDestroy(); + PRINT( _L("Camera <= CCamThumbnailGridSizer::DoCancel") ); + } + +// ----------------------------------------------------------------------------- +// CCamThumbnailGridSizer::RunL +// ----------------------------------------------------------------------------- +// +void CCamThumbnailGridSizer::RunL() + { + PRINT2( _L("Camera => CCamThumbnailGridSizer::RunL .. observer 0x%x err %d"), iObserver, iStatus.Int() ); + // If there is an observer, notify them of the scaling completion + if ( iObserver ) + { + PRINT1( _L("Camera <> CCamThumbnailGridSizer::RunL .. scale array count %d"), iScaleTaskArray.Count() ); + // Note; passing iTmpBitmap in this call is passing ownership of the + // bitmap to the observer. This also places the restriction that there + // can only be one observer to an implementation of the GridSizer, which + // is fine for our requirements + iObserver->BitmapScaleCompleteL( iStatus.Int(), iTmpBitmap, iScaleTaskArray[0]->Info() ); + iTmpBitmap = NULL; + } + + CScaleTask* task = NULL; + if ( iScaleTaskArray.Count() > 0 ) + { + // Remove from the array and delete this (completed) task + task = iScaleTaskArray[0]; + iScaleTaskArray.Remove(0); + delete task; + task = NULL; + } + + // If completed successfully... + // ... and there are more tasks on the queue... + // ... and the task is valid, then do next task + if ( iStatus.Int() == KErrNone && + iScaleTaskArray.Count() > 0 ) + { + task = iScaleTaskArray[0]; + if ( task ) + { + StartScaleL( task ); + } + } + PRINT ( _L("Camera <= CCamThumbnailGridSizer::RunL") ); + } + + +// End of File