mmplugins/imagingplugins/codecs/MBMCodec/MBMCodec.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     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 <s32mem.h>
       
    18 #include "ImageClientMain.h"
       
    19 #include "MBMCodec.h"
       
    20 
       
    21 _LIT(KMBMPanicCategory, "MBMConvertPlugin");
       
    22 
       
    23 // Global panic function
       
    24 GLDEF_C void Panic(TIclPanic aError)
       
    25 	{
       
    26 	User::Panic(KMBMPanicCategory, aError);
       
    27 	}
       
    28 
       
    29 
       
    30 // CMbmReadCodec
       
    31 CMbmReadCodec::CMbmReadCodec(TUint32 aMbmRootStreamOffset)
       
    32 :iMbmRootStreamOffset(aMbmRootStreamOffset)
       
    33 	{
       
    34 	}
       
    35 
       
    36 CMbmReadCodec::~CMbmReadCodec()
       
    37 	{
       
    38 	delete iCodecProc;
       
    39 	}
       
    40 
       
    41 
       
    42 CMbmReadCodec* CMbmReadCodec::NewL(TUint32 aMbmRootStreamOffset)
       
    43 {
       
    44 	CMbmReadCodec* self = new(ELeave) CMbmReadCodec(aMbmRootStreamOffset);
       
    45 	CleanupStack::PushL(self);
       
    46 	self->ConstructL();
       
    47 	CleanupStack::Pop(self); 
       
    48 	return self;
       
    49 }
       
    50 
       
    51 TDisplayMode CMbmReadCodec::DisplayModeL(TInt aBitsPerPixel, TUint32 aFlags)
       
    52 	{	
       
    53 	if (aFlags & TFrameInfo::EColor)
       
    54 		{
       
    55 		switch (aBitsPerPixel)
       
    56 			{
       
    57 			case 4:
       
    58 				return EColor16;
       
    59 			case 8:
       
    60 				return EColor256;
       
    61 			case 12:
       
    62 				return EColor4K;
       
    63 			case 16:
       
    64 				return EColor64K;
       
    65 			case 24:
       
    66 				return EColor16M;
       
    67 			case 32:	
       
    68 				if(aFlags & TFrameInfo::EAlphaChannel)
       
    69 					{
       
    70 					return EColor16MA;	
       
    71 					}
       
    72 				else
       
    73 					{
       
    74 					return EColor16MU;
       
    75 					}
       
    76 			default:
       
    77 				User::Leave(KErrNotSupported);
       
    78 			}
       
    79 		}
       
    80 	else
       
    81 		{
       
    82 		switch (aBitsPerPixel)
       
    83 			{
       
    84 			case 1:
       
    85 				return EGray2;
       
    86 			case 2:
       
    87 				return EGray4;
       
    88 			case 4:
       
    89 				return EGray16;
       
    90 			case 8:
       
    91 				return EGray256;
       
    92 			default:
       
    93 				User::Leave(KErrNotSupported);
       
    94 			}
       
    95 		}
       
    96 
       
    97 	return ENone;
       
    98 	}
       
    99 
       
   100 void CMbmReadCodec::InitFrameL(TFrameInfo& aFrameInfo, CFrameImageData& aFrameImageData, TBool aDisableErrorDiffusion, CFbsBitmap& aFrame, CFbsBitmap* /*aFrameMask*/)
       
   101 	{
       
   102 	iFrameInfo = &aFrameInfo;
       
   103 	iFrameData = STATIC_CAST(TMbmDecodeData*, aFrameImageData.GetFrameData(0));
       
   104  	iCompressed = iFrameData->iCompressed;
       
   105 
       
   106 	iByteLength = iFrameData->iImageDataSizeInBytes;
       
   107 
       
   108 	TPoint& pos = Pos();
       
   109 	pos.SetXY(0,0);
       
   110 
       
   111 	TSize originalSize(iFrameInfo->iFrameCoordsInPixels.Size());
       
   112 
       
   113 	TDisplayMode displayMode = DisplayModeL(iFrameInfo->iBitsPerPixel,iFrameInfo->iFlags);
       
   114 	const TSize destinationSize(aFrame.SizeInPixels());
       
   115 	TInt reductionFactor = ReductionFactor(originalSize, destinationSize);
       
   116 	
       
   117 	CImageProcessor* imageProc = ImageProcessorUtility::NewImageProcessorL(aFrame, reductionFactor, displayMode, aDisableErrorDiffusion);
       
   118 	SetImageProcessor(imageProc);
       
   119 
       
   120 	imageProc->PrepareL(aFrame,originalSize);
       
   121 	TInt scanLinePixels = ScanLinePixels(originalSize.iWidth);
       
   122 	imageProc->SetPixelPadding(scanLinePixels - originalSize.iWidth);
       
   123 	SetCodecProcessorL();
       
   124 
       
   125 	ClearBitmapL(aFrame, KRgbWhite);
       
   126 		// clear in case of streamed partial decodes
       
   127 	}
       
   128 
       
   129 void CMbmReadCodec::InitFrameHeader(TFrameInfo& aFrameSettings, CFrameImageData& aFrameImageData)
       
   130 	{
       
   131 	ASSERT(aFrameSettings.CurrentFrameState() == TFrameInfo::EFrameInfoUninitialised);
       
   132 	iFrameInfo = &aFrameSettings;
       
   133 	iImageData = &aFrameImageData;
       
   134 	iFrameInfo->SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingFrameHeader);
       
   135 	}
       
   136 
       
   137 TFrameState CMbmReadCodec::ProcessFrameHeaderL(TBufPtr8& aData)
       
   138 	{
       
   139 	iStartDataPtr = CONST_CAST(TUint8*,aData.Ptr());
       
   140 	iDataPtr = iStartDataPtr;
       
   141 	iDataPtrLimit = iStartDataPtr + aData.Length();
       
   142 
       
   143 	if (iFrameInfo->CurrentFrameState() == TFrameInfo::EFrameInfoProcessingFrame)
       
   144 		{
       
   145 		if(iFrameDataRemaining <= aData.Length())
       
   146 			iNumberOfFrames++;
       
   147 		else
       
   148 			{
       
   149 			iMbmRootStreamOffset -= aData.Length();
       
   150 			iFrameDataRemaining -= aData.Length();
       
   151 			aData.Shift(aData.Length());
       
   152 			return EFrameIncomplete;
       
   153 			}
       
   154 	
       
   155 		if ((iMbmRootStreamOffset-iFrameDataRemaining) == 0)
       
   156 			{
       
   157 			iFrameInfo->SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingComplete);
       
   158 			return EFrameComplete;
       
   159 			}
       
   160 		else if ((iMbmRootStreamOffset - iFrameDataRemaining) < KMbmInfoHeaderSize)
       
   161 			{
       
   162 			//Bitmap StreamLength is too short to continue processing. 
       
   163 			User::Leave(KErrCorrupt);
       
   164 			}
       
   165 		else
       
   166 			{
       
   167 			aData.Shift(iFrameDataRemaining);
       
   168 			iMbmRootStreamOffset -= iFrameDataRemaining;
       
   169 
       
   170 			iFrameInfo->SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingComplete);
       
   171 			return EFrameIncomplete;
       
   172 			}
       
   173 		}
       
   174 
       
   175 	if (iFrameInfo->CurrentFrameState() == TFrameInfo::EFrameInfoProcessingFrameHeader)
       
   176 		{
       
   177 		if (aData.Length()<KMbmInfoHeaderSize)
       
   178 			User::Leave(KErrUnderflow);
       
   179 		
       
   180 		TMbmDecodeData* mbmDecodeData = new(ELeave)TMbmDecodeData;
       
   181 		CleanupStack::PushL(mbmDecodeData);
       
   182 
       
   183 		User::LeaveIfError(iImageData->AppendFrameData(mbmDecodeData));
       
   184 		CleanupStack::Pop(); // mbmImageData
       
   185 
       
   186 		SEpocBitmapHeader header;
       
   187 		RDesReadStream stream;
       
   188 		stream.Open(aData);
       
   189 		CleanupClosePushL(stream);
       
   190 		header.iBitmapSize=stream.ReadInt32L();
       
   191 		header.iStructSize=stream.ReadInt32L();
       
   192 		if (header.iStructSize!=sizeof(SEpocBitmapHeader)) User::Leave(KErrCorrupt);
       
   193 		header.iSizeInPixels.iWidth=stream.ReadInt32L();
       
   194 		header.iSizeInPixels.iHeight=stream.ReadInt32L();
       
   195 		header.iSizeInTwips.iWidth=stream.ReadInt32L();
       
   196 		header.iSizeInTwips.iHeight=stream.ReadInt32L();
       
   197 		header.iBitsPerPixel=stream.ReadInt32L();
       
   198 		header.iColor=stream.ReadUint32L();
       
   199 		header.iPaletteEntries=stream.ReadInt32L();
       
   200 		header.iCompression=(TBitmapfileCompression)stream.ReadUint32L();
       
   201 		CleanupStack::PopAndDestroy(); //stream
       
   202 
       
   203 		if (header.iBitmapSize<KMbmInfoHeaderSize)
       
   204 			User::Leave(KErrCorrupt);
       
   205 
       
   206 		iFrameDataRemaining = header.iBitmapSize - KMbmInfoHeaderSize;
       
   207 		if (iMbmRootStreamOffset<KMbmInfoHeaderSize)
       
   208 			User::Leave(KErrCorrupt);
       
   209 
       
   210 		iMbmRootStreamOffset -= KMbmInfoHeaderSize;
       
   211 		TInt frameDataOffset = iFrameInfo->FrameDataOffset();
       
   212 		iFrameInfo->SetFrameDataOffset(frameDataOffset + KMbmInfoHeaderSize);
       
   213 		iFrameInfo->iFrameCoordsInPixels.SetRect(TPoint(0,0),header.iSizeInPixels);
       
   214 		iFrameInfo->iOverallSizeInPixels = header.iSizeInPixels;
       
   215 		iFrameInfo->iFrameSizeInTwips = header.iSizeInTwips;
       
   216 		iFrameInfo->iBitsPerPixel = header.iBitsPerPixel;
       
   217 		iFrameInfo->iDelay = 0;
       
   218 		iFrameInfo->iFlags = TFrameInfo::ECanDither;
       
   219 
       
   220 		switch(header.iColor)
       
   221 			{
       
   222 			case SEpocBitmapHeader::ENoColor:
       
   223 				break;
       
   224 			case SEpocBitmapHeader::EColor:
       
   225 				iFrameInfo->iFlags |= TFrameInfo::EColor;
       
   226 				break;
       
   227 			case SEpocBitmapHeader::EColorAlpha:
       
   228 				iFrameInfo->iFlags |= TFrameInfo::EColor;
       
   229 				iFrameInfo->iFlags |= TFrameInfo::ETransparencyPossible;
       
   230 				iFrameInfo->iFlags |= TFrameInfo::EAlphaChannel;
       
   231 				break;
       
   232 			default:
       
   233 				User::Leave(KErrNotSupported);
       
   234 			}
       
   235 
       
   236 		mbmDecodeData->iCompressed = header.iCompression;
       
   237 		mbmDecodeData->iImageDataSizeInBytes = header.iBitmapSize - header.iStructSize;
       
   238 
       
   239 		if (iFrameInfo->iFrameCoordsInPixels.iBr.iX < 0 || iFrameInfo->iFrameCoordsInPixels.iBr.iY < 0 ||
       
   240 			iFrameInfo->iFrameSizeInTwips.iWidth < 0 || iFrameInfo->iFrameSizeInTwips.iHeight < 0 ||
       
   241 			!(iFrameInfo->iBitsPerPixel == 1 || iFrameInfo->iBitsPerPixel == 2 || 
       
   242 			iFrameInfo->iBitsPerPixel == 4 || iFrameInfo->iBitsPerPixel == 8 || 
       
   243 			iFrameInfo->iBitsPerPixel == 12 || iFrameInfo->iBitsPerPixel == 16 || 
       
   244 			iFrameInfo->iBitsPerPixel == 24 || iFrameInfo->iBitsPerPixel == 32))
       
   245 			User::Leave(KErrCorrupt);
       
   246 
       
   247 		switch (iFrameInfo->iBitsPerPixel)
       
   248 			{
       
   249 		case 1:
       
   250 			iFrameInfo->iFrameDisplayMode = EGray2;
       
   251 			break;
       
   252 
       
   253 		case 2:
       
   254 			iFrameInfo->iFrameDisplayMode = EGray4;
       
   255 			break;
       
   256 
       
   257 		case 4:
       
   258 			iFrameInfo->iFrameDisplayMode = (iFrameInfo->iFlags & TFrameInfo::EColor) ? EColor16 : EGray16;
       
   259 			break;
       
   260 
       
   261 		case 8:
       
   262 			iFrameInfo->iFrameDisplayMode = (iFrameInfo->iFlags & TFrameInfo::EColor) ? EColor256 : EGray256;
       
   263 			break;
       
   264 
       
   265 		case 12:
       
   266 			iFrameInfo->iFrameDisplayMode = EColor4K;
       
   267 			break;
       
   268 
       
   269 		case 16:
       
   270 			iFrameInfo->iFrameDisplayMode = EColor64K;
       
   271 			break;
       
   272 
       
   273 		case 24:
       
   274 			iFrameInfo->iFrameDisplayMode = EColor16M;
       
   275 			break;
       
   276 
       
   277 		case 32:
       
   278 			if(iFrameInfo->iFlags & TFrameInfo::ETransparencyPossible && iFrameInfo->iFlags & TFrameInfo::EAlphaChannel)
       
   279 				{
       
   280 				iFrameInfo->iFrameDisplayMode = EColor16MA;
       
   281 				}
       
   282 			else
       
   283 				{
       
   284 				iFrameInfo->iFrameDisplayMode = EColor16MU;
       
   285 				}
       
   286 			break;
       
   287 			}
       
   288 
       
   289 		aData.Shift(KMbmInfoHeaderSize);
       
   290 		iFrameInfo->SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingFrame);
       
   291 		}
       
   292 
       
   293 	return EFrameIncomplete;
       
   294 	}
       
   295 
       
   296 TFrameState CMbmReadCodec::ProcessFrameL(TBufPtr8& aSrc)
       
   297 	{
       
   298 	TUint8* srcPtr = CONST_CAST(TUint8*,aSrc.Ptr());
       
   299 	iDataPtr = srcPtr;
       
   300 	iDataPtrLimit = iDataPtr + Min(aSrc.Length(),iByteLength);
       
   301 
       
   302 	iCodecProc->DoProcessL(iDataPtr,iDataPtrLimit);
       
   303 	TInt bytesUsed = iDataPtr - srcPtr;
       
   304 	aSrc.Shift(bytesUsed);
       
   305 	iByteLength -= bytesUsed;
       
   306 
       
   307 	if (iByteLength == 0)
       
   308 		{
       
   309 		ImageProcessor()->FlushPixels();
       
   310 		delete iCodecProc;
       
   311 		iCodecProc = NULL;
       
   312 		return EFrameComplete;
       
   313 		}
       
   314 	return EFrameIncomplete;
       
   315 	}
       
   316 
       
   317 TInt CMbmReadCodec::ScanLinePixels(TInt aWidth)
       
   318 	{
       
   319 	switch (iFrameInfo->iBitsPerPixel)
       
   320 		{
       
   321 	case 1:
       
   322 		return CFbsBitmap::ScanLineLength(aWidth,EGray2) << 3;
       
   323 	case 2:
       
   324 		return CFbsBitmap::ScanLineLength(aWidth,EGray4) << 2;
       
   325 	case 4:
       
   326 		return CFbsBitmap::ScanLineLength(aWidth,EGray16) << 1;
       
   327 	case 8:
       
   328 		return CFbsBitmap::ScanLineLength(aWidth,EGray256);
       
   329 	case 12:
       
   330 	case 16:
       
   331 		return CFbsBitmap::ScanLineLength(aWidth,EColor64K) >> 1;
       
   332 	case 24:
       
   333 		return CFbsBitmap::ScanLineLength(aWidth,EColor16M) / 3;
       
   334 	case 32:
       
   335 		return CFbsBitmap::ScanLineLength(aWidth,EColor16MU) / 4; // for all 32bit modes
       
   336 	default:
       
   337 		return 0;
       
   338 		}
       
   339 	}
       
   340 
       
   341 void CMbmReadCodec::SetCodecProcessorL()
       
   342 	{
       
   343 	delete iCodecProc;
       
   344 	iCodecProc = NULL;
       
   345 	const TBool color = (iFrameInfo->iFlags & TFrameInfo::EColor);
       
   346 
       
   347 	switch (iFrameInfo->iBitsPerPixel)
       
   348 		{
       
   349 	case 1:
       
   350 		if (iCompressed)
       
   351 			iCodecProc = new(ELeave) T1BppCompressedMbmReadCodec;
       
   352 		else
       
   353 			iCodecProc = new(ELeave) T1BppMbmReadCodec;
       
   354 		break;
       
   355 	case 2:
       
   356 		if (iCompressed)
       
   357 			iCodecProc = new(ELeave) T2BppCompressedMbmReadCodec;
       
   358 		else
       
   359 			iCodecProc = new(ELeave) T2BppMbmReadCodec;
       
   360 		break;
       
   361 	case 4:
       
   362 		if (color)
       
   363 			{
       
   364 			if (iCompressed)
       
   365 				iCodecProc = new(ELeave) T4BppColorCompressedMbmReadCodec;
       
   366 			else
       
   367 				iCodecProc = new(ELeave) T4BppColorMbmReadCodec;
       
   368 			}
       
   369 		else
       
   370 			{
       
   371 			if (iCompressed)
       
   372 				iCodecProc = new(ELeave) T4BppMonoCompressedMbmReadCodec;
       
   373 			else
       
   374 				iCodecProc = new(ELeave) T4BppMonoMbmReadCodec;
       
   375 			}
       
   376 		break;
       
   377 	case 8:
       
   378 		if (color)
       
   379 			{
       
   380 			if (iCompressed)
       
   381 				iCodecProc = new(ELeave) T8BppColorCompressedMbmReadCodec;
       
   382 			else
       
   383 				iCodecProc = new(ELeave) T8BppColorMbmReadCodec;
       
   384 			}
       
   385 		else
       
   386 			{
       
   387 			if (iCompressed)
       
   388 				iCodecProc = new(ELeave) T8BppMonoCompressedMbmReadCodec;
       
   389 			else
       
   390 				iCodecProc = new(ELeave) T8BppMonoMbmReadCodec;
       
   391 			}
       
   392 		break;
       
   393 	case 12:
       
   394 		if (iCompressed)
       
   395 			iCodecProc = new(ELeave) T12BppCompressedMbmReadCodec;
       
   396 		else
       
   397 			iCodecProc = new(ELeave) T12BppMbmReadCodec;
       
   398 		break;
       
   399 	case 16:
       
   400 		if (iCompressed)
       
   401 			iCodecProc = new(ELeave) T16BppCompressedMbmReadCodec;
       
   402 		else
       
   403 			iCodecProc = new(ELeave) T16BppMbmReadCodec;
       
   404 		break;
       
   405 	case 24:
       
   406 		if (iCompressed)
       
   407 			iCodecProc = new(ELeave) T24BppCompressedMbmReadCodec;
       
   408 		else
       
   409 			iCodecProc = new(ELeave) T24BppMbmReadCodec;
       
   410 		break;
       
   411 	case 32:
       
   412 		if (iCompressed)
       
   413 			User::Leave(KErrNotSupported);
       
   414 		else
       
   415 			iCodecProc = new(ELeave) T32BppMbmReadCodec;
       
   416 		break;
       
   417 	default:
       
   418 		User::Leave(KErrCorrupt);
       
   419 		}
       
   420 
       
   421 	iCodecProc->iImageProc = ImageProcessor();
       
   422 	}
       
   423 
       
   424 
       
   425 // TMbmReadCodec
       
   426 void TMbmReadCodec::AddPixelRun(TRgb aColor,TInt aNumberOfPixels)
       
   427 	{
       
   428 	iImageProc->SetPixelRun(aColor,aNumberOfPixels);
       
   429 	}
       
   430 
       
   431 
       
   432 // T1BppMbmReadCodec
       
   433 void T1BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   434 	{
       
   435 	while (aDataPtr < aDataPtrLimit)
       
   436 		AddPixelValue(*aDataPtr++);
       
   437 	}
       
   438 
       
   439 void T1BppMbmReadCodec::AddPixelValue(TUint8 aValue)
       
   440 	{
       
   441 	iImageProc->SetPixel((aValue & 0x01) ? KRgbWhite : KRgbBlack);
       
   442 	iImageProc->SetPixel((aValue & 0x02) ? KRgbWhite : KRgbBlack);
       
   443 	iImageProc->SetPixel((aValue & 0x04) ? KRgbWhite : KRgbBlack);
       
   444 	iImageProc->SetPixel((aValue & 0x08) ? KRgbWhite : KRgbBlack);
       
   445 	iImageProc->SetPixel((aValue & 0x10) ? KRgbWhite : KRgbBlack);
       
   446 	iImageProc->SetPixel((aValue & 0x20) ? KRgbWhite : KRgbBlack);
       
   447 	iImageProc->SetPixel((aValue & 0x40) ? KRgbWhite : KRgbBlack);
       
   448 	iImageProc->SetPixel((aValue & 0x80) ? KRgbWhite : KRgbBlack);
       
   449 	}
       
   450 
       
   451 
       
   452 // T1BppCompressedMbmReadCodec
       
   453 void T1BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   454 	{
       
   455 	while (aDataPtr < aDataPtrLimit)
       
   456 		{
       
   457 		TInt8 count = *aDataPtr++;
       
   458 
       
   459 		if (count >= 0)
       
   460 			{
       
   461 			if (aDataPtr >= aDataPtrLimit)
       
   462 				{
       
   463 				aDataPtr--;
       
   464 				break;
       
   465 				}
       
   466 			AddPixelRun(*aDataPtr++,count + 1);
       
   467 			}
       
   468 		else
       
   469 			{
       
   470 			TUint8* tempDataPtrLimit = aDataPtr - count;
       
   471 			if (tempDataPtrLimit > aDataPtrLimit)
       
   472 				{
       
   473 				aDataPtr--;
       
   474 				break;
       
   475 				}
       
   476 			while (aDataPtr < tempDataPtrLimit)
       
   477 				AddPixelValue(*aDataPtr++);
       
   478 			}
       
   479 		}
       
   480 	}
       
   481 
       
   482 void T1BppCompressedMbmReadCodec::AddPixelRun(TUint8 aValue,TInt aNumberOfValues)
       
   483 	{
       
   484 	TRgb color0 = (aValue & 0x01) ? KRgbWhite : KRgbBlack;
       
   485 	TRgb color1 = (aValue & 0x02) ? KRgbWhite : KRgbBlack;
       
   486 	TRgb color2 = (aValue & 0x04) ? KRgbWhite : KRgbBlack;
       
   487 	TRgb color3 = (aValue & 0x08) ? KRgbWhite : KRgbBlack;
       
   488 	TRgb color4 = (aValue & 0x10) ? KRgbWhite : KRgbBlack;
       
   489 	TRgb color5 = (aValue & 0x20) ? KRgbWhite : KRgbBlack;
       
   490 	TRgb color6 = (aValue & 0x40) ? KRgbWhite : KRgbBlack;
       
   491 	TRgb color7 = (aValue & 0x80) ? KRgbWhite : KRgbBlack;
       
   492 
       
   493 	for (; aNumberOfValues > 0; aNumberOfValues--)
       
   494 		{
       
   495 		iImageProc->SetPixel(color0);
       
   496 		iImageProc->SetPixel(color1);
       
   497 		iImageProc->SetPixel(color2);
       
   498 		iImageProc->SetPixel(color3);
       
   499 		iImageProc->SetPixel(color4);
       
   500 		iImageProc->SetPixel(color5);
       
   501 		iImageProc->SetPixel(color6);
       
   502 		iImageProc->SetPixel(color7);
       
   503 		}
       
   504 	}
       
   505 
       
   506 
       
   507 // T2BppMbmReadCodec
       
   508 void T2BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   509 	{
       
   510 	while (aDataPtr < aDataPtrLimit)
       
   511 		AddPixelValue(*aDataPtr++);
       
   512 	}
       
   513 
       
   514 void T2BppMbmReadCodec::AddPixelValue(TUint8 aValue)
       
   515 	{
       
   516 	iImageProc->SetPixel(TRgb::Gray4(aValue & 0x3));
       
   517 	iImageProc->SetPixel(TRgb::Gray4((aValue >> 2) & 0x3));
       
   518 	iImageProc->SetPixel(TRgb::Gray4((aValue >> 4) & 0x3));
       
   519 	iImageProc->SetPixel(TRgb::Gray4((aValue >> 6) & 0x3));
       
   520 	}
       
   521 
       
   522 
       
   523 // T2BppCompressedMbmReadCodec
       
   524 void T2BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   525 	{
       
   526 	while (aDataPtr < aDataPtrLimit)
       
   527 		{
       
   528 		TInt8 count = *aDataPtr++;
       
   529 
       
   530 		if (count >= 0)
       
   531 			{
       
   532 			if (aDataPtr >= aDataPtrLimit)
       
   533 				{
       
   534 				aDataPtr--;
       
   535 				break;
       
   536 				}
       
   537 			AddPixelRun(*aDataPtr++,count + 1);
       
   538 			}
       
   539 		else
       
   540 			{
       
   541 			TUint8* tempDataPtrLimit = aDataPtr - count;
       
   542 			if (tempDataPtrLimit > aDataPtrLimit)
       
   543 				{
       
   544 				aDataPtr--;
       
   545 				break;
       
   546 				}
       
   547 			while (aDataPtr < tempDataPtrLimit)
       
   548 				AddPixelValue(*aDataPtr++);
       
   549 			}
       
   550 		}
       
   551 	}
       
   552 
       
   553 void T2BppCompressedMbmReadCodec::AddPixelRun(TUint8 aValue,TInt aNumberOfQuads)
       
   554 	{
       
   555 	TRgb color0 = TRgb::Gray4(aValue & 0x3);
       
   556 	TRgb color1 = TRgb::Gray4((aValue >> 2) & 0x3);
       
   557 	TRgb color2 = TRgb::Gray4((aValue >> 4) & 0x3);
       
   558 	TRgb color3 = TRgb::Gray4((aValue >> 6) & 0x3);
       
   559 
       
   560 	for (; aNumberOfQuads > 0; aNumberOfQuads--)
       
   561 		{
       
   562 		iImageProc->SetPixel(color0);
       
   563 		iImageProc->SetPixel(color1);
       
   564 		iImageProc->SetPixel(color2);
       
   565 		iImageProc->SetPixel(color3);
       
   566 		}
       
   567 	}
       
   568 
       
   569 
       
   570 // T4BppMbmReadCodec
       
   571 void T4BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   572 	{
       
   573 	while (aDataPtr < aDataPtrLimit)
       
   574 		{
       
   575 		TInt value = *aDataPtr++;
       
   576 		iImageProc->SetPixel(ColorFromIndex(value & 0xf));
       
   577 		iImageProc->SetPixel(ColorFromIndex(value >> 4));
       
   578 		}
       
   579 	}
       
   580 
       
   581 
       
   582 // T4BppCompressedMbmReadCodec
       
   583 void T4BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   584 	{
       
   585 	while (aDataPtr < aDataPtrLimit)
       
   586 		{
       
   587 		TInt8 count = *aDataPtr++;
       
   588 
       
   589 		if (count >= 0)
       
   590 			{
       
   591 			if (aDataPtr >= aDataPtrLimit)
       
   592 				{
       
   593 				aDataPtr--;
       
   594 				break;
       
   595 				}
       
   596 			TInt value = *aDataPtr++;
       
   597 			AddPixelRun(ColorFromIndex(value & 0xf),ColorFromIndex(value >> 4),count + 1);
       
   598 			}
       
   599 		else
       
   600 			{
       
   601 			TUint8* tempDataPtrLimit = aDataPtr - count;
       
   602 			if (tempDataPtrLimit > aDataPtrLimit)
       
   603 				{
       
   604 				aDataPtr--;
       
   605 				break;
       
   606 				}
       
   607 			while (aDataPtr < tempDataPtrLimit)
       
   608 				{
       
   609 				TInt value = *aDataPtr++;
       
   610 				iImageProc->SetPixel(ColorFromIndex(value & 0xf));
       
   611 				iImageProc->SetPixel(ColorFromIndex(value >> 4));
       
   612 				}
       
   613 			}
       
   614 		}
       
   615 	}
       
   616 
       
   617 void T4BppCompressedMbmReadCodec::AddPixelRun(TRgb aColor1,TRgb aColor2,TInt aNumberOfPairs)
       
   618 	{
       
   619 	for (; aNumberOfPairs > 0; aNumberOfPairs--)
       
   620 		{
       
   621 		iImageProc->SetPixel(aColor1);
       
   622 		iImageProc->SetPixel(aColor2);
       
   623 		}
       
   624 	}
       
   625 
       
   626 
       
   627 // T8BppMbmReadCodec
       
   628 void T8BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   629 	{
       
   630 	while (aDataPtr < aDataPtrLimit)
       
   631 		iImageProc->SetPixel(ColorFromIndex(*aDataPtr++));
       
   632 	}
       
   633 
       
   634 
       
   635 // T8BppCompressedMbmReadCodec
       
   636 void T8BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   637 	{
       
   638 	while (aDataPtr < aDataPtrLimit)
       
   639 		{
       
   640 		TInt8 count = *aDataPtr++;
       
   641 
       
   642 		if (count >= 0)
       
   643 			{
       
   644 			if (aDataPtr >= aDataPtrLimit)
       
   645 				{
       
   646 				aDataPtr--;
       
   647 				break;
       
   648 				}
       
   649 			AddPixelRun(ColorFromIndex(*aDataPtr++),count + 1);
       
   650 			}
       
   651 		else
       
   652 			{
       
   653 			TUint8* tempDataPtrLimit = aDataPtr - count;
       
   654 			if (tempDataPtrLimit > aDataPtrLimit)
       
   655 				{
       
   656 				aDataPtr--;
       
   657 				break;
       
   658 				}
       
   659 			while (aDataPtr < tempDataPtrLimit)
       
   660 				iImageProc->SetPixel(ColorFromIndex(*aDataPtr++));
       
   661 			}
       
   662 		}
       
   663 	}
       
   664 
       
   665 
       
   666 // T12BppMbmReadCodec
       
   667 void T12BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   668 	{
       
   669 	ASSERT(!(TInt(aDataPtr) & 1));
       
   670 
       
   671 	TUint16* tempDataPtr = (TUint16*)aDataPtr;
       
   672 	TUint16* tempDataPtrLimit = tempDataPtr + ((aDataPtrLimit - aDataPtr) >> 1);
       
   673 
       
   674 	while (tempDataPtr < tempDataPtrLimit)
       
   675 		iImageProc->SetPixel(TRgb::Color4K((*tempDataPtr++) & 0x0fff));
       
   676 
       
   677 	aDataPtr = (TUint8*)tempDataPtr;
       
   678 	}
       
   679 
       
   680 
       
   681 // T12BppCompressedMbmReadCodec
       
   682 void T12BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   683 	{
       
   684 	if((TInt(aDataPtr) & 1))
       
   685 		{
       
   686 		// Not word aligned
       
   687 		while (aDataPtr < aDataPtrLimit)
       
   688 			{
       
   689 			TInt value = (aDataPtr[0] | aDataPtr[1] << 8);
       
   690 			AddPixelRun(TRgb::Color4K(value & 0x0fff),(value >> 12) + 1);
       
   691 			aDataPtr += 2;
       
   692 			}
       
   693 		}	
       
   694 	else
       
   695 		{
       
   696 		//Word Aligned
       
   697 		TUint16* tempDataPtr = (TUint16*)aDataPtr;
       
   698 		TUint16* tempDataPtrLimit = tempDataPtr + ((aDataPtrLimit - aDataPtr) >> 1);
       
   699 
       
   700 		while (tempDataPtr < tempDataPtrLimit)
       
   701 			{
       
   702 			TInt value = *tempDataPtr++;
       
   703 			AddPixelRun(TRgb::Color4K(value & 0x0fff),(value >> 12) + 1);
       
   704 			}
       
   705 
       
   706 		aDataPtr = (TUint8*)tempDataPtr;
       
   707 		}
       
   708 	}
       
   709 
       
   710 
       
   711 // T16BppMbmReadCodec
       
   712 void T16BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   713 	{
       
   714 	ASSERT(!(TInt(aDataPtr) & 1));
       
   715 
       
   716 	TUint16* tempDataPtr = (TUint16*)aDataPtr;
       
   717 	TUint16* tempDataPtrLimit = tempDataPtr + ((aDataPtrLimit - aDataPtr) >> 1);
       
   718 
       
   719 	while (tempDataPtr < tempDataPtrLimit)
       
   720 		iImageProc->SetPixel(TRgb::Color64K(*tempDataPtr++));
       
   721 
       
   722 	aDataPtr = (TUint8*)tempDataPtr;
       
   723 	}
       
   724 
       
   725 
       
   726 // T16BppCompressedMbmReadCodec
       
   727 void T16BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   728 	{
       
   729 	while (aDataPtr < aDataPtrLimit)
       
   730 		{
       
   731 		TInt8 count = *aDataPtr++;
       
   732 
       
   733 		if (count >= 0)
       
   734 			{
       
   735 			if (aDataPtr + 2 > aDataPtrLimit)
       
   736 				{
       
   737 				aDataPtr--;
       
   738 				break;
       
   739 				}
       
   740 			AddPixelRun(TRgb::Color64K(aDataPtr[0] | (aDataPtr[1] << 8)),count + 1);
       
   741 			aDataPtr += 2;
       
   742 			}
       
   743 		else
       
   744 			{
       
   745 			TUint8* tempDataPtrLimit = aDataPtr + (count * -2);
       
   746 			if (tempDataPtrLimit > aDataPtrLimit)
       
   747 				{
       
   748 				aDataPtr--;
       
   749 				break;
       
   750 				}
       
   751 			while (aDataPtr < tempDataPtrLimit)
       
   752 				{
       
   753 				iImageProc->SetPixel(TRgb::Color64K(aDataPtr[0] | (aDataPtr[1] << 8)));
       
   754 				aDataPtr += 2;
       
   755 				}
       
   756 			}
       
   757 		}
       
   758 	}
       
   759 
       
   760 
       
   761 // T24BppMbmReadCodec
       
   762 void T24BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   763 	{
       
   764 	TUint8* tempDataPtrLimit = aDataPtrLimit - 2; // Safe limit for jumps of three bytes
       
   765 	while (aDataPtr < tempDataPtrLimit)
       
   766 		{
       
   767 		iImageProc->SetPixel(TRgb(aDataPtr[2],aDataPtr[1],aDataPtr[0]));
       
   768 		aDataPtr += 3;
       
   769 		}
       
   770 	}
       
   771 
       
   772 
       
   773 // T24BppCompressedMbmReadCodec
       
   774 void T24BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   775 	{
       
   776 	while (aDataPtr < aDataPtrLimit)
       
   777 		{
       
   778 		TInt8 count = *aDataPtr++;
       
   779 
       
   780 		if (count >= 0)
       
   781 			{
       
   782 			if (aDataPtr + 3 > aDataPtrLimit)
       
   783 				{
       
   784 				aDataPtr--;
       
   785 				break;
       
   786 				}
       
   787 			AddPixelRun(TRgb(aDataPtr[2],aDataPtr[1],aDataPtr[0]),count + 1);
       
   788 			aDataPtr += 3;
       
   789 			}
       
   790 		else
       
   791 			{
       
   792 			TUint8* tempDataPtrLimit = aDataPtr + (count * -3);
       
   793 			if (tempDataPtrLimit > aDataPtrLimit)
       
   794 				{
       
   795 				aDataPtr--;
       
   796 				break;
       
   797 				}
       
   798 			while (aDataPtr < tempDataPtrLimit)
       
   799 				{
       
   800 				iImageProc->SetPixel(TRgb(aDataPtr[2],aDataPtr[1],aDataPtr[0]));
       
   801 				aDataPtr += 3;
       
   802 				}
       
   803 			}
       
   804 		}
       
   805 	}
       
   806 
       
   807 // T32BppMbmReadCodec
       
   808 void T32BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
       
   809 	{
       
   810 	TUint8* tempDataPtrLimit = aDataPtrLimit - 3; // Safe limit for jumps of four bytes
       
   811 	while (aDataPtr < tempDataPtrLimit)
       
   812 		{
       
   813 		TRgb rgb(aDataPtr[2],aDataPtr[1],aDataPtr[0],aDataPtr[3]);
       
   814 		iImageProc->SetPixel(rgb);
       
   815 		aDataPtr += 4;
       
   816 		}
       
   817 	}
       
   818 
       
   819 // CMbmWriteCodec
       
   820 CMbmWriteCodec::CMbmWriteCodec(TDisplayMode aDisplayMode):
       
   821 	iDisplayMode(aDisplayMode)
       
   822 	{}
       
   823 
       
   824 CMbmWriteCodec::~CMbmWriteCodec()
       
   825 	{
       
   826 	delete iCodecProc;
       
   827 	}
       
   828 
       
   829 CMbmWriteCodec* CMbmWriteCodec::NewL(TDisplayMode aDisplayMode)
       
   830 {
       
   831 	CMbmWriteCodec* self = new(ELeave) CMbmWriteCodec(aDisplayMode);
       
   832 	CleanupStack::PushL(self);
       
   833 	self->ConstructL();
       
   834 	CleanupStack::Pop(self); 
       
   835 	return self;
       
   836 }
       
   837 
       
   838 TFrameState CMbmWriteCodec::ProcessFrameL(TBufPtr8& aDst)
       
   839 	{
       
   840 	TUint8* destStartPtr = CONST_CAST(TUint8*,aDst.Ptr());
       
   841 	iDataPtr = destStartPtr;
       
   842 	iDataPtrLimit = iDataPtr + aDst.MaxLength();
       
   843 
       
   844 	if (iStreamTablePending)
       
   845 		{
       
   846 		TUint32 data = 1;
       
   847 		Mem::Copy(iDataPtr,&data,sizeof(TUint32));
       
   848 		data = KMbmFirstBitmapOffset;
       
   849 		iDataPtr += sizeof(TUint32);
       
   850 		Mem::Copy(iDataPtr,&data,sizeof(TUint32));
       
   851 		iDataPtr += sizeof(TUint32);
       
   852 		aDst.SetLength(iDataPtr - destStartPtr);
       
   853 
       
   854 		return EFrameComplete;
       
   855 		}
       
   856 
       
   857 	DoProcessL(*Source());
       
   858 
       
   859 	aDst.SetLength(iDataPtr - destStartPtr);
       
   860 
       
   861 	if (iPos.iY >= iSourceRect.iBr.iY)
       
   862 		{
       
   863 		if (iDataPtrLimit - iDataPtr >= 8)
       
   864 			{
       
   865 			TUint32 data = 1;
       
   866 			Mem::Copy(iDataPtr,&data,sizeof(TUint32));
       
   867 			iDataPtr += sizeof(TUint32);
       
   868 			data = KMbmFirstBitmapOffset;
       
   869 			Mem::Copy(iDataPtr,&data,sizeof(TUint32));
       
   870 			iDataPtr += sizeof(TUint32);
       
   871 			aDst.SetLength(iDataPtr - destStartPtr);
       
   872 			return EFrameComplete;
       
   873 			}
       
   874 		else
       
   875 			iStreamTablePending = ETrue;
       
   876 		}
       
   877 
       
   878 	return EFrameIncomplete;
       
   879 	}
       
   880 
       
   881 void CMbmWriteCodec::InitFrameL(TBufPtr8& aDst, const CFbsBitmap& aFrame)
       
   882 	{
       
   883 	SetSource(&aFrame);
       
   884 
       
   885 	TUint8* destStartPtr = CONST_CAST(TUint8*,aDst.Ptr());
       
   886 	iDataPtr = destStartPtr;
       
   887 	iDataPtrLimit = iDataPtr + aDst.MaxLength();
       
   888 
       
   889 	iStreamTablePending = EFalse;
       
   890 
       
   891 	iSourceRect = TRect(aFrame.SizeInPixels());
       
   892 	iPos.SetXY(0,0);
       
   893 
       
   894 	TInt byteWidth = CFbsBitmap::ScanLineLength(iSourceRect.Size().iWidth,iDisplayMode);
       
   895 	SEpocBitmapHeader bmpHeader;
       
   896 
       
   897 	bmpHeader.iStructSize = sizeof(SEpocBitmapHeader);
       
   898 	bmpHeader.iSizeInPixels = iSourceRect.Size();
       
   899 	bmpHeader.iSizeInTwips = aFrame.SizeInTwips();
       
   900 
       
   901 	delete iCodecProc;
       
   902 	iCodecProc = NULL;
       
   903 
       
   904 	switch (iDisplayMode)
       
   905 		{
       
   906 	case EGray2:
       
   907 		bmpHeader.iBitsPerPixel = 1;
       
   908 		iCodecProc = new(ELeave) T1BppWriteCodecProcessor;
       
   909 		break;
       
   910 	case EGray4:
       
   911 		bmpHeader.iBitsPerPixel = 2;
       
   912 		iCodecProc = new(ELeave) T2BppWriteCodecProcessor;
       
   913 		break;
       
   914 	case EGray16:
       
   915 	case EColor16:
       
   916 		bmpHeader.iBitsPerPixel = 4;
       
   917 		iCodecProc = new(ELeave) T4BppWriteCodecProcessor;
       
   918 		break;
       
   919 	case EGray256:
       
   920 	case EColor256:
       
   921 		bmpHeader.iBitsPerPixel = 8;
       
   922 		iCodecProc = new(ELeave) T8BppWriteCodecProcessor;
       
   923 		break;
       
   924 	case EColor4K:
       
   925 		bmpHeader.iBitsPerPixel = 12;
       
   926 		iCodecProc = new(ELeave) T16BppWriteCodecProcessor;
       
   927 		break;
       
   928 	case EColor64K:
       
   929 		bmpHeader.iBitsPerPixel = 16;
       
   930 		iCodecProc = new(ELeave) T16BppWriteCodecProcessor;
       
   931 		break;
       
   932 	case EColor16M:
       
   933 		bmpHeader.iBitsPerPixel = 24;
       
   934 		iCodecProc = new(ELeave) T24BppWriteCodecProcessor;
       
   935 		break;
       
   936 	case EColor16MU:
       
   937 	case EColor16MA:
       
   938 		bmpHeader.iBitsPerPixel = 32;
       
   939 		iCodecProc = new(ELeave) T32BppWriteCodecProcessor;
       
   940 		break;
       
   941 	default:
       
   942 		Panic(EBadDisplayMode);
       
   943 		break;
       
   944 		}
       
   945 
       
   946 	switch (iDisplayMode)
       
   947 		{
       
   948 	case EGray2:
       
   949 	case EGray4:
       
   950 	case EGray16:
       
   951 	case EGray256:
       
   952 		bmpHeader.iColor = 0;
       
   953 		break;
       
   954 	case EColor16:
       
   955 	case EColor256:
       
   956 	case EColor4K:
       
   957 	case EColor64K:
       
   958 	case EColor16M:
       
   959 	case EColor16MU:
       
   960 		bmpHeader.iColor = 1;
       
   961 		break;
       
   962 	case EColor16MA:
       
   963 		bmpHeader.iColor = 2;
       
   964 		break;
       
   965 	default:
       
   966 		Panic(EBadDisplayMode);
       
   967 		break;
       
   968 		}
       
   969 	
       
   970 	bmpHeader.iPaletteEntries = 0;
       
   971 	bmpHeader.iCompression = ENoBitmapCompression;
       
   972 	bmpHeader.iBitmapSize = bmpHeader.iStructSize + (byteWidth * iSourceRect.Size().iHeight);
       
   973 
       
   974 	Mem::Copy(iDataPtr,&bmpHeader,sizeof(SEpocBitmapHeader));
       
   975 	iDataPtr += sizeof(SEpocBitmapHeader);
       
   976 	ASSERT(iDataPtr < iDataPtrLimit);
       
   977 
       
   978 	iPaddingBytes = byteWidth - iCodecProc->PixelsToBytes(iSourceRect.Size().iWidth);
       
   979 
       
   980 	aDst.SetLength(iDataPtr - destStartPtr);
       
   981 	}
       
   982 
       
   983 void CMbmWriteCodec::DoProcessL(const CFbsBitmap& aFrame)
       
   984 	{
       
   985 	TUint8* safeDataPtrLimit = iDataPtrLimit - 2;
       
   986 	while (iDataPtr < safeDataPtrLimit)
       
   987 		{
       
   988 		while (iBytesToWrite > 0)
       
   989 			{
       
   990 			*iDataPtr++ = 0;
       
   991 			iBytesToWrite--;
       
   992 			if (iDataPtr == iDataPtrLimit)
       
   993 				break;
       
   994 			}
       
   995 
       
   996 		if (iPos.iY >= iSourceRect.iBr.iY)
       
   997 			break;
       
   998 
       
   999 		TInt scanLength = Min(iSourceRect.iBr.iX - iPos.iX,iCodecProc->BytesToPixels(iDataPtrLimit - iDataPtr));
       
  1000 		TInt dstLength = iCodecProc->PixelsToBytes(scanLength);
       
  1001 		TPtr8 dstBuf(iDataPtr,dstLength,dstLength);
       
  1002 
       
  1003 		aFrame.GetScanLine(dstBuf,iPos,scanLength,iDisplayMode);
       
  1004 
       
  1005 		iPos.iX += scanLength;
       
  1006 		iDataPtr += dstLength;
       
  1007 
       
  1008 		if (iPos.iX == iSourceRect.iBr.iX)
       
  1009 			{
       
  1010 			iPos.iX = iSourceRect.iTl.iX;
       
  1011 			iPos.iY++;
       
  1012 			iBytesToWrite = iPaddingBytes;
       
  1013 			}
       
  1014 		}
       
  1015 	}
       
  1016