imaging/imagingfws/src/Reciclutilbody.cpp
changeset 0 5752a19fdefe
equal deleted inserted replaced
-1:000000000000 0:5752a19fdefe
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // This is the body of the ICL recognizer utility class
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "ImageConversion.h"
       
    19 #include "ImageResolverAPI.h"
       
    20 #include "ImageConvResolvrUtils.h"
       
    21 #include "ImageRelay.h"
       
    22 #include "EnDecoderUtils.h"
       
    23 #include "RecIclUtilBody.h"
       
    24 
       
    25 // ICL Recognizer Utility class body constructor
       
    26 CIclRecognizerUtil::CBody::CBody():
       
    27 	CActive(CActive::EPriorityStandard)
       
    28 	{
       
    29 	}
       
    30 
       
    31 CIclRecognizerUtil::CBody::~CBody()
       
    32 	{
       
    33 	Cancel();
       
    34 	iEcomSession.Close();
       
    35 	iFs.Close();
       
    36 	iPluginArray.ResetAndDestroy();
       
    37 	}
       
    38 
       
    39 // Request ECom to be notified when interface implementation registration 
       
    40 // data changes so that we can refresh the list of interface implementations.
       
    41 void CIclRecognizerUtil::CBody::StartNotification()
       
    42 	{
       
    43 	iEcomSession.NotifyOnChange(iStatus);
       
    44 	SetActive();
       
    45 	}
       
    46 
       
    47 // build a list of interface implementation objects
       
    48 void CIclRecognizerUtil::CBody::BuildControllerListL()
       
    49 	{
       
    50 	iPluginArray.ResetAndDestroy();
       
    51 	REComSession::ListImplementationsL(
       
    52 		KImageDecoderInterfaceUid, 
       
    53 		iPluginArray);
       
    54 	}
       
    55 
       
    56 void CIclRecognizerUtil::CBody::ConstructL()
       
    57 	{
       
    58 	BuildControllerListL();
       
    59 
       
    60 	CActiveScheduler::Add(this);
       
    61 
       
    62 	User::LeaveIfError(iFs.Connect());
       
    63 
       
    64     iEcomSession = REComSession::OpenL();
       
    65 
       
    66 	// request notification from ECOM of any file system changes
       
    67 	StartNotification();
       
    68 	}
       
    69 
       
    70 void CIclRecognizerUtil::CBody::RunL()
       
    71 	{
       
    72 	BuildControllerListL();
       
    73 	StartNotification();
       
    74 	}
       
    75 
       
    76 void CIclRecognizerUtil::CBody::DoCancel()
       
    77 	{
       
    78 	if (iStatus == KRequestPending)
       
    79 		iEcomSession.CancelNotifyOnChange(iStatus);
       
    80 	}
       
    81 
       
    82 // Determine whether the supplied data header or file extension is recognized
       
    83 // and if so return the associated MIME type
       
    84 // @param	aImageData
       
    85 //          A descriptor containing the header. Set to KNullDesC8 for match by file extension.
       
    86 // @param	aFileName
       
    87 //			A file name for file extension matching. Set to KNullDesC for match by image data
       
    88 // @param   aMimeType
       
    89 //          A user-supplied descriptor in which the MIME type is returned
       
    90 // @return	ETrue if a match was found.
       
    91 //			EFalse if a match was not found.
       
    92 // @leave	This method may also leave with one of the system-wide error codes.
       
    93 // @post    If recognized, the caller's descriptor is filled with the MIME types
       
    94 TBool CIclRecognizerUtil::CBody::GetMimeTypeL(const TDesC8& aImageData, const TDesC& aFileName, TDes8& aMimeType)
       
    95 	{
       
    96 	TBool matchImageData = ETrue;
       
    97 	HBufC* fileSuffix = NULL;
       
    98 
       
    99 	if(aFileName==KNullDesC)
       
   100 		{// match on image data
       
   101 		if (aImageData.Length() < KImageHeaderSize) // There is not enough data in this source
       
   102 			return EFalse; 
       
   103 		}
       
   104 	else
       
   105 		{// match on file extension
       
   106 		// Ensure aFileName is < KMaxFileName
       
   107 		if ( aFileName.Length() > KMaxFileName )
       
   108 			{
       
   109 			User::Leave(KErrBadName);
       
   110 			}
       
   111 		
       
   112 		TParse fileName;
       
   113  
       
   114  		TDes* const fName = new(ELeave) TFileName;
       
   115  		
       
   116  		CleanupStack::PushL(fName);
       
   117  		
       
   118  		fName->Copy(aFileName);
       
   119  
       
   120  		// if illegalifier character has been added to the file name,
       
   121  		// remove the illegalifier and pass the file name only to the parser.
       
   122  		if (fName->Match(_L("::*")) == 0)
       
   123  			{
       
   124  			fName->Delete(0, 2);
       
   125  			}
       
   126  
       
   127  		fileName.Set(*fName, NULL, NULL);
       
   128  
       
   129  		CleanupStack::PopAndDestroy(fName);
       
   130 
       
   131 
       
   132 		//No file extension
       
   133 		if (!fileName.ExtPresent())	
       
   134 			return EFalse;
       
   135 		
       
   136 		//Get the suffix
       
   137 		fileSuffix = fileName.Ext().AllocLC();
       
   138 
       
   139 		matchImageData = EFalse;
       
   140 		}
       
   141 
       
   142 	TBool matchFound = EFalse;
       
   143 
       
   144 	// loop through every plugin
       
   145 	// until we find one that matches the file extension
       
   146 	const TInt count = iPluginArray.Count();
       
   147 	TInt oldMatchLevel = 0; // number of characters matched in best match
       
   148 
       
   149 	for(TInt index = 0; index < count && !matchFound; index++)
       
   150 		{
       
   151 		const CImplementationInformation& impData = *(iPluginArray[index]);
       
   152 
       
   153 		COpaqueDataParse *parse = NULL;
       
   154 		TRAPD(error, parse = COpaqueDataParse::NewL(impData.OpaqueData()));
       
   155 		if (error != KErrNone)
       
   156 			{
       
   157 			if (error==KErrNotSupported)
       
   158 				continue;
       
   159 			else
       
   160 				User::Leave(error);
       
   161 			}
       
   162 		CleanupStack::PushL(parse);
       
   163 
       
   164 		// we can assume the version is valid as it is checked in 
       
   165 		// COpaqueDataParse::ConstructL() which leaves if not valid
       
   166 		ASSERT(parse->Version() <= KIclPluginFrameworkVersionMax);
       
   167 		
       
   168 		if (!impData.Disabled() && !parse->OnlyUidsAvail())
       
   169 			{
       
   170 			if(matchImageData)
       
   171 				{// match image data 
       
   172 				TInt matchLevel = 0;
       
   173 				if (CImageConversionResolverUtils::Match(aImageData, impData.DataType(), matchLevel))
       
   174 					{
       
   175 					TInt error = KErrNone;
       
   176 					// do we need to create a decoder to fully verify the header data ?
       
   177 					if (parse->IsOpenNeededToRecognize())
       
   178 						{
       
   179 						CImageDecoder* decoder = NULL;
       
   180            				TRAP(error, decoder = CImageDecoder::DataNewL(iFs, aImageData));
       
   181 						delete decoder;
       
   182 						if (error==KErrNoMemory) // handle OOM, but assume everything else is a do not recognize
       
   183 							User::Leave(KErrNoMemory);
       
   184 						else if (error==KErrUnderflow && aImageData.Length()>=KImageHeaderSize) 
       
   185 							{
       
   186 							// assuming we have enough data, means the format requires more
       
   187 							// might as well assume OK
       
   188 							error=KErrNone;
       
   189 							}
       
   190 						}
       
   191 					if(error == KErrNone && oldMatchLevel < matchLevel)
       
   192 						{
       
   193 						// either found a match or a better match
       
   194 						oldMatchLevel = matchLevel;
       
   195 						parse->EnsureMIMETypesReadL();
       
   196 						aMimeType = (parse->MIMETypesCount()==0) ? KNullDesC8() : parse->MIMEType(0);
       
   197 						}
       
   198 					}
       
   199 				}
       
   200 			else
       
   201 				{// match file extension
       
   202 				ASSERT(!matchImageData);
       
   203 				ASSERT(fileSuffix!=NULL);
       
   204 
       
   205 				if(parse->IsRecognizeAgainstSuffix())
       
   206 					{ //If codec has file extensions and allow matching on them
       
   207 					parse->EnsureExtnsReadL();
       
   208 					const TInt numExtns = parse->ExtnsCount();
       
   209 					for (TInt index2 = 0; index2 < numExtns; index2++)
       
   210 						{
       
   211 						const TDesC8& extn = parse->Extn(index2);
       
   212 						if (COpaqueDataParse::CompareFileSuffixL(*fileSuffix, extn))
       
   213 							{
       
   214 							// return the first MIME type listed for this plugin
       
   215 							matchFound = ETrue;
       
   216 							parse->EnsureMIMETypesReadL();
       
   217 							aMimeType = (parse->MIMETypesCount()==0) ? KNullDesC8() : parse->MIMEType(0);
       
   218 							break;
       
   219 							}
       
   220 						}
       
   221 					}
       
   222 				}
       
   223 			}
       
   224 		CleanupStack::PopAndDestroy(parse);
       
   225 		}
       
   226 	
       
   227 	if(oldMatchLevel>0) 
       
   228 			{
       
   229 			// looked at all plugins now 
       
   230 			// return the best MIME type listed for this plugin
       
   231 			matchFound = ETrue;
       
   232 			}
       
   233 
       
   234 	if(!matchImageData)
       
   235 		CleanupStack::PopAndDestroy(fileSuffix);
       
   236 
       
   237 	return matchFound;
       
   238 	}
       
   239 
       
   240 
       
   241 // Static factory constructor. Uses two phase
       
   242 // construction and leaves nothing on the cleanup stack
       
   243 // 
       
   244 // @leave KErrNoMemory
       
   245 // @return A pointer to the newly created CIclRecognizerUtil::CBody object
       
   246 // 
       
   247 CIclRecognizerUtil::CBody* CIclRecognizerUtil::CBody::NewL()
       
   248 	{
       
   249 	CBody* self=new (ELeave) CBody();   
       
   250 	CleanupStack::PushL(self);
       
   251 	self->ConstructL();
       
   252 	CleanupStack::Pop(self);
       
   253 	return self;
       
   254 	}
       
   255