imagehandlinglib/Src/CIHLFileImageExtJpg.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 26 Jan 2010 15:18:05 +0200
changeset 0 2014ca87e772
permissions -rw-r--r--
Revision: 201004

/*
* Copyright (c) 2006 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 FileImageExtJpg class.
*
*/


// INCLUDE FILES
#include "CIHLFileImageExtJpg.h"

#include "CIHLBitmap.h"
#include "IHLImplementationIds.h"
#include <IHLInterfaceIds.h>
#include <IclExtJpegApi.h>

// Private namespace for constants and functions
namespace
	{
	// Fixed scale factors
	enum TScaleFactors
		{
		EHalf		= 2,
		EQuarter	= 4,
		EEighth		= 8,
		};

	// Panic function
	_LIT( KIHLExtJpgPanic, "IHLImageExtJpg" );
	void Panic( TInt aPanicCode ) { User::Panic( KIHLExtJpgPanic, aPanicCode ); }
	}

// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
//
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
CIHLFileImageExtJpg::CIHLFileImageExtJpg( TInt aImageIndex )
:CActive( CActive::EPriorityStandard ),
iImageIndex( aImageIndex )
    {
	CActiveScheduler::Add( this );
    }

// -----------------------------------------------------------------------------
//
// Two-phased constructor.
// -----------------------------------------------------------------------------

CIHLFileImageExtJpg* CIHLFileImageExtJpg::NewL( RFs& aFs, const TDesC8& aDataBuf,
                                    TInt aImageIndex, const TUint32 aOptions )
    {
    CIHLFileImageExtJpg* self = new (ELeave) CIHLFileImageExtJpg( aImageIndex );
	CleanupStack::PushL( self );
	self->ConstructL( aFs, aDataBuf, aOptions );
	CleanupStack::Pop(); // self
    return self;
    }

CIHLFileImageExtJpg* CIHLFileImageExtJpg::NewL( RFs& aFs, const TDesC& aFilename, 
									TInt aImageIndex, const TUint32 aOptions )
    {
    CIHLFileImageExtJpg* self = new (ELeave) CIHLFileImageExtJpg( aImageIndex );
	CleanupStack::PushL( self );
	self->ConstructL( aFs, aFilename, aOptions );
	CleanupStack::Pop(); // self
    return self;
    }

// -----------------------------------------------------------------------------
//
// Symbian constructor can leave.
// -----------------------------------------------------------------------------


void CIHLFileImageExtJpg::ConstructL( RFs& aFs, const TDesC& aFilename, const TUint32 /*aOptions*/ )
	{
	TRAPD( err,	iDecoder = CExtJpegDecoder::FileNewL( CExtJpegDecoder::EHwImplementation, aFs, aFilename ) );
	
	if ( err != KErrNone )
		{
		iDecoder = CExtJpegDecoder::FileNewL( CExtJpegDecoder::ESwImplementation, aFs, aFilename );
		}

	ConstructCommonL();
	}
	
void CIHLFileImageExtJpg::ConstructL( RFs& aFs, const TDesC8& aDataBuf, const TUint32 /*aOptions*/ )
    {
	TRAPD( err,	iDecoder = CExtJpegDecoder::DataNewL( CExtJpegDecoder::EHwImplementation, aFs, aDataBuf ) );
	
	if ( err != KErrNone )
		{
		iDecoder = CExtJpegDecoder::DataNewL( CExtJpegDecoder::ESwImplementation, aFs, aDataBuf );
		}
    
	ConstructCommonL();
    }
		
// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::ConstructCommonL
// -----------------------------------------------------------------------------	
void CIHLFileImageExtJpg::ConstructCommonL()
    {
	// Check frame count and image index
	iImageCount = iDecoder->FrameCount();
	__ASSERT_ALWAYS( iImageCount > 0, User::Leave( KErrCorrupt ) );

	// Get image types
	iDecoder->ImageType( iImageIndex, iImageType, iImageSubType );
	
	__ASSERT_ALWAYS( iImageIndex >= 0 && iImageIndex < iImageCount, User::Leave( KErrArgument ) );

	// cache frame info and set scale sizes
	iFrameInfo = iDecoder->FrameInfo( iImageIndex );
	if( iFrameInfo.iFlags & TFrameInfo::EFullyScaleable )
		{
		iFullyScaleable = ETrue;
		}
    }

// -----------------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------------
CIHLFileImageExtJpg::~CIHLFileImageExtJpg()
    {
	Cancel();
	delete iDecoder;
    }

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::Type
// -----------------------------------------------------------------------------
TIHLInterfaceType CIHLFileImageExtJpg::Type() const
	{
	return TIHLInterfaceType( KIHLInterfaceIdFileImage,
							  KIHLImplementationIdFileImageExtJpg );
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::ImageType
// -----------------------------------------------------------------------------
const TUid& CIHLFileImageExtJpg::ImageType() const
	{
	return iImageType;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::ImageSubType
// -----------------------------------------------------------------------------
const TUid& CIHLFileImageExtJpg::ImageSubType() const
	{
	return iImageSubType;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::ImageIndex
// -----------------------------------------------------------------------------
TInt CIHLFileImageExtJpg::ImageIndex() const
	{
	return iImageIndex;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::ImageCount
// -----------------------------------------------------------------------------
TInt CIHLFileImageExtJpg::ImageCount() const
	{
	return iImageCount;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::Size
// -----------------------------------------------------------------------------
TSize CIHLFileImageExtJpg::Size() const
	{
	return iFrameInfo.iOverallSizeInPixels;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::DisplayMode
// -----------------------------------------------------------------------------
TDisplayMode CIHLFileImageExtJpg::DisplayMode() const
	{
	TDisplayMode displayMode( iFrameInfo.iFrameDisplayMode );
	if( iFrameInfo.iFrameDisplayMode <= EGray256 )
		{
		displayMode = EGray256;
		}
	else if( iFrameInfo.iFrameDisplayMode <= EColor256 )
		{
		displayMode = EColor256;
		}

	return displayMode;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::MaskDisplayMode
// -----------------------------------------------------------------------------
TDisplayMode CIHLFileImageExtJpg::MaskDisplayMode() const
	{
	if( iFrameInfo.iFlags & TFrameInfo::ETransparencyPossible )
		{
		if( iFrameInfo.iFlags & TFrameInfo::EAlphaChannel )
			{
			return EGray256;
			}
		return EGray2;
		}
	return ENone;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::BackgroundColor
// -----------------------------------------------------------------------------
TRgb CIHLFileImageExtJpg::BackgroundColor() const
	{
	return iFrameInfo.iBackgroundColor;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::CustomLoadSizeArray
// -----------------------------------------------------------------------------
const RArray<TSize>& CIHLFileImageExtJpg::CustomLoadSizeArray() const
	{
	return iLoadSizeArray;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::IsFullyScaleable
// -----------------------------------------------------------------------------
TBool CIHLFileImageExtJpg::IsFullyScaleable() const
	{
	return iFullyScaleable;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::IsAnimation
// -----------------------------------------------------------------------------
TBool CIHLFileImageExtJpg::IsAnimation() const
	{
	return iAnimation;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::AnimationFrameCount
// -----------------------------------------------------------------------------
TInt CIHLFileImageExtJpg::AnimationFrameCount() const
	{
	return iAnimationFrameCount;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::AnimationFrameDelay
// -----------------------------------------------------------------------------
TTimeIntervalMicroSeconds32 CIHLFileImageExtJpg::AnimationFrameDelay( TInt aAnimationFrameIndex ) const
	{
	//Animation is not supported
	( void ) aAnimationFrameIndex;
	Panic( KErrNotSupported );
	return 0; 
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::Load
// -----------------------------------------------------------------------------
TInt CIHLFileImageExtJpg::Load( TRequestStatus& aStatus, MIHLBitmap& aDestination, TInt aFrameIndex )
	{
	iImageIndex = aFrameIndex;
	return LoadRequest( aStatus, aDestination, iImageIndex );
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::Load
// -----------------------------------------------------------------------------
TInt CIHLFileImageExtJpg::Load( TRect aSrcRect, TRequestStatus& aStatus, MIHLBitmap& aDestination, TInt aFrameIndex )
	{
	TRAPD( err, SetCroppingL( aSrcRect ) );
	if( err )
		{
		return err;
		}
	iImageIndex = aFrameIndex;
	return LoadRequest( aStatus, aDestination, iImageIndex );
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::LoadAnimation
// -----------------------------------------------------------------------------
TInt CIHLFileImageExtJpg::LoadAnimation( TRequestStatus& aStatus, MIHLBitmap& aDestination,
							  TInt aAnimationFrameIndex )
	{
	//Animation is not supported
	( void ) aStatus;
	( void ) aDestination;
	( void ) aAnimationFrameIndex;
	Panic( KErrNotSupported );
	return 0;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::IsBusy
// -----------------------------------------------------------------------------
TBool CIHLFileImageExtJpg::IsBusy() const
	{
	return ( iImageState != EInactive );
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::CancelLoad
// -----------------------------------------------------------------------------
void CIHLFileImageExtJpg::CancelLoad()
	{
	Cancel();
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::SetFilter
// -----------------------------------------------------------------------------
void CIHLFileImageExtJpg::SetFilter( MIHLFilter* /*aFilter*/ )
	{
	// Not in use
	}


// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::Decoder
// -----------------------------------------------------------------------------
const CExtJpegDecoder& CIHLFileImageExtJpg::Decoder() const
	{
	return *iDecoder;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::DoCancel
// -----------------------------------------------------------------------------
void CIHLFileImageExtJpg::DoCancel()
	{
	iDecoder->Cancel();

	// Delete all processed bitmaps
	ErrorCleanup();

	// Complete with cancel
	iImageState = EInactive;
	RequestComplete( KErrCancel );
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::RunL
// -----------------------------------------------------------------------------
void CIHLFileImageExtJpg::RunL()
	{
	__ASSERT_DEBUG( iDestination, Panic( KErrGeneral ) );
	User::LeaveIfError( iStatus.Int() );

	switch( iImageState )
		{
		case EStartLoad:
			{
			// start loading the bitmaps
			StartLoadL();
			break;
			}
		case ECompleteLoad:
			{
			// complete loading the bitmaps
			CompleteLoadL();
			break;
			}
		default:
			{
			Panic( KErrTotalLossOfPrecision );
			}
		}
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::RunError
// -----------------------------------------------------------------------------
TInt CIHLFileImageExtJpg::RunError( TInt aError )
	{
	// Delete all processed bitmaps
	ErrorCleanup();

	// Complete with error
	iImageState = EInactive;
	RequestComplete( aError );
	return KErrNone;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::LoadRequest
// -----------------------------------------------------------------------------
TInt CIHLFileImageExtJpg::LoadRequest( TRequestStatus& aStatus, MIHLBitmap& aDestination, TInt aFrameIndex )
	{
	if( IsBusy() )
		{
		return KErrNotReady;
		}

	if( aFrameIndex < 0 || aFrameIndex >= iDecoder->FrameCount() )
		{
		return KErrArgument;
		}

	const CFbsBitmap& dstBitmap = aDestination.Bitmap();
	if( !dstBitmap.Handle() )
		{
		return KErrArgument;
		}

	iImageStatus = &aStatus;
	*iImageStatus = KRequestPending;

	iDestination = static_cast<CIHLBitmap*>( &aDestination ); //lint !e826
	iFrameIndex = aFrameIndex;

	// Start the active object
	iImageState = EStartLoad;
	SelfComplete();
	return KErrNone;
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::StartLoadL
// -----------------------------------------------------------------------------
void CIHLFileImageExtJpg::StartLoadL()
	{
	CFbsBitmap& dstBitmap = iDestination->BitmapModifyable();
	CFbsBitmap& dstMask = iDestination->MaskModifyable();

	if( MaskDisplayMode() && dstMask.Handle() )
		{
		iDecoder->Convert( &iStatus, dstBitmap, dstMask, iFrameIndex );
		}
	else
		{
		dstMask.Reset();
		iDecoder->Convert( &iStatus, dstBitmap, iFrameIndex );
		}
	iImageState = ECompleteLoad;
	SetActive();
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::CompleteLoadL
// -----------------------------------------------------------------------------
void CIHLFileImageExtJpg::CompleteLoadL()
	{
	// Save source info destination
	iDestination->SetEditorPtr( this );
	iDestination->SetEditorValue( iFrameIndex );

	// Normal image ready
	iDestination = NULL;
	iImageState = EInactive;
	RequestComplete( KErrNone );
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::ErrorCleanup
// -----------------------------------------------------------------------------
void CIHLFileImageExtJpg::ErrorCleanup()
	{
	if( iDestination )
		{
		iDestination = NULL;
		}
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::SelfComplete
// -----------------------------------------------------------------------------
void CIHLFileImageExtJpg::SelfComplete()
	{
	SetActive();
	iStatus = KRequestPending;
	TRequestStatus* status = &iStatus;
	User::RequestComplete( status, KErrNone );
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::RequestComplete
// -----------------------------------------------------------------------------
void CIHLFileImageExtJpg::RequestComplete( TInt aReason )
	{
	ASSERT( iImageStatus );
	User::RequestComplete( iImageStatus, aReason );
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::SetCroppingL
// -----------------------------------------------------------------------------

void CIHLFileImageExtJpg::SetCroppingL( TRect aCropRect )
	{
	iDecoder->SetCroppingL( aCropRect );
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::SetStreamingL
// -----------------------------------------------------------------------------

void CIHLFileImageExtJpg::SetStreamingL( TSize& aMacroBlockSize )
	{
	iDecoder->SetStreamingL( aMacroBlockSize );
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::SetRotationL
// -----------------------------------------------------------------------------

void CIHLFileImageExtJpg::SetRotationL( TInt aDegree )
	{
	iDecoder->SetRotationL( aDegree );
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::SetFlippingL
// -----------------------------------------------------------------------------

void CIHLFileImageExtJpg::SetFlippingL()
	{
	iDecoder->SetFlippingL();
	}
	
// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::SetMirroringL
// -----------------------------------------------------------------------------

void CIHLFileImageExtJpg::SetMirroringL()
	{
	iDecoder->SetMirroringL();
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::SetDctDecodingL
// -----------------------------------------------------------------------------

void CIHLFileImageExtJpg::SetDctDecodingL()
	{
	iDecoder->SetDctDecodingL();
	}
	
// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::ConvertL
// -----------------------------------------------------------------------------

void CIHLFileImageExtJpg::ConvertL( 
                        TRequestStatus* aRequestStatus, 
                        const CVisualFrame* aDestinationFrame, 
                        TInt& aNoOfDecodedMBlocks,
                        TInt aFrameNumber )
	{
	iDecoder->ConvertL( 
                        aRequestStatus, 
                        aDestinationFrame, 
                        aNoOfDecodedMBlocks,
                        aFrameNumber );
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::ContinueConvertL
// -----------------------------------------------------------------------------

void CIHLFileImageExtJpg::ContinueConvertL( 
                        TRequestStatus* aRequestStatus, 
                        const CVisualFrame* aDestinationFrame, 
                        TInt& aNoOfDecodedMBlocks,
                        TInt aFrameNumber )
	{
	iDecoder->ContinueConvertL( 
                        aRequestStatus, 
                        aDestinationFrame, 
                        aNoOfDecodedMBlocks,
                        aFrameNumber );	
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::SupportedFormatsL
// -----------------------------------------------------------------------------

TInt CIHLFileImageExtJpg::SupportedFormatsL()
	{
	return iDecoder->SupportedFormatsL();
	}

// -----------------------------------------------------------------------------
// CIHLFileImageExtJpg::CapabilitiesL
// -----------------------------------------------------------------------------
	
TInt CIHLFileImageExtJpg::CapabilitiesL()
	{
	return iDecoder->CapabilitiesL();
	}
	
//End of file