 /*
  * Khoros: $Id: warp.c,v 1.2 1991/10/02 00:20:20 khoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: warp.c,v 1.2 1991/10/02 00:20:20 khoros Exp $";
#endif

 /*
  * $Log: warp.c,v $
 * Revision 1.2  1991/10/02  00:20:20  khoros
 * HellPatch2
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 *            Copyright 1990 University of New Mexico
 *
 *  Permission to use, copy, modify, distribute, and sell this
 *  software and its documentation for any purpose is hereby
 *  granted without fee, provided that the above copyright
 *  notice appear in all copies and that both that copyright
 *  notice and this permission notice appear in supporting docu-
 *  mentation, and that the name of UNM not be used in advertis-
 *  ing or publicity pertaining to distribution of the software
 *  without specific, written prior permission.  UNM makes no
 *  representations about the suitability of this software for
 *  any purpose.  It is provided "as is" without express or
 *  implied warranty.
 *
 *  UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 *  NESS, IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 *  INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 *  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 *  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 *  OF THIS SOFTWARE.
 *
 *----------------------------------------------------------------------
 */
#include "unmcopyright.h"
#include "warpimage.h"

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>			FIle Routines  		              <<<<
   >>>>                                                       <<<<
   >>>>			warp_src_image()		      <<<<
   >>>>			compute_tiepoint_coeffs()	      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  */

/************************************************************
*
*  MODULE NAME: warp_src_image()
*
*      PURPOSE: generates the coefficients for warping the source image
*		then systems off vwarp with a putimage to warp the image.
*
*        INPUT: None
*
*       OUTPUT: None
*
*   WRITTEN BY:Tom Sauer
*
**************************************************************/

warp_src_image()

{
	int      num_tiepoints = 0, len;
	struct   xvimage *image_x, *image_y, *srcimg;
	char 	 temp1[MaxLength], *temp, *answers[1], *prompts[1];
	char	 *outfile;
	char	 *vtempnam();
	TiePointNode *tiepts;
	
	if (tiepoints == NULL) return;
	if (tiepoint_mode == SourceOnly) return;

	srcimg = &source_image_header;

	if (srcimg->data_storage_type == VFF_TYP_BIT)
	{
	   bzero(temp1, MaxLength);
           sprintf(temp1, 
		"ERROR: Unable to warp the source image. This image is a BIT image. Only Byte images can be warped\n");
           xvf_error_wait(temp1, "warp_src_image", NULL);
	   return;
	}

	if (srcimg->data_storage_type == VFF_TYP_COMPLEX)
	{
	   bzero(temp1, MaxLength);
           sprintf(temp1, 
		"ERROR: Unable to warp the source image. This image is a COMPLEX image. Only Byte images can be warped\n");
           xvf_error_wait(temp1, "warp_src_image", NULL);
	   return;
	}

	if (srcimg->map_enable == VFF_MAP_FORCE)
	{
	   bzero(temp1, MaxLength);
           sprintf(temp1, 
		"ERROR: Unable to warp the source image. This image  has a map enable of FORCE. Only images with a map enable type of OPTIONAL can be warped");
           xvf_error_wait(temp1, "warp_src_image", NULL);
	   return;
	}
	    
	tiepts = tiepoints;
	while(tiepts != NULL)
	{
	   num_tiepoints++;
	   tiepts = tiepts->next;
	}

	if (num_tiepoints < 4)
	{
	   bzero(temp1, MaxLength);
           sprintf(temp1, 
		"At least 4 tiepoints must be specified in order to compute the warping polynomial coefficients. Only %d tiepoints have been specified",
                num_tiepoints);
           xvf_error_wait(temp1, "warp_src_image", NULL);
	   return;
	}

        if ( ! (compute_binom_coeffs(num_tiepoints, &image_x, &image_y)))
        {
           bzero(temp1, MaxLength);
           (void) sprintf(temp1,
          "Unable to compute the polynomial coefficients used for warping");
           xvf_error_wait(temp1, "warp_src_image", NULL);
           freeimage(image_x);
           freeimage(image_y);
           return;
        }

	if (tmpxcoeffs != NULL) 
        {
	   (void) unlink(tmpxcoeffs);
	   free(tmpxcoeffs);
	}
	if (tmpycoeffs != NULL) 
	{
	   (void) unlink(tmpycoeffs);
	   free(tmpycoeffs);
	}

	tmpxcoeffs = vtempnam("warpx");
	tmpycoeffs = vtempnam("warpy");

        if (!writeimage(tmpxcoeffs, image_x))
        {
	   bzero(temp1, MaxLength);
           sprintf(temp1, 
		"writeimage failed! Unable to write X coefficients temporary file");
           xvf_error_wait(temp1, "warp_src_image", NULL);
	   (void) unlink(tmpxcoeffs);
           free(tmpxcoeffs);
           freeimage(image_x); 
           freeimage(image_y); 
           return;
        }

        if (!writeimage(tmpycoeffs, image_y))
        {
	   bzero(temp1, MaxLength);
           sprintf(temp1, 
	       "writeimage failed! Unable to write Y coefficients temporary file");
           xvf_error_wait(temp1, "warp_src_image", NULL);
	   (void) unlink(tmpycoeffs);
           free(tmpycoeffs);
           freeimage(image_y); 
           freeimage(image_x); 
           return;
        }

	/* ask the user if the warped image should be saved */
	
	bzero(temp1, MaxLength);
	sprintf(temp1, "SAVE RESULTING WARPED IMAGE\nEnter the filename to save the resulting warped image in\nIf no filename is specified, the resulting warped image will not be saved.");

	prompts[0] = xvf_strcpy("Filename");
	answers[0] = NULL;

	xvf_query_wait(temp1, prompts, NULL, answers, 1, 60);
	
	len = VStrlen(answers[0]);

	if (len > 0)
	{
	  outfile = vfullpath(answers[0], NULL, NULL);
	  bzero(temp1, MaxLength);
	  (void) sprintf(temp1, 
		"vwarp -i1 %s -i2 %s -i3 %s -o %s; putimage -i %s &",
		 input_source_image, tmpxcoeffs, tmpycoeffs, 
		 outfile, outfile);
	  xvf_fork(temp1, NULL, NULL);
	}
	else
	{
	    bzero(temp1, MaxLength);
	    (void) sprintf(temp1, 
		"vwarp -i1 %s -i2 %s -i3 %s -o - | putimage -i - &",
		 input_source_image, tmpxcoeffs, tmpycoeffs);
	    xvf_fork(temp1, NULL, NULL);
	}

	bzero(temp1, MaxLength);
        sprintf(temp1, "The source image is being warped. When the ");
	temp = VStrcpy(temp1);
	bzero(temp1, MaxLength);
        sprintf(temp1, 
	       "warpping is finished, the warped image will be displayed.");
	temp = VStrcat(temp, temp1);
	bzero(temp1, MaxLength);
/*
        sprintf(temp1, "\n\nNote, this may take a while, and if the warping fails no error message is given!!");
	temp = VStrcat(temp, temp1);
*/
	
        xvf_error_wait(temp, "warp_src_image", NULL);

	/*
	 *  Cleanup
	 */
	
	freeimage(image_x);
	freeimage(image_y);
}



/************************************************************
*
*  MODULE NAME: compute_binom_coeffs()
*
*      PURPOSE: This routine will take the tiepoints and
*		call vbilinco to generate the x and y 
*		coefficients necessary to warp the image
*
*        INPUT: num_tiepoints - number of tiepoints
*		x_coeff - a pointer to the x coefficient image
*		y_coeff - a pointer to the y coefficient image
*
*       OUTPUT: x_coeff - a pointer to the x coefficient image
*			 malloc and contains the data.
*               y_coeff - a pointer to the y coefficient image
*			 malloc and contains the data.
*
*   WRITTEN BY:Tom Sauer
*
**************************************************************/

compute_binom_coeffs(num_tiepoints, x_coeff, y_coeff)

int num_tiepoints;
struct xvimage **x_coeff, **y_coeff;
{

	struct   xvimage *image_x, *image_y, *createimage();
	TiePointNode *tiepts;
	float    *src_ptr_x, *src_ptr_y, *tgt_ptr_x, *tgt_ptr_y;
	float	 *src_tie_x, *src_tie_y, *tgt_tie_x, *tgt_tie_y;
	float	 xc[4], yc[4];

	src_tie_x = (float *) malloc(num_tiepoints * sizeof(float));
	src_tie_y = (float *) malloc(num_tiepoints * sizeof(float));
	tgt_tie_x = (float *) malloc(num_tiepoints * sizeof(float));
	tgt_tie_y = (float *) malloc(num_tiepoints * sizeof(float));
	
	tiepts = tiepoints;
	src_ptr_x = src_tie_x;
	src_ptr_y = src_tie_y;
	tgt_ptr_x = tgt_tie_x;
	tgt_ptr_y = tgt_tie_y;
	while(tiepts != NULL)
        {
	   *src_ptr_x = tiepts->src_x; 	     src_ptr_x++;
	   *src_ptr_y = tiepts->src_y; 	     src_ptr_y++;
           *tgt_ptr_x = tiepts->dest_x;      tgt_ptr_x++;
           *tgt_ptr_y = tiepts->dest_y;      tgt_ptr_y++;
	   tiepts = tiepts->next;
	}


	if (! lvbilinco(src_tie_x, src_tie_y, tgt_tie_x, tgt_tie_y, 
			xc, yc, num_tiepoints))
	{
	   free(src_tie_x);
	   free(src_tie_y);
	   free(tgt_tie_x);
	   free(tgt_tie_y);
	   return(0);
	}


	image_x = createimage(2, 2, VFF_TYP_FLOAT, 1, 1, NULL, 0, 0, 
		     VFF_MS_NONE, VFF_MAPTYP_NONE, VFF_LOC_IMPLICIT, 0);

	image_y = createimage(2, 2, VFF_TYP_FLOAT, 1, 1, NULL, 0, 0, 
		    VFF_MS_NONE, VFF_MAPTYP_NONE, VFF_LOC_IMPLICIT, 0);

        image_x->color_space_model = VFF_CM_NONE;
        image_y->color_space_model = VFF_CM_NONE;


	bcopy(xc, image_x->imagedata, 4 * sizeof(float));
	bcopy(yc, image_y->imagedata, 4 * sizeof(float));

	free(src_tie_x);
	free(src_tie_y);
	free(tgt_tie_x);
	free(tgt_tie_y);

	*x_coeff = image_x;
	*y_coeff = image_y;
	
	return(1);
}
