fbs/fontandbitmapserver/sfbs/BMPUTIL.CPP
changeset 0 5d03bc08d59c
child 11 fed1595b188e
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 1995-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 <fbs.h>
       
    17 #include <graphics/lookuptable.h>
       
    18 #include "fbsdefs.h"
       
    19 #include "UTILS.H"
       
    20 
       
    21 GLREF_C void Panic(TFbsPanic aPanic);
       
    22 
       
    23 /* Macros used in support of EColor16M mode bitmaps in TBitmapUtil.
       
    24 PTR2UINT, UINT2PTR defined to ease byte pointer arithmatic using
       
    25 the existing iWordPos word sized pointer.
       
    26 i MACROS redefine the meaning of members in the class for 16M use.
       
    27 All in the name of Binary Compatibility - adding 16M support but
       
    28 without wasting memory or increasing the size of this class's objects. */
       
    29 #define PTR2UINT(_ptr)      reinterpret_cast<TUint32>(_ptr)
       
    30 #define UINT2PTR(_expr)     reinterpret_cast<TUint32*>(_expr)
       
    31 #define iNUM_WASTE_BYTES    iMask
       
    32 #define iSTART_OF_SCAN_LINE iWordPos
       
    33 #define iPIXEL_BYTE_OFFSET  iPixelShift
       
    34 #define iPIXEL_ADDRESS      UINT2PTR(PTR2UINT(iWordPos)+iPixelShift)
       
    35 
       
    36 
       
    37 /** Constructs a TBitmapUtil object for the specified bitmap.
       
    38 
       
    39 @param aBitmap The bitmap on which this TBitmapUtil will operate. */
       
    40 EXPORT_C TBitmapUtil::TBitmapUtil(CFbsBitmap* aBitmap):
       
    41     iFbsBitmap(aBitmap),	// Address of bitmap to navigate and modify.
       
    42 	iWordPos(NULL),			// Non16M: Address of the word containing the bits
       
    43 							//         of the current pixel.
       
    44 							// 16M: Redefined to iSTART_OF_SCAN_LINE - word address
       
    45 							//      of the scan line containing the current pixel.
       
    46 	iMinWordPos(NULL),		// Member holds the word address of the top left pixel.
       
    47 	iMaxWordPos(NULL),		// Member holds address of the word following the last
       
    48 							// word in the last scan line of the bitmap.
       
    49 	iBpp(0),				// Number of bits needed for each pixel's data.
       
    50 	iPixelShift(0),			// Non16M: Right shift factor to convert pixel index
       
    51 	                        //         to word index into scan line.
       
    52 							// 16M: Redefined to iPIXEL_BYTE_OFFSET - index to first
       
    53 							//      byte in pixel from the start of the scan line.
       
    54 	iBitShift(0),			// Non16M: Changing index of right shift require to
       
    55 	                        //         move pixel bits into LSB of word.
       
    56 							// 16M: Not used, always 0
       
    57 	iMask(0),               // Non16M: Mask of LSB required to hold
       
    58 	                        //         pixel data eg. 16cols 0x0f
       
    59 							// 16M: Redefined to iNUM_WASTE_BYTES - number of
       
    60 							//      padding bytes at end of scan line 0,3,6,9 as 16M
       
    61 							//      scanlines are always multiples of 12 bytes.
       
    62 	iScanlineWordLength(0), // Number of 4-byte words in bitmap scan line
       
    63 	iWritten(EFalse)
       
    64 	{}
       
    65 
       
    66 /** Sets the current pixel position to the specified position and prepares
       
    67 the bitmap for access to its pixel data.
       
    68 
       
    69 This function must be called before using any of the other functions provided
       
    70 by this class, otherwise damage to data may occur. It must also be matched
       
    71 by a subsequent call to End().
       
    72 
       
    73 @pre The bitmap which was passed on class construction has been created and holds 
       
    74 	a valid handle.
       
    75 @param aPosition The position to which the current pixel position should be
       
    76 set. */
       
    77 EXPORT_C void TBitmapUtil::Begin(const TPoint& aPosition)
       
    78 	{
       
    79 	ASSERT(iFbsBitmap);
       
    80 	iFbsBitmap->BeginDataAccess();
       
    81 	TSize bmpsize(iFbsBitmap->SizeInPixels());
       
    82 	ASSERT(bmpsize.iWidth > 0 && bmpsize.iHeight > 0);
       
    83 
       
    84 	iWritten = EFalse;
       
    85 
       
    86 	TDisplayMode dm=iFbsBitmap->DisplayMode();
       
    87 	TInt numBytesInScanline = CFbsBitmap::ScanLineLength(bmpsize.iWidth,dm);
       
    88 	switch(dm)
       
    89 		{
       
    90 	case EGray2:
       
    91 		iMask=1;
       
    92 		iPixelShift=5;
       
    93 		iBpp=1;
       
    94 		break;
       
    95 	case EGray4:
       
    96 		iMask=3;
       
    97 		iPixelShift=4;
       
    98 		iBpp=2;
       
    99 		break;
       
   100 	case EGray16:
       
   101 	case EColor16:
       
   102 		iMask=0xf;
       
   103 		iPixelShift=3;
       
   104 		iBpp=4;
       
   105 		break;
       
   106 	case EGray256:
       
   107 	case EColor256:
       
   108 		iMask=0xff;
       
   109 		iPixelShift=2;
       
   110 		iBpp=8;
       
   111 		break;
       
   112 	case EColor4K:
       
   113 	case EColor64K:
       
   114 		iMask=0xffff;
       
   115 		iPixelShift=1;
       
   116 		iBpp=16;
       
   117 		break;
       
   118 	/* Bit twiddling not used in the EColor16M, members redefined for
       
   119      different use.	 */
       
   120 	case EColor16M:
       
   121 		iNUM_WASTE_BYTES = numBytesInScanline-(bmpsize.iWidth*3);
       
   122 		iPIXEL_BYTE_OFFSET=0;
       
   123 		iBpp=24; // Indicates 16M display mode, flag for member functions
       
   124 		         // to switch functionality.
       
   125 		break;
       
   126 	case EColor16MU:
       
   127 	case EColor16MA:
       
   128 	case EColor16MAP:
       
   129 		iMask=0xffffffff;
       
   130 		iPixelShift=0;
       
   131 		iBpp=32;
       
   132 		break;
       
   133 	default: //shouldn't reach this point
       
   134 		Panic(EFbsBitmapInvalidMode);
       
   135 		}
       
   136 
       
   137 	iMinWordPos=(TUint32*)iFbsBitmap->DataAddress();
       
   138 	iScanlineWordLength = numBytesInScanline / 4;
       
   139 	iMaxWordPos = iMinWordPos + (bmpsize.iHeight * iScanlineWordLength);
       
   140 
       
   141 	TPoint correct(aPosition);
       
   142 	if(correct.iX<0) correct.iX=0;
       
   143 	if(correct.iY<0) correct.iY=0;
       
   144 	if(correct.iX>=bmpsize.iWidth) correct.iX=bmpsize.iWidth;
       
   145 	if(correct.iY>=bmpsize.iHeight) correct.iY=bmpsize.iHeight;
       
   146 	SetPos(correct);
       
   147 	}
       
   148 
       
   149 /** Sets the current pixel position to the specified position and prepares
       
   150 the bitmap for access to its pixel data.
       
   151 
       
   152 This function is deprecated. Use the other overload, Begin(const TPoint&).
       
   153 @deprecated
       
   154 
       
   155 @param aPosition The position to which the current pixel position should be
       
   156 set.
       
   157 @param aUtil Not used.
       
   158 @panic FBCLI 10 The bitmap's display mode is ERgb or ENone. */
       
   159 EXPORT_C void TBitmapUtil::Begin(const TPoint& aPosition, const TBitmapUtil& /*aUtil*/)
       
   160 	{
       
   161 	Begin(aPosition);
       
   162 	}
       
   163 
       
   164 /** Marks the end of the access to the bitmap data.
       
   165 This function must be called when finished using all the other functions
       
   166 provided by this class.
       
   167 
       
   168 There must be exactly one call to End() for each previous call to Begin()
       
   169 for a given TBitmapUtil object. */
       
   170 EXPORT_C void TBitmapUtil::End()
       
   171 	{
       
   172 	iFbsBitmap->EndDataAccess(!iWritten);
       
   173 	}
       
   174 
       
   175 
       
   176 
       
   177 /** Gets the value of the pixel at the current pixel position.
       
   178 
       
   179 In normal usage, the value returned will immediately be used as the parameter
       
   180 to a call to SetPixel(). To remove the overhead of constructing a TRgb, the
       
   181 function uses a TUint32 rather than a TRgb to hold an RGB value.
       
   182 
       
   183 @return The value of the pixel at the current pixel position. */
       
   184 EXPORT_C TUint32 TBitmapUtil::GetPixel() const
       
   185 	{
       
   186 	if (iBpp!=24)
       
   187 		// 1,2,4,8,12,16,32-bit pixels
       
   188 		return((*iWordPos>>iBitShift)&iMask);
       
   189 	else
       
   190 		{
       
   191 		// 24-bit pixels
       
   192 		// Due to machine word alignment requirement on ARM, need to copy
       
   193 		// pixel data at iWordPos a byte at a time if address is not aligned
       
   194 		// on a 4 byte boundary i.e. 1st or 2nd least sig. bits set.
       
   195 		if (iPIXEL_BYTE_OFFSET & 0x3)
       
   196 			{
       
   197 			TUint32 pixel = 0;
       
   198 			Mem::Copy(&pixel, iPIXEL_ADDRESS, 3);
       
   199 			return pixel;
       
   200 			}
       
   201 		else
       
   202 			return (*( iPIXEL_ADDRESS )&0x00ffffff);
       
   203 		}
       
   204 	}
       
   205 
       
   206 /** Sets the value of the pixel at the current pixel position.
       
   207 
       
   208 To remove the overhead of constructing a TRgb, the function uses a TUint32
       
   209 rather than a TRgb to hold an RGB value.
       
   210 
       
   211 @param aValue The value to which the pixel at the current pixel position is
       
   212 to be set. */
       
   213 EXPORT_C void TBitmapUtil::SetPixel(TUint32 aValue)
       
   214 	{
       
   215 	iWritten = ETrue;
       
   216 	if (iBpp!=24)
       
   217 		{
       
   218 		// 1,2,4,8,12,16,32-bit pixels
       
   219 		*iWordPos&=~(iMask<<iBitShift);
       
   220 		*iWordPos|=(aValue&iMask)<<iBitShift;
       
   221 		if(iBpp==32 && iFbsBitmap && iFbsBitmap->DisplayMode() == EColor16MU)
       
   222 				{
       
   223 				*iWordPos|= 0xff000000;
       
   224 				}
       
   225 		}
       
   226 	else
       
   227 		{
       
   228 		// 24-bit pixels
       
   229 		// Due to machine word alignment requirement on ARM, need to copy
       
   230 		// pixel data at iWordPos a byte at a time if address is not aligned
       
   231 		// on a 4 byte boundary i.e. 1st or 2nd least sig. bits set.
       
   232 		if (iPIXEL_BYTE_OFFSET & 0x3)
       
   233 			Mem::Copy(iPIXEL_ADDRESS, &aValue, 3);
       
   234 		else
       
   235 			{
       
   236 			*(iPIXEL_ADDRESS) &= ~0xffffff;
       
   237 			*(iPIXEL_ADDRESS) |= (aValue&0x00ffffff);
       
   238 			}
       
   239 		}
       
   240 	}
       
   241 
       
   242 /** Sets the value of the pixel at the current pixel position to that returned
       
   243 by aSource.GetPixel().
       
   244 
       
   245 @param aSource The TBitmapUtil of the source bitmap, whose pixel value is
       
   246 used to set the pixel at the current pixel position. */
       
   247 EXPORT_C void TBitmapUtil::SetPixel(const TBitmapUtil& aSource)
       
   248 	{
       
   249 	SetPixel(aSource.GetPixel());
       
   250 	}
       
   251 
       
   252 /** Sets a new current pixel position.
       
   253 
       
   254 @param aPosition The new current pixel position. */
       
   255 EXPORT_C void TBitmapUtil::SetPos(const TPoint& aPosition)
       
   256 	{
       
   257 	TSize bmpsize(iFbsBitmap->SizeInPixels());
       
   258 	TPoint correct(aPosition);
       
   259 
       
   260 	correct.iX%=bmpsize.iWidth;
       
   261 	correct.iY%=bmpsize.iHeight;
       
   262 	if(correct.iX<0) correct.iX+=bmpsize.iWidth;
       
   263 	if(correct.iY<0) correct.iY+=bmpsize.iHeight;
       
   264 
       
   265 	iWordPos=iMinWordPos;
       
   266 	iWordPos+=iScanlineWordLength*correct.iY;
       
   267 	if (iBpp!=24)
       
   268 		{
       
   269 		// 1,2,4,8,12,16,32-bit pixels
       
   270 		iWordPos+=correct.iX>>iPixelShift;
       
   271 		iBitShift=(correct.iX*iBpp)%32;
       
   272 		}
       
   273 	else
       
   274 		{
       
   275 		// 24-bit pixels
       
   276 		// iSTART_OF_SCAN_LINE (iWordPos) has correct value at this point
       
   277 		// iBitShift not used in 16M modes
       
   278 		iPIXEL_BYTE_OFFSET = correct.iX*3;	// Byte offset in iY scan line to iX pixel
       
   279 		}
       
   280 }
       
   281 
       
   282 /** Decrements the x co-ordinate of the current pixel position. */
       
   283 EXPORT_C void TBitmapUtil::DecXPos()
       
   284 	{
       
   285 	if (iBpp!=24)
       
   286 		{
       
   287 		// 1,2,4,8,12,16,32-bit pixels
       
   288 		iBitShift-=iBpp;
       
   289 		if(iBitShift<0)
       
   290 			{
       
   291 			iBitShift+=32;
       
   292 			iWordPos--;
       
   293 			if(iWordPos<iMinWordPos) iWordPos=iMaxWordPos-1;
       
   294 			}
       
   295 		}
       
   296 	else
       
   297 		{
       
   298 		// 24-bit pixels
       
   299 		iPIXEL_BYTE_OFFSET -= 3;
       
   300 
       
   301 		// Scanline underflow?
       
   302 		if (iPIXEL_BYTE_OFFSET < 0)
       
   303 			{
       
   304 			iPIXEL_BYTE_OFFSET = (iScanlineWordLength*4)-iNUM_WASTE_BYTES-3;
       
   305 
       
   306 			// Bitmap underflow?
       
   307 		    if (iSTART_OF_SCAN_LINE == iMinWordPos)
       
   308 				iSTART_OF_SCAN_LINE = iMaxWordPos-iScanlineWordLength;
       
   309 			else
       
   310 		        iSTART_OF_SCAN_LINE -= iScanlineWordLength;
       
   311 			}
       
   312 		}
       
   313 	}
       
   314 
       
   315 /** Decrements the y co-ordinate of the current pixel position. */
       
   316 EXPORT_C void TBitmapUtil::DecYPos()
       
   317 	{
       
   318 	iWordPos-=iScanlineWordLength;
       
   319 	if(iWordPos<iMinWordPos) iWordPos+=iMaxWordPos-iMinWordPos;
       
   320 	}
       
   321 
       
   322 /** Increments the x co-ordinate of the current pixel position. */
       
   323 EXPORT_C void TBitmapUtil::IncXPos()
       
   324 	{
       
   325 	if (iBpp!=24)
       
   326 		{
       
   327 		// 1,2,4,8,12,16,32-bit pixels
       
   328 		iBitShift+=iBpp;
       
   329 		if(iBitShift>=32)
       
   330 			{
       
   331 			iBitShift=0;
       
   332 			iWordPos++;
       
   333 			if(iWordPos>=iMaxWordPos) iWordPos=iMinWordPos;
       
   334 			}
       
   335 		}
       
   336 	else
       
   337 		{
       
   338 		// 24-bit pixels
       
   339 		iPIXEL_BYTE_OFFSET += 3;
       
   340 
       
   341 		// Scanline overflow?
       
   342 		if (iPIXEL_BYTE_OFFSET >=
       
   343 				(iScanlineWordLength*4)-static_cast<TInt>(iNUM_WASTE_BYTES))
       
   344 			{
       
   345 			iPIXEL_BYTE_OFFSET = 0;
       
   346 			iSTART_OF_SCAN_LINE += iScanlineWordLength;
       
   347 
       
   348 			// Bitmap overflow?
       
   349 			if (iSTART_OF_SCAN_LINE >= iMaxWordPos)
       
   350 				iSTART_OF_SCAN_LINE = iMinWordPos;
       
   351 			}
       
   352 		}
       
   353 	}
       
   354 
       
   355 /** Increments the y co-ordinate of the current pixel position. */
       
   356 EXPORT_C void TBitmapUtil::IncYPos()
       
   357 	{
       
   358 	iWordPos+=iScanlineWordLength;
       
   359 	if(iWordPos>=iMaxWordPos) iWordPos-=iMaxWordPos-iMinWordPos;
       
   360 	}
       
   361 
       
   362 
       
   363 
       
   364 //
       
   365 // CDitherColor256
       
   366 //
       
   367 
       
   368 class TDitherColorError
       
   369 	{
       
   370 public:
       
   371 	inline TDitherColorError() {};
       
   372 	inline TDitherColorError(TInt aRed,TInt aGreen,TInt aBlue) : iRed(aRed), iGreen(aGreen), iBlue(aBlue) {}
       
   373 public:
       
   374 	TInt iRed;
       
   375 	TInt iGreen;
       
   376 	TInt iBlue;
       
   377 	};
       
   378 
       
   379 NONSHARABLE_CLASS(CDitherColor256) : public CBase
       
   380 	{
       
   381 public:
       
   382 	void ConstructL(TInt aLineWidth,const TColor256Util* aColorUtil = NULL);
       
   383 	void Reset();
       
   384 	void ConvertLine(TUint8* aDestination,TRgb* aSource);
       
   385 	~CDitherColor256();
       
   386 private:
       
   387 	const TColor256Util* iColorUtil;
       
   388 	TInt iLineWidth;
       
   389 	TDitherColorError* iErrorBuffer;
       
   390 	TInt iErrorBufferLength;
       
   391 	};
       
   392 
       
   393 CDitherColor256::~CDitherColor256()
       
   394 	{
       
   395 	delete[] iErrorBuffer;
       
   396 	}
       
   397 
       
   398 void CDitherColor256::ConstructL(TInt aLineWidth,const TColor256Util* aColorUtil)
       
   399 	{
       
   400 	if(iErrorBufferLength<=aLineWidth)
       
   401 		{
       
   402 		delete[] iErrorBuffer;
       
   403 		iErrorBuffer = NULL;
       
   404 		}
       
   405 
       
   406 	if(!iErrorBuffer)
       
   407 		{
       
   408 		iErrorBuffer = new (ELeave) TDitherColorError[aLineWidth+1];
       
   409 		iErrorBufferLength = aLineWidth+1;
       
   410 		}
       
   411 
       
   412 	iLineWidth = aLineWidth;
       
   413 	if(!aColorUtil)
       
   414 		aColorUtil = TColor256Util::Default();
       
   415 	iColorUtil = aColorUtil;
       
   416 
       
   417 	Reset();
       
   418 	}
       
   419 
       
   420 void CDitherColor256::Reset()
       
   421 	{
       
   422 	Mem::FillZ(iErrorBuffer,iErrorBufferLength*sizeof(iErrorBuffer[0]));
       
   423 	}
       
   424 
       
   425 void CDitherColor256::ConvertLine(TUint8* aDestination,TRgb* aSource)
       
   426 	{
       
   427 	TUint8* dstLimit = aDestination+iLineWidth;
       
   428 	TDitherColorError* errorBuffer = iErrorBuffer;
       
   429 
       
   430 	TInt r = errorBuffer->iRed;
       
   431 	TInt g = errorBuffer->iGreen;
       
   432 	TInt b = errorBuffer->iBlue;
       
   433 	errorBuffer->iRed = 0;
       
   434 	errorBuffer->iGreen = 0;
       
   435 	errorBuffer->iBlue = 0;
       
   436 
       
   437 	while(aDestination<dstLimit)
       
   438 		{
       
   439 
       
   440 		{
       
   441 		TInt value = 0;
       
   442 
       
   443 		r += aSource->Red();
       
   444 		if(r>255)
       
   445 			value = 255;
       
   446 		else if(r>0)
       
   447 			value = r;
       
   448 
       
   449 		g += aSource->Green();
       
   450 		if(g>255)
       
   451 			value |= 255<<8;
       
   452 		else if(g>0)
       
   453 			value |= g<<8;
       
   454 
       
   455 		b += aSource->Blue();
       
   456 		if(b>255)
       
   457 			value |= 255<<16;
       
   458 		else if(b>0)
       
   459 			value |= b<<16;
       
   460 
       
   461 		aSource++;
       
   462 
       
   463 		value = iColorUtil->Color256(TRgb(value));
       
   464 		*(aDestination) = (TUint8)value;
       
   465 		value = iColorUtil->Color256(value).Value();
       
   466 
       
   467 		r -= value&0xFF;
       
   468 		g -= (value>>8)&0xFF;
       
   469 		b -= (value>>16)&0xFF;
       
   470 		}
       
   471 
       
   472 		{
       
   473 		TInt x = r>>2;
       
   474 		r = (r>>1)-(r>>3);
       
   475 		errorBuffer->iRed += r;
       
   476 		r += errorBuffer[1].iRed;
       
   477 		errorBuffer[1].iRed = x;
       
   478 
       
   479 		x = g>>2;
       
   480 		g = (g>>1)-(g>>3);
       
   481 		errorBuffer->iGreen += g;
       
   482 		g += errorBuffer[1].iGreen;
       
   483 		errorBuffer[1].iGreen = x;
       
   484 
       
   485 		x = b>>2;
       
   486 		b = (b>>1)-(b>>3);
       
   487 		errorBuffer->iBlue += b;
       
   488 		b += errorBuffer[1].iBlue;
       
   489 		errorBuffer[1].iBlue = x;
       
   490 
       
   491 		errorBuffer++;
       
   492 		}
       
   493 
       
   494 		aDestination++;
       
   495 		}
       
   496 	}
       
   497 
       
   498 //
       
   499 // CFbsColor256BitmapUtil
       
   500 //
       
   501 
       
   502 inline CFbsColor256BitmapUtil::CFbsColor256BitmapUtil()
       
   503 	{ }
       
   504 
       
   505 /** Allocates and constructs a new 256 colour bitmap utility object, optionally
       
   506 specifying a palette.
       
   507 
       
   508 @param aPalette The palette of colours to use for the destination 256 colour
       
   509 bitmap. If there are more than 256 colours in the palette, only the first
       
   510 256 are used. May be NULL, in which case the system default 256 colour palette
       
   511 is used.
       
   512 @return The newly constructed object. */
       
   513 EXPORT_C CFbsColor256BitmapUtil* CFbsColor256BitmapUtil::NewL(const CPalette* aPalette)
       
   514 	{
       
   515 	CFbsColor256BitmapUtil* self = new (ELeave) CFbsColor256BitmapUtil;
       
   516 	CleanupStack::PushL(self);
       
   517 	if(aPalette)
       
   518 		{
       
   519 		self->iColor256Util = new (ELeave) TColor256Util;
       
   520 		self->iColor256Util->Construct(*aPalette);
       
   521 		}
       
   522 	// coverity[leave_without_push : FALSE]
       
   523 	// class member variables should not be pushed onto the cleanupstack 
       
   524 	self->iDither = new (ELeave) CDitherColor256;
       
   525 	CleanupStack::Pop();
       
   526 	return self;
       
   527 	}
       
   528 
       
   529 CFbsColor256BitmapUtil::~CFbsColor256BitmapUtil()
       
   530 	{
       
   531 	delete iColor256Util;
       
   532 	delete iDither;
       
   533 	}
       
   534 
       
   535 /** Copies the contents of a source bitmap to a destination 256 colour bitmap.
       
   536 Both bitmaps must be the same size and the destination bitmap's display mode
       
   537 must be EColor256.
       
   538 
       
   539 @param aColor256Destination The destination to copy the bitmap to. Its display
       
   540 mode must be EColor256.
       
   541 @param aSource The source bitmap to copy from. Its display mode can be EColor16M,
       
   542 EColor64K, EColor4K or EColor256.
       
   543 @param aDither Specify EFloydSteinberg for Floyd-Steinberg dithering. By default,
       
   544 no dithering.
       
   545 @return KErrNone, if successful; otherwise, another of the system-wide error
       
   546 codes. KErrNotSupported is returned if aSource's display mode is not one of
       
   547 the values listed.
       
   548 @panic EFbsColor256UtilError Either aColor256Destination's display mode is
       
   549 not EColor256, or the two bitmaps are not the same size. */
       
   550 EXPORT_C TInt CFbsColor256BitmapUtil::CopyBitmap(CFbsBitmap* aColor256Destination,CFbsBitmap* aSource,TDither aDither)
       
   551 	{
       
   552 	aSource->BeginDataAccess();
       
   553 	aColor256Destination->BeginDataAccess();
       
   554 	const TDisplayMode sourceMode = aSource->DisplayMode();
       
   555 
       
   556 	TSize size(aSource->SizeInPixels());
       
   557 	TInt width = size.iWidth;
       
   558 	TInt height = size.iHeight;
       
   559 
       
   560 	// Check we are being askes to copy a bitmap to a color256 bitmap of the same size
       
   561 	if( aColor256Destination->DisplayMode()!=EColor256 || aColor256Destination->SizeInPixels()!=size )
       
   562 		Panic(EFbsColor256UtilError);
       
   563 
       
   564 	if( sourceMode!=EColor256 && sourceMode!=EColor4K && sourceMode!=EColor64K &&
       
   565 		sourceMode!=EColor16M && sourceMode!=EColor16MU && sourceMode!=EColor16MA && sourceMode!=EColor16MAP)
       
   566 		{
       
   567 		aSource->EndDataAccess(ETrue);
       
   568 		aColor256Destination->EndDataAccess(ETrue);
       
   569 		return KErrNotSupported;
       
   570 		}
       
   571 
       
   572 	// get a TColor256Utils to use
       
   573 	const TColor256Util* colorUtil = iColor256Util;
       
   574 	if(!colorUtil)
       
   575 		colorUtil = TColor256Util::Default();
       
   576 
       
   577 	if(aDither==EFloydSteinberg)
       
   578 		{
       
   579 		TRAPD(err,iDither->ConstructL(width,colorUtil));
       
   580 		if(err!=KErrNone)
       
   581 			{
       
   582 			aSource->EndDataAccess(ETrue);
       
   583 			aColor256Destination->EndDataAccess(ETrue);
       
   584 			return err;
       
   585 			}
       
   586 		}
       
   587 
       
   588 	TRgb* pixelBuffer = new TRgb[width];
       
   589 	if(!pixelBuffer)
       
   590 		{
       
   591 		aSource->EndDataAccess(ETrue);
       
   592 		aColor256Destination->EndDataAccess(ETrue);
       
   593 		return KErrNoMemory;
       
   594 		}
       
   595 
       
   596 	TUint8* src = (TUint8*)aSource->DataAddress();
       
   597 	TInt srcPitch = aSource->ScanLineLength(width,sourceMode);
       
   598 	TUint8* dst = (TUint8*)aColor256Destination->DataAddress();
       
   599 	TInt dstPitch = aColor256Destination->ScanLineLength(width,EColor256);
       
   600 
       
   601 	while(height--)
       
   602 		{
       
   603 		TInt i(0);
       
   604 		switch(sourceMode)
       
   605 			{
       
   606 			case EColor256:
       
   607 				for(i=0; i<width; i++)
       
   608 					pixelBuffer[i] = TRgb::Color256(((TUint8*)src)[i]);
       
   609 				break;
       
   610 			case EColor4K:
       
   611 				for(i=0; i<width; i++)
       
   612 					pixelBuffer[i] = TRgb::_Color4K(((TUint16*)src)[i]);
       
   613 				break;
       
   614 			case EColor64K:
       
   615 				for(i=0; i<width; i++)
       
   616 					pixelBuffer[i] = TRgb::_Color64K(((TUint16*)src)[i]);
       
   617 				break;
       
   618 			case EColor16M:
       
   619 				{
       
   620 				TUint8* data = src;
       
   621 				TUint8* dataLimit = data+width*3;
       
   622 				i = 0;
       
   623 				while(data<dataLimit)
       
   624 					{
       
   625 					TUint32 value = *(data++)<<16;
       
   626 					value += *(data++)<<8;
       
   627 					value += *(data++);
       
   628 					pixelBuffer[i++] = TRgb(value);
       
   629 					}
       
   630 				}
       
   631 				break;
       
   632 			case EColor16MU:
       
   633 				{
       
   634 				TInt32* data = reinterpret_cast<TInt32*> (src);
       
   635 				TInt32* dataLimit = data+width;
       
   636 				i = 0;
       
   637 				while(data<dataLimit)
       
   638 					{
       
   639 					pixelBuffer[i++] = TRgb::_Color16MU(*data++);
       
   640 					}
       
   641 				}
       
   642 				break;
       
   643 			case EColor16MA:
       
   644 				{
       
   645 				TInt32* data = reinterpret_cast<TInt32*> (src);
       
   646 				TInt32* dataLimit = data+width;
       
   647 				i = 0;
       
   648 				while(data<dataLimit)
       
   649 					{
       
   650 					pixelBuffer[i++] = TRgb::_Color16MA(*data++);
       
   651 					}
       
   652 				}
       
   653 				break;
       
   654 			case EColor16MAP:
       
   655 				{
       
   656 				// perform division of color channels by alpha.
       
   657 				TInt32* data = reinterpret_cast<TInt32*> (src);
       
   658 				TInt32* dataLimit = data+width;
       
   659 				while(data<dataLimit)
       
   660 					{
       
   661 					pixelBuffer[i++] = TRgb::_Color16MAP(*data++);
       
   662 					}
       
   663 				}
       
   664 				break;
       
   665 			default:
       
   666 				break;
       
   667 			}
       
   668 		if(aDither==EFloydSteinberg)
       
   669 			iDither->ConvertLine(dst,pixelBuffer);
       
   670 		else
       
   671 			colorUtil->Color256(dst,pixelBuffer,width);
       
   672 		dst += dstPitch;
       
   673 		src += srcPitch;
       
   674 		}
       
   675 
       
   676 	aSource->EndDataAccess(ETrue);
       
   677 	aColor256Destination->EndDataAccess(EFalse);
       
   678 
       
   679 	delete[] pixelBuffer;
       
   680 	return KErrNone;
       
   681 	}
       
   682 
       
   683 /**
       
   684 
       
   685 Required to ensure BC between NGage and 7.0S platforms.
       
   686 Function is exported at ordinal corresponding to where NGage platform
       
   687 has extended this library and must not be moved. */
       
   688 EXPORT_C void DummyReserved1()
       
   689 	{
       
   690 	User::Panic(_L("Dummy Function"), 0);
       
   691 	}
       
   692 
       
   693