/*
* Copyright (c) 2005-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:
* Provides methods for CPbk2ImageManager implementation classes
*
*/
// INCLUDE FILES
#include "CPbk2ImageWriterBase.h"
// From Phonebook2
#include "CPbk2ImageReader.h"
#include "MPbk2ImageOperationObservers.h"
#include "CPbk2ImageData.h"
#include "Pbk2PresentationUtils.h"
// From System
#include <imageconversion.h>
#include <bitmaptransforms.h>
/// Unnamed namespace for local defintions
namespace {
// LOCAL CONSTANTS
/// JPEG file mime type
_LIT8(KJpegMimeType, "image/jpeg");
// States for CPbk2ImageWriterBase
enum TWriterState
{
EStateInitialize = 0,
EStateCheckFormatAndSize,
EStateScaleBitmap,
EStateCreateImage,
EStateConvertToJpeg,
EStateStoreImage,
EStateComplete,
EStateEnd
};
#ifdef _DEBUG
enum TPanicCode
{
EPanicPreCond_ConstructL,
EPanicPreCond_CheckFormatAndSizeL,
EPanicPreCond_ScaleBitmapL,
EPanicPreCond_CreateImageL,
EPanicPreCond_ConvertToJpegL,
EPanicPreCond_StoreImageL,
EPanicPreCond_DoCancel
};
#endif // _DEBUG
// ==================== LOCAL FUNCTIONS ====================
/**
* Comparison operator for TSize objects. Compares width and height members.
*
* @param aLhs Reference to left hand side TSize
* @param aRhs Reference to right hand side TSize
* @return ETrue if lhs's width and height are less or equal to rhs's
* width and height. Otherwise returns EFalse.
*/
inline TBool operator<=(const TSize& aLhs, const TSize& aRhs)
{
return (aLhs.iWidth<=aRhs.iWidth && aLhs.iHeight<=aRhs.iHeight);
}
#ifdef _DEBUG
void Panic(TPanicCode aReason)
{
_LIT(KPanicText, "CPbk2ImageWriterBase");
User::Panic(KPanicText,aReason);
}
#endif // _DEBUG
} // namespace
// ================= MEMBER FUNCTIONS =======================
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::CPbk2ImageWriterBase
// --------------------------------------------------------------------------
//
CPbk2ImageWriterBase::CPbk2ImageWriterBase
(MPbk2ImageSetObserver& aObserver) :
CActive(CActive::EPriorityStandard),
iObserver(aObserver)
{
CActiveScheduler::Add(this);
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::~CPbk2ImageWriterBase
// --------------------------------------------------------------------------
//
CPbk2ImageWriterBase::~CPbk2ImageWriterBase()
{
Cancel();
delete iImageEncoder;
delete iBitmapScaler;
delete iBitmap;
delete iImageData;
delete iImageReader;
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::ConstructL
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::ConstructL()
{
__ASSERT_DEBUG(!iImageReader, Panic(EPanicPreCond_ConstructL));
iImageReader = CPbk2ImageReader::NewL(*this);
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::StartWriteL
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::StartWriteL(const CFbsBitmap& aBitmap)
{
CancelWrite();
iBitmap = new(ELeave) CFbsBitmap;
User::LeaveIfError(iBitmap->Duplicate(aBitmap.Handle()));
ScaleBitmapL();
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::StartWriteL
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::StartWriteL(const TDesC8& aBuffer)
{
CancelWrite();
if (iImageData)
{
delete iImageData;
iImageData = NULL;
}
iImageData = CPbk2ImageBufferData::NewL(aBuffer);
iImageReader->RecognizeFormatFromBufferL(aBuffer);
TPbk2ImageManagerParams readerParams;
SetupReaderParams(readerParams);
iImageReader->ReadFromBufferL(aBuffer,&readerParams);
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::StartWriteL
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::StartWriteL(const TDesC& aFileName)
{
CancelWrite();
if (iImageData)
{
delete iImageData;
iImageData = NULL;
}
iImageData = CPbk2ImageFileData::NewL(aFileName);
iImageReader->RecognizeFormatFromFileL(aFileName);
TPbk2ImageManagerParams readerParams;
SetupReaderParams(readerParams);
iImageReader->ReadFromFileL(aFileName, &readerParams);
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::CancelWrite
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::CancelWrite()
{
Cancel();
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::ImageReadComplete
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::ImageReadComplete
(CPbk2ImageReader& /*aReader*/, CFbsBitmap* aBitmap)
{
delete iBitmap;
iBitmap = aBitmap;
NextState();
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::ImageReadFailed
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::ImageReadFailed
(CPbk2ImageReader& /*aReader*/, TInt aError)
{
CancelWrite();
iObserver.Pbk2ImageSetFailed(*this,aError);
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::ImageOpenComplete
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::ImageOpenComplete(CPbk2ImageReader& /*aReader*/)
{
NextState();
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::NextState
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::NextState()
{
++iState;
TRAPD(err, ExecuteStateL());
if (err)
{
CancelWrite();
iObserver.Pbk2ImageSetFailed(*this,err);
}
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::ExecuteStateL
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::ExecuteStateL()
{
switch (iState)
{
case EStateCheckFormatAndSize:
{
CheckFormatAndSizeL();
break;
}
case EStateScaleBitmap:
{
ScaleBitmapL();
break;
}
case EStateCreateImage:
{
CreateImageL();
break;
}
case EStateConvertToJpeg:
{
ConvertToJpegL();
break;
}
case EStateStoreImage:
{
StoreImageL();
break;
}
case EStateComplete:
{
Complete();
break;
}
default:
{
// Media server objects might sometimes complete although they have
// been canceled. Catch those cases here.
CancelWrite();
break;
}
}
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::CheckFormatAndSizeL
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::CheckFormatAndSizeL()
{
__ASSERT_DEBUG(iImageReader, Panic(EPanicPreCond_CheckFormatAndSizeL));
iState = EStateCheckFormatAndSize;
TFrameInfo frameInfo;
iImageReader->FrameInfo(0,frameInfo);
if (frameInfo.iOverallSizeInPixels <= ImageSize() &&
iImageReader->MimeString() == KJpegMimeType)
{
// Image resolution is <= personal image size and it is in JPEG
// format -> store the image directly skipping scaling and
// conversion.
iImageReader->Cancel();
StoreImageL();
}
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::ScaleBitmapL
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::ScaleBitmapL()
{
__ASSERT_DEBUG(iBitmap, Panic(EPanicPreCond_ScaleBitmapL));
iState = EStateScaleBitmap;
Pbk2PresentationImageUtils::CropImageL(
*iBitmap,
Pbk2PresentationImageUtils::EOptimizedCropping,
ImageSize() );
if (iBitmap->SizeInPixels() <= ImageSize())
{
// Bitmap size is <= personal image size -> skip scaling
CreateImageL();
}
else
{
if (!iBitmapScaler)
{
iBitmapScaler = CBitmapScaler::NewL();
}
iBitmapScaler->Scale(&iStatus, *iBitmap, ImageSize());
SetActive();
}
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::CreateImageL
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::CreateImageL()
{
__ASSERT_DEBUG(
iBitmap && iBitmap->SizeInPixels()<=ImageSize() && !iImageEncoder,
Panic(EPanicPreCond_CreateImageL));
iState = EStateCreateImage;
iImageEncoder = CreateImageWriterL();
TRequestStatus* status = &iStatus;
User::RequestComplete(status, KErrNone);
SetActive();
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::ConvertToJpegL
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::ConvertToJpegL()
{
__ASSERT_DEBUG(
iBitmap && iBitmap->SizeInPixels()<=ImageSize() && iImageEncoder,
Panic(EPanicPreCond_ConvertToJpegL));
iImageEncoder->Convert(&iStatus, *iBitmap);
SetActive();
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::StoreImageL
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::StoreImageL()
{
iState = EStateStoreImage;
if (iImageEncoder)
{
// Store converted image
StoreImageL(*iImageEncoder);
}
else
{
// Store input image directly
__ASSERT_DEBUG(iImageData, Panic(EPanicPreCond_StoreImageL));
StoreImageL(*iImageData);
}
// this causes moving to next state asynchronously
TRequestStatus* status = &iStatus;
User::RequestComplete(status, KErrNone);
SetActive();
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::Complete
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::Complete()
{
// End state machine
iState = EStateEnd;
// Notify observer
iObserver.Pbk2ImageSetComplete(*this);
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::SetupReaderParams
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::SetupReaderParams(TPbk2ImageManagerParams& aParams)
{
aParams.iSize = ImageSize();
aParams.iFlags =
TPbk2ImageManagerParams::EScaleImage |
TPbk2ImageManagerParams::EUseFastScaling;
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::RunL
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::RunL()
{
TInt status = iStatus.Int();
if (status == KErrNone)
{
NextState();
}
else
{
iObserver.Pbk2ImageSetFailed(*this, status);
}
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::RunError
// --------------------------------------------------------------------------
//
TInt CPbk2ImageWriterBase::RunError(TInt aError)
{
iObserver.Pbk2ImageSetFailed(*this, aError);
return KErrNone;
}
// --------------------------------------------------------------------------
// CPbk2ImageWriterBase::DoCancel
// --------------------------------------------------------------------------
//
void CPbk2ImageWriterBase::DoCancel()
{
__ASSERT_DEBUG(iImageReader, Panic(EPanicPreCond_DoCancel));
// Cancel own operations
iState = EStateInitialize;
if (iImageEncoder)
{
iImageEncoder->Cancel();
delete iImageEncoder;
iImageEncoder = NULL;
}
if (iBitmapScaler)
{
iBitmapScaler->Cancel();
}
iImageReader->Cancel();
delete iImageData;
iImageData = NULL;
delete iBitmap;
iBitmap = NULL;
}
// End of File