diff -r 000000000000 -r bde4ae8d615e os/graphics/fbs/fontandbitmapserver/sfbs/BitmapCompr.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/graphics/fbs/fontandbitmapserver/sfbs/BitmapCompr.cpp Fri Jun 15 03:10:57 2012 +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 +#include +#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::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::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::CopyPixel(TUint8* aDestPtr, + const TUint8* aSrcPtr, + TInt aCount) const + { + __ASSERT_DEBUG((reinterpret_cast(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(aDestPtr) & 0x3)== 0) // the start address is word aligned + { + const TUint32 pixel = (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; + TUint32* destPtr32 = reinterpret_cast (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 (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::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(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 (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 (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::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::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::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::CopyBlockPixel(TUint8* aDestPtr, + const TUint8* /*aSrcPtr*/, + TInt /*aCount*/) const + { + return aDestPtr; + }