camerauis/cameraapp/generic/src/CamBurstThumbnailGridSizer.cpp
branchRCL_3
changeset 24 bac7acad7cb3
parent 0 1ddebce53859
--- /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 <e32base.h>
+#include <e32std.h>
+
+#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 <<static>>
+// -----------------------------------------------------------------------------
+//
+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 <<virtual>>
+// -----------------------------------------------------------------------------
+//
+CScaleTask::~CScaleTask()
+  {
+  delete iSrc;
+  iSrc = NULL;
+  }
+
+// -----------------------------------------------------------------------------
+// CScaleTask constructor <<virtual>>
+// -----------------------------------------------------------------------------
+//
+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<CFbsBitmap&>(*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