mmplugins/imagingplugins/imagedisplay/plugins/mng/MngReadCodec.cpp
changeset 0 40261b775718
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmplugins/imagingplugins/imagedisplay/plugins/mng/MngReadCodec.cpp	Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,287 @@
+// Copyright (c) 2005-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 <icl/imagecodec.h>
+#include <icl/imagedata.h>
+#include <icl/imagedisplayplugin.h>
+#include "MngPlayer.h"
+#include "MngChunks.h"
+#include "MngRenderer.h"
+
+#include "MngReadCodec.h"
+
+/*static*/
+CMngReadCodec* CMngReadCodec::NewL(CMngFileReadStream& aMngReadStream, MMngCodecObserver& aObserver, TBool aMngSubframesNoLoops)  //Subframes with No Loops
+	{
+	CMngReadCodec* self = new (ELeave) CMngReadCodec(aObserver, aMngSubframesNoLoops);
+	CleanupStack::PushL(self);
+	self->ConstructL(aMngReadStream);
+	CleanupStack::Pop(self); 
+	return self;
+	}
+
+CMngReadCodec::~CMngReadCodec()
+	{
+	delete iMngPlayer;
+	if (iMngReadStream)
+		{
+		iMngReadStream->Release();
+		iMngReadStream = NULL;
+		}
+	}
+
+void CMngReadCodec::ConstructL(CMngFileReadStream& aMngReadStream)
+	{
+	CImageMaskProcessorReadCodec::ConstructL();
+	
+	iMngReadStream = &aMngReadStream;
+	iMngReadStream->AddRef();
+
+	CreatePlayerL();
+	Restart();
+	}
+
+void CMngReadCodec::CreatePlayerL()
+	{
+	ASSERT(iMngPlayer==NULL);
+	TMNGChunkHeader header;
+	iMngReadStream->SeekL(KMngSignatureSize);
+	header.ReadL(*iMngReadStream);
+	if (header.iChunkId != KMhdrChunkId)
+		{
+		User::Leave(KErrCorrupt);
+		}
+	TMhdrChunk* headerChunk = new (ELeave) TMhdrChunk(header);
+	CleanupDeletePushL(headerChunk);
+	headerChunk->ReadL(*iMngReadStream);
+
+	iMngPlayer= CMngPlayer::NewL(iMngReadStream, *this, iMngSubframesNoLoops);  //Subframes with No Loops
+	iImageFeatures = (&headerChunk->iNominalPlayTime)[1];	// get the next word following the iNominalPlayTime
+	iMngPlayer->SetMngHeader(headerChunk);
+	iMngPlayer->SetInternalDelayOn(EFalse);
+	CleanupStack::Pop(); // headerChunk
+	iMngReadStream->SeekL(0); // set srteam position back to the beginning	
+	}
+
+void CMngReadCodec::StopDecode()
+	{
+	if (iMngPlayer)
+		{
+		iMngPlayer->StopDecode();
+		}
+	delete iMngPlayer;
+	iMngPlayer = NULL;
+	Restart();
+	}
+
+void CMngReadCodec::Restart()
+	{
+	iFrameStatus= 0;
+	iFrameNumber= 0;
+	iFrameDelay = 0;
+	}
+
+void CMngReadCodec::DecodeL()
+	{
+	if (iMngPlayer == NULL)
+		{
+		CreatePlayerL();
+		//set the destination bitmap to mngplayer
+		iMngPlayer->SetDestinationBitmap(iCurrentFrame);
+		}
+	
+	iMngPlayer->SetRequiredDisplayModes(iCurrentFrame->DisplayMode(), iCurrentMask ? iCurrentMask->DisplayMode() : ENone);
+		
+	if (iFrameNumber !=0 ) // that's not the first frame, so fetch bitmaps from MngPlayer
+		{
+		User::LeaveIfError( GetBitmaps() );
+		}
+	// that's last frame, so we have to send it to client
+	if (iFrameStatus & CImageDisplayPlugin::EStatusNoMoreToDecode) 
+		{
+		SendFrameUpdate(KErrNone);
+		}
+	else
+		{
+		iMngPlayer->Decode();
+		}
+	}
+
+void CMngReadCodec::InitFrameL(TFrameInfo& /*aFrameInfo*/, CFrameImageData& /*aFrameImageData*/,
+								TBool /*aDisableErrorDiffusion*/, 
+								CFbsBitmap& aDestination, CFbsBitmap* aDestinationMask)
+	{
+	if (aDestination.DisplayMode() != EColor16M &&
+		aDestination.DisplayMode() != EColor16MA &&
+		aDestination.DisplayMode() != EColor16MU)
+		{
+		User::Leave(KErrNotSupported);
+		}
+	
+	if (aDestinationMask && aDestinationMask->DisplayMode() != EGray256)
+		{
+		User::Leave(KErrNotSupported);
+		}
+		
+	iCurrentFrame	= &aDestination;
+	iCurrentMask	= aDestinationMask;
+	//set the destination bitmap to mngplayer
+	if(iMngPlayer)
+		{
+		iMngPlayer->SetDestinationBitmap(iCurrentFrame);
+		}
+	}
+
+TFrameState CMngReadCodec::ProcessFrameL(TBufPtr8& /*aSrc*/)
+	{
+	return TFrameState();
+	}
+
+
+void CMngReadCodec::InitFrameHeader(TFrameInfo& aFrameSettings, CFrameImageData& /* aFrameImageData */)
+	{
+	ASSERT(aFrameSettings.CurrentFrameState() == TFrameInfo::EFrameInfoUninitialised);
+	iFrameInfo = &aFrameSettings;
+	iFrameInfo->SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingFrame); //EFrameInfoProcessingFrameHeader ?
+	iFrameInfo->iOverallSizeInPixels	=iMngPlayer->FrameSize();
+	iFrameInfo->iFrameCoordsInPixels.SetSize( iFrameInfo->iOverallSizeInPixels );
+	iFrameInfo->iFrameDisplayMode		= EColor16M;
+	iFrameInfo->iBitsPerPixel			= 24;
+	iFrameInfo->iFlags					= TFrameInfo::EColor | TFrameInfo::ERestoreToBackground |
+		(iMngPlayer->IsAlphaNeeded()? TFrameInfo::ETransparencyPossible|TFrameInfo::EAlphaChannel : 0);
+	}
+
+TInt CMngReadCodec::ReducedSize(const TSize& aOriginalSize, TInt /* aReductionFactor */, TSize& aReducedSize) const
+	{
+	aReducedSize = aOriginalSize;
+	return KErrArgument;
+	}
+
+TInt CMngReadCodec::GetBitmaps()
+	{
+	//updatedrect
+	//Subframes with No Loops
+    
+    TSize mngSize;
+	
+	if(iMngSubframesNoLoops)
+		{
+		mngSize = iFrameRect.Size(); 
+		}
+	else
+    	{
+    	mngSize = iMngPlayer->FrameSize();
+		iFrameRect.SetRect(TPoint(0,0), mngSize.AsPoint());
+    	}
+	
+	TInt error=KErrNone;
+	if (mngSize != iCurrentFrame->SizeInPixels())
+		{
+		error=iCurrentFrame->Resize(mngSize);
+		}
+		
+	if (iCurrentMask && error==KErrNone && mngSize != iCurrentMask->SizeInPixels())
+		{
+		error=iCurrentMask->Resize(mngSize);
+		}
+	if (error!=KErrNone )
+		{
+		return error;
+		}
+
+	iMngPlayer->Renderer()->CurrentFrame(*iCurrentFrame, iFrameRect );
+	if (iCurrentMask)
+		{
+		iMngPlayer->Renderer()->CurrentMask(*iCurrentMask, iFrameRect );
+		}
+	return KErrNone;
+	}
+
+void CMngReadCodec::OnDecodeEvent(TUint aEventFlags, TInt aErrorCode)
+	{
+	if (aEventFlags==0)
+		{
+		iObserver.OnCodecEvent(MMngCodecObserver::KDataParseCompleted, aErrorCode);
+		iMngPlayer->Pause();
+		return;
+		}
+	if (aErrorCode!=KErrNone)
+		{
+		iFrameInfo->iFlags &= ( ~TUint(TFrameInfo::EMngMoreFramesToDecode) );
+		iObserver.OnCodecEvent(MMngCodecObserver::KDecodeCompleted, aErrorCode);
+		}
+	else	// we have got frame decoded
+		{
+		//Subframes with No Loops
+		if(iMngSubframesNoLoops)
+			{
+			iFrameRect = iMngPlayer->Renderer()->UpdatedRect();
+			
+			if(iFrameRect.Height() < 0)
+				{
+				iFrameRect.SetRect(0,0,0,0);
+				}
+				
+			if(iFrameRect.Width() < 0) 
+				{
+				iFrameRect.SetRect(0,0,0,0);
+				}
+				
+			iMngPlayer->Renderer()->UpdateRectEmpty();
+			}
+		//
+		if (iFrameNumber != 0) // that's not the first frame
+			{
+			iFrameDelay = iMngPlayer->ThisFrameDelay();
+			iMngPlayer->Pause();
+			SendFrameUpdate(aErrorCode);
+			}
+		else
+			{
+			aErrorCode=GetBitmaps();
+			}
+		++iFrameNumber;
+		iFrameStatus= aEventFlags;
+		// image has got only 1 frame, so send update right now
+		if (iFrameNumber==1 && (iFrameStatus & CImageDisplayPlugin::EStatusNoMoreToDecode))
+			{
+			SendFrameUpdate(aErrorCode);
+			}
+		}
+	}
+
+void CMngReadCodec::SendFrameUpdate(TInt aError)
+	{
+	iFrameInfo->iFlags &=(TFrameInfo::ELeaveInPlace-1);
+	iFrameInfo->iFlags |= ((iFrameStatus & CImageDisplayPlugin::EStatusNoMoreToDecode)==0? TFrameInfo::EMngMoreFramesToDecode : 0);
+	iFrameInfo->iFlags |= TFrameInfo::ERestoreToBackground;
+	iFrameInfo->iDelay = TInt64(iFrameDelay.Int());
+	iFrameInfo->iFrameCoordsInPixels = iFrameRect ;
+	iFrameInfo->iBackgroundColor=iMngPlayer->Renderer()->BgColour();
+	iObserver.OnCodecEvent(MMngCodecObserver::KFrameReady, aError);
+
+#if !defined(DISABLE_LOGGING) && defined(_DEBUG)
+	RDebug::Print(_L("Mng Frame#%4d Delay b4 next=%5d Rect(%d,%d)-(%d,%d)"),iFrameNumber, iFrameDelay.Int(),
+									iFrameInfo->iFrameCoordsInPixels.iTl.iX, iFrameInfo->iFrameCoordsInPixels.iTl.iY,
+									iFrameInfo->iFrameCoordsInPixels.iBr.iX, iFrameInfo->iFrameCoordsInPixels.iBr.iY
+									);
+#endif
+	}
+