/* Convert to and from display RGB
 *
 * 28/10/09
 * 	- from colour.c
 * 14/12/09
 * 	- oop, im_disp2Lab() was broken
 */

/*

    This file is part of VIPS.
    
    VIPS is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 */

/*

    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk

 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

#include <vips/vips.h>
#include <vips/internal.h>

#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/

/**
 * SECTION: disp
 * @short_description: convert to and from display RGB
 * @stability: Stable
 * @see_also: <link linkend="libvips-colour">colour</link>
 * @include: vips/vips.h
 *
 * Convert to and from display RGB. These functions are still used by nip2,
 * but most programs will be better off with im_icc_transform() and friends.
 */

/* Tables we've generated, indexed by display name.
 */
static GHashTable *im__col_display_tables = NULL;

/* Values for IM_TYPE_sRGB.
 */
static struct im_col_display srgb_profile = {
	"sRGB",
	DISP_DUMB,
	{			/* XYZ -> luminance matrix */
		{  3.2410, -1.5374, -0.4986 },
		{  -0.9692, 1.8760, 0.0416 },
		{  0.0556, -0.2040, 1.0570 }
	},	

	80.0,			/* Luminosity of reference white */
	.3127, .3291,		/* x, y for reference white */
	100, 100, 100,		/* Light o/p for reference white */
	255, 255, 255,		/* Pixel values for ref. white */
	1, 1, 1,		/* Residual light o/p for black pixel */
	2.4, 2.4, 2.4,		/* Gamma values for the three guns */
	100,			/* 'Background' (like brightness) */
	100			/* 'Picture' (like contrast) */
};

/* Values for my Ultra2, 20/2/98. Figures from a Minolta CA-100 CRT analyser.
 * Contrast at max, brightness at 42, room lights out.
 */
static struct im_col_display ultra2 = {
	"ultra2-20/2/98",
	DISP_DUMB,
	{			/* XYZ -> luminance matrix */
		{  .704, -0.302, -.103 },
		{ -.708, 1.317, .032 },
		{  .005, -.015, .071 }
	},	

	64.0,			/* Luminosity of reference white */
	.2137, .3291,		/* x, y for reference white */
	14.4, 44.0, 5.4,	/* Light o/p for reference white */
	255, 255, 255,		/* Pixel values for ref. white */
	0.03, 0.03, 0.03,	/* Residual light o/p for black pixel */
	2.5, 2.5, 2.4,		/* Gamma values for the three guns */
	100,			/* 'Background' (like brightness) */
	100			/* 'Picture' (like contrast) */
};

/* Values for our display. These were obtained with a TV analyser in late 
 * Feb. 1990. The reference white is simply r=g=b=255.			
 */
static struct im_col_display im_col_screen_white = {
	"Screen",
	DISP_DUMB,
	{			/* XYZ -> luminance matrix */
		{  .660, -0.276, -.10 },
		{ -.663, 1.293, .0265 },
		{  .003, -.017, .0734 }
	},	

	58.7,			/* Luminosity of reference white */
	.284, .273,		/* x, y for reference white */
	14.2, 38.4, 6.1, 	/* Light o/p for reference white */
	255, 255, 255,		/* Pixel values for ref. white */
	0.0, 0.0, 0.0,		/* Residual light o/p for black pixel */
	2.8, 2.9, 2.9,		/* Gamma values for the three guns */
	100,			/* 'Background' (like brightness) */
	100			/* 'Picture' (like contrast) */
};

/* Adjusted version of above for SPARCstation2 screens. Turn down the gamma
 * to make blacks blacker.
 */
static struct im_col_display im_col_SPARC_white = {
	"SPARC",
	DISP_DUMB,
	{			/* XYZ -> luminance matrix */
		{  .660, -0.276, -.10 },
		{ -.663, 1.293, .0265 },
		{  .003, -.017, .0734 }
	},	

	58.7,			/* Luminosity of reference white */
	.284, .273,		/* x, y for reference white */
	14.2, 38.4, 4,	 	/* Light o/p for reference white */
	255, 255, 255,		/* Pixel values for ref. white */
	0.0, 0.0, 0.0,		/* Residual light o/p for black pixel */
	2.0, 2.0, 2.0,		/* Gamma values for the three guns */
	100,			/* 'Background' (like brightness) */
	100			/* 'Picture' (like contrast) */
};

/* Values for D65 white. This gives a smaller range of colours than
 * screen_white. 
 */
static struct im_col_display im_col_D65_white = {
	"D65",
	DISP_DUMB,
	{			/* XYZ -> luminance matrix */
		{  .660, -0.276, -.10 },
		{ -.663, 1.293, .0265 },
		{  .003, -.017, .0734 }
	},	

	49.9,			/* Luminosity of reference white */
	.3127, .3290,		/* x, y for reference white */
	11.6, 35.0, 3.3, 	/* Light o/p for reference white */
	241, 255, 177,		/* Pixel values for ref. white */
	0.1, 0.1, 0.1,		/* Residual light o/p for black pixel */
	2.8, 2.9, 2.7,		/* Gamma values for the three guns */
	100,			/* 'Background' (like brightness) */
	100			/* 'Picture' (like contrast) */
};

/* Values for Barco calibrator monitor
 */
static struct im_col_display im_col_barco_white = {
	"Barco",
	DISP_DUMB,
	{                       /* XYZ -> luminance matrix */
		{  .749, -0.322, -.123 },
		{ -.755, 1.341, .033 },
		{  .007, -.019, .0898 }
	},        

	80.0,			/* Luminosity of reference white */
	.3128, .3292,		/* x, y for reference white */
	20.45, 52.73, 6.81,	/* Light o/p for reference white */
	255, 255, 255,		/* Pixel values for ref. white */
	0.02, 0.053, 0.007,	/* Residual light o/p for black pixel */
	2.23, 2.13, 2.12,	/* Gamma values for the three guns */
	100,			/* 'Background' (like brightness) */
	100			/* 'Picture' (like contrast) */
};

/* Values for Mitsubishi dye-sub colour printer.
 */
static struct im_col_display im_col_mitsubishi = {
	"Mitsubishi_3_colour",
	DISP_DUMB,
	{                       /* XYZ -> luminance matrix */
		{ 1.1997, -0.6296, -0.2755 },
		{ -1.1529, 1.7383, -0.1074 },
		{ -0.047, -0.109, 0.3829 }
	},        

	95,			/* Luminosity of reference white */
	.3152, .3316,		/* x, y for reference white */
	25.33, 42.57, 15.85,	/* Y all red, Y all green, Y all blue */
	255, 255, 255,		/* Pixel values for ref. white */
	1.0, 1.0, 1.0,		/* Residual light o/p for black pixel */
	1.0, 1.0, 1.0,		/* Gamma values for the three guns */
	100,			/* 'Background' (like brightness) */
	100			/* 'Picture' (like contrast) */
};

/* Display LAB of 100, 0, 0 as 255, 255, 255. 
 */
static struct im_col_display im_col_relative = {
	"relative",
	DISP_DUMB,
	{			/* XYZ -> luminance matrix */
		{  .660, -0.276, -.10 },
		{ -.663, 1.293, .0265 },
		{  .003, -.017, .0734 }
	},	

	100.0,			/* Luminosity of reference white */
	.284, .273,		/* x, y for reference white */
	24.23, 69.20, 6.57, 	/* Light o/p for reference white */
	255, 255, 255,		/* Pixel values for ref. white */
	0.0, 0.0, 0.0,		/* Residual light o/p for black pixel */
	2.3, 2.3, 2.3,		/* Gamma values for the three guns */
	100,			/* 'Background' (like brightness) */
	100			/* 'Picture' (like contrast) */
};

struct im_col_display *
im_col_displays( int n )
{
	static struct im_col_display *displays[] = {
		&im_col_screen_white,	/* index 0 */
		&im_col_SPARC_white,	/* index 1 */
		&im_col_D65_white,	/* index 2 */
		&im_col_barco_white,	/* index 3 */
		&im_col_mitsubishi,	/* index 4 */
		&im_col_relative,	/* index 5 */
		&ultra2,		/* index 6 */
		&srgb_profile,		/* index 7 */
		NULL
	};

	if( n < 0 || n > IM_NUMBER( displays ) )
		return( NULL );

	return( displays[n] );
}

struct im_col_display *
im_col_display_name( const char *name )
{
	int i;
	struct im_col_display *d;

	for( i = 0; (d = im_col_displays( i )); i++ )
		if( g_ascii_strcasecmp( d->d_name, name ) == 0 )
			return( d );

	return( NULL );
}

/* Make look_up tables for the Yr,Yb,Yg <=> r,g,b conversions.
 */
static void
calcul_tables( struct im_col_display *d, struct im_col_tab_disp	*table )
{
	int i;
	float a, ga_i, ga, c, f, yo, p;
	float maxr, maxg, maxb;

	c = (d->d_B - 100.0) / 500.0;

	/**** Red ****/
	yo = d->d_Y0R;
	a = d->d_YCR - yo;
	ga = d->d_gammaR;
	ga_i = 1.0 / ga;
	p = d->d_P / 100.0;
	f = d->d_Vrwr / p;

	maxr = (float) d->d_Vrwr;
	table->ristep = maxr / 1500.0;
	table->rstep = a / 1500.0;

	for( i = 0; i < 1501; i++ )
		table->t_Yr2r[i] = f * (pow( i * table->rstep / a, ga_i ) - c);

	for( i = 0; i < 1501; i++ )
		table->t_r2Yr[i] = yo + 
			a * pow( i * table->ristep / f + c, ga );

	/**** Green ****/
	yo = d->d_Y0G;
	a = d->d_YCG - yo;
	ga = d->d_gammaG;
	ga_i = 1.0 / ga;
	p = d->d_P / 100.0;
	f = d->d_Vrwg / p;

	maxg = (float)d->d_Vrwg;
	table->gistep = maxg / 1500.0;
	table->gstep = a / 1500.0;

	for( i = 0; i < 1501; i++ )
		table->t_Yg2g[i] = f * (pow( i * table->gstep / a, ga_i ) - c);

	for( i = 0; i < 1501; i++ )
		table->t_g2Yg[i] = yo + 
			a * pow( i * table->gistep / f + c, ga );

	/**** Blue ****/
	yo = d->d_Y0B;
	a = d->d_YCB - yo;
	ga = d->d_gammaB;
	ga_i = 1.0 / ga;
	p = d->d_P / 100.0;
	f = d->d_Vrwb / p;

	maxb = (float)d->d_Vrwb;
	table->bistep = maxb / 1500.0;
	table->bstep = a / 1500.0;

	for( i = 0; i < 1501; i++ )
		table->t_Yb2b[i] = f * (pow( i * table->bstep / a, ga_i ) - c);

	for( i = 0; i < 1501; i++ )
		table->t_b2Yb[i] = yo + 
			a * pow( i * table->bistep / f + c, ga );
}

/* Make the lookup tables for rgb. Pass an IMAGE to allocate memory from.
 */
struct im_col_tab_disp *
im_col_make_tables_RGB( IMAGE *im, struct im_col_display *d )
{
	struct im_col_tab_disp *table;
	double **temp;
	int i, j;

	if( !(table = IM_NEW( im, struct im_col_tab_disp )) )
		return( NULL );

	if( d->d_type == DISP_DUMB ) 
		calcul_tables( d, table );

	if( !(temp = im_dmat_alloc( 0, 2, 0, 2 )) )
		return( NULL );

	for( i = 0; i < 3; i++ )
		for( j = 0; j < 3; j++ ) {
			table->mat_XYZ2lum[i][j] = d->d_mat[i][j];
			temp[i][j] = d->d_mat[i][j];
		}

	if( im_invmat( temp, 3 ) ) {
		im_free_dmat( temp, 0, 2, 0, 2 );
		return( NULL );
	}

	for( i = 0; i < 3; i++ )
		for( j = 0; j < 3; j++ )
			table->mat_lum2XYZ[i][j] = temp[i][j];

	im_free_dmat( temp, 0, 2, 0, 2 );

	return( table );
}

struct im_col_tab_disp *
im_col_display_get_table( struct im_col_display *d )
{
	struct im_col_tab_disp *table;

	if( !im__col_display_tables )
		im__col_display_tables = g_hash_table_new( 
			g_str_hash, g_str_equal );

	if( !(table = g_hash_table_lookup( im__col_display_tables, 
		d->d_name )) ) {
		table = im_col_make_tables_RGB( NULL, d );
		g_hash_table_insert( im__col_display_tables, d->d_name, table );
	}

	return( table );
}

/* Computes the transform: r,g,b => Yr,Yg,Yb. It finds Y values in 
 * lookup tables and calculates X, Y, Z.
 */
int
im_col_rgb2XYZ( struct im_col_display *d, 
	int r, int g, int b, float *X, float *Y, float *Z )
{
	struct im_col_tab_disp *table = im_col_display_get_table( d );
	float *mat = &table->mat_lum2XYZ[0][0];

	float Yr, Yg, Yb;
	int i;

	if( r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 ) {
		im_error( "im_col_rgb2XYZ", "%s", _( "out of range [0,255]" ) );
		return( -1 );
	}

	switch( d->d_type ) {
	case DISP_DUMB:
		/* Convert rgb to Yr, Yg, Yb. 3 times: r, g, b.
	    	 */
		i = r / table->ristep;
		Yr = table->t_r2Yr[i];

		i = g / table->gistep;
		Yg = table->t_g2Yg[i];

		i = b / table->bistep;
		Yb = table->t_b2Yb[i];

		break;

	case DISP_BARCO:
		Yr = d->d_Y0R + r*(d->d_YCR-d->d_Y0R)/255.0;
		Yg = d->d_Y0G + g*(d->d_YCG-d->d_Y0G)/255.0;
		Yb = d->d_Y0B + b*(d->d_YCB-d->d_Y0B)/255.0;
		break;
	
	default:
		im_error( "im_col_rgb2XYZ", "%s", _( "bad display type" ) );
		return( -1 );
	}

	/* Multiply through the inverse matrix to get XYZ values. 
	 */
	*X = mat[0] * Yr + mat[1] * Yg + mat[2] * Yb;
	*Y = mat[3] * Yr + mat[4] * Yg + mat[5] * Yb;
	*Z = mat[6] * Yr + mat[7] * Yg + mat[8] * Yb;

	return( 0 );
}

/* Turn XYZ into display colour. Return or=1 for out of gamut - rgb will
 * contain an approximation of the right colour.
 */
int
im_col_XYZ2rgb( struct im_col_display *d, 
	float X, float Y, float Z, int *r_ret, int *g_ret, int *b_ret, 
	int *or_ret )
{
	struct im_col_tab_disp *table = im_col_display_get_table( d );
	float *mat = &table->mat_XYZ2lum[0][0];

	int or = 0;		/* Out of range flag */

	float Yr, Yg, Yb;
	int Yint;
	int r, g, b;

	/* Multiply through the matrix to get luminosity values. 
	 */
	Yr = mat[0] * X + mat[1] * Y + mat[2] * Z;
	Yg = mat[3] * X + mat[4] * Y + mat[5] * Z;
	Yb = mat[6] * X + mat[7] * Y + mat[8] * Z;

	/* Any negatives? If yes, set the out-of-range flag and bump up.
	 */
	if( Yr < d->d_Y0R ) { 
		or = 1; 
		Yr = d->d_Y0R; 
	}
	if( Yg < d->d_Y0G ) { 
		or = 1; 
		Yg = d->d_Y0G; 
	}
	if( Yb < d->d_Y0B ) { 
		or = 1; 
		Yb = d->d_Y0B; 
	}

	/* Work out colour value (0-Vrw) to feed the tube to get that
	 * luminosity. Easy for BARCOs, harder for others.
	 */
	switch( d->d_type ) {
	case DISP_DUMB:
		Yint = (Yr - d->d_Y0R) / table->rstep;
		if( Yint > 1500 ) {
			or = 1;
			Yint = 1500;
		}
		r = IM_RINT( table->t_Yr2r[Yint] );

		Yint = (Yg - d->d_Y0G) / table->gstep;
		if( Yint > 1500 ) {
			or = 1;
			Yint = 1500;
		}
		g = IM_RINT( table->t_Yg2g[Yint] );

		Yint = (Yb - d->d_Y0B) / table->bstep;
		if( Yint > 1500 ) {
			or = 1;
			Yint = 1500;
		}
		b = IM_RINT( table->t_Yb2b[Yint] );

		break;

	case DISP_BARCO:
		r = IM_RINT( ((Yr - d->d_Y0R) / (d->d_YCR - d->d_Y0R)) * 255 );
		g = IM_RINT( ((Yg - d->d_Y0G) / (d->d_YCG - d->d_Y0G)) * 255 );
		b = IM_RINT( ((Yb - d->d_Y0B) / (d->d_YCB - d->d_Y0B)) * 255 );

		/* Any silly values? Set out of range and adjust.
		 */
		if( r > d->d_Vrwr ) { 
			or = 1; 
			r = d->d_Vrwr; 
		}
		if( g > d->d_Vrwg ) { 
			or = 1; 
			g = d->d_Vrwg; 
		}
		if( b > d->d_Vrwb ) { 
			or = 1; 
			b = d->d_Vrwb; 
		}
		if( r < 0 ) { 
			or = 1; 
			r = 0; 
		}
		if( g < 0 ) { 
			or = 1; 
			g = 0; 
		}
		if( b < 0 ) { 
			or = 1; 
			b = 0; 
		}

		break;

	default:
		im_error( "XYZ2rgb", "%s", _( "display unknown" ) );
		return( -1 );
		/*NOTREACHED*/
	}

	*r_ret = r;
	*g_ret = g;
	*b_ret = b;

	*or_ret = or; 

	return( 0 ); 
} 

/**
 * im_Lab2disp:
 * @in: input image
 * @out: output image
 *
 * Convert an image from LabQ (Coding == IM_CODING_LABQ) to XYZ.
 *
 * Returns: 0 on success, -1 on error.
 */
int 
im_Lab2disp( IMAGE *in, IMAGE *out, struct im_col_display *disp )
{	
	IMAGE *t[1];

	if( im_open_local_array( out, t, 1, "im_Lab2disp:1", "p" ) ||
		im_Lab2XYZ( in, t[0] ) ||
		im_XYZ2disp( t[0], out, disp ) )
		return( -1 );

	return( 0 );
}

int 
im_dECMC_fromdisp( IMAGE *im1, IMAGE *im2, 
	IMAGE *out, struct im_col_display *d )
{	
	IMAGE *t[4];

	if( im_open_local_array( out, t, 4, "im_dECMC_fromdisp:1", "p" ) ||
		im_disp2XYZ( im1, t[0], d ) ||
		im_XYZ2Lab( t[0], t[1] ) ||
		im_disp2XYZ( im2, t[2], d ) ||
		im_XYZ2Lab( t[2], t[3] ) ||
		im_dECMC_fromLab( t[1], t[3], out ) )
		return( -1 );

	return( 0 );
}

int 
im_dE_fromdisp( IMAGE *im1, IMAGE *im2, IMAGE *out, struct im_col_display *d )
{
	IMAGE *t[2];

	if( im_open_local_array( out, t, 2, "im_dE_fromdisp:1", "p" ) ||
		im_disp2XYZ( im1, t[0], d ) ||
		im_disp2XYZ( im2, t[1], d ) ||
		im_dE_fromXYZ( t[0], t[1], out ) )
		return( -1 );

	return( 0 );
}

int 
im_disp2Lab( IMAGE *in, IMAGE *out, struct im_col_display *d )
{
	IMAGE *t[1];

	if( im_open_local_array( out, t, 1, "im_disp2Lab:1", "p" ) ||
		im_disp2XYZ( in, t[0], d ) ||
		im_XYZ2Lab( t[0], out ) )
		return( -1 );
	
	return( 0 );
}
