fbs/fontandbitmapserver/sfbs/BitmapCompr.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     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 	}