 /*
  * Khoros: $Id: lvmcustom.c,v 1.1 1991/05/10 15:41:54 khoros Exp $
  */

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

 /*
  * $Log: lvmcustom.c,v $
 * Revision 1.1  1991/05/10  15:41:54  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: lvmcustom.c
 >>>>
 >>>>      Program Name: vmcustom
 >>>>
 >>>> Date Last Updated: Sat Mar  9 08:25:24 1991 
 >>>>
 >>>>          Routines: lvmcustom - the library call for vmcustom
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/


#include "vinclude.h"


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


/****************************************************************
*
* Routine Name: lvmcustom - library call for vmcustom
*
* Purpose:
*    
*    Customizes a morphological kernel via keyboard entry
*    
*    
* Input:
*    
*         1.  kernel - pointer to xvimage structure pointer
*         2.  rows   - number of rows of image to generate
*         3.  cols   - number of columns of image to generate
*         4.  xstart - x coordinate of upper left pixel
*         5.  ystart - y coordinate of upper left pixel
*    
*    
* Output:
*    
*         1.  kernel - Holds the created kernel
*    
*    
*
* Written By: Pascal ADAM
*    
*    Converted with GHOST on Thu May 24 16:24:44 MDT 1990
*    
*    
****************************************************************/


/* -library_def */
int
lvmcustom ( image, name, rows, cols, starti, startj)
struct xvimage **image;
int rows, cols, starti, startj;
char *name;
/* -library_def_end */

/* -library_code */
{

#define EMPTY    0
#define NONEMPTY 1
#define MIN_BORDER ((last_row == NONEMPTY) && (first_row == NONEMPTY) && \
                    (last_col == NONEMPTY) && (first_col == NONEMPTY))

        int     i, 
                j, 
                k, 
                first_row, 
                last_row, 
                first_col, 
                last_col;
  

        int type = VFF_TYP_1_BYTE;

        struct xvimage *kern, *createimage();

        unsigned char *cptr, *kptr, *newkptr, *kernel; 

        char buffer[512];

        char *program = "lvmcustom";
  

 
        /* before creating the image that will contain the kernel ....*/
        /* temporary storage to test after value entry if rows and ...*/
        /* cols are minimum (first and last rows and cols nonempty "0"*/
        kernel=(unsigned char *)malloc(rows*cols*sizeof(unsigned char));
        if  ( kernel == NULL ) 
        {
            (void) fprintf(stderr, " \n%s:   ", program);
            (void) fprintf(stderr, "Insufficient space available\n");
            return(0);
        } 
        kptr = (unsigned char *)kernel;
        
        (void) printf("\n\nkernel initialization\n\n");
        (void) printf("Name                             :  %s \n",name);
        (void) printf("Upper left hand corner position  : x=%d, y=%d\n",
                       starti,startj);
        (void) printf("Rows size                        :  %d \n",cols);
        (void) printf("Columns size                     :  %d \n\n",rows);
        (void) printf("Enter 0 or 1 for kernel elements !\n\n");
        for (i = 0; i < rows; i++) 
        {
            for (j = 0; j < cols; j++)
            {
                (void) printf("kernel[%d][%d] = ",i+starti,j+startj);

                while (scanf("%d",&k) !=1)
                {
                    (void) gets(buffer);
                    (void) printf("'%s' not a valid integer. re-enter:\
                                  \nkernel[%d][%d] = ", 
                                  buffer, i+starti,j+startj);
                }
                while (k!=0 && k!=1)
                {
                   (void) printf("lvcustom: Invalid input -- Valid input 0 or 1\n");
                   (void) printf("\nkernel[%d][%d] = ",i+starti,
                                 j+startj);
                
                   while (scanf("%d",&k) !=1)
                   {
                       (void) gets(buffer);
                       (void) printf("'%s' not a valid integer. re-enter:\
                              \nkernel[%d][%d] = ", buffer, 
                              i+starti,j+startj);
                   }
                }
                *kptr++ = k*255;
            }
        }

        /* check that 1st or last row or column are NONEMPTY      */
        /* that is to contain at least a element different from 0 */
        do 
        {
            kptr = (unsigned char *) kernel;

            first_col = last_col = first_row = last_row = EMPTY;

            for (i=0;i<rows;i++)
            {
                for (j=0;j<cols;j++)
                {
        
                    if ((i == 0)      && (*kptr != 0)) first_row = NONEMPTY;
                    if ((i == rows-1) && (*kptr != 0)) last_row  = NONEMPTY;
                    if ((j == 0)      && (*kptr != 0)) first_col = NONEMPTY;
                    if ((j == cols-1) && (*kptr != 0)) last_col  = NONEMPTY;
      
                    kptr++;
                }
            }
            /* in case of one of the border contains only pixel with */
            /* a value 0, the kernel dimension has to be reduced and */
            /* the data have to be reorganised in the kernel struct. */
            kptr = newkptr = (unsigned char *)kernel;

            if ( MIN_BORDER == FALSE ) 
            {
                if (first_row == EMPTY) starti += 1; 
                if (first_col == EMPTY) startj += 1; 
                for (i=0;i<rows;i++)
                {
                    for (j=0;j<cols;j++)
                    {
                        if ( ((first_row == EMPTY) && (i == 0)     ) ||
                             ((last_row  == EMPTY) && (i == rows-1)) ||
                             ((first_col == EMPTY) && (j == 0)     ) ||
                             ((last_col  == EMPTY) && (j == cols-1)) )
                             kptr++;
                        else *newkptr++ = *kptr++;
                    }
                }
                if (first_row == EMPTY) 
                {
                   rows -= 1;
                   if (rows == 0 ) 
                   {
                      (void) fprintf(stderr,"lvmcustom : kernel must have one");
                      (void) fprintf(stderr," value other than zero \n");
                      return(0);
                   }
                }
                if (last_row  == EMPTY) 
                {
                   rows -= 1;
                   if (rows == 0 ) 
                   {
                      (void) fprintf(stderr,"lvmcustom : kernel must have one");
                      (void) fprintf(stderr," value other than zero \n");
                       return(0);
                   }
                }

                if (first_col == EMPTY) 
                {
                   cols -= 1;
                   if (cols == 0 ) 
                   {
                      (void) fprintf(stderr,"lvmcustom : kernel must have one");
                      (void) fprintf(stderr," value other than zero \n");
                       return(0);
                   }
                }
                if (last_col  == EMPTY) 
                {
                   cols -= 1;
                   if (cols == 0 ) 
                   {
                      (void) fprintf(stderr,"lvmcustom : kernel must have one");
                      (void) fprintf(stderr," value other than zero \n");
                       return(0);
                   }
               }
            }
        }
        while ( MIN_BORDER == FALSE );                       

        (void) printf("\n\nYour kernel will be ............ \n");
        (void) printf("Name                           :  %s \n",name);
        (void) printf("Upper left hand corner position: x = %d, y = %d\n",
                      starti,startj);
        (void) printf("Rows size                      :  %d \n",cols);
        (void) printf("Columns size                   :  %d \n\n",rows);
        (void) printf("Values .........................\n");

        for (i = 0; i < rows; i++) 
        {
            (void) printf("\n row %3d ....     ",i);
            for (j = 0; j < cols; j++)
                (void) printf("%d ",*(kptr++)/255);
        }
        (void) printf("\n\n\n");
        (void) printf("The number of rows and columns may \n");
        (void) printf("have changed if one of the borders \n");
        (void) printf("of the kernel was all zeros\n");
  
        /* creation of image structure that will contain the kernel   */        
        kern = createimage((unsigned long) rows, /* number of rows    */
                        (unsigned long) cols,    /* number of columns */
                        (unsigned long) type,    /* data_storage_type */
                        (unsigned long) 1,       /* num_of_images     */
                        (unsigned long) 1,       /* num_data_bands    */
                        "created by vmcustom",   /* comment           */
                        (unsigned long) 0,       /* map_row_size      */
                        (unsigned long) 0,       /* map_col_size      */
                        (unsigned long)
                        VFF_MS_NONE,             /* map_scheme        */
                        (unsigned long)
                        VFF_MAPTYP_NONE,         /* map_storage_type  */
                        (unsigned long)
                        VFF_LOC_IMPLICIT,        /* location_type     */
                        (unsigned long) 0);      /* location_dim      */

        if (kern == NULL)
        {
           (void)fprintf(stderr,"lvmcustom: Unable to allocate new image!\n");
           *image = NULL;
           return(0);
        }

        cptr = (unsigned char *) kern->imagedata;
        kptr = (unsigned char *) kernel;
        for (i=0 ;i < rows*cols ; i++) *(cptr++) = *(kptr++);

        kern->ispare1=starti;
        kern->ispare2=startj;

        *image = kern;

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