// 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