--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imaging/imagingfws/src/Reciclutilbody.cpp Wed Aug 25 12:29:52 2010 +0300
@@ -0,0 +1,255 @@
+// Copyright (c) 2003-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:
+// This is the body of the ICL recognizer utility class
+//
+//
+
+#include "ImageConversion.h"
+#include "ImageResolverAPI.h"
+#include "ImageConvResolvrUtils.h"
+#include "ImageRelay.h"
+#include "EnDecoderUtils.h"
+#include "RecIclUtilBody.h"
+
+// ICL Recognizer Utility class body constructor
+CIclRecognizerUtil::CBody::CBody():
+ CActive(CActive::EPriorityStandard)
+ {
+ }
+
+CIclRecognizerUtil::CBody::~CBody()
+ {
+ Cancel();
+ iEcomSession.Close();
+ iFs.Close();
+ iPluginArray.ResetAndDestroy();
+ }
+
+// Request ECom to be notified when interface implementation registration
+// data changes so that we can refresh the list of interface implementations.
+void CIclRecognizerUtil::CBody::StartNotification()
+ {
+ iEcomSession.NotifyOnChange(iStatus);
+ SetActive();
+ }
+
+// build a list of interface implementation objects
+void CIclRecognizerUtil::CBody::BuildControllerListL()
+ {
+ iPluginArray.ResetAndDestroy();
+ REComSession::ListImplementationsL(
+ KImageDecoderInterfaceUid,
+ iPluginArray);
+ }
+
+void CIclRecognizerUtil::CBody::ConstructL()
+ {
+ BuildControllerListL();
+
+ CActiveScheduler::Add(this);
+
+ User::LeaveIfError(iFs.Connect());
+
+ iEcomSession = REComSession::OpenL();
+
+ // request notification from ECOM of any file system changes
+ StartNotification();
+ }
+
+void CIclRecognizerUtil::CBody::RunL()
+ {
+ BuildControllerListL();
+ StartNotification();
+ }
+
+void CIclRecognizerUtil::CBody::DoCancel()
+ {
+ if (iStatus == KRequestPending)
+ iEcomSession.CancelNotifyOnChange(iStatus);
+ }
+
+// Determine whether the supplied data header or file extension is recognized
+// and if so return the associated MIME type
+// @param aImageData
+// A descriptor containing the header. Set to KNullDesC8 for match by file extension.
+// @param aFileName
+// A file name for file extension matching. Set to KNullDesC for match by image data
+// @param aMimeType
+// A user-supplied descriptor in which the MIME type is returned
+// @return ETrue if a match was found.
+// EFalse if a match was not found.
+// @leave This method may also leave with one of the system-wide error codes.
+// @post If recognized, the caller's descriptor is filled with the MIME types
+TBool CIclRecognizerUtil::CBody::GetMimeTypeL(const TDesC8& aImageData, const TDesC& aFileName, TDes8& aMimeType)
+ {
+ TBool matchImageData = ETrue;
+ HBufC* fileSuffix = NULL;
+
+ if(aFileName==KNullDesC)
+ {// match on image data
+ if (aImageData.Length() < KImageHeaderSize) // There is not enough data in this source
+ return EFalse;
+ }
+ else
+ {// match on file extension
+ // Ensure aFileName is < KMaxFileName
+ if ( aFileName.Length() > KMaxFileName )
+ {
+ User::Leave(KErrBadName);
+ }
+
+ TParse fileName;
+
+ TDes* const fName = new(ELeave) TFileName;
+
+ CleanupStack::PushL(fName);
+
+ fName->Copy(aFileName);
+
+ // if illegalifier character has been added to the file name,
+ // remove the illegalifier and pass the file name only to the parser.
+ if (fName->Match(_L("::*")) == 0)
+ {
+ fName->Delete(0, 2);
+ }
+
+ fileName.Set(*fName, NULL, NULL);
+
+ CleanupStack::PopAndDestroy(fName);
+
+
+ //No file extension
+ if (!fileName.ExtPresent())
+ return EFalse;
+
+ //Get the suffix
+ fileSuffix = fileName.Ext().AllocLC();
+
+ matchImageData = EFalse;
+ }
+
+ TBool matchFound = EFalse;
+
+ // loop through every plugin
+ // until we find one that matches the file extension
+ const TInt count = iPluginArray.Count();
+ TInt oldMatchLevel = 0; // number of characters matched in best match
+
+ for(TInt index = 0; index < count && !matchFound; index++)
+ {
+ const CImplementationInformation& impData = *(iPluginArray[index]);
+
+ COpaqueDataParse *parse = NULL;
+ TRAPD(error, parse = COpaqueDataParse::NewL(impData.OpaqueData()));
+ if (error != KErrNone)
+ {
+ if (error==KErrNotSupported)
+ continue;
+ else
+ User::Leave(error);
+ }
+ CleanupStack::PushL(parse);
+
+ // we can assume the version is valid as it is checked in
+ // COpaqueDataParse::ConstructL() which leaves if not valid
+ ASSERT(parse->Version() <= KIclPluginFrameworkVersionMax);
+
+ if (!impData.Disabled() && !parse->OnlyUidsAvail())
+ {
+ if(matchImageData)
+ {// match image data
+ TInt matchLevel = 0;
+ if (CImageConversionResolverUtils::Match(aImageData, impData.DataType(), matchLevel))
+ {
+ TInt error = KErrNone;
+ // do we need to create a decoder to fully verify the header data ?
+ if (parse->IsOpenNeededToRecognize())
+ {
+ CImageDecoder* decoder = NULL;
+ TRAP(error, decoder = CImageDecoder::DataNewL(iFs, aImageData));
+ delete decoder;
+ if (error==KErrNoMemory) // handle OOM, but assume everything else is a do not recognize
+ User::Leave(KErrNoMemory);
+ else if (error==KErrUnderflow && aImageData.Length()>=KImageHeaderSize)
+ {
+ // assuming we have enough data, means the format requires more
+ // might as well assume OK
+ error=KErrNone;
+ }
+ }
+ if(error == KErrNone && oldMatchLevel < matchLevel)
+ {
+ // either found a match or a better match
+ oldMatchLevel = matchLevel;
+ parse->EnsureMIMETypesReadL();
+ aMimeType = (parse->MIMETypesCount()==0) ? KNullDesC8() : parse->MIMEType(0);
+ }
+ }
+ }
+ else
+ {// match file extension
+ ASSERT(!matchImageData);
+ ASSERT(fileSuffix!=NULL);
+
+ if(parse->IsRecognizeAgainstSuffix())
+ { //If codec has file extensions and allow matching on them
+ parse->EnsureExtnsReadL();
+ const TInt numExtns = parse->ExtnsCount();
+ for (TInt index2 = 0; index2 < numExtns; index2++)
+ {
+ const TDesC8& extn = parse->Extn(index2);
+ if (COpaqueDataParse::CompareFileSuffixL(*fileSuffix, extn))
+ {
+ // return the first MIME type listed for this plugin
+ matchFound = ETrue;
+ parse->EnsureMIMETypesReadL();
+ aMimeType = (parse->MIMETypesCount()==0) ? KNullDesC8() : parse->MIMEType(0);
+ break;
+ }
+ }
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(parse);
+ }
+
+ if(oldMatchLevel>0)
+ {
+ // looked at all plugins now
+ // return the best MIME type listed for this plugin
+ matchFound = ETrue;
+ }
+
+ if(!matchImageData)
+ CleanupStack::PopAndDestroy(fileSuffix);
+
+ return matchFound;
+ }
+
+
+// Static factory constructor. Uses two phase
+// construction and leaves nothing on the cleanup stack
+//
+// @leave KErrNoMemory
+// @return A pointer to the newly created CIclRecognizerUtil::CBody object
+//
+CIclRecognizerUtil::CBody* CIclRecognizerUtil::CBody::NewL()
+ {
+ CBody* self=new (ELeave) CBody();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+