guestrendering/guestopenvg/src/vgimage.cpp
branchbug235_bringup_0
changeset 24 a3f46bb01be2
parent 14 acbd4400e82b
--- a/guestrendering/guestopenvg/src/vgimage.cpp	Thu Sep 16 12:43:44 2010 +0100
+++ b/guestrendering/guestopenvg/src/vgimage.cpp	Mon Sep 20 14:29:05 2010 +0100
@@ -1,773 +1,773 @@
-// Copyright (c) 2010 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:
-// Client-side state information for Open VG handle based objects
-
-#include "vgstate.h"
-#include "remotefunctioncall.h"
-#include "openvgrfc.h"
-
-
-const TInt KColorMatrixSize = 20;
-const TInt KLUTLength = 256;
-
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-// CVgImageInfo
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-CVgImageInfo::CVgImageInfo(VGImageFormat aFormat, VGint aWidth, VGint aHeight, CVgImageInfo* aParent, VGbitfield aAllowedQuality,
-			EGLImageKHR aEglImage, TUint64 aSgImageId) :
-		CVgImageBase(EVgHandleForImage, aWidth, aHeight), iFormat(aFormat), iParent(aParent),
-		iAllowedQuality(aAllowedQuality), iIsEglSibling( aSgImageId ? ETrue : EFalse),
-		iEglImage(aEglImage), iSgImageId(aSgImageId),
-		iChildCount(0)
-	{
-	if (aParent)
-		{
-		aParent->IncChildCount();
-		}
-	}
-
-
-// eglChildImage
-CVgImageInfo* CVgImageInfo::New(VGint aWidth, VGint aHeight, CVgImageInfo* aParent)
-	{
-	VGPANIC_ASSERT_DEBUG(aParent, EVgPanicImageParentIsInvalid);
-	RHeap* clientHeap = CVghwUtils::SwitchToVghwHeap();
-	CVgImageInfo* self = new CVgImageInfo(aParent->iFormat, aWidth, aHeight, aParent, aParent->AllowedQuality(),
-			aParent->EglImage(), aParent->SgImageId());
-	CVghwUtils::SwitchFromVghwHeap(clientHeap);
-	return self;
-	}
-
-
-// vgCreateEGLImageTargetKHR
-CVgImageInfo* CVgImageInfo::New(VGImageFormat aFormat, VGint aWidth, VGint aHeight, EGLImageKHR aEglImage, TUint64& aSgImageId)
-	{
-	RHeap* clientHeap = CVghwUtils::SwitchToVghwHeap();
-	CVgImageInfo* self = new CVgImageInfo(aFormat, aWidth, aHeight, VG_INVALID_HANDLE, 0, aEglImage, aSgImageId);
-	CVghwUtils::SwitchFromVghwHeap(clientHeap);
-	return self;
-	}
-
-
-// eglCreateImage
-CVgImageInfo* CVgImageInfo::New(VGImageFormat aFormat, VGint aWidth, VGint aHeight, VGbitfield aAllowedQuality)
-	{
-	RHeap* clientHeap = CVghwUtils::SwitchToVghwHeap();
-	CVgImageInfo* self = new CVgImageInfo(aFormat, aWidth, aHeight, VG_INVALID_HANDLE, aAllowedQuality, NULL, 0l);
-	CVghwUtils::SwitchFromVghwHeap(clientHeap);
-	return self;
-	}
-
-
-CVgImageInfo::~CVgImageInfo()
-	{
-	VGPANIC_ASSERT(iChildCount == 0, EVgPanicDeleteInUseVgImageInfo);
-	if (iParent)
-		{
-		iParent->DecChildCount();
-		}
-	}
-
-
-CVgImageInfo* CVgImageInfo::Parent() const
-	{
-	return iParent;
-	}
-
-
-TInt CVgImageInfo::ChildCount() const
-	{
-	return iChildCount;
-	}
-
-
-void CVgImageInfo::IncChildCount()
-	{
-	VGPANIC_ASSERT(!iIsDestroyed, EVgPanicParentImageAlreadyDestroyed);
-	User::LockedInc(iChildCount);
-	}
-
-
-void CVgImageInfo::DecChildCount()
-	{
-	User::LockedDec(iChildCount);
-	if ((iChildCount == 0) && iIsDestroyed)
-		{
-		if (iParent == NULL)
-			{
-			if (IsEglSibling())
-				{ // close the root EglImage
-				OpenVgState.EglImageClose(iEglImage);
-				}
-			}
-		else
-			{
-			iParent->DecChildCount();
-			}
-		// delete this image & remove it from HandleMap
-		RHeap* clientHeap = CVghwUtils::SwitchToVghwHeap();
-		OpenVgState.UnMapHandle(iClientHandle);
-		delete this;
-		CVghwUtils::SwitchFromVghwHeap(clientHeap);
-		}
-	}
-
-
-VGbitfield CVgImageInfo::AllowedQuality() const
-	{
-	return iAllowedQuality;
-	}
-
-
-TBool CVgImageInfo::IsEglSibling() const
-	{
-	return iIsEglSibling;
-	}
-
-
-EGLImageKHR CVgImageInfo::EglImage() const
-	{
-	return iEglImage;
-	}
-
-
-TUint64 CVgImageInfo::SgImageId() const
-	{
-	return iSgImageId;
-	}
-
-
-TBool CVgImageInfo::DestroyObject(MVgContext& aVgContext)
-	{
-	VGPANIC_ASSERT_DEBUG(iIsDestroyed, EVgPanicTemp);
-	OPENVG_TRACE("  CVgImageInfo::DestroyObject HostHandle=0x%x; ChildCount=%d, Parent=0x%x, IsEglSibling=%d, EglImage=0x%x",
-			iHostHandle, ChildCount(), Parent(), IsEglSibling(), EglImage());
-
-	if (iHostHandle)
-		{
-		// Destroy image, but not for eglImages/SgImages
-		if (!IsEglSibling())
-			{
-			RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
-			vgApiData.Init(OpenVgRFC::EvgDestroyImage, RemoteFunctionCallData::EOpRequest);
-			vgApiData.AppendParam(iHostHandle);
-			aVgContext.ExecuteVgCommand(vgApiData);
-			}
-		iHostHandle = VG_INVALID_HANDLE;
-		}
-
-	if (iChildCount == 0)
-		{
-		if (iParent == NULL)
-			{
-			if (IsEglSibling())
-				{ // close the root EglImage
-				OpenVgState.EglImageClose(iEglImage);
-				}
-			}
-		else
-			{
-			iParent->DecChildCount();
-			}
-		return ETrue;
-		}
-	// don't delete this image until all children have been destroyed
-	return EFalse;
-	}
-
-
-TInt CVgImageInfo::BitsPerPixelForVgImageFormat(VGImageFormat aFormat)
-	{
-	TInt result = -1;
-	if ((aFormat == VG_BW_1) || (aFormat == VG_A_1))
-		{
-		result = 1;
-		}
-	else if (aFormat == VG_A_4)
-		{
-		result = 4;
-		}
-	else if ((aFormat == VG_sL_8) || (aFormat == VG_lL_8) || (aFormat == VG_A_8))
-		{
-		result = 8;
-		}
-	else if ((aFormat >= 0) && (aFormat < 256))
-		{ // low bits of format number repeat in a pattern for 16/32 bit per pel
-		TInt format = aFormat & 0x3f;
-		if ((format >= VG_sRGB_565) && (format <= VG_sRGBA_4444))
-			{
-			result = 16;
-			}
-		else if (format <= VG_lRGBA_8888_PRE)
-			{
-			result = 32;
-			}
-		}
-	return result;
-	}
-
-
-void CVgImageInfo::PixmapBlit(TUint8* aDest, const TUint8* aSource, TInt aDestStride, TInt aSourceStride, TInt aRowCount,
-		size_t aRowLength, TInt aLastBits)
-	{
-	VGPANIC_ASSERT_DEBUG(aDest, EVgPanicNullPointer);
-	VGPANIC_ASSERT_DEBUG(aSource, EVgPanicNullPointer);
-	VGPANIC_ASSERT_DEBUG(aDestStride >= aRowLength, EVgPanicStrideSmallerThanRowLength);
-	VGPANIC_ASSERT_DEBUG(aSourceStride >= aRowLength, EVgPanicStrideSmallerThanRowLength);
-	VGPANIC_ASSERT_DEBUG(aRowCount > 0, EVgPanicBadRowCountParam);
-	VGPANIC_ASSERT_DEBUG(aRowLength > 0, EVgPanicBadRowLengthParam);
-	VGPANIC_ASSERT_DEBUG( (aLastBits >= 0) && (aLastBits <= 7), EVgPanicBadLastBitsParam);
-
-	if (aLastBits)
-		{ // bits per pixel < 8, only copy lowest <aLastBits> from source to dest
-		TUint8 destMask = 0xFF << aLastBits; // high bits
-		TUint8 srcMask = 0xFF ^ destMask; // low bits
-		aRowLength -= 1;
-		for (VGint row = 0; row < aRowCount; ++row)
-			{
-			memcpy(aDest, aSource, aRowLength);
-			TUint8 byte = (aDest[aRowLength] & destMask) | (aSource[aRowLength] & srcMask);
-			aDest[aRowLength] = byte;
-			aSource += aSourceStride;
-			aDest += aDestStride;
-			}
-		}
-	else
-		{
-		for (VGint row = 0; row < aRowCount; ++row)
-			{
-			memcpy(aDest, aSource, aRowLength);
-			aSource += aSourceStride;
-			aDest += aDestStride;
-			}
-		}
-	}
-
-
-VGint CVgImageInfo::GetParameterVectorSize(MVgContext& aVgContext, VGint aParamType)
-	{
-	switch (aParamType)
-		{
-		case VG_IMAGE_FORMAT:
-		case VG_IMAGE_WIDTH:
-		case VG_IMAGE_HEIGHT:
-			return 1;
-		}
-
-	// invalid ParamType
-	aVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR);
-	return 0;
-	}
-
-
-VGfloat CVgImageInfo::GetParameterf(MVgContext& aVgContext, VGint aParamType)
-	{
-	switch (aParamType)
-		{
-		case VG_IMAGE_FORMAT:
-			if (iFormat != VG_IMAGE_FORMAT_INVALID)
-				{
-				return (VGfloat)iFormat;
-				}
-			// for EglImage need to get format of underlying VgImage
-			return HostVgGetParameterf(aVgContext, aParamType);
-
-		case VG_IMAGE_WIDTH:
-			return (VGfloat)iWidth;
-
-		case VG_IMAGE_HEIGHT:
-			return (VGfloat)iHeight;
-		}
-
-	// invalid ParamType
-	aVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR);
-	return 0;
-	}
-
-
-VGint CVgImageInfo::GetParameteri(MVgContext& aVgContext, VGint aParamType)
-	{
-	switch (aParamType)
-		{
-		case VG_IMAGE_FORMAT:
-			if (iFormat != VG_IMAGE_FORMAT_INVALID)
-				{
-				return iFormat;
-				}
-			// for EglImage need to get format of underlying VgImage
-			iFormat = (VGImageFormat) HostVgGetParameteri(aVgContext, aParamType);
-			return iFormat;
-
-		case VG_IMAGE_WIDTH:
-			return iWidth;
-
-		case VG_IMAGE_HEIGHT:
-			return iHeight;
-		}
-
-	// invalid ParamType
-	aVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR);
-	return 0;
-	}
-
-
-void CVgImageInfo::ClearImage(MVgContext& aVgContext, VGint aX, VGint aY, VGint aWidth, VGint aHeight)
-	{
-	// **** Desirable: check aImage is not rendering target
-	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
-	vgApiData.Init(OpenVgRFC::EvgClearImage, RemoteFunctionCallData::EOpRequest);
-	vgApiData.AppendParam(iHostHandle);
-	vgApiData.AppendParam(aX);
-	vgApiData.AppendParam(aY);
-	vgApiData.AppendParam(aWidth);
-	vgApiData.AppendParam(aHeight);
-	TUint64 sgId(0L);
-	if (iIsEglSibling)
-		{
-		sgId = iSgImageId;
-		}
-	vgApiData.AppendTUint64(sgId);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-void CVgImageInfo::ImageSubData(MVgContext& aVgContext, const void * aData, VGint aDataStride, VGImageFormat aDataFormat, VGint aX, VGint aY,
-		VGint aWidth, VGint aHeight)
-	{
-	// **** Desirable: check image is not a rendering target
-
-	// Limit aWidth & aHeight to the dimensions of aImage
-	if (iWidth < aWidth)
-		{
-		aWidth = iWidth;
-		}
-	if (iHeight < aHeight)
-		{
-		aHeight = iHeight;
-		}
-	OPENVG_TRACE("CVgImageInfo::ImageSubData.1a dest Image: width=%d, height=%d; clipped width=%d, clipped height=%d",
-			iWidth, iHeight, aWidth, aHeight);
-	TInt bitsPerPixel = BitsPerPixelForVgImageFormat(aDataFormat);
-	TUint32 lineLength = ((static_cast<TUint32>(aWidth) * static_cast<TUint32>(bitsPerPixel)) + 7) / 8;
-	OPENVG_TRACE("CVgImageInfo::ImageSubData.1b bitsPerPixel=%d, lineLength=%d", bitsPerPixel, lineLength);
-
-	if (bitsPerPixel <= 0)
-		{
-		aVgContext.SetVgError(VG_UNSUPPORTED_IMAGE_FORMAT_ERROR);
-		}
-	else
-		{
-		if (lineLength  == aDataStride)
-			{ // use original parameters
-			OPENVG_TRACE("CVgImageInfo::ImageSubData.2a: lineLength == dataStride");
-			HostVgImageSubData(aVgContext, aData, aDataStride * aHeight, aDataStride,
-					aDataFormat, aX, aY, aWidth, aHeight);
-			}
-		else if (0 == aDataStride)
-			{ // Fill operation, pixmap size = lineLength
-			OPENVG_TRACE("CVgImageInfo::ImageSubData.2b: 0 == dataStride");
-			HostVgImageSubData(aVgContext, aData, lineLength, aDataStride,
-					aDataFormat, aX, aY, aWidth, aHeight);
-			}
-		else
-			{ // try to alloc a translation buffer - datastride maybe negative or simply > lineLength
-			size_t pixmapSize = lineLength * aHeight;
-			TUint8* localBuffer = (TUint8*) CVghwUtils::Alloc(pixmapSize);
-			OPENVG_TRACE("CVgImageInfo::ImageSubData.2c: dataStride not 0 or lineLength, localBuffer=0x%x", localBuffer);
-			if (localBuffer != NULL)
-				{ // reformat data into temporary buffer
-				PixmapBlit(localBuffer, static_cast<const TUint8*>(aData), lineLength, aDataStride, aHeight, lineLength);
-				HostVgImageSubData(aVgContext, localBuffer, pixmapSize, lineLength, aDataFormat, aX, aY, aWidth, aHeight);
-				CVghwUtils::Free(localBuffer);
-				}
-			else
-				{ // alloc failed, so do VG operation row by row
-				const TUint8* source = static_cast<const TUint8*>(aData);
-				for (VGint row = 0; row < aHeight; ++row)
-					{
-					HostVgImageSubData(aVgContext, source, lineLength, lineLength, aDataFormat, aX + row, aY, aWidth, 1);
-					source += aDataStride;
-					}
-				}
-			}
-		}
-	}
-
-
-void CVgImageInfo::HostVgImageSubData(MVgContext& aVgContext, const void* aPixmap, size_t aPixmapSize, VGint aHostDataStride,
-		VGImageFormat aDataFormat, VGint aX, VGint aY, VGint aWidth, VGint aHeight)
-	{
-	VGPANIC_ASSERT(aPixmap != NULL, EVgPanicNullPixmapPointer);
-	VGPANIC_ASSERT(aPixmapSize >= (aHostDataStride * aHeight), EVgPanicPixmapSizeError);
-
-	RemoteFunctionCallData rfcdata; OpenVgRFC vgApiData(rfcdata);
-	vgApiData.Init(OpenVgRFC::EvgImageSubData, RemoteFunctionCallData::EOpRequest);
-	vgApiData.AppendParam(iHostHandle);
-	vgApiData.AppendVector(aPixmap, aPixmapSize);
-	vgApiData.AppendParam(aHostDataStride);
-	vgApiData.AppendParam(aDataFormat);
-	vgApiData.AppendParam(aX);
-	vgApiData.AppendParam(aY);
-	vgApiData.AppendParam(aWidth);
-	vgApiData.AppendParam(aHeight);
-	TUint64 sgId(0L);
-	if (iIsEglSibling)
-		{
-		sgId = iSgImageId;
-		}
-	OPENVG_TRACE("CVgImageInfo::HostVgImageSubData sgId 0x%lx", sgId);
-	vgApiData.AppendTUint64(sgId);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-void CVgImageInfo::GetImageSubData(MVgContext& aVgContext, void * aData, VGint aDataStride, VGImageFormat aDataFormat, VGint aX, VGint aY, VGint aWidth, VGint aHeight)
-	{
-	// **** Desirable: check VGImage is not currently a rendering target
-
-	// Limit aWidth & aHeight to the dimensions of aImage
-	if (iWidth < aWidth)
-		{
-		aWidth = iWidth;
-		}
-	if (iHeight < aHeight)
-		{
-		aHeight = iHeight;
-		}
-	OPENVG_TRACE("CVgImageInfo::GetImageSubData.1a source Image: width=%d, height=%d; clipped width=%d, clipped height=%d",
-			iWidth, iHeight, aWidth, aHeight);
-	TInt bitsPerPixel = BitsPerPixelForVgImageFormat(aDataFormat);
-	TUint32 lineLength = static_cast<TUint32>(aWidth) * static_cast<TUint32>(bitsPerPixel);
-	TUint32 tailBits = lineLength & 7;
-	lineLength = (lineLength + 7) / 8;
-	OPENVG_TRACE("CVgImageInfo::GetImageSubData.1b bitsPerPixel=%d, lineLength=%d, tailBits=%d", bitsPerPixel, lineLength, tailBits);
-
-	if (bitsPerPixel <= 0)
-		{
-		aVgContext.SetVgError(VG_UNSUPPORTED_IMAGE_FORMAT_ERROR);
-		}
-	else
-		{
-		if (lineLength  == aDataStride)
-			{ // use original params
-			OPENVG_TRACE("CVgImageInfo::GetImageSubData.2a: lineLength == dataStride");
-			HostVgGetImageSubData(aVgContext, aData, aDataStride * aHeight, aDataStride, aDataFormat, aX, aY, aWidth, aHeight);
-			}
-		else if (0 == aDataStride)
-			{ // unlikely unless aHeight = 1, symmetric to fill function for vgGetImageSubData
-			OPENVG_TRACE("CVgImageInfo::GetImageSubData.2b: 0 == dataStride");
-			HostVgGetImageSubData(aVgContext, aData, lineLength, aDataStride, aDataFormat, aX, aY, aWidth, aHeight);
-			}
-		else
-			{ // datastride maybe negative or simply > lineLength
-			TInt pixmapSize = lineLength * aHeight;
-			TUint8* localBuffer = (TUint8*) CVghwUtils::Alloc(pixmapSize);
-			OPENVG_TRACE("CVgImageInfo::GetImageSubData.2c: dataStride not 0 or lineLength, localBuffer=0x%x", localBuffer);
-
-			if (localBuffer != NULL)
-				{ // read pixels into temporary buffer
-				HostVgGetImageSubData(aVgContext, localBuffer, pixmapSize, lineLength, aDataFormat, aX, aY, aWidth, aHeight);
-				// reformat into client memory
-				PixmapBlit(static_cast<TUint8*>(aData), localBuffer, aDataStride, lineLength, aHeight, lineLength, tailBits);
-				CVghwUtils::Free(localBuffer);
-				}
-			else
-				{ // alloc failed, so do VG operation row by row
-				TUint8* dest = static_cast<TUint8*>(aData);
-				for (VGint row = 0; row < aHeight; ++row)
-					{
-					HostVgGetImageSubData(aVgContext, dest, lineLength, lineLength, aDataFormat, aX + row, aY, aWidth, 1);
-					dest += aDataStride;
-					}
-				}
-			}
-		}
-	}
-
-
-void CVgImageInfo::HostVgGetImageSubData(MVgContext& aVgContext, void* aPixmap, size_t aPixmapSize, VGint aHostDataStride,
-		VGImageFormat aDataFormat, VGint aX, VGint aY, VGint aWidth, VGint aHeight)
-	{
-	VGPANIC_ASSERT_DEBUG(aPixmap != NULL, EVgPanicNullPixmapPointer);
-	VGPANIC_ASSERT_DEBUG(aPixmapSize >= (aHostDataStride * aHeight), EVgPanicPixmapSizeError);
-
-	RemoteFunctionCallData rfcdata; OpenVgRFC vgApiData(rfcdata);
-	vgApiData.Init(OpenVgRFC::EvgGetImageSubData);
-	vgApiData.AppendParam(iHostHandle);
-	vgApiData.AppendVector(aPixmap, aPixmapSize, RemoteFunctionCallData::EOut);
-	vgApiData.AppendParam(aHostDataStride);
-	vgApiData.AppendParam(aDataFormat);
-	vgApiData.AppendParam(aX);
-	vgApiData.AppendParam(aY);
-	vgApiData.AppendParam(aWidth);
-	vgApiData.AppendParam(aHeight);
-	vgApiData.AppendParam((VGint)aPixmapSize); // ToDo overload AppendParam for TUint32
-	TUint64 sgId(0L);
-	if (iIsEglSibling)
-		{
-		sgId = iSgImageId;
-		}
-	vgApiData.AppendTUint64(sgId);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-void CVgImageInfo::CopyImage(MVgContext& aVgContext, VGint aDx, VGint aDy, CVgImageInfo& aSrcImageInfo, VGint aSx, VGint aSy, VGint aWidth,
-		VGint aHeight, VGboolean aDither)
-	{
-	// **** Desirable: verify src & dst are not a rendering target, ...
-	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
-	vgApiData.Init(OpenVgRFC::EvgCopyImage, RemoteFunctionCallData::EOpRequest);
-	vgApiData.AppendParam(iHostHandle);
-	vgApiData.AppendParam(aDx);
-	vgApiData.AppendParam(aDy);
-	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
-	vgApiData.AppendParam(aSx);
-	vgApiData.AppendParam(aSy);
-	vgApiData.AppendParam(aWidth);
-	vgApiData.AppendParam(aHeight);
-	vgApiData.AppendParam(aDither);
-	TUint64 dstSgId(0L);
-	TUint64 srcSgId(0L);
-	if (iIsEglSibling)
-		{
-		dstSgId = iSgImageId;
-		}
-	if (aSrcImageInfo.IsEglSibling())
-		{
-		srcSgId = aSrcImageInfo.SgImageId();
-		}
-	vgApiData.AppendTUint64(dstSgId);
-	vgApiData.AppendTUint64(srcSgId);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-void CVgImageInfo::DrawImage(MVgContext& aVgContext)
-	{
-	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
-	vgApiData.Init(OpenVgRFC::EvgDrawImage, RemoteFunctionCallData::EOpRequest);
-	vgApiData.AppendParam(iHostHandle);
-	TUint64 sgId(0L);
-	if (iIsEglSibling)
-		{
-		sgId = iSgImageId;
-		}
-	vgApiData.AppendTUint64(sgId);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-void CVgImageInfo::SetPixels(MVgContext& aVgContext, VGint aDx, VGint aDy, VGint aSx, VGint aSy, VGint aWidth, VGint aHeight)
-	{
-	// **** Desirable: verify aSrc image is not a rendering target
-	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
-	vgApiData.Init(OpenVgRFC::EvgSetPixels, RemoteFunctionCallData::EOpRequest);
-	vgApiData.AppendParam(aDx);
-	vgApiData.AppendParam(aDy);
-	vgApiData.AppendParam(iHostHandle);
-	vgApiData.AppendParam(aSx);
-	vgApiData.AppendParam(aSy);
-	vgApiData.AppendParam(aWidth);
-	vgApiData.AppendParam(aHeight);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-void CVgImageInfo::GetPixels(MVgContext& aVgContext, VGint aDx, VGint aDy, VGint aSx, VGint aSy, VGint aWidth, VGint aHeight)
-	{
-	// **** Desirable: verify aDst is not currently a rendering target
-	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
-	vgApiData.Init(OpenVgRFC::EvgGetPixels, RemoteFunctionCallData::EOpRequest);
-	vgApiData.AppendParam(iHostHandle);
-	vgApiData.AppendParam(aDx);
-	vgApiData.AppendParam(aDy);
-	vgApiData.AppendParam(aSx);
-	vgApiData.AppendParam(aSy);
-	vgApiData.AppendParam(aWidth);
-	vgApiData.AppendParam(aHeight);
-	TUint64 sgId(0L);
-	if (iIsEglSibling)
-		{
-		sgId = iSgImageId;
-		}
-	vgApiData.AppendTUint64(sgId);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-void CVgImageInfo::ColorMatrix(MVgContext& aVgContext, CVgImageInfo& aSrcImageInfo, const VGfloat * aMatrix)
-	{
-	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
-	vgApiData.Init(OpenVgRFC::EvgColorMatrix, RemoteFunctionCallData::EOpRequest);
-	vgApiData.AppendParam(iHostHandle);
-	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
-	vgApiData.AppendVector(aMatrix, KColorMatrixSize);
-	TUint64 dstSgId(0L);
-	TUint64 srcSgId(0L);
-	if (IsEglSibling())
-		{
-		dstSgId = SgImageId();
-		}
-	if (aSrcImageInfo.IsEglSibling())
-		{
-		srcSgId = aSrcImageInfo.SgImageId();
-		}
-	vgApiData.AppendTUint64(dstSgId);
-	vgApiData.AppendTUint64(srcSgId);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-void CVgImageInfo::Convolve(MVgContext& aVgContext, CVgImageInfo& aSrcImageInfo, VGint aKernelWidth, VGint aKernelHeight,
-		VGint aShiftX, VGint aShiftY, const VGshort * aKernel, VGfloat aScale, VGfloat aBias, VGTilingMode aTilingMode)
-	{
-	// **** Desirable: verify aDst & aSrc are valid and do not overlap
-	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
-	vgApiData.Init(OpenVgRFC::EvgConvolve, RemoteFunctionCallData::EOpRequest);
-	vgApiData.AppendParam(iHostHandle);
-	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
-	vgApiData.AppendParam(aKernelWidth);
-	vgApiData.AppendParam(aKernelHeight);
-	vgApiData.AppendParam(aShiftX);
-	vgApiData.AppendParam(aShiftY);
-	vgApiData.AppendVector(aKernel, aKernelWidth*aKernelHeight);
-	vgApiData.AppendParam(aScale);
-	vgApiData.AppendParam(aBias);
-	vgApiData.AppendParam(aTilingMode);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-void CVgImageInfo::SeparableConvolve(MVgContext& aVgContext, CVgImageInfo& aSrcImageInfo, VGint aKernelWidth, VGint aKernelHeight,
-		VGint aShiftX, VGint aShiftY, const VGshort * aKernelX, const VGshort * aKernelY, 
-		VGfloat aScale, VGfloat aBias, VGTilingMode aTilingMode)
-	{
-	// **** Desirable: verify aDst & aSrc are valid and do not overlap
-	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
-	vgApiData.Init(OpenVgRFC::EvgSeparableConvolve, RemoteFunctionCallData::EOpRequest);
-	vgApiData.AppendParam(iHostHandle);
-	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
-	vgApiData.AppendParam(aKernelWidth);
-	vgApiData.AppendParam(aKernelHeight);
-	vgApiData.AppendParam(aShiftX);
-	vgApiData.AppendParam(aShiftY);
-	vgApiData.AppendVector(aKernelX, aKernelWidth);
-	vgApiData.AppendVector(aKernelY, aKernelHeight);
-	vgApiData.AppendParam(aScale);
-	vgApiData.AppendParam(aBias);
-	vgApiData.AppendParam(aTilingMode);
-	TUint64 dstSgId(0L);
-	TUint64 srcSgId(0L);
-	if (IsEglSibling())
-		{
-		dstSgId = SgImageId();
-		}
-	if (aSrcImageInfo.IsEglSibling())
-		{
-		srcSgId = aSrcImageInfo.SgImageId();
-		}
-	vgApiData.AppendTUint64(dstSgId);
-	vgApiData.AppendTUint64(srcSgId);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-void CVgImageInfo::GaussianBlur(MVgContext& aVgContext, CVgImageInfo& aSrcImageInfo, VGfloat aStdDeviationX, VGfloat aStdDeviationY, VGTilingMode aTilingMode)
-	{
-	// **** Desirable: verify aDst & src are not currently a rendering target or overlap
-	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
-	vgApiData.Init(OpenVgRFC::EvgGaussianBlur, RemoteFunctionCallData::EOpRequest);
-	vgApiData.AppendParam(iHostHandle);
-	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
-	vgApiData.AppendParam(aStdDeviationX);
-	vgApiData.AppendParam(aStdDeviationY);
-	vgApiData.AppendParam(aTilingMode);
-	TUint64 dstSgId(0L);
-	TUint64 srcSgId(0L);
-	if (IsEglSibling())
-		{
-		dstSgId = SgImageId();
-		}
-	if (aSrcImageInfo.IsEglSibling())
-		{
-		srcSgId = aSrcImageInfo.SgImageId();
-		}
-	vgApiData.AppendTUint64(dstSgId);
-	vgApiData.AppendTUint64(srcSgId);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-void CVgImageInfo::Lookup(MVgContext& aVgContext, CVgImageInfo& aSrcImageInfo, const VGubyte * aRedLUT, const VGubyte * aGreenLUT, const VGubyte * aBlueLUT,
-		const VGubyte * aAlphaLUT, VGboolean aOutputLinear, VGboolean aOutputPremultiplied)
-	{
-	// **** Desirable: verify aDst & aSrc are not currently a rendering target or overlap
-	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
-	vgApiData.Init(OpenVgRFC::EvgLookup, RemoteFunctionCallData::EOpRequest);
-	vgApiData.AppendParam(iHostHandle);
-	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
-	vgApiData.AppendVector(aRedLUT, KLUTLength);
-	vgApiData.AppendVector(aGreenLUT, KLUTLength);
-	vgApiData.AppendVector(aBlueLUT, KLUTLength);
-	vgApiData.AppendVector(aAlphaLUT, KLUTLength);
-	vgApiData.AppendParam(aOutputLinear);
-	vgApiData.AppendParam(aOutputPremultiplied);
-	TUint64 dstSgId(0L);
-	TUint64 srcSgId(0L);
-	if (IsEglSibling())
-		{
-		dstSgId = SgImageId();
-		}
-	if (aSrcImageInfo.IsEglSibling())
-		{
-		srcSgId = aSrcImageInfo.SgImageId();
-		}
-	vgApiData.AppendTUint64(dstSgId);
-	vgApiData.AppendTUint64(srcSgId);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-void CVgImageInfo::LookupSingle(MVgContext& aVgContext, CVgImageInfo& aSrcImageInfo, const VGuint * aLookupTable, VGImageChannel aSourceChannel,
-		VGboolean aOutputLinear, VGboolean aOutputPremultiplied)
-	{
-	// **** Desirable: check aSrc is in an RGB pixel format, and that aSourceChannel is okay
-	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
-	vgApiData.Init(OpenVgRFC::EvgLookupSingle, RemoteFunctionCallData::EOpRequest);
-	vgApiData.AppendParam(iHostHandle);
-	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
-	vgApiData.AppendVector(aLookupTable, KLUTLength);
-	vgApiData.AppendParam(aSourceChannel);
-	vgApiData.AppendParam(aOutputLinear);
-	vgApiData.AppendParam(aOutputPremultiplied);
-	TUint64 dstSgId(0L);
-	TUint64 srcSgId(0L);
-	if (IsEglSibling())
-		{
-		dstSgId = SgImageId();
-		}
-	if (aSrcImageInfo.IsEglSibling())
-		{
-		srcSgId = aSrcImageInfo.SgImageId();
-		}
-	vgApiData.AppendTUint64(dstSgId);
-	vgApiData.AppendTUint64(srcSgId);
-	aVgContext.ExecuteVgCommand(vgApiData);
-	}
-
-
-// end of file vgimage.cpp
+// Copyright (c) 2010 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:
+// Client-side state information for Open VG handle based objects
+
+#include "vgstate.h"
+#include "remotefunctioncall.h"
+#include "openvgrfc.h"
+
+
+const TInt KColorMatrixSize = 20;
+const TInt KLUTLength = 256;
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// CVgImageInfo
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+CVgImageInfo::CVgImageInfo(VGImageFormat aFormat, VGint aWidth, VGint aHeight, CVgImageInfo* aParent, VGbitfield aAllowedQuality,
+			EGLImageKHR aEglImage, TUint64 aSgImageId) :
+		CVgImageBase(EVgHandleForImage, aWidth, aHeight), iFormat(aFormat), iParent(aParent),
+		iAllowedQuality(aAllowedQuality), iIsEglSibling( aSgImageId ? ETrue : EFalse),
+		iEglImage(aEglImage), iSgImageId(aSgImageId),
+		iChildCount(0)
+	{
+	if (aParent)
+		{
+		aParent->IncChildCount();
+		}
+	}
+
+
+// eglChildImage
+CVgImageInfo* CVgImageInfo::New(VGint aWidth, VGint aHeight, CVgImageInfo* aParent)
+	{
+	VGPANIC_ASSERT_DEBUG(aParent, EVgPanicImageParentIsInvalid);
+	RHeap* clientHeap = CVghwUtils::SwitchToVghwHeap();
+	CVgImageInfo* self = new CVgImageInfo(aParent->iFormat, aWidth, aHeight, aParent, aParent->AllowedQuality(),
+			aParent->EglImage(), aParent->SgImageId());
+	CVghwUtils::SwitchFromVghwHeap(clientHeap);
+	return self;
+	}
+
+
+// vgCreateEGLImageTargetKHR
+CVgImageInfo* CVgImageInfo::New(VGImageFormat aFormat, VGint aWidth, VGint aHeight, EGLImageKHR aEglImage, TUint64& aSgImageId)
+	{
+	RHeap* clientHeap = CVghwUtils::SwitchToVghwHeap();
+	CVgImageInfo* self = new CVgImageInfo(aFormat, aWidth, aHeight, VG_INVALID_HANDLE, 0, aEglImage, aSgImageId);
+	CVghwUtils::SwitchFromVghwHeap(clientHeap);
+	return self;
+	}
+
+
+// eglCreateImage
+CVgImageInfo* CVgImageInfo::New(VGImageFormat aFormat, VGint aWidth, VGint aHeight, VGbitfield aAllowedQuality)
+	{
+	RHeap* clientHeap = CVghwUtils::SwitchToVghwHeap();
+	CVgImageInfo* self = new CVgImageInfo(aFormat, aWidth, aHeight, VG_INVALID_HANDLE, aAllowedQuality, NULL, 0l);
+	CVghwUtils::SwitchFromVghwHeap(clientHeap);
+	return self;
+	}
+
+
+CVgImageInfo::~CVgImageInfo()
+	{
+	VGPANIC_ASSERT(iChildCount == 0, EVgPanicDeleteInUseVgImageInfo);
+	if (iParent)
+		{
+		iParent->DecChildCount();
+		}
+	}
+
+
+CVgImageInfo* CVgImageInfo::Parent() const
+	{
+	return iParent;
+	}
+
+
+TInt CVgImageInfo::ChildCount() const
+	{
+	return iChildCount;
+	}
+
+
+void CVgImageInfo::IncChildCount()
+	{
+	VGPANIC_ASSERT(!iIsDestroyed, EVgPanicParentImageAlreadyDestroyed);
+	User::LockedInc(iChildCount);
+	}
+
+
+void CVgImageInfo::DecChildCount()
+	{
+	User::LockedDec(iChildCount);
+	if ((iChildCount == 0) && iIsDestroyed)
+		{
+		if (iParent == NULL)
+			{
+			if (IsEglSibling())
+				{ // close the root EglImage
+				OpenVgState.EglImageClose(iEglImage);
+				}
+			}
+		else
+			{
+			iParent->DecChildCount();
+			}
+		// delete this image & remove it from HandleMap
+		RHeap* clientHeap = CVghwUtils::SwitchToVghwHeap();
+		OpenVgState.UnMapHandle(iClientHandle);
+		delete this;
+		CVghwUtils::SwitchFromVghwHeap(clientHeap);
+		}
+	}
+
+
+VGbitfield CVgImageInfo::AllowedQuality() const
+	{
+	return iAllowedQuality;
+	}
+
+
+TBool CVgImageInfo::IsEglSibling() const
+	{
+	return iIsEglSibling;
+	}
+
+
+EGLImageKHR CVgImageInfo::EglImage() const
+	{
+	return iEglImage;
+	}
+
+
+TUint64 CVgImageInfo::SgImageId() const
+	{
+	return iSgImageId;
+	}
+
+
+TBool CVgImageInfo::DestroyObject(MVgContext& aVgContext)
+	{
+	VGPANIC_ASSERT_DEBUG(iIsDestroyed, EVgPanicTemp);
+	OPENVG_TRACE("  CVgImageInfo::DestroyObject HostHandle=0x%x; ChildCount=%d, Parent=0x%x, IsEglSibling=%d, EglImage=0x%x",
+			iHostHandle, ChildCount(), Parent(), IsEglSibling(), EglImage());
+
+	if (iHostHandle)
+		{
+		// Destroy image, but not for eglImages/SgImages
+		if (!IsEglSibling())
+			{
+			RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+			vgApiData.Init(OpenVgRFC::EvgDestroyImage, RemoteFunctionCallData::EOpRequest);
+			vgApiData.AppendParam(iHostHandle);
+			aVgContext.ExecuteVgCommand(vgApiData);
+			}
+		iHostHandle = VG_INVALID_HANDLE;
+		}
+
+	if (iChildCount == 0)
+		{
+		if (iParent == NULL)
+			{
+			if (IsEglSibling())
+				{ // close the root EglImage
+				OpenVgState.EglImageClose(iEglImage);
+				}
+			}
+		else
+			{
+			iParent->DecChildCount();
+			}
+		return ETrue;
+		}
+	// don't delete this image until all children have been destroyed
+	return EFalse;
+	}
+
+
+TInt CVgImageInfo::BitsPerPixelForVgImageFormat(VGImageFormat aFormat)
+	{
+	TInt result = -1;
+	if ((aFormat == VG_BW_1) || (aFormat == VG_A_1))
+		{
+		result = 1;
+		}
+	else if (aFormat == VG_A_4)
+		{
+		result = 4;
+		}
+	else if ((aFormat == VG_sL_8) || (aFormat == VG_lL_8) || (aFormat == VG_A_8))
+		{
+		result = 8;
+		}
+	else if ((aFormat >= 0) && (aFormat < 256))
+		{ // low bits of format number repeat in a pattern for 16/32 bit per pel
+		TInt format = aFormat & 0x3f;
+		if ((format >= VG_sRGB_565) && (format <= VG_sRGBA_4444))
+			{
+			result = 16;
+			}
+		else if (format <= VG_lRGBA_8888_PRE)
+			{
+			result = 32;
+			}
+		}
+	return result;
+	}
+
+
+void CVgImageInfo::PixmapBlit(TUint8* aDest, const TUint8* aSource, TInt aDestStride, TInt aSourceStride, TInt aRowCount,
+		size_t aRowLength, TInt aLastBits)
+	{
+	VGPANIC_ASSERT_DEBUG(aDest, EVgPanicNullPointer);
+	VGPANIC_ASSERT_DEBUG(aSource, EVgPanicNullPointer);
+	VGPANIC_ASSERT_DEBUG(aDestStride >= aRowLength, EVgPanicStrideSmallerThanRowLength);
+	VGPANIC_ASSERT_DEBUG(aSourceStride >= aRowLength, EVgPanicStrideSmallerThanRowLength);
+	VGPANIC_ASSERT_DEBUG(aRowCount > 0, EVgPanicBadRowCountParam);
+	VGPANIC_ASSERT_DEBUG(aRowLength > 0, EVgPanicBadRowLengthParam);
+	VGPANIC_ASSERT_DEBUG( (aLastBits >= 0) && (aLastBits <= 7), EVgPanicBadLastBitsParam);
+
+	if (aLastBits)
+		{ // bits per pixel < 8, only copy lowest <aLastBits> from source to dest
+		TUint8 destMask = 0xFF << aLastBits; // high bits
+		TUint8 srcMask = 0xFF ^ destMask; // low bits
+		aRowLength -= 1;
+		for (VGint row = 0; row < aRowCount; ++row)
+			{
+			memcpy(aDest, aSource, aRowLength);
+			TUint8 byte = (aDest[aRowLength] & destMask) | (aSource[aRowLength] & srcMask);
+			aDest[aRowLength] = byte;
+			aSource += aSourceStride;
+			aDest += aDestStride;
+			}
+		}
+	else
+		{
+		for (VGint row = 0; row < aRowCount; ++row)
+			{
+			memcpy(aDest, aSource, aRowLength);
+			aSource += aSourceStride;
+			aDest += aDestStride;
+			}
+		}
+	}
+
+
+VGint CVgImageInfo::GetParameterVectorSize(MVgContext& aVgContext, VGint aParamType)
+	{
+	switch (aParamType)
+		{
+		case VG_IMAGE_FORMAT:
+		case VG_IMAGE_WIDTH:
+		case VG_IMAGE_HEIGHT:
+			return 1;
+		}
+
+	// invalid ParamType
+	aVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR);
+	return 0;
+	}
+
+
+VGfloat CVgImageInfo::GetParameterf(MVgContext& aVgContext, VGint aParamType)
+	{
+	switch (aParamType)
+		{
+		case VG_IMAGE_FORMAT:
+			if (iFormat != VG_IMAGE_FORMAT_INVALID)
+				{
+				return (VGfloat)iFormat;
+				}
+			// for EglImage need to get format of underlying VgImage
+			return HostVgGetParameterf(aVgContext, aParamType);
+
+		case VG_IMAGE_WIDTH:
+			return (VGfloat)iWidth;
+
+		case VG_IMAGE_HEIGHT:
+			return (VGfloat)iHeight;
+		}
+
+	// invalid ParamType
+	aVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR);
+	return 0;
+	}
+
+
+VGint CVgImageInfo::GetParameteri(MVgContext& aVgContext, VGint aParamType)
+	{
+	switch (aParamType)
+		{
+		case VG_IMAGE_FORMAT:
+			if (iFormat != VG_IMAGE_FORMAT_INVALID)
+				{
+				return iFormat;
+				}
+			// for EglImage need to get format of underlying VgImage
+			iFormat = (VGImageFormat) HostVgGetParameteri(aVgContext, aParamType);
+			return iFormat;
+
+		case VG_IMAGE_WIDTH:
+			return iWidth;
+
+		case VG_IMAGE_HEIGHT:
+			return iHeight;
+		}
+
+	// invalid ParamType
+	aVgContext.SetVgError(VG_ILLEGAL_ARGUMENT_ERROR);
+	return 0;
+	}
+
+
+void CVgImageInfo::ClearImage(MVgContext& aVgContext, VGint aX, VGint aY, VGint aWidth, VGint aHeight)
+	{
+	// **** Desirable: check aImage is not rendering target
+	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+	vgApiData.Init(OpenVgRFC::EvgClearImage, RemoteFunctionCallData::EOpRequest);
+	vgApiData.AppendParam(iHostHandle);
+	vgApiData.AppendParam(aX);
+	vgApiData.AppendParam(aY);
+	vgApiData.AppendParam(aWidth);
+	vgApiData.AppendParam(aHeight);
+	TUint64 sgId(0L);
+	if (iIsEglSibling)
+		{
+		sgId = iSgImageId;
+		}
+	vgApiData.AppendTUint64(sgId);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+void CVgImageInfo::ImageSubData(MVgContext& aVgContext, const void * aData, VGint aDataStride, VGImageFormat aDataFormat, VGint aX, VGint aY,
+		VGint aWidth, VGint aHeight)
+	{
+	// **** Desirable: check image is not a rendering target
+
+	// Limit aWidth & aHeight to the dimensions of aImage
+	if (iWidth < aWidth)
+		{
+		aWidth = iWidth;
+		}
+	if (iHeight < aHeight)
+		{
+		aHeight = iHeight;
+		}
+	OPENVG_TRACE("CVgImageInfo::ImageSubData.1a dest Image: width=%d, height=%d; clipped width=%d, clipped height=%d",
+			iWidth, iHeight, aWidth, aHeight);
+	TInt bitsPerPixel = BitsPerPixelForVgImageFormat(aDataFormat);
+	TUint32 lineLength = ((static_cast<TUint32>(aWidth) * static_cast<TUint32>(bitsPerPixel)) + 7) / 8;
+	OPENVG_TRACE("CVgImageInfo::ImageSubData.1b bitsPerPixel=%d, lineLength=%d", bitsPerPixel, lineLength);
+
+	if (bitsPerPixel <= 0)
+		{
+		aVgContext.SetVgError(VG_UNSUPPORTED_IMAGE_FORMAT_ERROR);
+		}
+	else
+		{
+		if (lineLength  == aDataStride)
+			{ // use original parameters
+			OPENVG_TRACE("CVgImageInfo::ImageSubData.2a: lineLength == dataStride");
+			HostVgImageSubData(aVgContext, aData, aDataStride * aHeight, aDataStride,
+					aDataFormat, aX, aY, aWidth, aHeight);
+			}
+		else if (0 == aDataStride)
+			{ // Fill operation, pixmap size = lineLength
+			OPENVG_TRACE("CVgImageInfo::ImageSubData.2b: 0 == dataStride");
+			HostVgImageSubData(aVgContext, aData, lineLength, aDataStride,
+					aDataFormat, aX, aY, aWidth, aHeight);
+			}
+		else
+			{ // try to alloc a translation buffer - datastride maybe negative or simply > lineLength
+			size_t pixmapSize = lineLength * aHeight;
+			TUint8* localBuffer = (TUint8*) CVghwUtils::Alloc(pixmapSize);
+			OPENVG_TRACE("CVgImageInfo::ImageSubData.2c: dataStride not 0 or lineLength, localBuffer=0x%x", localBuffer);
+			if (localBuffer != NULL)
+				{ // reformat data into temporary buffer
+				PixmapBlit(localBuffer, static_cast<const TUint8*>(aData), lineLength, aDataStride, aHeight, lineLength);
+				HostVgImageSubData(aVgContext, localBuffer, pixmapSize, lineLength, aDataFormat, aX, aY, aWidth, aHeight);
+				CVghwUtils::Free(localBuffer);
+				}
+			else
+				{ // alloc failed, so do VG operation row by row
+				const TUint8* source = static_cast<const TUint8*>(aData);
+				for (VGint row = 0; row < aHeight; ++row)
+					{
+					HostVgImageSubData(aVgContext, source, lineLength, lineLength, aDataFormat, aX + row, aY, aWidth, 1);
+					source += aDataStride;
+					}
+				}
+			}
+		}
+	}
+
+
+void CVgImageInfo::HostVgImageSubData(MVgContext& aVgContext, const void* aPixmap, size_t aPixmapSize, VGint aHostDataStride,
+		VGImageFormat aDataFormat, VGint aX, VGint aY, VGint aWidth, VGint aHeight)
+	{
+	VGPANIC_ASSERT(aPixmap != NULL, EVgPanicNullPixmapPointer);
+	VGPANIC_ASSERT(aPixmapSize >= (aHostDataStride * aHeight), EVgPanicPixmapSizeError);
+
+	RemoteFunctionCallData rfcdata; OpenVgRFC vgApiData(rfcdata);
+	vgApiData.Init(OpenVgRFC::EvgImageSubData, RemoteFunctionCallData::EOpRequest);
+	vgApiData.AppendParam(iHostHandle);
+	vgApiData.AppendVector(aPixmap, aPixmapSize);
+	vgApiData.AppendParam(aHostDataStride);
+	vgApiData.AppendParam(aDataFormat);
+	vgApiData.AppendParam(aX);
+	vgApiData.AppendParam(aY);
+	vgApiData.AppendParam(aWidth);
+	vgApiData.AppendParam(aHeight);
+	TUint64 sgId(0L);
+	if (iIsEglSibling)
+		{
+		sgId = iSgImageId;
+		}
+	OPENVG_TRACE("CVgImageInfo::HostVgImageSubData sgId 0x%lx", sgId);
+	vgApiData.AppendTUint64(sgId);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+void CVgImageInfo::GetImageSubData(MVgContext& aVgContext, void * aData, VGint aDataStride, VGImageFormat aDataFormat, VGint aX, VGint aY, VGint aWidth, VGint aHeight)
+	{
+	// **** Desirable: check VGImage is not currently a rendering target
+
+	// Limit aWidth & aHeight to the dimensions of aImage
+	if (iWidth < aWidth)
+		{
+		aWidth = iWidth;
+		}
+	if (iHeight < aHeight)
+		{
+		aHeight = iHeight;
+		}
+	OPENVG_TRACE("CVgImageInfo::GetImageSubData.1a source Image: width=%d, height=%d; clipped width=%d, clipped height=%d",
+			iWidth, iHeight, aWidth, aHeight);
+	TInt bitsPerPixel = BitsPerPixelForVgImageFormat(aDataFormat);
+	TUint32 lineLength = static_cast<TUint32>(aWidth) * static_cast<TUint32>(bitsPerPixel);
+	TUint32 tailBits = lineLength & 7;
+	lineLength = (lineLength + 7) / 8;
+	OPENVG_TRACE("CVgImageInfo::GetImageSubData.1b bitsPerPixel=%d, lineLength=%d, tailBits=%d", bitsPerPixel, lineLength, tailBits);
+
+	if (bitsPerPixel <= 0)
+		{
+		aVgContext.SetVgError(VG_UNSUPPORTED_IMAGE_FORMAT_ERROR);
+		}
+	else
+		{
+		if (lineLength  == aDataStride)
+			{ // use original params
+			OPENVG_TRACE("CVgImageInfo::GetImageSubData.2a: lineLength == dataStride");
+			HostVgGetImageSubData(aVgContext, aData, aDataStride * aHeight, aDataStride, aDataFormat, aX, aY, aWidth, aHeight);
+			}
+		else if (0 == aDataStride)
+			{ // unlikely unless aHeight = 1, symmetric to fill function for vgGetImageSubData
+			OPENVG_TRACE("CVgImageInfo::GetImageSubData.2b: 0 == dataStride");
+			HostVgGetImageSubData(aVgContext, aData, lineLength, aDataStride, aDataFormat, aX, aY, aWidth, aHeight);
+			}
+		else
+			{ // datastride maybe negative or simply > lineLength
+			TInt pixmapSize = lineLength * aHeight;
+			TUint8* localBuffer = (TUint8*) CVghwUtils::Alloc(pixmapSize);
+			OPENVG_TRACE("CVgImageInfo::GetImageSubData.2c: dataStride not 0 or lineLength, localBuffer=0x%x", localBuffer);
+
+			if (localBuffer != NULL)
+				{ // read pixels into temporary buffer
+				HostVgGetImageSubData(aVgContext, localBuffer, pixmapSize, lineLength, aDataFormat, aX, aY, aWidth, aHeight);
+				// reformat into client memory
+				PixmapBlit(static_cast<TUint8*>(aData), localBuffer, aDataStride, lineLength, aHeight, lineLength, tailBits);
+				CVghwUtils::Free(localBuffer);
+				}
+			else
+				{ // alloc failed, so do VG operation row by row
+				TUint8* dest = static_cast<TUint8*>(aData);
+				for (VGint row = 0; row < aHeight; ++row)
+					{
+					HostVgGetImageSubData(aVgContext, dest, lineLength, lineLength, aDataFormat, aX + row, aY, aWidth, 1);
+					dest += aDataStride;
+					}
+				}
+			}
+		}
+	}
+
+
+void CVgImageInfo::HostVgGetImageSubData(MVgContext& aVgContext, void* aPixmap, size_t aPixmapSize, VGint aHostDataStride,
+		VGImageFormat aDataFormat, VGint aX, VGint aY, VGint aWidth, VGint aHeight)
+	{
+	VGPANIC_ASSERT_DEBUG(aPixmap != NULL, EVgPanicNullPixmapPointer);
+	VGPANIC_ASSERT_DEBUG(aPixmapSize >= (aHostDataStride * aHeight), EVgPanicPixmapSizeError);
+
+	RemoteFunctionCallData rfcdata; OpenVgRFC vgApiData(rfcdata);
+	vgApiData.Init(OpenVgRFC::EvgGetImageSubData);
+	vgApiData.AppendParam(iHostHandle);
+	vgApiData.AppendVector(aPixmap, aPixmapSize, RemoteFunctionCallData::EOut);
+	vgApiData.AppendParam(aHostDataStride);
+	vgApiData.AppendParam(aDataFormat);
+	vgApiData.AppendParam(aX);
+	vgApiData.AppendParam(aY);
+	vgApiData.AppendParam(aWidth);
+	vgApiData.AppendParam(aHeight);
+	vgApiData.AppendParam((VGint)aPixmapSize); // ToDo overload AppendParam for TUint32
+	TUint64 sgId(0L);
+	if (iIsEglSibling)
+		{
+		sgId = iSgImageId;
+		}
+	vgApiData.AppendTUint64(sgId);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+void CVgImageInfo::CopyImage(MVgContext& aVgContext, VGint aDx, VGint aDy, CVgImageInfo& aSrcImageInfo, VGint aSx, VGint aSy, VGint aWidth,
+		VGint aHeight, VGboolean aDither)
+	{
+	// **** Desirable: verify src & dst are not a rendering target, ...
+	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+	vgApiData.Init(OpenVgRFC::EvgCopyImage, RemoteFunctionCallData::EOpRequest);
+	vgApiData.AppendParam(iHostHandle);
+	vgApiData.AppendParam(aDx);
+	vgApiData.AppendParam(aDy);
+	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
+	vgApiData.AppendParam(aSx);
+	vgApiData.AppendParam(aSy);
+	vgApiData.AppendParam(aWidth);
+	vgApiData.AppendParam(aHeight);
+	vgApiData.AppendParam(aDither);
+	TUint64 dstSgId(0L);
+	TUint64 srcSgId(0L);
+	if (iIsEglSibling)
+		{
+		dstSgId = iSgImageId;
+		}
+	if (aSrcImageInfo.IsEglSibling())
+		{
+		srcSgId = aSrcImageInfo.SgImageId();
+		}
+	vgApiData.AppendTUint64(dstSgId);
+	vgApiData.AppendTUint64(srcSgId);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+void CVgImageInfo::DrawImage(MVgContext& aVgContext)
+	{
+	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+	vgApiData.Init(OpenVgRFC::EvgDrawImage, RemoteFunctionCallData::EOpRequest);
+	vgApiData.AppendParam(iHostHandle);
+	TUint64 sgId(0L);
+	if (iIsEglSibling)
+		{
+		sgId = iSgImageId;
+		}
+	vgApiData.AppendTUint64(sgId);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+void CVgImageInfo::SetPixels(MVgContext& aVgContext, VGint aDx, VGint aDy, VGint aSx, VGint aSy, VGint aWidth, VGint aHeight)
+	{
+	// **** Desirable: verify aSrc image is not a rendering target
+	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+	vgApiData.Init(OpenVgRFC::EvgSetPixels, RemoteFunctionCallData::EOpRequest);
+	vgApiData.AppendParam(aDx);
+	vgApiData.AppendParam(aDy);
+	vgApiData.AppendParam(iHostHandle);
+	vgApiData.AppendParam(aSx);
+	vgApiData.AppendParam(aSy);
+	vgApiData.AppendParam(aWidth);
+	vgApiData.AppendParam(aHeight);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+void CVgImageInfo::GetPixels(MVgContext& aVgContext, VGint aDx, VGint aDy, VGint aSx, VGint aSy, VGint aWidth, VGint aHeight)
+	{
+	// **** Desirable: verify aDst is not currently a rendering target
+	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+	vgApiData.Init(OpenVgRFC::EvgGetPixels, RemoteFunctionCallData::EOpRequest);
+	vgApiData.AppendParam(iHostHandle);
+	vgApiData.AppendParam(aDx);
+	vgApiData.AppendParam(aDy);
+	vgApiData.AppendParam(aSx);
+	vgApiData.AppendParam(aSy);
+	vgApiData.AppendParam(aWidth);
+	vgApiData.AppendParam(aHeight);
+	TUint64 sgId(0L);
+	if (iIsEglSibling)
+		{
+		sgId = iSgImageId;
+		}
+	vgApiData.AppendTUint64(sgId);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+void CVgImageInfo::ColorMatrix(MVgContext& aVgContext, CVgImageInfo& aSrcImageInfo, const VGfloat * aMatrix)
+	{
+	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+	vgApiData.Init(OpenVgRFC::EvgColorMatrix, RemoteFunctionCallData::EOpRequest);
+	vgApiData.AppendParam(iHostHandle);
+	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
+	vgApiData.AppendVector(aMatrix, KColorMatrixSize);
+	TUint64 dstSgId(0L);
+	TUint64 srcSgId(0L);
+	if (IsEglSibling())
+		{
+		dstSgId = SgImageId();
+		}
+	if (aSrcImageInfo.IsEglSibling())
+		{
+		srcSgId = aSrcImageInfo.SgImageId();
+		}
+	vgApiData.AppendTUint64(dstSgId);
+	vgApiData.AppendTUint64(srcSgId);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+void CVgImageInfo::Convolve(MVgContext& aVgContext, CVgImageInfo& aSrcImageInfo, VGint aKernelWidth, VGint aKernelHeight,
+		VGint aShiftX, VGint aShiftY, const VGshort * aKernel, VGfloat aScale, VGfloat aBias, VGTilingMode aTilingMode)
+	{
+	// **** Desirable: verify aDst & aSrc are valid and do not overlap
+	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+	vgApiData.Init(OpenVgRFC::EvgConvolve, RemoteFunctionCallData::EOpRequest);
+	vgApiData.AppendParam(iHostHandle);
+	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
+	vgApiData.AppendParam(aKernelWidth);
+	vgApiData.AppendParam(aKernelHeight);
+	vgApiData.AppendParam(aShiftX);
+	vgApiData.AppendParam(aShiftY);
+	vgApiData.AppendVector(aKernel, aKernelWidth*aKernelHeight);
+	vgApiData.AppendParam(aScale);
+	vgApiData.AppendParam(aBias);
+	vgApiData.AppendParam(aTilingMode);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+void CVgImageInfo::SeparableConvolve(MVgContext& aVgContext, CVgImageInfo& aSrcImageInfo, VGint aKernelWidth, VGint aKernelHeight,
+		VGint aShiftX, VGint aShiftY, const VGshort * aKernelX, const VGshort * aKernelY, 
+		VGfloat aScale, VGfloat aBias, VGTilingMode aTilingMode)
+	{
+	// **** Desirable: verify aDst & aSrc are valid and do not overlap
+	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+	vgApiData.Init(OpenVgRFC::EvgSeparableConvolve, RemoteFunctionCallData::EOpRequest);
+	vgApiData.AppendParam(iHostHandle);
+	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
+	vgApiData.AppendParam(aKernelWidth);
+	vgApiData.AppendParam(aKernelHeight);
+	vgApiData.AppendParam(aShiftX);
+	vgApiData.AppendParam(aShiftY);
+	vgApiData.AppendVector(aKernelX, aKernelWidth);
+	vgApiData.AppendVector(aKernelY, aKernelHeight);
+	vgApiData.AppendParam(aScale);
+	vgApiData.AppendParam(aBias);
+	vgApiData.AppendParam(aTilingMode);
+	TUint64 dstSgId(0L);
+	TUint64 srcSgId(0L);
+	if (IsEglSibling())
+		{
+		dstSgId = SgImageId();
+		}
+	if (aSrcImageInfo.IsEglSibling())
+		{
+		srcSgId = aSrcImageInfo.SgImageId();
+		}
+	vgApiData.AppendTUint64(dstSgId);
+	vgApiData.AppendTUint64(srcSgId);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+void CVgImageInfo::GaussianBlur(MVgContext& aVgContext, CVgImageInfo& aSrcImageInfo, VGfloat aStdDeviationX, VGfloat aStdDeviationY, VGTilingMode aTilingMode)
+	{
+	// **** Desirable: verify aDst & src are not currently a rendering target or overlap
+	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+	vgApiData.Init(OpenVgRFC::EvgGaussianBlur, RemoteFunctionCallData::EOpRequest);
+	vgApiData.AppendParam(iHostHandle);
+	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
+	vgApiData.AppendParam(aStdDeviationX);
+	vgApiData.AppendParam(aStdDeviationY);
+	vgApiData.AppendParam(aTilingMode);
+	TUint64 dstSgId(0L);
+	TUint64 srcSgId(0L);
+	if (IsEglSibling())
+		{
+		dstSgId = SgImageId();
+		}
+	if (aSrcImageInfo.IsEglSibling())
+		{
+		srcSgId = aSrcImageInfo.SgImageId();
+		}
+	vgApiData.AppendTUint64(dstSgId);
+	vgApiData.AppendTUint64(srcSgId);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+void CVgImageInfo::Lookup(MVgContext& aVgContext, CVgImageInfo& aSrcImageInfo, const VGubyte * aRedLUT, const VGubyte * aGreenLUT, const VGubyte * aBlueLUT,
+		const VGubyte * aAlphaLUT, VGboolean aOutputLinear, VGboolean aOutputPremultiplied)
+	{
+	// **** Desirable: verify aDst & aSrc are not currently a rendering target or overlap
+	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+	vgApiData.Init(OpenVgRFC::EvgLookup, RemoteFunctionCallData::EOpRequest);
+	vgApiData.AppendParam(iHostHandle);
+	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
+	vgApiData.AppendVector(aRedLUT, KLUTLength);
+	vgApiData.AppendVector(aGreenLUT, KLUTLength);
+	vgApiData.AppendVector(aBlueLUT, KLUTLength);
+	vgApiData.AppendVector(aAlphaLUT, KLUTLength);
+	vgApiData.AppendParam(aOutputLinear);
+	vgApiData.AppendParam(aOutputPremultiplied);
+	TUint64 dstSgId(0L);
+	TUint64 srcSgId(0L);
+	if (IsEglSibling())
+		{
+		dstSgId = SgImageId();
+		}
+	if (aSrcImageInfo.IsEglSibling())
+		{
+		srcSgId = aSrcImageInfo.SgImageId();
+		}
+	vgApiData.AppendTUint64(dstSgId);
+	vgApiData.AppendTUint64(srcSgId);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+void CVgImageInfo::LookupSingle(MVgContext& aVgContext, CVgImageInfo& aSrcImageInfo, const VGuint * aLookupTable, VGImageChannel aSourceChannel,
+		VGboolean aOutputLinear, VGboolean aOutputPremultiplied)
+	{
+	// **** Desirable: check aSrc is in an RGB pixel format, and that aSourceChannel is okay
+	RemoteFunctionCallData data; OpenVgRFC vgApiData(data);
+	vgApiData.Init(OpenVgRFC::EvgLookupSingle, RemoteFunctionCallData::EOpRequest);
+	vgApiData.AppendParam(iHostHandle);
+	vgApiData.AppendParam(aSrcImageInfo.HostHandle());
+	vgApiData.AppendVector(aLookupTable, KLUTLength);
+	vgApiData.AppendParam(aSourceChannel);
+	vgApiData.AppendParam(aOutputLinear);
+	vgApiData.AppendParam(aOutputPremultiplied);
+	TUint64 dstSgId(0L);
+	TUint64 srcSgId(0L);
+	if (IsEglSibling())
+		{
+		dstSgId = SgImageId();
+		}
+	if (aSrcImageInfo.IsEglSibling())
+		{
+		srcSgId = aSrcImageInfo.SgImageId();
+		}
+	vgApiData.AppendTUint64(dstSgId);
+	vgApiData.AppendTUint64(srcSgId);
+	aVgContext.ExecuteVgCommand(vgApiData);
+	}
+
+
+// end of file vgimage.cpp