--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/imaging/imagingfws/src/ImageUtils.h Wed Aug 25 12:29:52 2010 +0300
@@ -0,0 +1,359 @@
+// Copyright (c) 2002-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:
+//
+
+#ifndef __ImageUtils_h
+#define __ImageUtils_h
+
+/*Template class CleanupResetAndDestroy
+ *
+ * Shamelessly copied from CleanupClose to clean up
+ * the array of implementation information from the cleanup stack.
+ */
+
+template <class T>
+class CleanupResetAndDestroy
+ {
+public:
+ inline static void PushL(T& aRef);
+private:
+ static void ResetAndDestroy(TAny *aPtr);
+ };
+template <class T>
+inline void CleanupResetAndDestroyPushL(T& aRef);
+
+
+template <class T>
+inline void CleanupResetAndDestroy<T>::PushL(T& aRef)
+ {CleanupStack::PushL(TCleanupItem(&ResetAndDestroy,&aRef));}
+template <class T>
+void CleanupResetAndDestroy<T>::ResetAndDestroy(TAny *aPtr)
+ {(STATIC_CAST(T*,aPtr))->ResetAndDestroy();}
+template <class T>
+inline void CleanupResetAndDestroyPushL(T& aRef)
+ {CleanupResetAndDestroy<T>::PushL(aRef);}
+
+//
+// PtrReadUtil - utility class with methods for standard
+// reading stuff from a TUint8* string
+//
+
+class PtrReadUtil
+ {
+public:
+ // This calls decode from TUint8*
+ static TInt8 ReadInt8(const TUint8* aPtr);
+ static TUint8 ReadUint8(const TUint8* aPtr);
+ static TInt16 ReadInt16(const TUint8* aPtr);
+ static TInt16 ReadBigEndianInt16(const TUint8* aPtr);
+ static TUint16 ReadUint16(const TUint8* aPtr);
+ static TUint16 ReadBigEndianUint16(const TUint8* aPtr);
+ static TInt32 ReadInt32(const TUint8* aPtr);
+ static TInt32 ReadBigEndianInt32(const TUint8* aPtr);
+ static TUint32 ReadUint32(const TUint8* aPtr);
+ static TUint32 ReadBigEndianUint32(const TUint8* aPtr);
+ // these calls also increment the pointer
+ static TInt8 ReadInt8Inc(const TUint8*& aPtr);
+ static TUint8 ReadUint8Inc(const TUint8*& aPtr);
+ static TInt16 ReadInt16Inc(const TUint8*& aPtr);
+ static TInt16 ReadBigEndianInt16Inc(const TUint8*& aPtr);
+ static TUint16 ReadUint16Inc(const TUint8*& aPtr);
+ static TUint16 ReadBigEndianUint16Inc(const TUint8*& aPtr);
+ static TInt32 ReadInt32Inc(const TUint8*& aPtr);
+ static TInt32 ReadBigEndianInt32Inc(const TUint8*& aPtr);
+ static TUint32 ReadUint32Inc(const TUint8*& aPtr);
+ static TUint32 ReadBigEndianUint32Inc(const TUint8*& aPtr);
+ };
+
+inline TUint8 PtrReadUtil::ReadUint8(const TUint8* aPtr)
+ {
+ return *aPtr ;
+ }
+
+inline TInt8 PtrReadUtil::ReadInt8(const TUint8* aPtr)
+ {
+ return TInt8(ReadUint8(aPtr));
+ }
+
+inline TUint16 PtrReadUtil::ReadUint16(const TUint8* aPtr)
+ {
+ return TUint16(aPtr[0] | (aPtr[1]<<8));
+ }
+
+inline TInt16 PtrReadUtil::ReadInt16(const TUint8* aPtr)
+ {
+ return TInt16(ReadUint16(aPtr));
+ }
+
+inline TUint32 PtrReadUtil::ReadUint32(const TUint8* aPtr)
+ {
+ return TUint32(aPtr[0] | (aPtr[1]<<8) | (aPtr[2]<<16) | (aPtr[3]<<24));
+ }
+
+inline TInt32 PtrReadUtil::ReadInt32(const TUint8* aPtr)
+ {
+ return TInt32(ReadUint32(aPtr));
+ }
+
+inline TUint16 PtrReadUtil::ReadBigEndianUint16(const TUint8* aPtr)
+ {
+ return TUint16((aPtr[0]<<8) | aPtr[1]);
+ }
+
+inline TInt16 PtrReadUtil::ReadBigEndianInt16(const TUint8* aPtr)
+ {
+ return TInt16(ReadBigEndianUint16(aPtr));
+ }
+
+inline TUint32 PtrReadUtil::ReadBigEndianUint32(const TUint8* aPtr)
+ {
+ return TUint32((aPtr[0]<<24) | (aPtr[1]<<16) | (aPtr[2]<<8) | aPtr[3]);
+ }
+
+inline TInt32 PtrReadUtil::ReadBigEndianInt32(const TUint8* aPtr)
+ {
+ return TInt32(ReadBigEndianInt32(aPtr));
+ }
+
+inline TInt8 PtrReadUtil::ReadInt8Inc(const TUint8*& aPtr)
+ {
+ TInt8 result = ReadInt8(aPtr);
+ aPtr += 1;
+ return result;
+ }
+
+inline TUint8 PtrReadUtil::ReadUint8Inc(const TUint8*& aPtr)
+ {
+ TUint8 result = ReadUint8(aPtr);
+ aPtr += 1;
+ return result;
+ }
+
+inline TInt16 PtrReadUtil::ReadInt16Inc(const TUint8*& aPtr)
+ {
+ TInt16 result = ReadInt16(aPtr);
+ aPtr += 2;
+ return result;
+ }
+
+inline TUint16 PtrReadUtil::ReadUint16Inc(const TUint8*& aPtr)
+ {
+ TUint16 result = ReadUint16(aPtr);
+ aPtr += 2;
+ return result;
+ }
+
+inline TInt16 PtrReadUtil::ReadBigEndianInt16Inc(const TUint8*& aPtr)
+ {
+ TInt16 result = ReadBigEndianInt16(aPtr);
+ aPtr += 2;
+ return result;
+ }
+
+inline TUint16 PtrReadUtil::ReadBigEndianUint16Inc(const TUint8*& aPtr)
+ {
+ TUint16 result = ReadBigEndianUint16(aPtr);
+ aPtr += 2;
+ return result;
+ }
+
+inline TInt32 PtrReadUtil::ReadInt32Inc(const TUint8*& aPtr)
+ {
+ TInt32 result = ReadInt32(aPtr);
+ aPtr += 4;
+ return result;
+ }
+
+inline TUint32 PtrReadUtil::ReadUint32Inc(const TUint8*& aPtr)
+ {
+ TUint32 result = ReadUint32(aPtr);
+ aPtr += 4;
+ return result;
+ }
+
+inline TInt32 PtrReadUtil::ReadBigEndianInt32Inc(const TUint8*& aPtr)
+ {
+ TInt32 result = ReadBigEndianInt32(aPtr);
+ aPtr += 4;
+ return result;
+ }
+
+inline TUint32 PtrReadUtil::ReadBigEndianUint32Inc(const TUint8*& aPtr)
+ {
+ TUint32 result = ReadBigEndianUint32(aPtr);
+ aPtr += 4;
+ return result;
+ }
+
+class PtrWriteUtil
+ {
+public:
+ static void WriteInt8(TUint8* aPtr, TInt aData);
+ static void WriteInt16(TUint8* aPtr, TInt aData);
+ static void WriteInt32(TUint8* aPtr, TInt aData);
+ // Big endian version
+ static void WriteBigEndianInt32(TUint8* aPtr, TInt32 aData);
+ static void WriteBigEndianInt16(TUint8* aPtr, TInt aData);
+ };
+
+inline void PtrWriteUtil::WriteInt8(TUint8* aPtr, TInt aData)
+ {
+ aPtr[0] = TUint8(aData);
+ }
+
+inline void PtrWriteUtil::WriteInt16(TUint8* aPtr, TInt aData)
+ {
+ aPtr[0] = TUint8(aData);
+ aPtr[1] = TUint8(aData>>8);
+ }
+
+inline void PtrWriteUtil::WriteInt32(TUint8* aPtr, TInt aData)
+ {
+ aPtr[0] = TUint8(aData);
+ aPtr[1] = TUint8(aData>>8);
+ aPtr[2] = TUint8(aData>>16);
+ aPtr[3] = TUint8(aData>>24);
+ }
+
+inline void PtrWriteUtil::WriteBigEndianInt32(TUint8* aPtr, TInt32 aData)
+ {
+ aPtr[0] = TUint8(aData>>24);
+ aPtr[1] = TUint8(aData>>16);
+ aPtr[2] = TUint8(aData>>8);
+ aPtr[3] = TUint8(aData);
+ }
+
+inline void PtrWriteUtil::WriteBigEndianInt16(TUint8* aPtr, TInt aData)
+ {
+ aPtr[0] = TUint8(aData>>8);
+ aPtr[1] = TUint8(aData);
+ }
+
+class ColorCcomponent
+ {
+public:
+ static TInt ClampColorComponent(TInt value);
+ };
+
+inline TInt ColorCcomponent::ClampColorComponent(TInt value)
+ {
+ return (value < 0) ? 0 : (value > 255) ? 255 : value;
+ }
+
+
+//
+// The following routines have been copied from Graphics subsystem.
+// They deal with alpha to premultiplied alpha and viceversa conversions.
+// The original files are: blendingalgorithms.h and blendingalgorithms.inl
+//
+
+const TUint32 KRBMask = 0x00ff00ff;
+const TUint32 KAGMask = 0xff00ff00;
+const TUint32 KGMask = 0x0000ff00;
+const TUint32 KAMask = 0xff000000;
+const TUint32 KRBBias = 0x00800080;
+const TUint32 KGBias = 0x00008000;
+
+
+/**
+Premultiplies the color channel values with the Alpha channel value.
+Alpha value remains unchanged. An approximation is used in the operation where the division
+by 255 is approximated by a shift-by-8-bits operation (i.e. division by 256).
+@param aPixel The 32 bit pixel value to be pre-multiplied.
+@return The PMA value.
+@internalTechnology
+@released
+*/
+inline TUint32 NonPMA2PMAPixel(TUint32 aPixel)
+ {
+ TUint8 tA = (TUint8)(aPixel >> 24);
+ if (tA==0)
+ {
+ return 0;
+ }
+ if (tA==0xff)
+ {
+ return aPixel;
+ }
+
+ // Use a bias value of 128 rather than 255, but also add 1/256 of the numerator
+ // before dividing the sum by 256.
+
+ TUint32 scaledRB = (aPixel & KRBMask) * tA + KRBBias;
+ scaledRB = (scaledRB + ( (scaledRB >> 8) & KRBMask) ) >> 8;
+ TUint32 scaledG = (aPixel & KGMask ) * tA + KGBias;
+ scaledG = (scaledG + (scaledG >> 8)) >> 8;
+
+ return (aPixel & KAMask) | (scaledRB & KRBMask) | (scaledG & KGMask);
+ }
+
+
+/**
+Divives the PMA pixel color channels with the Alpha value, to convert them to non-PMA format.
+Alpha value remains unchanged.
+@param aPixel the premultiplied 32 bit pixel value.
+@param aNormTable The lookup table used to do the normalisation (the table converts the division
+ to multiplication operation).
+ The table is usually obtainable by a call to the method:
+ PtrTo16BitNormalisationTable, which is defined in lookuptable.dll(.lib).
+ The lookup table for normalised alpha is compluted using this equation:
+ Table[index] = (255*256) / index (where index is an 8 bit value).
+@return The NON-PMA 32 bit pixel value.
+@internalTechnology
+@released
+*/
+inline TUint32 PMA2NonPMAPixel(TUint32 aPixel, const TUint16* aNormTable)
+ {
+ TUint8 alpha = (TUint8)(aPixel >> 24);
+ if (alpha==0)
+ {
+ return 0;
+ }
+ if (alpha==0xff)
+ {
+ return aPixel;
+ }
+ TUint16 norm = aNormTable[alpha];
+ TUint32 norm_rb = (((aPixel & KRBMask) * norm) >> 8) & KRBMask;
+ TUint32 norm_g = (((aPixel & KGMask ) * norm) >> 8) & KGMask;
+
+ return ((aPixel & KAMask) | norm_rb | norm_g);
+ }
+
+
+/**
+In-place version of NonPMA2PMAPixel.
+@see NonPMA2PMAPixel
+@internalTechnology
+@released
+*/
+inline void Convert2PMA(TUint32& aInOutValue)
+ {
+ aInOutValue = NonPMA2PMAPixel(aInOutValue);
+ }
+
+
+/**
+In-place version of PMA2NonPMAPixel
+@see PMA2NonPMAPixel
+@internalTechnology
+@released
+*/
+inline void Convert2NonPMA(TUint32& aInOutValue, const TUint16* aNormTable)
+ {
+ aInOutValue = PMA2NonPMAPixel(aInOutValue, aNormTable);
+ }
+
+
+#endif // __ImageUtils_h