imaging/imagingplugins/codecs/PNGCodec/PngDecoderFactory.cpp
changeset 0 5752a19fdefe
equal deleted inserted replaced
-1:000000000000 0:5752a19fdefe
       
     1 // Copyright (c) 2004-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 <ecom/ecom.h>
       
    17 #include "PNGCodec.h"
       
    18 
       
    19 #include "PngDecoderFactory.h"
       
    20 
       
    21 
       
    22 
       
    23 /*static*/
       
    24 MImageStreamDecoderFactory* CPngImageStreamDecoderFactory::NewL()
       
    25 	{
       
    26 	return static_cast<MImageStreamDecoderFactory*>(new (ELeave) CPngImageStreamDecoderFactory());
       
    27 	}
       
    28 
       
    29 
       
    30 CPngImageStreamDecoderFactory::CPngImageStreamDecoderFactory()
       
    31 	{
       
    32 	}
       
    33 
       
    34 CPngImageStreamDecoderFactory::~CPngImageStreamDecoderFactory()
       
    35 	{
       
    36 	REComSession::DestroyedImplementation(iDtorKey);
       
    37 	}
       
    38 
       
    39 // MImageStreamDecoderFactory // 
       
    40 void CPngImageStreamDecoderFactory::SetDtorKey(TUid aUid)
       
    41 	{
       
    42 	iDtorKey = aUid;
       
    43 	}
       
    44 
       
    45 void CPngImageStreamDecoderFactory::Release()
       
    46 	{
       
    47 	ASSERT(iDtorKey.iUid);
       
    48 	delete this;
       
    49 	}
       
    50 
       
    51 class CPngImage: protected CPngReadCodec, protected MPngDecoder, public MImageStreamDecoder 
       
    52 	{
       
    53 public:
       
    54 	static CPngImage* NewL();
       
    55 
       
    56 //  from the MImageStreamDecoder //
       
    57 	virtual void InitL(CImageProcessor& aImageProcessor, CImageProcessor* aMaskProcessor, CFbsBitmap* aDestination, 
       
    58 						const TPtrC8& aData, MUniqueChunkDataProvider& aProvider);
       
    59 	virtual void DecodeL();
       
    60 	virtual void ResetL();
       
    61 	virtual void Release();
       
    62 	virtual const TSize& ImageSize();	
       
    63 
       
    64 protected:
       
    65 	CPngImage();
       
    66 
       
    67 	virtual void DoProcessPLTEL(const TUint8* aDataPtr,TInt aChunkLength);
       
    68 	virtual void DoProcesstRNSL(const TUint8* aDataPtr,TInt aChunkLength);
       
    69 	virtual void DoProcessbKGDL(const TUint8* aDataPtr,TInt aChunkLength);
       
    70 	virtual void DoProcesspHYsL(const TUint8* aDataPtr,TInt aChunkLength);
       
    71 
       
    72 	void InitFrameL();
       
    73 // from the MPngDecoder  //
       
    74 	void GoToProcessDataState();
       
    75 	
       
    76 protected:
       
    77 	CPngImage(const TBufPtr8& aData);
       
    78 	TFrameInfo iFrameInfo;
       
    79 	TBufPtr8 iCurrentData;
       
    80 	TBufPtr8 iData;
       
    81 	MUniqueChunkDataProvider* iChunkProvider;
       
    82 	TBool iDataProcessing;
       
    83 	TBool ibKGDChunkFound;
       
    84 	TBool ipHYsChunkFound;
       
    85 	TBool itRNSChunkFound;
       
    86 	CFbsBitmap* iCurrentFrame; //destination bitmap; not owned.
       
    87 	};
       
    88 
       
    89 /*static*/
       
    90 CPngImage* CPngImage::NewL()
       
    91 	{
       
    92 	return new (ELeave) CPngImage();
       
    93 	}
       
    94 
       
    95 CPngImage::CPngImage():CPngReadCodec(static_cast<MPngDecoder&>(*this))
       
    96 	{
       
    97 	}
       
    98 
       
    99 void CPngImage::Release()
       
   100 	{
       
   101 	delete this;
       
   102 	}
       
   103 
       
   104 void CPngImage::GoToProcessDataState()
       
   105 	{
       
   106 	iDataProcessing = ETrue;
       
   107 	}
       
   108 
       
   109 void CPngImage::InitL(CImageProcessor& aImageProcessor, CImageProcessor* aMaskProcessor, CFbsBitmap* aDestination,
       
   110 						const TPtrC8& aData, MUniqueChunkDataProvider& aProvider)
       
   111 	{
       
   112 	CPngReadCodec::ConstructL();
       
   113 	iCurrentFrame = aDestination;
       
   114 	SetImageProcessor(&aImageProcessor, EFalse);
       
   115 	if (NULL != aMaskProcessor)
       
   116 		{
       
   117 		SetMaskProcessor(aMaskProcessor, EFalse);
       
   118 		}
       
   119 	iCurrentData.Set(aData);
       
   120 	iData.Set(aData);
       
   121 	iChunkProvider = &aProvider;
       
   122 
       
   123 	TFrameInfo inf; 
       
   124 	inf.SetCurrentFrameState(TFrameInfo::EFrameInfoUninitialised);
       
   125 	CFrameImageData* DummyData=NULL;
       
   126 	InitFrameHeader(inf, *DummyData );
       
   127 	ProcessFrameHeaderL( iCurrentData );
       
   128 	if (!ibKGDChunkFound)
       
   129 		{
       
   130 		const TUint8* Ptr;
       
   131 		TInt ChunkLength;
       
   132 		if (KErrNone == iChunkProvider->GetChunkData(KPngbKGDChunkId().Ptr(), Ptr, ChunkLength))
       
   133 			{
       
   134 			DoProcessbKGDL(Ptr, ChunkLength);
       
   135 			}
       
   136 		}
       
   137 	if (!ipHYsChunkFound)
       
   138 		{
       
   139 		const TUint8* Ptr;
       
   140 		TInt ChunkLength;
       
   141 		if (KErrNone == iChunkProvider->GetChunkData(KPngpHYsChunkId().Ptr(), Ptr, ChunkLength))
       
   142 			{
       
   143 			DoProcesspHYsL(Ptr, ChunkLength);
       
   144 			}
       
   145 		}
       
   146 	InitFrameL();
       
   147 	}
       
   148 
       
   149 void CPngImage::ResetL()
       
   150 	{
       
   151 	iCurrentData.Set(iData);
       
   152 	iDataProcessing = EFalse;
       
   153 	ibKGDChunkFound = EFalse;
       
   154 	ipHYsChunkFound	= EFalse;
       
   155 	itRNSChunkFound = EFalse;
       
   156 	InitFrameL();
       
   157 	}
       
   158 
       
   159 const TSize& CPngImage::ImageSize()
       
   160 	{
       
   161 	return iImageInfo.iSize;
       
   162 	}
       
   163 
       
   164 void CPngImage::DoProcessPLTEL(const TUint8* aDataPtr,TInt aChunkLength)
       
   165 	{
       
   166 	if (0 == aChunkLength)
       
   167 		{
       
   168 		const TUint8* Plte;
       
   169 		if (KErrNone == iChunkProvider->GetChunkData(KPngPLTEChunkId().Ptr(), Plte, aChunkLength))
       
   170 			{
       
   171 			// try to get inherited tRNS as well...
       
   172 			const TUint8* Trns;
       
   173 			TInt TrnsLen=0;
       
   174 			if (!itRNSChunkFound && KErrNone == iChunkProvider->GetChunkData(KPngtRNSChunkId().Ptr(), Trns, TrnsLen))
       
   175 				{
       
   176 				CPngReadCodec::DoProcesstRNSL(Trns, TrnsLen); 
       
   177 				}
       
   178 			aDataPtr = Plte;
       
   179 			}
       
   180 		}
       
   181 	CPngReadCodec::DoProcessPLTEL(aDataPtr, aChunkLength);
       
   182 	}
       
   183 
       
   184 void CPngImage::DoProcesstRNSL(const TUint8* aDataPtr,TInt aChunkLength)
       
   185 	{
       
   186 	if (0 == aChunkLength)
       
   187 		{
       
   188 		const TUint8* Trns;
       
   189 		if (KErrNone == iChunkProvider->GetChunkData(KPngtRNSChunkId().Ptr(), Trns, aChunkLength))
       
   190 			{
       
   191 			aDataPtr = Trns;
       
   192 			}
       
   193 		}
       
   194 	itRNSChunkFound = (0 != aChunkLength);
       
   195 	CPngReadCodec::DoProcesstRNSL(aDataPtr,aChunkLength);
       
   196 	}
       
   197 
       
   198 void CPngImage::DoProcessbKGDL(const TUint8* aDataPtr,TInt aChunkLength)
       
   199 	{
       
   200 	if (0 == aChunkLength || ibKGDChunkFound)
       
   201 		{
       
   202 		User::Leave(KErrCorrupt);
       
   203 		}
       
   204 	ibKGDChunkFound = ETrue;
       
   205 	CPngReadCodec::DoProcessbKGDL(aDataPtr,aChunkLength);
       
   206 	}
       
   207 
       
   208 void CPngImage::DoProcesspHYsL(const TUint8* aDataPtr,TInt aChunkLength)
       
   209 	{
       
   210 	if (0 == aChunkLength || ipHYsChunkFound)
       
   211 		{
       
   212 		User::Leave(KErrCorrupt);
       
   213 		}
       
   214 	ipHYsChunkFound = ETrue;
       
   215 	CPngReadCodec::DoProcessbKGDL(aDataPtr,aChunkLength);
       
   216 	}
       
   217 
       
   218 void CPngImage::InitFrameL()
       
   219 	{
       
   220 	iChunkBytesRemaining = 0;
       
   221 	iChunkId = KNullDesC8;
       
   222 
       
   223 		
       
   224 	if (iDecoder == NULL) 
       
   225 		{	
       
   226 		TBool fastProcessorMode = EFalse;
       
   227 		CFastProcessor* fastProc = NULL;
       
   228 		SetFastProcessor(NULL);
       
   229 		
       
   230 		/*Check if Image processor is to be ignored. 
       
   231 		Ignore Image processor only when decoding 24 or 32 bpp images.
       
   232 		In case of non interlaced images and if destination and source height/width differ then don't skip Image processor.
       
   233 		*/
       
   234 		if (((iImageInfo.iBitDepth == 8) && (iImageInfo.iColorType == TPngImageInformation::EDirectColor || iImageInfo.iColorType == TPngImageInformation::EAlphaDirectColor)) && (iImageInfo.iInterlaceMethod == TPngImageInformation::ENoInterlace) && (iImageInfo.iTransparencyPresent == EFalse ))
       
   235 			{
       
   236 			
       
   237 			CFbsBitmap* destBitmap=NULL;		
       
   238 			
       
   239 			fastProc = CFastProcessor::NewL(iImageInfo, destBitmap, NULL, ETrue);
       
   240 			SetFastProcessor(fastProc);
       
   241 			fastProcessorMode = ETrue;
       
   242 			}
       
   243 		
       
   244 		iDecoder = CPngReadSubCodec::NewL(ImageProcessor(), MaskProcessor(), iImageInfo , FastProcessor(), fastProcessorMode);
       
   245 		iDecoder->SetRgbaMode(ETrue);		
       
   246 		}
       
   247 
       
   248 	if (iDecompressor == NULL)
       
   249 		{
       
   250 		iDecompressor = CEZDecompressor::NewL(*this);
       
   251 		}
       
   252 		
       
   253 	}
       
   254 
       
   255 void CPngImage::DecodeL()
       
   256 	{
       
   257 	const TPoint ZeroPoint(0,0);
       
   258 	const TRect ImageRect(ZeroPoint, ImageSize().AsPoint());
       
   259 
       
   260 	if ((iImageInfo.iTransparencyPresent || (iImageInfo.iColorType & TPngImageInformation::EAlphaChannelUsed))
       
   261 		 && MaskProcessor() )
       
   262 		{		
       
   263 		
       
   264 		MaskProcessor()->PrepareL(*iCurrentFrame, ImageRect);
       
   265 		MaskProcessor()->SetPos(ZeroPoint);
       
   266 		}
       
   267 
       
   268 	ImageProcessor()->PrepareL(*iCurrentFrame, ImageRect);
       
   269 	ImageProcessor()->SetPos(ZeroPoint);
       
   270 
       
   271 	while (EFrameIncomplete == ProcessFrameL( iCurrentData )) 
       
   272 		{
       
   273 		if (iDataProcessing)
       
   274 			{
       
   275 			while (  ! DoProcessDataL() ) 
       
   276 				{
       
   277 				(void)0;
       
   278 				}
       
   279 			}
       
   280 		iDataProcessing = EFalse;
       
   281 		}
       
   282 	delete iDecompressor;
       
   283 	iDecompressor=NULL;
       
   284 	iDecoder->ResetL();
       
   285 	}
       
   286 
       
   287 // MImageStreamDecoderFactory // 
       
   288 void CPngImageStreamDecoderFactory::CreatePngDecoderL(MImageStreamDecoder*& aPtr)
       
   289 	{
       
   290 	aPtr = NULL;
       
   291 	aPtr = static_cast<MImageStreamDecoder*>(  CPngImage::NewL() );
       
   292 	}
       
   293