mmplugins/imagingplugins/imagedisplay/plugins/mng/MngProcessor.cpp
changeset 0 40261b775718
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmplugins/imagingplugins/imagedisplay/plugins/mng/MngProcessor.cpp	Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,258 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/** 	@file
+	@internalTechnology */
+#include "MngPlayer.h"
+#include "MngPanic.h"
+#include "logger.h"
+
+#include "MngProcessor.h"
+
+class MngChunkFactory 
+	{
+public:
+	static	TMngChunk*	CreateChunkObjectL(const TMNGChunkHeader& aHeader);
+	};
+
+/*static*/
+TMngChunk* MngChunkFactory::CreateChunkObjectL(const TMNGChunkHeader& aHeader)
+	{
+	TMngChunk* pChunk=NULL;
+	switch (aHeader.iChunkId.iChunkIdInt)
+		{
+		case KMhdrChunkId:
+			pChunk=new (ELeave) TMhdrChunk(aHeader);
+			break;
+		case KDefiChunkId:
+			pChunk=new (ELeave) TDefiChunk(aHeader);
+			break;
+		case KTermChunkId:
+			pChunk=new (ELeave) TTermChunk(aHeader);
+			break;
+		case KBackChunkId:
+			pChunk=new (ELeave) TBackChunk(aHeader);
+			break;
+		case KMagnChunkId:
+			pChunk=new (ELeave) TMagnChunk(aHeader);
+			break;
+		case KFramChunkId:
+			pChunk=new (ELeave) TFramChunk(aHeader);
+			break;
+		case KLoopChunkId:
+			pChunk=new (ELeave) TLoopChunk(aHeader);
+			break;
+		case KEndlChunkId:
+			pChunk=new (ELeave) TEndlChunk(aHeader);
+			break;
+
+		case KMendChunkId:
+		case KPlteChunkId:
+		case KTrnsChunkId:
+		case KBkgdChunkId:
+		case KPhysChunkId:
+			pChunk=TMngRawChunk::CreateL(aHeader);
+			break;
+			
+		//With MNG_LC we do not support the following chunks
+		case KPastChunkId:
+		case KBasiChunkId:
+		case KMoveChunkId:
+		case KGamaChunkId:
+			User::Leave(KErrNotSupported);
+			break;
+			
+		default:
+			// Unknown chunk
+			pChunk = NULL;
+		}
+	return pChunk;
+	}
+
+
+/*static*/
+CMngProcessor* CMngProcessor::NewL(CMngPlayer& aMngPlayer, TBool aMngSubframesNoLoops)  //Subframes with No Loops
+	{
+	CMngProcessor* self=new (ELeave) CMngProcessor(aMngPlayer, aMngSubframesNoLoops); //Subframes with No Loops
+	return self;
+	}
+
+CMngProcessor::CMngProcessor(CMngPlayer& aMngPlayer, TBool aMngSubframesNoLoops):  //Subframes with No Loops
+							           		CChunkProcessor(aMngPlayer),
+							           		iMngSubframesNoLoops(aMngSubframesNoLoops)  //Subframes with No Loops
+	{
+	}
+
+CMngProcessor::~CMngProcessor()
+	{
+	delete iCurrentChunk;
+	iCurrentChunk = NULL;
+	Stop();
+	}
+
+void CMngProcessor::DoRunL()
+	{
+	switch (iState)
+		{
+		case EReadMngSignature:
+			iInputStream->WaitForData(KMngSignatureSize, iStatus);
+			iState=TState(iState+1);
+			SetActive();
+			break;
+
+		case ECheckSignature:
+			iInputStream->ReadL(iSignature);
+			if (0 != iSignature.Compare(KMngSignature))
+				{
+				User::Leave(KErrCorrupt);
+				}
+			iState=TState(iState+1);
+			RunAgain();
+			break;
+
+		case EReadHeader:
+			delete iCurrentChunk;
+			iCurrentChunk = NULL;
+			if (iInputStream->DataAvailable() < TMNGChunkHeader::RequiredData() )
+				{
+				iInputStream->WaitForData(TMNGChunkHeader::RequiredData(), iStatus);
+				SetActive();
+				break;
+				}
+			else 
+				{
+				TMNGChunkHeader Header;
+				Header.ReadL(*iInputStream);
+				LOG3("Chunk %4s, len=%d", Header.iChunkId.iChunkIdChr, Header.iLength);
+				iCurrentChunk=MngChunkFactory::CreateChunkObjectL(Header);
+				if (NULL == iCurrentChunk) //unknown one 
+					{
+					if (NULL != iSubProcessor && iSubProcessor->OfferChunkType(Header.iChunkId))
+						{
+						iInputStream->SeekL(iInputStream->Tell() - TMNGChunkHeader::RequiredData());
+						iSubProcessor->Start(*iInputStream, iStatus);
+						SetActive();
+						iState=EReadHeader;
+						break;
+						}
+					else
+						{
+						iCurrentChunk = new (ELeave) TUnknownChunk(Header);
+						}
+					}
+				}
+			// go further for reading the chunk body
+		case EReadChunk:
+			iState=EReadChunk;
+			if (iInputStream->DataAvailable() < iCurrentChunk->RequiredData() )
+				{
+				iInputStream->WaitForData(iCurrentChunk->RequiredData(), iStatus);
+				SetActive();
+				break;
+				}
+			else
+				{
+				iCurrentChunk->ReadL(*iInputStream);
+				switch (iCurrentChunk->iHeader.iChunkId.iChunkIdInt)
+					{
+					case KMhdrChunkId:
+						iMngPlayer.InitL(reinterpret_cast<TMhdrChunk*&>(iCurrentChunk));
+						iState = EReadHeader;
+						RunAgain();
+						break;
+					case KTermChunkId:
+						{
+						CMngTermination* pTerm=CMngTermination::NewL(reinterpret_cast<TTermChunk*&>(iCurrentChunk), iMngSubframesNoLoops); //Subframes with No Loops
+						iMngPlayer.SetTerminationCtrlL(pTerm);
+						iState = EReadHeader;
+						RunAgain();
+						}
+
+						break;
+					case KMendChunkId:
+						NotifyCaller(KErrNone);
+						delete iCurrentChunk;
+						iCurrentChunk = NULL;
+						break;
+					
+					//Subframes with No Loops
+					case KLoopChunkId:  //deliberate fall through to default case
+					case KEndlChunkId:
+					    if(iMngSubframesNoLoops)
+					    	{
+					    	iState = EReadHeader;
+							RunAgain();
+					    	break;
+					    	}
+								
+					default:
+						{
+						TMngChunk::TObjectFactoryFuncL FuncL=iCurrentChunk->MngObjectFactoryFunc();
+						if (NULL==FuncL)
+							{
+							delete iCurrentChunk;
+							iCurrentChunk = NULL;
+							}
+						else 
+							{
+							CMngObject* pObject=FuncL(iCurrentChunk);
+							iMngPlayer.AppendObjectL( pObject );
+							}
+							
+						iState = EReadHeader;
+						RunAgain();
+						}
+					}
+				}
+			break;
+
+		default:
+			ASSERT(EFalse);
+		}
+	}
+
+void CMngProcessor::Start(MInputStream& aInputStream, TRequestStatus& aRequest)
+	{
+	if (NULL != iCallerRequest)
+		{
+		MngPanic(EPanicAlreadyStarted);
+		}
+	iCallerRequest	= &aRequest;
+	*iCallerRequest	= KRequestPending;
+	iInputStream	= &aInputStream;
+	iInputStream->AddRef();
+	iIsPaused = EFalse;
+	RunAgain();
+	}
+
+
+
+TInt CMngProcessor::AddSubProcessor(MChunkProcessor& aSubProcessor)
+	{
+	if (NULL != iSubProcessor)
+		{
+		MngPanic(EPanicNotImplementedYet);
+		}
+	iSubProcessor = &aSubProcessor;
+	return KErrNone;
+	}
+
+
+
+TBool CMngProcessor::OfferChunkType(const TChunkId& /*aChunkId*/)
+	{
+	ASSERT(EFalse);
+	return EFalse;
+	}