/* Various functions relating to tone curve adjustment.
 *
 * Author: John Cupitt
 * Written on: 18/7/1995
 * 17/9/96 JC
 *	- restrictions on Ps, Pm, Ph relaxed
 *	- restrictions on S, M, H relaxed
 * 25/7/01 JC
 *	- patched for im_extract_band() change
 * 11/7/04
 *	- generalised to im_tone_build_range() ... so you can use it for any
 *	  image, not just LabS
 * 26/3/10
 * 	- cleanups
 * 	- gtkdoc
 */

/*

    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 <stdlib.h>
#include <math.h>

#include <vips/vips.h>

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

/* Parameters for tone curve formation.
 */
typedef struct {
	/* Parameters.
	 */
	double Lb, Lw;
	double Ps, Pm, Ph; 
	double S, M, H;

	/* Derived values.
	 */
	double Ls, Lm, Lh;
} ToneShape;

/* Calculate shadow curve.
 */
static double
shad( ToneShape *ts, double x )
{
	double x1 = (x - ts->Lb) / (ts->Ls - ts->Lb);
	double x2 = (x - ts->Ls) / (ts->Lm - ts->Ls);
	double out;

	if( x < ts->Lb )
		out = 0;
	else if( x < ts->Ls )
		out = 3.0 * x1 * x1 - 2.0 * x1 * x1 * x1;
	else if( x < ts->Lm )
		out = 1.0 - 3.0 * x2 * x2 + 2.0 * x2 * x2 * x2;
	else 
		out = 0;

	return( out );
}

/* Calculate mid-tone curve.
 */
static double
mid( ToneShape *ts, double x )
{
	double x1 = (x - ts->Ls) / (ts->Lm - ts->Ls);
	double x2 = (x - ts->Lm) / (ts->Lh - ts->Lm);
	double out;

	if( x < ts->Ls )
		out = 0;
	else if( x < ts->Lm )
		out = 3.0 * x1 * x1 - 2.0 * x1 * x1 * x1;
	else if( x < ts->Lh )
		out = 1.0 - 3.0 * x2 * x2 + 2.0 * x2 * x2 * x2;
	else 
		out = 0;

	return( out );
}

/* Calculate highlight curve.
 */
static double
high( ToneShape *ts, double x )
{
	double x1 = (x - ts->Lm) / (ts->Lh - ts->Lm);
	double x2 = (x - ts->Lh) / (ts->Lw - ts->Lh);
	double out;

	if( x < ts->Lm )
		out = 0;
	else if( x < ts->Lh )
		out = 3.0 * x1 * x1 - 2.0 * x1 * x1 * x1;
	else if( x < ts->Lw )
		out = 1.0 - 3.0 * x2 * x2 + 2.0 * x2 * x2 * x2;
	else 
		out = 0;

	return( out );
}

/* Generate a point on the tone curve. Everything is 0-100.
 */
static double
tone_curve( ToneShape *ts, double x )
{
	double out;

	out = x + 
		ts->S * shad( ts, x ) + ts->M * mid( ts, x ) + 
		ts->H * high( ts, x );
	
	return( out );
}

/**
 * im_tone_build_range:
 * out: output image 
 * in_max: input range 
 * out_max: output range
 * Lb: black-point [0-100]
 * Lw: white-point [0-100]
 * Ps: shadow point (eg. 0.2)
 * Pm: mid-tone point (eg. 0.5)
 * Ph: highlight point (eg. 0.8)
 * S: shadow adjustment (+/- 30)
 * M: mid-tone adjustment (+/- 30)
 * H: highlight adjustment (+/- 30)
 *
 * im_tone_build_range() generates a tone curve for the adjustment of image 
 * levels. It is mostly designed for adjusting the L* part of a LAB image in
 * way suitable for print work, but you can use it for other things too.
 *
 * The curve is an unsigned 16-bit image with (@in_max + 1) entries, 
 * each in the range [0, @out_max].
 *
 * @Lb, @Lw are expressed as 0-100, as in LAB colour space. You 
 * specify the scaling for the input and output images with the @in_max and 
 * @out_max parameters.
 *
 * See also: im_ismonotonic(), im_tone_map(), im_tone_analyse().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_tone_build_range( IMAGE *out, 
	int in_max, int out_max,
	double Lb, double Lw,
	double Ps, double Pm, double Ph, 
	double S, double M, double H )
{
	ToneShape *ts;
	unsigned short lut[65536];
	int i;

	/* Check args.
	 */
	if( !(ts = IM_NEW( out, ToneShape )) ||
		im_outcheck( out ) )
		return( -1 );
	if( in_max < 0 || in_max > 65535 ||
		out_max < 0 || out_max > 65535 ) {
		im_error( "im_tone_build", 
			"%s", _( "bad in_max, out_max parameters" ) );
		return( -1 );
	}
	if( Lb < 0 || Lb > 100 || Lw < 0 || Lw > 100 || Lb > Lw ) {
		im_error( "im_tone_build", 
			"%s", _( "bad Lb, Lw parameters" ) );
		return( -1 );
	}
	if( Ps < 0.0 || Ps > 1.0 ) {
		im_error( "im_tone_build", 
			"%s", _( "Ps not in range [0.0,1.0]" ) );
		return( -1 );
	}
	if( Pm < 0.0 || Pm > 1.0 ) {
		im_error( "im_tone_build", 
			"%s", _( "Pm not in range [0.0,1.0]" ) );
		return( -1 );
	}
	if( Ph < 0.0 || Ph > 1.0 ) {
		im_error( "im_tone_build", 
			"%s", _( "Ph not in range [0.0,1.0]" ) );
		return( -1 );
	}
	if( S < -30 || S > 30 ) {
		im_error( "im_tone_build", 
			"%s", _( "S not in range [-30,+30]" ) );
		return( -1 );
	}
	if( M < -30 || M > 30 ) {
		im_error( "im_tone_build", 
			"%s", _( "M not in range [-30,+30]" ) );
		return( -1 );
	}
	if( H < -30 || H > 30 ) {
		im_error( "im_tone_build", 
			"%s", _( "H not in range [-30,+30]" ) );
		return( -1 );
	}

	/* Note params.
	 */
	ts->Lb = Lb; 
	ts->Lw = Lw;
	ts->Ps = Ps; 
	ts->Pm = Pm; 
	ts->Ph = Ph;
	ts->S = S; 
	ts->M = M; 
	ts->H = H;

	/* Note derived params.
	 */
	ts->Ls = Lb + Ps * (Lw - Lb);
	ts->Lm = Lb + Pm * (Lw - Lb);
	ts->Lh = Lb + Ph * (Lw - Lb);

	/* Generate curve.
	 */
	for( i = 0; i <= in_max; i++ ) {
		int v = (out_max / 100.0) * 
			tone_curve( ts, 100.0 * i / in_max );

		if( v < 0 )
			v = 0;
		else if( v > out_max )
			v = out_max;
		
		lut[i] = v;
	}

	/* Make the output image.
	 */
	im_initdesc( out,
		in_max + 1, 1, 1, IM_BBITS_SHORT, IM_BANDFMT_USHORT, 
		IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 );
	if( im_setupout( out ) )
		return( -1 );

	if( im_writeline( 0, out, (PEL *) lut ) )
		return( -1 );

	return( 0 );
}

/**
 * im_tone_build:
 * out: output image 
 * Lb: black-point [0-100]
 * Lw: white-point [0-100]
 * Ps: shadow point (eg. 0.2)
 * Pm: mid-tone point (eg. 0.5)
 * Ph: highlight point (eg. 0.8)
 * S: shadow adjustment (+/- 30)
 * M: mid-tone adjustment (+/- 30)
 * H: highlight adjustment (+/- 30)
 *
 * As im_tone_build_range(), but set 32767 and 32767 as values for @in_max 
 * and @out_max. This makes a curve suitable for correcting LABS
 * images, the most common case.
 *
 * See also: im_tone_build_range().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_tone_build( IMAGE *out, 
	double Lb, double Lw,
	double Ps, double Pm, double Ph, 
	double S, double M, double H )
{
	IMAGE *t1;

	if( !(t1 = im_open_local( out, "im_tone_build", "p" )) ||
		im_tone_build_range( t1, 32767, 32767,
			Lb, Lw, Ps, Pm, Ph, S, M, H ) ||
		im_clip2fmt( t1, out, IM_BANDFMT_SHORT ) )
		return( -1 );

	return( 0 );
}

/**
 * im_ismonotonic:
 * @lut: lookup-table to test
 * @out: set non-zero if @lut is monotonic 
 *
 * Test @lut for monotonicity. @out is set non-zero if @lut is monotonic.
 *
 * See also: im_tone_build_range().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_ismonotonic( IMAGE *lut, int *out )
{
	IMAGE *t[2];
	INTMASK *mask;
	double m;

	if( im_check_hist( "im_ismonotonic", lut ) ||
		im_open_local_array( lut, t, 2, "im_ismonotonic", "p" ) )
		return( -1 );

	if( lut->Xsize == 1 ) 
		mask = im_create_imaskv( "im_ismonotonic", 1, 2, -1, 1 );
	else 
		mask = im_create_imaskv( "im_ismonotonic", 2, 1, -1, 1 );
	if( !(mask = im_local_imask( lut, mask )) )
		return( -1 );
	mask->offset = 128;

	/* We want >=128 everywhere, ie. no -ve transitions.
	 */
	if( im_conv( lut, t[0], mask ) ||
		im_moreeqconst( t[0], t[1], 128 ) ||
		im_min( t[1], &m ) )
		return( -1 );

	*out = m;

	return( 0 );
}

/**
 * im_tone_map:
 * @in: input image
 * @out: output image
 * @lut: look-up table
 *
 * Map the first channel of @in through @lut. If @in is IM_CODING_LABQ, unpack
 * to LABS, map L and then repack. 
 *
 * @in should be a LABS or LABQ image for this to work
 * sensibly.
 *
 * See also: im_maplut().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_tone_map( IMAGE *in, IMAGE *out, IMAGE *lut )
{
	IMAGE *t[8];

	if( im_check_hist( "im_tone_map", lut ) ||
		im_open_local_array( out, t, 8, "im_tone_map", "p" ) )
		return( -1 );

	/* If in is IM_CODING_LABQ, unpack.
	 */
	if( in->Coding == IM_CODING_LABQ ) {
		if( im_LabQ2LabS( in, t[0] ) )
			return( -1 );
	}
	else
		t[0] = in;

	/* Split into bands.
	 */
	if( im_extract_band( t[0], t[1], 0 ) )
		return( -1 );
	if( t[0]->Bands > 1 ) {
		if( im_extract_bands( t[0], t[2], 1, t[0]->Bands - 1 ) )
			return( -1 );
	}

	/* Map L.
	 */
	if( im_maplut( t[1], t[3], lut ) )
		return( -1 );

	/* Recombine bands. 
	 */
	if( t[0]->Bands > 1 ) {
		if( im_bandjoin( t[3], t[2], t[4] ) )
			return( -1 );
	}
	else
		t[4] = t[3];

	/* If input was LabQ, repack.
	 */
	if( in->Coding == IM_CODING_LABQ ) {
		if( im_LabS2LabQ( t[4], t[5] ) )
			return( -1 );
	}
	else 
		t[5] = t[4];
	
	return( im_copy( t[4], out ) );
}

/**
 * im_tone_analyse:
 * in: input image 
 * out: output image 
 * Ps: shadow point (eg. 0.2)
 * Pm: mid-tone point (eg. 0.5)
 * Ph: highlight point (eg. 0.8)
 * S: shadow adjustment (+/- 30)
 * M: mid-tone adjustment (+/- 30)
 * H: highlight adjustment (+/- 30)
 *
 * As im_tone_build(), but analyse the histogram of @in and use it to
 * pick the 0.1% and 99.9% points for @Lb and @Lw.
 *
 * See also: im_tone_build().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_tone_analyse( 
	IMAGE *in, 
	IMAGE *out, 
	double Ps, double Pm, double Ph,
	double S, double M, double H )
{
	IMAGE *t[4];
	int low, high;
	double Lb, Lw;

	if( im_open_local_array( out, t, 4, "im_tone_map", "p" ) )
		return( -1 );

	/* If in is IM_CODING_LABQ, unpack.
	 */
	if( in->Coding == IM_CODING_LABQ ) {
		if( im_LabQ2LabS( in, t[0] ) )
			return( -1 );
	}
	else
		t[0] = in;

	/* Should now be 3-band short.
	 */
	if( im_check_uncoded( "im_tone_analyse", t[0] ) ||
		im_check_bands( "im_tone_analyse", t[0], 3 ) ||
		im_check_format( "im_tone_analyse", t[0], IM_BANDFMT_SHORT ) )
		return( -1 );

	if( im_extract_band( t[0], t[1], 0 ) ||
		im_clip2fmt( t[1], t[2], IM_BANDFMT_USHORT ) ||
		im_histgr( t[2], t[3], -1 ) )
		return( -1 );

	if( im_mpercent_hist( t[3], 0.1 / 100.0, &high ) ||
		im_mpercent_hist( t[3], 99.9 / 100.0, &low ) )
		return( -1 );

	Lb = 100 * low / 32768;
	Lw = 100 * high / 32768;

	im_diag( "im_tone_analyse", "set Lb = %g, Lw = %g", Lb, Lw );

	return( im_tone_build( out, Lb, Lw, Ps, Pm, Ph, S, M, H ) );
}
