//========================================================================
// Color library header file
//
// AUTHOR:  Gabor Nagy
// DATE:    2026-Aug-02 01:00:29
//
// Copyright (C) 1996-2026 by Gabor Nagy. All rights reserved.
//========================================================================
#ifndef	_EColor_h
#define	_EColor_h

#include <EClass.h>
#include <EResource.h>

#define EcAUTO_DEPTH     0

#define EcCOLOR_CHANGED  1

#define EcR  0
#define EcG  1
#define EcB  2
#define EcA  3

#define EcLumaR    0.212671
#define EcLumaG    0.715160
#define EcLumaB    0.072169

#define EcLumaI8R  54
#define EcLumaI8G  183
#define EcLumaI8B  19

#define EcLumaI13R  1742
#define EcLumaI13G  5859
#define EcLumaI13B  591

#define EcLumaI16R  13937
#define EcLumaI16G  46868
#define EcLumaI16B  4730


/*
#define EcLumaR   0.3086
#define EcLumaG   0.6094
#define EcLumaB   0.0820

#define EcLumaIR  79
#define EcLumaIG  156
#define EcLumaIB  21
*/

//--------------------------------
// Macros
//--------------------------------
#define Ec_ClampTo0_RGBf_s(p) do\
{\
	if(p.R < 0.0) p.R = 0.0;\
	if(p.G < 0.0) p.G = 0.0;\
	if(p.B < 0.0) p.B = 0.0;\
} while(0)

#define Ec_ClampTo0_3f(p) do\
{\
	int  lI = 0;for(;lI < 3;lI++) if(p[lI] < 0.0) p[lI] = 0.0;\
} while(0)

#define Ec_ClampTo0_1_RGBf_s(p)\
{\
	if(p.R < 0.0) p.R = 0.0;else if(p.R > 1.0) p.R = 1.0;\
	if(p.G < 0.0) p.G = 0.0;else if(p.G > 1.0) p.G = 1.0;\
	if(p.B < 0.0) p.B = 0.0;else if(p.B > 1.0) p.B = 1.0;\
} while(0)

#define Ec_ClampTo0_1_3f(m) do\
{\
	int  lI = 0;for(;lI < 3;lI++) { if(m[lI] < 0.0) m[lI] = 0.0;else if(m[lI] > 1.0) m[lI] = 1.0; }\
}

#define Ec_Float32ToUInt8(pIn, pOut) do\
{\
	float  lOut = (pIn) * 255.999;if(!EFinite(lOut)) lOut = 0.0;if(lOut < 0.0) lOut = 0.0;else if(lOut > 255.0) lOut = 255.999;\
	pOut = (uint8_t)lOut;\
} while(0)


#define EcM_LumaI8(pR, pG, pB)      ((EcLumaI8R  * (pR) + EcLumaI8G  * (pG) + EcLumaI8B  * (pB)) >> 8)

// We are using 13-bit luma weights to avoid overflow on signed int32_t, as we lose a bit to the sign and 2 bits because we are adding 3 values here
//
#define EcM_LumaI16(pR, pG, pB)     ((EcLumaI13R * (pR) + EcLumaI13G * (pG) + EcLumaI13B * (pB)) >> 13)
#define EcM_LumaI16to8(pR, pG, pB)  ((EcLumaI8R  * (pR) + EcLumaI8G  * (pG) + EcLumaI8B  * (pB)) >> 24)

// 16-bit luminance from RGB8 source. This gives better precision than simply up-shifting EcM_LumaI8 because it doest the weighted average of RGB on 14 bits.
// (not 16 bit, to avoid overflow on signed int32_t, as we lose a bit to the sign and 2 bits because we are adding 3 values here)
#define EcM_LumaI8to16(pR, pG, pB)  ((EcLumaI13R * (pR) + EcLumaI13G * (pG) + EcLumaI13B * (pB)) >> 5)

#define EcM_LumaF(pR, pG, pB)       (EcLumaR * (pR) + EcLumaG * (pG) + EcLumaB * (pB))
#define EcM_LumaRGBA(RGBA)       ((EcLumaI8R * (((RGBA) >> 24) & 0xFF) + EcLumaI8G * (((RGBA)>>16) & 0xFF) + EcLumaI8B * (((RGBA) >> 8) & 0xFF)) >> 8)
#define EcM_ABGRToRGBA(ABGR)     (((ABGR & 0xFF000000) >> 24) | ((ABGR & 0x00FF0000) >> 8) | ((ABGR & 0x0000FF00) << 8) | ((ABGR & 0x000000FF) << 24))



#define Ec_YUV8toRGB8_sp(pY, pU, pV,  pDst) do\
{\
	const float  lY = 1.1643 * ((float)pY - 16.0), lU = (float)pU - 128.0, lV = (float)pV - 128.0;\
	int  lR = lY                + 1.5980 * lV;if(lR < 0) lR = 0;if(lR > 255) lR = 255;\
	int  lG = lY - 0.39173 * lU - 0.8129 * lV;if(lG < 0) lG = 0;if(lG > 255) lG = 255;\
	int  lB = lY + 2.01700 * lU;              if(lB < 0) lB = 0;if(lB > 255) lB = 255;\
\
	pDst->R = lR;\
	pDst->G = lG;\
	pDst->B = lB;\
} while(0)

#define Ec_AlphaMult_s(pRGBA) do\
{\
	const float  lA = (pRGBA).A;\
	(pRGBA).R *= lA;\
	(pRGBA).G *= lA;\
	(pRGBA).B *= lA;\
} while(0)

#define Ec_AlphaMultSetA_s(pRGBA, pA) do\
{\
	(pRGBA).R *= pA;\
	(pRGBA).G *= pA;\
	(pRGBA).B *= pA;\
	(pRGBA).A = pA;\
} while(0)


//--------------------------------
// OpenGL color macros
//--------------------------------
#define EcM_glColorRGBAp8(c)      EpglColor4ub(EcM_R_RGBAp8(c), EcM_G_RGBAp8(c), EcM_B_RGBAp8(c), EcM_A_RGBAp8(c))
#define EcM_glColorRGBA8_s(c)     EpglColor4ub((c).R, (c).G, (c).B, (c).A)
#define EcM_glColorRGBAi_s(c)     EpglColor4f((float)((c).R) * 0.0000153,  (float)((c).G) * 0.0000153,  (float)((c).B) * 0.0000153,  (float)((c).A) * 0.0000153)
#define EcM_glColorRGBAi_p(c)     EpglColor4f((float)((c)->R) * 0.0000153, (float)((c)->G) * 0.0000153, (float)((c)->B) * 0.0000153, (float)((c)->A) * 0.0000153)

#define EcM_glColorRGBAf_s(c)     EpglColor4f((c).R,  (c).G,  (c).B,  (c).A)
#define EcM_glColorRGBAf_p(c)     EpglColor4f((c)->R, (c)->G, (c)->B, (c)->A)
#define EcM_glColorRGBAf_a(c)     EpglColor4fv(c)

#define EcM_glClearColorRGBAi(c)  EpglClearColor((float)((c).R) * 0.0000153, (float)((c).G) * 0.0000153, (float)((c).B) * 0.0000153, (float)((c).A) * 0.0000153)
#define EcM_glClearColorRGBf(c)   EpglClearColor((c).R, (c).G, (c).B, 1.0)
#define EcM_glClearColorRGBAf(c)  EpglClearColor((c).R, (c).G, (c).B, (c).A)



#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
extern "C" {
#endif


// Packed integer color
// This is adjusted, depending on endianness, so it's always in RGBA order in memory.
//
typedef uint32_t  EcRGBAp8Color;


#if BYTE_ORDER == LITTLE_ENDIAN
#define EcM_PackRGBA8(r,g,b,a)  ((((EcRGBAp8Color)(r))) | (((EcRGBAp8Color)(g)) << 8) | (((EcRGBAp8Color)(b)) << 16) | ((EcRGBAp8Color)(a) << 24))

//========================================
// EcRGBAp8Color from an uint32_t
//========================================
static inline uint32_t EcRGBAp8Color_i(const uint32_t P)
{
	const uint32_t  LR = (P >> 24) & 0xFF , LG = (P >> 16) & 0xFF, LB = (P >> 8) & 0xFF, LA = P & 0xFF;
	return(EcM_PackRGBA8(LR, LG, LB, LA));
}

#define EcM_R_RGBAp8(RGBA)      ((RGBA)         & 0xFF)
#define EcM_G_RGBAp8(RGBA)      (((RGBA) >>  8) & 0xFF)
#define EcM_B_RGBAp8(RGBA)      (((RGBA) >> 16) & 0xFF)
#define EcM_A_RGBAp8(RGBA)      (((RGBA) >> 24) & 0xFF)
#else
#define EcM_R_RGBAp8(RGBA)      (((RGBA) >> 24) & 0xFF)
#define EcM_G_RGBAp8(RGBA)      (((RGBA) >> 16) & 0xFF)
#define EcM_B_RGBAp8(RGBA)      (((RGBA) >> 8)  & 0xFF)
#define EcM_A_RGBAp8(RGBA)      ((RGBA)         & 0xFF)
#define EcM_PackRGBA8(r,g,b,a)  ((((EcRGBAp8Color)(r)) << 24) | (((EcRGBAp8Color)(g)) << 16) | (((EcRGBAp8Color)(b)) << 8) | ((EcRGBAp8Color)(a)))
#define EcRGBAp8Color_i(p)            p
#endif // LITTLE_ENDIAN

//========================================
// EcRGBAp8Color from 4 uint8_ts
//========================================
static inline EcRGBAp8Color EcRGBAp8Color_s(const uint8_t PR, const uint8_t PG, const uint8_t PB, const uint8_t PA)
{
	return(EcM_PackRGBA8(PR, PG, PB, PA));
}

#define EcM_Gamma(pV, mGamma)  pow(pV, 1.0 / mGamma)



typedef struct
{
	uint8_t  R, G, B;
} EcRGB8Color;

static inline EcRGB8Color EcRGB8Color_s(const uint8_t PR, const uint8_t PG, const uint8_t PB)
{
	EcRGB8Color  LResult = { PR, PG, PB };
	return(LResult);
}


// Integer-component RGBA color 
// Normal range: 0...0xFF
//
typedef struct
{
	uint8_t  R, G, B, A;
} EcRGBAu8Color;

static inline EcRGBAu8Color EcRGBAu8Color_s(const uint8_t PR, const uint8_t PG, const uint8_t PB, const uint8_t PA)
{
	EcRGBAu8Color  LResult = { PR, PG, PB, PA };
	return(LResult);
}



// Integer-component RGB color 
// Normal range: 0...0xFFFF
//
typedef struct
{
	int  R, G, B;
} EcRGBiColor;

static inline EcRGBiColor EcRGBiColor_s(const int PR, const int PG, const int PB)
{
	const EcRGBiColor  LV = { PR, PG, PB };
	return(LV);
}


// Integer-component RGBA color 
// Normal range: 0...0xFFFF
//
typedef struct
{
	int  R, G, B, A;
} EcRGBAiColor;

static inline EcRGBAiColor EcRGBAiColor_s(const int PR, const int PG, const int PB, const int PA)
{
	const EcRGBAiColor  LV = { PR, PG, PB, PA };
	return(LV);
}


// Float-component color
// Normal range:	0.0...1.0
typedef struct
{
	float  R, G, B;
} EcRGBf32Color;

static inline EcRGBf32Color EcRGBf32Color_s(const float PR, const float PG, const float  PB)
{
	const EcRGBf32Color  LResult = { .R= PR, .G= PG, .B= PB };
	return(LResult);
}


typedef struct
{
	uint16_t  R, G, B, A;
} EcRGBAu16Color;

typedef struct
{
	int16_t  R, G, B, A;
} EcRGBAi16Color;


typedef struct
{
	uint16_t  R, G, B;
} EcRGBu16Color;

typedef struct
{
	int16_t  R, G, B;
} EcRGBi16Color;


typedef struct
{
	float  R, G;
} EcRGf32Color;

typedef struct
{
	uint16_t  R, G;
} EcRGu16Color;

typedef struct
{
	int16_t  R, G;
} EcRGi16Color;

typedef struct
{
	uint8_t  R, G;
} EcRGu8Color;

typedef struct
{
	int8_t  R, G;
} EcRGi8Color;


// Float-component color
// Normal range:	0.0...1.0
typedef struct
{
	float  R, G, B, A;
} EcRGBAf32Color;

static inline EcRGBAf32Color EcRGBAf32Color_s(const float PR, const float PG, const float  PB, const float PA)
{
	const EcRGBAf32Color  LResult = { .R= PR, .G= PG, .B= PB, .A= PA };
	return(LResult);
}


// RGB -> Spectrum and Spectrum -> RGB conversion type
//
enum
{
	EcINTERPOLATE = 1, EcCIE
};


#define EcMAX_NUM_OF_SPECTRAL_SAMPLES  32


typedef struct
{
	EcRGBf32Color  RGB;
	uint8_t        RGBConversion;    // EcINTERPOLATE or EcCIE

// Spectrum
//
	float*         Wavelengths;float*  Values;EIndex  Values_Count;  // User-defined (may be non-uniformly sampled)

// Regularly sampled spectrum
//
	int            NumOfValidSamples;
	float          Samples[EcMAX_NUM_OF_SPECTRAL_SAMPLES];           // The size is hard-wired for now because of the temporary copies of shaders, used for texturing
	uint16_t       Monochromatic : 1;                                // This should be set to TRUE if all spectral sample values are equal
} EcColor;


// Color Matching function by wavelength from
// http://cvrl.ioo.ucl.ac.uk/database/text/tables/table3ss.htm
//
// wavelength (nm)  R, G, B contributions
//
typedef struct
{
	float  Wavelength, R, G, B;
} EcCIEEntry;


typedef struct
{
	float  Wavelength, Sensitivity;
} EcColorSensor;


enum
{
	EcLINEAR = 1,
	EcsRGB,
	EcAdobeRGB
};


enum
{
	EcSpectrumWavelengthDescending = 1,
	EcSpectrumWavelengthAscending,
};



static inline void ERes_ResourceSetColorRGBf(void* PStructAddress, const EResource* PResource,  const float PR, const float PG, const float PB)
{
	if(PResource)
	{
// If PStructAddress is NULL, the addresses are absolute. Otherwise they're relative to PStructAddress.
//
		uint8_t*  LVariableAddress;
		if(PStructAddress) LVariableAddress = (EPointerUInt)PStructAddress + (uint8_t*)(PResource->Address);
		else LVariableAddress = (uint8_t*)(PResource->Address);

		switch(PResource->Type & (~(EResDYNAMIC|EResCOUNT|EResCOUNT_FUNC)))
		{
			case EResCOLOR:
				{
					EcColor*  LAddress = (EcColor*)LVariableAddress;
					LAddress->RGB = EcRGBf32Color_s(PR, PG, PB);
				}
			break;
			default:  printf("%s() %s:%d  %sIMPLEMENT ME  %04x%s\n", __FUNCTION__, __FILE__, __LINE__, ECodeYellow, PResource->Type & (~(EResDYNAMIC|EResCOUNT|EResCOUNT_FUNC)), ECodeNormal);fflush(stdout);break;
		}
	}
}


extern const EcCIEEntry     Ec_CIE[];extern const int  Ec_CIE_count;

extern const EcRGBf32Color  Ec_CIE_Inv_380to720_16[];
extern const EcRGBf32Color  Ec_CIE_Inv_380to720_32[];
extern const EcRGBf32Color  Ec_CIE_Inv_380to720_64[];

extern EResourceList        EcColor_resources;
extern ECoreClass           EcColor_class[];

extern void  Ec_GetForegroundColorRGBAi(const EcRGBAiColor* PBackgroundColor, EcRGBAiColor* PForegroundColor);

extern void  EcColor_Init(EcColor* PColor);
extern void  EcColor_InitRGB(EcColor* PColor,  const float PR, const float PG, const float PB);
extern void  EcColor_SetRGB(EcColor* PColor,  const float PR, const float PG, const float PB);
extern void  EcColor_Update(EcColor* PColor);

extern EcColor*  EResource_GetColor(void* PStructAddress, const EResource* PResource);

extern void      EResource_SetColorRGB(void* PStructAddress, const EResource* PResource,  const float PR, const float PG, const float PB);


//================================================================
// Set the value of a Resource in an EObject, from an EcColor
//================================================================
static inline int EObject_NamedResourceSetColorRGBf(void* PObject, const char* PName,  const float PR, const float PG, const float PB)
{
	EObject*       LObject = (EObject*)PObject;
	EObjectClass*  LClass = LObject->Class;while(LClass)
	{
		EResource*  LResource = EResource_ByName(&LClass->Resources, PName);if(LResource)
		{
			EResource_SetColorRGB(PObject, LResource,  PR, PG, PB);
			
			return(E_SUCCESS);
		}
		LClass = LClass->SuperClass;
	}
	return(E_NOT_FOUND);
}

extern void  EcColor_FreeContents(EcColor* PSpectrum);
extern void  EcColor_Copy(const EcColor* PS, EcColor* PD);


// Spectrum.c
//
extern void  EcColor_SampleSpectrum(EcColor* PColor,  const float PWavelengthMin, const float PWavelengthMax, const int PColorModel, const int PNSpectralSamples);
extern int   EcRGBf32Color_ToSpectrumCIE(const EcRGBf32Color* PRGBfColor, const int PNSpectralSamples, const float PScaler,  float* PSamples);
extern int   EcRGBf32Color_ToSpectrumInterp(const EcRGBf32Color* PRGBfColor, const int PNSpectralSamples, const float PScaler,  float* PSamples);

extern void  EcColor_RGBToSpectrum(EcColor* PColor, const int PNSpectralSamples, const float PScalerIn);
extern int   EcColor_RGBToSpectrumD(EcColor* PColor, const int PNSpectralSamples, const float PScalerIn,  float* PSpectralSamples);
extern void  EcColor_RGBToSpectrumCIE(EcColor* PColor, const int PNSpectralSamples, const float PScalerIn);
extern void  EcColor_RGBToSpectrumInterp(EcColor* PColor, const int PNSpectralSamples, const float PScalerIn);
extern void  EcColor_ToSpectrum(EcColor* PColor, const int PNSpectralSamples, const float PScaler,  float* PSamples);
extern int   EcColor_SpectrumToRGB(const EcColor* PColor, EcRGBf32Color* PRGBColor);

extern void  Ec_RGBtoXYZInit(const uint16_t PColorSpace, float* PRGBtoXYZ);

extern int   Ec_AlphaMultRGBAi(const EcRGBAiColor* PSrc, EcRGBAiColor* PDst);


extern int   Ec_LumaRGBAi(const EcRGBAiColor* PColor);

extern EcRGBAp8Color    Ec_GainRGBAp8(const EcRGBAp8Color PColor, const float PGain);

extern EcRGB8Color*     Ec_GainRGB8(const EcRGB8Color* PColor, const float PGain, EcRGB8Color* PColorRet);
extern EcRGBAiColor*    Ec_GainRGBAi(const EcRGBAiColor* PColor, const float PGain, EcRGBAiColor* PColorRet);
extern EcRGBf32Color*   Ec_GainRGBf(const EcRGBf32Color* PColor, const float PGain, EcRGBf32Color* PColorRet);
extern EcRGBAf32Color*  Ec_GainRGBAf(const EcRGBAf32Color* PColor, const float PGain, EcRGBAf32Color* PColorRet);

extern EcRGBf32Color*   Ec_ContrastRGBf(const EcRGBf32Color* PColor, const float PContrast, EcRGBf32Color* PColorRet);
extern EcRGBAf32Color*  Ec_ContrastRGBAf(const EcRGBAf32Color* PColor, const float PContrast, EcRGBAf32Color* PColorRet);


extern EcRGBAiColor*    Ec_SaturateRGBAi(const EcRGBAiColor* PColor, const float PSaturation, EcRGBAiColor* PColorRet);
extern EcRGBf32Color*   Ec_SaturateRGBf(const EcRGBf32Color* PColor, const float PSaturation, EcRGBf32Color* PColorRet);
extern EcRGBAf32Color*  Ec_SaturateRGBAf(const EcRGBAf32Color* PColor, const float PSaturation, EcRGBAf32Color* PColorRet);

extern void             Ec_FColorShadeBy(const EcRGBf32Color* PColor, EcRGBf32Color* PColorLum, EcRGBf32Color* PDstColor);

extern EcRGB8Color*     Ec_LerpRGB8(const EcRGB8Color* PColor1, const EcRGB8Color* PColor2, const float PFactor, EcRGB8Color* PDst);
extern EcRGBiColor*     Ec_LerpRGBi(const EcRGBAiColor* PColor1, const EcRGBiColor* PColor2, const float PFactor, EcRGBiColor* PDst);
extern EcRGBf32Color*   Ec_LerpRGBf(const EcRGBf32Color* PColor1, const EcRGBf32Color* PColor2, const float PFactor, EcRGBf32Color* PDst);

extern EcRGBAiColor*    Ec_LerpRGBAi(const EcRGBAiColor* PColor1, const EcRGBAiColor* PColor2, const float PFactor, EcRGBAiColor* PDst);
extern EcRGBAf32Color*  Ec_LerpRGBAf(const EcRGBAf32Color* PColor1, const EcRGBAf32Color* PColor2, const float PFactor, EcRGBAf32Color* PDst);

extern double           Ec_GetAngle(const double PXPos, const double PYPos);

extern EcRGB8Color*     Ec_RGBfToRGB8(const float PR, const float PG, const float PB, EcRGB8Color* PResult);
extern EcRGBAp8Color    Ec_RGBfToRGBAp8(const float PR, const float PG, const float PB);
extern EcRGBAp8Color    Ec_RGBAfVToRGBAp8(const float PR, const float PG, const float PB, const float PA);
extern EcRGBAu8Color     Ec_RGBAfToRGBA8(const EcRGBAf32Color* PSrcColor);
extern EcRGBAu8Color     Ec_RGBAfVToRGBA8(const float PR, const float PG, const float PB, const float PA);

extern EBool            EcRGBAiColor_Equal(const EcRGBAiColor* P0, const EcRGBAiColor* P1);


extern EcRGBAiColor     Ec_RGBAp8ToRGBAi(const EcRGBAp8Color PColor);
extern EcRGBAf32Color   Ec_RGBAp8ToRGBAf32(const EcRGBAp8Color PColor);
extern EcRGBAf32Color   Ec_RGBAu8ToRGBAf32(const EcRGBAu8Color PColor);

extern void             Ec_RGBf32ToRGBAi(const EcRGBf32Color* PRGBfColor, EcRGBAiColor* PRGBAiColor);

extern EcRGBAp8Color    Ec_RGBAiToRGBAp8(const EcRGBAiColor* PColor);
extern EcRGBAp8Color    Ec_RGBAfToRGBAp8AlphaMult(const EcRGBAf32Color* PColor);

extern EcRGBAp8Color    Ec_RGBAfToRGBAp8(const EcRGBAf32Color* PColor);
extern EcRGBAu8Color    Ec_RGBAf32ToRGBA8(const EcRGBAf32Color* PRGBAf32Color);
extern void             Ec_RGBAf32ToRGBAi(const EcRGBAf32Color* PRGBAf32Color, EcRGBAiColor* PRGBAiColor);
extern uint8_t          Ec_RGBAf32ToGray8(const EcRGBAf32Color* PColor);

extern EcRGBAu8Color    Ec_RGBAiToRGBA8(const EcRGBAiColor* PSrc);
extern void             Ec_RGBAiToRGBAf32(const EcRGBAiColor* PRGBAiColor, EcRGBAf32Color* PDst);
extern void             Ec_RGBAiToRGBf32(const EcRGBAiColor* PRGBAiColor, EcRGBf32Color* PDst);

extern void             Ec_RGBAiToRGBAu16(const EcRGBAiColor* PSrc, EcRGBAu16Color* PDst);
extern void             Ec_RGBAiToRGBAi16(const EcRGBAiColor* PSrc, EcRGBAi16Color* PDst);

extern void             Ec_RGBAiToRGBu16(const EcRGBAiColor* PSrc, EcRGBu16Color* PDst);
extern void             Ec_RGBAiToRGBi16(const EcRGBAiColor* PSrc, EcRGBi16Color* PDst);


extern void             Ec_HSVtoRGB(double PHue, const double PSaturation, const double PValue, int* PR, int* PG, int* PB);
extern void             Ec_HSVtoRGBf(double PHue, const double PSaturation, const double PValue, float* PR, float* PG, float* PB);
extern void             Ec_HLStoRGB(double PHue, const double PLevel, const double PSaturation, int* PR, int* PG, int* PB);

extern void             Ec_RGBtoHSV(const EcRGBf32Color* PColor, float* PH, float* PS, float* PV);
extern void             Ec_RGBAtoHSV(const EcRGBAf32Color* PColor, float* PH, float* PS, float* PV);

extern void             Ec_Matrix3x3Invert_f32(const float* const PM, float* PDst);

#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
}	// Close scope of 'extern "C"' declaration
#endif

#endif // _EColor_h
