 /*
  * Khoros: $Id$
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id$";
#endif

 /*
  * $Log$
  */ 

/*
 *---------------------------------------------------------------------
 *            Copyright 1990 University of New Mexico
 * 
 * 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"
#include "spectrum.h"

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 >>>>
 >>>>		   Routines To Read Map Data   
 >>>>
 >>>>		   read_normal_map()
 >>>>		   create_ramp_map()
 >>>>		   create_count_column()
 >>>>		   class_registered()
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


/********************************************************
*
*  Routine Name: read_normal_map
*
*       Purpose: Given a 1-D array of map data, this routine sets up
*                a set of pointers into the data array so the data can be
*                accessed by [cluster][col] format.  It is assumed that
*                the map data is stored by columns.
*         Input: numr - # rows
*		 numc - # cols
*		 mapdata - mapdata
*	 Output: returns a 2D float map data array
*
* Written by:  Danielle Argiro & Patrick M. Kelly
*
********************************************************/

float **read_normal_map ( numr, numc, mapdata )

int numr;               /* Number of rows in the image */
int numc;               /* Number of columns in the image */
float *mapdata;         /* map data */

{
        float **map;                            /* Structure to return */
        int i, j;                               /* Loop control */
	float *tmp_map;
	int  *create_count_column();
	int  sum;

	/*
	 *  read in mean vectors 
	 */
        map = (float **) malloc (numr * sizeof(float *));
        if ( map == NULL ) 
        {
		xvf_error_wait("ERROR: Memory allocation failure", "Spectrum",
				NULL);
		return(NULL);
        }
        for ( i = 0; i < numc; i++ ) 
                map [i] = & ( mapdata [ i * numr ] ) ;

	/*
	 *  read in count column (if there is one)
	 */
        if (spc_map_contents & SpcCount)
        {
 	   spc_count = (int *) malloc(spc_map_rownum * sizeof(int));
	   tmp_map = & ( mapdata [ i * numr ] ) ;
	   for (j = 0; j < spc_map_rownum; j++)
	   {
	       spc_count[j] = (int) *tmp_map;
	       tmp_map++;
	   }
	   i++;
        }
	/*
	 *  create the count column 
	 */
        else 
	{
	   spc_count = create_count_column();
	}

	/*
	 *  read in class array (if applicable)
	 */
        spc_img_classnum = 0;
        if (spc_map_contents & SpcClass)
        {
 	   spc_classes = (int *) malloc(spc_map_rownum * sizeof(int));
	   tmp_map = & ( mapdata [ i * numr ] ) ;
	   for (j = 0; j < spc_map_rownum; j++)
	   {
	       spc_classes[j] = (int) *tmp_map;
	       if (spc_classes[j] != -1) 
	       {
		    if (!(class_registered(spc_img_classes, 
		          spc_img_classnum, spc_classes[j])))
		    {
		        spc_img_classes[spc_img_classnum] = spc_classes[j];
		        spc_img_classnum++;
		    }
	       }
	       tmp_map++;
	   }
	   i++;
        }
        else spc_classes = NULL;

	/*
	 *  covariance matrix & covariance diagonal are mutually exclusive
	 */
        spc_matrix_size = 0;
        spc_diag_size   = 0;
        if (spc_map_contents & SpcCovarMatrix & SpcCovarDiag)
        {
	    xvf_error_wait("Warning:  Input Images are allowed to have a covariance matrix OR a covariance diagonal, NOT BOTH. ", "Spectrum", NULL);
	    return(NULL);
        }

	/*
	 *  read in covariance matrix (if applicable)
	 */
        else if (spc_map_contents & SpcCovarMatrix)
        {
           spc_matrix_size = ((spc_map_colnum * (spc_map_colnum+1)) / 2) ;
	   spc_covar_matrix = (float **) malloc (numr * sizeof(float *));
           if ( spc_covar_matrix == NULL )
           {
                xvf_error_wait("ERROR: Memory allocation failure", "Spectrum",
                                NULL);
                return(NULL);
            }

            for ( i = 0; i < spc_matrix_size; i++ )
                spc_covar_matrix [i] = & ( mapdata [ i * numr ] ) ;
        }

	/*
	 *  read in covariance diagonal (if applicable)
	 */
        else if (spc_map_contents & SpcCovarDiag)
        {
           spc_diag_size = spc_map_colnum;
           spc_covar_diag = (float **) malloc (numr * sizeof(float *));
           if ( spc_covar_diag == NULL )
           {
                xvf_error_wait("ERROR: Memory allocation failure", "Spectrum",
                                NULL);
                return(NULL);
           }

           for ( i = 0; i < spc_diag_size; i++ )
                spc_covar_diag[i] = & ( mapdata [ i * numr ] ) ;
        }

        return ( map );
}


/********************************************************
*
*  Routine Name: create_ramp_map
*       Purpose: given a VIFF image with map scheme NONE,
*		 creates three map columns with ramp numbers.
*
*	  Input: none
*	 Output: spc_map
*    Written by: Danielle Argiro
*
********************************************************/
#define RowNum 256 
#define ColNum 3

float **create_ramp_map()
{
	int i, j;
	float **map;
	int   *create_count_column();

        map = (float **) malloc (RowNum * sizeof(float *));
	for (i = 0; i < ColNum; i++)
	{
	    map[i] =  (float *) malloc (RowNum * sizeof(float *));
	    for (j = 0; j < RowNum; j++)
		map[i][j] = j;
	}
	spc_map_rownum = RowNum;
	spc_map_colnum = ColNum;
	spc_count = create_count_column();
	return(map);
}

/********************************************************
*
*  Routine Name: create_count_column
*       Purpose: Creates a count column for the image if there was
*		 not one provided.  This is done by counting the occurances
*		 of each cluster in the image data, and entering that number
*		 at the location indexed by the cluster number.
*	  Input: none
*	 Output: the count column
*    Written by: Danielle Argiro
*
********************************************************/
int *create_count_column()
{
    int  i, cluster, nr, nc;
    int *count_col;
    unsigned char *cptr;

    count_col = (int *) malloc(spc_map_rownum * sizeof(int));

    for (i = 0; i < spc_map_rownum; i++)
        count_col[i] = 0;

    cptr = (unsigned char *) spc_image->imagedata;
    nr = spc_image->col_size; 
    nc = spc_image->row_size;

    for (i = 0; i < nr*nc; i++)
    {
	cluster = (int) *cptr;
	if (cluster < spc_map_rownum)
           count_col[cluster] += 1;
        else
        {
	   fprintf(stderr, "Spectrum: Warning - image data value outside range\n");
	}
	cptr++;
    }

    return(count_col);
}


/********************************************************
*
*  Routine Name: class_registered
*       Purpose: given an integer array with all the current class
*		 numbers stored in it, sees if the class passed in
*		 is already registered in the array. Returns True
*		 if the class number is stored in the array,
*		 False otherwise.
*	  Input: classes -- array with class numbers
*		 num_classes -- number of classes (size of classees array)
* 		 class -- class number to be checked
*	 Output: True if class is registered in class array, False otherwise
*    Written by: Danielle Argiro
*
********************************************************/
int class_registered ( classes, num_classes, class)
int *classes;
int num_classes;
int class;
{
	int i = 0, found = False;

	while ((i < num_classes) && !(found))
	{
	    if (classes[i] == class) found = true;
	    i++;
	}

	if (found) return(True);
	else return(False);
}

