imagingandcamerafws/imagingfws/src/Test/TImageViewer/TImageViewer.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 1997-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 #include <barsread.h>
       
    17 #include <bidi.h>
       
    18 #include <eikenv.h>
       
    19 #include <techview/eikchlst.h>
       
    20 #include <techview/eikinfo.h>
       
    21 #include <techview/eikmenup.h>
       
    22 #include <e32math.h>
       
    23 #include <badesca.h>
       
    24 #include <techview/eikon.rsg>	
       
    25 #include <eikpriv.rsg>
       
    26 #include <techview/eiktxlbx.h>
       
    27 #include <techview/eikmfne.h>
       
    28 #include <techview/eiktxlbm.h>
       
    29 #include <iclexif.h>
       
    30 
       
    31 #include <icl/icl_uids.hrh>
       
    32 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    33 #include <icl/icl_uids_const.hrh>
       
    34 #include <icl/icl_uids_def.hrh>
       
    35 #endif
       
    36 #include "TImageViewer.h"
       
    37 
       
    38 const TInt KVideoMinZoomFactor = -3;
       
    39 const TInt KVideoMaxZoomFactor = 0;
       
    40 
       
    41 const TInt KDefaultStreamDelay = 1000000; // 1s. Used when streaming non-animated
       
    42 const TInt KDefaultFolderDelay = 2000000; // 2s. Used when playing a folder
       
    43 
       
    44 const TInt KButtonMoveIncr = 16;
       
    45 const TInt KScaleFactor = 10;
       
    46 
       
    47 const TInt KInfoBufferSize = 1024;
       
    48 
       
    49 _LIT(KDefPath, "C:\\");
       
    50 const TInt KShortestPossiblePath=4;
       
    51 
       
    52 // #define __USE_PURE_SCALING // fine scaling scales to 1/2, 1/4 and 1/8 - check non-universal scaling
       
    53 
       
    54 #define __CLEAR_BITMAPS_FIRST // for debugging purposes, get TImageViewer to clear bitmaps prior to
       
    55 							  // decode conversion. Really the codecs should do this, but...
       
    56 
       
    57 inline TBool IsMngImage(const CImageDecoder* aDecoder)
       
    58 	{
       
    59 	TUid type, subtype;
       
    60 	aDecoder->ImageType(0, type, subtype);
       
    61 	return (type.iUid==KMngMimeTypeUidValue);
       
    62 	}
       
    63 
       
    64 inline TBool HasMoreMngFrames(const CImageDecoder* aDecoder)
       
    65 	{
       
    66 	const TFrameInfo& info=aDecoder->FrameInfo(0);
       
    67 	return (info.iFlags & TFrameInfo::EMngMoreFramesToDecode);
       
    68 	}
       
    69 
       
    70 CPluginInfoArray* CPluginInfoArray::NewL()
       
    71 	{
       
    72 	CPluginInfoArray* self = new (ELeave) CPluginInfoArray;
       
    73 	CleanupStack::PushL(self);
       
    74 	self->ConstructL();
       
    75 	CleanupStack::Pop(self);
       
    76 	return self;
       
    77 	}
       
    78 
       
    79 void CPluginInfoArray::ConstructL()
       
    80 	{
       
    81 	RefreshPluginListL();
       
    82 	}
       
    83 
       
    84 CPluginInfoArray::CPluginInfoArray()
       
    85 	{
       
    86 	}
       
    87 
       
    88 void CPluginInfoArray::Reset()
       
    89 	{
       
    90 	iPluginArray.ResetAndDestroy();
       
    91 	}
       
    92 
       
    93 void CPluginInfoArray::RefreshPluginListL()
       
    94 	{
       
    95 	Reset();
       
    96 	CImageEncoder::GetImageTypesL(iPluginArray);
       
    97 	}
       
    98 
       
    99 CPluginInfoArray::~CPluginInfoArray()
       
   100 	{
       
   101 	Reset();
       
   102 	}
       
   103 
       
   104 TInt CPluginInfoArray::MdcaCount() const
       
   105 	{
       
   106 	return iPluginArray.Count();
       
   107 	}
       
   108 
       
   109 TPtrC CPluginInfoArray::MdcaPoint(TInt aIndex) const
       
   110 	{
       
   111 	return iPluginArray[aIndex]->Description(); 
       
   112 	}
       
   113 
       
   114 TUid CPluginInfoArray::ImageType(TInt aIndex)
       
   115 	{
       
   116 	return iPluginArray[aIndex]->ImageType(); 
       
   117 	}
       
   118 
       
   119 TUid CPluginInfoArray::SubType(TInt aIndex)
       
   120 	{
       
   121 	return iPluginArray[aIndex]->SubType(); 
       
   122 	}
       
   123 
       
   124 // CFrameInfoDialog
       
   125 class CFrameInfoDialog : public CEikDialog
       
   126 	{
       
   127 public:
       
   128 	CFrameInfoDialog(const TDesC& aPropertiesText, const TDesC& aImageCommentText, const TDesC& aFrameCommentText);
       
   129 
       
   130 protected:
       
   131 	void PreLayoutDynInitL();
       
   132 
       
   133 private:
       
   134 	const TDesC& iPropertiesText;
       
   135 	const TDesC& iImageCommentText;
       
   136 	const TDesC& iFrameCommentText;
       
   137 	};
       
   138 
       
   139 CFrameInfoDialog::CFrameInfoDialog(const TDesC& aPropertiesText, const TDesC& aImageCommentText, const TDesC& aFrameCommentText)
       
   140 	: iPropertiesText(aPropertiesText), iImageCommentText(aImageCommentText), iFrameCommentText(aFrameCommentText)
       
   141 	{
       
   142 	}
       
   143 
       
   144 void CFrameInfoDialog::PreLayoutDynInitL()
       
   145 	{
       
   146 	// Grab each Edwin and set the text.
       
   147 	CEikEdwin* page = STATIC_CAST(CEikEdwin*, Control(EFramePropertiesPage));
       
   148 	page->SetTextL(&iPropertiesText);
       
   149 
       
   150 	page = STATIC_CAST(CEikEdwin*, Control(EImageCommentsPage));
       
   151 	page->SetTextL(&iImageCommentText);
       
   152 
       
   153 	page = STATIC_CAST(CEikEdwin*, Control(EFrameCommentsPage));
       
   154 	page->SetTextL(&iFrameCommentText);
       
   155 	}
       
   156 
       
   157 //
       
   158 // CVideoWalker
       
   159 //
       
   160 
       
   161 class CVideoWalker : public CActive
       
   162 	{
       
   163 public:
       
   164 	static CVideoWalker* NewL(CVideoAppUi* aAppUi);
       
   165 	~CVideoWalker();
       
   166 	TRequestStatus& ActiveStatus();
       
   167 	void SelfComplete(TInt aError);
       
   168 protected:
       
   169 	CVideoWalker(CVideoAppUi* aAppUi);
       
   170 	// from CActive
       
   171 	void RunL();
       
   172 	void DoCancel();
       
   173 protected:
       
   174 	CVideoAppUi* const iAppUi; // not owned
       
   175 	};
       
   176 
       
   177 
       
   178 //
       
   179 //  CVideoAppUi
       
   180 //
       
   181 
       
   182 CVideoAppUi::CVideoAppUi():
       
   183 	iStreamBuffer(NULL,0,0)
       
   184 	{
       
   185 	iDecoderOptions = (CImageDecoder::EAllowGeneratedMask | CImageDecoder::EPreferFastDecode);
       
   186 	}
       
   187 
       
   188 void CVideoAppUi::ConstructL()
       
   189     {
       
   190 	CEikAppUi::ConstructL();
       
   191 
       
   192     iAppView = CVideoAppView::NewL(ClientRect());
       
   193 
       
   194 	::new(&iFrame) CWsBitmap(iEikonEnv->WsSession());
       
   195 	::new(&iMask) CWsBitmap(iEikonEnv->WsSession());
       
   196 
       
   197 	iRotator = CBitmapRotator::NewL();
       
   198 	iScaler = CBitmapScaler::NewL();
       
   199 
       
   200 	iBackgroundColor = KRgbWhite.Color16();
       
   201 
       
   202 	iAppView->SetBackgroundColor(TRgb::Color16(iBackgroundColor), ENoDrawNow);
       
   203 
       
   204 	iWalker = CVideoWalker::NewL(this);
       
   205 	User::LeaveIfError(iTimer.CreateLocal());
       
   206 	iStreamGen = CVideoWalker::NewL(this);
       
   207 	User::LeaveIfError(iStreamTimer.CreateLocal());
       
   208 
       
   209 	// Note iStreamSeed deliberated left as 0 to give consistent behaviour
       
   210 
       
   211 	iSaveInfo.iImageTypeUid = KImageTypeJPGUid;
       
   212 	iSaveInfo.iBpp = 6;
       
   213 	iSaveInfo.iColor = ETrue;
       
   214 	iSaveInfo.iQualityFactor = 40;
       
   215 	iSaveInfo.iSampling = 2;
       
   216 	
       
   217 	iUseNativeDisplayMode = ETrue;
       
   218 	
       
   219 	iScalingCoefficient = 1; // Full size
       
   220 	}
       
   221 
       
   222 CVideoAppUi::~CVideoAppUi()
       
   223 	{
       
   224 	Cancel();
       
   225 
       
   226 	iFrame.Reset();
       
   227 	iMask.Reset();
       
   228 	if (iAppView)
       
   229 		{
       
   230 		RemoveFromStack(iAppView);
       
   231 		delete iAppView;
       
   232 		}
       
   233 	delete iFrameImageData;
       
   234 	delete iLoadUtil;
       
   235 	delete iSaveUtil;
       
   236 	delete iRotator;
       
   237 	delete iScaler;
       
   238 	delete iWalker;
       
   239 	iTimer.Close();
       
   240 	iStreamTimer.Close();
       
   241 	delete iStreamGen;
       
   242 	User::Free(REINTERPRET_CAST(TAny*,CONST_CAST(TUint8*, iStreamBuffer.Ptr())));
       
   243 	delete iDir;
       
   244 	iOperations.Close();
       
   245 	}
       
   246 
       
   247 void CVideoAppUi::Cancel()
       
   248 	{
       
   249 	if (iWalker)
       
   250 		iWalker->Cancel(); // if active will callback on DoCancel()
       
   251 	if (iStreamGen)
       
   252 		iStreamGen->Cancel();
       
   253 	iState = EIdle;
       
   254 	}
       
   255 
       
   256 TKeyResponse CVideoAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
       
   257 	{
       
   258 	TKeyResponse ret = EKeyWasConsumed;
       
   259 
       
   260 	if (aType!=EEventKey)
       
   261 		return ret;
       
   262 
       
   263 	TUint code = aKeyEvent.iCode;
       
   264 
       
   265 	switch (code)
       
   266 		{
       
   267 	case EKeyLeftArrow:
       
   268 	case EKeyRightArrow:
       
   269 	case EKeyUpArrow:
       
   270 	case EKeyDownArrow:
       
   271 		{
       
   272 		if ( aKeyEvent.iModifiers & EModifierShift )
       
   273 			{
       
   274 			// update crop region
       
   275 			UpdateClippingRect(code);
       
   276 			}
       
   277 		else
       
   278 			{
       
   279 			TPoint moveBy;
       
   280 			switch (code)
       
   281 				{
       
   282 			case EKeyLeftArrow:
       
   283 				moveBy.SetXY(KButtonMoveIncr,0);
       
   284 				break;
       
   285 			case EKeyRightArrow:
       
   286 				moveBy.SetXY(-KButtonMoveIncr,0);
       
   287 				break;
       
   288 			case EKeyUpArrow:
       
   289 				moveBy.SetXY(0,KButtonMoveIncr);
       
   290 				break;
       
   291 			case EKeyDownArrow:
       
   292 				moveBy.SetXY(0,-KButtonMoveIncr);
       
   293 				break;
       
   294 				}
       
   295 			iAppView->MoveBy(moveBy);
       
   296 			}
       
   297 		}
       
   298 		break;
       
   299 	case EKeyEscape:
       
   300 		Cancel();
       
   301 		ASSERT(iState==EIdle);
       
   302 		iEikonEnv->BusyMsgCancel();
       
   303 		iEikonEnv->InfoMsg(_L("Cancelled"));
       
   304 		break;
       
   305 	default:
       
   306 		ret = EKeyWasNotConsumed;
       
   307 		break;
       
   308 		}
       
   309 	return ret;
       
   310 	}
       
   311 
       
   312 void CVideoAppUi::HandleCommandL(TInt aCommand)
       
   313 	{
       
   314 	switch (aCommand)
       
   315 		{
       
   316 	case EVideoCmdOpenFile:
       
   317 		OpenFileL(EFileTypeUnknown);
       
   318 		break;
       
   319 	case EVideoCmdOpenOtaFile:
       
   320 		OpenFileL(EFileTypeOta);
       
   321 		break;
       
   322 	case EVideoCmdOpenWbmpFile:
       
   323 		OpenFileL(EFileTypeWbmp);
       
   324 		break;
       
   325 	case EVideoCmdOpenFolder:
       
   326 		OpenFolderL();
       
   327 		break;
       
   328 	case EVideoCmdSaveAs:
       
   329 		SaveAsL();
       
   330 		break;
       
   331 	case EVideoCmdMask:
       
   332 		iDisableMask = ! iDisableMask;
       
   333 		if (iDisableMask)
       
   334 			{
       
   335 			iEikonEnv->InfoMsg(_L("Mask reset"));
       
   336 			}
       
   337 		else
       
   338 			{
       
   339 			iEikonEnv->InfoMsg(_L("Mask enabled"));
       
   340 			}
       
   341 		if (iMask.Handle() && iDisableMask)
       
   342 			{
       
   343 			iMask.Reset();
       
   344 			}
       
   345 		else if (iMask.Handle()==0 && !iDisableMask)
       
   346 			{
       
   347 			User::LeaveIfError(iMask.Create(TSize(0,0),EGray256));
       
   348 			}
       
   349 		break;
       
   350 	case EVideoCmdZoomIn:
       
   351 		iZoomFactor++;
       
   352 		if (iZoomFactor > KVideoMaxZoomFactor)
       
   353 			iZoomFactor = KVideoMinZoomFactor;
       
   354 		if ( iUseExtensions )
       
   355 			{
       
   356 			iScalingCoefficient = iZoomFactor - 1;
       
   357 			}
       
   358 		LoadFileL();
       
   359 		break;
       
   360 	case EVideoCmdZoomOut:
       
   361 		iZoomFactor--;
       
   362 		if (iZoomFactor < KVideoMinZoomFactor)
       
   363 			iZoomFactor = KVideoMaxZoomFactor;
       
   364 		if ( iUseExtensions )
       
   365 			{
       
   366 			iScalingCoefficient = iZoomFactor - 1;
       
   367 			}
       
   368 		LoadFileL();
       
   369 		break;
       
   370 	case EVideoCmdFineZoomIn:
       
   371 		ZoomFrameL(ETrue);
       
   372 		break;
       
   373 	case EVideoCmdFineZoomOut:
       
   374 		ZoomFrameL(EFalse);
       
   375 		break;
       
   376 	case EVideoCmdDisplayMode:
       
   377 		DisplayModeL();
       
   378 		break;
       
   379 	case EVideoCmdBackgroundColor:
       
   380 		BackgroundColorL();
       
   381 		break;
       
   382 	case EVideoCmdPlay:
       
   383 		if (iState == EPlaying || iState == ELoading)
       
   384 			iEikonEnv->InfoMsg(_L("Busy..."));
       
   385 		else
       
   386 			PlayClipL();
       
   387 		break;
       
   388 	case EVideoCmdStream:
       
   389 		StreamPlayL(EFileTypeUnknown);
       
   390 		break;
       
   391 	case EVideoCmdOtaStream:
       
   392 		StreamPlayL(EFileTypeOta);
       
   393 		break;
       
   394 	case EVideoCmdWbmpStream:
       
   395 		StreamPlayL(EFileTypeWbmp);
       
   396 		break;
       
   397 	case EVideoCmdDecoderOptions:
       
   398 		DecoderOptionsL();
       
   399 		break;
       
   400 	case EVideoCmdExtension:
       
   401 		ExtensionOptionsL();
       
   402 		break;
       
   403 	case EVideoCmdUseExtensions:
       
   404 	    iUseExtensions = !iUseExtensions;
       
   405 		break;
       
   406 	case EVideoCmdRefresh:
       
   407 		LoadFileL();
       
   408 		break;
       
   409 	case EVideoCmdExtractFrame:
       
   410 		ExtractFrameL();
       
   411 		break;
       
   412 	case EVideoCmdExtractStreamedFrame:
       
   413 		StreamPlayL(EFileTypeUnknown, ETrue);
       
   414 		break;
       
   415 	case EVideoCmdFrameInfo:
       
   416 		FrameInfoL(); 
       
   417 		break;
       
   418 	case EVideoCmdRotateClockwise:
       
   419 		FrameRotateL(ETrue);
       
   420 		break;
       
   421 	case EVideoCmdRotateAntiClockwise:
       
   422 		FrameRotateL(EFalse);
       
   423 		break;
       
   424 	case EVideoCmdMirrorHorizontalAxis:
       
   425 		FrameMirrorL(ETrue);
       
   426 		break;
       
   427 	case EVideoCmdMirrorVerticalAxis:
       
   428 		FrameMirrorL(EFalse);
       
   429 		break;
       
   430 	case EEikCmdExit:
       
   431 		Exit();
       
   432 		break;
       
   433 	default:
       
   434 		iEikonEnv->InfoMsg(R_VIDEO_UNKNOWN);
       
   435 		break;
       
   436 		}
       
   437 	}
       
   438 
       
   439 TBool CVideoAppUi::ProcessCommandParametersL(TApaCommand aCommand,TFileName& aDocumentName,const TDesC8& aTail)
       
   440 	{
       
   441 	switch (aCommand)
       
   442 		{
       
   443 	case EApaCommandOpen:
       
   444 		iLoadFileName = aDocumentName;
       
   445 		break;
       
   446 	case EApaCommandCreate:
       
   447 	case EApaCommandRun:
       
   448 		break;
       
   449 	case EApaCommandBackground:
       
   450 	default:
       
   451 		break;
       
   452 		}
       
   453 
       
   454 	return CEikAppUi::ProcessCommandParametersL(aCommand,aDocumentName,aTail);
       
   455 	}
       
   456 
       
   457 void CVideoAppUi::OpenFileL(TFileType aFileType)
       
   458 	{
       
   459 	if (iLoadFileName.Length() < KShortestPossiblePath)
       
   460 		iLoadFileName = KDefPath;
       
   461 
       
   462 	Cancel();
       
   463 	delete iLoadUtil; iLoadUtil = NULL;
       
   464 
       
   465 	TInt title;
       
   466 	switch (aFileType)
       
   467 		{
       
   468 		default:
       
   469 			title = 0;
       
   470 			break;
       
   471 		case EFileTypeWbmp:
       
   472 			title = R_VIDEO_OPEN_WBMP;
       
   473 			break;
       
   474 		case EFileTypeOta:
       
   475 			title = R_VIDEO_OPEN_OTA;
       
   476 			break;
       
   477 		}
       
   478 	CEikDialog* dialog = new(ELeave) CEikFileOpenDialog(&iLoadFileName, title);
       
   479 	if (!dialog->ExecuteLD(R_EIK_DIALOG_FILE_OPEN))
       
   480 		return;
       
   481 
       
   482 	iLastFileType = aFileType;
       
   483 	iOpeningFolder = EFalse;
       
   484 	LoadFileL();
       
   485 	}
       
   486 
       
   487 void CVideoAppUi::OpenFolderL()
       
   488 	{
       
   489 	Cancel();
       
   490 
       
   491 	if (iLoadFileName.Length() < KShortestPossiblePath)
       
   492 		iLoadFileName = KDefPath;
       
   493 
       
   494 	TFileName folderName = iLoadFileName;
       
   495 
       
   496 	CEikDialog* dialog = new(ELeave) CEikFileOpenDialog(&folderName, R_VIDEO_SELECT_FOLDER);
       
   497 	if (!dialog->ExecuteLD(R_EIK_DIALOG_FILE_OPEN))
       
   498 		return;
       
   499 
       
   500 	iLastFileType = EFileTypeUnknown;
       
   501 	iOpeningFolder = ETrue;
       
   502 	LoadFolderL(folderName);
       
   503 	}
       
   504 	
       
   505 void CVideoAppUi::DecoderOptionsL()
       
   506 	{
       
   507 	CEikDialog* dialog = new(ELeave) CDecoderOptionsDialog(iDecoderOptions);
       
   508 	dialog->ExecuteLD(R_VIDEO_DECODER_OPTIONS_DIALOG);
       
   509 	}
       
   510 
       
   511 void CVideoAppUi::ExtensionOptionsL()
       
   512 	{
       
   513 	CEikDialog* dialog = new(ELeave) CExtensionOptionsDialog(iClippingRect,
       
   514 															 iOperations,
       
   515 															 iScalingCoefficient,
       
   516 															 iScalingQuality,
       
   517 															 iLockAspectRatio);
       
   518 	TInt buttonPressed = dialog->ExecuteLD(R_VIDEO_DECODER_EXTENSION_DIALOG);
       
   519 	if ( buttonPressed == EEikBidOk && iLoadUtil )
       
   520 		{
       
   521 		// re-convert the image e.g. if clipping rect has changed
       
   522 		LoadFileL();
       
   523 		}
       
   524 	}
       
   525 	
       
   526 void CVideoAppUi::LoadFileL()
       
   527 	{
       
   528 	Cancel();
       
   529 	if ( !iLoadUtil )
       
   530 		{
       
   531 		if (iLoadFileName.Length() < KShortestPossiblePath)
       
   532 			return;
       
   533 
       
   534 		TUid format;
       
   535 		switch (iLastFileType)
       
   536 			{
       
   537 			case EFileTypeOta:
       
   538 				format = KImageTypeOTAUid;
       
   539 				break;
       
   540 			case EFileTypeWbmp:
       
   541 				format = KImageTypeWBMPUid;
       
   542 				break;
       
   543 			default:
       
   544 				format = KNullUid;
       
   545 			}
       
   546 
       
   547 		TRAPD(error,iLoadUtil = CImageDecoder::FileNewL(iCoeEnv->FsSession(), iLoadFileName, CImageDecoder::TOptions(iDecoderOptions), format));
       
   548 		if (error!=KErrNone)
       
   549 			{
       
   550 			iEikonEnv->HandleError(error);
       
   551 			iAppView->Reset(EDrawNow); // ensure we redraw whole screen - replace previous cross if required
       
   552 			return;
       
   553 			}
       
   554 		}
       
   555 
       
   556 	HandleNewlyOpenedImageL();
       
   557 
       
   558 	StartFrameOpen(EPlaying);
       
   559 	}
       
   560 
       
   561 void CVideoAppUi::LoadFolderL(const TDesC& aDirName)
       
   562 	{
       
   563 	delete iDir; iDir = NULL;
       
   564 
       
   565 	TParsePtrC parse(aDirName);
       
   566 	iDirName = parse.DriveAndPath();
       
   567 
       
   568 	iEikonEnv->FsSession().GetDir(iDirName, 0, 0, iDir);
       
   569 
       
   570 	if (iDir->Count()==0)
       
   571 		{
       
   572 		iEikonEnv->InfoMsg(R_VIDEO_EMPTY_FOLDER);
       
   573 		return;
       
   574 		}
       
   575 
       
   576 	iDirIndex = 0; 
       
   577 	OpenNextFolderEntry();
       
   578 	}
       
   579 
       
   580 void CVideoAppUi::OpenNextFolderEntry()
       
   581 	{
       
   582 	if (iDirIndex >= iDir->Count())
       
   583 		{
       
   584 		// end of processing - so stop
       
   585 		iEikonEnv->BusyMsgCancel();
       
   586 		Cancel(); 
       
   587 		iState = EIdle;
       
   588 		return;
       
   589 		}
       
   590 
       
   591 	const TEntry& entry = (*iDir)[iDirIndex];
       
   592 	iLoadFileName.Copy(iDirName);
       
   593 	iLoadFileName.Append(entry.iName);
       
   594 
       
   595 	delete iLoadUtil; 
       
   596 	iLoadUtil = NULL;
       
   597 	TRAPD(error, LoadFileL());
       
   598 
       
   599 	if (error==KErrNone)
       
   600 		iEikonEnv->InfoMsg(entry.iName);
       
   601 	else
       
   602 		{
       
   603 		TBuf<64> errorMsg;
       
   604 		errorMsg.Format(_L("%S - error %d"), &entry.iName, error);
       
   605 		iEikonEnv->InfoMsg(errorMsg);
       
   606 		LoadFolderWait();
       
   607 		}
       
   608 	}
       
   609 
       
   610 void CVideoAppUi::DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane)
       
   611 	{
       
   612 	if(aResourceId==R_VIDEO_CLIP_MENU)
       
   613 		{
       
   614 		if (iLoadUtil==NULL || iState!=EIdle) // nothing open or we are busy
       
   615 			aMenuPane->SetItemDimmed(EVideoCmdPlay,ETrue);
       
   616 		}
       
   617 	else if (aResourceId==R_VIDEO_OPERATE_MENU)
       
   618 		{
       
   619 		if (iLoadUtil==NULL || iState!=EIdle || iUseExtensions)
       
   620 			{
       
   621 			// nothing open or we are busy
       
   622 			aMenuPane->SetItemDimmed(EVideoCmdRotateClockwise,ETrue);
       
   623 			aMenuPane->SetItemDimmed(EVideoCmdRotateAntiClockwise,ETrue);
       
   624 			aMenuPane->SetItemDimmed(EVideoCmdMirrorHorizontalAxis,ETrue);
       
   625 			aMenuPane->SetItemDimmed(EVideoCmdMirrorVerticalAxis,ETrue);
       
   626 			}
       
   627 		}
       
   628 	else if (aResourceId==R_VIDEO_ZOOM_MENU)
       
   629 		{
       
   630 		if (iLoadUtil==NULL || iState!=EIdle || iUseExtensions)
       
   631 			{
       
   632 			aMenuPane->SetItemDimmed(EVideoCmdZoomIn,ETrue);
       
   633 			aMenuPane->SetItemDimmed(EVideoCmdZoomOut,ETrue);
       
   634 			}
       
   635 		}
       
   636 	else if ( aResourceId==R_VIDEO_VIEW_MENU )
       
   637 		{
       
   638 		aMenuPane->SetItemButtonState(EVideoCmdUseExtensions,(iUseExtensions) ? EEikMenuItemSymbolOn : 0);
       
   639 		}
       
   640 	}
       
   641 
       
   642 TBool CVideoAppUi::CheckHotKeyNotDimmedL(TInt aCommandId)
       
   643 	{
       
   644 	TInt result = ETrue;
       
   645 	switch (aCommandId)
       
   646 		{
       
   647 		case EVideoCmdPlay:
       
   648 		case EVideoCmdRotateClockwise:
       
   649 		case EVideoCmdRotateAntiClockwise:
       
   650 		case EVideoCmdFineZoomIn:
       
   651 		case EVideoCmdFineZoomOut:
       
   652 		case EVideoCmdMirrorHorizontalAxis:
       
   653 		case EVideoCmdMirrorVerticalAxis:
       
   654 			if (iLoadUtil==NULL || iState!=EIdle || iUseExtensions)
       
   655 				result = EFalse;
       
   656 			break;
       
   657 		default:
       
   658 			// do nothing
       
   659 			break;
       
   660 		}
       
   661 	return result;
       
   662 	}
       
   663 
       
   664 void CVideoAppUi::LoadFolderWait()
       
   665 	{
       
   666 	ASSERT(!iWalker->IsActive()); // if we get here, should not be doing anything
       
   667 	
       
   668 	iTimer.After(iWalker->ActiveStatus(), KDefaultFolderDelay);
       
   669 	iState = EFolderWait;
       
   670 	}
       
   671 
       
   672 void CVideoAppUi::HandleNewlyOpenedImageL()
       
   673 	{
       
   674 	ASSERT(iLoadUtil); // should have already been opened
       
   675 
       
   676 	TFrameInfo frameInfo = iLoadUtil->FrameInfo(0);
       
   677 
       
   678 	// jf 3/12/01. Assume frame 0 gives the main image characteristics
       
   679 	iOverallSize = frameInfo.iOverallSizeInPixels;
       
   680 	if (iOverallSize.iWidth==0 || iOverallSize.iHeight==0)
       
   681 		{
       
   682 		iOverallSize = frameInfo.iFrameCoordsInPixels.Size();
       
   683 		if (iOverallSize.iWidth==0 || iOverallSize.iHeight==0)
       
   684 			{
       
   685 			iEikonEnv->InfoMsg(_L("Invalid image dimensions."));
       
   686 			User::Leave(KErrCorrupt);
       
   687 			}
       
   688 		}	
       
   689 	
       
   690 	iAnimating = (frameInfo.iDelay != TTimeIntervalMicroSeconds(0) || IsMngImage(iLoadUtil));
       
   691 
       
   692 	iFrameNumber = 0;
       
   693 
       
   694 	iTime.HomeTime();
       
   695 	}
       
   696 
       
   697 void CVideoAppUi::ExtractFrameL()
       
   698 	{
       
   699 	if (iLoadFileName.Length() < KShortestPossiblePath)
       
   700 		return;
       
   701 
       
   702 	ASSERT(iLoadUtil);
       
   703 
       
   704 	Cancel();
       
   705 
       
   706 	TInt frameCount = iLoadUtil->FrameCount();
       
   707 
       
   708 	if (iFrameNumber >= frameCount)
       
   709 		iFrameNumber = 0;
       
   710 
       
   711 	CEikDialog* dialog = new(ELeave) CVideoCurrentFrameDialog(iFrameNumber,frameCount);
       
   712 	if (!dialog->ExecuteLD(R_VIDEO_FRAME_DIALOG))
       
   713 		return;
       
   714 
       
   715 	StartFrameOpen(ELoading);
       
   716 	}
       
   717 
       
   718 void CVideoAppUi::StartFrameOpen(TState aNextState, TBool aSizeFrame)
       
   719 	{
       
   720 	TRAPD(error, DoStartFrameOpenL(aSizeFrame));
       
   721 	if (error!=KErrNone)
       
   722 		iWalker->SelfComplete(error);
       
   723 	iState = aNextState; // what ever happens we go to next state, and will handle any error there
       
   724 	}
       
   725 
       
   726 void CVideoAppUi::DoStartFrameOpenL(TBool aSizeFrame)
       
   727 	{
       
   728 	ASSERT(iLoadUtil); // should be true by now
       
   729 	ASSERT(!iWalker->IsActive()); // we are going to use it
       
   730 
       
   731 	ASSERT(iFrameNumber>=0 && iFrameNumber<iLoadUtil->FrameCount());
       
   732 
       
   733 	// Set up extensions
       
   734 	if ( iClippingRect.IsEmpty() )
       
   735 		{
       
   736 		TRAPD(err, iLoadUtil->SetClippingRectL(NULL));
       
   737 		// Plugin may not support the call at all
       
   738 		if(err != KErrNone && err != KErrNotSupported)
       
   739 			{
       
   740 			User::Leave(err);
       
   741 			}
       
   742 		}
       
   743 	else
       
   744 		{
       
   745 		TRAPD(err,iLoadUtil->SetClippingRectL((iUseExtensions) ? &iClippingRect : NULL ));
       
   746 		// Plugin may not support the call at all
       
   747 		if(err == KErrNotSupported)
       
   748 			{
       
   749 			iEikonEnv->InfoMsg(_L("Clipping Not Supported using this codec."));
       
   750 			}
       
   751 		}
       
   752 	
       
   753 	TImageConvScaler* scaler = NULL;
       
   754 	TRAPD(err,scaler = iLoadUtil->ScalerL());
       
   755 	if ( err == KErrNone )
       
   756 		{
       
   757 		scaler->SetScalingL( (iUseExtensions) ? iScalingCoefficient : -1 , iScalingQuality);	
       
   758 		}
       
   759 	else if ( iScalingCoefficient != -1 && err == KErrNotSupported )
       
   760 		{
       
   761 		iEikonEnv->InfoMsg(_L("Scaler extension Not Supported using this codec."));
       
   762 		}
       
   763 		
       
   764 	
       
   765 	if ( iOperations.Count() )
       
   766 		{
       
   767 		TImageConvOperation* operation = NULL;
       
   768 		TRAPD(err,operation = iLoadUtil->OperationL());
       
   769 		if ( err == KErrNone )
       
   770 			{
       
   771 			operation->ClearOperationStack();
       
   772 			
       
   773 			if ( iUseExtensions)
       
   774 				{
       
   775 				for ( TInt i = 0; i < iOperations.Count(); i++)
       
   776 					{
       
   777 					operation->AddOperationL(static_cast<TImageConvOperation::TOperation>(iOperations[i]));
       
   778 					}
       
   779 				}
       
   780 			}
       
   781 		else if ( err == KErrNotSupported )
       
   782 			{
       
   783 			iEikonEnv->InfoMsg(_L("Operations Not Supported using this codec."));
       
   784 			}
       
   785 		}
       
   786 
       
   787 	if (aSizeFrame)
       
   788 		{
       
   789 		TFrameInfo frameInfo = iLoadUtil->FrameInfo(iFrameNumber);
       
   790 
       
   791 		if (iFrame.Handle() == 0) // Only create the bitmap if we haven't done it already.
       
   792 			{
       
   793 			if ( !iUseNativeDisplayMode && (frameInfo.iFlags & TFrameInfo::ECanDither) )
       
   794 				User::LeaveIfError(iFrame.Create(TSize(0,0),iAppView->DisplayMode())); 
       
   795 			else
       
   796 				User::LeaveIfError(iFrame.Create(TSize(0,0),frameInfo.iFrameDisplayMode)); 
       
   797 			}
       
   798 
       
   799 		// with 16MA and 16MAP we don't use the mask anymore, this since the introduction
       
   800 		// with CR894 & CR1111 of alpha channel support in PNG decoding
       
   801 
       
   802 		if (frameInfo.iFlags & TFrameInfo::ETransparencyPossible && !iDisableMask
       
   803 			 && iAppView->DisplayMode() != EColor16MA && iAppView->DisplayMode() != EColor16MAP )
       
   804 			{
       
   805 			if (iMask.Handle() == 0)
       
   806 				User::LeaveIfError(iMask.Create(TSize(0,0),EGray256));
       
   807 			}
       
   808 		else
       
   809 			{
       
   810 			if (iMask.Handle())
       
   811 				iMask.Reset();
       
   812 			}
       
   813 
       
   814 		
       
   815 		SetFrameSizeAndPosL(frameInfo.iFrameCoordsInPixels,frameInfo.iOverallSizeInPixels); 
       
   816 		}
       
   817 
       
   818 	ASSERT(iDisableMask && iMask.Handle()==0 || !iDisableMask); // iDisableMask -> iMask.Handle()==0
       
   819 	ASSERT(iMask.Handle()==0 || iFrame.SizeInPixels()==iMask.SizeInPixels()); // if mask must be same size
       
   820 	
       
   821 	// DEF090667: T: SetDisplayMode causes another file to be opened with wrong size
       
   822 	if(iFrameNumber == 0)
       
   823 		{
       
   824 		iAppView->Reset(ENoDrawNow);
       
   825 		}
       
   826 
       
   827 	if (iMask.Handle())
       
   828 		iLoadUtil->Convert(&(iWalker->ActiveStatus()),iFrame,iMask,iFrameNumber); 
       
   829 	else
       
   830 		iLoadUtil->Convert(&(iWalker->ActiveStatus()),iFrame,iFrameNumber); 
       
   831 
       
   832 	iViewResized = EFalse;
       
   833 	}
       
   834 	
       
   835 TBool CVideoAppUi::ExtensionIsSetup()
       
   836 	{
       
   837 	return ( ( !iClippingRect.IsEmpty() ) || Abs(iScalingCoefficient) > 1 || iOperations.Count() );
       
   838 	}
       
   839 
       
   840 void CVideoAppUi::PlayClipL()
       
   841 	{
       
   842 	iFrameNumber = 0;
       
   843 	iTime.HomeTime();
       
   844 
       
   845 	StartFrameOpen(EPlaying);
       
   846 	}
       
   847 
       
   848 void CVideoAppUi::SaveAsL()
       
   849 	{
       
   850 	if (iSaveFileName.Length() < KShortestPossiblePath)
       
   851 		iSaveFileName = KDefPath;
       
   852 
       
   853 	Cancel();
       
   854 
       
   855 	CEikDialog* dialog = new(ELeave) CVideoSaveAsDialog(&iSaveFileName,iSaveInfo,iEncodeOperations,iCreateThumbnail,iSaveAsEXIF);
       
   856 	if (!dialog->ExecuteLD(R_VIDEO_FILE_SAVEAS_DIALOG))
       
   857 		return;
       
   858 	iEikonEnv->FsSession().Delete(iSaveFileName);
       
   859 
       
   860 	delete iFrameImageData; iFrameImageData = NULL;
       
   861 
       
   862 	const TUid imageType = iSaveInfo.iImageTypeUid;
       
   863 	TImageDataBlock *imageData = NULL;
       
   864 	TFrameDataBlock *frameData = NULL;
       
   865 
       
   866 	if(imageType == KImageTypeBMPUid)
       
   867 		{
       
   868 		imageData = new (ELeave) TBmpImageData;
       
   869 		TBmpImageData* data = STATIC_CAST(TBmpImageData*, imageData);
       
   870 		switch (iSaveInfo.iBpp)
       
   871 			{
       
   872 		case 0:		data->iBitsPerPixel = 1; break;
       
   873 		case 2:		data->iBitsPerPixel = 4; break;
       
   874 		case 3:		data->iBitsPerPixel = 8; break;
       
   875 		case 6:		data->iBitsPerPixel = 24; break;
       
   876 		default:	ASSERT(EFalse);			break;
       
   877 			}
       
   878 		}
       
   879 	else if(imageType == KImageTypeGIFUid)
       
   880 		{// gif does not have encoding options
       
   881 		}
       
   882 	else if(imageType == KImageTypeJPGUid)
       
   883 		{
       
   884 		imageData = new (ELeave) TJpegImageData;
       
   885 		TJpegImageData* data = STATIC_CAST(TJpegImageData*, imageData);
       
   886 		if (!iSaveInfo.iColor)
       
   887 			data->iSampleScheme = TJpegImageData::EMonochrome;
       
   888 		else
       
   889 			data->iSampleScheme = TJpegImageData::TColorSampling(3 - iSaveInfo.iSampling);
       
   890 		data->iQualityFactor = iSaveInfo.iQualityFactor;
       
   891 		}
       
   892 	else if(imageType == KImageTypeMBMUid)
       
   893 		{
       
   894 		frameData = new (ELeave) TMbmEncodeData;
       
   895 		TMbmEncodeData* data = STATIC_CAST(TMbmEncodeData*, frameData);
       
   896 		switch (iSaveInfo.iBpp)
       
   897 			{
       
   898 		case 0:		data->iDisplayMode = EGray2;		break;
       
   899 		case 1:		data->iDisplayMode = EGray4;		break;
       
   900 		case 2:		data->iDisplayMode = iSaveInfo.iColor ? EColor16 : EGray16;	break;
       
   901 		case 3:		data->iDisplayMode = iSaveInfo.iColor ? EColor256 : EGray256;	break;
       
   902 		case 4:		data->iDisplayMode = EColor4K;		break;
       
   903 		case 5:		data->iDisplayMode = EColor64K;	break;
       
   904 		case 6:		data->iDisplayMode = EColor16M;	break;
       
   905 		case 7:		data->iDisplayMode = EColor16MU;	break;		
       
   906 		default:	ASSERT(EFalse);	break;
       
   907 			}
       
   908 		}
       
   909 	else if(imageType == KImageTypePNGUid)
       
   910 		{
       
   911 		frameData = new (ELeave) TPngEncodeData;
       
   912 		TPngEncodeData* data = STATIC_CAST(TPngEncodeData*, frameData);
       
   913 		// bpp
       
   914 		switch (iSaveInfo.iBpp)
       
   915 			{
       
   916 			case 0:		data->iBitsPerPixel = 1; break;		// 1 bpp 
       
   917 			case 1:		data->iBitsPerPixel = 2; break;		// 2 bpp
       
   918 			case 2:		data->iBitsPerPixel = 4; break;		// 4 bpp
       
   919 			case 3:		data->iBitsPerPixel = 8; break;		// 8 bpp
       
   920 			case 6:		data->iBitsPerPixel = 24; break;	// 24 bpp
       
   921 			default:	ASSERT(EFalse);	break;				// unsupported bit depth
       
   922 			}
       
   923 		// colour or grayscale?
       
   924 		data->iColor = iSaveInfo.iColor;
       
   925 		// compression level
       
   926 		switch (iSaveInfo.iCompression)
       
   927 			{
       
   928 			case 0:
       
   929 				data->iLevel = TPngEncodeData::EDefaultCompression;
       
   930 				break;
       
   931 			case 1:
       
   932 				data->iLevel = TPngEncodeData::ENoCompression;
       
   933 				break;
       
   934 			case 2:
       
   935 				data->iLevel = TPngEncodeData::EBestSpeed;
       
   936 				break;
       
   937 			case 3:
       
   938 				data->iLevel = TPngEncodeData::EBestCompression;
       
   939 				break;
       
   940 			default:			// unsupported compression
       
   941 				ASSERT(EFalse);
       
   942 				break;		
       
   943 			}
       
   944 		}
       
   945 	else
       
   946 		{
       
   947 		//custom encoder
       
   948 		}
       
   949 
       
   950 	if (frameData)
       
   951 		CleanupStack::PushL(frameData);
       
   952 
       
   953 	if (imageData)
       
   954 		CleanupStack::PushL(imageData);
       
   955 
       
   956 	delete iSaveUtil; iSaveUtil = NULL;
       
   957 	if ( iSaveAsEXIF && (imageType == KImageTypeJPGUid) )
       
   958 		{
       
   959 		iSaveUtil = CJPEGExifEncoder::FileNewL(iCoeEnv->FsSession(), iSaveFileName, CImageEncoder::EOptionNone, imageType);
       
   960 		// force creation of metadata - this will cause save as EXIF rather than JFIF
       
   961 	    MExifMetadataWriter* metaData=static_cast<CJPEGExifEncoder*>(iSaveUtil)->ExifMetadata(); 
       
   962 		}
       
   963 		else
       
   964 		{
       
   965 		iSaveUtil = CImageEncoder::FileNewL(iCoeEnv->FsSession(), iSaveFileName, CImageEncoder::EOptionNone, imageType);		
       
   966 		}
       
   967 
       
   968 
       
   969 	ASSERT(iFrameImageData==NULL); // deleted above
       
   970 	if (imageData)
       
   971 		{
       
   972 		iFrameImageData = CFrameImageData::NewL();
       
   973 
       
   974 		User::LeaveIfError(iFrameImageData->AppendImageData(imageData));
       
   975 		CleanupStack::Pop(); // imageData - ownership now passed to iFrameImageData
       
   976 		}
       
   977 
       
   978 	if (frameData)
       
   979 		{
       
   980 		if (iFrameImageData == NULL)
       
   981 			iFrameImageData = CFrameImageData::NewL();
       
   982 
       
   983 		User::LeaveIfError(iFrameImageData->AppendFrameData(frameData));
       
   984 		CleanupStack::Pop(); // frameData - ownership now passed to iFrameImageData
       
   985 		}
       
   986 		
       
   987 	if (iCreateThumbnail)
       
   988 	{
       
   989 		iSaveUtil->SetThumbnail(iCreateThumbnail);
       
   990 	}
       
   991 		
       
   992 	if ( iEncodeOperations.Count() )
       
   993 		{
       
   994 		TImageConvOperation* operation = NULL;
       
   995 		TRAPD(err, operation = iSaveUtil->OperationL());
       
   996 		if ( err == KErrNone )
       
   997 			{
       
   998 			operation->ClearOperationStack();
       
   999 			
       
  1000 			for ( TInt i = 0; i < iEncodeOperations.Count(); i++)
       
  1001 				{
       
  1002 				operation->AddOperationL(static_cast<TImageConvOperation::TOperation>(iEncodeOperations[i]));
       
  1003 				}
       
  1004 			}
       
  1005 		}
       
  1006 
       
  1007 	StartFrameSave();
       
  1008 	}
       
  1009 
       
  1010 void CVideoAppUi::DisplayModeL()
       
  1011 	{
       
  1012 	Cancel();
       
  1013 	TDisplayMode displayMode = iAppView->DisplayMode();
       
  1014 	CEikDialog* dialog = new(ELeave) CVideoDisplayModeDialog(displayMode,iUseNativeDisplayMode);
       
  1015 	if (dialog->ExecuteLD(R_VIDEO_DISPLAY_MODE_DIALOG))
       
  1016 		{
       
  1017 		if ( iUseNativeDisplayMode && iLoadUtil )
       
  1018 			{
       
  1019 			TFrameInfo frameInfo = iLoadUtil->FrameInfo(0);
       
  1020 			displayMode = frameInfo.iFrameDisplayMode;
       
  1021 			}
       
  1022 
       
  1023 		iAppView->SetDisplayModeL(displayMode, &iFrame);
       
  1024 		}
       
  1025 	}
       
  1026 
       
  1027 void CVideoAppUi::BackgroundColorL()
       
  1028 	{
       
  1029 	Cancel();
       
  1030 	TInt backgroundColor = iBackgroundColor;
       
  1031 	TBool override = iOverrideBackgroundColor;
       
  1032 	CEikDialog* dialog = new(ELeave) CVideoBackgroundColorDialog(backgroundColor, override);
       
  1033 	if (dialog->ExecuteLD(R_VIDEO_BACKGROUND_COLOR_DIALOG))
       
  1034 		{
       
  1035 		iBackgroundColor = backgroundColor;
       
  1036 		iOverrideBackgroundColor = override;
       
  1037 		if (iOverrideBackgroundColor)
       
  1038 			{
       
  1039 			iAppView->SetBackgroundColor(TRgb::Color16(iBackgroundColor), ENoDrawNow);
       
  1040 			iAppView->Clear(ENoDrawNow);
       
  1041 			//redraw without reloading
       
  1042 			if (iMask.Handle()==0)
       
  1043 				iAppView->DrawImage(&iFrame, iOffset, EDrawNow);
       
  1044 			else
       
  1045 				iAppView->DrawImage(&iFrame, &iMask, iOffset, EDrawNow);
       
  1046 			}
       
  1047 		}
       
  1048 	}
       
  1049 
       
  1050 void CVideoAppUi::StreamPlayL(TFileType aFileType, TBool aMultiFrameStreaming)
       
  1051 	{
       
  1052 	Cancel();
       
  1053 	iLastFileType = aFileType;
       
  1054 	iMultiFrameStreaming = aMultiFrameStreaming;
       
  1055 
       
  1056 	if (iLoadFileName.Length() < 4)
       
  1057 		iLoadFileName = KDefPath;
       
  1058 	CEikDialog* dialog = new(ELeave) CEikFileOpenDialog(&iLoadFileName);
       
  1059 	if (!dialog->ExecuteLD(R_EIK_DIALOG_FILE_OPEN))
       
  1060 		return;
       
  1061 
       
  1062 	delete iLoadUtil; iLoadUtil = NULL;
       
  1063 
       
  1064 	User::Free(REINTERPRET_CAST(TAny*,CONST_CAST(TUint8*, iStreamBuffer.Ptr())));
       
  1065 	iStreamBuffer.Set(NULL, 0, 0);
       
  1066 
       
  1067 	RFile file;
       
  1068 	User::LeaveIfError(file.Open(iEikonEnv->FsSession(), iLoadFileName, EFileShareReadersOnly|EFileStream|EFileRead));
       
  1069 	CleanupClosePushL(file);
       
  1070 	TInt fileSize;
       
  1071 	User::LeaveIfError(file.Size(fileSize));
       
  1072 	iStreamBuffer.Set(STATIC_CAST(TUint8 *, User::AllocL(fileSize)), 0, fileSize);
       
  1073 	User::LeaveIfError(file.Read(iStreamBuffer));
       
  1074 	CleanupStack::PopAndDestroy(); // file
       
  1075 
       
  1076 	iEikonEnv->BusyMsgL(_L("Busy..."));
       
  1077 
       
  1078 	// NB. State machine assumes no leaves after this point
       
  1079 
       
  1080 	ASSERT(!iStreamGen->IsActive()); // no async behav should be going on at this point
       
  1081 	ASSERT(!iWalker->IsActive());
       
  1082 
       
  1083 	// initialize the buffer
       
  1084 	iStreamBuffer.SetLength(0); // data is in buffer, and we increase length to simulate data arriving
       
  1085 	User::LeaveIfError(ExtendStreamBuffer());
       
  1086 
       
  1087 	iState = EStreamOpening;
       
  1088 	}
       
  1089 
       
  1090 TInt CVideoAppUi::ExtendStreamBuffer()
       
  1091 	{
       
  1092 //	ASSERT(iStreamBuffer.Length()<iStreamBuffer.MaxLength()); // assumed we don't call when no more streaming to do
       
  1093 
       
  1094 	// We CAN get called when there's no more data if the decoders have failed
       
  1095 	// to detect end-of-data - e.g. when the input file's header contains a length
       
  1096 	// greater than the file size - so return KErrUnderflow if this happens
       
  1097 	ASSERT(iStreamBuffer.Length() <= iStreamBuffer.MaxLength()); 
       
  1098 	if (iStreamBuffer.Length() == iStreamBuffer.MaxLength())
       
  1099 		return KErrUnderflow;
       
  1100 
       
  1101 	// 95% change of 128 bytes - else random 1..128
       
  1102 	TInt chance = Math::Rand(iStreamSeed) % 100;
       
  1103 	TInt increment;
       
  1104 	if (chance < 95)
       
  1105 		increment = 128;
       
  1106 	else
       
  1107 		increment = Math::Rand(iStreamSeed) % 127 + 1; // 1 .. 128
       
  1108 	TInt newSize = Min(iStreamBuffer.Length()+increment, iStreamBuffer.MaxLength());
       
  1109 	iStreamBuffer.SetLength(newSize);
       
  1110 
       
  1111 	// random time is 99% chance between 0 and 1/20s, with remainder between 0 and 5s
       
  1112 	chance = Math::Rand(iStreamSeed) % 100;
       
  1113 	TInt waitTime;
       
  1114 	if (chance>=99)
       
  1115 		waitTime = Math::Rand(iStreamSeed) % 5000000;
       
  1116 	else
       
  1117 		waitTime = Math::Rand(iStreamSeed) % 50000;
       
  1118 
       
  1119 	iStreamTimer.After(iStreamGen->ActiveStatus(), waitTime);
       
  1120 	iSourceHasGrown = ETrue;
       
  1121 
       
  1122 #if defined(_DEBUG) && defined(__ENABLE_DEBUG_OUTPUT)
       
  1123 	RDebug::Print(_L("ExtendingStreamBuffer(%d,%d->%d)"), increment, waitTime, newSize); 
       
  1124 #endif 
       
  1125 
       
  1126 	return KErrNone;
       
  1127 	}
       
  1128 
       
  1129 void CVideoAppUi::FrameInfoL()
       
  1130 	{
       
  1131 	if (iFrame.Handle() == 0)
       
  1132 		return;
       
  1133 
       
  1134 	Cancel();
       
  1135 
       
  1136 	const TInt frameCount = iLoadUtil->FrameCount();
       
  1137 	if(iFrameNumber >= frameCount)
       
  1138 		iFrameNumber = frameCount-1;
       
  1139 
       
  1140 	HBufC* infoBuffer = HBufC::NewLC(KInfoBufferSize);
       
  1141 	TPtr info(infoBuffer->Des());
       
  1142 
       
  1143 	CFrameInfoStrings *frameInfoStrings = iLoadUtil->FrameInfoStringsLC(iFrameNumber);
       
  1144 	TInt count = frameInfoStrings->Count();
       
  1145 	TInt index;
       
  1146 	for (index=0; index<count; index++)
       
  1147 		{
       
  1148 		TPtrC frameInfoString = frameInfoStrings->String(index);
       
  1149 		info.Append(frameInfoString);
       
  1150 		info.Append(TChar(CEditableText::ELineBreak));
       
  1151 		}
       
  1152 
       
  1153 	HBufC* imageComments = HBufC::NewLC(0);
       
  1154 	TInt numImageComments = iLoadUtil->NumberOfImageComments();
       
  1155 	for (index = 0; index<numImageComments; index++)
       
  1156 		{
       
  1157 		HBufC* nextComment = iLoadUtil->ImageCommentL(index);
       
  1158 		CleanupStack::PushL(nextComment);
       
  1159 
       
  1160 		TPtr commentTPtr(nextComment->Des());
       
  1161 		ReplaceNewlinesWithLineBreaks(commentTPtr);
       
  1162 
       
  1163 		if (index==0)
       
  1164 			{
       
  1165 			// first go through, so should have nothing in comments - just assign
       
  1166 			ASSERT(imageComments->Length()==0);
       
  1167 			imageComments = imageComments->ReAllocL(nextComment->Length());
       
  1168 			*imageComments = *nextComment;
       
  1169 			}
       
  1170 		else
       
  1171 			{
       
  1172 			// append line break and then new comments
       
  1173 			imageComments = imageComments->ReAllocL(imageComments->Length() + nextComment->Length() + 1); // 1 for linebreak character
       
  1174 			TPtr imageCommentsPtr(imageComments->Des());
       
  1175 			imageCommentsPtr.Append(TChar(CEditableText::ELineBreak));
       
  1176 			imageCommentsPtr.Append(*nextComment);
       
  1177 			}
       
  1178 		CleanupStack::PopAndDestroy(); // nextComment
       
  1179 		CleanupStack::Pop(); // old imageComments (already deleted by ReAlloc)
       
  1180 		CleanupStack::PushL(imageComments);
       
  1181 		}
       
  1182 	
       
  1183 	HBufC* frameComments = HBufC::NewLC(0);
       
  1184 	TInt numFrameComments = iLoadUtil->NumberOfFrameComments(iFrameNumber);
       
  1185 	for (index = 0; index<numFrameComments; index++)
       
  1186 		{
       
  1187 		HBufC* nextComment = iLoadUtil->FrameCommentL(iFrameNumber, index);
       
  1188 		CleanupStack::PushL(nextComment);
       
  1189 
       
  1190 		TPtr commentTPtr(nextComment->Des());
       
  1191 		ReplaceNewlinesWithLineBreaks(commentTPtr);
       
  1192 
       
  1193 		if (index==0)
       
  1194 			{
       
  1195 			// first go through, so should have nothing in comments - just assign
       
  1196 			ASSERT(frameComments->Length()==0);
       
  1197 			frameComments = frameComments->ReAllocL(nextComment->Length());
       
  1198 			*frameComments = *nextComment;
       
  1199 			}
       
  1200 		else
       
  1201 			{
       
  1202 			// append line break and then new comments
       
  1203 			frameComments->ReAllocL(frameComments->Length() + nextComment->Length() + 1); // 1 for linebreak character
       
  1204 			TPtr frameCommentsPtr(frameComments->Des());
       
  1205 			frameCommentsPtr.Append(TChar(CEditableText::ELineBreak));
       
  1206 			frameCommentsPtr.Append(*nextComment);
       
  1207 			}
       
  1208 		CleanupStack::PopAndDestroy(); // nextComment
       
  1209 		CleanupStack::Pop(); // old frameComments (already deleted by ReAlloc)
       
  1210 		CleanupStack::PushL(frameComments);
       
  1211 		}
       
  1212 	
       
  1213 	CEikDialog* dialog = new(ELeave) CFrameInfoDialog(info, *imageComments, *frameComments);
       
  1214 	dialog->ExecuteLD(R_VIDEO_INFO_DIALOG);
       
  1215 
       
  1216 	CleanupStack::PopAndDestroy(4); // frameComments, imageComments, frameInfoStrings + infoBuffer
       
  1217 	}
       
  1218 
       
  1219 void CVideoAppUi::FrameRotateL(TBool aClockwise)
       
  1220 	{
       
  1221 	ASSERT(iState == EIdle);
       
  1222 	CBitmapRotator::TRotationAngle angle = aClockwise ?
       
  1223 			CBitmapRotator::ERotation90DegreesClockwise :
       
  1224 			CBitmapRotator::ERotation270DegreesClockwise;
       
  1225 	if (iMask.Handle() != 0)
       
  1226 		{
       
  1227 		iRotateAngle = angle; //keep for second phase
       
  1228 		iRotator->Rotate(&(iWalker->ActiveStatus()), iMask, angle);
       
  1229 		iState = ERotatingMask;
       
  1230 		}
       
  1231 	else
       
  1232 		{
       
  1233 		iRotator->Rotate(&(iWalker->ActiveStatus()), iFrame, angle);
       
  1234 		iState = ERotating;
       
  1235 		}
       
  1236 	iViewResized = EFalse;
       
  1237 	}
       
  1238 
       
  1239 void CVideoAppUi::FrameMirrorL(TBool aHorizontalAxis)
       
  1240 	{
       
  1241 	ASSERT(iState == EIdle);
       
  1242 	CBitmapRotator::TRotationAngle angle = aHorizontalAxis ? 
       
  1243 			CBitmapRotator::EMirrorHorizontalAxis : 
       
  1244 			CBitmapRotator::EMirrorVerticalAxis;
       
  1245 	if (iMask.Handle() != 0)
       
  1246 		{
       
  1247 		iRotateAngle = angle; //keep for second phase
       
  1248 		iRotator->Rotate(&(iWalker->ActiveStatus()), iMask,	angle);
       
  1249 		iState = ERotatingMask;
       
  1250 		}
       
  1251 	else
       
  1252 		{
       
  1253 		iRotator->Rotate(&(iWalker->ActiveStatus()), iFrame, angle);
       
  1254 		iState = ERotating;
       
  1255 		}
       
  1256 	iViewResized = EFalse;
       
  1257 	}
       
  1258 
       
  1259 void CVideoAppUi::ZoomFrameL(TBool aZoomIn)
       
  1260 	{
       
  1261 	TSize size(iFrame.SizeInPixels());
       
  1262 	const TSize adjust(size.iWidth / KScaleFactor, size.iHeight / KScaleFactor);
       
  1263 
       
  1264 	if (aZoomIn)
       
  1265 		size += adjust;
       
  1266 	else
       
  1267 		size -= adjust;
       
  1268 
       
  1269 	Cancel();
       
  1270 
       
  1271 	TFrameInfo frameInfo = iLoadUtil->FrameInfo(iFrameNumber);
       
  1272 
       
  1273 	if (!(frameInfo.iFlags&TFrameInfo::EFullyScaleable))
       
  1274 		{
       
  1275 		if (iMask.Handle()!=0)
       
  1276 			{
       
  1277 			iScaleSize = size; // keep for second scale action
       
  1278 			iScaler->Scale(&(iWalker->ActiveStatus()),iMask,size);
       
  1279 			iViewResized = EFalse;
       
  1280 			iState = EScalingMask;
       
  1281 			}
       
  1282 		else
       
  1283 			{
       
  1284 			iScaler->Scale(&(iWalker->ActiveStatus()),iFrame,size);
       
  1285 			iViewResized = EFalse;
       
  1286 			iState = EScaling;
       
  1287 			}
       
  1288 		}
       
  1289 	else
       
  1290 		{
       
  1291 		SetFrameSizeAndPosL(frameInfo.iFrameCoordsInPixels,size);
       
  1292 
       
  1293 		if (!(frameInfo.iFlags&TFrameInfo::ECanDither))
       
  1294 			{
       
  1295 			iFrame.Reset();
       
  1296 			User::LeaveIfError(iFrame.Create(TSize(0,0),frameInfo.iFrameDisplayMode)); // We will dither later
       
  1297 			}
       
  1298 
       
  1299 #if !defined(__CLEAR_BITMAPS_FIRST)
       
  1300 		if (iFrame.SizeInPixels() != size)
       
  1301 #endif 
       
  1302 			{
       
  1303 			#if defined(__CLEAR_BITMAPS_FIRST)
       
  1304 				User::LeaveIfError(iFrame.Resize(TSize(0,0)));
       
  1305 			#endif 
       
  1306 			User::LeaveIfError(iFrame.Resize(size));
       
  1307 			}
       
  1308 
       
  1309 		if (iMask.Handle())
       
  1310 			{
       
  1311 			if (iMask.SizeInPixels() != size)
       
  1312 				User::LeaveIfError(iMask.Resize(size));
       
  1313 			#if defined(__CLEAR_BITMAPS_FIRST)
       
  1314 			// set mask to black, so it is opaque and by default nothing is drawn
       
  1315 				CFbsBitmapDevice* device = CFbsBitmapDevice::NewL(&iMask);
       
  1316 				CleanupStack::PushL(device);
       
  1317 				CFbsBitGc* bmGc = CFbsBitGc::NewL();
       
  1318 				CleanupStack::PushL(bmGc);
       
  1319 				bmGc->Activate(device);
       
  1320 				bmGc->SetPenStyle(CGraphicsContext::ENullPen);
       
  1321 				bmGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1322 				bmGc->SetBrushColor(KRgbBlack);
       
  1323 				const TRect drawRect(TPoint(0,0), iMask.SizeInPixels());
       
  1324 				bmGc->DrawRect(drawRect);
       
  1325 				CleanupStack::PopAndDestroy(2);
       
  1326 			#endif 
       
  1327 			}
       
  1328 
       
  1329 		StartFrameOpen(ELoading, EFalse); 
       
  1330 		}
       
  1331 	}
       
  1332 
       
  1333 void CVideoAppUi::StartFrameSave()
       
  1334 	{
       
  1335 	ASSERT(iSaveUtil); // should be true by now
       
  1336 	ASSERT(iState==EIdle); 
       
  1337 	ASSERT(!iWalker->IsActive()); // we are going to use it
       
  1338 	iSaveUtil->Convert(&(iWalker->ActiveStatus()),iFrame,iFrameImageData); 
       
  1339 	iState = ESaving;
       
  1340 	}
       
  1341 
       
  1342 void CVideoAppUi::DrawConvertedFrameL()
       
  1343 	{
       
  1344 	ASSERT(iDisableMask && iMask.Handle()==0 || !iDisableMask); // iDisableMask -> iMask.Handle()==0
       
  1345 	ASSERT(iMask.Handle()==0 || iFrame.SizeInPixels()==iMask.SizeInPixels()); // if mask must be same size
       
  1346 
       
  1347 	TBool fullRedrawReq = EFalse;
       
  1348 	if (!iViewResized)
       
  1349 		{
       
  1350 		TFrameInfo frameInfo = iLoadUtil->FrameInfo(iFrameNumber);
       
  1351 		TRgb backgroundColor = iOverrideBackgroundColor ? TRgb::Color16(iBackgroundColor) : frameInfo.iBackgroundColor;
       
  1352 		fullRedrawReq = iAppView->SetBackgroundColor(backgroundColor, ENoDrawNow);
       
  1353 		if (iState == EScaling || iState == ERotating)
       
  1354 			{
       
  1355 			// size and center based on bitmap, rather than the official image size
       
  1356 			TBool resized = iAppView->ResizeL(iFrame.SizeInPixels(), ETrue, ENoDrawNow);
       
  1357 			if (resized)
       
  1358 				iAppView->Center(ENoDrawNow);
       
  1359 			fullRedrawReq = fullRedrawReq || resized;
       
  1360 			}
       
  1361 		else if (!iAnimating || iFrameNumber==0)
       
  1362 			{
       
  1363 			TBool resized = iAppView->ResizeL(iImageDisplaySize, ETrue, ENoDrawNow);
       
  1364 				// implies Resize
       
  1365 			
       
  1366 			// PDEF088116: TImageViewer USER 0 with certain animated gifs
       
  1367 			if(frameInfo.iFlags & TFrameInfo::EUsesFrameSizeInPixels) 
       
  1368 				{
       
  1369 				if(iFrame.SizeInPixels() != frameInfo.iFrameSizeInPixels) 
       
  1370 					{
       
  1371 					iFrame.Resize(frameInfo.iFrameSizeInPixels);
       
  1372 					}
       
  1373 				}
       
  1374 			//Resize iFrame to iImageDisplaySize if they are different
       
  1375 			else if (iFrame.SizeInPixels() != iImageDisplaySize)
       
  1376 				{
       
  1377 				iFrame.Resize(iImageDisplaySize);
       
  1378 				}
       
  1379 				
       
  1380 			if (resized)
       
  1381 				iAppView->Center(ENoDrawNow);
       
  1382 			else if (IsMngImage(iLoadUtil) && (iLastFrameFlags & TFrameInfo::ERestoreToBackground))
       
  1383 				{
       
  1384 				iAppView->Clear(EFalse, EDrawNow);
       
  1385 				}
       
  1386 			fullRedrawReq = fullRedrawReq || resized;
       
  1387 			}
       
  1388 		else if (iFrameNumber > 0 && iLastFrameFlags & TFrameInfo::ERestoreToBackground
       
  1389 				 || iState != EPlaying && iState != EStreamDecoding && iFrameNumber-1!=iPrevFrameNumber)
       
  1390 			{
       
  1391 			iAppView->Clear(EFalse, EDrawNow);
       
  1392 			ASSERT(iAnimating); // should be true given above, avoids complicating below
       
  1393 			if (iState != EPlaying && iState != EStreamDecoding && iFrameNumber-1!=iPrevFrameNumber)
       
  1394 				fullRedrawReq = ETrue;
       
  1395 				// usually will want to redraw _whole_ bitmap area - otherwise we only
       
  1396 				// redraw that part of the bitmap we DrawImage to
       
  1397 				// exception is when we are extracting frames in the correct sequence
       
  1398 			}
       
  1399 		else if (iAnimating && (iState==EPlaying||iState==EStreamDecoding))
       
  1400 			{
       
  1401 			// if animating and playing, should have frame greater than 0 and no restore to background - or will trigger above
       
  1402 			ASSERT(! (iLastFrameFlags & TFrameInfo::ERestoreToBackground));
       
  1403 			ASSERT(iFrameNumber>0 && iFrameNumber-1==iPrevFrameNumber);
       
  1404 			fullRedrawReq = EFalse; // don't redraw full - even if background changed, want to just redraw our bit
       
  1405 			}
       
  1406 		iViewResized = ETrue;
       
  1407 		}
       
  1408 
       
  1409 	if (iMask.Handle()==0)
       
  1410 		iAppView->DrawImage(&iFrame, iOffset, fullRedrawReq?ENoDrawNow:EDrawNow);
       
  1411 	else
       
  1412 		iAppView->DrawImage(&iFrame, &iMask, iOffset, fullRedrawReq?ENoDrawNow:EDrawNow);
       
  1413 
       
  1414 	if (fullRedrawReq)
       
  1415 		iAppView->DrawNow();
       
  1416 	}
       
  1417 
       
  1418 void CVideoAppUi::HandleConvertCompleteL()
       
  1419 	{
       
  1420 	DrawConvertedFrameL();
       
  1421 
       
  1422 	TFrameInfo frameInfo = iLoadUtil->FrameInfo(iFrameNumber);
       
  1423 
       
  1424 	iLastFrameFlags = frameInfo.iFlags;
       
  1425 	iPrevFrameNumber = iFrameNumber;
       
  1426 
       
  1427 	if (iAnimating && iState==EPlaying ||
       
  1428 		iState==EStreamDecoding && (iMultiFrameStreaming||iAnimating))
       
  1429 		{
       
  1430 		ASSERT(!iWalker->IsActive()); // we will use it again
       
  1431 		TBool mustSelfComplete=EFalse;
       
  1432 		if ((iAnimating && frameInfo.iDelay > TTimeIntervalMicroSeconds(0))||iMultiFrameStreaming)
       
  1433 			{
       
  1434 			TTime endTime;
       
  1435 			endTime.HomeTime();
       
  1436 
       
  1437 			TTimeIntervalMicroSeconds timeTaken = endTime.MicroSecondsFrom(iTime);
       
  1438 			if (frameInfo.iDelay > timeTaken)
       
  1439 				{
       
  1440 				TInt64 delay = frameInfo.iDelay.Int64() - timeTaken.Int64();
       
  1441 				TInt delayPeriod = I64LOW(delay);
       
  1442 				if (delayPeriod<0)
       
  1443 					delayPeriod=0; // can get negative if we took longer on the streaming than this
       
  1444 				iTimer.After(iWalker->ActiveStatus(), delayPeriod);
       
  1445 				}
       
  1446 			else if(iMultiFrameStreaming)
       
  1447 				{
       
  1448 				TInt delay = KDefaultStreamDelay - I64LOW(timeTaken.Int64());
       
  1449 				if (delay<0)
       
  1450 					delay=0; // can get negative if we took longer on the streaming than this
       
  1451 				iTimer.After(iWalker->ActiveStatus(), delay);
       
  1452 				}
       
  1453 			else
       
  1454 				mustSelfComplete=ETrue;
       
  1455 			}
       
  1456 		else
       
  1457 			mustSelfComplete=ETrue;
       
  1458 		if (mustSelfComplete)
       
  1459 			iWalker->SelfComplete(KErrNone);
       
  1460 		if (iState==EPlaying)
       
  1461 			iState = EPlayingWait;
       
  1462 		else 
       
  1463 			{
       
  1464 			ASSERT(iState==EStreamDecoding);
       
  1465 			iState = EStreamDecodeWait;
       
  1466 			}
       
  1467 		}
       
  1468 	else if (iOpeningFolder)
       
  1469 		LoadFolderWait();
       
  1470 	else
       
  1471 		{
       
  1472 		iEikonEnv->BusyMsgCancel();
       
  1473 		Cancel(); // cancel any background streaming
       
  1474 		iState = EIdle;
       
  1475 		}
       
  1476 	}
       
  1477 
       
  1478 void CVideoAppUi::RunL(CVideoWalker* aWalker, TInt aStatus)
       
  1479 	{
       
  1480 	ASSERT(aWalker==iWalker || aWalker==iStreamGen); // ones we know about
       
  1481 
       
  1482 #if defined(_DEBUG) && defined(__ENABLE_DEBUG_OUTPUT)
       
  1483 	RDebug::Print(_L("RunL(%x,%d,%d)(%x,%x)"), aWalker, aStatus, iState, iWalker, iStreamGen);
       
  1484 #endif 
       
  1485 
       
  1486 	switch (iState)
       
  1487 		{
       
  1488 	case EIdle:
       
  1489 		ASSERT(EFalse); // should not happen
       
  1490 		break;
       
  1491 	case ELoading:
       
  1492 	case EPlaying:
       
  1493 	case EScaling:
       
  1494 	case ERotating:
       
  1495 		{
       
  1496 		ASSERT(aWalker==iWalker);
       
  1497 		TInt error = aStatus;
       
  1498 		if (error==KErrNone)
       
  1499 			TRAP(error, HandleConvertCompleteL());
       
  1500 		if (error!=KErrNone)
       
  1501 			HandleRunError(aWalker, error);
       
  1502 		}
       
  1503 		break;
       
  1504 	case ERotatingMask:
       
  1505 		{
       
  1506 		ASSERT(aWalker == iWalker);
       
  1507 		if (aStatus==KErrNone)
       
  1508 			{
       
  1509 			// having done mask, kick off rotate the image itself
       
  1510 			iRotator->Rotate(&(iWalker->ActiveStatus()), iFrame, iRotateAngle);
       
  1511 			iState = ERotating;
       
  1512 			}
       
  1513 		else
       
  1514 			{
       
  1515 			HandleRunError(aWalker, aStatus);
       
  1516 			}
       
  1517 		break;
       
  1518 		}
       
  1519 	case EScalingMask:
       
  1520 		{
       
  1521 		ASSERT(aWalker==iWalker);
       
  1522 		if (aStatus==KErrNone)
       
  1523 			{
       
  1524 			// having done mask, kick off scale of normal
       
  1525 			iScaler->Scale(&iWalker->ActiveStatus(), iFrame, iScaleSize);
       
  1526 			iState = EScaling;
       
  1527 			}
       
  1528 		else
       
  1529 			HandleRunError(aWalker, aStatus);
       
  1530 		}
       
  1531 		break;
       
  1532 	case EPlayingWait:
       
  1533 		{
       
  1534 		ASSERT(iWalker==aWalker);
       
  1535 		iTime.HomeTime(); // whatever reset the time here
       
  1536 		if (aStatus!=KErrNone)
       
  1537 			HandleRunError(aWalker, aStatus);
       
  1538 		else if (iFrameNumber < iLoadUtil->FrameCount()-1 || (IsMngImage(iLoadUtil)&&HasMoreMngFrames(iLoadUtil)) )
       
  1539 			{
       
  1540 			iFrameNumber += ( IsMngImage(iLoadUtil)==EFalse );
       
  1541 			StartFrameOpen(EPlaying);
       
  1542 			}
       
  1543 		else if (iOpeningFolder)
       
  1544 			LoadFolderWait();
       
  1545 		else
       
  1546 			{
       
  1547 			ASSERT(!iWalker->IsActive() && !iStreamGen->IsActive()); // should have stopped naturally
       
  1548 			iEikonEnv->BusyMsgCancel();
       
  1549 			iState = EIdle;
       
  1550 			}
       
  1551 		}
       
  1552 		break;
       
  1553 	case ESaving:
       
  1554 		{
       
  1555 		ASSERT(iWalker==aWalker);
       
  1556 		iEikonEnv->BusyMsgCancel();
       
  1557 		iState = EIdle;
       
  1558 		if (aStatus!=KErrNone)
       
  1559 			HandleRunError(aWalker, aStatus);
       
  1560 		}
       
  1561 		break;
       
  1562 	case EStreamOpening:
       
  1563 		{
       
  1564 		ASSERT(aWalker==iStreamGen); 
       
  1565 		TInt error = aStatus;
       
  1566 
       
  1567 		if (error==KErrNone)
       
  1568 			{
       
  1569 			delete iLoadUtil; iLoadUtil = NULL;
       
  1570 
       
  1571 			TUid format;
       
  1572 			switch (iLastFileType)
       
  1573 				{
       
  1574 				case EFileTypeOta:
       
  1575 					format = KImageTypeOTAUid;
       
  1576 					break;
       
  1577 				case EFileTypeWbmp:
       
  1578 					format = KImageTypeWBMPUid;
       
  1579 					break;
       
  1580 				default:
       
  1581 					format = KNullUid;
       
  1582 				}
       
  1583 
       
  1584 			TRAP(error, iLoadUtil = CImageDecoder::DataNewL(iCoeEnv->FsSession(), iStreamBuffer, 
       
  1585 											CImageDecoder::TOptions(iDecoderOptions | CImageDecoder::EOptionAllowZeroFrameOpen), format));
       
  1586 			}
       
  1587 
       
  1588 		if (error==KErrUnderflow)
       
  1589 			{
       
  1590 			error = KErrNone; // clear so we don't hit the error handler below
       
  1591 			if (!iStreamGen->IsActive())
       
  1592 				error = ExtendStreamBuffer(); // wait for more input. remain in current state
       
  1593 			}
       
  1594 		else if (error==KErrNone)
       
  1595 			{
       
  1596 			if (iLoadUtil->FrameCount()>0)
       
  1597 				{
       
  1598 				TRAP(error,HandleNewlyOpenedImageL());
       
  1599 				if (error==KErrNone)
       
  1600 					TRAP(error,StreamOpenFrameIfPosL());
       
  1601 				}
       
  1602 			else
       
  1603 				{
       
  1604 				// insufficient data, so wait until it comes along
       
  1605 				if (!iStreamGen->IsActive())
       
  1606 					error = ExtendStreamBuffer(); // wait for more input. switch to EStreamWaitForFirstFrame
       
  1607 				iState = EStreamWaitForFirstFrame;
       
  1608 				}
       
  1609 			}
       
  1610 
       
  1611 		if (error!=KErrNone)
       
  1612 			HandleRunError(aWalker, error);
       
  1613 		}
       
  1614 		break;
       
  1615 	case EStreamWaitAndContinue:
       
  1616 #if defined(__BYPASS_CONTINUE_CONVERT)
       
  1617 		ASSERT(EFalse); // should not happen when bypassing 
       
  1618 #else
       
  1619 		{
       
  1620 		ASSERT(aWalker==iStreamGen); 
       
  1621 
       
  1622 		TInt error = aStatus;
       
  1623 
       
  1624 		if (error==KErrNone)
       
  1625 			{
       
  1626 			if ((iStreamBuffer.Length()<iStreamBuffer.MaxLength()) && !iStreamGen->IsActive())
       
  1627 				error = ExtendStreamBuffer(); // "new data has arrived"
       
  1628 			ASSERT(iSourceHasGrown);
       
  1629 			ASSERT(iState==EStreamWaitAndContinue);
       
  1630 			iLoadUtil->ContinueConvert(&(iWalker->ActiveStatus()));
       
  1631 			iSourceHasGrown = EFalse;
       
  1632 			iState = EStreamDecoding;
       
  1633 			}
       
  1634 
       
  1635 		if (error!=KErrNone)
       
  1636 			HandleRunError(aWalker, error);
       
  1637 		}
       
  1638 #endif 
       
  1639 		break;
       
  1640 	case EStreamWaitForFirstFrame:
       
  1641 		{
       
  1642 		ASSERT(aWalker==iStreamGen); 
       
  1643 
       
  1644 		TInt error = aStatus;
       
  1645 
       
  1646 		if (error==KErrNone)
       
  1647 			{
       
  1648 			ASSERT(!iLoadUtil->IsImageHeaderProcessingComplete()); // should not be reading more than we need to know
       
  1649 			iLoadUtil->ContinueProcessingHeaderL();
       
  1650 			if (iLoadUtil->FrameCount()>0)
       
  1651 				{
       
  1652 				TRAP(error,HandleNewlyOpenedImageL());
       
  1653 				if (error==KErrNone)
       
  1654 					TRAP(error,StreamOpenFrameIfPosL());
       
  1655 				}
       
  1656 			else
       
  1657 				{
       
  1658 				// insufficient data, so wait until it comes along
       
  1659 				if (!iStreamGen->IsActive())
       
  1660 					error = ExtendStreamBuffer(); // wait for more input. stay in same state
       
  1661 				}
       
  1662 			}
       
  1663 
       
  1664 		if (error!=KErrNone)
       
  1665 			HandleRunError(aWalker, error);
       
  1666 		}
       
  1667 		break;
       
  1668 	case EStreamWaitForDetails:
       
  1669 		{
       
  1670 		ASSERT(aWalker==iStreamGen); 
       
  1671 		TInt error = aStatus;
       
  1672 
       
  1673 		if (error==KErrNone)
       
  1674 			{
       
  1675 			TRAP(error, StreamOpenFrameIfPosL());
       
  1676 			}
       
  1677 		if (error!=KErrNone)
       
  1678 			HandleRunError(aWalker, error);
       
  1679 		}
       
  1680 		break;
       
  1681 	case EStreamDecoding:
       
  1682 		{
       
  1683 		ASSERT(aWalker==iWalker || aWalker==iStreamGen);
       
  1684 		TInt error = aStatus;
       
  1685 		if (aWalker==iWalker)
       
  1686 			{
       
  1687 			TBool timerActive = iStreamGen->IsActive();
       
  1688 			if (error==KErrNone)
       
  1689 				{
       
  1690 				TRAP(error, HandleConvertCompleteL());
       
  1691 				}
       
  1692 			else if (error==KErrUnderflow && (timerActive || iSourceHasGrown))
       
  1693 				{
       
  1694 				// draw partial result to the screen if possible, else set error to KErrNone so we don't stop
       
  1695 				TFrameInfo frameInfo = iLoadUtil->FrameInfo(iFrameNumber);
       
  1696 				if (!(frameInfo.iFlags & TFrameInfo::EPartialDecodeInvalid))
       
  1697 					{
       
  1698 					TRAP(error, DrawConvertedFrameL());
       
  1699 					}
       
  1700 				else
       
  1701 					error = KErrNone;
       
  1702 
       
  1703 				if (error==KErrNone)
       
  1704 					{
       
  1705 					// wait for more data to arrive before we try again
       
  1706 					#if defined(__BYPASS_CONTINUE_CONVERT)
       
  1707 						iState = EStreamWaitForDetails;
       
  1708 					#else
       
  1709 						iState = EStreamWaitAndContinue;
       
  1710 					#endif 
       
  1711 					if(!timerActive)
       
  1712 						{ // final buffer was added after last Convert()/ContinueConvert()
       
  1713 						ASSERT(iStreamBuffer.Length()==iStreamBuffer.MaxLength());
       
  1714 						ASSERT(iSourceHasGrown);
       
  1715 						// force a final decode
       
  1716 						iStreamTimer.After(iStreamGen->ActiveStatus(),0);
       
  1717 						}
       
  1718 					}
       
  1719 				}
       
  1720 			}
       
  1721 		else
       
  1722 			{
       
  1723 			ASSERT(aWalker==iStreamGen);
       
  1724 			if (error==KErrNone && iStreamBuffer.Length()<iStreamBuffer.MaxLength())
       
  1725 				error = ExtendStreamBuffer(); // data can arrive concurrent with decode
       
  1726 			}
       
  1727 		if (error!=KErrNone)
       
  1728 			HandleRunError(aWalker, error);
       
  1729 		}
       
  1730 		break;
       
  1731 	case EStreamDecodeWait:
       
  1732 		{
       
  1733 		ASSERT(aWalker==iWalker || aWalker==iStreamGen);
       
  1734 		TInt error = aStatus;
       
  1735 		if (aWalker==iWalker)
       
  1736 			{
       
  1737 			iTime.HomeTime(); // whatever reset the time here
       
  1738 			if (error==KErrNone)
       
  1739 				{
       
  1740 				if (iFrameNumber < iLoadUtil->FrameCount()-1 || !iLoadUtil->IsImageHeaderProcessingComplete())
       
  1741 					{
       
  1742 					iFrameNumber += 1;
       
  1743 					TRAP(error,StreamOpenFrameIfPosL());
       
  1744 					}
       
  1745 				else
       
  1746 					{
       
  1747 					Cancel(); // may be required true, eg if there is data after the frame, other AO may be busy
       
  1748 					iEikonEnv->BusyMsgCancel();
       
  1749 					iState = EIdle;
       
  1750 					}
       
  1751 				}
       
  1752 			}
       
  1753 		else
       
  1754 			{
       
  1755 			ASSERT(aWalker==iStreamGen);
       
  1756 			if (error==KErrNone && iStreamBuffer.Length()<iStreamBuffer.MaxLength())
       
  1757 				error = ExtendStreamBuffer(); // data can arrive concurrent with wait
       
  1758 			}
       
  1759 		if (error!=KErrNone)
       
  1760 			HandleRunError(aWalker, error);
       
  1761 		}
       
  1762 		break;
       
  1763 	case EFolderWait:
       
  1764 		iDirIndex++;
       
  1765 		OpenNextFolderEntry();
       
  1766 		break;
       
  1767 	default:
       
  1768 		ASSERT(EFalse); // unknown state
       
  1769 		}
       
  1770 	}
       
  1771 
       
  1772 void CVideoAppUi::DoCancel(CVideoWalker *aWalker)
       
  1773 	{
       
  1774 	ASSERT(aWalker==iWalker || aWalker==iStreamGen); // only ones we know about
       
  1775 
       
  1776 #if defined(_DEBUG) && defined(__ENABLE_DEBUG_OUTPUT)
       
  1777 	RDebug::Print(_L("DoCancel(%x,%d)(%x,%x)"), aWalker, iState, iWalker, iStreamGen); 
       
  1778 #endif 
       
  1779 
       
  1780 	if (aWalker==iWalker)
       
  1781 		{
       
  1782 		switch (iState)
       
  1783 			{
       
  1784 		case ELoading:
       
  1785 		case EPlaying:
       
  1786 		case EStreamDecoding:
       
  1787 			iLoadUtil->Cancel();
       
  1788 			break;
       
  1789 		case ESaving:
       
  1790 			iSaveUtil->Cancel();
       
  1791 			break;
       
  1792 		case EScaling:
       
  1793 		case EScalingMask:
       
  1794 			iScaler->Cancel();
       
  1795 			break;
       
  1796 		case ERotating:
       
  1797 		case ERotatingMask:
       
  1798 			iRotator->Cancel();
       
  1799 			break;
       
  1800 		case EStreamDecodeWait:
       
  1801 		case EPlayingWait: // ignore scenario where we self complete - will not get here
       
  1802 		case EFolderWait:
       
  1803 			iTimer.Cancel();
       
  1804 			break;
       
  1805 		default:
       
  1806 			ASSERT(EFalse); // unknown state or should not happen
       
  1807 			}
       
  1808 		}
       
  1809 	else
       
  1810 		{
       
  1811 		ASSERT(aWalker==iStreamGen);
       
  1812 		switch (iState)
       
  1813 			{
       
  1814 		case EStreamOpening:
       
  1815 		case EStreamWaitForDetails:
       
  1816 		case EStreamWaitAndContinue:
       
  1817 		case EStreamDecoding:
       
  1818 		case EStreamDecodeWait:
       
  1819 		case EStreamWaitForFirstFrame:
       
  1820 			iStreamTimer.Cancel();
       
  1821 			break;
       
  1822 		default:
       
  1823 			ASSERT(EFalse); // unknown state or should not happen
       
  1824 			}
       
  1825 		}
       
  1826 	}
       
  1827 
       
  1828 void CVideoAppUi::HandleRunError(CVideoWalker* /*aWalker*/, TInt aError)
       
  1829 	{
       
  1830 	Cancel();
       
  1831 	iEikonEnv->BusyMsgCancel();
       
  1832 	iEikonEnv->HandleError(aError);
       
  1833 	ASSERT(iState == EIdle);
       
  1834 	}
       
  1835 
       
  1836 void CVideoAppUi::StreamOpenFrameIfPosL()
       
  1837 	{
       
  1838 	if (iFrameNumber >= iLoadUtil->FrameCount())
       
  1839 		{
       
  1840 		// Continue processing headers if necessary and only if we are not in the middle of an image conversion.
       
  1841 		ASSERT(!iLoadUtil->IsImageHeaderProcessingComplete()); // should not be reading more than we need to know
       
  1842 		iLoadUtil->ContinueProcessingHeaderL();
       
  1843 		}
       
  1844 
       
  1845 	if (iFrameNumber >= iLoadUtil->FrameCount())
       
  1846 		{
       
  1847 		if (iLoadUtil->IsImageHeaderProcessingComplete())
       
  1848 			{
       
  1849 			Cancel(); // other AO could still be busy if there were bytes after last frame data
       
  1850 			iEikonEnv->BusyMsgCancel();
       
  1851 			iState = EIdle;
       
  1852 			}
       
  1853 		else
       
  1854 			{
       
  1855 			// not yet reached the frame header
       
  1856 			iState = EStreamWaitForDetails;
       
  1857 			if (!iStreamGen->IsActive())
       
  1858 				// this shuld cope with reaching end of stream prematurely :
       
  1859 				User::LeaveIfError(ExtendStreamBuffer()); 
       
  1860 			}
       
  1861 		}
       
  1862 	else
       
  1863 		{
       
  1864 		if ((iStreamBuffer.Length()<iStreamBuffer.MaxLength()) && !iStreamGen->IsActive())
       
  1865 			User::LeaveIfError(ExtendStreamBuffer()); // "new data has arrived"
       
  1866 		ASSERT(iSourceHasGrown);
       
  1867 		StartFrameOpen(EStreamDecoding);
       
  1868 		iSourceHasGrown = EFalse;
       
  1869 		}
       
  1870 	ASSERT(iState==EIdle||iStreamBuffer.Length()==iStreamBuffer.MaxLength()||iStreamGen->IsActive()); // either we've finished, reached the end or we expect more data
       
  1871 	}
       
  1872 
       
  1873 void CVideoAppUi::SetFrameSizeAndPosL(const TRect& aFrameRect,const TSize& aOverallSize)
       
  1874 	{
       
  1875 	TRect zoomedFrame(aFrameRect);
       
  1876 	TSize zoomedSize(aOverallSize);
       
  1877 	TSize zoomedOverallSize(iOverallSize); // effectively size on frame 0
       
  1878 	if (aOverallSize.iWidth == 0 || aOverallSize.iHeight == 0)
       
  1879 		zoomedSize = aFrameRect.Size();
       
  1880 
       
  1881 	if ( iUseExtensions )
       
  1882 		{
       
  1883 		// using PREQ1630 extensions
       
  1884 		TInt err = iLoadUtil->GetDestinationSize(zoomedSize,iFrameNumber);
       
  1885 		if ( err != KErrNone )
       
  1886 			{
       
  1887 			TBuf<256> buf;
       
  1888 			buf.Format(_L("GetDestinationSize Error %d"),err);
       
  1889 			iEikonEnv->InfoMsg(buf);
       
  1890 			}
       
  1891 
       
  1892 		User::LeaveIfError(iFrame.Resize(zoomedSize));			
       
  1893 		}
       
  1894 	else
       
  1895 		{
       
  1896 		if (iZoomFactor > 0)
       
  1897 			{
       
  1898 			zoomedFrame.iTl.iX <<= iZoomFactor;
       
  1899 			zoomedFrame.iTl.iY <<= iZoomFactor;
       
  1900 			zoomedFrame.iBr.iX <<= iZoomFactor;
       
  1901 			zoomedFrame.iBr.iY <<= iZoomFactor;
       
  1902 			zoomedSize.iWidth <<= iZoomFactor;
       
  1903 			zoomedSize.iHeight <<= iZoomFactor;
       
  1904 			zoomedOverallSize.iWidth <<= iZoomFactor;
       
  1905 			zoomedOverallSize.iHeight <<= iZoomFactor;
       
  1906 			}
       
  1907 		else if (iZoomFactor < 0)
       
  1908 			{
       
  1909 			const TInt absZoomFactor = -iZoomFactor;
       
  1910 #if defined(__USE_PURE_SCALING)
       
  1911 			const TInt roundingFactor = 0; // set 0 to get pure scaling
       
  1912 #else
       
  1913 			const TInt roundingFactor = (1 << absZoomFactor) - 1; 
       
  1914 #endif 
       
  1915 			zoomedFrame.iTl.iX = (zoomedFrame.iTl.iX) >> absZoomFactor;
       
  1916 			zoomedFrame.iTl.iY = (zoomedFrame.iTl.iY) >> absZoomFactor;
       
  1917 	//		zoomedFrame.iBr.iX = (zoomedFrame.iBr.iX + roundingFactor) >> absZoomFactor;
       
  1918 	//		zoomedFrame.iBr.iY = (zoomedFrame.iBr.iY + roundingFactor) >> absZoomFactor;
       
  1919 
       
  1920 			zoomedSize.iWidth = (zoomedSize.iWidth + roundingFactor) >> absZoomFactor;
       
  1921 			zoomedSize.iHeight = (zoomedSize.iHeight + roundingFactor) >> absZoomFactor;
       
  1922 
       
  1923 			zoomedFrame.iBr = zoomedFrame.iTl + zoomedSize;
       
  1924 
       
  1925 			zoomedOverallSize.iWidth = (zoomedOverallSize.iWidth + roundingFactor) >> absZoomFactor;
       
  1926 			zoomedOverallSize.iHeight = (zoomedOverallSize.iHeight + roundingFactor) >> absZoomFactor;
       
  1927 			}
       
  1928 
       
  1929 #if !defined(__CLEAR_BITMAPS_FIRST)
       
  1930 		if (iFrame.SizeInPixels() != zoomedFrame.Size())
       
  1931 #endif 
       
  1932 			{
       
  1933 #if defined(__CLEAR_BITMAPS_FIRST)
       
  1934 				// resize via 0 so that we clear original
       
  1935 				User::LeaveIfError(iFrame.Resize(TSize(0,0)));
       
  1936 #endif 
       
  1937 				User::LeaveIfError(iFrame.Resize(zoomedSize));
       
  1938 			}
       
  1939 		}
       
  1940 
       
  1941 	if (iMask.Handle())
       
  1942 		{
       
  1943 		if (iMask.SizeInPixels() != zoomedFrame.Size())
       
  1944 			User::LeaveIfError(iMask.Resize(zoomedSize));
       
  1945 		#if defined(__CLEAR_BITMAPS_FIRST)
       
  1946 		// set mask to black, so it is opaque and by default nothing is drawn
       
  1947 			CFbsBitmapDevice* device = CFbsBitmapDevice::NewL(&iMask);
       
  1948 			CleanupStack::PushL(device);
       
  1949 			CFbsBitGc* bmGc = CFbsBitGc::NewL();
       
  1950 			CleanupStack::PushL(bmGc);
       
  1951 			bmGc->Activate(device);
       
  1952 			bmGc->SetPenStyle(CGraphicsContext::ENullPen);
       
  1953 			bmGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  1954 			bmGc->SetBrushColor(KRgbBlack);
       
  1955 			const TRect drawRect(TPoint(0,0), zoomedSize);
       
  1956 			bmGc->DrawRect(drawRect);
       
  1957 			CleanupStack::PopAndDestroy(2);
       
  1958 		#endif 
       
  1959 		}
       
  1960 
       
  1961 	iImageDisplaySize = zoomedSize;
       
  1962 	iOffset = zoomedFrame.iTl;
       
  1963 
       
  1964 	ASSERT(iMask.Handle()==0 || iFrame.SizeInPixels()==iMask.SizeInPixels()); // if mask must be same size
       
  1965 	}
       
  1966 
       
  1967 void CVideoAppUi::ReplaceNewlinesWithLineBreaks(TDes& aText)
       
  1968 	{
       
  1969 	TInt pos=0;
       
  1970 
       
  1971 	for (;;)
       
  1972 		{
       
  1973 		if (pos >= aText.Length()) // will occur if last character in comment is new line
       
  1974 			break;
       
  1975 		const TPtrC restOfText(aText.Mid(pos));
       
  1976 		TInt posOfNextNewLine = restOfText.Locate(TChar('\n'));
       
  1977 		if (posOfNextNewLine<0) // no more new lines in text
       
  1978 			break;
       
  1979 		posOfNextNewLine += pos; // position relative to whole descriptor
       
  1980 		aText[posOfNextNewLine] = CEditableText::ELineBreak;
       
  1981 		pos = posOfNextNewLine + 1; // next cycle, start at next character
       
  1982 		}
       
  1983 	}
       
  1984 
       
  1985 // update crop region
       
  1986 void CVideoAppUi::UpdateClippingRect(TUint code)
       
  1987 	{
       
  1988 	TFrameInfo frameInfo;
       
  1989 	if ( iLoadUtil )
       
  1990 		{
       
  1991 		switch (code)
       
  1992 			{
       
  1993 			case EKeyLeftArrow:
       
  1994 				iClippingRect.Move(-Min(iClippingRect.Width(),iClippingRect.iTl.iX),0);
       
  1995 				break;
       
  1996 			case EKeyRightArrow:
       
  1997 				{
       
  1998 				const TFrameInfo& frameInfo = iLoadUtil->FrameInfo(iFrameNumber);
       
  1999 				iClippingRect.Move(Min(iClippingRect.Width(),frameInfo.iOverallSizeInPixels.iWidth-iClippingRect.iBr.iX),0);
       
  2000 				}
       
  2001 				break;
       
  2002 			case EKeyUpArrow:
       
  2003 				iClippingRect.Move(0,-Min(iClippingRect.Height(),iClippingRect.iTl.iY));
       
  2004 				break;
       
  2005 			case EKeyDownArrow:
       
  2006 				{
       
  2007 				const TFrameInfo& frameInfo = iLoadUtil->FrameInfo(iFrameNumber);
       
  2008 				iClippingRect.Move(0,Min(iClippingRect.Height(),frameInfo.iOverallSizeInPixels.iHeight-iClippingRect.iBr.iY));
       
  2009 				}
       
  2010 				break;
       
  2011 			}
       
  2012 		}
       
  2013 		LoadFileL();
       
  2014 	}
       
  2015 //
       
  2016 // CVideoAppView
       
  2017 //
       
  2018 
       
  2019 CVideoAppView* CVideoAppView::NewL(const TRect& aRect)
       
  2020 	{
       
  2021 	CVideoAppView* self = new (ELeave) CVideoAppView;
       
  2022 	CleanupStack::PushL(self);
       
  2023 	self->ConstructL(aRect);
       
  2024 	CleanupStack::Pop();
       
  2025 	return self;
       
  2026 	}
       
  2027 
       
  2028 CVideoAppView::CVideoAppView():
       
  2029 	CCoeControl()
       
  2030 	{}
       
  2031 
       
  2032 void CVideoAppView::ConstructL(const TRect& /*aRect*/)
       
  2033     {
       
  2034 	CreateWindowL();
       
  2035 #if defined(__WINS__)
       
  2036 	Window().SetRequiredDisplayMode(SystemGc().Device()->DisplayMode());
       
  2037 #endif
       
  2038 	iDisplayMode = Window().DisplayMode();
       
  2039 	EnableDragEvents();
       
  2040     SetExtentToWholeScreen();
       
  2041 
       
  2042 	iBmBuffer = new (ELeave) CWsBitmap(iCoeEnv->WsSession());
       
  2043 	ActivateL();
       
  2044 	}
       
  2045 
       
  2046 CVideoAppView::~CVideoAppView()
       
  2047 	{
       
  2048 	delete iBmGc;
       
  2049 	delete iBmDevice;
       
  2050 	delete iBmBuffer;
       
  2051 	}
       
  2052 
       
  2053 void CVideoAppView::Draw(const TRect& aRect) const
       
  2054 	{
       
  2055 	CWindowGc& gc = SystemGc();
       
  2056 	TRect drawRect=Rect();
       
  2057 
       
  2058 	ASSERT(!iBitmapValid || iBmRect.Size() == iBmBuffer->SizeInPixels()); // either bitmap not valid or size of bmrect is same as the buffer
       
  2059 
       
  2060 	if (iBitmapValid)
       
  2061 		{
       
  2062 		// if the required rect includes some background, then draw it
       
  2063 		// check is to see if the passed aRect is a pure subset of the bitmap rect
       
  2064 		TRect intersection(aRect);
       
  2065 		intersection.Intersection(iBmRect);
       
  2066 		if (intersection != aRect)
       
  2067 			{
       
  2068 			gc.SetPenStyle(CGraphicsContext::ENullPen); // solid background rect
       
  2069 			gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  2070 			gc.SetBrushColor(KRgbWhite);
       
  2071 			gc.DrawRect(drawRect);
       
  2072 			TRect frame(iBmRect); // draw a frame one pixel larger than bitmap
       
  2073 			frame.Grow(1,1);
       
  2074 			gc.SetBrushStyle(CGraphicsContext::ENullBrush);
       
  2075 			gc.SetPenStyle(CGraphicsContext::ESolidPen);
       
  2076 			gc.DrawRect(frame);
       
  2077 			}
       
  2078 		// now if there is some bitmap to be drawn...
       
  2079 		if (!intersection.IsEmpty())
       
  2080 			{
       
  2081 			gc.BitBlt(iBmRect.iTl, iBmBuffer);
       
  2082 			}			
       
  2083 		}
       
  2084 	else
       
  2085 		{
       
  2086 		gc.Clear();
       
  2087 		drawRect.Shrink(10,10);
       
  2088 		gc.DrawRect(drawRect);
       
  2089 		gc.DrawLine(drawRect.iTl,drawRect.iBr);
       
  2090 		gc.DrawLine(TPoint(drawRect.iTl.iX,drawRect.iBr.iY),TPoint(drawRect.iBr.iX,drawRect.iTl.iY));
       
  2091 		}
       
  2092 	}
       
  2093 
       
  2094 void CVideoAppView::Reset(TDrawNow aDrawNow)
       
  2095 	{
       
  2096 	iBmBuffer->Reset();
       
  2097 	iBitmapValid = EFalse;
       
  2098 	if (aDrawNow!=ENoDrawNow)
       
  2099 		DrawNow();
       
  2100 	}
       
  2101 
       
  2102 void CVideoAppView::DrawImage(CFbsBitmap* aBitmap, const TPoint& aOffset, TDrawNow aDrawNow)
       
  2103 	{
       
  2104 	DrawImage(aBitmap, NULL, aOffset, aDrawNow);
       
  2105 	}
       
  2106 
       
  2107 void CVideoAppView::DrawImage(CFbsBitmap* aBitmap, CFbsBitmap* aMask, const TPoint& aOffset, TDrawNow aDrawNow)
       
  2108 	{
       
  2109 	ASSERT(iBitmapValid && iBmBuffer->Handle()); // should only be called when size setup properly
       
  2110 	ASSERT(aMask==NULL || aBitmap->SizeInPixels()==aMask->SizeInPixels());
       
  2111 		// if we have a mask, assumed to be the same size as the original
       
  2112 
       
  2113 	const TPoint screenOffset = iBmRect.iTl + aOffset; // relative to screen instead of iBmRect
       
  2114 	const TRect bitmapRect (screenOffset, aBitmap->SizeInPixels()); // the rect for this bitmap
       
  2115 
       
  2116 #if defined(_DEBUG)
       
  2117 	TRect intersection (bitmapRect); // check that this rect is same or smaller than the bitmap
       
  2118 	ASSERT(iBmRect.Size() == iBmBuffer->SizeInPixels());
       
  2119 	intersection.Intersection(iBmRect);
       
  2120 	ASSERT(intersection==bitmapRect);
       
  2121 #endif 
       
  2122 
       
  2123 	// first draw to bitmap buffer
       
  2124 	if (aMask)
       
  2125 		iBmGc->BitBltMasked(aOffset, aBitmap, TRect(aBitmap->SizeInPixels()), aMask, EFalse);
       
  2126 	else
       
  2127 		iBmGc->BitBlt(aOffset, aBitmap);
       
  2128 
       
  2129 	// if required, also draw to screen
       
  2130 	if (aDrawNow!=ENoDrawNow)
       
  2131 		{
       
  2132 		ActivateGc();
       
  2133 		CWindowGc& gc = SystemGc();
       
  2134 		if (aMask)
       
  2135 			gc.BitBltMasked(screenOffset, aBitmap, TRect(aBitmap->SizeInPixels()), aMask, EFalse);
       
  2136 		else
       
  2137 			gc.BitBlt(screenOffset, aBitmap);
       
  2138 		DeactivateGc();
       
  2139 		}
       
  2140 	}
       
  2141 
       
  2142 TBool CVideoAppView::ResizeL(const TSize& aNewSize, TBool aClear, TDrawNow aDrawNow)
       
  2143 	{
       
  2144 	//Resize iBmBuffer to iBmRect where iBmBuffer holds the aNewSize. 
       
  2145 	if(iBmRect.Size() != aNewSize)
       
  2146 		{
       
  2147 		iBmBuffer->Resize(iBmRect.Size());
       
  2148 		}
       
  2149 	ASSERT(!iBitmapValid || iBmRect.Size() == iBmBuffer->SizeInPixels()); // either bitmap not valid or size of bmrect is same as the buffer
       
  2150 	if (iBitmapValid && aNewSize==iBmRect.Size())
       
  2151 		{
       
  2152 		// special cases where we don't actually modify the size
       
  2153 		if (aDrawNow!=ENoDrawNow)
       
  2154 			DrawNow();
       
  2155 		return EFalse;
       
  2156 		}
       
  2157 
       
  2158 	CFbsBitmap* tempBuffer = NULL;
       
  2159 
       
  2160 	TBool preserveOrig = !aClear && iBitmapValid;
       
  2161 
       
  2162 	if (preserveOrig)
       
  2163 		{
       
  2164 		// tempBuffer becomes copy of original
       
  2165 		tempBuffer = new (ELeave) CWsBitmap(iCoeEnv->WsSession());
       
  2166 		CleanupStack::PushL(tempBuffer);
       
  2167 		User::LeaveIfError(tempBuffer->Duplicate(iBmBuffer->Handle()));
       
  2168 		}
       
  2169 
       
  2170 	ResizeBufferL(aNewSize, iDisplayMode);
       
  2171 		// resize bitmap
       
  2172 
       
  2173 	iBitmapValid = ETrue;
       
  2174 	iBmRect.SetRect(iBmRect.iTl, aNewSize); // rect with same Tl but new size
       
  2175 	ASSERT(iBmRect.Size() == iBmBuffer->SizeInPixels()); // check resized bitmap OK
       
  2176 
       
  2177 	if (preserveOrig)
       
  2178 		{
       
  2179 		// draw original back at new size
       
  2180 		EnsureSizeInTwipsSet(tempBuffer);
       
  2181 		EnsureSizeInTwipsSet(iBmBuffer);
       
  2182 		iBmGc->DrawBitmap(TPoint(0,0), tempBuffer);
       
  2183 		CleanupStack::PopAndDestroy(); // tempBuffer
       
  2184 		}
       
  2185 	else
       
  2186 		Clear(EFalse, ENoDrawNow); // get background correct colour
       
  2187 
       
  2188 	if (aDrawNow!=ENoDrawNow)
       
  2189 		DrawNow();
       
  2190 
       
  2191 	return ETrue;
       
  2192 	}
       
  2193 
       
  2194 void CVideoAppView::ResizeBufferL(const TSize& aNewSize, TDisplayMode aDisplayMode)
       
  2195 	{
       
  2196 	delete iBmGc; iBmGc = NULL;
       
  2197 	delete iBmDevice; iBmDevice = NULL;
       
  2198 	User::LeaveIfError(iBmBuffer->Create(aNewSize, aDisplayMode));
       
  2199 	iBmDevice = CFbsBitmapDevice::NewL(iBmBuffer);
       
  2200 	iBmGc = CFbsBitGc::NewL();
       
  2201 	iBmGc->Activate(iBmDevice);
       
  2202 	}
       
  2203 
       
  2204 void CVideoAppView::EnsureSizeInTwipsSet(CFbsBitmap* aBitmap) const
       
  2205 	{
       
  2206 	// ensure the bitmap has twips size set - this allows us to use DrawBitmap
       
  2207 	// note this does not itself resize the bitmap - size in pixels remains unchanged
       
  2208 	TSize size = aBitmap->SizeInTwips();
       
  2209 	ASSERT(size.iWidth==0 && size.iHeight==0 || size.iWidth>0 && size.iHeight>0); 
       
  2210 		// assumption that if we've set the size it is properly formatted
       
  2211 	if (size==TSize(0,0))
       
  2212 		{
       
  2213 		CWsScreenDevice *const screenDevice = iEikonEnv->ScreenDevice();
       
  2214 		size = aBitmap->SizeInPixels();
       
  2215 		size.iWidth = screenDevice->HorizontalTwipsToPixels(size.iWidth);
       
  2216 		size.iHeight = screenDevice->VerticalTwipsToPixels(size.iHeight);
       
  2217 		aBitmap->SetSizeInTwips(size);
       
  2218 		}
       
  2219 	}
       
  2220 
       
  2221 void CVideoAppView::Clear(TBool aClearFull, TDrawNow aDrawNow)
       
  2222 	{
       
  2223 	// if we have a bitmap buffer clear that. Otherwise clear the whole screen depending
       
  2224 	// on aClearFull
       
  2225 	if (iBmGc)
       
  2226 		{
       
  2227 		iBmGc->Reset();
       
  2228 		iBmGc->SetPenStyle(CGraphicsContext::ENullPen);
       
  2229 		iBmGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  2230 		iBmGc->SetBrushColor(iBackgroundColor);
       
  2231 		iBmGc->Clear();
       
  2232 		}
       
  2233 	if (aDrawNow!=ENoDrawNow)
       
  2234 		{
       
  2235 		if (aClearFull)
       
  2236 			DrawNow();
       
  2237 		else
       
  2238 			{
       
  2239 			ActivateGc();
       
  2240 			CWindowGc& gc = SystemGc();
       
  2241 			RWindow& window = Window();
       
  2242 			window.Invalidate(iBmRect);
       
  2243 			window.BeginRedraw(iBmRect);
       
  2244 			gc.SetPenStyle(CGraphicsContext::ENullPen);
       
  2245 			gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  2246 			gc.SetBrushColor(iBackgroundColor);
       
  2247 			gc.Clear();
       
  2248 			window.EndRedraw();
       
  2249 			DeactivateGc();
       
  2250 			}
       
  2251 		}
       
  2252 	}
       
  2253 
       
  2254 
       
  2255 void CVideoAppView::MoveBy(const TPoint& aRelMove, TDrawNow aDrawNow)
       
  2256 	{
       
  2257 	iBmRect.Move(aRelMove);
       
  2258 
       
  2259 	if (aDrawNow!=ENoDrawNow)
       
  2260 		DrawNow();
       
  2261 	}
       
  2262 
       
  2263 void CVideoAppView::Center(TDrawNow aDrawNow)
       
  2264 	{
       
  2265 	ASSERT(iBitmapValid && iBmRect.Size() == iBmBuffer->SizeInPixels()); // should only be called when size setup properly
       
  2266 
       
  2267 #ifdef CENTRE_IMAGE
       
  2268 	const TPoint center = Rect().Center();
       
  2269 	const TSize bitmapSize = iBmRect.Size();
       
  2270 	const TPoint requiredTl (center.iX-bitmapSize.iWidth/2, center.iY-bitmapSize.iHeight/2);
       
  2271 	const TRect newRect(requiredTl, bitmapSize);
       
  2272 	iBmRect = newRect;
       
  2273 #endif
       
  2274 
       
  2275 	ASSERT(iBitmapValid && iBmRect.Size() == iBmBuffer->SizeInPixels()); // checked worked
       
  2276 
       
  2277 	if (aDrawNow!=ENoDrawNow)
       
  2278 		DrawNow();
       
  2279 	}
       
  2280 
       
  2281 TBool CVideoAppView::SetBackgroundColor(const TRgb& aColor, TDrawNow aDrawNow)
       
  2282 	{
       
  2283 	TBool changed = iBackgroundColor!=aColor;
       
  2284 
       
  2285 	iBackgroundColor = aColor;
       
  2286 
       
  2287 	if (aDrawNow!=ENoDrawNow)
       
  2288 		DrawNow();
       
  2289 
       
  2290 	return changed;
       
  2291 	}
       
  2292 
       
  2293 void CVideoAppView::SetDisplayModeL(TDisplayMode aDisplayMode, CWsBitmap* aFrame, TDrawNow aDrawNow)
       
  2294 	{
       
  2295 	
       
  2296 	TBool change=aDisplayMode!=iDisplayMode;
       
  2297 
       
  2298 	iDisplayMode = aDisplayMode; 
       
  2299 
       
  2300 	if (iBitmapValid && change)
       
  2301 		{
       
  2302 		ASSERT(iBmBuffer->Handle());
       
  2303 
       
  2304 		// temp buffer becomes copy of original
       
  2305 		CFbsBitmap* tempBuffer = new (ELeave) CWsBitmap(iCoeEnv->WsSession());
       
  2306 		CleanupStack::PushL(tempBuffer);
       
  2307 		User::LeaveIfError(tempBuffer->Duplicate(iBmBuffer->Handle()));
       
  2308 
       
  2309 		ASSERT(iBmRect.Size()==iBmBuffer->SizeInPixels()); // should be the same
       
  2310 		ResizeBufferL(iBmBuffer->SizeInPixels(), iDisplayMode);
       
  2311 			// change bitmap
       
  2312 
       
  2313 		// bitblt original back
       
  2314 		iBmGc->BitBlt(TPoint(0,0), tempBuffer);
       
  2315 		CleanupStack::PopAndDestroy(); // tempBuffer
       
  2316 
       
  2317 		aFrame->Reset(); // reset the frame
       
  2318 		aFrame->Duplicate(iBmBuffer->Handle()); // duplicate the aFrame bitmap handle 
       
  2319 		}
       
  2320 
       
  2321 	Window().SetRequiredDisplayMode(iDisplayMode);
       
  2322 
       
  2323 	if (aDrawNow!=ENoDrawNow)
       
  2324 		DrawNow();
       
  2325 	}
       
  2326 
       
  2327 //
       
  2328 // CVideoDisplayModeDialog
       
  2329 //
       
  2330 
       
  2331 // list of supported display modes (it matches r_video_display_mode_array in TImageViewer.rss)
       
  2332 
       
  2333 const TDisplayMode KDispMode[] = { EGray2, EGray4, EGray16, EGray256, EColor16, EColor256, EColor4K, EColor64K, EColor16M, EColor16MU, EColor16MA, EColor16MAP };
       
  2334 const TInt KNumDispMode = sizeof(KDispMode) / sizeof(KDispMode[0]);
       
  2335 
       
  2336 CVideoDisplayModeDialog::CVideoDisplayModeDialog(TDisplayMode& aDisplayMode,TBool& aUseNativeDisplayMode):
       
  2337 	iDisplayMode(aDisplayMode), iUseNativeDisplayMode(aUseNativeDisplayMode)
       
  2338 	{}
       
  2339 
       
  2340 void CVideoDisplayModeDialog::PreLayoutDynInitL()
       
  2341 	{
       
  2342 	TInt choice = -1;
       
  2343 
       
  2344 	for (TInt index=0; index<KNumDispMode; index++)
       
  2345 		{
       
  2346 		if (KDispMode[index]==iDisplayMode)
       
  2347 			{
       
  2348 			choice = index;
       
  2349 			break;
       
  2350 			}
       
  2351 		}
       
  2352 		
       
  2353 	SetCheckBoxState(EVideoIdUseImageNativeMode, iUseNativeDisplayMode ? CEikButtonBase::ESet : CEikButtonBase::EClear);
       
  2354 
       
  2355 	ASSERT(choice>=0); // should always match something
       
  2356 	SetChoiceListCurrentItem(EVideoIdDisplayMode,choice);
       
  2357 	}
       
  2358 
       
  2359 TBool CVideoDisplayModeDialog::OkToExitL(TInt /*aButtonId*/)
       
  2360 	{
       
  2361 	const TInt chosenIndex = ChoiceListCurrentItem(EVideoIdDisplayMode);
       
  2362 	ASSERT(chosenIndex<KNumDispMode);
       
  2363 	iDisplayMode = KDispMode[chosenIndex];
       
  2364 	iUseNativeDisplayMode = CheckBoxState(EVideoIdUseImageNativeMode) == CEikButtonBase::ESet ? ETrue : EFalse;	
       
  2365 	return ETrue;
       
  2366 	}
       
  2367 
       
  2368 //
       
  2369 // CVideoBackgroundColorDialog
       
  2370 //
       
  2371 
       
  2372 CVideoBackgroundColorDialog::CVideoBackgroundColorDialog(TInt& aColor16, TBool& aOverride):
       
  2373 	iColor16(aColor16), iOverride(aOverride)
       
  2374 	{}
       
  2375 
       
  2376 void CVideoBackgroundColorDialog::PreLayoutDynInitL()
       
  2377 	{
       
  2378 	CEikButtonBase::TState state = iOverride ? CEikButtonBase::ESet : CEikButtonBase::EClear;
       
  2379 	SetCheckBoxState(EVideoIdOverrideBackgroundColor, state);
       
  2380 	SetChoiceListCurrentItem(EVideoIdBackgroundColor,iColor16);
       
  2381 	if (!iOverride)
       
  2382 		SetLineDimmedNow(EVideoIdBackgroundColor,ETrue);
       
  2383 	}
       
  2384 
       
  2385 TBool CVideoBackgroundColorDialog::OkToExitL(TInt /*aButtonId*/)
       
  2386 	{
       
  2387 	iColor16 = ChoiceListCurrentItem(EVideoIdBackgroundColor);
       
  2388 	CEikButtonBase::TState state = CheckBoxState(EVideoIdOverrideBackgroundColor);
       
  2389 	iOverride = state != CEikButtonBase::EClear;
       
  2390 	return ETrue;
       
  2391 	}
       
  2392 
       
  2393 void CVideoBackgroundColorDialog::HandleControlStateChangeL(TInt aControlId)
       
  2394 	{
       
  2395 	if (aControlId == EVideoIdOverrideBackgroundColor)
       
  2396 		{
       
  2397 		CEikButtonBase::TState state = CheckBoxState(EVideoIdOverrideBackgroundColor);
       
  2398 		TBool isSet = state != CEikButtonBase::EClear;
       
  2399 		SetLineDimmedNow(EVideoIdBackgroundColor,!isSet);
       
  2400 		}
       
  2401 	}
       
  2402 
       
  2403 //
       
  2404 // CVideoCurrentFrameDialog
       
  2405 //
       
  2406 
       
  2407 CVideoCurrentFrameDialog::CVideoCurrentFrameDialog(TInt& aCurrentFrame,TInt aNumberOfFrames):
       
  2408 	iCurrentFrame(aCurrentFrame),
       
  2409 	iNumberOfFrames(aNumberOfFrames)
       
  2410 	{}
       
  2411 
       
  2412 void CVideoCurrentFrameDialog::PreLayoutDynInitL()
       
  2413 	{
       
  2414 	SetNumberEditorValue(EVideoIdNumberOfFrames,iNumberOfFrames);
       
  2415 	SetLineDimmedNow(EVideoIdNumberOfFrames,ETrue);
       
  2416 	const TInt lastFrame = iNumberOfFrames - 1;
       
  2417 	SetNumberEditorMinAndMax(EVideoIdCurrentFrameNumber,0,lastFrame);
       
  2418 	SetNumberEditorValue(EVideoIdCurrentFrameNumber,Min(iCurrentFrame,lastFrame));
       
  2419 	}
       
  2420 
       
  2421 TBool CVideoCurrentFrameDialog::OkToExitL(TInt /*aButtonId*/)
       
  2422 	{
       
  2423 	iCurrentFrame = NumberEditorValue(EVideoIdCurrentFrameNumber);
       
  2424 	return ETrue;
       
  2425 	}
       
  2426 
       
  2427 //
       
  2428 // CVideoSaveAsDialog
       
  2429 //
       
  2430 
       
  2431 CVideoSaveAsDialog::CVideoSaveAsDialog(TDes* aFileName,TFileSaveInfo& aSaveInfo,RArray<TInt>& aEncodeOperations,TBool& aCreateThumbnail,TBool& aSaveAsEXIF):
       
  2432 	CEikFileSaveAsDialog(aFileName),
       
  2433 	iSaveInfo(aSaveInfo),
       
  2434 	iEncodeOperations(aEncodeOperations),
       
  2435 	iCreateThumbnail(&aCreateThumbnail),
       
  2436 	iSaveAsEXIF(&aSaveAsEXIF)
       
  2437 	{}
       
  2438 
       
  2439 void CVideoSaveAsDialog::PreLayoutDynInitL()
       
  2440 	{
       
  2441 	SetTypeL();
       
  2442 	SetCheckBoxState(EVideoIdCreateThumbnailChbx, *iCreateThumbnail ? CEikButtonBase::ESet : CEikButtonBase::EClear);
       
  2443 	SetCheckBoxState(EVideoIdSaveAsEXIFChbx, *iSaveAsEXIF ? CEikButtonBase::ESet : CEikButtonBase::EClear);
       
  2444 
       
  2445 	CEikFileSaveAsDialog::PreLayoutDynInitL();
       
  2446 	}
       
  2447 
       
  2448 void CVideoSaveAsDialog::SetTypeL()
       
  2449 	{
       
  2450 	const TUid imageType = iSaveInfo.iImageTypeUid;
       
  2451 
       
  2452 	if(imageType == KImageTypeBMPUid)
       
  2453 		SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_BMP);
       
  2454 	else if(imageType == KImageTypeGIFUid)
       
  2455 		SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_GIF);
       
  2456 	else if(imageType == KImageTypeJPGUid)
       
  2457 		{
       
  2458 		if ( *iSaveAsEXIF )
       
  2459 			{
       
  2460 			SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_EXIF);
       
  2461 			}
       
  2462 			else
       
  2463 			{
       
  2464 			SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_JPEG);
       
  2465 			}
       
  2466 		}
       
  2467 	else if(imageType == KImageTypeMBMUid)
       
  2468 		SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_MBM);
       
  2469 	else if(imageType == KImageTypePNGUid)
       
  2470 		SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_PNG);
       
  2471 	else
       
  2472 		SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_CUSTOM);
       
  2473 
       
  2474 	}
       
  2475 
       
  2476 void CVideoSaveAsDialog::HandleControlStateChangeL(TInt aControlId)
       
  2477 	{
       
  2478 	if (aControlId == EVideoIdSaveAsEXIFChbx)
       
  2479 		{
       
  2480 		*iSaveAsEXIF = CheckBoxState(EVideoIdSaveAsEXIFChbx) == CEikButtonBase::ESet ? ETrue : EFalse;	
       
  2481 		SetTypeL();
       
  2482 		}
       
  2483 	}
       
  2484 	
       
  2485 TBool CVideoSaveAsDialog::OkToExitL(TInt aButtonId)
       
  2486 	{
       
  2487 	if (aButtonId == EVideoIdSaveAsFormat)
       
  2488 		{
       
  2489 		CEikDialog* dialog = new(ELeave) CVideoFormatDialog(iSaveInfo);
       
  2490 		if (dialog->ExecuteLD(R_VIDEO_FILE_FORMAT_DIALOG))
       
  2491 			SetTypeL();
       
  2492 
       
  2493 		return EFalse;
       
  2494 		}
       
  2495 	else if (aButtonId == EVideoIdEncodeOperations)
       
  2496 		{
       
  2497 		CEikDialog* dialog = new(ELeave) CExtensionOptionsDialog(iEncodeOperations);
       
  2498 		dialog->ExecuteLD(R_VIDEO_ENCODER_EXTENSION_DIALOG);
       
  2499 		return EFalse;
       
  2500 		}
       
  2501 	else if (aButtonId == EEikBidOk)
       
  2502 		{
       
  2503 		*iCreateThumbnail = CheckBoxState(EVideoIdCreateThumbnailChbx) == CEikButtonBase::ESet ? ETrue : EFalse;	
       
  2504 		*iSaveAsEXIF = CheckBoxState(EVideoIdSaveAsEXIFChbx) == CEikButtonBase::ESet ? ETrue : EFalse;	
       
  2505 		}
       
  2506 
       
  2507 	return CEikFileSaveAsDialog::OkToExitL(aButtonId);
       
  2508 	}
       
  2509 
       
  2510 SEikControlInfo CVideoSaveAsDialog::CreateCustomControlL(TInt /*aControlType*/)
       
  2511 	{
       
  2512 	/* never called */
       
  2513 	SEikControlInfo info;
       
  2514 	info.iTrailerTextId = 0;
       
  2515 	info.iFlags = 0;
       
  2516 	info.iControl = new (ELeave) CEikTextListBox;
       
  2517 	return info;
       
  2518 	}
       
  2519 //
       
  2520 // CVideoFormatDialog
       
  2521 //
       
  2522 
       
  2523 CVideoFormatDialog::CVideoFormatDialog(TFileSaveInfo& aSaveInfo):
       
  2524 	iSaveInfo(aSaveInfo)
       
  2525 	{}
       
  2526 
       
  2527 void CVideoFormatDialog::PreLayoutDynInitL()
       
  2528 	{
       
  2529 	CEikChoiceList* formatList = STATIC_CAST(CEikChoiceList*,Control(EVideoIdFileFormatType));
       
  2530 
       
  2531 	//Add the available encoders to the dialog
       
  2532 	iEncoderList = CPluginInfoArray::NewL();
       
  2533 	formatList->SetArrayL(iEncoderList); //ownership of iEncoderList passed to dialog
       
  2534 
       
  2535 	const TInt noOfEncoders = iEncoderList->MdcaCount();
       
  2536 	if(noOfEncoders == 0)
       
  2537 		User::Leave(KErrNotFound);
       
  2538 	
       
  2539 	//Find the index for the selected encoder (via ImageTypeUid)
       
  2540 	//if it is not found use the first
       
  2541 	TInt index;
       
  2542 	for(index=noOfEncoders-1; index > 0; index--)
       
  2543 		{
       
  2544 		if(iEncoderList->ImageType(index) == iSaveInfo.iImageTypeUid)
       
  2545 			break;
       
  2546 		}
       
  2547 	iSaveInfo.iImageTypeUid = iEncoderList->ImageType(index);
       
  2548 
       
  2549 	SetChoiceListCurrentItem(EVideoIdFileFormatType,index);
       
  2550 	SetChoiceListCurrentItem(EVideoIdFileFormatBpp,iSaveInfo.iBpp);
       
  2551 	SetChoiceListCurrentItem(EVideoIdFileFormatColor,iSaveInfo.iColor);
       
  2552 	SetNumberEditorValue(EVideoIdFileFormatFactor,iSaveInfo.iQualityFactor);
       
  2553 	SetChoiceListCurrentItem(EVideoIdFileFormatSampling,iSaveInfo.iSampling);
       
  2554 	SetChoiceListCurrentItem(EVideoIdFileFormatCompression,iSaveInfo.iCompression);
       
  2555 
       
  2556 	ValidateControlState();
       
  2557 	}
       
  2558 
       
  2559 void CVideoFormatDialog::HandleControlStateChangeL(TInt /*aControlId*/)
       
  2560 	{
       
  2561 	ValidateControlState();
       
  2562 	}
       
  2563 
       
  2564 void CVideoFormatDialog::ValidateControlState()
       
  2565 	{
       
  2566 	TInt type = ChoiceListCurrentItem(EVideoIdFileFormatType);
       
  2567 	TInt bpp = ChoiceListCurrentItem(EVideoIdFileFormatBpp);
       
  2568 	TInt color = ChoiceListCurrentItem(EVideoIdFileFormatColor);
       
  2569 	TInt compression = ChoiceListCurrentItem(EVideoIdFileFormatCompression);
       
  2570 
       
  2571 	TBool bppVisible = ETrue;
       
  2572 	TBool colorVisible = ETrue;
       
  2573 	TBool factorVisible = EFalse;
       
  2574 	TBool samplingVisible = EFalse;
       
  2575 	TBool compressionVisible = EFalse;
       
  2576 
       
  2577 
       
  2578 	const TUid imageType = iEncoderList->ImageType(type);
       
  2579 
       
  2580 	if(imageType == KImageTypeBMPUid)
       
  2581 		{
       
  2582 		colorVisible = EFalse;
       
  2583 		if (bpp == 1)
       
  2584 			bpp = 2;
       
  2585 		else if ((bpp > 3) && (bpp < 6))
       
  2586 			bpp = 6;
       
  2587 		else if (bpp > 6)
       
  2588 			bpp = 0;
       
  2589 		}
       
  2590 	else if(imageType == KImageTypeGIFUid)
       
  2591 		{
       
  2592 		bppVisible = EFalse;
       
  2593 		colorVisible = EFalse;
       
  2594 		}
       
  2595 	else if(imageType == KImageTypeJPGUid)
       
  2596 		{
       
  2597 		bppVisible = EFalse;
       
  2598 		factorVisible = ETrue;
       
  2599 		if (color)
       
  2600 			samplingVisible = ETrue;
       
  2601 		}
       
  2602 	else if(imageType == KImageTypeMBMUid)
       
  2603 		{
       
  2604 		if (color == 0)
       
  2605 			{
       
  2606 			if (bpp > 3)
       
  2607 				bpp = 0;
       
  2608 			}
       
  2609 		else
       
  2610 			{
       
  2611 			if (bpp < 2)
       
  2612 				bpp = 2;
       
  2613 			}
       
  2614 		}
       
  2615 	else if(imageType == KImageTypePNGUid)
       
  2616 		{
       
  2617 		if ((bpp > 3) && (bpp < 6))
       
  2618 			bpp = 6;
       
  2619 		else if (bpp > 6)
       
  2620 			bpp = 0;
       
  2621 		compressionVisible = ETrue;
       
  2622 		}
       
  2623 	else //Custom encoder
       
  2624 		{
       
  2625 		bppVisible = EFalse;
       
  2626 		colorVisible = EFalse;
       
  2627 		}
       
  2628 
       
  2629 	SetChoiceListCurrentItem(EVideoIdFileFormatBpp,bpp);
       
  2630 	SetChoiceListCurrentItem(EVideoIdFileFormatColor,color);
       
  2631 	SetChoiceListCurrentItem(EVideoIdFileFormatCompression,compression);
       
  2632 
       
  2633 	MakeLineVisible(EVideoIdFileFormatBpp,bppVisible);
       
  2634 	MakeLineVisible(EVideoIdFileFormatColor,colorVisible);
       
  2635 	MakeLineVisible(EVideoIdFileFormatFactor,factorVisible);
       
  2636 	MakeLineVisible(EVideoIdFileFormatSampling,samplingVisible);
       
  2637 	MakeLineVisible(EVideoIdFileFormatCompression,compressionVisible);
       
  2638 	}
       
  2639 
       
  2640 TBool CVideoFormatDialog::OkToExitL(TInt /*aButtonId*/)
       
  2641 	{
       
  2642 	TInt type = ChoiceListCurrentItem(EVideoIdFileFormatType);
       
  2643 	iSaveInfo.iImageTypeUid = iEncoderList->ImageType(type);
       
  2644 	iSaveInfo.iBpp = ChoiceListCurrentItem(EVideoIdFileFormatBpp);
       
  2645 	iSaveInfo.iColor = ChoiceListCurrentItem(EVideoIdFileFormatColor);
       
  2646 	iSaveInfo.iQualityFactor = NumberEditorValue(EVideoIdFileFormatFactor);
       
  2647 	iSaveInfo.iSampling = ChoiceListCurrentItem(EVideoIdFileFormatSampling);
       
  2648 	iSaveInfo.iCompression = ChoiceListCurrentItem(EVideoIdFileFormatCompression);
       
  2649 
       
  2650 	return ETrue;
       
  2651 	}
       
  2652 	
       
  2653 CDecoderOptionsDialog::CDecoderOptionsDialog(TUint& aOptions):iOptions(aOptions)
       
  2654 	{
       
  2655 	}
       
  2656 
       
  2657 	// from CEikDialog
       
  2658 void CDecoderOptionsDialog::PreLayoutDynInitL()
       
  2659 	{
       
  2660 	SetCheckBoxState(EVideoIdUseThreadForDecoder, iOptions&CImageDecoder::EOptionAlwaysThread ? CEikButtonBase::ESet : CEikButtonBase::EClear);
       
  2661 	SetCheckBoxState(EVideoIdDecoderDisableDithering,  iOptions&CImageDecoder::EOptionNoDither ? CEikButtonBase::ESet : CEikButtonBase::EClear);
       
  2662 	SetCheckBoxState(EVideoIdDecoderAutogenMask, iOptions&CImageDecoder::EAllowGeneratedMask ? CEikButtonBase::ESet : CEikButtonBase::EClear);
       
  2663 	SetCheckBoxState(EVideoIdDecodeHighSpeedDecode, iOptions&CImageDecoder::EPreferFastDecode ? CEikButtonBase::ESet : CEikButtonBase::EClear);
       
  2664 	SetCheckBoxState(EVideoIdAutoRotateDecode, iOptions&CImageDecoder::EOptionAutoRotate ? CEikButtonBase::ESet : CEikButtonBase::EClear);
       
  2665 	}
       
  2666 	
       
  2667 TBool CDecoderOptionsDialog::OkToExitL(TInt /*aButtonId*/)
       
  2668 	{
       
  2669 	iOptions = CheckBoxState(EVideoIdUseThreadForDecoder) 		== CEikButtonBase::ESet ? CImageDecoder::EOptionAlwaysThread : 0;
       
  2670 	iOptions|= CheckBoxState(EVideoIdDecoderDisableDithering) 	== CEikButtonBase::ESet ? CImageDecoder::EOptionNoDither : 0;
       
  2671 	iOptions|= CheckBoxState(EVideoIdDecoderAutogenMask) 		== CEikButtonBase::ESet ? CImageDecoder::EAllowGeneratedMask : 0;
       
  2672 	iOptions|= CheckBoxState(EVideoIdDecodeHighSpeedDecode) 	== CEikButtonBase::ESet ? CImageDecoder::EPreferFastDecode : 0;
       
  2673 	iOptions|= CheckBoxState(EVideoIdAutoRotateDecode) 			== CEikButtonBase::ESet ? CImageDecoder::EOptionAutoRotate : 0;
       
  2674 	
       
  2675 	return ETrue;
       
  2676 	}
       
  2677 
       
  2678 CExtensionOptionsDialog::CExtensionOptionsDialog(TRect& aClippingRect,
       
  2679 							RArray<TInt>& aOperations,
       
  2680 							TInt& aScalingCoefficient,
       
  2681 							TImageConvScaler::TScalerQuality& aScalingQuality,
       
  2682 							TBool& aLockAspectRatio) 
       
  2683  : iClippingRect(&aClippingRect), iOperations(aOperations), iScalingCoefficient(&aScalingCoefficient), 
       
  2684    iScalingQuality(&aScalingQuality), iLockAspectRatio(&aLockAspectRatio)
       
  2685 	{
       
  2686 	iSelectedOperations = new (ELeave) CDesCArrayFlat(20);
       
  2687 	}
       
  2688 
       
  2689 CExtensionOptionsDialog::CExtensionOptionsDialog(RArray<TInt>& aOperations) 
       
  2690  : iOperations(aOperations)
       
  2691 	{
       
  2692 	iSelectedOperations = new (ELeave) CDesCArrayFlat(20);
       
  2693 	iOperationOnly = ETrue;
       
  2694 	}
       
  2695 
       
  2696 void CExtensionOptionsDialog::PageChangedL(TInt /*aPageId*/)
       
  2697 	{
       
  2698 	// enable/disable add and clear buttons which are only enabled on Operation Page
       
  2699 // The lines below panic on teh Control call. Looks like a dialog button is not a control
       
  2700 //	Control(EVideoIdAdd)->SetDimmed(aPageId != EDecoderExtensionOperationPage);
       
  2701 //	Control(EVideoIdClear)->SetDimmed(aPageId != EDecoderExtensionOperationPage);
       
  2702 	}
       
  2703 
       
  2704 	// from CEikDialog
       
  2705 void CExtensionOptionsDialog::PreLayoutDynInitL()
       
  2706 	{
       
  2707 	if ( !iOperationOnly )
       
  2708 		{
       
  2709 		// crop rect number edits
       
  2710 		static_cast<CEikNumberEditor*>(Control(EVideoIdCropTopLeftX))->SetNumber(iClippingRect->iTl.iX);
       
  2711 		static_cast<CEikNumberEditor*>(Control(EVideoIdCropTopLeftY))->SetNumber(iClippingRect->iTl.iY);	
       
  2712 		static_cast<CEikNumberEditor*>(Control(EVideoIdCropWidth))->SetNumber(iClippingRect->Width());	
       
  2713 		static_cast<CEikNumberEditor*>(Control(EVideoIdCropHeight))->SetNumber(iClippingRect->Height());
       
  2714 		
       
  2715 		/* scaling
       
  2716 			coefficient number edit
       
  2717 			quality choicelist
       
  2718 			aspectratio checkbox
       
  2719 	    */
       
  2720 		static_cast<CEikNumberEditor*>(Control(EVideoIdScaleCoeff))->SetNumber(*iScalingCoefficient);	
       
  2721 		static_cast<CEikChoiceList*>(Control(EVideoIdScaleQuality))->SetCurrentItem(*iScalingQuality);	
       
  2722 		SetCheckBoxState(EVideoIdScalePreserveAspect, *iLockAspectRatio ? CEikButtonBase::ESet : CEikButtonBase::EClear);
       
  2723 		}
       
  2724 			
       
  2725 	/* operations
       
  2726 		fill selected operations
       
  2727 	*/
       
  2728 	CEikTextListBox* selectOpsListBox = static_cast<CEikTextListBox*>(Control(EVideoIdSelectedOperations));
       
  2729 	
       
  2730 	selectOpsListBox->CreateScrollBarFrameL();
       
  2731 	selectOpsListBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOn);
       
  2732 	
       
  2733 	operationName[0] = _L("0x01 | ERotation90DegreesClockwise");
       
  2734 	operationName[1] = _L("0x02 | ERotation180DegreesClockwise");
       
  2735 	operationName[2] = _L("0x04 | ERotation270DegreesClockwise");
       
  2736 	operationName[3] = _L("0x08 | EMirrorHorizontalAxis");
       
  2737 	operationName[4] = _L("0x10 | EMirrorVerticalAxis");
       
  2738 		
       
  2739 	for (TInt i = 0; i < iOperations.Count(); i++)
       
  2740 		{
       
  2741 		if ( iOperations[i] > 0 )
       
  2742 			{
       
  2743 			TInt temp = iOperations[i];
       
  2744 			TInt shiftCount = 0;
       
  2745 			while ( temp )
       
  2746 				{
       
  2747 				temp = temp >> 1;
       
  2748 				++shiftCount;
       
  2749 				}
       
  2750 			iSelectedOperations->AppendL(operationName[shiftCount-1]);
       
  2751 			}
       
  2752 		}
       
  2753 	
       
  2754 	selectOpsListBox->Model()->SetItemTextArray(iSelectedOperations);
       
  2755 	selectOpsListBox->Model()->SetOwnershipType(ELbmDoesNotOwnItemArray);
       
  2756  	
       
  2757 	}
       
  2758 
       
  2759 // DEF115967: Panic while editing Setup extensions Value
       
  2760 void CExtensionOptionsDialog::PrepareForFocusTransitionL()
       
  2761 	{
       
  2762 	// The dialog will check for blank input in the control that
       
  2763 	// has been edited. If it is blank the value 9999...9 will be
       
  2764 	// placed there to ensure control->Number() returns something.
       
  2765 	// There appears to be no way of getting a different value put
       
  2766 	// in a blank control (IsBlank function is protected).
       
  2767 
       
  2768 	CEikDialog::PrepareForFocusTransitionL();
       
  2769 	}
       
  2770 
       
  2771 
       
  2772 SEikControlInfo CExtensionOptionsDialog::CreateCustomControlL(TInt /*aControlType*/)
       
  2773 	{
       
  2774 	/* never called */
       
  2775 	SEikControlInfo info;
       
  2776 	info.iTrailerTextId = 0;
       
  2777 	info.iFlags = 0;
       
  2778 	info.iControl = new (ELeave) CEikTextListBox;
       
  2779 	return info;
       
  2780 	}
       
  2781 		
       
  2782 TBool CExtensionOptionsDialog::OkToExitL(TInt aButtonId)
       
  2783 	{
       
  2784 	TBool exit = EFalse;
       
  2785 	
       
  2786 	switch ( aButtonId )
       
  2787 		{
       
  2788 	case EEikBidOk:
       
  2789 		{
       
  2790 		if ( !iOperationOnly )
       
  2791 			{
       
  2792 			// get crop rect 
       
  2793 			iClippingRect->iTl.iX = static_cast<CEikNumberEditor*>(Control(EVideoIdCropTopLeftX))->Number();
       
  2794 			iClippingRect->iTl.iY = static_cast<CEikNumberEditor*>(Control(EVideoIdCropTopLeftY))->Number();	
       
  2795 			iClippingRect->SetWidth(static_cast<CEikNumberEditor*>(Control(EVideoIdCropWidth))->Number());	
       
  2796 			iClippingRect->SetHeight(static_cast<CEikNumberEditor*>(Control(EVideoIdCropHeight))->Number());
       
  2797 
       
  2798 			// get scaling
       
  2799 			*iScalingCoefficient = static_cast<CEikNumberEditor*>(Control(EVideoIdScaleCoeff))->Number();	
       
  2800 			*iScalingQuality = static_cast<TImageConvScaler::TScalerQuality>
       
  2801 				(static_cast<CEikChoiceList*>(Control(EVideoIdScaleQuality))->CurrentItem());	
       
  2802 			*iLockAspectRatio = (CheckBoxState(EVideoIdScalePreserveAspect) == CEikButtonBase::ESet) ? ETrue : EFalse;
       
  2803 			}
       
  2804 			
       
  2805 		// get operations 
       
  2806 		CTextListBoxModel * selectOpsModel = static_cast<CEikTextListBox*>(Control(EVideoIdSelectedOperations))->Model();
       
  2807 		iOperations.Reset();
       
  2808 		for (TInt i = 0; i < selectOpsModel->NumberOfItems(); i++)
       
  2809 			{
       
  2810 			TLex enumLex(selectOpsModel->ItemText(i).Mid(2,2)); // Hex value of enum
       
  2811 			TUint operation = 0;
       
  2812 			enumLex.Val(operation,EHex);
       
  2813 			iOperations.Append(operation);
       
  2814 			}
       
  2815 		}
       
  2816 		// deliberate fall through
       
  2817 	case EEikBidCancel:
       
  2818 		{
       
  2819 		// iOperations fill up from iSeletedOperations
       
  2820 		delete iSelectedOperations; 
       
  2821 		exit = ETrue;
       
  2822 		}
       
  2823 		break;
       
  2824 
       
  2825 	case EVideoIdAdd:
       
  2826 		{
       
  2827 		TInt currentItem = static_cast<CEikChoiceList*>(Control(EVideoIdOperations))->CurrentItem();
       
  2828 		iSelectedOperations->AppendL(operationName[currentItem]);
       
  2829 		CEikTextListBox* selectOpsListBox = static_cast<CEikTextListBox*>(Control(EVideoIdSelectedOperations));
       
  2830 		selectOpsListBox->Model()->SetItemTextArray(iSelectedOperations);
       
  2831 		selectOpsListBox->HandleItemAdditionL();
       
  2832 		}
       
  2833 		break;				
       
  2834 
       
  2835 	case EVideoIdClear:
       
  2836 		{
       
  2837 		iSelectedOperations->Reset();
       
  2838 		CEikTextListBox* selectOpsListBox = static_cast<CEikTextListBox*>(Control(EVideoIdSelectedOperations));
       
  2839 		selectOpsListBox->Model()->SetItemTextArray(iSelectedOperations);
       
  2840 		selectOpsListBox->HandleItemAdditionL();		
       
  2841 		}
       
  2842 		break;
       
  2843 		
       
  2844 	default:
       
  2845 		break;
       
  2846 		}
       
  2847 
       
  2848 	return exit;
       
  2849 	}
       
  2850 
       
  2851 //
       
  2852 // CVideoWalker implementation
       
  2853 //
       
  2854 
       
  2855 CVideoWalker* CVideoWalker::NewL(CVideoAppUi* aAppUi)
       
  2856 	{
       
  2857 	CVideoWalker* result = new (ELeave) CVideoWalker(aAppUi);
       
  2858 	return result;
       
  2859 	}
       
  2860 
       
  2861 CVideoWalker::CVideoWalker(CVideoAppUi* aAppUi):
       
  2862 	CActive(CActive::EPriorityStandard),
       
  2863 	iAppUi(aAppUi)
       
  2864 	{
       
  2865 	CActiveScheduler::Add(this);
       
  2866 	}
       
  2867 
       
  2868 CVideoWalker::~CVideoWalker()
       
  2869 	{
       
  2870 	Cancel();
       
  2871 	}
       
  2872 
       
  2873 // used when we need to pass status variable - simultaneously calls SetActive
       
  2874 TRequestStatus& CVideoWalker::ActiveStatus()
       
  2875 	{
       
  2876 	SetActive();
       
  2877 	return iStatus;
       
  2878 	}
       
  2879 
       
  2880 // for completion ASAP on this
       
  2881 void CVideoWalker::SelfComplete(TInt aError)
       
  2882 	{
       
  2883 	TRequestStatus* status = &ActiveStatus();
       
  2884 	User::RequestComplete(status, aError);
       
  2885 	}
       
  2886 
       
  2887 // calls AppUi->RunL() which is expected to handle the call
       
  2888 void CVideoWalker::RunL()
       
  2889 	{
       
  2890 	iAppUi->RunL(this, iStatus.Int());
       
  2891 	}
       
  2892 
       
  2893 // calls AppUi->DoCancel() which is expected to handle the call
       
  2894 void CVideoWalker::DoCancel()
       
  2895 	{
       
  2896 	iAppUi->DoCancel(this);
       
  2897 	}
       
  2898 
       
  2899 //
       
  2900 // CVideoDocument
       
  2901 //
       
  2902 
       
  2903 CVideoDocument::CVideoDocument(CEikApplication& aApp)
       
  2904 		: CEikDocument(aApp)
       
  2905 	{
       
  2906 	}
       
  2907 
       
  2908 CEikAppUi* CVideoDocument::CreateAppUiL()
       
  2909 	{
       
  2910     return new(ELeave) CVideoAppUi;
       
  2911 	}
       
  2912 
       
  2913 //
       
  2914 // CVideoApp
       
  2915 //
       
  2916 
       
  2917 TUid CVideoApp::AppDllUid() const
       
  2918 	{
       
  2919 	return KUidTVideo;
       
  2920 	}
       
  2921 
       
  2922 CApaDocument* CVideoApp::CreateDocumentL()
       
  2923 	{
       
  2924 	return new(ELeave) CVideoDocument(*this);
       
  2925 	}
       
  2926 
       
  2927 
       
  2928 //
       
  2929 // Base factory function
       
  2930 //
       
  2931 
       
  2932 #include <eikstart.h>
       
  2933 LOCAL_C CApaApplication* NewApplication()
       
  2934 	{
       
  2935 	return new CVideoApp;
       
  2936 	}
       
  2937 
       
  2938 //
       
  2939 // EXE Entry point
       
  2940 //
       
  2941 
       
  2942 GLDEF_C TInt E32Main()
       
  2943 	{
       
  2944 	return EikStart::RunApplication(NewApplication);
       
  2945 	}
       
  2946