/////////////////////////////////////////////////////////////
// CINEMA SDK : BITMAP FILTER                              //
/////////////////////////////////////////////////////////////
// VERSION    : CINEMA 4D																	 //
/////////////////////////////////////////////////////////////
// (c) 1989-2002 MAXON Computer GmbH, all rights reserved	 //
/////////////////////////////////////////////////////////////

#ifndef	__X4D_COLORS_H
#define	__X4D_COLORS_H

#include	"ge_math.h"

//----------------------------------------------------------------------------------------
// Colors and color spaces
//----------------------------------------------------------------------------------------

enum																												// Color spaces (color_space)
{
	CSPACE_FLAGS	= 	0xff00,																	// the upper 8 bits are for flags
	CSPACE_MASK		=	0x00ff,																		// the lower bits contain the color space id

	CSPACE_ALPHA_FLAG	= 0x0100,																// alpha flag

	CSPACE_UNKNOWN =	0x0000,

	CSPACE_RGB		=	0x0001,																		// RGB color space
	CSPACE_ARGB		=	0x0101,																		// RGB color space with alpha channel

	CSPACE_HSV		=	0x0002,																		// HSV color space
	CSPACE_HSL		=	0x0003,																		// HSL color space

	CSPACE_CMYK		=	0x0004,																		// CMYK color space

	CSPACE_YCbCr	=	0x0005,																		// YCbCr color space
	CSPACE_AYCbCr	=	0x0105,																		// YCbCr color space with alpha
	CSPACE_YCCK		=	0x0006,																		// YCbCrK color space

	CSPACE_GRAY		=	0x0007,																		// gray space
	CSPACE_AGRAY	=	0x0107,																		// gray with alpha

	CSPACE_PhotoYCC = 0x0008,																	// YCC color space (PhotoCD)
	CSPACE_APhotoYCC = 0x0108,																// YCC color space (PhotoCD) with alpha

	CSPACE_XYZ		= 	0x0010,																	// XYZ color space
	CSPACE_Yxy		= 	0x0011,																	// Yxy color space
	CSPACE_Lab		=	0x0012,																		// L*a*b* color space
	CSPACE_Luv		=	0x0013																		// L*u*v* color space
};

enum																												// number of components in the color table (flags)
{
	CSPACE_1COMPONENT		=	0x0001,
	CSPACE_2COMPONENTS	=	0x0002,
	CSPACE_3COMPONENTS	= 0x0003,
	CSPACE_4COMPONENTS	=	0x0004,
	CSPACE_5COMPONENTS	=	0x0005,
	CSPACE_6COMPONENTS	=	0x0006,
	CSPACE_7COMPONENTS	=	0x0007,
	CSPACE_COMP_MASK		=	0x000f															// mask for number of components
};

struct COLOR_RGB																						// RGB color value
{
	UWORD	reserved;
	UWORD	red;
	UWORD	green;
	UWORD	blue;
};

struct COLOR_ARGB																						// ARGB color value
{
	UWORD	alpha;
	UWORD	red;
	UWORD	green;
	UWORD	blue;
};

struct COLOR_HSL																						// HSL color value
{
	UWORD	reserved;
	UWORD	hue;
	UWORD	saturation;
	UWORD	lightness;
};

struct COLOR_HSV																						// HSV color value
{
	UWORD	reserved;
	UWORD	hue;
	UWORD	saturation;
	UWORD	value;
};

struct COLOR_CMYK																						// CMYK color value
{
	UWORD	cyan;
	UWORD	magenta;
	UWORD	yellow;
	UWORD	black;
};

struct COLOR_YCbCr																					// YCbCr color value
{
	UWORD	reserved;
	UWORD	Y;
	UWORD	Cb;
	UWORD	Cr;
};

struct COLOR_GRAY																						// gray value
{
	UWORD	reserved;
	UWORD	reserved1;																					// set to the same value as gray (compatibility with RGB)
	UWORD	reserved2;																					// set to the same value as gray (compatibility with RGB)
	UWORD	gray;
};

struct COLOR_AGRAY																					// gray with alpha
{
	UWORD	alpha;
	UWORD	reserved1;																					// set to the same value as gray (compatibility with RGB)
	UWORD	reserved2;																					// set to the same value as gray (compatibility with RGB)
	UWORD	gray;
};

struct COLOR_XYZ																						// XYZ color value
{
	UWORD	reserved;
	UWORD	X;
	UWORD	Y;
	UWORD	Z;
};

struct COLOR_Yxy																						// Yxy color value
{
	UWORD	reserved;
	UWORD	Y;
	UWORD	x;
	UWORD	y;
};

struct COLOR_Lab																						// L*a*b* color value
{
	UWORD	reserved;
	UWORD	L;																									// 0 is equivalent to 0.0, 0xffffU is equivalent to 1.0
	UWORD	a;																									// 0 is equivalent to  -1.0, 0x8000 is equivalent to 0.0, 0xffff is equivalent to 1.0
	UWORD	b;																									// 0 is equivalent to  -1.0, 0x8000 is equivalent to 0.0, 0xffff is equivalent to 1.0
};

struct COLOR_Luv																						// L*u*v* color value
{
	UWORD	reserved;
	UWORD	L;																									// 0 is equivalent to 0.0, 0xffffU is equivalent to 1.0
	UWORD	u;																									// 0 is equivalent to -1.0, 0x8000 is equivalent to 0.0, 0xffff is equivalent to 1.0
	UWORD	v;																									// 0 is equivalent to -1.0, 0x8000 is equivalent to 0.0, 0xffff is equivalent to 1.0
};

union COLOR_ENTRY
{
	COLOR_RGB		rgb;
	COLOR_ARGB	argb;
	COLOR_HSV		hsv;
	COLOR_HSL		hsl;
	COLOR_CMYK	cmyk;
	COLOR_YCbCr	ycc;
	COLOR_GRAY	gray;
	COLOR_AGRAY	agray;
	COLOR_XYZ		xyz;
	COLOR_Yxy		yxy;
	COLOR_Lab		lab;
	COLOR_Luv		luv;
};

//----------------------------------------------------------------------------------------
// Pixel formats
//----------------------------------------------------------------------------------------

// number of used pixel components
#define	PX_1COMP		0x01000000UL														// pixel consists of one used component: color index
#define	PX_2COMP		0x02000000UL														// pixel consists of two used components, e.g. AG
#define	PX_3COMP		0x03000000UL														// pixel consists of three used components, e.g. RGB, YCbCr, XYZ, Yxy, Lab, Luv
#define	PX_4COMP		0x04000000UL														// pixel consists of four used components, e.g. CMYK, ARGB
#define	PX_5COMP		0x05000000UL														// pixel consists of five used components
#define	PX_6COMP		0x06000000UL														// pixel consists of six used components
#define	PX_7COMP		0x07000000UL														// pixel consists of seven used components

// little endian flag
#define	PX_REVERSED	0x00800000UL														// pixel output is done in reversed byte order

// rotation of pixel components
#define	PX_0LROTATE	0x00400000UL														// unused bits are on the left
#define	PX_1LROTATE	0x00500000UL														// rotate left by 1 component

#define	PX_0RROTATE	0x00000000UL														// unused bits are on the right
#define	PX_1RROTATE	0x00100000UL														// rotate right by one component

#define	PX_xFIRST		0x00400000UL														// xRGB: unused bits are left (PX_0LROTATE)
#define	PX_xLAST		0x00000000UL														// RGBx: unused bits are right (PX_0RROTATE)

// bit packing
#define	PX_PACKED		0x00020000UL														// components are packed (default case), one byte for red is followed by one for green and blue - the same goes for the next pixel
#define	PX_PLANES		0x00010000UL														// the bits of each component are stored in seperate planes (order: 0, 1, ..., n)

// number of used bits
#define	PX_USES1		0x00000100UL														// 1 bit of the pixel is used
#define	PX_USES2		0x00000200UL														// 2 bits of the pixel are used
#define	PX_USES3		0x00000300UL														// 3 bits of the pixel are used
#define	PX_USES4		0x00000400UL														// 4 bits of the pixel are used
#define	PX_USES8		0x00000800UL														// 8 bits of the pixel are used
#define	PX_USES15		0x00000f00UL														// 15 bits of the pixel are used
#define	PX_USES16		0x00001000UL														// 16 bits of the pixel are used
#define	PX_USES24		0x00001800UL														// 24 bits of the pixel are used
#define	PX_USES30		0x00001e00UL														// 30 bits of the pixel are used
#define	PX_USES32		0x00002000UL														// 32 bits of the pixel are used
#define	PX_USES48		0x00003000UL														// 48 bits of the pixel are used
#define	PX_USES64		0x00004000UL														// 64 bits of the pixel are used

// number of bits per pixel
#define	PX_1BIT			0x00000001UL														// pixel consists of 1 bit
#define	PX_2BIT			0x00000002UL														// pixel consists of 2 bits
#define	PX_3BIT			0x00000003UL														// pixel consists of 3 bits
#define	PX_4BIT			0x00000004UL														// pixel consists of 4 bits
#define	PX_8BIT			0x00000008UL														// pixel consists of 8 bits
#define	PX_16BIT		0x00000010UL														// pixel consists of 16 bits
#define	PX_24BIT		0x00000018UL														// pixel consists of 24 bits
#define	PX_32BIT		0x00000020UL														// pixel consists of 32 bits
#define	PX_48BIT		0x00000030UL														// pixel consists of 48 bits
#define	PX_64BIT		0x00000040UL														// pixel consists of 64 bits

// masks
#define	PX_CMPNTS		0x0f000000UL														// number of pixel components
#define	PX_FLAGS		0x00f00000UL														// flags (little endian, component rotation, ...)
#define	PX_RTDIR		0x00400000UL														// rotation direction
#define	PX_RTCMPNTS	0x00300000UL														// number of rotated pixel components
#define	PX_PACKING	0x00030000UL														// bit packing
#define	PX_USED			0x0000ff00UL														// number of used bits
#define	PX_BITS			0x000000ffUL														// total number of bits

//----------------------------------------------------------------------------------------
// easy access macros
//----------------------------------------------------------------------------------------
#define	get_PX_CMPNTS( px_format )		((( px_format ) & PX_CMPNTS ) >> 24 )
#define	get_PX_USED( px_format )			((( px_format ) & PX_USED ) >> 8 )
#define	get_PX_BITS( px_format )			((( px_format ) & PX_BITS ))

#define	set_PX_CMPNTS( components )		(( components ) << 24 )
#define	set_PX_USED( used_bits )			(( used_bits ) << 8 )
#define	set_PX_BITS( total_bits )			(( total_bits ))

//----------------------------------------------------------------------------------------
// common Macintosh pixel formats (RGB)
//----------------------------------------------------------------------------------------
#define	PX_MAC1			( PX_1COMP + PX_PACKED + PX_USES1 + PX_1BIT )
#define	PX_MAC4			( PX_1COMP + PX_PACKED + PX_USES4 + PX_4BIT )
#define	PX_MAC8			( PX_1COMP + PX_PACKED + PX_USES8 + PX_8BIT )
#define	PX_MAC15		( PX_3COMP + PX_PACKED + PX_USES15 + PX_16BIT + PX_xFIRST )
#define	PX_MAC32		( PX_3COMP + PX_PACKED + PX_USES24 + PX_32BIT + PX_xFIRST )

//----------------------------------------------------------------------------------------
// common x86 pixel formats (RGB)
//----------------------------------------------------------------------------------------
#define	PX_VGA8			( PX_1COMP + PX_PACKED + PX_USES8 + PX_8BIT )
#define	PX_VGA15		( PX_3COMP + PX_PACKED + PX_USES15 + PX_16BIT + PX_REVERSED + PX_xFIRST )
#define	PX_VGA16		( PX_3COMP + PX_PACKED + PX_USES16 + PX_16BIT + PX_REVERSED )
#define	PX_VGA24		( PX_3COMP + PX_PACKED + PX_USES24 + PX_24BIT + PX_REVERSED )
#define	PX_VGA32		( PX_3COMP + PX_PACKED + PX_USES24 + PX_32BIT + PX_REVERSED + PX_xFIRST )

//----------------------------------------------------------------------------------------
// some RGB pixel formats
//----------------------------------------------------------------------------------------
#define	PX_xRGB15		( PX_3COMP + PX_PACKED + PX_USES15 + PX_16BIT + PX_xFIRST )
#define	PX_RGB24		( PX_3COMP + PX_PACKED + PX_USES24 + PX_24BIT )
#define	PX_xRGB24		( PX_3COMP + PX_PACKED + PX_USES24 + PX_32BIT + PX_xFIRST )
#define	PX_RGB48		( PX_3COMP + PX_PACKED + PX_USES48 + PX_48BIT )
#define	PX_xRGB48		( PX_3COMP + PX_PACKED + PX_USES48 + PX_64BIT + PX_xFIRST )

#define	PX_RGBx24		( PX_3COMP + PX_PACKED + PX_USES24 + PX_32BIT + PX_xLAST )

//----------------------------------------------------------------------------------------
// pixel formats for RGB with alpha
//----------------------------------------------------------------------------------------
#define	PX_ARGB32		( PX_4COMP + PX_PACKED + PX_USES32 + PX_32BIT )
#define	PX_ARGB64		( PX_4COMP + PX_PACKED + PX_USES64 + PX_64BIT )

#define	PX_RGBA32		( PX_4COMP + PX_PACKED + PX_USES32 + PX_32BIT + PX_1LROTATE )	// ARGB rotated left by one component
#define	PX_RGBA64		( PX_4COMP + PX_PACKED + PX_USES64 + PX_64BIT + PX_1LROTATE )

//----------------------------------------------------------------------------------------
// pixel formats for gray
//----------------------------------------------------------------------------------------
#define	PX_GRAY8		( PX_1COMP + PX_PACKED + PX_USES8 + PX_8BIT )
#define	PX_GRAY16		( PX_1COMP + PX_PACKED + PX_USES16 + PX_16BIT )

//----------------------------------------------------------------------------------------
// pixel formats for gray with alpha
//----------------------------------------------------------------------------------------
#define	PX_AGRAY16	( PX_2COMP + PX_PACKED + PX_USES16 + PX_16BIT )
#define	PX_AGRAY32	( PX_2COMP + PX_PACKED + PX_USES32 + PX_32BIT )

#define	PX_GRAYA16	( PX_2COMP + PX_PACKED + PX_USES16 + PX_16BIT + PX_1LROTATE )	// AGRAY rotated left by one component
#define	PX_GRAYA32	( PX_2COMP + PX_PACKED + PX_USES32 + PX_32BIT + PX_1LROTATE )

#endif
