imaging/imagingplugins/codecs/BMPCodec/BMPCodec.cpp
changeset 0 5752a19fdefe
equal deleted inserted replaced
-1:000000000000 0:5752a19fdefe
       
     1 // Copyright (c) 1999-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 <fbs.h>
       
    17 #include "ImageUtils.h"
       
    18 
       
    19 #include "BMPCodec.h"
       
    20 
       
    21 /**
       
    22 @file
       
    23 @internalComponent
       
    24 */
       
    25 
       
    26 // CBmpReadCodec
       
    27 CBmpReadCodec::CBmpReadCodec(const TSize& aBmpSize, const TRgb* aPalette):
       
    28 	iOriginalSize(aBmpSize),
       
    29 	iPalette(aPalette)
       
    30 	{}
       
    31 
       
    32 CBmpReadCodec::~CBmpReadCodec()
       
    33 	{
       
    34 	}
       
    35 
       
    36 
       
    37 
       
    38 TFrameState CBmpReadCodec::ProcessFrameL(TBufPtr8& aSrc)
       
    39 	{
       
    40 	const TUint8* srcStart = aSrc.Ptr();
       
    41 	iDataPtr = srcStart;
       
    42 	iDataPtrLimit = srcStart + aSrc.Length();
       
    43 
       
    44 	DoProcessL();
       
    45 
       
    46 	TInt bytesUsed = iDataPtr - srcStart;
       
    47 	aSrc.Shift(bytesUsed);
       
    48 	iBytesProcessed += bytesUsed;
       
    49 	if (iBytesProcessed >= iBytesExpected)
       
    50 		{
       
    51 		ImageProcessor()->FlushPixels();
       
    52 		return EFrameComplete;
       
    53 		}
       
    54 
       
    55 	return EFrameIncomplete;
       
    56 	}
       
    57 	
       
    58 void CBmpReadCodec::InitFrameL(TFrameInfo& aFrameInfo, CFrameImageData& /*aFrameImageData*/, TBool aDisableErrorDiffusion, CFbsBitmap& aDestination, CFbsBitmap* /*aDestinationMask*/)
       
    59 	{
       
    60 	iFrameSize = aFrameInfo.iFrameCoordsInPixels.Size();
       
    61 	Pos().iY = iOriginalSize.iHeight - 1;
       
    62 
       
    63 	const TSize destinationSize(aDestination.SizeInPixels());
       
    64 	TInt reductionFactor = ReductionFactor(iOriginalSize, destinationSize);
       
    65 	
       
    66 	CImageProcessor* imageProc = ImageProcessorUtility::NewImageProcessorL(aDestination, reductionFactor, ERgb, aDisableErrorDiffusion);
       
    67 
       
    68 	SetImageProcessor(imageProc);
       
    69 	
       
    70 	imageProc->PrepareL(aDestination, iOriginalSize);
       
    71 	imageProc->SetPos(TPoint(0,iOriginalSize.iHeight - 1));
       
    72 	imageProc->SetYPosIncrement(-1);
       
    73 	iBytesProcessed = 0;
       
    74 	DoNewFrameL();
       
    75 
       
    76 	ClearBitmapL(aDestination, KRgbWhite);
       
    77 		// clear full bitmap, in case of streaming partial decode
       
    78 	}
       
    79 
       
    80 void CBmpReadCodec::InitFrameHeader(TFrameInfo& aFrameInfo, CFrameImageData& /*aFrameData*/)
       
    81 	{
       
    82 	ASSERT(aFrameInfo.CurrentFrameState() == TFrameInfo::EFrameInfoUninitialised);
       
    83 	iFrameInfo = &aFrameInfo;
       
    84 	aFrameInfo.SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingFrameHeader);
       
    85 	}
       
    86 
       
    87 TFrameState CBmpReadCodec::ProcessFrameHeaderL(TBufPtr8&/* aData*/)
       
    88 	{
       
    89 	ASSERT(iFrameInfo);
       
    90 	iFrameInfo->SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingComplete);
       
    91 	return EFrameComplete;
       
    92 	}
       
    93 
       
    94 void CBmpReadCodec::DoNewFrameL()
       
    95 	{}
       
    96 
       
    97 
       
    98 // CBmp1BppReadCodec
       
    99 CBmp1BppReadCodec::CBmp1BppReadCodec(const TSize& aBmpSize, const TRgb* aPalette):
       
   100 	CBmpReadCodec(aBmpSize, aPalette)
       
   101 	{
       
   102 	ASSERT(iPalette);
       
   103 	}
       
   104 
       
   105 
       
   106 CBmp1BppReadCodec* CBmp1BppReadCodec::NewL(const TSize& aBmpSize, const TRgb* aPalette)
       
   107 {
       
   108 	CBmp1BppReadCodec* self = new(ELeave) CBmp1BppReadCodec(aBmpSize, aPalette);
       
   109 	CleanupStack::PushL(self);
       
   110 	self->ConstructL();
       
   111 	CleanupStack::Pop(self); // self
       
   112 	return self;
       
   113 }
       
   114 
       
   115 void CBmp1BppReadCodec::DoProcessL()
       
   116 	{
       
   117 	CImageProcessor *const imageProc = ImageProcessor();
       
   118 	while (iDataPtr < iDataPtrLimit)
       
   119 		{
       
   120 		TUint8 value = *iDataPtr++;
       
   121 
       
   122 		for(TUint8 pixelMask = 0x80; pixelMask!=0 ;pixelMask >>= 1)
       
   123 			imageProc->SetPixel((value & pixelMask) ? iEntry1 : iEntry0);
       
   124 		}
       
   125 	}
       
   126 
       
   127 void CBmp1BppReadCodec::DoNewFrameL()
       
   128 	{
       
   129 	iEntry0 = iPalette[0];
       
   130 	iEntry1 = iPalette[1];
       
   131 
       
   132 	TInt actualWidth = (iOriginalSize.iWidth + 31) & ~31;
       
   133 	ImageProcessor()->SetPixelPadding(actualWidth - iOriginalSize.iWidth);
       
   134 	iBytesExpected = (actualWidth >> 3) * iOriginalSize.iHeight;
       
   135 	}
       
   136 
       
   137 
       
   138 // CBmpNoComp4BppReadCodec
       
   139 CBmpNoComp4BppReadCodec* CBmpNoComp4BppReadCodec::NewL(const TSize& aBmpSize, const TRgb* aPalette)
       
   140 {
       
   141 	CBmpNoComp4BppReadCodec* self = new(ELeave) CBmpNoComp4BppReadCodec(aBmpSize, aPalette);
       
   142 	CleanupStack::PushL(self);
       
   143 	self->ConstructL();
       
   144 	CleanupStack::Pop(self); 
       
   145 	return self;
       
   146 }
       
   147 
       
   148 CBmpNoComp4BppReadCodec::CBmpNoComp4BppReadCodec(const TSize& aBmpSize, const TRgb* aPalette):
       
   149 	CBmpReadCodec(aBmpSize, aPalette)
       
   150 	{
       
   151 	ASSERT(iPalette);
       
   152 	}
       
   153 
       
   154 void CBmpNoComp4BppReadCodec::DoNewFrameL()
       
   155 	{
       
   156 	TInt actualWidth = (iOriginalSize.iWidth + 7) & ~7;
       
   157 	ImageProcessor()->SetPixelPadding(actualWidth - iOriginalSize.iWidth);
       
   158 	iBytesExpected = (actualWidth >> 1) * iOriginalSize.iHeight;
       
   159 	}
       
   160 
       
   161 void CBmpNoComp4BppReadCodec::DoProcessL()
       
   162 	{
       
   163 	CImageProcessor *const imageProc = ImageProcessor();
       
   164 	while (iDataPtr < iDataPtrLimit)
       
   165 		{
       
   166 		TUint8 value = *iDataPtr++;
       
   167 		imageProc->SetPixel(iPalette[value >> 4]);
       
   168 		imageProc->SetPixel(iPalette[value & 0x0f]);
       
   169 		}
       
   170 	}
       
   171 
       
   172 
       
   173 // CBmpRLE4ReadCodec
       
   174 CBmpRLE4ReadCodec* CBmpRLE4ReadCodec::NewL(const TSize& aBmpSize, const TRgb* aPalette)
       
   175 {
       
   176 	CBmpRLE4ReadCodec* self = new(ELeave) CBmpRLE4ReadCodec(aBmpSize, aPalette);
       
   177 	CleanupStack::PushL(self);
       
   178 	self->ConstructL();
       
   179 	CleanupStack::Pop(self); 
       
   180 	return self;
       
   181 }
       
   182 
       
   183 CBmpRLE4ReadCodec::CBmpRLE4ReadCodec(const TSize& aBmpSize, const TRgb* aPalette):
       
   184 	CBmpReadCodec(aBmpSize, aPalette)
       
   185 	{
       
   186 	ASSERT(iPalette);
       
   187 	}
       
   188 
       
   189 void CBmpRLE4ReadCodec::DoNewFrameL()
       
   190 	{
       
   191 	iBytesExpected = KMaxTInt;
       
   192 	}
       
   193 
       
   194 void CBmpRLE4ReadCodec::DoProcessL()
       
   195 	{
       
   196 	const TUint8* srcSafeLimit = iDataPtrLimit - 1;
       
   197 
       
   198 	TPoint& pos = Pos();
       
   199 	CImageProcessor*const imageProc = ImageProcessor();
       
   200 
       
   201 	while (iDataPtr < srcSafeLimit || pos.iY < 0)
       
   202 		{
       
   203 		TUint8 index = *iDataPtr++;
       
   204 		if (index > 0) // Encoded mode
       
   205 			WriteRun(*iDataPtr++,index);
       
   206 		else
       
   207 			{
       
   208 			index = *iDataPtr++;
       
   209 			if (index > 2) // Absolute mode
       
   210 				{
       
   211 				TInt byteCount = (index + ((index & 1) ? 1 : 0)) >> 1;
       
   212 				TInt padding = (byteCount & 1) ? 1 : 0;
       
   213 				if ((iDataPtr + (byteCount + padding)) > iDataPtrLimit)
       
   214 					{
       
   215 					iDataPtr -= 2;
       
   216 					break;
       
   217 					}
       
   218 				WriteData(index);
       
   219 				if (padding)
       
   220 					iDataPtr++;
       
   221 				}
       
   222 			else if (index == 0) // End of line
       
   223 				{
       
   224 				pos.iX = 0;
       
   225 				pos.iY--;
       
   226 				if (!imageProc->SetPos(pos))
       
   227 					{
       
   228 					iBytesExpected = 0;
       
   229 					break;
       
   230 					}
       
   231 				}
       
   232 			else if (index == 1) // End of bitmap
       
   233 				{
       
   234 				iBytesExpected = 0;
       
   235 				Pos().iY = -1;
       
   236 				break;
       
   237 				}
       
   238 			else // Delta
       
   239 				{
       
   240 				if ((iDataPtr + 2) > iDataPtrLimit)
       
   241 					{
       
   242 					iDataPtr -= 2;
       
   243 					break;
       
   244 					}
       
   245 				imageProc->FlushPixels();
       
   246 				pos.iX += *iDataPtr++;
       
   247 				pos.iY -= *iDataPtr++;
       
   248 				if (!imageProc->SetPos(pos))
       
   249 					break;
       
   250 				}
       
   251 			}
       
   252 		}
       
   253 	if (pos.iY < 0)
       
   254 	    {
       
   255 	    // that may mean a dodgy image, so flag decoding immediately complete
       
   256 	    iBytesExpected = 0;
       
   257 	    }		
       
   258 	}
       
   259 
       
   260 void CBmpRLE4ReadCodec::WriteRun(TUint8 aValue, TInt aNumPixels)
       
   261 	{
       
   262 	CImageProcessor*const imageProc = ImageProcessor();
       
   263 	Pos().iX += aNumPixels;
       
   264 	TRgb highValue = iPalette[aValue >> 4];
       
   265 	TRgb lowValue = iPalette[aValue & 0x0f];
       
   266 	TInt numPixels;
       
   267 	for (numPixels = aNumPixels; numPixels > 1; numPixels -= 2)
       
   268 		{
       
   269 		imageProc->SetPixel(highValue);
       
   270 		imageProc->SetPixel(lowValue);
       
   271 		}
       
   272 	if (numPixels & 1)
       
   273 		imageProc->SetPixel(highValue);
       
   274 	}
       
   275 
       
   276 void CBmpRLE4ReadCodec::WriteData(TInt aNumPixels)
       
   277 	{
       
   278 	CImageProcessor*const imageProc = ImageProcessor();
       
   279 	const TUint8* dataPtrLimit = iDataPtr + (aNumPixels >> 1);
       
   280 	while (iDataPtr < dataPtrLimit)
       
   281 		{
       
   282 		TUint8 value = *iDataPtr++;
       
   283 		imageProc->SetPixel(iPalette[value >> 4]);
       
   284 		imageProc->SetPixel(iPalette[value & 0x0f]);
       
   285 		}
       
   286 	if (aNumPixels & 1)
       
   287 		{
       
   288 		TUint8 value = *iDataPtr++;
       
   289 		imageProc->SetPixel(iPalette[value >> 4]);
       
   290 		}
       
   291 	Pos().iX += aNumPixels;
       
   292 	}
       
   293 
       
   294 
       
   295 // CBmpNoComp8BppReadCodec
       
   296 CBmpNoComp8BppReadCodec* CBmpNoComp8BppReadCodec::NewL(const TSize& aBmpSize, const TRgb* aPalette)
       
   297 {
       
   298 	CBmpNoComp8BppReadCodec* self = new(ELeave) CBmpNoComp8BppReadCodec(aBmpSize, aPalette);
       
   299 	CleanupStack::PushL(self);
       
   300 	self->ConstructL();
       
   301 	CleanupStack::Pop(self);
       
   302 	return self;
       
   303 }
       
   304 
       
   305 CBmpNoComp8BppReadCodec::CBmpNoComp8BppReadCodec(const TSize& aBmpSize, const TRgb* aPalette):
       
   306 	CBmpReadCodec(aBmpSize, aPalette)
       
   307 	{
       
   308 	ASSERT(iPalette);
       
   309 	}
       
   310 
       
   311 void CBmpNoComp8BppReadCodec::DoNewFrameL()
       
   312 	{
       
   313 	TInt actualWidth = (iOriginalSize.iWidth + 3) & ~3;
       
   314 	ImageProcessor()->SetPixelPadding(actualWidth - iOriginalSize.iWidth);
       
   315 	iBytesExpected = actualWidth * iOriginalSize.iHeight;
       
   316 	}
       
   317 
       
   318 void CBmpNoComp8BppReadCodec::DoProcessL()
       
   319 	{
       
   320 	CImageProcessor*const imageProc = ImageProcessor();
       
   321 	while (iDataPtr < iDataPtrLimit)
       
   322 		imageProc->SetPixel(iPalette[*iDataPtr++]);
       
   323 	}
       
   324 
       
   325 
       
   326 // CBmpRLE8ReadCodec
       
   327 CBmpRLE8ReadCodec* CBmpRLE8ReadCodec::NewL(const TSize& aBmpSize, const TRgb* aPalette)
       
   328 {
       
   329 	CBmpRLE8ReadCodec* self = new(ELeave) CBmpRLE8ReadCodec(aBmpSize, aPalette);
       
   330 	CleanupStack::PushL(self);
       
   331 	self->ConstructL();
       
   332 	CleanupStack::Pop(self); 
       
   333 	return self;
       
   334 }
       
   335 
       
   336 CBmpRLE8ReadCodec::CBmpRLE8ReadCodec(const TSize& aBmpSize, const TRgb* aPalette):
       
   337 	CBmpReadCodec(aBmpSize, aPalette)
       
   338 	{
       
   339 	ASSERT(iPalette);
       
   340 	}
       
   341 
       
   342 void CBmpRLE8ReadCodec::DoNewFrameL()
       
   343 	{
       
   344 	iBytesExpected = KMaxTInt;
       
   345 	}
       
   346 
       
   347 void CBmpRLE8ReadCodec::DoProcessL()
       
   348 	{
       
   349 	const TUint8* srcSafeLimit = iDataPtrLimit - 1;
       
   350 
       
   351 	TPoint& pos = Pos();
       
   352 	CImageProcessor*const imageProc = ImageProcessor();
       
   353 
       
   354 	while (iDataPtr < srcSafeLimit || pos.iY < 0)
       
   355 		{
       
   356 		TUint8 index = *iDataPtr++;
       
   357 		if (index > 0) // Encoded mode
       
   358 			WriteRun(*iDataPtr++,index);
       
   359 		else
       
   360 			{
       
   361 			index = *iDataPtr++;
       
   362 			if (index > 2) // Absolute mode
       
   363 				{
       
   364 				TInt padding = (index & 1) ? 1 : 0;
       
   365 				if ((iDataPtr + (index + padding)) > iDataPtrLimit)
       
   366 					{
       
   367 					iDataPtr -= 2;
       
   368 					break;
       
   369 					}
       
   370 				WriteData(index);
       
   371 				if (padding)
       
   372 					iDataPtr++;
       
   373 				}
       
   374 			else if (index == 0) // End of line
       
   375 				{
       
   376 				pos.iX = 0;
       
   377 				pos.iY--;
       
   378 				if (!imageProc->SetPos(pos))
       
   379 					{
       
   380 					iBytesExpected = 0;
       
   381 					break;
       
   382 					}
       
   383 				}
       
   384 			else if (index == 1) // End of bitmap
       
   385 				{
       
   386 				iBytesExpected = 0;
       
   387 				Pos().iY = -1;
       
   388 				break;
       
   389 				}
       
   390 			else // Delta
       
   391 				{
       
   392 				if ((iDataPtr + 2) > iDataPtrLimit)
       
   393 					{
       
   394 					iDataPtr -= 2;
       
   395 					break;
       
   396 					}
       
   397 				imageProc->FlushPixels();
       
   398 				pos.iX += *iDataPtr++;
       
   399 				pos.iY -= *iDataPtr++;
       
   400 				if (!imageProc->SetPos(pos))
       
   401 					break;
       
   402 				}
       
   403 			}
       
   404 		}
       
   405 	
       
   406 	if (pos.iY < 0)
       
   407 	    {
       
   408 	    // that may indicate a dodgy image, so flag decoding complete
       
   409 	    iBytesExpected = 0;
       
   410 	    }
       
   411 	}
       
   412 
       
   413 void CBmpRLE8ReadCodec::WriteRun(TUint8 aValue, TInt aNumPixels)
       
   414 	{
       
   415 	CImageProcessor*const imageProc = ImageProcessor();
       
   416 	Pos().iX += aNumPixels;
       
   417 	TRgb value = iPalette[aValue];
       
   418 	for (; aNumPixels > 0; aNumPixels--)
       
   419 		imageProc->SetPixel(value);
       
   420 	}
       
   421 
       
   422 void CBmpRLE8ReadCodec::WriteData(TInt aNumPixels)
       
   423 	{
       
   424 	CImageProcessor*const imageProc = ImageProcessor();
       
   425 	Pos().iX += aNumPixels;
       
   426 	const TUint8* dataPtrLimit = iDataPtr + aNumPixels;
       
   427 	while (iDataPtr < dataPtrLimit)
       
   428 		imageProc->SetPixel(iPalette[*iDataPtr++]);
       
   429 	}
       
   430 
       
   431 /*static*/
       
   432 CBmpBiRgbReadCodec* CBmpBiRgbReadCodec::NewL(const TSize& aBmpSize, TInt aPixelSize, const TRgb* aPalette)
       
   433 	{
       
   434 	CBmpBiRgbReadCodec* self = new(ELeave) CBmpBiRgbReadCodec(aBmpSize, aPixelSize, aPalette);
       
   435 	CleanupStack::PushL(self);
       
   436 	self->ConstructL();
       
   437 	CleanupStack::Pop(self); 
       
   438 	return self;
       
   439 	}
       
   440 
       
   441 CBmpBiRgbReadCodec::CBmpBiRgbReadCodec(const TSize& aBmpSize, TInt aPixelSize, const TRgb* aPalette): 
       
   442 	CBmpReadCodec(aBmpSize, aPalette),
       
   443 	iPixelSize(aPixelSize)
       
   444 	{
       
   445 	}
       
   446 /**
       
   447 	calculate:
       
   448 	1. mask used to extract channel value
       
   449 	2. right shift value used to place channel value into "low" byte
       
   450 	3. left shift value used to scale up channel if it has got less than 8 bits
       
   451 */	
       
   452 void CBmpBiRgbReadCodec::ConstructL()
       
   453 	{
       
   454 	// 16 Bpp 5-5-5 bitmaps do not have masks defined
       
   455 	// as they are "standard", so use predefined ones
       
   456 	static const TUint32 KDefault555Masks[]=
       
   457 		{
       
   458 		0x7C00u,	//red
       
   459 		0x03E0u,	//green
       
   460 		0x001Fu  	//blue
       
   461 		};
       
   462 		
       
   463 	CBmpReadCodec::ConstructL();
       
   464 	
       
   465 	const TRgb* const masks= iPalette ? iPalette : reinterpret_cast<const TRgb*>(KDefault555Masks);
       
   466 
       
   467 	for (TInt comp=0; comp<=KBlueCompIdx; comp++)
       
   468 		{
       
   469 		iCompInfo[comp].iMask = 0x00FFFFFF & masks[comp].Internal(); // ignore the alpha channel
       
   470 		TInt shiftVal=0;
       
   471 		const TUint maskValue=iCompInfo[comp].iMask;
       
   472 		while (shiftVal < sizeof(TUint32) * 8 && ((maskValue >> shiftVal) &1 )==0)
       
   473 			{
       
   474 			++shiftVal;
       
   475 			}
       
   476 		iCompInfo[comp].iRightShiftValue = shiftVal;
       
   477 		while (shiftVal < sizeof(TUint32) * 8 && ((maskValue >> shiftVal) &1) !=0 )
       
   478 			{
       
   479 			++shiftVal;
       
   480 			}
       
   481 		iCompInfo[comp].iLeftShiftValue = 8 - (shiftVal - iCompInfo[comp].iRightShiftValue);
       
   482 		if (iCompInfo[comp].iLeftShiftValue < 0)
       
   483 			{
       
   484 			// We've got image with bad mask
       
   485 			User::Leave(KErrCorrupt);
       
   486 			}
       
   487 		}
       
   488 	}
       
   489 	
       
   490 void CBmpBiRgbReadCodec::DoProcessL()
       
   491 	{
       
   492 	TInt bytesRemaining = iDataPtrLimit - iDataPtr;			
       
   493 	CImageProcessor* const imageProc = ImageProcessor();
       
   494 	while (bytesRemaining >= iPixelSize)
       
   495 		{
       
   496 		TInt bytesToWrite = iPixelByteWidth - iBytePos;
       
   497 		if (bytesToWrite > 0)
       
   498 			{
       
   499 			TInt pixelsToWrite = Min(bytesRemaining, bytesToWrite) / iPixelSize;
       
   500 			const TInt bytesWritten = pixelsToWrite * iPixelSize;
       
   501 			const TUint8* const tempDataPtrLimit = iDataPtr + bytesWritten;
       
   502 			bytesRemaining 	-= bytesWritten;
       
   503 			iBytePos 		+= bytesWritten;
       
   504 			while (iDataPtr < tempDataPtrLimit)
       
   505 				{
       
   506 				TUint pixelValue;
       
   507 				switch (iPixelSize)
       
   508 					{
       
   509 					case sizeof(TUint16):
       
   510 						pixelValue=PtrReadUtil::ReadUint16(iDataPtr);
       
   511 						break;
       
   512 						
       
   513 					case sizeof(TUint16) + sizeof(TUint8):
       
   514 						pixelValue=PtrReadUtil::ReadUint16(iDataPtr) | (iDataPtr[2] << 16);
       
   515 						break;
       
   516 						
       
   517 					case sizeof(TUint32):
       
   518 						pixelValue=PtrReadUtil::ReadUint32(iDataPtr);
       
   519 						break;						
       
   520 						
       
   521 					default:
       
   522 						ASSERT(EFalse);
       
   523 						pixelValue = 0;
       
   524 					}
       
   525 				TInt red=((pixelValue & iCompInfo[KRedCompIdx].iMask) >> iCompInfo[KRedCompIdx].iRightShiftValue) << iCompInfo[KRedCompIdx].iLeftShiftValue;
       
   526 				red |=red >> (8 - iCompInfo[KRedCompIdx].iLeftShiftValue);
       
   527 				
       
   528 				TInt green = ((pixelValue & iCompInfo[KGreenCompIdx].iMask) >> iCompInfo[KGreenCompIdx].iRightShiftValue) << iCompInfo[KGreenCompIdx].iLeftShiftValue;
       
   529 				green |= green >> (8 - iCompInfo[KGreenCompIdx].iLeftShiftValue);
       
   530 				
       
   531 				TInt blue = ((pixelValue & iCompInfo[KBlueCompIdx].iMask) >> iCompInfo[KBlueCompIdx].iRightShiftValue) << iCompInfo[KBlueCompIdx].iLeftShiftValue;
       
   532 				blue |= blue >> (8 - iCompInfo[KBlueCompIdx].iLeftShiftValue);
       
   533 				
       
   534 				imageProc->SetPixel( TRgb(red, green, blue) );
       
   535 				iDataPtr += iPixelSize;
       
   536 				}
       
   537 			}
       
   538 
       
   539 		if (iBytePos >= iPixelByteWidth)
       
   540 			{
       
   541 			const TInt KBytesToSkip = Min(bytesRemaining, iTotalByteWidth - iBytePos);
       
   542 			bytesRemaining -= KBytesToSkip;
       
   543 			iBytePos += KBytesToSkip;
       
   544 			iDataPtr += KBytesToSkip;
       
   545 			}
       
   546 
       
   547 		if (iBytePos >= iTotalByteWidth)
       
   548 			{
       
   549 			iBytePos = 0;
       
   550 			}
       
   551 		}	
       
   552 	}
       
   553 	
       
   554 void CBmpBiRgbReadCodec::DoNewFrameL()
       
   555 	{
       
   556 	if (iPixelSize < 4)
       
   557 		{
       
   558 		iTotalByteWidth = ((iOriginalSize.iWidth * iPixelSize) + iPixelSize) & ~iPixelSize;
       
   559 		}
       
   560 	else
       
   561 		{
       
   562 		iTotalByteWidth = (iOriginalSize.iWidth * iPixelSize);
       
   563 		}
       
   564 	
       
   565 	iPixelByteWidth = (iOriginalSize.iWidth * iPixelSize);
       
   566 	iPaddingByteWidth = iTotalByteWidth - iPixelByteWidth;
       
   567 	iBytePos = 0;
       
   568 	iBytesExpected = iTotalByteWidth * iOriginalSize.iHeight;
       
   569 	}
       
   570 
       
   571 // CBmp24BppReadCodec
       
   572 CBmp24BppReadCodec* CBmp24BppReadCodec::NewL(const TSize& aBmpSize)
       
   573 {
       
   574 	CBmp24BppReadCodec* self = new(ELeave) CBmp24BppReadCodec(aBmpSize);
       
   575 	CleanupStack::PushL(self);
       
   576 	self->ConstructL();
       
   577 	CleanupStack::Pop(self); 
       
   578 	return self;
       
   579 }
       
   580 
       
   581 CBmp24BppReadCodec::CBmp24BppReadCodec(const TSize& aBmpSize)
       
   582 	: CBmpReadCodec(aBmpSize, NULL)
       
   583 	{}
       
   584 
       
   585 void CBmp24BppReadCodec::DoProcessL()
       
   586 	{
       
   587 	TInt bytesRemaining = iDataPtrLimit - iDataPtr;			
       
   588 	CImageProcessor*const imageProc = ImageProcessor();
       
   589 	while (bytesRemaining > 2)
       
   590 		{
       
   591 		TInt bytesToWrite = iPixelByteWidth - iBytePos;
       
   592 		if (bytesToWrite > 0)
       
   593 			{
       
   594 			TInt pixelsToWrite = Min(bytesRemaining, bytesToWrite) / 3;
       
   595 			TInt bytesWritten = pixelsToWrite * 3;
       
   596 			const TUint8* tempDataPtrLimit = iDataPtr + bytesWritten;
       
   597 			bytesRemaining -= bytesWritten;
       
   598 			iBytePos += bytesWritten;
       
   599 			while (iDataPtr < tempDataPtrLimit)
       
   600 				{
       
   601 				imageProc->SetPixel(TRgb(iDataPtr[2], iDataPtr[1], iDataPtr[0]));
       
   602 				iDataPtr += 3;
       
   603 				}
       
   604 			}
       
   605 
       
   606 		if (iBytePos >= iPixelByteWidth)
       
   607 			{
       
   608 			TInt bytesToSkip = Min(bytesRemaining, iTotalByteWidth - iBytePos);
       
   609 			bytesRemaining -= bytesToSkip;
       
   610 			iBytePos += bytesToSkip;
       
   611 			iDataPtr += bytesToSkip;
       
   612 			}
       
   613 
       
   614 		if (iBytePos >= iTotalByteWidth)
       
   615 			iBytePos = 0;
       
   616 		}
       
   617 	}
       
   618 
       
   619 void CBmp24BppReadCodec::DoNewFrameL()
       
   620 	{
       
   621 	iTotalByteWidth = ((iOriginalSize.iWidth * 3) + 3) & ~3;
       
   622 	iPixelByteWidth = (iOriginalSize.iWidth * 3);
       
   623 	iPaddingByteWidth = iTotalByteWidth - iPixelByteWidth;
       
   624 	iBytePos = 0;
       
   625 	iBytesExpected = iTotalByteWidth * iOriginalSize.iHeight;
       
   626 	}
       
   627 
       
   628 // CBmp32BppReadCodec
       
   629 CBmp32BppReadCodec* CBmp32BppReadCodec::NewL(const TSize& aBmpSize)
       
   630 {
       
   631 	CBmp32BppReadCodec* self = new(ELeave) CBmp32BppReadCodec(aBmpSize);
       
   632 	CleanupStack::PushL(self);
       
   633 	self->ConstructL();
       
   634 	CleanupStack::Pop(self); 
       
   635 	return self;
       
   636 }
       
   637 
       
   638 CBmp32BppReadCodec::CBmp32BppReadCodec(const TSize& aBmpSize)
       
   639 	: CBmpReadCodec(aBmpSize, NULL)
       
   640 	{}
       
   641 
       
   642 void CBmp32BppReadCodec::DoProcessL()
       
   643 	{
       
   644 	TInt bytesRemaining = iDataPtrLimit - iDataPtr;
       
   645 	CImageProcessor*const imageProc = ImageProcessor();
       
   646 	while (bytesRemaining > 3)
       
   647 		{
       
   648 		TInt bytesToWrite = iPixelByteWidth - iBytePos;
       
   649 		if (bytesToWrite > 0)
       
   650 			{
       
   651 			TInt pixelsToWrite = Min(bytesRemaining, bytesToWrite) / 4;
       
   652 			TInt bytesWritten = pixelsToWrite * 4;
       
   653 			const TUint8* tempDataPtrLimit = iDataPtr + bytesWritten;
       
   654 			bytesRemaining -= bytesWritten;
       
   655 			iBytePos += bytesWritten;
       
   656 			while (iDataPtr < tempDataPtrLimit)
       
   657 				{
       
   658 				imageProc->SetPixel(TRgb(iDataPtr[2], iDataPtr[1], iDataPtr[0]));
       
   659 				iDataPtr += 4;
       
   660 				}
       
   661 			}
       
   662 
       
   663 		if (iBytePos >= iPixelByteWidth)
       
   664 			{
       
   665 			TInt bytesToSkip = Min(bytesRemaining, iTotalByteWidth - iBytePos);
       
   666 			bytesRemaining -= bytesToSkip;
       
   667 			iBytePos += bytesToSkip;
       
   668 			iDataPtr += bytesToSkip;
       
   669 			}
       
   670 
       
   671 		if (iBytePos >= iTotalByteWidth)
       
   672 			iBytePos = 0;
       
   673 		}
       
   674 	}
       
   675 
       
   676 void CBmp32BppReadCodec::DoNewFrameL()
       
   677 	{
       
   678 	iTotalByteWidth = iOriginalSize.iWidth * 4;
       
   679 	iPixelByteWidth = iTotalByteWidth;
       
   680 	iPaddingByteWidth = iTotalByteWidth - iPixelByteWidth;
       
   681 	iBytePos = 0;
       
   682 	iBytesExpected = iTotalByteWidth * iOriginalSize.iHeight;
       
   683 	}
       
   684 
       
   685 // CBmpWriteCodec
       
   686 void CBmpWriteCodec::InitFrameL(TBufPtr8& aDst, const CFbsBitmap& aSource)
       
   687 	{
       
   688 	SetSource(&aSource);
       
   689 	iSourceRect = TRect(aSource.SizeInPixels());
       
   690 	iPos.SetXY(0,0);
       
   691 	iPos.iY = iSourceRect.iBr.iY - 1;
       
   692 	iPaddingBytes = PaddingBytes();
       
   693 	iBytesToWrite = 0;
       
   694 	aDst.SetLength(0); //No frame header
       
   695 	}
       
   696 
       
   697 TFrameState CBmpWriteCodec::ProcessFrameL(TBufPtr8& aDst)
       
   698 	{
       
   699 	//Setup buffer to use all available space
       
   700 	TUint8* destStartPtr = CONST_CAST(TUint8*,aDst.Ptr());
       
   701 	iDestPtr = destStartPtr;
       
   702 	iDestPtrLimit = iDestPtr + aDst.MaxLength();
       
   703 
       
   704 	DoProcessL(*Source());
       
   705 
       
   706 	aDst.SetLength(iDestPtr - destStartPtr);
       
   707 
       
   708 	// If processed all pixels
       
   709 	if (iPos.iY < iSourceRect.iTl.iY)
       
   710 		return EFrameComplete;
       
   711 
       
   712 	return EFrameIncomplete;
       
   713 	}
       
   714 
       
   715 
       
   716 // CBmp1BppWriteCodec
       
   717 CBmp1BppWriteCodec* CBmp1BppWriteCodec::NewL(void)
       
   718 {
       
   719 	CBmp1BppWriteCodec* self = new(ELeave) CBmp1BppWriteCodec();
       
   720 	CleanupStack::PushL(self);
       
   721 	self->ConstructL();
       
   722 	CleanupStack::Pop(self); 
       
   723 	return self;
       
   724 }
       
   725 
       
   726 TInt CBmp1BppWriteCodec::PaddingBytes()
       
   727 	{
       
   728 	TInt byteWidth = (iSourceRect.Size().iWidth + 7) / 8;
       
   729 	return ((byteWidth + 3) & ~3) - byteWidth;
       
   730 	}
       
   731 
       
   732 void CBmp1BppWriteCodec::DoProcessL(const CFbsBitmap& aFrame)
       
   733 	{
       
   734 	while (iDestPtr < iDestPtrLimit)
       
   735 		{
       
   736 		for ( ; (iBytesToWrite > 0) && (iDestPtr < iDestPtrLimit) ; iBytesToWrite--)
       
   737 			*iDestPtr++ = 0;
       
   738 
       
   739 		if (iPos.iY < 0)
       
   740 			break;
       
   741 
       
   742 		TInt scanLength = Min(iSourceRect.iBr.iX - iPos.iX, (iDestPtrLimit - iDestPtr) * 8);
       
   743 		TInt dstLength = (scanLength + 7) / 8;
       
   744 		TPtr8 dstBuf(iDestPtr,dstLength,dstLength);
       
   745 
       
   746 		aFrame.GetScanLine(dstBuf, iPos, scanLength, EGray2);
       
   747 
       
   748 		iPos.iX += scanLength;
       
   749 		TUint8* tempDestPtrLimit = iDestPtr + dstLength;
       
   750 		while (iDestPtr < tempDestPtrLimit)
       
   751 			{
       
   752 			TUint8 tempVal = iDestPtr[0];
       
   753 			TUint reverseVal = 0;
       
   754 			TUint origValCopy = tempVal;
       
   755 			for(TInt countBit = 0; countBit<8; countBit++)
       
   756 				{
       
   757 				reverseVal<<=1;
       
   758 				reverseVal |= origValCopy & 1;
       
   759 				origValCopy>>=1;
       
   760 				}
       
   761 			iDestPtr[0] = TUint8(reverseVal);
       
   762 			iDestPtr++;
       
   763 			}
       
   764 
       
   765 		if (iPos.iX == iSourceRect.iBr.iX)
       
   766 			{
       
   767 			iPos.iX = iSourceRect.iTl.iX;
       
   768 			iPos.iY--;
       
   769 			iBytesToWrite = iPaddingBytes;
       
   770 			}
       
   771 		}
       
   772 	}
       
   773 
       
   774 
       
   775 // CBmp4BppWriteCodec
       
   776 CBmp4BppWriteCodec* CBmp4BppWriteCodec::NewL(void)
       
   777 {
       
   778 	CBmp4BppWriteCodec* self = new(ELeave) CBmp4BppWriteCodec();
       
   779 	CleanupStack::PushL(self);
       
   780 	self->ConstructL();
       
   781 	CleanupStack::Pop(self); 
       
   782 	return self;
       
   783 }
       
   784 
       
   785 TInt CBmp4BppWriteCodec::PaddingBytes()
       
   786 	{
       
   787 	TInt byteWidth = (iSourceRect.Size().iWidth + 1) / 2;
       
   788 	return ((byteWidth + 3) & ~3) - byteWidth;
       
   789 	}
       
   790 
       
   791 void CBmp4BppWriteCodec::DoProcessL(const CFbsBitmap& aFrame)
       
   792 	{
       
   793 	while (iDestPtr < iDestPtrLimit)
       
   794 		{
       
   795 		for ( ; (iBytesToWrite > 0) && (iDestPtr < iDestPtrLimit) ; iBytesToWrite--)
       
   796 			*iDestPtr++ = 0;
       
   797 
       
   798 		if (iPos.iY < 0)
       
   799 			break;
       
   800 
       
   801 		TInt scanLength = Min(iSourceRect.iBr.iX - iPos.iX, (iDestPtrLimit - iDestPtr) * 2);
       
   802 		TInt dstLength = (scanLength + 1) / 2;
       
   803 		TPtr8 dstBuf(iDestPtr,dstLength,dstLength);
       
   804 
       
   805 		aFrame.GetScanLine(dstBuf, iPos, scanLength, EColor16);
       
   806 
       
   807 		iPos.iX += scanLength;
       
   808 		TUint8* tempDestPtrLimit = iDestPtr + dstLength;
       
   809 		while (iDestPtr < tempDestPtrLimit)
       
   810 			{
       
   811 			TInt tempVal = iDestPtr[0];
       
   812 			TInt lowNibble = tempVal << 4;
       
   813 			TInt highNibble = tempVal >> 4;
       
   814 			iDestPtr[0] = TUint8(lowNibble | highNibble);
       
   815 			iDestPtr++;
       
   816 			}
       
   817 
       
   818 		if (iPos.iX == iSourceRect.iBr.iX)
       
   819 			{
       
   820 			iPos.iX = iSourceRect.iTl.iX;
       
   821 			iPos.iY--;
       
   822 			iBytesToWrite = iPaddingBytes;
       
   823 			}
       
   824 		}
       
   825 	}
       
   826 
       
   827 
       
   828 // CBmp8BppWriteCodec
       
   829 CBmp8BppWriteCodec* CBmp8BppWriteCodec::NewL(void)
       
   830 {
       
   831 	CBmp8BppWriteCodec* self = new(ELeave) CBmp8BppWriteCodec();
       
   832 	CleanupStack::PushL(self);
       
   833 	self->ConstructL();
       
   834 	CleanupStack::Pop(self); 
       
   835 	return self;
       
   836 }
       
   837 
       
   838 TInt CBmp8BppWriteCodec::PaddingBytes()
       
   839 	{
       
   840 	TInt byteWidth = iSourceRect.Size().iWidth;
       
   841 	return ((byteWidth + 3) & ~3) - byteWidth;
       
   842 	}
       
   843 
       
   844 void CBmp8BppWriteCodec::DoProcessL(const CFbsBitmap& aFrame)
       
   845 	{
       
   846 	while (iDestPtr < iDestPtrLimit)
       
   847 		{
       
   848 		for ( ; (iBytesToWrite > 0) && (iDestPtr < iDestPtrLimit) ; iBytesToWrite--)
       
   849 			*iDestPtr++ = 0;
       
   850 
       
   851 		if (iPos.iY < 0)
       
   852 			break;
       
   853 
       
   854 		TInt scanLength = Min(iSourceRect.iBr.iX - iPos.iX, iDestPtrLimit - iDestPtr);
       
   855 		TPtr8 dstBuf(iDestPtr, scanLength, scanLength);
       
   856 
       
   857 		aFrame.GetScanLine(dstBuf, iPos, scanLength, EColor256);
       
   858 
       
   859 		iPos.iX += scanLength;
       
   860 		iDestPtr += scanLength;
       
   861 
       
   862 		if (iPos.iX == iSourceRect.iBr.iX)
       
   863 			{
       
   864 			iPos.iX = iSourceRect.iTl.iX;
       
   865 			iPos.iY--;
       
   866 			iBytesToWrite = iPaddingBytes;
       
   867 			}
       
   868 		}
       
   869 	}
       
   870 
       
   871 
       
   872 // CBmp24BppWriteCodec
       
   873 CBmp24BppWriteCodec* CBmp24BppWriteCodec::NewL(void)
       
   874 {
       
   875 	CBmp24BppWriteCodec* self = new(ELeave) CBmp24BppWriteCodec();
       
   876 	CleanupStack::PushL(self);
       
   877 	self->ConstructL();
       
   878 	CleanupStack::Pop(self); 
       
   879 	return self;
       
   880 }
       
   881 
       
   882 TInt CBmp24BppWriteCodec::PaddingBytes()
       
   883 	{
       
   884 	TInt byteWidth = iSourceRect.Size().iWidth * 3;
       
   885 	return ((byteWidth + 3) & ~3) - byteWidth;
       
   886 	}
       
   887 
       
   888 void CBmp24BppWriteCodec::DoProcessL(const CFbsBitmap& aFrame)
       
   889 	{
       
   890 	TUint8* safeDestPtrLimit = iDestPtrLimit - 2;
       
   891 
       
   892 	while (iDestPtr < safeDestPtrLimit)
       
   893 		{
       
   894 		for ( ; (iBytesToWrite > 0) && (iDestPtr < iDestPtrLimit) ; iBytesToWrite--)
       
   895 			*iDestPtr++ = 0;
       
   896 
       
   897 		if (iPos.iY < 0)
       
   898 			break;
       
   899 
       
   900 		TInt scanLength = Min(iSourceRect.iBr.iX - iPos.iX, (iDestPtrLimit - iDestPtr) / 3);
       
   901 		TInt dstLength = scanLength * 3;
       
   902 		TPtr8 dstBuf(iDestPtr, dstLength, dstLength);
       
   903 
       
   904 		aFrame.GetScanLine(dstBuf, iPos, scanLength, EColor16M);
       
   905 
       
   906 		iPos.iX += scanLength;
       
   907 		iDestPtr += dstLength;
       
   908 
       
   909 		if (iPos.iX == iSourceRect.iBr.iX)
       
   910 			{
       
   911 			iPos.iX = iSourceRect.iTl.iX;
       
   912 			iPos.iY--;
       
   913 			iBytesToWrite = iPaddingBytes;
       
   914 			}
       
   915 		}
       
   916 	}
       
   917