--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook/View/src/CPbkImageReader.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,399 @@
+/*
+* Copyright (c) 2002 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 Phonebook image reader class methods.
+*
+*/
+
+
+// INCLUDE FILES
+#include "CPbkImageReader.h"
+#include "MPbkImageReaderObserver.h"
+#include "TPbkImageLoadParameters.h"
+
+#include <imageconversion.h>
+#include <bitmaptransforms.h>
+
+/// Unnamed namespace for local defintions
+namespace {
+
+// LOCAL CONSTANTS AND MACROS
+
+enum TReaderState
+ {
+ EStateIntialize = 0,
+ EStateOpenImage,
+ EStateConvertImageToBitmap,
+ EStateScaleBitmap,
+ EStateComplete,
+ EStateCancelled
+ };
+
+const TInt KMaxMimeTypeLength = 256;
+
+#ifdef _DEBUG
+enum TPanicCode
+ {
+ EPanicPreCond_ConvertImageToBitmapL = 1,
+ EPanicPreCond_ScaleBitmapL,
+ EPanicPreCond_Complete,
+ EPanicPostCond_Complete,
+ EPanicPostCond_OptimalLoadingSize
+ };
+#endif
+
+
+// ==================== LOCAL FUNCTIONS ====================
+
+#ifdef _DEBUG
+void Panic(TPanicCode aPanicCode)
+ {
+ _LIT(KPanicText, "CPbkImageReader");
+ User::Panic(KPanicText, aPanicCode);
+ }
+#endif
+
+inline TBool operator<=(const TSize& aLhs, const TSize& aRhs)
+ {
+ return (aLhs.iWidth<=aRhs.iWidth && aLhs.iHeight<=aRhs.iHeight);
+ }
+
+// Copied from CPalbBitmap, remove when possible
+TInt Ceil(const TInt aVal, const TInt aDiv)
+ {
+ return (((aVal%aDiv)>0) ? (TInt)((aVal/aDiv)+1):(TInt)(aVal/aDiv));
+ }
+
+// Copied from CPalbBitmap, remove when possible
+TSize SizeDividedByValueAndCeil(const TSize& aSize, const TInt aDiv)
+ {
+ return TSize(
+ Ceil( aSize.iWidth, aDiv),
+ Ceil( aSize.iHeight, aDiv) );
+ }
+
+// Copied from CPalbBitmap, remove when possible
+TSize OptimalLoadingSize(const TSize& aOriginalSize, const TSize& aNeededSize)
+ {
+ TSize resSize = SizeDividedByValueAndCeil( aOriginalSize, 8 );
+ if( !(aNeededSize <= resSize) )
+ {
+ resSize = SizeDividedByValueAndCeil( aOriginalSize, 4 );
+ if( !(aNeededSize <= resSize) )
+ {
+ resSize = SizeDividedByValueAndCeil( aOriginalSize, 2 );
+ if( !(aNeededSize <= resSize) )
+ {
+ resSize = aOriginalSize;
+ }
+ }
+ }
+
+ // if the resulting size is not the original size,
+ // it has to be between needed size and original size
+ __ASSERT_DEBUG(resSize == aOriginalSize
+ || (aNeededSize <= resSize && resSize <= aOriginalSize),
+ Panic(EPanicPostCond_OptimalLoadingSize));
+
+ return resSize;
+ }
+
+} // namespace
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+inline CPbkImageReader::CPbkImageReader
+ (MPbkImageReaderObserver& aObserver) :
+ CActive(CActive::EPriorityStandard),
+ iObserver(aObserver)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CPbkImageReader* CPbkImageReader::NewL
+ (MPbkImageReaderObserver& aObserver)
+ {
+ CPbkImageReader* self = new(ELeave) CPbkImageReader(aObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+void CPbkImageReader::ConstructL()
+ {
+ User::LeaveIfError(iFsSession.Connect());
+ }
+
+CPbkImageReader::~CPbkImageReader()
+ {
+ Cancel();
+ delete iBitmapScaler;
+ delete iImageDecoder;
+ delete iMimeString;
+ delete iBitmap;
+ iFsSession.Close();
+ }
+
+void CPbkImageReader::ReadFromFileL
+ (const TDesC& aFileName, const TPbkImageLoadParameters* aParams)
+ {
+ InitReadL(aParams);
+ delete iImageDecoder;
+ iImageDecoder = NULL;
+ iImageDecoder = CImageDecoder::FileNewL(iFsSession, aFileName);
+
+ // Make the open phase asynchronous as well by signaling own iStatus
+ iState = EStateOpenImage;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ SetActive();
+ }
+
+void CPbkImageReader::ReadFromBufferL
+ (const TDesC8& aBuffer, const TPbkImageLoadParameters* aParams/*=NULL*/)
+ {
+ InitReadL(aParams);
+ delete iImageDecoder;
+ iImageDecoder = NULL;
+ iImageDecoder = CImageDecoder::DataNewL(iFsSession, aBuffer);
+
+ // Make the open phase asynchronous as well by signaling own iStatus
+ iState = EStateOpenImage;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ SetActive();
+ }
+
+const TDesC8& CPbkImageReader::MimeString() const
+ {
+ if (iMimeString)
+ {
+ return *iMimeString;
+ }
+ else
+ {
+ return KNullDesC8;
+ }
+ }
+
+void CPbkImageReader::RecognizeFormatFromFileL(const TDesC& aFileName)
+ {
+ delete iMimeString;
+ iMimeString = NULL;
+ iMimeString = HBufC8::NewL(KMaxMimeTypeLength);
+ TPtr8 mimePtr = iMimeString->Des();
+ CImageDecoder::GetMimeTypeFileL(iFsSession, aFileName, mimePtr);
+ }
+
+void CPbkImageReader::RecognizeFormatFromBufferL(const TDesC8& aBuffer)
+ {
+ delete iMimeString;
+ iMimeString = NULL;
+ iMimeString = HBufC8::NewL(KMaxMimeTypeLength);
+ TPtr8 mimePtr = iMimeString->Des();
+ CImageDecoder::GetMimeTypeDataL(aBuffer, mimePtr);
+ }
+
+void CPbkImageReader::FrameInfo(TInt aFrame, TFrameInfo& aInfo) const
+ {
+ aInfo = iImageDecoder->FrameInfo(aFrame);
+ }
+
+TInt CPbkImageReader::FrameCount() const
+ {
+ return iImageDecoder->FrameCount();
+ }
+
+void CPbkImageReader::NextStateL()
+ {
+ ++iState;
+
+ switch (iState)
+ {
+ case EStateConvertImageToBitmap:
+ {
+ ConvertImageToBitmapL();
+ break;
+ }
+ case EStateScaleBitmap:
+ {
+ ScaleBitmapL();
+ break;
+ }
+ case EStateComplete:
+ {
+ Complete();
+ break;
+ }
+ default:
+ {
+ // iImageReader might sometimes complete although it has been canceled!
+ // Catch those cases here.
+ break;
+ }
+ }
+ }
+
+void CPbkImageReader::ConvertImageToBitmapL()
+ {
+ __ASSERT_DEBUG(iImageDecoder && !iBitmap,
+ Panic(EPanicPreCond_ConvertImageToBitmapL));
+
+ // Get image size
+ const TFrameInfo& frameInfo =
+ iImageDecoder->FrameInfo(iParams.iFrameNumber);
+ TSize bitmapSize = frameInfo.iOverallSizeInPixels;
+ if (iParams.iFlags & TPbkImageLoadParameters::EScaleImage)
+ {
+ // Get optimal loading size >= desired size
+ bitmapSize = OptimalLoadingSize(bitmapSize,iParams.iSize);
+ }
+
+ // Create bitmap
+ delete iBitmap;
+ iBitmap = NULL;
+ iBitmap = new(ELeave) CFbsBitmap;
+ User::LeaveIfError(iBitmap->Create(bitmapSize,iParams.iDisplayMode));
+
+ // Convert image to bitmap
+ iImageDecoder->Convert(&iStatus, *iBitmap, iParams.iFrameNumber);
+ SetActive();
+ }
+
+void CPbkImageReader::ScaleBitmapL()
+ {
+ __ASSERT_DEBUG(iBitmap, Panic(EPanicPreCond_ScaleBitmapL));
+
+ if ((iParams.iFlags & TPbkImageLoadParameters::EScaleImage) &&
+ !(iParams.iFlags & TPbkImageLoadParameters::EUseFastScaling))
+ {
+ const TSize bitmapSize = iBitmap->SizeInPixels();
+ if (bitmapSize.iWidth > iParams.iSize.iWidth ||
+ bitmapSize.iHeight > iParams.iSize.iHeight)
+ {
+ if (!iBitmapScaler)
+ {
+ iBitmapScaler = CBitmapScaler::NewL();
+ }
+ iBitmapScaler->Scale(&iStatus, *iBitmap, iParams.iSize);
+ SetActive();
+ return;
+ }
+ }
+
+ // No scaling requested or needed, go directly to next state
+ NextStateL();
+ }
+
+void CPbkImageReader::Complete()
+ {
+ __ASSERT_DEBUG(iImageDecoder && iBitmap, Panic(EPanicPreCond_Complete));
+
+ // End state machine
+ ++iState;
+
+ // Close the image source
+ CloseImage();
+
+ // Release ownership of iBitmap
+ CFbsBitmap* bitmap = iBitmap;
+ iBitmap = NULL;
+
+ __ASSERT_DEBUG(!iImageDecoder && !iBitmap,
+ Panic(EPanicPostCond_Complete));
+
+ // Notify observer about completion
+ iObserver.ImageReadComplete(*this,bitmap);
+ }
+
+void CPbkImageReader::InitReadL(const TPbkImageLoadParameters* aParams)
+ {
+ Cancel();
+ if (aParams)
+ {
+ iParams = *aParams;
+ }
+ iState = EStateOpenImage;
+ }
+
+void CPbkImageReader::CloseImage()
+ {
+ delete iImageDecoder;
+ iImageDecoder = NULL;
+ }
+
+void CPbkImageReader::RunL()
+ {
+ TInt status = iStatus.Int();
+ switch (status)
+ {
+ case KErrNone:
+ {
+ if (iState == EStateOpenImage)
+ {
+ iObserver.ImageOpenComplete(*this);
+ }
+ NextStateL();
+ break;
+ }
+ case KErrCancel:
+ {
+ // In case of cancel the observer is not signaled
+ break;
+ }
+ default:
+ {
+ iObserver.ImageReadFailed(*this, status);
+ break;
+ }
+ }
+ }
+
+void CPbkImageReader::Cancel()
+ {
+ if (!IsActive())
+ {
+ DoCancel();
+ }
+ else
+ {
+ CActive::Cancel();
+ }
+ }
+
+TInt CPbkImageReader::RunError(TInt aError)
+ {
+ iObserver.ImageReadFailed(*this, aError);
+ return KErrNone;
+ }
+
+void CPbkImageReader::DoCancel()
+ {
+ if (iImageDecoder)
+ {
+ iImageDecoder->Cancel();
+ }
+ if (iBitmapScaler)
+ {
+ iBitmapScaler->Cancel();
+ }
+ CloseImage();
+ delete iBitmap;
+ iBitmap = NULL;
+ iState = EStateCancelled;
+ }
+
+// End of File