--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmplugins/imagingplugins/codecs/MBMCodec/MBMCodec.cpp Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,1016 @@
+// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <fbs.h>
+#include <s32mem.h>
+#include "ImageClientMain.h"
+#include "MBMCodec.h"
+
+_LIT(KMBMPanicCategory, "MBMConvertPlugin");
+
+// Global panic function
+GLDEF_C void Panic(TIclPanic aError)
+ {
+ User::Panic(KMBMPanicCategory, aError);
+ }
+
+
+// CMbmReadCodec
+CMbmReadCodec::CMbmReadCodec(TUint32 aMbmRootStreamOffset)
+:iMbmRootStreamOffset(aMbmRootStreamOffset)
+ {
+ }
+
+CMbmReadCodec::~CMbmReadCodec()
+ {
+ delete iCodecProc;
+ }
+
+
+CMbmReadCodec* CMbmReadCodec::NewL(TUint32 aMbmRootStreamOffset)
+{
+ CMbmReadCodec* self = new(ELeave) CMbmReadCodec(aMbmRootStreamOffset);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+}
+
+TDisplayMode CMbmReadCodec::DisplayModeL(TInt aBitsPerPixel, TUint32 aFlags)
+ {
+ if (aFlags & TFrameInfo::EColor)
+ {
+ switch (aBitsPerPixel)
+ {
+ case 4:
+ return EColor16;
+ case 8:
+ return EColor256;
+ case 12:
+ return EColor4K;
+ case 16:
+ return EColor64K;
+ case 24:
+ return EColor16M;
+ case 32:
+ if(aFlags & TFrameInfo::EAlphaChannel)
+ {
+ return EColor16MA;
+ }
+ else
+ {
+ return EColor16MU;
+ }
+ default:
+ User::Leave(KErrNotSupported);
+ }
+ }
+ else
+ {
+ switch (aBitsPerPixel)
+ {
+ case 1:
+ return EGray2;
+ case 2:
+ return EGray4;
+ case 4:
+ return EGray16;
+ case 8:
+ return EGray256;
+ default:
+ User::Leave(KErrNotSupported);
+ }
+ }
+
+ return ENone;
+ }
+
+void CMbmReadCodec::InitFrameL(TFrameInfo& aFrameInfo, CFrameImageData& aFrameImageData, TBool aDisableErrorDiffusion, CFbsBitmap& aFrame, CFbsBitmap* /*aFrameMask*/)
+ {
+ iFrameInfo = &aFrameInfo;
+ iFrameData = STATIC_CAST(TMbmDecodeData*, aFrameImageData.GetFrameData(0));
+ iCompressed = iFrameData->iCompressed;
+
+ iByteLength = iFrameData->iImageDataSizeInBytes;
+
+ TPoint& pos = Pos();
+ pos.SetXY(0,0);
+
+ TSize originalSize(iFrameInfo->iFrameCoordsInPixels.Size());
+
+ TDisplayMode displayMode = DisplayModeL(iFrameInfo->iBitsPerPixel,iFrameInfo->iFlags);
+ const TSize destinationSize(aFrame.SizeInPixels());
+ TInt reductionFactor = ReductionFactor(originalSize, destinationSize);
+
+ CImageProcessor* imageProc = ImageProcessorUtility::NewImageProcessorL(aFrame, reductionFactor, displayMode, aDisableErrorDiffusion);
+ SetImageProcessor(imageProc);
+
+ imageProc->PrepareL(aFrame,originalSize);
+ TInt scanLinePixels = ScanLinePixels(originalSize.iWidth);
+ imageProc->SetPixelPadding(scanLinePixels - originalSize.iWidth);
+ SetCodecProcessorL();
+
+ ClearBitmapL(aFrame, KRgbWhite);
+ // clear in case of streamed partial decodes
+ }
+
+void CMbmReadCodec::InitFrameHeader(TFrameInfo& aFrameSettings, CFrameImageData& aFrameImageData)
+ {
+ ASSERT(aFrameSettings.CurrentFrameState() == TFrameInfo::EFrameInfoUninitialised);
+ iFrameInfo = &aFrameSettings;
+ iImageData = &aFrameImageData;
+ iFrameInfo->SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingFrameHeader);
+ }
+
+TFrameState CMbmReadCodec::ProcessFrameHeaderL(TBufPtr8& aData)
+ {
+ iStartDataPtr = CONST_CAST(TUint8*,aData.Ptr());
+ iDataPtr = iStartDataPtr;
+ iDataPtrLimit = iStartDataPtr + aData.Length();
+
+ if (iFrameInfo->CurrentFrameState() == TFrameInfo::EFrameInfoProcessingFrame)
+ {
+ if(iFrameDataRemaining <= aData.Length())
+ iNumberOfFrames++;
+ else
+ {
+ iMbmRootStreamOffset -= aData.Length();
+ iFrameDataRemaining -= aData.Length();
+ aData.Shift(aData.Length());
+ return EFrameIncomplete;
+ }
+
+ if ((iMbmRootStreamOffset-iFrameDataRemaining) == 0)
+ {
+ iFrameInfo->SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingComplete);
+ return EFrameComplete;
+ }
+ else if ((iMbmRootStreamOffset - iFrameDataRemaining) < KMbmInfoHeaderSize)
+ {
+ //Bitmap StreamLength is too short to continue processing.
+ User::Leave(KErrCorrupt);
+ }
+ else
+ {
+ aData.Shift(iFrameDataRemaining);
+ iMbmRootStreamOffset -= iFrameDataRemaining;
+
+ iFrameInfo->SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingComplete);
+ return EFrameIncomplete;
+ }
+ }
+
+ if (iFrameInfo->CurrentFrameState() == TFrameInfo::EFrameInfoProcessingFrameHeader)
+ {
+ if (aData.Length()<KMbmInfoHeaderSize)
+ User::Leave(KErrUnderflow);
+
+ TMbmDecodeData* mbmDecodeData = new(ELeave)TMbmDecodeData;
+ CleanupStack::PushL(mbmDecodeData);
+
+ User::LeaveIfError(iImageData->AppendFrameData(mbmDecodeData));
+ CleanupStack::Pop(); // mbmImageData
+
+ SEpocBitmapHeader header;
+ RDesReadStream stream;
+ stream.Open(aData);
+ CleanupClosePushL(stream);
+ header.iBitmapSize=stream.ReadInt32L();
+ header.iStructSize=stream.ReadInt32L();
+ if (header.iStructSize!=sizeof(SEpocBitmapHeader)) User::Leave(KErrCorrupt);
+ header.iSizeInPixels.iWidth=stream.ReadInt32L();
+ header.iSizeInPixels.iHeight=stream.ReadInt32L();
+ header.iSizeInTwips.iWidth=stream.ReadInt32L();
+ header.iSizeInTwips.iHeight=stream.ReadInt32L();
+ header.iBitsPerPixel=stream.ReadInt32L();
+ header.iColor=stream.ReadUint32L();
+ header.iPaletteEntries=stream.ReadInt32L();
+ header.iCompression=(TBitmapfileCompression)stream.ReadUint32L();
+ CleanupStack::PopAndDestroy(); //stream
+
+ if (header.iBitmapSize<KMbmInfoHeaderSize)
+ User::Leave(KErrCorrupt);
+
+ iFrameDataRemaining = header.iBitmapSize - KMbmInfoHeaderSize;
+ if (iMbmRootStreamOffset<KMbmInfoHeaderSize)
+ User::Leave(KErrCorrupt);
+
+ iMbmRootStreamOffset -= KMbmInfoHeaderSize;
+ TInt frameDataOffset = iFrameInfo->FrameDataOffset();
+ iFrameInfo->SetFrameDataOffset(frameDataOffset + KMbmInfoHeaderSize);
+ iFrameInfo->iFrameCoordsInPixels.SetRect(TPoint(0,0),header.iSizeInPixels);
+ iFrameInfo->iOverallSizeInPixels = header.iSizeInPixels;
+ iFrameInfo->iFrameSizeInTwips = header.iSizeInTwips;
+ iFrameInfo->iBitsPerPixel = header.iBitsPerPixel;
+ iFrameInfo->iDelay = 0;
+ iFrameInfo->iFlags = TFrameInfo::ECanDither;
+
+ switch(header.iColor)
+ {
+ case SEpocBitmapHeader::ENoColor:
+ break;
+ case SEpocBitmapHeader::EColor:
+ iFrameInfo->iFlags |= TFrameInfo::EColor;
+ break;
+ case SEpocBitmapHeader::EColorAlpha:
+ iFrameInfo->iFlags |= TFrameInfo::EColor;
+ iFrameInfo->iFlags |= TFrameInfo::ETransparencyPossible;
+ iFrameInfo->iFlags |= TFrameInfo::EAlphaChannel;
+ break;
+ default:
+ User::Leave(KErrNotSupported);
+ }
+
+ mbmDecodeData->iCompressed = header.iCompression;
+ mbmDecodeData->iImageDataSizeInBytes = header.iBitmapSize - header.iStructSize;
+
+ if (iFrameInfo->iFrameCoordsInPixels.iBr.iX < 0 || iFrameInfo->iFrameCoordsInPixels.iBr.iY < 0 ||
+ iFrameInfo->iFrameSizeInTwips.iWidth < 0 || iFrameInfo->iFrameSizeInTwips.iHeight < 0 ||
+ !(iFrameInfo->iBitsPerPixel == 1 || iFrameInfo->iBitsPerPixel == 2 ||
+ iFrameInfo->iBitsPerPixel == 4 || iFrameInfo->iBitsPerPixel == 8 ||
+ iFrameInfo->iBitsPerPixel == 12 || iFrameInfo->iBitsPerPixel == 16 ||
+ iFrameInfo->iBitsPerPixel == 24 || iFrameInfo->iBitsPerPixel == 32))
+ User::Leave(KErrCorrupt);
+
+ switch (iFrameInfo->iBitsPerPixel)
+ {
+ case 1:
+ iFrameInfo->iFrameDisplayMode = EGray2;
+ break;
+
+ case 2:
+ iFrameInfo->iFrameDisplayMode = EGray4;
+ break;
+
+ case 4:
+ iFrameInfo->iFrameDisplayMode = (iFrameInfo->iFlags & TFrameInfo::EColor) ? EColor16 : EGray16;
+ break;
+
+ case 8:
+ iFrameInfo->iFrameDisplayMode = (iFrameInfo->iFlags & TFrameInfo::EColor) ? EColor256 : EGray256;
+ break;
+
+ case 12:
+ iFrameInfo->iFrameDisplayMode = EColor4K;
+ break;
+
+ case 16:
+ iFrameInfo->iFrameDisplayMode = EColor64K;
+ break;
+
+ case 24:
+ iFrameInfo->iFrameDisplayMode = EColor16M;
+ break;
+
+ case 32:
+ if(iFrameInfo->iFlags & TFrameInfo::ETransparencyPossible && iFrameInfo->iFlags & TFrameInfo::EAlphaChannel)
+ {
+ iFrameInfo->iFrameDisplayMode = EColor16MA;
+ }
+ else
+ {
+ iFrameInfo->iFrameDisplayMode = EColor16MU;
+ }
+ break;
+ }
+
+ aData.Shift(KMbmInfoHeaderSize);
+ iFrameInfo->SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingFrame);
+ }
+
+ return EFrameIncomplete;
+ }
+
+TFrameState CMbmReadCodec::ProcessFrameL(TBufPtr8& aSrc)
+ {
+ TUint8* srcPtr = CONST_CAST(TUint8*,aSrc.Ptr());
+ iDataPtr = srcPtr;
+ iDataPtrLimit = iDataPtr + Min(aSrc.Length(),iByteLength);
+
+ iCodecProc->DoProcessL(iDataPtr,iDataPtrLimit);
+ TInt bytesUsed = iDataPtr - srcPtr;
+ aSrc.Shift(bytesUsed);
+ iByteLength -= bytesUsed;
+
+ if (iByteLength == 0)
+ {
+ ImageProcessor()->FlushPixels();
+ delete iCodecProc;
+ iCodecProc = NULL;
+ return EFrameComplete;
+ }
+ return EFrameIncomplete;
+ }
+
+TInt CMbmReadCodec::ScanLinePixels(TInt aWidth)
+ {
+ switch (iFrameInfo->iBitsPerPixel)
+ {
+ case 1:
+ return CFbsBitmap::ScanLineLength(aWidth,EGray2) << 3;
+ case 2:
+ return CFbsBitmap::ScanLineLength(aWidth,EGray4) << 2;
+ case 4:
+ return CFbsBitmap::ScanLineLength(aWidth,EGray16) << 1;
+ case 8:
+ return CFbsBitmap::ScanLineLength(aWidth,EGray256);
+ case 12:
+ case 16:
+ return CFbsBitmap::ScanLineLength(aWidth,EColor64K) >> 1;
+ case 24:
+ return CFbsBitmap::ScanLineLength(aWidth,EColor16M) / 3;
+ case 32:
+ return CFbsBitmap::ScanLineLength(aWidth,EColor16MU) / 4; // for all 32bit modes
+ default:
+ return 0;
+ }
+ }
+
+void CMbmReadCodec::SetCodecProcessorL()
+ {
+ delete iCodecProc;
+ iCodecProc = NULL;
+ const TBool color = (iFrameInfo->iFlags & TFrameInfo::EColor);
+
+ switch (iFrameInfo->iBitsPerPixel)
+ {
+ case 1:
+ if (iCompressed)
+ iCodecProc = new(ELeave) T1BppCompressedMbmReadCodec;
+ else
+ iCodecProc = new(ELeave) T1BppMbmReadCodec;
+ break;
+ case 2:
+ if (iCompressed)
+ iCodecProc = new(ELeave) T2BppCompressedMbmReadCodec;
+ else
+ iCodecProc = new(ELeave) T2BppMbmReadCodec;
+ break;
+ case 4:
+ if (color)
+ {
+ if (iCompressed)
+ iCodecProc = new(ELeave) T4BppColorCompressedMbmReadCodec;
+ else
+ iCodecProc = new(ELeave) T4BppColorMbmReadCodec;
+ }
+ else
+ {
+ if (iCompressed)
+ iCodecProc = new(ELeave) T4BppMonoCompressedMbmReadCodec;
+ else
+ iCodecProc = new(ELeave) T4BppMonoMbmReadCodec;
+ }
+ break;
+ case 8:
+ if (color)
+ {
+ if (iCompressed)
+ iCodecProc = new(ELeave) T8BppColorCompressedMbmReadCodec;
+ else
+ iCodecProc = new(ELeave) T8BppColorMbmReadCodec;
+ }
+ else
+ {
+ if (iCompressed)
+ iCodecProc = new(ELeave) T8BppMonoCompressedMbmReadCodec;
+ else
+ iCodecProc = new(ELeave) T8BppMonoMbmReadCodec;
+ }
+ break;
+ case 12:
+ if (iCompressed)
+ iCodecProc = new(ELeave) T12BppCompressedMbmReadCodec;
+ else
+ iCodecProc = new(ELeave) T12BppMbmReadCodec;
+ break;
+ case 16:
+ if (iCompressed)
+ iCodecProc = new(ELeave) T16BppCompressedMbmReadCodec;
+ else
+ iCodecProc = new(ELeave) T16BppMbmReadCodec;
+ break;
+ case 24:
+ if (iCompressed)
+ iCodecProc = new(ELeave) T24BppCompressedMbmReadCodec;
+ else
+ iCodecProc = new(ELeave) T24BppMbmReadCodec;
+ break;
+ case 32:
+ if (iCompressed)
+ User::Leave(KErrNotSupported);
+ else
+ iCodecProc = new(ELeave) T32BppMbmReadCodec;
+ break;
+ default:
+ User::Leave(KErrCorrupt);
+ }
+
+ iCodecProc->iImageProc = ImageProcessor();
+ }
+
+
+// TMbmReadCodec
+void TMbmReadCodec::AddPixelRun(TRgb aColor,TInt aNumberOfPixels)
+ {
+ iImageProc->SetPixelRun(aColor,aNumberOfPixels);
+ }
+
+
+// T1BppMbmReadCodec
+void T1BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ while (aDataPtr < aDataPtrLimit)
+ AddPixelValue(*aDataPtr++);
+ }
+
+void T1BppMbmReadCodec::AddPixelValue(TUint8 aValue)
+ {
+ iImageProc->SetPixel((aValue & 0x01) ? KRgbWhite : KRgbBlack);
+ iImageProc->SetPixel((aValue & 0x02) ? KRgbWhite : KRgbBlack);
+ iImageProc->SetPixel((aValue & 0x04) ? KRgbWhite : KRgbBlack);
+ iImageProc->SetPixel((aValue & 0x08) ? KRgbWhite : KRgbBlack);
+ iImageProc->SetPixel((aValue & 0x10) ? KRgbWhite : KRgbBlack);
+ iImageProc->SetPixel((aValue & 0x20) ? KRgbWhite : KRgbBlack);
+ iImageProc->SetPixel((aValue & 0x40) ? KRgbWhite : KRgbBlack);
+ iImageProc->SetPixel((aValue & 0x80) ? KRgbWhite : KRgbBlack);
+ }
+
+
+// T1BppCompressedMbmReadCodec
+void T1BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ while (aDataPtr < aDataPtrLimit)
+ {
+ TInt8 count = *aDataPtr++;
+
+ if (count >= 0)
+ {
+ if (aDataPtr >= aDataPtrLimit)
+ {
+ aDataPtr--;
+ break;
+ }
+ AddPixelRun(*aDataPtr++,count + 1);
+ }
+ else
+ {
+ TUint8* tempDataPtrLimit = aDataPtr - count;
+ if (tempDataPtrLimit > aDataPtrLimit)
+ {
+ aDataPtr--;
+ break;
+ }
+ while (aDataPtr < tempDataPtrLimit)
+ AddPixelValue(*aDataPtr++);
+ }
+ }
+ }
+
+void T1BppCompressedMbmReadCodec::AddPixelRun(TUint8 aValue,TInt aNumberOfValues)
+ {
+ TRgb color0 = (aValue & 0x01) ? KRgbWhite : KRgbBlack;
+ TRgb color1 = (aValue & 0x02) ? KRgbWhite : KRgbBlack;
+ TRgb color2 = (aValue & 0x04) ? KRgbWhite : KRgbBlack;
+ TRgb color3 = (aValue & 0x08) ? KRgbWhite : KRgbBlack;
+ TRgb color4 = (aValue & 0x10) ? KRgbWhite : KRgbBlack;
+ TRgb color5 = (aValue & 0x20) ? KRgbWhite : KRgbBlack;
+ TRgb color6 = (aValue & 0x40) ? KRgbWhite : KRgbBlack;
+ TRgb color7 = (aValue & 0x80) ? KRgbWhite : KRgbBlack;
+
+ for (; aNumberOfValues > 0; aNumberOfValues--)
+ {
+ iImageProc->SetPixel(color0);
+ iImageProc->SetPixel(color1);
+ iImageProc->SetPixel(color2);
+ iImageProc->SetPixel(color3);
+ iImageProc->SetPixel(color4);
+ iImageProc->SetPixel(color5);
+ iImageProc->SetPixel(color6);
+ iImageProc->SetPixel(color7);
+ }
+ }
+
+
+// T2BppMbmReadCodec
+void T2BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ while (aDataPtr < aDataPtrLimit)
+ AddPixelValue(*aDataPtr++);
+ }
+
+void T2BppMbmReadCodec::AddPixelValue(TUint8 aValue)
+ {
+ iImageProc->SetPixel(TRgb::Gray4(aValue & 0x3));
+ iImageProc->SetPixel(TRgb::Gray4((aValue >> 2) & 0x3));
+ iImageProc->SetPixel(TRgb::Gray4((aValue >> 4) & 0x3));
+ iImageProc->SetPixel(TRgb::Gray4((aValue >> 6) & 0x3));
+ }
+
+
+// T2BppCompressedMbmReadCodec
+void T2BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ while (aDataPtr < aDataPtrLimit)
+ {
+ TInt8 count = *aDataPtr++;
+
+ if (count >= 0)
+ {
+ if (aDataPtr >= aDataPtrLimit)
+ {
+ aDataPtr--;
+ break;
+ }
+ AddPixelRun(*aDataPtr++,count + 1);
+ }
+ else
+ {
+ TUint8* tempDataPtrLimit = aDataPtr - count;
+ if (tempDataPtrLimit > aDataPtrLimit)
+ {
+ aDataPtr--;
+ break;
+ }
+ while (aDataPtr < tempDataPtrLimit)
+ AddPixelValue(*aDataPtr++);
+ }
+ }
+ }
+
+void T2BppCompressedMbmReadCodec::AddPixelRun(TUint8 aValue,TInt aNumberOfQuads)
+ {
+ TRgb color0 = TRgb::Gray4(aValue & 0x3);
+ TRgb color1 = TRgb::Gray4((aValue >> 2) & 0x3);
+ TRgb color2 = TRgb::Gray4((aValue >> 4) & 0x3);
+ TRgb color3 = TRgb::Gray4((aValue >> 6) & 0x3);
+
+ for (; aNumberOfQuads > 0; aNumberOfQuads--)
+ {
+ iImageProc->SetPixel(color0);
+ iImageProc->SetPixel(color1);
+ iImageProc->SetPixel(color2);
+ iImageProc->SetPixel(color3);
+ }
+ }
+
+
+// T4BppMbmReadCodec
+void T4BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ while (aDataPtr < aDataPtrLimit)
+ {
+ TInt value = *aDataPtr++;
+ iImageProc->SetPixel(ColorFromIndex(value & 0xf));
+ iImageProc->SetPixel(ColorFromIndex(value >> 4));
+ }
+ }
+
+
+// T4BppCompressedMbmReadCodec
+void T4BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ while (aDataPtr < aDataPtrLimit)
+ {
+ TInt8 count = *aDataPtr++;
+
+ if (count >= 0)
+ {
+ if (aDataPtr >= aDataPtrLimit)
+ {
+ aDataPtr--;
+ break;
+ }
+ TInt value = *aDataPtr++;
+ AddPixelRun(ColorFromIndex(value & 0xf),ColorFromIndex(value >> 4),count + 1);
+ }
+ else
+ {
+ TUint8* tempDataPtrLimit = aDataPtr - count;
+ if (tempDataPtrLimit > aDataPtrLimit)
+ {
+ aDataPtr--;
+ break;
+ }
+ while (aDataPtr < tempDataPtrLimit)
+ {
+ TInt value = *aDataPtr++;
+ iImageProc->SetPixel(ColorFromIndex(value & 0xf));
+ iImageProc->SetPixel(ColorFromIndex(value >> 4));
+ }
+ }
+ }
+ }
+
+void T4BppCompressedMbmReadCodec::AddPixelRun(TRgb aColor1,TRgb aColor2,TInt aNumberOfPairs)
+ {
+ for (; aNumberOfPairs > 0; aNumberOfPairs--)
+ {
+ iImageProc->SetPixel(aColor1);
+ iImageProc->SetPixel(aColor2);
+ }
+ }
+
+
+// T8BppMbmReadCodec
+void T8BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ while (aDataPtr < aDataPtrLimit)
+ iImageProc->SetPixel(ColorFromIndex(*aDataPtr++));
+ }
+
+
+// T8BppCompressedMbmReadCodec
+void T8BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ while (aDataPtr < aDataPtrLimit)
+ {
+ TInt8 count = *aDataPtr++;
+
+ if (count >= 0)
+ {
+ if (aDataPtr >= aDataPtrLimit)
+ {
+ aDataPtr--;
+ break;
+ }
+ AddPixelRun(ColorFromIndex(*aDataPtr++),count + 1);
+ }
+ else
+ {
+ TUint8* tempDataPtrLimit = aDataPtr - count;
+ if (tempDataPtrLimit > aDataPtrLimit)
+ {
+ aDataPtr--;
+ break;
+ }
+ while (aDataPtr < tempDataPtrLimit)
+ iImageProc->SetPixel(ColorFromIndex(*aDataPtr++));
+ }
+ }
+ }
+
+
+// T12BppMbmReadCodec
+void T12BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ ASSERT(!(TInt(aDataPtr) & 1));
+
+ TUint16* tempDataPtr = (TUint16*)aDataPtr;
+ TUint16* tempDataPtrLimit = tempDataPtr + ((aDataPtrLimit - aDataPtr) >> 1);
+
+ while (tempDataPtr < tempDataPtrLimit)
+ iImageProc->SetPixel(TRgb::Color4K((*tempDataPtr++) & 0x0fff));
+
+ aDataPtr = (TUint8*)tempDataPtr;
+ }
+
+
+// T12BppCompressedMbmReadCodec
+void T12BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ if((TInt(aDataPtr) & 1))
+ {
+ // Not word aligned
+ while (aDataPtr < aDataPtrLimit)
+ {
+ TInt value = (aDataPtr[0] | aDataPtr[1] << 8);
+ AddPixelRun(TRgb::Color4K(value & 0x0fff),(value >> 12) + 1);
+ aDataPtr += 2;
+ }
+ }
+ else
+ {
+ //Word Aligned
+ TUint16* tempDataPtr = (TUint16*)aDataPtr;
+ TUint16* tempDataPtrLimit = tempDataPtr + ((aDataPtrLimit - aDataPtr) >> 1);
+
+ while (tempDataPtr < tempDataPtrLimit)
+ {
+ TInt value = *tempDataPtr++;
+ AddPixelRun(TRgb::Color4K(value & 0x0fff),(value >> 12) + 1);
+ }
+
+ aDataPtr = (TUint8*)tempDataPtr;
+ }
+ }
+
+
+// T16BppMbmReadCodec
+void T16BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ ASSERT(!(TInt(aDataPtr) & 1));
+
+ TUint16* tempDataPtr = (TUint16*)aDataPtr;
+ TUint16* tempDataPtrLimit = tempDataPtr + ((aDataPtrLimit - aDataPtr) >> 1);
+
+ while (tempDataPtr < tempDataPtrLimit)
+ iImageProc->SetPixel(TRgb::Color64K(*tempDataPtr++));
+
+ aDataPtr = (TUint8*)tempDataPtr;
+ }
+
+
+// T16BppCompressedMbmReadCodec
+void T16BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ while (aDataPtr < aDataPtrLimit)
+ {
+ TInt8 count = *aDataPtr++;
+
+ if (count >= 0)
+ {
+ if (aDataPtr + 2 > aDataPtrLimit)
+ {
+ aDataPtr--;
+ break;
+ }
+ AddPixelRun(TRgb::Color64K(aDataPtr[0] | (aDataPtr[1] << 8)),count + 1);
+ aDataPtr += 2;
+ }
+ else
+ {
+ TUint8* tempDataPtrLimit = aDataPtr + (count * -2);
+ if (tempDataPtrLimit > aDataPtrLimit)
+ {
+ aDataPtr--;
+ break;
+ }
+ while (aDataPtr < tempDataPtrLimit)
+ {
+ iImageProc->SetPixel(TRgb::Color64K(aDataPtr[0] | (aDataPtr[1] << 8)));
+ aDataPtr += 2;
+ }
+ }
+ }
+ }
+
+
+// T24BppMbmReadCodec
+void T24BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ TUint8* tempDataPtrLimit = aDataPtrLimit - 2; // Safe limit for jumps of three bytes
+ while (aDataPtr < tempDataPtrLimit)
+ {
+ iImageProc->SetPixel(TRgb(aDataPtr[2],aDataPtr[1],aDataPtr[0]));
+ aDataPtr += 3;
+ }
+ }
+
+
+// T24BppCompressedMbmReadCodec
+void T24BppCompressedMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ while (aDataPtr < aDataPtrLimit)
+ {
+ TInt8 count = *aDataPtr++;
+
+ if (count >= 0)
+ {
+ if (aDataPtr + 3 > aDataPtrLimit)
+ {
+ aDataPtr--;
+ break;
+ }
+ AddPixelRun(TRgb(aDataPtr[2],aDataPtr[1],aDataPtr[0]),count + 1);
+ aDataPtr += 3;
+ }
+ else
+ {
+ TUint8* tempDataPtrLimit = aDataPtr + (count * -3);
+ if (tempDataPtrLimit > aDataPtrLimit)
+ {
+ aDataPtr--;
+ break;
+ }
+ while (aDataPtr < tempDataPtrLimit)
+ {
+ iImageProc->SetPixel(TRgb(aDataPtr[2],aDataPtr[1],aDataPtr[0]));
+ aDataPtr += 3;
+ }
+ }
+ }
+ }
+
+// T32BppMbmReadCodec
+void T32BppMbmReadCodec::DoProcessL(TUint8*& aDataPtr,TUint8* aDataPtrLimit)
+ {
+ TUint8* tempDataPtrLimit = aDataPtrLimit - 3; // Safe limit for jumps of four bytes
+ while (aDataPtr < tempDataPtrLimit)
+ {
+ TRgb rgb(aDataPtr[2],aDataPtr[1],aDataPtr[0],aDataPtr[3]);
+ iImageProc->SetPixel(rgb);
+ aDataPtr += 4;
+ }
+ }
+
+// CMbmWriteCodec
+CMbmWriteCodec::CMbmWriteCodec(TDisplayMode aDisplayMode):
+ iDisplayMode(aDisplayMode)
+ {}
+
+CMbmWriteCodec::~CMbmWriteCodec()
+ {
+ delete iCodecProc;
+ }
+
+CMbmWriteCodec* CMbmWriteCodec::NewL(TDisplayMode aDisplayMode)
+{
+ CMbmWriteCodec* self = new(ELeave) CMbmWriteCodec(aDisplayMode);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+}
+
+TFrameState CMbmWriteCodec::ProcessFrameL(TBufPtr8& aDst)
+ {
+ TUint8* destStartPtr = CONST_CAST(TUint8*,aDst.Ptr());
+ iDataPtr = destStartPtr;
+ iDataPtrLimit = iDataPtr + aDst.MaxLength();
+
+ if (iStreamTablePending)
+ {
+ TUint32 data = 1;
+ Mem::Copy(iDataPtr,&data,sizeof(TUint32));
+ data = KMbmFirstBitmapOffset;
+ iDataPtr += sizeof(TUint32);
+ Mem::Copy(iDataPtr,&data,sizeof(TUint32));
+ iDataPtr += sizeof(TUint32);
+ aDst.SetLength(iDataPtr - destStartPtr);
+
+ return EFrameComplete;
+ }
+
+ DoProcessL(*Source());
+
+ aDst.SetLength(iDataPtr - destStartPtr);
+
+ if (iPos.iY >= iSourceRect.iBr.iY)
+ {
+ if (iDataPtrLimit - iDataPtr >= 8)
+ {
+ TUint32 data = 1;
+ Mem::Copy(iDataPtr,&data,sizeof(TUint32));
+ iDataPtr += sizeof(TUint32);
+ data = KMbmFirstBitmapOffset;
+ Mem::Copy(iDataPtr,&data,sizeof(TUint32));
+ iDataPtr += sizeof(TUint32);
+ aDst.SetLength(iDataPtr - destStartPtr);
+ return EFrameComplete;
+ }
+ else
+ iStreamTablePending = ETrue;
+ }
+
+ return EFrameIncomplete;
+ }
+
+void CMbmWriteCodec::InitFrameL(TBufPtr8& aDst, const CFbsBitmap& aFrame)
+ {
+ SetSource(&aFrame);
+
+ TUint8* destStartPtr = CONST_CAST(TUint8*,aDst.Ptr());
+ iDataPtr = destStartPtr;
+ iDataPtrLimit = iDataPtr + aDst.MaxLength();
+
+ iStreamTablePending = EFalse;
+
+ iSourceRect = TRect(aFrame.SizeInPixels());
+ iPos.SetXY(0,0);
+
+ TInt byteWidth = CFbsBitmap::ScanLineLength(iSourceRect.Size().iWidth,iDisplayMode);
+ SEpocBitmapHeader bmpHeader;
+
+ bmpHeader.iStructSize = sizeof(SEpocBitmapHeader);
+ bmpHeader.iSizeInPixels = iSourceRect.Size();
+ bmpHeader.iSizeInTwips = aFrame.SizeInTwips();
+
+ delete iCodecProc;
+ iCodecProc = NULL;
+
+ switch (iDisplayMode)
+ {
+ case EGray2:
+ bmpHeader.iBitsPerPixel = 1;
+ iCodecProc = new(ELeave) T1BppWriteCodecProcessor;
+ break;
+ case EGray4:
+ bmpHeader.iBitsPerPixel = 2;
+ iCodecProc = new(ELeave) T2BppWriteCodecProcessor;
+ break;
+ case EGray16:
+ case EColor16:
+ bmpHeader.iBitsPerPixel = 4;
+ iCodecProc = new(ELeave) T4BppWriteCodecProcessor;
+ break;
+ case EGray256:
+ case EColor256:
+ bmpHeader.iBitsPerPixel = 8;
+ iCodecProc = new(ELeave) T8BppWriteCodecProcessor;
+ break;
+ case EColor4K:
+ bmpHeader.iBitsPerPixel = 12;
+ iCodecProc = new(ELeave) T16BppWriteCodecProcessor;
+ break;
+ case EColor64K:
+ bmpHeader.iBitsPerPixel = 16;
+ iCodecProc = new(ELeave) T16BppWriteCodecProcessor;
+ break;
+ case EColor16M:
+ bmpHeader.iBitsPerPixel = 24;
+ iCodecProc = new(ELeave) T24BppWriteCodecProcessor;
+ break;
+ case EColor16MU:
+ case EColor16MA:
+ bmpHeader.iBitsPerPixel = 32;
+ iCodecProc = new(ELeave) T32BppWriteCodecProcessor;
+ break;
+ default:
+ Panic(EBadDisplayMode);
+ break;
+ }
+
+ switch (iDisplayMode)
+ {
+ case EGray2:
+ case EGray4:
+ case EGray16:
+ case EGray256:
+ bmpHeader.iColor = 0;
+ break;
+ case EColor16:
+ case EColor256:
+ case EColor4K:
+ case EColor64K:
+ case EColor16M:
+ case EColor16MU:
+ bmpHeader.iColor = 1;
+ break;
+ case EColor16MA:
+ bmpHeader.iColor = 2;
+ break;
+ default:
+ Panic(EBadDisplayMode);
+ break;
+ }
+
+ bmpHeader.iPaletteEntries = 0;
+ bmpHeader.iCompression = ENoBitmapCompression;
+ bmpHeader.iBitmapSize = bmpHeader.iStructSize + (byteWidth * iSourceRect.Size().iHeight);
+
+ Mem::Copy(iDataPtr,&bmpHeader,sizeof(SEpocBitmapHeader));
+ iDataPtr += sizeof(SEpocBitmapHeader);
+ ASSERT(iDataPtr < iDataPtrLimit);
+
+ iPaddingBytes = byteWidth - iCodecProc->PixelsToBytes(iSourceRect.Size().iWidth);
+
+ aDst.SetLength(iDataPtr - destStartPtr);
+ }
+
+void CMbmWriteCodec::DoProcessL(const CFbsBitmap& aFrame)
+ {
+ TUint8* safeDataPtrLimit = iDataPtrLimit - 2;
+ while (iDataPtr < safeDataPtrLimit)
+ {
+ while (iBytesToWrite > 0)
+ {
+ *iDataPtr++ = 0;
+ iBytesToWrite--;
+ if (iDataPtr == iDataPtrLimit)
+ break;
+ }
+
+ if (iPos.iY >= iSourceRect.iBr.iY)
+ break;
+
+ TInt scanLength = Min(iSourceRect.iBr.iX - iPos.iX,iCodecProc->BytesToPixels(iDataPtrLimit - iDataPtr));
+ TInt dstLength = iCodecProc->PixelsToBytes(scanLength);
+ TPtr8 dstBuf(iDataPtr,dstLength,dstLength);
+
+ aFrame.GetScanLine(dstBuf,iPos,scanLength,iDisplayMode);
+
+ iPos.iX += scanLength;
+ iDataPtr += dstLength;
+
+ if (iPos.iX == iSourceRect.iBr.iX)
+ {
+ iPos.iX = iSourceRect.iTl.iX;
+ iPos.iY++;
+ iBytesToWrite = iPaddingBytes;
+ }
+ }
+ }
+