imagingandcamerafws/imagingfws/ImageDisplay/src/ImageDisplayFramework.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2004-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 //
       
    15 
       
    16 /**    @file
       
    17    @internalComponent */
       
    18 #include <caf/data.h>
       
    19 #include <caf/content.h>
       
    20 #include "ImageDisplayFramework.h"
       
    21 #include "ImageDisplay.h"
       
    22 #include "ImageDisplay.hrh"
       
    23 #include "ImageDisplayMain.h"
       
    24 #include "../../src/ImageUtils.h"
       
    25 #include "ImageDisplayResolverAPI.h"
       
    26 #include "ImageDisplayResolvrUtils.h"
       
    27 using namespace ContentAccess;
       
    28 
       
    29 /**
       
    30 * NewL
       
    31 * The function NewL constructs a CImageDisplayFramework
       
    32 *
       
    33 * @return	CImageDisplayFramework*
       
    34 *
       
    35 */
       
    36 CImageDisplayFramework* CImageDisplayFramework::NewL(CImageDisplay& aHandle, MIclImageDisplayObserver& aCallback, RFs& aFs)
       
    37 	{
       
    38 	CImageDisplayFramework* self = new(ELeave) CImageDisplayFramework(aHandle, aCallback, aFs);
       
    39 	return self;
       
    40 	}
       
    41 
       
    42 /**
       
    43 *
       
    44 * CImageDisplayFramework
       
    45 *
       
    46 */
       
    47 CImageDisplayFramework::CImageDisplayFramework(CImageDisplay& aHandle, MIclImageDisplayObserver& aCallback, RFs& aFs) : 
       
    48 	iHandle(aHandle), iCallback(aCallback), iFs(aFs)
       
    49 	{
       
    50 	Reset();
       
    51 	}
       
    52 
       
    53 /**
       
    54 *
       
    55 * ~CImageDisplayFramework
       
    56 * This is the destructor for the CImageDisplayFramework 
       
    57 * and is resposible for deallocating all resources 
       
    58 * allocated by the CImageDisplayFramework
       
    59 *
       
    60 */
       
    61 CImageDisplayFramework::~CImageDisplayFramework()
       
    62 	{
       
    63 	// make sure any existing displayation is cancelled
       
    64 	if (iPlugin && (EStateProcessing == iState || iState == EStatePluginLoaded
       
    65 						|| iState == EStatePaused))
       
    66 		{
       
    67 		iPlugin->StopPlay();
       
    68 		}
       
    69 	DeletePlugin();
       
    70 	}
       
    71 
       
    72 CImageDisplayPlugin::TImageSourceType CImageDisplayFramework::SourceType() const
       
    73 	{
       
    74 	return iSourceImage.ImageSourceType();
       
    75 	}
       
    76 
       
    77 const TDesC& CImageDisplayFramework::SourceFilename() const
       
    78 	{
       
    79 	if (CImageDisplayPlugin::EImgSrcFileName != iSourceImage.ImageSourceType())
       
    80 		{
       
    81 		Panic(EImageWrongType);
       
    82 		}
       
    83 	return iSourceImage.Filename();
       
    84 	}
       
    85 
       
    86 const TDesC8& CImageDisplayFramework::SourceData() const
       
    87 	{
       
    88 	if (CImageDisplayPlugin::EImgSrcDescriptor != iSourceImage.ImageSourceType())
       
    89 		{
       
    90 		Panic(EImageWrongType);
       
    91 		}
       
    92 	return iSourceImage.Data();
       
    93 	}
       
    94 
       
    95 RFile& CImageDisplayFramework::SourceFileHandle() const
       
    96 	{
       
    97 	if (CImageDisplayPlugin::EImgSrcFileHandle != iSourceImage.ImageSourceType())
       
    98 		{
       
    99 		Panic(EImageWrongType);
       
   100 		}
       
   101 	return iSourceImage.FileHandle();
       
   102 	}
       
   103 
       
   104 TInt CImageDisplayFramework::SetImageSource(const TMMSource& aImageSource)
       
   105 	{
       
   106 	if (EStatePluginLoaded == iState)
       
   107 		{
       
   108 		DeletePlugin();
       
   109 		iState = EStateOpened;
       
   110 		}
       
   111 	if (iState != EStateOpened)
       
   112 		{
       
   113 		Panic(EIllegalCallSequence);
       
   114 		}
       
   115 	iState = EStateConfigured;
       
   116 	if (aImageSource.SourceType() == KUidMMFileSource)
       
   117 		{
       
   118 		iSourceImage.SetFilename(static_cast<const TMMFileSource&>(aImageSource).Name());
       
   119 		}
       
   120 	else if (aImageSource.SourceType() == KUidMMFileHandleSource)
       
   121 		{
       
   122 		iSourceImage.SetFileHandle(static_cast<const TMMFileHandleSource&>(aImageSource).Handle());
       
   123 		}
       
   124 	else if (aImageSource.SourceType() == KUidDescDataSource)
       
   125 		{
       
   126 		iSourceImage.SetData(static_cast<const TDescriptorDataSource&>(aImageSource).DataBuf());
       
   127 		}
       
   128 	else
       
   129 		{
       
   130 		return KErrNotSupported;
       
   131 		}
       
   132 	iSourceImage.SetIntent(aImageSource.Intent());
       
   133 	iSourceImage.SetContentId(aImageSource.UniqueId());
       
   134 	return KErrNone;
       
   135 	}
       
   136 
       
   137 void CImageDisplayFramework::SetSourceRect(const TRect& aRect)
       
   138 	{
       
   139 	if (!(EStateOpened == iState || EStateConfigured == iState || EStatePluginLoaded == iState))
       
   140 		{
       
   141 		Panic(EIllegalCallSequence);
       
   142 		}
       
   143 	iSourceRect = aRect;
       
   144 	SetFlag(EFlagSourceRectSet);
       
   145 	}
       
   146 
       
   147 void CImageDisplayFramework::ResetSourceRect()
       
   148 	{
       
   149 	if (!(EStateOpened == iState || EStateConfigured == iState || EStatePluginLoaded == iState))
       
   150 		{
       
   151 		Panic(EIllegalCallSequence);
       
   152 		}
       
   153 	ClearFlag(EFlagSourceRectSet);
       
   154 	}
       
   155 
       
   156 void CImageDisplayFramework::SetSizeInPixels(const TSize& aDestinationSize, TBool aMaintainAspectRatio)
       
   157 	{
       
   158 	if (!(EStateOpened == iState || EStateConfigured == iState || EStatePluginLoaded == iState))
       
   159 		{
       
   160 		Panic(EIllegalCallSequence);
       
   161 		}
       
   162 	iDestinationSize = aDestinationSize;
       
   163 	if (aMaintainAspectRatio)
       
   164 		{
       
   165 		SetFlag(EFlagMaintainAspectRatio);
       
   166 		}
       
   167 	else
       
   168 		{
       
   169 		ClearFlag(EFlagMaintainAspectRatio);
       
   170 		}
       
   171 	}
       
   172 
       
   173 TInt CImageDisplayFramework::SetOptions(TUint aOptions)
       
   174 	{
       
   175 	if (!(EStateOpened == iState || EStateConfigured == iState))
       
   176 		{
       
   177 		Panic(EIllegalCallSequence);
       
   178 		}
       
   179 	if ((aOptions & CImageDisplay::EOptionMainImage) != CImageDisplay::EOptionMainImage  
       
   180 			&& (aOptions & CImageDisplay::EOptionThumbnail) != CImageDisplay::EOptionThumbnail)
       
   181 		{
       
   182 		return KErrArgument;
       
   183 		}
       
   184 	iOptions = aOptions;
       
   185 	return KErrNone;
       
   186 	}
       
   187 
       
   188 void CImageDisplayFramework::SetSourceMimeType(const TDesC8& aMimeType)
       
   189 	{
       
   190 	if (!(EStateOpened == iState || EStateConfigured == iState))
       
   191 		{
       
   192 		Panic(EIllegalCallSequence);
       
   193 		}
       
   194 	iSourceImage.SetMimeType(aMimeType);
       
   195 	}
       
   196 
       
   197 void CImageDisplayFramework::SetSourceImageType(TUid aImageType, TUid aImageSubType)
       
   198 	{
       
   199 	if (!(EStateOpened == iState || EStateConfigured == iState))
       
   200 		{
       
   201 		Panic(EIllegalCallSequence);
       
   202 		}
       
   203 	iSourceImage.SetImageType(aImageType, aImageSubType);
       
   204 	}
       
   205 
       
   206 void CImageDisplayFramework::SetPluginUid(TUid aPluginUid)
       
   207 	{
       
   208 	if (!(EStateOpened == iState || EStateConfigured == iState))
       
   209 		{
       
   210 		Panic(EIllegalCallSequence);
       
   211 		}
       
   212 	iPluginUid = aPluginUid;
       
   213 	}
       
   214 
       
   215 void CImageDisplayFramework::SetDisplayMode(TDisplayMode aDisplayMode)
       
   216 	{
       
   217 	if (!(EStateOpened == iState || EStateConfigured == iState))
       
   218 		{
       
   219 		Panic(EIllegalCallSequence);
       
   220 		}
       
   221 	iDisplayMode = aDisplayMode;	
       
   222 	}
       
   223 
       
   224 const TDesC8& CImageDisplayFramework::SourceMimeType() const
       
   225 	{
       
   226 	// this will return KNullDesC8 if not defined
       
   227 	return iSourceImage.MimeType();
       
   228 	}
       
   229 
       
   230 const TUid CImageDisplayFramework::SourceImageType() const
       
   231 	{
       
   232 	return iSourceImage.ImageType();
       
   233 	}
       
   234 
       
   235 const TUid CImageDisplayFramework::SourceImageSubType() const
       
   236 	{
       
   237 	return iSourceImage.ImageSubType();
       
   238 	}
       
   239 
       
   240 TBool CImageDisplayFramework::SourceRect(TRect& aRect) const
       
   241 	{
       
   242 	if (FlagSet(EFlagSourceRectSet))
       
   243 		{
       
   244 		aRect = iSourceRect;
       
   245 		return ETrue;
       
   246 		}
       
   247 	else
       
   248 		{
       
   249 		return EFalse;
       
   250 		}
       
   251 	}
       
   252 
       
   253 const TSize& CImageDisplayFramework::DestinationSizeInPixels() const
       
   254 	{
       
   255 	return iDestinationSize;
       
   256 	}
       
   257 
       
   258 TUint CImageDisplayFramework::Options() const
       
   259 	{
       
   260 	return iOptions;
       
   261 	}
       
   262 
       
   263 TBool CImageDisplayFramework::MaintainAspectRatio() const
       
   264 	{
       
   265 	return FlagSet(EFlagMaintainAspectRatio);
       
   266 	}
       
   267 
       
   268 TDisplayMode CImageDisplayFramework::DisplayMode() const
       
   269 	{
       
   270 	return iDisplayMode;
       
   271 	}
       
   272 
       
   273 void CImageDisplayFramework::CallbackImageReady(const CFbsBitmap* aBitmap, TUint aStatus, const TRect& aUpdatedArea, TInt aError)
       
   274 	{
       
   275 	if (CImageDisplayPlugin::EStatusNoMoreToDecode & aStatus)
       
   276 		{
       
   277 		iState = EStatePluginLoaded;
       
   278 		}
       
   279 	else if (CImageDisplayPlugin::EStatusPaused & aStatus)
       
   280 		{
       
   281 		iState = EStatePaused;
       
   282 		}
       
   283 
       
   284 	iCallback.MiidoImageReady(aBitmap, aStatus, aUpdatedArea, aError);
       
   285 	}
       
   286 
       
   287 void CImageDisplayFramework::SetupL()
       
   288 	{
       
   289 	if (EStateConfigured != iState )
       
   290 		{
       
   291 		Panic(EUndefinedSourceType);
       
   292 		}
       
   293 // pre-conditions
       
   294 	if (iOptions == CImageDisplay::EOptionsUndefined)
       
   295 		{
       
   296 		User::Leave(KErrArgument);
       
   297 		}
       
   298 	if (!iSourceImage.IsDataTypeDefined())
       
   299 		{
       
   300 		Panic(EUndefinedSourceType);
       
   301 		}
       
   302 
       
   303 	DeletePlugin();
       
   304 
       
   305 	if (CImageDisplayPlugin::EImgSrcFileName == iSourceImage.ImageSourceType())
       
   306 		{
       
   307 		// check arguments
       
   308 		TEntry entry;
       
   309 		User::LeaveIfError(iFs.Entry(iSourceImage.Filename(), entry));
       
   310 		if (SourceMimeType() == KNullDesC8)
       
   311 			{
       
   312 			iPlugin = FileNewImplL(
       
   313 				iSourceImage.Filename(),
       
   314 				iSourceImage.ImageType(), 
       
   315 				iSourceImage.ImageSubType(),
       
   316 				iPluginUid);
       
   317 			}
       
   318 		else
       
   319 			{
       
   320 			iPlugin = NewImplL(SourceMimeType());
       
   321 			}
       
   322 		}
       
   323 	else if (CImageDisplayPlugin::EImgSrcFileHandle == iSourceImage.ImageSourceType())
       
   324 			{
       
   325 			iPlugin = FileHandleNewImplL(
       
   326 						iSourceImage.FileHandle(),
       
   327 						iSourceImage.ImageType(), 
       
   328 					iSourceImage.ImageSubType(),
       
   329 					iPluginUid
       
   330 				);
       
   331 			}
       
   332 	else
       
   333 		{
       
   334 		if (iSourceImage.Data().Length() == 0)
       
   335 			{
       
   336 			User::Leave(KErrArgument);
       
   337 			}
       
   338 		if (SourceMimeType() == KNullDesC8)
       
   339 			{
       
   340 			iPlugin = DataNewL(
       
   341 				iSourceImage.Data(), 
       
   342 				iSourceImage.ImageType(), 
       
   343 				iSourceImage.ImageSubType(),
       
   344 				iPluginUid);
       
   345 			}
       
   346 		else
       
   347 			{
       
   348 			iPlugin = NewImplL(SourceMimeType());
       
   349 			}
       
   350 		}
       
   351 
       
   352 	ASSERT(iPlugin);
       
   353 	
       
   354 	// if the plugin leaves in the OpenL() call, then we should 
       
   355 	// delete the plugin in case SetupL() is called again (with no Reset())
       
   356 	TRAPD(err, iPlugin->OpenL());
       
   357 	if (err != KErrNone)
       
   358 		{
       
   359 		DeletePlugin();
       
   360 		User::Leave(err);
       
   361 		}
       
   362 	iState = EStatePluginLoaded;
       
   363 	}
       
   364 
       
   365 void CImageDisplayFramework::Play()
       
   366 	{
       
   367 	if (!(iState == EStateProcessing || iState == EStatePaused || iState == EStatePluginLoaded))
       
   368 		{
       
   369 		Panic(EIllegalCallSequence);
       
   370 		}
       
   371 	if (iDestinationSize == TSize(0, 0))
       
   372 		{
       
   373 		Panic(EUndefinedDestSize);
       
   374 		}
       
   375 	iState = EStateProcessing;
       
   376 	iPlugin->Play();
       
   377 	}
       
   378 
       
   379 void CImageDisplayFramework::Pause()
       
   380 	{
       
   381 	if (!(iState == EStateProcessing || iState == EStatePaused))
       
   382 		{
       
   383 		Panic(EIllegalCallSequence);
       
   384 		}
       
   385 	iState = EStatePaused;
       
   386 	iPlugin->Pause();
       
   387 	}
       
   388 
       
   389 void CImageDisplayFramework::StopPlay()
       
   390 	{
       
   391 	if (EStateProcessing != iState && iState != EStatePluginLoaded && iState != EStatePaused)
       
   392 		{
       
   393 		Panic(EIllegalCallSequence);
       
   394 		}
       
   395 	iState = EStatePluginLoaded;
       
   396 	iPlugin->StopPlay();
       
   397 	}
       
   398 
       
   399 void CImageDisplayFramework::Reset()
       
   400 	{
       
   401 	// Reset state to "just created" state
       
   402 	DeletePlugin();
       
   403 
       
   404 	iSourceImage.Reset();
       
   405 	iDestinationSize = TSize(0, 0);
       
   406 	iDisplayMode = ENone;
       
   407 	ClearFlag(EFlagSourceRectSet);
       
   408 	iOptions = CImageDisplay::EOptionsUndefined;
       
   409 	iState = EStateOpened;
       
   410 	}
       
   411 
       
   412 
       
   413 /**
       
   414  * Create a display plugin for the image in the named file. The client supplies a
       
   415  * MIME type which will be used to try and select an appropriate plugin
       
   416  * Displayer. If it finds a Displayer it creates it and then goes on to use that
       
   417  * displayer to scan the beginning of the image file.
       
   418  * @internalTechnology
       
   419  * @param	"aFs"
       
   420  *			A reference to a file server session for the displayer to use.
       
   421  * @param	"aSourceFilename"
       
   422  *			The name of the file to be convertd.
       
   423  * @param	"aMIMEType"
       
   424  *			The MIME type of the image in the file.
       
   425  * @return	Returns a pointer to the newly created displayer.
       
   426  * @leave   KEComErrNoInterfaceIdentified
       
   427  *			No plugin displayers were found.
       
   428  */
       
   429 CImageDisplayPlugin* CImageDisplayFramework::NewImplL(const TDesC8& aMIMEType)
       
   430 	{
       
   431 	//Get a sorted list of displayers that will handle the image
       
   432 	RImplInfoPtrArray displayerList;
       
   433 	CleanupResetAndDestroyPushL(displayerList);
       
   434 	MimeTypeGetDisplayerListL(displayerList, aMIMEType);
       
   435 
       
   436 	CImageDisplayPlugin* displayer = NULL;
       
   437 	displayer = FindDisplayerNewL(displayerList);
       
   438 	ASSERT(displayer!=NULL);
       
   439 
       
   440 	CleanupStack::PopAndDestroy(&displayerList);
       
   441 	return displayer;
       
   442 	}
       
   443 
       
   444 
       
   445 /**
       
   446  *
       
   447  * Create a displayer for the image in the named file. If the client supplies an
       
   448  * image type (and sub-type, if applicable) or displayer uid, these will be used 
       
   449  * to try and select an appropriate plugin displayer. If not, then the selection 
       
   450  * will be done by matching the image header in the file. If it finds a displayer
       
   451  * it creates it and then goes on to use that displayer to scan the beginning of
       
   452  * the image file.
       
   453  * @internalTechnology
       
   454  * @param	"aFs"
       
   455  *			A reference to a file server session for the displayer to use.
       
   456  * @param	"aSourceFilename"
       
   457  *			The name of the file to be converted.
       
   458  * @param	"aImageType"
       
   459  *			The image type of the image in the file (optional, defaults to KNullUid).
       
   460  * @param	"aImageSubType"
       
   461  *			The image sub-type of the image in the file (optional, defaults to KNullUid).
       
   462  * @param	"aPluginUid"
       
   463  *			The implementation uid for a specific codec (optional, defaults to KNullUid).
       
   464  *			If this option is selected the image type and
       
   465  *			image sub type for the displayer must be supplied.
       
   466  * @return	Returns a pointer to the newly created displayer.
       
   467  * @leave	KErrUnderflow
       
   468  *			Not enough data in file to identify which plugin displayer to use.
       
   469  * @leave   KEComErrNoInterfaceIdentified
       
   470  *			No plugin displayers were found.
       
   471  * @panic   EIllegalImageSubType
       
   472  *			No base type given for sub-type.
       
   473  * @panic   EIllegalImageType
       
   474  *			No base type given for displayer implementation.
       
   475  */
       
   476 CImageDisplayPlugin* CImageDisplayFramework::FileNewImplL(
       
   477 	const TDesC& aSourceFilename, 
       
   478 	const TUid aImageType, 
       
   479 	const TUid aImageSubType, 
       
   480 	const TUid aPluginUid)
       
   481 	{
       
   482 	if ((aImageType == KNullUid) && (aImageSubType != KNullUid))
       
   483 		{ // Get out, no base type given for sub-type
       
   484 		Panic(EIllegalImageSubType); 
       
   485 		}
       
   486 
       
   487 	RImplInfoPtrArray displayerList;
       
   488 	CleanupResetAndDestroyPushL(displayerList);
       
   489 
       
   490 	TBuf8<KImageHeaderSize> imageHeader;
       
   491 
       
   492 	ContentAccess::CData* data = ContentAccess::CData::NewLC(TVirtualPathPtr(aSourceFilename, iSourceImage.ContentId()), ContentAccess::EContentShareReadOnly);
       
   493 	TInt err = data->SetProperty(EAgentPropertyAgentUI, iSourceImage.IsUIEnabled());
       
   494 	// KErrCANotSupported doesn't prevent us from continuing so eat the error code.
       
   495 	if (err != KErrNone && err != KErrCANotSupported)
       
   496 		{
       
   497 		User::Leave(err);
       
   498 		}
       
   499 	User::LeaveIfError(data->Read(imageHeader, KImageHeaderSize));
       
   500 
       
   501 	TRAP(err, ImageTypeGetDisplayerListL(
       
   502 					displayerList, 
       
   503 					imageHeader, 
       
   504 					aImageType, 
       
   505 					aImageSubType, 
       
   506 					aPluginUid)
       
   507 		);
       
   508 
       
   509 	if (!(err==KErrNone || err==KErrUnderflow))
       
   510 		{
       
   511 		User::Leave(err);
       
   512 		}
       
   513 	
       
   514 	//Try to match by file extension only
       
   515 	//1) If no plugin was found and 
       
   516 	//2) No specific displayer or format was specified
       
   517 	const TBool formatSpecified = (aImageType!=KNullUid || aImageSubType!=KNullUid || aPluginUid!=KNullUid);
       
   518 	if(displayerList.Count()==0 && !formatSpecified)
       
   519 		{
       
   520 		SuffixTypeGetDisplayerListL(
       
   521 			displayerList, 
       
   522 			aSourceFilename);
       
   523 		}
       
   524 
       
   525 	CImageDisplayPlugin* displayer = NULL;
       
   526 	displayer = FindDisplayerNewL(displayerList);
       
   527 
       
   528 	ASSERT(displayer!=NULL);
       
   529 
       
   530 	CleanupStack::PushL(displayer);
       
   531 	User::LeaveIfError( data->EvaluateIntent(iSourceImage.Intent()) );
       
   532 	CleanupStack::Pop(displayer);
       
   533 	CleanupStack::PopAndDestroy(2, &displayerList);
       
   534 	return displayer;
       
   535 	}
       
   536 
       
   537 /**
       
   538  *
       
   539  * Create a displayer for the image using the given file handle. If the client supplies an
       
   540  * image type (and sub-type, if applicable) or displayer uid, these will be used 
       
   541  * to try and select an appropriate plugin displayer. If not, then the selection 
       
   542  * will be done by matching the image header in the file. If it finds a displayer
       
   543  * it creates it and then goes on to use that displayer to scan the beginning of
       
   544  * the image file.
       
   545  * @internalTechnology
       
   546  * @param	"aFileHandle"
       
   547  *			A reference to a file handle that contains an image data 
       
   548  * @param	"aImageType"
       
   549  *			The image type of the image in the file (optional, defaults to KNullUid).
       
   550  * @param	"aImageSubType"
       
   551  *			The image sub-type of the image in the file (optional, defaults to KNullUid).
       
   552  * @param	"aPluginUid"
       
   553  *			The implementation uid for a specific codec (optional, defaults to KNullUid).
       
   554  *			If this option is selected the image type and
       
   555  *			image sub type for the displayer must be supplied.
       
   556  * @return	Returns a pointer to the newly created displayer.
       
   557  * @leave	KErrUnderflow
       
   558  *			Not enough data in file to identify which plugin displayer to use.
       
   559  * @leave   KEComErrNoInterfaceIdentified
       
   560  *			No plugin displayers were found.
       
   561  * @panic   EIllegalImageSubType
       
   562  *			No base type given for sub-type.
       
   563  * @panic   EIllegalImageType
       
   564  *			No base type given for displayer implementation.
       
   565  */
       
   566 CImageDisplayPlugin* CImageDisplayFramework::FileHandleNewImplL(
       
   567 	RFile& aFileHandle, 
       
   568 	const TUid aImageType, 
       
   569 	const TUid aImageSubType, 
       
   570 	const TUid aPluginUid)
       
   571 	{
       
   572 	if ((aImageType == KNullUid) && (aImageSubType != KNullUid))
       
   573 		{ // Get out, no base type given for sub-type
       
   574 		Panic(EIllegalImageSubType); 
       
   575 		}
       
   576 
       
   577 	RImplInfoPtrArray displayerList;
       
   578 	CleanupResetAndDestroyPushL(displayerList);
       
   579 
       
   580 	TBuf8<KImageHeaderSize> imageHeader;
       
   581 
       
   582 	ContentAccess::CData* data = ContentAccess::CData::NewLC(aFileHandle, iSourceImage.ContentId());
       
   583 	TInt err = data->SetProperty(EAgentPropertyAgentUI, iSourceImage.IsUIEnabled());
       
   584 	// KErrCANotSupported doesn't prevent us from continuing so eat the error code.
       
   585 	if (err != KErrNone && err != KErrCANotSupported)
       
   586 		{
       
   587 		User::Leave(err);
       
   588 		}
       
   589 	User::LeaveIfError(data->Read(imageHeader, KImageHeaderSize));
       
   590 
       
   591 	ImageTypeGetDisplayerListL(
       
   592 		displayerList, 
       
   593 		imageHeader, 
       
   594 		aImageType, 
       
   595 		aImageSubType, 
       
   596 		aPluginUid);	
       
   597 
       
   598 	CImageDisplayPlugin* displayer = NULL;
       
   599 	displayer = FindDisplayerNewL(displayerList);
       
   600 	ASSERT(displayer!=NULL);
       
   601 
       
   602 	CleanupStack::PushL(displayer);
       
   603 	User::LeaveIfError( data->EvaluateIntent(iSourceImage.Intent()) );
       
   604 	CleanupStack::Pop(displayer);
       
   605 	CleanupStack::PopAndDestroy(2, &displayerList);
       
   606 	return displayer;
       
   607 	}
       
   608 
       
   609 
       
   610 /**
       
   611 Creates a displayer for the image in the source buffer. 
       
   612 
       
   613 If the client supplies an image type (and sub-type, if applicable) or displayer UID, 
       
   614 these will be used to try and select an appropriate plugin displayer. If not, then 
       
   615 the selection will be done by matching the image header from the buffer. If it
       
   616 finds a displayer, it is created and then used to scan the beginning of the image
       
   617 buffer.
       
   618 
       
   619 @param  aSourceData
       
   620         The buffer containing the image to be displayed.
       
   621 @param  aImageType
       
   622         The image type of the image in the file (optional, defaults to KNullUid).
       
   623 @param  aImageSubType
       
   624         The image sub-type of the image in the file (optional, defaults to KNullUid).
       
   625 @param	aPluginUid
       
   626         The implementation UID for a specific codec (optional, defaults to KNullUid).
       
   627         If this option is selected the image type and
       
   628         image sub type for the displayer must be supplied.
       
   629 
       
   630 @return	Returns a pointer to the newly created displayer.
       
   631 
       
   632 @leave  KErrUnderflow
       
   633         Not enough data in descriptor to identify which plugin displayer to use.
       
   634 @leave  KEComErrNoInterfaceIdentified
       
   635         No plugin displayers were found.
       
   636 @panic  EIllegalImageSubType
       
   637         No base type given for sub-type.
       
   638 
       
   639 */
       
   640 CImageDisplayPlugin* CImageDisplayFramework::DataNewL(
       
   641 	const TDesC8& aSourceData, 
       
   642 	const TUid aImageType, 
       
   643 	const TUid aImageSubType, 
       
   644 	const TUid aPluginUid)
       
   645 	{
       
   646 
       
   647 	if ((aImageType == KNullUid) && (aImageSubType != KNullUid))
       
   648 		{ // Get out, no base type given for sub-type
       
   649 		Panic(EIllegalImageSubType); 
       
   650 		}
       
   651 
       
   652 	//Get a list of displayers that will convert the image
       
   653 	RImplInfoPtrArray displayerList;
       
   654 	CleanupResetAndDestroyPushL(displayerList);
       
   655 	ImageTypeGetDisplayerListL(displayerList, aSourceData, aImageType, aImageSubType, aPluginUid);
       
   656 
       
   657 	CImageDisplayPlugin* displayer = NULL;
       
   658 	displayer = FindDisplayerNewL(displayerList);
       
   659 	ASSERT(displayer!=NULL);
       
   660 
       
   661 	CleanupStack::PopAndDestroy(&displayerList);
       
   662 	return displayer;
       
   663 	}
       
   664 
       
   665 
       
   666 
       
   667 /**
       
   668  * Create a list of converts that support the specified MIME type.
       
   669  *
       
   670  * @param	"aDisplayerList"
       
   671  *			Create a list of converts that support the given MIME type.
       
   672  * @param	"aMIMEType"
       
   673  *			The MIME type to convert.
       
   674  * @panic EUndefinedMIMEType
       
   675  */
       
   676 void CImageDisplayFramework::MimeTypeGetDisplayerListL(RImplInfoPtrArray& aDisplayerList, const TDesC8& aMIMEType)
       
   677 	{
       
   678 	if (aMIMEType.Length() == 0)
       
   679 		{ // Get out, empty MIME type string
       
   680 		Panic(EUndefinedMIMEType);
       
   681 		}
       
   682 
       
   683 	CCustomMatchData* customMatchData = CCustomMatchData::NewLC();
       
   684 	customMatchData->SetMatchType(EMatchMIMEType);
       
   685 	customMatchData->SetMatchStringL(aMIMEType);
       
   686 	if (FlagSet(EFlagSourceRectSet))
       
   687 		{
       
   688 		customMatchData->SetPluginFlagsNeeded(ESetSourceRectSupportNeeded);
       
   689 		}
       
   690 
       
   691 	HBufC8* package  = customMatchData->NewPackLC();
       
   692 	TPtr8 packageDes = package->Des();
       
   693 
       
   694 	TEComResolverParams resolverParams; // Parameters on which to match
       
   695 	resolverParams.SetDataType(packageDes);
       
   696 
       
   697 	REComSession::ListImplementationsL(
       
   698 		TUid::Uid(KUidDisplayInterface), 
       
   699 		resolverParams, 
       
   700 		TUid::Uid(KUidDisplayImplementationResolver), 
       
   701 		aDisplayerList);
       
   702 
       
   703 	CleanupStack::PopAndDestroy(2); // package, customMatchData
       
   704 	}
       
   705 
       
   706 
       
   707 /**
       
   708  * Create a list of displayers that support the specified image type.
       
   709  * @param	"aDisplayerList"
       
   710  *			A list of displayers that support the specified image type.
       
   711  * @param	"aImageHeader"
       
   712  *			The header of the image file.
       
   713  * @param	"aImageType"
       
   714  *			The image base type.
       
   715  * @param	"aImageSubType"
       
   716  *			The image sub type.
       
   717  * @param	"aPluginUid"
       
   718  *			A specific displayer to convert the image.
       
   719  */
       
   720 void CImageDisplayFramework::ImageTypeGetDisplayerListL(
       
   721 	RImplInfoPtrArray& aDisplayerList, 
       
   722 	const TDesC8& aImageHeader, 
       
   723 	const TUid aImageType, 
       
   724 	const TUid aImageSubType, 
       
   725 	const TUid aPluginUid)
       
   726 	{
       
   727 	TBuf8<KImageHeaderSize> imageHeader;
       
   728 
       
   729 	CCustomMatchData* customMatchData = CCustomMatchData::NewLC();
       
   730 
       
   731 	if ((aImageType != KNullUid) || (aPluginUid != KNullUid))
       
   732 		{ // We have a specific image type we are trying to convert
       
   733 		customMatchData->SetMatchType(EMatchUids);
       
   734 		customMatchData->SetBaseType(aImageType);
       
   735 		customMatchData->SetSubType(aImageSubType);
       
   736 		customMatchData->SetImplementationType(aPluginUid);
       
   737 		}
       
   738 	else
       
   739 		{
       
   740 		if (aImageHeader.Length() < KImageHeaderSize) // There is not enough data in the header
       
   741 			{ // Get out - clean up and leave
       
   742 			User::Leave(KErrUnderflow); 
       
   743 			}
       
   744 		imageHeader = aImageHeader.Left(KImageHeaderSize);
       
   745 		customMatchData->SetMatchType(EMatchString);
       
   746 		customMatchData->SetMatchStringL(imageHeader);
       
   747 		}
       
   748 
       
   749 	if (FlagSet(EFlagSourceRectSet))
       
   750 		{
       
   751 		customMatchData->SetPluginFlagsNeeded(ESetSourceRectSupportNeeded);
       
   752 		}
       
   753 
       
   754 	HBufC8* package  = customMatchData->NewPackLC();
       
   755 	TPtr8 packageDes = package->Des();
       
   756 
       
   757 	TEComResolverParams resolverParams; // Parameters on which to match
       
   758 	resolverParams.SetDataType(packageDes);
       
   759 
       
   760 	REComSession::ListImplementationsL(
       
   761 		TUid::Uid(KUidDisplayInterface), 
       
   762 		resolverParams, 
       
   763 		TUid::Uid(KUidDisplayImplementationResolver), 
       
   764 		aDisplayerList);
       
   765 
       
   766 	CleanupStack::PopAndDestroy(2); // package, customMatchData
       
   767 	}
       
   768 
       
   769 /**
       
   770  * Create a list of displayers that support the specified file extension.
       
   771  *
       
   772  * @param	"aDisplayerList"
       
   773  *			Create a list of displayers that support the given file extension.
       
   774  * @param	"aFileName"
       
   775  *			The file name from which the file extension will be taken.
       
   776  * @internalComponent
       
   777  */
       
   778 void CImageDisplayFramework::SuffixTypeGetDisplayerListL(
       
   779 	RImplInfoPtrArray& aDisplayerList, 
       
   780 	const TDesC& aFileName)
       
   781 	{
       
   782 	TParse fileName;
       
   783 	fileName.Set(aFileName,NULL,NULL);
       
   784 
       
   785 	//No file extension
       
   786 	if (!fileName.ExtPresent())	
       
   787 		{
       
   788 		User::Leave(KErrNotFound);
       
   789 		}
       
   790 		
       
   791 	//Get the suffix
       
   792 	TPtrC suffix(fileName.Ext());
       
   793 
       
   794 	CCustomMatchData* customMatchData = CCustomMatchData::NewLC();
       
   795 	customMatchData->SetMatchType(EMatchFileSuffix);
       
   796 	customMatchData->SetFileSuffixL(suffix);
       
   797 	if (FlagSet(EFlagSourceRectSet))
       
   798 		{
       
   799 		customMatchData->SetPluginFlagsNeeded( ESetSourceRectSupportNeeded );
       
   800 		}
       
   801 	HBufC8* package  = customMatchData->NewPackLC();
       
   802 	TPtr8 packageDes = package->Des();
       
   803 
       
   804 	TEComResolverParams resolverParams; // Parameters on which to match
       
   805 	resolverParams.SetDataType(packageDes);
       
   806 
       
   807 	REComSession::ListImplementationsL(
       
   808 		TUid::Uid(KUidDisplayInterface),
       
   809 		resolverParams, 
       
   810 		TUid::Uid(KUidDisplayImplementationResolver),
       
   811 		aDisplayerList);
       
   812 
       
   813 	CleanupStack::PopAndDestroy(2,customMatchData); // package, customMatchData
       
   814 	}
       
   815 
       
   816 
       
   817 /**
       
   818  * Scan a sorted list of displayers for the first one that can convert the image.
       
   819  * @internalTechnology
       
   820  * @param	"aDisplayerList"
       
   821  *			A list of displayers that support the image format.
       
   822  * @return	A pointer to the displayer.
       
   823  */
       
   824 CImageDisplayPlugin* CImageDisplayFramework::FindDisplayerNewL(
       
   825 	const RImplInfoPtrArray& aDisplayerList)
       
   826 	{
       
   827 	TInt noOfDisplayers = aDisplayerList.Count();
       
   828 
       
   829 	if(noOfDisplayers == 0)
       
   830 		{
       
   831 		User::Leave(KErrNotFound);
       
   832 		}
       
   833 
       
   834 	CImageDisplayPlugin* displayer = NULL;
       
   835 	TInt displayerNo = 0;
       
   836 	TInt error = KErrNone;
       
   837 	do
       
   838 		{
       
   839 		const CImplementationInformation& displayerInfo = *(aDisplayerList[displayerNo++]);
       
   840 		
       
   841 		TRAP(error, displayer = CImageDisplayPlugin::NewL(displayerInfo.ImplementationUid(), *this));
       
   842 
       
   843 		if (error != KErrCorrupt && error != KErrNotSupported && error != KErrNotFound)
       
   844 			{
       
   845 			break;
       
   846 			}
       
   847 		}
       
   848 	while(displayerNo < noOfDisplayers);
       
   849 
       
   850 	if(error!=KErrNone)
       
   851 		{
       
   852 		ASSERT(displayer==NULL);
       
   853 		if (error == KErrCorrupt || error == KErrNotSupported)
       
   854 			{
       
   855 			error = KErrNotFound;
       
   856 			}
       
   857 		User::Leave(error);
       
   858 		}
       
   859 
       
   860 	return displayer;
       
   861 	}
       
   862 
       
   863 inline
       
   864 void CImageDisplayFramework::DeletePlugin()
       
   865 	{
       
   866 	delete iPlugin;
       
   867 	iPlugin = NULL;
       
   868 	}
       
   869 	
       
   870 /**
       
   871 Gets a pointer to a plugin extension
       
   872 
       
   873 @panic	EIllegalCallSequence
       
   874 		No plugin loaded.
       
   875 @return	A pointer to a fully constructed  Image Display Plugin Extension interface
       
   876 		NULL, if there is no extension to the plugin
       
   877 */
       
   878 TInt CImageDisplayFramework::ExtensionInterface(TUid aIFaceUid, TAny*& aIFacePtr)
       
   879 	{
       
   880 	if (!iPlugin)
       
   881 		{
       
   882 		Panic(EIllegalCallSequence);
       
   883 		}
       
   884 		
       
   885 	return iPlugin->ExtensionInterface(aIFaceUid, aIFacePtr);
       
   886 	}
       
   887 	
       
   888 void CImageDisplayFramework::GetBitmap(const CFbsBitmap*& aBitmap, const CFbsBitmap*& aMask) const
       
   889 	{
       
   890 	if (EStateOpened == iState || EStateConfigured == iState )
       
   891 		{
       
   892 		Panic(EIllegalCallSequence);
       
   893 		}
       
   894 	iPlugin->GetBitmap(aBitmap, aMask);	
       
   895 	}
       
   896 
       
   897 TBool CImageDisplayFramework::ValidBitmap() const
       
   898 	{
       
   899 	if (!iPlugin)
       
   900 		{
       
   901 		Panic(EIllegalCallSequence);
       
   902 		}
       
   903 	return iPlugin->ValidBitmap();
       
   904 	}
       
   905 	
       
   906 const CImageDisplay::RImageSizeArray& CImageDisplayFramework::RecommendedImageSizes() const
       
   907 	{
       
   908 	if (!iPlugin)
       
   909 		{
       
   910 		Panic(EIllegalCallSequence);
       
   911 		}
       
   912 	return iPlugin->RecommendedImageSizes();
       
   913 	}
       
   914 
       
   915 TUint CImageDisplayFramework::ImageStatus() const
       
   916 	{
       
   917 	if (EStateOpened == iState || EStateConfigured == iState )
       
   918 		{
       
   919 		Panic(EIllegalCallSequence);
       
   920 		}
       
   921 	return iPlugin->ImageStatus();
       
   922 	}
       
   923 
       
   924 TInt CImageDisplayFramework::NumFrames(TInt& aNumFrames) const
       
   925 	{
       
   926 	aNumFrames = -1;
       
   927 	if (EStateOpened == iState || EStateConfigured == iState )
       
   928 		{
       
   929 		Panic(EIllegalCallSequence);
       
   930 		}
       
   931 	return iPlugin->NumFrames(aNumFrames);
       
   932 	}