diff -r 000000000000 -r 40261b775718 imagingandcamerafws/imagingfws/ImageDisplay/src/ImageDisplayFramework.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imagingandcamerafws/imagingfws/ImageDisplay/src/ImageDisplayFramework.cpp Tue Feb 02 01:56:55 2010 +0200 @@ -0,0 +1,932 @@ +// Copyright (c) 2004-2009 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: +// + +/** @file + @internalComponent */ +#include +#include +#include "ImageDisplayFramework.h" +#include "ImageDisplay.h" +#include "ImageDisplay.hrh" +#include "ImageDisplayMain.h" +#include "../../src/ImageUtils.h" +#include "ImageDisplayResolverAPI.h" +#include "ImageDisplayResolvrUtils.h" +using namespace ContentAccess; + +/** +* NewL +* The function NewL constructs a CImageDisplayFramework +* +* @return CImageDisplayFramework* +* +*/ +CImageDisplayFramework* CImageDisplayFramework::NewL(CImageDisplay& aHandle, MIclImageDisplayObserver& aCallback, RFs& aFs) + { + CImageDisplayFramework* self = new(ELeave) CImageDisplayFramework(aHandle, aCallback, aFs); + return self; + } + +/** +* +* CImageDisplayFramework +* +*/ +CImageDisplayFramework::CImageDisplayFramework(CImageDisplay& aHandle, MIclImageDisplayObserver& aCallback, RFs& aFs) : + iHandle(aHandle), iCallback(aCallback), iFs(aFs) + { + Reset(); + } + +/** +* +* ~CImageDisplayFramework +* This is the destructor for the CImageDisplayFramework +* and is resposible for deallocating all resources +* allocated by the CImageDisplayFramework +* +*/ +CImageDisplayFramework::~CImageDisplayFramework() + { + // make sure any existing displayation is cancelled + if (iPlugin && (EStateProcessing == iState || iState == EStatePluginLoaded + || iState == EStatePaused)) + { + iPlugin->StopPlay(); + } + DeletePlugin(); + } + +CImageDisplayPlugin::TImageSourceType CImageDisplayFramework::SourceType() const + { + return iSourceImage.ImageSourceType(); + } + +const TDesC& CImageDisplayFramework::SourceFilename() const + { + if (CImageDisplayPlugin::EImgSrcFileName != iSourceImage.ImageSourceType()) + { + Panic(EImageWrongType); + } + return iSourceImage.Filename(); + } + +const TDesC8& CImageDisplayFramework::SourceData() const + { + if (CImageDisplayPlugin::EImgSrcDescriptor != iSourceImage.ImageSourceType()) + { + Panic(EImageWrongType); + } + return iSourceImage.Data(); + } + +RFile& CImageDisplayFramework::SourceFileHandle() const + { + if (CImageDisplayPlugin::EImgSrcFileHandle != iSourceImage.ImageSourceType()) + { + Panic(EImageWrongType); + } + return iSourceImage.FileHandle(); + } + +TInt CImageDisplayFramework::SetImageSource(const TMMSource& aImageSource) + { + if (EStatePluginLoaded == iState) + { + DeletePlugin(); + iState = EStateOpened; + } + if (iState != EStateOpened) + { + Panic(EIllegalCallSequence); + } + iState = EStateConfigured; + if (aImageSource.SourceType() == KUidMMFileSource) + { + iSourceImage.SetFilename(static_cast(aImageSource).Name()); + } + else if (aImageSource.SourceType() == KUidMMFileHandleSource) + { + iSourceImage.SetFileHandle(static_cast(aImageSource).Handle()); + } + else if (aImageSource.SourceType() == KUidDescDataSource) + { + iSourceImage.SetData(static_cast(aImageSource).DataBuf()); + } + else + { + return KErrNotSupported; + } + iSourceImage.SetIntent(aImageSource.Intent()); + iSourceImage.SetContentId(aImageSource.UniqueId()); + return KErrNone; + } + +void CImageDisplayFramework::SetSourceRect(const TRect& aRect) + { + if (!(EStateOpened == iState || EStateConfigured == iState || EStatePluginLoaded == iState)) + { + Panic(EIllegalCallSequence); + } + iSourceRect = aRect; + SetFlag(EFlagSourceRectSet); + } + +void CImageDisplayFramework::ResetSourceRect() + { + if (!(EStateOpened == iState || EStateConfigured == iState || EStatePluginLoaded == iState)) + { + Panic(EIllegalCallSequence); + } + ClearFlag(EFlagSourceRectSet); + } + +void CImageDisplayFramework::SetSizeInPixels(const TSize& aDestinationSize, TBool aMaintainAspectRatio) + { + if (!(EStateOpened == iState || EStateConfigured == iState || EStatePluginLoaded == iState)) + { + Panic(EIllegalCallSequence); + } + iDestinationSize = aDestinationSize; + if (aMaintainAspectRatio) + { + SetFlag(EFlagMaintainAspectRatio); + } + else + { + ClearFlag(EFlagMaintainAspectRatio); + } + } + +TInt CImageDisplayFramework::SetOptions(TUint aOptions) + { + if (!(EStateOpened == iState || EStateConfigured == iState)) + { + Panic(EIllegalCallSequence); + } + if ((aOptions & CImageDisplay::EOptionMainImage) != CImageDisplay::EOptionMainImage + && (aOptions & CImageDisplay::EOptionThumbnail) != CImageDisplay::EOptionThumbnail) + { + return KErrArgument; + } + iOptions = aOptions; + return KErrNone; + } + +void CImageDisplayFramework::SetSourceMimeType(const TDesC8& aMimeType) + { + if (!(EStateOpened == iState || EStateConfigured == iState)) + { + Panic(EIllegalCallSequence); + } + iSourceImage.SetMimeType(aMimeType); + } + +void CImageDisplayFramework::SetSourceImageType(TUid aImageType, TUid aImageSubType) + { + if (!(EStateOpened == iState || EStateConfigured == iState)) + { + Panic(EIllegalCallSequence); + } + iSourceImage.SetImageType(aImageType, aImageSubType); + } + +void CImageDisplayFramework::SetPluginUid(TUid aPluginUid) + { + if (!(EStateOpened == iState || EStateConfigured == iState)) + { + Panic(EIllegalCallSequence); + } + iPluginUid = aPluginUid; + } + +void CImageDisplayFramework::SetDisplayMode(TDisplayMode aDisplayMode) + { + if (!(EStateOpened == iState || EStateConfigured == iState)) + { + Panic(EIllegalCallSequence); + } + iDisplayMode = aDisplayMode; + } + +const TDesC8& CImageDisplayFramework::SourceMimeType() const + { + // this will return KNullDesC8 if not defined + return iSourceImage.MimeType(); + } + +const TUid CImageDisplayFramework::SourceImageType() const + { + return iSourceImage.ImageType(); + } + +const TUid CImageDisplayFramework::SourceImageSubType() const + { + return iSourceImage.ImageSubType(); + } + +TBool CImageDisplayFramework::SourceRect(TRect& aRect) const + { + if (FlagSet(EFlagSourceRectSet)) + { + aRect = iSourceRect; + return ETrue; + } + else + { + return EFalse; + } + } + +const TSize& CImageDisplayFramework::DestinationSizeInPixels() const + { + return iDestinationSize; + } + +TUint CImageDisplayFramework::Options() const + { + return iOptions; + } + +TBool CImageDisplayFramework::MaintainAspectRatio() const + { + return FlagSet(EFlagMaintainAspectRatio); + } + +TDisplayMode CImageDisplayFramework::DisplayMode() const + { + return iDisplayMode; + } + +void CImageDisplayFramework::CallbackImageReady(const CFbsBitmap* aBitmap, TUint aStatus, const TRect& aUpdatedArea, TInt aError) + { + if (CImageDisplayPlugin::EStatusNoMoreToDecode & aStatus) + { + iState = EStatePluginLoaded; + } + else if (CImageDisplayPlugin::EStatusPaused & aStatus) + { + iState = EStatePaused; + } + + iCallback.MiidoImageReady(aBitmap, aStatus, aUpdatedArea, aError); + } + +void CImageDisplayFramework::SetupL() + { + if (EStateConfigured != iState ) + { + Panic(EUndefinedSourceType); + } +// pre-conditions + if (iOptions == CImageDisplay::EOptionsUndefined) + { + User::Leave(KErrArgument); + } + if (!iSourceImage.IsDataTypeDefined()) + { + Panic(EUndefinedSourceType); + } + + DeletePlugin(); + + if (CImageDisplayPlugin::EImgSrcFileName == iSourceImage.ImageSourceType()) + { + // check arguments + TEntry entry; + User::LeaveIfError(iFs.Entry(iSourceImage.Filename(), entry)); + if (SourceMimeType() == KNullDesC8) + { + iPlugin = FileNewImplL( + iSourceImage.Filename(), + iSourceImage.ImageType(), + iSourceImage.ImageSubType(), + iPluginUid); + } + else + { + iPlugin = NewImplL(SourceMimeType()); + } + } + else if (CImageDisplayPlugin::EImgSrcFileHandle == iSourceImage.ImageSourceType()) + { + iPlugin = FileHandleNewImplL( + iSourceImage.FileHandle(), + iSourceImage.ImageType(), + iSourceImage.ImageSubType(), + iPluginUid + ); + } + else + { + if (iSourceImage.Data().Length() == 0) + { + User::Leave(KErrArgument); + } + if (SourceMimeType() == KNullDesC8) + { + iPlugin = DataNewL( + iSourceImage.Data(), + iSourceImage.ImageType(), + iSourceImage.ImageSubType(), + iPluginUid); + } + else + { + iPlugin = NewImplL(SourceMimeType()); + } + } + + ASSERT(iPlugin); + + // if the plugin leaves in the OpenL() call, then we should + // delete the plugin in case SetupL() is called again (with no Reset()) + TRAPD(err, iPlugin->OpenL()); + if (err != KErrNone) + { + DeletePlugin(); + User::Leave(err); + } + iState = EStatePluginLoaded; + } + +void CImageDisplayFramework::Play() + { + if (!(iState == EStateProcessing || iState == EStatePaused || iState == EStatePluginLoaded)) + { + Panic(EIllegalCallSequence); + } + if (iDestinationSize == TSize(0, 0)) + { + Panic(EUndefinedDestSize); + } + iState = EStateProcessing; + iPlugin->Play(); + } + +void CImageDisplayFramework::Pause() + { + if (!(iState == EStateProcessing || iState == EStatePaused)) + { + Panic(EIllegalCallSequence); + } + iState = EStatePaused; + iPlugin->Pause(); + } + +void CImageDisplayFramework::StopPlay() + { + if (EStateProcessing != iState && iState != EStatePluginLoaded && iState != EStatePaused) + { + Panic(EIllegalCallSequence); + } + iState = EStatePluginLoaded; + iPlugin->StopPlay(); + } + +void CImageDisplayFramework::Reset() + { + // Reset state to "just created" state + DeletePlugin(); + + iSourceImage.Reset(); + iDestinationSize = TSize(0, 0); + iDisplayMode = ENone; + ClearFlag(EFlagSourceRectSet); + iOptions = CImageDisplay::EOptionsUndefined; + iState = EStateOpened; + } + + +/** + * Create a display plugin for the image in the named file. The client supplies a + * MIME type which will be used to try and select an appropriate plugin + * Displayer. If it finds a Displayer it creates it and then goes on to use that + * displayer to scan the beginning of the image file. + * @internalTechnology + * @param "aFs" + * A reference to a file server session for the displayer to use. + * @param "aSourceFilename" + * The name of the file to be convertd. + * @param "aMIMEType" + * The MIME type of the image in the file. + * @return Returns a pointer to the newly created displayer. + * @leave KEComErrNoInterfaceIdentified + * No plugin displayers were found. + */ +CImageDisplayPlugin* CImageDisplayFramework::NewImplL(const TDesC8& aMIMEType) + { + //Get a sorted list of displayers that will handle the image + RImplInfoPtrArray displayerList; + CleanupResetAndDestroyPushL(displayerList); + MimeTypeGetDisplayerListL(displayerList, aMIMEType); + + CImageDisplayPlugin* displayer = NULL; + displayer = FindDisplayerNewL(displayerList); + ASSERT(displayer!=NULL); + + CleanupStack::PopAndDestroy(&displayerList); + return displayer; + } + + +/** + * + * Create a displayer for the image in the named file. If the client supplies an + * image type (and sub-type, if applicable) or displayer uid, these will be used + * to try and select an appropriate plugin displayer. If not, then the selection + * will be done by matching the image header in the file. If it finds a displayer + * it creates it and then goes on to use that displayer to scan the beginning of + * the image file. + * @internalTechnology + * @param "aFs" + * A reference to a file server session for the displayer to use. + * @param "aSourceFilename" + * The name of the file to be converted. + * @param "aImageType" + * The image type of the image in the file (optional, defaults to KNullUid). + * @param "aImageSubType" + * The image sub-type of the image in the file (optional, defaults to KNullUid). + * @param "aPluginUid" + * The implementation uid for a specific codec (optional, defaults to KNullUid). + * If this option is selected the image type and + * image sub type for the displayer must be supplied. + * @return Returns a pointer to the newly created displayer. + * @leave KErrUnderflow + * Not enough data in file to identify which plugin displayer to use. + * @leave KEComErrNoInterfaceIdentified + * No plugin displayers were found. + * @panic EIllegalImageSubType + * No base type given for sub-type. + * @panic EIllegalImageType + * No base type given for displayer implementation. + */ +CImageDisplayPlugin* CImageDisplayFramework::FileNewImplL( + const TDesC& aSourceFilename, + const TUid aImageType, + const TUid aImageSubType, + const TUid aPluginUid) + { + if ((aImageType == KNullUid) && (aImageSubType != KNullUid)) + { // Get out, no base type given for sub-type + Panic(EIllegalImageSubType); + } + + RImplInfoPtrArray displayerList; + CleanupResetAndDestroyPushL(displayerList); + + TBuf8 imageHeader; + + ContentAccess::CData* data = ContentAccess::CData::NewLC(TVirtualPathPtr(aSourceFilename, iSourceImage.ContentId()), ContentAccess::EContentShareReadOnly); + TInt err = data->SetProperty(EAgentPropertyAgentUI, iSourceImage.IsUIEnabled()); + // KErrCANotSupported doesn't prevent us from continuing so eat the error code. + if (err != KErrNone && err != KErrCANotSupported) + { + User::Leave(err); + } + User::LeaveIfError(data->Read(imageHeader, KImageHeaderSize)); + + TRAP(err, ImageTypeGetDisplayerListL( + displayerList, + imageHeader, + aImageType, + aImageSubType, + aPluginUid) + ); + + if (!(err==KErrNone || err==KErrUnderflow)) + { + User::Leave(err); + } + + //Try to match by file extension only + //1) If no plugin was found and + //2) No specific displayer or format was specified + const TBool formatSpecified = (aImageType!=KNullUid || aImageSubType!=KNullUid || aPluginUid!=KNullUid); + if(displayerList.Count()==0 && !formatSpecified) + { + SuffixTypeGetDisplayerListL( + displayerList, + aSourceFilename); + } + + CImageDisplayPlugin* displayer = NULL; + displayer = FindDisplayerNewL(displayerList); + + ASSERT(displayer!=NULL); + + CleanupStack::PushL(displayer); + User::LeaveIfError( data->EvaluateIntent(iSourceImage.Intent()) ); + CleanupStack::Pop(displayer); + CleanupStack::PopAndDestroy(2, &displayerList); + return displayer; + } + +/** + * + * Create a displayer for the image using the given file handle. If the client supplies an + * image type (and sub-type, if applicable) or displayer uid, these will be used + * to try and select an appropriate plugin displayer. If not, then the selection + * will be done by matching the image header in the file. If it finds a displayer + * it creates it and then goes on to use that displayer to scan the beginning of + * the image file. + * @internalTechnology + * @param "aFileHandle" + * A reference to a file handle that contains an image data + * @param "aImageType" + * The image type of the image in the file (optional, defaults to KNullUid). + * @param "aImageSubType" + * The image sub-type of the image in the file (optional, defaults to KNullUid). + * @param "aPluginUid" + * The implementation uid for a specific codec (optional, defaults to KNullUid). + * If this option is selected the image type and + * image sub type for the displayer must be supplied. + * @return Returns a pointer to the newly created displayer. + * @leave KErrUnderflow + * Not enough data in file to identify which plugin displayer to use. + * @leave KEComErrNoInterfaceIdentified + * No plugin displayers were found. + * @panic EIllegalImageSubType + * No base type given for sub-type. + * @panic EIllegalImageType + * No base type given for displayer implementation. + */ +CImageDisplayPlugin* CImageDisplayFramework::FileHandleNewImplL( + RFile& aFileHandle, + const TUid aImageType, + const TUid aImageSubType, + const TUid aPluginUid) + { + if ((aImageType == KNullUid) && (aImageSubType != KNullUid)) + { // Get out, no base type given for sub-type + Panic(EIllegalImageSubType); + } + + RImplInfoPtrArray displayerList; + CleanupResetAndDestroyPushL(displayerList); + + TBuf8 imageHeader; + + ContentAccess::CData* data = ContentAccess::CData::NewLC(aFileHandle, iSourceImage.ContentId()); + TInt err = data->SetProperty(EAgentPropertyAgentUI, iSourceImage.IsUIEnabled()); + // KErrCANotSupported doesn't prevent us from continuing so eat the error code. + if (err != KErrNone && err != KErrCANotSupported) + { + User::Leave(err); + } + User::LeaveIfError(data->Read(imageHeader, KImageHeaderSize)); + + ImageTypeGetDisplayerListL( + displayerList, + imageHeader, + aImageType, + aImageSubType, + aPluginUid); + + CImageDisplayPlugin* displayer = NULL; + displayer = FindDisplayerNewL(displayerList); + ASSERT(displayer!=NULL); + + CleanupStack::PushL(displayer); + User::LeaveIfError( data->EvaluateIntent(iSourceImage.Intent()) ); + CleanupStack::Pop(displayer); + CleanupStack::PopAndDestroy(2, &displayerList); + return displayer; + } + + +/** +Creates a displayer for the image in the source buffer. + +If the client supplies an image type (and sub-type, if applicable) or displayer UID, +these will be used to try and select an appropriate plugin displayer. If not, then +the selection will be done by matching the image header from the buffer. If it +finds a displayer, it is created and then used to scan the beginning of the image +buffer. + +@param aSourceData + The buffer containing the image to be displayed. +@param aImageType + The image type of the image in the file (optional, defaults to KNullUid). +@param aImageSubType + The image sub-type of the image in the file (optional, defaults to KNullUid). +@param aPluginUid + The implementation UID for a specific codec (optional, defaults to KNullUid). + If this option is selected the image type and + image sub type for the displayer must be supplied. + +@return Returns a pointer to the newly created displayer. + +@leave KErrUnderflow + Not enough data in descriptor to identify which plugin displayer to use. +@leave KEComErrNoInterfaceIdentified + No plugin displayers were found. +@panic EIllegalImageSubType + No base type given for sub-type. + +*/ +CImageDisplayPlugin* CImageDisplayFramework::DataNewL( + const TDesC8& aSourceData, + const TUid aImageType, + const TUid aImageSubType, + const TUid aPluginUid) + { + + if ((aImageType == KNullUid) && (aImageSubType != KNullUid)) + { // Get out, no base type given for sub-type + Panic(EIllegalImageSubType); + } + + //Get a list of displayers that will convert the image + RImplInfoPtrArray displayerList; + CleanupResetAndDestroyPushL(displayerList); + ImageTypeGetDisplayerListL(displayerList, aSourceData, aImageType, aImageSubType, aPluginUid); + + CImageDisplayPlugin* displayer = NULL; + displayer = FindDisplayerNewL(displayerList); + ASSERT(displayer!=NULL); + + CleanupStack::PopAndDestroy(&displayerList); + return displayer; + } + + + +/** + * Create a list of converts that support the specified MIME type. + * + * @param "aDisplayerList" + * Create a list of converts that support the given MIME type. + * @param "aMIMEType" + * The MIME type to convert. + * @panic EUndefinedMIMEType + */ +void CImageDisplayFramework::MimeTypeGetDisplayerListL(RImplInfoPtrArray& aDisplayerList, const TDesC8& aMIMEType) + { + if (aMIMEType.Length() == 0) + { // Get out, empty MIME type string + Panic(EUndefinedMIMEType); + } + + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + customMatchData->SetMatchType(EMatchMIMEType); + customMatchData->SetMatchStringL(aMIMEType); + if (FlagSet(EFlagSourceRectSet)) + { + customMatchData->SetPluginFlagsNeeded(ESetSourceRectSupportNeeded); + } + + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + + TEComResolverParams resolverParams; // Parameters on which to match + resolverParams.SetDataType(packageDes); + + REComSession::ListImplementationsL( + TUid::Uid(KUidDisplayInterface), + resolverParams, + TUid::Uid(KUidDisplayImplementationResolver), + aDisplayerList); + + CleanupStack::PopAndDestroy(2); // package, customMatchData + } + + +/** + * Create a list of displayers that support the specified image type. + * @param "aDisplayerList" + * A list of displayers that support the specified image type. + * @param "aImageHeader" + * The header of the image file. + * @param "aImageType" + * The image base type. + * @param "aImageSubType" + * The image sub type. + * @param "aPluginUid" + * A specific displayer to convert the image. + */ +void CImageDisplayFramework::ImageTypeGetDisplayerListL( + RImplInfoPtrArray& aDisplayerList, + const TDesC8& aImageHeader, + const TUid aImageType, + const TUid aImageSubType, + const TUid aPluginUid) + { + TBuf8 imageHeader; + + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + + if ((aImageType != KNullUid) || (aPluginUid != KNullUid)) + { // We have a specific image type we are trying to convert + customMatchData->SetMatchType(EMatchUids); + customMatchData->SetBaseType(aImageType); + customMatchData->SetSubType(aImageSubType); + customMatchData->SetImplementationType(aPluginUid); + } + else + { + if (aImageHeader.Length() < KImageHeaderSize) // There is not enough data in the header + { // Get out - clean up and leave + User::Leave(KErrUnderflow); + } + imageHeader = aImageHeader.Left(KImageHeaderSize); + customMatchData->SetMatchType(EMatchString); + customMatchData->SetMatchStringL(imageHeader); + } + + if (FlagSet(EFlagSourceRectSet)) + { + customMatchData->SetPluginFlagsNeeded(ESetSourceRectSupportNeeded); + } + + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + + TEComResolverParams resolverParams; // Parameters on which to match + resolverParams.SetDataType(packageDes); + + REComSession::ListImplementationsL( + TUid::Uid(KUidDisplayInterface), + resolverParams, + TUid::Uid(KUidDisplayImplementationResolver), + aDisplayerList); + + CleanupStack::PopAndDestroy(2); // package, customMatchData + } + +/** + * Create a list of displayers that support the specified file extension. + * + * @param "aDisplayerList" + * Create a list of displayers that support the given file extension. + * @param "aFileName" + * The file name from which the file extension will be taken. + * @internalComponent + */ +void CImageDisplayFramework::SuffixTypeGetDisplayerListL( + RImplInfoPtrArray& aDisplayerList, + const TDesC& aFileName) + { + TParse fileName; + fileName.Set(aFileName,NULL,NULL); + + //No file extension + if (!fileName.ExtPresent()) + { + User::Leave(KErrNotFound); + } + + //Get the suffix + TPtrC suffix(fileName.Ext()); + + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + customMatchData->SetMatchType(EMatchFileSuffix); + customMatchData->SetFileSuffixL(suffix); + if (FlagSet(EFlagSourceRectSet)) + { + customMatchData->SetPluginFlagsNeeded( ESetSourceRectSupportNeeded ); + } + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + + TEComResolverParams resolverParams; // Parameters on which to match + resolverParams.SetDataType(packageDes); + + REComSession::ListImplementationsL( + TUid::Uid(KUidDisplayInterface), + resolverParams, + TUid::Uid(KUidDisplayImplementationResolver), + aDisplayerList); + + CleanupStack::PopAndDestroy(2,customMatchData); // package, customMatchData + } + + +/** + * Scan a sorted list of displayers for the first one that can convert the image. + * @internalTechnology + * @param "aDisplayerList" + * A list of displayers that support the image format. + * @return A pointer to the displayer. + */ +CImageDisplayPlugin* CImageDisplayFramework::FindDisplayerNewL( + const RImplInfoPtrArray& aDisplayerList) + { + TInt noOfDisplayers = aDisplayerList.Count(); + + if(noOfDisplayers == 0) + { + User::Leave(KErrNotFound); + } + + CImageDisplayPlugin* displayer = NULL; + TInt displayerNo = 0; + TInt error = KErrNone; + do + { + const CImplementationInformation& displayerInfo = *(aDisplayerList[displayerNo++]); + + TRAP(error, displayer = CImageDisplayPlugin::NewL(displayerInfo.ImplementationUid(), *this)); + + if (error != KErrCorrupt && error != KErrNotSupported && error != KErrNotFound) + { + break; + } + } + while(displayerNo < noOfDisplayers); + + if(error!=KErrNone) + { + ASSERT(displayer==NULL); + if (error == KErrCorrupt || error == KErrNotSupported) + { + error = KErrNotFound; + } + User::Leave(error); + } + + return displayer; + } + +inline +void CImageDisplayFramework::DeletePlugin() + { + delete iPlugin; + iPlugin = NULL; + } + +/** +Gets a pointer to a plugin extension + +@panic EIllegalCallSequence + No plugin loaded. +@return A pointer to a fully constructed Image Display Plugin Extension interface + NULL, if there is no extension to the plugin +*/ +TInt CImageDisplayFramework::ExtensionInterface(TUid aIFaceUid, TAny*& aIFacePtr) + { + if (!iPlugin) + { + Panic(EIllegalCallSequence); + } + + return iPlugin->ExtensionInterface(aIFaceUid, aIFacePtr); + } + +void CImageDisplayFramework::GetBitmap(const CFbsBitmap*& aBitmap, const CFbsBitmap*& aMask) const + { + if (EStateOpened == iState || EStateConfigured == iState ) + { + Panic(EIllegalCallSequence); + } + iPlugin->GetBitmap(aBitmap, aMask); + } + +TBool CImageDisplayFramework::ValidBitmap() const + { + if (!iPlugin) + { + Panic(EIllegalCallSequence); + } + return iPlugin->ValidBitmap(); + } + +const CImageDisplay::RImageSizeArray& CImageDisplayFramework::RecommendedImageSizes() const + { + if (!iPlugin) + { + Panic(EIllegalCallSequence); + } + return iPlugin->RecommendedImageSizes(); + } + +TUint CImageDisplayFramework::ImageStatus() const + { + if (EStateOpened == iState || EStateConfigured == iState ) + { + Panic(EIllegalCallSequence); + } + return iPlugin->ImageStatus(); + } + +TInt CImageDisplayFramework::NumFrames(TInt& aNumFrames) const + { + aNumFrames = -1; + if (EStateOpened == iState || EStateConfigured == iState ) + { + Panic(EIllegalCallSequence); + } + return iPlugin->NumFrames(aNumFrames); + }