--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imaging/imagingfws/src/ImageBitmapUtil.cpp Wed Aug 25 12:29:52 2010 +0300
@@ -0,0 +1,479 @@
+// 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 <icl/imageprocessor.h>
+
+//
+// this file contains many performance-critical code, so use ARM instruction set for it
+//
+#ifdef __ARMCC__
+#pragma arm
+#pragma O3
+#pragma Otime
+#endif
+
+/**
+ @internalComponent
+*/
+GLDEF_C void Panic(TImageBitmapUtilPanic aError);
+
+/**
+ @internalComponent
+*/
+GLDEF_C TColorConvertor* CreateColorConvertorL(TDisplayMode aDisplayMode);
+
+/**
+Static factory function for creating instances of TColorConvertor derived classes
+based on the supplied display mode.
+
+@param aDisplayMode
+ The display mode. This determines the TColorConvertor derived type returned.
+
+@return A pointer to a fully constructed TColorConvertor derived object.
+
+@leave KErrNotSupported
+ The display mode is not supported.
+*/
+EXPORT_C TColorConvertor* TColorConvertor::NewL(TDisplayMode aDisplayMode)
+ {
+ return CreateColorConvertorL(aDisplayMode);
+ }
+
+//
+// TImageBitmapUtil
+//
+
+/**
+Default constructor for this class.
+*/
+EXPORT_C TImageBitmapUtil::TImageBitmapUtil():
+ iBitmap(NULL),
+ iBpp(0),
+ iBppShift(0),
+ iPixelShift(0),
+ iBitShift(0),
+ iScanlineWordLength(0)
+ {}
+
+/**
+Requests a lock for the current bitmap from the font & bitmap server and
+sets the current position in the bitmap to the first pixel.
+*/
+EXPORT_C void TImageBitmapUtil::Begin()
+ {
+ ASSERT(iBitmap && iBitmap->Handle());
+
+ iBase.iWordPos = iBitmap->DataAddress();
+ }
+
+/**
+Requests a lock for the current bitmap from the font & bitmap server and
+sets the current position in the bitmap to aPosition.
+
+@param aPosition
+ The position to move to.
+
+@return A boolean indicating if the position was out of bounds. EFalse if the position was out of
+ bounds, otherwise ETrue.
+*/
+EXPORT_C TBool TImageBitmapUtil::Begin(const TPoint& aPosition)
+ {
+ Begin();
+ if (!SetPos(aPosition))
+ {
+ End();
+ return EFalse;
+ }
+
+ return ETrue;
+ }
+
+/**
+Releases a lock previously acquired using TImageBitmapUtil::Begin().
+*/
+EXPORT_C void TImageBitmapUtil::End()
+ {
+ }
+
+/**
+Sets the current bitmap to aBitmap.
+
+@param aBitmap
+ A pointer to the bitmap.
+
+@leave KErrNotFound
+ The bitmap or its handle is NULL or its display mode is not recognised.
+*/
+EXPORT_C void TImageBitmapUtil::SetBitmapL(CFbsBitmap* aBitmap)
+ {
+ if (!aBitmap || !aBitmap->Handle())
+ User::Leave(KErrNotFound);
+
+ if(aBitmap->ExtendedBitmapType()!=KNullUid)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+ iBitmap = aBitmap;
+ iWordAccess = ETrue;
+
+ switch(iBitmap->DisplayMode())
+ {
+ case EGray2:
+ iBppShift = 0;
+ iMask = 1;
+ break;
+ case EGray4:
+ iBppShift = 1;
+ iMask = 3;
+ break;
+ case EGray16:
+ case EColor16:
+ iBppShift = 2;
+ iMask = 0xF;
+ break;
+ case EGray256:
+ case EColor256:
+ iBppShift = 3;
+ iMask = 0xFF;
+ break;
+ case EColor4K:
+ case EColor64K:
+ iBppShift = 4;
+ iMask = 0xFFFF;
+ break;
+ case EColor16M:
+ iWordAccess = EFalse;
+ break;
+ case EColor16MU:
+ iBppShift = 5;
+ iMask = 0xFF000000; // | with pixel value to set alpha channel to opaque
+ break;
+ case EColor16MA:
+ iBppShift = 5;
+ iMask = 0x00000000; // | with pixel value to set alpha channel level
+ break;
+ default:
+ User::Leave(KErrNotFound);
+ break;
+ }
+
+ iBpp = 1<<iBppShift;
+ iPixelsPerWord = 32>>iBppShift;
+ iPixelShift = 5-iBppShift;
+
+ iSize = iBitmap->SizeInPixels();
+ iScanlineWordLength = CFbsBitmap::ScanLineLength(iSize.iWidth,iBitmap->DisplayMode()) / 4;
+ }
+
+/**
+Sets the pixel value at the current bitmap position using aPixelIndex.
+
+@post
+The current position is updated.
+
+@param aPixelIndex
+ The pixel index.
+*/
+EXPORT_C void TImageBitmapUtil::SetPixel(TUint32 aPixelIndex)
+ {
+ ASSERT(iPosition.iX < iSize.iWidth);
+
+ iPosition.iX++;
+
+ if (iWordAccess)
+ {
+ TUint32* dataPtr = iData.iWordPos;
+ switch(iBppShift)
+ {
+ case 5:
+ *dataPtr = aPixelIndex|iMask;
+ break;
+ default:
+ TInt bitShift = iBitShift;
+
+ *dataPtr &= ~(iMask << bitShift);
+ *dataPtr |= aPixelIndex << bitShift;
+
+ bitShift += iBpp;
+ if (bitShift >= 32)
+ {
+ bitShift = 0;
+ iData.iWordPos = dataPtr+1;
+ }
+ iBitShift = bitShift;
+ break;
+ }
+ }
+ else
+ {
+ TUint8* dataPtr = iData.iBytePos;
+
+ *dataPtr++ = TUint8(aPixelIndex);
+ *dataPtr++ = TUint8(aPixelIndex >> 8);
+ *dataPtr++ = TUint8(aPixelIndex >> 16);
+
+ iData.iBytePos = dataPtr;
+ }
+
+ }
+
+/**
+Sets an array of pixel values, starting at the current bitmap position using the
+values supplied in aPixelIndex.
+
+@post
+The current position is updated.
+
+@param aPixelIndex
+ A pointer to the first element in the array.
+@param aNumberOfPixels
+ The number of elements in the array.
+*/
+EXPORT_C void TImageBitmapUtil::SetPixels(TUint32* aPixelIndex,TInt aNumberOfPixels)
+ {
+ TInt newXPos = iPosition.iX + aNumberOfPixels;
+ ASSERT(newXPos <= iSize.iWidth);
+
+ if (newXPos == iSize.iWidth)
+ {
+ iPosition.iX = 0;
+ iPosition.iY++;
+ }
+ else
+ {
+ iPosition.iX = newXPos;
+ }
+
+ if (iWordAccess)
+ {
+ TUint32* dataPtr = iData.iWordPos;
+ TInt bitShift = iBitShift;
+ TInt bpp = iBpp;
+
+ // Do pixels in first data word (if first pixel isn't on 32 bit word boundary)
+
+ if(bitShift > 0)
+ {
+ TInt bitShiftLimit = bitShift+(aNumberOfPixels<<iBppShift);
+ if(bitShiftLimit>32)
+ bitShiftLimit = 32;
+
+ TInt numMaskBits = bitShiftLimit-bitShift;
+ aNumberOfPixels -= numMaskBits>>iBppShift;
+ TInt mask = (1<<numMaskBits)-1; //mask has lowest 'numMaskBits' set
+
+ TInt wordValue = *dataPtr;
+
+ wordValue &= ~(mask << bitShift); //zero the destination pixels we are about to write
+ do {
+ wordValue |= *aPixelIndex++ << bitShift;
+ bitShift += bpp;
+ }
+ while(bitShift<bitShiftLimit);
+
+ *dataPtr = wordValue;
+
+ if(bitShift >= 32)
+ {
+ bitShift = 0;
+ dataPtr++;
+ }
+ }
+
+ // Do pixels which fill whole data words
+
+ TUint32* dataPtrLimit = dataPtr+(aNumberOfPixels >> iPixelShift);
+
+ aNumberOfPixels &= ~(0xFFFFFFFF<<iPixelShift);
+
+ if(dataPtr < dataPtrLimit)
+ {
+ switch(iBppShift)
+ {
+ case 5:
+ if(iMask == 0xFF000000)
+ {
+ do {
+ *dataPtr++ = *aPixelIndex++|0xFF000000;
+ }
+ while(dataPtr < dataPtrLimit);
+ }
+ else
+ {
+ do {
+ *dataPtr++ = *aPixelIndex++;
+ }
+ while(dataPtr < dataPtrLimit);
+ }
+
+ break;
+
+ case 4:
+ do {
+ TUint32 wordValue = *aPixelIndex++;
+ wordValue |= *aPixelIndex++ << 16;
+ *dataPtr++ = wordValue;
+ }
+ while(dataPtr < dataPtrLimit);
+ break;
+
+ case 3:
+ do {
+ TUint32 wordValue = *aPixelIndex++;
+ wordValue |= *aPixelIndex++ << 8;
+ wordValue |= *aPixelIndex++ << 8*2;
+ wordValue |= *aPixelIndex++ << 8*3;
+ *dataPtr++ = wordValue;
+ }
+ while(dataPtr < dataPtrLimit);
+ break;
+
+ case 2:
+ do {
+ TUint32 wordValue = *aPixelIndex++;
+ wordValue |= *aPixelIndex++ << 4;
+ wordValue |= *aPixelIndex++ << 4*2;
+ wordValue |= *aPixelIndex++ << 4*3;
+ wordValue |= *aPixelIndex++ << 4*4;
+ wordValue |= *aPixelIndex++ << 4*5;
+ wordValue |= *aPixelIndex++ << 4*6;
+ wordValue |= *aPixelIndex++ << 4*7;
+ *dataPtr++ = wordValue;
+ }
+ while(dataPtr < dataPtrLimit);
+ break;
+
+ case 1:
+ do {
+ TUint32 wordValue = 0;
+ TInt pixelShift = 0;
+ do {
+ TUint32 eightPixels = *aPixelIndex++;
+ eightPixels |= *aPixelIndex++ << 2;
+ eightPixels |= *aPixelIndex++ << 2*2;
+ eightPixels |= *aPixelIndex++ << 2*3;
+ eightPixels |= *aPixelIndex++ << 2*4;
+ eightPixels |= *aPixelIndex++ << 2*5;
+ eightPixels |= *aPixelIndex++ << 2*6;
+ eightPixels |= *aPixelIndex++ << 2*7;
+ wordValue |= eightPixels << pixelShift;
+ pixelShift += 2*8;
+ }
+ while(pixelShift < 32);
+ *dataPtr++ = wordValue;
+ }
+ while(dataPtr < dataPtrLimit);
+ break;
+
+ case 0:
+ do {
+ TUint32 wordValue = 0;
+ TInt pixelShift = 0;
+ do {
+ TUint32 eightPixels = *aPixelIndex++;
+ eightPixels |= *aPixelIndex++ << 1;
+ eightPixels |= *aPixelIndex++ << 2;
+ eightPixels |= *aPixelIndex++ << 3;
+ eightPixels |= *aPixelIndex++ << 4;
+ eightPixels |= *aPixelIndex++ << 5;
+ eightPixels |= *aPixelIndex++ << 6;
+ eightPixels |= *aPixelIndex++ << 7;
+ wordValue |= eightPixels << pixelShift;
+ pixelShift += 8;
+ }
+ while(pixelShift < 32);
+ *dataPtr++ = wordValue;
+ }
+ while(dataPtr < dataPtrLimit);
+ break;
+ default:
+ Panic(ECorrupt);
+ break;
+ }
+ }
+
+ // Do remaining pixels for colour depths that are < 32bit.
+
+ if(aNumberOfPixels)
+ {
+ TInt bitShiftLimit = aNumberOfPixels<<iBppShift;
+ TInt wordValue = *dataPtr;
+
+ wordValue &= 0xFFFFFFFF<<bitShiftLimit; //zero the destination pixels we are about to write
+ do {
+ wordValue |= *aPixelIndex++ << bitShift;
+ bitShift += bpp;
+ }
+ while(bitShift<bitShiftLimit);
+
+ *dataPtr = wordValue;
+ }
+
+ // Finished
+
+ iData.iWordPos = dataPtr;
+ iBitShift = bitShift;
+ }
+ else
+ {
+ TUint32* pixelPtrLimit = aPixelIndex + aNumberOfPixels;
+
+ TUint8* dataPtr = iData.iBytePos;
+
+ while (aPixelIndex < pixelPtrLimit)
+ {
+ TUint32 pixel = *aPixelIndex++;
+ *dataPtr++ = TUint8(pixel);
+ *dataPtr++ = TUint8(pixel >> 8);
+ *dataPtr++ = TUint8(pixel >> 16);
+ }
+
+ iData.iBytePos = dataPtr;
+ }
+
+ }
+
+/**
+Sets the current position in the bitmap to aPosition.
+
+@param aPosition
+ The position to move to.
+
+@return A boolean indicating if the position was out of bounds. EFalse if the position was out of
+ bounds, otherwise ETrue.
+*/
+EXPORT_C TBool TImageBitmapUtil::SetPos(const TPoint& aPosition)
+ {
+ ASSERT(iBitmap);
+ ASSERT(iBase.iWordPos);
+
+ if (aPosition.iX < 0 || aPosition.iX >= iSize.iWidth || aPosition.iY < 0 || aPosition.iY >= iSize.iHeight)
+ return EFalse;
+
+ iData.iWordPos = iBase.iWordPos + (iScanlineWordLength * aPosition.iY);
+
+ if (iWordAccess)
+ {
+ iData.iWordPos += aPosition.iX >> iPixelShift;
+ iBitShift = (aPosition.iX << iBppShift) & 0x1f;
+ }
+ else
+ iData.iBytePos += (aPosition.iX << 1) + aPosition.iX;
+
+ iPosition = aPosition;
+ return ETrue;
+ }
+