diff -r 000000000000 -r 5752a19fdefe imaging/imagingfws/src/ImageClientApi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imaging/imagingfws/src/ImageClientApi.cpp Wed Aug 25 12:29:52 2010 +0300 @@ -0,0 +1,5056 @@ +// Copyright (c) 2001-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: +// + +#include +#include +#include +#include +#include +using namespace ContentAccess; + +#include "ImageConversion.h" +#include "ImageClientMain.h" +#include "ImageResolverAPI.h" +#include "ImageUtils.h" +#include "ImageConvResolvrUtils.h" +#include "ImageRelay.h" +#include "icl/ImageConstruct.h" +#include "icl/ImagePlugin.h" +#include "ImageConversion.inl" +#include "ImageCodecBody.h" +#include "EnDecoderUtils.h" +#include "icl/imageconversionextension.h" +#include "fwextconstants.h" + +const TInt KMaxMimeLength = 256; +const TInt KMinimumHeaderLength = 2; + + +// +// CImageTypeDescription +// + +/** +Constructs a new image type description entry. + +A leave occurs if there is insufficient memory available. + +@param aDescription + A description of the plugin decoder/encoder. +@param aImageType + The plugin decoder/encoder type UID. +@param aSubType + The plugin decoder/encoder sub-type UID. + +@return A pointer to the new image type description entry. +*/ +CImageTypeDescription* CImageTypeDescription::NewL(const TDesC& aDescription, const TUid aImageType, const TUid aSubType) + { + CImageTypeDescription* self = CImageTypeDescription::NewLC(aDescription, aImageType, aSubType); + CleanupStack::Pop(); + return self; + } + +/** +Constructs a new image type description entry. The new object created on the clean-up stack. + +A leave occurs if there is insufficient memory available. + +@param aDescription + A description of the plugin decoder/encoder. +@param aImageType + The plugin decoder/encoder type UID. +@param aSubType + The plugin decoder/encoder sub-type UID. + +@return A pointer to the new image type description entry. +*/ +CImageTypeDescription* CImageTypeDescription::NewLC(const TDesC& aDescription, const TUid aImageType, const TUid aSubType) + { + CImageTypeDescription* self = new(ELeave) CImageTypeDescription(aImageType, aSubType); + CleanupStack::PushL(self); + self->ConstructL(aDescription); + return self; + } + + +/** +Default constructor. +@param aImageType + The plugin decoder/encoder type UID. +@param aSubType + The plugin decoder/encoder sub-type UID +*/ + +CImageTypeDescription::CImageTypeDescription(const TUid aImageType, const TUid aSubType) + : iImageType(aImageType), iSubType(aSubType) + { + } + +/** +Second phase constructor. +@param aDescription + A description of the plugin decoder/encoder. +*/ + +void CImageTypeDescription::ConstructL(const TDesC& aDescription) + { + iDescription = aDescription.AllocL(); + } + +/** +Destructor. +*/ +EXPORT_C CImageTypeDescription::~CImageTypeDescription() + { + delete iDescription; + } + +/** +Returns the image description info. + +@return A reference to the descriptor containing the description. +*/ +EXPORT_C const TDesC& CImageTypeDescription::Description() const + { + return *iDescription; + } + +/** +Returns the image type info. + +@return The image type info as a TUid object. +*/ +EXPORT_C TUid CImageTypeDescription::ImageType() const + { + return iImageType; + } + +/** +Returns the image sub-type information. + +@return The image sub-type information as a TUid object. +*/ +EXPORT_C TUid CImageTypeDescription::SubType() const + { + return iSubType; + } + +// +// CFileExtensionMIMEType +// + +/** +Constructs a new file extension/MIME type entry. + +A leave occurs if there is insufficient memory available. + +@param aExtn + The file extension. +@param aMIMEType + The associated MIME type. +@param aDisplayName The display name of the implementation +@param aImageType The plugin decoder/encoder type UID. +@param aImageSubType The plugin decoder/encoder sub-type UID. +@param aImplementationUid The unique ID of the implementation. +@return A pointer to the new file extension/MIME type entry. +*/ +CFileExtensionMIMEType* CFileExtensionMIMEType::NewL(const TDesC8& aExtn, const TDesC8& aMIMEType, const TDesC& aDisplayName, TUid aImageType, TUid aImageSubType, TUid aImplementationUid) + { + CFileExtensionMIMEType* self = CFileExtensionMIMEType::NewLC(aExtn, aMIMEType, aDisplayName, aImageType, aImageSubType, aImplementationUid); + CleanupStack::Pop(); + return self; + } + +/** +Constructs a new file extension/MIME type entry. The new object is left on the clean-up stack. + +A leave occurs if there is insufficient memory available. + +@param aExtn + The file extension. +@param aMIMEType + The associated MIME type. +@param aDisplayName The display name of the implementation +@param aImageType The plugin decoder/encoder type UID. +@param aImageSubType The plugin decoder/encoder sub-type UID. +@param aImplementationUid The unique ID of the implementation. +@return A pointer to the new file extension/MIME type entry. +*/ +EXPORT_C CFileExtensionMIMEType* CFileExtensionMIMEType::NewLC(const TDesC8& aExtn, const TDesC8& aMIMEType, const TDesC& aDisplayName, TUid aImageType, TUid aImageSubType, TUid aImplementationUid) + { + CFileExtensionMIMEType* self = new(ELeave) CFileExtensionMIMEType; + CleanupStack::PushL(self); + self->ConstructL(aExtn, aMIMEType, aDisplayName, aImageType, aImageSubType, aImplementationUid); + return self; + } +/** +Default constructor. +*/ +CFileExtensionMIMEType::CFileExtensionMIMEType() + { + } + +/** +Second phase constructor. +@param aExtn The file extension +@param aMIMEType The associated MIME type. +@param aDisplayName The display name of the implementation +@param aImageType The plugin decoder/encoder type UID. +@param aImageSubType The plugin decoder/encoder sub-type UID. +@param aImplementationUid The unique ID of the implementation. +*/ +void CFileExtensionMIMEType::ConstructL(const TDesC8& aExtn, const TDesC8& aMIMEType, const TDesC& aDisplayName, TUid aImageType, TUid aImageSubType, TUid aImplementationUid) + { + iFileExtension = HBufC::NewL(aExtn.Length()); + iFileExtension->Des().Copy(aExtn); // Create a 16 bit copy of the 8 bit original + ASSERT(iFileExtension->Length() == aExtn.Length()); + iMIMEType = aMIMEType.AllocL(); + ASSERT(iMIMEType->Length() == aMIMEType.Length()); + iDisplayName = aDisplayName.AllocL(); + iImageTypeUid = aImageType; + iImageSubTypeUid = aImageSubType; + iImplementationUid = aImplementationUid; + } + +/** +Destructor. + +Frees all resources owned by the object prior to its destruction. +*/ +EXPORT_C CFileExtensionMIMEType::~CFileExtensionMIMEType() + { + delete iFileExtension; + delete iMIMEType; + delete iDisplayName; + } + +/** +Returns the image file extension info. + +@return A reference to the descriptor containing the file extension. +*/ +EXPORT_C const TDesC& CFileExtensionMIMEType::FileExtension() const + { + return *iFileExtension; + } + +/** +Returns the image MIME type info. + +@return A reference to the descriptor containing the MIME type. +*/ +EXPORT_C const TDesC8& CFileExtensionMIMEType::MIMEType() const + { + return *iMIMEType; + } + +/** +Returns the human-readable plugin description. + +@return A reference to the display descriptor. +*/ +EXPORT_C const TDesC& CFileExtensionMIMEType::DisplayName() const + { + return *iDisplayName; + } + +/** +Returns the image type associated with the plugin. + +@return The image type associated with the plugin +*/ +EXPORT_C TUid CFileExtensionMIMEType::ImageType() const + { + return iImageTypeUid; + } + +/** +Returns the image sub-type associated with the plugin. + +@return The image sub-type associated with the plugin. +*/ +EXPORT_C TUid CFileExtensionMIMEType::ImageSubType() const + { + return iImageSubTypeUid; + } + +/** +Returns the implementation UID of the plugin. + +@return The implementation UID of the plugin. +*/ +EXPORT_C TUid CFileExtensionMIMEType::ImplementationUid() const + { + return iImplementationUid; + } + +// +// CImplementationInformationType +// + +/** +Constructs a new implementation information object. + +@return A pointer to the new implementation information object. +*/ + +CImplementationInformationType* CImplementationInformationType::NewL() + { + CImplementationInformationType* self = CImplementationInformationType::NewLC(); + CleanupStack::Pop(); + return self; + } + +// CImplementationInformationType transfer ownership of iDisplyName, iDataType and iOpaqueData + +/** +Sets the contents of the CImplementationInformationType object. + +Use this variant of SetDataL() if the plugin is installed on a drive other than the default, which is zero. + +@param aImplementationUid + The unique ID of the implementation. +@param aVersion + The version number of the implementation. +@param aDisplayName + The display name of the implementation. +@param aDataType + The data type supported by the implementation. +@param aOpaqueData + Additional data for this implementation. This data is not used by the ECom framework. +@param aDrive + The drive on which the plugin is installed. +*/ +void CImplementationInformationType::SetDataL(TUid aImplementationUid, TInt aVersion, const TDesC& aDisplayName, const TDesC8& aDataType, const TDesC8& aOpaqueData, TDriveUnit aDrive) + { + iImplementationUid = aImplementationUid; + iVersion = aVersion; + + delete iDisplayName; iDisplayName = NULL; + iDisplayName = aDisplayName.AllocL(); + + delete iDataType; iDataType = NULL; + iDataType = aDataType.AllocL(); + + delete iOpaqueData; iOpaqueData = NULL; + iOpaqueData = aOpaqueData.AllocL(); + + iDrive = aDrive; + } + +/** +Default constructor. + +This member is internal and not intended for use. +*/ +CImplementationInformationType::CImplementationInformationType() + { + } + +/** +Constructs a new implementation information object. The new object is left on the clean-up stack. + +@return A pointer to the new implementation information object. +*/ +CImplementationInformationType* CImplementationInformationType::NewLC() + { + CImplementationInformationType* self = new(ELeave) CImplementationInformationType; + CleanupStack::PushL(self); + return self; + } + +/** +Destructor. + +Frees all resources owned by the object prior to its destruction. +*/ +EXPORT_C CImplementationInformationType::~CImplementationInformationType() + { + delete iDisplayName; + delete iDataType; + delete iOpaqueData; + } + + +/** +Returns the implementation UID. + +@return The implementation UID as a TUid object. +*/ +EXPORT_C TUid CImplementationInformationType::ImplementationUid() const + { + return iImplementationUid; + } + +/** +Returns the version number of the implementation. + +@return The version number of the implementation. +*/ +EXPORT_C TInt CImplementationInformationType::Version() const + { + return iVersion; + } + +/** +Returns the display name of the implementation. + +@return A reference to the display name of the implementation. +*/ +EXPORT_C const TDesC& CImplementationInformationType::DisplayName() const + { + return *iDisplayName; + } + +/** +Returns the data type supported by the implementation. + +@return A reference to the descriptor containing the data type. +*/ +EXPORT_C const TDesC8& CImplementationInformationType::DataType() const + { + return *iDataType; + } + +/** +Returns the opaque binary data for the implementation. + +@return A reference to the descriptor containing the data. +*/ +EXPORT_C const TDesC8& CImplementationInformationType::OpaqueData() const + { + return *iOpaqueData; + } + +/** +Returns the drive location information for the implementation. + +@return The drive location information as a TDriveUnit object. +*/ +EXPORT_C TDriveUnit CImplementationInformationType::Drive() + { + return iDrive; + } + +/** +Function to sort an array of CFileExtensionMIMEType in ascending +order of file extesion and MIME type. + +@param aItem1 + The first element. +@param aItem2 + The second element. + +@return An indication of the element swapping order. +*/ +TInt ImageEnDecoderUtils::SortAsending(const CFileExtensionMIMEType& aItem1, const CFileExtensionMIMEType& aItem2) + { + TInt result = aItem1.FileExtension().Compare(aItem2.FileExtension()); + if(result==0) + result = aItem1.MIMEType().Compare(aItem2.MIMEType()); + return result; + } + +// Used by the 4 decoder and encoder functions that return arrays of Uids and plugin descriptions +void ImageEnDecoderUtils::DoGetImageTypesL(TUid aInterfaceUid, RImageTypeDescriptionArray& aImageTypeArray, TUid aBaseType) + { + RImplInfoPtrArray pluginArray; // Array to return matching plugins in + CleanupResetAndDestroyPushL(pluginArray); + + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + TEComResolverParams resolverParams; // Parameters on which to match + + customMatchData->SetMatchType(EListImageTypes); + customMatchData->SetBaseType(aBaseType); + customMatchData->SetSubType(KNullUid); + customMatchData->SetImplementationType(KNullUid); + + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + resolverParams.SetDataType(packageDes); + + REComSession::ListImplementationsL(aInterfaceUid, resolverParams, KImageConvertResolverUid, pluginArray); + if (pluginArray.Count() == 0) + User::Leave(KErrNotFound); + + CleanupStack::PopAndDestroy(2); // package, customMatchData + + // Transfer data to our array + for (TInt index = 0; index < pluginArray.Count(); index++) + { + COpaqueDataParse* parser = NULL; + TRAPD(error, parser = COpaqueDataParse::NewL(pluginArray[index]->OpaqueData())); + if (error!=KErrNone) + { + if (error==KErrNotSupported) + { + // means that the resource entry was not valid + continue; + } + else + User::Leave(error); + } + + CleanupStack::PushL(parser); + CImageTypeDescription* imageTypeDescription = CImageTypeDescription::NewLC(pluginArray[index]->DisplayName(), parser->ImageTypeUid(), parser->ImageSubTypeUid()); + + TBool mustAppend = ETrue; + for(TInt i=0; i< aImageTypeArray.Count(); i++) + { + if( aImageTypeArray[i]->ImageType().iUid == imageTypeDescription->ImageType().iUid && + aImageTypeArray[i]->SubType().iUid == imageTypeDescription->SubType().iUid && + (aImageTypeArray[i]->Description().Compare(imageTypeDescription->Description())) == 0) + { + // If here - image type implementation with same description is already in array. + mustAppend = EFalse; + CleanupStack::PopAndDestroy(imageTypeDescription); + break; + } + } + if(mustAppend) + { + //A new image type implementation, add it to array. + User::LeaveIfError(aImageTypeArray.Append(imageTypeDescription)); + CleanupStack::Pop(imageTypeDescription); + } + CleanupStack::PopAndDestroy(parser); + } + CleanupStack::PopAndDestroy(&pluginArray); + } + +// Used by both the decoder and encoder functions that return arrays of file extensions and MIME types. +// This function creates an array of each valid file extension along with the associated "primary" +// (ie. first) MIME type plus the "secondary" MIME type(s). +void ImageEnDecoderUtils::DoGetFileTypesL(TUid aInterfaceUid, RFileExtensionMIMETypeArray& aFileTypeArray) + { + RImplInfoPtrArray pluginArray; // Array to return matching plugins in + CleanupResetAndDestroyPushL(pluginArray); + + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + TEComResolverParams resolverParams; // Parameters on which to match + + customMatchData->SetMatchType(EListFileTypes); + + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + resolverParams.SetDataType(packageDes); + + REComSession::ListImplementationsL(aInterfaceUid, resolverParams, KImageConvertResolverUid, pluginArray); + if (pluginArray.Count() == 0) + { + User::Leave(KErrNotFound); + } + + CleanupStack::PopAndDestroy(2); // package, customMatchData + + // Transfer data to our array + for (TInt index = 0; index < pluginArray.Count(); index++) + { + CImplementationInformation* implInfo = pluginArray[index]; + COpaqueDataParse* parser = NULL; + TRAPD(error, parser = COpaqueDataParse::NewL(implInfo->OpaqueData())); + if (error != KErrNone) + { + if (error==KErrNotSupported) + { + // means that the resource entry was not valid + continue; + } + else + { + User::Leave(error); + } + } + + CleanupStack::PushL(parser); + if (parser->OnlyUidsAvail() || parser->IsSubCodec()) // ignore simple descriptions + { + CleanupStack::PopAndDestroy(); // parser + continue; + } + parser->EnsureMIMETypesReadL(); + + // Return all the MIME types specified in the resource file, not just the primary + // one by filling the file type array with elements created multiplicatively + // for each extension and each MIME type. + + // use a blank MIME type if none provided by the plugin + const TBool blankMIMEType = (parser->MIMETypesCount() == 0); + const TInt numMIMETypes = blankMIMEType ? 1 : parser->MIMETypesCount(); + + //use a blank extension if not provided by plugin + const TBool blankExtn = (parser->ExtnsCount() == 0); + const TInt numExtns = blankExtn ? 1 : parser->ExtnsCount(); + + TLinearOrder sortFunction(SortAsending); + for (TInt index2 = 0; index2 < numExtns; index2++) + { + const TDesC8& extn = blankExtn ? KNullDesC8() : parser->Extn(index2); + for (TInt index3 = 0; index3 < numMIMETypes; index3++) + { + const TDesC8& MIMEType = blankMIMEType ? KNullDesC8() : parser->MIMEType(index3); + CFileExtensionMIMEType* fileExtensionMIMEType = CFileExtensionMIMEType::NewLC( extn, MIMEType, + implInfo->DisplayName(), + parser->ImageTypeUid(), + parser->ImageSubTypeUid(), + implInfo->ImplementationUid()); + //InsertInOrder will return KErrAlreadyExists if an entry already exists that + //has the same MIME type and file extension. Thus, aFileTypeArray may not + //contain all implementation UIDs that are present. + //We assume the resolver CImageConversionResolver::ListAllL() return highest version number first + //if calls succeed ownership is transferred + TInt error = aFileTypeArray.InsertInOrder(fileExtensionMIMEType, sortFunction); + if (error != KErrNone) + { + CleanupStack::PopAndDestroy(fileExtensionMIMEType); + if (error != KErrAlreadyExists) + { + User::Leave(error); + } + } + else + { + CleanupStack::Pop(fileExtensionMIMEType); + } + } + } + CleanupStack::PopAndDestroy(parser); + } + CleanupStack::PopAndDestroy(&pluginArray); + } + +// Used by the decoder and encoder functions to obtain the implementation information a specific codec +void ImageEnDecoderUtils::DoGetImplementationInformationL(const TUid aInterfaceUid, CImplementationInformationType& aImplementationInformation, const TUid aImplementationUid) + { + RImplInfoPtrArray pluginArray; // Array to return matching plugins in + CleanupResetAndDestroyPushL(pluginArray); + + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + TEComResolverParams resolverParams; // Parameters on which to match + + customMatchData->SetMatchType(EMatchUids); + customMatchData->SetImplementationType(aImplementationUid); + + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + resolverParams.SetDataType(packageDes); + + REComSession::ListImplementationsL(aInterfaceUid, resolverParams, KImageConvertResolverUid, pluginArray); + if (pluginArray.Count() == 0) + User::Leave(KErrNotFound); + + CleanupStack::PopAndDestroy(2); // package, customMatchData + + // Transfer data (if more than one is found take first) + CImplementationInformation* impInfo = pluginArray[0]; + aImplementationInformation.SetDataL(impInfo->ImplementationUid(), + impInfo->Version(), + impInfo->DisplayName(), + impInfo->DataType(), + impInfo->OpaqueData(), + impInfo->Drive() + ); + + CleanupStack::PopAndDestroy(); // pluginArray + } + +// Used by the decoder and encoder functions to obtain the implementation properties of a specific codec +// Since this function can be called by both CImageEncoder and CImageDecoder functions we must +// use the generic TUint data type for the aOptions parameter rather than TOptions. +void ImageEnDecoderUtils::DoGetPluginPropertiesL(const TUid aInterfaceUid, const TUid aImplementationUid, RUidDataArray& aPropertiesArray, const TUint aOptions) + { + RImplInfoPtrArray pluginArray; // Array to return matching plugins in + CleanupResetAndDestroyPushL(pluginArray); + + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + TEComResolverParams resolverParams; // Parameters on which to match + + customMatchData->SetMatchType(EMatchUids); + customMatchData->SetImplementationType(aImplementationUid); + customMatchData->SetOptions(CImageDecoder::TOptions(aOptions)); + customMatchData->SetExtensionOptions(aOptions); + + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + resolverParams.SetDataType(packageDes); + + REComSession::ListImplementationsL(aInterfaceUid, resolverParams, KImageConvertResolverUid, pluginArray); + if (pluginArray.Count() == 0) + { + User::Leave(KErrNotFound); + } + + CleanupStack::PopAndDestroy(2); // package, customMatchData + + // Transfer data to our array + COpaqueDataParse* parser = NULL; + TRAPD(error, parser = COpaqueDataParse::NewL((pluginArray[0])->OpaqueData())); + if (error != KErrNone) + { + User::Leave(error); + } + + CleanupStack::PushL(parser); + parser->EnsureBinaryPropertiesReadL(); + parser->GetBinaryPropertiesArrayL(aPropertiesArray); + + CleanupStack::PopAndDestroy(2); // parser, &pluginArray + } + +// Used by the decoder and encoder functions to obtain the implementations (array of uids) that have the required properties and UIDs +void ImageEnDecoderUtils::DoGetInterfaceImplementationsL(const TUid aInterfaceUid, const RUidDataArray& aRequiredUids, RUidDataArray& aImplArray) + { + RImplInfoPtrArray pluginArray; // Array to return matching plugins in + CleanupResetAndDestroyPushL(pluginArray); + + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + TEComResolverParams resolverParams; // Parameters on which to match + + customMatchData->SetMatchType(EMatchReqUids); + customMatchData->SetMatchReqUidsL(aRequiredUids); + + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + resolverParams.SetDataType(packageDes); + + REComSession::ListImplementationsL(aInterfaceUid, resolverParams, KImageConvertResolverUid, pluginArray); + if (pluginArray.Count() == 0) + { + User::Leave(KErrNotFound); + } + + CleanupStack::PopAndDestroy(2); // package, customMatchData + + // Transfer data to our array + aImplArray.Reset(); + for (TInt index = 0; index < pluginArray.Count(); index++) + { + User::LeaveIfError(aImplArray.Append((pluginArray[index])->ImplementationUid())); + } + + CleanupStack::PopAndDestroy(&pluginArray); + } + +/** +Static factory function for creating instances of CFrameImageData. +The managed list of image data is created/destroyed internally. + +@return A pointer to a fully constructed CFrameImageData. +*/ +EXPORT_C CFrameImageData* CFrameImageData::NewL() + { + CImageDataArray* newImageData = new(ELeave) CImageDataArray; + CleanupStack::PushL(newImageData); + + CFrameImageData* newFrameImageData = new(ELeave) CFrameImageData(*newImageData, ETrue); + CleanupStack::Pop(); // newImageData + + return newFrameImageData; + } + +/** +Static factory function for creating instances of CFrameImageData. + +The managed list of image data is created internally. If a data owner is specified then the responsibility +for destroying the managed list is that of the owner. If no owner is specified the managed list is +destroyed internally. + +@param aImageData + A reference to an externally created CImageDataArray. +@param aImageDataOwner + If set to true, responsibility for deleting CImageDataArray + is passed to the CFrameImageData object. + +@return A pointer to a fully constructed CFrameImageData. +*/ +EXPORT_C CFrameImageData* CFrameImageData::NewL(CImageDataArray& aImageData, TBool aImageDataOwner) + { + CFrameImageData* newFrameImageData = new(ELeave) CFrameImageData(aImageData, aImageDataOwner); + return newFrameImageData; + } + +CFrameImageData::CFrameImageData(CImageDataArray& aImageData, TBool aImageDataOwner) + : iImageData(aImageData), + iImageDataOwner(aImageDataOwner) + { + } + +/** +Destructor for this class. + +If ownership of the image data was transfered, it is now destroyed. +*/ +EXPORT_C CFrameImageData::~CFrameImageData() + { + if (iImageDataOwner) + delete &iImageData; + + iFrameData.ResetAndDestroy(); + } + +/** +Intended for future proofing - will panic if called. + +@panic ImageConversion 30 +*/ +EXPORT_C void CFrameImageData::Reserved_1() + { + Panic(EReservedCall); + } + +/** +Intended for future proofing - will panic if called. + +@panic ImageConversion 30 +*/ +EXPORT_C void CFrameImageData::Reserved_2() + { + Panic(EReservedCall); + } + +/** +Intended for future proofing - will panic if called. + +@panic ImageConversion 30 +*/ +EXPORT_C void CFrameImageData::Reserved_3() + { + Panic(EReservedCall); + } + +/** +Intended for future proofing - will panic if called. + +@panic ImageConversion 30 +*/ +EXPORT_C void CFrameImageData::Reserved_4() + { + Panic(EReservedCall); + } + +/** +@see CFrameImageData::ImageDataCount(). + +Inserts a pointer to an image data block into the internally held list in front +of the item at position aPos. + +@param aEntry + The image data block pointer to be inserted. +@param aPos + The position at which to insert the pointer into the internal list. + Must not be less than 0 or greater than the value returned by + CFrameImageData::ImageDataCount(). + +@return An error code indicating if the function call was successful. KErrNone on success, otherwise + another of the system-wide error codes. +*/ +EXPORT_C TInt CFrameImageData::InsertImageData(const TImageDataBlock* aEntry, TInt aPos) + { + ASSERT(aEntry != NULL); + return iImageData.InsertImageData(aEntry, aPos); + } + +/** +Adds a pointer to an image data block to the end of the internally held list. + +@param aEntry + The image data block pointer to be inserted. + +@return An error code indicating if the function call was successful. KErrNone on success, otherwise + another of the system-wide error codes. +*/ +EXPORT_C TInt CFrameImageData::AppendImageData(const TImageDataBlock* aEntry) + { + ASSERT(aEntry != NULL); + return iImageData.AppendImageData(aEntry); + } + +/** +Removes a pointer to an image data block at position aIndex from the +internally held list. + +@param aIndex + The index into the list. Must not be less than 0 or greater + than the value returned by CFrameImageData::ImageDataCount(). + +@see CFrameImageData::ImageDataCount(). +*/ +EXPORT_C void CFrameImageData::RemoveImageData(TInt aIndex) + { + iImageData.RemoveImageData(aIndex); + } + +/** +Inserts a pointer to a frame data block into the internally held list in front +of the item at position aPos. + +@param aEntry + The frame data block pointer to be inserted. +@param aPos + The position at which to insert the pointer into the internal list. Must not be + less than 0 or greater than the value returned by CFrameImageData::FrameDataCount(). + +@return An error code indicating if the function call was successful. KErrNone on success, otherwise + another of the system-wide error codes. + +@see CFrameImageData::FrameDataCount() +*/ +EXPORT_C TInt CFrameImageData::InsertFrameData(const TFrameDataBlock* aEntry, TInt aPos) + { + ASSERT(aEntry != NULL); + return iFrameData.Insert(aEntry, aPos); + } + +/** +Adds a pointer to a frame data block to the end of the internally held list. + +@param aEntry + The frame data block pointer to be inserted. + +@return An error code indicating if the function call was successful. KErrNone on success, otherwise + another of the system-wide error codes. +*/ +EXPORT_C TInt CFrameImageData::AppendFrameData(const TFrameDataBlock* aEntry) + { + ASSERT(aEntry != NULL); + return iFrameData.Append(aEntry); + } + +/** +Removes a pointer to a frame data block at position aIndex from the +internally held list. + +@param aIndex + Position of the pointer to delete. Must not be less than 0 or greater + than the value returned by CFrameImageData::ImageDataCount(). + +@see CFrameImageData::FrameDataCount(). +*/ +EXPORT_C void CFrameImageData::RemoveFrameData(TInt aIndex) + { + iFrameData.Remove(aIndex); + } + +/** +Creates a full copy of the objects data. +Ownership is transferred to the caller. + +@return A pointer to the new copy of the frame data. +*/ +EXPORT_C CFrameImageData* CFrameImageData::AllocL() const + { + // Make copies of the TImageDataBlock arrays. + CImageDataArray* newImageData = new (ELeave) CImageDataArray; + CleanupStack::PushL(newImageData); + + CFrameImageData* newFrameData = new (ELeave) CFrameImageData(*newImageData, ETrue); + CleanupStack::Pop(newImageData); + CleanupStack::PushL(newFrameData); + + // Copy the contents. + TInt index; + TInt count = ImageDataCount(); + for (index = 0 ; indexDuplicateL(*newFrameData); + CleanupDeletePushL(tmpImageData); + + User::LeaveIfError(newFrameData->AppendImageData(tmpImageData)); + CleanupStack::Pop(); // tmpImageData + } + + count = FrameDataCount(); + for (index = 0 ; indexDuplicateL(*newFrameData); + CleanupDeletePushL(tmpFrameData); + + User::LeaveIfError(newFrameData->AppendFrameData(tmpFrameData)); + CleanupStack::Pop(); // tmpFrameData + } + + CleanupStack::Pop(newFrameData); // newFrameData + return newFrameData; + } + +/** +Returns the image data block at the given position from the +internally held list. + +@param aIndex + The position of the image data block to retrieve. Must be in the range 0 to ImageDataCount(). + +@return A pointer to the image data block. +*/ +EXPORT_C const TImageDataBlock* CFrameImageData::GetImageData(TInt aIndex) const + { + return iImageData.GetImageData(aIndex); + } + +/** +Returns the image data block at the given position from the +internally held list. + +@param aIndex + The position of the image data block to retrieve. Must be in the range 0 to ImageDataCount(). + +@return A pointer to the image data block. +*/ +EXPORT_C TImageDataBlock* CFrameImageData::GetImageData(TInt aIndex) + { + return iImageData.GetImageData(aIndex); + } + +/** +Const version. + +Returns the frame data block at the given position from the +internally held list. + +@param aIndex + The position of the frame data block to retrieve. Must be in the range 0 to FrameDataCount(). + +@return A pointer to the image data block. +*/ +EXPORT_C const TFrameDataBlock* CFrameImageData::GetFrameData(TInt aIndex) const + { + return iFrameData[aIndex]; + } + +/** +Non const version. + +Returns the frame data block at the given position from the +internally held list. + +@param aIndex + The position of the frame data block to retrieve. Must be in the range 0 to FrameDataCount(). + +@return A pointer to the image data block. +*/ +EXPORT_C TFrameDataBlock* CFrameImageData::GetFrameData(TInt aIndex) + { + return iFrameData[aIndex]; + } + +/** +Returns the number of image data blocks in the internally held list. + +@return The number of image data blocks. +*/ +EXPORT_C TInt CFrameImageData::ImageDataCount() const + { + return iImageData.ImageDataCount(); + } + +/** +Returns the number of frame data blocks in the internally held list. + +@return The number of image data blocks. +*/ +EXPORT_C TInt CFrameImageData::FrameDataCount() const + { + return iFrameData.Count(); + } + +/** +Stores the supplied image data in a newly allocated entry in the image buffer array. + +@param aImageBuffer + The HBufC8 pointer to take ownership of. + +@return An error code indicating if the function call was successful. KErrNone on success, otherwise + another of the system-wide error codes. +*/ +EXPORT_C TInt CFrameImageData::AppendImageBuffer(const HBufC8* aImageBuffer) + { + return iImageData.AppendImageBuffer(aImageBuffer); + } + +// Codec virtual fns. + +// CImageReadCodec + +/** +Default constructor. +*/ +EXPORT_C CImageReadCodec::CImageReadCodec() + { + } + +/** +Second phase constructor. +*/ +EXPORT_C void CImageReadCodec::ConstructL() + { + // NO-OP - reserved in case we need to do Cheshire Cat at a later state. Should always be called. + } + +/** +Destructor. +*/ +EXPORT_C CImageReadCodec::~CImageReadCodec() + { + } + +/** +Used to initialise the frame header data structures. + +The default version of this function does nothing. It should be implemented by +the codec to at least update the appropriate processing state of the current +frame using its TFrameInfo structure. + +@param aFrameInfo + A reference to a TFrameInfo object which will contain the current frame's header info +@param aFrameData + A reference to a TFrameInfo object which will contain the current frame's header data +*/ +EXPORT_C void CImageReadCodec::InitFrameHeader(TFrameInfo& /*aFrameInfo*/, CFrameImageData& /*aFrameData*/) + { + } + +/** +Processes the header for one frame. + +The default version of this function and simply returns EFrameComplete. It +should be implemented by the codec to at least update the appropriate +processing state of the current frame using its TFrameInfo structure. + +@param aData + A reference to a TBufPtr8 that contains the frame data. +@return The completion status of this frame's processing +*/ +EXPORT_C TFrameState CImageReadCodec::ProcessFrameHeaderL(TBufPtr8& /*aData*/) + { + return EFrameComplete; + } + +/** +Processes/displays converted image data. + +This function is called on frame completion and on underflow. The default version of this function +does nothing. It should be implemented by the codec if required. + +If it is called on underflow for example, it can enable display of a partially decoded image. In such +cases this function could display all the image data up to the point of the underflow. +*/ +EXPORT_C void CImageReadCodec::Complete() + { + } + +/** +Returns a new position and number of bytes to read for the data stream. + +The default version of this function does nothing. +It should be implemented by the codec, if required. + +@param aPosition + A reference to the returned new position. +@param aLength + A reference to the number of bytes to read. +*/ +EXPORT_C void CImageReadCodec::GetNewDataPosition(TInt& /*aPosition*/, TInt& /*aLength*/) + { + } + +/** +@internalComponent + +Sets the current frame number. +Called by the framework before InitFrameHeader() and InitFrameL() + +@param aFrameNumber + The current frame number +*/ +void CImageReadCodec::SetCurrentFrame(TInt aFrameNumber) + { + iCurrentFrame = aFrameNumber; + } + +/** +Return the current frame number + +@return The current frame number +*/ +EXPORT_C TInt CImageReadCodec::CurrentFrame() const + { + return iCurrentFrame; + } + +/** +Calculates reduction factor based on the input parameters. +The default Implementation is given here. It should be implemented by the Codecs, If required. + +@param aOriginalSize + A reference to the original size of an image. +@param aReducedSize + A reference to the new size of an image. +@return The reduction factor. +*/ + +EXPORT_C TInt CImageReadCodec::ReductionFactor(const TSize& aOriginalSize,const TSize& aReducedSize) const + { + if( (aReducedSize.iWidth<=0) || (aReducedSize.iHeight<=0)) + { + return 0; + } + TInt reductionFactor = 0; + TInt roundup=0; + while( ((aOriginalSize.iWidth+roundup)>>reductionFactor) > aReducedSize.iWidth || + ((aOriginalSize.iHeight+roundup)>>reductionFactor) > aReducedSize.iHeight) + { + reductionFactor++; + roundup=(1<0? (1<>aReductionFactor), + ((aOriginalSize.iHeight+roundup)>>aReductionFactor) ); + return KErrNone; + } + +/** +Intended for future proofing - will panic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageReadCodec::ReservedVirtual1() + { + Panic(EReservedCall); + } + +/** +Intended for future proofing - will panic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageReadCodec::ReservedVirtual2() + { + Panic(EReservedCall); + } + +/** +Intended for future proofing - will panic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageReadCodec::ReservedVirtual3() + { + Panic(EReservedCall); + } + +/** +Intended for future proofing - will panic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageReadCodec::ReservedVirtual4() + { + Panic(EReservedCall); + } + +// CImageProcessorReadCodec + +/** +Default constructor. +*/ +EXPORT_C CImageProcessorReadCodec::CImageProcessorReadCodec() + { + } + +/** +Second phase constructor. +*/ +EXPORT_C void CImageProcessorReadCodec::ConstructL() + { + CImageReadCodec::ConstructL(); + + iBody = CImageProcessorReadCodecBody::NewL(); + } + +/** +Destructor. +*/ +EXPORT_C CImageProcessorReadCodec::~CImageProcessorReadCodec() + { + delete iBody; + } + +/** +Returns a pointer to the codec's CImageProcessor. + +@return A pointer to the codec's CImageProcessor derived object. +*/ +EXPORT_C CImageProcessor* CImageProcessorReadCodec::ImageProcessor() const + { + return iBody->ImageProcessor(); + } + +/** +Sets the codec's CImageProcessor. + +Ownership is transferred. + +@param aImageProc + A pointer to a full constructed CImageProcessor derived object. +*/ +EXPORT_C void CImageProcessorReadCodec::SetImageProcessor(CImageProcessor *aImageProc) + { + iBody->SetImageProcessor(aImageProc); + } + +/** +Returns the current position within the bitmap (const version). + +@return A reference to a TPoint object specifying the location. +*/ +EXPORT_C const TPoint& CImageProcessorReadCodec::Pos() const + { + return iBody->Pos(); + } + +/** +Returns the current position within the bitmap (non const version). + +@return A reference to a TPoint object specifying the location. +*/ +EXPORT_C TPoint& CImageProcessorReadCodec::Pos() + { + return iBody->Pos(); + } + +/** +Sets the current position within the bitmap. + +@param aPos + A reference to a TPoint object specifying the location. +*/ +EXPORT_C void CImageProcessorReadCodec::SetPos(const TPoint& aPos) + { + iBody->SetPos(aPos); + } + +// CImageMaskProcessorReadCodec + +/** +Default constructor. +*/ +EXPORT_C CImageMaskProcessorReadCodec::CImageMaskProcessorReadCodec() + { + } + +/** +Second phase constructor. +*/ +EXPORT_C void CImageMaskProcessorReadCodec::ConstructL() + { + CImageProcessorReadCodec::ConstructL(); + + iBody = CImageMaskProcessorReadCodecBody::NewL(); + } + +/** +Destructor. +*/ +EXPORT_C CImageMaskProcessorReadCodec::~CImageMaskProcessorReadCodec() + { + delete iBody; + } + +/** +Returns a pointer to the codec's CImageProcessor used when decoding +the image mask. + +@return A pointer to the codec's CImageProcessor derived object. +*/ +EXPORT_C CImageProcessor* CImageMaskProcessorReadCodec::MaskProcessor() const + { + return iBody->MaskProcessor(); + } + +/** +Replaces a codec's existing CImageProcessor with a new fully constructed instance of the same +object. + +Ownership of the new instance is transferred. + +@param aMaskProc + A pointer to a full constructed CImageProcessor derived object. +*/ +EXPORT_C void CImageMaskProcessorReadCodec::SetMaskProcessor(CImageProcessor *aMaskProc) + { + iBody->SetMaskProcessor(aMaskProc); + } + +/** +Constructor for this class. +*/ +EXPORT_C CImageProcessorReadCodecExtension::CImageProcessorReadCodecExtension() + { + } + +EXPORT_C void CImageProcessorReadCodecExtension::ConstructL() + { + CImageProcessorReadCodec::ConstructL(); + } + +/** +Destructor for this class. +*/ +EXPORT_C CImageProcessorReadCodecExtension::~CImageProcessorReadCodecExtension() + { + } + +EXPORT_C TInt CImageProcessorReadCodecExtension::ScalingCoefficient(const TSize& aOriginalSize, const TSize& aDesiredSize) const + { + TInt reductionFactor = ReductionFactor(aOriginalSize, aDesiredSize); + return -(reductionFactor+1); + } + +EXPORT_C TInt CImageProcessorReadCodecExtension::GetReducedSize(const TSize& aOriginalSize, TInt aScalingCoeff, TSize& aReducedSize) const + { + return ReducedSize(aOriginalSize, -(aScalingCoeff+1), aReducedSize); + } + +EXPORT_C CImageMaskProcessorReadCodecExtension::CImageMaskProcessorReadCodecExtension() + { + } + +EXPORT_C void CImageMaskProcessorReadCodecExtension::ConstructL() + { + CImageMaskProcessorReadCodec::ConstructL(); + } + +EXPORT_C CImageMaskProcessorReadCodecExtension::~CImageMaskProcessorReadCodecExtension() + { + } + +EXPORT_C TInt CImageMaskProcessorReadCodecExtension::ScalingCoefficient(const TSize& aOriginalSize, const TSize& aDesiredSize) const + { + TInt reductionFactor = ReductionFactor(aOriginalSize, aDesiredSize); + return -(reductionFactor+1); + } + +EXPORT_C TInt CImageMaskProcessorReadCodecExtension::GetReducedSize(const TSize& aOriginalSize, TInt aScalingCoeff, TSize& aReducedSize) const + { + return ReducedSize(aOriginalSize, -(aScalingCoeff+1), aReducedSize); + } + +// CImageWriteCodec + +/** +Default constructor. +*/ +EXPORT_C CImageWriteCodec::CImageWriteCodec() + { + } + +/** +Second phase constructor. +*/ +EXPORT_C void CImageWriteCodec::ConstructL() + { + // NO-OP - reserved in case we need to do Cheshire Cat at a later state. Should always be called. + } + +/** +Destructor. +*/ +EXPORT_C CImageWriteCodec::~CImageWriteCodec() + { + } + +/** +Performs initial processing of image data from an internally held buffer. + +Used to initialise the frame header. The default version of this function does nothing. +It should be implemented by the codec, if required. + +@param aDst + The destination buffer. +@param aSource + The source internally held buffer. +*/ +EXPORT_C void CImageWriteCodec::InitFrameL(TBufPtr8& /*aDst*/, const CFbsBitmap& /*aSource*/) + { + } + +/** +Returns the codec's source bitmap. + +@return A pointer to the codec's source bitmap. +*/ +EXPORT_C const CFbsBitmap* CImageWriteCodec::Source() const + { + return iSource; + } + +/** +Sets the codec's source bitmap. + +Use this function if you need to process more than one internally held buffer. This +will be necessary if, for example, you need to add a bitmap mask to the destination buffer. + +@param aSource + A pointer to the codec's source bitmap. +*/ +EXPORT_C void CImageWriteCodec::SetSource(const CFbsBitmap* aSource) + { + iSource = aSource; + } + + +/** +Intended for future proofing - will panic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageWriteCodec::ReservedVirtual1() + { + Panic(EReservedCall); + } + +/** +Intended for future proofing - will panic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageWriteCodec::ReservedVirtual2() + { + Panic(EReservedCall); + } + +/** +Intended for future proofing - will panic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageWriteCodec::ReservedVirtual3() + { + Panic(EReservedCall); + } + +/** +Intended for future proofing - will panic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageWriteCodec::ReservedVirtual4() + { + Panic(EReservedCall); + } + +// CFrameInfoStrings fns. + +CFrameInfoStrings::CFrameInfoStrings() + { + } + +/** +Static factory function for creating instances of CFrameInfoStrings. +Leaves the newly allocated object on the cleanup stack. + +@return A pointer to a fully constructed CFrameInfoStrings. +*/ +EXPORT_C CFrameInfoStrings* CFrameInfoStrings::NewLC() + { + CFrameInfoStrings* result = new (ELeave) CFrameInfoStrings; + CleanupStack::PushL(result); + result->ConstructL(); + return result; + } + +/** +Static factory function for creating instances of CFrameInfoStrings. + +@return A pointer to a fully constructed CFrameInfoStrings. +*/ +EXPORT_C CFrameInfoStrings* CFrameInfoStrings::NewL() + { + CFrameInfoStrings* result = NewLC(); + CleanupStack::Pop(result); + return result; + } + +/** +Destructor. + +Frees all resources owned by the object prior to its destruction. +*/ +EXPORT_C CFrameInfoStrings::~CFrameInfoStrings() + { + delete iFrameInfoStrings; + } + +void CFrameInfoStrings::ConstructL() + { + iFrameInfoStrings = new (ELeave) CDesC16ArrayFlat(6); + } + +void CFrameInfoStrings::SetStringL(TInt aIndex, const TDesC& aString) + { + // ensure we have enough to just append to - as standard case + const TInt minRequired = aIndex; + while (iFrameInfoStrings->Count() < minRequired) + iFrameInfoStrings->AppendL(KNullDesC); + + if (iFrameInfoStrings->Count()==minRequired) + iFrameInfoStrings->AppendL(aString); + else + { + // delete the original and insert + iFrameInfoStrings->Delete(aIndex); + iFrameInfoStrings->InsertL(aIndex, aString); + } + + ASSERT(String(aIndex)==aString); + } + +/** +Returns the string at position aIndex in the string table. +The index runs from 0 to CFrameInfoStrings::Count() - 1. + +@param aIndex + The position of the string to retrieve. + +@return A pointer to the string at the given index. +*/ +EXPORT_C const TPtrC CFrameInfoStrings::String(TInt aIndex) const + { + ASSERT(aIndex < iFrameInfoStrings->Count()); + return (*iFrameInfoStrings)[aIndex]; + } + +/** +Returns the number of strings in the string table. + +@return Returns the number of entries in the string table. +*/ +EXPORT_C TInt CFrameInfoStrings::Count() const + { + return iFrameInfoStrings->Count(); + } + +/** +Returns a pointer to the 'decoder' entry string from this object. + +@return A read-only pointer to the returned string. +*/ +EXPORT_C const TPtrC CFrameInfoStrings::Decoder() const + { + return String(EDecoder); + } + +/** +Adds the supplied string to this object as the 'decoder' entry. + +@param aString + A descriptor containing the string to add. +*/ +EXPORT_C void CFrameInfoStrings::SetDecoderL(const TDesC& aString) + { + SetStringL(EDecoder, aString); + } + +/** +Retruns a pointer to the 'format' entry string from this object. + +@return A pointer to the returned read-only string. +*/ +EXPORT_C const TPtrC CFrameInfoStrings::Format() const + { + return String(EFormat); + } + +/** +Adds the supplied string to this object as the 'format' entry. + +@param aString + A descriptor containing the string to add. +*/ +EXPORT_C void CFrameInfoStrings::SetFormatL(const TDesC& aString) + { + SetStringL(EFormat, aString); + } + +/** +Returns a pointer to the 'dimensions' entry string from this object. + +@return A pointer to the returned read-only string. +*/ +EXPORT_C const TPtrC CFrameInfoStrings::Dimensions() const + { + return String(EDimensions); + } + +/** +Adds the supplied string to this object as the 'dimensions' entry. + +@param aString + A descriptor containing the string to add. +*/ +EXPORT_C void CFrameInfoStrings::SetDimensionsL(const TDesC& aString) + { + SetStringL(EDimensions, aString); + } + +/** +Returns a pointer to the 'depth' entry string from this object. + +@return A pointer to the returned read-only string. +*/ +EXPORT_C const TPtrC CFrameInfoStrings::Depth() const + { + return String(EDepth); + } + +/** +Adds the supplied string to this object as the 'depth' entry. + +@param aString + A descriptor containing the string to add. +*/ +EXPORT_C void CFrameInfoStrings::SetDepthL(const TDesC& aString) + { + SetStringL(EDepth, aString); + } + +/** +Returns a pointer to the 'details' entry string from this object. + +@return A pointer to the returned read-only string. +*/ +EXPORT_C const TPtrC CFrameInfoStrings::Details() const + { + return String(EDetails); + } + +/** +Adds the supplied string to this object as the 'details' entry. + +@param aString + A descriptor containing the string to add. +*/ +EXPORT_C void CFrameInfoStrings::SetDetailsL(const TDesC& aString) + { + SetStringL(EDetails, aString); + } + +/** +Get a list of the basic image types that can be decoded, based on the +currently available decoder plugins. + +@param aImageTypeArray + An empty array, into which this function will put a list of + entries. Each entry will consist of the "display string" from + the registry entry for a plugin that has been found and that is + a decoder for a basic image type, accompanied by the Uids for + that image type. Since we asked for basic types the second Uid, + for the image sub-type, will always be zero. + + Ownership of the array is passed to the caller so, before the + array goes out of scope in the client, the caller must call + ResetAndDestroy() on it to free the entries. +*/ +EXPORT_C void CImageDecoder::GetImageTypesL(RImageTypeDescriptionArray& aImageTypeArray) + { + ImageEnDecoderUtils::DoGetImageTypesL(KImageDecoderInterfaceUid, aImageTypeArray); + } + +/** +For a given basic image type, get a list of the sub image types that can +be decoded, based on the currently available decoder plugins. + +@param aImageType + The basic image type for which you want a list of sub-types. +@param aSubTypeArray + An empty array, into which this function will put a list of + entries. Each entry will consist of the "display string" from + the registry entry for a plugin that has been found and that is + a decoder for a sub-type of the given basic image type, + accompanied by the Uids for the sub type. The first Uid, for + the basic type, will always correspond to aImageType. + + Ownership of the array is passed to the caller so, before the + array goes out of scope in the client, the caller must call + ResetAndDestroy() on it to free the entries. +*/ +EXPORT_C void CImageDecoder::GetImageSubTypesL(const TUid aImageType, RImageTypeDescriptionArray& aSubTypeArray) + { + ImageEnDecoderUtils::DoGetImageTypesL(KImageDecoderInterfaceUid, aSubTypeArray, aImageType); + } + +/** +Get a list of the file extensions that can be decoded and their corresponding +MIME types, based on the currently available decoder plugins. + +@param aFileTypeArray + An empty array, into which this function will put a list of + entries. Each entry will consist of a file extension string for + which a decoder plugin has been found, accompanied by the + primary MIME type and then any secondary MIME types + (if present). + + Ownership of the array is passed to the caller so, before the + array goes out of scope in the client, the caller must call + ResetAndDestroy() on it to free the entries. +*/ +EXPORT_C void CImageDecoder::GetFileTypesL(RFileExtensionMIMETypeArray& aFileTypeArray) + { + ImageEnDecoderUtils::DoGetFileTypesL(KImageDecoderInterfaceUid, aFileTypeArray); + } + +/** +Get the primary MIME type of the decoder that will be used to +decode a file. +Some file types (like OTA or WBPM), which do not have unique +pattern in their header may not be recognised, in case when +the source file name doesn't have extension or, extension is +not common to that file type. Such files are not supported by this API. + +@param aFs + A reference to a file server session to use. +@param aFileName + The name of the file for which a MIME type has to be determined +@param aMimeType + An empty descriptor in which the MIME type assosiated with the file + will be returned. Ownership is passed to the caller. +*/ +EXPORT_C void CImageDecoder::GetMimeTypeFileL(RFs& /*aFs*/, const TDesC& aFileName, TDes8& aMimeType) + { + CContent* content = CContent::NewLC(aFileName, EContentShareReadWrite); + CData* data = content->OpenContentL(EPeek); + + CleanupStack::PushL(data); + TBool mimeTypeKnown = data->GetMimeTypeL(aMimeType); + + if (!mimeTypeKnown) + { + TBuf8 imageHeader; + User::LeaveIfError(data->Read(imageHeader, KImageHeaderSize)); + + if (imageHeader.Length() < KImageHeaderSize) // There is not enough data in the file + { // Get out - clean up and leave + User::Leave(KErrUnderflow); + } + + DoGetMimeTypeL(aFileName, imageHeader, aMimeType); + } + CleanupStack::PopAndDestroy(2, content); // content, data + } + +/** +Get the primary MIME type of the decoder that will be used to +decode a descriptor. +Some file types (like OTA or WBPM), which do not have unique +pattern in their header may not be recognised. +Such files are not supported by this API + +@param aImageData + A descriptor containing the image data for which a MIME + type has to be determined. +@param aMimeType + An empty descriptor in which the MIME type assosiated with the file + will be returned. Ownership is passed to the caller. +*/ +EXPORT_C void CImageDecoder::GetMimeTypeDataL(const TDesC8& aImageData, TDes8& aMimeType) + { + TBuf8 imageHeader; + + if (aImageData.Length() < KImageHeaderSize) // There is not enough data in this source + { // Get out - clean up and leave + User::Leave(KErrUnderflow); + } + + imageHeader = aImageData.Left(KImageHeaderSize); + + DoGetMimeTypeL(KNullDesC, imageHeader, aMimeType); + } + +/** +Gets the implementation information for a specific decoder plugin + +Ownership of the implementation information is passed to the caller. + +@param aImplementationUid + The decoder implementation UID for which to retrieve implementation information +@return A pointer to the implementation information. +*/ +EXPORT_C CImplementationInformationType* CImageDecoder::GetImplementationInformationL(TUid aImplementationUid) + { + CImplementationInformationType* implementationInformation; + implementationInformation = CImplementationInformationType::NewLC(); + ImageEnDecoderUtils::DoGetImplementationInformationL(KImageDecoderInterfaceUid, *implementationInformation, aImplementationUid); + CleanupStack::Pop(implementationInformation); + return implementationInformation; + } + +/** +Gets a list of the properties of a specific decoder plugin. + +@publishedAll +@released +@param aImplementationUid + The decoder implementation UID for which the plugin properties need to be retrieved. +@param aPropertiesArray + The array of plugin properties owned by the specified decoder. + The caller has the ownership of the array. +*/ +EXPORT_C void CImageDecoder::GetPluginPropertiesL(const TUid aImplementationUid, RUidDataArray& aPropertiesArray) + { + ImageEnDecoderUtils::DoGetPluginPropertiesL(KImageDecoderInterfaceUid, aImplementationUid, aPropertiesArray); + } + +/** +@publishedAll +@released + +Gets a list of decoder implementations UIDs which have a set of specific capabilities defined by UIDs. + +@param aRequiredUids + The array containing the required UIDs (properties, image type, image sub-type or class UIDs). +@param aImplArray + The array containing the implementation UIDs of the available decoder plugins with the required UIDs. + The caller has the ownership of the array. +*/ +EXPORT_C void CImageDecoder::GetInterfaceImplementationsL(const RUidDataArray& aRequiredUids, RUidDataArray& aImplArray) + { + ImageEnDecoderUtils::DoGetInterfaceImplementationsL(KImageDecoderInterfaceUid, aRequiredUids, aImplArray); + } + +/** +@publishedAll +@released + +Gets a list of decoder implementations UIDs which have a set of specific capabilities defined by UIDs. + +@param aRequiredUids + The array containing the required UIDs (properties, image type, image sub-type or class UIDs). +@param aLength + The length of aRequiredUids (number of required UIDs). +@param aImplArray + The array containing the implementation UIDs of the available decoder plugins with the required UIDs. + The caller has the ownership of the array. +*/ +EXPORT_C void CImageDecoder::GetInterfaceImplementationsL(const TUid* aRequiredUids, const TInt aLength, RUidDataArray& aImplArray) + { + RUidDataArray requiredUids; + CleanupClosePushL(requiredUids); + for(TInt index = 0 ; index < aLength ; index++) + { + User::LeaveIfError(requiredUids.Append(aRequiredUids[index])); + } + ImageEnDecoderUtils::DoGetInterfaceImplementationsL(KImageDecoderInterfaceUid, requiredUids, aImplArray); + CleanupStack::PopAndDestroy(1); //requiredUids + } + +/** +Create a list of decoders that support the specified MIME type. + +@param aDecoderList + A list of decoders that support the given MIME type. +@param aMIMEType + The MIME type to decode. +@param aOptions + Extension options which must be supported by the plugin. +*/ +void CImageDecoder::MimeTypeGetDecoderListL(RImplInfoPtrArray& aDecoderList, const TDesC8& aMIMEType, const TOptions aOptions) + { + if (aMIMEType.Length() == 0) + { // Get out, empty MIME type string + User::Leave(KErrArgument); + } + + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + customMatchData->SetMatchType(EMatchMIMEType); + customMatchData->SetMatchStringL(aMIMEType); + customMatchData->SetOptions(aOptions); + customMatchData->SetExtensionOptions(aOptions); + + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + + TEComResolverParams resolverParams; // Parameters on which to match + resolverParams.SetDataType(packageDes); + + REComSession::ListImplementationsL(KImageDecoderInterfaceUid, resolverParams, KImageConvertResolverUid, aDecoderList); + + CleanupStack::PopAndDestroy(2); // package, customMatchData + } + + +/** +Create a list of decoders that support the specified image type. + +@param aDecoderList + A list of decoders 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 aDecoderUid + The implementation UID for a specific codec or a decoder/encoder class UID. +@param aOptions + Extension options which must be supported by the plugin. +@see KUidICLJpegEXIFInterface +@see KUidICLJpegImageFrameInterface +*/ +void CImageDecoder::ImageTypeGetDecoderListL(RImplInfoPtrArray& aDecoderList, const TDesC8& aImageHeader, const TUid aImageType, const TUid aImageSubType, const TUid aDecoderUid, const TOptions aOptions) + { + if (aDecoderUid != KNullUid) + { + RImplInfoPtrArray list; + CleanupResetAndDestroyPushL(list); + + REComSession::ListImplementationsL(KImageDecoderInterfaceUid, list); + + for (TInt i = 0; i < list.Count(); i++) + { + if (list[i]->ImplementationUid() == aDecoderUid) + { + User::LeaveIfError(aDecoderList.Append(list[i])); + } + else + { + delete list[i]; + } + list[i] = NULL; + } + + CleanupStack::PopAndDestroy(&list); + if (aDecoderList.Count() > 0) + { + return; + } + } + + TBuf8 imageHeader; + + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + + if ((aImageType != KNullUid) || (aDecoderUid != KNullUid)) + { // We have a specific image type we are trying to convert + customMatchData->SetMatchType(EMatchUids); + customMatchData->SetBaseType(aImageType); + customMatchData->SetSubType(aImageSubType); + customMatchData->SetImplementationType(aDecoderUid); + } + else + { + if (aImageHeader.Length() < KMinimumHeaderLength) // 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); + } + + customMatchData->SetOptions(aOptions); + customMatchData->SetExtensionOptions(aOptions); + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + + TEComResolverParams resolverParams; // Parameters on which to match + resolverParams.SetDataType(packageDes); + + #if defined(__ICL_PROFILING) + // intended for use with TProfImage only + RDebug::ProfileStart(2); + TRAPD(err,REComSession::ListImplementationsL(KImageDecoderInterfaceUid, resolverParams, KImageConvertResolverUid, aDecoderList)); + RDebug::ProfileEnd(2); + User::LeaveIfError(err); + #else + REComSession::ListImplementationsL(KImageDecoderInterfaceUid, resolverParams, KImageConvertResolverUid, aDecoderList); + #endif // defined(__ICL_PROFILING) + + CleanupStack::PopAndDestroy(2); // package, customMatchData + } + +/** +@internalComponent + +Creates a list of decoders that support the specified file extension. + +@param aDecoderList + A list of decoders that support the given file extension. +@param aFileName + The file name from which the file extension will be taken. +@param aOptions + Extension options which must be supported by the plugin. +*/ +void CImageDecoder::SuffixTypeGetDecoderListL(RImplInfoPtrArray& aDecoderList, const TDesC& aFileName, const TOptions aOptions) + { + 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); + customMatchData->SetOptions(aOptions); + customMatchData->SetExtensionOptions(aOptions); + + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + + TEComResolverParams resolverParams; // Parameters on which to match + resolverParams.SetDataType(packageDes); + + REComSession::ListImplementationsL(KImageDecoderInterfaceUid, resolverParams, KImageConvertResolverUid, aDecoderList); + + CleanupStack::PopAndDestroy(2,customMatchData); // package, customMatchData + } + +/** +@internalTechnology + +Scans a sorted list of decoders for the first one that can decode the image. + +@param aDecoderList + A list of decoders that support the image format. +@param aFs + A file server session for the decoder to use. +@param aSourceFilename + The filename of the file to decode. +@param aOptions + The options to use during decoding. + +@return A pointer to the decoder. +*/ + +CImageDecoder* CImageDecoder::FileFindDecoderNewL(const RImplInfoPtrArray& aDecoderList, RFs& aFs, const TDesC& aSourceFilename, const TOptions aOptions, const TDesC& aUniqueId) + { + TInt noOfDecoders = aDecoderList.Count(); + + if (noOfDecoders == 0) + { + User::Leave(KErrNotFound); + } + + CImageDecoder* decoder = NULL; + TInt decoderNo = 0; + TInt error = KErrNone; + + do + { + const CImplementationInformation& decoderInfo = *(aDecoderList[decoderNo++]); + + TRAP(error,decoder=FileDecoderNewL(decoderInfo, aFs, aSourceFilename, aOptions, aUniqueId)); + + if (error != KErrCorrupt && error != KErrNotSupported && error != KErrNotFound) + break; + } + while(decoderNo < noOfDecoders); + + if(error!=KErrNone) + { + ASSERT(decoder==NULL); + if (error == KErrCorrupt || error == KErrNotSupported) + error = KErrNotFound; + User::Leave(error); + } + + return decoder; + } + +/** +@internalTechnology + +Create a construct that can create a decoder and call +functions to initialise the decoder with the image data. + +@param aDecoderInfo + Implementation information for the decoder to be created. +@param aFs + A file server session for the decoder to use. +@param aSourceFilename + The filename of the file to decode. +@param aOptions + Options the decoder must use. + +@return A pointer to the decoder. +*/ + +CImageDecoder* CImageDecoder::FileDecoderNewL(const CImplementationInformation& aDecoderInfo, RFs& aFs, const TDesC& aSourceFilename, const TOptions aOptions, const TDesC& aUniqueId) + { + CImageDecodeConstruct* construct = NULL; + construct = NewDecodeConstructL(aDecoderInfo, aOptions); + ASSERT(construct!= NULL); + + CImageDecoder* decoder = NewL(construct, aOptions); // note NewL takes ownership of construct - don't push on stack + ASSERT(decoder!=NULL); + CleanupStack::PushL(decoder); + + decoder->iRelay->SetUniqueIdL(aUniqueId); + + decoder->iRelay->SetFileL(aFs, aSourceFilename, aOptions); + decoder->iRelay->HandleNewlyOpenedImageL(); + + CleanupStack::Pop(decoder); + return decoder; + } + +/** +@internalTechnology +@released +Scan a sorted list of decoders for the first one that can decode the image. + +@param aDecoderList + A list of decoders that support the image format. +@param aFs + A file server session for the decoder to use. +@param aSourceData + The data to decode. +@param aOptions + Options to use during decoding. + +@return A pointer to the decoder. + */ +CImageDecoder* CImageDecoder::DataFindDecoderNewL(const RImplInfoPtrArray& aDecoderList, RFs& aFs, const TDesC8& aSourceData, const TOptions aOptions) + { + TInt noOfDecoders = aDecoderList.Count(); + + if(noOfDecoders == 0) + User::Leave(KErrNotFound); + + CImageDecoder* decoder = NULL; + TInt decoderNo = 0; + TInt error = KErrNone; + do + { + const CImplementationInformation& decoderInfo = *(aDecoderList[decoderNo++]); + TRAP(error,decoder=DataDecoderNewL(decoderInfo, aFs, aSourceData, aOptions)); + if (error != KErrCorrupt && error != KErrNotSupported && error != KErrNotFound) + break; + } + while(decoderNo < noOfDecoders); + + if(error!=KErrNone) + { + ASSERT(decoder==NULL); + if (error == KErrCorrupt || error == KErrNotSupported) + error = KErrNotFound; + User::Leave(error); + } + + return decoder; + } + +/** +@internalTechnology +@released +Create a construct that can create a decoder and call +functions to initialise the decoder with the image data. + +@param aDecoderInfo + Implementation information for the decoder to be created. +@param aFs + A file server session for the decoder to use. +@param aSourceData + The data to decode. +@param aOptions + Options the decoder must use. + +@return A pointer to the decoder. +*/ +CImageDecoder* CImageDecoder::DataDecoderNewL(const CImplementationInformation& aDecoderInfo, RFs& aFs, const TDesC8& aSourceData, const TOptions aOptions) + { + CImageDecodeConstruct* construct = NULL; + construct = NewDecodeConstructL(aDecoderInfo, aOptions); + ASSERT(construct!= NULL); + + CImageDecoder* decoder = NewL(construct, aOptions); // note NewL takes ownership of construct - don't push on stack + ASSERT(decoder!=NULL); + CleanupStack::PushL(decoder); + + decoder->iRelay->SetDataL(aFs, aSourceData, aOptions); + decoder->iRelay->HandleNewlyOpenedImageL(); + + CleanupStack::Pop(decoder); + return decoder; + } + +/** +@internalTechnology + +Create a construct object for the specified decoder. + +@param aDecoderInfo + Implementation information for the decoder to be created. +@param aOptions + Extension options which must be supported by the plugin. +@return A construct object that can create the decoder. +*/ +CImageDecodeConstruct* CImageDecoder::NewDecodeConstructL(const CImplementationInformation& aDecoderInfo, const TOptions aOptions) + { + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + COpaqueDataParse* parse = COpaqueDataParse::NewLC(aDecoderInfo.OpaqueData()); + + customMatchData->SetMatchType(EMatchUids); + customMatchData->SetBaseType(parse->ImageTypeUid()); + customMatchData->SetSubType(parse->ImageSubTypeUid()); + customMatchData->SetImplementationType(aDecoderInfo.ImplementationUid()); + + CleanupStack::PopAndDestroy(parse); + + customMatchData->SetOptions(aOptions); + customMatchData->SetExtensionOptions(aOptions); + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + + TEComResolverParams resolverParams; + resolverParams.SetDataType(packageDes); + + CImageDecodeConstruct* construct = NULL; +#if defined(__ICL_PROFILING) + // intended for use with TProfImage only + RDebug::ProfileStart(3); + TRAPD(err, construct = STATIC_CAST(CImageDecodeConstruct*, + REComSession::CreateImplementationL(KImageDecoderInterfaceUid, + _FOFF(CImageDecodeConstruct, iDtorIDKey), + resolverParams, + KImageConvertResolverUid))); + RDebug::ProfileEnd(3); + User::LeaveIfError(err); +#else + construct = STATIC_CAST(CImageDecodeConstruct*, + REComSession::CreateImplementationL(KImageDecoderInterfaceUid, + _FOFF(CImageDecodeConstruct, iDtorIDKey), + resolverParams, + KImageConvertResolverUid)); +#endif // defined(__ICL_PROFILING) + + ASSERT(construct!=NULL); + + CleanupStack::PopAndDestroy(2, customMatchData); //package, customMatchData + + return construct; + } + +/** +@internalTechnology + +Get the MIME type for a given match string. + +@param aFileName + The file name of the image file. +@param aMatchString + An image header of an image file. +@param aMimeType + The primary MIME type returned. +*/ +void CImageDecoder::DoGetMimeTypeL(const TDesC& aFileName, const TDesC8& aMatchString, TDes8& aMimeType) + { + // Get a list of decoders that will decode the image. + RImplInfoPtrArray decoderList; + CleanupResetAndDestroyPushL(decoderList); + CImageDecoder::ImageTypeGetDecoderListL(decoderList, aMatchString, KNullUid, KNullUid, KNullUid); + + // Try to match by file extension. + // aFileName will be KNullDesC when called from GetMimeTypeDataL() + if(aFileName!=KNullDesC && decoderList.Count() == 0) + CImageDecoder::SuffixTypeGetDecoderListL(decoderList, aFileName); + + if(decoderList.Count() == 0) + User::Leave(KErrNotFound); + + TInt decoderNo = 0; + +#if defined (__GET_MIME_TYPE_THOROUGH) + RFs fs; + CleanupClosePushL(fs); + User::LeaveIfError(fs.Connect()); + TInt noOfDecoders = decoderList.Count(); + + CImageDecoder* decoder = NULL; + TInt error = KErrNotFound; + while(decoderNo < noOfDecoders) + { + const CImplementationInformation& decoderInfo = *(decoderList[decoderNo]); + TRAP(error,decoder=DataDecoderNewL(decoderInfo, fs, aMatchString, EOptionAllowZeroFrameOpen)); + // if decoder didn't match, then it should return KErrCorrupt, + // but we also accept KErrNotSupported & KErrNotFound + if (error != KErrCorrupt && error != KErrNotSupported && error != KErrNotFound) + break; + decoderNo++; + } + + if (error!=KErrNone) + { + ASSERT(decoder==NULL); + if (error == KErrCorrupt || error == KErrNotSupported) + error = KErrNotFound; + User::Leave(error); + } + delete decoder; + CleanupStack::PopAndDestroy(&fs); +#endif // defined (__GET_MIME_TYPE_THOROUGH) + + //Use the highest rated decoder. + CImageDecodeConstruct* construct = NewDecodeConstructL(*decoderList[decoderNo]); + CleanupStack::PopAndDestroy(&decoderList); + if (construct == NULL) + { // We didn't get a match - leave + User::Leave(KErrNotFound); + } + CleanupStack::PushL(construct); + + // Determine the primary Mime type of the decoder + CImplementationInformationType* implementationInformation = NULL; + implementationInformation = GetImplementationInformationL(construct->ImplementationUid()); + CleanupStack::PushL(implementationInformation); + + TPtrC8 opaqueDataPtr = implementationInformation->OpaqueData(); + COpaqueDataParse* parse = COpaqueDataParse::NewLC(opaqueDataPtr); + + if(parse->OnlyUidsAvail()) + { + User::Leave(KErrNotFound); + } + + parse->EnsureMIMETypesReadL(); + + aMimeType = parse->MIMEType(0); + + CleanupStack::PopAndDestroy(3); // parse, ImplementationInformation, decoderPtr + } + +/** +Create a decoder for the image in the named file. The client supplies a +MIME type which will be used to try and select an appropriate plugin +decoder. If it finds a decoder it creates it and then goes on to use that +decoder to scan the beginning of the image file. + +If any file related errors are encountered opening the specified file, this +function leaves with an appropriate file related leave code. + +@param aFs + A reference to a file server session for the decoder to use. +@param aSourceFilename + The name of the file to be decoded. +@param aMIMEType + The MIME type of the image in the file. +@param aOptions + Decoder options to use. + +@return Returns a pointer to the newly created decoder. + +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. +@leave KErrNotFound + Either the specific plugin decoder for this file hasn't been found, or the file itself is missing. + +@see TOptions +*/ +EXPORT_C CImageDecoder* CImageDecoder::FileNewL(RFs& aFs, const TDesC& aSourceFilename, const TDesC8& aMIMEType, const TOptions aOptions) + { + return CImageDecoder::FileNewImplL(aFs, aSourceFilename, aMIMEType, KDefaultContentObject, EPeek, aOptions); + } + +/** +Create a decoder for the image in the named file. The client supplies a +MIME type which will be used to try and select an appropriate plugin +decoder. If it finds a decoder it creates it and then goes on to use that +decoder to scan the beginning of the image file. + +@param aFs + A reference to a file server session for the decoder to use. +@param aSourceFilename + The name of the file to be decoded. +@param aMIMEType + The MIME type of the image in the file. +@param aIntent + The DRM Intent for image conversion. +@param aOptions + The decoder options to use. + +@return A pointer to the newly created decoder. + +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. +@leave KErrNotFound + Either the specific plugin decoder for this file hasn't been found, or the file itself is missing. +*/ +EXPORT_C CImageDecoder* CImageDecoder::FileNewL(RFs& aFs, const TDesC& aSourceFilename, const TDesC8& aMIMEType, TIntent aIntent, const TOptions aOptions) + { + return CImageDecoder::FileNewImplL(aFs, aSourceFilename, aMIMEType, KDefaultContentObject, aIntent, aOptions); + } + +/** +Create a decoder for the image in the named file. The client supplies a +MIME type which will be used to try and select an appropriate plugin +decoder. If it finds a decoder it creates it and then goes on to use that +decoder to scan the beginning of the image file. + +@param aFs + A reference to a file server session for the decoder to use. +@param aSource + An interface between filename based and file handle. +@param aMIMEType + The MIME type of the image in the file. +@param aOptions + The decoder options to use. Specifying one of more extension options (for example EOptionExtCrop) can be used to cause the + to cause a plugin to load which supports the image type and supports the requested extensions. + +@return A pointer to the newly created decoder. + +@leave KErrNotSupported + A matching decoder could not be found for the MIME type. +@leave KErrNotFound + Either the specific plugin decoder for this source image hasn't been found, or the source image itself is missing, or + a plugin with the requested extensions cannot be found. +*/ +EXPORT_C CImageDecoder* CImageDecoder::FileNewL(RFs& aFs, const TMMSource& aSource, const TDesC8& aMIMEType, const TOptions aOptions) + { + if (aSource.SourceType()==KUidMMFileHandleSource) + { + const TMMFileHandleSource& source = static_cast(aSource); + return CImageDecoder::FileNewImplL(source.Handle(), aMIMEType, source.UniqueId(), source.Intent(), aOptions); + } + else if (aSource.SourceType()==KUidMMFileSource) + { + const TMMFileSource& source = static_cast(aSource); + return CImageDecoder::FileNewImplL(aFs, source.Name(), aMIMEType, source.UniqueId(), source.Intent(), aOptions); + } + else + { + // unknown source type + User::Leave(KErrNotSupported); + return NULL; + } + } + +/** +Create a decoder for the image in the named source. + +@param aFs + A reference to a file server session for the decoder to use. +@param aSource + An interface between filename based and file handle. +@param aOptions + The decoder options to use. Specifying one of more extension options (for example EOptionExtCrop) can be used to cause the + to cause a plugin to load which supports the image type and supports the requested extensions. +@param aImageType + The image type of the image in the file. +@param aImageSubType + The image sub-type of the image in the file. +@param aDecoderUid + The implementation UID for a specific codec or a decoder/encoder class UID. +@see KUidICLJpegEXIFInterface +@see KUidICLJpegImageFrameInterface +@return A pointer to the newly created decoder. + +@leave KErrNotSupported + A matching decoder could not be found for the MIME type. +@leave KErrNotFound + Either the specific plugin decoder for this source image hasn't been found, or the source image itself is missing. +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. + +@panic ImageConversion 19 + No base type given for sub-type. +*/ +EXPORT_C CImageDecoder* CImageDecoder::FileNewL(RFs& aFs, const TMMSource& aSource, + const TOptions aOptions, const TUid aImageType, + const TUid aImageSubType, const TUid aDecoderUid) + { + if (aSource.SourceType()==KUidMMFileHandleSource) + { + const TMMFileHandleSource& source = static_cast(aSource); + return CImageDecoder::FileNewImplL(source.Handle(), source.UniqueId(), source.Intent(), aOptions, aImageType, aImageSubType, aDecoderUid); + } + else if (aSource.SourceType()==KUidMMFileSource) + { + const TMMFileSource& source = static_cast(aSource); + return CImageDecoder::FileNewImplL(aFs, source.Name(), source.UniqueId(), source.Intent(), aOptions, aImageType, aImageSubType, aDecoderUid); + } + else + { + // unknown source type + User::Leave(KErrNotSupported); + return NULL; + } + } + +/** + +Sets the properties for the Image decoder. + +@param aProperty + The property to set. +@param aValue + The value of the property. + +@return KErrNone if successful, otherwise one of the system-wide errors. +*/ +EXPORT_C TInt CImageDecoder::SetAgentProperty(ContentAccess::TAgentProperty aProperty, TInt aValue) + { + ASSERT(ValidProperties()); + return iRelay->SetAgentProperty(aProperty, aValue); + } + +/** +@internalTechnology + +Creates a decoder for the image in the named file. The client supplies a +MIME type which will be used to try and select an appropriate plugin +decoder. If it finds a decoder it creates it and then goes on to use that +decoder to scan the beginning of the image file. + +@param aFs + A reference to a file server session for the decoder to use. +@param aSourceFilename + The name of the file to be decoded. +@param aMIMEType + The MIME type of the image in the file. +@param aUniqueId + The object to open for reading. If the UniqueId is set to KNullDesC the entire file will be opened for reading with no transformation. +@param aIntent + The DRM Intent for image conversion. +@param aOptions + The decoder options to use. + +@return A pointer to the newly created decoder. + +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. +@leave KErrNotFound + Either the specific plugin decoder for this file hasn't been found, or the file itself is missing. +*/ + +CImageDecoder* CImageDecoder::FileNewImplL(RFs& aFs, const TDesC& aSourceFilename, const TDesC8& aMIMEType, const TDesC& aUniqueId, TIntent aIntent, const TOptions aOptions) + { + CContent* content = NULL; + content = GetContentLC(aSourceFilename); + CData* data = content->OpenContentL(aIntent, aUniqueId); // check file presence, evaluate (not execute) intent + CleanupStack::PopAndDestroy(content); + + delete data; // close file + + + //Get a sorted list of decoders that will decode the image + RImplInfoPtrArray decoderList; + CleanupResetAndDestroyPushL(decoderList); + CImageDecoder::MimeTypeGetDecoderListL(decoderList, aMIMEType, aOptions); + + CImageDecoder* decoder = NULL; + decoder = CImageDecoder::FileFindDecoderNewL(decoderList, aFs, aSourceFilename, aOptions, aUniqueId); + + ASSERT(decoder!=NULL); + CleanupStack::PushL(decoder); + decoder->iRelay->SetIntent(aIntent); + + CleanupStack::Pop(decoder); + CleanupStack::PopAndDestroy(&decoderList); + return decoder; + } + +/** +Create a decoder for the image in the source buffer. The client supplies a +MIME type which will be used to try and select an appropriate plugin +decoder. If a decoder is found it is created and then used to scan +the beginning of the image file. + +@param aFs + A reference to a file server session for the decoder to use. +@param aSourceData + The buffer containing the image to be decoded. Note that the framework + doesn't take a copy of the actual data, therefore both the descriptor + object and the data must persist during decoding. +@param aMIMEType + The MIME type of the image in the file(used to determine the plugin + to create). +@param aOptions + The decoder options to use. Specifying one of more extension options (for example EOptionExtCrop) can be used to cause the + to cause a plugin to load which supports the image type and supports the requested extensions. + +@return Returns a pointer to the newly created decoder. + +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. +@leave KErrNotFound + No appropriate plugin decoder for this image has been found. + +@see TOptions +*/ +EXPORT_C CImageDecoder* CImageDecoder::DataNewL(RFs& aFs, const TDesC8& aSourceData, const TDesC8& aMIMEType, const TOptions aOptions) + { + //Get a list of decoders that will decode the image + RImplInfoPtrArray decoderList; + CleanupResetAndDestroyPushL(decoderList); + CImageDecoder::MimeTypeGetDecoderListL(decoderList, aMIMEType, aOptions); + + CImageDecoder* decoder = NULL; + decoder = CImageDecoder::DataFindDecoderNewL(decoderList, aFs, aSourceData, aOptions); + ASSERT(decoder!=NULL); + + CleanupStack::PopAndDestroy(&decoderList); + return decoder; + } + +/** +Create a decoder for the image in the named file. + +If the client supplies an image type (and sub-type, if applicable) or decoder +UID, these will be used to try and select an appropriate plugin decoder. If +not, then the selection will be done by matching the image header in the file. +If it finds a decoder, it will be created and then used to scan the beginning +of the image file. + +Note: Every image format has two IDs, known as the type and the sub-type (although +generally the sub-type is KNullUid). To retrieve a list of supported types and +sub-types that can be decoded, use the static functions GetImageTypesL() and +GetImageSubTypesL(). + +@param aFs + A reference to a file server session for the decoder to use. +@param aSourceFilename + The name of the file to be decoded. +@param aOptions + Decoder options to use. +@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 aDecoderUid + The implementation UID for a specific codec or a decoder/encoder class UID (optional, defaults to KNullUid). + If this option is selected for a specific codec the image type and image sub type for the displayer must be supplied. + When loading plugins by class UID the image type and image subtype are not mandatory and the first valid plugin from + the list of available plugins with the specified class UID will be loaded. +@see KUidICLJpegEXIFInterface +@see KUidICLJpegImageFrameInterface +@return Returns a pointer to the newly created decoder. + +@leave KErrUnderflow + Not enough data in file to identify which plugin decoder to use. +@leave KErrNotFound + Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing. +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. + +@panic ImageConversion 19 + No base type given for sub-type. + +@see TOptions +*/ +EXPORT_C CImageDecoder* CImageDecoder::FileNewL(RFs& aFs, const TDesC& aSourceFilename, const TOptions aOptions, const TUid aImageType, const TUid aImageSubType, const TUid aDecoderUid) + { + return CImageDecoder::FileNewImplL(aFs, aSourceFilename, KDefaultContentObject, EPeek, aOptions, aImageType, aImageSubType, aDecoderUid); + } + +/** +Creates a decoder for the image in the named file. If the client supplies an +image type (and sub-type, if applicable) or decoder UID, these will be used +to try and select an appropriate plugin decoder. If not, then the selection +will be done by matching the image header in the file. If it finds a decoder +it creates it and then goes on to use that decoder to scan the beginning of +the image file. + +@param aFs + A reference to a file server session for the decoder to use. +@param aSourceFilename + The name of the file to be decoded. +@param aIntent + The DRM Intent for image conversion. +@param aOptions + The decoder options to use. See TOptions. +@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 aDecoderUid + The implementation UID for a specific codec or a decoder/encoder class UID (optional, defaults to KNullUid). + If this option is selected for a specific codec the image type and image sub type for the displayer must be supplied. + When loading plugins by class UID the image type and image subtype are not mandatory and the first valid plugin from + the list of available plugins with the specified class UID will be loaded. +@see KUidICLJpegEXIFInterface +@see KUidICLJpegImageFrameInterface + +@return A pointer to the newly created decoder. + +@leave KErrUnderflow + Not enough data in file to identify which plugin decoder to use. +@leave KErrNotFound + Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing. +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. + +@panic ImageConversion 19 + No base type given for sub-type. + +@see TOptions +*/ +EXPORT_C CImageDecoder* CImageDecoder::FileNewL(RFs& aFs, const TDesC& aSourceFilename, TIntent aIntent, const TOptions aOptions, const TUid aImageType, const TUid aImageSubType, const TUid aDecoderUid) + { + return CImageDecoder::FileNewImplL(aFs, aSourceFilename, KDefaultContentObject, aIntent, aOptions, aImageType, aImageSubType, aDecoderUid); + } + +/** +@internalTechnology + +Creates a decoder for the image in the named file. If the client supplies an +image type (and sub-type, if applicable) or decoder UID, these will be used +to try and select an appropriate plugin decoder. If not, then the selection +will be done by matching the image header in the file. If it finds a decoder +it creates it and then goes on to use that decoder to scan the beginning of +the image file. + + +@param aFs + A reference to a file server session for the decoder to use. +@param aSourceFilename + The name of the file to be decoded. +@param aUniqueId + The object to open for reading. If the UniqueId is set to KNullDesC the entire file will be opened for reading with no transformation. +@param aIntent + The DRM Intent for image conversion +@param aOptions + The decoder options to use. See TOptions. +@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 aDecoderUid + The implementation UID for a specific codec or a decoder/encoder class UID (optional, defaults to KNullUid). + If this option is selected for a specific codec the image type and image sub type for the displayer must be supplied. + When loading plugins by class UID the image type and image subtype are not mandatory and the first valid plugin from + the list of available plugins with the specified class UID will be loaded. +@see KUidICLJpegEXIFInterface +@see KUidICLJpegImageFrameInterface + +@return A pointer to the newly created decoder. + +@leave KErrUnderflow + Not enough data in file to identify which plugin decoder to use. +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. +@leave KErrNotFound + Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing. +@panic ImageConversion 19 + No base type given for sub-type. + +@see TOptions + */ + +CImageDecoder* CImageDecoder::FileNewImplL(RFs& aFs, const TDesC& aSourceFilename, const TDesC& aUniqueId, const TIntent aIntent, const TOptions aOptions, const TUid aImageType, const TUid aImageSubType, const TUid aDecoderUid) + { + if ((aImageType == KNullUid) && (aImageSubType != KNullUid)) + { // Get out, no base type given for sub-type + Panic(EIllegalImageSubType); + } + + RImplInfoPtrArray decoderList; + CleanupResetAndDestroyPushL(decoderList); + + CContent* content = NULL; + content = GetContentLC(aSourceFilename); + CData* data = content->OpenContentL(aIntent, aUniqueId); + CleanupStack::PopAndDestroy(content); + + CleanupStack::PushL(data); + + if (aImageType == KNullUid && aDecoderUid == KNullUid) + { + TBuf8 mimeType; + if (data->GetMimeTypeL(mimeType)) + { + // try to find a controller based on MIME type + CImageDecoder::MimeTypeGetDecoderListL(decoderList, mimeType, aOptions); + } + if (decoderList.Count()==0) + { + // read header data + TBuf8 imageHeader; + User::LeaveIfError(data->Read(imageHeader, KImageHeaderSize)); + CImageDecoder::ImageTypeGetDecoderListL(decoderList, imageHeader, aImageType, aImageSubType, aDecoderUid, aOptions); + } + } + else + { + TBuf8 imageHeader; + User::LeaveIfError(data->Read(imageHeader, KImageHeaderSize)); + CImageDecoder::ImageTypeGetDecoderListL(decoderList, imageHeader, aImageType, aImageSubType, aDecoderUid, aOptions); + } + + CleanupStack::PopAndDestroy(1, data); //data + + //Try to match by file extension only + //1) If no plugin was found and + //2) No specific decoder or format was specified + const TBool formatSpecified = (aImageType!=KNullUid || aImageSubType!=KNullUid || aDecoderUid!=KNullUid); + if(decoderList.Count()==0 && !formatSpecified) + { + CImageDecoder::SuffixTypeGetDecoderListL(decoderList, aSourceFilename, aOptions); + } + + CImageDecoder* decoder = NULL; + decoder = CImageDecoder::FileFindDecoderNewL(decoderList, aFs, aSourceFilename, aOptions, aUniqueId); + + + ASSERT(decoder!=NULL); + CleanupStack::PushL(decoder); + decoder->iRelay->SetIntent(aIntent); + + CleanupStack::Pop(decoder); + CleanupStack::PopAndDestroy(&decoderList); + return decoder; + } + + +/** +Creates a decoder for the image in the source buffer. + +If the client supplies an image type (and sub-type, if applicable) or decoder UID, +these will be used to try and select an appropriate plugin decoder. If not, then +the selection will be done by matching the image header from the buffer. If it +finds a decoder, it is created and then used to scan the beginning of the image +buffer. + +@param aFs + A reference to a file server session for the decoder to use. +@param aSourceData + The buffer containing the image to be decoded. Note that the framework + doesn't take a copy of the actual data, therefore both the descriptor + object and the data must persist during decoding. +@param aOptions + Decoder options to use. +@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 aDecoderUid + The implementation UID for a specific codec or a decoder/encoder class UID (optional, defaults to KNullUid). + If this option is selected for a specific codec the image type and image sub type for the displayer must be supplied. + When loading plugins by class UID the image type and image subtype are not mandatory and the first valid plugin from + the list of available plugins with the specified class UID will be loaded. +@see KUidICLJpegEXIFInterface +@see KUidICLJpegImageFrameInterface + +@return Returns a pointer to the newly created decoder. + +@leave KErrUnderflow + Not enough data in descriptor to identify which plugin decoder to use. +@leave KErrNotFound + No appropriate plugin decoder for this image has been found. +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. + +@panic ImageConversion 19 + No base type given for sub-type. + +@see TOptions +*/ +EXPORT_C CImageDecoder* CImageDecoder::DataNewL(RFs& aFs, const TDesC8& aSourceData, const TOptions aOptions, const TUid aImageType, const TUid aImageSubType, const TUid aDecoderUid) + { + if ((aImageType == KNullUid) && (aImageSubType != KNullUid)) + { // Get out, no base type given for sub-type + Panic(EIllegalImageSubType); + } + + //Get a list of decoders that will decode the image + RImplInfoPtrArray decoderList; + CleanupResetAndDestroyPushL(decoderList); + CImageDecoder::ImageTypeGetDecoderListL(decoderList, aSourceData, aImageType, aImageSubType, aDecoderUid, aOptions); + + CImageDecoder* decoder = NULL; + decoder = CImageDecoder::DataFindDecoderNewL(decoderList, aFs, aSourceData, aOptions); + ASSERT(decoder!=NULL); + + CleanupStack::PopAndDestroy(&decoderList); + return decoder; + + + } + +/** +@internalTechnology + +Called internally to create a CImageDecoder and associated iRelay body + +This member is internal and not intended for use. +*/ +CImageDecoder* CImageDecoder::NewL(CImageDecodeConstruct* aConstruct, TOptions aOptions) + { + CleanupStack::PushL(aConstruct); // we take ownership of this until can pass to relay + CImageDecoder* self = aConstruct->NewDecoderL(); // typically will callback to CImageDecoder::NewL() + CleanupStack::PushL(self); + TBool alwaysThread = (aOptions & EOptionAlwaysThread)!=EFalse; + self->iRelay = MImageDecoderRelay::NewL(aConstruct, alwaysThread); + CleanupStack::Pop(2); // self and construct + self->iRelay->TransferConstructOwnership(); + return self; + } + +/** +@internalTechnology + +Actual factory function for CImageDecoder - ie. it creates the object +Called back plugin - to allow plugin to override if required + +This member is internal and not intended for use. +*/ +CImageDecoder* CImageDecoder::NewL() + { + CImageDecoder* self = new (ELeave) CImageDecoder; + return self; + } + +/** +Constructor for this class. +@internalTechnology +*/ +EXPORT_C CImageDecoder::CImageDecoder() + { + } + +/** +Destructor for this class. + +If using a local file session, it closes it. +It also informs ECom that has finished with the decoder instance. + +Frees all resources owned by the object prior to its destruction. +*/ +EXPORT_C CImageDecoder::~CImageDecoder() + { + Cancel(); + + delete iRelay; + } + +/** +Start decoding an image frame asynchronously. + +@pre +The destination bitmap aDestination, must be created before the call to +Convert() is made. aDestination must be large enough to contain the frame and +be set to the required display mode. FrameInfo() can be used to obtain +the size and display mode of the frame. + +When the conversion is complete, successfully or otherwise, the status is +returned in aRequestStatus. + +If the operations completes with KErrUnderflow, then there is insufficient +information in the descriptor. In this situation, ContinueConvert() should be +called repeatedly until the descriptor has accumulated enough information +for ContinueConvert() to complete with KErrNone.It is the responsibility of the +caller to ensure that the original data source used to create this decoder object +gets enough information. If there is no data available then a caller can ignore +this error code and use partially decoded image. + +@param aRequestStatus + Request status. On completion contains an error code. + KErrNone if frame was decoded successfully, + KErrUnderflow if the frame was partially decoded + otherwise another of the system-wide error codes. +@param aDestination + A bitmap that will contain the decoded frame. +@param aFrameNumber + The frame in a multi-frame image to decode (optional, defaults to zero). + +@note +As most codec plugins support downscaling the image but not upscaling, the standard behaviour (i.e. no requested +transformations) for codecs begins with the size of the destination bitmap passed to CImageDecoder::Convert being +inspected, and: + +- 1. If the destination size matches the frame size of the image then the image is decoded full size into the destination +bitmap. +- 2. If the destination size is larger than the frame size of the image then the image is decoded full size into the +destination bitmap with no upscaling. The image origin is aligned with the top left corner of the bitmap and any area +in the bitmap to the bottom and right of image is left in its initialised state. +- 3. If the destination size is smaller than the frame size of the image then a reduction factor is calculated and the +image is scaled down (1/2, 1/4, 1/8 size) whilst maintaining the aspect ratio of the image. The size is the next +smallest size that will fit in the destination bitmap. The use case for this is when the client wants to pass in the +screen size of device and have the image scaled to fill as much of the screen as possible. +However, if the extension interfaces (clipping, scale, operation) are used then the additional behaviour below applies. +- 4. If the extension interfaces for clipping rectangle and/or operation are applied, but not scaling, then the size of +the destination bitmap for an unscaled image can be obtained via CImageDecoder::GetDestinationSize. +Lets call that SizeA. The same rules apply as given in 1, 2, 3 above resulting in a down-scaled destination if the +destination bitmap is smaller than SizeA. +- 5. If the extension interface for scaling is called via one of the two TImageConvScaler::SetScalingL(.. functions then +it is required that the destination size is obtained through CImageDecoder::GetDestinationSize and that a destination +bitmap of that size is passed to CImageDecoder::Convert. Failure to do this will cause the decoder to fail with KErrArgument. +This rule holds if clipping and/or operation is applied as well as scaling. +*/ +EXPORT_C void CImageDecoder::Convert(TRequestStatus* aRequestStatus, CFbsBitmap& aDestination, TInt aFrameNumber) + { + ASSERT(ValidProperties()); + iRelay->Convert(aRequestStatus, aDestination, aFrameNumber); + } + +/** +Set the source image type, this can be any value from TImageType. It can leave with a system wide +error. Typical leaves are documented below. + +@param aImageType + An image type from TImageType to denote source image that the decoder should use. +@leave KErrNotFound + If the image for the type specified is not found. +@leave KErrCorrupt + For a corrupt image. In the case of failing to change the source image from a valid + EImageTypeMain image to a corrupt EImageTypeThumbnail, the decoder resets the image + type back to the valid EImageTypeMain. +*/ +EXPORT_C void CImageDecoder::SetImageTypeL(TInt aImageType) + { + ASSERT(ValidProperties()); + iRelay->SetImageTypeL(aImageType); + } + + +/** +Start decoding an image frame and mask asynchronously. + +@pre +The destination bitmap aDestination, must be created before the call to +Convert() is made. aDestination must be large enough to contain the frame and +be set to the required display mode. FrameInfo() can be used to obtain +the size and display mode of the frame. The destination mask aDestinationMask +must be created before the call to Convert() is made and must be large enough for +the mask. The display mode must be EGray2 or EGray256 and must be EGray256 if the +image contains alpha-blending information. This information can be obtained from +the iFlags property of TFrameInfo obtained from a FrameInfo() call. + +When the conversion is complete, successfully or otherwise, the status is +returned in aRequestStatus. + +If the operations completes with KErrUnderflow, then there is insufficient +information in the descriptor. In this situation, ContinueConvert() should be +called repeatedly until the descriptor has accumulated enough information +for ContinueConvert() to complete with KErrNone.It is the responsibility of the +caller to ensure that the original data source used to create this decoder object +gets enough information. If there is no data available then a caller can ignore +this error code and use partially decoded image. + +@param aRequestStatus + Request status. On completion contains an error code. + KErrNone if frame was decoded successfully, + KErrUnderflow if the frame was partially decoded + otherwise another of the system-wide error codes. +@param aDestination + A bitmap that will contain the decoded frame. +@param aDestinationMask + A bitmap that will contain the decoded frame mask. +@param aFrameNumber + The frame in multi-frame image to decode (optional, defaults to zero). + +@see TFrameInfo +*/ +EXPORT_C void CImageDecoder::Convert(TRequestStatus* aRequestStatus, CFbsBitmap& aDestination, CFbsBitmap& aDestinationMask, TInt aFrameNumber) + { + ASSERT(ValidProperties()); + iRelay->Convert(aRequestStatus, aDestination, aDestinationMask, aFrameNumber); + } + +/** +Continue decoding a frame and/or mask after new image data was added to +the source file or descriptor and a previous call to Convert() or +ContinueConvert() returned KErrUnderflow. + +@param aRequestStatus + Request status. On completion contains an error code. + KErrNone if frame was decoded successfully, + KErrUnderflow if the frame was partially decoded + otherwise another of the system-wide error codes. +*/ +EXPORT_C void CImageDecoder::ContinueConvert(TRequestStatus* aRequestStatus) + { + ASSERT(ValidProperties()); + iRelay->ContinueConvert(aRequestStatus); + } + +/** +Return the number of frames in the image being decoded. + +This function can be called immediately after the call to create the decoder, +thus enabling the caller to know how many frames need to be converted. Client +may have to call IsImageHeaderProcessingComplete() & ContinueProcessingHeaders() +to ensure all all data is available. + +@return The number of frames in the source image. +*/ +EXPORT_C TInt CImageDecoder::FrameCount() const + { + ASSERT(ValidProperties()); + return iRelay->FrameCount(); + } + +/** +Return the status of the image. + +If the image is incomplete EFalse will be returned. The client should continue +to supply more data and call ContinueProcessingHeaders() until ETrue is returned. + +Panic categories: Many CImageDecoder functions are dependent upon this function +returning ETrue before they can successfully be called. If the client calls one +of these dependent functions, then that function call may panic with either the +'ImageConversion' panic category or a decoder plugin specific panic category, +for example: 'BMPConvertPlugin', 'GIFConvertPlugin', 'ICOConvertPlugin', +'JPEGConvertPlugin', 'MBMConvertPlugin', 'OTAConvertPlugin', 'PNGConvertPlugin', +'TIFFConvertPlugin', 'WBMPConvertPlugin', 'WMFConvertPlugin'. + + +@return Image status. +*/ +EXPORT_C TBool CImageDecoder::IsImageHeaderProcessingComplete() const + { + return iRelay->IsImageHeaderProcessingComplete(); + } + +/** +Continue processing image headers after new image data was added to +the source file or descriptor. + +@see IsImageHeaderProcessingComplete() +*/ +EXPORT_C void CImageDecoder::ContinueProcessingHeaderL() + { + ASSERT(ValidProperties()); + iRelay->ContinueProcessingHeaderL(); + } + +/** +Cancels any conversions currently in progress (Cancel is synchronous). +*/ +EXPORT_C void CImageDecoder::Cancel() + { + if(ValidProperties()) + iRelay->Cancel(); + } + +/** +Return the frame info for a specified frame of the image. + +This function can be called immediately after the call to create +the decoder, thus enabling the caller to know about each frame in +advance of converting it. + +The returned information contains details of the size of the image, +the dimensions of the frame, its colour depth and so on. More advanced +information may be available for the image using FrameData(). + +Use FrameCount() to determine how many frames are contained in the image +before using this function. + +@param aFrameNumber + The frame number. + +@return The returned information for the specified frame. + +@panic ImageConversion 10 + Frame number outside the range 0 to FrameCount()-1. + See CImageDecoder::FrameCount(). + +@see CImageDecoder::FrameCount() +*/ +EXPORT_C const TFrameInfo& CImageDecoder::FrameInfo(TInt aFrameNumber) const + { + // Return the frame info for a particular frame + ASSERT(ValidProperties()); + return iRelay->FrameInfo(aFrameNumber); + } + +/** +Returns additional plugin specific information on a specified frame. + +The plugin specific information usually covers advanced image features such +as image quality, advanced colour settings and so on. + +Use FrameCount() to determine how many frames are contained in the +image before using this function. + +@param aFrameNumber + The frame number. + +@return The data for the specified frame. + +@panic ImageConversion 10 + Frame number outside the range 0 to FrameCount()-1. + See CImageDecoder::FrameCount(). + +@see CImageDecoder::FrameCount() +*/ +EXPORT_C const CFrameImageData& CImageDecoder::FrameData(TInt aFrameNumber) const + { + // Return the frame image data for a particular frame. + ASSERT(ValidProperties()); + return iRelay->FrameData(aFrameNumber); + } + +/** +Return the number of comments attached to the image (as opposed to +a particular frame). + +For further informantion on panic categories, please see the note in +CImageDecoder::IsImageHeaderProcessingComplete(). + +@panic ImageConversion 13 Header processing has not completed. + See CImageDecoder::IsImageHeaderProcessingComplete(). + +@see IsImageHeaderProcessingComplete() + +@return The number of comments attached to the image. +*/ +EXPORT_C TInt CImageDecoder::NumberOfImageComments() const + { + ASSERT(ValidProperties()); + return iRelay->Plugin()->NumberOfImageComments(); + } + +/** +Return a particular comment attached to the image. + +Ownership of the returned buffer is transferred to the caller. Use NumberOfImageComments() +to determine how many (if any) comments are contained within the image. + +For further informantion on panic categories, please see the note in +CImageDecoder::IsImageHeaderProcessingComplete(). + +@param aCommentNumber The comment number. + +@panic ImageConversion 12 Comments are not supported. + See CImageDecoder::NumberOfImageComments(). + +@panic ImageConversion 13 Header processing has not completed. + See CImageDecoder::IsImageHeaderProcessingComplete(). + +@panic ImageConversion 14 aCommentNumber is not valid. + See CImageDecoder::NumberOfImageComments(). + +@see IsImageHeaderProcessingComplete() +@see NumberOfImageComments() + +@return A buffer containing the comment. +*/ +EXPORT_C HBufC* CImageDecoder::ImageCommentL(TInt aCommentNumber) const + { + ASSERT(ValidProperties()); + return iRelay->Plugin()->ImageCommentL(aCommentNumber); + } + +/** +Return the number of comments attached to a given frame of the image +(as opposed to the whole image). + +Use FrameCount() to retrieve the number of frames in the image to ensure +that a valid aFrameNumber is used. + +For further informantion on panic categories, please see the note in +CImageDecoder::IsImageHeaderProcessingComplete(). + +@param aFrameNumber The frame number. + +@panic ImageConversion 10 aFrameNumber is not valid. + See CImageDecoder::FrameCount(). + +@panic ImageConversion 13 Header processing has not completed. + See CImageDecoder::IsImageHeaderProcessingComplete(). + +@see IsImageHeaderProcessingComplete() +@see FrameCount() + +@return The number of comments attached to a given frame of the image. +*/ +EXPORT_C TInt CImageDecoder::NumberOfFrameComments(TInt aFrameNumber) const + { + ASSERT(ValidProperties()); + return iRelay->Plugin()->NumberOfFrameComments(aFrameNumber); + } + +/** +Return a particular comment attached to a given frame of the image. + +The desired order of calling methods should be FrameCount(),NumberOfFrameComments() and then FrameCommentL(). + +Use FrameCount() to retrieve the number of frames in the image to ensure that a valid aFrameNumber is used. + +Use NumberOfFrameComments() to retrieve the number of comments attached to a given frame +of the image (as opposed to the whole image),to ensure that a valid aCommentNumber is used. + +Ownership of the returned buffer is transferred to the caller. + +For further informantion on panic categories, please see the note in +CImageDecoder::IsImageHeaderProcessingComplete(). + +@param aFrameNumber The frame number within the image from which to retrieve the specified comment. + +@param aCommentNumber The comment number to retrieve from the specified frame. + +@panic ImageConversion 10 aFrameNumber is not valid. + See CImageDecoder::FrameCount(). + +@panic ImageConversion 13 Header processing has not completed. + See CImageDecoder::IsImageHeaderProcessingComplete(). + +@panic ImageConversion 14 aCommentNumber is not valid. + See CImageDecoder::NumberOfFrameComments(). + +@see IsImageHeaderProcessingComplete() +@see FrameCount() +@see NumberOfFrameComments() + +@return A buffer containing the specified comment. +*/ +EXPORT_C HBufC* CImageDecoder::FrameCommentL(TInt aFrameNumber, TInt aCommentNumber) const + { + ASSERT(ValidProperties()); + return iRelay->Plugin()->FrameCommentL(aFrameNumber, aCommentNumber); + } + +/** +Return the formatted frame information strings for a specific frame +and leave it on the cleanup stack. + +Ownership is transferred to the caller. + +@param aFrameNumber + The frame number from which to retrieve the formatted information string. + +@return The formatted frame information strings. +*/ +EXPORT_C CFrameInfoStrings* CImageDecoder::FrameInfoStringsLC(TInt aFrameNumber) + { + ASSERT(ValidProperties()); + return iRelay->FrameInfoStringsLC(aFrameNumber); + } + +/** +Return the formatted frame information strings for a specific frame. +Ownership is transferred to the caller. + +@param aFrameNumber + The frame number from which to retrieve the formatted information string. + +@return The formatted frame information strings. +*/ +EXPORT_C CFrameInfoStrings* CImageDecoder::FrameInfoStringsL(TInt aFrameNumber) + { + CFrameInfoStrings* frameInfoStrings = FrameInfoStringsLC(aFrameNumber); + CleanupStack::Pop(); + + return frameInfoStrings; + } + +/** +Return the implementation UID of the decoder being used to decode the image. + +@return The implementation UID of the decoder. +*/ +EXPORT_C TUid CImageDecoder::ImplementationUid() const + { + return iRelay->ImplementationUid(); + } + +/** +Retrieves the image type and sub-type for a given frame of the image that +has just been decoded. + +For further informantion on panic categories, please see the note in +CImageDecoder::IsImageHeaderProcessingComplete(). + +@param aFrameNumber + The frame number for which type information should be retreived. +@param aImageType + On return contains the image type UID for the specified frame. +@param aImageSubType + On return contains the image sub-type UID if there is one (or KNullUid if + there is not). + +@panic ImageConversion 10 aFrameNumber is not valid. + See CImageDecoder::FrameCount(). + +@see IsImageHeaderProcessingComplete() +@see FrameCount() +*/ +EXPORT_C void CImageDecoder::ImageType(TInt aFrameNumber, TUid& aImageType, TUid& aImageSubType) const + { + ASSERT(ValidProperties()); + iRelay->Plugin()->ImageType(aFrameNumber, aImageType, aImageSubType); + } + +/** +Calls CImageDecoderPlugin::HandleCustomSyncL(aParam) that executes user defined plugin +specific functions. Subsequent behaviour depends on the CImageDecoderPlugin class. + +This function is part of the support for extended codecs for use within classes +derived from CImageDecoder. + +Note: This function is intended for use by plugin writers only. + +@param aParam + Interpretation dependent on plugin. + +@see CImageDecoderPlugin::HandleCustomSyncL() +*/ + +EXPORT_C void CImageDecoder::CustomSyncL(TInt aParam) + { + ASSERT(ValidProperties()); + iRelay->CustomSyncL(aParam); + } + +/** +Sets up background convert cycle, bypassing Convert(). +A call to this will result in a call to the associated CImageDecoderPlugin::InitCustomAsyncL(aParam), +which if successful will start background processing. This function uses the same mechanism as Convert(), +and therefore cannot be used concurrently. Cancel() etc work as expected. + +Note: This function is intended for use by plugin writers only. + +@param aRequestStatus + Request status. On completion contains an error code. + KErrNone if the bitmap was successfully decoded, + otherwise another of the system-wide error codes. +@param aParam + Interpretation dependent on plugin. +*/ +EXPORT_C void CImageDecoder::CustomAsync(TRequestStatus* aRequestStatus, TInt aParam) + { + ASSERT(ValidProperties()); + iRelay->CustomAsync(aRequestStatus, aParam); + } + +/** +Returns associated CImageDecoderPlugin. + +Allows the extended CImageDecoder object to talk to its CImageDecoderPlugin equivalent. + +Note: This function is intendend for use by plugin writers only. + +@return A pointer to the related CImageDecoderPlugin instance. +*/ +EXPORT_C CImageDecoderPlugin* CImageDecoder::Plugin() const + { + ASSERT(ValidProperties()); + return iRelay->Plugin(); + } + +/** +@internalTechnology + +Intended for future proofing - will panic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageDecoder::ReservedVirtual1() + { + Panic(EReservedCall); + } + +/** +@internalTechnology + +Intended for future proofing - will panic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageDecoder::ReservedVirtual2() + { + Panic(EReservedCall); + } + +/** +@internalTechnology + +Intended for future proofing - will panic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageDecoder::ReservedVirtual3() + { + Panic(EReservedCall); + } + +/** +@internalTechnology + +Intended for future proofing - will panic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageDecoder::ReservedVirtual4() + { + Panic(EReservedCall); + } + +/** +Function to calculate the reduction factor based on the input parameters. + +@param aOriginalSize + A reference to the original size of an image. +@param aReducedSize + A reference to the new size of an image. +@return The reduction factor. +*/ + +EXPORT_C TInt CImageDecoder::ReductionFactor(const TSize& aOriginalSize, const TSize& aReducedSize) const + { + ASSERT(ValidProperties()); + return iRelay->ReductionFactor(aOriginalSize, aReducedSize); + } + +/** +Calculates reduced size of the decoded bitmap based on the input parameters and updates aReducedSize with this value. + +@param aOriginalSize + A reference to the original size of an image. +@param aReductionFactor + The Reduction Factor to be applied +@param aReducedSize + A reference to the new size of the image. +@return An error code indicating if the function call was successful. KErrNone on success, otherwise + KErrArgument. +*/ + +EXPORT_C TInt CImageDecoder::ReducedSize(const TSize& aOriginalSize, TInt aReductionFactor, TSize& aReducedSize) const + { + ASSERT(ValidProperties()); + return iRelay->ReducedSize(aOriginalSize, aReductionFactor, aReducedSize); + } + + +/** +Set the decoder worker thread priority + +@param aPriority + a new value for worker thread priority +@return KErrNotSupported + the decoder object doesn't use a worker thread. + Other system-wide error codes. +@see TThreadPriority +*/ +EXPORT_C TInt CImageDecoder::SetDecoderThreadPriority(TThreadPriority aPriority) + { + return iRelay->SetDecoderThreadPriority( aPriority ); + } + + +/* IMAGE ENCODER */ + +/** +Returns a list of the basic image types that can be encoded, based on the +currently available encoder plugins. + +The returned array contains entries for the supported image types. Each entry +consists of the "display string" as well as the UID for that image type. Since +this function only returns basic image type UID's, the second UID which represents +the sub-type will always be zero. + +Ownership of the array is passed to the caller so, before the array goes out of +scope in the client, the caller must call the array's ResetAndDestroy() method to free +any entries. + +@param aImageTypeArray + An empty array, into which this function will put a list of supported image types. +*/ +EXPORT_C void CImageEncoder::GetImageTypesL(RImageTypeDescriptionArray& aImageTypeArray) + { + ImageEnDecoderUtils::DoGetImageTypesL(KImageEncoderInterfaceUid, aImageTypeArray); + } + +/** +@publishedAll +@released + +Gets a list of the properties of a specific encoder plugin. + +@param aImplementationUid + The encoder implementation UID for which the plugin properties need to be retrieved. +@param aPropertiesArray + The array of plugin properties owned by the specified encoder. + The caller has the ownership of the array. +*/ +EXPORT_C void CImageEncoder::GetPluginPropertiesL(const TUid aImplementationUid, RUidDataArray& aPropertiesArray) + { + ImageEnDecoderUtils::DoGetPluginPropertiesL(KImageEncoderInterfaceUid, aImplementationUid, aPropertiesArray); + } + +/** +@publishedAll +@released + +Gets a list of encoder implementations UIDs that have some specific uids (properties, image type, image sub-type or class uids). + +@param aRequiredUids + The array containing the UIDs of the required uids (properties, image type, image sub-type or class uids). +@param aImplArray + The array containing the implementation UIDs of the available encoder plugins with the required UIDs. + The caller has the ownership of the array. +*/ +EXPORT_C void CImageEncoder::GetInterfaceImplementationsL(const RUidDataArray& aRequiredUids, RUidDataArray& aImplArray) + { + ImageEnDecoderUtils::DoGetInterfaceImplementationsL(KImageEncoderInterfaceUid, aRequiredUids, aImplArray); + } + +/** +@publishedAll +@released + +Gets a list of encoder implementations UIDs that have some specific required uids (properties, image type, image sub-type or class uids). + +@param aRequiredUids + The array containing the UIDs of the required uids (properties, image type, image sub-type or class uids). +@param aLength + The length of aRequiredUids (number of required uids). +@param aImplArray + The array containing the implementation UIDs of the available encoder plugins with the required UIDs. + The caller has the ownership of the array. +*/ +EXPORT_C void CImageEncoder::GetInterfaceImplementationsL(const TUid* aRequiredUids, const TInt aLength, RUidDataArray& aImplArray) + { + RUidDataArray requiredUids; + CleanupClosePushL(requiredUids); + for(TInt index = 0 ; index < aLength ; index++) + { + User::LeaveIfError(requiredUids.Append(aRequiredUids[index])); + } + ImageEnDecoderUtils::DoGetInterfaceImplementationsL(KImageEncoderInterfaceUid, requiredUids, aImplArray); + CleanupStack::PopAndDestroy(1); //requiredUids + } + +/** +For a given basic image type, returns a list of the image sub-types that can +be encoded, based on the currently available encoder plugins. + +Each entry in the returned array consists of the "display string" for +the plugin as well as the UID for the sub-type. The first UID represents +the basic type and is always set to aImageType. + +Ownership of the array is passed to the caller, so before the +array goes out of scope in the client, the caller must call +the array's ResetAndDestroy() method to free any entries. + +@param aImageType + The basic image type for which a list of sub-types should be returned. +@param aSubTypeArray + An empty array, into which this function will put a list of of supported + image sub-types. +*/ +EXPORT_C void CImageEncoder::GetImageSubTypesL(const TUid aImageType, RImageTypeDescriptionArray& aSubTypeArray) + { + ImageEnDecoderUtils::DoGetImageTypesL(KImageEncoderInterfaceUid, aSubTypeArray, aImageType); + } + +/** +Get a list of the file extensions that can be encoded and their corresponding +MIME types, based on the currently available encoder plugins. + +@param aFileTypeArray + An empty array, into which this function will put a list of + entries. Each entry will consist of a file extension string for + which an encoder plugin has been found, accompanied by the + primary MIME type and then any secondary MIME types + (if present). + + Ownership of the array is passed to the caller, so before the + array goes out of scope in the client, the caller must call + the array's ResetAndDestroy() method to free any entries. +*/ +EXPORT_C void CImageEncoder::GetFileTypesL(RFileExtensionMIMETypeArray& aFileTypeArray) + { + ImageEnDecoderUtils::DoGetFileTypesL(KImageEncoderInterfaceUid, aFileTypeArray); + } + + +/** +Creates an encoder based on a specified MIME type and write output to a named file. + +The client supplies a MIME type which will be used to try and select an appropriate +plugin encoder. If an appropriate encoder is found, it is created. + +If any file related errors are encountered opening the specified file, this +function leaves with an appropriate file related leave code. + +@param aFs + A reference to a file server session for the encoder to use. +@param aDestinationFilename + The name of the file into which to put the encoded image. +@param aMIMEType + The MIME type to use for the encoding. +@param aOptions + The encoder options to use. + +@return Returns a pointer to the newly created encoder. + +@see TOptions +*/ +EXPORT_C CImageEncoder* CImageEncoder::FileNewL(RFs& aFs, const TDesC& aDestinationFilename, const TDesC8& aMIMEType, const TOptions aOptions) + { + //Get a sorted list of encoders + RImplInfoPtrArray encoderList; + CleanupResetAndDestroyPushL(encoderList); + CImageEncoder::MimeTypeGetEncoderListL(encoderList, aMIMEType, aOptions); + + if(encoderList.Count() == 0) + User::Leave(KErrNotFound); + + //Use the highest rated encoder. + CImageEncodeConstruct* construct = NewEncodeConstructL(*encoderList[0], aOptions); + CleanupStack::PopAndDestroy(&encoderList); + + CImageEncoder* encoderPtr = NewL(construct, aOptions); // NewL takes ownership of construct - no need to push on stack + CleanupStack::PushL(encoderPtr); + encoderPtr->iRelay->SetFileL(aFs, aDestinationFilename, aOptions); + CleanupStack::Pop(encoderPtr); + + return encoderPtr; + } + +/** +Creates a plugin encoder for a specified MIME type and writes output to a descriptor. + +The client supplies a MIME type which will be used to try and select an appropriate +plugin encoder. If an appropriate encoder is found, it creates it. + +@param aDestinationData + The buffer pointer into which to put the encoded image. This must be + a NULL pointer. Memory will be allocated internally and ownership of + the data passed to the caller. +@param aMIMEType + The MIME type to use for the encoding. +@param aOptions + Encoder options to use. + +@return A pointer to the newly created encoder. + +@see TOptions +*/ +EXPORT_C CImageEncoder* CImageEncoder::DataNewL(HBufC8*& aDestinationData, const TDesC8& aMIMEType, const TOptions aOptions) + { + if (aDestinationData!=NULL) + Panic(ENonNullDescriptorPassed); + + //Get a sorted list of encoders + RImplInfoPtrArray encoderList; + CleanupResetAndDestroyPushL(encoderList); + CImageEncoder::MimeTypeGetEncoderListL(encoderList, aMIMEType, aOptions); + + if(encoderList.Count() == 0) + User::Leave(KErrNotFound); + + //Use the highest rated encoder. + CImageEncodeConstruct* construct = NewEncodeConstructL(*encoderList[0], aOptions); + CleanupStack::PopAndDestroy(&encoderList); + CImageEncoder* encoderPtr = NewL(construct, aOptions); // NewL takes ownership of construct - no need to push on stack + CleanupStack::PushL(encoderPtr); + encoderPtr->iRelay->SetDataL(aDestinationData, aOptions); + CleanupStack::Pop(encoderPtr); + return encoderPtr; + } + +/** +@internalTechnology + +Creates a list of encoders that support the specified MIME type. + +@param aEncoderList + Create a list of encoders that support the given MIME type. +@param aMIMEType + The MIME type to encode to. +@param aOptions + Decoder options to use. +*/ +void CImageEncoder::MimeTypeGetEncoderListL(RImplInfoPtrArray& aEncoderList, const TDesC8& aMIMEType, const TOptions aOptions) + { + if (aMIMEType.Length() == 0) + { // Get out, empty MIME type string + User::Leave(KErrArgument); + } + + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + customMatchData->SetMatchType(EMatchMIMEType); + customMatchData->SetMatchStringL(aMIMEType); + customMatchData->SetExtensionOptions(aOptions); + + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + + TEComResolverParams resolverParams; // Parameters on which to match + resolverParams.SetDataType(packageDes); + + REComSession::ListImplementationsL(KImageEncoderInterfaceUid, resolverParams, KImageConvertResolverUid, aEncoderList); + + CleanupStack::PopAndDestroy(2); // package, customMatchData + } + +/** +@internalTechnology + +Create a list of encoders that support the specified image type. + +@param aEncoderList + A list of encoders that support the specified image type. +@param aImageType + The image base type. +@param aImageSubType + The image sub type. +@param aEncoderUid + The implementation UID for a specific codec or a decoder/encoder class UID. +@param aOptions + Encoder options to use. + +@see KUidICLJpegEXIFInterface +@see KUidICLJpegImageFrameInterface +*/ +void CImageEncoder::ImageTypeGetEncoderListL(RImplInfoPtrArray& aEncoderList, const TUid aImageType, const TUid aImageSubType, const TUid aEncoderUid, const TOptions aOptions) + { + if ((aImageType == KNullUid) && (aEncoderUid == KNullUid)) + { // Get out, no base type specified + Panic(EIllegalImageType); + } + + if ((aImageType == KNullUid) && (aImageSubType != KNullUid)) + { // Get out, no base type given for sub-type + Panic(EIllegalImageSubType); + } + + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + customMatchData->SetMatchType(EMatchUids); + customMatchData->SetBaseType(aImageType); + customMatchData->SetSubType(aImageSubType); + customMatchData->SetImplementationType(aEncoderUid); + customMatchData->SetExtensionOptions(aOptions); + + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + + TEComResolverParams resolverParams; // Parameters on which to match + resolverParams.SetDataType(packageDes); + + REComSession::ListImplementationsL(KImageEncoderInterfaceUid, resolverParams, KImageConvertResolverUid, aEncoderList); + + CleanupStack::PopAndDestroy(2); // package, customMatchData + } + +/** +@internalTechnology + +Create an encode construct using a image type, sub type and encoder +implementation UID. + +@param aEncoderInfo + Implementation information for the encoder to be created. +@param aOptions + Encoder options to use. +@return Returns a pointer to the newly created encoder construct. + +*/ +CImageEncodeConstruct* CImageEncoder::NewEncodeConstructL(const CImplementationInformation& aEncoderInfo, const TOptions aOptions) + { + CCustomMatchData* customMatchData = CCustomMatchData::NewLC(); + COpaqueDataParse* parse = COpaqueDataParse::NewLC(aEncoderInfo.OpaqueData()); + + customMatchData->SetMatchType(EMatchUids); + customMatchData->SetBaseType(parse->ImageTypeUid()); + customMatchData->SetSubType(parse->ImageSubTypeUid()); + customMatchData->SetImplementationType(aEncoderInfo.ImplementationUid()); + customMatchData->SetExtensionOptions(aOptions); + + CleanupStack::PopAndDestroy(parse); + + HBufC8* package = customMatchData->NewPackLC(); + TPtr8 packageDes = package->Des(); + + TEComResolverParams resolverParams; + resolverParams.SetDataType(packageDes); + + CImageEncodeConstruct* construct = NULL; + construct = STATIC_CAST(CImageEncodeConstruct*, + REComSession::CreateImplementationL(KImageEncoderInterfaceUid, + _FOFF(CImageEncodeConstruct, iDtorIDKey), + resolverParams, + KImageConvertResolverUid)); + ASSERT(construct!=NULL); + + CleanupStack::PopAndDestroy(2, customMatchData); //package, customMatchData + + return construct; + } + +/** +Creates an encoder based on a supplied parameters and writes output to a named file. + +The client must supply a basic image type (and a sub-type, if applicable) or a specific +encoder implementation UID, which will be used to try and select an appropriate plugin +encoder. If an appropriate encoder is found, it is created. + +Note: +Every image format has two IDs, known as the type and the sub-type (although generally +the sub-type is KNullUid). To retrieve a list of supported types and sub-types that can be +encoded, use the static functions GetImageTypesL() and GetImageSubTypesL(). + +If no plugin encoder can be found that matches the details provided in aImageType, aImageSubType +and possibly aEncoderUid this function leaves with KErrNotFound or KEComErrNoInterfaceIdentified. + +If any file related errors are encountered opening the specified file, this function leaves +with an appropriate file related leave code. + +@param aFs + A reference to a file server session for the encoder to use. +@param aDestinationFilename + The name of the file into which to put the encoded image. +@param aOptions + Options to use. +@param aImageType + The image type to use for the encoding (mandatory). +@param aImageSubType + The image sub-type to use for the encoding (only if applicable, defaults to KNullUid). +@param aEncoderUid + The implementation UID for a specific codec or a decoder/encoder class UID (optional, defaults to KNullUid). + If this option is selected for a specific codec the image type and image sub type for the displayer must be supplied. + When loading plugins by class UID the image type and image subtype are not mandatory and the first valid plugin from + the list of available plugins with the specified class UID will be loaded. +@see KUidICLJpegEXIFInterface +@see KUidICLJpegImageFrameInterface + +@return A pointer to the newly created encoder. + +@leave KErrNotFound + No appropriate plugin encoder for this image has been found. +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. + +@panic ImageConversion 19 + No base type given for sub-type. +@panic ImageConversion 20 + No base type given for encoder implementation. + +@see TOptions +*/ +EXPORT_C CImageEncoder* CImageEncoder::FileNewL(RFs& aFs, const TDesC& aDestinationFilename, const TOptions aOptions, const TUid aImageType, const TUid aImageSubType, const TUid aEncoderUid) + { + //Get a sorted list of encoders + RImplInfoPtrArray encoderList; + CleanupResetAndDestroyPushL(encoderList); + CImageEncoder::ImageTypeGetEncoderListL(encoderList, aImageType, aImageSubType, aEncoderUid, aOptions); + + if(encoderList.Count() == 0) + User::Leave(KErrNotFound); + + //Use the highest rated encoder. + CImageEncodeConstruct* construct = NewEncodeConstructL(*encoderList[0], aOptions); + CleanupStack::PopAndDestroy(&encoderList); + CImageEncoder* encoderPtr = NewL(construct, aOptions); // NewL takes ownership of construct - no need to push on cleanstack + CleanupStack::PushL(encoderPtr); + encoderPtr->iRelay->SetFileL(aFs, aDestinationFilename, aOptions); + CleanupStack::Pop(); //encoderPtr + return encoderPtr; + } + +/** +Creates a plugin encoder based on optional parameters and writes output to a descriptor. + +The client must supply a basic image type (and a sub-type, if applicable) or specific encoder/class, +implementation UID which will be used to try and select an appropriate plugin +encoder. If an appropriate encoder is found, it is created. + +Note: +Every image format has two IDs, known as the type and the sub-type (although generally the sub-type +is KNullUid). To retrieve a list of supported types and sub-types that can be encoded, use the +static functions GetImageTypesL() and GetImageSubTypesL(). + +If no plugin encoder can be found that matches the details provided in aImageType, aImageSubType +and possibly aEncoderUid this function leaves with KErrNotFound or KEComErrNoInterfaceIdentified. + +@param aDestinationData + The buffer pointer into which to put the encoded image. +@param aOptions + The encoder options to use. +@param aImageType + The image type to use for the encoding (mandatory). +@param aImageSubType + The image sub-type to use for the encoding (only if applicable, defaults to KNullUid). +@param aEncoderUid + The implementation UID for a specific codec or a decoder/encoder class UID (optional, defaults to KNullUid). + If this option is selected for a specific codec the image type and image sub type for the displayer must be supplied. + When loading plugins by class UID the image type and image subtype are not mandatory and the first valid plugin from + the list of available plugins with the specified class UID will be loaded. +@see KUidICLJpegEXIFInterface +@see KUidICLJpegImageFrameInterface + +@return A pointer to the newly created encoder. + +@leave KErrNotFound + No appropriate plugin encoder for this image has been found. +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. + +@panic ImageConversion 19 + No base type given for sub-type. +@panic ImageConversion 20 + No base type given for encoder implementation. + +@see TOptions +*/ +EXPORT_C CImageEncoder* CImageEncoder::DataNewL(HBufC8*& aDestinationData, const TOptions aOptions, const TUid aImageType, const TUid aImageSubType, const TUid aEncoderUid) + { + if (aDestinationData!=NULL) + Panic(ENonNullDescriptorPassed); + + //Get a sorted list of encoders + RImplInfoPtrArray encoderList; + CleanupResetAndDestroyPushL(encoderList); + CImageEncoder::ImageTypeGetEncoderListL(encoderList, aImageType, aImageSubType, aEncoderUid, aOptions); + + if(encoderList.Count() == 0) + User::Leave(KErrNotFound); + + //Use the highest rated encoder. + CImageEncodeConstruct* construct = NewEncodeConstructL(*encoderList[0], aOptions); + CleanupStack::PopAndDestroy(&encoderList); + CImageEncoder* encoderPtr = NewL(construct, aOptions); // NewL takes ownership of construct - no need to push on cleanstack + CleanupStack::PushL(encoderPtr); + encoderPtr->iRelay->SetDataL(aDestinationData, aOptions); + CleanupStack::Pop(); //encoderPtr + return encoderPtr; + } + +/** +@internalTechnology + +Called internally to create a CImageEncoder and associated iRelay body +*/ +CImageEncoder* CImageEncoder::NewL(CImageEncodeConstruct* aConstruct, TOptions aOptions) + { + CleanupStack::PushL(aConstruct); // we take ownership of aConstruct + CImageEncoder* self = aConstruct->NewEncoderL(); // typically will callback to CImageEncoder::NewL() + CleanupStack::PushL(self); + TBool alwaysThread = (aOptions & EOptionAlwaysThread)!=EFalse; + self->iRelay = MImageEncoderRelay::NewL(aConstruct, alwaysThread); // ownership of aConstruct switches to properties + CleanupStack::Pop(2); // self and aConstruct + self->iRelay->TransferConstructOwnership(); + return self; + } + +/** +@internalTechnology + +Actual factory function for CImageEncoder - ie. it creates the object +Called back plugin - to allow plugin to override if required +*/ +CImageEncoder* CImageEncoder::NewL() + { + CImageEncoder* self = new (ELeave) CImageEncoder; + return self; + } + +/** +Constructor for this class. +*/ +EXPORT_C CImageEncoder::CImageEncoder() + { + } + +/** +Destructor for this class. + +Closes the file. If using a local file session, it closes it. +Calls ECom to tell it the encoder instance is no longer required. + +Frees all other resources owned by the object prior to its destruction. +*/ +EXPORT_C CImageEncoder::~CImageEncoder() + { + Cancel(); + + delete iRelay; + } + +/** +Encodes a bitmap asynchronously. + +When encoding is complete, successfully or otherwise, the +status is returned in aRequestStatus. + +@param aRequestStatus + The request status. On completion contains an error code. + KErrNone if the bitmap was successfully encoded, + otherwise another of the system-wide error codes. +@param aSource + A bitmap to encode. +@param aFrameImageData + The frame image data (optional, defaults to NULL). + There exists format-specific image data variants that are used by + encoders to obtain image specific data. This behaviour is invoked by specifying + aFrameImageData. Otherwise, encoder specific defaults are invoked. +@see TBmpImageData +*/ +EXPORT_C void CImageEncoder::Convert(TRequestStatus* aRequestStatus, const CFbsBitmap& aSource, const CFrameImageData* aFrameImageData) + { + ASSERT(ValidProperties()); + iRelay->Convert(aRequestStatus, aSource, aFrameImageData); + } + +/** +Asynchronously cancels any conversions currently in progress. +*/ +EXPORT_C void CImageEncoder::Cancel() + { + if(ValidProperties()) + iRelay->Cancel(); + } + +/** +Returns the implementation UID of the encoder being used to encode the bitmap. + +@return The implementation UID of the encoder. +*/ +EXPORT_C TUid CImageEncoder::ImplementationUid() const + { + return iRelay->ImplementationUid(); + } + +/** +Calls CImageEncoderPlugin::HandleCustomSyncL() that executes user defined +plugin specific functions. Subsequent behaviour therefore depends on the +CImageEncoderPlugin class. + +Note: +For use by plugin writers only. + +@param aParam + Interpretation determined by plugin. +*/ +EXPORT_C void CImageEncoder::CustomSyncL(TInt aParam) + { + ASSERT(ValidProperties()); + iRelay->CustomSyncL(aParam); + } + +/** +Sets up background convert cycle, bypassing Convert(). + +Use this function to inititate CImageEncoderPlugin::InitCustomAsyncL(aParam), +which if successful will start background processing. Convert() uses the same +mechanism as CustomAsync(), and therefore cannot be used concurrently. Cancel() +and other related functions still work as expected. + +Note: +For use by plugin writers only. + +@param aRequestStatus + The request status. On completion contains an error code. + KErrNone if the bitmap was successfully encoded, + otherwise another of the system-wide error codes. +@param aParam + Interpretation determined by plugin. +*/ +EXPORT_C void CImageEncoder::CustomAsync(TRequestStatus* aRequestStatus, TInt aParam) + { + ASSERT(ValidProperties()); + iRelay->CustomAsync(aRequestStatus, aParam); + } + +/** +Returns the associated CImageEncoderPlugin. + +This is part of support for extended codecs, for use within classes derived from +CImageEncoder. Allows the extended CImageEncoder object to talk to its +CImageEncoderPlugin equivalent. + +Note: +For use by plugin writers only. +*/ +EXPORT_C CImageEncoderPlugin* CImageEncoder::Plugin() const + { + ASSERT(ValidProperties()); + return iRelay->Plugin(); + } + +/** +@internalTechnology + +Intended for future proofing - will pannic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageEncoder::ReservedVirtual1() + { + Panic(EReservedCall); + } + +/** +@internalTechnology + +Intended for future proofing - will pannic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageEncoder::ReservedVirtual2() + { + Panic(EReservedCall); + } + +/** +@internalTechnology + +Intended for future proofing - will pannic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageEncoder::ReservedVirtual3() + { + Panic(EReservedCall); + } + +/** +@internalTechnology + +Intended for future proofing - will pannic if called + +@panic ImageConversion 30 +*/ +EXPORT_C void CImageEncoder::ReservedVirtual4() + { + Panic(EReservedCall); + } + +/** +Create a decoder for the image in the named file. The client supplies a +MIME type which will be used to try and select an appropriate plugin +decoder. If it finds a decoder it creates it and then goes on to use that +decoder to scan the beginning of the image file. + +If any file related errors are encountered opening the specified file, this +function leaves with an appropriate file related leave code. + +@param aFile + The handle of the file to decode +@param aMIMEType + The MIME type of the image in the file. +@param aIntent + The DRM Intent to open the file with +@param aOptions + Decoder options to use. + +@return Returns a pointer to the newly created decoder. + +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. +@leave KErrNotFound + Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing. + +@see TOptions +*/ +EXPORT_C CImageDecoder* CImageDecoder::FileNewL(RFile& aFile, const TDesC8& aMIMEType, TIntent aIntent, const TOptions aOptions) + { + return CImageDecoder::FileNewImplL(aFile, aMIMEType, KDefaultContentObject, aIntent, aOptions); + } + +/** +Creates a decoder for the image in the named file. If the client supplies an +image type (and sub-type, if applicable) or decoder UID, these will be used +to try and select an appropriate plugin decoder. If not, then the selection +will be done by matching the image header in the file. If it finds a decoder +it creates it and then goes on to use that decoder to scan the beginning of +the image file. + +@param aFile + The handle of the file to decode +@param aIntent + The DRM Intent for image conversion. +@param aOptions + The decoder options to use. See TOptions. +@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 aDecoderUid + The implementation UID for a specific codec or a decoder/encoder class UID (optional, defaults to KNullUid). + If this option is selected for a specific codec the image type and image sub type for the displayer must be supplied. + When loading plugins by class UID the image type and image subtype are not mandatory and the first valid plugin from + the list of available plugins with the specified class UID will be loaded. +@see KUidICLJpegEXIFInterface +@see KUidICLJpegImageFrameInterface + +@return A pointer to the newly created decoder. + +@leave KErrUnderflow + Not enough data in file to identify which plugin decoder to use. +@leave KErrNotFound + Either the appropriate plugin decoder for this file hasn't been found, or the file itself is missing. +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. + +@panic ImageConversion 19 + No base type given for sub-type. + +@see TOptions +*/ + +EXPORT_C CImageDecoder* CImageDecoder::FileNewL(RFile& aFile, TIntent aIntent, const TOptions aOptions, const TUid aImageType, const TUid aImageSubType, const TUid aDecoderUid) + { + return CImageDecoder::FileNewImplL(aFile, KDefaultContentObject, aIntent, aOptions, aImageType, aImageSubType, aDecoderUid); + } + +CImageDecoder* CImageDecoder::FileNewImplL(RFile& aFile, const TDesC8& aMIMEType, const TDesC& aUniqueId, TIntent aIntent, const TOptions aOptions) + { + CContent* content = CContent::NewLC(aFile); + CData* data = content->OpenContentL(aIntent, aUniqueId); // check file presence, evaluate (not execute) intent + + delete data; // close file + CleanupStack::PopAndDestroy(content); + + //Get a sorted list of decoders that will decode the image + RImplInfoPtrArray decoderList; + CleanupResetAndDestroyPushL(decoderList); + CImageDecoder::MimeTypeGetDecoderListL(decoderList, aMIMEType, aOptions); + + CImageDecoder* decoder = NULL; + decoder = CImageDecoder::FileFindDecoderNewL(decoderList, aFile, aOptions, aUniqueId); + + ASSERT(decoder!=NULL); + CleanupStack::PushL(decoder); + decoder->iRelay->SetIntent(aIntent); + + CleanupStack::Pop(decoder); + CleanupStack::PopAndDestroy(&decoderList); + return decoder; + } + +CImageDecoder* CImageDecoder::FileNewImplL(RFile& aFile, const TDesC& aUniqueId, const TIntent aIntent, const TOptions aOptions, const TUid aImageType, const TUid aImageSubType, const TUid aDecoderUid) + { + if ((aImageType == KNullUid) && (aImageSubType != KNullUid)) + { // Get out, no base type given for sub-type + Panic(EIllegalImageSubType); + } + + RImplInfoPtrArray decoderList; + CleanupResetAndDestroyPushL(decoderList); + + CContent* content = CContent::NewLC(aFile); + CData* data = content->OpenContentL(aIntent, aUniqueId); + CleanupStack::PushL(data); + + if (aImageType == KNullUid && aDecoderUid == KNullUid) + { + TBuf8 mimeType; + if (data->GetMimeTypeL(mimeType)) + { + // try to find a controller based on MIME type + CImageDecoder::MimeTypeGetDecoderListL(decoderList, mimeType, aOptions); + } + if (decoderList.Count()==0) + { + // read header data + TBuf8 imageHeader; + User::LeaveIfError(data->Read(imageHeader, KImageHeaderSize)); + CImageDecoder::ImageTypeGetDecoderListL(decoderList, imageHeader, aImageType, aImageSubType, aDecoderUid, aOptions); + } + } + else + { + TBuf8 imageHeader; + User::LeaveIfError(data->Read(imageHeader, KImageHeaderSize)); + CImageDecoder::ImageTypeGetDecoderListL(decoderList, imageHeader, aImageType, aImageSubType, aDecoderUid, aOptions); + } + + CleanupStack::PopAndDestroy(2, content); // content, data + + //Try to match by file extension only + //1) If no plugin was found and + //2) No specific decoder or format was specified + TBuf<256> filename; + aFile.Name(filename); + const TBool formatSpecified = (aImageType!=KNullUid || aImageSubType!=KNullUid || aDecoderUid!=KNullUid); + if(decoderList.Count()==0 && !formatSpecified) + { + CImageDecoder::SuffixTypeGetDecoderListL(decoderList, filename, aOptions); + } + + CImageDecoder* decoder = NULL; + decoder = CImageDecoder::FileFindDecoderNewL(decoderList, aFile, aOptions, aUniqueId); + ASSERT(decoder!=NULL); + CleanupStack::PushL(decoder); + decoder->iRelay->SetIntent(aIntent); + + CleanupStack::Pop(decoder); + CleanupStack::PopAndDestroy(&decoderList); + return decoder; + } + +/** +@internalTechnology + +Scans a sorted list of decoders for the first one that can decode the image. + +@param aDecoderList + A list of decoders that support the image format. +@param aFile + A file server session for the decoder to use. +@param aOptions + The options to use during decoding. +@param aUniqueId + Identifier of file within a multi-part archive. + +@return A pointer to the decoder. +*/ +CImageDecoder* CImageDecoder::FileFindDecoderNewL(const RImplInfoPtrArray& aDecoderList, RFile& aFile, const TOptions aOptions, const TDesC& aUniqueId) + { + TInt noOfDecoders = aDecoderList.Count(); + + if(noOfDecoders == 0) + User::Leave(KErrNotFound); + + CImageDecoder* decoder = NULL; + TInt decoderNo = 0; + TInt error = KErrNone; + do + { + const CImplementationInformation& decoderInfo = *(aDecoderList[decoderNo++]); + TRAP(error,decoder=FileDecoderNewL(decoderInfo, aFile, aOptions, aUniqueId)); + if (error != KErrCorrupt && error != KErrNotSupported && error != KErrNotFound) + break; + } + while(decoderNo < noOfDecoders); + + if(error!=KErrNone) + { + ASSERT(decoder==NULL); + if (error == KErrCorrupt || error == KErrNotSupported) + error = KErrNotFound; + User::Leave(error); + } + + return decoder; + } + +/** +@internalTechnology + +Create a construct that can create a decoder and call +functions to initialise the decoder with the image data. + +@param aDecoderInfo + Implementation information for the decoder to be created. +@param aFile + A file server session for the decoder to use. +@param aOptions + Options the decoder must use. +@param aUniqueId + Identifier of file within a multi-part archive. + +@return A pointer to the decoder. +*/ +CImageDecoder* CImageDecoder::FileDecoderNewL(const CImplementationInformation& aDecoderInfo, RFile& aFile, const TOptions aOptions, const TDesC& aUniqueId) + { + CImageDecodeConstruct* construct = NULL; + construct = NewDecodeConstructL(aDecoderInfo, aOptions); + ASSERT(construct!= NULL); + + CImageDecoder* decoder = NewL(construct, aOptions); // note NewL takes ownership of construct - don't push on stack + ASSERT(decoder!=NULL); + CleanupStack::PushL(decoder); + + decoder->iRelay->SetUniqueIdL(aUniqueId); + + decoder->iRelay->SetFileL(aFile, aOptions); + decoder->iRelay->HandleNewlyOpenedImageL(); + + CleanupStack::Pop(decoder); + return decoder; + } + + +/** +Creates an encoder based on a specified MIME type and write output to a named file. + +The client supplies a MIME type which will be used to try and select an appropriate +plugin encoder. If an appropriate encoder is found, it is created. + +If any file related errors are encountered opening the specified file, this +function leaves with an appropriate file related leave code. + +@param aFile + The handle of an open file to write the encoded image to +@param aMIMEType + The MIME type to use for the encoding. +@param aOptions + The encoder options to use. + +@return Returns a pointer to the newly created encoder. + +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. +@leave KErrNotFound + No appropriate plugin encoder for this image has been found. + +@see TOptions +*/ +EXPORT_C CImageEncoder* CImageEncoder::FileNewL(RFile& aFile, const TDesC8& aMIMEType, const TOptions aOptions) + { + //Get a sorted list of encoders + RImplInfoPtrArray encoderList; + CleanupResetAndDestroyPushL(encoderList); + CImageEncoder::MimeTypeGetEncoderListL(encoderList, aMIMEType, aOptions); + + if(encoderList.Count() == 0) + User::Leave(KErrNotFound); + + //Use the highest rated encoder. + CImageEncodeConstruct* construct = NewEncodeConstructL(*encoderList[0], aOptions); + CleanupStack::PopAndDestroy(&encoderList); + + CImageEncoder* encoderPtr = NewL(construct, aOptions); // NewL takes ownership of construct - no need to push on stack + CleanupStack::PushL(encoderPtr); + encoderPtr->iRelay->SetFileL(aFile, aOptions); + CleanupStack::Pop(encoderPtr); + return encoderPtr; + } + +/** +Creates an encoder based on a supplied parameters and writes output to a named file. + +The client must supply a basic image type (and a sub-type, if applicable) or a specific +encoder/class implementation UID, which will be used to try and select an appropriate plugin +encoder. If an appropriate encoder is found, it is created. + +Note: +Every image format has two IDs, known as the type and the sub-type (although generally +the sub-type is KNullUid). To retrieve a list of supported types and sub-types that can be +encoded, use the static functions GetImageTypesL() and GetImageSubTypesL(). + +If no plugin encoder can be found that matches the details provided in aImageType, aImageSubType +and possibly aEncoderUid this function leaves with KErrNotFound or KEComErrNoInterfaceIdentified. + +If any file related errors are encountered opening the specified file, this function leaves +with an appropriate file related leave code. + +@param aFile + The handle of an open file to write the encoded image to +@param aOptions + Options to use. +@param aImageType + The image type to use for the encoding (mandatory). +@param aImageSubType + The image sub-type to use for the encoding (only if applicable, defaults to KNullUid). +@param aEncoderUid + The implementation UID for a specific codec or a decoder/encoder class UID (optional, defaults to KNullUid). + If this option is selected for a specific codec the image type and image sub type for the displayer must be supplied. + When loading plugins by class UID the image type and image subtype are not mandatory and the first valid plugin from + the list of available plugins with the specified class UID will be loaded. +@see KUidICLJpegEXIFInterface +@see KUidICLJpegImageFrameInterface + +@return A pointer to the newly created encoder. + +@leave KErrNotFound + No appropriate plugin encoder for this image has been found. +@leave KEComErrNoInterfaceIdentified + ECom could not find the specified interface. + +@panic ImageConversion 19 + No base type given for sub-type. +@panic ImageConversion 20 + No base type given for encoder implementation. + +@see TOptions +*/ +EXPORT_C CImageEncoder* CImageEncoder::FileNewL(RFile& aFile, const TOptions aOptions, const TUid aImageType, const TUid aImageSubType, const TUid aEncoderUid) + { + //Get a sorted list of encoders + RImplInfoPtrArray encoderList; + CleanupResetAndDestroyPushL(encoderList); + CImageEncoder::ImageTypeGetEncoderListL(encoderList, aImageType, aImageSubType, aEncoderUid, aOptions); + + if(encoderList.Count() == 0) + User::Leave(KErrNotFound); + + //Use the highest rated encoder. + CImageEncodeConstruct* construct = NewEncodeConstructL(*encoderList[0], aOptions); + CleanupStack::PopAndDestroy(&encoderList); + CImageEncoder* encoderPtr = NewL(construct, aOptions); // NewL takes ownership of construct - no need to push on cleanstack + CleanupStack::PushL(encoderPtr); + encoderPtr->iRelay->SetFileL(aFile, aOptions); + CleanupStack::Pop(); //encoderPtr + return encoderPtr; + } + + +/** +Select to encode or not the thumbnail + +@param aDoGenerateThumbnail + EFalse if no generation of thumbnail +*/ +EXPORT_C void CImageEncoder::SetThumbnail(TBool aDoGenerateThumbnail) + { + ASSERT(ValidProperties()); + iRelay->SetThumbnail(aDoGenerateThumbnail); + } + +/** +Set the encoder worker thread priority + +@param aPriority + a new value for worker thread priority +@return KErrNotSupported + the encoder object doesn't use a worker thread. + Other system-wide error codes. +@see TThreadPriority +*/ +EXPORT_C TInt CImageEncoder::SetEncoderThreadPriority(TThreadPriority aPriority) + { + return iRelay->SetEncoderThreadPriority( aPriority ); + } + +/** +@publishedAll +@released + +Optional call from client which may be made on the encoder to allow analysis of image prior to calling +Convert. + +Should be called once encode is fully set up e.g. any encode operations defined. + +@param aRequestStatus + Request status. On completion this contains an error code. This is KErrNone if the frame + was analyzed successfully, KErrNotSupported if the codec does not support analysis, or a + system-wide error code. + +@see CImageEncoder::Convert +*/ +EXPORT_C void CImageEncoder::Prepare(TRequestStatus* aRequestStatus) + { + ASSERT(ValidProperties()); + ASSERT(aRequestStatus); + + CImageConvExtensionCache* cache = &iRelay->ExtensionCache(); + TImageConvPrepare* prepare = cache->Prepare(); + + if(!prepare) + { + MImageConvExtension* prepareExtension = NULL; + TRAPD(err, + { + iRelay->GetExtensionL(KICLPrepareUid, prepareExtension); + prepare = new (ELeave) TImageConvPrepare(); + prepare->SetExtension(prepareExtension); + cache->SetPrepareExtension(prepare); + }); + if ( err != KErrNone ) + { + User::RequestComplete(aRequestStatus, err); + return; + } + } + prepare->Prepare(aRequestStatus); + } + +CContent* CImageDecoder::GetContentLC(const TDesC& aSourceFilename) + { + CContent* content = NULL; + TRAPD(err,content = CContent::NewL(aSourceFilename, EContentShareReadOnly)); + if(err != KErrNone && err != KErrNoMemory) + { + content = CContent::NewL(aSourceFilename, EContentShareReadWrite); + } + User::LeaveIfNull(content); + CleanupStack::PushL(content); + return content; + } + +/** +@publishedAll +@released + + +Get the extension interface for operations on the image. +@return Interface to image conversion operations. +@leave KErrNotSupported if loaded codec plugin does not support this optional extension. +@leave Other system wide errors + +@note The order of post processing operations when applied for decoding is + +- 1. Clip the image +- 2. Scale the image +- 3. Operate on the image + +@see CImageDecoder::SetClippingRectL() +@see TImageConvScaler +@see TImageConvOperation +*/ +EXPORT_C TImageConvOperation* CImageDecoder::OperationL() + { + ASSERT(ValidProperties()); + + CImageConvExtensionCache* cache = &iRelay->ExtensionCache(); + TImageConvOperation* operation = cache->Operation(); + + if(!operation) + { + MImageConvExtension* operationExtension = NULL; + iRelay->GetExtensionL(KICLOperationUid, operationExtension); + operation = new (ELeave) TImageConvOperation(); + operation->SetExtension(operationExtension); + cache->SetOperationExtension(operation); + } + return operation; + } + +/** +@publishedAll +@released + + +Get the extension interface for scaling the image. @see TImageConvScaler +@return Interface to image conversion scaler. +@leave KErrNotSupported if loaded codec plugin does not support this optional extension. +@leave Other system wide errors. + +@see note under CImageDecoder::OperationL. +*/ +EXPORT_C TImageConvScaler* CImageDecoder::ScalerL() + { + ASSERT(ValidProperties()); + + CImageConvExtensionCache* cache = &iRelay->ExtensionCache(); + TImageConvScaler* scaler = cache->Scaler(); + + if(!scaler) + { + MImageConvExtension* scalerExtension = NULL; + iRelay->GetExtensionL(KICLScalerUid, scalerExtension); + scaler = new (ELeave) TImageConvScaler(); + scaler->SetExtension(scalerExtension); + cache->SetScalerExtension(scaler); + } + return scaler; + } + +/** +@publishedAll +@released + + +Get the extension interface for block streaming on the image. @see TImageConvStreamedDecode +@return Interface to image conversion block streamer. +@leave KErrNotSupported if loaded codec plugin does not support this optional extension. +@leave Other system wide errors. +*/ +EXPORT_C TImageConvStreamedDecode* CImageDecoder::BlockStreamerL() + { + ASSERT(ValidProperties()); + + CImageConvExtensionCache* cache = &iRelay->ExtensionCache(); + TImageConvStreamedDecode* streamer = cache->DecodeBlockStreamer(); + + if(!streamer) + { + MImageConvExtension* streamExtension = NULL; + iRelay->GetExtensionL(KICLStreamedDecodeUid, streamExtension); + streamer = new (ELeave) TImageConvStreamedDecode(); + streamer->SetExtension(streamExtension); + cache->SetBlockStreamerExtension(streamer); + } + return streamer; + } + +/** +@publishedAll +@released + + +Sets the area of interest of the image to be decoded. This function can leave with +any of the system-wide error codes. + +@param aClipRect A pointer to a TRect that specifies the + location and size of the region to be decoded. This + rectangle must have positive width and height values as + per TRect::IsNormalized() and TRect::Normalize(). + Passing in a NULL value will clear the clipping rectangle. + Note that a clipping rectangle may not be valid for all frames of an image. + +@leave KErrNotSupported This function is not supported. +@leave KErrArgument Returned if the clipping rectangle: + a) is empty (i.e. IsEmpty() returns ETrue) + b) is not normalised (i.e. IsNormalized() returns EFalse) + c) has coordinates that are not located within, or on, + the coodinates of at least one frame of the original image. + d) has a width or a height of 0 + +@see TRect::IsEmpty() +@see TRect::IsNormalized() +@see TRect::Normalize() + +@see note under CImageDecoder::OperationL +*/ +EXPORT_C void CImageDecoder::SetClippingRectL(const TRect* aClipRect) + { + ASSERT(ValidProperties()); + iRelay->SetClippingRectL(aClipRect); + } + +/** +@publishedAll +@released + + +Optional call from client which may be made on the decoder to allow analysis of image prior to calling +Convert. + +Should be called once decode is fully set up e.g. clipping rectangle set. + +@param aRequestStatus + Request status. On completion this contains an error code. This is KErrNone if the frame + was analyzed successfully, KErrNotSupported if the codec does not support analysis, or a + system-wide error code. + +@see CImageDecoder::Convert +*/ +EXPORT_C void CImageDecoder::Prepare(TRequestStatus* aRequestStatus) + { + ASSERT(ValidProperties()); + ASSERT(aRequestStatus); + + CImageConvExtensionCache* cache = &iRelay->ExtensionCache(); + TImageConvPrepare* prepare = cache->Prepare(); + + if(!prepare) + { + MImageConvExtension* prepareExtension = NULL; + TRAPD(err, + { + iRelay->GetExtensionL(KICLPrepareUid, prepareExtension); + prepare = new (ELeave) TImageConvPrepare(); + prepare->SetExtension(prepareExtension); + cache->SetPrepareExtension(prepare); + }); + if ( err != KErrNone ) + { + User::RequestComplete(aRequestStatus, err); + return; + } + } + prepare->Prepare(aRequestStatus); + } + +/** +@publishedAll +@released + + +Get the size of the decoded image for the given frame. The calculation will account for any clipping rectangle set, +scaling applied through the TImageConvScaler extension and any operation applied through TImageConvOperation. +If TImageConvScaler::SetScalingL(.. has been called then the size of the bitmap passed to CImageDecoder::Convert must match the size returned from +this function. + +@param aSize + Returns the size of the decoded image. +@param aFrameNumber + The frame number. + +@return KErrArgument if an error in calculation is detected e.g. if clipping rectangle is outside of the overall frame boundary. +@return Other system wide errors. +*/ +EXPORT_C TInt CImageDecoder::GetDestinationSize(TSize& aSize, TInt aFrameNumber) + { + ASSERT(ValidProperties()); + return iRelay->GetDestinationSize(aSize, aFrameNumber); + } + +/** +@publishedAll +@released + + +Get the extension interface for operations on image. @see TImageConvOperation +@return Interface to image conversion operations (rotate/mirror over axis). +@leave KErrNotSupported if loaded codec plugin does not support this optional extension. +@leave Other system wide errors +*/ +EXPORT_C TImageConvOperation* CImageEncoder::OperationL() + { + ASSERT(ValidProperties()); + + CImageConvExtensionCache* cache = &iRelay->ExtensionCache(); + TImageConvOperation* operation = cache->Operation(); + + if(!operation) + { + MImageConvExtension* operationExtension = NULL; + iRelay->GetExtensionL(KICLOperationUid, operationExtension); + operation = new (ELeave) TImageConvOperation(); + operation->SetExtension(operationExtension); + cache->SetOperationExtension(operation); + } + return operation; + } + +/** +@publishedAll +@released + + +Get the extension interface for block streaming on image. @see TImageConvStreamedEncode +@return Interface to image conversion operations. +@leave KErrNotSupported if loaded codec plugin does not support this optional extension. +@leave Other system wide errors +*/ +EXPORT_C TImageConvStreamedEncode* CImageEncoder::BlockStreamerL() + { + ASSERT(ValidProperties()); + + CImageConvExtensionCache* cache = &iRelay->ExtensionCache(); + TImageConvStreamedEncode* streamer = cache->EncodeBlockStreamer(); + + if(!streamer) + { + MImageConvExtension* streamExtension = NULL; + iRelay->GetExtensionL(KICLStreamedEncodeUid, streamExtension); + streamer = new (ELeave) TImageConvStreamedEncode(); + streamer->SetExtension(streamExtension); + cache->SetBlockStreamerExtension(streamer); + } + return streamer; + } + + +