fbs/fontandbitmapserver/sfbs/BMPUTIL.CPP
changeset 0 5d03bc08d59c
child 11 fed1595b188e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fbs/fontandbitmapserver/sfbs/BMPUTIL.CPP	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,693 @@
+// Copyright (c) 1995-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 <fbs.h>
+#include <graphics/lookuptable.h>
+#include "fbsdefs.h"
+#include "UTILS.H"
+
+GLREF_C void Panic(TFbsPanic aPanic);
+
+/* Macros used in support of EColor16M mode bitmaps in TBitmapUtil.
+PTR2UINT, UINT2PTR defined to ease byte pointer arithmatic using
+the existing iWordPos word sized pointer.
+i MACROS redefine the meaning of members in the class for 16M use.
+All in the name of Binary Compatibility - adding 16M support but
+without wasting memory or increasing the size of this class's objects. */
+#define PTR2UINT(_ptr)      reinterpret_cast<TUint32>(_ptr)
+#define UINT2PTR(_expr)     reinterpret_cast<TUint32*>(_expr)
+#define iNUM_WASTE_BYTES    iMask
+#define iSTART_OF_SCAN_LINE iWordPos
+#define iPIXEL_BYTE_OFFSET  iPixelShift
+#define iPIXEL_ADDRESS      UINT2PTR(PTR2UINT(iWordPos)+iPixelShift)
+
+
+/** Constructs a TBitmapUtil object for the specified bitmap.
+
+@param aBitmap The bitmap on which this TBitmapUtil will operate. */
+EXPORT_C TBitmapUtil::TBitmapUtil(CFbsBitmap* aBitmap):
+    iFbsBitmap(aBitmap),	// Address of bitmap to navigate and modify.
+	iWordPos(NULL),			// Non16M: Address of the word containing the bits
+							//         of the current pixel.
+							// 16M: Redefined to iSTART_OF_SCAN_LINE - word address
+							//      of the scan line containing the current pixel.
+	iMinWordPos(NULL),		// Member holds the word address of the top left pixel.
+	iMaxWordPos(NULL),		// Member holds address of the word following the last
+							// word in the last scan line of the bitmap.
+	iBpp(0),				// Number of bits needed for each pixel's data.
+	iPixelShift(0),			// Non16M: Right shift factor to convert pixel index
+	                        //         to word index into scan line.
+							// 16M: Redefined to iPIXEL_BYTE_OFFSET - index to first
+							//      byte in pixel from the start of the scan line.
+	iBitShift(0),			// Non16M: Changing index of right shift require to
+	                        //         move pixel bits into LSB of word.
+							// 16M: Not used, always 0
+	iMask(0),               // Non16M: Mask of LSB required to hold
+	                        //         pixel data eg. 16cols 0x0f
+							// 16M: Redefined to iNUM_WASTE_BYTES - number of
+							//      padding bytes at end of scan line 0,3,6,9 as 16M
+							//      scanlines are always multiples of 12 bytes.
+	iScanlineWordLength(0), // Number of 4-byte words in bitmap scan line
+	iWritten(EFalse)
+	{}
+
+/** Sets the current pixel position to the specified position and prepares
+the bitmap for access to its pixel data.
+
+This function must be called before using any of the other functions provided
+by this class, otherwise damage to data may occur. It must also be matched
+by a subsequent call to End().
+
+@pre The bitmap which was passed on class construction has been created and holds 
+	a valid handle.
+@param aPosition The position to which the current pixel position should be
+set. */
+EXPORT_C void TBitmapUtil::Begin(const TPoint& aPosition)
+	{
+	ASSERT(iFbsBitmap);
+	iFbsBitmap->BeginDataAccess();
+	TSize bmpsize(iFbsBitmap->SizeInPixels());
+	ASSERT(bmpsize.iWidth > 0 && bmpsize.iHeight > 0);
+
+	iWritten = EFalse;
+
+	TDisplayMode dm=iFbsBitmap->DisplayMode();
+	TInt numBytesInScanline = CFbsBitmap::ScanLineLength(bmpsize.iWidth,dm);
+	switch(dm)
+		{
+	case EGray2:
+		iMask=1;
+		iPixelShift=5;
+		iBpp=1;
+		break;
+	case EGray4:
+		iMask=3;
+		iPixelShift=4;
+		iBpp=2;
+		break;
+	case EGray16:
+	case EColor16:
+		iMask=0xf;
+		iPixelShift=3;
+		iBpp=4;
+		break;
+	case EGray256:
+	case EColor256:
+		iMask=0xff;
+		iPixelShift=2;
+		iBpp=8;
+		break;
+	case EColor4K:
+	case EColor64K:
+		iMask=0xffff;
+		iPixelShift=1;
+		iBpp=16;
+		break;
+	/* Bit twiddling not used in the EColor16M, members redefined for
+     different use.	 */
+	case EColor16M:
+		iNUM_WASTE_BYTES = numBytesInScanline-(bmpsize.iWidth*3);
+		iPIXEL_BYTE_OFFSET=0;
+		iBpp=24; // Indicates 16M display mode, flag for member functions
+		         // to switch functionality.
+		break;
+	case EColor16MU:
+	case EColor16MA:
+	case EColor16MAP:
+		iMask=0xffffffff;
+		iPixelShift=0;
+		iBpp=32;
+		break;
+	default: //shouldn't reach this point
+		Panic(EFbsBitmapInvalidMode);
+		}
+
+	iMinWordPos=(TUint32*)iFbsBitmap->DataAddress();
+	iScanlineWordLength = numBytesInScanline / 4;
+	iMaxWordPos = iMinWordPos + (bmpsize.iHeight * iScanlineWordLength);
+
+	TPoint correct(aPosition);
+	if(correct.iX<0) correct.iX=0;
+	if(correct.iY<0) correct.iY=0;
+	if(correct.iX>=bmpsize.iWidth) correct.iX=bmpsize.iWidth;
+	if(correct.iY>=bmpsize.iHeight) correct.iY=bmpsize.iHeight;
+	SetPos(correct);
+	}
+
+/** Sets the current pixel position to the specified position and prepares
+the bitmap for access to its pixel data.
+
+This function is deprecated. Use the other overload, Begin(const TPoint&).
+@deprecated
+
+@param aPosition The position to which the current pixel position should be
+set.
+@param aUtil Not used.
+@panic FBCLI 10 The bitmap's display mode is ERgb or ENone. */
+EXPORT_C void TBitmapUtil::Begin(const TPoint& aPosition, const TBitmapUtil& /*aUtil*/)
+	{
+	Begin(aPosition);
+	}
+
+/** Marks the end of the access to the bitmap data.
+This function must be called when finished using all the other functions
+provided by this class.
+
+There must be exactly one call to End() for each previous call to Begin()
+for a given TBitmapUtil object. */
+EXPORT_C void TBitmapUtil::End()
+	{
+	iFbsBitmap->EndDataAccess(!iWritten);
+	}
+
+
+
+/** Gets the value of the pixel at the current pixel position.
+
+In normal usage, the value returned will immediately be used as the parameter
+to a call to SetPixel(). To remove the overhead of constructing a TRgb, the
+function uses a TUint32 rather than a TRgb to hold an RGB value.
+
+@return The value of the pixel at the current pixel position. */
+EXPORT_C TUint32 TBitmapUtil::GetPixel() const
+	{
+	if (iBpp!=24)
+		// 1,2,4,8,12,16,32-bit pixels
+		return((*iWordPos>>iBitShift)&iMask);
+	else
+		{
+		// 24-bit pixels
+		// Due to machine word alignment requirement on ARM, need to copy
+		// pixel data at iWordPos a byte at a time if address is not aligned
+		// on a 4 byte boundary i.e. 1st or 2nd least sig. bits set.
+		if (iPIXEL_BYTE_OFFSET & 0x3)
+			{
+			TUint32 pixel = 0;
+			Mem::Copy(&pixel, iPIXEL_ADDRESS, 3);
+			return pixel;
+			}
+		else
+			return (*( iPIXEL_ADDRESS )&0x00ffffff);
+		}
+	}
+
+/** Sets the value of the pixel at the current pixel position.
+
+To remove the overhead of constructing a TRgb, the function uses a TUint32
+rather than a TRgb to hold an RGB value.
+
+@param aValue The value to which the pixel at the current pixel position is
+to be set. */
+EXPORT_C void TBitmapUtil::SetPixel(TUint32 aValue)
+	{
+	iWritten = ETrue;
+	if (iBpp!=24)
+		{
+		// 1,2,4,8,12,16,32-bit pixels
+		*iWordPos&=~(iMask<<iBitShift);
+		*iWordPos|=(aValue&iMask)<<iBitShift;
+		if(iBpp==32 && iFbsBitmap && iFbsBitmap->DisplayMode() == EColor16MU)
+				{
+				*iWordPos|= 0xff000000;
+				}
+		}
+	else
+		{
+		// 24-bit pixels
+		// Due to machine word alignment requirement on ARM, need to copy
+		// pixel data at iWordPos a byte at a time if address is not aligned
+		// on a 4 byte boundary i.e. 1st or 2nd least sig. bits set.
+		if (iPIXEL_BYTE_OFFSET & 0x3)
+			Mem::Copy(iPIXEL_ADDRESS, &aValue, 3);
+		else
+			{
+			*(iPIXEL_ADDRESS) &= ~0xffffff;
+			*(iPIXEL_ADDRESS) |= (aValue&0x00ffffff);
+			}
+		}
+	}
+
+/** Sets the value of the pixel at the current pixel position to that returned
+by aSource.GetPixel().
+
+@param aSource The TBitmapUtil of the source bitmap, whose pixel value is
+used to set the pixel at the current pixel position. */
+EXPORT_C void TBitmapUtil::SetPixel(const TBitmapUtil& aSource)
+	{
+	SetPixel(aSource.GetPixel());
+	}
+
+/** Sets a new current pixel position.
+
+@param aPosition The new current pixel position. */
+EXPORT_C void TBitmapUtil::SetPos(const TPoint& aPosition)
+	{
+	TSize bmpsize(iFbsBitmap->SizeInPixels());
+	TPoint correct(aPosition);
+
+	correct.iX%=bmpsize.iWidth;
+	correct.iY%=bmpsize.iHeight;
+	if(correct.iX<0) correct.iX+=bmpsize.iWidth;
+	if(correct.iY<0) correct.iY+=bmpsize.iHeight;
+
+	iWordPos=iMinWordPos;
+	iWordPos+=iScanlineWordLength*correct.iY;
+	if (iBpp!=24)
+		{
+		// 1,2,4,8,12,16,32-bit pixels
+		iWordPos+=correct.iX>>iPixelShift;
+		iBitShift=(correct.iX*iBpp)%32;
+		}
+	else
+		{
+		// 24-bit pixels
+		// iSTART_OF_SCAN_LINE (iWordPos) has correct value at this point
+		// iBitShift not used in 16M modes
+		iPIXEL_BYTE_OFFSET = correct.iX*3;	// Byte offset in iY scan line to iX pixel
+		}
+}
+
+/** Decrements the x co-ordinate of the current pixel position. */
+EXPORT_C void TBitmapUtil::DecXPos()
+	{
+	if (iBpp!=24)
+		{
+		// 1,2,4,8,12,16,32-bit pixels
+		iBitShift-=iBpp;
+		if(iBitShift<0)
+			{
+			iBitShift+=32;
+			iWordPos--;
+			if(iWordPos<iMinWordPos) iWordPos=iMaxWordPos-1;
+			}
+		}
+	else
+		{
+		// 24-bit pixels
+		iPIXEL_BYTE_OFFSET -= 3;
+
+		// Scanline underflow?
+		if (iPIXEL_BYTE_OFFSET < 0)
+			{
+			iPIXEL_BYTE_OFFSET = (iScanlineWordLength*4)-iNUM_WASTE_BYTES-3;
+
+			// Bitmap underflow?
+		    if (iSTART_OF_SCAN_LINE == iMinWordPos)
+				iSTART_OF_SCAN_LINE = iMaxWordPos-iScanlineWordLength;
+			else
+		        iSTART_OF_SCAN_LINE -= iScanlineWordLength;
+			}
+		}
+	}
+
+/** Decrements the y co-ordinate of the current pixel position. */
+EXPORT_C void TBitmapUtil::DecYPos()
+	{
+	iWordPos-=iScanlineWordLength;
+	if(iWordPos<iMinWordPos) iWordPos+=iMaxWordPos-iMinWordPos;
+	}
+
+/** Increments the x co-ordinate of the current pixel position. */
+EXPORT_C void TBitmapUtil::IncXPos()
+	{
+	if (iBpp!=24)
+		{
+		// 1,2,4,8,12,16,32-bit pixels
+		iBitShift+=iBpp;
+		if(iBitShift>=32)
+			{
+			iBitShift=0;
+			iWordPos++;
+			if(iWordPos>=iMaxWordPos) iWordPos=iMinWordPos;
+			}
+		}
+	else
+		{
+		// 24-bit pixels
+		iPIXEL_BYTE_OFFSET += 3;
+
+		// Scanline overflow?
+		if (iPIXEL_BYTE_OFFSET >=
+				(iScanlineWordLength*4)-static_cast<TInt>(iNUM_WASTE_BYTES))
+			{
+			iPIXEL_BYTE_OFFSET = 0;
+			iSTART_OF_SCAN_LINE += iScanlineWordLength;
+
+			// Bitmap overflow?
+			if (iSTART_OF_SCAN_LINE >= iMaxWordPos)
+				iSTART_OF_SCAN_LINE = iMinWordPos;
+			}
+		}
+	}
+
+/** Increments the y co-ordinate of the current pixel position. */
+EXPORT_C void TBitmapUtil::IncYPos()
+	{
+	iWordPos+=iScanlineWordLength;
+	if(iWordPos>=iMaxWordPos) iWordPos-=iMaxWordPos-iMinWordPos;
+	}
+
+
+
+//
+// CDitherColor256
+//
+
+class TDitherColorError
+	{
+public:
+	inline TDitherColorError() {};
+	inline TDitherColorError(TInt aRed,TInt aGreen,TInt aBlue) : iRed(aRed), iGreen(aGreen), iBlue(aBlue) {}
+public:
+	TInt iRed;
+	TInt iGreen;
+	TInt iBlue;
+	};
+
+NONSHARABLE_CLASS(CDitherColor256) : public CBase
+	{
+public:
+	void ConstructL(TInt aLineWidth,const TColor256Util* aColorUtil = NULL);
+	void Reset();
+	void ConvertLine(TUint8* aDestination,TRgb* aSource);
+	~CDitherColor256();
+private:
+	const TColor256Util* iColorUtil;
+	TInt iLineWidth;
+	TDitherColorError* iErrorBuffer;
+	TInt iErrorBufferLength;
+	};
+
+CDitherColor256::~CDitherColor256()
+	{
+	delete[] iErrorBuffer;
+	}
+
+void CDitherColor256::ConstructL(TInt aLineWidth,const TColor256Util* aColorUtil)
+	{
+	if(iErrorBufferLength<=aLineWidth)
+		{
+		delete[] iErrorBuffer;
+		iErrorBuffer = NULL;
+		}
+
+	if(!iErrorBuffer)
+		{
+		iErrorBuffer = new (ELeave) TDitherColorError[aLineWidth+1];
+		iErrorBufferLength = aLineWidth+1;
+		}
+
+	iLineWidth = aLineWidth;
+	if(!aColorUtil)
+		aColorUtil = TColor256Util::Default();
+	iColorUtil = aColorUtil;
+
+	Reset();
+	}
+
+void CDitherColor256::Reset()
+	{
+	Mem::FillZ(iErrorBuffer,iErrorBufferLength*sizeof(iErrorBuffer[0]));
+	}
+
+void CDitherColor256::ConvertLine(TUint8* aDestination,TRgb* aSource)
+	{
+	TUint8* dstLimit = aDestination+iLineWidth;
+	TDitherColorError* errorBuffer = iErrorBuffer;
+
+	TInt r = errorBuffer->iRed;
+	TInt g = errorBuffer->iGreen;
+	TInt b = errorBuffer->iBlue;
+	errorBuffer->iRed = 0;
+	errorBuffer->iGreen = 0;
+	errorBuffer->iBlue = 0;
+
+	while(aDestination<dstLimit)
+		{
+
+		{
+		TInt value = 0;
+
+		r += aSource->Red();
+		if(r>255)
+			value = 255;
+		else if(r>0)
+			value = r;
+
+		g += aSource->Green();
+		if(g>255)
+			value |= 255<<8;
+		else if(g>0)
+			value |= g<<8;
+
+		b += aSource->Blue();
+		if(b>255)
+			value |= 255<<16;
+		else if(b>0)
+			value |= b<<16;
+
+		aSource++;
+
+		value = iColorUtil->Color256(TRgb(value));
+		*(aDestination) = (TUint8)value;
+		value = iColorUtil->Color256(value).Value();
+
+		r -= value&0xFF;
+		g -= (value>>8)&0xFF;
+		b -= (value>>16)&0xFF;
+		}
+
+		{
+		TInt x = r>>2;
+		r = (r>>1)-(r>>3);
+		errorBuffer->iRed += r;
+		r += errorBuffer[1].iRed;
+		errorBuffer[1].iRed = x;
+
+		x = g>>2;
+		g = (g>>1)-(g>>3);
+		errorBuffer->iGreen += g;
+		g += errorBuffer[1].iGreen;
+		errorBuffer[1].iGreen = x;
+
+		x = b>>2;
+		b = (b>>1)-(b>>3);
+		errorBuffer->iBlue += b;
+		b += errorBuffer[1].iBlue;
+		errorBuffer[1].iBlue = x;
+
+		errorBuffer++;
+		}
+
+		aDestination++;
+		}
+	}
+
+//
+// CFbsColor256BitmapUtil
+//
+
+inline CFbsColor256BitmapUtil::CFbsColor256BitmapUtil()
+	{ }
+
+/** Allocates and constructs a new 256 colour bitmap utility object, optionally
+specifying a palette.
+
+@param aPalette The palette of colours to use for the destination 256 colour
+bitmap. If there are more than 256 colours in the palette, only the first
+256 are used. May be NULL, in which case the system default 256 colour palette
+is used.
+@return The newly constructed object. */
+EXPORT_C CFbsColor256BitmapUtil* CFbsColor256BitmapUtil::NewL(const CPalette* aPalette)
+	{
+	CFbsColor256BitmapUtil* self = new (ELeave) CFbsColor256BitmapUtil;
+	CleanupStack::PushL(self);
+	if(aPalette)
+		{
+		self->iColor256Util = new (ELeave) TColor256Util;
+		self->iColor256Util->Construct(*aPalette);
+		}
+	// coverity[leave_without_push : FALSE]
+	// class member variables should not be pushed onto the cleanupstack 
+	self->iDither = new (ELeave) CDitherColor256;
+	CleanupStack::Pop();
+	return self;
+	}
+
+CFbsColor256BitmapUtil::~CFbsColor256BitmapUtil()
+	{
+	delete iColor256Util;
+	delete iDither;
+	}
+
+/** Copies the contents of a source bitmap to a destination 256 colour bitmap.
+Both bitmaps must be the same size and the destination bitmap's display mode
+must be EColor256.
+
+@param aColor256Destination The destination to copy the bitmap to. Its display
+mode must be EColor256.
+@param aSource The source bitmap to copy from. Its display mode can be EColor16M,
+EColor64K, EColor4K or EColor256.
+@param aDither Specify EFloydSteinberg for Floyd-Steinberg dithering. By default,
+no dithering.
+@return KErrNone, if successful; otherwise, another of the system-wide error
+codes. KErrNotSupported is returned if aSource's display mode is not one of
+the values listed.
+@panic EFbsColor256UtilError Either aColor256Destination's display mode is
+not EColor256, or the two bitmaps are not the same size. */
+EXPORT_C TInt CFbsColor256BitmapUtil::CopyBitmap(CFbsBitmap* aColor256Destination,CFbsBitmap* aSource,TDither aDither)
+	{
+	aSource->BeginDataAccess();
+	aColor256Destination->BeginDataAccess();
+	const TDisplayMode sourceMode = aSource->DisplayMode();
+
+	TSize size(aSource->SizeInPixels());
+	TInt width = size.iWidth;
+	TInt height = size.iHeight;
+
+	// Check we are being askes to copy a bitmap to a color256 bitmap of the same size
+	if( aColor256Destination->DisplayMode()!=EColor256 || aColor256Destination->SizeInPixels()!=size )
+		Panic(EFbsColor256UtilError);
+
+	if( sourceMode!=EColor256 && sourceMode!=EColor4K && sourceMode!=EColor64K &&
+		sourceMode!=EColor16M && sourceMode!=EColor16MU && sourceMode!=EColor16MA && sourceMode!=EColor16MAP)
+		{
+		aSource->EndDataAccess(ETrue);
+		aColor256Destination->EndDataAccess(ETrue);
+		return KErrNotSupported;
+		}
+
+	// get a TColor256Utils to use
+	const TColor256Util* colorUtil = iColor256Util;
+	if(!colorUtil)
+		colorUtil = TColor256Util::Default();
+
+	if(aDither==EFloydSteinberg)
+		{
+		TRAPD(err,iDither->ConstructL(width,colorUtil));
+		if(err!=KErrNone)
+			{
+			aSource->EndDataAccess(ETrue);
+			aColor256Destination->EndDataAccess(ETrue);
+			return err;
+			}
+		}
+
+	TRgb* pixelBuffer = new TRgb[width];
+	if(!pixelBuffer)
+		{
+		aSource->EndDataAccess(ETrue);
+		aColor256Destination->EndDataAccess(ETrue);
+		return KErrNoMemory;
+		}
+
+	TUint8* src = (TUint8*)aSource->DataAddress();
+	TInt srcPitch = aSource->ScanLineLength(width,sourceMode);
+	TUint8* dst = (TUint8*)aColor256Destination->DataAddress();
+	TInt dstPitch = aColor256Destination->ScanLineLength(width,EColor256);
+
+	while(height--)
+		{
+		TInt i(0);
+		switch(sourceMode)
+			{
+			case EColor256:
+				for(i=0; i<width; i++)
+					pixelBuffer[i] = TRgb::Color256(((TUint8*)src)[i]);
+				break;
+			case EColor4K:
+				for(i=0; i<width; i++)
+					pixelBuffer[i] = TRgb::_Color4K(((TUint16*)src)[i]);
+				break;
+			case EColor64K:
+				for(i=0; i<width; i++)
+					pixelBuffer[i] = TRgb::_Color64K(((TUint16*)src)[i]);
+				break;
+			case EColor16M:
+				{
+				TUint8* data = src;
+				TUint8* dataLimit = data+width*3;
+				i = 0;
+				while(data<dataLimit)
+					{
+					TUint32 value = *(data++)<<16;
+					value += *(data++)<<8;
+					value += *(data++);
+					pixelBuffer[i++] = TRgb(value);
+					}
+				}
+				break;
+			case EColor16MU:
+				{
+				TInt32* data = reinterpret_cast<TInt32*> (src);
+				TInt32* dataLimit = data+width;
+				i = 0;
+				while(data<dataLimit)
+					{
+					pixelBuffer[i++] = TRgb::_Color16MU(*data++);
+					}
+				}
+				break;
+			case EColor16MA:
+				{
+				TInt32* data = reinterpret_cast<TInt32*> (src);
+				TInt32* dataLimit = data+width;
+				i = 0;
+				while(data<dataLimit)
+					{
+					pixelBuffer[i++] = TRgb::_Color16MA(*data++);
+					}
+				}
+				break;
+			case EColor16MAP:
+				{
+				// perform division of color channels by alpha.
+				TInt32* data = reinterpret_cast<TInt32*> (src);
+				TInt32* dataLimit = data+width;
+				while(data<dataLimit)
+					{
+					pixelBuffer[i++] = TRgb::_Color16MAP(*data++);
+					}
+				}
+				break;
+			default:
+				break;
+			}
+		if(aDither==EFloydSteinberg)
+			iDither->ConvertLine(dst,pixelBuffer);
+		else
+			colorUtil->Color256(dst,pixelBuffer,width);
+		dst += dstPitch;
+		src += srcPitch;
+		}
+
+	aSource->EndDataAccess(ETrue);
+	aColor256Destination->EndDataAccess(EFalse);
+
+	delete[] pixelBuffer;
+	return KErrNone;
+	}
+
+/**
+
+Required to ensure BC between NGage and 7.0S platforms.
+Function is exported at ordinal corresponding to where NGage platform
+has extended this library and must not be moved. */
+EXPORT_C void DummyReserved1()
+	{
+	User::Panic(_L("Dummy Function"), 0);
+	}
+
+