 /*
  * Khoros: $Id: lvcost.c,v 1.1 1991/05/10 15:43:20 khoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: lvcost.c,v 1.1 1991/05/10 15:43:20 khoros Exp $";
#endif

 /*
  * $Log: lvcost.c,v $
 * Revision 1.1  1991/05/10  15:43:20  khoros
 * Initial revision
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1991, University of New Mexico.  All rights reserved.
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability 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 OTHER DAMAGES WHAT-
 * SOEVER 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 PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *---------------------------------------------------------------------
 */

#include "unmcopyright.h"        /* Copyright 1991 by UNM */

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 >>>>
 >>>>         File Name: lvcost.c
 >>>>
 >>>>      Program Name: vcost
 >>>>
 >>>> Date Last Updated: Thu Mar 28 00:18:59 1991 
 >>>>
 >>>>          Routines: lvcost - the library call for vcost
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "vinclude.h"


/* -library_includes */
#define VCALL(func) if (! func ) { fprintf(stderr,"lvcost: %s failed\n","func"); return(0); }
/* -library_includes_end */


/****************************************************************
*
* Routine Name: lvcost - library call for vcost
*
* Purpose:
*    
*    Compute cost (surface arc length) for an image
*    
*    
* Input:
*    
*    img            Pointer to FLOAT image used to  represent  a  sur-
*                   face.
*    
*    mask           Pointer to FLOAT image used to gate the operation.
*                   If this is NULL, then no masking is done.
*    
*    x              X coordinate of pixel to serve  as  the  reference
*                   location (integer)
*    
*    y              Y coordinate of pixel to serve  as  the  reference
*                   location (integer)
*    
*    
* Output:
*    
*    img            is modified to be of type  FLOAT,  with  the  cost
*                   data assigned to the imagedata pointer. The origi-
*                   nal imagedata area is free()'d.
*    
*    
*
* Written By: Scott Wilson
****************************************************************/


/* -library_def */
int
lvcost(img,mask,x,y)
struct xvimage *img,*mask;
int x,y;
/* -library_def_end */

/* -library_code */
  {
    int i,j,k,rows,cols,n;
    float *f,*m,*fptr;
    double f1,f2,sum;
    struct xvimage *line;

    if (img->num_of_images != 1 ||
        img->num_data_bands != 1 ||
        img->location_type != VFF_LOC_IMPLICIT)
      {
         fprintf(stderr,"lvcost: Surface image should be a single band,");
         fprintf(stderr,"        single image, implitic location, FLOAT");
         fprintf(stderr,"        image.");
         return(0);
      }
    if (mask != NULL)
      {
        if (mask->num_of_images != 1 ||
            mask->num_data_bands != 1 ||
            mask->location_type != VFF_LOC_IMPLICIT ||
            mask->row_size != img->row_size ||
            mask->col_size != img->col_size)
          {
            fprintf(stderr,"lvcost: mask image should match surface image!\n");
            return(0);
          }
        }

    rows = img->number_of_rows;
    cols = img->number_of_cols;

    f = (float *)malloc(rows*cols*sizeof(float));
    if (f == NULL)
      {
        fprintf(stderr,"lvcost: unable to malloc work array\n");
        return(0);
      }
    bzero(f,rows*cols*sizeof(float));

    if (mask != NULL) m = (float *)(mask->imagedata);

    for (i=0; i<rows; i++)
      {
        for (j=0; j<cols; j++)
          {
            if (mask == NULL)
              {
                if (i == y && j == x) f[PIXEL(j,i,rows,cols)] = 0.0;
                else
                  {
                    n = 10*sqrt((double)((x-j)*(x-j)+(y-i)*(y-i)));
                    VCALL(lvsamp(img,&line,x,y,j,i,n));
                    fptr = (float *)(line->imagedata);
                    sum = 0.0;
                    for (k=0; k<(n-1); k++)
                      {
                        f1 = fptr[PIXEL(k+1,0,1,n)]-fptr[PIXEL(k,0,1,n)];
                        f2 = line->pixsizx;
                        sum += sqrt(f1*f1+f2*f2);
                      }
                    f[PIXEL(j,i,rows,cols)] = sum;
                    freeimage(line);
                  } 
              }
            else
              {
                if (m[PIXEL(j,i,rows,cols)] == 0.0)
                  f[PIXEL(j,i,rows,cols)] = -1.0;
                else if (i == y && j == x)
                  f[PIXEL(j,i,rows,cols)] = 0.0;
                else
                  {
                    n = 10*sqrt((double)((x-j)*(x-j)+(y-i)*(y-i)));
                    VCALL(lvsamp(img,&line,x,y,j,i,n));
                    fptr = (float *)(line->imagedata);
                    sum = 0.0;
                    for (k=0; k<(n-1); k++)
                      {
                        f1 = fptr[PIXEL(k+1,0,1,n)]-fptr[PIXEL(k,0,1,n)];
                        f2 = line->pixsizx;
                        sum += sqrt(f1*f1+f2*f2);
                      }
                    f[PIXEL(j,i,rows,cols)] = sum;
                    freeimage(line);
                  } 
              }
          }
      }
    free(img->imagedata);
    img->imagedata = (char *)f;
    return(1);
  }
/* -library_code_end */
