/*******************************************/
/*                                         */
/* colors.cpp                              */
/*                                         */
/* scol colors primitives                  */
/*                                         */
/* Loïc Berthelot, CryoNetworks, june 2002 */
/*                                         */
/*******************************************/


extern "C" {
#include "../kernel/include/kernel.h"
}
//#include "../kernel/mmemory.h"
#include "../kernel/mainscol.h"
#include "../kernel/macros.h"
#include "../kernel/loadpak.h"
#include "colors.h"
#include "macros.h"



// Matrix of conversions op.

typedef int (*ColorOp) (mmachine,int);

static ColorOp _convertMat[COLOR_NB_MODE][COLOR_NB_MODE];




// list of operations

int _COLOR_CONVERT_IDENTITY (mmachine m, int value) { return value; }


int _COLOR_CONVERT_8_RGB16 (mmachine m, int value) 
{
	int palette = MMget(m, 0)>>1;

	if (palette = NIL) return -1;
	return 0;
}



int _COLOR_CONVERT_8_RGB24 (mmachine m, int value) {/*TO DO*/ return 0;}
int _COLOR_CONVERT_8_BGR16 (mmachine m, int value) {/*TO DO*/ return 0;}
int _COLOR_CONVERT_8_BGR24 (mmachine m, int value) {/*TO DO*/ return 0;}

int _COLOR_CONVERT_RGB16_8 (mmachine m, int value) {/*TO DO*/ return 0;}
int _COLOR_CONVERT_RGB24_8 (mmachine m, int value) {/*TO DO*/ return 0;}
int _COLOR_CONVERT_BGR16_8 (mmachine m, int value) {/*TO DO*/ return 0;}
int _COLOR_CONVERT_BGR24_8 (mmachine m, int value) {/*TO DO*/ return 0;}


int _COLOR_CONVERT_16_24 (mmachine m, int value) { return ( ((value<<9) &0xF80000) | ((value<<6) &0xF800) | ((value<<3) &0xF8) );}

int _COLOR_CONVERT_24_16 (mmachine m, int value) { return ( ((value>>9) &0x7C00) | ((value>>6) &0x03E0) | ((value>>3) &0x1F) );}

int _COLOR_CONVERT_RGB_BGR_16 (mmachine m, int value) { return ( ((value>>10) &0x1F) | (value &0x03E0) | ((value<<10) &0x7C00) );}

int _COLOR_CONVERT_RGB_BGR_24 (mmachine m, int value) { return ( ((value>>16) &0xFF) | (value &0xFF00) | ((value<<16) &0xFF0000) );}

int _COLOR_CONVERT_RGB24_BGR16 (mmachine m, int value) { return ( ((value>>19) &0x1F) | ((value>>6) &0x03E0) | ((value <<7) &0x7C00) ); } 

int _COLOR_CONVERT_RGB16_BGR24 (mmachine m, int value) { return ( ((value>>7) &0xF8) | ((value<<6) &0xF800) | ((value<<19) &0xF80000) );}








/***********************************************************************************/
/*                                                                                 */
/* _color_convert                                                                  */
/*                                                                                 */
/* fun [I value   I from_mode    I to_mode    tab I palette]     I converted_value */
/*                                                                                 */
/***********************************************************************************/
int _color_convert (mmachine m)
{
int to_mode   = SEW2I (MMget(m, 1));
int from_mode = SEW2I (MMget(m, 2));
int value     = SEW2I (MMget(m, 3));
int res;


	if ((to_mode == NIL) || (from_mode == NIL) || (value == NIL)) return -1;

	if (((res = _convertMat[from_mode][to_mode] (m, value))) < 0) return -1;

	SEDROP(m, 3);
	MMset (m, 0, res<<1);
	return 0;
}





/***********************************************************************************/
/*                                                                                 */
/* _color_init                                                                     */
/*                                                                                 */
/* initialize the matrix of operations                                             */
/*                                                                                 */
/***********************************************************************************/
void _color_init ()
{

	_convertMat[COLOR_8][COLOR_8]         = _COLOR_CONVERT_IDENTITY;
	_convertMat[COLOR_8][COLOR_RGB16]     = _COLOR_CONVERT_8_RGB16;
	_convertMat[COLOR_8][COLOR_RGB24]     = _COLOR_CONVERT_8_RGB24;
	_convertMat[COLOR_8][COLOR_BGR16]     = _COLOR_CONVERT_8_BGR16;
	_convertMat[COLOR_8][COLOR_BGR24]     = _COLOR_CONVERT_8_BGR24;

	_convertMat[COLOR_RGB16][COLOR_8]     = _COLOR_CONVERT_RGB16_8;
	_convertMat[COLOR_RGB16][COLOR_RGB16] = _COLOR_CONVERT_IDENTITY;
	_convertMat[COLOR_RGB16][COLOR_RGB24] = _COLOR_CONVERT_16_24;
	_convertMat[COLOR_RGB16][COLOR_BGR16] = _COLOR_CONVERT_RGB_BGR_16;
	_convertMat[COLOR_RGB16][COLOR_BGR24] = _COLOR_CONVERT_RGB16_BGR24;

	_convertMat[COLOR_RGB24][COLOR_8]     = _COLOR_CONVERT_RGB24_8;
	_convertMat[COLOR_RGB24][COLOR_RGB16] = _COLOR_CONVERT_24_16;
	_convertMat[COLOR_RGB24][COLOR_RGB24] = _COLOR_CONVERT_IDENTITY;
	_convertMat[COLOR_RGB24][COLOR_BGR16] = _COLOR_CONVERT_RGB24_BGR16;
	_convertMat[COLOR_RGB24][COLOR_BGR24] = _COLOR_CONVERT_RGB_BGR_24;

	_convertMat[COLOR_BGR16][COLOR_8]     = _COLOR_CONVERT_BGR16_8;
	_convertMat[COLOR_BGR16][COLOR_RGB16] = _COLOR_CONVERT_RGB_BGR_16;
	_convertMat[COLOR_BGR16][COLOR_RGB24] = _COLOR_CONVERT_RGB16_BGR24;
	_convertMat[COLOR_BGR16][COLOR_BGR16] = _COLOR_CONVERT_IDENTITY;
	_convertMat[COLOR_BGR16][COLOR_BGR24] = _COLOR_CONVERT_16_24;

	_convertMat[COLOR_BGR24][COLOR_8]     = _COLOR_CONVERT_BGR24_8;
	_convertMat[COLOR_BGR24][COLOR_RGB16] = _COLOR_CONVERT_RGB24_BGR16;
	_convertMat[COLOR_BGR24][COLOR_RGB24] = _COLOR_CONVERT_RGB_BGR_24;
	_convertMat[COLOR_BGR24][COLOR_BGR16] = _COLOR_CONVERT_24_16;
	_convertMat[COLOR_BGR24][COLOR_BGR24] = _COLOR_CONVERT_IDENTITY;
}















/************************************************************************************************/
//                                                                                              //
// L O A D    C O L O R S    P A C K A G E                                                      //
//                                                                                              //
/************************************************************************************************/



#define COLORSpkg 6

char * COLORSname [ COLORSpkg ] = 
{
	"COLOR_8",
	"COLOR_RGB16",
	"COLOR_RGB24",
	"COLOR_BGR16",
	"COLOR_BGR24",
	"_color_convert"
} ; 

char * COLORStype [ COLORSpkg ] = 
{
	"I",
	"I",
	"I",
	"I",
	"I",
	"fun [I I I tab I] I"
} ;

int COLORSarg [ COLORSpkg ] = 
{
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	TYPVAR,
	4
} ;

int (*COLORSfun[COLORSpkg])(mmachine m)= 
{
	(int (__cdecl *)(struct Mmachine*))(COLOR_8<<1),
	(int (__cdecl *)(struct Mmachine*))(COLOR_RGB16<<1),
	(int (__cdecl *)(struct Mmachine*))(COLOR_RGB24<<1),
	(int (__cdecl *)(struct Mmachine*))(COLOR_BGR16<<1),
	(int (__cdecl *)(struct Mmachine*))(COLOR_BGR24<<1),
	_color_convert
} ;                                                                   


extern "C"
{
int SCOLloadCOLORS(mmachine m)
{
	int k;
	_color_init ();
	k=PKhardpak(m,"COLORS.pkg", COLORSpkg, COLORSname, COLORSfun, COLORSarg, COLORStype);

	return k;
}
}





