/* affine transforms
 */

/*

    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

 */

/*
 */
#define DEBUG

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <limits.h>

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

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

/* Calculate the inverse transformation.
 */
int
im__transform_calc_inverse( Transformation *trn )
{
	DOUBLEMASK *msk, *msk2;

	if( !(msk = im_create_dmaskv( "boink", 2, 2, 
		trn->a, trn->b, trn->c, trn->d )) )
		return( -1 );
	if( !(msk2 = im_matinv( msk, "boink2" )) ) {
		(void) im_free_dmask( msk );
		return( -1 );
	}
	trn->ia = msk2->coeff[0];
	trn->ib = msk2->coeff[1];
	trn->ic = msk2->coeff[2];
	trn->id = msk2->coeff[3];
	(void) im_free_dmask( msk );
	(void) im_free_dmask( msk2 );

	return( 0 );
}

/* Init a Transform.
 */
void
im__transform_init( Transformation *trn )
{
	trn->oarea.left = 0;
	trn->oarea.top = 0;
	trn->oarea.width = -1;
	trn->oarea.height = -1;
	trn->iarea.left = 0;
	trn->iarea.top = 0;
	trn->iarea.width = -1;
	trn->iarea.height = -1;
	trn->a = 1.0;	/* Identity transform */
	trn->b = 0.0;
	trn->c = 0.0;
	trn->d = 1.0;
	trn->dx = 0.0;
	trn->dy = 0.0;

	(void) im__transform_calc_inverse( trn );
}

/* Test for transform is identity function.
 */
int
im__transform_isidentity( const Transformation *trn )
{
	if( trn->a == 1.0 && trn->b == 0.0 && trn->c == 0.0 &&
		trn->d == 1.0 && trn->dx == 0.0 && trn->dy == 0.0 )
		return( 1 );
	else
		return( 0 );
}

/* Combine two transformations. out can be one of the ins.
 */
int
im__transform_add( const Transformation *in1, const Transformation *in2, 
	Transformation *out )
{
	out->a = in1->a * in2->a + in1->c * in2->b;
	out->b = in1->b * in2->a + in1->d * in2->b;
	out->c = in1->a * in2->c + in1->c * in2->d;
	out->d = in1->b * in2->c + in1->d * in2->d;

	out->dx = in1->dx * in2->a + in1->dy * in2->b + in2->dx;
	out->dy = in1->dx * in2->c + in1->dy * in2->d + in2->dy;

	if( im__transform_calc_inverse( out ) )
		return( -1 );

	return( 0 );
}

void 
im__transform_print( const Transformation *trn )
{
	printf( "im__transform_print:\n" );
	printf( " iarea: left=%d, top=%d, width=%d, height=%d\n",
		trn->iarea.left,
		trn->iarea.top,
		trn->iarea.width,
		trn->iarea.height );
	printf( " oarea: left=%d, top=%d, width=%d, height=%d\n",
		trn->oarea.left,
		trn->oarea.top,
		trn->oarea.width,
		trn->oarea.height );
	printf( " mat: a=%g, b=%g, c=%g, d=%g\n",
		trn->a, trn->b, trn->c, trn->d );
	printf( " off: dx=%g, dy=%g\n",
		trn->dx, trn->dy );
}

/* Map a pixel coordinate through the transform. 
 */
void
im__transform_forward_point( const Transformation *trn, 
	const double x, const double y,		/* In input space */
	double *ox, double *oy )	/* In output space */
{
	*ox = trn->a * x + trn->b * y + trn->dx;
	*oy = trn->c * x + trn->d * y + trn->dy;
}

/* Map a pixel coordinate through the inverse transform. 
 */
void
im__transform_invert_point( const Transformation *trn, 
	const double x, const double y,		/* In output space */
	double *ox, double *oy )	/* In input space */
{
	double mx = x - trn->dx;
	double my = y - trn->dy;

	*ox = trn->ia * mx + trn->ib * my;
	*oy = trn->ic * mx + trn->id * my;
}

typedef void (*transform_fn)( const Transformation *, 
	const double, const double, double*, double* );

/* Transform a rect using a point transformer.
 */
static void
transform_rect( const Transformation *trn, transform_fn transform,
	const Rect *in,		/* In input space */
	Rect *out )		/* In output space */
{
	double x1, y1;		/* Map corners */
	double x2, y2;
	double x3, y3;
	double x4, y4;
	double left, right, top, bottom;

	/* Map input Rect.
	 */
	transform( trn, in->left, in->top, &x1, &y1 );
	transform( trn, in->left, IM_RECT_BOTTOM( in ), &x3, &y3 );
	transform( trn, IM_RECT_RIGHT( in ), in->top, &x2, &y2 );
	transform( trn, IM_RECT_RIGHT( in ), IM_RECT_BOTTOM( in ), &x4, &y4 );

	/* Find bounding box for these four corners. Round-to-nearest to try
	 * to stop rounding errors growing images.
	 */
	left = IM_MIN( x1, IM_MIN( x2, IM_MIN( x3, x4 ) ) );
	right = IM_MAX( x1, IM_MAX( x2, IM_MAX( x3, x4 ) ) );
	top = IM_MIN( y1, IM_MIN( y2, IM_MIN( y3, y4 ) ) );
	bottom = IM_MAX( y1, IM_MAX( y2, IM_MAX( y3, y4 ) ) );

	out->left = IM_RINT( left );
	out->top = IM_RINT( top );
	out->width = IM_RINT( right - left );
	out->height = IM_RINT( bottom - top );
}

/* Given an area in the input image, calculate the bounding box for those
 * pixels in the output image.
 */
void
im__transform_forward_rect( const Transformation *trn,
	const Rect *in, 	/* In input space */
	Rect *out )		/* In output space */
{
	transform_rect( trn, im__transform_forward_point, in, out );
}

/* Given an area in the output image, calculate the bounding box for the 
 * corresponding pixels in the input image.
 */
void
im__transform_invert_rect( const Transformation *trn, 
	const Rect *in,		/* In output space */
	Rect *out )		/* In input space */
{
	transform_rect( trn, im__transform_invert_point, in, out );
}

/* Set output area of trn so that it just holds all of our input pels.
 */
void
im__transform_set_area( Transformation *trn )
{
	im__transform_forward_rect( trn, &trn->iarea, &trn->oarea );
}
