diff -r 000000000000 -r 5d03bc08d59c graphicsresourceservices/graphicsresource/src/sgutils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicsresourceservices/graphicsresource/src/sgutils.cpp Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,633 @@ +// Copyright (c) 2008-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 "sgutils.h" + + +// Helper function used to transfer a scanline in 64K to the various formats of the destination. +LOCAL_C void TransferScanLine64K(TUint8* aDest, const TUint16* aSrc, TUidPixelFormat aPixelFormatDest, TInt aPixelLength) + { + switch (aPixelFormatDest) + { + case EUidPixelFormatRGB_565: + { + Mem::Copy(aDest, aSrc, aPixelLength << 1); + break; + } + case EUidPixelFormatARGB_8888_PRE: + { + TUint32* dest = reinterpret_cast(aDest); + const TUint16* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *dest++ = TRgb::Color64K(*aSrc++).Color16MAP(); + } + break; + } + case EUidPixelFormatARGB_8888: + { + TUint32* dest = reinterpret_cast(aDest); + const TUint16* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *dest++ = TRgb::Color64K(*aSrc++).Color16MA(); + } + break; + } + case EUidPixelFormatXRGB_8888: + { + TUint32* dest = reinterpret_cast(aDest); + const TUint16* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *dest++ = (TRgb::Color64K(*aSrc++).Color16MU() | 0xff000000); + } + break; + } + case EUidPixelFormatRGB_888: + { + const TUint16* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + TInt col = TRgb::Color64K(*aSrc++).Color16M(); + *aDest++ = col; + *aDest++ = col >> 8; + *aDest++ = col >> 16; + } + break; + } + case EUidPixelFormatXRGB_4444: + { + TUint16* dest = reinterpret_cast(aDest); + const TUint16* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *dest++ = TRgb::Color64K(*aSrc++).Color4K(); + } + break; + } + case EUidPixelFormatP_8: + { + const TUint16* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *aDest++ = TRgb::Color64K(*aSrc++).Color256(); + } + break; + } + case EUidPixelFormatL_8: + { + const TUint16* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *aDest++ = TRgb::Color64K(*aSrc++).Gray256(); + } + break; + } + case EUidPixelFormatL_4: + { + const TUint16* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *aDest = 0; + for (TInt index = 0; (index < 8) && (aSrc < srcEnd); index+= 4) + { + TInt col = TRgb::Color64K(*aSrc++).Gray16(); + col <<= index; + *aDest |= col; + } + aDest++; + } + break; + } + case EUidPixelFormatP_4: + { + const TUint16* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *aDest = 0; + for (TInt index = 0; (index < 8) && (aSrc < srcEnd); index+= 4) + { + TInt col = TRgb::Color64K(*aSrc++).Color16(); + col <<= index; + *aDest |= col; + } + aDest++; + } + break; + } + case EUidPixelFormatL_2: + { + const TUint16* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *aDest = 0; + for (TInt index = 0; (index < 8) && (aSrc < srcEnd); index+= 2) + { + TInt col = TRgb::Color64K(*aSrc++).Gray4(); + col <<= index; + *aDest |= col; + } + aDest++; + } + break; + } + case EUidPixelFormatL_1: + { + const TUint16* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *aDest = 0; + for (TInt index = 0; (index < 8) && (aSrc < srcEnd); index++) + { + TInt col = TRgb::Color64K(*aSrc++).Gray2(); + col <<= index; + *aDest |= col; + } + aDest++; + } + break; + } + default: + break; + } + } + +// Helper function used to transfer a scanline in 16MAP to the various formats of the destination. +LOCAL_C void TransferScanLine16MAP(TUint8* aDest, const TUint32* aSrc, TUidPixelFormat aPixelFormatDest, TInt aPixelLength) + { + switch (aPixelFormatDest) + { + case EUidPixelFormatARGB_8888_PRE: + { + Mem::Copy(aDest, aSrc, aPixelLength << 2); + break; + } + case EUidPixelFormatARGB_8888: + { + TUint32* dest = reinterpret_cast(aDest); + const TUint32* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *dest++ = TRgb::Color16MAP(*aSrc++).Color16MA(); + } + break; + } + case EUidPixelFormatXRGB_8888: + { + TUint32* dest = reinterpret_cast(aDest); + const TUint32* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *dest++ = (TRgb::Color16MAP(*aSrc++).Color16MU() | 0xff000000); + } + break; + } + case EUidPixelFormatRGB_888: + { + const TUint32* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + TInt col = TRgb::Color16MAP(*aSrc++).Color16M(); + *aDest++ = col; + *aDest++ = col >> 8; + *aDest++ = col >> 16; + } + break; + } + case EUidPixelFormatRGB_565: + { + TUint16* dest = reinterpret_cast(aDest); + const TUint32* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *dest++ = TRgb::Color16MAP(*aSrc++).Color64K(); + } + break; + } + case EUidPixelFormatXRGB_4444: + { + TUint16* dest = reinterpret_cast(aDest); + const TUint32* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *dest++ = TRgb::Color16MAP(*aSrc++).Color4K(); + } + break; + } + case EUidPixelFormatP_8: + { + const TUint32* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *aDest++ = TRgb::Color16MAP(*aSrc++).Color256(); + } + break; + } + case EUidPixelFormatL_8: + { + const TUint32* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *aDest++ = TRgb::Color16MAP(*aSrc++).Gray256(); + } + break; + } + case EUidPixelFormatL_4: + { + const TUint32* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *aDest = 0; + for (TInt index = 0; (index < 8) && (aSrc < srcEnd); index+= 4) + { + TInt col = TRgb::Color16MAP(*aSrc++).Gray16(); + col <<= index; + *aDest |= col; + } + aDest++; + } + break; + } + case EUidPixelFormatP_4: + { + const TUint32* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *aDest = 0; + for (TInt index = 0; (index < 8) && (aSrc < srcEnd); index+= 4) + { + TInt col = TRgb::Color16MAP(*aSrc++).Color16(); + col <<= index; + *aDest |= col; + } + aDest++; + } + break; + } + case EUidPixelFormatL_2: + { + const TUint32* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *aDest = 0; + for (TInt index = 0; (index < 8) && (aSrc < srcEnd); index+= 2) + { + TInt col = TRgb::Color16MAP(*aSrc++).Gray4(); + col <<= index; + *aDest |= col; + } + aDest++; + } + break; + } + case EUidPixelFormatL_1: + { + const TUint32* srcEnd = aSrc + aPixelLength; + while (aSrc < srcEnd) + { + *aDest = 0; + for (TInt index = 0; (index < 8) && (aSrc < srcEnd); index++) + { + TInt col = TRgb::Color16MAP(*aSrc++).Gray2(); + col <<= index; + *aDest |= col; + } + aDest++; + } + } + default: + break; + } + } + +// Helper function used to copy a buffer in 64K to the various formats of the destination. +LOCAL_C TInt TransferPixels64K(TAny* aDataAddressDest, TInt aDataStrideDest, TUidPixelFormat aPixelFormatDest, + const TUint16* aDataAddressSrc, TInt aDataStrideSrc, const TRect& aRectSource) + { + TInt err = KErrNone; + const TInt width = aRectSource.Width(); + const TUint16* dataAddressSrc = PtrAdd(aDataAddressSrc + aRectSource.iTl.iX, aRectSource.iTl.iY * aDataStrideSrc); + const TUint16* dataAddressSrcEnd = PtrAdd(dataAddressSrc, aDataStrideSrc * aRectSource.Height()); + + switch (aPixelFormatDest) + { + case EUidPixelFormatRGB_565: + { + TUint8* dataAddressDest = static_cast(aDataAddressDest); + const TInt dataLength = width << 1; + while (dataAddressSrcEnd > dataAddressSrc) + { + Mem::Copy(dataAddressDest, dataAddressSrc, dataLength); + dataAddressSrc = PtrAdd(dataAddressSrc, aDataStrideSrc); + dataAddressDest += aDataStrideDest; + } + break; + } + case EUidPixelFormatARGB_8888_PRE: + case EUidPixelFormatARGB_8888: + case EUidPixelFormatXRGB_8888: + case EUidPixelFormatXRGB_4444: + case EUidPixelFormatL_1: + case EUidPixelFormatL_2: + case EUidPixelFormatL_4: + case EUidPixelFormatL_8: + case EUidPixelFormatP_4: + case EUidPixelFormatP_8: + case EUidPixelFormatRGB_888: + { + TUint8* dataAddressDest = static_cast(aDataAddressDest); + while (dataAddressSrcEnd > dataAddressSrc) + { + TransferScanLine64K(dataAddressDest, dataAddressSrc, aPixelFormatDest, width); + dataAddressSrc = PtrAdd(dataAddressSrc, aDataStrideSrc); + dataAddressDest += aDataStrideDest; + } + break; + } + default: + err = KErrNotSupported; + break; + } + return err; + } + +// Helper function used to copy a buffer in 16MAP to the various formats of the destination. +LOCAL_C TInt TransferPixels16MAP(TAny* aDataAddressDest, TInt aDataStrideDest, TUidPixelFormat aPixelFormatDest, + const TUint32* aDataAddressSrc, TInt aDataStrideSrc, const TRect& aRectSource) + { + TInt err = KErrNone; + const TInt width = aRectSource.Width(); + const TUint32* dataAddressSrc = PtrAdd(aDataAddressSrc + aRectSource.iTl.iX, aRectSource.iTl.iY * aDataStrideSrc); + const TUint32* dataAddressSrcEnd = PtrAdd(dataAddressSrc, aRectSource.Height() * aDataStrideSrc); + + switch (aPixelFormatDest) + { + case EUidPixelFormatARGB_8888_PRE: + { + TUint8* dataAddressDest = static_cast(aDataAddressDest); + const TInt dataLength = width << 2; + while (dataAddressSrcEnd > dataAddressSrc) + { + Mem::Copy(dataAddressDest, dataAddressSrc, dataLength); + dataAddressSrc = PtrAdd(dataAddressSrc, aDataStrideSrc); + dataAddressDest += aDataStrideDest; + } + break; + } + case EUidPixelFormatXRGB_8888: + case EUidPixelFormatARGB_8888: + case EUidPixelFormatRGB_565: + case EUidPixelFormatXRGB_4444: + case EUidPixelFormatL_1: + case EUidPixelFormatL_2: + case EUidPixelFormatL_4: + case EUidPixelFormatL_8: + case EUidPixelFormatP_4: + case EUidPixelFormatP_8: + case EUidPixelFormatRGB_888: + { + TUint8* dataAddressDest = static_cast (aDataAddressDest); + while (dataAddressSrcEnd > dataAddressSrc) + { + TransferScanLine16MAP(dataAddressDest, dataAddressSrc, aPixelFormatDest, width); + dataAddressSrc = PtrAdd(dataAddressSrc, aDataStrideSrc); + dataAddressDest += aDataStrideDest; + } + break; + } + default: + err = KErrNotSupported; + break; + } + return err; + } + + +/** +@publishedPartner +@prototype +@deprecated + +Convert from display mode to pixel format. + +@param aDisplayMode Display mode to convert. + +@return Pixel format corresponding to aDisplayMode, or EUidPixelFormatUnknown if aDisplayMode does not match any existing pixel format. +*/ +EXPORT_C TUidPixelFormat SgUtils::DisplayModeToPixelFormat(TDisplayMode aDisplayMode) + { + switch (aDisplayMode) + { + case EGray2: + return EUidPixelFormatL_1; + case EGray4: + return EUidPixelFormatL_2; + case EGray16: + return EUidPixelFormatL_4; + case EGray256: + return EUidPixelFormatL_8; + case EColor16: + return EUidPixelFormatP_4; + case EColor256: + return EUidPixelFormatP_8; + case EColor4K: + return EUidPixelFormatXRGB_4444; + case EColor64K: + return EUidPixelFormatRGB_565; + case EColor16M: + return EUidPixelFormatRGB_888; + case EColor16MU: + return EUidPixelFormatXRGB_8888; + case ERgb: + case EColor16MA: + return EUidPixelFormatARGB_8888; + case EColor16MAP: + return EUidPixelFormatARGB_8888_PRE; + default: + break; + } + return EUidPixelFormatUnknown; + } + + +/** +@publishedPartner +@prototype +@deprecated + +Convert from pixel format to display mode. + +@param aPixelFormat Pixel format to convert. + +@return Display mode corresponding to aPixelFormat, or ENone if aPixelFormat does not match any existing display mode. +*/ +EXPORT_C TDisplayMode SgUtils::PixelFormatToDisplayMode(TUidPixelFormat aPixelFormat) + { + switch (aPixelFormat) + { + case EUidPixelFormatL_1: + return EGray2; + case EUidPixelFormatL_2: + return EGray4; + case EUidPixelFormatL_4: + return EGray16; + case EUidPixelFormatL_8: + return EGray256; + case EUidPixelFormatP_4: + return EColor16; + case EUidPixelFormatP_8: + return EColor256; + case EUidPixelFormatXRGB_4444: + return EColor4K; + case EUidPixelFormatRGB_565: + return EColor64K; + case EUidPixelFormatRGB_888: + return EColor16M; + case EUidPixelFormatXRGB_8888: + return EColor16MU; + case EUidPixelFormatARGB_8888: + return EColor16MA; + case EUidPixelFormatARGB_8888_PRE: + return EColor16MAP; + default: + break; + } + return ENone; + } + + +/** +@publishedPartner +@prototype +@deprecated + +Calculates the minimum number of bytes between rows of data in a bi-dimensional pixel buffer. +The returned value is not guaranteed to be aligned onto any boundary. + +@param aWidth Width in pixels of the buffer. +@param aPixelFormat Pixel format of the buffer. +@return The minimum number of bytes between rows of data in a buffer with the given width and pixel format, + or KErrNotSupported if aPixelFormat is not recognized. +*/ +EXPORT_C TInt SgUtils::MinDataStride(TInt aWidth, TUidPixelFormat aPixelFormat) + { + switch (aPixelFormat) + { + case EUidPixelFormatXRGB_8888: + case EUidPixelFormatBGRX_8888: + case EUidPixelFormatXBGR_8888: + case EUidPixelFormatBGRA_8888: + case EUidPixelFormatARGB_8888: + case EUidPixelFormatABGR_8888: + case EUidPixelFormatARGB_8888_PRE: + case EUidPixelFormatABGR_8888_PRE: + case EUidPixelFormatBGRA_8888_PRE: + case EUidPixelFormatARGB_2101010: + case EUidPixelFormatABGR_2101010: + return aWidth << 2; + case EUidPixelFormatBGR_888: + case EUidPixelFormatRGB_888: + return aWidth * 3; + case EUidPixelFormatRGB_565: + case EUidPixelFormatBGR_565: + case EUidPixelFormatARGB_1555: + case EUidPixelFormatXRGB_1555: + case EUidPixelFormatARGB_4444: + case EUidPixelFormatARGB_8332: + case EUidPixelFormatBGRX_5551: + case EUidPixelFormatBGRA_5551: + case EUidPixelFormatBGRA_4444: + case EUidPixelFormatBGRX_4444: + case EUidPixelFormatAP_88: + case EUidPixelFormatXRGB_4444: + case EUidPixelFormatXBGR_4444: + return aWidth << 1; + case EUidPixelFormatRGB_332: + case EUidPixelFormatA_8: + case EUidPixelFormatBGR_332: + case EUidPixelFormatP_8: + case EUidPixelFormatL_8: + return aWidth; + case EUidPixelFormatP_4: + case EUidPixelFormatL_4: + return (aWidth + 1) >> 1; + case EUidPixelFormatP_2: + case EUidPixelFormatL_2: + return (aWidth + 3) >> 2; + case EUidPixelFormatP_1: + case EUidPixelFormatL_1: + return (aWidth + 7) >> 3; + default: + return KErrNotSupported; + } + } + + +/** +@publishedPartner +@prototype +@deprecated + +Transfer data from one bi-dimensional pixel buffer to another bi-dimensional pixel buffer with a different pixel format. +The pixel format conversion may involve some data loss. This function currently supports the following pixel formats. + - For the source: EUidPixelFormatRGB_565, EUidPixelFormatARGB_8888_PRE. + - For the destination: EUidPixelFormatARGB_8888_PRE, EUidPixelFormatARGB_8888, EUidPixelFormatXRGB_8888, EUidPixelFormatRGB_888, + EUidPixelFormatRGB_565, EUidPixelFormatXRGB_4444, EUidPixelFormatP_8, EUidPixelFormatL_8, EUidPixelFormatL_4, EUidPixelFormatP_4, + EUidPixelFormatL_2, EUidPixelFormatL_1. + +@param aDataAddressDest The base address of the destination pixel buffer. +@param aDataStrideDest The number of bytes between rows of data in the destination pixel buffer. +@param aPixelFormatDest Pixel format of the destination buffer. +@param aDataAddressSrc The base address of the source pixel buffer. +@param aDataStrideSrc The number of bytes between rows of data in the source pixel buffer. +@param aPixelFormatSrc Pixel format of the source buffer. +@param aRectSource Rectangle of the source pixel buffer which will be transferred to the destination pixel buffer. + +@return KErrNone if successful. +@return KErrArgument If arguments do not lie within expected range. +@return KErrNotSupported If source or destination format is not supported. +*/ +EXPORT_C TInt SgUtils::TransferPixels(TAny* aDataAddressDest, TInt aDataStrideDest, TUidPixelFormat aPixelFormatDest, + const TAny* aDataAddressSrc, TInt aDataStrideSrc, TUidPixelFormat aPixelFormatSrc, + const TRect& aRectSource) + { + if (aRectSource.IsEmpty() || !aDataAddressDest || !aDataAddressSrc || (aDataStrideDest <= 0) || (aDataStrideSrc <= 0) + || (SgUtils::MinDataStride(aRectSource.iBr.iX, aPixelFormatSrc) > aDataStrideSrc) + || (SgUtils::MinDataStride(aRectSource.Width(), aPixelFormatDest) > aDataStrideDest)) + { + return KErrArgument; + } + + TInt err = KErrNotSupported; + switch (aPixelFormatSrc) + { + case EUidPixelFormatRGB_565: + { + err = TransferPixels64K(aDataAddressDest, aDataStrideDest, aPixelFormatDest, + static_cast(aDataAddressSrc), aDataStrideSrc, aRectSource); + break; + } + case EUidPixelFormatARGB_8888_PRE: + { + err = TransferPixels16MAP(aDataAddressDest, aDataStrideDest, aPixelFormatDest, + static_cast(aDataAddressSrc), aDataStrideSrc, aRectSource); + break; + } + default: + break; + } + return err; + }