--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PECengine/AttributeLibrary2/SrcWVAttributes/CPEngMyLogoConverter.cpp Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,573 @@
+/*
+* Copyright (c) 2005 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: MyLogo converter.
+*
+*/
+
+// INCLUDE FILES
+#include "CPEngMyLogoConverter.h"
+#include "PresenceDebugPrint.h"
+
+#include <E32Std.h>
+#include <PEngWVPresenceAttributes2.h>
+#include <ImageConversion.h>
+#include <BitmapTransforms.h>
+
+
+
+//LOCAL constants
+namespace
+ {
+ //MyLogo image frame
+ const TInt KPEngMyLogoFrame = 0;
+
+ //MyLogo converter panics
+ _LIT( KPEngMyLogoConverterPanic, "MyLogoConv" );
+
+ //MyLogo converter panic reasons
+ enum TPEngMyLogoConverterPanicReasons
+ {
+ EConvUnkownConvertState,
+ EConvNoImageDecoder,
+ EConvNoMyLogoBitmap,
+ EConvMyLogoBitmapExists,
+ EConvMyLogoEncoderExists,
+ EConvMyLogoScalerExists,
+ EConvParamsMissingNotifyNewLogo,
+ EConvParamsMissingVerifyMyLogoRequirements1,
+ EConvParamsMissingVerifyMyLogoRequirements2
+ };
+ }
+
+
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::FileNewL()
+// -----------------------------------------------------------------------------
+//
+CPEngMyLogoConverter* CPEngMyLogoConverter::FileNewL( const TDesC& aFileName,
+ MPEngMyLogoConversionObserver& aObserver )
+ {
+ CPEngMyLogoConverter* self = new ( ELeave ) CPEngMyLogoConverter( aObserver );
+ CleanupStack::PushL( self );
+ self->ConstructFromFileL( aFileName );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::DataNewL()
+// -----------------------------------------------------------------------------
+//
+CPEngMyLogoConverter* CPEngMyLogoConverter::DataNewL( const TDesC8& aImageData,
+ MPEngMyLogoConversionObserver& aObserver )
+ {
+ CPEngMyLogoConverter* self = new ( ELeave ) CPEngMyLogoConverter( aObserver );
+ CleanupStack::PushL( self );
+ self->ConstructFromDataL( aImageData );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+
+// Destructor
+CPEngMyLogoConverter::~CPEngMyLogoConverter()
+ {
+ CActive::Cancel();
+ iObserver.HandleConverterDestroy();
+
+ delete iImageDataBuffer;
+ delete iImageMimeTypeBuffer;
+ delete iImageFileNameBuffer;
+ delete iImageDecoder;
+ delete iImageEncoder;
+ delete iBitmapScaler;
+ delete iMyLogoBitmap;
+
+ iFs.Close();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::CPEngMyLogoConverter
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CPEngMyLogoConverter::CPEngMyLogoConverter( MPEngMyLogoConversionObserver& aObserver )
+ : CActive( EPriorityIdle ),
+ iState( EConverterIdle ),
+ iObserver( aObserver )
+ {
+ CActiveScheduler::Add( this );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::ConstructFromFileL()
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CPEngMyLogoConverter::ConstructFromFileL( const TDesC& aImageFile )
+ {
+ User::LeaveIfError( iFs.Connect() );
+ iImageFileNameBuffer = aImageFile.AllocL();
+
+ if ( aImageFile.Length() > 0 )
+ {
+ RFile imageFile;
+ CleanupClosePushL( imageFile );
+
+
+ //Try open source file with different access modes
+ TInt openErr = imageFile.Open( iFs, aImageFile, EFileShareReadersOnly );
+ if ( openErr != KErrNone )
+ {
+ openErr = imageFile.Open( iFs, aImageFile, EFileShareAny | EFileStream );
+ }
+ User::LeaveIfError( openErr );
+
+
+ //And read file contents to buffer
+ TInt fileSize;
+ User::LeaveIfError( imageFile.Size( fileSize ) );
+ iImageDataBuffer = HBufC8::NewL( fileSize );
+ TPtr8 imageData( iImageDataBuffer->Des() );
+
+ User::LeaveIfError( imageFile.Read( imageData ) );
+
+ CleanupStack::PopAndDestroy(); // imageFile
+
+
+ //And open image decoder to buffer
+ iImageDecoder = CImageDecoder::DataNewL( iFs,
+ *iImageDataBuffer,
+ CImageDecoder::EOptionAlwaysThread );
+ }
+
+ else
+ {
+ iImageDataBuffer = HBufC8::NewL( 0 );
+ iImageMimeTypeBuffer = HBufC8::NewL( 0 );
+ }
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::ConstructFromDataL()
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CPEngMyLogoConverter::ConstructFromDataL( const TDesC8& aImageData )
+ {
+ iImageFileNameBuffer = HBufC::NewL( 0 );
+
+ if ( aImageData.Length() > 0 )
+ {
+ //Make a local copy from image
+ iImageDataBuffer = aImageData.AllocL();
+
+ //And open image decoder to buffer
+ iImageDecoder = CImageDecoder::DataNewL( iFs,
+ *iImageDataBuffer,
+ CImageDecoder::EOptionAlwaysThread );
+ }
+
+ else
+ {
+ iImageDataBuffer = HBufC8::NewL( 0 );
+ iImageMimeTypeBuffer = HBufC8::NewL( 0 );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::IssueConvert()
+// -----------------------------------------------------------------------------
+//
+void CPEngMyLogoConverter::IssueConvert( TRequestStatus& aRequestStatus )
+ {
+ //Issue first image processing round
+ iStatus = KRequestPending;
+ SetStateActive( EConverterIdle );
+
+ TRequestStatus *s = &iStatus;
+ User::RequestComplete( s, KErrNone );
+
+ //And cache client request status so it can be signalled later
+ //Client request status must be also set to pending state..
+ iClientRequest = &aRequestStatus;
+ *iClientRequest = KRequestPending;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::RunL()
+// From CActive
+// -----------------------------------------------------------------------------
+//
+void CPEngMyLogoConverter::RunL()
+ {
+ PENG_DP( D_PENG_LIT( "CPEngMyLogoConverter::RunL() iState[%d], iStatus[%d]" ),
+ iState, iStatus.Int() );
+
+ switch ( iState )
+ {
+ case EConverterIdle:
+ {
+ if ( VerifyMyLogoRequirementsL() )
+ {
+ NotifyNewLogo();
+ ConversionCompletedD( KErrNone );
+ }
+
+ else
+ {
+ IssueImageOpenToBitmapL();
+ SetStateActive( EImageOpenToBitmap );
+ }
+
+ break;
+ }
+
+ case EImageOpenToBitmap:
+ {
+ User::LeaveIfError( iStatus.Int() );
+
+ delete iImageDecoder;
+ iImageDecoder = NULL;
+
+ IssueBitmapScaleDownL();
+ SetStateActive( EBitmapScaleDown );
+ break;
+ }
+
+
+ case EBitmapScaleDown:
+ {
+ User::LeaveIfError( iStatus.Int() );
+
+ delete iBitmapScaler;
+ iBitmapScaler = NULL;
+
+ IssueBitmapStoreToImageL();
+ SetStateActive( EBitmapStoreToImage );
+ break;
+ }
+
+ case EBitmapStoreToImage:
+ {
+ User::LeaveIfError( iStatus.Int() );
+ if ( iImageDataBuffer->Size() > KPEngWVMyLogoImageMaxByteSize )
+ {
+ User::Leave( KErrTooBig );
+ }
+
+ NotifyNewLogo();
+ ConversionCompletedD( KErrNone );
+ break;
+ }
+
+
+ default:
+ {
+ PanicConverter( EConvUnkownConvertState );
+ break;
+ }
+ }
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::RunError()
+// From CActive
+// -----------------------------------------------------------------------------
+//
+TInt CPEngMyLogoConverter::RunError( TInt aError )
+ {
+ PENG_DP( D_PENG_LIT( "CPEngMyLogoConverter::RunError [%d]" ), aError );
+
+ //RunL() has leaved. Stop the processing.
+ ConversionCompletedD( aError );
+
+ return KErrNone;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::DoCancel()
+// From CActive
+// -----------------------------------------------------------------------------
+//
+void CPEngMyLogoConverter::DoCancel()
+ {
+ //cancel the operation step currently running...
+ switch ( iState )
+ {
+ case EConverterIdle:
+ {
+ //no issued request to cancel
+ break;
+ }
+
+ case EImageOpenToBitmap:
+ {
+ iImageDecoder->Cancel();
+ break;
+ }
+
+ case EBitmapScaleDown:
+ {
+ iBitmapScaler->Cancel();
+ break;
+ }
+
+ case EBitmapStoreToImage:
+ {
+ iImageEncoder->Cancel();
+ break;
+ }
+
+ default:
+ {
+ //nothing to do
+ break;
+ }
+ }
+
+ //and complete original client request
+ User::RequestComplete( iClientRequest, KErrCancel );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::SetStateActive()
+// -----------------------------------------------------------------------------
+//
+void CPEngMyLogoConverter::SetStateActive( TLogoConverterState aNewState )
+ {
+ SetActive();
+ iState = aNewState;
+
+ //Give other threads a chance
+ User::After( 0 ); // CSI: 92 #
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::VerifyMyLogoRequirements()
+// -----------------------------------------------------------------------------
+//
+TBool CPEngMyLogoConverter::VerifyMyLogoRequirementsL()
+ {
+ __ASSERT_DEBUG( iImageDataBuffer,
+ PanicConverter( EConvParamsMissingVerifyMyLogoRequirements1 ) );
+
+ if ( iImageDataBuffer->Length() == 0 )
+ {
+ //Empty logo - no processing needed
+ return ETrue;
+ }
+
+
+ //verify image properties
+ __ASSERT_DEBUG( iImageDecoder && !iImageMimeTypeBuffer,
+ PanicConverter( EConvParamsMissingVerifyMyLogoRequirements2 ) );
+
+ if ( iImageDecoder->FrameCount() == 0 )
+ {
+ User::Leave( KErrNotSupported ); //no frames in image
+ }
+
+
+ TFrameInfo fi;
+ fi = iImageDecoder->FrameInfo( KPEngMyLogoFrame );
+
+
+ TUid imageType;
+ TUid imageSubType;
+ iImageDecoder->ImageType( KPEngMyLogoFrame, imageType, imageSubType );
+
+
+ //Check image type
+ if ( ( imageType != KImageTypeGIFUid ) && ( imageType != KImageTypeJPGUid ) )
+ {
+ PENG_DP( D_PENG_LIT( "CPEngMyLogoConverter::VerifyMyLogoRequirementsL() - wrong image format [%08x]" ),
+ imageType.iUid );
+ return EFalse;
+ }
+
+ //Check image pixel size
+ if ( ( fi.iOverallSizeInPixels.iHeight > KPEngWVMyLogoImageMaxHeight ) ||
+ ( fi.iOverallSizeInPixels.iWidth > KPEngWVMyLogoImageMaxWidth ) )
+ {
+ PENG_DP( D_PENG_LIT( "CPEngMyLogoConverter::VerifyMyLogoRequirementsL() - image pixel size too big h[%d] w[%d]" ),
+ fi.iOverallSizeInPixels.iHeight, fi.iOverallSizeInPixels.iWidth );
+ return EFalse;
+ }
+
+ //Check image byte size
+ if ( iImageDataBuffer->Size() > KPEngWVMyLogoImageMaxByteSize )
+ {
+ PENG_DP( D_PENG_LIT( "CPEngMyLogoConverter::VerifyMyLogoRequirementsL() - image byte size too big [%d]" ),
+ iImageDataBuffer->Size() );
+ return EFalse;
+ }
+
+
+ //Perfectly OK logo image.
+ if ( imageType == KImageTypeGIFUid )
+ {
+ iImageMimeTypeBuffer = KPEngWVMyLogoMimeImageGif().AllocL();
+ }
+ else
+ {
+ iImageMimeTypeBuffer = KPEngWVMyLogoMimeJpeg().AllocL();
+ }
+
+ return ETrue;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::IssueImageOpenToBitmapL()
+// -----------------------------------------------------------------------------
+//
+void CPEngMyLogoConverter::IssueImageOpenToBitmapL()
+ {
+ __ASSERT_DEBUG( !iMyLogoBitmap,
+ PanicConverter( EConvMyLogoBitmapExists ) );
+
+ __ASSERT_DEBUG( iImageDecoder,
+ PanicConverter( EConvNoImageDecoder ) );
+
+
+ //For future: This could be optimized to take just 1/8 sized image...
+ TFrameInfo fi;
+ fi = iImageDecoder->FrameInfo( KPEngMyLogoFrame );
+
+ iMyLogoBitmap = new( ELeave ) CFbsBitmap;
+ User::LeaveIfError( iMyLogoBitmap->Create( fi.iOverallSizeInPixels,
+ fi.iFrameDisplayMode ) );
+
+ iImageDecoder->Convert( &iStatus, *iMyLogoBitmap, KPEngMyLogoFrame );
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::IssueBitmapScaleDownL()
+// -----------------------------------------------------------------------------
+//
+void CPEngMyLogoConverter::IssueBitmapScaleDownL()
+ {
+ __ASSERT_DEBUG( !iBitmapScaler,
+ PanicConverter( EConvMyLogoScalerExists ) );
+
+ __ASSERT_DEBUG( iMyLogoBitmap,
+ PanicConverter( EConvNoMyLogoBitmap ) );
+
+
+ iBitmapScaler = CBitmapScaler::NewL();
+ iBitmapScaler->Scale( &iStatus,
+ *iMyLogoBitmap,
+ TSize( KPEngWVMyLogoImageMaxWidth, KPEngWVMyLogoImageMaxHeight ),
+ ETrue );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::IssueBitmapStoreToImageL()
+// -----------------------------------------------------------------------------
+//
+void CPEngMyLogoConverter::IssueBitmapStoreToImageL()
+ {
+ __ASSERT_DEBUG( !iImageEncoder && !iImageMimeTypeBuffer,
+ PanicConverter( EConvMyLogoEncoderExists ) );
+
+ __ASSERT_DEBUG( iMyLogoBitmap,
+ PanicConverter( EConvNoMyLogoBitmap ) );
+
+
+ iImageMimeTypeBuffer = KPEngWVMyLogoMimeJpeg().AllocL();
+
+ delete iImageDataBuffer;
+ iImageDataBuffer = NULL;
+
+ iImageEncoder = CImageEncoder::DataNewL( iImageDataBuffer,
+ KPEngWVMyLogoMimeJpeg,
+ CImageEncoder::EOptionAlwaysThread );
+ iImageEncoder->SetThumbnail( EFalse );
+ iImageEncoder->Convert( &iStatus, *iMyLogoBitmap );
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::NotifyNewLogo()
+// -----------------------------------------------------------------------------
+//
+void CPEngMyLogoConverter::NotifyNewLogo()
+ {
+ __ASSERT_DEBUG( iImageDataBuffer && iImageMimeTypeBuffer && iImageFileNameBuffer,
+ PanicConverter( EConvParamsMissingNotifyNewLogo ) );
+
+
+
+ iObserver.HandleNewMyLogo( iImageDataBuffer, iImageMimeTypeBuffer, iImageFileNameBuffer );
+
+ //HandleNewMyLogo took the ownership of passed
+ //iImageDataBuffer and iImageMimeTypeBuffer and iImageFileNameBuffer
+ //==> NULL own member pointers
+ iImageDataBuffer = NULL;
+ iImageMimeTypeBuffer = NULL;
+ iImageFileNameBuffer = NULL;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::ConversionCompletedD()
+// -----------------------------------------------------------------------------
+//
+void CPEngMyLogoConverter::ConversionCompletedD( TInt aStatus )
+ {
+ User::RequestComplete( iClientRequest, aStatus );
+ delete this;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPEngMyLogoConverter::PanicConverter()
+// -----------------------------------------------------------------------------
+//
+void CPEngMyLogoConverter::PanicConverter( TInt aPanicReason ) const
+ {
+ User::Panic( KPEngMyLogoConverterPanic, aPanicReason );
+ }
+
+
+
+// End of File
+
+