imagehandlinglib/Src/CIHLImageViewerExtJpg.cpp
changeset 0 2014ca87e772
child 9 2eb74cf6572e
equal deleted inserted replaced
-1:000000000000 0:2014ca87e772
       
     1 /*
       
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation of Image Viewer class.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "CIHLImageViewerExtJpg.h"
       
    21 
       
    22 #include "CIHLBitmap.h"
       
    23 #include "CIHLBitmapProcessor.h"
       
    24 #include "IHLImplementationIds.h"
       
    25 #include <IHLInterfaceIds.h>
       
    26 #include <IclExtJpegApi.h>
       
    27 #include <ImageCodecData.h>
       
    28 #include <MIHLViewerObserver.h>
       
    29 #include "MIHLFileImageExtJpg.h"
       
    30 #include <fbs.h>
       
    31 
       
    32 // Private namespace for constants and functions
       
    33 namespace
       
    34 	{
       
    35 	// Panic function
       
    36 	_LIT( KIHLImageViewerExtJpgPanic, "IHLImageViewerExtJpg" );
       
    37 	void Panic( TInt aPanicCode ) { User::Panic( KIHLImageViewerExtJpgPanic, aPanicCode ); }
       
    38 	}
       
    39 
       
    40 // ============================ MEMBER FUNCTIONS ===============================
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 // C++ constructor can NOT contain any code, that might leave.
       
    44 // -----------------------------------------------------------------------------
       
    45 CIHLImageViewerExtJpg::CIHLImageViewerExtJpg( const TSize& aViewerSize,
       
    46 								  MIHLFileImageExtJpg& aSource,
       
    47 								  MIHLBitmap& aDestination,
       
    48 								  MIHLViewerObserver& aObserver,
       
    49 								  const TUint32 aOptions )
       
    50 : CTimer( EPriorityNormal ), iObserver( aObserver ),
       
    51 iSource( aSource ), iDestination( aDestination ),
       
    52 iOptions( aOptions ), iViewerSize( aViewerSize ), iSrcBitmapScaleFactor(1)
       
    53     {
       
    54 
       
    55 	CActiveScheduler::Add( this );
       
    56     }
       
    57 
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 // Two-phased constructor.
       
    61 // -----------------------------------------------------------------------------
       
    62 CIHLImageViewerExtJpg* CIHLImageViewerExtJpg::NewL( const TSize& aViewerSize,
       
    63 										MIHLFileImageExtJpg& aSource,
       
    64 										MIHLBitmap& aDestination,
       
    65 										MIHLViewerObserver& aObserver,
       
    66 										const TUint32 aOptions )
       
    67     {
       
    68     CIHLImageViewerExtJpg* self = new( ELeave ) CIHLImageViewerExtJpg(
       
    69 		aViewerSize, aSource, aDestination, aObserver, aOptions );
       
    70     CleanupStack::PushL( self );
       
    71     self->ConstructL();
       
    72 	CleanupStack::Pop(); // self
       
    73     return self;
       
    74     }
       
    75 
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 // Symbian constructor can leave.
       
    79 // -----------------------------------------------------------------------------
       
    80 void CIHLImageViewerExtJpg::ConstructL()
       
    81 	{
       
    82 	CTimer::ConstructL();
       
    83 
       
    84 	iCacheSource = CIHLBitmap::NewL();
       
    85 	iCacheDestination = CIHLBitmap::NewL();
       
    86 
       
    87 	// Check codec capabilities
       
    88 	iCapabilities = iSource.CapabilitiesL();
       
    89 	if( !( iCapabilities & ( CExtJpegDecoder::ECapRotation +
       
    90 						CExtJpegDecoder::ECapMirroring +
       
    91 						CExtJpegDecoder::ECapFlipping ) ) )
       
    92 		{
       
    93 		iInternalProcessingNeeded = ETrue;
       
    94 		iProcessor = CIHLBitmapProcessor::NewL( iOptions );
       
    95 		}
       
    96 
       
    97 	// Initialize settings and start load (default is zoom to fit)
       
    98 	iSourceSize = iSource.Size();
       
    99 	CalculateZoomToFitRatio();
       
   100 	User::LeaveIfError( SetZoomRatio( iZoomToFitRatio ) );
       
   101 	}
       
   102 
       
   103 // -----------------------------------------------------------------------------
       
   104 // Destructor
       
   105 // -----------------------------------------------------------------------------
       
   106 CIHLImageViewerExtJpg::~CIHLImageViewerExtJpg()
       
   107     {
       
   108 	Cancel();
       
   109 	if( iProcessor )
       
   110 		{
       
   111 		delete iProcessor;
       
   112 		}
       
   113 	delete iCacheSource;
       
   114     delete iCacheDestination;
       
   115     }
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // CIHLImageViewerExtJpg::Id
       
   119 // -----------------------------------------------------------------------------
       
   120 TIHLInterfaceType CIHLImageViewerExtJpg::Type() const
       
   121 	{
       
   122 	return TIHLInterfaceType( KIHLInterfaceIdImageViewer, KIHLImplementationIdImageViewerExtJpg );
       
   123 	}
       
   124 
       
   125 // -----------------------------------------------------------------------------
       
   126 // CIHLImageViewerExtJpg::IsAnimation
       
   127 // -----------------------------------------------------------------------------
       
   128 TBool CIHLImageViewerExtJpg::IsAnimation() const
       
   129 	{
       
   130 	return EFalse;
       
   131 	}
       
   132 
       
   133 // -----------------------------------------------------------------------------
       
   134 // CIHLImageViewerExtJpg::Play
       
   135 // -----------------------------------------------------------------------------
       
   136 void CIHLImageViewerExtJpg::Play()
       
   137 	{
       
   138 
       
   139 	}
       
   140 
       
   141 // -----------------------------------------------------------------------------
       
   142 // CIHLImageViewerExtJpg::Stop
       
   143 // -----------------------------------------------------------------------------
       
   144 void CIHLImageViewerExtJpg::Stop()
       
   145 	{
       
   146 
       
   147 	}
       
   148 
       
   149 // -----------------------------------------------------------------------------
       
   150 // CIHLImageViewerExtJpg::IsPlaying
       
   151 // -----------------------------------------------------------------------------
       
   152 TBool CIHLImageViewerExtJpg::IsPlaying() const
       
   153 	{
       
   154 	return EFalse;
       
   155 	}
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // CIHLImageViewerExtJpg::AnimationFrameCount
       
   159 // -----------------------------------------------------------------------------
       
   160 TInt CIHLImageViewerExtJpg::AnimationFrameCount() const
       
   161 	{
       
   162 	return KErrNone;
       
   163 	}
       
   164 
       
   165 // -----------------------------------------------------------------------------
       
   166 // CIHLImageViewerExtJpg::AnimationFrame
       
   167 // -----------------------------------------------------------------------------
       
   168 TInt CIHLImageViewerExtJpg::AnimationFrame() const
       
   169 	{
       
   170 	return KErrNone;
       
   171 	}
       
   172 
       
   173 // -----------------------------------------------------------------------------
       
   174 // CIHLImageViewerExtJpg::SetAnimationFrame
       
   175 // -----------------------------------------------------------------------------
       
   176 TInt CIHLImageViewerExtJpg::SetAnimationFrame( TInt /*aFrameIndex*/ )
       
   177 	{
       
   178     return KErrNone;
       
   179 	}
       
   180 
       
   181 // -----------------------------------------------------------------------------
       
   182 // CIHLImageViewerExtJpg::SetViewerSize
       
   183 // -----------------------------------------------------------------------------
       
   184 TInt CIHLImageViewerExtJpg::SetViewerSize( const TSize& aViewerSize, int aSrcBitmapScaleFactor )
       
   185 	{
       
   186     // Public API, negative value check -> panic also on hardware
       
   187 	__ASSERT_ALWAYS( aViewerSize.iWidth >= 0 &&
       
   188 					 aViewerSize.iHeight >= 0, Panic( KErrArgument ) );
       
   189 
       
   190 	iSrcBitmapScaleFactor = aSrcBitmapScaleFactor;
       
   191 
       
   192 	// Save new viewer size
       
   193 	iViewerSize = aViewerSize;
       
   194 
       
   195 	// Recalculate source rect and destination size
       
   196 	CalculateSourceRectAndDestinationSize();
       
   197 
       
   198 	// Recalculate zoom to fit ratio
       
   199 	CalculateZoomToFitRatio();
       
   200 
       
   201 	// Start load
       
   202 	return ApplySettings();
       
   203 	}
       
   204 
       
   205 // -----------------------------------------------------------------------------
       
   206 // CIHLImageViewerExtJpg::ViewerSize
       
   207 // -----------------------------------------------------------------------------
       
   208 TSize CIHLImageViewerExtJpg::ViewerSize() const
       
   209 	{
       
   210 	return iViewerSize;
       
   211 	}
       
   212 
       
   213 // -----------------------------------------------------------------------------
       
   214 // CIHLImageViewerExtJpg::MoveSourceRect
       
   215 // -----------------------------------------------------------------------------
       
   216 TInt CIHLImageViewerExtJpg::MoveSourceRect( TInt aDx, TInt aDy )
       
   217 	{
       
   218 	TInt dx( aDx );
       
   219 	TInt dy( aDy );
       
   220 	switch( iRotationAngle )
       
   221 		{
       
   222 		case ERotationAngle0:
       
   223 			{
       
   224 			break;
       
   225 			}
       
   226 		case ERotationAngle90:
       
   227 			{
       
   228 			dx = aDy;
       
   229 			dy = -aDx;
       
   230 			break;
       
   231 			}
       
   232 		case ERotationAngle180:
       
   233 			{
       
   234 			dx = -aDx;
       
   235 			dy = -aDy;
       
   236 			break;
       
   237 			}
       
   238 		case ERotationAngle270:
       
   239 			{
       
   240 			dx = -aDy;
       
   241 			dy = aDx;
       
   242 			break;
       
   243 			}
       
   244 		default:
       
   245 			{
       
   246             // Internal state error, debug panic only
       
   247             #ifdef _DEBUG
       
   248 			    Panic( KErrGeneral );
       
   249             #endif
       
   250 			}
       
   251 		}
       
   252 	if( iHorizontalMirroring )
       
   253 		{
       
   254 		dx = -dx;
       
   255 		}
       
   256 	if( iVerticalMirroring )
       
   257 		{
       
   258 		dy = -dy;
       
   259 		}
       
   260 
       
   261 	if( iSourceRect.iTl.iX + dx < 0 ||
       
   262 		iSourceRect.iBr.iX + dx > iSourceSize.iWidth ||
       
   263 		iSourceRect.iTl.iY + dy < 0 ||
       
   264 		iSourceRect.iBr.iY + dy > iSourceSize.iHeight )
       
   265 		{
       
   266 		return KErrArgument;
       
   267 		}
       
   268 
       
   269 	iSourceRect.Move( dx, dy );
       
   270 
       
   271 	// Start load
       
   272 	return ApplySettings();
       
   273 	}
       
   274 
       
   275 // -----------------------------------------------------------------------------
       
   276 // CIHLImageViewerExtJpg::SetSourceRectPosition
       
   277 // -----------------------------------------------------------------------------
       
   278 TInt CIHLImageViewerExtJpg::SetSourceRectPosition( const TPoint& aPosition )
       
   279 	{
       
   280 	TPoint newPosition( aPosition );
       
   281 	TSize sourceRectSize( iSourceRect.Size() );
       
   282 	switch( iRotationAngle )
       
   283 		{
       
   284 		case ERotationAngle0:
       
   285 			{
       
   286 			break;
       
   287 			}
       
   288 		case ERotationAngle90:
       
   289 			{
       
   290 			newPosition.iX = aPosition.iY;
       
   291 			newPosition.iY = iSourceSize.iHeight - sourceRectSize.iHeight - aPosition.iX;
       
   292 			break;
       
   293 			}
       
   294 		case ERotationAngle180:
       
   295 			{
       
   296 			newPosition.iX = iSourceSize.iWidth - sourceRectSize.iWidth - aPosition.iX;
       
   297 			newPosition.iY = iSourceSize.iHeight - sourceRectSize.iHeight - aPosition.iY;
       
   298 			break;
       
   299 			}
       
   300 		case ERotationAngle270:
       
   301 			{
       
   302 			newPosition.iX = iSourceSize.iWidth - sourceRectSize.iWidth - aPosition.iY;
       
   303 			newPosition.iY = aPosition.iX;
       
   304 			break;
       
   305 			}
       
   306 		default:
       
   307 			{
       
   308             // Internal state error, debug panic only
       
   309             #ifdef _DEBUG
       
   310     			Panic( KErrGeneral );
       
   311             #endif
       
   312 			}
       
   313 		}
       
   314 	if( iHorizontalMirroring )
       
   315 		{
       
   316 		newPosition.iX = iSourceSize.iWidth - sourceRectSize.iWidth - newPosition.iX;
       
   317 		}
       
   318 	if( iVerticalMirroring )
       
   319 		{
       
   320 		newPosition.iY = iSourceSize.iHeight - sourceRectSize.iHeight - newPosition.iY;
       
   321 		}
       
   322 
       
   323 	if( newPosition.iX < 0 ||
       
   324 		newPosition.iX > ( iSourceSize.iWidth - sourceRectSize.iWidth ) ||
       
   325 		newPosition.iY < 0 ||
       
   326 		newPosition.iY > ( iSourceSize.iHeight - sourceRectSize.iHeight ) )
       
   327 		{
       
   328 		return KErrArgument;
       
   329 		}
       
   330 
       
   331 	iSourceRect = TRect( newPosition, sourceRectSize );
       
   332 
       
   333 	// Start load
       
   334 	return ApplySettings();
       
   335 	}
       
   336 
       
   337 // -----------------------------------------------------------------------------
       
   338 // CIHLImageViewerExtJpg::SourceRect
       
   339 // -----------------------------------------------------------------------------
       
   340 TRect CIHLImageViewerExtJpg::SourceRect() const
       
   341 	{
       
   342 	TRect mirroredSourceRect( iSourceRect );
       
   343 	if( iHorizontalMirroring )
       
   344 		{
       
   345 		mirroredSourceRect.iTl.iX  = iSourceSize.iWidth - iSourceRect.iBr.iX;
       
   346 		mirroredSourceRect.iBr.iX  = iSourceSize.iWidth - iSourceRect.iTl.iX;
       
   347 		}
       
   348 	if( iVerticalMirroring )
       
   349 		{
       
   350 		mirroredSourceRect.iTl.iY  = iSourceSize.iHeight - iSourceRect.iBr.iY;
       
   351 		mirroredSourceRect.iBr.iY  = iSourceSize.iHeight - iSourceRect.iTl.iY;
       
   352 		}
       
   353 
       
   354 	TRect rotatedSourceRect( mirroredSourceRect );
       
   355 	switch( iRotationAngle )
       
   356 		{
       
   357 		case ERotationAngle0:
       
   358 			{
       
   359 			break;
       
   360 			}
       
   361 		case ERotationAngle90:
       
   362 			{
       
   363 			rotatedSourceRect.iTl.iX = iSourceSize.iHeight - mirroredSourceRect.iBr.iY;
       
   364 			rotatedSourceRect.iTl.iY = mirroredSourceRect.iTl.iX;
       
   365 			rotatedSourceRect.iBr.iX = iSourceSize.iHeight - mirroredSourceRect.iTl.iY;
       
   366 			rotatedSourceRect.iBr.iY = mirroredSourceRect.iBr.iX;
       
   367 			break;
       
   368 			}
       
   369 		case ERotationAngle180:
       
   370 			{
       
   371 			rotatedSourceRect.iTl.iX = iSourceSize.iWidth - mirroredSourceRect.iBr.iX;
       
   372 			rotatedSourceRect.iTl.iY = iSourceSize.iHeight - mirroredSourceRect.iBr.iY;
       
   373 			rotatedSourceRect.iBr.iX = iSourceSize.iWidth - mirroredSourceRect.iTl.iX;
       
   374 			rotatedSourceRect.iBr.iY = iSourceSize.iHeight - mirroredSourceRect.iTl.iY;
       
   375 			break;
       
   376 			}
       
   377 		case ERotationAngle270:
       
   378 			{
       
   379 			rotatedSourceRect.iTl.iX = mirroredSourceRect.iTl.iY;
       
   380 			rotatedSourceRect.iTl.iY = iSourceSize.iWidth - mirroredSourceRect.iBr.iX;
       
   381 			rotatedSourceRect.iBr.iX = mirroredSourceRect.iBr.iY;
       
   382 			rotatedSourceRect.iBr.iY = iSourceSize.iWidth - mirroredSourceRect.iTl.iX;
       
   383 			break;
       
   384 			}
       
   385 		default:
       
   386 			{
       
   387             // Internal state error, debug panic only
       
   388             #ifdef _DEBUG
       
   389     			Panic( KErrGeneral );
       
   390             #endif
       
   391 			}
       
   392 		}
       
   393 
       
   394 	return rotatedSourceRect;
       
   395 	}
       
   396 
       
   397 // -----------------------------------------------------------------------------
       
   398 // CIHLImageViewerExtJpg::SourceSize
       
   399 // -----------------------------------------------------------------------------
       
   400 TSize CIHLImageViewerExtJpg::SourceSize() const
       
   401 	{
       
   402 	if( iRotationAngle == ERotationAngle90 ||
       
   403 		iRotationAngle == ERotationAngle270 )
       
   404 		{
       
   405 		return TSize( iSourceSize.iHeight, iSourceSize.iWidth );
       
   406 		}
       
   407 	else
       
   408 		{
       
   409 		return iSourceSize;
       
   410 		}
       
   411 	}
       
   412 
       
   413 // -----------------------------------------------------------------------------
       
   414 // CIHLImageViewerExtJpg::SetZoomRatio
       
   415 // -----------------------------------------------------------------------------
       
   416 TInt CIHLImageViewerExtJpg::SetZoomRatio( TReal aZoomRatio )
       
   417 	{
       
   418 	if( aZoomRatio <= 0 )
       
   419 		{
       
   420 		return KErrArgument;
       
   421 		}
       
   422 
       
   423 	iZoomRatio = aZoomRatio;
       
   424 
       
   425 	// Recalculate source rect and destination size
       
   426 	CalculateSourceRectAndDestinationSize();
       
   427 
       
   428 	// Start load
       
   429 	return ApplySettings();
       
   430 	}
       
   431 
       
   432 // -----------------------------------------------------------------------------
       
   433 // CIHLImageViewerExtJpg::ZoomRatio
       
   434 // -----------------------------------------------------------------------------
       
   435 TReal CIHLImageViewerExtJpg::ZoomRatio() const
       
   436 	{
       
   437 	return iZoomRatio;
       
   438 	}
       
   439 
       
   440 // -----------------------------------------------------------------------------
       
   441 // CIHLImageViewerExtJpg::ZoomToFitRatio
       
   442 // -----------------------------------------------------------------------------
       
   443 TReal CIHLImageViewerExtJpg::ZoomToFitRatio() const
       
   444 	{
       
   445 	return iZoomToFitRatio;
       
   446 	}
       
   447 
       
   448 // -----------------------------------------------------------------------------
       
   449 // CIHLImageViewerExtJpg::RotateClockwise
       
   450 // -----------------------------------------------------------------------------
       
   451 TInt CIHLImageViewerExtJpg::RotateClockwise()
       
   452 	{
       
   453 	TInt rotationAngle( iRotationAngle + ERotationAngle90 );
       
   454 	if( rotationAngle > ERotationAngle270 )
       
   455 		{
       
   456 		rotationAngle = ERotationAngle0;
       
   457 		}
       
   458 
       
   459 	return SetRotationAngle( rotationAngle );
       
   460 	}
       
   461 
       
   462 // -----------------------------------------------------------------------------
       
   463 // CIHLImageViewerExtJpg::RotateCounterClockwise
       
   464 // -----------------------------------------------------------------------------
       
   465 TInt CIHLImageViewerExtJpg::RotateCounterClockwise()
       
   466 	{
       
   467 	TInt rotationAngle( iRotationAngle - ERotationAngle90 );
       
   468 	if( rotationAngle < ERotationAngle0 )
       
   469 		{
       
   470 		rotationAngle = ERotationAngle270;
       
   471 		}
       
   472 
       
   473 	return SetRotationAngle( rotationAngle );
       
   474 	}
       
   475 
       
   476 // -----------------------------------------------------------------------------
       
   477 // CIHLImageViewerExtJpg::SetRotationAngle
       
   478 // -----------------------------------------------------------------------------
       
   479 TInt CIHLImageViewerExtJpg::SetRotationAngle( TInt aRotationAngle )
       
   480 	{
       
   481 	if( aRotationAngle != ERotationAngle0 &&
       
   482 		aRotationAngle != ERotationAngle90 &&
       
   483 		aRotationAngle != ERotationAngle180 &&
       
   484 		aRotationAngle != ERotationAngle270 )
       
   485 		{
       
   486 		return KErrArgument;
       
   487 		}
       
   488 
       
   489 	iRotationAngle = aRotationAngle;
       
   490 
       
   491 	// Recalculate source rect and destination size
       
   492 	CalculateSourceRectAndDestinationSize();
       
   493 
       
   494 	// Recalculate zoom to fit ratio
       
   495 	CalculateZoomToFitRatio();
       
   496 
       
   497 	// Start load
       
   498 	return ApplySettings();
       
   499 	}
       
   500 
       
   501 // -----------------------------------------------------------------------------
       
   502 // CIHLImageViewerExtJpg::RotationAngle
       
   503 // -----------------------------------------------------------------------------
       
   504 TInt CIHLImageViewerExtJpg::RotationAngle() const
       
   505 	{
       
   506 	return iRotationAngle;
       
   507 	}
       
   508 
       
   509 // -----------------------------------------------------------------------------
       
   510 // CIHLImageViewerExtJpg::SetVerticalMirroring
       
   511 // -----------------------------------------------------------------------------
       
   512 TInt CIHLImageViewerExtJpg::SetVerticalMirroring( TBool aValue )
       
   513 	{
       
   514 	if( iVerticalMirroring != aValue )
       
   515 		{
       
   516 		iVerticalMirroring = aValue;
       
   517 
       
   518 		// Start load
       
   519 		return ApplySettings();
       
   520 		}
       
   521 	return KErrNone;
       
   522 	}
       
   523 
       
   524 // -----------------------------------------------------------------------------
       
   525 // CIHLImageViewerExtJpg::VerticalMirroring
       
   526 // -----------------------------------------------------------------------------
       
   527 TBool CIHLImageViewerExtJpg::VerticalMirroring() const
       
   528 	{
       
   529 	return iVerticalMirroring;
       
   530 	}
       
   531 
       
   532 // -----------------------------------------------------------------------------
       
   533 // CIHLImageViewerExtJpg::SetHorizontalMirroring
       
   534 // -----------------------------------------------------------------------------
       
   535 TInt CIHLImageViewerExtJpg::SetHorizontalMirroring( TBool aValue )
       
   536 	{
       
   537 	if( iHorizontalMirroring != aValue )
       
   538 		{
       
   539 		iHorizontalMirroring = aValue;
       
   540 		return ApplySettings();
       
   541 		}
       
   542 	return KErrNone;
       
   543 	}
       
   544 
       
   545 // -----------------------------------------------------------------------------
       
   546 // CIHLImageViewerExtJpg::HorizontalMirroring
       
   547 // -----------------------------------------------------------------------------
       
   548 TBool CIHLImageViewerExtJpg::HorizontalMirroring() const
       
   549 	{
       
   550 	return iHorizontalMirroring;
       
   551 	}
       
   552 
       
   553 // -----------------------------------------------------------------------------
       
   554 // CIHLImageViewerExtJpg::SetFilter
       
   555 // -----------------------------------------------------------------------------
       
   556 void CIHLImageViewerExtJpg::SetFilter( MIHLFilter* /*aFilter*/ )
       
   557 	{
       
   558 	// Not in use
       
   559 	}
       
   560 
       
   561 
       
   562 
       
   563 // Private methods
       
   564 // -----------------------------------------------------------------------------
       
   565 // CIHLImageViewerExtJpg::DoCancel
       
   566 // -----------------------------------------------------------------------------
       
   567 void CIHLImageViewerExtJpg::DoCancel()
       
   568 	{
       
   569 	CTimer::DoCancel();
       
   570 	// Set state to inactive
       
   571 	switch( iViewerState )
       
   572 		{
       
   573 		case ELoad:
       
   574 			{
       
   575 			// Cancel asynchronous source loading
       
   576 			iSource.CancelLoad();
       
   577 			iCacheSource->Reset();
       
   578 			break;
       
   579 			}
       
   580 		case EProcess:
       
   581 			{
       
   582 			// Cancel asynchronous processing
       
   583 			iProcessor->CancelProcess();
       
   584 			iCacheDestination->Reset();
       
   585 			break;
       
   586 			}
       
   587 		default:
       
   588 			{
       
   589 			break;
       
   590 			}
       
   591 		}
       
   592 	}
       
   593 
       
   594 // -----------------------------------------------------------------------------
       
   595 // CIHLImageViewerExtJpg::RunL
       
   596 // -----------------------------------------------------------------------------
       
   597 void CIHLImageViewerExtJpg::RunL()
       
   598 	{
       
   599 	User::LeaveIfError( iStatus.Int() );
       
   600 
       
   601 	// Save previous state and set current state immediately
       
   602 	// to inactive to keep state up-to-date
       
   603 	TViewerState prevState( iViewerState );
       
   604 	iViewerState = EInactive;
       
   605 
       
   606 	switch( prevState )
       
   607 		{
       
   608 		case ELoad:
       
   609 			{
       
   610 			//Use the internal processor if the codec is lacking some processing capability
       
   611 			if( iInternalProcessingNeeded )
       
   612 				{
       
   613 				const CFbsBitmap& srcBitmap = iCacheSource->Bitmap();
       
   614 				User::LeaveIfError( iCacheDestination->Create( iDestinationSize, srcBitmap.DisplayMode() ) );
       
   615 				TRect processSourceRect( CalculateProcessSourceRect( iCacheSource->Bitmap().SizeInPixels() ) );
       
   616 				TRect destinationRect( CalculateProcessDestinationRect() );
       
   617 
       
   618 				User::LeaveIfError( iProcessor->Process( iStatus, *iCacheSource, processSourceRect,
       
   619 									  *iCacheDestination, destinationRect ) );
       
   620 
       
   621 				iViewerState = EProcess;
       
   622 				SetActive();
       
   623 				}
       
   624 			else
       
   625 				{
       
   626 				User::LeaveIfError( Finish() );
       
   627 				iObserver.ViewerBitmapChangedL();
       
   628 				}
       
   629 			break;
       
   630 			}
       
   631 		case EProcess:
       
   632 			{
       
   633 			User::LeaveIfError( Finish() );
       
   634 			iObserver.ViewerBitmapChangedL();
       
   635 			break;
       
   636 			}
       
   637 		default:
       
   638 			{
       
   639             // Internal state error, debug panic only
       
   640 			#ifdef _DEBUG
       
   641 				Panic( KErrGeneral );
       
   642 			#endif
       
   643 			}
       
   644 		}
       
   645 	}
       
   646 
       
   647 // -----------------------------------------------------------------------------
       
   648 // CIHLImageViewerExtJpg::RunError
       
   649 // -----------------------------------------------------------------------------
       
   650 TInt CIHLImageViewerExtJpg::RunError( TInt aError )
       
   651 	{
       
   652 	switch( iViewerState )
       
   653 		{
       
   654 		case ELoad:
       
   655 			{
       
   656 			// Cleanup cached source if load has been failed
       
   657 			iCacheSource->Reset();
       
   658 			break;
       
   659 			}
       
   660 		case EProcess:
       
   661 			{
       
   662 			// Cleanup cached destination if process has been failed
       
   663 			iCacheDestination->Reset();
       
   664 			break;
       
   665 			}
       
   666 		default:
       
   667 			{
       
   668 			break;
       
   669 			}
       
   670 		}
       
   671 
       
   672 	iViewerState = EInactive;
       
   673 	iObserver.ViewerError( aError );
       
   674 	return KErrNone;
       
   675 	}
       
   676 
       
   677 // -----------------------------------------------------------------------------
       
   678 // CIHLImageViewerExtJpg::ApplySettings
       
   679 // -----------------------------------------------------------------------------
       
   680 TInt CIHLImageViewerExtJpg::ApplySettings()
       
   681 	{
       
   682 	// Assert source rect and destination, debug build only
       
   683 #ifdef _DEBUG
       
   684 	AssertSourceRectAndDestinationSize();
       
   685 #endif
       
   686 
       
   687 	// Cancel current process if any
       
   688 	Cancel();
       
   689 
       
   690 	// Perform processing if supported by codec
       
   691 	if( !iInternalProcessingNeeded )
       
   692 		{
       
   693 		TRAPD( err, iSource.SetRotationL( iRotationAngle ) );
       
   694 		if( !err && iHorizontalMirroring )
       
   695 			{
       
   696 			TRAP( err, iSource.SetFlippingL() );
       
   697 			}
       
   698 		if( !err && iVerticalMirroring )
       
   699 			{
       
   700 			TRAP( err, iSource.SetMirroringL() );
       
   701 			}
       
   702 		if( err )
       
   703 			{
       
   704 			return err;
       
   705 			}
       
   706 		}
       
   707 
       
   708 	// Start async load/process.
       
   709 	TInt err( KErrNone );
       
   710 
       
   711 	err = AsyncLoad();
       
   712 	if( !err )
       
   713 		{
       
   714 		iViewerState = ELoad;
       
   715 		SetActive();
       
   716 		}
       
   717 
       
   718 	return err;
       
   719 	}
       
   720 
       
   721 // -----------------------------------------------------------------------------
       
   722 // CIHLImageViewerExtJpg::AsyncLoad
       
   723 // -----------------------------------------------------------------------------
       
   724 TInt CIHLImageViewerExtJpg::AsyncLoad()
       
   725 	{
       
   726     // Internal state check, debug panic only
       
   727 	__ASSERT_DEBUG( !iCacheDestination->Bitmap().Handle(), Panic( KErrGeneral ) );
       
   728 
       
   729 	TInt err( KErrNone );
       
   730 
       
   731 	// Load source bitmap
       
   732 
       
   733 	iCacheSource->Reset();
       
   734 
       
   735 	err = iCacheSource->Create( iDestinationSize, iSource.DisplayMode() );
       
   736 
       
   737 	if( !err )
       
   738 		{
       
   739 		err = iSource.Load( iSourceRect, iStatus, *iCacheSource );
       
   740 		}
       
   741 
       
   742 	// Error cleanup if needed
       
   743 	if( err )
       
   744 		{
       
   745 		iCacheSource->Reset();
       
   746 		}
       
   747 	return err;
       
   748 	}
       
   749 
       
   750 
       
   751 
       
   752 // -----------------------------------------------------------------------------
       
   753 // CIHLImageViewerExtJpg::Finish
       
   754 // -----------------------------------------------------------------------------
       
   755 TInt CIHLImageViewerExtJpg::Finish()
       
   756 	{
       
   757     // Internal state check, debug panic only
       
   758 	__ASSERT_DEBUG( iCacheSource->Bitmap().Handle(), Panic( KErrGeneral ) );
       
   759 
       
   760 	TInt err( KErrNone );
       
   761 
       
   762 	// Check if internal processor was used
       
   763 	if( iInternalProcessingNeeded )
       
   764 		{
       
   765 		err = iDestination.Copy( *iCacheDestination, ETrue );
       
   766 		iCacheDestination->Reset();
       
   767 		}
       
   768 	else
       
   769 		{
       
   770 		err = iDestination.Copy( *iCacheSource, ETrue );
       
   771 		iCacheSource->Reset();
       
   772 		}
       
   773 
       
   774 	// Error cleanup if needed
       
   775 	if( err )
       
   776 		{
       
   777 		iDestination.Reset();
       
   778 		}
       
   779 
       
   780 	return err;
       
   781 	}
       
   782 
       
   783 
       
   784 // -----------------------------------------------------------------------------
       
   785 // CIHLImageViewerExtJpg::SelfComplete
       
   786 // -----------------------------------------------------------------------------
       
   787 void CIHLImageViewerExtJpg::SelfComplete()
       
   788 	{
       
   789 	SetActive();
       
   790 	iStatus = KRequestPending;
       
   791 	TRequestStatus* status = &iStatus;
       
   792 	User::RequestComplete( status, KErrNone );
       
   793 	}
       
   794 
       
   795 // -----------------------------------------------------------------------------
       
   796 // CIHLImageViewerExtJpg::CalculateProcessSourceRect
       
   797 // -----------------------------------------------------------------------------
       
   798 TRect CIHLImageViewerExtJpg::CalculateProcessSourceRect( const TSize& aSourceCacheSize )
       
   799 	{
       
   800 
       
   801 	TRect loadRect( aSourceCacheSize );
       
   802 
       
   803 	switch( iRotationAngle )
       
   804 		{
       
   805 		case ERotationAngle0:
       
   806 			{
       
   807 			break;
       
   808 			}
       
   809 		case ERotationAngle90:
       
   810 			{
       
   811 			TInt tmp( loadRect.iTl.iY );
       
   812 			loadRect.iTl.iY = loadRect.iBr.iY;
       
   813 			loadRect.iBr.iY = tmp;
       
   814 			break;
       
   815 			}
       
   816 		case ERotationAngle180:
       
   817 			{
       
   818 			TPoint tmp( loadRect.iTl );
       
   819 			loadRect.iTl = loadRect.iBr;
       
   820 			loadRect.iBr = tmp;
       
   821 			break;
       
   822 			}
       
   823 		case ERotationAngle270:
       
   824 			{
       
   825 			TInt tmp( loadRect.iTl.iX );
       
   826 			loadRect.iTl.iX = loadRect.iBr.iX;
       
   827 			loadRect.iBr.iX = tmp;
       
   828 			break;
       
   829 			}
       
   830 		default:
       
   831 			{
       
   832             // Internal state error, debug panic only
       
   833             #ifdef _DEBUG
       
   834     			Panic( KErrGeneral );
       
   835             #endif
       
   836 			}
       
   837 		}
       
   838 
       
   839 	return loadRect;
       
   840 	}
       
   841 
       
   842 // -----------------------------------------------------------------------------
       
   843 // CIHLImageViewerExtJpg::CalculateProcessDestinationRect
       
   844 // -----------------------------------------------------------------------------
       
   845 TRect CIHLImageViewerExtJpg::CalculateProcessDestinationRect()
       
   846 	{
       
   847 	TRect dstRect( iDestinationSize );
       
   848 	switch( iRotationAngle )
       
   849 		{
       
   850 		case ERotationAngle0:
       
   851 		case ERotationAngle180:
       
   852 			{
       
   853 			if( iHorizontalMirroring )
       
   854 				{
       
   855 				TInt tmp( dstRect.iTl.iX );
       
   856 				dstRect.iTl.iX = dstRect.iBr.iX;
       
   857 				dstRect.iBr.iX = tmp;
       
   858 				}
       
   859 			if( iVerticalMirroring )
       
   860 				{
       
   861 				TInt tmp( dstRect.iTl.iY );
       
   862 				dstRect.iTl.iY = dstRect.iBr.iY;
       
   863 				dstRect.iBr.iY = tmp;
       
   864 				}
       
   865 			break;
       
   866 			}
       
   867 		case ERotationAngle90:
       
   868 		case ERotationAngle270:
       
   869 			{
       
   870 			if( iHorizontalMirroring )
       
   871 				{
       
   872 				TInt tmp( dstRect.iTl.iY );
       
   873 				dstRect.iTl.iY = dstRect.iBr.iY;
       
   874 				dstRect.iBr.iY = tmp;
       
   875 				}
       
   876 			if( iVerticalMirroring )
       
   877 				{
       
   878 				TInt tmp( dstRect.iTl.iX );
       
   879 				dstRect.iTl.iX = dstRect.iBr.iX;
       
   880 				dstRect.iBr.iX = tmp;
       
   881 				}
       
   882 			break;
       
   883 			}
       
   884 		default:
       
   885 			{
       
   886             // Internal state error, debug panic only
       
   887             #ifdef _DEBUG
       
   888 			    Panic( KErrGeneral );
       
   889             #endif
       
   890 			}
       
   891 		}
       
   892 	return dstRect;
       
   893 	}
       
   894 
       
   895 // -----------------------------------------------------------------------------
       
   896 // CIHLImageViewerExtJpg::CalculateZoomToFitRatio
       
   897 // -----------------------------------------------------------------------------
       
   898 void CIHLImageViewerExtJpg::CalculateZoomToFitRatio()
       
   899 	{
       
   900 	TSize sourceSize( SourceSize() );
       
   901 	TReal widthRatio( TReal( iViewerSize.iWidth ) / TReal( sourceSize.iWidth ) );
       
   902 	TReal heightRatio( TReal( iViewerSize.iHeight ) / TReal( sourceSize.iHeight ) );
       
   903 
       
   904 	if( iOptions & MIHLImageViewer::EOptionIgnoreAspectRatio )
       
   905 		{
       
   906 		iZoomToFitRatio = ( widthRatio > heightRatio ) ? widthRatio : heightRatio;
       
   907 		}
       
   908 	else
       
   909 		{
       
   910 		iZoomToFitRatio = ( widthRatio < heightRatio ) ? widthRatio : heightRatio;
       
   911 		}
       
   912 	}
       
   913 
       
   914 // -----------------------------------------------------------------------------
       
   915 // CIHLImageViewerExtJpg::CalculateSourceRectAndDestinationSize
       
   916 // -----------------------------------------------------------------------------
       
   917 void CIHLImageViewerExtJpg::CalculateSourceRectAndDestinationSize()
       
   918 	{
       
   919 	// Calculate new source rect
       
   920 	TSize oldSourceRectSize( iSourceRect.Size() );
       
   921 
       
   922 	TReal newSourceRectWidth;
       
   923 	TReal newSourceRectHeight;
       
   924 	TReal widthZoomRatio( iZoomRatio );
       
   925 	TReal heightZoomRatio( iZoomRatio );
       
   926 
       
   927 	if( iOptions & MIHLImageViewer::EOptionIgnoreAspectRatio )
       
   928 		{
       
   929 		TReal widthRatio( TReal( iViewerSize.iWidth ) / TReal( iSourceSize.iWidth ) );
       
   930 		TReal heightRatio( TReal( iViewerSize.iHeight ) / TReal( iSourceSize.iHeight ) );
       
   931 		if( widthRatio < heightRatio )
       
   932 			{
       
   933 			widthZoomRatio = widthZoomRatio * widthRatio / heightRatio;
       
   934 			}
       
   935 		else
       
   936 			{
       
   937 			heightZoomRatio = heightZoomRatio * heightRatio / widthRatio;
       
   938 			}
       
   939 		}
       
   940 
       
   941 	if( iRotationAngle == ERotationAngle90 ||
       
   942 		iRotationAngle == ERotationAngle270 )
       
   943 		{
       
   944 		newSourceRectWidth = iSrcBitmapScaleFactor * iViewerSize.iHeight / heightZoomRatio; //widthZoomRatio
       
   945 		newSourceRectHeight = iSrcBitmapScaleFactor * iViewerSize.iWidth / widthZoomRatio; //heightZoomRatio
       
   946 		}
       
   947 	else
       
   948 		{
       
   949 		newSourceRectWidth = iSrcBitmapScaleFactor * iViewerSize.iWidth / widthZoomRatio;
       
   950 		newSourceRectHeight = iSrcBitmapScaleFactor * iViewerSize.iHeight / heightZoomRatio;
       
   951 		}
       
   952 
       
   953 	// Check if source rect is not larger than source area
       
   954 	if( newSourceRectWidth > iSourceSize.iWidth )
       
   955 		{
       
   956 		newSourceRectWidth = iSourceSize.iWidth;
       
   957 		}
       
   958 	if( newSourceRectHeight > iSourceSize.iHeight )
       
   959 		{
       
   960 		newSourceRectHeight = iSourceSize.iHeight;
       
   961 		}
       
   962 	iSourceRect.SetWidth( (TInt)newSourceRectWidth );
       
   963 	iSourceRect.SetHeight( (TInt)newSourceRectHeight );
       
   964 
       
   965 	// Calculate actual destination size (always same or smaller than iViewerSize !)
       
   966 	if( iRotationAngle == ERotationAngle90 ||
       
   967 		iRotationAngle == ERotationAngle270 )
       
   968 		{
       
   969 		iDestinationSize.iWidth = (TInt)( newSourceRectHeight * widthZoomRatio ); //heightZoomRatio
       
   970 		iDestinationSize.iHeight = (TInt)( newSourceRectWidth * heightZoomRatio  ); //widthZoomRatio
       
   971 		}
       
   972 	else
       
   973 		{
       
   974 		iDestinationSize.iWidth = (TInt)( newSourceRectWidth * widthZoomRatio );
       
   975 		iDestinationSize.iHeight = (TInt)( newSourceRectHeight * heightZoomRatio );
       
   976 		}
       
   977 	// Check that destination size is not rounded to zero
       
   978 	if( iDestinationSize.iWidth == 0 )
       
   979 		{
       
   980 		iDestinationSize.iWidth = 1;
       
   981 		}
       
   982 	if( iDestinationSize.iHeight == 0 )
       
   983 		{
       
   984 		iDestinationSize.iHeight = 1;
       
   985 		}
       
   986 
       
   987 	// Move source rect keeping center point in same location
       
   988 	iSourceRect.Move( ( oldSourceRectSize.iWidth - (TInt)newSourceRectWidth ) / 2,
       
   989 					  ( oldSourceRectSize.iHeight - (TInt)newSourceRectHeight ) / 2 );
       
   990 
       
   991 	// Move rect if partially out of source area
       
   992 	TPoint moveOffset( 0, 0 );
       
   993 	if( iSourceRect.iTl.iX < 0 )
       
   994 		{
       
   995 		moveOffset.iX = -iSourceRect.iTl.iX;
       
   996 		}
       
   997 	else if( iSourceRect.iBr.iX > iSourceSize.iWidth )
       
   998 		{
       
   999 		moveOffset.iX = iSourceSize.iWidth - iSourceRect.iBr.iX;
       
  1000 		}
       
  1001 	if( iSourceRect.iTl.iY < 0 ) //lint !e961
       
  1002 		{
       
  1003 		moveOffset.iY = -iSourceRect.iTl.iY;
       
  1004 		}
       
  1005 	else if( iSourceRect.iBr.iY > iSourceSize.iHeight )
       
  1006 		{
       
  1007 		moveOffset.iY = iSourceSize.iHeight - iSourceRect.iBr.iY;
       
  1008 		}
       
  1009 	iSourceRect.Move( moveOffset );  //lint !e961
       
  1010 
       
  1011 	// Assert that rectangle is valid, debug build only
       
  1012 #ifdef _DEBUG
       
  1013 	AssertSourceRectAndDestinationSize();
       
  1014 #endif
       
  1015 	}
       
  1016 
       
  1017 // -----------------------------------------------------------------------------
       
  1018 // CIHLImageViewerExtJpg::AssertSourceRectAndDestinationSize
       
  1019 // Used in debug build only
       
  1020 // -----------------------------------------------------------------------------
       
  1021 #ifdef _DEBUG
       
  1022 void CIHLImageViewerExtJpg::AssertSourceRectAndDestinationSize()
       
  1023 	{
       
  1024 	if( iSourceRect.iTl.iX < 0 ||
       
  1025 		iSourceRect.iBr.iX > iSourceSize.iWidth ||
       
  1026 		iSourceRect.iTl.iY < 0 ||
       
  1027 		iSourceRect.iBr.iY > iSourceSize.iHeight ||
       
  1028 		iDestinationSize.iWidth <= 0 || iDestinationSize.iHeight <= 0 )
       
  1029 		{
       
  1030 		Panic( KErrGeneral );
       
  1031 		}
       
  1032 	}
       
  1033 #endif
       
  1034 
       
  1035 //  End of File
       
  1036 
       
  1037