--- /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
+ }
+