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

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Jun 28 23:54:51 PDT 2012


Author: momsen
Date: 2012-06-28 23:54:51 -0700 (Thu, 28 Jun 2012)
New Revision: 52253

Modified:
   grass-addons/grass7/imagery/i.segment/create_isegs.c
   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/times.txt
   grass-addons/grass7/imagery/i.segment/write_output.c
Log:
moved flags and segment ID's into RAM (out of segmentation file)  input bands are still in segmentation file.  Significant speed improvement.

Modified: grass-addons/grass7/imagery/i.segment/create_isegs.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/create_isegs.c	2012-06-28 22:43:02 UTC (rev 52252)
+++ grass-addons/grass7/imagery/i.segment/create_isegs.c	2012-06-29 06:54:51 UTC (rev 52253)
@@ -4,7 +4,7 @@
 
 #include <stdlib.h>
 #include <float.h>		/* to get value of LDBL_MAX -> change this if there is a more usual grass way */
-										    /* #include <math.h>    *//* for sqrt() and pow() */
+																				  /* #include <math.h>    *//* for sqrt() and pow() */
 #include <grass/gis.h>
 #include <grass/glocale.h>
 #include <grass/raster.h>
@@ -13,7 +13,7 @@
 #include "iseg.h"
 
 #define LINKM
-#define REVERSE
+/* #define REVERSE */
 
 int create_isegs(struct files *files, struct functions *functions)
 {
@@ -80,9 +80,7 @@
 	    /* files->out_val[0] = col + row; */
 	    segment_get(&files->bands_seg, (void *)files->bands_val, row,
 			col);
-	    files->out_val[0] = files->bands_val[0] * 100;	/*pushing DCELL into CELL */
-	    files->out_val[1] = 1;	/*processing flag */
-	    segment_put(&files->out_seg, (void *)files->out_val, row, col);
+	    files->iseg[row][col] = files->bands_val[0] * 100;	/*pushing DCELL into CELL */
 	}
 	G_percent(row, files->nrows, 1);
     }
@@ -232,9 +230,7 @@
     for (row = 0; row < files->nrows; row++) {
 	for (col = 0; col < files->ncols; col++) {
 	    /*files->out_val[0] = files->out_val[0]; *//*segment number *//* just copying the map for testing. */
-	    files->out_val[0] = col + row;
-	    files->out_val[1] = TRUE;	/*processing flag */
-	    segment_put(&files->out_seg, (void *)files->out_val, row, col);
+	    files->iseg[row][col] = col + row;
 	}
 	G_percent(row, files->nrows, 1);
     }
@@ -300,7 +296,8 @@
      * 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. */
+     * 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. */
 
     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() */
@@ -333,36 +330,34 @@
 	if (files->bounds_map == NULL) {	/*normal processing */
 	    for (row = 0; row < files->nrows; row++) {
 		for (col = 0; col < files->ncols; col++) {
-		    segment_get(&files->out_seg, (void *)files->out_val, row, col);	/*need to get, since we only want to change the flag, and not overwrite the segment value. 
-											   TODO: consider splitting this, put flag in one segmentmentation file (or RAM), and segment assignment in another. */
 		    /* 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 */
-		    files->out_val[1] = TRUE;	/*candidate pixel flag */
-		    segment_put(&files->out_seg, (void *)files->out_val, row,
-				col);
+		    if (!(FLAG_GET(files->null_flag, row, col))) {
+			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 */
+			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++) {
-		    segment_get(&files->bounds_seg, &files->bounds_val, row,
-				col);
-		    segment_get(&files->out_seg, (void *)files->out_val, row,
-				col);
+		    if (!(FLAG_GET(files->null_flag, 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.) */
-			files->out_val[1] = TRUE;	/*candidate pixel flag */
-		    else
-			files->out_val[1] = FALSE;
+			segment_get(&files->bounds_seg, &files->bounds_val,
+				    row, col);
 
-		    segment_put(&files->out_seg, (void *)files->out_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);
 
-		    files->candidate_count++;	/*TODO this assumes full grid with no null or mask!! But need something to prevent "pathflag" infinite loop */
+		    }
 		}
 	    }
 	}
@@ -377,8 +372,8 @@
 	/* reverse order 
 	 */
 #ifdef REVERSE
-	for (row = files->nrows; row >= 0; row--) {
-	    for (col = files->ncols; col >= 0; col--) {
+	for (row = files->nrows - 1; row >= 0; row--) {
+	    for (col = files->ncols - 1; col >= 0; col--) {
 #else
 	for (row = 0; row < files->nrows; row++) {
 	    for (col = 0; col < files->ncols; col++) {
@@ -387,16 +382,13 @@
 		G_debug(4,
 			"Next starting pixel from next row/col, not from Rk");
 
-		segment_get(&files->out_seg, (void *)files->out_val, row, col);	/*TODO small time savings - if candidate_count reaches zero, bail out of these loops too? */
-		if (files->out_val[1] == TRUE && files->out_val != NULL) {	/* out_val[1] is the candidate pixel flag, want to process the 1's *//*TODO MASK handling - checking if we have a segment ID already, in open_files() we will put nulls in [0] slot... better/faster way to do this? */
-		    G_debug(4, "going to free memory on linked lists...");
+		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? */
 		    Rk_count = 0;
-		    G_debug(4, "finished free memory on linked lists...");
 
 		    /* First pixel in Ri is current row/col pixel.  We may add more later if it is part of a segment */
 		    Ri_count = 1;
@@ -413,7 +405,7 @@
 		    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.
+		    /* 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, 0, files);	/* TODO: error trap? */
 		    G_debug(4, "line 165, \t\t\t\tcc = %d",
@@ -436,7 +428,7 @@
 			(&Ri_head, &Rin_head, &Ri_count, files,
 			 functions) != TRUE) {
 			G_fatal_error("find_segment_neighbors() failed");
-		    }		/* TODO - shouldn't be just fatal error - need to still close_files().  Just put that here then fatal error? */
+		    }
 
 		    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 */
@@ -495,10 +487,13 @@
 				    Ri_similarity, Ri_bestn->row,
 				    Ri_bestn->col);
 
-			    segment_get(&files->out_seg,
-					(void *)files->out_val, Ri_bestn->row,
-					Ri_bestn->col);
-			    if (files->out_val[1] == FALSE)
+			    //~ 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_similarity = threshold + 1;
@@ -599,351 +594,363 @@
 	    /* 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
+	}
+    }
+    /* to balance brackets in first ifdef statement */
+#endif
 
-	/* finished one pass for processing candidate pixels */
+    }				/*next row */
 
-	G_debug(4, "Finished one pass, t was = %d", t);
-	t++;
-    } while (t <= functions->end_t && endflag == FALSE);
+    /* finished one pass for processing candidate pixels */
+
+    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? */
 
     /* free memory *//*TODO: anything ? */
 
 
     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, m, Ri_seg_ID = -1;
-    struct pixels *newpixel, *current, *to_check;	/* need to check the pixel neighbors of to_check */
-    int val_no_check = -1;	/*value of the no_check flag for the particular pixel. */
-    int pixel_neighbors[8][2];	/* TODO: data type?  put in files to allocate memory once? */
+    int find_segment_neighbors(struct pixels **R_head,
+			       struct pixels **neighbors_head, int *seg_count,
+			       struct files *files,
+			       struct functions *functions)
+    {
+	int n, Ri_seg_ID = -1;
+	struct pixels *newpixel, *current, *to_check;	/* need to check the pixel neighbors of to_check */
+	int pixel_neighbors[8][2];	/* TODO: data type?  put in files to allocate memory once? */
 
+	/* files->no_check is a FLAG structure, only used here but allocating memory 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...
-     */
+	/* 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...
+	 */
 
-    /* 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 ?
-     * files->out_seg is currently an array [0] for seg ID and [1] for "candidate pixel"
-     * files->no_check is a segmentation data structure, if the pixel should no longer be checked on this current find_neighbors() run
-     * functions->num_pn  int, 4 or 8, for number of pixel neighbors 
-     * */
+	/* 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 ?
+	 * files->out_seg is currently an array [0] for seg ID and [1] for "candidate pixel"
+	 * files->no_check is a segmentation data structure, if the pixel should no longer be checked on this current find_neighbors() run
+	 * functions->num_pn  int, 4 or 8, for number of pixel neighbors 
+	 * */
 
-    /* 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); */
+	/* 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); */
 
-    /*initialize data.... TODO: maybe remember min max row/col that was looked at each time, initialize in open_files, and reset smaller region at end of this functions */
-    for (n = 0; n < files->nrows; n++) {
-	for (m = 0; m < files->ncols; m++) {
-	    val_no_check = FALSE;
-	    segment_put(&files->no_check, &val_no_check, n, m);
-	}
-    }
+	/*initialize data.... TODO: maybe remember min max row/col that was looked at each time, initialize in open_files, and reset smaller region at end of this functions */
+	/*todo, dlete this loop for (n = 0; n < files->nrows; n++) {
+	   for (m = 0; m < files->ncols; m++) {
+	   val_no_check = FALSE;
+	   segment_put(&files->no_check, &val_no_check, n, m);
+	   }
+	   } */
+	flag_clear_all(files->no_check);
 
-    to_check = NULL;
+	to_check = NULL;
 
-    /* Copy R in to_check and no_check data structures (don't expand them if we find them again) */
-    /* NOTE: in pseudo code also have a "current segment" list, but think we can just pass Ri and use it directly */
+	/* Copy R in to_check and no_check data structures (don't expand them if we find them again) */
+	/* NOTE: in pseudo code also have a "current segment" list, but think we can just pass Ri and use it directly */
 
-    for (current = *R_head; current != NULL; current = current->next) {
+	for (current = *R_head; current != NULL; current = current->next) {
 
-	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. */
+	    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. */
 
-	val_no_check = 1;
-	segment_put(&files->no_check, &val_no_check, current->row,
-		    current->col);
-    }
+	    flag_set(files->no_check, current->row, current->col);
+	}
 
-    /* empty "neighbor" list  Note: this step is in pseudo code, but think we just pass in Rin - it was already initialized, and later could have Ri data available to start from */
+	/* empty "neighbor" list  Note: this step is in pseudo code, but think we just pass in Rin - it was already initialized, and later could have Ri data available to start from */
 
-    /* get Ri's segment ID */
-    segment_get(&files->out_seg, (void *)files->out_val, (*R_head)->row,
-		(*R_head)->col);
-    Ri_seg_ID = files->out_val[0];
+	/* get Ri's segment ID */
+	Ri_seg_ID = files->iseg[(*R_head)->row][(*R_head)->col];	/* old data structure needed, this... keep for readability? */
 
-    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);
+	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);
+	    functions->find_pixel_neighbors(to_check->row,
+					    to_check->col,
+					    pixel_neighbors, files);
 
-	/* Done using this to_check pixels coords, remove from list */
+	    /* 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);
+	    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 */
-	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);
+	    /*print out to_check */
+	    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);
 
-	/*now check the pixel neighbors and add to the lists */
+	    /*now check the pixel neighbors and add to the lists */
 
-	/*debug what 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]);
-	   } */
+	    /*debug what 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]);
+	       } */
 
-	for (n = 0; n < functions->num_pn; n++) {	/* with pixel neighbors */
+	    for (n = 0; n < functions->num_pn; n++) {	/* with pixel neighbors */
 
-	    segment_get(&files->no_check, &val_no_check,
-			pixel_neighbors[n][0], pixel_neighbors[n][1]);
-	    G_debug(5,
-		    "\twith pixel neigh %d, row: %d col: %d, val_no_check = %d",
-		    n, pixel_neighbors[n][0], pixel_neighbors[n][1],
-		    val_no_check);
-	    if (val_no_check == FALSE) {	/* want to check this neighbor */
-		val_no_check = 1;
-		segment_put(&files->no_check, &val_no_check, pixel_neighbors[n][0], pixel_neighbors[n][1]);	/* don't check it again */
+		G_debug(5,
+			"\twith pixel neigh %d, row: %d col: %d, val_no_check = %d",
+			n, pixel_neighbors[n][0], pixel_neighbors[n][1],
+			flag_get(files->no_check, pixel_neighbors[n][0],
+				 pixel_neighbors[n][1]));
+		if (flag_get(files->no_check, pixel_neighbors[n][0], pixel_neighbors[n][1]) == FALSE) {	/* want to check this neighbor */
+		    flag_set(files->no_check, pixel_neighbors[n][0], pixel_neighbors[n][1]);	/* don't check it again */
 
-		segment_get(&files->out_seg, (void *)files->out_val, pixel_neighbors[n][0], pixel_neighbors[n][1]);	/*TODO : do I need a second "out_val" data structure? */
+		    if (!(FLAG_GET(files->null_flag, pixel_neighbors[n][0], pixel_neighbors[n][1]))) {	/* all pixels, not just valid pixels */
 
-		if (files->out_val[1] == TRUE || files->out_val[1] == FALSE) {	/* all pixels, not just valid pixels */
-		    /* TODO: use -1 for NULL/MASKED pixels? */
+			G_debug(5, "\tfiles->iseg[][] = %d Ri_seg_ID = %d",
+				files->
+				iseg[pixel_neighbors[n][0]][pixel_neighbors[n]
+							    [1]], Ri_seg_ID);
+			if (files->
+			    iseg[pixel_neighbors[n][0]][pixel_neighbors[n][1]]
+			    == Ri_seg_ID) {
+			    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);
 
-		    G_debug(5, "\tfiles->out_val[0] = %d Ri_seg_ID = %d",
-			    files->out_val[0], Ri_seg_ID);
-		    if (files->out_val[0] == Ri_seg_ID) {
-			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);
+			    /* 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. */
 
-			/* 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. */
+			}
+			else {	/* segment id's were different */
+			    /* 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. */
 
-		    }
-		    else {	/* segment id's were different */
-			/* 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. */
+			}
+		    }		/*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]);
 
-		    }
-		}		/*end if valid candidate pixel */
-		else
-		    G_debug(5,
-			    "pixel row: %d col: %d was not a valid candidate pixel",
-			    pixel_neighbors[n][0], pixel_neighbors[n][1]);
+		}		/*end if for pixel_neighbor was in "don't check" list */
+	    }			/* end for loop - next pixel neighbor */
+	    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");
+	}			/* while to_check has more elements */
 
-	    }			/*end if for pixel_neighbor was in "don't check" list */
-	}			/* end for loop - next pixel neighbor */
-	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");
-    }				/* while to_check has more elements */
+	return TRUE;
+    }
 
-    return TRUE;
-}
 
-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... */
 
-    /* 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? */
+    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... */
 
-    /* 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;
+	/* 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? */
 
-    /* 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;
+	/* 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;
 
-    /* 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;
+	/* 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;
 
-    /*TODO: seems there should be a more elegent way to do this... */
-    return TRUE;
-}
+	/* 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;
 
-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);
+	/*TODO: seems there should be a more elegent way to do this... */
+	return TRUE;
+    }
 
-    /* get the 4 diagonal neighbors */
-    G_warning("Diagonal neighbors Not Implemented");
-    /*TODO... continue as above */
-    return TRUE;
-}
+    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);
 
-/* 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;
-
-    /* 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]);
+	/* get the 4 diagonal neighbors */
+	G_warning("Diagonal neighbors Not Implemented");
+	/*TODO... continue as above */
+	return TRUE;
     }
 
-    /* val = sqrt(val); *//* use squared distance, save the calculation time */
+    /* 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;
 
-    return val;
+	/* 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]);
+	}
 
-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;
+	/* val = sqrt(val); *//* use squared distance, save the calculation time */
 
-    /*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);
+	return val;
 
-    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 process flag ==0 */
+    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;
 
-    segment_get(&files->out_seg, (void *)files->out_val, Ri_head->row,
-		Ri_head->col);
-    files->out_val[1] = FALSE;	/*candidate pixel flag, only one merge allowed per t iteration */
-    /* if separate out candidate flag, can do all changes with helper function...otherwise remember: */
+	/*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);
 
+	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);
+	}
 
-    G_debug(4, "\t\tMerging, segment number: %d, including pixels:",
-	    files->out_val[0]);
+	/* update segment number and candidate flag ==0 */
 
-    /* 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);
-	segment_put(&files->out_seg, (void *)files->out_val, current->row,
-		    current->col);
-	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);
-	segment_put(&files->out_seg, (void *)files->out_val, 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);
+	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);
+
+	}
+
+	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;
     }
 
-    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. */
+    /* 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;
 
-/* TODO.. helper function, maybe make more general? */
-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) {
-	segment_get(&files->out_seg, (void *)files->out_val, current->row, current->col);	/* this may change... */
-	files->out_val[1] = value;	/*candidate pixel flag */
-	segment_put(&files->out_seg, (void *)files->out_val, current->row,
-		    current->col);
 
-	/* also increment how many pixels remain to be processed */
+	    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 == 0)
-	    files->candidate_count--;
-	else if (value == 1)
-	    files->candidate_count++;
-	G_debug(4, "line 544, \t\t\t\tcc = %d", files->candidate_count);
-
+	    G_debug(4, "line 544, \t\t\t\tcc = %d", files->candidate_count);
+	}
+	return TRUE;
     }
-    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;
+    /* 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;
 
-    while ((*head) != NULL) {
-	current = *head;	/* rememer "old" head */
-	*head = (*head)->next;	/* move head to next pixel */
-	link_dispose(token, (VOID_T *) current);	/* remove "old" head */
+	while ((*head) != NULL) {
+	    current = *head;	/* rememer "old" head */
+	    *head = (*head)->next;	/* move head to next pixel */
+	    link_dispose(token, (VOID_T *) current);	/* remove "old" head */
+	}
+
+	return TRUE;
     }
-
-    return TRUE;
-}

Modified: grass-addons/grass7/imagery/i.segment/iseg.h
===================================================================
--- grass-addons/grass7/imagery/i.segment/iseg.h	2012-06-28 22:43:02 UTC (rev 52252)
+++ grass-addons/grass7/imagery/i.segment/iseg.h	2012-06-29 06:54:51 UTC (rev 52253)
@@ -14,6 +14,7 @@
 
 #include <grass/segment.h>
 #include <grass/linkm.h>
+#include "flag.h"
 
 /* pixel stack */
 struct pixels
@@ -38,15 +39,21 @@
     char *seeds, *bounds_map, *bounds_mapset;	/* optional segment seeds and polygon constraints/boundaries */
     char *out_band;		/* for debug */
 
-    /* file processing */
+    /* 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. */
     int nbands;			/* number of rasters in the image group */
-    SEGMENT bands_seg, out_seg, bounds_seg;	/* bands is for input, normal application is landsat bands, but other input can be included in the 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 *out_val, bounds_val, current_bound;	/* out_val is array, to hold the segment ID and processing flag(s) */
+    int bounds_val, current_bound;
 
-    SEGMENT no_check;		/* pixels that have already been checked during this neighbor finding routine */
+    /* 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 */
+
     /* memory management, linked lists */
     struct link_head *token;	/* for linkm linked list memory management. */
 

Modified: grass-addons/grass7/imagery/i.segment/open_files.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/open_files.c	2012-06-28 22:43:02 UTC (rev 52252)
+++ grass-addons/grass7/imagery/i.segment/open_files.c	2012-06-29 06:54:51 UTC (rev 52253)
@@ -11,12 +11,17 @@
 {
     struct Ref Ref;		/* group reference list */
     int *in_fd, bounds_fd, null_check;
-    int n, s, row, col, srows, scols, inlen, outlen, nseg;
+    int i, n, s, row, col, srows, scols, inlen, outlen, 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;
 
+    /*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);
+
     G_debug(1, "Checking image group...");
     /* references: i.cost r.watershed/seg and http://grass.osgeo.org/programming7/segmentlib.html */
 
@@ -94,23 +99,18 @@
 	 scols, inlen, nseg) != TRUE)
 	G_fatal_error("Unable to create input temporary files");
 
-    /* G_debug(1, "finished segment_open(...bands_seg...)"); */
-
     /* TODO: signed integer gives a 2 billion segment limit, depending on how the initialization is done, this means 2 billion max input pixels. */
-    if (segment_open
-	(&files->out_seg, G_tempfile(), files->nrows, files->ncols, srows,
-	 scols, outlen, nseg) != TRUE)
-	G_fatal_error("Unable to create output temporary files");
+    files->iseg = G_malloc(files->nrows * sizeof(int *));
+    for (i = 0; i < files->nrows; i++)
+	files->iseg[i] = G_malloc(files->ncols * sizeof(int));
 
-    if (segment_open(&files->no_check, G_tempfile(), files->nrows, files->ncols, srows, scols, sizeof(int), nseg) != TRUE)	/* todo could make this smaller ? just need 0 or 1 */
-	G_fatal_error("Unable to create flag temporary files");
+    /* TODO, need error check for running out of memory, or does G_malloc included a G_fatal_error call? */
 
-    /* load input bands to segment structure and initialize output segmentation file */
+    /* 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);
-    files->out_val = (int *)G_malloc(2 * sizeof(int));
     s = 1;			/* initial segment ID */
 
     for (row = 0; row < files->nrows; row++) {
@@ -118,10 +118,8 @@
 	    Rast_get_d_row(in_fd[n], inbuf[n], row);
 	}
 	for (col = 0; col < files->ncols; col++) {
-	    /*tempval = 0; Doesn't work, no "null" for doubles in c *//* want a number, not null */
 	    null_check = 1;	/*Assume there is data */
 	    for (n = 0; n < Ref.nfiles; n++) {
-		/*tempval += inbuf[n][col]; *//* if mask/null, adding a null value should set tempval to NULL */
 		if (Rast_is_d_null_value(&inbuf[n][col]))
 		    null_check = -1;
 		if (files->weighted == TRUE)
@@ -132,16 +130,14 @@
 	    segment_put(&files->bands_seg, (void *)files->bands_val, row, col);	/* store input bands */
 
 	    if (null_check != -1) {	/*good pixel */
-		files->out_val[0] = s;	/*starting segment number TODO: for seeds this will be different */
-		files->out_val[1] = TRUE;	/*flag */
+		files->iseg[row][col] = s;	/*starting segment number TODO: for seeds this will be different */
+		FLAG_UNSET(files->null_flag, row, col);	/*flag */
+		s++;		/* sequentially number all pixels with their own segment ID */
 	    }
 	    else {		/*don't use this pixel */
-
-		files->out_val[0] = -1;	/*starting segment number */
-		files->out_val[1] = -1;	/*flag */
+		files->iseg[row][col] = -1;	/* place holder...TODO this could be a conflict if constraints included a -1 */
+		FLAG_SET(files->null_flag, row, col);	/*flag */
 	    }
-	    segment_put(&files->out_seg, (void *)files->out_val, row, col);	/* initialize input */
-	    s++;		/* sequentially number all pixels with their own segment ID */
 	}
     }
 

Modified: grass-addons/grass7/imagery/i.segment/parse_args.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/parse_args.c	2012-06-28 22:43:02 UTC (rev 52252)
+++ grass-addons/grass7/imagery/i.segment/parse_args.c	2012-06-29 06:54:51 UTC (rev 52253)
@@ -103,7 +103,7 @@
 	G_fatal_error("Invalid output raster name.");
 
     functions->threshold = atof(threshold->answer);	/* Note: this threshold is scaled after we know more at the beginning of create_isegs() */
-    if (weighted->answer == TRUE &&
+    if (weighted->answer == FALSE &&
 	(functions->threshold <= 0 || functions->threshold >= 1))
 	G_fatal_error(_("threshold should be >= 0 and <= 1"));	/* TODO OK to have fatal error here, seems this would be an invalid entry. */
 

Modified: grass-addons/grass7/imagery/i.segment/times.txt
===================================================================
--- grass-addons/grass7/imagery/i.segment/times.txt	2012-06-28 22:43:02 UTC (rev 52252)
+++ grass-addons/grass7/imagery/i.segment/times.txt	2012-06-29 06:54:51 UTC (rev 52253)
@@ -1,5 +1,39 @@
+NC sample landsat images, lsat7_2000_10
+
+g.region rast=lsat7_2000_10 at landsat
+rows:       475
+cols:       527
+cells:      250325
+
+still running...
+
+
+g.region s=222000 e=637000
+cells:      56334
+< 5 minutes
+
+
+g.region s=220000 e=639000
+cells: 94783
+
+13 min (just one time test)
+
+
+
+
+typical i.segment options:
+time i.segment -w --overwrite group=landsat1 at user1 output=val threshold=5 method=region_growing endt=1000 final_mean=val_mean --verbose
+
+threshold of 3 ran faster, but visually seemed oversegmented.
+
+
+
+#########older data below
+
 Using version from around June 20, SVN 52181, it does not remember fragment membership.
 
+After some updates...June 26, SVN 52232.  (I don't recall changing anything to specifically improve things by this much ?!?)
+
 50 x 50 = 2500 pixels
 
 real	0m5.767s
@@ -20,13 +54,47 @@
 
 140 x 140 = 19,600 pixels
 
+52181:
 real	150m7.509s
 user	149m27.656s
 sys	0m9.025s
 
 0.45 s/pixel
 
+52232:
 
+real	0m55.961s
+user	0m52.655s
+sys	0m3.040s
+
+
+
+10k pixels, but [Raster MASK present]
+52232:
+real	1m43.085s
+user	1m42.338s
+sys	0m0.152s
+10k pixels, but [Raster MASK present]
+
+basic flag implementation:
+real	0m47.079s
+user	0m46.651s
+sys	0m0.092s
+[Raster MASK present]
+
+
+19600 pixels
+52232:
+real	0m55.961s
+user	0m52.655s
+sys	0m3.040s
+
+basic implementation:
+real	1m4.718s
+user	1m0.016s
+sys	0m4.340s
+
+
 Rough target:
 
 10,000 x 10,000 = 100,000,000 pixels

Modified: grass-addons/grass7/imagery/i.segment/write_output.c
===================================================================
--- grass-addons/grass7/imagery/i.segment/write_output.c	2012-06-28 22:43:02 UTC (rev 52252)
+++ grass-addons/grass7/imagery/i.segment/write_output.c	2012-06-29 06:54:51 UTC (rev 52253)
@@ -22,7 +22,7 @@
 
     /* Todo: return codes are 1 for these, need to check and react to errors? programmer's manual didn't include it... */
 
-    segment_flush(&files->out_seg);	/* force all data to disk */
+    /* force all data to disk */
     segment_flush(&files->bands_seg);	/* TODO use IFDEF or just delete for all these parts? for debug/validation output */
 
     G_debug(1, "preparing output raster");
@@ -39,13 +39,11 @@
 	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->out_seg, (void *)files->out_val, row, col);
 	    segment_get(&files->bands_seg, (void *)files->bands_val, row,
 			col);
-	    G_debug(5, "outval[0] = %i", files->out_val[0]);
-	    if (files->out_val[0] >= 0) {	/* only write positive segment ID's, using -1 as indicator of Null/Masked pixels.  TODO: OK to use -1 as flag for this? */
-		outbuf[col] = files->out_val[0];	/*just want segment assignment, not the other processing flag(s) */
-		meanbuf[col] = files->out_val[0];
+	    if (!(flag_get(files->null_flag, row, col))) {
+		outbuf[col] = files->iseg[row][col];
+		meanbuf[col] = files->bands_val[0];
 	    }
 	}
 	Rast_put_row(out_fd, outbuf, CELL_TYPE);
@@ -76,23 +74,27 @@
 
 int close_files(struct files *files)
 {
+    int i;
+
     /* close segmentation files and output raster */
     G_debug(1, "closing files");
     segment_close(&files->bands_seg);
-    segment_close(&files->out_seg);
-    segment_close(&files->no_check);
     segment_close(&files->bounds_seg);
 
     G_free(files->bands_val);
     G_free(files->second_val);
-    G_free(files->out_val);
 
+    for (i = 0; i < files->nrows; i++)
+	G_free(files->iseg[i]);
+    G_free(files->iseg);
+
+    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((struct link_head *)files->token); */
     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