diff -r 000000000000 -r 2014ca87e772 imagehandlinglib/Src/CIHLImageViewerExtJpg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imagehandlinglib/Src/CIHLImageViewerExtJpg.cpp Tue Jan 26 15:18:05 2010 +0200 @@ -0,0 +1,1037 @@ +/* +* Copyright (c) 2006-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: Implementation of Image Viewer class. +* +*/ + + +// INCLUDE FILES +#include "CIHLImageViewerExtJpg.h" + +#include "CIHLBitmap.h" +#include "CIHLBitmapProcessor.h" +#include "IHLImplementationIds.h" +#include +#include +#include +#include +#include "MIHLFileImageExtJpg.h" +#include + +// Private namespace for constants and functions +namespace + { + // Panic function + _LIT( KIHLImageViewerExtJpgPanic, "IHLImageViewerExtJpg" ); + void Panic( TInt aPanicCode ) { User::Panic( KIHLImageViewerExtJpgPanic, aPanicCode ); } + } + +// ============================ MEMBER FUNCTIONS =============================== +// ----------------------------------------------------------------------------- +// +// C++ constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +CIHLImageViewerExtJpg::CIHLImageViewerExtJpg( const TSize& aViewerSize, + MIHLFileImageExtJpg& aSource, + MIHLBitmap& aDestination, + MIHLViewerObserver& aObserver, + const TUint32 aOptions ) +: CTimer( EPriorityNormal ), iObserver( aObserver ), +iSource( aSource ), iDestination( aDestination ), +iOptions( aOptions ), iViewerSize( aViewerSize ), iSrcBitmapScaleFactor(1) + { + + CActiveScheduler::Add( this ); + } + +// ----------------------------------------------------------------------------- +// +// Two-phased constructor. +// ----------------------------------------------------------------------------- +CIHLImageViewerExtJpg* CIHLImageViewerExtJpg::NewL( const TSize& aViewerSize, + MIHLFileImageExtJpg& aSource, + MIHLBitmap& aDestination, + MIHLViewerObserver& aObserver, + const TUint32 aOptions ) + { + CIHLImageViewerExtJpg* self = new( ELeave ) CIHLImageViewerExtJpg( + aViewerSize, aSource, aDestination, aObserver, aOptions ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); // self + return self; + } + +// ----------------------------------------------------------------------------- +// +// Symbian constructor can leave. +// ----------------------------------------------------------------------------- +void CIHLImageViewerExtJpg::ConstructL() + { + CTimer::ConstructL(); + + iCacheSource = CIHLBitmap::NewL(); + iCacheDestination = CIHLBitmap::NewL(); + + // Check codec capabilities + iCapabilities = iSource.CapabilitiesL(); + if( !( iCapabilities & ( CExtJpegDecoder::ECapRotation + + CExtJpegDecoder::ECapMirroring + + CExtJpegDecoder::ECapFlipping ) ) ) + { + iInternalProcessingNeeded = ETrue; + iProcessor = CIHLBitmapProcessor::NewL( iOptions ); + } + + // Initialize settings and start load (default is zoom to fit) + iSourceSize = iSource.Size(); + CalculateZoomToFitRatio(); + User::LeaveIfError( SetZoomRatio( iZoomToFitRatio ) ); + } + +// ----------------------------------------------------------------------------- +// Destructor +// ----------------------------------------------------------------------------- +CIHLImageViewerExtJpg::~CIHLImageViewerExtJpg() + { + Cancel(); + if( iProcessor ) + { + delete iProcessor; + } + delete iCacheSource; + delete iCacheDestination; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::Id +// ----------------------------------------------------------------------------- +TIHLInterfaceType CIHLImageViewerExtJpg::Type() const + { + return TIHLInterfaceType( KIHLInterfaceIdImageViewer, KIHLImplementationIdImageViewerExtJpg ); + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::IsAnimation +// ----------------------------------------------------------------------------- +TBool CIHLImageViewerExtJpg::IsAnimation() const + { + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::Play +// ----------------------------------------------------------------------------- +void CIHLImageViewerExtJpg::Play() + { + + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::Stop +// ----------------------------------------------------------------------------- +void CIHLImageViewerExtJpg::Stop() + { + + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::IsPlaying +// ----------------------------------------------------------------------------- +TBool CIHLImageViewerExtJpg::IsPlaying() const + { + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::AnimationFrameCount +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::AnimationFrameCount() const + { + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::AnimationFrame +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::AnimationFrame() const + { + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::SetAnimationFrame +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::SetAnimationFrame( TInt /*aFrameIndex*/ ) + { + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::SetViewerSize +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::SetViewerSize( const TSize& aViewerSize, int aSrcBitmapScaleFactor ) + { + // Public API, negative value check -> panic also on hardware + __ASSERT_ALWAYS( aViewerSize.iWidth >= 0 && + aViewerSize.iHeight >= 0, Panic( KErrArgument ) ); + + iSrcBitmapScaleFactor = aSrcBitmapScaleFactor; + + // Save new viewer size + iViewerSize = aViewerSize; + + // Recalculate source rect and destination size + CalculateSourceRectAndDestinationSize(); + + // Recalculate zoom to fit ratio + CalculateZoomToFitRatio(); + + // Start load + return ApplySettings(); + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::ViewerSize +// ----------------------------------------------------------------------------- +TSize CIHLImageViewerExtJpg::ViewerSize() const + { + return iViewerSize; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::MoveSourceRect +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::MoveSourceRect( TInt aDx, TInt aDy ) + { + TInt dx( aDx ); + TInt dy( aDy ); + switch( iRotationAngle ) + { + case ERotationAngle0: + { + break; + } + case ERotationAngle90: + { + dx = aDy; + dy = -aDx; + break; + } + case ERotationAngle180: + { + dx = -aDx; + dy = -aDy; + break; + } + case ERotationAngle270: + { + dx = -aDy; + dy = aDx; + break; + } + default: + { + // Internal state error, debug panic only + #ifdef _DEBUG + Panic( KErrGeneral ); + #endif + } + } + if( iHorizontalMirroring ) + { + dx = -dx; + } + if( iVerticalMirroring ) + { + dy = -dy; + } + + if( iSourceRect.iTl.iX + dx < 0 || + iSourceRect.iBr.iX + dx > iSourceSize.iWidth || + iSourceRect.iTl.iY + dy < 0 || + iSourceRect.iBr.iY + dy > iSourceSize.iHeight ) + { + return KErrArgument; + } + + iSourceRect.Move( dx, dy ); + + // Start load + return ApplySettings(); + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::SetSourceRectPosition +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::SetSourceRectPosition( const TPoint& aPosition ) + { + TPoint newPosition( aPosition ); + TSize sourceRectSize( iSourceRect.Size() ); + switch( iRotationAngle ) + { + case ERotationAngle0: + { + break; + } + case ERotationAngle90: + { + newPosition.iX = aPosition.iY; + newPosition.iY = iSourceSize.iHeight - sourceRectSize.iHeight - aPosition.iX; + break; + } + case ERotationAngle180: + { + newPosition.iX = iSourceSize.iWidth - sourceRectSize.iWidth - aPosition.iX; + newPosition.iY = iSourceSize.iHeight - sourceRectSize.iHeight - aPosition.iY; + break; + } + case ERotationAngle270: + { + newPosition.iX = iSourceSize.iWidth - sourceRectSize.iWidth - aPosition.iY; + newPosition.iY = aPosition.iX; + break; + } + default: + { + // Internal state error, debug panic only + #ifdef _DEBUG + Panic( KErrGeneral ); + #endif + } + } + if( iHorizontalMirroring ) + { + newPosition.iX = iSourceSize.iWidth - sourceRectSize.iWidth - newPosition.iX; + } + if( iVerticalMirroring ) + { + newPosition.iY = iSourceSize.iHeight - sourceRectSize.iHeight - newPosition.iY; + } + + if( newPosition.iX < 0 || + newPosition.iX > ( iSourceSize.iWidth - sourceRectSize.iWidth ) || + newPosition.iY < 0 || + newPosition.iY > ( iSourceSize.iHeight - sourceRectSize.iHeight ) ) + { + return KErrArgument; + } + + iSourceRect = TRect( newPosition, sourceRectSize ); + + // Start load + return ApplySettings(); + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::SourceRect +// ----------------------------------------------------------------------------- +TRect CIHLImageViewerExtJpg::SourceRect() const + { + TRect mirroredSourceRect( iSourceRect ); + if( iHorizontalMirroring ) + { + mirroredSourceRect.iTl.iX = iSourceSize.iWidth - iSourceRect.iBr.iX; + mirroredSourceRect.iBr.iX = iSourceSize.iWidth - iSourceRect.iTl.iX; + } + if( iVerticalMirroring ) + { + mirroredSourceRect.iTl.iY = iSourceSize.iHeight - iSourceRect.iBr.iY; + mirroredSourceRect.iBr.iY = iSourceSize.iHeight - iSourceRect.iTl.iY; + } + + TRect rotatedSourceRect( mirroredSourceRect ); + switch( iRotationAngle ) + { + case ERotationAngle0: + { + break; + } + case ERotationAngle90: + { + rotatedSourceRect.iTl.iX = iSourceSize.iHeight - mirroredSourceRect.iBr.iY; + rotatedSourceRect.iTl.iY = mirroredSourceRect.iTl.iX; + rotatedSourceRect.iBr.iX = iSourceSize.iHeight - mirroredSourceRect.iTl.iY; + rotatedSourceRect.iBr.iY = mirroredSourceRect.iBr.iX; + break; + } + case ERotationAngle180: + { + rotatedSourceRect.iTl.iX = iSourceSize.iWidth - mirroredSourceRect.iBr.iX; + rotatedSourceRect.iTl.iY = iSourceSize.iHeight - mirroredSourceRect.iBr.iY; + rotatedSourceRect.iBr.iX = iSourceSize.iWidth - mirroredSourceRect.iTl.iX; + rotatedSourceRect.iBr.iY = iSourceSize.iHeight - mirroredSourceRect.iTl.iY; + break; + } + case ERotationAngle270: + { + rotatedSourceRect.iTl.iX = mirroredSourceRect.iTl.iY; + rotatedSourceRect.iTl.iY = iSourceSize.iWidth - mirroredSourceRect.iBr.iX; + rotatedSourceRect.iBr.iX = mirroredSourceRect.iBr.iY; + rotatedSourceRect.iBr.iY = iSourceSize.iWidth - mirroredSourceRect.iTl.iX; + break; + } + default: + { + // Internal state error, debug panic only + #ifdef _DEBUG + Panic( KErrGeneral ); + #endif + } + } + + return rotatedSourceRect; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::SourceSize +// ----------------------------------------------------------------------------- +TSize CIHLImageViewerExtJpg::SourceSize() const + { + if( iRotationAngle == ERotationAngle90 || + iRotationAngle == ERotationAngle270 ) + { + return TSize( iSourceSize.iHeight, iSourceSize.iWidth ); + } + else + { + return iSourceSize; + } + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::SetZoomRatio +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::SetZoomRatio( TReal aZoomRatio ) + { + if( aZoomRatio <= 0 ) + { + return KErrArgument; + } + + iZoomRatio = aZoomRatio; + + // Recalculate source rect and destination size + CalculateSourceRectAndDestinationSize(); + + // Start load + return ApplySettings(); + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::ZoomRatio +// ----------------------------------------------------------------------------- +TReal CIHLImageViewerExtJpg::ZoomRatio() const + { + return iZoomRatio; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::ZoomToFitRatio +// ----------------------------------------------------------------------------- +TReal CIHLImageViewerExtJpg::ZoomToFitRatio() const + { + return iZoomToFitRatio; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::RotateClockwise +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::RotateClockwise() + { + TInt rotationAngle( iRotationAngle + ERotationAngle90 ); + if( rotationAngle > ERotationAngle270 ) + { + rotationAngle = ERotationAngle0; + } + + return SetRotationAngle( rotationAngle ); + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::RotateCounterClockwise +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::RotateCounterClockwise() + { + TInt rotationAngle( iRotationAngle - ERotationAngle90 ); + if( rotationAngle < ERotationAngle0 ) + { + rotationAngle = ERotationAngle270; + } + + return SetRotationAngle( rotationAngle ); + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::SetRotationAngle +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::SetRotationAngle( TInt aRotationAngle ) + { + if( aRotationAngle != ERotationAngle0 && + aRotationAngle != ERotationAngle90 && + aRotationAngle != ERotationAngle180 && + aRotationAngle != ERotationAngle270 ) + { + return KErrArgument; + } + + iRotationAngle = aRotationAngle; + + // Recalculate source rect and destination size + CalculateSourceRectAndDestinationSize(); + + // Recalculate zoom to fit ratio + CalculateZoomToFitRatio(); + + // Start load + return ApplySettings(); + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::RotationAngle +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::RotationAngle() const + { + return iRotationAngle; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::SetVerticalMirroring +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::SetVerticalMirroring( TBool aValue ) + { + if( iVerticalMirroring != aValue ) + { + iVerticalMirroring = aValue; + + // Start load + return ApplySettings(); + } + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::VerticalMirroring +// ----------------------------------------------------------------------------- +TBool CIHLImageViewerExtJpg::VerticalMirroring() const + { + return iVerticalMirroring; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::SetHorizontalMirroring +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::SetHorizontalMirroring( TBool aValue ) + { + if( iHorizontalMirroring != aValue ) + { + iHorizontalMirroring = aValue; + return ApplySettings(); + } + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::HorizontalMirroring +// ----------------------------------------------------------------------------- +TBool CIHLImageViewerExtJpg::HorizontalMirroring() const + { + return iHorizontalMirroring; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::SetFilter +// ----------------------------------------------------------------------------- +void CIHLImageViewerExtJpg::SetFilter( MIHLFilter* /*aFilter*/ ) + { + // Not in use + } + + + +// Private methods +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::DoCancel +// ----------------------------------------------------------------------------- +void CIHLImageViewerExtJpg::DoCancel() + { + CTimer::DoCancel(); + // Set state to inactive + switch( iViewerState ) + { + case ELoad: + { + // Cancel asynchronous source loading + iSource.CancelLoad(); + iCacheSource->Reset(); + break; + } + case EProcess: + { + // Cancel asynchronous processing + iProcessor->CancelProcess(); + iCacheDestination->Reset(); + break; + } + default: + { + break; + } + } + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::RunL +// ----------------------------------------------------------------------------- +void CIHLImageViewerExtJpg::RunL() + { + User::LeaveIfError( iStatus.Int() ); + + // Save previous state and set current state immediately + // to inactive to keep state up-to-date + TViewerState prevState( iViewerState ); + iViewerState = EInactive; + + switch( prevState ) + { + case ELoad: + { + //Use the internal processor if the codec is lacking some processing capability + if( iInternalProcessingNeeded ) + { + const CFbsBitmap& srcBitmap = iCacheSource->Bitmap(); + User::LeaveIfError( iCacheDestination->Create( iDestinationSize, srcBitmap.DisplayMode() ) ); + TRect processSourceRect( CalculateProcessSourceRect( iCacheSource->Bitmap().SizeInPixels() ) ); + TRect destinationRect( CalculateProcessDestinationRect() ); + + User::LeaveIfError( iProcessor->Process( iStatus, *iCacheSource, processSourceRect, + *iCacheDestination, destinationRect ) ); + + iViewerState = EProcess; + SetActive(); + } + else + { + User::LeaveIfError( Finish() ); + iObserver.ViewerBitmapChangedL(); + } + break; + } + case EProcess: + { + User::LeaveIfError( Finish() ); + iObserver.ViewerBitmapChangedL(); + break; + } + default: + { + // Internal state error, debug panic only + #ifdef _DEBUG + Panic( KErrGeneral ); + #endif + } + } + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::RunError +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::RunError( TInt aError ) + { + switch( iViewerState ) + { + case ELoad: + { + // Cleanup cached source if load has been failed + iCacheSource->Reset(); + break; + } + case EProcess: + { + // Cleanup cached destination if process has been failed + iCacheDestination->Reset(); + break; + } + default: + { + break; + } + } + + iViewerState = EInactive; + iObserver.ViewerError( aError ); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::ApplySettings +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::ApplySettings() + { + // Assert source rect and destination, debug build only +#ifdef _DEBUG + AssertSourceRectAndDestinationSize(); +#endif + + // Cancel current process if any + Cancel(); + + // Perform processing if supported by codec + if( !iInternalProcessingNeeded ) + { + TRAPD( err, iSource.SetRotationL( iRotationAngle ) ); + if( !err && iHorizontalMirroring ) + { + TRAP( err, iSource.SetFlippingL() ); + } + if( !err && iVerticalMirroring ) + { + TRAP( err, iSource.SetMirroringL() ); + } + if( err ) + { + return err; + } + } + + // Start async load/process. + TInt err( KErrNone ); + + err = AsyncLoad(); + if( !err ) + { + iViewerState = ELoad; + SetActive(); + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::AsyncLoad +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::AsyncLoad() + { + // Internal state check, debug panic only + __ASSERT_DEBUG( !iCacheDestination->Bitmap().Handle(), Panic( KErrGeneral ) ); + + TInt err( KErrNone ); + + // Load source bitmap + + iCacheSource->Reset(); + + err = iCacheSource->Create( iDestinationSize, iSource.DisplayMode() ); + + if( !err ) + { + err = iSource.Load( iSourceRect, iStatus, *iCacheSource ); + } + + // Error cleanup if needed + if( err ) + { + iCacheSource->Reset(); + } + return err; + } + + + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::Finish +// ----------------------------------------------------------------------------- +TInt CIHLImageViewerExtJpg::Finish() + { + // Internal state check, debug panic only + __ASSERT_DEBUG( iCacheSource->Bitmap().Handle(), Panic( KErrGeneral ) ); + + TInt err( KErrNone ); + + // Check if internal processor was used + if( iInternalProcessingNeeded ) + { + err = iDestination.Copy( *iCacheDestination, ETrue ); + iCacheDestination->Reset(); + } + else + { + err = iDestination.Copy( *iCacheSource, ETrue ); + iCacheSource->Reset(); + } + + // Error cleanup if needed + if( err ) + { + iDestination.Reset(); + } + + return err; + } + + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::SelfComplete +// ----------------------------------------------------------------------------- +void CIHLImageViewerExtJpg::SelfComplete() + { + SetActive(); + iStatus = KRequestPending; + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::CalculateProcessSourceRect +// ----------------------------------------------------------------------------- +TRect CIHLImageViewerExtJpg::CalculateProcessSourceRect( const TSize& aSourceCacheSize ) + { + + TRect loadRect( aSourceCacheSize ); + + switch( iRotationAngle ) + { + case ERotationAngle0: + { + break; + } + case ERotationAngle90: + { + TInt tmp( loadRect.iTl.iY ); + loadRect.iTl.iY = loadRect.iBr.iY; + loadRect.iBr.iY = tmp; + break; + } + case ERotationAngle180: + { + TPoint tmp( loadRect.iTl ); + loadRect.iTl = loadRect.iBr; + loadRect.iBr = tmp; + break; + } + case ERotationAngle270: + { + TInt tmp( loadRect.iTl.iX ); + loadRect.iTl.iX = loadRect.iBr.iX; + loadRect.iBr.iX = tmp; + break; + } + default: + { + // Internal state error, debug panic only + #ifdef _DEBUG + Panic( KErrGeneral ); + #endif + } + } + + return loadRect; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::CalculateProcessDestinationRect +// ----------------------------------------------------------------------------- +TRect CIHLImageViewerExtJpg::CalculateProcessDestinationRect() + { + TRect dstRect( iDestinationSize ); + switch( iRotationAngle ) + { + case ERotationAngle0: + case ERotationAngle180: + { + if( iHorizontalMirroring ) + { + TInt tmp( dstRect.iTl.iX ); + dstRect.iTl.iX = dstRect.iBr.iX; + dstRect.iBr.iX = tmp; + } + if( iVerticalMirroring ) + { + TInt tmp( dstRect.iTl.iY ); + dstRect.iTl.iY = dstRect.iBr.iY; + dstRect.iBr.iY = tmp; + } + break; + } + case ERotationAngle90: + case ERotationAngle270: + { + if( iHorizontalMirroring ) + { + TInt tmp( dstRect.iTl.iY ); + dstRect.iTl.iY = dstRect.iBr.iY; + dstRect.iBr.iY = tmp; + } + if( iVerticalMirroring ) + { + TInt tmp( dstRect.iTl.iX ); + dstRect.iTl.iX = dstRect.iBr.iX; + dstRect.iBr.iX = tmp; + } + break; + } + default: + { + // Internal state error, debug panic only + #ifdef _DEBUG + Panic( KErrGeneral ); + #endif + } + } + return dstRect; + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::CalculateZoomToFitRatio +// ----------------------------------------------------------------------------- +void CIHLImageViewerExtJpg::CalculateZoomToFitRatio() + { + TSize sourceSize( SourceSize() ); + TReal widthRatio( TReal( iViewerSize.iWidth ) / TReal( sourceSize.iWidth ) ); + TReal heightRatio( TReal( iViewerSize.iHeight ) / TReal( sourceSize.iHeight ) ); + + if( iOptions & MIHLImageViewer::EOptionIgnoreAspectRatio ) + { + iZoomToFitRatio = ( widthRatio > heightRatio ) ? widthRatio : heightRatio; + } + else + { + iZoomToFitRatio = ( widthRatio < heightRatio ) ? widthRatio : heightRatio; + } + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::CalculateSourceRectAndDestinationSize +// ----------------------------------------------------------------------------- +void CIHLImageViewerExtJpg::CalculateSourceRectAndDestinationSize() + { + // Calculate new source rect + TSize oldSourceRectSize( iSourceRect.Size() ); + + TReal newSourceRectWidth; + TReal newSourceRectHeight; + TReal widthZoomRatio( iZoomRatio ); + TReal heightZoomRatio( iZoomRatio ); + + if( iOptions & MIHLImageViewer::EOptionIgnoreAspectRatio ) + { + TReal widthRatio( TReal( iViewerSize.iWidth ) / TReal( iSourceSize.iWidth ) ); + TReal heightRatio( TReal( iViewerSize.iHeight ) / TReal( iSourceSize.iHeight ) ); + if( widthRatio < heightRatio ) + { + widthZoomRatio = widthZoomRatio * widthRatio / heightRatio; + } + else + { + heightZoomRatio = heightZoomRatio * heightRatio / widthRatio; + } + } + + if( iRotationAngle == ERotationAngle90 || + iRotationAngle == ERotationAngle270 ) + { + newSourceRectWidth = iSrcBitmapScaleFactor * iViewerSize.iHeight / heightZoomRatio; //widthZoomRatio + newSourceRectHeight = iSrcBitmapScaleFactor * iViewerSize.iWidth / widthZoomRatio; //heightZoomRatio + } + else + { + newSourceRectWidth = iSrcBitmapScaleFactor * iViewerSize.iWidth / widthZoomRatio; + newSourceRectHeight = iSrcBitmapScaleFactor * iViewerSize.iHeight / heightZoomRatio; + } + + // Check if source rect is not larger than source area + if( newSourceRectWidth > iSourceSize.iWidth ) + { + newSourceRectWidth = iSourceSize.iWidth; + } + if( newSourceRectHeight > iSourceSize.iHeight ) + { + newSourceRectHeight = iSourceSize.iHeight; + } + iSourceRect.SetWidth( (TInt)newSourceRectWidth ); + iSourceRect.SetHeight( (TInt)newSourceRectHeight ); + + // Calculate actual destination size (always same or smaller than iViewerSize !) + if( iRotationAngle == ERotationAngle90 || + iRotationAngle == ERotationAngle270 ) + { + iDestinationSize.iWidth = (TInt)( newSourceRectHeight * widthZoomRatio ); //heightZoomRatio + iDestinationSize.iHeight = (TInt)( newSourceRectWidth * heightZoomRatio ); //widthZoomRatio + } + else + { + iDestinationSize.iWidth = (TInt)( newSourceRectWidth * widthZoomRatio ); + iDestinationSize.iHeight = (TInt)( newSourceRectHeight * heightZoomRatio ); + } + // Check that destination size is not rounded to zero + if( iDestinationSize.iWidth == 0 ) + { + iDestinationSize.iWidth = 1; + } + if( iDestinationSize.iHeight == 0 ) + { + iDestinationSize.iHeight = 1; + } + + // Move source rect keeping center point in same location + iSourceRect.Move( ( oldSourceRectSize.iWidth - (TInt)newSourceRectWidth ) / 2, + ( oldSourceRectSize.iHeight - (TInt)newSourceRectHeight ) / 2 ); + + // Move rect if partially out of source area + TPoint moveOffset( 0, 0 ); + if( iSourceRect.iTl.iX < 0 ) + { + moveOffset.iX = -iSourceRect.iTl.iX; + } + else if( iSourceRect.iBr.iX > iSourceSize.iWidth ) + { + moveOffset.iX = iSourceSize.iWidth - iSourceRect.iBr.iX; + } + if( iSourceRect.iTl.iY < 0 ) //lint !e961 + { + moveOffset.iY = -iSourceRect.iTl.iY; + } + else if( iSourceRect.iBr.iY > iSourceSize.iHeight ) + { + moveOffset.iY = iSourceSize.iHeight - iSourceRect.iBr.iY; + } + iSourceRect.Move( moveOffset ); //lint !e961 + + // Assert that rectangle is valid, debug build only +#ifdef _DEBUG + AssertSourceRectAndDestinationSize(); +#endif + } + +// ----------------------------------------------------------------------------- +// CIHLImageViewerExtJpg::AssertSourceRectAndDestinationSize +// Used in debug build only +// ----------------------------------------------------------------------------- +#ifdef _DEBUG +void CIHLImageViewerExtJpg::AssertSourceRectAndDestinationSize() + { + if( iSourceRect.iTl.iX < 0 || + iSourceRect.iBr.iX > iSourceSize.iWidth || + iSourceRect.iTl.iY < 0 || + iSourceRect.iBr.iY > iSourceSize.iHeight || + iDestinationSize.iWidth <= 0 || iDestinationSize.iHeight <= 0 ) + { + Panic( KErrGeneral ); + } + } +#endif + +// End of File + +