--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmplugins/imagingplugins/codecs/PNGCodec/PngDecoderFactory.cpp Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,293 @@
+// 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:
+//
+
+#include <ecom/ecom.h>
+#include "PNGCodec.h"
+
+#include "PngDecoderFactory.h"
+
+
+
+/*static*/
+MImageStreamDecoderFactory* CPngImageStreamDecoderFactory::NewL()
+ {
+ return static_cast<MImageStreamDecoderFactory*>(new (ELeave) CPngImageStreamDecoderFactory());
+ }
+
+
+CPngImageStreamDecoderFactory::CPngImageStreamDecoderFactory()
+ {
+ }
+
+CPngImageStreamDecoderFactory::~CPngImageStreamDecoderFactory()
+ {
+ REComSession::DestroyedImplementation(iDtorKey);
+ }
+
+// MImageStreamDecoderFactory //
+void CPngImageStreamDecoderFactory::SetDtorKey(TUid aUid)
+ {
+ iDtorKey = aUid;
+ }
+
+void CPngImageStreamDecoderFactory::Release()
+ {
+ ASSERT(iDtorKey.iUid);
+ delete this;
+ }
+
+class CPngImage: protected CPngReadCodec, protected MPngDecoder, public MImageStreamDecoder
+ {
+public:
+ static CPngImage* NewL();
+
+// from the MImageStreamDecoder //
+ virtual void InitL(CImageProcessor& aImageProcessor, CImageProcessor* aMaskProcessor, CFbsBitmap* aDestination,
+ const TPtrC8& aData, MUniqueChunkDataProvider& aProvider);
+ virtual void DecodeL();
+ virtual void ResetL();
+ virtual void Release();
+ virtual const TSize& ImageSize();
+
+protected:
+ CPngImage();
+
+ virtual void DoProcessPLTEL(const TUint8* aDataPtr,TInt aChunkLength);
+ virtual void DoProcesstRNSL(const TUint8* aDataPtr,TInt aChunkLength);
+ virtual void DoProcessbKGDL(const TUint8* aDataPtr,TInt aChunkLength);
+ virtual void DoProcesspHYsL(const TUint8* aDataPtr,TInt aChunkLength);
+
+ void InitFrameL();
+// from the MPngDecoder //
+ void GoToProcessDataState();
+
+protected:
+ CPngImage(const TBufPtr8& aData);
+ TFrameInfo iFrameInfo;
+ TBufPtr8 iCurrentData;
+ TBufPtr8 iData;
+ MUniqueChunkDataProvider* iChunkProvider;
+ TBool iDataProcessing;
+ TBool ibKGDChunkFound;
+ TBool ipHYsChunkFound;
+ TBool itRNSChunkFound;
+ CFbsBitmap* iCurrentFrame; //destination bitmap; not owned.
+ };
+
+/*static*/
+CPngImage* CPngImage::NewL()
+ {
+ return new (ELeave) CPngImage();
+ }
+
+CPngImage::CPngImage():CPngReadCodec(static_cast<MPngDecoder&>(*this))
+ {
+ }
+
+void CPngImage::Release()
+ {
+ delete this;
+ }
+
+void CPngImage::GoToProcessDataState()
+ {
+ iDataProcessing = ETrue;
+ }
+
+void CPngImage::InitL(CImageProcessor& aImageProcessor, CImageProcessor* aMaskProcessor, CFbsBitmap* aDestination,
+ const TPtrC8& aData, MUniqueChunkDataProvider& aProvider)
+ {
+ CPngReadCodec::ConstructL();
+ iCurrentFrame = aDestination;
+ SetImageProcessor(&aImageProcessor, EFalse);
+ if (NULL != aMaskProcessor)
+ {
+ SetMaskProcessor(aMaskProcessor, EFalse);
+ }
+ iCurrentData.Set(aData);
+ iData.Set(aData);
+ iChunkProvider = &aProvider;
+
+ TFrameInfo inf;
+ inf.SetCurrentFrameState(TFrameInfo::EFrameInfoUninitialised);
+ CFrameImageData* DummyData=NULL;
+ InitFrameHeader(inf, *DummyData );
+ ProcessFrameHeaderL( iCurrentData );
+ if (!ibKGDChunkFound)
+ {
+ const TUint8* Ptr;
+ TInt ChunkLength;
+ if (KErrNone == iChunkProvider->GetChunkData(KPngbKGDChunkId().Ptr(), Ptr, ChunkLength))
+ {
+ DoProcessbKGDL(Ptr, ChunkLength);
+ }
+ }
+ if (!ipHYsChunkFound)
+ {
+ const TUint8* Ptr;
+ TInt ChunkLength;
+ if (KErrNone == iChunkProvider->GetChunkData(KPngpHYsChunkId().Ptr(), Ptr, ChunkLength))
+ {
+ DoProcesspHYsL(Ptr, ChunkLength);
+ }
+ }
+ InitFrameL();
+ }
+
+void CPngImage::ResetL()
+ {
+ iCurrentData.Set(iData);
+ iDataProcessing = EFalse;
+ ibKGDChunkFound = EFalse;
+ ipHYsChunkFound = EFalse;
+ itRNSChunkFound = EFalse;
+ InitFrameL();
+ }
+
+const TSize& CPngImage::ImageSize()
+ {
+ return iImageInfo.iSize;
+ }
+
+void CPngImage::DoProcessPLTEL(const TUint8* aDataPtr,TInt aChunkLength)
+ {
+ if (0 == aChunkLength)
+ {
+ const TUint8* Plte;
+ if (KErrNone == iChunkProvider->GetChunkData(KPngPLTEChunkId().Ptr(), Plte, aChunkLength))
+ {
+ // try to get inherited tRNS as well...
+ const TUint8* Trns;
+ TInt TrnsLen=0;
+ if (!itRNSChunkFound && KErrNone == iChunkProvider->GetChunkData(KPngtRNSChunkId().Ptr(), Trns, TrnsLen))
+ {
+ CPngReadCodec::DoProcesstRNSL(Trns, TrnsLen);
+ }
+ aDataPtr = Plte;
+ }
+ }
+ CPngReadCodec::DoProcessPLTEL(aDataPtr, aChunkLength);
+ }
+
+void CPngImage::DoProcesstRNSL(const TUint8* aDataPtr,TInt aChunkLength)
+ {
+ if (0 == aChunkLength)
+ {
+ const TUint8* Trns;
+ if (KErrNone == iChunkProvider->GetChunkData(KPngtRNSChunkId().Ptr(), Trns, aChunkLength))
+ {
+ aDataPtr = Trns;
+ }
+ }
+ itRNSChunkFound = (0 != aChunkLength);
+ CPngReadCodec::DoProcesstRNSL(aDataPtr,aChunkLength);
+ }
+
+void CPngImage::DoProcessbKGDL(const TUint8* aDataPtr,TInt aChunkLength)
+ {
+ if (0 == aChunkLength || ibKGDChunkFound)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ ibKGDChunkFound = ETrue;
+ CPngReadCodec::DoProcessbKGDL(aDataPtr,aChunkLength);
+ }
+
+void CPngImage::DoProcesspHYsL(const TUint8* aDataPtr,TInt aChunkLength)
+ {
+ if (0 == aChunkLength || ipHYsChunkFound)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ ipHYsChunkFound = ETrue;
+ CPngReadCodec::DoProcessbKGDL(aDataPtr,aChunkLength);
+ }
+
+void CPngImage::InitFrameL()
+ {
+ iChunkBytesRemaining = 0;
+ iChunkId = KNullDesC8;
+
+
+ if (iDecoder == NULL)
+ {
+ TBool fastProcessorMode = EFalse;
+ CFastProcessor* fastProc = NULL;
+ SetFastProcessor(NULL);
+
+ /*Check if Image processor is to be ignored.
+ Ignore Image processor only when decoding 24 or 32 bpp images.
+ In case of non interlaced images and if destination and source height/width differ then don't skip Image processor.
+ */
+ if (((iImageInfo.iBitDepth == 8) && (iImageInfo.iColorType == TPngImageInformation::EDirectColor || iImageInfo.iColorType == TPngImageInformation::EAlphaDirectColor)) && (iImageInfo.iInterlaceMethod == TPngImageInformation::ENoInterlace) && (iImageInfo.iTransparencyPresent == EFalse ))
+ {
+
+ CFbsBitmap* destBitmap=NULL;
+
+ fastProc = CFastProcessor::NewL(iImageInfo, destBitmap, NULL, ETrue);
+ SetFastProcessor(fastProc);
+ fastProcessorMode = ETrue;
+ }
+
+ iDecoder = CPngReadSubCodec::NewL(ImageProcessor(), MaskProcessor(), iImageInfo , FastProcessor(), fastProcessorMode);
+ iDecoder->SetRgbaMode(ETrue);
+ }
+
+ if (iDecompressor == NULL)
+ {
+ iDecompressor = CEZDecompressor::NewL(*this);
+ }
+
+ }
+
+void CPngImage::DecodeL()
+ {
+ const TPoint ZeroPoint(0,0);
+ const TRect ImageRect(ZeroPoint, ImageSize().AsPoint());
+
+ if ((iImageInfo.iTransparencyPresent || (iImageInfo.iColorType & TPngImageInformation::EAlphaChannelUsed))
+ && MaskProcessor() )
+ {
+
+ MaskProcessor()->PrepareL(*iCurrentFrame, ImageRect);
+ MaskProcessor()->SetPos(ZeroPoint);
+ }
+
+ ImageProcessor()->PrepareL(*iCurrentFrame, ImageRect);
+ ImageProcessor()->SetPos(ZeroPoint);
+
+ while (EFrameIncomplete == ProcessFrameL( iCurrentData ))
+ {
+ if (iDataProcessing)
+ {
+ while ( ! DoProcessDataL() )
+ {
+ (void)0;
+ }
+ }
+ iDataProcessing = EFalse;
+ }
+ delete iDecompressor;
+ iDecompressor=NULL;
+ iDecoder->ResetL();
+ }
+
+// MImageStreamDecoderFactory //
+void CPngImageStreamDecoderFactory::CreatePngDecoderL(MImageStreamDecoder*& aPtr)
+ {
+ aPtr = NULL;
+ aPtr = static_cast<MImageStreamDecoder*>( CPngImage::NewL() );
+ }
+