 /*
  * Khoros: $Id: lvmapdata.c,v 1.2 1991/12/18 09:25:13 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: lvmapdata.c,v 1.2 1991/12/18 09:25:13 dkhoros Exp $";
#endif

 /*
  * $Log: lvmapdata.c,v $
 * Revision 1.2  1991/12/18  09:25:13  dkhoros
 * HellPatch3
 *
  */

/*
 *----------------------------------------------------------------------
 *
 * 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 to 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: lvmapdata.c
 >>>>
 >>>>      Program Name: vmapdata
 >>>>
 >>>> Date Last Updated: Wed Nov 13 08:58:32 1991 
 >>>>
 >>>>          Routines: lvmapdata - the library call for vmapdata
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "vinclude.h"


/* -library_includes */
/* -library_includes_end */


/****************************************************************
*
* Routine Name: lvmapdata - library call for vmapdata
*
* Purpose:
*    
*    Maps the data through the map to create a new data set  with
*    no map.
*    
*    

* Input:
*    
*    image          xvimage structure containing the data.
*    
*    

* Output:
*    
*    image          holds the result of the remapped data.  The output
*                   data  type  is  the  will be that of the input map
*                   type.
*    
*    

*
* Written By: Tom Sauer
*    
*    10-Jan-91 -Scott Wilson : Fixed bugs in the map  addressing  that
*    prevented  this routine from ever working in SHORT, INT, or FLOAT
*    map data.
*    
*    11-Jan-91 - Scott Wilson : Added support for INT image data type
*    
*    30-Jan-91 - Scott  Wilson  :  Fix  bugs  regarding  subrow  size:
*    map_subrow_size was being left alone instead of being transferred
*    to subrow_size, which was always zero.
*    
*    Tue Nov 12 19:24:41 MST  1991:   John  Rasure:   Added  calls  to
*    kfree()  to free memory where appropriate and cleaned up documen-
*    tation.
*    
*    

****************************************************************/


/* -library_def */
int
lvmapdata(image)

struct xvimage *image;
/* -library_def_end */

/* -library_code */
{
        int i, j, k, imgsize;
        int map_rows, map_cols,*idataptr;
        unsigned char *bptr, *newdata_char, *btmpmap, *bdataptr,*bmap;
        short *sptr, *newdata_short, *stmpmap,*smap;
        long *lptr, *newdata_long, *ltmpmap,*lmap;
        float *fptr, *newdata_float, *ftmpmap,*fmap;
        char *program = "lvmapdata";

             /* make some checks -- must have a map_scheme, the input image
              * must be of type BYTE or INT, and the input must contain only 1
              * image.                                                        */
 
        if (image->map_scheme  == VFF_MS_NONE)
        {
           (void) fprintf(stderr,"\n\nlvmapdata:   ");
           (void) fprintf(stderr,"A map does not exist. Map scheme = none.\n\n");
           return(0);
        }
        if (! (propertype(program,image,VFF_TYP_1_BYTE,FALSE) ||
               propertype(program,image,VFF_TYP_4_BYTE,FALSE))) {
           (void) fprintf(stderr,"\n\nlvmapdata:   ");
           (void) fprintf(stderr,"Input image must be of type BYTE or INTEGER\n\n");
           return(0);
        }
        if (! (proper_num_images(program,image,1,FALSE)))
        {
           (void) fprintf(stderr,"\n\nlvmapdata:   ");
           (void) fprintf(stderr,"Can only work on files with one image\n\n");
           return(0);
        }

        imgsize = image->number_of_rows * image->number_of_cols;
        map_rows = image->map_row_size;
        map_cols = image->map_col_size;

           /*  This routine can operate on map storage types: BYTE, SHORT,
            *   INT, and FLOAT.  For each map type the map scheme can be 
            *   ONE_PER_BAND or SHARED.
            */
      
        switch(image->map_storage_type) {
          case VFF_MAPTYP_1_BYTE:
             if (!(newdata_char = (unsigned char *) 
                     malloc(imgsize*image->map_row_size* 
                            image->num_data_bands*sizeof(char)))) {
                (void) fprintf(stderr, "\n\nlvmapdata: Could not ");
                (void) fprintf(stderr,"malloc room for intermediate image.\n");
                return(0);
             }
             bptr = newdata_char;
             bmap = (unsigned char *)(image->maps);
             switch(image->map_scheme) {
                case VFF_MS_ONEPERBAND:
                    for (i=0; i<image->num_data_bands; i++) {
                      for (j=0; j<map_rows; j++) {
                         bdataptr = (unsigned char *) 
                                (&image->imagedata[i*imgsize]);
                         idataptr = (int *)bdataptr; 
                         btmpmap = bmap+i*map_cols*map_rows+j*map_cols;
                        if (image->data_storage_type == VFF_TYP_1_BYTE)
                          for (k=0; k<imgsize; k++)
                            *bptr++ = btmpmap[*bdataptr++];
                        else
                          for (k=0; k<imgsize; k++)
                            *bptr++ = btmpmap[*idataptr++];
                      }
                    }
                    kfree(image->imagedata);
                    image->imagedata = (char *)newdata_char;
                    break;

                case VFF_MS_SHARED:
                   for (i=0; i<image->num_data_bands; i++) {
                     for (j=0; j<map_rows; j++) {
                       bdataptr = (unsigned char *) 
                                  (&image->imagedata[i*imgsize]);
                       idataptr = (int *)bdataptr; 
                       btmpmap = bmap+j*map_cols;
                       if (image->data_storage_type == VFF_TYP_1_BYTE)
                         for (k=0; k<imgsize; k++)
                           *bptr++ = btmpmap[*bdataptr++];
                       else
                         for (k=0; k<imgsize; k++)
                           *bptr++ = btmpmap[*idataptr++];
                     }
                   }
                    kfree(image->imagedata);
                   image->imagedata = (char *)newdata_char;
                   break;
                 default:
                    (void) fprintf(stderr, "\n\nlvmapdata: Invalid Map Scheme\n");
                    (void) fprintf(stderr,"Can not map data.\n");
                    return(0);
                    break;
             }
             break;


          case VFF_MAPTYP_2_BYTE:
             if (!(newdata_short = (short *)malloc(imgsize*image->map_row_size*
                                   image->num_data_bands*sizeof(short))))
             {
                (void) fprintf(stderr, "\n\nlvmapdata: Could not ");
                (void) fprintf(stderr,"malloc room for intermediate image.\n");
                return(0);
             }
             sptr = newdata_short;
             smap = (short *)(image->maps);
             switch(image->map_scheme) {
                case VFF_MS_ONEPERBAND:
                    for (i=0; i<image->num_data_bands; i++) {
                      for (j=0; j<map_rows; j++) {
                        bdataptr = (unsigned char *) 
                                   (&image->imagedata[i*imgsize]);
                        idataptr = (int *)bdataptr; 
                        stmpmap = smap+i*map_cols*map_rows+j*map_cols;
                        if (image->data_storage_type == VFF_TYP_1_BYTE)
                          for (k=0; k<imgsize; k++)
                            *sptr++ = stmpmap[*bdataptr++];
                        else
                          for (k=0; k<imgsize; k++)
                            *sptr++ = stmpmap[*idataptr++];
                      }
                    }
                    kfree(image->imagedata);
                    image->imagedata = (char *)newdata_short;
                    break;
        
                case VFF_MS_SHARED:
                   for (i=0; i<image->num_data_bands; i++) {
                     for (j=0; j<map_rows; j++) {
                          bdataptr = (unsigned char *) 
                                   (&image->imagedata[i*imgsize]);
                          idataptr = (int *)bdataptr; 
                          stmpmap = smap+j*map_cols;
                       if (image->data_storage_type == VFF_TYP_1_BYTE)
                         for (k=0; k<imgsize; k++)
                           *sptr++ = stmpmap[*bdataptr++];
                       else
                         for (k=0; k<imgsize; k++)
                           *sptr++ = stmpmap[*idataptr++];
                      }
                   }
                    kfree(image->imagedata);
                   image->imagedata = (char *)newdata_short;
                   break;
                 default:
                    (void) fprintf(stderr, "\n\nlvmapdata: Invalid Map Scheme\n");
                    (void) fprintf(stderr,"Can not map data.\n");
                    return(0);
                    break;
             }
             break;

          case VFF_MAPTYP_4_BYTE:
             if (! (newdata_long = (long *)malloc(imgsize*image->map_row_size*
                                   image->num_data_bands*sizeof(long))))
             {
                (void) fprintf(stderr, "\n\nlvmapdata: Could not ");
                (void) fprintf(stderr,"malloc room for intermediate image.\n");
                return(0);
             }
             lptr = newdata_long;
             lmap = (long *)(image->maps);

             switch(image->map_scheme) {
                case VFF_MS_ONEPERBAND:
                    for (i=0; i<image->num_data_bands; i++) {
                      for (j=0; j<map_rows; j++) {
                         bdataptr = (unsigned char *) 
                                   (&image->imagedata[i*imgsize]);
                         idataptr = (int *)bdataptr;
                         ltmpmap = lmap+i*map_cols*map_rows+j*map_cols;
                         if (image->data_storage_type == VFF_TYP_1_BYTE)
                           for (k=0; k<imgsize; k++)
                             *lptr++ = ltmpmap[*bdataptr++];
                         else
                           for (k=0; k<imgsize; k++)
                             *lptr++ = ltmpmap[*idataptr++];
                      }
                    }
                    kfree(image->imagedata);
                    image->imagedata = (char *)newdata_long;
                    break;

                case VFF_MS_SHARED:
                   for (i=0; i<image->num_data_bands; i++) {
                     for (j=0; j<map_rows; j++) {
                          bdataptr = (unsigned char *) 
                                   (&image->imagedata[i*imgsize]);
                          idataptr = (int *)bdataptr; 
                          ltmpmap = lmap+j*map_cols;
                          if (image->data_storage_type == VFF_TYP_1_BYTE)
                            for (k=0; k<imgsize; k++)
                              *lptr++ = ltmpmap[*bdataptr++];
                          else
                            for (k=0; k<imgsize; k++)
                              *lptr++ = ltmpmap[*idataptr++];
                     }
                   }
                    kfree(image->imagedata);
                   image->imagedata = (char *)newdata_long;
                   break;
                 default:
                    (void) fprintf(stderr, "\n\nlvmapdata: Invalid Map Scheme\n");
                    (void) fprintf(stderr,"Can not map data.\n");
                    return(0);
                    break;
             }
             break;

          case VFF_MAPTYP_FLOAT:
             if (! (newdata_float = (float *)malloc(imgsize*image->map_row_size*
                                   image->num_data_bands*sizeof(float))))
             {
                (void) fprintf(stderr, "\n\nlvmapdata: Could not ");
                (void) fprintf(stderr,"malloc room for intermediate image.\n");
                return(0);
             }
             fptr = newdata_float;
             fmap = (float *)(image->maps);

             switch(image->map_scheme) {
                case VFF_MS_ONEPERBAND:
                    for (i=0; i<image->num_data_bands; i++) {
                      for (j=0; j<map_rows; j++) {
                         bdataptr = (unsigned char *) 
                                   (&image->imagedata[i*imgsize]);
                         idataptr = (int *)bdataptr; 
                         ftmpmap = fmap+i*map_cols*map_rows+j*map_cols;
                        if (image->data_storage_type == VFF_TYP_1_BYTE)
                          for (k=0; k<imgsize; k++)
                            *fptr++ = ftmpmap[*bdataptr++];
                        else
                          for (k=0; k<imgsize; k++)
                            *fptr++ = ftmpmap[*idataptr++];
                      }
                    }
                    kfree(image->imagedata);
                    image->imagedata = (char *)newdata_float;
                    break;

                case VFF_MS_SHARED:
                   for (i=0; i<image->num_data_bands; i++) {
                     for (j=0; j<map_rows; j++) {
                          bdataptr = (unsigned char *) 
                                   (&image->imagedata[i*imgsize]);
                          idataptr = (int *)bdataptr; 
                          ftmpmap = fmap+j*map_cols;
                       if (image->data_storage_type == VFF_TYP_1_BYTE)
                         for (k=0; k<imgsize; k++)
                           *fptr++ = ftmpmap[*bdataptr];
                       else
                         for (k=0; k<imgsize; k++)
                           *fptr++ = ftmpmap[*idataptr];
                     }
                   }
                    kfree(image->imagedata);
                   image->imagedata = (char *)newdata_float;
                   break;
                 default:
                    (void) fprintf(stderr, "\n\nlvmapdata: Invalid Map Scheme\n");
                    (void) fprintf(stderr,"Can not map data.\n");
                    return(0);
                    break;
             }
             break;

       default:
            (void) fprintf(stderr, "\n\nlvmapdata: Invalid Map Storage Type\n");
            return(0);
            break;
   
    }

           /* assign image the proper size and set the map to NULL */
    image->data_storage_type = image->map_storage_type;
    image->num_data_bands = image->num_data_bands*image->map_row_size;
    image->map_scheme = VFF_CM_NONE;
    image->map_storage_type = VFF_MAPTYP_NONE;
    image->map_enable = VFF_MAP_OPTIONAL;
    image->map_col_size = 0;
    image->map_row_size = 0;
    image->subrow_size = image->map_subrow_size;
    image->map_subrow_size = 0;
    kfree(image->maps);
    image->maps = NULL;

    return(1);
}
/* -library_code_end */
