mmplugins/imagingplugins/codecs/PNGCodec/PngScanlineDecoder.cpp
changeset 0 40261b775718
child 14 cd271b19d824
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 1997-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 "PNGCodec.h"
       
    17 #include "ImageUtils.h"
       
    18 
       
    19 const TInt KPngScanlineFilterTypeLength = 1;
       
    20 
       
    21 const TInt KColStart[KPngNumInterlacedPasses] = { 0, 4, 0, 2, 0, 1, 0, 0 };
       
    22 const TInt KRowStart[KPngNumInterlacedPasses] = { 0, 0, 4, 0, 2, 0, 1, 0 };
       
    23 const TInt KColIncrement[KPngNumInterlacedPasses] = { 8, 8, 4, 4, 2, 2, 1, 0 };
       
    24 const TInt KRowIncrement[KPngNumInterlacedPasses] = { 8, 8, 8, 4, 4, 2, 2, 0 };
       
    25 const TInt KBlockWidth[KPngNumInterlacedPasses] = { 8, 4, 4, 2, 2, 1, 1, 0 };
       
    26 const TInt KBlockHeight[KPngNumInterlacedPasses] = { 8, 8, 4, 4, 2, 2, 1, 0 };
       
    27 
       
    28 const TInt KPngDepth1BytesPerPixel = 1;
       
    29 const TInt KPngDepth3BytesPerPixel = 3;
       
    30 const TInt KPngDepth4BytesPerPixel = 4;
       
    31 
       
    32 // CFastProcessor16MAto16MA
       
    33 /**This class is a specific implementation of CFastProcessor.
       
    34 It provides a conversion of 24bpp + 8bpp alpha to EColor16MA display mode.
       
    35 */
       
    36 class CFastProcessor16MAto16MA: public CFastProcessor
       
    37     {
       
    38 public:
       
    39 	CFastProcessor16MAto16MA(CFbsBitmap* aDestination, TBool aRgbaMode);
       
    40     void SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* aLineCache, TPoint& aPos);
       
    41     };
       
    42    
       
    43 // CFastProcessor16MAto16MAP
       
    44 /**This class is a specific implementation of CFastProcessor.
       
    45 It provides a conversion of 24bpp + 8bpp alpha to EColor16MAP display mode.
       
    46 */
       
    47 class CFastProcessor16MAto16MAP: public CFastProcessor
       
    48     {
       
    49 public:
       
    50 	CFastProcessor16MAto16MAP(CFbsBitmap* aDestination, TBool aRgbaMode);
       
    51     void SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* aLineCache, TPoint& aPos);
       
    52     };
       
    53    
       
    54 // CFastProcessor16MtoM
       
    55 /**This class is a specific implementation of CFastProcessor.
       
    56 It provides a conversion of 24bpp to EColor16M display mode. 
       
    57 */
       
    58 class CFastProcessor16Mto16M: public CFastProcessor
       
    59     {
       
    60 public:
       
    61 	CFastProcessor16Mto16M(CFbsBitmap* aDestination, TBool aRgbaMode);
       
    62     void SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* aLineCache, TPoint& aPos);
       
    63     };
       
    64 
       
    65 // CFastProcessor16MtoMA
       
    66 /**This class is a specific implementation of CFastProcessor.
       
    67 It provides a conversion of 24bpp to EColor16MU, EColor16MA or EColor16MAP display mode. 
       
    68 */
       
    69 class CFastProcessor16Mto16MA: public CFastProcessor
       
    70     {
       
    71 public:
       
    72 	CFastProcessor16Mto16MA(CFbsBitmap* aDestination, TBool aRgbaMode);
       
    73     void SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* aLineCache, TPoint& aPos);
       
    74     };
       
    75 
       
    76 // CFastProcessor16MAto16MU
       
    77 /**This class is a specific implementation of CFastProcessor.
       
    78 It provides a conversion of a 24bpp + 8bpp alpha source to a EColor16MU (setting alpha as 0xFF).
       
    79 */
       
    80 class CFastProcessor16MAto16MU: public CFastProcessor
       
    81     {
       
    82 public:
       
    83 	CFastProcessor16MAto16MU(CFbsBitmap* aDestination, TBool aRgbaMode);
       
    84     void SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* aLineCache, TPoint& aPos);
       
    85     };
       
    86 
       
    87 // CFastProcessor32bitTo32bitAndMask
       
    88 /**This class is a specific implementation of CFastProcessor.
       
    89 It provides a conversion of a 24bpp + 8bpp alpha source to an opaque 32 bit destination bitmap (i.e.
       
    90 setting the alpha channel to 0xFF) and EGray256 mask (which contains the alpha channel of the source).
       
    91 */
       
    92 class CFastProcessor32bitTo32bitAndMask: public CFastProcessor
       
    93     {
       
    94 public:
       
    95 	CFastProcessor32bitTo32bitAndMask(CFbsBitmap* aDestination, CFbsBitmap* aMask, TBool aRgbaMode);
       
    96     void SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* aLineCache, TPoint& aPos);
       
    97     };
       
    98 
       
    99 /**
       
   100 Constructs a new FastProcessor based on the conversion type.
       
   101 
       
   102 @param  aImageInfo
       
   103         A reference to TPngImageInformation for the FastProcessor to use.
       
   104 @param  aDestination
       
   105         A reference to the destination bitmap.
       
   106 @param  aRgbaMode
       
   107         This flag indicates that MNG frames are being processed.
       
   108 */
       
   109 CFastProcessor* CFastProcessor::NewL(const TPngImageInformation& aImageInfo, CFbsBitmap* aDestination, CFbsBitmap* aMask, TBool aRgbaMode)
       
   110     {
       
   111 	CFastProcessor* self = NULL;
       
   112 
       
   113 	if (aRgbaMode) //if MNG
       
   114 		{
       
   115 		if (aImageInfo.iColorType == TPngImageInformation::EDirectColor)
       
   116 			{
       
   117 			self = new (ELeave) CFastProcessor16Mto16MA(aDestination, aRgbaMode);	
       
   118 			}
       
   119 		else if(aImageInfo.iColorType == TPngImageInformation::EAlphaDirectColor)
       
   120 			{
       
   121 			self = new (ELeave) CFastProcessor16MAto16MA(aDestination, aRgbaMode);	
       
   122 			}
       
   123 		else
       
   124 			{
       
   125 			User::Leave(KErrNotSupported);	
       
   126 			}
       
   127 		}
       
   128 	else
       
   129 		{
       
   130 		TDisplayMode mode = aDestination->DisplayMode();
       
   131 		
       
   132 		switch (aImageInfo.iColorType)
       
   133 			{
       
   134 			case TPngImageInformation::EDirectColor:
       
   135 				if(EColor16M == mode)
       
   136 					{
       
   137 					self = new (ELeave) CFastProcessor16Mto16M(aDestination, aRgbaMode);	
       
   138 					}
       
   139 				else if(EColor16MAP == mode || EColor16MA == mode || EColor16MU == mode)
       
   140 					{
       
   141 					self = new (ELeave) CFastProcessor16Mto16MA(aDestination, aRgbaMode);	
       
   142 					}
       
   143 				break;
       
   144 
       
   145 			case TPngImageInformation::EAlphaDirectColor:
       
   146 				if(aMask && (EColor16MA == mode || EColor16MU == mode || EColor16MAP == mode))
       
   147 					{
       
   148 					self = new (ELeave) CFastProcessor32bitTo32bitAndMask(aDestination, aMask, aRgbaMode);
       
   149 					}
       
   150 				else if(EColor16MA == mode)
       
   151 					{
       
   152 					self = new (ELeave) CFastProcessor16MAto16MA(aDestination, aRgbaMode);	
       
   153 					}
       
   154 				else if(EColor16MAP == mode)
       
   155 					{
       
   156 					self = new (ELeave) CFastProcessor16MAto16MAP(aDestination, aRgbaMode);	
       
   157 					}
       
   158 				else if(EColor16MU == mode)
       
   159 					{
       
   160 					self = new (ELeave) CFastProcessor16MAto16MU(aDestination, aRgbaMode);
       
   161 					}
       
   162 				else
       
   163 					{
       
   164 					User::Leave(KErrNotSupported);	
       
   165 					}
       
   166 				break;
       
   167 		
       
   168 			default:
       
   169 				User::Leave(KErrNotSupported);
       
   170 				break;				
       
   171 			}		
       
   172 		}
       
   173 	
       
   174 	CleanupStack::PushL(self);
       
   175 	self->ConstructL();
       
   176 	CleanupStack::Pop(self); 
       
   177 	return self;	   
       
   178     }
       
   179 
       
   180 /**
       
   181 Destructor for this class.
       
   182 Releases the lock for the current bitmap.
       
   183 */
       
   184 CFastProcessor::~CFastProcessor()
       
   185     {
       
   186     }
       
   187 
       
   188 /**
       
   189 Second phase constructor.
       
   190 Requests a lock for the current bitmap.
       
   191 */    
       
   192 void CFastProcessor::ConstructL()
       
   193 	{
       
   194 	// NO-OP - reserved for changes at a later stage.
       
   195 	}
       
   196 
       
   197 /**
       
   198 Default constructor 
       
   199 */
       
   200 CFastProcessor::CFastProcessor(CFbsBitmap* aDestination, CFbsBitmap* aMask, TBool aRgbaMode)
       
   201     {
       
   202     iRgbaMode = aRgbaMode;
       
   203     
       
   204     if (!aRgbaMode)
       
   205 	    {
       
   206 	    iBitmap = aDestination;
       
   207 	    iBitmapSize = iBitmap->SizeInPixels();	
       
   208 		if (aMask)
       
   209 			{
       
   210 			ASSERT(aMask->SizeInPixels() == iBitmapSize);
       
   211 			iMask = aMask;
       
   212 			}
       
   213 		}    	
       
   214 	}
       
   215 
       
   216 /**
       
   217 Requests a lock for the current bitmap from the font & bitmap server and
       
   218 sets the current position in the bitmap to the first pixel.
       
   219 */
       
   220 void CFastProcessor::Begin()
       
   221 	{
       
   222 	if (!iRgbaMode)
       
   223 		{
       
   224 		if (iBitmapBuffer==NULL)
       
   225 			{
       
   226 			iBitmapBuffer = reinterpret_cast<TUint8*>( iBitmap->DataAddress() );
       
   227      		if (iMask)
       
   228      			{
       
   229      			iMaskBuffer = reinterpret_cast<TUint8*>( iMask->DataAddress() );
       
   230      			}
       
   231 			}
       
   232 		}
       
   233 	}
       
   234 
       
   235 /**
       
   236 Releases a lock previously acquired using CFastProcessor::Begin().
       
   237 */
       
   238 void CFastProcessor::End()
       
   239 	{
       
   240 	if (!iRgbaMode)
       
   241 		{    
       
   242 		if (iBitmapBuffer)
       
   243 			{
       
   244 			iBitmapBuffer = NULL;
       
   245 			}
       
   246 		if (iMaskBuffer)
       
   247 			{
       
   248 			iMaskBuffer = NULL;
       
   249 			}
       
   250 		}
       
   251 	}
       
   252 
       
   253 /**
       
   254 Default constructor for this class.
       
   255 */
       
   256 CFastProcessor16Mto16M::CFastProcessor16Mto16M(CFbsBitmap* aDestination, TBool aRgbaMode):
       
   257 	CFastProcessor(aDestination, NULL, aRgbaMode)
       
   258     {}
       
   259 
       
   260 /**
       
   261 Sets an array of pixel values, starting at the current bitmap position using the
       
   262 values supplied in aDataPtr.
       
   263 
       
   264 @param  aDataPtr
       
   265         A pointer to the first element in the array.
       
   266 @param  aDataPtrLimit
       
   267         A pointer to the last element in the array.
       
   268 */
       
   269 void CFastProcessor16Mto16M::SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* /*aLineCache*/, TPoint& /*aPos*/)
       
   270     {       
       
   271     TUint8* scanLinePtr = (iBitmapBuffer + KPngDepth3BytesPerPixel * ( iPos.iX +  iPos.iY * (( (iBitmapSize.iWidth + 3)>>2)<<2))); //aligns the specified value onto a 4-byte boundary.
       
   272        
       
   273     iPos.iX += TUint(aDataPtrLimit - aDataPtr) / KPngDepth3BytesPerPixel;
       
   274 
       
   275     while (aDataPtr < aDataPtrLimit)
       
   276         {
       
   277         scanLinePtr[0] = aDataPtr[2];
       
   278         scanLinePtr[1] = aDataPtr[1];
       
   279         scanLinePtr[2] = aDataPtr[0];
       
   280       	
       
   281  		scanLinePtr += KPngDepth3BytesPerPixel;
       
   282         aDataPtr += KPngDepth3BytesPerPixel;
       
   283         }
       
   284 
       
   285     while (iPos.iX >= iBitmapSize.iWidth)
       
   286         {
       
   287         iPos.iY++;
       
   288         iPos.iX -= iBitmapSize.iWidth;
       
   289         }
       
   290     }
       
   291 
       
   292 /**
       
   293 Default constructor for this class.
       
   294 */
       
   295 CFastProcessor16Mto16MA::CFastProcessor16Mto16MA(CFbsBitmap* aDestination, TBool aRgbaMode):
       
   296 	CFastProcessor(aDestination, NULL, aRgbaMode)
       
   297     {}
       
   298 
       
   299 /**
       
   300 Sets an array of pixel values, starting at the current bitmap position using the
       
   301 values supplied in aDataPtr.
       
   302 
       
   303 @param  aDataPtr
       
   304         A pointer to the first element in the array.
       
   305 @param  aDataPtrLimit
       
   306         A pointer to the last element in the array.
       
   307 //used only if RgbaMode i.e MNG processing        
       
   308 @param  aLineCache
       
   309         A pointer to current scanline buffer.
       
   310 @param  aPos
       
   311         Current pixel position.
       
   312 */
       
   313 void CFastProcessor16Mto16MA::SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* aLineCache, TPoint& aPos)
       
   314     {
       
   315     TUint32* scanLinePtr;
       
   316  
       
   317     if (!iRgbaMode)
       
   318 	    {
       
   319 		scanLinePtr = (TUint32*)(iBitmapBuffer + (KPngDepth3BytesPerPixel + 1) * ( iPos.iX +  iPos.iY * iBitmapSize.iWidth));
       
   320 		iPos.iX += TUint(aDataPtrLimit - aDataPtr) / KPngDepth3BytesPerPixel;
       
   321 	    }
       
   322 	else
       
   323 		{
       
   324 		scanLinePtr = reinterpret_cast<TUint32*>(aLineCache);
       
   325 		aPos.iX = TUint(aDataPtrLimit - aDataPtr) / KPngDepth3BytesPerPixel;
       
   326 		}
       
   327     
       
   328     while (aDataPtr < aDataPtrLimit)
       
   329         {
       
   330         *scanLinePtr++ = (0xFF << 24) | (aDataPtr[0] << 16) | (aDataPtr[1] << 8) | aDataPtr[2]; 
       
   331 
       
   332         aDataPtr += KPngDepth3BytesPerPixel;
       
   333         }
       
   334         	
       
   335 	if (!iRgbaMode)
       
   336 		{
       
   337 	    while (iPos.iX >= iBitmapSize.iWidth)
       
   338 	        {
       
   339 	        iPos.iY++;
       
   340 	        iPos.iX -= iBitmapSize.iWidth;
       
   341 	        }              
       
   342 		}
       
   343     }
       
   344 
       
   345 /**
       
   346 Default constructor for this class.
       
   347 */
       
   348 CFastProcessor16MAto16MA::CFastProcessor16MAto16MA(CFbsBitmap* aDestination, TBool aRgbaMode):
       
   349 	CFastProcessor(aDestination, NULL, aRgbaMode)
       
   350     {}
       
   351 
       
   352 /**
       
   353 Sets an array of pixel values, starting at the current bitmap position using the
       
   354 values supplied in aDataPtr.
       
   355 
       
   356 @param  aDataPtr
       
   357         A pointer to the first element in the array.
       
   358 @param  aDataPtrLimit
       
   359         A pointer to the last element in the array.
       
   360 //used only if RgbaMode i.e MNG processing        
       
   361 @param  aLineCache
       
   362         A pointer to current scanline buffer.
       
   363 @param  aPos
       
   364         Current pixel position.
       
   365 */
       
   366 void CFastProcessor16MAto16MA::SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* aLineCache, TPoint& aPos)
       
   367     {
       
   368     TUint32* scanLinePtr;
       
   369 
       
   370     if (!iRgbaMode)
       
   371 	    {
       
   372     	scanLinePtr = (TUint32*)(iBitmapBuffer + KPngDepth4BytesPerPixel * ( iPos.iX + iPos.iY * iBitmapSize.iWidth));
       
   373     	iPos.iX += TUint(aDataPtrLimit - aDataPtr) / KPngDepth4BytesPerPixel;	    	
       
   374 	    }
       
   375     else
       
   376 	    {
       
   377 		scanLinePtr = reinterpret_cast<TUint32*>(aLineCache);
       
   378 		aPos.iX = TUint(aDataPtrLimit - aDataPtr) / KPngDepth4BytesPerPixel;	    	
       
   379 	    }
       
   380 
       
   381     while (aDataPtr + sizeof(TUint32) < aDataPtrLimit)
       
   382         {       
       
   383         TUint32 pixel1 = *(TUint32*) aDataPtr;
       
   384         aDataPtr += KPngDepth4BytesPerPixel;
       
   385         TUint32 pixel2 = *(TUint32*) aDataPtr;
       
   386         aDataPtr += KPngDepth4BytesPerPixel;
       
   387 
       
   388         pixel1 = (pixel1 & 0xFF00FF00) | ((pixel1 & 0xFF)<<16) | ((pixel1>>16) & 0xFF);
       
   389         pixel2 = (pixel2 & 0xFF00FF00) | ((pixel2 & 0xFF)<<16) | ((pixel2>>16) & 0xFF);
       
   390 
       
   391         *scanLinePtr++ = pixel1;
       
   392         *scanLinePtr++ = pixel2;
       
   393         }
       
   394         
       
   395     if (aDataPtr + sizeof(TUint32) == aDataPtrLimit)
       
   396     	{
       
   397     	TUint32 pixel1 = *(TUint32*) aDataPtr;
       
   398     	
       
   399     	*scanLinePtr = (pixel1 & 0xFF00FF00) | ((pixel1 & 0xFF)<<16) | ((pixel1>>16) & 0xFF);
       
   400     	}        
       
   401 
       
   402 	if (!iRgbaMode)
       
   403 		{
       
   404 	    while (iPos.iX >= iBitmapSize.iWidth)
       
   405 	        {
       
   406 	        iPos.iY++;
       
   407 	        iPos.iX -= iBitmapSize.iWidth;
       
   408 	        }		
       
   409 		}
       
   410     }
       
   411 
       
   412 /**
       
   413 Default constructor for this class.
       
   414 */
       
   415 CFastProcessor16MAto16MAP::CFastProcessor16MAto16MAP(CFbsBitmap* aDestination, TBool aRgbaMode):
       
   416 	CFastProcessor(aDestination, NULL, aRgbaMode)
       
   417     {}
       
   418 
       
   419 /**
       
   420 Sets an array of pixel values, starting at the current bitmap position using the
       
   421 values supplied in aDataPtr.
       
   422 
       
   423 @param  aDataPtr
       
   424         A pointer to the first element in the array.
       
   425 @param  aDataPtrLimit
       
   426         A pointer to the last element in the array.
       
   427 //used only if RgbaMode i.e MNG processing        
       
   428 @param  aLineCache
       
   429         A pointer to current scanline buffer.
       
   430 @param  aPos
       
   431         Current pixel position.
       
   432 */
       
   433 
       
   434 // function to convert PNG pixel to 16MAP pixel
       
   435 
       
   436 static TUint32 PngTo16Map(TUint32 aPngPixel)
       
   437 	{
       
   438 	TUint8 const alpha = TUint8( aPngPixel >> 24 );
       
   439 
       
   440 	if (alpha == 0)
       
   441 		{
       
   442 		aPngPixel = 0;
       
   443 		}
       
   444 	else
       
   445 		{
       
   446 		// PNG bytes position in TUint32 are ABGR and must be coverted to ARGB in our case
       
   447 
       
   448 		if (alpha == 0xff)
       
   449 			{
       
   450 			aPngPixel = (aPngPixel & 0xFF00FF00) | ((aPngPixel & 0xFF) << 16) | ((aPngPixel >> 16) & 0xFF);
       
   451 			}
       
   452 		else
       
   453 			{   
       
   454 			// Use a bias value of 128 rather than 255, but also add 1/256 of the numerator 
       
   455 			// before dividing the sum by 256.
       
   456 
       
   457 			TUint32 scaledRB = (aPngPixel & KRBMask) * alpha + KRBBias;
       
   458 			scaledRB = (scaledRB + ( (scaledRB >> 8) & KRBMask) ) >> 8;
       
   459 			// swap now the R & B channels
       
   460 			scaledRB = (scaledRB << 16) | (scaledRB >> 16);
       
   461 
       
   462 			TUint32 scaledG = (aPngPixel & KGMask) * alpha + KGBias;
       
   463 			scaledG = (scaledG + (scaledG >> 8)) >> 8;
       
   464 
       
   465 			// compose the new pixel swapping R with B as we premultiplied alpha on a PNG pixel 
       
   466 
       
   467 			aPngPixel = (aPngPixel & KAMask) | (scaledRB & KRBMask) | (scaledG & KGMask); 
       
   468 			}
       
   469 		}
       
   470 
       
   471 	return aPngPixel;
       
   472 	}
       
   473 
       
   474 void CFastProcessor16MAto16MAP::SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* aLineCache, TPoint& aPos)
       
   475     {
       
   476     TUint32* scanLinePtr;
       
   477 
       
   478 	if (!iRgbaMode)
       
   479 		{
       
   480 		scanLinePtr = (TUint32*)(iBitmapBuffer + KPngDepth4BytesPerPixel * ( iPos.iX +  iPos.iY * iBitmapSize.iWidth));
       
   481 		iPos.iX += TUint(aDataPtrLimit - aDataPtr) / KPngDepth4BytesPerPixel;      
       
   482 		}
       
   483 	else
       
   484 		{
       
   485 		scanLinePtr = reinterpret_cast<TUint32*>(aLineCache);
       
   486 		aPos.iX = TUint(aDataPtrLimit - aDataPtr) / KPngDepth4BytesPerPixel;      
       
   487 		}
       
   488 
       
   489 	// perform a direct conversion PNG -> Pixel 16MAP
       
   490 
       
   491     while (aDataPtr + sizeof(TUint32) < aDataPtrLimit)
       
   492 		{
       
   493 		TUint32 pixel1 = *(TUint32*) aDataPtr;
       
   494 		aDataPtr += KPngDepth4BytesPerPixel;
       
   495 		TUint32 pixel2 = *(TUint32*) aDataPtr;
       
   496 		aDataPtr += KPngDepth4BytesPerPixel;
       
   497 
       
   498 		pixel1 = PngTo16Map(pixel1);
       
   499 		pixel2 = PngTo16Map(pixel2);
       
   500 
       
   501 		*scanLinePtr++ = pixel1;
       
   502 		*scanLinePtr++ = pixel2;
       
   503 		}
       
   504 
       
   505     if (aDataPtr + sizeof(TUint32) == aDataPtrLimit)
       
   506 		{
       
   507 		*scanLinePtr = PngTo16Map(*(TUint32*) aDataPtr);
       
   508 		}
       
   509 
       
   510  	if (!iRgbaMode)
       
   511   		{
       
   512 		while (iPos.iX >= iBitmapSize.iWidth)
       
   513 			{
       
   514 			iPos.iY++;
       
   515 			iPos.iX -= iBitmapSize.iWidth;
       
   516 			}  
       
   517 		}
       
   518     }
       
   519 
       
   520 /**
       
   521 Default constructor for this class.
       
   522 */
       
   523 CFastProcessor32bitTo32bitAndMask::CFastProcessor32bitTo32bitAndMask(CFbsBitmap* aDestination, CFbsBitmap* aMask, TBool aRgbaMode)
       
   524 : CFastProcessor(aDestination, aMask, aRgbaMode)
       
   525 	{}
       
   526 
       
   527 /**
       
   528 Sets an array of pixel values, starting at the current bitmap position using the
       
   529 values supplied in aDataPtr.
       
   530 
       
   531 @param  aDataPtr
       
   532         A pointer to the first element in the array.
       
   533 @param  aDataPtrLimit
       
   534         A pointer to the last element in the array.
       
   535 //used only if RgbaMode i.e MNG processing        
       
   536 @param  aLineCache
       
   537         A pointer to current scanline buffer.
       
   538 @param  aPos
       
   539         Current pixel position.
       
   540 */
       
   541 void CFastProcessor32bitTo32bitAndMask::SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* /*aLineCache*/, TPoint& /*aPos*/)
       
   542 	{
       
   543 	ASSERT(!iRgbaMode); // Not configured for MNG use
       
   544 	
       
   545 	TUint32* scanLinePtr;  // alpha channel set to fully opaque
       
   546 	TUint8* maskScanLinePtr;  // set alpha channel in mask
       
   547 
       
   548 	scanLinePtr = (TUint32*)(iBitmapBuffer + KPngDepth4BytesPerPixel * ( iPos.iX +  iPos.iY * iBitmapSize.iWidth));
       
   549 	maskScanLinePtr = (TUint8*)(iMaskBuffer + KPngDepth1BytesPerPixel * ( iPos.iX +  iPos.iY * iBitmapSize.iWidth));
       
   550 	iPos.iX += TUint(aDataPtrLimit - aDataPtr) / KPngDepth4BytesPerPixel;
       
   551 	
       
   552 	if (iBitmap->DisplayMode() == EColor16MAP)
       
   553 		{
       
   554 	    while (aDataPtr + sizeof(TUint32) < aDataPtrLimit)
       
   555 			{
       
   556 			TUint32 pixel1 = *(TUint32*) aDataPtr;
       
   557 			aDataPtr += KPngDepth4BytesPerPixel;
       
   558 			TUint32 pixel2 = *(TUint32*) aDataPtr;
       
   559 			aDataPtr += KPngDepth4BytesPerPixel;
       
   560 
       
   561 			pixel1 = PngTo16Map(pixel1);
       
   562 			pixel2 = PngTo16Map(pixel2);
       
   563 			
       
   564 			*scanLinePtr++ = 0xFF000000 | pixel1;
       
   565 			*maskScanLinePtr++ = (pixel1 & 0xFF000000) >> 24;
       
   566 			
       
   567 			*scanLinePtr++ = 0xFF000000 | pixel2;
       
   568 			*maskScanLinePtr++ = (pixel2 & 0xFF000000) >> 24;
       
   569 			}
       
   570 		
       
   571 		if (aDataPtr + sizeof(TUint32) == aDataPtrLimit)
       
   572 			{
       
   573 			TUint32 oddPixel = *(TUint32*) aDataPtr;
       
   574 			
       
   575 			oddPixel = PngTo16Map(oddPixel);
       
   576 			
       
   577 			*scanLinePtr++ = 0xFF000000 | oddPixel;
       
   578 			*maskScanLinePtr++ = (oddPixel & 0xFF000000) >> 24;
       
   579 			}
       
   580 		}
       
   581 	else
       
   582 		{
       
   583 		while (aDataPtr < aDataPtrLimit)
       
   584 			{
       
   585 			*scanLinePtr++ = 0xFF000000 | (aDataPtr[0] << 16) | (aDataPtr[1] << 8) | aDataPtr[2];
       
   586 			*maskScanLinePtr++ = (aDataPtr[3]);
       
   587 
       
   588 			aDataPtr += KPngDepth4BytesPerPixel;
       
   589 			}
       
   590 		}
       
   591 	
       
   592 	while (iPos.iX >= iBitmapSize.iWidth)
       
   593 		{
       
   594 		iPos.iY++;
       
   595 		iPos.iX -= iBitmapSize.iWidth;
       
   596 		}
       
   597 	}
       
   598 
       
   599 /**
       
   600 Default constructor for this class.
       
   601 */
       
   602 CFastProcessor16MAto16MU::CFastProcessor16MAto16MU(CFbsBitmap* aDestination, TBool aRgbaMode)
       
   603 : CFastProcessor(aDestination, NULL, aRgbaMode)
       
   604 	{}
       
   605 
       
   606 /**
       
   607 Sets an array of pixel values, starting at the current bitmap position using the
       
   608 values supplied in aDataPtr.
       
   609 
       
   610 @param  aDataPtr
       
   611         A pointer to the first element in the array.
       
   612 @param  aDataPtrLimit
       
   613         A pointer to the last element in the array.
       
   614 //used only if RgbaMode i.e MNG processing        
       
   615 @param  aLineCache
       
   616         A pointer to current scanline buffer.
       
   617 @param  aPos
       
   618         Current pixel position.
       
   619 */
       
   620 void CFastProcessor16MAto16MU::SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* aLineCache, TPoint& aPos)
       
   621     {
       
   622     TUint32* scanLinePtr;
       
   623 
       
   624     if (!iRgbaMode)
       
   625 	    {
       
   626     	scanLinePtr = (TUint32*)(iBitmapBuffer + KPngDepth4BytesPerPixel * ( iPos.iX + iPos.iY * iBitmapSize.iWidth));
       
   627     	iPos.iX += TUint(aDataPtrLimit - aDataPtr) / KPngDepth4BytesPerPixel;	    	
       
   628 	    }
       
   629     else
       
   630 	    {
       
   631 		scanLinePtr = reinterpret_cast<TUint32*>(aLineCache);
       
   632 		aPos.iX = TUint(aDataPtrLimit - aDataPtr) / KPngDepth4BytesPerPixel;	    	
       
   633 	    }
       
   634 
       
   635     while (aDataPtr < aDataPtrLimit)
       
   636         {
       
   637         *scanLinePtr++ = 0xFF000000 | (aDataPtr[0] << 16) | (aDataPtr[1] << 8) | aDataPtr[2]; 
       
   638 
       
   639         aDataPtr += KPngDepth4BytesPerPixel;
       
   640         }       
       
   641 
       
   642 	if (!iRgbaMode)
       
   643 		{
       
   644 	    while (iPos.iX >= iBitmapSize.iWidth)
       
   645 	        {
       
   646 	        iPos.iY++;
       
   647 	        iPos.iX -= iBitmapSize.iWidth;
       
   648 	        }		
       
   649 		}
       
   650     }
       
   651 
       
   652 class CBitDepth1Decoder : public CPngReadSubCodec
       
   653 	{
       
   654 private:
       
   655 	virtual void DoConstructL();
       
   656 	virtual TInt ScanlineBufferSize(TInt aPixelLength);
       
   657 	virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
       
   658 	};
       
   659 
       
   660 class CBitDepth2Decoder : public CPngReadSubCodec
       
   661 	{
       
   662 private:
       
   663 	virtual void DoConstructL();
       
   664 	virtual TInt ScanlineBufferSize(TInt aPixelLength);
       
   665 	virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
       
   666 	};
       
   667 
       
   668 class CBitDepth4Decoder : public CPngReadSubCodec
       
   669 	{
       
   670 private:
       
   671 	virtual void DoConstructL();
       
   672 	virtual TInt ScanlineBufferSize(TInt aPixelLength);
       
   673 	virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
       
   674 	};
       
   675 
       
   676 class CBitDepth8Decoder : public CPngReadSubCodec
       
   677 	{
       
   678 private:
       
   679 	virtual void DoConstructL();
       
   680 	virtual TInt ScanlineBufferSize(TInt aPixelLength);
       
   681 	virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
       
   682 	};
       
   683 
       
   684 class CBitDepth8ColorType2Decoder : public CPngReadSubCodec
       
   685 	{
       
   686 private:
       
   687 	virtual void DoConstructL();
       
   688 	virtual TInt ScanlineBufferSize(TInt aPixelLength);
       
   689 	virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
       
   690 	};
       
   691 
       
   692 class CBitDepth8ColorType4Decoder : public CPngReadSubCodec
       
   693 	{
       
   694 private:
       
   695 	virtual void DoConstructL();
       
   696 	virtual TInt ScanlineBufferSize(TInt aPixelLength);
       
   697 	virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
       
   698 	};
       
   699 
       
   700 class CBitDepth8ColorType6Decoder : public CPngReadSubCodec
       
   701 	{
       
   702 private:
       
   703 	virtual void DoConstructL();
       
   704 	virtual TInt ScanlineBufferSize(TInt aPixelLength);
       
   705 	virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
       
   706 	};
       
   707 
       
   708 class CBitDepth16ColorType0Decoder : public CPngReadSubCodec
       
   709 	{
       
   710 private:
       
   711 	virtual void DoConstructL();
       
   712 	virtual TInt ScanlineBufferSize(TInt aPixelLength);
       
   713 	virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
       
   714 	};
       
   715 
       
   716 class CBitDepth16ColorType2Decoder : public CPngReadSubCodec
       
   717 	{
       
   718 private:
       
   719 	virtual void DoConstructL();
       
   720 	virtual TInt ScanlineBufferSize(TInt aPixelLength);
       
   721 	virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
       
   722 	};
       
   723 
       
   724 class CBitDepth16ColorType4Decoder : public CPngReadSubCodec
       
   725 	{
       
   726 private:
       
   727 	virtual void DoConstructL();
       
   728 	virtual TInt ScanlineBufferSize(TInt aPixelLength);
       
   729 	virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
       
   730 	};
       
   731 
       
   732 class CBitDepth16ColorType6Decoder : public CPngReadSubCodec
       
   733 	{
       
   734 private:
       
   735 	virtual void DoConstructL();
       
   736 	virtual TInt ScanlineBufferSize(TInt aPixelLength);
       
   737 	virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
       
   738 	};
       
   739 
       
   740 // CPngReadSubCodec
       
   741 CPngReadSubCodec* CPngReadSubCodec::NewL(CImageProcessor* aImageProc,CImageProcessor* aMaskProc,const TPngImageInformation& aInfo, CFastProcessor* aFastProc, TBool aFastProcessorMode)
       
   742 	{
       
   743 	CPngReadSubCodec* self = NULL;
       
   744 
       
   745 	switch (aInfo.iBitDepth)
       
   746 		{
       
   747 	case 1:
       
   748 		self = new(ELeave) CBitDepth1Decoder;
       
   749 		break;
       
   750 	case 2:
       
   751 		self = new(ELeave) CBitDepth2Decoder;
       
   752 		break;
       
   753 	case 4:
       
   754 		self = new(ELeave) CBitDepth4Decoder;
       
   755 		break;
       
   756 	case 8:
       
   757 		switch (aInfo.iColorType)
       
   758 			{
       
   759 		case TPngImageInformation::EGrayscale:
       
   760 		case TPngImageInformation::EIndexedColor:
       
   761 			self = new(ELeave) CBitDepth8Decoder;
       
   762 			break;
       
   763 		case TPngImageInformation::EDirectColor:
       
   764 			self = new(ELeave) CBitDepth8ColorType2Decoder;
       
   765 			break;
       
   766 		case TPngImageInformation::EAlphaGrayscale:
       
   767 			self = new(ELeave) CBitDepth8ColorType4Decoder;
       
   768 			break;
       
   769 		case TPngImageInformation::EAlphaDirectColor:
       
   770 			self = new(ELeave) CBitDepth8ColorType6Decoder;
       
   771 			break;
       
   772 		default:
       
   773 			User::Leave(KErrNotSupported);
       
   774 			break;
       
   775 			}
       
   776 		break;
       
   777 	case 16:
       
   778 		switch (aInfo.iColorType)
       
   779 			{
       
   780 		case TPngImageInformation::EGrayscale:
       
   781 			self = new(ELeave) CBitDepth16ColorType0Decoder;
       
   782 			break;
       
   783 		case TPngImageInformation::EDirectColor:
       
   784 			self = new(ELeave) CBitDepth16ColorType2Decoder;
       
   785 			break;
       
   786 		case TPngImageInformation::EAlphaGrayscale:
       
   787 			self = new(ELeave) CBitDepth16ColorType4Decoder;
       
   788 			break;
       
   789 		case TPngImageInformation::EAlphaDirectColor:
       
   790 			self = new(ELeave) CBitDepth16ColorType6Decoder;
       
   791 			break;
       
   792 		case TPngImageInformation::EIndexedColor:
       
   793 		default:
       
   794 			User::Leave(KErrNotSupported);
       
   795 			break;
       
   796 			}
       
   797 		break;
       
   798 	default:
       
   799 		User::Leave(KErrNotSupported);
       
   800 		break;
       
   801 		}
       
   802 
       
   803 	CleanupStack::PushL(self);
       
   804 	self->ConstructL(aImageProc,aMaskProc,aInfo, aFastProc, aFastProcessorMode);
       
   805 	CleanupStack::Pop(self); 
       
   806 	return self;
       
   807 	}
       
   808 
       
   809 CPngReadSubCodec::CPngReadSubCodec():
       
   810 	iScanlineDes1(NULL,0),
       
   811 	iScanlineDes2(NULL,0)
       
   812 	{}
       
   813 
       
   814 CPngReadSubCodec::~CPngReadSubCodec()
       
   815 	{
       
   816 	delete iScanlineBuffer1;
       
   817 	delete iScanlineBuffer2;
       
   818 	delete [] iLineCache;
       
   819 	}
       
   820 
       
   821 void CPngReadSubCodec::ConstructL(CImageProcessor* aImageProc,CImageProcessor* aMaskProc,const TPngImageInformation& aInfo, CFastProcessor* aFastProc, TBool aFastProcessorMode)
       
   822 	{
       
   823 	iImageProc = aImageProc;
       
   824 	iMaskProc = aMaskProc;
       
   825 	iFastProc = aFastProc;
       
   826 	
       
   827 	iInfo = aInfo;
       
   828 	
       
   829 	SetFastProcessorMode(aFastProcessorMode);				
       
   830 
       
   831 	iScanlineBufferSize = ScanlineBufferSize(iInfo.iSize.iWidth);
       
   832 
       
   833 	DoConstructL();
       
   834 	if (iInfo.iInterlaceMethod != TPngImageInformation::EAdam7Interlace)
       
   835 		{
       
   836 		iLineCache = new (ELeave) TRgb [iInfo.iSize.iWidth + 8]; // +8 to be sure we won't exceed buffer for padded images (up to 8 pixels padding)
       
   837 		}
       
   838 
       
   839 	iScanlineBuffer1 = HBufC8::NewMaxL(iScanlineBufferSize + 7);
       
   840 	iScanlineBuffer2 = HBufC8::NewMaxL(iScanlineBufferSize + 7);
       
   841 
       
   842 	if (iInfo.iInterlaceMethod == TPngImageInformation::EAdam7Interlace)
       
   843 		{
       
   844 		iInterlacedScanlineBufferSize[0] = ScanlineBufferSize((iInfo.iSize.iWidth + 7) >> 3);
       
   845 		iInterlacedScanlineBufferSize[1] = ScanlineBufferSize((iInfo.iSize.iWidth + 3) >> 3);
       
   846 		iInterlacedScanlineBufferSize[2] = ScanlineBufferSize((iInfo.iSize.iWidth + 3) >> 2);
       
   847 		iInterlacedScanlineBufferSize[3] = ScanlineBufferSize((iInfo.iSize.iWidth + 1) >> 2);
       
   848 		iInterlacedScanlineBufferSize[4] = ScanlineBufferSize((iInfo.iSize.iWidth + 1) >> 1);
       
   849 		iInterlacedScanlineBufferSize[5] = ScanlineBufferSize(iInfo.iSize.iWidth >> 1);
       
   850 		iInterlacedScanlineBufferSize[6] = iScanlineBufferSize;
       
   851 		iInterlacedScanlineBufferSize[7] = 0;
       
   852 		iPass = 0;
       
   853 
       
   854 		iScanlineDes1.Set(&(iScanlineBuffer1->Des())[0],iInterlacedScanlineBufferSize[0],iInterlacedScanlineBufferSize[0]);
       
   855 		iScanlineDes2.Set(&(iScanlineBuffer2->Des())[0],iInterlacedScanlineBufferSize[0],iInterlacedScanlineBufferSize[0]);
       
   856 		
       
   857 		if(iImageProc)
       
   858 			{
       
   859 			const TInt lineRepeat = ClampValue(KBlockHeight[iPass]-1,0,iInfo.iSize.iHeight-iPos.iY-2);
       
   860 			iImageProc->SetLineRepeat(lineRepeat);	
       
   861 			}
       
   862 		}
       
   863 	else
       
   864 		{
       
   865 		// to align actual data per word boudary
       
   866 		iScanlineDes1.Set(&(iScanlineBuffer1->Des())[3],iScanlineBufferSize,iScanlineBufferSize);
       
   867 		iScanlineDes2.Set(&(iScanlineBuffer2->Des())[3],iScanlineBufferSize,iScanlineBufferSize);
       
   868 		}
       
   869 	}
       
   870 
       
   871 void CPngReadCodec::SetImageProcessor(CImageProcessor* aImageProc, TBool aOwnsProcessor)
       
   872 	{
       
   873 	if (iOwnsImageProcessor)
       
   874 		delete iImageProc;
       
   875 	iImageProc = aImageProc;
       
   876 	iOwnsImageProcessor = aOwnsProcessor;
       
   877 	}
       
   878 
       
   879 void CPngReadCodec::SetMaskProcessor(CImageProcessor* aMaskProc, TBool aOwnsProcessor)
       
   880 	{
       
   881 	if (iOwnsMaskProcessor)
       
   882 		delete iMaskProc;
       
   883 	iMaskProc = aMaskProc;
       
   884 	iOwnsMaskProcessor = aOwnsProcessor;
       
   885 	}
       
   886 
       
   887 void CPngReadCodec::SetFastProcessor(CFastProcessor* aFastProc, TBool aOwnsProcessor)
       
   888 	{
       
   889 	if (iOwnsFastProcessor)
       
   890 		delete iFastProc;
       
   891 	iFastProc = aFastProc;
       
   892 	iOwnsFastProcessor = aOwnsProcessor;		
       
   893 	}
       
   894 
       
   895 void CPngReadSubCodec::SetFastProcessorMode(TBool aMode)
       
   896 	{
       
   897 	iFastProcessorMode = aMode;
       
   898 	}
       
   899 
       
   900 void CPngReadSubCodec::ResetL()
       
   901 	{
       
   902 	iPos.SetXY(0,0);
       
   903 	iPass = 0;
       
   904 	if (iInfo.iInterlaceMethod == TPngImageInformation::EAdam7Interlace)
       
   905 		{
       
   906 		iScanlineDes1.Set(&(iScanlineBuffer1->Des())[0],iInterlacedScanlineBufferSize[0],iInterlacedScanlineBufferSize[0]);
       
   907 		iScanlineDes2.Set(&(iScanlineBuffer2->Des())[0],iInterlacedScanlineBufferSize[0],iInterlacedScanlineBufferSize[0]);
       
   908 	
       
   909 		if(iImageProc)
       
   910 			{
       
   911 			const TInt lineRepeat = ClampValue(KBlockHeight[iPass]-1,0,iInfo.iSize.iHeight-iPos.iY-2);
       
   912 			iImageProc->SetLineRepeat(lineRepeat);
       
   913 			}
       
   914 		}
       
   915 	}
       
   916 
       
   917 TDes8& CPngReadSubCodec::FirstBuffer()
       
   918 	{
       
   919 	iScanlineDes1.FillZ();
       
   920 	iCurrentScanlineBuffer = 2;
       
   921 	return iScanlineDes2;
       
   922 	}
       
   923 
       
   924 TDes8& CPngReadSubCodec::DecodeL()
       
   925 	{
       
   926 	TUint8* dataPtr = (iCurrentScanlineBuffer == 1) ? &iScanlineDes1[1] : &iScanlineDes2[1];
       
   927 	const TUint8* dataPtrLimit = dataPtr + iScanlineDes1.Length() - 1;
       
   928 
       
   929 	FilterScanlineDataL(dataPtr,dataPtrLimit);
       
   930 	
       
   931 	if (iFastProcessorMode)
       
   932 		{
       
   933 		iFastProc->Begin();	
       
   934 		}
       
   935 	
       
   936 	DoDecode(dataPtr,dataPtrLimit);
       
   937 
       
   938 	if (iFastProcessorMode)
       
   939 		{
       
   940 		iFastProc->End();	
       
   941 		}
       
   942 	
       
   943 	UpdatePos();
       
   944 	
       
   945 	if (iCurrentScanlineBuffer == 1)
       
   946 		{
       
   947 		iCurrentScanlineBuffer = 2;
       
   948 		return iScanlineDes2;
       
   949 		}
       
   950 	else
       
   951 		{
       
   952 		iCurrentScanlineBuffer = 1;
       
   953 		return iScanlineDes1;
       
   954 		}
       
   955 	}
       
   956 
       
   957 void CPngReadSubCodec::FilterScanlineDataL(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
       
   958 	{
       
   959 	TInt filterType = (iCurrentScanlineBuffer == 1) ? iScanlineDes1[0] : iScanlineDes2[0];
       
   960 
       
   961 	switch (filterType)
       
   962 		{
       
   963 	case 0: // None
       
   964 		break;
       
   965 	case 1: // Sub
       
   966 		{
       
   967 		aDataPtr += iBytesPerPixel;
       
   968 
       
   969 		while (aDataPtr < aDataPtrLimit)
       
   970 			{
       
   971 			aDataPtr[0] = TUint8(aDataPtr[0] + aDataPtr[-iBytesPerPixel]);
       
   972 			aDataPtr++;
       
   973 			}
       
   974 		}
       
   975 		break;
       
   976 	case 2: // Up
       
   977 		{
       
   978 		TUint8* altDataPtr = (iCurrentScanlineBuffer == 1) ? &iScanlineDes2[1] : &iScanlineDes1[1];
       
   979 
       
   980 		while (aDataPtr < aDataPtrLimit)
       
   981 			{
       
   982 			*aDataPtr = TUint8(*aDataPtr + *altDataPtr);
       
   983 			aDataPtr++;
       
   984 			altDataPtr++;
       
   985 			}
       
   986 		}
       
   987 		break;
       
   988 	case 3: // Average
       
   989 		{
       
   990 		const TUint8* tempDataPtrLimit = Min<const TUint8*>(aDataPtr + iBytesPerPixel,aDataPtrLimit);
       
   991 		TUint8* altDataPtr = (iCurrentScanlineBuffer == 1) ? &iScanlineDes2[1] : &iScanlineDes1[1];
       
   992 
       
   993 		while (aDataPtr < tempDataPtrLimit)
       
   994 			{
       
   995 			aDataPtr[0] = TUint8(aDataPtr[0] + (altDataPtr[0] / 2));
       
   996 			aDataPtr++;
       
   997 			altDataPtr++;
       
   998 			}
       
   999 
       
  1000 		while (aDataPtr < aDataPtrLimit)
       
  1001 			{
       
  1002 			aDataPtr[0] = TUint8(aDataPtr[0] + ((altDataPtr[0] + aDataPtr[-iBytesPerPixel]) / 2));
       
  1003 			aDataPtr++;
       
  1004 			altDataPtr++;
       
  1005 			}
       
  1006 		}
       
  1007 		break;
       
  1008 	case 4: // Paeth
       
  1009 		{
       
  1010 		const TUint8* tempDataPtrLimit = Min<const TUint8*>(aDataPtr + iBytesPerPixel,aDataPtrLimit);
       
  1011 		TUint8* altDataPtr = (iCurrentScanlineBuffer == 1) ? &iScanlineDes2[1] : &iScanlineDes1[1];
       
  1012 
       
  1013 		while (aDataPtr < tempDataPtrLimit)
       
  1014 			{
       
  1015 			aDataPtr[0] = TUint8(aDataPtr[0] + altDataPtr[0]);
       
  1016 			aDataPtr++;
       
  1017 			altDataPtr++;
       
  1018 			}
       
  1019 
       
  1020 		while (aDataPtr < aDataPtrLimit)
       
  1021 			{
       
  1022 			aDataPtr[0] = TUint8(aDataPtr[0] + PaethPredictor(aDataPtr[-iBytesPerPixel],altDataPtr[0],altDataPtr[-iBytesPerPixel]));
       
  1023 			aDataPtr++;
       
  1024 			altDataPtr++;
       
  1025 			}
       
  1026 		}
       
  1027 		break;
       
  1028 
       
  1029 	case 64: // support for additional MNG-defined filter (Adaptive filtering with five basic types and intrapixel differencing)
       
  1030 		{
       
  1031 		const TInt plusAlpha=(0 != (iInfo.iColorType & TPngImageInformation::EAlphaChannelUsed));
       
  1032 		if ( iInfo.iBitDepth == 16)
       
  1033 			{
       
  1034 			const TUint KBytesPerPixel=2*(3+plusAlpha);
       
  1035 			aDataPtrLimit-=KBytesPerPixel;
       
  1036 			while(aDataPtr < aDataPtrLimit)
       
  1037 				{
       
  1038 				const TUint32 s0   = (aDataPtr[0] << 8) | aDataPtr[1];
       
  1039 				const TUint32 s1   = 0x10000u + (aDataPtr[2] << 8) | aDataPtr[3];
       
  1040 				const TUint32 s2   = (aDataPtr[4] << 8) | aDataPtr[5];
       
  1041 				const TUint32 red  = ((s0+s1) & 0xffffu);
       
  1042 				const TUint32 blue = ((s2+s1) & 0xffffu);
       
  1043 				aDataPtr[0] = TUint8((red >> 8) & 0xff);
       
  1044 				aDataPtr[1] = TUint8(red & 0xff);
       
  1045 				aDataPtr[4] = TUint8((blue >> 8) & 0xff);
       
  1046 				aDataPtr[5] = TUint8(blue & 0xff);
       
  1047 				aDataPtr+=KBytesPerPixel;
       
  1048 				}
       
  1049 			}
       
  1050 		else if (iInfo.iBitDepth == 8)
       
  1051 			{
       
  1052 			const TUint KBytesPerPixel=3+plusAlpha;
       
  1053 			aDataPtrLimit-=KBytesPerPixel;
       
  1054 			while(aDataPtr < aDataPtrLimit)
       
  1055 				{
       
  1056 				aDataPtr[0] = TUint8((0x100u + aDataPtr[0] + aDataPtr[1])&0xffu);
       
  1057 				aDataPtr[1] = TUint8((0x100u + aDataPtr[2] + aDataPtr[1])&0xffu);
       
  1058 				aDataPtr +=KBytesPerPixel;
       
  1059 				}
       
  1060 			}
       
  1061 		}
       
  1062 		break;
       
  1063 
       
  1064 	default: // Error
       
  1065 		User::Leave(KErrCorrupt);
       
  1066 		break;
       
  1067 		}
       
  1068 	}
       
  1069 
       
  1070 TInt CPngReadSubCodec::PaethPredictor(TInt aLeft,TInt aAbove,TInt aAboveLeft)
       
  1071 	{
       
  1072 	TInt p = aLeft + aAbove - aAboveLeft;
       
  1073 	TInt pa = Abs(p - aLeft);
       
  1074 	TInt pb = Abs(p - aAbove);
       
  1075 	TInt pc = Abs(p - aAboveLeft);
       
  1076 
       
  1077 	if (pa <= pb && pa <= pc)
       
  1078 		return aLeft;
       
  1079 	else if (pb <= pc)
       
  1080 		return aAbove;
       
  1081 	else
       
  1082 		return aAboveLeft;
       
  1083 	}
       
  1084 
       
  1085 void CPngReadSubCodec::WritePixel(TRgb aPixelColor)
       
  1086 	{
       
  1087 	if (iInfo.iInterlaceMethod == TPngImageInformation::EAdam7Interlace)
       
  1088 		{
       
  1089 		const TInt width = ClampValue(KBlockWidth[iPass],0,iInfo.iSize.iWidth - iPos.iX);
       
  1090 		TPoint pos(iPos);
       
  1091 		iImageProc->SetPos(pos);
       
  1092 		iImageProc->SetPixelRun(aPixelColor,width);
       
  1093 		iPos.iX += KColIncrement[iPass];
       
  1094 		}
       
  1095 	else
       
  1096 		{
       
  1097 		if (iRgbaMode)
       
  1098 			{
       
  1099 			iLineCache[iPos.iX++]=aPixelColor;
       
  1100 			}
       
  1101 		else
       
  1102 			{
       
  1103 			iImageProc->SetPixel(aPixelColor);
       
  1104 			}
       
  1105 		}
       
  1106 	}
       
  1107 
       
  1108 void CPngReadSubCodec::WritePixel(TRgb aPixelColor,TUint8 aAlphaValue)
       
  1109 	{
       
  1110 	if(iAlphaMode || iRgbaMode)
       
  1111 		{
       
  1112 		TRgb RgbaColour( aPixelColor.Internal()&0xFFFFFF, (TUint32(aAlphaValue)) );
       
  1113 		
       
  1114 		if (iInfo.iInterlaceMethod == TPngImageInformation::EAdam7Interlace)
       
  1115 			{
       
  1116 			iImageProc->SetPos(iPos);
       
  1117 			iImageProc->SetPixel(RgbaColour);
       
  1118 			iPos.iX += KColIncrement[iPass];
       
  1119 			}
       
  1120 		else
       
  1121 			{
       
  1122 			iRgbaMode ? iLineCache[iPos.iX++]=RgbaColour : iImageProc->SetPixel(RgbaColour);
       
  1123 			}
       
  1124 		}
       
  1125 	else
       
  1126 		{
       
  1127 		ASSERT(iMaskProc);
       
  1128 			{
       
  1129 			TRgb maskColor(TRgb::Gray256(aAlphaValue));
       
  1130 		
       
  1131 			if (iInfo.iInterlaceMethod == TPngImageInformation::EAdam7Interlace)
       
  1132 				{
       
  1133 				iImageProc->SetPos(iPos);
       
  1134 				iMaskProc->SetPos(iPos);
       
  1135 				iImageProc->SetPixel(aPixelColor);
       
  1136 				iMaskProc->SetPixel(maskColor);
       
  1137 
       
  1138 				iPos.iX += KColIncrement[iPass];
       
  1139 				}
       
  1140 			else
       
  1141 				{
       
  1142 				iImageProc->SetPixel(aPixelColor);
       
  1143 				iMaskProc->SetPixel(maskColor);
       
  1144 				}	
       
  1145 			}
       
  1146 		}
       
  1147 	}
       
  1148 
       
  1149 void CPngReadSubCodec::UpdatePos()
       
  1150 	{
       
  1151 	if (iInfo.iInterlaceMethod == TPngImageInformation::EAdam7Interlace)
       
  1152 		{
       
  1153 		ASSERT(iPass <= 7);
       
  1154 
       
  1155 		iPos.iX = KColStart[iPass];
       
  1156 		iPos.iY += KRowIncrement[iPass];
       
  1157 
       
  1158 		while (iPos.iX >= iInfo.iSize.iWidth || iPos.iY >= iInfo.iSize.iHeight)
       
  1159 			{
       
  1160 			iPass++;
       
  1161 			
       
  1162 			/* Coverity may flag this up as an overrun of KColStart and KRowStart.  This is a false
       
  1163 			positive because both arrays have a 'safety entry' at index [7], which is 0.  Thus,
       
  1164 			iPos.iX and iPos.iY will be be 0, and so never equal to the image width/height as we
       
  1165 			won't decode images with these dimensions.  Therefore, this loop will never be entered.*/
       
  1166 			
       
  1167 			iPos.iX = KColStart[iPass];
       
  1168 			iPos.iY = KRowStart[iPass];
       
  1169 			iScanlineDes1.Set(&(iScanlineBuffer1->Des())[0],iInterlacedScanlineBufferSize[iPass],iInterlacedScanlineBufferSize[iPass]);
       
  1170 			iScanlineDes2.Set(&(iScanlineBuffer2->Des())[0],iInterlacedScanlineBufferSize[iPass],iInterlacedScanlineBufferSize[iPass]);
       
  1171 			iScanlineDes1.FillZ();
       
  1172 			iScanlineDes2.FillZ();
       
  1173 			}
       
  1174 
       
  1175 		if(iImageProc)
       
  1176 			{
       
  1177 			const TInt lineRepeat = ClampValue(KBlockHeight[iPass]-1,0,iInfo.iSize.iHeight-iPos.iY-2);
       
  1178 			iImageProc->SetLineRepeat(lineRepeat);
       
  1179 			}
       
  1180 		}
       
  1181 	else
       
  1182 		{
       
  1183 		if (iRgbaMode)
       
  1184 			{
       
  1185 			iImageProc->SetPixels(iLineCache, iPos.iX);
       
  1186 			}
       
  1187 		iPos.iX=0;
       
  1188 		}
       
  1189 	}
       
  1190 
       
  1191 
       
  1192 // CBitDepth1Decoder
       
  1193 void CBitDepth1Decoder::DoConstructL()
       
  1194 	{
       
  1195 	if (!(iInfo.iColorType & TPngImageInformation::EPaletteUsed))
       
  1196 		{ // Set up palette to be grayscale values
       
  1197 		iInfo.iPalette[0] = KRgbBlack;
       
  1198 		iInfo.iPalette[1] = KRgbWhite;
       
  1199 
       
  1200 
       
  1201 		if (iInfo.iTransparencyPresent)
       
  1202 			{
       
  1203 			if (iInfo.iTransparentGray <= 1)
       
  1204 				iInfo.iTransparencyValue[iInfo.iTransparentGray] = 0;
       
  1205 			}
       
  1206 		}
       
  1207 
       
  1208 	// Replicate values to avoid shifts when decoding
       
  1209 	iInfo.iPalette[2] = iInfo.iPalette[1];
       
  1210 	iInfo.iPalette[4] = iInfo.iPalette[1];
       
  1211 	iInfo.iPalette[8] = iInfo.iPalette[1];
       
  1212 	iInfo.iPalette[16] = iInfo.iPalette[1];
       
  1213 	iInfo.iPalette[32] = iInfo.iPalette[1];
       
  1214 	iInfo.iPalette[64] = iInfo.iPalette[1];
       
  1215 	iInfo.iPalette[128] = iInfo.iPalette[1];
       
  1216 
       
  1217 	if (iInfo.iTransparencyPresent && iInfo.iTransparencyValue[1] != 255)
       
  1218 		{
       
  1219 		iInfo.iTransparencyValue[2] = iInfo.iTransparencyValue[1];
       
  1220 		iInfo.iTransparencyValue[4] = iInfo.iTransparencyValue[1];
       
  1221 		iInfo.iTransparencyValue[8] = iInfo.iTransparencyValue[1];
       
  1222 		iInfo.iTransparencyValue[16] = iInfo.iTransparencyValue[1];
       
  1223 		iInfo.iTransparencyValue[32] = iInfo.iTransparencyValue[1];
       
  1224 		iInfo.iTransparencyValue[64] = iInfo.iTransparencyValue[1];
       
  1225 		iInfo.iTransparencyValue[128] = iInfo.iTransparencyValue[1];
       
  1226 		}
       
  1227 
       
  1228 	iBytesPerPixel = 1;
       
  1229 	if (iInfo.iInterlaceMethod == TPngImageInformation::ENoInterlace)
       
  1230 		{
       
  1231 		TInt pixelPadding = ((iInfo.iSize.iWidth + 7) & ~7) - iInfo.iSize.iWidth;
       
  1232 		if(iImageProc)
       
  1233 			{
       
  1234 			iImageProc->SetPixelPadding(pixelPadding);	
       
  1235 			}
       
  1236 		if (iMaskProc)
       
  1237 			{
       
  1238 			iMaskProc->SetPixelPadding(pixelPadding);	
       
  1239 			}
       
  1240 		}
       
  1241 	}
       
  1242 
       
  1243 TInt CBitDepth1Decoder::ScanlineBufferSize(TInt aPixelLength)
       
  1244 	{
       
  1245 	return ((aPixelLength + 7) / 8) + KPngScanlineFilterTypeLength;
       
  1246 	}
       
  1247 
       
  1248 void CBitDepth1Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
       
  1249 	{
       
  1250 	if (iInfo.iTransparencyPresent && (iMaskProc || iAlphaMode) )
       
  1251 		{
       
  1252 		while (aDataPtr < aDataPtrLimit)
       
  1253 			{
       
  1254 			TInt dataValue = *aDataPtr++;
       
  1255 
       
  1256 			for (TUint mask=0x80; mask!=0; mask>>=1) // iterate with 0x80, 0x40 .. 0x01
       
  1257 				WritePixel(iInfo.iPalette[dataValue & mask],iInfo.iTransparencyValue[dataValue & mask]);
       
  1258 			}
       
  1259 		}
       
  1260 	else
       
  1261 		{
       
  1262 		while (aDataPtr < aDataPtrLimit)
       
  1263 			{
       
  1264 			TInt dataValue = *aDataPtr++;
       
  1265 
       
  1266 			for (TUint mask=0x80; mask!=0; mask>>=1) // iterate with 0x80, 0x40 .. 0x01
       
  1267 				WritePixel(iInfo.iPalette[dataValue & mask]);
       
  1268 			}
       
  1269 		}
       
  1270 	}
       
  1271 
       
  1272 
       
  1273 // CBitDepth2Decoder
       
  1274 void CBitDepth2Decoder::DoConstructL()
       
  1275 	{
       
  1276 	if (!(iInfo.iColorType & TPngImageInformation::EPaletteUsed))
       
  1277 		{ // Set up palette to be grayscale values
       
  1278 		iInfo.iPalette[0] = KRgbBlack;
       
  1279 		iInfo.iPalette[1] = KRgbDarkGray;
       
  1280 		iInfo.iPalette[2] = KRgbGray;
       
  1281 		iInfo.iPalette[3] = KRgbWhite;
       
  1282 
       
  1283 		if (iInfo.iTransparencyPresent)
       
  1284 			{
       
  1285 			if (iInfo.iTransparentGray <= 3)
       
  1286 				iInfo.iTransparencyValue[iInfo.iTransparentGray] = 0;
       
  1287 			}
       
  1288 		}
       
  1289 
       
  1290 	// Replicate values to avoid shifts when decoding
       
  1291 	iInfo.iPalette[4] = iInfo.iPalette[1];
       
  1292 	iInfo.iPalette[8] = iInfo.iPalette[2];
       
  1293 	iInfo.iPalette[12] = iInfo.iPalette[3];
       
  1294 
       
  1295 	iInfo.iPalette[16] = iInfo.iPalette[1];
       
  1296 	iInfo.iPalette[32] = iInfo.iPalette[2];
       
  1297 	iInfo.iPalette[48] = iInfo.iPalette[3];
       
  1298 
       
  1299 	iInfo.iPalette[64] = iInfo.iPalette[1];
       
  1300 	iInfo.iPalette[128] = iInfo.iPalette[2];
       
  1301 	iInfo.iPalette[192] = iInfo.iPalette[3];
       
  1302 
       
  1303 	if (iInfo.iTransparencyPresent)
       
  1304 		{
       
  1305 		iInfo.iTransparencyValue[4] = iInfo.iTransparencyValue[1];
       
  1306 		iInfo.iTransparencyValue[8] = iInfo.iTransparencyValue[2];
       
  1307 		iInfo.iTransparencyValue[12] = iInfo.iTransparencyValue[3];
       
  1308 
       
  1309 		iInfo.iTransparencyValue[16] = iInfo.iTransparencyValue[1];
       
  1310 		iInfo.iTransparencyValue[32] = iInfo.iTransparencyValue[2];
       
  1311 		iInfo.iTransparencyValue[48] = iInfo.iTransparencyValue[3];
       
  1312 
       
  1313 		iInfo.iTransparencyValue[64] = iInfo.iTransparencyValue[1];
       
  1314 		iInfo.iTransparencyValue[128] = iInfo.iTransparencyValue[2];
       
  1315 		iInfo.iTransparencyValue[192] = iInfo.iTransparencyValue[3];
       
  1316 		}
       
  1317 
       
  1318 	iBytesPerPixel = 1;
       
  1319 	if (iInfo.iInterlaceMethod == TPngImageInformation::ENoInterlace)
       
  1320 		{
       
  1321 		TInt pixelPadding = ((iInfo.iSize.iWidth + 3) & ~3) - iInfo.iSize.iWidth;
       
  1322 		if(iImageProc)
       
  1323 			{
       
  1324 			iImageProc->SetPixelPadding(pixelPadding);	
       
  1325 			}
       
  1326 		if (iMaskProc)
       
  1327 			{
       
  1328 			iMaskProc->SetPixelPadding(pixelPadding);	
       
  1329 			}
       
  1330 		}
       
  1331 	}
       
  1332 
       
  1333 TInt CBitDepth2Decoder::ScanlineBufferSize(TInt aPixelLength)
       
  1334 	{
       
  1335 	return ((aPixelLength + 3) / 4) + KPngScanlineFilterTypeLength;
       
  1336 	}
       
  1337 
       
  1338 void CBitDepth2Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
       
  1339 	{
       
  1340 	if (iInfo.iTransparencyPresent && (iMaskProc || iAlphaMode) )
       
  1341 		{
       
  1342 		while (aDataPtr < aDataPtrLimit)
       
  1343 			{
       
  1344 			TInt dataValue = *aDataPtr++;
       
  1345 
       
  1346 			for (TInt mask=0xc0; mask!=0; mask>>=2) // iterate through 0xc0, 0x30, 0x0c and 0x03
       
  1347 				WritePixel(iInfo.iPalette[dataValue & mask],iInfo.iTransparencyValue[dataValue & mask]);
       
  1348 			}
       
  1349 		}
       
  1350 	else
       
  1351 		{
       
  1352 		while (aDataPtr < aDataPtrLimit)
       
  1353 			{
       
  1354 			TInt dataValue = *aDataPtr++;
       
  1355 
       
  1356 			for (TInt mask=0xc0; mask!=0; mask>>=2) // iterate through 0xc0, 0x30, 0x0c and 0x03
       
  1357 				WritePixel(iInfo.iPalette[dataValue & mask]);
       
  1358 			}
       
  1359 		}
       
  1360 	}
       
  1361 
       
  1362 
       
  1363 // CBitDepth4Decoder
       
  1364 void CBitDepth4Decoder::DoConstructL()
       
  1365 	{
       
  1366 	if (!(iInfo.iColorType & TPngImageInformation::EPaletteUsed))
       
  1367 		{ // Set up palette to be grayscale values
       
  1368 		for (TInt index = 0; index < 16; index++)
       
  1369 			iInfo.iPalette[index] = TRgb::Gray16(index);
       
  1370 
       
  1371 		if (iInfo.iTransparencyPresent)
       
  1372 			{
       
  1373 			if (iInfo.iTransparentGray <= 15)
       
  1374 				iInfo.iTransparencyValue[iInfo.iTransparentGray] = 0;
       
  1375 			}
       
  1376 		}
       
  1377 
       
  1378 	iBytesPerPixel = 1;
       
  1379 	if (iInfo.iInterlaceMethod == TPngImageInformation::ENoInterlace)
       
  1380 		{
       
  1381 		TInt pixelPadding = ((iInfo.iSize.iWidth + 1) & ~1) - iInfo.iSize.iWidth;
       
  1382 		if(iImageProc)
       
  1383 			{
       
  1384 			iImageProc->SetPixelPadding(pixelPadding);
       
  1385 			}			
       
  1386 		if (iMaskProc)
       
  1387 			{
       
  1388 			iMaskProc->SetPixelPadding(pixelPadding);
       
  1389 			}			
       
  1390 		}
       
  1391 	}
       
  1392 
       
  1393 TInt CBitDepth4Decoder::ScanlineBufferSize(TInt aPixelLength)
       
  1394 	{
       
  1395 	return ((aPixelLength + 1) / 2) + KPngScanlineFilterTypeLength;
       
  1396 	}
       
  1397 
       
  1398 void CBitDepth4Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
       
  1399 	{
       
  1400 	if (iInfo.iTransparencyPresent && (iMaskProc || iAlphaMode) )
       
  1401 		{
       
  1402 		while (aDataPtr < aDataPtrLimit)
       
  1403 			{
       
  1404 			TInt dataValue = *aDataPtr++;
       
  1405 
       
  1406 			WritePixel(iInfo.iPalette[dataValue >> 4],iInfo.iTransparencyValue[dataValue >> 4]);
       
  1407 			WritePixel(iInfo.iPalette[dataValue & 0x0f],iInfo.iTransparencyValue[dataValue & 0x0f]);
       
  1408 			}
       
  1409 		}
       
  1410 	else
       
  1411 		{
       
  1412 		while (aDataPtr < aDataPtrLimit)
       
  1413 			{
       
  1414 			TInt dataValue = *aDataPtr++;
       
  1415 
       
  1416 			WritePixel(iInfo.iPalette[dataValue >> 4]);
       
  1417 			WritePixel(iInfo.iPalette[dataValue & 0x0f]);
       
  1418 			}
       
  1419 		}
       
  1420 	}
       
  1421 
       
  1422 
       
  1423 // CBitDepth8Decoder
       
  1424 void CBitDepth8Decoder::DoConstructL()
       
  1425 	{
       
  1426 	if (!(iInfo.iColorType & TPngImageInformation::EPaletteUsed))
       
  1427 		{ // Set up palette to be grayscale values
       
  1428 		for (TInt index = 0; index < 256; index++)
       
  1429 			iInfo.iPalette[index] = TRgb::Gray256(index);
       
  1430 
       
  1431 		if (iInfo.iTransparencyPresent)
       
  1432 			{
       
  1433 			if (iInfo.iTransparentGray <= 255)
       
  1434 				iInfo.iTransparencyValue[iInfo.iTransparentGray] = 0;
       
  1435 			}
       
  1436 		}
       
  1437 
       
  1438 	iBytesPerPixel = 1;
       
  1439 	}
       
  1440 
       
  1441 TInt CBitDepth8Decoder::ScanlineBufferSize(TInt aPixelLength)
       
  1442 	{
       
  1443 	return aPixelLength + KPngScanlineFilterTypeLength;
       
  1444 	}
       
  1445 
       
  1446 void CBitDepth8Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
       
  1447 	{
       
  1448 	if (iInfo.iTransparencyPresent && (iMaskProc || iAlphaMode) )
       
  1449 		{
       
  1450 		while (aDataPtr < aDataPtrLimit)
       
  1451 			{
       
  1452 			WritePixel(iInfo.iPalette[aDataPtr[0]],iInfo.iTransparencyValue[aDataPtr[0]]);
       
  1453 			aDataPtr++;
       
  1454 			}
       
  1455 		}
       
  1456 	else
       
  1457 		{
       
  1458 		while (aDataPtr < aDataPtrLimit)
       
  1459 			WritePixel(iInfo.iPalette[*aDataPtr++]);
       
  1460 		}
       
  1461 	}
       
  1462 
       
  1463 
       
  1464 // CBitDepth8ColorType2Decoder
       
  1465 void CBitDepth8ColorType2Decoder::DoConstructL()
       
  1466 	{
       
  1467 	iBytesPerPixel = 3;
       
  1468 	}
       
  1469 
       
  1470 TInt CBitDepth8ColorType2Decoder::ScanlineBufferSize(TInt aPixelLength)
       
  1471 	{
       
  1472 	return (aPixelLength * 3) + KPngScanlineFilterTypeLength;
       
  1473 	}
       
  1474 
       
  1475 void CBitDepth8ColorType2Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
       
  1476 	{
       
  1477 	if (!iFastProcessorMode)
       
  1478 		{
       
  1479 		if (iInfo.iTransparencyPresent && (iMaskProc || iAlphaMode) )
       
  1480 			{
       
  1481 			while (aDataPtr < aDataPtrLimit)
       
  1482 				{
       
  1483 				TInt red = aDataPtr[0];
       
  1484 				TInt green = aDataPtr[1];
       
  1485 				TInt blue = aDataPtr[2];
       
  1486 				TRgb pixelColor(red,green,blue);
       
  1487 				if (red == iInfo.iTransparentRed && green == iInfo.iTransparentGreen && blue == iInfo.iTransparentBlue)
       
  1488 					{
       
  1489 					WritePixel(pixelColor,0);	
       
  1490 					}
       
  1491 				else
       
  1492 					{
       
  1493 					WritePixel(pixelColor,255);	
       
  1494 					}
       
  1495 				aDataPtr += 3;
       
  1496 				}
       
  1497 			}
       
  1498 		else
       
  1499 			{
       
  1500 			while (aDataPtr < aDataPtrLimit)
       
  1501 				{
       
  1502 				WritePixel(TRgb(aDataPtr[0],aDataPtr[1],aDataPtr[2]));
       
  1503 				aDataPtr += 3;
       
  1504 				}
       
  1505 			}
       
  1506 		}
       
  1507 	else
       
  1508 		{
       
  1509 		iFastProc->SetPixels(aDataPtr, aDataPtrLimit, iLineCache, iPos);
       
  1510 		}
       
  1511 	}
       
  1512 
       
  1513 
       
  1514 // CBitDepth8ColorType4Decoder
       
  1515 void CBitDepth8ColorType4Decoder::DoConstructL()
       
  1516 	{
       
  1517 	iBytesPerPixel = 2;
       
  1518 	}
       
  1519 
       
  1520 TInt CBitDepth8ColorType4Decoder::ScanlineBufferSize(TInt aPixelLength)
       
  1521 	{
       
  1522 	return (aPixelLength * 2) + KPngScanlineFilterTypeLength;
       
  1523 	}
       
  1524 
       
  1525 void CBitDepth8ColorType4Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
       
  1526 	{
       
  1527 	if (iMaskProc || iAlphaMode)
       
  1528 		{
       
  1529 		while (aDataPtr < aDataPtrLimit)
       
  1530 			{
       
  1531 			WritePixel(TRgb::Gray256(aDataPtr[0]),aDataPtr[1]);
       
  1532 			aDataPtr += 2;
       
  1533 			}
       
  1534 		}
       
  1535 	else
       
  1536 		{
       
  1537 		while (aDataPtr < aDataPtrLimit)
       
  1538 			{
       
  1539 			WritePixel(TRgb::Gray256(aDataPtr[0]));
       
  1540 			aDataPtr += 2;
       
  1541 			}
       
  1542 		}
       
  1543 	}
       
  1544 
       
  1545 
       
  1546 // CBitDepth8ColorType6Decoder
       
  1547 void CBitDepth8ColorType6Decoder::DoConstructL()
       
  1548 	{
       
  1549 	iBytesPerPixel = 4;
       
  1550 	}
       
  1551 
       
  1552 TInt CBitDepth8ColorType6Decoder::ScanlineBufferSize(TInt aPixelLength)
       
  1553 	{
       
  1554 	return (aPixelLength * 4) + KPngScanlineFilterTypeLength;
       
  1555 	}
       
  1556 
       
  1557 void CBitDepth8ColorType6Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
       
  1558 	{
       
  1559 	if (!iFastProcessorMode)
       
  1560 		{
       
  1561 		if (iMaskProc || iAlphaMode)
       
  1562 			{
       
  1563 			while (aDataPtr < aDataPtrLimit)
       
  1564 				{
       
  1565 				WritePixel(TRgb(aDataPtr[0],aDataPtr[1],aDataPtr[2]),aDataPtr[3]);
       
  1566 				aDataPtr += 4;
       
  1567 				}
       
  1568 			}
       
  1569 		else
       
  1570 			{
       
  1571 			while (aDataPtr < aDataPtrLimit)
       
  1572 				{
       
  1573 				WritePixel(TRgb(aDataPtr[0],aDataPtr[1],aDataPtr[2]));
       
  1574 				aDataPtr += 4;
       
  1575 				}
       
  1576 			}
       
  1577 		}
       
  1578 	else
       
  1579 		{
       
  1580 		iFastProc->SetPixels(aDataPtr, aDataPtrLimit, iLineCache, iPos);						
       
  1581 		}
       
  1582 	}
       
  1583 
       
  1584 
       
  1585 // CBitDepth16ColorType0Decoder
       
  1586 void CBitDepth16ColorType0Decoder::DoConstructL()
       
  1587 	{
       
  1588 	iBytesPerPixel = 2;
       
  1589 	}
       
  1590 
       
  1591 TInt CBitDepth16ColorType0Decoder::ScanlineBufferSize(TInt aPixelLength)
       
  1592 	{
       
  1593 	return (aPixelLength * 2) + KPngScanlineFilterTypeLength;
       
  1594 	}
       
  1595 
       
  1596 void CBitDepth16ColorType0Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
       
  1597 	{
       
  1598 	if (iInfo.iTransparencyPresent && (iMaskProc || iAlphaMode) )
       
  1599 		{
       
  1600 		while (aDataPtr < aDataPtrLimit)
       
  1601 			{
       
  1602 			TInt gray = (aDataPtr[0] << 8) | aDataPtr[1];
       
  1603 			TRgb pixelColor(TRgb::Gray256(aDataPtr[0]));
       
  1604 			if (gray == iInfo.iTransparentGray)
       
  1605 				WritePixel(pixelColor,0);
       
  1606 			else
       
  1607 				WritePixel(pixelColor,255);
       
  1608 			aDataPtr += 2;
       
  1609 			}
       
  1610 		}
       
  1611 	else
       
  1612 		{
       
  1613 		while (aDataPtr < aDataPtrLimit)
       
  1614 			{
       
  1615 			WritePixel(TRgb::Gray256(aDataPtr[0]));
       
  1616 			aDataPtr += 2;
       
  1617 			}
       
  1618 		}
       
  1619 	}
       
  1620 
       
  1621 
       
  1622 // CBitDepth16ColorType2Decoder
       
  1623 void CBitDepth16ColorType2Decoder::DoConstructL()
       
  1624 	{
       
  1625 	iBytesPerPixel = 6;
       
  1626 	}
       
  1627 
       
  1628 TInt CBitDepth16ColorType2Decoder::ScanlineBufferSize(TInt aPixelLength)
       
  1629 	{
       
  1630 	return (aPixelLength * 6) + KPngScanlineFilterTypeLength;
       
  1631 	}
       
  1632 
       
  1633 void CBitDepth16ColorType2Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
       
  1634 	{
       
  1635 	if (iInfo.iTransparencyPresent && (iMaskProc || iAlphaMode) )
       
  1636 		{
       
  1637 		while (aDataPtr < aDataPtrLimit)
       
  1638 			{
       
  1639 			TInt red = (aDataPtr[0] << 8) | aDataPtr[1];
       
  1640 			TInt green = (aDataPtr[2] << 8) | aDataPtr[3];
       
  1641 			TInt blue = (aDataPtr[4] << 8) | aDataPtr[5];
       
  1642 			TRgb pixelColor(aDataPtr[0],aDataPtr[2],aDataPtr[4]);
       
  1643 			if (red == iInfo.iTransparentRed && green == iInfo.iTransparentGreen && blue == iInfo.iTransparentBlue)
       
  1644 				WritePixel(pixelColor,0);
       
  1645 			else
       
  1646 				WritePixel(pixelColor,255);
       
  1647 			aDataPtr += 6;
       
  1648 			}
       
  1649 		}
       
  1650 	else
       
  1651 		{
       
  1652 		while (aDataPtr < aDataPtrLimit)
       
  1653 			{
       
  1654 			WritePixel(TRgb(aDataPtr[0],aDataPtr[2],aDataPtr[4]));
       
  1655 			aDataPtr += 6;
       
  1656 			}
       
  1657 		}
       
  1658 	}
       
  1659 
       
  1660 
       
  1661 // CBitDepth16ColorType4Decoder
       
  1662 void CBitDepth16ColorType4Decoder::DoConstructL()
       
  1663 	{
       
  1664 	iBytesPerPixel = 4;
       
  1665 	}
       
  1666 
       
  1667 TInt CBitDepth16ColorType4Decoder::ScanlineBufferSize(TInt aPixelLength)
       
  1668 	{
       
  1669 	return (aPixelLength * 4) + KPngScanlineFilterTypeLength;
       
  1670 	}
       
  1671 
       
  1672 void CBitDepth16ColorType4Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
       
  1673 	{
       
  1674 	if (iMaskProc || iAlphaMode)
       
  1675 		{
       
  1676 		while (aDataPtr < aDataPtrLimit)
       
  1677 			{
       
  1678 			WritePixel(TRgb::Gray256(aDataPtr[0]),aDataPtr[2]);
       
  1679 			aDataPtr += 4;
       
  1680 			}
       
  1681 		}
       
  1682 	else
       
  1683 		{
       
  1684 		while (aDataPtr < aDataPtrLimit)
       
  1685 			{
       
  1686 			WritePixel(TRgb::Gray256(aDataPtr[0]));
       
  1687 			aDataPtr += 4;
       
  1688 			}
       
  1689 		}
       
  1690 	}
       
  1691 
       
  1692 
       
  1693 // CBitDepth16ColorType6Decoder
       
  1694 void CBitDepth16ColorType6Decoder::DoConstructL()
       
  1695 	{
       
  1696 	iBytesPerPixel = 8;
       
  1697 	}
       
  1698 
       
  1699 TInt CBitDepth16ColorType6Decoder::ScanlineBufferSize(TInt aPixelLength)
       
  1700 	{
       
  1701 	return (aPixelLength * 8) + KPngScanlineFilterTypeLength;
       
  1702 	}
       
  1703 
       
  1704 void CBitDepth16ColorType6Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
       
  1705 	{
       
  1706 	if (iMaskProc || iAlphaMode)
       
  1707 		{
       
  1708 		while (aDataPtr < aDataPtrLimit)
       
  1709 			{
       
  1710 			WritePixel(TRgb(aDataPtr[0],aDataPtr[2],aDataPtr[4]),aDataPtr[6]);
       
  1711 			aDataPtr += 8;
       
  1712 			}
       
  1713 		}
       
  1714 	else
       
  1715 		{
       
  1716 		while (aDataPtr < aDataPtrLimit)
       
  1717 			{
       
  1718 			WritePixel(TRgb(aDataPtr[0],aDataPtr[2],aDataPtr[4]));
       
  1719 			aDataPtr += 8;
       
  1720 			}
       
  1721 		}
       
  1722 	}