[GRASS-SVN] r52419 - grass-addons/grass7/imagery/i.segment

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Jul 19 22:36:54 PDT 2012


Author: momsen
Date: 2012-07-19 22:36:54 -0700 (Thu, 19 Jul 2012)
New Revision: 52419

Added:
   grass-addons/grass7/imagery/i.segment/flag.c
Removed:
   grass-addons/grass7/imagery/i.segment/flag_clr_all.c
   grass-addons/grass7/imagery/i.segment/flag_create.c
   grass-addons/grass7/imagery/i.segment/flag_destroy.c
   grass-addons/grass7/imagery/i.segment/flag_get.c
   grass-addons/grass7/imagery/i.segment/flag_set.c
   grass-addons/grass7/imagery/i.segment/flag_unset.c
Modified:
   grass-addons/grass7/imagery/i.segment/create_isegs.c
   grass-addons/grass7/imagery/i.segment/flag.h
   grass-addons/grass7/imagery/i.segment/i.segment.html
   grass-addons/grass7/imagery/i.segment/iseg.h
   grass-addons/grass7/imagery/i.segment/open_files.c
   grass-addons/grass7/imagery/i.segment/parse_args.c
   grass-addons/grass7/imagery/i.segment/write_output.c
Log:
added 8 neighbor option.  Lots of small todo's resolved, general code clean up.  Added pathflag implementation, decreases time/iteration but increased number of iterations???

Modified: grass-addons/grass7/imagery/i.segment/create_isegs.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/create_isegs.c	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/create_isegs.c	2012-07-20 05:36:54 UTC (rev 52419)
@@ -3,6 +3,7 @@
 /* Currently only region growing is implemented */
 
 #include <stdlib.h>
+#include <float.h>		/* for DBL_MAX */
 #include <grass/gis.h>
 #include <grass/glocale.h>
 #include <grass/raster.h>
@@ -12,57 +13,133 @@
 #include "iseg.h"
 
 #ifdef DEBUG
-	#include <time.h>
+#include <time.h>
+#include <limits.h>
 #endif
 
 #define LINKM
-/* #define REVERSE */
 
 int create_isegs(struct files *files, struct functions *functions)
 {
-    int lower_bound, upper_bound;
+    int lower_bound, upper_bound, row, col;
     int successflag = 1;
     struct Range range;
 
-    /* TODO consider if there are _method specific_ parameter set up and memory allocation, should that happen here? */
+    functions->threshold = functions->threshold * functions->threshold * files->nbands;	/* use modified threshold to account for scaled input and to avoid square root in similarity comparison. */
 
-    G_debug(1, "Threshold: %g", functions->threshold);
-    G_debug(1, "segmentation method: %d", functions->method);
-
-    functions->threshold = functions->threshold * functions->threshold * files->nbands;	/* use modified threshold to account for scaled input and to avoid square root in similarity comparison. *//* Todo, small, could put this in main outside of polygon loop */
-
     /* set parameters for outer processing loop for polygon constraints */
     if (files->bounds_map == NULL) {	/*normal processing */
-	lower_bound = upper_bound = 0;
-    }				/* just one time through loop */
+	lower_bound = upper_bound = 0;	/* so run the segmentation algorithm just one time */
+    }
     else {
 	if (Rast_read_range(files->bounds_map, files->bounds_mapset, &range) != 1) {	/* returns -1 on error, 2 on empty range, quiting either way. */
 	    G_fatal_error(_("No min/max found in raster map <%s>"),
 			  files->bounds_map);
 	}
-	Rast_get_range_min_max(&range, &lower_bound, &upper_bound);	/* todo, faster way to do this?  maybe do it manually when open and write to the segment file? But it is just once.... */
+	Rast_get_range_min_max(&range, &lower_bound, &upper_bound);
+	/* TODO polish, should we instead/also get unique values?
+	 * As is, we will iterate at least one time over the entire raster for each integer between the upper and lower bound. */
     }
 
-    for (files->current_bound = lower_bound; files->current_bound <= upper_bound; files->current_bound++) {	/* outer processing loop for polygon constraints */
-	G_debug(1, "current_bound = %d", files->current_bound);
+    /* processing loop for polygon/boundary constraints */
+    for (files->current_bound = lower_bound;
+	 files->current_bound <= upper_bound; files->current_bound++) {
+
+	/* check the processing window */
+	if (files->bounds_map == NULL) {
+	    files->minrow = files->mincol = 0;
+	    files->maxrow = files->nrows;
+	    files->maxcol = files->ncols;
+	    /* todo polish: could actually check the NULL flag to see where the first/last row/col of real data are, and reduce the processing window.
+	     * This could help (a little?) if a MASK is used that removes a large part of the map. */
+	}
+	else {
+	    /* todo, Markus, should there be a faster way to find this?  Something already in GRASS that I can call? */
+	    /* find first row that matches the current bound value */
+	    for (row = 0; row < files->nrows; row++) {
+		for (col = 0; col < files->ncols; col++) {
+		    segment_get(&files->bounds_seg, &files->bounds_val, row,
+				col);
+		    if (files->bounds_val == files->current_bound) {
+			files->minrow = row;
+			/* break a nested loop... hmm, could change this to a function call, use a flag, or use peano iteration. */
+			goto done1;	/* or is this one of the few places where a goto loop is OK? */
+		    }
+		}
+	    }
+	  done1:
+
+	    for (col = 0; col < files->ncols; col++) {
+		for (row = 0; row < files->nrows; row++) {
+		    segment_get(&files->bounds_seg, &files->bounds_val, row,
+				col);
+		    if (files->bounds_val == files->current_bound) {
+			files->mincol = col;
+			goto done2;
+		    }
+		}
+	    }
+	  done2:
+
+	    for (row = files->nrows - 1; row >= 0; row--) {
+		for (col = files->ncols - 1; col >= 0; col--) {
+		    segment_get(&files->bounds_seg, &files->bounds_val, row,
+				col);
+		    if (files->bounds_val == files->current_bound) {
+			files->maxrow = row;
+			goto done3;
+		    }
+		}
+	    }
+	  done3:
+
+	    for (col = files->ncols - 1; col >= 0; col--) {
+		for (row = files->nrows - 1; row >= 0; row--) {
+		    segment_get(&files->bounds_seg, &files->bounds_val, row,
+				col);
+		    if (files->bounds_val == files->current_bound) {
+			files->maxcol = col;
+			goto done4;
+		    }
+		}
+	    }
+	  done4:
+	    G_message("minrow: %d, maxrow: %d, mincol: %d, maxcol: %d", files->minrow, files->maxrow, files->mincol, files->maxcol);	//TODO change to debug.
+
+	    /* set the in_bound_flag */
+	    for (row = 0; row < files->nrows; row++) {
+		for (col = 0; col < files->ncols; col++) {
+		    if (!(FLAG_GET(files->null_flag, row, col))) {
+			segment_get(&files->bounds_seg, &files->bounds_val,
+				    row, col);
+			if (files->bounds_val == files->current_bound) {
+			    FLAG_SET(files->in_bounds_flag, row, col);
+			}
+			else
+			    FLAG_UNSET(files->in_bounds_flag, row, col);
+		    }
+		}
+	    }
+	    /* clear candidate flag, so only need to reset the processing area on each iteration. */
+	    flag_clear_all(files->candidate_flag);
+
+	}			/* end of else, set up for bounded segmentation */
+
+	/* run the segmentation algorithm */
+
 	if (functions->method == 1) {
-	    G_debug(1, "starting region_growing()");
 	    successflag = region_growing(files, functions);
 	}
-	#ifdef DEBUG
+#ifdef DEBUG
 	else if (functions->method == 0)
-	    successflag = io_debug(files, functions);	/* TODO: why does it want `&files` in main, but `files` here ??? */
+	    successflag = io_debug(files, functions);
 	else if (functions->method == 2)
 	    successflag = ll_test(files, functions);
-	    
 	else if (functions->method == 3)
 	    successflag = seg_speed_test(files, functions);
-	#endif
+#endif
     }				/* end outer loop for processing polygons */
 
-    /* clean up? */
-
-
     return successflag;
 }
 
@@ -218,7 +295,6 @@
     else
 	G_message("hmm, still need to set Rkn to null?!");
 
-    /* Rkn = NULL;      not needed *//* TODO: if emptying whole list - can just empty and then set head to null ? */
 
     G_message("Printing out, after removed Rin and Rkn:");
     for (current = Rin_head; current != NULL; current = current->next)
@@ -261,7 +337,6 @@
 	for (current = Rin_head; current != NULL; current = current->next)
 	    G_message("Rin: row: %d, col: %d", current->row, current->col);
 
-	/* TODO: anyway to confirm if linkm memory manager knows they are gone???" */
     }
 
     link_cleanup(Rkn_token);
@@ -292,237 +367,279 @@
 
 int seg_speed_test(struct files *files, struct functions *functions)
 {
-	int i, j, k, n, max;
-	clock_t start, end;
+    int i, j, k, n, max;
+    clock_t start, end;
     double temp, cpu_time_used;
-    int (*get) (struct files *, int, int); /* files, row, col */
-	struct RB_TREE *no_check_tree, *known_iseg_tree; 
-	struct RB_TRAV trav;
-	struct pixels *to_check, *newpixel, *current, *tree_pix;
-	FLAG *check_flag;
-	G_message("checking speed of RAM vs SEG vs get function performance");
-	
-	G_message("Access in the same region, so shouldn't have any disk I/O");
-	
-	max = 100000000;
-	G_message("repeating everything %d times.", max);
-	
-	{ /* Array vs. SEG ... when working in local area */
+    int (*get) (struct files *, int, int);	/* files, row, col */
+    struct RB_TREE *no_check_tree, *known_iseg_tree;
+    struct RB_TRAV trav;
+    struct pixels *to_check, *newpixel, *current, *tree_pix;
+    FLAG *check_flag;
+
+    G_message("checking speed of RAM vs SEG vs get function performance");
+
+    G_message("Access in the same region, so shouldn't have any disk I/O");
+
+    max = 100000000;
+    G_message("repeating everything %d times.", max);
+
+    {				/* Array vs. SEG ... when working in local area */
 	start = clock();
-	for (i=0; i<max; i++){
-		segment_get(&files->bands_seg, (void *)files->bands_val, 12, 12);
-		temp = files->bands_val[0];
+	for (i = 0; i < max; i++) {
+	    segment_get(&files->bands_seg, (void *)files->bands_val, 12, 12);
+	    temp = files->bands_val[0];
 	}
 	end = clock();
-	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+	cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
 	G_message("Using SEG: %g", cpu_time_used);
-	
+
 	start = clock();
-	for (i=0; i<max; i++){
-		temp = files->iseg[12][12];
+	for (i = 0; i < max; i++) {
+	    temp = files->iseg[12][12];
 	}
 	end = clock();
-	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+	cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
 	G_message("Using array in RAM: %g", cpu_time_used);
 
 	get = &get_segID_SEG;
 
 	start = clock();
-	for (i=0; i<max; i++){
-		temp = get(files, 12, 12);
+	for (i = 0; i < max; i++) {
+	    temp = get(files, 12, 12);
 	}
 	end = clock();
-	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+	cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
 	G_message("Using SEG w/ get(): %g", cpu_time_used);
 
 	get = &get_segID_RAM;
 
 	start = clock();
-	for (i=0; i<max; i++){
-		temp = get(files, 12, 12);
+	for (i = 0; i < max; i++) {
+	    temp = get(files, 12, 12);
 	}
 	end = clock();
-	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
+	cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
 	G_message("Using RAM w/ get(): %g", cpu_time_used);
-	}
-	
-	G_message("to check storage requirements... system dependent... :");
-	G_message("unsigned char: %lu", sizeof(unsigned char));
-	G_message("unsigned char pointer: %lu", sizeof(unsigned char *));
-	G_message("int: %lu", sizeof(int));
-	G_message("unsigned int: %lu", sizeof(unsigned int));
-	G_message("double: %lu", sizeof(double));
-	
-	
-	max = 100000;
-	G_message("repeating everything %d times.", max);
+    }
 
-	{ /* compare rbtree with linked list and array */
+    G_message("to check storage requirements... system dependent... :");
+    G_message("unsigned char: %lu", sizeof(unsigned char));
+    G_message("unsigned char pointer: %lu", sizeof(unsigned char *));
+    G_message("int: %lu", sizeof(int));
+    G_message("unsigned int: %lu", sizeof(unsigned int));
+    G_message("double: %lu", sizeof(double));
 
+
+    max = 100000;
+    G_message("repeating everything %d times.", max);
+    {				/* compare rbtree with linked list and array */
+
 	n = 100;
 	start = clock();
-	for (i=0; i<max; i++){
-		no_check_tree = rbtree_create(compare_ids, sizeof(struct pixels));
-		/*build*/
-		for(j=0; j<n; j++){
-			tree_pix->row = tree_pix->col = j;
-			rbtree_insert(no_check_tree, &tree_pix);
-		}
-		//~ /*access*/
-		rbtree_init_trav(&trav, no_check_tree);
-		//~ while ((data = rbtree_traverse(&trav)) != NULL) {
-			//~ if (my_compare_fn(data, threshold_data) == 0) break;
-				//~ G_message("%d", data);
-		//~ }
-		/*free memory*/
-		rbtree_destroy(no_check_tree);
+	for (i = 0; i < max; i++) {
+	    no_check_tree = rbtree_create(compare_ids, sizeof(struct pixels));
+	    /*build */
+	    for (j = 0; j < n; j++) {
+		tree_pix->row = tree_pix->col = j;
+		rbtree_insert(no_check_tree, &tree_pix);
+	    }
+	    /*access */
+	    rbtree_init_trav(&trav, no_check_tree);
+	    /*not sure how to do this...
+	       while ((data = rbtree_traverse(&trav)) != NULL) {
+	       if (my_compare_fn(data, threshold_data) == 0) break;
+	       G_message("%d", data);
+	       }
+	     */
+	    /*free memory */
+	    rbtree_destroy(no_check_tree);
 	}
 	end = clock();
-	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
-	G_message("Using rbtree of pixels (just build/destroy), %d elements, time: %g", n, cpu_time_used);
+	cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
+	G_message
+	    ("Using rbtree of pixels (just build/destroy), %d elements, time: %g",
+	     n, cpu_time_used);
 
 	start = clock();
-	for (i=0; i<max; i++){
-		known_iseg_tree = rbtree_create(compare_ids, sizeof(int));
-		/*build*/
-		for(j=0; j<n; j++){
-			rbtree_insert(known_iseg_tree, &j);
-		}
-		//~ /*access*/
-		rbtree_init_trav(&trav, known_iseg_tree);
-		//~ while ((data = rbtree_traverse(&trav)) != NULL) {
-			//~ if (my_compare_fn(data, threshold_data) == 0) break;
-				//~ G_message("%d", data);
-		//~ }
-		/*free memory*/
-		rbtree_destroy(known_iseg_tree);
+	for (i = 0; i < max; i++) {
+	    known_iseg_tree = rbtree_create(compare_ids, sizeof(int));
+	    /*build */
+	    for (j = 0; j < n; j++) {
+		rbtree_insert(known_iseg_tree, &j);
+	    }
+	    /*access */
+	    rbtree_init_trav(&trav, known_iseg_tree);
+	    /*
+	       while ((data = rbtree_traverse(&trav)) != NULL) {
+	       if (my_compare_fn(data, threshold_data) == 0) break;
+	       G_message("%d", data);
+	       } */
+	    /*free memory */
+	    rbtree_destroy(known_iseg_tree);
 	}
 	end = clock();
-	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
-	G_message("Using rbtree ints (just build/destroy), %d elements, time: %g", n, cpu_time_used);
+	cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
+	G_message
+	    ("Using rbtree ints (just build/destroy), %d elements, time: %g",
+	     n, cpu_time_used);
 
 
 	to_check = NULL;
-	
+
 	start = clock();
-	for (i=0; i<max; i++){
-		/*build*/
-		for(j=0; j<n; j++){
-			newpixel = (struct pixels *)link_new(files->token);
-			newpixel->next = to_check;	/*point the new pixel to the current first pixel */
-			newpixel->row = j;
-			newpixel->col = i;
-			to_check = newpixel;	/*change the first pixel to be the new pixel. */
-		}
-		/*access*/
-		for (current = to_check; current != NULL; current = current->next) {	/* for each of Ri's neighbors */
-			temp = current->row;
-		}
-		/*free memory*/
-		my_dispose_list(files->token, &to_check);
+	for (i = 0; i < max; i++) {
+	    /*build */
+	    for (j = 0; j < n; j++) {
+		newpixel = (struct pixels *)link_new(files->token);
+		newpixel->next = to_check;	/*point the new pixel to the current first pixel */
+		newpixel->row = j;
+		newpixel->col = i;
+		to_check = newpixel;	/*change the first pixel to be the new pixel. */
+	    }
+	    /*access */
+	    for (current = to_check; current != NULL; current = current->next) {	/* for each of Ri's neighbors */
+		temp = current->row;
+	    }
+	    /*free memory */
+	    my_dispose_list(files->token, &to_check);
 
 	}
 	end = clock();
-	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
-	G_message("Using linked list and linkm (build/access/free), %d elements, time: %g", n, cpu_time_used);
+	cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
+	G_message
+	    ("Using linked list and linkm (build/access/free), %d elements, time: %g",
+	     n, cpu_time_used);
 
-	
-	n=1000;
-	//repeat for both with larger membership
-	
-		start = clock();
-	for (i=0; i<max; i++){
-		known_iseg_tree = rbtree_create(compare_ids, sizeof(int));
-		rbtree_init_trav(&trav, known_iseg_tree);
 
-		/*build*/
-		for(j=0; j<n; j++){
-			rbtree_insert(known_iseg_tree, &j);
-		}
-		//~ /*access*/
-		//~ while ((data = rbtree_traverse(&trav)) != NULL) {
-			//~ if (my_compare_fn(data, threshold_data) == 0) break;
-				//~ G_message("%d", data);
-		//~ }
-		/*free memory*/
-		rbtree_destroy(known_iseg_tree);
+	n = 1000;
+	/* repeat for both with larger membership */
+
+	start = clock();
+	for (i = 0; i < max; i++) {
+	    known_iseg_tree = rbtree_create(compare_ids, sizeof(int));
+	    rbtree_init_trav(&trav, known_iseg_tree);
+
+	    /*build */
+	    for (j = 0; j < n; j++) {
+		rbtree_insert(known_iseg_tree, &j);
+	    }
+	    /*access */
+	    /* while ((data = rbtree_traverse(&trav)) != NULL) {
+	       if (my_compare_fn(data, threshold_data) == 0) break;
+	       G_message("%d", data);
+	       } */
+	    /*free memory */
+	    rbtree_destroy(known_iseg_tree);
 	}
 	end = clock();
-	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
-	G_message("Using rbtree ints, %d elements, time: %g", n, cpu_time_used);
+	cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
+	G_message("Using rbtree ints, %d elements, time: %g", n,
+		  cpu_time_used);
 
 	to_check = NULL;
-	
+
 	start = clock();
-	for (i=0; i<max; i++){
-		/*build*/
-		for(j=0; j<n; j++){
-			newpixel = (struct pixels *)link_new(files->token);
-			newpixel->next = to_check;	/*point the new pixel to the current first pixel */
-			newpixel->row = j;
-			newpixel->col = i;
-			to_check = newpixel;	/*change the first pixel to be the new pixel. */
-		}
-		/*access*/
-		for (current = to_check; current != NULL; current = current->next) {	/* for each of Ri's neighbors */
-			temp = current->row;
-		}
-		/*free memory*/
-		my_dispose_list(files->token, &to_check);
+	for (i = 0; i < max; i++) {
+	    /*build */
+	    for (j = 0; j < n; j++) {
+		newpixel = (struct pixels *)link_new(files->token);
+		newpixel->next = to_check;	/*point the new pixel to the current first pixel */
+		newpixel->row = j;
+		newpixel->col = i;
+		to_check = newpixel;	/*change the first pixel to be the new pixel. */
+	    }
+	    /*access */
+	    for (current = to_check; current != NULL; current = current->next) {	/* for each of Ri's neighbors */
+		temp = current->row;
+	    }
+	    /*free memory */
+	    my_dispose_list(files->token, &to_check);
 
 	}
 	end = clock();
-	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
-	G_message("Using linked list and linkm, %d elements, time: %g", n, cpu_time_used);
-	
-	k=100;
-	n=50;
-    check_flag = flag_create(k, k);
+	cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
+	G_message("Using linked list and linkm, %d elements, time: %g", n,
+		  cpu_time_used);
+
+	k = 100;
+	n = 50;
+	check_flag = flag_create(k, k);
 	start = clock();
-	for (i=0; i<max; i++){
-		/*set to zero*/
-		flag_clear_all(check_flag);
-		/*write and access*/
-		for(j=0; j<n; j++){
-			flag_set(check_flag, j, j);
-			temp = flag_get(check_flag, j, j);
-		}
+	for (i = 0; i < max; i++) {
+	    /*set to zero */
+	    flag_clear_all(check_flag);
+	    /*write and access */
+	    for (j = 0; j < n; j++) {
+		FLAG_SET(check_flag, j, j);
+		temp = FLAG_GET(check_flag, j, j);
+	    }
 	}
 	end = clock();
-	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
-	G_message("Using %d pixel flag array (all cleared), %d elements set and get, time: %g", k*k, n, cpu_time_used);
-	
+	cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
+	G_message
+	    ("Using %d pixel flag array (all cleared), %d elements set and get, time: %g",
+	     k * k, n, cpu_time_used);
 
-	k=10000;
-    check_flag = flag_create(k, k);
+
+	k = 10000;
+	check_flag = flag_create(k, k);
 	start = clock();
-	for (i=0; i<max; i++){
-		/*set to zero*/
-		flag_clear_all(check_flag);
-		/*write and access*/
-		for(j=0; j<n; j++){
-			flag_set(check_flag, j, j);
-			temp = flag_get(check_flag, j, j);
-		}
+	for (i = 0; i < max; i++) {
+	    /*set to zero */
+	    flag_clear_all(check_flag);
+	    /*write and access */
+	    for (j = 0; j < n; j++) {
+		FLAG_SET(check_flag, j, j);
+		temp = FLAG_GET(check_flag, j, j);
+	    }
 	}
 	end = clock();
-	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
-	G_message("Using %d pixel flag array (all cleared), %d elements set and get, time: %g", k*k, n, cpu_time_used);
+	cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
+	G_message
+	    ("Using %d pixel flag array (all cleared), %d elements set and get, time: %g",
+	     k * k, n, cpu_time_used);
 
+    }
+
+    /* iff bounding constraints have been given, need to confirm neighbors are in the same area.
+     * Faster to check if the bounds map is null, or if no bounds just set all the bounds flags to 1 and directly check the bounds flag? */
+    max = INT_MAX;
+    j = 0;
+    G_message("compare if statement to FLAG_GET, repeating %d times", max);
+    G_message("Flag = %d", FLAG_GET(files->candidate_flag, 1, 1));
+
+    start = clock();
+    for (i = 0; i < max; i++) {
+	if ((FLAG_GET(files->candidate_flag, 1, 1)) != 0) {
+	    j++;
+	}
+    }
+    end = clock();
+    cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
+    G_message("FLAG_GET: %g, temp: %d", cpu_time_used, j);
+    j = 0;
+    start = clock();
+    for (i = 0; i < max; i++) {
+	if (files->bounds_map != NULL) {
+	    j++;
+	}
+    }
+    end = clock();
+    cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
+    G_message("check for NULL: %g, temp: %d", cpu_time_used, j);	/* was faster by about 20% */
+
+    return TRUE;
 }
-	
-	return TRUE;
-}
 
 int get_segID_SEG(struct files *files, int row, int col)
 {
-	segment_get(&files->bands_seg, (void *)files->bands_val, row, col);
-	return files->bands_val[0]; /*todo for accurate comparison, is converting double to int a time penalty? */
+    segment_get(&files->bands_seg, (void *)files->bands_val, row, col);
+    return files->bands_val[0];	/* for accurate comparison, is converting double to int a time penalty? */
 }
 
 int get_segID_RAM(struct files *files, int row, int col)
 {
-	return files->iseg[row][col];
+    return files->iseg[row][col];
 }
 #endif
 
@@ -530,25 +647,23 @@
 {
     int row, col, t;
     double threshold, Ri_similarity, Rk_similarity, tempsim;
-    int endflag;		/* =1 if there were no merges on that processing iteration */
-    int pathflag;		/* =1 if we didn't find mutual neighbors, and should continue with Rk */
+    int endflag;		/* =TRUE if there were no merges on that processing iteration */
+    int pathflag;		/* =TRUE if we didn't find mutual neighbors, and should continue with Rk */
+    struct pixels *Ri_head, *Rk_head, *Rin_head, *Rkn_head, *current,
+	*newpixel, *Ri_bestn;
+    int Ri_count, Rk_count;	/* number of pixels/cells in Ri and Rk */
 
-    /*int mergeflag;    just did it based on if statment... *//* =1 if we have mutually agreeing best neighbors */
-
-    /* Ri = current focus segment
+    /* files->token has the "link_head" for linkm: linked list memory allocation.
+     * 
+     * 4 linked lists of pixels:
+     * Ri = current focus segment
      * Rk = Ri's most similar neighbor
      * Rkn = Rk's neighbors
-     * Rin = Ri's neigbors  currently as pixels, so repeat calculations are made when multiple neighbors in same segment
-     * Todo: should Rin be checked for unique segments?  Or is checking for unique longer then just calculating similarity a few extra times?
-     * files->token has the "link_head" for linkm: linked list memory allocation.
-     * just moved iseg to RAM, bands is in SEG, so probably faster to check for unique. */
+     * Rin = Ri's neigbors
+     * */
 
-    struct pixels *Ri_head, *Rk_head, *Rin_head, *Rkn_head, *current, *newpixel;	/*current will be used to iterate over any of the linked lists. */
-    int Ri_count, Rk_count;	/*TODO when to calculate these, currently accumulating during find_neighbor() */
-    struct pixels *Ri_bestn;	/* best neighbor pixel for Ri, not used as a linked list, just one pixel... */
+    G_message("Running region growing algorithm, the percent completed is based on %d max iterations, but the process will end earlier if no further merges can be made.", functions->end_t);	/*TODO polish: can _() be combined with %d ? */
 
-    G_verbose_message("Running region growing algorithm");
-
     t = 1;
     files->candidate_count = 0;
 
@@ -559,81 +674,39 @@
     Rkn_head = NULL;
     Ri_bestn = NULL;
 
-    /* TODO, want to get a min/max row/col to narrow the processing window ??? */
+    /* TODO, want to get a min/max row/col to narrow the processing window ??? certainly if polygon constraints. */
 
+    /* do while loop until no merges are made, or until t reaches maximum number of iterations */
     do {
-	/* do while loop on t to slowly lower threshold. also check that endflag==0 (no merges were made) */
 
 	G_debug(3, "#######   Starting outer do loop! t = %d    #######", t);
+	G_verbose_message("Pass %d: ", t);
+	G_percent(t, functions->end_t, 1);
 
 	threshold = functions->threshold;	/* TODO, consider making this a function of t. */
 
 	endflag = TRUE;
 
-	/* Set candidate flag to true/1 for all pixels TODO: for polygon/vector constraint, need to just set to true for those being processed */
-	if (files->bounds_map == NULL) {	/*normal processing */
-	    for (row = 0; row < files->nrows; row++) {
-		for (col = 0; col < files->ncols; col++) {
-		    /* TODO: if we are starting from seeds...and only allow merges between unassigned pixels
-		     *  and seeds/existing segments, then this needs an if (and will be very inefficient)
-		     * maybe consider the sorted array, btree, map... but the number of seeds could still be high for a large map */
-		    if (!(FLAG_GET(files->null_flag, row, col))) {
-			FLAG_SET(files->candidate_flag, row, col);	/*candidate pixel flag */
+	set_all_candidate_flags(files);
+	/* Set candidate flag to true/1 for all pixels */
 
-			files->candidate_count++;
-		    }		/* Need something to prevent "pathflag" infinite loop */
-		}
-	    }
-	}
-	else {			/* polygon constraints/boundaries were supplied, include that criteria.  TODO: this repeats a lot of code, is there a way to combine this check without having too many extra if/etc statements ??? */
-	    for (row = 0; row < files->nrows; row++) {
-		for (col = 0; col < files->ncols; col++) {
-		    if (!(FLAG_GET(files->null_flag, row, col))) {
-
-			segment_get(&files->bounds_seg, &files->bounds_val,
-				    row, col);
-
-			if (files->bounds_val == files->current_bound) {
-			    /*TODO could move this if statement one line up, and only set "1" flags if we can assume all flags are already zero.  (i.e. only get/put the ones we want to set to 1.) */
-			    FLAG_SET(files->candidate_flag, row, col);	/*candidate pixel flag */
-			    files->candidate_count++;	/*TODO this assumes full grid with no null or mask!! But need something to prevent "pathflag" infinite loop */
-			}
-			//~ else   !!!TODO is it safe to assume that all flag's are zero at this point?
-			//~ FLAG_UNSET(files->candidate_flag, row, col);
-
-		    }
-		}
-	    }
-	}
-
 	G_debug(4, "Starting to process %d candidate pixels",
 		files->candidate_count);
 
-	/*process candidate pixels */
-	G_message("Pass %d: ", t);
+	/*process candidate pixels for this iteration */
+
 	/*check each pixel, start the processing only if it is a candidate pixel */
-	/* for validation, select one of the two... could make this IFDEF or input parameter */
-	/* reverse order 
-	 */
-#ifdef REVERSE
-	for (row = files->nrows - 1; row >= 0; row--) {
-		G_percent(files->nrows - row, files->nrows, 5);
-	    for (col = files->ncols - 1; col >= 0; col--) {
-#else
 	for (row = 0; row < files->nrows; row++) {
-		G_percent(row, files->nrows, 5);	/* TODO, can a message be included with G_percent? */
 	    for (col = 0; col < files->ncols; col++) {
-#endif
 
-		G_debug(4,
-			"Next starting pixel from next row/col, not from Rk");
+		G_debug(4, "Starting pixel from next row/col, not from Rk");
 
 		if (FLAG_GET(files->candidate_flag, row, col)) {
 		    /*free memory for linked lists */
 		    my_dispose_list(files->token, &Ri_head);
 		    my_dispose_list(files->token, &Rk_head);
 		    my_dispose_list(files->token, &Rin_head);
-		    my_dispose_list(files->token, &Rkn_head);	/* TODO, better style for repeating this for all structures? */
+		    my_dispose_list(files->token, &Rkn_head);
 		    Rk_count = 0;
 
 		    /* First pixel in Ri is current row/col pixel.  We may add more later if it is part of a segment */
@@ -646,280 +719,224 @@
 
 		    pathflag = TRUE;
 
-		    //      while (pathflag == TRUE && files->candidate_count > 0) {   /*if don't find mutual neighbors on first try, will use Rk as next Ri. */
+		    while (pathflag == TRUE && files->candidate_count > 0) {	/*if don't find mutual neighbors on first try, will use Rk as next Ri. */
 
-		    G_debug(4, "Next starting pixel: row, %d, col, %d",
-			    Ri_head->row, Ri_head->col);
+			G_debug(4, "Next starting pixel: row, %d, col, %d",
+				Ri_head->row, Ri_head->col);
 
-		    /* Setting Ri to be not a candidate allows using "itself" when at edge of raster. TODO THIS NEEDS TO BE CHANGED!!!!
-		     * Otherwise need to use a list/count/something to know the number of pixel neighbors */
-		    set_candidate_flag(Ri_head, FALSE, files);	/* TODO: error trap? */
-		    G_debug(4, "line 165, \t\t\t\tcc = %d",
-			    files->candidate_count);
+			/* find segment neighbors, if we don't already have them */
+			if (Rin_head == NULL) {
+			    if (find_segment_neighbors
+				(&Ri_head, &Rin_head, &Ri_count, files,
+				 functions) != TRUE) {
+				G_fatal_error
+				    ("find_segment_neighbors() failed");
+			    }
+			}
 
-		    /* what is passed to find segment neighors: */
-		    /*    G_debug(4, "calling find_segment_neigors() with:");
-		       for (current = Ri_head; current != NULL;
-		       current = current->next)
-		       G_debug(4, "Ri: row: %d, col: %d", current->row,
-		       current->col);
-		       for (current = Rin_head; current != NULL;
-		       current = current->next)
-		       G_debug(4, "Rin: row: %d, col: %d", current->row,
-		       current->col);
-		       G_debug(4, "also passing Ri_count: %d", Ri_count);
-		     */
-		     
-		    /* find segment neighbors */
-		    if (find_segment_neighbors
-			(&Ri_head, &Rin_head, &Ri_count, files,
-			 functions) != TRUE) {
-			G_fatal_error("find_segment_neighbors() failed");
-		    }
+			if (Rin_head != NULL) {	/*found neighbors, find best neighbor then see if is mutually best neighbor */
 
-		    if (Rin_head == NULL) {
-			G_debug(4, "2a, Segment had no valid neighbors");	/*this could happen if there is a segment surrounded by pixels that have already been processed */
-			pathflag = FALSE;
-			Ri_count = 0;
-			set_candidate_flag(Ri_head, FALSE, files);	/* TODO: error trap? */
-			files->candidate_count++;	/* already counted out Ri[0]; */
-			G_debug(4, "line 176, \t\t\t\tcc = %d",
-				files->candidate_count);
-		    }
-		    else {	/*found neighbors, go ahead until find mutually agreeing neighbors */
+#ifdef DEBUG
+			    /*print out segment membership */
+			    G_debug(4, "2b, Found Ri's pixels");
+			    for (current = Ri_head; current != NULL;
+				 current = current->next)
+				G_debug(4, "Ri: row: %d, col: %d",
+					current->row, current->col);
+			    /*print out neighbors */
+			    G_debug(4, "2b, Found Ri's neighbors");
+			    for (current = Rin_head; current != NULL;
+				 current = current->next)
+				G_debug(4, "Rin: row: %d, col: %d",
+					current->row, current->col);
+#endif
 
-			G_debug(4, "2b, Found Ri's pixels");
-			#ifdef DEBUG
-			/*print out neighbors */
-			for (current = Ri_head; current != NULL;
-			     current = current->next)
-			    G_debug(4, "Ri: row: %d, col: %d", current->row,
-				    current->col);
-			#endif
-			G_debug(4, "2b, Found Ri's neighbors");
-			#ifdef DEBUG
-			/*print out neighbors */
-			for (current = Rin_head; current != NULL;
-			     current = current->next)
-			    G_debug(4, "Rin: row: %d, col: %d", current->row,
-				    current->col);
-			#endif
+			    /* ********  find Ri's most similar neighbor  ******** */
+			    Ri_bestn = NULL;
+			    Ri_similarity = threshold + 1;	/* set current similarity to max value */
+			    segment_get(&files->bands_seg, (void *)files->bands_val, Ri_head->row, Ri_head->col);	/* current segment values */
 
-			/* find Ri's most similar neighbor */
-			Ri_bestn = NULL;
-			Ri_similarity = threshold + 1;	/* set current similarity to max value */
-			segment_get(&files->bands_seg, (void *)files->bands_val, Ri_head->row, Ri_head->col);	/* current segment values */
+			    /* for each of Ri's neighbors */
+			    for (current = Rin_head; current != NULL;
+				 current = current->next) {
+				tempsim =
+				    (*functions->calculate_similarity)
+				    (Ri_head, current, files, functions);
+				G_debug(4,
+					"simularity = %g for neighbor : row: %d, col %d.",
+					tempsim, current->row, current->col);
 
-			for (current = Rin_head; current != NULL; current = current->next) {	/* for each of Ri's neighbors */
-			    tempsim =
-				(*functions->calculate_similarity) (Ri_head,
-								    current,
-								    files,
-								    functions);
-			    G_debug(4,
-				    "simularity = %g for neighbor : row: %d, col %d.",
-				    tempsim, current->row, current->col);
+				if (tempsim < Ri_similarity) {
+				    Ri_similarity = tempsim;
+				    Ri_bestn = current;
+				    G_debug(4,
+					    "Current lowest Ri_similarity = %g, for neighbor pixel row: %d col: %d",
+					    Ri_similarity, Ri_bestn->row,
+					    Ri_bestn->col);
+				}
+			    }	/* finished similiarity check for all neighbors */
 
-			    if (tempsim < Ri_similarity) {
-				Ri_similarity = tempsim;
-				Ri_bestn = current;	/*TODO want to point to the current pixel...confirm  when current changes need this to stay put! */
+			    if (Ri_bestn != NULL) {
 				G_debug(4,
-					"Current lowest Ri_similarity = %g, for neighbor pixel row: %d col: %d",
+					"Lowest Ri_similarity = %g, for neighbor pixel row: %d col: %d",
 					Ri_similarity, Ri_bestn->row,
 					Ri_bestn->col);
+				if (!
+				    (FLAG_GET
+				     (files->candidate_flag, Ri_bestn->row,
+				      Ri_bestn->col))) {
+				    /* this check is important:
+				     * best neighbor is not a valid candidate, was already merged earlier in this time step */
+				    Ri_bestn = NULL;
+				    pathflag = FALSE;
+				}
 			    }
-			}
 
-			if (Ri_bestn != NULL) {
-			    G_debug(4,
-				    "Lowest Ri_similarity = %g, for neighbor pixel row: %d col: %d",
-				    Ri_similarity, Ri_bestn->row,
-				    Ri_bestn->col);
+			    if (Ri_bestn != NULL && Ri_similarity < threshold) {	/* small TODO: should this be < or <= for threshold? */
 
-			    //~ segment_get(&files->out_seg,
-			    //~ (void *)files->out_val, Ri_bestn->row,
-			    //~ Ri_bestn->col);
-			    if (!
-				(FLAG_GET
-				 (files->candidate_flag, Ri_bestn->row,
-				  Ri_bestn->col)))
-				/* this check is important:
-				 * best neighbor is not a valid candidate, was already merged earlier in this time step */
-				Ri_bestn = NULL;
-			}
+				/* Rk starts from Ri's best neighbor */
+				Rk_count = 1;
+				newpixel =
+				    (struct pixels *)link_new(files->token);
+				newpixel->next = NULL;
+				newpixel->row = Ri_bestn->row;
+				newpixel->col = Ri_bestn->col;
+				Rk_head = newpixel;
 
-			if (Ri_bestn != NULL && Ri_similarity < threshold) {	/* small TODO: should this be < or <= for threshold? */
-			    /* we'll have the neighbor pixel to start with. */
-			    G_debug(4, "3a: Working with Rk");
-			    Rk_count = 1;
-			    newpixel =
-				(struct pixels *)link_new(files->token);
-			    newpixel->next = NULL;	/* or = Rk_head; *//*TODO, should this be Rk_head or just NULL? amounts to the same thing here? */
-			    newpixel->row = Ri_bestn->row;
-			    newpixel->col = Ri_bestn->col;
-			    Rk_head = newpixel;
-			    /* TODO - lists starting, should this be a helper function, did at start of Ri and Rk.  */
+				find_segment_neighbors(&Rk_head, &Rkn_head,
+						       &Rk_count, files,
+						       functions);
 
-			    /*Todo: Do we want to put Ri into Rkn ?  Hmm, we don't want to actually check similarity on them when they are in Rkn, since we'll
-			     * start with Ri as the initial similarity.  Maybe add a 3rd input list to find_segment_neighbors(), and put them directily into
-			     * the no_check list so we avoid a small amount of processing?  But that might take longer then just checking their similarity in the first place! */
+#ifdef DEBUG
+				/*print out neighbors */
+				G_debug(4, "Found Rk's pixels");
+				for (current = Rk_head; current != NULL;
+				     current = current->next)
+				    G_debug(4, "Rk: row: %d, col: %d",
+					    current->row, current->col);
+				/*print out neighbors */
+				G_debug(4, "Found Rk's neighbors");
+				for (current = Rkn_head; current != NULL;
+				     current = current->next)
+				    G_debug(4, "Rkn: row: %d, col: %d",
+					    current->row, current->col);
+#endif
 
-			    find_segment_neighbors(&Rk_head, &Rkn_head, &Rk_count, files, functions);	/* data structure for Rk's neighbors, and pixels in Rk if we don't already have it */
+				/* ********  find Rk's most similar neighbor  ******** */
+				Rk_similarity = Ri_similarity;	/*Ri gets first priority - ties won't change anything, so we'll accept Ri and Rk as mutually best neighbors */
+				segment_get(&files->bands_seg, (void *)files->bands_val, Rk_head->row, Rk_head->col);	/* current segment values */
 
-			    G_debug(4, "Found Rk's pixels");
-			    #ifdef DEBUG
-			    /*print out neighbors */
-			    for (current = Rk_head; current != NULL;
-				 current = current->next)
-				G_debug(4, "Rk: row: %d, col: %d",
-					current->row, current->col);
-				#endif
-			    G_debug(4, "Found Rk's neighbors");
-			    #ifdef DEBUG
-			    /*print out neighbors */
-			    for (current = Rkn_head; current != NULL;
-				 current = current->next)
-				G_debug(4, "Rkn: row: %d, col: %d",
-					current->row, current->col);
-				#endif
-				
-			    /*find Rk's most similar neighbor */
-			    Rk_similarity = Ri_similarity;	/*Ri gets first priority - ties won't change anything, so we'll accept Ri and Rk as mutually best neighbors */
-			    segment_get(&files->bands_seg, (void *)files->bands_val, Rk_head->row, Rk_head->col);	/* current segment values */
+				/* check similarity for each of Rk's neighbors */
+				for (current = Rkn_head; current != NULL;
+				     current = current->next) {
+				    tempsim =
+					functions->calculate_similarity
+					(Rk_head, current, files, functions);
 
-			    for (current = Rkn_head; current != NULL; current = current->next) {	/* for each of Rk's neighbors */
-				tempsim = functions->calculate_similarity(Rk_head, current, files, functions);	/*TODO: need an error trap here, if something goes wrong with calculating similarity? */
+				    if (tempsim < Rk_similarity) {
+					Rk_similarity = tempsim;
+					break;	/* exit for Rk's neighbors loop here, we know that Ri and Rk aren't mutually best neighbors */
+				    }
+				}	/* have checked all of Rk's neighbors */
 
-				if (tempsim < Rk_similarity) {
-				    Rk_similarity = tempsim;
-				    break;	/* exit for Rk's neighbors loop here, we know that Ri and Rk aren't mutually best neighbors */
+				if (Rk_similarity == Ri_similarity) {	/* mutually most similar neighbors */
+				    merge_values(Ri_head, Rk_head, Ri_count,
+						 Rk_count, files);
+				    endflag = FALSE;	/* we've made at least one merge, so want another t iteration */
+				    pathflag = FALSE;	/* go to next row,column pixel - end of Rk -> Ri chain since we found mutual best neighbors */
 				}
+				else {	/* they weren't mutually best neighbors */
+				    G_debug(4,
+					    "Ri was not Rk's best neighbor, Ri_sim: %g, Rk_sim, %g",
+					    Ri_similarity, Rk_similarity);
+
+				    /* checked Ri once, didn't find a mutually best neighbor, so remove all members of Ri from candidate pixels for this iteration */
+				    set_candidate_flag(Ri_head, FALSE, files);
+				    G_debug(4, "line 247, \t\t\t\tcc = %d",
+					    files->candidate_count);
+				}
+			    }	/* end if (Ri_bestn != NULL && Ri_similarity < threshold) */
+			    else {
+				/* no valid best neighbor for this Ri
+				 * exclude this Ri from further comparisons 
+				 * because we checked already Ri for a mutually best neighbor with all valid candidates
+				 * thus Ri can not be the mutually best neighbor later on during this pass
+				 * unfortunately this does happen sometimes */
+				set_candidate_flag(Ri_head, FALSE, files);
+				G_debug(4,
+					"3b Ri's best neighbor was not valid candidate, or their similarity was > threshold");
+				pathflag = FALSE;
 			    }
+			}	/* end if(Rin_head != NULL) */
+			else {	/* Ri didn't have a neighbor */
+			    G_debug(4, "Segment had no neighbors");
+			    pathflag = FALSE;
+			    set_candidate_flag(Ri_head, FALSE, files);
+			    G_debug(4, "line 176, \t\t\t\tcc = %d",
+				    files->candidate_count);
+			}
 
-			    if (Rk_similarity == Ri_similarity) {	/* so they agree, both are mutually most similar neighbors, none of Rk's other neighbors were more similar */
-				merge_values(Ri_head, Rk_head, Ri_count, Rk_count, files);	/* TODO error trap */
-				endflag = FALSE;	/* we've made at least one merge, so need another t iteration */
-				pathflag = FALSE;	/* go to next row,column pixel - end of Rk -> Ri chain since we found mutual best neighbors */
+			if (pathflag) {	/*initialize Ri, Rin, Rk, Rin using Rk as Ri. */
+			    /* So for the next iteration, lets start with Rk as the focus segment */
+			    /* Seems this should be a bit faster, since we already have segment membership pixels */
+			    /* TODO: this shortened each iteration time by about 10% but increased the number of iterations by 20% ?!?!?!? */
+			if(functions->path == TRUE){
+			    Ri_count = Rk_count;
+			    Rk_count = 0;
+			    my_dispose_list(files->token, &Ri_head);
+			    Ri_head = Rk_head;
+			    Rk_head = NULL;
+			    if (Rkn_head != NULL) {
+				my_dispose_list(files->token, &Rin_head);
+				Rin_head = Rkn_head;
+				Rkn_head = NULL;
 			    }
-			    else {	/* they weren't mutually best neighbors */
-				G_debug(4,
-					"Ri was not Rk's best neighbor, Ri_sim: %g, Rk_sim, %g",
-					Ri_similarity, Rk_similarity);
+			    else
+				my_dispose_list(files->token, &Rin_head);
+			}
+			else
+			pathflag = FALSE;
+			
+			}
 
-				/* did this at beginning of path loop */
-				set_candidate_flag(Ri_head, FALSE, files);	/* remove all Ri members from candidate pixels (set flag) */
-				files->candidate_count++;	/* add one back, we had already set Ri[0] flag at the beginning. */
-				G_debug(4, "line 247, \t\t\t\tcc = %d",
-					files->candidate_count);
-				//~ /* Use Rk as next Ri:   this is the eCognition technique.  Seems this is a bit faster, we already have segment membership pixels */
-				//~ Ri_count = Rk_count;
-				//~ /* Ri = &Rk; *//* TODO fast/correct way to use arrays and pointers? Ri now will just point to Rk? */
-				//~ /* at beginning, when initialize Rk ` Rk[n][m] = 0 ` ?? with that just remove the Rk pointer, and leave Ri pointing to the original Rk data? */
-				//~ for (n = 0; n < 100; n++) {     /*TODO shortcut code...get rid of this... */
-				//~ for (m = 0; m < 2; m++) {
-				//~ Ri[n][m] = Rk[n][m];
-				//~ }
-				//~ }
-
-			    }
-			}	/*end else (from if mutually best neighbors) */
-			else {
-			    /* no valid best neighbor for this Ri
-			     * exclude this Ri from further comparisons 
-			     * because we checked already Ri for a mutually best neighbor with all valid candidates
-			     * thus Ri can not be the mutually best neighbor later on during this pass
-			     * unfortunately this does happen sometimes */
-			    set_candidate_flag(Ri_head, FALSE, files);	/* TODO: error trap? */
-			    files->candidate_count++;	/*first pixel was already set */
-			    G_debug(4,
-				    "3b Rk didn't didn't exist, was not valid candidate, or similarity was > threshold");
-			}	/*end else - Ri's best neighbor was not a candidate */
-		    }		/* end else - Ri did have neighbors */
-		    //          }           /*end pathflag do loop */
+		    }		/*end pathflag do loop */
 		}		/*end if pixel is candidate pixel */
 	    }			/*next column */
-#ifdef REVERSE
-	     G_percent(files->nrows - row, files->nrows, 5);
-#else
-	     G_percent(row, files->nrows-1, 5);	/* TODO, can a message be included with G_percent? */
-#endif
-	    /* TODO, the REVERSE version gets printed on a new line, and isnt' covered.  The else version is. ? */
-	    /* TODO, shows up in CLI, not in GUI */
+	}			/*next row */
 
-#ifdef NODEF
-	}
+	/* finished one iteration over entire raster */
+	G_debug(4, "Finished one pass, t was = %d", t);
+	t++;
     }
-    /* to balance brackets in first ifdef statement */
-#endif
+    while (t <= functions->end_t && endflag == FALSE);	/*end t loop, either reached max iterations or didn't merge any segments */
 
-    }				/*next row */
-    /* finished one pass for processing candidate pixels */
+    if (t == 2 && files->bounds_map == NULL)
+	G_warning(_("No segments were created. Verify threshold and region settings."));
+    /* included the bound_map check, since we check all values between min/max, intermediate values might not be present.  TODO polish, add back in if we check for unique bounds values. */
 
-    G_debug(4, "Finished one pass, t was = %d", t);
-    t++;
-    } while (t <= functions->end_t && endflag == FALSE);
-    /*end t loop *//*TODO, should there be a max t that it can iterate for?  Include t in G_message? */
-    
-	if(endflag == FALSE) G_message(_("Merging processes stopped due to reaching max iteration limit, more merges may be possible"));
+    if (endflag == FALSE)
+	G_message(_("Merging processes stopped due to reaching max iteration limit, more merges may be possible"));
 
 
-	/* ****************************************************************************************** */
-	/* final pass, ignore threshold and force a merge for small segments with their best neighbor */
-	/* ****************************************************************************************** */
-	
-	
-	if (functions->min_segment_size > 1) {
-		G_verbose_message("Final iteration, force merges for small segments.");
-		
-		/* TODO: It would be possible to use some sort of "forced merge" flag and if statements in the above code.
- * This might be easier to maintain... but I wasn't sure which would be easier to read
- * and it would add some extra if statements to each iteration...
- * 
- * for the final forced merge, the candidate flag is just to keep track if we have confirmed if:
- * 		a. the segment size is >= to the minimum allowed size  or
- * 		b. we have merged it with its best neighbor
- */
-	/* TODO: repeating this twice, move to helper function? */
-	
-	/* Set candidate flag to true/1 for all pixels TODO: for polygon/vector constraint, need to just set to true for those being processed */
-	if (files->bounds_map == NULL) {	/*normal processing */
-	    for (row = 0; row < files->nrows; row++) {
-		for (col = 0; col < files->ncols; col++) {
-		    /* TODO: if we are starting from seeds...and only allow merges between unassigned pixels
-		     *  and seeds/existing segments, then this needs an if (and will be very inefficient)
-		     * maybe consider the sorted array, btree, map... but the number of seeds could still be high for a large map */
-		    if (!(FLAG_GET(files->null_flag, row, col))) {
-			FLAG_SET(files->candidate_flag, row, col);	/*candidate pixel flag */
+    /* ****************************************************************************************** */
+    /* final pass, ignore threshold and force a merge for small segments with their best neighbor */
+    /* ****************************************************************************************** */
 
-			files->candidate_count++;
-		    }		/* Need something to prevent "pathflag" infinite loop */
-		}
-	    }
-	}
-	else {			/* polygon constraints/boundaries were supplied, include that criteria.  TODO: this repeats a lot of code, is there a way to combine this check without having too many extra if/etc statements ??? */
-	    for (row = 0; row < files->nrows; row++) {
-		for (col = 0; col < files->ncols; col++) {
-		    if (!(FLAG_GET(files->null_flag, row, col))) {
 
-			segment_get(&files->bounds_seg, &files->bounds_val,
-				    row, col);
+    if (functions->min_segment_size > 1) {
+	G_verbose_message
+	    (_("Final iteration, forcing merges for small segments, percent complete based on rows."));
 
-			if (files->bounds_val == files->current_bound) {
-			    /*TODO could move this if statement one line up, and only set "1" flags if we can assume all flags are already zero.  (i.e. only get/put the ones we want to set to 1.) */
-			    FLAG_SET(files->candidate_flag, row, col);	/*candidate pixel flag */
-			    files->candidate_count++;	/*TODO this assumes full grid with no null or mask!! But need something to prevent "pathflag" infinite loop */
-			}
-			//~ else   !!!TODO is it safe to assume that all flag's are zero at this point?
-			//~ FLAG_UNSET(files->candidate_flag, row, col);
+	/* for the final forced merge, the candidate flag is just to keep track if we have confirmed if:
+	 *              a. the segment size is >= to the minimum allowed size  or
+	 *              b. we have merged it with its best neighbor
+	 */
 
-		    }
-		}
-	    }
-	}
+	set_all_candidate_flags(files);
 
-
 	for (row = 0; row < files->nrows; row++) {
-	for (col = 0; col < files->ncols; col++) {
+	    G_percent(row, files->nrows - 1, 5);
+	    for (col = 0; col < files->ncols; col++) {
 
 		if (FLAG_GET(files->candidate_flag, row, col)) {
 		    /*free memory for linked lists */
@@ -940,10 +957,6 @@
 		    G_debug(4, "Next starting pixel: row, %d, col, %d",
 			    Ri_head->row, Ri_head->col);
 
-		    set_candidate_flag(Ri_head, FALSE, files);	/* TODO: error trap? */
-		    G_debug(4, "line 165, \t\t\t\tcc = %d",
-			    files->candidate_count);
-
 		    /* find segment neighbors */
 		    if (find_segment_neighbors
 			(&Ri_head, &Rin_head, &Ri_count, files,
@@ -951,516 +964,534 @@
 			G_fatal_error("find_segment_neighbors() failed");
 		    }
 
-		    if (Rin_head != NULL)  /*found neighbors */
-		    {
-				if (Ri_count >= functions->min_segment_size) /* don't force a merge */
-					set_candidate_flag(Ri_head, FALSE, files);
-					
-				else /* Merge with most similar neighbor */
-				{
-					//~ TODO DELETE?
-					//~ G_debug(4, "2b, Found Ri's pixels");
-					//~ 
-					//~ /*print out neighbors */
-					//~ for (current = Ri_head; current != NULL;
-						 //~ current = current->next)
-						//~ G_debug(4, "Ri: row: %d, col: %d", current->row,
-							//~ current->col);
-//~ 
-					//~ G_debug(4, "2b, Found Ri's neighbors");
-					//~ /*print out neighbors */
-					//~ for (current = Rin_head; current != NULL;
-						 //~ current = current->next)
-						//~ G_debug(4, "Rin: row: %d, col: %d", current->row,
-							//~ current->col);
+		    if (Rin_head != NULL) {	/*found neighbors */
+			if (Ri_count >= functions->min_segment_size)	/* don't force a merge */
+			    set_candidate_flag(Ri_head, FALSE, files);
 
-					/* find Ri's most similar neighbor */
-					Ri_bestn = NULL;
-					Ri_similarity = threshold + 1;	/* set current similarity to max value */
-					segment_get(&files->bands_seg, (void *)files->bands_val, Ri_head->row, Ri_head->col);	/* current segment values */
+			else {	/* Merge with most similar neighbor */
 
-					for (current = Rin_head; current != NULL; current = current->next) {	/* for each of Ri's neighbors */
-						tempsim =
-						(*functions->calculate_similarity) (Ri_head,
-											current,
-											files,
-											functions);
-						G_debug(4,
-							"simularity = %g for neighbor : row: %d, col %d.",
-							tempsim, current->row, current->col);
+			    /* find Ri's most similar neighbor */
+			    Ri_bestn = NULL;
+			    Ri_similarity = DBL_MAX;	/* set current similarity to max value */
+			    segment_get(&files->bands_seg, (void *)files->bands_val, Ri_head->row, Ri_head->col);	/* current segment values */
 
-						if (tempsim < Ri_similarity) {
-						Ri_similarity = tempsim;
-						Ri_bestn = current;	/*TODO want to point to the current pixel...confirm  when current changes need this to stay put! */
-						G_debug(4,
-							"Current lowest Ri_similarity = %g, for neighbor pixel row: %d col: %d",
-							Ri_similarity, Ri_bestn->row,
-							Ri_bestn->col);
-						}
-					}
+			    /* for each of Ri's neighbors */
+			    for (current = Rin_head; current != NULL;
+				 current = current->next) {
+				tempsim = (*functions->calculate_similarity)
+				    (Ri_head, current, files, functions);
+				G_debug(4,
+					"simularity = %g for neighbor : row: %d, col %d.",
+					tempsim, current->row, current->col);
 
-					if (Ri_bestn != NULL)
-						G_debug(4,
-							"Lowest Ri_similarity = %g, for neighbor pixel row: %d col: %d",
-							Ri_similarity, Ri_bestn->row,
-							Ri_bestn->col);
-				
-					if (Ri_bestn != NULL)
-					{
-						/* we'll have the neighbor pixel to start with. */
-						G_debug(4, "3a: Working with Rk");
-						Rk_count = 1;
-						newpixel =
-						(struct pixels *)link_new(files->token);
-						newpixel->next = NULL;	/* or = Rk_head; *//*TODO, should this be Rk_head or just NULL? amounts to the same thing here? */
-						newpixel->row = Ri_bestn->row;
-						newpixel->col = Ri_bestn->col;
-						Rk_head = newpixel;
-						/* TODO - lists starting, should this be a helper function, did at start of Ri and Rk.  */
+				if (tempsim < Ri_similarity) {
+				    Ri_similarity = tempsim;
+				    Ri_bestn = current;
+				    G_debug(4,
+					    "Current lowest Ri_similarity = %g, for neighbor pixel row: %d col: %d",
+					    Ri_similarity, Ri_bestn->row,
+					    Ri_bestn->col);
+				}
+			    }
+			    if (Ri_bestn != NULL) {
+				G_debug(4,
+					"Lowest Ri_similarity = %g, for neighbor pixel row: %d col: %d",
+					Ri_similarity, Ri_bestn->row,
+					Ri_bestn->col);
 
-						/* using this just to get the full pixel/cell membership list for Rk */
-						find_segment_neighbors(&Rk_head, &Rkn_head, &Rk_count, files, functions);	/* data structure for Rk's neighbors, and pixels in Rk if we don't already have it */
+				/* we'll have the neighbor pixel to start with. */
+				Rk_count = 1;
+				newpixel =
+				    (struct pixels *)link_new(files->token);
+				newpixel->next = NULL;
+				newpixel->row = Ri_bestn->row;
+				newpixel->col = Ri_bestn->col;
+				Rk_head = newpixel;
 
-//~ TODO DELETE?
-						//~ G_debug(4, "Found Rk's pixels");
-						//~ /*print out neighbors */
-						//~ for (current = Rk_head; current != NULL;
-						 //~ current = current->next)
-						//~ G_debug(4, "Rk: row: %d, col: %d",
-							//~ current->row, current->col);
-//~ 
-						//~ G_debug(4, "Found Rk's neighbors");
-						//~ /*print out neighbors */
-						//~ for (current = Rkn_head; current != NULL;
-						 //~ current = current->next)
-						//~ G_debug(4, "Rkn: row: %d, col: %d",
-							//~ current->row, current->col);
+				/* get the full pixel/cell membership list for Rk *//* todo polish: worth having a seperate function for this, since we don't need the neighbors? */
+				find_segment_neighbors(&Rk_head, &Rkn_head,
+						       &Rk_count, files,
+						       functions);
 
-						merge_values(Ri_head, Rk_head, Ri_count, Rk_count, files);	/* TODO error trap */
+				merge_values(Ri_head, Rk_head, Ri_count,
+					     Rk_count, files);
 
-						/* merge_values sets Ri and Rk candidate flag to FALSE.  Put Rk back to TRUE if the size is too small. */
-						if(Ri_count + Rk_count < functions->min_segment_size)
-							set_candidate_flag(Rk_head, TRUE, files);
-					} /* end if best neighbor != null */
-					else
-					G_warning("No best neighbor found in final merge, this shouldn't happen?");
-					
-					
-				}		/* end else - pixel count was below minimum allowed */
-		    } /* end if neighbors found */
-		    else{ /* no neighbors were found */
-				G_warning("no neighbors found, this means only one segment was created.");
-				set_candidate_flag(Ri_head, FALSE, files);
+				/* merge_values sets Ri and Rk candidate flag to FALSE.  Put Rk back to TRUE if the size is too small. */
+				if (Ri_count + Rk_count <
+				    functions->min_segment_size)
+				    set_candidate_flag(Rk_head, TRUE, files);
+			    }	/* end if best neighbor != null */
+			    else
+				G_warning
+				    ("No best neighbor found in final merge for small segment, this shouldn't happen!");
+
+
+			}	/* end else - pixel count was below minimum allowed */
+		    }		/* end if neighbors found */
+		    else {	/* no neighbors were found */
+			G_warning
+			    ("no neighbors found, this means only one segment was created.");
+			set_candidate_flag(Ri_head, FALSE, files);
 		    }
-		}		/*end if pixel is candidate pixel */
-	}			/*next column */
-	G_percent(row, files->nrows-1, 5);
-    }			/*next row */
-	} /* end if for force merge */
-	else
-		G_message(_("Input for minimum pixels in a segment was 1, skipping final iteration for joining small segments."));
+		}		/* end if pixel is candidate pixel */
+	    }			/* next column */
+	}			/* next row */
+    }				/* end if for force merge */
+    else
+	G_verbose_message(_("Input for minimum pixels in a segment was 1, will not force a merge for small segments."));
 
-    /* free memory *//*TODO: anything ? */
+    G_message("temporary(?) message, number of passes: %d", t - 1);
 
+    return TRUE;
+}
 
-    return TRUE;
+int find_segment_neighbors(struct pixels **R_head,
+			   struct pixels **neighbors_head, int *seg_count,
+			   struct files *files, struct functions *functions)
+{
+    int n, current_seg_ID, Ri_seg_ID = -1;
+    struct pixels *newpixel, *current, *to_check, tree_pix;	/* need to check the pixel neighbors of to_check */
+    int pixel_neighbors[8][2];
+    struct RB_TREE *no_check_tree;	/* pixels that should no longer be checked on this current find_neighbors() run */
+    struct RB_TREE *known_iseg;
+
+#ifdef DEBUG
+    struct RB_TRAV trav;
+#endif
+
+    /* TODO, any time savings to move any variables to files (mem allocation in open_files) */
+
+    /* neighbor list will be a listing of pixels that are neighbors?  Include segment numbers?  Only include unique segments?
+     * MM: counting unique neighbor segments could have the advantage of dealing with special
+     * segments that have only one neighbor, i.e. segments within segments
+     * 
+
+     * Maybe the most complete return would be a structure array, structure to include the segment ID and a list of points in it?  
+     * But the list of points would NOT be inclusive - just the points bordering the current segment...
+     */
+
+    /* parameter: R, current segment membership, could be single pixel (incomplete list) or list of pixels.
+     * parameter: neighbors/Rin/Rik, neighbor pixels, could have a list already, or could be empty ?
+     * functions->num_pn  int, 4 or 8, for number of pixel neighbors 
+     * */
+
+
+    /* *** initialize data *** */
+
+    Ri_seg_ID = files->iseg[(*R_head)->row][(*R_head)->col];
+    no_check_tree = rbtree_create(compare_pixels, sizeof(struct pixels));
+    known_iseg = rbtree_create(compare_ids, sizeof(int));
+    to_check = NULL;
+
+    /* Copy R in to_check and no_check data structures (don't expand them if we find them again) */
+
+    for (current = *R_head; current != NULL; current = current->next) {
+	/* put in to_check linked list */
+	newpixel = (struct pixels *)link_new(files->token);
+	newpixel->next = to_check;	/*point the new pixel to the current first pixel */
+	newpixel->row = current->row;
+	newpixel->col = current->col;
+	to_check = newpixel;	/*change the first pixel to be the new pixel. */
+
+	/* put in no_check tree */
+	tree_pix.row = current->row;
+	tree_pix.col = current->col;
+	if (rbtree_insert(no_check_tree, &tree_pix) == 0)	/* don't check it again */
+	    G_warning("could not insert data!?");
     }
 
-    int find_segment_neighbors(struct pixels **R_head,
-			       struct pixels **neighbors_head, int *seg_count,
-			       struct files *files,
-			       struct functions *functions)
-    {
-	int n, current_seg_ID, Ri_seg_ID = -1;
-	struct pixels *newpixel, *current, *to_check, tree_pix;	/* need to check the pixel neighbors of to_check */
-	int pixel_neighbors[8][2];	/* TODO: data type? use list instead?  put in files to allocate memory once? */
-	
-//TODO remove...	/* files->no_check is a FLAG structure, only used here but allocating memory in open_files */
-	struct RB_TREE *no_check_tree; /* pixels that should no longer be checked on this current find_neighbors() run */
-	struct RB_TREE *known_iseg;
+    while (to_check != NULL) {	/* removing from to_check list as we go, NOT iterating over the list. */
+	G_debug(5,
+		"\tfind_pixel_neighbors for row: %d , col %d",
+		to_check->row, to_check->col);
+
+	functions->find_pixel_neighbors(to_check->row,
+					to_check->col,
+					pixel_neighbors, files);
+
+	/* Done using this to_check pixels coords, remove from list */
+	current = to_check;	/* temporary store the old head */
+	to_check = to_check->next;	/*head now points to the next element in the list */
+	link_dispose(files->token, (VOID_T *) current);
+
+	/*print out to_check */
 #ifdef DEBUG
-	struct RB_TRAV trav;
+	G_debug(5, "remaining pixel's in to_check, after popping:");
+	for (current = to_check; current != NULL; current = current->next)
+	    G_debug(5, "to_check... row: %d, col: %d", current->row,
+		    current->col);
+	for (current = *neighbors_head; current != NULL;
+	     current = current->next)
+	    G_debug(5, "Rn... row: %d, col: %d", current->row, current->col);
 #endif
-	
-	/* TODO, any time savings to move any variables to files (mem allocation in open_files) */
 
-	/* neighbor list will be a listing of pixels that are neighbors?  Include segment numbers?  Only include unique segments?
-	 * Maybe the most complete return would be a structure array, structure to include the segment ID and a list of points in it?  
-	 * But the list of points would NOT be inclusive - just the points bordering the current segment...
-	 */
+	/*now check the pixel neighbors and add to the lists */
 
-	/* parameter: R, current segment membership, could be single pixel or list of pixels.
-	 * parameter: neighbors/Rin/Rik, neighbor pixels, could have a list already, or could be empty ?
-	 * functions->num_pn  int, 4 or 8, for number of pixel neighbors 
-	 * */
+	/*print what pixel neighbors were found: */
+	/*      for (n = 0; n < functions->num_pn; n++){
+	   G_debug(5, "\tpixel_neighbors[n][0]: %d, pixel_neighbors[n][1]: %d",  pixel_neighbors[n][0], pixel_neighbors[n][1]);
+	   } */
 
-	/* show what was sent to function *//*
-	   G_debug(5, "in find_segment_neigors() with:");
-	   for (current = *R_head; current != NULL; current = current->next)
-	   G_debug(5, "R: row: %d, col: %d", current->row, current->col);
-	   for (current = *neighbors_head; current != NULL; current = current->next)
-	   G_debug(5, "neig: row: %d, col: %d", current->row, current->col);
-	   G_debug(5, "also passing Ri_count: %d", *seg_count); */
+	/* for each pixel neighbors, check if they should be processed, check segment ID, and add to appropriate lists */
+	for (n = 0; n < functions->num_pn; n++) {
 
-	/* *** initialize data *** */
-	
-	/* get Ri's segment ID */
-	Ri_seg_ID = files->iseg[(*R_head)->row][(*R_head)->col];
-	
-//	flag_clear_all(files->no_check);
-	no_check_tree = rbtree_create(compare_pixels, sizeof(struct pixels));
-	known_iseg = rbtree_create(compare_ids, sizeof(int));
-	to_check = NULL;
+	    /* skip pixel if out of computational area or null */
+	    if (pixel_neighbors[n][0] < 0 ||
+		pixel_neighbors[n][0] >= files->nrows ||
+		pixel_neighbors[n][1] < 0 ||
+		pixel_neighbors[n][1] >= files->ncols ||
+		FLAG_GET(files->null_flag, pixel_neighbors[n][0],
+			 pixel_neighbors[n][1])
+		)
+		continue;
 
-	/* Copy R in to_check and no_check data structures (don't expand them if we find them again) */
+	    /* skip pixel if not in same boundary area */
+	    //~ if(files->bounds_map != NULL){
+	    //~ segment_get(&files->bounds_seg, &files->bounds_val, pixel_neighbors[n][0], pixel_neighbors[n][1]);
+	    //~ if (files->bounds_val != files->current_bound) {
+	    //~ continue;
+	    //~ }
+	    //~ }
 
-	for (current = *R_head; current != NULL; current = current->next) {
-		/* put in to_check linked list */
-	    newpixel = (struct pixels *)link_new(files->token);
-	    newpixel->next = to_check;	/*point the new pixel to the current first pixel */
-	    newpixel->row = current->row;
-	    newpixel->col = current->col;
-	    to_check = newpixel;	/*change the first pixel to be the new pixel. */
-	
-		/* put in no_check tree */
-		tree_pix.row = current->row;
-		tree_pix.col = current->col;
-		if(rbtree_insert(no_check_tree, &tree_pix)==0)	/* don't check it again */
-			G_warning("could not insert data!?");
-
-		//todo delete	    flag_set(files->no_check, current->row, current->col);
-	
-	}	
-	
-	while (to_check != NULL) {	/* removing from to_check list as we go, NOT iterating over the list. */
+	    tree_pix.row = pixel_neighbors[n][0];
+	    tree_pix.col = pixel_neighbors[n][1];
 	    G_debug(5,
-		    "\tfind_pixel_neighbors for row: %d , col %d",
-		    to_check->row, to_check->col);
+		    "********* rbtree_find(no_check_tree, &tree_pix) = %p",
+		    rbtree_find(no_check_tree, &tree_pix));
 
-	    functions->find_pixel_neighbors(to_check->row,
-					    to_check->col,
-					    pixel_neighbors, files);
+	    if (rbtree_find(no_check_tree, &tree_pix) == FALSE) {	/* want to check this neighbor */
+		current_seg_ID =
+		    files->iseg[pixel_neighbors[n][0]][pixel_neighbors[n][1]];
 
-	    /* Done using this to_check pixels coords, remove from list */
-	    current = to_check;	/* temporary store the old head */
-	    to_check = to_check->next;	/*head now points to the next element in the list */
-	    link_dispose(files->token, (VOID_T *) current);
+		rbtree_insert(no_check_tree, &tree_pix);	/* don't check it again */
 
-	    /*print out to_check */
-	    #ifdef DEBUG
-	    G_debug(5, "remaining pixel's in to_check, after popping:");
-	    for (current = to_check; current != NULL; current = current->next)
-		G_debug(5, "to_check... row: %d, col: %d", current->row,
-			current->col);
-	    for (current = *neighbors_head; current != NULL;
-		 current = current->next)
-		G_debug(5, "Rn... row: %d, col: %d", current->row,
-			current->col);
-		#endif
-		
-	    /*now check the pixel neighbors and add to the lists */
+		G_debug(5, "\tfiles->iseg[][] = %d Ri_seg_ID = %d",
+			files->iseg[pixel_neighbors[n][0]]
+			[pixel_neighbors[n]
+			 [1]], Ri_seg_ID);
 
-	    /*debug what pixel neighbors were found: */
-	    /*      for (n = 0; n < functions->num_pn; n++){
-	       G_debug(5, "\tpixel_neighbors[n][0]: %d, pixel_neighbors[n][1]: %d",  pixel_neighbors[n][0], pixel_neighbors[n][1]);
-	       } */
+		if (current_seg_ID == Ri_seg_ID) {	/* pixel is member of current segment, add to R */
+		    G_debug(5, "\tputing pixel_neighbor in Ri");
+		    /* put pixel_neighbor[n] in Ri */
+		    newpixel = (struct pixels *)link_new(files->token);
+		    newpixel->next = *R_head;	/*point the new pixel to the current first pixel */
+		    newpixel->row = pixel_neighbors[n][0];
+		    newpixel->col = pixel_neighbors[n][1];
+		    *R_head = newpixel;	/*change the first pixel to be the new pixel. */
+		    *seg_count = *seg_count + 1;	/* zero index... Ri[0] had first pixel and set count =1.  increment after save data. */
+		    G_debug(5, "\t*seg_count now = %d", *seg_count);
 
-	    for (n = 0; n < functions->num_pn; n++) {	/* with pixel neighbors */
+		    /* put pixel_neighbor[n] in to_check -- want to check this pixels neighbors */
+		    newpixel = (struct pixels *)link_new(files->token);
+		    newpixel->next = to_check;	/*point the new pixel to the current first pixel */
+		    newpixel->row = pixel_neighbors[n][0];
+		    newpixel->col = pixel_neighbors[n][1];
+		    to_check = newpixel;	/*change the first pixel to be the new pixel. */
 
-		// TODO delete   if (flag_get(files->no_check, pixel_neighbors[n][0], pixel_neighbors[n][1]) == FALSE) 
-		tree_pix.row = pixel_neighbors[n][0];
-		tree_pix.col = pixel_neighbors[n][1];
-		G_debug(5, "\tcurrent_seg_ID = %d", current_seg_ID);
-		G_debug(5, "********* rbtree_find(no_check_tree, &tree_pix) = %p", rbtree_find(no_check_tree, &tree_pix)); 
-		G_debug(5, "if evaluation: %d", rbtree_find(no_check_tree, &tree_pix) == FALSE);
+		}
+		else {		/* segment id's were different */
+		    //TODO: if current ID not found in known neighbors list
+		    //add to known neighbors list
+		    /* put pixel_neighbor[n] in Rin */
+		    G_debug(5, "Put in neighbors_head");
+		    newpixel = (struct pixels *)link_new(files->token);
+		    newpixel->next = *neighbors_head;	/*point the new pixel to the current first pixel */
+		    newpixel->row = pixel_neighbors[n][0];
+		    newpixel->col = pixel_neighbors[n][1];
+		    *neighbors_head = newpixel;	/*change the first pixel to be the new pixel. */
+		    //}
 
-		if(rbtree_find(no_check_tree, &tree_pix) == FALSE) {	/* want to check this neighbor */
-			current_seg_ID = files->iseg[pixel_neighbors[n][0]][pixel_neighbors[n][1]];		
+		}
 
-		    rbtree_insert(no_check_tree, &tree_pix);	/* don't check it again */
 
-		    if (!(FLAG_GET(files->null_flag, pixel_neighbors[n][0], pixel_neighbors[n][1]))) {	/* all pixels, not just valid pixels */
+	    }			/*end if for pixel_neighbor was in "don't check" list */
+	}			/* end for loop - next pixel neighbor */
 
-				G_debug(5, "\tfiles->iseg[][] = %d Ri_seg_ID = %d",
-					files->
-					iseg[pixel_neighbors[n][0]][pixel_neighbors[n]
-									[1]], Ri_seg_ID);
-									
-				if(current_seg_ID == Ri_seg_ID) { /* pixel is member of current segment, add to R */
-					G_debug(5, "\tputing pixel_neighbor in Ri");
-					/* put pixel_neighbor[n] in Ri */
-					newpixel =
-					(struct pixels *)link_new(files->token);
-					newpixel->next = *R_head;	/*point the new pixel to the current first pixel */
-					newpixel->row = pixel_neighbors[n][0];
-					newpixel->col = pixel_neighbors[n][1];
-					*R_head = newpixel;	/*change the first pixel to be the new pixel. */
-					*seg_count = *seg_count + 1;	/* zero index... Ri[0] had first pixel and set count =1.  increment after save data. */
-					G_debug(5, "\t*seg_count now = %d", *seg_count);
+#ifdef DEBUG
+	G_debug(5,
+		"remaining pixel's in to_check, after processing the last pixel's neighbors:");
+	for (current = to_check; current != NULL; current = current->next)
+	    G_debug(5, "to_check... row: %d, col: %d", current->row,
+		    current->col);
 
-					/* put pixel_neighbor[n] in to_check -- want to check this pixels neighbors */
-					newpixel =
-					(struct pixels *)link_new(files->token);
-					newpixel->next = to_check;	/*point the new pixel to the current first pixel */
-					newpixel->row = pixel_neighbors[n][0];
-					newpixel->col = pixel_neighbors[n][1];
-					to_check = newpixel;	/*change the first pixel to be the new pixel. */
+	G_debug(5, "\t### end of pixel neighors");
+#endif
+    }				/* end while to_check has more elements */
 
-				}
-				else {	/* segment id's were different */
-					//if current ID not found in known neighbors list
-						//add to known neighbors list
-						/* put pixel_neighbor[n] in Rin */
-						G_debug(5, "Put in neighbors_head");
-						/* TODO - helper function for adding pixel to a list */
-						newpixel =
-						(struct pixels *)link_new(files->token);
-						newpixel->next = *neighbors_head;	/*point the new pixel to the current first pixel */
-						newpixel->row = pixel_neighbors[n][0];
-						newpixel->col = pixel_neighbors[n][1];
-						*neighbors_head = newpixel;	/*change the first pixel to be the new pixel. */
-					//}
+    /* clean up */
+    rbtree_destroy(no_check_tree);
+    rbtree_destroy(known_iseg);
 
-				}
-		    }		/*end if not a null pixel */
-		    else
-			G_debug(5,
-				"pixel row: %d col: %d was a null pixel",
-				pixel_neighbors[n][0], pixel_neighbors[n][1]);
+    return TRUE;
+}
 
-		}		/*end if for pixel_neighbor was in "don't check" list */
-	    }			/* end for loop - next pixel neighbor */
-	    #ifdef DEBUG
-	    G_debug(5,
-		    "remaining pixel's in to_check, after processing the last pixel's neighbors:");
-	    for (current = to_check; current != NULL; current = current->next)
-			G_debug(5, "to_check... row: %d, col: %d", current->row,
-				current->col);
-	
-	    G_debug(5, "\t### end of pixel neighors");
-	    #endif
-	}			/* while to_check has more elements */
+int find_four_pixel_neighbors(int p_row, int p_col,
+			      int pixel_neighbors[8][2], struct files *files)
+{
+    /* Note: this will return neighbors outside of the raster boundary.
+     * Check in the calling routine if the pixel should be processed.
+     */
 
-	/* TODO - anything to free??? */
-	/* clean up */
-	rbtree_destroy(no_check_tree);
-	rbtree_destroy(known_iseg);
+    /* north */
+    pixel_neighbors[0][1] = p_col;
+    pixel_neighbors[0][0] = p_row - 1;
 
-	return TRUE;
-    }
+    /* east */
+    pixel_neighbors[1][0] = p_row;
+    pixel_neighbors[1][1] = p_col + 1;
 
-    int find_four_pixel_neighbors(int p_row, int p_col,
-				  int pixel_neighbors[8][2],
-				  struct files *files)
-    {
-	/*   
-	   G_debug(5,"\t\tin find 4 pixel neighbors () ");
-	   G_debug(5,"\t\tpixel row: %d pixel col: %d", p_row, p_col);
-	   G_debug(5, "\t\tTotal rows: %d, total cols: %d", files->nrows, files->ncols); *//*check that we have files... */
+    /* south */
+    pixel_neighbors[2][1] = p_col;
+    pixel_neighbors[2][0] = p_row + 1;
 
-	/* north */
-	pixel_neighbors[0][1] = p_col;
-	if (p_row > 0)
-	    pixel_neighbors[0][0] = p_row - 1;
-	else
-	    pixel_neighbors[0][0] = p_row;	/*This is itself, which will be in "already checked" list.  TODO: use null or -1 as flag to skip?  What is fastest to process? */
+    /* west */
+    pixel_neighbors[3][0] = p_row;
+    pixel_neighbors[3][1] = p_col - 1;
 
-	/* east */
-	pixel_neighbors[1][0] = p_row;
-	if (p_col < files->ncols - 1)
-	    pixel_neighbors[1][1] = p_col + 1;
-	else
-	    pixel_neighbors[1][1] = p_col;
+    return TRUE;
+}
 
-	/* south */
-	pixel_neighbors[2][1] = p_col;
-	if (p_row < files->nrows - 1)
-	    pixel_neighbors[2][0] = p_row + 1;
-	else
-	    pixel_neighbors[2][0] = p_row;
+int find_eight_pixel_neighbors(int p_row, int p_col,
+			       int pixel_neighbors[8][2], struct files *files)
+{
+    /* get the 4 orthogonal neighbors: */
+    find_four_pixel_neighbors(p_row, p_col, pixel_neighbors, files);
 
-	/* west */
-	pixel_neighbors[3][0] = p_row;
-	if (p_col > 0)
-	    pixel_neighbors[3][1] = p_col - 1;
-	else
-	    pixel_neighbors[3][1] = p_col;
+    /* and then the diagonals: */
 
-	/*TODO: seems there should be a more elegent way to do this... */
-	return TRUE;
-    }
+    /* north west */
+    pixel_neighbors[4][0] = p_row - 1;
+    pixel_neighbors[4][1] = p_col - 1;
 
-    int find_eight_pixel_neighbors(int p_row, int p_col,
-				   int pixel_neighbors[8][2],
-				   struct files *files)
-    {
-	/* get the 4 orthogonal neighbors */
-	find_four_pixel_neighbors(p_row, p_col, pixel_neighbors, files);
+    /* north east */
+    pixel_neighbors[5][0] = p_row - 1;
+    pixel_neighbors[5][1] = p_col + 1;
 
-	/* get the 4 diagonal neighbors */
-	G_warning("Diagonal neighbors Not Implemented");
-	/*TODO... continue as above? or "nicer" way to do it? */
-	return TRUE;
-    }
+    /* south east */
+    pixel_neighbors[6][0] = p_row + 1;
+    pixel_neighbors[6][1] = p_col + 1;
 
+    /* south west */
+    pixel_neighbors[7][0] = p_row + 1;
+    pixel_neighbors[7][1] = p_col - 1;
+
+    return TRUE;
+}
+
     /* similarity / distance between two points based on their input raster values */
     /* assumes first point values already saved in files->bands_seg - only run segment_get once for that value... */
     /* TODO: segment_get already happened for a[] values in the main function.  Could remove a[] from these parameters */
-    double calculate_euclidean_similarity(struct pixels *a, struct pixels *b,
-					  struct files *files,
-					  struct functions *functions)
-    {
-	double val = 0;
-	int n;
+double calculate_euclidean_similarity(struct pixels *a, struct pixels *b,
+				      struct files *files,
+				      struct functions *functions)
+{
+    double val = 0;
+    int n;
 
-	/* get values for pixel b */
-	segment_get(&files->bands_seg, (void *)files->second_val, b->row,
-		    b->col);
+    /* get values for pixel b */
+    segment_get(&files->bands_seg, (void *)files->second_val, b->row, b->col);
 
-	/* euclidean distance, sum the square differences for each dimension */
-	for (n = 0; n < files->nbands; n++) {
-	    val =
-		val + (files->bands_val[n] -
-		       files->second_val[n]) * (files->bands_val[n] -
-						files->second_val[n]);
-	}
+    /* euclidean distance, sum the square differences for each dimension */
+    for (n = 0; n < files->nbands; n++) {
+	val =
+	    val + (files->bands_val[n] -
+		   files->second_val[n]) * (files->bands_val[n] -
+					    files->second_val[n]);
+    }
 
-	/* val = sqrt(val); *//* use squared distance, save the calculation time */
+    /* val = sqrt(val); *//* use squared distance, save the calculation time. */
 
-	return val;
+    return val;
 
-    }
+}
 
-    int merge_values(struct pixels *Ri_head, struct pixels *Rk_head,
-		     int Ri_count, int Rk_count, struct files *files)
-    {				/* TODO: correct assumption that this should be a weighted mean? */
-	int n;
-	struct pixels *current;
+int merge_values(struct pixels *Ri_head, struct pixels *Rk_head,
+		 int Ri_count, int Rk_count, struct files *files)
+{
+    int n;
+    struct pixels *current;
 
-	/*get input values, maybe if handle earlier gets correctly this can be avoided. */
-	segment_get(&files->bands_seg, (void *)files->bands_val, Ri_head->row,
-		    Ri_head->col);
-	segment_get(&files->bands_seg, (void *)files->second_val,
-		    Rk_head->row, Rk_head->col);
+    /*get input values *//*TODO polish, confirm if we can assume we already have bands_val for Ri, so don't need to segment_get() again? */
+    segment_get(&files->bands_seg, (void *)files->bands_val, Ri_head->row,
+		Ri_head->col);
+    segment_get(&files->bands_seg, (void *)files->second_val,
+		Rk_head->row, Rk_head->col);
 
-	for (n = 0; n < files->nbands; n++) {
-	    files->bands_val[n] =
-		(files->bands_val[n] * Ri_count +
-		 files->second_val[n] * Rk_count) / (Ri_count + Rk_count);
-	}
+    for (n = 0; n < files->nbands; n++) {
+	files->bands_val[n] =
+	    (files->bands_val[n] * Ri_count +
+	     files->second_val[n] * Rk_count) / (Ri_count + Rk_count);
+    }
 
-	/* update segment number and candidate flag ==0 */
+    /* update segment number and candidate flag ==0 */
 
-	G_debug(4, "\t\tMerging, segment number: %d, including pixels:",
-		files->iseg[Ri_head->row][Ri_head->col]);
+    G_debug(4, "\t\tMerging, segment number: %d, including pixels:",
+	    files->iseg[Ri_head->row][Ri_head->col]);
 
-	/* for each member of Ri and Rk, write new average bands values and segment values */
-	for (current = Ri_head; current != NULL; current = current->next) {
-	    segment_put(&files->bands_seg, (void *)files->bands_val,
-			current->row, current->col);
-	    FLAG_UNSET(files->candidate_flag, current->row, current->col);	/*candidate pixel flag, only one merge allowed per t iteration */
-	    files->candidate_count--;
-	    G_debug(4, "line 508, \t\t\t\tcc = %d", files->candidate_count);
-	    G_debug(4, "\t\tRi row: %d, col: %d", current->row, current->col);
-	}
-	for (current = Rk_head; current != NULL; current = current->next) {
-	    segment_put(&files->bands_seg, (void *)files->bands_val,
-			current->row, current->col);
-	    files->iseg[current->row][current->col] =
-		files->iseg[Ri_head->row][Ri_head->col];
-	    FLAG_UNSET(files->candidate_flag, current->row, current->col);
-	    files->candidate_count--;
-	    G_debug(4, "line 516, \t\t\t\tcc = %d", files->candidate_count);
-	    G_debug(4, "\t\tRk row: %d, col: %d", current->row, current->col);
+    /* for each member of Ri and Rk, write new average bands values and segment values */
+    for (current = Ri_head; current != NULL; current = current->next) {
+	segment_put(&files->bands_seg, (void *)files->bands_val,
+		    current->row, current->col);
+	FLAG_UNSET(files->candidate_flag, current->row, current->col);	/*candidate pixel flag, only one merge allowed per t iteration */
+	files->candidate_count--;
+	G_debug(4, "line 508, \t\t\t\tcc = %d", files->candidate_count);
+	G_debug(4, "\t\tRi row: %d, col: %d", current->row, current->col);
+    }
+    for (current = Rk_head; current != NULL; current = current->next) {
+	segment_put(&files->bands_seg, (void *)files->bands_val,
+		    current->row, current->col);
+	files->iseg[current->row][current->col] =
+	    files->iseg[Ri_head->row][Ri_head->col];
+	FLAG_UNSET(files->candidate_flag, current->row, current->col);
+	files->candidate_count--;
+	G_debug(4, "line 516, \t\t\t\tcc = %d", files->candidate_count);
+	G_debug(4, "\t\tRk row: %d, col: %d", current->row, current->col);
 
-	}
-
-	files->candidate_count++;	/* had already counted down the starting pixel Ri[0] at the beginning... */
-	G_debug(4, "line 522, \t\t\t\tcc = %d", files->candidate_count);
-	return TRUE;
     }
 
-    /* TODO.. helper function, maybe make more general? */
-    /* todo, not using this in all cases, plus this used to be more complicated but now is two lines.  maybe get rid of this function. */
+    return TRUE;
+}
+
     /* besides setting flag, also increments how many pixels remain to be processed */
-    int set_candidate_flag(struct pixels *head, int value,
-			   struct files *files)
-    {
-	/* head is linked list of pixels, value is new value of flag */
-	struct pixels *current;
+int set_candidate_flag(struct pixels *head, int value, struct files *files)
+{
+    /* head is linked list of pixels, value is new value of flag */
+    struct pixels *current;
 
-	for (current = head; current != NULL; current = current->next) {
+    for (current = head; current != NULL; current = current->next) {
 
 
-	    if (value == FALSE) {
-		FLAG_UNSET(files->candidate_flag, current->row, current->col);
-		files->candidate_count--;
-	    }
-	    else if (value == TRUE) {
-		FLAG_SET(files->candidate_flag, current->row, current->col);
-		files->candidate_count++;
-	    }
-	    else
-		G_fatal_error
-		    ("programming bug, helper function called with invalid argument");
+	if (value == FALSE) {
+	    FLAG_UNSET(files->candidate_flag, current->row, current->col);
+	    files->candidate_count--;
+	}
+	else if (value == TRUE) {
+	    FLAG_SET(files->candidate_flag, current->row, current->col);
+	    files->candidate_count++;
+	}
+	else
+	    G_fatal_error
+		("programming bug, helper function called with invalid argument");
 
-	    G_debug(4, "line 544, \t\t\t\tcc = %d", files->candidate_count);
-	}
-	return TRUE;
+	G_debug(4, "line 1253, \t\t\t\tcc = %d", files->candidate_count);
     }
+    return TRUE;
+}
 
     /* let memory manager know space is available again and reset head to NULL */
-    int my_dispose_list(struct link_head *token, struct pixels **head)
-    {
-	struct pixels *current;
+int my_dispose_list(struct link_head *token, struct pixels **head)
+{
+    struct pixels *current;
 
-	while ((*head) != NULL) {
-	    current = *head;	/* remember "old" head */
-	    *head = (*head)->next;	/* move head to next pixel */
-	    link_dispose(token, (VOID_T *) current);	/* remove "old" head */
-	}
-
-	return TRUE;
+    while ((*head) != NULL) {
+	current = *head;	/* remember "old" head */
+	*head = (*head)->next;	/* move head to next pixel */
+	link_dispose(token, (VOID_T *) current);	/* remove "old" head */
     }
 
-/* function used by binary tree to compare items */
+    return TRUE;
+}
 
-/* TODO
- * "static" was used in break_polygons.c  extern was suggested in docs.  */
+    /* functions used by binary tree to compare items */
 
+    /* TODO "static" was used in break_polygons.c  extern was suggested in docs.  */
+
 int compare_ids(const void *first, const void *second)
 {
-	int *a = (int *)first, *b = (int *)second;
+    int *a = (int *)first, *b = (int *)second;
 
-	if (*a < *b)
-		return -1;
-	else if (*a > *b)
-		return 1;
-	else if (*a == *b)
-		return 0;
-	
-	
-	G_warning(_("find neighbors: Bug in binary tree!"));
+    if (*a < *b)
+	return -1;
+    else if (*a > *b)
 	return 1;
-	
+    else if (*a == *b)
+	return 0;
+
+
+    G_warning(_("find neighbors: Bug in binary tree!"));
+    return 1;
+
 }
 
 int compare_pixels(const void *first, const void *second)
 {
-	struct pixels *a = (struct pixels *)first, *b = (struct pixels *)second;
+    struct pixels *a = (struct pixels *)first, *b = (struct pixels *)second;
 
-	if (a->row < b->row)
-		return -1;
-	else if (a->row > b->row)
-		return 1;
-	//else if (*a->row == *b->row) todo - a little faster to use else.  But what if (can) a null pixel be passed?
-	else {
-            /* same row */
-	    if (a->col < b->col)
-		    return -1;
-	    else if (a->col > b->col)
-		    return 1;
-        }
-	/* same row and col todo, same as above, need an == check to be sure?*/
-	return 0;
+    if (a->row < b->row)
+	return -1;
+    else if (a->row > b->row)
+	return 1;
+    else {
+	/* same row */
+	if (a->col < b->col)
+	    return -1;
+	else if (a->col > b->col)
+	    return 1;
+    }
+    /* same row and col */
+    return 0;
 }
+
+/* Set candidate flag to true/1 or false/0 for all pixels in current processing area
+ * checks for NULL flag and if it is in current "polygon" if a bounds map is given */
+int set_all_candidate_flags(struct files *files)
+{
+    int row, col;
+
+    if (files->bounds_map == NULL) {	/* process entire raster */
+	for (row = files->minrow; row < files->maxrow; row++) {
+	    for (col = files->mincol; col < files->maxcol; col++) {
+		/* TODO: if we are starting from seeds...and only allow merges between unassigned pixels
+		 *  and seeds/existing segments, then this needs an if (and will be very inefficient)
+		 * maybe consider the sorted array, btree, map... but the number of seeds could still be high for a large map */
+		/* MM: could be solved/not necessary if all pixels of an existing segment have the same ID */
+		if (!(FLAG_GET(files->null_flag, row, col))) {
+		    FLAG_SET(files->candidate_flag, row, col);
+		    files->candidate_count++;
+		}
+		else
+		    FLAG_UNSET(files->candidate_flag, row, col);
+	    }
+	}
+    }
+    else {			/* process part of the raster, polygon constraints/boundaries */
+	for (row = files->minrow; row < files->maxrow; row++) {
+	    for (col = files->mincol; col < files->maxcol; col++) {
+		if (!(FLAG_GET(files->in_bounds_flag, row, col))) {
+		    FLAG_SET(files->candidate_flag, row, col);
+		    files->candidate_count++;
+		}
+		else
+		    FLAG_UNSET(files->candidate_flag, row, col);
+	    }
+	}
+    }
+
+    return TRUE;
+}
+
+
+/* TODO polish: helper functions:
+ * 
+ * starting a list
+ * 
+ * */
+
+#ifdef NODEF
+G_message("2b, Found Ri's pixels");
+			/*print out neighbors */
+for (current = Ri_head; current != NULL; current = current->next)
+    G_message("Ri: row: %d, col: %d", current->row, current->col);
+G_message("2b, Found Ri's neighbors");
+			/*print out neighbors */
+for (current = Rin_head; current != NULL; current = current->next)
+    G_message("Rin: row: %d, col: %d", current->row, current->col);
+G_message("Found Rk's pixels");
+			    /*print out neighbors */
+for (current = Rk_head; current != NULL; current = current->next)
+    G_message("Rk: row: %d, col: %d", current->row, current->col);
+G_message("Found Rk's neighbors");
+			    /*print out neighbors */
+for (current = Rkn_head; current != NULL; current = current->next)
+    G_message("Rkn: row: %d, col: %d", current->row, current->col);
+#endif

Added: grass-addons/grass7/imagery/i.segment/flag.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/flag.c	                        (rev 0)
+++ grass-addons/grass7/imagery/i.segment/flag.c	2012-07-20 05:36:54 UTC (rev 52419)
@@ -0,0 +1,49 @@
+#include <grass/gis.h>
+#include "flag.h"
+
+int flag_clear_all(FLAG * flags)
+{
+    register int r, c;
+
+    for (r = 0; r < flags->nrows; r++) {
+	for (c = 0; c < flags->leng; c++) {
+	    flags->array[r][c] = 0;
+	}
+    }
+
+    return 0;
+}
+
+FLAG *flag_create(int nrows, int ncols)
+{
+    unsigned char *temp;
+    FLAG *new_flag;
+    register int i;
+
+    new_flag = (FLAG *) G_malloc(sizeof(FLAG));
+    new_flag->nrows = nrows;
+    new_flag->ncols = ncols;
+    new_flag->leng = (ncols + 7) / 8;
+    new_flag->array =
+	(unsigned char **)G_malloc(nrows * sizeof(unsigned char *));
+
+    temp =
+	(unsigned char *)G_malloc(nrows * new_flag->leng *
+				  sizeof(unsigned char));
+
+    for (i = 0; i < nrows; i++) {
+	new_flag->array[i] = temp;
+	temp += new_flag->leng;
+    }
+
+    return (new_flag);
+}
+
+int flag_destroy(FLAG * flags)
+{
+    G_free(flags->array[0]);
+    G_free(flags->array);
+    G_free(flags);
+
+    return 0;
+}

Modified: grass-addons/grass7/imagery/i.segment/flag.h
===================================================================
--- grass-addons/grass7/imagery/i.segment/flag.h	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/flag.h	2012-07-20 05:36:54 UTC (rev 52419)
@@ -20,6 +20,8 @@
  ** FLAG *flags;
  **     sets all values in flags to zero.
  **
+ * following 3 were changed to macros, same usage
+ * 
  ** flag_unset(flags, row, col)
  ** FLAG *flags;
  ** int row, col;
@@ -55,23 +57,9 @@
 #define FLAG_GET(flags,row,col) \
 	(flags)->array[(row)][(col)>>3] & (1<<((col) & 7))
 
-/* flag_clr_all.c */
+/* flag.c */
 int flag_clear_all(FLAG *);
-
-/* flag_create.c */
 FLAG *flag_create(int, int);
-
-/* flag_destroy.c */
 int flag_destroy(FLAG *);
 
-/* flag_get.c */
-int flag_get(FLAG *, int, int);
-
-/* flag_set.c */
-int flag_set(FLAG *, int, int);
-
-/* flag_unset.c */
-int flag_unset(FLAG *, int, int);
-
-
 #endif /* __FLAG_H__ */

Deleted: grass-addons/grass7/imagery/i.segment/flag_clr_all.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/flag_clr_all.c	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/flag_clr_all.c	2012-07-20 05:36:54 UTC (rev 52419)
@@ -1,14 +0,0 @@
-#include "flag.h"
-
-int flag_clear_all(FLAG * flags)
-{
-    register int r, c;
-
-    for (r = 0; r < flags->nrows; r++) {
-	for (c = 0; c < flags->leng; c++) {
-	    flags->array[r][c] = 0;
-	}
-    }
-
-    return 0;
-}

Deleted: grass-addons/grass7/imagery/i.segment/flag_create.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/flag_create.c	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/flag_create.c	2012-07-20 05:36:54 UTC (rev 52419)
@@ -1,27 +0,0 @@
-#include <grass/gis.h>
-#include "flag.h"
-
-FLAG *flag_create(int nrows, int ncols)
-{
-    unsigned char *temp;
-    FLAG *new_flag;
-    register int i;
-
-    new_flag = (FLAG *) G_malloc(sizeof(FLAG));
-    new_flag->nrows = nrows;
-    new_flag->ncols = ncols;
-    new_flag->leng = (ncols + 7) / 8;
-    new_flag->array =
-	(unsigned char **)G_malloc(nrows * sizeof(unsigned char *));
-
-    temp =
-	(unsigned char *)G_malloc(nrows * new_flag->leng *
-				  sizeof(unsigned char));
-
-    for (i = 0; i < nrows; i++) {
-	new_flag->array[i] = temp;
-	temp += new_flag->leng;
-    }
-
-    return (new_flag);
-}

Deleted: grass-addons/grass7/imagery/i.segment/flag_destroy.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/flag_destroy.c	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/flag_destroy.c	2012-07-20 05:36:54 UTC (rev 52419)
@@ -1,11 +0,0 @@
-#include <grass/gis.h>
-#include "flag.h"
-
-int flag_destroy(FLAG * flags)
-{
-    G_free(flags->array[0]);
-    G_free(flags->array);
-    G_free(flags);
-
-    return 0;
-}

Deleted: grass-addons/grass7/imagery/i.segment/flag_get.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/flag_get.c	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/flag_get.c	2012-07-20 05:36:54 UTC (rev 52419)
@@ -1,6 +0,0 @@
-#include "flag.h"
-
-int flag_get(FLAG * flags, int row, int col)
-{
-    return (flags->array[row][col >> 3] & (1 << (col & 7)));
-}

Deleted: grass-addons/grass7/imagery/i.segment/flag_set.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/flag_set.c	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/flag_set.c	2012-07-20 05:36:54 UTC (rev 52419)
@@ -1,8 +0,0 @@
-#include "flag.h"
-
-int flag_set(FLAG * flags, int row, int col)
-{
-    flags->array[row][col >> 3] |= (1 << (col & 7));
-
-    return 0;
-}

Deleted: grass-addons/grass7/imagery/i.segment/flag_unset.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/flag_unset.c	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/flag_unset.c	2012-07-20 05:36:54 UTC (rev 52419)
@@ -1,8 +0,0 @@
-#include "flag.h"
-
-int flag_unset(FLAG * flags, int row, int col)
-{
-    flags->array[row][col >> 3] &= ~(1 << (col & 7));
-
-    return 0;
-}

Modified: grass-addons/grass7/imagery/i.segment/i.segment.html
===================================================================
--- grass-addons/grass7/imagery/i.segment/i.segment.html	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/i.segment.html	2012-07-20 05:36:54 UTC (rev 52419)
@@ -2,7 +2,9 @@
 <H2>NOTES</h2>
 <H2>EXAMPLES</h2>
 <h2>TODO</h2>
+For Region Growing, the current limit with CELL storage is 2 billion starting segment ID's.  Workaround: If the original image has a larger number of pixels, please use the starting seeds option to limit the number of starting segments.
 <h2>BUGS</h2>
 <H2>REFERENCES</h2>
 <h2>SEE ALSO</h2>
 <h2>AUTHORS</h2>
+Eric Momsen

Modified: grass-addons/grass7/imagery/i.segment/iseg.h
===================================================================
--- grass-addons/grass7/imagery/i.segment/iseg.h	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/iseg.h	2012-07-20 05:36:54 UTC (rev 52419)
@@ -16,6 +16,8 @@
 #include <grass/linkm.h>
 #include "flag.h"
 
+/* DEBUG will add some additional testing options to the segmentation method drop down.
+ * it also add some while loops that just have G_debug statements in them. */
 /* #define DEBUG */
 
 /* pixel stack */
@@ -36,66 +38,51 @@
     /* region info */
     int nrows, ncols;
 
-    /* files *//* TODO, for all map names, is this better for any reason, saw it in manual example: char name[GNAME_MAX]; */
+    /* files */
     char *out_name;		/* name of output raster map */
-    char *seeds, *bounds_map, *bounds_mapset;	/* optional segment seeds and polygon constraints/boundaries */
+    const char *seeds, *bounds_map;
+    const char *bounds_mapset;	/* optional segment seeds and polygon constraints/boundaries */
     char *out_band;		/* for debug */
 
-    /* file processing *//* TODO decide if bounds should be RAM or SEG */
-    /* input values initially, then bands_seg is updated with current mean values for the segment. */
+    /* file processing */
+    /* bands_seg is initialized with the input raster valuess, then is updated with current mean values for the segment. */
     int nbands;			/* number of rasters in the image group */
     SEGMENT bands_seg, bounds_seg;	/* bands is for input, normal application is landsat bands, but other input can be included in the group. */
     double *bands_val;		/* array, to hold all input values at one pixel */
     double *second_val;		/* to hold values at second point for similarity comparison */
     int bounds_val, current_bound;
+    int minrow, maxrow, mincol, maxcol;
 
     /* results */
     int **iseg;			/*segment ID assignment. */
 
     /* processing flags */
-    FLAG *candidate_flag, *null_flag;	/*TODO, need some way to remember MASK/NULL values.  Was using -1, 0, 1 in int array.  Better to use 2 FLAG structures, better readibility? */
-//    FLAG *no_check;		/* pixels that have already been checked during this neighbor finding routine */
+    FLAG *candidate_flag, *null_flag, *in_bounds_flag;
 
     /* memory management, linked lists */
-    struct link_head *token;	/* for linkm linked list memory management. */
+    struct link_head *token;	/* for linkm.h linked list memory management. */
 
     /* other info */
-    int candidate_count;	/*how many candidate pixels remain */
+    int candidate_count;	/*Number of remaining candidate pixels */
 
-    /* RASTER_MAP_TYPE data_type;       Removed: input is always DCELL, output is CELL. 
-     *  TODO: if input might be smaller then DCELL, we could detect size and allocate accordingly. */
-    /*
-     * Todo: Memory managment:
-     * If we want to implement the option to load directly to memory
-     * instead of declaring "SEGMENT" could we declare as void
-     * then assign either a SEGMENT or a matrix during the get_input procedure?
-     */
-
-    /* TODO: some parts of the data structure from i.smap
-     * confirm if there is any reason to be using them here
-     * struct Categories output_labels;
-     * char *isdata;
-     */
-
-    /* Todo: Additional data to be stored in this structure:
-     * seeds (Put directly into output map?)
-     */
-
 };
 
 struct functions
 {
     int method;			/* Segmentation method */
-    int num_pn;			/* number of pixel neighbors  int, 4 or 8. TODO: can remove if pixel neighbors is list instead of array.  But maybe this one is small enough that is faster as array? */
+    int num_pn;			/* number of pixel neighbors  int, 4 or 8. */
     float threshold;		/* similarity threshold */
-	int min_segment_size;		/* smallest number of pixels/cells allowed in a final segment */
-	
+    int min_segment_size;	/* smallest number of pixels/cells allowed in a final segment */
+
     /* Some function pointers to set one time in parse_args() */
     int (*find_pixel_neighbors) (int, int, int[8][2], struct files *);	/*parameters: row, col, pixel_neighbors */
     double (*calculate_similarity) (struct pixels *, struct pixels *, struct files *, struct functions *);	/*parameters: two points (row,col) to compare */
 
-    /* for debug */
+    /* max number of iterations/passes */
     int end_t;
+    
+    /* todo remove when decide on pathflag*/
+    int path;
 };
 
 
@@ -126,6 +113,7 @@
 int my_dispose_list(struct link_head *, struct pixels **);
 int compare_ids(const void *, const void *);
 int compare_pixels(const void *, const void *);
+int set_all_candidate_flags(struct files *);
 
 /* write_output.c */
 int write_output(struct files *);

Modified: grass-addons/grass7/imagery/i.segment/open_files.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/open_files.c	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/open_files.c	2012-07-20 05:36:54 UTC (rev 52419)
@@ -10,24 +10,40 @@
 int open_files(struct files *files)
 {
     struct Ref Ref;		/* group reference list */
-    int *in_fd, bounds_fd, null_check;
-    int i, n, s, row, col, srows, scols, inlen, outlen, nseg;
+    int *in_fd, bounds_fd, null_check, out_fd, mean_fd;
+    int i, n, s, row, col, srows, scols, inlen, nseg;
     DCELL **inbuf;		/* buffer array, to store lines from each of the imagery group rasters */
     CELL *boundsbuf;
     struct FPRange *fp_range;	/* for getting min/max values on each input raster */
     DCELL *min, *max;
 
+    /* confirm output maps can be opened (don't want to do all this work for nothing!) */
+    out_fd = Rast_open_new(files->out_name, CELL_TYPE);
+    if (out_fd < 0)
+	G_fatal_error(_("Could not open output raster for writing segment ID's"));
+    else
+	Rast_unopen(out_fd);
+
+    if (files->out_band != NULL) {
+	mean_fd = Rast_open_new(files->out_band, DCELL_TYPE);
+	if (mean_fd < 0)
+	    G_fatal_error(_("Could not open output raster for writing mean segment values"));
+	else
+	    Rast_unopen(mean_fd);
+    }
+
     /*allocate memory for flags */
     files->null_flag = flag_create(files->nrows, files->ncols);
     files->candidate_flag = flag_create(files->nrows, files->ncols);
-//    files->no_check = flag_create(files->nrows, files->ncols);
+    if (files->bounds_map != NULL)
+	files->in_bounds_flag = flag_create(files->nrows, files->ncols);
 
-    G_debug(1, "Checking image group...");
-    /* references: i.cost r.watershed/seg and http://grass.osgeo.org/programming7/segmentlib.html */
+    /* references for segmentation library: i.cost r.watershed/seg and http://grass.osgeo.org/programming7/segmentlib.html */
 
     /* ****** open the input rasters ******* */
 
-    /* TODO: I confirmed, the API does not check this.  Should this be checked in parse_args / validation ?  Or best to do here where I want to use the REF data? */
+    /* TODO: I confirmed, the API does not check this.  Markus, should this be checked in parse_args / validation ?  Or best to do here where I want to use the REF data? */
+    G_debug(1, "Checking image group...");
     if (!I_get_group_ref(files->image_group, &Ref))
 	G_fatal_error(_("Unable to read REF file for group <%s>"),
 		      files->image_group);
@@ -40,7 +56,7 @@
 
     in_fd = G_malloc(Ref.nfiles * sizeof(int));
     inbuf = (DCELL **) G_malloc(Ref.nfiles * sizeof(DCELL *));
-    fp_range = G_malloc(Ref.nfiles * sizeof(struct FPRange));	/* TODO, is this correct memory allocation for these three? */
+    fp_range = G_malloc(Ref.nfiles * sizeof(struct FPRange));
     min = G_malloc(Ref.nfiles * sizeof(DCELL));
     max = G_malloc(Ref.nfiles * sizeof(DCELL));
 
@@ -48,6 +64,9 @@
     for (n = 0; n < Ref.nfiles; n++) {
 	inbuf[n] = Rast_allocate_d_buf();
 	in_fd[n] = Rast_open_old(Ref.file[n].name, Ref.file[n].mapset);
+	if (in_fd[n] < 0)
+	    G_fatal_error("Error opening %s@%s", Ref.file[n].name,
+			  Ref.file[n].mapset);
     }
 
     /* Get min/max values of each input raster for scaling */
@@ -71,14 +90,12 @@
     /* size of each element to be stored */
 
     inlen = sizeof(double) * Ref.nfiles;
-    outlen = sizeof(int) * 2;	/* change in write_output.c if this value changes TODO: better to save this in the files data structure? */
 
-    /*TODO: i.cost and i.watershed take different approaches...hardcode for now */
     /* when fine tuning, should be a power of 2 and not larger than 256 for speed reasons */
     srows = 64;
     scols = 64;
 
-    /* TODO: make calculations for this */
+    /* TODO: make calculations for this, check i.cost and i.watershed */
     nseg = 10000;
 
 
@@ -89,28 +106,31 @@
     G_debug(1, "Image size:  %d rows, %d cols", files->nrows, files->ncols);
     G_debug(1, "Segmented to tiles with size:  %d rows, %d cols", srows,
 	    scols);
-    G_debug(1, "Data element size, in: %d , out: %d ", inlen, outlen);
+    G_debug(1, "Data element size, in: %d", inlen);
     G_debug(1, "number of segments to have in memory: %d", nseg);
 
-    /* size: reading all input bands as DCELL  TODO: could consider checking input to see if it is all FCELL or CELL, could reduce memory requirements. */
-
     if (segment_open
 	(&files->bands_seg, G_tempfile(), files->nrows, files->ncols, srows,
 	 scols, inlen, nseg) != TRUE)
 	G_fatal_error("Unable to create input temporary files");
 
-    /* TODO: signed integer gives a 2 billion segment limit, depending on how the initialization is done, this means 2 billion max input pixels. */
+    /* ******* remaining memory allocation ********* */
+
+    files->bands_val = (double *)G_malloc(inlen);
+    files->second_val = (double *)G_malloc(inlen);
+
     files->iseg = G_malloc(files->nrows * sizeof(int *));
     for (i = 0; i < files->nrows; i++)
 	files->iseg[i] = G_malloc(files->ncols * sizeof(int));
 
-    /* TODO, need error check for running out of memory, or does G_malloc included a G_fatal_error call? */
+    /*check the last one to make sure there was enough memory */
+    if (files->iseg[i - 1] != NULL) {	/* everything is OK, and assume all previous memory allocations are OK too. */
+    }
+    else
+	G_fatal_error(_("Unable to allocate memory for initial segment ID's"));
 
-    /* load input bands to segment structure and fill iseg array */
+    /* ********  load input bands to segment structure and fill iseg array ******** */
     G_debug(1, "Reading input rasters into segmentation data files...");
-
-    files->bands_val = (double *)G_malloc(inlen);
-    files->second_val = (double *)G_malloc(inlen);
     s = 1;			/* initial segment ID */
 
     for (row = 0; row < files->nrows; row++) {
@@ -152,7 +172,7 @@
 	    G_fatal_error("Unable to create bounds temporary files");
 
 	boundsbuf = Rast_allocate_c_buf();
-	bounds_fd = Rast_open_old(files->bounds_map, files->bounds_mapset);	/*OK to use directly, or need to convert to name and mapset? */
+	bounds_fd = Rast_open_old(files->bounds_map, files->bounds_mapset);
 
 	for (row = 0; row < files->nrows; row++) {
 	    Rast_get_c_row(bounds_fd, boundsbuf, row);
@@ -172,7 +192,7 @@
     files->candidate_count = 0;	/* counter for remaining candidate pixels */
 
     /* linked list memory management linkm */
-    link_set_chunk_size(20);	/* TODO: fine tune this number */
+    link_set_chunk_size(100);	/* TODO polish: fine tune this number */
 
     files->token = link_init(sizeof(struct pixels));
 
@@ -188,7 +208,6 @@
     G_free(fp_range);
     G_free(min);
     G_free(max);
-    /* Need to clean up anything else? */
 
     return TRUE;
 }

Modified: grass-addons/grass7/imagery/i.segment/parse_args.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/parse_args.c	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/parse_args.c	2012-07-20 05:36:54 UTC (rev 52419)
@@ -12,42 +12,43 @@
 {
     /* reference: http://grass.osgeo.org/programming7/gislib.html#Command_Line_Parsing */
 
-    struct Option *group, *seeds, *bounds, *output, *method, *threshold, *min_segment_size;	/* Establish an Option pointer for each option */
-    struct Flag *diagonal, *weighted;	/* Establish a Flag pointer for each option */
-    struct Option *outband, *endt;	/* debugging parameters... TODO: leave in code or remove?  hidden options? */
+    struct Option *group, *seeds, *bounds, *output, *method, *threshold, *min_segment_size, *endt;	/* Establish an Option pointer for each option */
+    struct Flag *diagonal, *weighted, *path;	/* Establish a Flag pointer for each option */
+    struct Option *outband;	/* TODO scrub: put all outband code inside of #ifdef DEBUG */
 
     /* required parameters */
-    group = G_define_standard_option(G_OPT_I_GROUP);	/* TODO: OK to require the user to create a group?  Otherwise later add an either/or option to give just a single raster map... */
+    group = G_define_standard_option(G_OPT_I_GROUP);	/* TODO? Polish, consider giving the option to process just one raster directly, without creating an image group. */
 
     output = G_define_standard_option(G_OPT_R_OUTPUT);
 
-/*TODO polish: any way to recommend a threshold to the user */
+    /*TODO polish: any way to recommend a threshold to the user */
     threshold = G_define_option();
     threshold->key = "threshold";
     threshold->type = TYPE_DOUBLE;
     threshold->required = YES;
-    threshold->description = _("Similarity threshold.");
+    threshold->description = _("Similarity threshold.");	/* TODO? Polish, should all descriptions get the _() locale macro? */
 
     method = G_define_option();
     method->key = "method";
     method->type = TYPE_STRING;
     method->required = YES;
     method->answer = "region_growing";
-    #ifdef DEBUG
+#ifdef DEBUG
     method->options = "region_growing, io_debug, ll_test, seg_time";
-    #else
+#else
     method->options = "region_growing";
-    #endif
+#endif
     method->description = _("Segmentation method.");
 
-	min_segment_size = G_define_option();
-	min_segment_size->key = "min"; /*TODO is there a preference for long or short key names? min is pretty generic...but short... */
-	min_segment_size->type = TYPE_INTEGER;
-	min_segment_size->required = YES;
-	min_segment_size->answer = "1"; /* default: no merges */
-	min_segment_size->options = "1-100000";
-	min_segment_size->description = _("Minimum number of pixels (cells) in a segment.  The final merge step will ignore the threshold for any segments with fewer pixels.");
-    
+    min_segment_size = G_define_option();
+    min_segment_size->key = "min";	/*TODO Markus, is there a preference for long or short key names? min is pretty generic...but short... */
+    min_segment_size->type = TYPE_INTEGER;
+    min_segment_size->required = YES;
+    min_segment_size->answer = "1";	/* default: no merges, a minimum of 1 pixel is allowed in a segment. */
+    min_segment_size->options = "1-100000";
+    min_segment_size->description =
+	_("Minimum number of pixels (cells) in a segment.  The final merge step will ignore the threshold for any segments with fewer pixels.");
+
     /* optional parameters */
 
     diagonal = G_define_flag();
@@ -60,7 +61,7 @@
     weighted->description =
 	_("Weighted input, don't perform the default scaling of input maps.");
 
-    /* Using raster for seeds, Low priority TODO: allow vector points/centroids seed input. */
+    /* Raster for initial segment seeds *//* TODO polish: allow vector points/centroids for seed input. */
     seeds = G_define_standard_option(G_OPT_R_INPUT);
     seeds->key = "seeds";
     seeds->required = NO;
@@ -80,9 +81,15 @@
     endt->key = "endt";
     endt->type = TYPE_INTEGER;
     endt->required = NO;
-    endt->answer = "10000";
-    endt->description = _("Debugging...Maximum number of time steps to complete.");
+    endt->answer = "1000";
+    endt->description =
+	_("Debugging...Maximum number of time steps to complete.");
 
+    path = G_define_flag();
+    path->key = 'p';
+    path->description =
+	_("temporary option, pathflag, select to use Rk as next Ri if not mutually best neighbors.");
+
     outband = G_define_standard_option(G_OPT_R_OUTPUT);
     outband->key = "final_mean";
     outband->required = NO;
@@ -94,19 +101,14 @@
 
     /* Validation */
 
-    /* TODO: use checker for any of the data validation steps!? */
+    /* TODO: use checker for any of the data validation steps? */
 
-    /* ToDo The most important things to check are if the
-       input and output raster maps can be opened (non-negative file
-       descriptor).  ??? Do this here or in open_files?  */
-
-
     /* Check and save parameters */
 
     files->image_group = group->answer;
 
     if (G_legal_filename(output->answer) == TRUE)
-	files->out_name = output->answer;	/* name of output raster map */
+	files->out_name = output->answer;	/* name of output (segment ID) raster map */
     else
 	G_fatal_error("Invalid output raster name.");
 
@@ -116,22 +118,23 @@
 	(functions->threshold <= 0 || functions->threshold >= 1))
 	G_fatal_error(_("threshold should be >= 0 and <= 1"));
 
-    /* segmentation methods:  0 = debug, 1 = region growing */
-    /* TODO, instead of string compare, does the Option structure have these already numbered? */
-    if (strncmp(method->answer, "io_debug", 5) == 0)
+    /* segmentation methods: 1 = region growing */
+    if (strncmp(method->answer, "region_growing", 10) == 0)
+	functions->method = 1;
+#ifdef DEBUG
+    else if (strncmp(method->answer, "io_debug", 5) == 0)
 	functions->method = 0;
-    else if (strncmp(method->answer, "region_growing", 10) == 0)
-	functions->method = 1;
     else if (strncmp(method->answer, "ll_test", 5) == 0)
 	functions->method = 2;
-	else if (strncmp(method->answer, "seg_time", 5) == 0)
+    else if (strncmp(method->answer, "seg_time", 5) == 0)
 	functions->method = 3;
+#endif
     else
 	G_fatal_error("Couldn't assign segmentation method.");	/*shouldn't be able to get here */
 
     G_debug(1, "segmentation method: %d", functions->method);
 
-	functions->min_segment_size = atoi(min_segment_size->answer);
+    functions->min_segment_size = atoi(min_segment_size->answer);
 
     if (diagonal->answer == FALSE) {
 	functions->find_pixel_neighbors = &find_four_pixel_neighbors;
@@ -143,6 +146,7 @@
 	functions->num_pn = 8;
 	G_debug(1, "eight (3x3) pixel neighborhood");
     }
+    /* TODO polish, check if function pointer or IF statement is faster */
 
     files->weighted = weighted->answer;	/* default/0 for performing the scaling, but selected/1 if user has weighted values so scaling should be skipped. */
 
@@ -155,7 +159,8 @@
     }
     else {			/* polygon constraints given */
 	files->bounds_map = bounds->answer;
-	if ((files->bounds_mapset = G_find_raster(files->bounds_map, "")) == NULL) {	/* TODO, compiler warning here:  parse_args.c:149:27: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default] */
+	if ((files->bounds_mapset =
+	     G_find_raster2(files->bounds_map, "")) == NULL) {
 	    G_fatal_error(_("Segmentation constraint/boundary map not found."));
 	}
 	if (Rast_map_type(files->bounds_map, files->bounds_mapset) !=
@@ -168,7 +173,17 @@
     files->nrows = Rast_window_rows();
     files->ncols = Rast_window_cols();
 
+    if (endt->answer != NULL && atoi(endt->answer) >= 0)
+	functions->end_t = atoi(endt->answer);
+    else {
+	functions->end_t = 1000;
+	G_warning(_("invalid number of iterations, 1000 will be used."));
+    }
+
     /* debug help */
+
+	functions->path = path->answer;	/* default/0 for no pathflag, but selected/1 to use Rk as next Ri if not mutually best neighbors. */
+    
     if (outband->answer == NULL)
 	files->out_band = NULL;
     else {
@@ -178,11 +193,5 @@
 	    G_fatal_error("Invalid output raster name for means.");
     }
 
-	if (endt->answer != NULL && endt->answer >= 0)
-    functions->end_t = atoi(endt->answer);
-	else {
-		functions->end_t = 10000;
-		G_warning(_("invalid number of iterations, 10000 will be used."));
-	}
     return TRUE;
 }

Modified: grass-addons/grass7/imagery/i.segment/write_output.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/write_output.c	2012-07-19 23:17:08 UTC (rev 52418)
+++ grass-addons/grass7/imagery/i.segment/write_output.c	2012-07-20 05:36:54 UTC (rev 52419)
@@ -1,5 +1,5 @@
-/* transfer the segmented regions from the segmented data file to a raster file */
-/* close_files() function is at bottom */
+/* write_output(): transfer the segmented regions from the segmented data file to a raster file */
+/* close_files(): close SEG files and free memory */
 
 #include <stdlib.h>
 #include <grass/gis.h>
@@ -7,41 +7,38 @@
 #include <grass/segment.h>	/* segmentation library */
 #include "iseg.h"
 
-/* TODO some time delay here with meanbuf, etc being processed.  I only put if statements on the actual files
+/* TODO polish: some time delay here with meanbuf, etc being processed.  I only put if statements on the actual files
  * to try and keep the code more clear.  Need to see if this raster makes stats processing easier?  Or IFDEF it out?
+ * If it is left in, need to refine it to save a raster for each band in the input group.
  */
 
 int write_output(struct files *files)
 {
-    int out_fd, mean_fd, row, col;	/* mean_fd for validiating/debug of means, todo, could add array... */
+    int out_fd, mean_fd, row, col;	/* mean_fd for validiating/debug of means */
     CELL *outbuf;
     DCELL *meanbuf;
-	struct Colors colors;
-	
-    outbuf = Rast_allocate_c_buf();	/*hold one row of data to put into raster */
+    struct Colors colors;
+
+    outbuf = Rast_allocate_c_buf();	/* hold one row of data to put into raster */
     meanbuf = Rast_allocate_d_buf();
 
-    /* Todo: return codes are 1 for these, need to check and react to errors? programmer's manual didn't include it... */
-
     /* force all data to disk */
-    segment_flush(&files->bands_seg);	/* TODO use IFDEF or just delete for all these parts? for debug/validation output */
+    segment_flush(&files->bands_seg);
 
-    G_debug(1, "preparing output raster");
     /* open output raster map */
+    G_debug(1, "preparing output raster");
     out_fd = Rast_open_new(files->out_name, CELL_TYPE);
     if (files->out_band != NULL)
 	mean_fd = Rast_open_new(files->out_band, DCELL_TYPE);
 
-    G_debug(1, "start data transfer from segmentation file to raster");
     /* transfer data from segmentation file to raster */
-
     for (row = 0; row < files->nrows; row++) {
 	Rast_set_c_null_value(outbuf, files->ncols);	/*set buffer to NULLs, only write those that weren't originally masked */
 	Rast_set_d_null_value(meanbuf, files->ncols);
 	for (col = 0; col < files->ncols; col++) {
 	    segment_get(&files->bands_seg, (void *)files->bands_val, row,
 			col);
-	    if (!(flag_get(files->null_flag, row, col))) {
+	    if (!(FLAG_GET(files->null_flag, row, col))) {
 		outbuf[col] = files->iseg[row][col];
 		meanbuf[col] = files->bands_val[0];
 	    }
@@ -53,28 +50,27 @@
 	G_percent(row, files->nrows, 1);
     }
 
-    /* TODO: I don't understand the header/history/etc for raster storage.  Can/should we save any information about the segmentation
-     * settings used to create the raster?  What the input image group was?  Anything else the statistics module would need?
-     * check it with r.info to see what we have by default.
+    /* TODO polish: update the data found by r.info
+     * current:         |   Data Description:                                                        |
+     *                          |    generated by i.segment                                                  |
+     * It would be nice to save the segmentation settings (just the CL?  Or something more human readable?)
      */
 
-    /* TODO after we have a count of create segments... if(total segments == 0) G_warning(_("No segments were created. Verify threshold and region settings.")); */
-
     /* close and save file */
     Rast_close(out_fd);
     if (files->out_band != NULL)
 	Rast_close(mean_fd);
 
-	/* set colors */
-	Rast_init_colors(&colors);
-	Rast_make_random_colors(&colors, 1, files->nrows*files->ncols); /* TODO polish - number segments from 1 - max ? and then can use that max here. */
-	Rast_write_colors(files->out_name, G_mapset(), &colors); /* TODO, OK to just use G_mapset() here, seems I don't use it anywhere else, and that is where the output has to be written.  (Should the library allow changing colors to other mapsets???) */
-	
+    /* set colors */
+    Rast_init_colors(&colors);
+    Rast_make_random_colors(&colors, 1, files->nrows * files->ncols);	/* TODO polish - number segments from 1 - max ? and then can use that max here. */
+    Rast_write_colors(files->out_name, G_mapset(), &colors);	/* TODO, OK to just use G_mapset() here, seems I don't use it anywhere else, and that is where the output has to be written.  (Markus, should the library allow changing colors to other mapsets? I was suprised it was needed as a parameter.) */
+
     /* free memory */
     G_free(outbuf);
     G_free(meanbuf);
-	Rast_free_colors(&colors);
-	
+    Rast_free_colors(&colors);
+
     return TRUE;
 }
 
@@ -86,9 +82,9 @@
     G_debug(1, "closing bands_seg...");
     segment_close(&files->bands_seg);
     G_debug(1, "closing bounds_seg...");
-    if (files->bounds_map != NULL) 
-        segment_close(&files->bounds_seg);
-    
+    if (files->bounds_map != NULL)
+	segment_close(&files->bounds_seg);
+
     G_debug(1, "freeing _val");
     G_free(files->bands_val);
     G_free(files->second_val);
@@ -101,13 +97,10 @@
     G_debug(1, "destroying flags");
     flag_destroy(files->null_flag);
     flag_destroy(files->candidate_flag);
-//    flag_destroy(files->no_check);
 
     G_debug(1, "close_files() before link_cleanup()");
     link_cleanup(files->token);
     G_debug(1, "close_files() after link_cleanup()");
 
-    /* anything else left to clean up? */
-
     return TRUE;
 }



More information about the grass-commit mailing list