/*
************************************************************
* MODULE: r.le.patch/driver.c                              *
*         Version 5.0                Nov. 1, 2001          *
*				                           *
* AUTHOR: W.L. Baker, University of Wyomirng               *
*         BAKERWL@UWYO.EDU                                 *
*                                                          *
* PURPOSE: To analyze attributes of patches in a landscape *
*         driver.c opens input and output files, and calls *
*         the moving window, unit, and whole map drivers   *
*				                           *
* COPYRIGHT: (C) 2001 by W.L. Baker                        *
*                                                          *
* This program is free software under the GNU General      *
* Public License(>=v2).  Read the file COPYING that comes  *
* with GRASS for details                                   *
*				                           *
************************************************************/

#include <grass/config.h>
#include "patch.h"



/* DEFINE GLOBAL VARIABLES */

  int               ntype=0, finput, n_scale=1, n_unit=1, size_cl_no=0, *recl_count,
                    shape_cl_no=0;
  static int        para1, para2, para3, para4, para5;
  float             *shape_PA, *shape_CPA, *shape_RCC, *size_cl, **recl_tb;
  extern struct     CHOICE *choice;
  char              cmdbuf[100];
  RASTER_MAP_TYPE   data_type;

/*
  Variables:
  GLOBAL:
    ntype =       the number of attribute groups if by gp measures are
                  calculated
    finput =      the raster map to be analyzed
    n_scale =     the number of sampling scales
    n_unit =      the number of sampling units
    para1 =       set to 1 if by gp measures are chosen
    para2 =       set to 1 if size classes are chosen
    para3 =       set to 1 if perimeter-area shape index classes are chosen
    para4 =       set to 1 if corrected perimeter-area shape index classes are
                  chosen
    para5 =       set to 1 if related circumscribing circle shape index classes
                  are chosen
    shape_PA[] =  array to hold the perimeter-area shape index classes
    shape_CPA[] = array to hold the corrected perimeter-area shape index
                  classes
    shape_RCC[] = array to hold the related circumscribing circle shape index
                  classes
    size_cl[] =   array to hold the size classes
    recl_tb[][]=  array to hold the attribute groups
    data_type =   the type of raster map: integer, floating point, or double
*/




                         /* RUN R.LE.PATCH IN FOREGROUND */

void  patch_fore()
{

  fputs("\nR.LE.PATCH IS WORKING....;\n\n", stderr);

                         /* check for input raster map and open it; this
                            map remains open on finput while all the programs
                            run, so it is globally available */
  
  if (0 > (finput = G_open_cell_old(choice->fn, G_mapset()))) {
     fprintf(stderr, "\n");
     fprintf(stderr, "   ******* *************************************************\n");
     fprintf(stderr, "    The raster map you specified with the 'map=' parameter \n");
     fprintf(stderr, "    was not found in your mapset.                          \n");
     fprintf(stderr, "   ********************************************************\n");
     exit(EXIT_FAILURE);
  }

                        /* determine whether the raster map is integer
                           (CELL_TYPE),floating point (FCELL_TYPE), or
                           double (DCELL_TYPE) and make globally available */

  else
     data_type = G_raster_map_type(choice->fn, G_mapset());


                         /* if using a moving window, get the parameters,
                            and start the moving window driver */

  if (choice->wrum == 'm') {
     get_para();
     mv_driver();
     if (para1 || para2 || para3 || para4 || para5)
        free_para();
  }

                        /* get the parameters; if using the whole raster map
                           as the sampling area, start the whole region driver;
                           if using sampling units, start the sampling unit
                           driver */

  else {
     get_para();
     open_files();
     if (choice->wrum != 'u')
        whole_reg_driver();
     else 
        unit_driver();
     if (para1 || para2 || para3 || para4 || para5)
        free_para();
  }

                         /* when everything is done, close the raster file
                            and print a completion message */

  G_close_cell(finput);
  fputs("\nR.LE.PATCH IS DONE;  ", stderr);
  if (choice->wrum != 'm')
     fputs("OUTPUT FILES IN SUBDIRECTORY \"r.le.out\"\n", stderr);
  return;

}





                         /* SETUP THE OUTPUT FILES WHEN SAM=W,U,R */

void  open_files()
{
  FILE   *fp;
  char    path[30];
  int     i;

  if (choice->att[1] || choice->att[2] ||
      choice->att[3] || choice->att[4]) {
     fp = fopen0("r.le.out/a1-4.out", "w");
     fprintf(fp, "Scale  Unit  MN. PIXEL ATT.   S.D. PIXEL ATT.  MN. PATCH ATT.   S.D. PATCH ATT.\n");
     fclose(fp);
  }

  if (choice->att[5]) {
     fp = fopen0("r.le.out/a5.out", "w");
     fprintf(fp, "               COVER (FRACTION) BY GROUP\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->att[6]) {
     fp = fopen0("r.le.out/a6.out", "w");
     fprintf(fp, "               DENSITY BY GROUP\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->att[7]) {
     fp = fopen0("r.le.out/a7.out", "w");
     fprintf(fp, "Scale  Unit  TOTAL DENSITY\n");
     fclose(fp);
  }

  if (choice->att[8]) {
     fp = fopen0("r.le.out/a8.out", "w");
     fprintf(fp, "Scale  Unit  EFF. MESH NUM.\n");
     fclose(fp);
  }

  if (choice->size[1] || choice->size[2]) {
     fp = fopen0("r.le.out/s1-2.out", "w");
     fprintf(fp, "Scale  Unit  MN. PATCH SIZE   S.D. PATCH SIZE -- in pixels\n");
     fclose(fp);
  }

  if (choice->size[3]) {
     fp = fopen0("r.le.out/s3.out", "w");
     fprintf(fp, "               MEAN PATCH SIZE BY GROUP -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->size[4]) {
     fp = fopen0("r.le.out/s4.out", "w");
     fprintf(fp, "               S.D. PATCH SIZE BY GROUP -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->size[5]) {
     fp = fopen0("r.le.out/s5.out", "w");
     fprintf(fp, "               NUMBER OF PATCHES BY SIZE CLASS -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < size_cl_no; i++)
        fprintf(fp, "   Class[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->size[6]) {
     fp = fopen0("r.le.out/s6.out", "w");
     fprintf(fp, "               NUMBER OF PATCHES BY SIZE CLASS BY GROUP -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < size_cl_no; i++)
        fprintf(fp, "   Class[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->size[7] || choice->size[8]) {
     fp = fopen0("r.le.out/s7-8.out", "w");
     fprintf(fp, "Scale  Unit  EFF. MESH SIZE   DEG. LAND. DIV.\n");
     fclose(fp);
  }

  if (choice->core[1] || choice->core[2] ||
      choice->core[3] || choice->core[4]) {
     fp = fopen0("r.le.out/c1-4.out", "w");
     fprintf(fp, "Scale  Unit  MEAN CORE SIZE   S.D. CORE SIZE   MEAN EDGE SIZE   S.D. EDGE SIZE\n");
     fclose(fp);
  }

  if (choice->core[5]) {
     fp = fopen0("r.le.out/c5.out", "w");
     fprintf(fp, "               MEAN CORE SIZE BY GROUP -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->core[6]) {
     fp = fopen0("r.le.out/c6.out", "w");
     fprintf(fp, "               S.D. CORE SIZE BY GROUP -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->core[7]) {
     fp = fopen0("r.le.out/c7.out", "w");
     fprintf(fp, "               MEAN EDGE SIZE BY GROUP -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->core[8]) {
     fp = fopen0("r.le.out/c8.out", "w");
     fprintf(fp, "               S.D. EDGE SIZE BY GROUP -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->core[9]) {
     fp = fopen0("r.le.out/c9c.out", "w");
     fprintf(fp, "               NUMBER OF PATCH CORES BY SIZE CLASS -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < size_cl_no; i++)
        fprintf(fp, "   Class[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
     fp = fopen0("r.le.out/c9e.out", "w");
     fprintf(fp, "               NUMBER OF PATCH EDGES BY SIZE CLASS -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < size_cl_no; i++)
        fprintf(fp, "   Class[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->core[10]) {
     fp = fopen0("r.le.out/c10c.out", "w");
     fprintf(fp, "               NUMBER OF PATCH CORES BY SIZE CLASS BY GROUP -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < size_cl_no; i++)
        fprintf(fp, "   Class[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
     fp = fopen0("r.le.out/c10e.out", "w");
     fprintf(fp, "               NUMBER OF PATCH EDGES BY SIZE CLASS BY GROUP -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < size_cl_no; i++)
        fprintf(fp, "   Class[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->shape[1] || choice->shape[2]) {
     fp = fopen0("r.le.out/h1-2.out", "w");
     fprintf(fp, "Scale  Unit  MN. PATCH SHAPE  SD. PATCH SHAPE\n");
     fclose(fp);
  }

  if (choice->shape[3]) {
     fp = fopen0("r.le.out/h3.out", "w");
     fprintf(fp, "               MEAN PATCH SHAPE BY GROUP\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->shape[4]) {
     fp = fopen0("r.le.out/h4.out", "w");
     fprintf(fp, "               S.D. PATCH SHAPE BY GROUP\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->shape[5]) {
     fp = fopen0("r.le.out/h5.out", "w");
     fprintf(fp, "               NO. OF PATCHES BY SHAPE INDEX CLASS\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < shape_cl_no; i++)
        fprintf(fp, "   Class[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->shape[6]) {
     fp = fopen0("r.le.out/h6.out", "w");
     fprintf(fp, "               NO. OF PATCHES BY SHAPE INDEX CLASS BY GROUP\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < shape_cl_no; i++)
        fprintf(fp, "   Class[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->boundary[1] || choice->boundary[2] ||
      choice->boundary[3] || choice->boundary[4]){
     fp = fopen0("r.le.out/n1-4.out", "w");
     fprintf(fp, "Scale  Unit  MEAN TWIST NUM.  SD. TWIST NUM.   MN. OMEGA INDEX  SD. OMEGA INDEX\n");
     fclose(fp);
  }

  if (choice->perim[1] || choice->perim[2] ||
      choice->perim[3]) {
     fp = fopen0("r.le.out/p1-3.out", "w");
     fprintf(fp, "Scale  Unit  SUM PERIMETER    MEAN PERIMETER   S.D. PERIMETER -- in pixels\n");
     fclose(fp);
  }

  if (choice->perim[4]) {
     fp = fopen0("r.le.out/p4.out", "w");
     fprintf(fp, "               SUM OF PERIMETERS BY GROUP -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->perim[5]) {
     fp = fopen0("r.le.out/p5.out", "w");
     fprintf(fp, "               MEAN PERIMETER BY GROUP -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (choice->perim[6]) {
     fp = fopen0("r.le.out/p6.out", "w");
     fprintf(fp, "               S.D. PERIMETER BY GROUP -- in pixels\n");
     fprintf(fp, "Scale  Unit ");
     for(i = 0; i < ntype; i++)
        fprintf(fp, "   Group[%2d]",i + 1);
     fprintf(fp, "\n");
     fclose(fp);
  }

  if (strcmp(choice->out,"") && choice->wrum != 'm') {
     sprintf(path, "r.le.out/%s", choice->out);
     fp = fopen0(path, "w");
     if (!strcmp(choice->out, "head"))
        fprintf(fp, "sc-  un-                 center     patch\
     core     edge               shape index        twist omega\n");
        fprintf(fp, "ale  it    num   att    row  col     size\
     size     size      per    P/A   CP/A    RCC   number index\n");
     fclose(fp);
  }

  return;

}




                         /* OPEN R.LE OUTPUT FILE, WITH ERROR TRAP */

FILE *fopen0 (char *name, char *flag)

{
  FILE *fp;

  if (!(fp = fopen(name, flag))){
     fprintf(stderr, "\n");
     fprintf(stderr, "   ******************************************\n");
     fprintf(stderr, "    Can't open output file \"%s\"            \n",name);
     fprintf(stderr, "    Do you have write permission in r.le.out \n");
     fprintf(stderr, "    subdirectory?                            \n");    
     fprintf(stderr, "   ******************************************\n");
  }
  return fp;
}



                         /* OPEN INPUT FILE, WITH ERROR TRAP */

FILE *fopen1 (char *name, char *flag)

{
  FILE *fp;

  if (!(fp = fopen(name, flag))) {
     fprintf(stderr, "\n");
     fprintf(stderr, "   ******************************************************\n");
     fprintf(stderr, "    You chose a moving window or sampling units analysis \n");
     fprintf(stderr, "       but r.le.patch can't find file \"%s\"             \n",name);
     fprintf(stderr, "       which defines the moving window or sampling units \n");
     fprintf(stderr, "    First use r.le.setup to define a moving window or    \n");
     fprintf(stderr, "       sampling units to make this file                  \n"); 
     fprintf(stderr, "   ******************************************************\n");
     exit(EXIT_FAILURE);
  }
  return fp;
}


                         /* OPEN INPUT FILE, WITH ERROR TRAP */

FILE *fopen2 (char *name, char *flag)

{
  FILE *fp;

  if (!(fp = fopen(name, flag))) {
     fprintf(stderr, "\n");
     fprintf(stderr, "   **************************************************\n");
     fprintf(stderr, "    You chose a 'by gp' or 'by class' analysis       \n");
     fprintf(stderr, "       but r.le.patch can't find file \"%s\"         \n",name);
     fprintf(stderr, "       which defines the attribute groups or classes \n");
     fprintf(stderr, "    First use r.le.setup to create this file         \n"); 
     fprintf(stderr, "   **************************************************\n");
     exit(EXIT_FAILURE);
  }
  return fp;
}



                         /* MOVING WINDOW DRIVER PROG. */

void  mv_driver()
{
  register int i, j;
  int          nr, nc, u_w, u_l, x0, y0, d, fmask, m, p;
  double       *row_buf, *tmp_buf, *tmp_buf2, **buff=NULL;
  int          a1,a2,a3,a4,a5,a6,a7,a8,s1,s2,s3,s4,s5,s6,s7,s8,c1,c2,c3,c4,c5,
               c6,c7,c8,c9,c10,h1,h2,h3,h4,h5,h6,p1,p2,p3,p4,p5,p6,n1,n2,n3,n4,
               b;
  long         finished_time;
  float        radius;
  struct       Cell_head wind;
  char         *nulltmp;

/* variables:  
          nr = #rows in search area minus height of mov. wind.
          nc = #cols. in search area minus width of mov. wind.
          u_w = width of mov. wind. in cells
          u_l = width of mov. wind. in cells
          x0 = starting column for upper L corner of mov. wind.
          y0 = starting row for upper L corner of mov. wind.
          row = row for moving-window center
          col = column for moving-window center
          *row_buf = temporary array that holds one row of the
               raster map that is being analyzed
          *tmp_buf = temporary array that holds one moving wind.
               measure for a single row
          **buff = temporary array that holds the set of chosen 
               measures for a row
          radius = radius of the sampling unit, if circles are used
*/

                        /* open the appropriate output moving window
                            maps. All maps currently are double,
                            rather than floating point or int */
  if (choice->att[1]) {
     if (G_find_cell("a1",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s","g.rename -o", "rast=a1,a1bak");
        system(cmdbuf);
     }
     a1 = G_open_raster_new("a1", DCELL_TYPE);
  }
  if (choice->att[2]) {
     if (G_find_cell("a2",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=a2,a2bak");
        system(cmdbuf);
     }
     a2 = G_open_raster_new("a2", DCELL_TYPE);
  }
  if (choice->att[3]) {
     if (G_find_cell("a3",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=a3,a3bak");
        system(cmdbuf);
     }
     a3 = G_open_raster_new("a3", DCELL_TYPE);
  }
  if (choice->att[4]) {
     if (G_find_cell("a4",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=a4,a4bak");
        system(cmdbuf);
     }
     a4 = G_open_raster_new("a4", DCELL_TYPE);
  }
  if (choice->att[5]) {
     if (G_find_cell("a5",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=a5,a5bak");
        system(cmdbuf);
     }
     a5 = G_open_raster_new("a5", DCELL_TYPE);
  }
  if (choice->att[6]) {
     if (G_find_cell("a6",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=a6,a6bak");
        system(cmdbuf);
     }
     a6 = G_open_raster_new("a6", DCELL_TYPE);
  }
  if (choice->att[7]) {
     if (G_find_cell("a7",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=a7,a7bak");
        system(cmdbuf);
     }
     a7 = G_open_raster_new("a7", DCELL_TYPE);
  }

  if (choice->att[8]) {
     if (G_find_cell("a8",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=a8,a8bak");
        system(cmdbuf);
     }
     a8 = G_open_raster_new("a8", DCELL_TYPE);
  }

  if (choice->size[1]) {
     if (G_find_cell("s1",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=s1,s1bak");
        system(cmdbuf);
     }
     s1 = G_open_raster_new("s1", DCELL_TYPE);
  }
  if (choice->size[2]) {
     if (G_find_cell("s2",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=s2,s2bak");
        system(cmdbuf);
     }
     s2 = G_open_raster_new("s2", DCELL_TYPE);
  }
  if (choice->size[3]) {
     if (G_find_cell("s3",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=s3,s3bak");
        system(cmdbuf);
     }
     s3 = G_open_raster_new("s3", DCELL_TYPE);
  }
  if (choice->size[4]) {
     if (G_find_cell("s4",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=s4,s4bak");
        system(cmdbuf);
     }
     s4 = G_open_raster_new("s4", DCELL_TYPE);
  }
  if (choice->size[5]) {
     if (G_find_cell("s5",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=s5,s5bak");
        system(cmdbuf);
     }
     s5 = G_open_raster_new("s5", DCELL_TYPE);
  }
  if (choice->size[6]) {
     if (G_find_cell("s6",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=s6,s6bak");
        system(cmdbuf);
     }
     s6 = G_open_raster_new("s6", DCELL_TYPE);
  }

  if (choice->size[7]) {
     if (G_find_cell("s7",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=s7,s7bak");
        system(cmdbuf);
     }
     s7 = G_open_raster_new("s7", DCELL_TYPE);
  }

  if (choice->size[8]) {
     if (G_find_cell("s8",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=s8,s8bak");
        system(cmdbuf);
     }
     s8 = G_open_raster_new("s8", DCELL_TYPE);
  }

  if (choice->core[1]) {
     if (G_find_cell("c1",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=c1,c1bak");
        system(cmdbuf);
     }
     c1 = G_open_raster_new("c1", DCELL_TYPE);
  }
  if (choice->core[2]) {
     if (G_find_cell("c2",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=c2,c2bak");
        system(cmdbuf);
     }
     c2 = G_open_raster_new("c2", DCELL_TYPE);
  }
  if (choice->core[3]) {
     if (G_find_cell("c3",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=c3,c3bak");
        system(cmdbuf);
     }
     c3 = G_open_raster_new("c3", DCELL_TYPE);
  }
  if (choice->core[4]) {
     if (G_find_cell("c4",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=c4,c4bak");
        system(cmdbuf);
     }
     c4 = G_open_raster_new("c4", DCELL_TYPE);
  }
  if (choice->core[5]) {
     if (G_find_cell("c5",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=c5,c5bak");
        system(cmdbuf);
     }
     c5 = G_open_raster_new("c5", DCELL_TYPE);
  }
  if (choice->core[6]) {
     if (G_find_cell("c6",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=c6,c6bak");
        system(cmdbuf);
     }
     c6 = G_open_raster_new("c6", DCELL_TYPE);
  }
  if (choice->core[7]) {
     if (G_find_cell("c7",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=c7,c7bak");
        system(cmdbuf);
     }
     c7 = G_open_raster_new("c7", DCELL_TYPE);
  }
  if (choice->core[8]) {
     if (G_find_cell("c8",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=c8,c8bak");
        system(cmdbuf);
     }
     c8 = G_open_raster_new("c8", DCELL_TYPE);
  }
  if (choice->core[9]) {
     if (G_find_cell("c9",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=c9,c9bak");
        system(cmdbuf);
     }
     c9 = G_open_raster_new("c9", DCELL_TYPE);
  }
  if (choice->core[10]) {
     if (G_find_cell("c10",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=c10,c10bak");
        system(cmdbuf);
     }
     c10 = G_open_raster_new("c10", DCELL_TYPE);
  }

  if (choice->shape[1]) {
     if (G_find_cell("h1",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=h1,h1bak");
        system(cmdbuf);
     }
     h1 = G_open_raster_new("h1", DCELL_TYPE);
  }
  if (choice->shape[2]) {
     if (G_find_cell("h2",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=h2,h2bak");
        system(cmdbuf);
     }
     h2 = G_open_raster_new("h2", DCELL_TYPE);
  }
  if (choice->shape[3]) {
     if (G_find_cell("h3",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=h3,h3bak");
        system(cmdbuf);
     }
     h3 = G_open_raster_new("h3", DCELL_TYPE);
  }
  if (choice->shape[4]) {
     if (G_find_cell("h4",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=h4,h4bak");
        system(cmdbuf);
     }
     h4 = G_open_raster_new("h4", DCELL_TYPE);
  }
  if (choice->shape[5]) {
     if (G_find_cell("h5",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=h5,h5bak");
        system(cmdbuf);
     }
     h5 = G_open_raster_new("h5", DCELL_TYPE);
  }
  if (choice->shape[6]) {
     if (G_find_cell("h6",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=h6,h6bak");
        system(cmdbuf);
     }
     h6 = G_open_raster_new("h6", DCELL_TYPE);
  }

  if (choice->boundary[1]) {
     if (G_find_cell("n1",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=n1,n1bak");
        system(cmdbuf);
     }
     n1 = G_open_raster_new("n1", DCELL_TYPE);
  }

  if (choice->boundary[2]) {
     if (G_find_cell("n2",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=n2,n2bak");
        system(cmdbuf);
     }
     n2 = G_open_raster_new("n2", DCELL_TYPE);
  }

  if (choice->boundary[3]) {
     if (G_find_cell("n3",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=n3,n3bak");
        system(cmdbuf);
     }
     n3 = G_open_raster_new("n3", DCELL_TYPE);
  }

  if (choice->boundary[4]) {
     if (G_find_cell("n4",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=n4,n4bak");
        system(cmdbuf);
     }
     n4 = G_open_raster_new("n4", DCELL_TYPE);
  }

  if (choice->perim[1]) {
     if (G_find_cell("p1",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=p1,p1bak");
        system(cmdbuf);
     }
     p1 = G_open_raster_new("p1", DCELL_TYPE);
  }
  if (choice->perim[2]) {
     if (G_find_cell("p2",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=p2,p2bak");
        system(cmdbuf);
     }
     p2 = G_open_raster_new("p2", DCELL_TYPE);
  }
  if (choice->perim[3]) {
     if (G_find_cell("p3",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=p3,p3bak");
        system(cmdbuf);
     }
     p3 = G_open_raster_new("p3", DCELL_TYPE);
  }
  if (choice->perim[4]) {
     if (G_find_cell("p4",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=p4,p4bak");
        system(cmdbuf);
     }
     p4 = G_open_raster_new("p4", DCELL_TYPE);
  }
  if (choice->perim[5]) {
     if (G_find_cell("p5",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=p5,p5bak");
        system(cmdbuf);
     }
     p5 = G_open_raster_new("p5", DCELL_TYPE);
  }
  if (choice->perim[6]) {
     if (G_find_cell("p6",G_mapset()) != NULL) {
        sprintf(cmdbuf, "%s %s", "g.rename -o", "rast=p6,p6bak");
        system(cmdbuf);
     }
     p6 = G_open_raster_new("p6", DCELL_TYPE); 
  }

                         /* get the moving window parameters */

  read_mwind(&u_w, &u_l, &nc, &nr, &x0, &y0, &radius);

                         /* check for an unacceptable
                            moving-window size */

  if (nc < 1 || nr < 1) {
     fprintf(stderr, "\n");
     fprintf(stderr, "   *******************************************************\n");
     fprintf(stderr, "    The moving window size specified in file r.le.para/   \n");
     fprintf(stderr, "    move_wind is less than 1 row or column.  Check this   \n");
     fprintf(stderr, "    file or redefine the moving window using r.le.setup.  \n");
     fprintf(stderr, "   *******************************************************\n");
     exit(EXIT_FAILURE);
  }

                         /* check for an unacceptable
                            search area and clip it */

  G_get_set_window(&wind);
  if (wind.rows < nr + y0 || wind.cols < nc + x0) {
     fprintf(stderr, "\n");
     fprintf(stderr, "   *******************************************************\n");
     fprintf(stderr, "    Moving window search area in file r.le.para/move_wind \n");
     fprintf(stderr, "    does not match the dimensions of the current region.  \n");
     fprintf(stderr, "    You must either rerun r.le.setup to make a new        \n");
     fprintf(stderr, "    r.le.para/move_wind file or reset the region to match \n");
     fprintf(stderr, "    the r.le.para/move_wind file                          \n");
     fprintf(stderr, "   *******************************************************\n");
     exit(EXIT_FAILURE);
  }

                         /* set the d parameter for the 
                            performance meter */

  if (nr*nc > 10000)
     d = nr*nc/1000;
  else if (nr*nc > 2500)
     d = nr*nc/100;
  else 
     d = 10;

                         /* return a value > 0 to fmask if
                            there is a MASK present */

  fprintf(stderr, "If a MASK is not present (see r.mask) a beep may sound and a\n");
  fprintf(stderr, "   warning may be printed or appear in a window; ignore this warning.\n");
  fprintf(stderr, "If a MASK is present there will be no warning.\n");
  fmask = G_open_cell_old("MASK", G_mapset()) ;
  fprintf(stderr, "\n") ;

                         /* allocate memory for the buffer that
                            will hold the set of 42 possible
                            measures for a row */

  buff = (double **)G_calloc(nc + 1, sizeof(double *));

                         /* allocate memory for each of 42 measures */

  for (p = 0; p < nc + 1; p++)
     buff[p] = (double *)G_calloc(42, sizeof(double));

                         /* allocate memory for a buffer to hold
                            a row of the MASK, if there is a MASK */

  if (fmask > 0)                
     row_buf = G_allocate_raster_buf(CELL_TYPE);

                         /* main loop for clipping & measuring
                            using the moving-window */

  for (i = 0; i < nr; i++) {

                         /* zero the measure buffer before
                            filling it again */

     for (m = 0; m < nc + 1; m++) {
        for (p = 0; p < 42; p++)
           *(*(buff + m) + p) = 0.0;
     }

                         /* if there is a MASK, then read in 
                            a row of MASK - this part skips 
                            cells with the value "0" in the
                            MASK to speed up the moving window
                            process */

     if (fmask > 0) {                  
        G_zero_raster_buf(row_buf,CELL_TYPE);
        G_get_raster_row_nomask(fmask, row_buf, y0 + i + u_l/2, CELL_TYPE);

                         /* for each cell whose value is "1"
                            in MASK */

        for (j = 0; j < nc; j++) {

                              /* display #cells left to do */

           if (i == 0 && j == 0)         
               fprintf (stdout,"TOTAL WINDOWS = %8d\n",nr*nc);
           meter(nr * nc, (i * nc + (j + 1)), d);
 
                         /* call the cell clip driver */

           if (row_buf[x0 + j + u_w/2])
              cell_clip_drv(x0 + j, y0 + i, u_w, u_l, buff, j, radius);
        }
     }

                         /* if there is no MASK, then clip
                            and measure at every cell */

     else { 
                
        for (j = 0; j < nc; j++) {

                              /* display #cells left to do */

           if (i==0 && j==0)
              fprintf (stdout,"TOTAL WINDOWS = %8d\n",nr*nc);
           meter(nr * nc, (i * nc + (j + 1)), d);

                         /* call the cell clip driver.  This routine will clip
                            the rectangle at x0 + j, y0 + i and u_w X u_l wide
                            (or in a circle with radius), and put the results
                            for each chosen moving windown measure in buff;
                            note that the center of the moving window is not
                            at x0 + j, y0 + i, but at x0 + j + u_w/2, y0 + i +
                            u_l/2 */

           cell_clip_drv(x0 + j, y0 + i, u_w, u_l, buff, j, radius);
        }
     }
                         /* copy the chosen measures into a temporary row
                            buffer which is then fed into the chosen output
                            maps; the map location is adjusted to the center
                            of the moving window */

     tmp_buf = G_allocate_raster_buf(DCELL_TYPE);
     nulltmp = G_allocate_null_buf();

     if (choice->att[1]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE);
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(a1, tmp_buf);
	}
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 0) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 0);
           }
           G_put_d_raster_row(a1, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE);
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(a1, tmp_buf2);
           G_free(tmp_buf2);
	}
     }

    if (choice->att[2]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE);
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(a2, tmp_buf);
	}
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 1) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 1);
           }
           G_put_d_raster_row(a2, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE);
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(a2, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->att[3]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(a3, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 2) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 2);
           }
           G_put_d_raster_row(a3, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(a3, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->att[4]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(a4, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 3) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 3);
           }
           G_put_d_raster_row(a4, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(a4, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->att[5]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(a5, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 4) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 4);
           }
           G_put_d_raster_row(a5, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(a5, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->att[6]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(a6, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 5) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 5);
           }
           G_put_d_raster_row(a6, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(a6, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->att[7]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(a7, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 6) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 6);
           }
           G_put_d_raster_row(a7, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(a7, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->size[1]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(s1, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 7) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 7);
           }
           G_put_d_raster_row(s1, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(s1, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->size[2]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(s2, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 8) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 8);
           }
           G_put_d_raster_row(s2, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(s2, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->size[3]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(s3, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 9) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 9);
           }
           G_put_d_raster_row(s3, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(s3, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->size[4]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(s4, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 10) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 10);
           }
           G_put_d_raster_row(s4, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(s4, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->size[5]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(s5, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 11) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 11);
           }
           G_put_d_raster_row(s5, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(s5, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->size[6]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(s6, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 12) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 12);
           }
           G_put_d_raster_row(s6, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(s6, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->core[1]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(c1, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 13) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 13);
           }
           G_put_d_raster_row(c1, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(c1, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->core[2]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(c2, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 14) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 14);
           }
           G_put_d_raster_row(c2, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(c2, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->core[3]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(c3, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 15) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 15);
           }
           G_put_d_raster_row(c3, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(c3, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->core[4]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(c4, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 16) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 16);
           }
           G_put_d_raster_row(c4, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(c4, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->core[5]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(c5, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 17) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 17);
           }
           G_put_d_raster_row(c5, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(c5, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->core[6]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(c6, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 18) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 18);
           }
           G_put_d_raster_row(c6, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(c6, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->core[7]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(c7, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 19) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 19);
           }
           G_put_d_raster_row(c7, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(c7, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->core[8]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(c8, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 20) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 20);
           }
           G_put_d_raster_row(c8, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(c8, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->core[9]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(c9, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 21) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 21);
           }
           G_put_d_raster_row(c9, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(c9, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->core[10]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(c10, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 22) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 22);
           }
           G_put_d_raster_row(c10, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(c10, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->shape[1]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(h1, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 23) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 23);
           }
           G_put_d_raster_row(h1, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(h1, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->shape[2]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(h2, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 24) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 24);
           }
           G_put_d_raster_row(h2, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(h2, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->shape[3]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(h3, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 25) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 25);
           }
           G_put_d_raster_row(h3, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(h3, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->shape[4]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(h4, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 26) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 26);
           }
           G_put_d_raster_row(h4, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(h4, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->shape[5]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(h5, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 27) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 27);
           }
           G_put_d_raster_row(h5, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(h5, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->shape[6]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(h6, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 28) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 28);
           }
           G_put_d_raster_row(h6, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(h6, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->boundary[1]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE);
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(n1, tmp_buf);
	}
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 29) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 29);
           }
           G_put_d_raster_row(n1, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE);
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(n1, tmp_buf2);
           G_free(tmp_buf2);
	}
     }
     if (choice->perim[1]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(p1, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 30) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 30);
           }
           G_put_d_raster_row(p1, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(p1, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->perim[2]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(p2, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 31) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 31);
           }
           G_put_d_raster_row(p2, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(p2, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->perim[3]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(p3, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 32) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 32);
           }
           G_put_d_raster_row(p3, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(p3, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->perim[4]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(p4, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 33) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 33);
           }
           G_put_d_raster_row(p4, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(p4, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->perim[5]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(p5, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 34) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 34);
           }
           G_put_d_raster_row(p5, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(p5, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }
     if (choice->perim[6]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(p6, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 35) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 35);
           }
           G_put_d_raster_row(p6, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(p6, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }

     if (choice->att[8]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(a8, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 36) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 36);
           }
           G_put_d_raster_row(a8, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(a8, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }

     if (choice->size[7]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(s7, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 37) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 37);
           }
           G_put_d_raster_row(s7, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(s7, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }

     if (choice->size[8]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE); 
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++) 
              G_put_d_raster_row(s8, tmp_buf);
	} 	
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 38) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 38);
           }
           G_put_d_raster_row(s8, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE); 
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(s8, tmp_buf2);
           G_free(tmp_buf2); 
	} 
     }

     if (choice->boundary[2]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE);
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(n2, tmp_buf);
	}
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 39) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 39);
           }
           G_put_d_raster_row(n2, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE);
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(n2, tmp_buf2);
           G_free(tmp_buf2);
	}
     }

     if (choice->boundary[3]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE);
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(n3, tmp_buf);
	}
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 40) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 40);
           }
           G_put_d_raster_row(n3, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE);
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(n3, tmp_buf2);
           G_free(tmp_buf2);
	}
     }

     if (choice->boundary[4]) {
        G_zero_raster_buf(tmp_buf, DCELL_TYPE);
        G_set_null_value(tmp_buf, x0 + nc + u_w, DCELL_TYPE);
        if (i == 0) {
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(n4, tmp_buf);
	}
        if (i < nr) {
	   for (m = 0; m < nc; m++) {
	      if (*(*(buff + m) + 41) > -BIG)
                 *(tmp_buf + (x0 + m + u_w/2)) = *(*(buff + m) + 41);
           }
           G_put_d_raster_row(n4, tmp_buf);
	}
        if (i == nr - 1) {
           tmp_buf2 = G_allocate_raster_buf(DCELL_TYPE);
           G_set_null_value(tmp_buf2, x0 + nc + u_w, DCELL_TYPE);
	   for (b = 0; b < u_l/2; b++)
              G_put_d_raster_row(n4, tmp_buf2);
           G_free(tmp_buf2);
	}
     }
     G_free(tmp_buf);
  }

  time(&finished_time);
  fprintf (stdout,"\nACTUAL COMPLETION = %s",asctime(localtime(&finished_time)) );
  fflush(stdout);


                         /* free the memory allocated for the
                            mask and other buffer */

  if (fmask > 0)
     G_free(row_buf);
  for (p = 0; p < nc + 1; p++)
     G_free(buff[p]);
  G_free(buff);

                         /* close the raster files, set the
                            color table for the new raster
                            map and compress the map */
	   

  if (choice->att[1]) {
     G_close_cell(a1);
     set_colors("a1");
     sprintf(cmdbuf,"%s %s","r.compress","a1") ;
     system(cmdbuf);
  }
  if (choice->att[2]) {
     G_close_cell(a2);
     set_colors("a2");
     sprintf(cmdbuf,"%s %s","r.compress","a2") ;
     system(cmdbuf);
  }
  if (choice->att[3]) {
     G_close_cell(a3);
     set_colors("a3");
     sprintf(cmdbuf,"%s %s","r.compress","a3") ;
     system(cmdbuf);
  }
  if (choice->att[4]) {
     G_close_cell(a4);
     set_colors("a4");
     sprintf(cmdbuf,"%s %s","r.compress","a4") ;
     system(cmdbuf);
  }
  if (choice->att[5]) {
     G_close_cell(a5);
     set_colors("a5");
     sprintf(cmdbuf,"%s %s","r.compress","a5") ;
     system(cmdbuf);
  }
  if (choice->att[6]) {
     G_close_cell(a6);
     set_colors("a6");
     sprintf(cmdbuf,"%s %s","r.compress","a6") ;
     system(cmdbuf);
  }
  if (choice->att[7]) {
     G_close_cell(a7);
     set_colors("a7");
     sprintf(cmdbuf,"%s %s","r.compress","a7") ;
     system(cmdbuf);
  }
  if (choice->att[8]) {
     G_close_cell(a8);
     set_colors("a8");
     sprintf(cmdbuf,"%s %s","r.compress","a8") ;
     system(cmdbuf);
  }
  if (choice->size[1]) {
     G_close_cell(s1);
     set_colors("s1");
     sprintf(cmdbuf,"%s %s","r.compress","s1") ;
     system(cmdbuf);
  }
  if (choice->size[2]) {
     G_close_cell(s2);
     set_colors("s2");
     sprintf(cmdbuf,"%s %s","r.compress","s2") ;
     system(cmdbuf);
  }
  if (choice->size[3]) {
     G_close_cell(s3);
     set_colors("s3");
     sprintf(cmdbuf,"%s %s","r.compress","s3") ;
     system(cmdbuf);
  }
  if (choice->size[4]) {
     G_close_cell(s4);
     set_colors("s4");
     sprintf(cmdbuf,"%s %s","r.compress","s4") ;
     system(cmdbuf);
  }
  if (choice->size[5]) {
     G_close_cell(s5);
     set_colors("s5");
     sprintf(cmdbuf,"%s %s","r.compress","s5") ;
     system(cmdbuf);
  }
  if (choice->size[6]) {
     G_close_cell(s6);
     set_colors("s6");
     sprintf(cmdbuf,"%s %s","r.compress","s6") ;
     system(cmdbuf);
  }
  if (choice->size[7]) {
     G_close_cell(s7);
     set_colors("s7");
     sprintf(cmdbuf,"%s %s","r.compress","s7") ;
     system(cmdbuf);
  }
  if (choice->size[8]) {
     G_close_cell(s8);
     set_colors("s8");
     sprintf(cmdbuf,"%s %s","r.compress","s8") ;
     system(cmdbuf);
  }
  if (choice->core[1]) {
     G_close_cell(c1);
     set_colors("c1");
     sprintf(cmdbuf,"%s %s","r.compress","c1") ;
     system(cmdbuf);
  }
  if (choice->core[2]) {
     G_close_cell(c2);
     set_colors("c2");
     sprintf(cmdbuf,"%s %s","r.compress","c2") ;
     system(cmdbuf);
  }
  if (choice->core[3]) {
     G_close_cell(c3);
     set_colors("c3");
     sprintf(cmdbuf,"%s %s","r.compress","c3") ;
     system(cmdbuf);
  }
  if (choice->core[4]) {
     G_close_cell(c4);
     set_colors("c4");
     sprintf(cmdbuf,"%s %s","r.compress","c4") ;
     system(cmdbuf);
  }
  if (choice->core[5]) {
     G_close_cell(c5);
     set_colors("c5");
     sprintf(cmdbuf,"%s %s","r.compress","c5") ;
     system(cmdbuf);
  }
  if (choice->core[6]) {
     G_close_cell(c6);
     set_colors("c6");
     sprintf(cmdbuf,"%s %s","r.compress","c6") ;
     system(cmdbuf);
  }
  if (choice->core[7]) {
     G_close_cell(c7);
     set_colors("c7");
     sprintf(cmdbuf,"%s %s","r.compress","c7") ;
     system(cmdbuf);
  }
  if (choice->core[8]) {
     G_close_cell(c8);
     set_colors("c8");
     sprintf(cmdbuf,"%s %s","r.compress","c8") ;
     system(cmdbuf);
  }
  if (choice->core[9]) {
     G_close_cell(c9);
     set_colors("c9");
     sprintf(cmdbuf,"%s %s","r.compress","c9") ;
     system(cmdbuf);
  }
  if (choice->core[10]) {
     G_close_cell(c10);
     set_colors("c10");
     sprintf(cmdbuf,"%s %s","r.compress","c10") ;
     system(cmdbuf);
  }
  if (choice->shape[1]) {
     G_close_cell(h1);
     set_colors("h1");
     sprintf(cmdbuf,"%s %s","r.compress","h1") ;
     system(cmdbuf);
  }
  if (choice->shape[2]) {
     G_close_cell(h2);
     set_colors("h2");
     sprintf(cmdbuf,"%s %s","r.compress","h2") ;
     system(cmdbuf);
  }
  if (choice->shape[3]) {
     G_close_cell(h3);
     set_colors("h3");
     sprintf(cmdbuf,"%s %s","r.compress","h3") ;
     system(cmdbuf);
  }
  if (choice->shape[4]) {
     G_close_cell(h4);
     set_colors("h4");
     sprintf(cmdbuf,"%s %s","r.compress","h4") ;
     system(cmdbuf);
  }
  if (choice->shape[5]) {
     G_close_cell(h5);
     set_colors("h5");
     sprintf(cmdbuf,"%s %s","r.compress","h5") ;
     system(cmdbuf);
  }
  if (choice->shape[6]) {
     G_close_cell(h6);
     set_colors("h6");
     sprintf(cmdbuf,"%s %s","r.compress","h6") ;
     system(cmdbuf);
  }
  if (choice->boundary[1]) {
     G_close_cell(n1);
     set_colors("n1");
     sprintf(cmdbuf,"%s %s","r.compress","n1") ;
     system(cmdbuf);
  }
  if (choice->boundary[2]) {
     G_close_cell(n2);
     set_colors("n2");
     sprintf(cmdbuf,"%s %s","r.compress","n2") ;
     system(cmdbuf);
  }
  if (choice->boundary[3]) {
     G_close_cell(n3);
     set_colors("n3");
     sprintf(cmdbuf,"%s %s","r.compress","n3") ;
     system(cmdbuf);
  }
  if (choice->boundary[4]) {
     G_close_cell(n4);
     set_colors("n4");
     sprintf(cmdbuf,"%s %s","r.compress","n4") ;
     system(cmdbuf);
  }
  if (choice->perim[1]) {
     G_close_cell(p1);
     set_colors("p1");
     sprintf(cmdbuf,"%s %s","r.compress","p1") ;
     system(cmdbuf);
  }
  if (choice->perim[2]) {
     G_close_cell(p2);
     set_colors("p2");
     sprintf(cmdbuf,"%s %s","r.compress","p2") ;
     system(cmdbuf);
  }
  if (choice->perim[3]) {
     G_close_cell(p3);
     set_colors("p3");
     sprintf(cmdbuf,"%s %s","r.compress","p3") ;
     system(cmdbuf);
  }
  if (choice->perim[4]) {
     G_close_cell(p4);
     set_colors("p4");
     sprintf(cmdbuf,"%s %s","r.compress","p4") ;
     system(cmdbuf);
  }
  if (choice->perim[5]) {
     G_close_cell(p5);
     set_colors("p5");
     sprintf(cmdbuf,"%s %s","r.compress","p5") ;
     system(cmdbuf);
  }
  if (choice->perim[6]) {
     G_close_cell(p6);
     set_colors("p6");
     sprintf(cmdbuf,"%s %s","r.compress","p6") ;
     system(cmdbuf);
  }

  G_close_cell(fmask);

  return;
}






                         /* SET COLOR TABLE FOR MOVING WINDOW 
					OUTPUT MAPS TO G-Y-R */

void set_colors (char *name)

{
  struct Colors colors;
  struct FPRange  fprange;

  G_read_fp_range(name, G_mapset(), &fprange);
  G_make_gyr_fp_colors(&colors, fprange.min, fprange.max);
  G_write_colors(name, G_mapset(), &colors);
  return;
  
}





                         /* READ IN THE MOVING WINDOW PARAMETERS */

void read_mwind (int *uw, int *ul, int *nc, int *nr, int *x0, int *y0, float *radius)

{
  FILE  *fp;
  int   ww, wl;
  char  *buf;

  fp = fopen1("r.le.para/move_wind", "r");
  buf = G_malloc(513);
  
  fgets(buf, 512, fp);
  sscanf(buf, "%d%d", uw, ul);

  fgets(buf, 512, fp);
  sscanf(buf, "%f", radius);

  fgets(buf, 512, fp);
  sscanf(buf, "%d%d", &ww, &wl);

  fgets(buf, 512, fp);
  sscanf(buf, "%d%d", x0, y0);

  *nc = ww - *uw + 1; 
  *nr = wl - *ul + 1;

  G_free(buf);
  fclose(fp);
  return;
}


                         /* PERFORMANCE METER - DISPLAYS
                            THE PROGRESS OF THE MOVING WINDOW
                            AS A COUNT AND ESTIMATED COMPLETION
                            TIME WHILE THE PROGRAM RUNS */

void meter (int n, int i, int div)

{ 
  long  current_time, time_left, elapsed, complete;
  static long start;
  float window_time;
  static  int  k=0;
  char  done[30];
  int d;

  if (i <= 1) {                  
     time(&start);
  }

  if (i < 10 )
     d = 1;
  else
     d = div;

  if (k > 2000) {
     if (fseek(stdout, 0L, 0))
        G_fatal_error("Can't reset the \"stdout\", exit.\n");
     k = 0;
  }

  if ((n - i) % d == 0 ) {
     time(&current_time);
     elapsed = current_time - start;
     window_time = ((float) elapsed) / (i + 1);
     time_left =  (long)((n-i) * window_time);
     complete = current_time + time_left;
     strncpy(done,asctime(localtime(&complete)),24);
     done[24] = '\0';
     fprintf (stdout,"WINDOWS LEFT  = %8d   EST. COMPLETION = %s\r",(n-i),done); 
     fflush(stdout);
     k ++; 
  }
  return;
}
                         /* READ IN THE PARAMETERS FOR
                            GROUPS & CLASSES */


void  get_para()
{
  register int i, j, k;
  float        *tmp;
  int          counter;

/*
  Variables:
  GLOBAL:
    para1 = set to 1 if by gp measures are chosen
    para2 = set to 1 if size classes are chosen
    para3 = set to 1 if perimeter-area shape index classes are chosen
    para4 = set to 1 if corrected perimeter-area shape index classes are chosen
    para5 = set to 1 if related circumscribing circle shape index classes are
            chosen
*/
                         /* set the parameter flags to 0 */
  
  para1 = para2 = para3 = para4 = para5 = 0;

                         /* read the reclass table for attribute gps */

  if (choice->att[5] || choice->att[6] || choice->size[3] || choice->size[4]
     || choice->size[6] || choice->core[5] || choice->core[6]
     || choice->core[7] || choice->core[8] || choice->core[10] 
     || choice->shape[3] || choice->shape[4] || choice->shape[6] 
     || choice->perim[4] || choice->perim[5] || choice->perim[6]) {

     para1 = 1;
     recl_tb = (float **)G_calloc(25, sizeof(float *));
     tmp = (float *)G_calloc(50, sizeof(float));
     if (choice->wrum == 'm')
        k = 1;
     else
        k = 25;
     recl_count = (int *)G_calloc(k, sizeof(int));
     for(i = 0; i < k; i++) {
        read_para("recl_tb", i + 1, tmp, &counter);
        if (counter < 2) break;
        recl_tb[i] = (float *)G_malloc(50 * sizeof(float));
        for(j = 0; j < counter; j++) {
           recl_tb[i][j] = tmp[j];
        }
        recl_count[i] = counter;
     }
     if (choice->wrum == 'm')
        ntype = 1;
     else 
        ntype = i;
     G_free(tmp);
     if (!ntype) {
        fprintf(stderr, "\n");
        fprintf(stderr, "   ********************************************************\n");
        fprintf(stderr, "    The attribute group file (r.le.para/recl_tb) seems to  \n");
        fprintf(stderr, "    be incorrect as no attribute groups were found.  Check \n");
        fprintf(stderr, "    this file or make it again using r.le.setup.           \n");
        fprintf(stderr, "   ********************************************************\n");
        exit(EXIT_FAILURE);
     }
  }

                         /* read the size classes */

  if (choice->size[5] || choice->size[6] || choice->core[9] ||
     choice->core[10]) {
     para2 = 1;
     size_cl = (float *)G_calloc(20, sizeof(float));
     read_line("size", 1, -999, NULL, size_cl, &size_cl_no);
  }

                         /* read shape index classes */ 

  if (choice->Mx[1] && (choice->shape[5] || choice->shape[6])){
     para3 = 1;
     shape_PA = (float *)G_calloc(20, sizeof(float));
     read_line("shape_PA", 1, -999, NULL, shape_PA, &shape_cl_no);
  } 
  else if (choice->Mx[2] && (choice->shape[5] || choice->shape[6])){
     para4 = 1;
     shape_CPA = (float *)G_calloc(20, sizeof(float));
     read_line("shape_CPA", 1, -999, NULL, shape_CPA, &shape_cl_no);
  } 
  else if (choice->Mx[3] && (choice->shape[5] || choice->shape[6])){
     para5 = 1;
     shape_RCC = (float *)G_calloc(20, sizeof(float));
     read_line("shape_RCC", 1, -999, NULL, shape_RCC, &shape_cl_no);
  }
  return;
}







                         /* RELEASE GLOBAL MEMORY */

void  free_para()
{
  register int i;

  if (para1) {
     for(i = 0; i < ntype; i++)
        G_free(recl_tb[i]);
     G_free(recl_tb);
     G_free(recl_count);
  }
  if (para2)
     G_free(size_cl);
  if (para3)
     G_free(shape_PA);
  if (para4)
     G_free(shape_CPA);
  if (para5)
     G_free(shape_RCC);
  return;

}





                         /* COUNT HOW MANY ATTRIBUTES ARE IN ONE
                            LINE OF THE RECL_TB FILE, WHICH DEFINES
                            ATTRIBUTE GROUPS */

void read_para (char *name, int line, float *value, int *count)

{
  FILE  *fp;
  int   i = 0, cnt = 1;
  char  *buf, path[30];

/* VARIABLES
    Incoming
     name       = always "recl_tb"
     line       = the line of the recl_tb file to be read
     value      = an array of 50 values, each of which is a
                  count of the number of attributes on the line;
                  this is the array returned to the calling program
     count      = ??
    Internal
     fp         = pointer to recl_tb file
     i          = counter for moving through buf array
     cnt        = count of number of attributes on this line
     buf        = buffer to hold one line of recl_tb
     path       = the relative path to the recl_tb file
*/


                               /* open the recl_tb, allocate enough memory,
                                   then read one line of the recl_tb into
                                   the buffer; then close the recl_tb */

  sprintf(path, "r.le.para/%s", name);
  fp = fopen2(path, "r");     
  buf = G_malloc(256);
  while(fgets(buf, 256, fp) && i < line - 1)
     i++;
  fclose(fp);

                               /* go through the line of the recl_tb character
                                  by character */

  for(i = 0; ; i++) {

                               /* if "e" of "end" is found or an "=" sign is found, then
                                  quit and set value to 1 */

     if (*(buf + i) == 'e' || *(buf + i) == '=')
        break;

                               /* if "t" of "thru" is found, set the corresponding element
                                  of the value array to -999, add one to cnt, then
                                  jump to the next character after "thru" */

     else if (*(buf + i) == 't') {
        *(value + cnt) = -999;
        cnt ++;
        i+=4;
     }

                               /* if a number is found, then scan it into the
                                  corresponding element in the value array */

     else if (isdigit(*(buf + i))) {
        sscanf(buf + i, "%f", value + cnt);
        while(isdigit(*(buf + i)))
           i++;
        cnt ++;
     }
  }
  *count = (float)cnt;
  G_free(buf);
  return;
}





                         /* READ IN ONE CLASS LINE */

void read_line (char *name, int line, int n, int *value, int *fvalue, int *number_classes)

{
  FILE  *fp;
  int   i;
  char  path[30], *buf;

  sprintf(path, "r.le.para/%s", name);

  fp = fopen2(path, "r");
  buf = G_malloc(256);

  for(i = 0; i < line - 1; i++)
     fgets(buf, 256, fp);
  G_free(buf);

  if (n > 0)
     for(i = 0; i < n; i++)
        fscanf(fp, "%d", value + i);
  else {
     for(i = 1; ; i++) {
        fscanf(fp, "%f", (float *)fvalue + i);
        if (fvalue[i] <= -999) {
           *number_classes = i - 1;
           break;
        }
     }
     if (3 > (fvalue[0] = (float)i)){
        buf = G_malloc(40);
        sprintf(buf, "\n No data in file\"%s\"; use r.le.setup to make file\n", path);
        G_fatal_error(buf);
        G_free(buf);
     }
  }     
  fclose(fp);
  return;
}






                         /* READ IN SAMPLING UNIT PARAMETERS
                            AND RUN R.LE.PATCH */

void  unit_driver()
{
  int              top, left, u_w, u_l, nscl, nu, fd;
  char             *buf, unitname[10], istr[3];
  register int     i, j, k, m;
  struct Cell_head wind;
  FILE             *fp;
  CELL             **units, *unit_buf;
  float            radius=0.0;


  G_get_set_window(&wind);
  fp = fopen1("r.le.para/units", "r");

  buf = G_malloc(513);

                         /* get the number of scales */

  fgets(buf, 512, fp);
  sscanf(buf, "%d", &nscl);

                         /* dynamically allocate storage for the buffer 
			    that will hold the map of the sampling units */

  if (choice->units) {
     units = (CELL **)G_calloc(wind.rows + 3, sizeof(CELL *));
     for(i = 0; i < wind.rows + 3; i++)
        units[i] = (CELL *)G_calloc(wind.cols + 3, sizeof(CELL));
  }

                         /* for each scale */

  for(i = 0; i < nscl; i++){  
     n_scale = i + 1;
     fgets(buf, 512, fp);
     sscanf(buf, "%d", &nu);

                         /* get the width and length */

     fgets(buf, 512, fp);
     sscanf(buf, "%d%d", &u_w, &u_l);

                         /* get the radius to see if sampling
                            units are circles */

     fgets(buf, 512, fp);
     sscanf(buf, "%f", &radius);

                         /* if units map was chosen, zero it,
                            then copy the number of the map
                            to the end of the word "units" */

     if (choice->units) {
        for (k = 0; k < wind.rows + 3; k++) {
           for (m = 0; m < wind.cols + 3; m++)
              *(*(units + k) + m) = 0;
        }

             if (i==0)  G_strcpy(istr,"1");
        else if (i==1)  G_strcpy(istr,"2");
        else if (i==2)  G_strcpy(istr,"3");
        else if (i==3)  G_strcpy(istr,"4");
        else if (i==4)  G_strcpy(istr,"5");
        else if (i==5)  G_strcpy(istr,"6");
        else if (i==6)  G_strcpy(istr,"7");
        else if (i==7)  G_strcpy(istr,"8");
        else if (i==8)  G_strcpy(istr,"9");
        else if (i==9)  G_strcpy(istr,"10");
        else if (i==10)  G_strcpy(istr,"11");
        else if (i==11)  G_strcpy(istr,"12");
        else if (i==12)  G_strcpy(istr,"13");
        else if (i==13)  G_strcpy(istr,"14");
        else if (i==14)  G_strcpy(istr,"15");
        else if (i > 14) {
           fprintf(stderr, "\n");
           fprintf(stderr, "   ***************************************************\n");
           fprintf(stderr, "    You cannot choose more than 15 scales             \n");
           fprintf(stderr, "   ***************************************************\n");
           exit(EXIT_FAILURE);
        }
     }
                         /* for each unit */

     for(j = 0; j < nu; j++) {
        n_unit = j + 1;
        fgets(buf, 512, fp);
        sscanf(buf, "%d%d", &left, &top);

                         /* call cell_clip driver */

        run_clip(wind.cols, wind.rows, u_w, u_l, left, top, units, j, radius);
     }

                         /* if a map of the sampling units
                            was requested */
     if (choice->units) {
        G_strcpy(unitname,"units_");
        G_strcat(unitname,istr);
        fd = G_open_raster_new(unitname, CELL_TYPE);
        unit_buf = G_allocate_raster_buf(CELL_TYPE);
        for(k = 1; k < wind.rows + 1; k++) {
           G_zero_raster_buf(unit_buf, CELL_TYPE);
           G_set_null_value(unit_buf, wind.cols + 1, CELL_TYPE);
           for (m = 1; m < wind.cols + 1; m++) {
              if (*(*(units + k) + m))
                 *(unit_buf + m - 1) = *(*(units + k) + m);
           }
           G_put_raster_row(fd, unit_buf, CELL_TYPE);
        }
        G_close_cell(fd);
        G_free(unit_buf);
     }
  }

  if (choice->units) {
     for (m = 0; m < wind.rows + 3; m++)
        G_free(units[m]);
     G_free(units);
  }
  G_free(buf);
  fclose(fp);
  return;
}





                         /* CHECK FOR OUT-OF MAP UNIT, THEN
                            CALL CELL CLIP DRIVER */

void run_clip (int ncols, int nrows, int u_w, int u_l, int left, int top, CELL **units, int id, float radius)

{
int i,j;
double center_row, center_col;
double dist;

  G_sleep_on_error(0); 

                         /* check unit */

  if (ncols < left + u_w || nrows < top + u_l) {
     fprintf(stderr, "\n");
     fprintf(stderr, "   ******************************************************\n");
     fprintf(stderr, "    Sampling units do not fit within the current region. \n");
     fprintf(stderr, "    Either correct the region or redo the sampling unit  \n");
     fprintf(stderr, "    selection using r.le.setup.  This error message came \n");
     fprintf(stderr, "    from an analysis of the r.le.para/units file and the \n");
     fprintf(stderr, "    current region setting.                              \n");
     fprintf(stderr, "   ******************************************************\n");
     exit(EXIT_FAILURE);
  }

  if (choice->units) {
     if (radius) {
        center_row = ((double)(top + 1) + ((double)u_l - 1)/2);
        center_col = ((double)(left + 1) + ((double)u_w - 1)/2);

        for (i = top + 1; i < top + 1 + u_l; i++) {
           for (j = left + 1; j < left + 1 + u_w; j++) {
              dist = sqrt(((double)i-center_row)*((double)i-center_row) + 
                          ((double)j-center_col)*((double)j-center_col));
              if (dist < radius)
                 *(*(units + i) + j) = id + 1;
           }
        }
     }
     else {
        for (i = top + 1; i < top + 1 + u_l; i++) {
           for (j = left + 1; j < left + 1 + u_w; j++)
              *(*(units + i) + j) = id + 1;
        }
     }
  }

  cell_clip_drv(left, top, u_w, u_l, NULL, 0, radius);

  return;
}



                         /* CLIP THE REGION, THEN
                            RUN R.LE.PATCH */

void  whole_reg_driver()
{
  register int     i, j;
  int              regcnt, found, fr,
                   nrows, ncols;
  REGLIST         *ptrfirst, *ptrthis, *ptrnew;
  CELL		  *row_buf;

  nrows = G_window_rows();
  ncols = G_window_cols();

  n_scale = 1;

  if (choice->wrum != 'r') {
     cell_clip_drv(0, 0, ncols, nrows, NULL, 0, 0.0);
  }
  else {
     regcnt = 0;
     fr = G_open_cell_old(choice->reg, G_mapset());
     row_buf = G_allocate_raster_buf(CELL_TYPE);
     for (i = 0; i < nrows; i++) {
        G_zero_raster_buf (row_buf, CELL_TYPE);
        G_get_raster_row(fr, row_buf, i, CELL_TYPE);
        for (j = 0; j < ncols; j++) {
           if (*(row_buf + j) > 0) {
              if (regcnt == 0)
                 ptrfirst = (REGLIST *) NULL;
              ptrthis = ptrfirst;
              found = 0;
              while (ptrthis) {
                 if (*(row_buf + j) == ptrthis->att) {
                    if (j < ptrthis->w) ptrthis->w = j;
                    if (j > ptrthis->e) ptrthis->e = j;
                    if (i < ptrthis->n) ptrthis->n = i;
                    if (i > ptrthis->s) ptrthis->s = i;
                    found = 1;
                 }
                 ptrthis = ptrthis->next;
              }
              if (!found) {
                 ptrnew = (REGLIST *)G_calloc(1, sizeof(REGLIST));
                 if (ptrfirst == (REGLIST *) NULL)
                    ptrfirst = ptrthis = ptrnew;
                 else {
                    ptrthis = ptrfirst;
                    while (ptrthis->next != (REGLIST *) NULL)
                       ptrthis = ptrthis->next;
                    ptrthis->next = ptrnew;
                    ptrthis = ptrnew;
                 }
                 ptrthis->att = *(row_buf + j);
                 ptrthis->n = i;
                 ptrthis->s = i;
                 ptrthis->e = j;
                 ptrthis->w = j;
                 regcnt++;
              }
           }
        }
     }
     n_unit = 0;
     ptrthis = ptrfirst;
     while (ptrthis) {
        n_unit = ptrthis->att;
        cell_clip_drv (ptrthis->w, ptrthis->n, ptrthis->e - ptrthis->w + 1, 
           ptrthis->s - ptrthis->n + 1, NULL, ptrthis->att, 0.0);
        ptrthis = ptrthis->next;
     }
     G_close_cell(fr);
     G_free (row_buf);
     G_free(ptrnew);
  }

  return;
}      
