os/graphics/fbs/fontandbitmapserver/sfbs/BitmapCompr.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2003-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 <e32base.h>
    17 #include <bitmap.h>
    18 #include "CompressionBookmark.h"
    19 #include "BitmapCompr.h"
    20 #include "UTILS.H"
    21 #include "bitmapconst.h"
    22 
    23 GLREF_C void Panic(TFbsPanic aPanic);
    24 
    25 /**
    26 The method recalculates aLineScanPos which is used for quick search of the
    27 nearest "length" byte before aStartPos.
    28 Note: The method should be used only for compressed in RAM bitmaps for which
    29 iPile != NULL.
    30 @internalComponent
    31 @post aLineScanPos might be updated
    32 */
    33 GLDEF_C void AdjustLineScanningPosition(TLineScanningPosition& aLineScanPos, 
    34 										const TUint32* aBase, 
    35 										TInt aBitmapWidth, 
    36 										TInt aStartPos,
    37 										TInt aCompressedDataBytes)
    38 	{
    39 	TInt difference = ::Abs(aStartPos - aLineScanPos.iCursorPos);
    40 	if(difference > aBitmapWidth && aCompressedDataBytes > KCompressionBookMarkThreshold)
    41 		{
    42 		const TCompressionBookMark* bookMarkPtr = 
    43 			(const TCompressionBookMark*)((const TUint8*)aBase + 
    44 										  (aCompressedDataBytes + 3) / 4 * 4 + 4);
    45 		if(bookMarkPtr->iSrcDataOffset && bookMarkPtr->IsCheckSumOk())
    46 			{
    47 			TInt difference2 = ::Abs(aStartPos - bookMarkPtr->iCursorPos);
    48 			if(difference2 < difference)
    49 				{
    50 				aLineScanPos.iCursorPos = bookMarkPtr->iCursorPos;
    51 				aLineScanPos.iSrcDataPtr = ((TUint8*)aBase) + bookMarkPtr->iSrcDataOffset;
    52 				}
    53 			}
    54 		}
    55 	}
    56 
    57 /**
    58 The method gets the first 16 bpp pixel value pointed by aSrcPtr and copies it aCount times
    59 to aDestPtr buffer.
    60 @internalComponent
    61 @pre aCount > 0
    62 @param aSrcPtr It points to the source pixel
    63 @param aDestPtr It points to the destination buffer where the pixel should be copied aCount times
    64 @param aCount How many times the pixel value should be copied
    65 @return The updated aDestPtr
    66 */
    67 template <> 
    68 TUint8* TScanLineDecompressor<E2bpp, E2bpp>::CopyPixel(TUint8* aDestPtr, 
    69 												 const TUint8* aSrcPtr, 
    70 												 TInt aCount) const
    71 	{
    72 	//We can't access directly the 16 bits data chunk, because it may be located at an odd address and
    73 	//THUMB build will fail with "KERNEL EXEC-3".
    74 	TUint8 lsb = *aSrcPtr;
    75 	TUint8 msb = *(aSrcPtr + 1);
    76 	TUint16 data = TUint16(lsb | (TUint16(msb) << 8));
    77 	TUint32 data32 = TUint32(data | (TUint32(data) << 16));
    78 	if((TUint32(aDestPtr) & 0x2) && aCount)
    79 		{
    80 		*(TUint16*)aDestPtr = data;
    81 		aDestPtr += 2;//+= 2 - the pixel color is coded into 16 bits - 2 bytes
    82 		aCount--;
    83 		}
    84 	while(aCount > 1)
    85 		{
    86 		*(TUint32*)aDestPtr = data32;
    87 		aDestPtr += 4;//+= 4 - the pixel color is coded into 16 bits - 2 x 2 bytes
    88 		aCount -= 2;
    89 		}
    90 	if(aCount)
    91 		{
    92 		*(TUint16*)aDestPtr = data;
    93 		aDestPtr += 2;//+= 2 - the pixel color is coded into 16 bits - 2 bytes
    94 		}
    95 	return aDestPtr;
    96 	}
    97 
    98 /**
    99 The method gets the first 24 bpp pixel value pointed by aSrcPtr and copies it aCount times
   100 to aDestPtr buffer.
   101 @internalComponent
   102 @pre aCount > 0
   103 @param aSrcPtr It points to the source pixel
   104 @param aDestPtr It points to the destination buffer where the pixel should be copied aCount times
   105 @param aCount How many times the pixel value should be copied
   106 @return The updated aDestPtr
   107 */
   108 template <> 
   109 TUint8* TScanLineDecompressor<E3bpp, E3bpp>::CopyPixel(TUint8* aDestPtr, 
   110 												 const TUint8* aSrcPtr, 
   111 												 TInt aCount) const
   112 	{
   113 	const TUint8 b1 = *aSrcPtr;
   114 	const TUint8 b2 = *(aSrcPtr + 1);
   115 	const TUint8 b3 = *(aSrcPtr + 2);
   116 	while(aCount--)
   117 		{
   118 		*aDestPtr++ = b1;
   119 		*aDestPtr++ = b2;
   120 		*aDestPtr++ = b3;
   121 		}
   122 	return aDestPtr;
   123 	}
   124 
   125 /**
   126 The method gets the first 32 bpp pixel value pointed by aSrcPtr and copies it aCount times
   127 to aDestPtr buffer.
   128 @internalComponent
   129 @pre aCount > 0
   130 @param aSrcPtr It points to the source pixel
   131 @param aDestPtr It points to the destination buffer where the pixel should be copied aCount times
   132 @param aCount How many times the pixel value should be copied
   133 @return The updated aDestPtr
   134 */
   135 template <> 
   136 TUint8* TScanLineDecompressor<E4bpp, E4bpp>::CopyPixel(TUint8* aDestPtr, 
   137 												 const TUint8* aSrcPtr, 
   138 												 TInt aCount) const
   139 	{
   140 	__ASSERT_DEBUG((reinterpret_cast<TUint32>(aDestPtr) & 0x3)==0,Panic(EFbsBitmapDecompressionError)); // make sure the start address is word aligned
   141 
   142 	const TUint8 b1 = *aSrcPtr;
   143 	const TUint8 b2 = *(aSrcPtr + 1);
   144 	const TUint8 b3 = *(aSrcPtr + 2);
   145 	const TUint8 b4 = *(aSrcPtr + 3);
   146 
   147 	if((reinterpret_cast<TUint32>(aDestPtr) & 0x3)== 0)	// the start address is word aligned
   148 		{
   149 		const TUint32 pixel = (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
   150 		TUint32* destPtr32 = reinterpret_cast <TUint32*>(aDestPtr);
   151 		TInt blocksOf16 = ((aCount + 0x0f) >> 4);	// number of blocks of upto 16 words to write
   152 		// the first iteration writes 1 to 15 words
   153 		switch (aCount & 0x0f)
   154 			{ // note that case statements intentionally cascade
   155 		case 0:
   156 			do {	// second and subsequent iterations always write 16 words
   157 			*destPtr32++ = pixel;
   158 		case 15:
   159 			*destPtr32++ = pixel;
   160 		case 14:
   161 			*destPtr32++ = pixel;
   162 		case 13:
   163 			*destPtr32++ = pixel;
   164 		case 12:
   165 			*destPtr32++ = pixel;
   166 		case 11:
   167 			*destPtr32++ = pixel;
   168 		case 10:
   169 			*destPtr32++ = pixel;
   170 		case 9:
   171 			*destPtr32++ = pixel;
   172 		case 8:
   173 			*destPtr32++ = pixel;
   174 		case 7:
   175 			*destPtr32++ = pixel;
   176 		case 6:
   177 			*destPtr32++ = pixel;
   178 		case 5:
   179 			*destPtr32++ = pixel;
   180 		case 4:
   181 			*destPtr32++ = pixel;
   182 		case 3:
   183 			*destPtr32++ = pixel;
   184 		case 2:
   185 			*destPtr32++ = pixel;
   186 		case 1:
   187 			*destPtr32++ = pixel;
   188 			} while(--blocksOf16 > 0);
   189 			}
   190 
   191 		return reinterpret_cast <TUint8*>(destPtr32);
   192 		}
   193 
   194 	while(aCount--)
   195 		{
   196 		*aDestPtr++ = b1;
   197 		*aDestPtr++ = b2;
   198 		*aDestPtr++ = b3;
   199 		*aDestPtr++ = b4;
   200 		}
   201 	return aDestPtr;
   202 	}
   203 
   204 /**
   205 The method gets the first 24 bpp pixel value pointed by aSrcPtr and copies it aCount times
   206 to aDestPtr 32 bpp buffer.
   207 @internalComponent
   208 @pre aCount > 0
   209 @param aSrcPtr It points to the source pixel
   210 @param aDestPtr It points to the destination buffer where the pixel should be copied aCount times
   211 @param aCount How many times the pixel value should be copied
   212 @return The updated aDestPtr
   213 */
   214 template <> 
   215 TUint8* TScanLineDecompressor<E3bpp, E4bpp>::CopyPixel(TUint8* aDestPtr, 
   216 												 const TUint8* aSrcPtr, 
   217 												 TInt aCount) const
   218 	{
   219 	const TUint8 b1 = *aSrcPtr;
   220 	const TUint8 b2 = *(aSrcPtr + 1);
   221 	const TUint8 b3 = *(aSrcPtr + 2);
   222 
   223 	if((reinterpret_cast<TUint32>(aDestPtr) & 0x3)== 0)	// the start address is word aligned
   224 		{
   225 		const TUint32 pixel = 0xFF000000 | (b3 << 16) | (b2 << 8) | b1; //it is more accurate to equalize to 0xff, 
   226 																		 //as top byte could correspond an alpha channel
   227 		TUint32* destPtr32 = reinterpret_cast <TUint32*>(aDestPtr);
   228 		TInt blocksOf16 = ((aCount + 0x0f) >> 4);	// number of blocks of upto 16 words to write
   229 		// the first iteration writes 1 to 15 words
   230 		switch (aCount & 0x0f)
   231 			{ // note that case statements intentionally cascade
   232 		case 0:
   233 			do {	// second and subsequent iterations always write 16 words
   234 			*destPtr32++ = pixel;
   235 		case 15:
   236 			*destPtr32++ = pixel;
   237 		case 14:
   238 			*destPtr32++ = pixel;
   239 		case 13:
   240 			*destPtr32++ = pixel;
   241 		case 12:
   242 			*destPtr32++ = pixel;
   243 		case 11:
   244 			*destPtr32++ = pixel;
   245 		case 10:
   246 			*destPtr32++ = pixel;
   247 		case 9:
   248 			*destPtr32++ = pixel;
   249 		case 8:
   250 			*destPtr32++ = pixel;
   251 		case 7:
   252 			*destPtr32++ = pixel;
   253 		case 6:
   254 			*destPtr32++ = pixel;
   255 		case 5:
   256 			*destPtr32++ = pixel;
   257 		case 4:
   258 			*destPtr32++ = pixel;
   259 		case 3:
   260 			*destPtr32++ = pixel;
   261 		case 2:
   262 			*destPtr32++ = pixel;
   263 		case 1:
   264 			*destPtr32++ = pixel;
   265 			} while(--blocksOf16 > 0);
   266 			}
   267 
   268 		return reinterpret_cast <TUint8*>(destPtr32);
   269 		}
   270 
   271 	while(aCount--)
   272 		{
   273 		*aDestPtr++ = b1;
   274 		*aDestPtr++ = b2;
   275 		*aDestPtr++ = b3;
   276 		*aDestPtr++ = 0xff; //it is more accurate to equalize to 0xff, as top byte 
   277 									//could correspond an alpha channel
   278 		}
   279 	return aDestPtr;
   280 	}
   281 
   282 /**
   283 The method gets the 24 bpp pixel value pointed by aSrcPtr and copies it aCount times
   284 to aDestPtr 32 bpp buffer.
   285 @internalComponent
   286 @pre aCount > 0
   287 @param aSrcPtr It points to the source pixel
   288 @param aDestPtr It points to the destination buffer where the pixel should be copied aCount times
   289 @param aCount How many times the pixel value should be copied
   290 @return The updated aDestPtr
   291 */
   292 template <> 
   293 TUint8* TScanLineDecompressor<E3bpp, E4bpp>::CopyBlockPixel(TUint8* aDestPtr, 
   294 												 const TUint8* aSrcPtr, 
   295 												 TInt aCount) const
   296 	{
   297 	while(aCount--)
   298 		{
   299 		*aDestPtr++ = *aSrcPtr++;
   300 		*aDestPtr++ = *aSrcPtr++;
   301 		*aDestPtr++ = *aSrcPtr++;
   302 		*aDestPtr++ = 0xff; //it is more accurate to equalize to 0xff, as top byte 
   303 									//could correspond an alpha channel
   304 		}
   305 	return aDestPtr;
   306 	}
   307 
   308 /**
   309 The method should never be executed.
   310 Introduced to prevent CCover compiler from failing.
   311 @internalComponent
   312 @return The unchanged aDestPtr
   313 */
   314 template <> 
   315 TUint8* TScanLineDecompressor<E2bpp, E2bpp>::CopyBlockPixel(TUint8* aDestPtr, 
   316 												 const TUint8* /*aSrcPtr*/, 
   317 												 TInt /*aCount*/) const
   318 	{
   319 	return aDestPtr;
   320 	}
   321 
   322 /**
   323 The method should never be executed.
   324 Introduced to prevent CCover compiler from failing.
   325 @internalComponent
   326 @return The unchanged aDestPtr
   327 */
   328 template <> 
   329 TUint8* TScanLineDecompressor<E3bpp, E3bpp>::CopyBlockPixel(TUint8* aDestPtr, 
   330 												 const TUint8* /*aSrcPtr*/, 
   331 												 TInt /*aCount*/) const
   332 	{
   333 	return aDestPtr;
   334 	}
   335 
   336 /**
   337 The method should never be executed.
   338 Introduced to prevent CCover compiler from failing.
   339 @internalComponent
   340 @return The unchanged aDestPtr
   341 */
   342 template <> 
   343 TUint8* TScanLineDecompressor<E4bpp, E4bpp>::CopyBlockPixel(TUint8* aDestPtr, 
   344 												 const TUint8* /*aSrcPtr*/, 
   345 												 TInt /*aCount*/) const
   346 	{
   347 	return aDestPtr;
   348 	}