/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014 Raytrix GmbH. All rights reserved.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "Rx.InlinePixel.h"

#include "Rx.Core.Development/RxDefines.h"

#include "Rx.Core.Math/RxFixedVectorTypes.h"
#include "Rx.Core.Math/RxInlineMath.h"

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// namespace: Rx
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace Rx
{
	typedef uchar1 TTexRaw_TPixel_Bay_BG_uc;
	typedef uchar1 TTexRaw_TPixel_Bay_GB_uc;
	typedef uchar1 TTexRaw_TPixel_Bay_GR_uc;
	typedef uchar1 TTexRaw_TPixel_Bay_RG_uc;
	typedef uchar1 TTexRaw_TPixel_L_uc;
	typedef uchar2 TTexRaw_TPixel_LA_uc;
	typedef uchar4 TTexRaw_TPixel_RGBA_uc;
	typedef uchar4 TTexRaw_TPixel_BGRA_uc;
	typedef ushort1 TTexRaw_TPixel_L_us;
	typedef ushort2 TTexRaw_TPixel_LA_us;
	typedef ushort4 TTexRaw_TPixel_RGBA_us;
	typedef ushort4 TTexRaw_TPixel_BGRA_us;
	typedef float1 TTexRaw_TPixel_L_f;
	typedef float2 TTexRaw_TPixel_LA_f;
	typedef float4 TTexRaw_TPixel_RGBA_f;
	typedef float4 TTexRaw_TPixel_BGRA_f;

	typedef float1 TTexNorm_TPixel_Bay_BG_uc;
	typedef float1 TTexNorm_TPixel_Bay_GB_uc;
	typedef float1 TTexNorm_TPixel_Bay_GR_uc;
	typedef float1 TTexNorm_TPixel_Bay_RG_uc;
	typedef float1 TTexNorm_TPixel_L_uc;
	typedef float1 TTexNorm_TPixel_L_f;
	typedef float1 TTexNorm_TPixel_L_us;
	typedef float2 TTexNorm_TPixel_LA_uc;
	typedef float2 TTexNorm_TPixel_LA_f;
	typedef float2 TTexNorm_TPixel_LA_us;
	typedef float4 TTexNorm_TPixel_RGBA_uc;
	typedef float4 TTexNorm_TPixel_BGRA_uc;
	typedef float4 TTexNorm_TPixel_RGBA_f;
	typedef float4 TTexNorm_TPixel_BGRA_f;
	typedef float4 TTexNorm_TPixel_RGBA_us;
	typedef float4 TTexNorm_TPixel_BGRA_us;

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(short& rPx, short shVal)
	{
		rPx = shVal;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(char& rPx, float fVal)
	{
		if (fVal > 0.0f)
		{
			fVal *= float(CHAR_MAX);
		}
		else
		{
			fVal *= -float(CHAR_MIN);
		}

		if (fVal > float(CHAR_MAX))
		{
			rPx = (char) CHAR_MAX;
		}
		else if (fVal < float(CHAR_MIN))
		{
			rPx = (char) CHAR_MIN;
		}
		else
		{
			rPx = (char) fVal;
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(unsigned char& ucPixel, unsigned char ucVal)
	{
		ucPixel = ucVal;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	Converts a value of type float to given pixel value type [float --> uchar].
	/// </summary>
	///
	/// <param name="ucPixel"> [out] The pixel value as uchar. </param>
	/// <param name="fVal">    The float value. </param>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(unsigned char& ucPixel, float fVal)
	{
		ucPixel = (unsigned char) (clamp(fVal * float(UCHAR_MAX), 0.0f, float(UCHAR_MAX)));
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(short& rPx, float fVal)
	{
		if (fVal > 0.0f)
		{
			fVal *= float(SHRT_MAX);
		}
		else
		{
			fVal *= -float(SHRT_MIN);
		}

		if (fVal > float(SHRT_MAX))
		{
			rPx = (short) SHRT_MAX;
		}
		else if (fVal < float(SHRT_MIN))
		{
			rPx = (short) SHRT_MIN;
		}
		else
		{
			rPx = (short) fVal;
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(unsigned short& rPx, float fValue)
	{
		rPx = (unsigned short) (clamp(fValue * float(USHRT_MAX), 0.0f, float(USHRT_MAX)));
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(int& rPx, float fVal)
	{
		if (fVal > 0.0f)
		{
			fVal *= float(INT_MAX);
		}
		else
		{
			fVal *= -float(INT_MIN);
		}

		if (fVal > float(INT_MAX))
		{
			rPx = (int) INT_MAX;
		}
		else if (fVal < float(INT_MIN))
		{
			rPx = (int) INT_MIN;
		}
		else
		{
			rPx = (int) fVal;
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(unsigned int& rPx, float fVal)
	{
		fVal *= float(UINT_MAX);

		if (fVal > float(UINT_MAX))
		{
			rPx = (unsigned int) UINT_MAX;
		}
		else if (fVal < 0.0f)
		{
			rPx = 0;
		}
		else
		{
			rPx = (unsigned int) fVal;
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(float& rPx, float fVal)
	{
		rPx = fVal;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(double& rPx, float fVal)
	{
		rPx = double(fVal);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(char& rPx, double fVal)
	{
		if (fVal > 0.0f)
		{
			fVal *= double(CHAR_MAX);
		}
		else
		{
			fVal *= -double(CHAR_MIN);
		}

		if (fVal > double(CHAR_MAX))
		{
			rPx = (char) CHAR_MAX;
		}
		else if (fVal < double(CHAR_MIN))
		{
			rPx = (char) CHAR_MIN;
		}
		else
		{
			rPx = (char) fVal;
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(unsigned char& rPx, double fVal)
	{
		fVal *= double(UCHAR_MAX);

		if (fVal > double(UCHAR_MAX))
		{
			rPx = (unsigned char) UCHAR_MAX;
		}
		else if (fVal < 0.0f)
		{
			rPx = 0;
		}
		else
		{
			rPx = (unsigned char) fVal;
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(short& rPx, double fVal)
	{
		if (fVal > 0.0f)
		{
			fVal *= double(SHRT_MAX);
		}
		else
		{
			fVal *= -double(SHRT_MIN);
		}

		if (fVal > double(SHRT_MAX))
		{
			rPx = (short) SHRT_MAX;
		}
		else if (fVal < double(SHRT_MIN))
		{
			rPx = (short) SHRT_MIN;
		}
		else
		{
			rPx = (short) fVal;
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(unsigned short& rPx, double dValue)
	{
		rPx = (unsigned short) (clamp(dValue * double(USHRT_MAX), 0.0, double(USHRT_MAX)));
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(int& rPx, double fVal)
	{
		if (fVal > 0.0f)
		{
			fVal *= double(INT_MAX);
		}
		else
		{
			fVal *= -double(INT_MIN);
		}

		if (fVal > double(INT_MAX))
		{
			rPx = (int) INT_MAX;
		}
		else if (fVal < double(INT_MIN))
		{
			rPx = (int) INT_MIN;
		}
		else
		{
			rPx = (int) fVal;
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(unsigned int& rPx, double fVal)
	{
		fVal *= double(UINT_MAX);

		if (fVal > double(UINT_MAX))
		{
			rPx = (unsigned int) UINT_MAX;
		}
		else if (fVal < 0.0f)
		{
			rPx = 0;
		}
		else
		{
			rPx = (unsigned int) fVal;
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(float& rPx, double fVal)
	{
		rPx = float(fVal);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Float2Pixel(double& rPx, double fVal)
	{
		rPx = double(fVal);
	}

	/************************************************************************/
	/* Pixel2Float                                                          */
	/************************************************************************/

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ float Pixel2Float(char tPixelValue)
	{
		return (tPixelValue > 0) * (float(tPixelValue) / float(CHAR_MAX)) + (tPixelValue <= 0) * (-float(tPixelValue) / float(CHAR_MIN));
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ float Pixel2Float(unsigned char tPixelValue)
	{
		return float(tPixelValue) / float(UCHAR_MAX);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ float Pixel2Float(short tPixelValue)
	{
		return (tPixelValue > 0) ? float(tPixelValue) / float(SHRT_MAX) : -float(tPixelValue) / float(SHRT_MIN);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ float Pixel2Float(unsigned short tPixelValue)
	{
		return float(tPixelValue) / float(USHRT_MAX);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ float Pixel2Float(int tPixelValue)
	{
		return (tPixelValue > 0) ? float(tPixelValue) / float(INT_MAX) : -float(tPixelValue) / float(INT_MIN);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ float Pixel2Float(unsigned int tPixelValue)
	{
		return float(tPixelValue) / float(UINT_MAX);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ float Pixel2Float(float tPixelValue)
	{
		return tPixelValue;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ float Pixel2Float(double tPixelValue)
	{
		return (float) tPixelValue;
	}

	/************************************************************************/
	/* Pixel2Float                                                          */
	/************************************************************************/

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(float& fVal, char rPx)
	{
		fVal = (rPx > char(0)) * (float(rPx) / float(CHAR_MAX)) + (rPx <= char(0)) * (-float(rPx) / float(CHAR_MIN));
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(float& fVal, unsigned char rPx)
	{
		fVal = float(rPx) / float(UCHAR_MAX);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(float& fVal, short rPx)
	{
		if (rPx > short(0))
		{
			fVal = float(rPx) / float(SHRT_MAX);
		}
		else
		{
			fVal = -float(rPx) / float(SHRT_MIN);
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(float& fVal, unsigned short rPx)
	{
		fVal = float(rPx) / float(USHRT_MAX);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(float& fVal, int rPx)
	{
		if (rPx > int(0))
		{
			fVal = float(rPx) / float(INT_MAX);
		}
		else
		{
			fVal = -float(rPx) / float(INT_MIN);
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(float& fVal, unsigned int rPx)
	{
		fVal = float(rPx) / float(UINT_MAX);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(float& fVal, float rPx)
	{
		fVal = rPx;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(float& fVal, double rPx)
	{
		fVal = float(rPx);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(double& dFloat, char cPixel)
	{
		if (cPixel > char(0))
		{
			dFloat = double(cPixel) / double(CHAR_MAX);
		}
		else
		{
			dFloat = -double(cPixel) / double(CHAR_MIN);
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(double& dFloat, unsigned char ucPixel)
	{
		dFloat = double(ucPixel) / double(UCHAR_MAX);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(double& dFloat, short sPixel)
	{
		if (sPixel > short(0))
		{
			dFloat = double(sPixel) / double(SHRT_MAX);
		}
		else
		{
			dFloat = -double(sPixel) / double(SHRT_MIN);
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(double& dFloat, unsigned short usPixel)
	{
		dFloat = double(usPixel) / double(USHRT_MAX);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(double& dFloat, int iPixel)
	{
		if (iPixel > int(0))
		{
			dFloat = double(iPixel) / double(INT_MAX);
		}
		else
		{
			dFloat = -double(iPixel) / double(INT_MIN);
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(double& dFloat, unsigned int uPixel)
	{
		dFloat = double(uPixel) / double(UINT_MAX);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(double& fFloat, float fPixel)
	{
		fFloat = (double) fPixel;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ void Pixel2Float(double& dFloat, double dPixel)
	{
		dFloat = (double) dPixel;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T, class TPix>
	__HDINL__ tvec4<T> ToColor(const float1& vfCol)
	{
		T tL;
		Float2Pixel(tL, vfCol.x);

		return tvec4<T>(tL, tL, tL, T(1));
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T, class TPix>
	__HDINL__ tvec4<T> ToColor(const float2& vfCol)
	{
		const float* pfC = (const float*) &vfCol;

		T tL, tA;
		Float2Pixel(tL, pfC[TPix::iRedIdx]);
		Float2Pixel(tA, pfC[TPix::iAlphaIdx]);

		return tvec4<T>(tL, tL, tL, tA);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T, class TPix>
	__HDINL__ tvec4<T> ToColor(const float3& vfCol)
	{
		const float* pfC = (const float*) &vfCol;

		T tR, tG, tB;
		Float2Pixel(tR, pfC[TPix::iRedIdx]);
		Float2Pixel(tG, pfC[TPix::iGreenIdx]);
		Float2Pixel(tB, pfC[TPix::iBlueIdx]);

		return tvec4<T>(tR, tG, tB, T(1));
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T, class TPix>
	__HDINL__ tvec4<T> ToColor(const float4& vfCol)
	{
		const float* pfC = (const float*) &vfCol;

		T tR, tG, tB, tA;
		Float2Pixel(tR, pfC[TPix::iRedIdx]);
		Float2Pixel(tG, pfC[TPix::iGreenIdx]);
		Float2Pixel(tB, pfC[TPix::iBlueIdx]);
		Float2Pixel(tA, pfC[TPix::iAlphaIdx]);

		return tvec4<T>(tR, tG, tB, tA);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T, class TPix>
	__HDINL__ tvec4<T> ToColor(const uchar1& vCol)
	{
		T fL;
		Pixel2Float(fL, vCol.x);

		return tvec4<T>(fL, fL, fL, T(1.0));
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T, class TPix>
	__HDINL__ tvec4<T> ToColor(const uchar2& vCol)
	{
		const unsigned char* puC = (const unsigned char*) &vCol;

		T fL, fA;
		Pixel2Float(fL, puC[TPix::iRedIdx]);
		Pixel2Float(fA, puC[TPix::iAlphaIdx]);

		return tvec4<T>(fL, fL, fL, fA);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T, class TPix>
	__HDINL__ tvec4<T> ToColor(const uchar3& vCol)
	{
		const unsigned char* puC = (const unsigned char*) &vCol;

		T fR, fG, fB;
		Pixel2Float(fR, puC[TPix::iRedIdx]);
		Pixel2Float(fG, puC[TPix::iGreenIdx]);
		Pixel2Float(fB, puC[TPix::iBlueIdx]);

		return tvec4<T>(fR, fG, fB, T(1.0));
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T, class TPix>
	__HDINL__ tvec4<T> ToColor(const uchar4& vCol)
	{
		const unsigned char* puC = (const unsigned char*) &vCol;

		T fR, fG, fB, fA;
		Pixel2Float(fR, puC[TPix::iRedIdx]);
		Pixel2Float(fG, puC[TPix::iGreenIdx]);
		Pixel2Float(fB, puC[TPix::iBlueIdx]);
		Pixel2Float(fA, puC[TPix::iAlphaIdx]);

		return tvec4<T>(fR, fG, fB, fA);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T, class TPix>
	__HDINL__ tvec4<T> ToColor(const ushort1& vCol)
	{
		T fL;
		Pixel2Float(fL, vCol.x);

		return tvec4<T>(fL, fL, fL, T(1.0));
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T, class TPix>
	__HDINL__ tvec4<T> ToColor(const ushort2& vCol)
	{
		const unsigned short* puC = (const unsigned short*) &vCol;

		T fL, fA;
		Pixel2Float(fL, puC[TPix::iRedIdx]);
		Pixel2Float(fA, puC[TPix::iAlphaIdx]);

		return tvec4<T>(fL, fL, fL, fA);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T, class TPix>
	__HDINL__ tvec4<T> ToColor(const ushort3& vCol)
	{
		const unsigned short* puC = (const unsigned short*) &vCol;

		T fR, fG, fB;
		Pixel2Float(fR, puC[TPix::iRedIdx]);
		Pixel2Float(fG, puC[TPix::iGreenIdx]);
		Pixel2Float(fB, puC[TPix::iBlueIdx]);

		return tvec4<T>(fR, fG, fB, T(1.0));
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T, class TPix>
	__HDINL__ tvec4<T> ToColor(const ushort4& vCol)
	{
		const unsigned short* puC = (const unsigned short*) &vCol;

		T fR, fG, fB, fA;
		Pixel2Float(fR, puC[TPix::iRedIdx]);
		Pixel2Float(fG, puC[TPix::iGreenIdx]);
		Pixel2Float(fB, puC[TPix::iBlueIdx]);
		Pixel2Float(fA, puC[TPix::iAlphaIdx]);

		return tvec4<T>(fR, fG, fB, fA);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class TPix>
	__HDINL__ tvec4<unsigned char> ToColor(const uchar1& vCol)
	{
		return tvec4<unsigned char>(vCol.x, vCol.x, vCol.x, (unsigned char) 255);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class TPix>
	__HDINL__ tvec4<unsigned char> ToColor(const uchar2& vCol)
	{
		return tvec4<unsigned char>(vCol.x, vCol.x, vCol.x, vCol.y);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class TPix>
	__HDINL__ tvec4<unsigned char> ToColor(const uchar3& vCol)
	{
		return tvec4<unsigned char>(vCol.x, vCol.y, vCol.z, (unsigned char) 255);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class TPix>
	__HDINL__ tvec4<unsigned char> ToColor(const uchar4& vCol)
	{
		return tvec4<unsigned char>(vCol.x, vCol.y, vCol.z, vCol.w);
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class TPix, class T>
	__HDINL__ void Vec2Pix(TPix& rPix, const T& vfPix)
	{
		// This conditional should be decided by compiler since we test static constant template value.
		if (TPix::uColorCnt == 1)
		{
			Float2Pixel(rPix.r(), vfPix);
		}
		else if (TPix::uColorCnt == 3)
		{
			Float2Pixel(rPix.r(), vfPix);
			Float2Pixel(rPix.g(), vfPix);
			Float2Pixel(rPix.b(), vfPix);
		}

		if (TPix::uAlphaCnt == 1)
		{
			Float2Pixel(rPix.a(), 1.0f);
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class TPix, class T>
	__HDINL__ void Vec2Pix(TPix& rPix, const tvec2<T>& vfPix)
	{
		// This conditional should be decided by compiler since we test static constant template value.
		// Disable warning messages 4127 (conditional expression is constant)
		#pragma warning( disable : 4127 )
		if (TPix::uColorCnt == 1)
		{
			Float2Pixel(rPix.r(), vfPix.x);
		}
		else if (TPix::uColorCnt == 3)
		{
			Float2Pixel(rPix.r(), vfPix.x);
			Float2Pixel(rPix.g(), vfPix.x);
			Float2Pixel(rPix.b(), vfPix.x);
		}

		if (TPix::uAlphaCnt == 1)
		{
			Float2Pixel(rPix.a(), vfPix.y);
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class TPix, class T>
	__HDINL__ void Vec2Pix(TPix& rPix, const tvec3<T>& vfPix)
	{
		// This conditional should be decided by compiler since we test static constant template value.
		// Disable warning messages 4127 (conditional expression is constant)
		#pragma warning( disable : 4127 )
		if (TPix::uColorCnt == 1)
		{
			Float2Pixel(rPix.r(), vfPix.x);
		}
		else if (TPix::uColorCnt == 3)
		{
			Float2Pixel(rPix.r(), vfPix.x);
			Float2Pixel(rPix.g(), vfPix.y);
			Float2Pixel(rPix.b(), vfPix.z);
		}

		if (TPix::uAlphaCnt == 1)
		{
			Float2Pixel(rPix.a(), 1.0f);
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class TPix, class T>
	__HDINL__ void Vec2Pix(TPix& rPix, const tvec4<T>& vfPix)
	{
		// This conditional should be decided by compiler since we test static constant template value.
		if (TPix::uColorCnt == 1)
		{
			Float2Pixel(rPix.r(), vfPix.x);
		}
		else if (TPix::uColorCnt == 3)
		{
			Float2Pixel(rPix.r(), vfPix.x);
			Float2Pixel(rPix.g(), vfPix.y);
			Float2Pixel(rPix.b(), vfPix.z);
		}

		if (TPix::uAlphaCnt == 1)
		{
			Float2Pixel(rPix.a(), vfPix.w);
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class TPix, class T>
	__HDINL__ void Pix2Vec(T& vfPix, const TPix& rPix)
	{
		Pixel2Float(vfPix, rPix.r());
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class TPix, class T>
	__HDINL__ void Pix2Vec(tvec3<T>& vfPix, const TPix& rPix)
	{
		// This conditional should be decided by compiler since we test static constant template value.
		// Disable warning messages 4127 (conditional expression is constant)
		#pragma warning( disable : 4127 )
		if (TPix::uColorCnt == 1)
		{
			Pixel2Float(vfPix.x, rPix.r());
			Pixel2Float(vfPix.y, rPix.r());
			Pixel2Float(vfPix.z, rPix.r());
		}
		else if (TPix::uColorCnt == 3)
		{
			Pixel2Float(vfPix.x, rPix.r());
			Pixel2Float(vfPix.y, rPix.g());
			Pixel2Float(vfPix.z, rPix.b());
		}
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class TPix, class T>
	__HDINL__ void Pix2Vec(tvec4<T>& vfPix, const TPix& rPix)
	{
		// This conditional should be decided by compiler since we test static constant template value.
		if (TPix::uColorCnt == 1)
		{
			Pixel2Float(vfPix.x, rPix.r());
			Pixel2Float(vfPix.y, rPix.r());
			Pixel2Float(vfPix.z, rPix.r());
		}
		else if (TPix::uColorCnt == 3)
		{
			Pixel2Float(vfPix.x, rPix.r());
			Pixel2Float(vfPix.y, rPix.g());
			Pixel2Float(vfPix.z, rPix.b());
		}

		if (TPix::uAlphaCnt == 1)
		{
			Pixel2Float(vfPix.w, rPix.a());
		}
		else
		{
			vfPix.w = T(1);
		}
	}

	#pragma region "Pixel to Raw"

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	Converts TPixel_RGBA_uc to uchar4.
	/// </summary>
	///
	/// <param name="tPixel">	TPixel_RGBA_uc. </param>
	///
	/// <returns>	uchar4. </returns>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ uchar4 PixelToRaw(const TPixel_RGBA_uc& tPixel)
	{
		uchar4 uc4;
		uc4.x = tPixel.r();
		uc4.y = tPixel.g();
		uc4.z = tPixel.b();
		uc4.w = tPixel.a();
		return uc4;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	Converts TPixel_BGRA_uc to uchar4.
	/// </summary>
	///
	/// <param name="tPixel">	TPixel_BGRA_uc. </param>
	///
	/// <returns>	uchar4. </returns>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ uchar4 PixelToRaw(const TPixel_BGRA_uc& tPixel)
	{
		uchar4 uc4;
		uc4.x = tPixel.r();
		uc4.y = tPixel.g();
		uc4.z = tPixel.b();
		uc4.w = tPixel.a();
		return uc4;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	Converts TPixel_L_uc to uchar1.
	/// </summary>
	///
	/// <param name="tPixel">	TPixel_L_uc. </param>
	///
	/// <returns>	uchar1. </returns>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ uchar1 PixelToRaw(const TPixel_L_uc& tPixel)
	{
		uchar1 uc1;
		uc1.x = tPixel.r();
		return uc1;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	Converts TPixel_L_s to short1.
	/// </summary>
	///
	/// <param name="tPixel">	TPixel_L_s. </param>
	///
	/// <returns>	short1. </returns>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ short1 PixelToRaw(const TPixel_L_s& tPixel)
	{
		short1 s1;
		s1.x = tPixel.r();
		return s1;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	Converts TPixel_L_us to ushort1.
	/// </summary>
	///
	/// <param name="tPixel">	TPixel_L_us. </param>
	///
	/// <returns>	ushort1. </returns>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ ushort1 PixelToRaw(const TPixel_L_us& tPixel)
	{
		ushort1 us1;
		us1.x = tPixel.r();
		return us1;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	Converts TPixel_L_ui to uint1.
	/// </summary>
	///
	/// <param name="tPixel">	TPixel_L_ui. </param>
	///
	/// <returns>	uint1. </returns>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ uint1 PixelToRaw(const TPixel_L_ui& tPixel)
	{
		uint1 ui1;
		ui1.x = tPixel.r();
		return ui1;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	Converts TPixel_L_f to float1.
	/// </summary>
	///
	/// <param name="tPixel">	TPixel_L_f. </param>
	///
	/// <returns>	float1. </returns>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ float1 PixelToRaw(const TPixel_L_f& tPixel)
	{
		float1 f1;
		f1.x = tPixel.r();
		return f1;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	Converts TPixel_RGB_f to float3.
	/// </summary>
	///
	/// <param name="tPixel">	TPixel_RGB_f. </param>
	///
	/// <returns>	float3. </returns>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ float3 PixelToRaw(const TPixel_RGB_f& tPixel)
	{
		float3 f3;
		f3.x = tPixel.r();
		f3.y = tPixel.g();
		f3.z = tPixel.b();
		return f3;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	Converts TPixel_RGBA_f to float4.
	/// </summary>
	///
	/// <param name="tPixel">	TPixel_RGBA_f. </param>
	///
	/// <returns>	float4. </returns>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ float4 PixelToRaw(const TPixel_RGBA_f& tPixel)
	{
		float4 f4;
		f4.x = tPixel.r();
		f4.y = tPixel.g();
		f4.z = tPixel.b();
		f4.w = tPixel.a();
		return f4;
	}

	#pragma endregion "Pixel to Raw"

	#pragma region "Raw to Pixel"

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief
	/// 	Converts short1 to TPixel_L_s.
	///
	/// \param	tRaw	short1.
	///
	/// \return TPixel_L_s.
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ TPixel_L_s RawToPixel(const short1& tRaw)
	{
		TPixel_L_s tPixel;
		tPixel.r() = tRaw.x;
		return tPixel;
	}

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \brief
	/// 	Converts short4 to TPixel_RGBA_s.
	///
	/// \param	tRaw	short4.
	///
	/// \return TPixel_RGBA_s.
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	__HDINL__ TPixel_RGBA_s RawToPixel(const short4& tRaw)
	{
		TPixel_RGBA_s tPixel;
		tPixel.r() = tRaw.x;
		tPixel.g() = tRaw.y;
		tPixel.b() = tRaw.z;
		tPixel.a() = tRaw.w;
		return tPixel;
	}

	#pragma endregion "Raw to Pixel"
}
