--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fbs/fontandbitmapserver/sfbs/BitmapCompr.cpp Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,348 @@
+// Copyright (c) 2003-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 <e32base.h>
+#include <bitmap.h>
+#include "CompressionBookmark.h"
+#include "BitmapCompr.h"
+#include "UTILS.H"
+#include "bitmapconst.h"
+
+GLREF_C void Panic(TFbsPanic aPanic);
+
+/**
+The method recalculates aLineScanPos which is used for quick search of the
+nearest "length" byte before aStartPos.
+Note: The method should be used only for compressed in RAM bitmaps for which
+iPile != NULL.
+@internalComponent
+@post aLineScanPos might be updated
+*/
+GLDEF_C void AdjustLineScanningPosition(TLineScanningPosition& aLineScanPos,
+ const TUint32* aBase,
+ TInt aBitmapWidth,
+ TInt aStartPos,
+ TInt aCompressedDataBytes)
+ {
+ TInt difference = ::Abs(aStartPos - aLineScanPos.iCursorPos);
+ if(difference > aBitmapWidth && aCompressedDataBytes > KCompressionBookMarkThreshold)
+ {
+ const TCompressionBookMark* bookMarkPtr =
+ (const TCompressionBookMark*)((const TUint8*)aBase +
+ (aCompressedDataBytes + 3) / 4 * 4 + 4);
+ if(bookMarkPtr->iSrcDataOffset && bookMarkPtr->IsCheckSumOk())
+ {
+ TInt difference2 = ::Abs(aStartPos - bookMarkPtr->iCursorPos);
+ if(difference2 < difference)
+ {
+ aLineScanPos.iCursorPos = bookMarkPtr->iCursorPos;
+ aLineScanPos.iSrcDataPtr = ((TUint8*)aBase) + bookMarkPtr->iSrcDataOffset;
+ }
+ }
+ }
+ }
+
+/**
+The method gets the first 16 bpp pixel value pointed by aSrcPtr and copies it aCount times
+to aDestPtr buffer.
+@internalComponent
+@pre aCount > 0
+@param aSrcPtr It points to the source pixel
+@param aDestPtr It points to the destination buffer where the pixel should be copied aCount times
+@param aCount How many times the pixel value should be copied
+@return The updated aDestPtr
+*/
+template <>
+TUint8* TScanLineDecompressor<E2bpp, E2bpp>::CopyPixel(TUint8* aDestPtr,
+ const TUint8* aSrcPtr,
+ TInt aCount) const
+ {
+ //We can't access directly the 16 bits data chunk, because it may be located at an odd address and
+ //THUMB build will fail with "KERNEL EXEC-3".
+ TUint8 lsb = *aSrcPtr;
+ TUint8 msb = *(aSrcPtr + 1);
+ TUint16 data = TUint16(lsb | (TUint16(msb) << 8));
+ TUint32 data32 = TUint32(data | (TUint32(data) << 16));
+ if((TUint32(aDestPtr) & 0x2) && aCount)
+ {
+ *(TUint16*)aDestPtr = data;
+ aDestPtr += 2;//+= 2 - the pixel color is coded into 16 bits - 2 bytes
+ aCount--;
+ }
+ while(aCount > 1)
+ {
+ *(TUint32*)aDestPtr = data32;
+ aDestPtr += 4;//+= 4 - the pixel color is coded into 16 bits - 2 x 2 bytes
+ aCount -= 2;
+ }
+ if(aCount)
+ {
+ *(TUint16*)aDestPtr = data;
+ aDestPtr += 2;//+= 2 - the pixel color is coded into 16 bits - 2 bytes
+ }
+ return aDestPtr;
+ }
+
+/**
+The method gets the first 24 bpp pixel value pointed by aSrcPtr and copies it aCount times
+to aDestPtr buffer.
+@internalComponent
+@pre aCount > 0
+@param aSrcPtr It points to the source pixel
+@param aDestPtr It points to the destination buffer where the pixel should be copied aCount times
+@param aCount How many times the pixel value should be copied
+@return The updated aDestPtr
+*/
+template <>
+TUint8* TScanLineDecompressor<E3bpp, E3bpp>::CopyPixel(TUint8* aDestPtr,
+ const TUint8* aSrcPtr,
+ TInt aCount) const
+ {
+ const TUint8 b1 = *aSrcPtr;
+ const TUint8 b2 = *(aSrcPtr + 1);
+ const TUint8 b3 = *(aSrcPtr + 2);
+ while(aCount--)
+ {
+ *aDestPtr++ = b1;
+ *aDestPtr++ = b2;
+ *aDestPtr++ = b3;
+ }
+ return aDestPtr;
+ }
+
+/**
+The method gets the first 32 bpp pixel value pointed by aSrcPtr and copies it aCount times
+to aDestPtr buffer.
+@internalComponent
+@pre aCount > 0
+@param aSrcPtr It points to the source pixel
+@param aDestPtr It points to the destination buffer where the pixel should be copied aCount times
+@param aCount How many times the pixel value should be copied
+@return The updated aDestPtr
+*/
+template <>
+TUint8* TScanLineDecompressor<E4bpp, E4bpp>::CopyPixel(TUint8* aDestPtr,
+ const TUint8* aSrcPtr,
+ TInt aCount) const
+ {
+ __ASSERT_DEBUG((reinterpret_cast<TUint32>(aDestPtr) & 0x3)==0,Panic(EFbsBitmapDecompressionError)); // make sure the start address is word aligned
+
+ const TUint8 b1 = *aSrcPtr;
+ const TUint8 b2 = *(aSrcPtr + 1);
+ const TUint8 b3 = *(aSrcPtr + 2);
+ const TUint8 b4 = *(aSrcPtr + 3);
+
+ if((reinterpret_cast<TUint32>(aDestPtr) & 0x3)== 0) // the start address is word aligned
+ {
+ const TUint32 pixel = (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
+ TUint32* destPtr32 = reinterpret_cast <TUint32*>(aDestPtr);
+ TInt blocksOf16 = ((aCount + 0x0f) >> 4); // number of blocks of upto 16 words to write
+ // the first iteration writes 1 to 15 words
+ switch (aCount & 0x0f)
+ { // note that case statements intentionally cascade
+ case 0:
+ do { // second and subsequent iterations always write 16 words
+ *destPtr32++ = pixel;
+ case 15:
+ *destPtr32++ = pixel;
+ case 14:
+ *destPtr32++ = pixel;
+ case 13:
+ *destPtr32++ = pixel;
+ case 12:
+ *destPtr32++ = pixel;
+ case 11:
+ *destPtr32++ = pixel;
+ case 10:
+ *destPtr32++ = pixel;
+ case 9:
+ *destPtr32++ = pixel;
+ case 8:
+ *destPtr32++ = pixel;
+ case 7:
+ *destPtr32++ = pixel;
+ case 6:
+ *destPtr32++ = pixel;
+ case 5:
+ *destPtr32++ = pixel;
+ case 4:
+ *destPtr32++ = pixel;
+ case 3:
+ *destPtr32++ = pixel;
+ case 2:
+ *destPtr32++ = pixel;
+ case 1:
+ *destPtr32++ = pixel;
+ } while(--blocksOf16 > 0);
+ }
+
+ return reinterpret_cast <TUint8*>(destPtr32);
+ }
+
+ while(aCount--)
+ {
+ *aDestPtr++ = b1;
+ *aDestPtr++ = b2;
+ *aDestPtr++ = b3;
+ *aDestPtr++ = b4;
+ }
+ return aDestPtr;
+ }
+
+/**
+The method gets the first 24 bpp pixel value pointed by aSrcPtr and copies it aCount times
+to aDestPtr 32 bpp buffer.
+@internalComponent
+@pre aCount > 0
+@param aSrcPtr It points to the source pixel
+@param aDestPtr It points to the destination buffer where the pixel should be copied aCount times
+@param aCount How many times the pixel value should be copied
+@return The updated aDestPtr
+*/
+template <>
+TUint8* TScanLineDecompressor<E3bpp, E4bpp>::CopyPixel(TUint8* aDestPtr,
+ const TUint8* aSrcPtr,
+ TInt aCount) const
+ {
+ const TUint8 b1 = *aSrcPtr;
+ const TUint8 b2 = *(aSrcPtr + 1);
+ const TUint8 b3 = *(aSrcPtr + 2);
+
+ if((reinterpret_cast<TUint32>(aDestPtr) & 0x3)== 0) // the start address is word aligned
+ {
+ const TUint32 pixel = 0xFF000000 | (b3 << 16) | (b2 << 8) | b1; //it is more accurate to equalize to 0xff,
+ //as top byte could correspond an alpha channel
+ TUint32* destPtr32 = reinterpret_cast <TUint32*>(aDestPtr);
+ TInt blocksOf16 = ((aCount + 0x0f) >> 4); // number of blocks of upto 16 words to write
+ // the first iteration writes 1 to 15 words
+ switch (aCount & 0x0f)
+ { // note that case statements intentionally cascade
+ case 0:
+ do { // second and subsequent iterations always write 16 words
+ *destPtr32++ = pixel;
+ case 15:
+ *destPtr32++ = pixel;
+ case 14:
+ *destPtr32++ = pixel;
+ case 13:
+ *destPtr32++ = pixel;
+ case 12:
+ *destPtr32++ = pixel;
+ case 11:
+ *destPtr32++ = pixel;
+ case 10:
+ *destPtr32++ = pixel;
+ case 9:
+ *destPtr32++ = pixel;
+ case 8:
+ *destPtr32++ = pixel;
+ case 7:
+ *destPtr32++ = pixel;
+ case 6:
+ *destPtr32++ = pixel;
+ case 5:
+ *destPtr32++ = pixel;
+ case 4:
+ *destPtr32++ = pixel;
+ case 3:
+ *destPtr32++ = pixel;
+ case 2:
+ *destPtr32++ = pixel;
+ case 1:
+ *destPtr32++ = pixel;
+ } while(--blocksOf16 > 0);
+ }
+
+ return reinterpret_cast <TUint8*>(destPtr32);
+ }
+
+ while(aCount--)
+ {
+ *aDestPtr++ = b1;
+ *aDestPtr++ = b2;
+ *aDestPtr++ = b3;
+ *aDestPtr++ = 0xff; //it is more accurate to equalize to 0xff, as top byte
+ //could correspond an alpha channel
+ }
+ return aDestPtr;
+ }
+
+/**
+The method gets the 24 bpp pixel value pointed by aSrcPtr and copies it aCount times
+to aDestPtr 32 bpp buffer.
+@internalComponent
+@pre aCount > 0
+@param aSrcPtr It points to the source pixel
+@param aDestPtr It points to the destination buffer where the pixel should be copied aCount times
+@param aCount How many times the pixel value should be copied
+@return The updated aDestPtr
+*/
+template <>
+TUint8* TScanLineDecompressor<E3bpp, E4bpp>::CopyBlockPixel(TUint8* aDestPtr,
+ const TUint8* aSrcPtr,
+ TInt aCount) const
+ {
+ while(aCount--)
+ {
+ *aDestPtr++ = *aSrcPtr++;
+ *aDestPtr++ = *aSrcPtr++;
+ *aDestPtr++ = *aSrcPtr++;
+ *aDestPtr++ = 0xff; //it is more accurate to equalize to 0xff, as top byte
+ //could correspond an alpha channel
+ }
+ return aDestPtr;
+ }
+
+/**
+The method should never be executed.
+Introduced to prevent CCover compiler from failing.
+@internalComponent
+@return The unchanged aDestPtr
+*/
+template <>
+TUint8* TScanLineDecompressor<E2bpp, E2bpp>::CopyBlockPixel(TUint8* aDestPtr,
+ const TUint8* /*aSrcPtr*/,
+ TInt /*aCount*/) const
+ {
+ return aDestPtr;
+ }
+
+/**
+The method should never be executed.
+Introduced to prevent CCover compiler from failing.
+@internalComponent
+@return The unchanged aDestPtr
+*/
+template <>
+TUint8* TScanLineDecompressor<E3bpp, E3bpp>::CopyBlockPixel(TUint8* aDestPtr,
+ const TUint8* /*aSrcPtr*/,
+ TInt /*aCount*/) const
+ {
+ return aDestPtr;
+ }
+
+/**
+The method should never be executed.
+Introduced to prevent CCover compiler from failing.
+@internalComponent
+@return The unchanged aDestPtr
+*/
+template <>
+TUint8* TScanLineDecompressor<E4bpp, E4bpp>::CopyBlockPixel(TUint8* aDestPtr,
+ const TUint8* /*aSrcPtr*/,
+ TInt /*aCount*/) const
+ {
+ return aDestPtr;
+ }