[GRASS-SVN] r34444 - in grass/trunk: include lib/gis raster/r.mapcalc

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Nov 22 16:52:26 EST 2008


Author: glynn
Date: 2008-11-22 16:52:25 -0500 (Sat, 22 Nov 2008)
New Revision: 34444

Removed:
   grass/trunk/lib/gis/init_map.c
Modified:
   grass/trunk/include/gis.h
   grass/trunk/include/gisdefs.h
   grass/trunk/lib/gis/G.h
   grass/trunk/lib/gis/closecell.c
   grass/trunk/lib/gis/color_init.c
   grass/trunk/lib/gis/color_org.c
   grass/trunk/lib/gis/debug.c
   grass/trunk/lib/gis/get_row.c
   grass/trunk/lib/gis/gisinit.c
   grass/trunk/lib/gis/opencell.c
   grass/trunk/lib/gis/put_row.c
   grass/trunk/lib/gis/set_window.c
   grass/trunk/raster/r.mapcalc/evaluate.c
   grass/trunk/raster/r.mapcalc/expression.c
   grass/trunk/raster/r.mapcalc/map.c
Log:
Add G__alloca(), G__freea() (uses alloca if available, G_malloc/G_free otherwise)
Remove pre-allocated row buffers
Remove G_open_cell_new_random() etc
Make G__organize_colors() re-entrant



Modified: grass/trunk/include/gis.h
===================================================================
--- grass/trunk/include/gis.h	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/include/gis.h	2008-11-22 21:52:25 UTC (rev 34444)
@@ -337,6 +337,7 @@
     struct _Color_Info_ modular;
     DCELL cmin;
     DCELL cmax;
+    int organizing;
 };
 
 

Modified: grass/trunk/include/gisdefs.h
===================================================================
--- grass/trunk/include/gisdefs.h	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/include/gisdefs.h	2008-11-22 21:52:25 UTC (rev 34444)
@@ -31,6 +31,19 @@
 
 /*============================== Prototypes ================================*/
 
+#ifdef __GNUC__
+# ifdef __MINGW32__
+#  include <malloc.h>
+# else
+#  include <alloca.h>
+# endif
+# define G__alloca(n) alloca(n)
+# define G__freea(p)
+#else
+# define G__alloca(n) G_malloc(n)
+# define G__freea(p) G_free(p)
+#endif
+
 /* adj_cellhd.c */
 char *G_adjust_Cell_head(struct Cell_head *, int, int);
 char *G_adjust_Cell_head3(struct Cell_head *, int, int, int);
@@ -629,10 +642,6 @@
 char *G_index(const char *, int);
 char *G_rindex(const char *, int);
 
-/* init_map.c */
-int G__random_d_initialize_0(int, int, int);
-int G__random_f_initialize_0(int, int, int);
-
 /* interp.c */
 DCELL G_interp_linear(double, DCELL, DCELL);
 DCELL G_interp_bilinear(double, double, DCELL, DCELL, DCELL, DCELL);
@@ -793,7 +802,6 @@
 int G_insert_f_null_values(FCELL *, char *, int);
 int G_insert_d_null_values(DCELL *, char *, int);
 int G__check_null_bit(const unsigned char *, int, int);
-int G__set_flags_from_01_random(const char *, unsigned char *, int, int, int);
 int G__convert_01_flags(const char *, unsigned char *, int);
 int G__convert_flags_01(char *, const unsigned char *, int);
 int G__init_null_bits(unsigned char *, int);
@@ -821,17 +829,12 @@
 int G_open_cell_old(const char *, const char *);
 int G__open_cell_old(const char *, const char *);
 int G_open_cell_new(const char *);
-int G_open_cell_new_random(const char *);
 int G_open_cell_new_uncompressed(const char *);
 int G_want_histogram(int);
 int G_set_cell_format(int);
 int G_cellvalue_format(CELL);
 int G_open_fp_cell_new(const char *);
 int G_open_fp_cell_new_uncompressed(const char *);
-int G__reallocate_work_buf(int);
-int G__reallocate_null_buf(void);
-int G__reallocate_mask_buf(void);
-int G__reallocate_temp_buf(void);
 int G_set_fp_type(RASTER_MAP_TYPE);
 int G_raster_map_is_fp(const char *, const char *);
 RASTER_MAP_TYPE G_raster_map_type(const char *, const char *);
@@ -914,14 +917,11 @@
 /* put_row.c */
 int G_zeros_r_nulls(int);
 int G_put_map_row(int, const CELL *);
-int G_put_map_row_random(int, const CELL *, int, int, int);
 int G__put_null_value_row(int, const char *);
 int G_put_raster_row(int, const void *, RASTER_MAP_TYPE);
 int G_put_c_raster_row(int, const CELL *);
 int G_put_f_raster_row(int, const FCELL *);
 int G_put_d_raster_row(int, const DCELL *);
-int G__write_data(int, int, int);
-int G__write_data_compressed(int, int, int);
 int G__open_null_write(int);
 int G__write_null_bits(int, const unsigned char *, int, int, int);
 

Modified: grass/trunk/lib/gis/G.h
===================================================================
--- grass/trunk/lib/gis/G.h	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/lib/gis/G.h	2008-11-22 21:52:25 UTC (rev 34444)
@@ -65,7 +65,6 @@
     int io_error;		/* io error warning given       */
     XDR xdrstream;		/* xdr stream for reading fp    */
     unsigned char *NULL_ROWS[NULL_ROWS_INMEM];
-    unsigned char *null_work_buf;	/* data buffer for reading null rows    */
     int min_null_row;		/* Minimum row null row number in memory */
     struct Quant quant;
     struct GDAL_link *gdal;
@@ -79,16 +78,6 @@
     int window_set;		/* Flag: window set?                    */
     int mask_fd;		/* File descriptor for automatic mask   */
     int auto_mask;		/* Flag denoting automatic masking      */
-    CELL *mask_buf;
-    char *null_buf;		/* buffer for reading null rows         */
-    CELL *temp_buf;
-    unsigned char *compressed_buf;	/* Pre/post compressed data buffer      */
-    int compressed_buf_size;	/* sizeof compressed_buf                */
-    unsigned char *work_buf;	/* work data buffer                     */
-    int work_buf_size;		/* sizeof work_buf                      */
-    int null_buf_size;		/* sizeof null_buf                      */
-    int mask_buf_size;		/* sizeof mask_buf                      */
-    int temp_buf_size;		/* sizeof temp_buf                      */
     int want_histogram;
 
     int fileinfo_count;
@@ -100,4 +89,3 @@
 #define OPEN_OLD              1
 #define OPEN_NEW_COMPRESSED   2
 #define OPEN_NEW_UNCOMPRESSED 3
-#define OPEN_NEW_RANDOM       4

Modified: grass/trunk/lib/gis/closecell.c
===================================================================
--- grass/trunk/lib/gis/closecell.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/lib/gis/closecell.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -139,7 +139,6 @@
 
     for (i = 0; i < NULL_ROWS_INMEM; i++)
 	G_free(fcb->NULL_ROWS[i]);
-    G_free(fcb->null_work_buf);
 
     if (fcb->cellhd.compressed)
 	G_free(fcb->row_ptr);
@@ -178,13 +177,9 @@
 	case OPEN_NEW_UNCOMPRESSED:
 	    G_debug(1, "close %s uncompressed", fcb->name);
 	    break;
-	case OPEN_NEW_RANDOM:
-	    G_debug(1, "close %s random", fcb->name);
-	    break;
 	}
 
-	if (fcb->open_mode != OPEN_NEW_RANDOM &&
-	    fcb->cur_row < fcb->cellhd.rows) {
+	if (fcb->cur_row < fcb->cellhd.rows) {
 	    G_zero_raster_buf(fcb->data, fcb->map_type);
 	    for (row = fcb->cur_row; row < fcb->cellhd.rows; row++)
 		G_put_raster_row(fd, fcb->data, fcb->map_type);
@@ -216,12 +211,13 @@
 				   row, fcb->cellhd.cols, fd);
 
 	    /* write missing rows */
-	    if (fcb->open_mode != OPEN_NEW_RANDOM
-		&& fcb->null_cur_row < fcb->cellhd.rows) {
-		G__init_null_bits(fcb->null_work_buf, fcb->cellhd.cols);
+	    if (fcb->null_cur_row < fcb->cellhd.rows) {
+		unsigned char *null_work_buf = G__allocate_null_bits(fcb->cellhd.cols);
+		G__init_null_bits(null_work_buf, fcb->cellhd.cols);
 		for (row = fcb->null_cur_row; row < fcb->cellhd.rows; row++)
-		    G__write_null_bits(null_fd, fcb->null_work_buf, row,
+		    G__write_null_bits(null_fd, null_work_buf, row,
 				       fcb->cellhd.cols, fd);
+		G_free(null_work_buf);
 	    }
 	    close(null_fd);
 
@@ -387,7 +383,6 @@
 
     for (i = 0; i < NULL_ROWS_INMEM; i++)
 	G_free(fcb->NULL_ROWS[i]);
-    G_free(fcb->null_work_buf);
 
     if (fcb->map_type != CELL_TYPE)
 	G_quant_free(&fcb->quant);

Modified: grass/trunk/lib/gis/color_init.c
===================================================================
--- grass/trunk/lib/gis/color_init.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/lib/gis/color_init.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -44,6 +44,7 @@
     colors->modular.lookup.active = 0;
     colors->modular.fp_lookup.active = 0;
     colors->modular.fp_lookup.nalloc = 0;
+    colors->organizing = 0;
 
     return 0;
 }

Modified: grass/trunk/lib/gis/color_org.c
===================================================================
--- grass/trunk/lib/gis/color_org.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/lib/gis/color_org.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -3,7 +3,6 @@
 
 #define LOOKUP_COLORS 2048
 
-static int organizing = 0;
 static int organize_lookup(struct Colors *, int);
 static int organize_fp_lookup(struct Colors *, int);
 static int double_comp(const void *, const void *);
@@ -11,8 +10,8 @@
 int G__organize_colors(struct Colors *colors)
 {
     /* don't do anything if called recursively */
-    if (!organizing) {
-	organizing = 1;
+    if (!colors->organizing) {
+	colors->organizing = 1;
 
 	organize_lookup(colors, 0);
 	organize_lookup(colors, 1);
@@ -20,7 +19,7 @@
 	organize_fp_lookup(colors, 0);
 	organize_fp_lookup(colors, 1);
 
-	organizing = 0;
+	colors->organizing = 0;
     }
 
     return 0;

Modified: grass/trunk/lib/gis/debug.c
===================================================================
--- grass/trunk/lib/gis/debug.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/lib/gis/debug.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -111,14 +111,6 @@
     G_message("Flag: window set? %d", G__.window_set);
     G_message("File descriptor for automatic mask %d", G__.mask_fd);
     G_message("Flag denoting automatic masking %d", G__.auto_mask);
-    G_message("CELL mask buffer %p", G__.mask_buf);
-    G_message("buffer for reading null rows %p", G__.null_buf);
-    G_message("Pre/post compressed data buffer %p", G__.compressed_buf);
-    G_message("sizeof compressed_buf %d", G__.compressed_buf_size);
-    G_message("work data buffer %p", G__.work_buf);
-    G_message("sizeof work_buf %d", G__.work_buf_size);
-    G_message("sizeof null_buf %d", G__.null_buf_size);
-    G_message("sizeof mask_buf %d", G__.mask_buf_size);
     G_message("Histogram request %d", G__.want_histogram);
 
     G_message("G_dump: file #%d", fd);
@@ -147,7 +139,6 @@
     G_message("io error warning given %d", fcb->io_error);
     G_message("xdr stream for reading fp %p", &fcb->xdrstream);
     G_message("NULL_ROWS array[%d] = %p", NULL_ROWS_INMEM, fcb->NULL_ROWS);
-    G_message("data buffer for reading null rows %p", fcb->null_work_buf);
     G_message("Minimum row null number in memory %d", fcb->min_null_row);
     G_message("Quant ptr = %p", &fcb->quant);
     G_message("G_dump: end");

Modified: grass/trunk/lib/gis/get_row.c
===================================================================
--- grass/trunk/lib/gis/get_row.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/lib/gis/get_row.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -146,14 +146,18 @@
     off_t t1 = fcb->row_ptr[row];
     off_t t2 = fcb->row_ptr[row + 1];
     ssize_t readamount = t2 - t1;
-    unsigned char *cmp = G__.compressed_buf;
+    unsigned char *cmp;
     int n;
 
     if (lseek(fd, t1, SEEK_SET) < 0)
 	return -1;
 
-    if (read(fd, cmp, readamount) != readamount)
+    cmp = G__alloca(readamount);
+
+    if (read(fd, cmp, readamount) != readamount) {
+	G__freea(cmp);
 	return -1;
+    }
 
     /* Now decompress the row */
     if (fcb->cellhd.compressed > 0) {
@@ -174,6 +178,8 @@
     else
 	memcpy(data_buf, cmp, readamount);
 
+    G__freea(cmp);
+
     return 0;
 }
 
@@ -475,11 +481,11 @@
 
 /* transfer_to_cell_XY takes bytes from fcb->data, converts these bytes with
    the appropriate procedure (e.g. XDR or byte reordering) into type X 
-   values which are put into array G__.work_buf.  
-   finally the values in G__.work_buf are converted into 
+   values which are put into array work_buf.  
+   finally the values in work_buf are converted into 
    type Y and put into 'cell'.
    if type X == type Y the intermediate step of storing the values in 
-   G__.work_buf might be ommited. check the appropriate function for XY to
+   work_buf might be ommited. check the appropriate function for XY to
    determine the procedure of conversion. 
  */
 
@@ -512,73 +518,89 @@
 static void transfer_to_cell_fi(int fd, void *cell)
 {
     struct fileinfo *fcb = &G__.fileinfo[fd];
+    FCELL *work_buf = G__alloca(G__.window.cols * sizeof(FCELL));
     int i;
 
-    transfer_to_cell_XX(fd, G__.work_buf);
+    transfer_to_cell_XX(fd, work_buf);
 
     for (i = 0; i < G__.window.cols; i++)
 	((CELL *) cell)[i] = (fcb->col_map[i] == 0)
 	    ? 0
-	    : G_quant_get_cell_value(&fcb->quant,
-				     ((FCELL *) G__.work_buf)[i]);
+	    : G_quant_get_cell_value(&fcb->quant, work_buf[i]);
+
+    G__freea(work_buf);
 }
 
 static void transfer_to_cell_di(int fd, void *cell)
 {
     struct fileinfo *fcb = &G__.fileinfo[fd];
+    DCELL *work_buf = G__alloca(G__.window.cols * sizeof(DCELL));
     int i;
 
-    transfer_to_cell_XX(fd, G__.work_buf);
+    transfer_to_cell_XX(fd, work_buf);
 
     for (i = 0; i < G__.window.cols; i++)
 	((CELL *) cell)[i] = (fcb->col_map[i] == 0)
 	    ? 0
-	    : G_quant_get_cell_value(&fcb->quant,
-				     ((DCELL *) G__.work_buf)[i]);
+	    : G_quant_get_cell_value(&fcb->quant, work_buf[i]);
+
+    G__freea(work_buf);
 }
 
 /*--------------------------------------------------------------------------*/
 
 static void transfer_to_cell_if(int fd, void *cell)
 {
+    CELL *work_buf = G__alloca(G__.window.cols * sizeof(CELL));
     int i;
 
-    transfer_to_cell_XX(fd, G__.work_buf);
+    transfer_to_cell_XX(fd, work_buf);
 
     for (i = 0; i < G__.window.cols; i++)
-	((FCELL *) cell)[i] = ((CELL *) G__.work_buf)[i];
+	((FCELL *) cell)[i] = work_buf[i];
+
+    G__freea(work_buf);
 }
 
 static void transfer_to_cell_df(int fd, void *cell)
 {
+    DCELL *work_buf = G__alloca(G__.window.cols * sizeof(DCELL));
     int i;
 
-    transfer_to_cell_XX(fd, G__.work_buf);
+    transfer_to_cell_XX(fd, work_buf);
 
     for (i = 0; i < G__.window.cols; i++)
-	((FCELL *) cell)[i] = ((DCELL *) G__.work_buf)[i];
+	((FCELL *) cell)[i] = work_buf[i];
+
+    G__freea(work_buf);
 }
 
 /*--------------------------------------------------------------------------*/
 
 static void transfer_to_cell_id(int fd, void *cell)
 {
+    CELL *work_buf = G__alloca(G__.window.cols * sizeof(CELL));
     int i;
 
-    transfer_to_cell_XX(fd, G__.work_buf);
+    transfer_to_cell_XX(fd, work_buf);
 
     for (i = 0; i < G__.window.cols; i++)
-	((DCELL *) cell)[i] = ((CELL *) G__.work_buf)[i];
+	((DCELL *) cell)[i] = work_buf[i];
+
+    G__freea(work_buf);
 }
 
 static void transfer_to_cell_fd(int fd, void *cell)
 {
+    FCELL *work_buf = G__alloca(G__.window.cols * sizeof(FCELL));
     int i;
 
-    transfer_to_cell_XX(fd, G__.work_buf);
+    transfer_to_cell_XX(fd, work_buf);
 
     for (i = 0; i < G__.window.cols; i++)
-	((DCELL *) cell)[i] = ((FCELL *) G__.work_buf)[i];
+	((DCELL *) cell)[i] = work_buf[i];
+
+    G__freea(work_buf);
 }
 
 /*--------------------------------------------------------------------------*/
@@ -661,13 +683,15 @@
 {
     struct fileinfo *fcb = &G__.fileinfo[fd];
     int size = G_raster_size(data_type);
+    CELL *temp_buf = NULL;
     void *buf;
     int type;
     int stat;
     int i;
 
     if (fcb->reclass_flag && data_type != CELL_TYPE) {
-	buf = G__.temp_buf;
+	temp_buf = G__alloca(G__.window.cols * sizeof(CELL));
+	buf = temp_buf;
 	type = CELL_TYPE;
     }
     else {
@@ -675,10 +699,12 @@
 	type = data_type;
     }
 
-    stat =
-	get_map_row_no_reclass(fd, buf, row, type, null_is_zero, with_mask);
-    if (stat < 0)
+    stat = get_map_row_no_reclass(fd, buf, row, type, null_is_zero, with_mask);
+    if (stat < 0) {
+	if (temp_buf)
+	    G__freea(temp_buf);
 	return stat;
+    }
 
     if (!fcb->reclass_flag)
 	return 1;
@@ -692,10 +718,12 @@
 	return 1;
 
     for (i = 0; i < G__.window.cols; i++) {
-	G_set_raster_value_c(rast, G__.temp_buf[i], data_type);
+	G_set_raster_value_c(rast, temp_buf[i], data_type);
 	rast = G_incr_void_ptr(rast, size);
     }
 
+    G__freea(temp_buf);
+
     return 1;
 }
 
@@ -1054,6 +1082,9 @@
 	(fcb->min_null_row + NULL_ROWS_INMEM - 1 < row))
 	/* the null row row is not in memory */
     {
+	unsigned char *null_work_buf = G__alloca(
+	    G__null_bitstream_size(fcb->cellhd.cols));
+
 	/* read in NULL_ROWS_INMEM rows from null file 
 	   so that the requested row is between fcb->min_null_row
 	   and fcb->min_null_row + NULL_ROWS_INMEM */
@@ -1067,21 +1098,19 @@
 	    if (i + fcb->min_null_row >= G__.window.rows)
 		break;
 
-	    if (read_null_bits(null_fd, fcb->null_work_buf,
+	    if (read_null_bits(null_fd, null_work_buf,
 			       i + fcb->min_null_row, fcb->cellhd.cols,
 			       fd) < 0) {
 		if (fcb->map_type == CELL_TYPE) {
-		    /*
-		       If can't read null row, assume  that all map 0's are nulls 
-		       use allocated G__.mask_buf to read map row */
-		    get_map_row_nomask(fd, (void *)G__.mask_buf,
-				       i + fcb->min_null_row, CELL_TYPE);
-		    for (j = 0; j < G__.window.cols; j++) {
-			if (G__.mask_buf[j] == 0)
-			    flags[j] = 1;
-			else
-			    flags[j] = 0;
-		    }
+		    /* If can't read null row, assume  that all map 0's are nulls */
+		    CELL *mask_buf = G__alloca(G__.window.cols * sizeof(CELL));
+
+		    get_map_row_nomask(fd, mask_buf, i + fcb->min_null_row,
+				       CELL_TYPE);
+		    for (j = 0; j < G__.window.cols; j++)
+			flags[j] = (mask_buf[j] == 0);
+
+		    G__freea(mask_buf);
 		}
 		else {		/* fp map */
 
@@ -1093,12 +1122,12 @@
 	    else {
 		/* copy null row to flags row translated by window column mapping */
 		/* the fcb->NULL_ROWS[row-fcb->min_null_row] has G__.window.cols bits, */
-		/* the fcb->null_work_buf has size fcb->cellhd.cols */
+		/* the null_work_buf has size fcb->cellhd.cols */
 		for (j = 0; j < G__.window.cols; j++) {
 		    if (!fcb->col_map[j])
 			flags[j] = 1;
 		    else
-			flags[j] = G__check_null_bit(fcb->null_work_buf,
+			flags[j] = G__check_null_bit(null_work_buf,
 						     fcb->col_map[j] - 1,
 						     fcb->cellhd.cols);
 		}
@@ -1120,6 +1149,8 @@
 
 	if (null_fd > 0)
 	    close(null_fd);
+
+	G__freea(null_work_buf);
     }				/* row is not in memory */
 
     /* copy null file data translated by column mapping to user null row */
@@ -1159,20 +1190,25 @@
 
 static void embed_mask(char *flags, int row)
 {
+    CELL *mask_buf = G__alloca(G__.window.cols * sizeof(CELL));
     int i;
 
     if (G__.auto_mask <= 0)
 	return;
 
-    if (get_map_row_nomask(G__.mask_fd, G__.mask_buf, row, CELL_TYPE) < 0)
+    if (get_map_row_nomask(G__.mask_fd, mask_buf, row, CELL_TYPE) < 0) {
+	G__freea(mask_buf);
 	return;
+    }
 
     if (G__.fileinfo[G__.mask_fd].reclass_flag)
-	do_reclass_int(G__.mask_fd, G__.mask_buf, 1);
+	do_reclass_int(G__.mask_fd, mask_buf, 1);
 
     for (i = 0; i < G__.window.cols; i++)
-	if (G__.mask_buf[i] == 0)
+	if (mask_buf[i] == 0)
 	    flags[i] = 1;
+
+    G__freea(mask_buf);
 }
 
 static void get_null_value_row(int fd, char *flags, int row, int with_mask)
@@ -1193,6 +1229,7 @@
 		       int null_is_zero, int with_mask)
 {
     struct fileinfo *fcb = &G__.fileinfo[fd];
+    char *null_buf;
     int i;
 
     /* this is because without null file the nulls can be only due to 0's
@@ -1201,12 +1238,14 @@
 	&& (G__.auto_mask <= 0 || !with_mask))
 	return 1;
 
-    get_null_value_row(fd, G__.null_buf, row, with_mask);
+    null_buf = G__alloca(G__.window.cols);
 
+    get_null_value_row(fd, null_buf, row, with_mask);
+
     for (i = 0; i < G__.window.cols; i++) {
 	/* also check for nulls which might be already embedded by quant
 	   rules in case of fp map. */
-	if (G__.null_buf[i] || G_is_null_value(buf, map_type)) {
+	if (null_buf[i] || G_is_null_value(buf, map_type)) {
 	    /* G__set_[f/d]_null_value() sets it to 0 is the embedded mode
 	       is not set and calls G_set_[f/d]_null_value() otherwise */
 	    G__set_null_value(buf, 1, null_is_zero, map_type);
@@ -1214,6 +1253,8 @@
 	buf = G_incr_void_ptr(buf, G_raster_size(map_type));
     }
 
+    G__freea(null_buf);
+
     return 1;
 }
 

Modified: grass/trunk/lib/gis/gisinit.c
===================================================================
--- grass/trunk/lib/gis/gisinit.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/lib/gis/gisinit.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -119,15 +119,6 @@
     /* no histograms */
     G__.want_histogram = 0;
 
-    /* Set compressed data buffer size to zero */
-    G__.compressed_buf_size = 0;
-    G__.work_buf_size = 0;
-    G__.null_buf_size = 0;
-    G__.mask_buf_size = 0;
-    G__.temp_buf_size = 0;
-    /* mask buf we always want to keep allocated */
-    G__reallocate_mask_buf();
-
     /* set the write type for floating maps */
     G__.fp_type = FCELL_TYPE;
     G__.fp_nbytes = XDR_FLOAT_NBYTES;

Deleted: grass/trunk/lib/gis/init_map.c
===================================================================
--- grass/trunk/lib/gis/init_map.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/lib/gis/init_map.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -1,86 +0,0 @@
-
-/*--------------------------------------------------------------------------*/
-
-/* inititializes the random file with descriptor "fd" with "nofRows" rows
-   of zero values columns. each row consists of "nofCols" columns. 
-   assumes that the file is rewound and empty.
-
-   returns 1 if successful and 0 for any kind of error. */
-
-#include "G.h"
-
-/*--------------------------------------------------------------------------*/
-
-int G__random_d_initialize_0(int fd, int nofRows, int nofCols)
-{
-    struct fileinfo *fcb = &G__.fileinfo[fd];
-    int row, col;
-    double zeroVal, *zeroValP;
-    XDR *xdrs;
-
-    xdrs = &fcb->xdrstream;	/* xdr stream is initialized to write into */
-    xdr_setpos(xdrs, 0);	/* G__.work_buf in 'opencell.c' */
-
-    zeroVal = 0;
-    zeroValP = &zeroVal;
-
-    for (col = nofCols; col--;)
-	if (!xdr_double(xdrs, zeroValP)) {
-	    G_warning
-		("G_random_d_initialize_0: xdr_double failed for index %d.\n",
-		 col);
-	    return -1;
-	}
-
-    for (row = 0; row < nofRows; row++)
-	if (G__write_data(fd, row, nofCols) == -1) {
-	    G_warning("G_random_d_initialize_0: write failed in row %d.\n",
-		      row);
-	    return -1;
-	}
-
-    return 1;
-}
-
-/*--------------------------------------------------------------------------*/
-
-/* inititializes the random file with descriptor "fd" with "nofRows" rows
-   of zero values columns. each row consists of "nofCols" columns. 
-   assumes that the file is rewound and empty.
-
-   returns 1 if successful and 0 for any kind of error. */
-
-
-int G__random_f_initialize_0(int fd, int nofRows, int nofCols)
-{
-    struct fileinfo *fcb = &G__.fileinfo[fd];
-    int row, col;
-    float zeroVal, *zeroValP;
-    XDR *xdrs;
-
-
-    xdrs = &fcb->xdrstream;	/* xdr stream is initialized to write into */
-    xdr_setpos(xdrs, 0);	/* G__.work_buf in 'opencell.c' */
-
-    zeroVal = 0;
-    zeroValP = &zeroVal;
-
-    for (col = nofCols; col--;)
-	if (!xdr_float(xdrs, zeroValP)) {
-	    G_warning
-		("G_random_f_initialize_0: xdr_float failed for index %d.\n",
-		 col);
-	    return 0;
-	}
-
-    for (row = 0; row < nofRows; row++)
-	if (G__write_data(fd, row, nofCols) == -1) {
-	    G_warning("G_random_f_initialize_0: write failed in row %d.\n",
-		      row);
-	    return 0;
-	}
-
-    return 1;
-}
-
-/*--------------------------------------------------------------------------*/

Modified: grass/trunk/lib/gis/opencell.c
===================================================================
--- grass/trunk/lib/gis/opencell.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/lib/gis/opencell.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -24,8 +24,6 @@
 #include <grass/gis.h>
 #include <grass/glocale.h>
 
-static int allocate_compress_buf(int);
-
 static struct fileinfo *new_fileinfo(int fd)
 {
     int oldsize = G__.fileinfo_count;
@@ -283,7 +281,6 @@
     /* allocate null bitstream buffers for reading null rows */
     for (i = 0; i < NULL_ROWS_INMEM; i++)
 	fcb->NULL_ROWS[i] = G__allocate_null_bits(G__.window.cols);
-    fcb->null_work_buf = G__allocate_null_bits(fcb->cellhd.cols);
     /* initialize : no NULL rows in memory */
     fcb->min_null_row = (-1) * NULL_ROWS_INMEM;
 
@@ -320,20 +317,9 @@
      */
 
     /* for reading fcb->data is allocated to be fcb->cellhd.cols * fcb->nbytes 
-       (= XDR_FLOAT/DOUBLE_NBYTES) and G__.work_buf to be G__.window.cols * 
-       sizeof(CELL or DCELL or FCELL) */
+       (= XDR_FLOAT/DOUBLE_NBYTES) */
     fcb->data = (unsigned char *)G_calloc(fcb->cellhd.cols, MAP_NBYTES);
 
-    G__reallocate_work_buf(INTERN_SIZE);
-    G__reallocate_mask_buf();
-    G__reallocate_null_buf();
-    G__reallocate_temp_buf();
-    /* work_buf is used as intermediate buf for conversions */
-    /*
-     * allocate/enlarge the compressed data buffer needed by get_map_row()
-     */
-    allocate_compress_buf(fd);
-
     /* initialize/read in quant rules for float point maps */
     if (fcb->map_type != CELL_TYPE) {
 	if (fcb->reclass_flag)
@@ -419,27 +405,6 @@
 }
 
 /*!
-  \brief Opens a new cell file in a database (random mode)
-
-  See also G_open_cell_new().
- 
-  Used for non sequential writes.
-  
-  \param name map name
-
-  \return open file descriptor ( >= 0) if successful
-  \return negative integer if error
-*/
-int G_open_cell_new_random(const char *name)
-{
-    WRITE_MAP_TYPE = CELL_TYPE;
-    /* bytes per cell for current map */
-    WRITE_NBYTES = NBYTES;
-    strcpy(cell_dir, "cell");
-    return G__open_raster_new(name, OPEN_NEW_RANDOM);
-}
-
-/*!
   \brief Opens a new cell file in a database (uncompressed)
 
   See also G_open_cell_new().
@@ -638,14 +603,10 @@
     fcb->open_mode = -1;
 
     /* for writing fcb->data is allocated to be G__.window.cols * 
-       sizeof(CELL or DCELL or FCELL) and G__.work_buf to be G__.window.cols *
-       fcb->nbytes (= XDR_FLOAT/DOUBLE_NBYTES) */
+       sizeof(CELL or DCELL or FCELL)  */
     fcb->data = (unsigned char *)G_calloc(G__.window.cols,
 					  G_raster_size(fcb->map_type));
 
-    G__reallocate_null_buf();
-    /* we need null buffer to automatically write embeded nulls in put_row */
-
     if (open_mode == OPEN_NEW_COMPRESSED && !COMPRESSION_TYPE)
 	COMPRESSION_TYPE = getenv("GRASS_INT_ZLIB") ? 2 : 1;
 
@@ -654,7 +615,6 @@
      * set format to cell/supercell
      * for compressed writing
      *   allocate space to hold the row address array
-     *   allocate/enlarge both the compress_buf and the work_buf
      */
     G_copy((char *)&fcb->cellhd, (char *)&G__.window, sizeof(fcb->cellhd));
 
@@ -664,11 +624,7 @@
 	G__write_row_ptrs(fd);
 	fcb->cellhd.compressed = COMPRESSION_TYPE;
 
-	allocate_compress_buf(fd);
 	fcb->nbytes = 1;	/* to the minimum */
-	G__reallocate_work_buf(sizeof(CELL));
-	G__reallocate_mask_buf();
-	G__reallocate_temp_buf();
     }
     else {
 	fcb->nbytes = WRITE_NBYTES;
@@ -680,32 +636,10 @@
 	}
 	else
 	    fcb->cellhd.compressed = 0;
-	G__reallocate_work_buf(fcb->nbytes);
-	G__reallocate_mask_buf();
-	G__reallocate_temp_buf();
 
 	if (fcb->map_type != CELL_TYPE) {
 	    G_quant_init(&(fcb->quant));
 	}
-
-	if (open_mode == OPEN_NEW_RANDOM) {
-	    G_warning(_("Unable to write embedded null values "
-			"for raster map open for random access"));
-	    if (fcb->map_type == CELL_TYPE)
-		G_write_zeros(fd,
-			      (long)WRITE_NBYTES * fcb->cellhd.cols *
-			      fcb->cellhd.rows);
-	    else if (fcb->map_type == FCELL_TYPE) {
-		if (G__random_f_initialize_0
-		    (fd, fcb->cellhd.rows, fcb->cellhd.cols) < 0)
-		    return -1;
-	    }
-	    else {
-		if (G__random_d_initialize_0
-		    (fd, fcb->cellhd.rows, fcb->cellhd.cols) < 0)
-		    return -1;
-	    }
-	}
     }
 
     /* save name and mapset, and tempfile name */
@@ -739,7 +673,6 @@
     for (i = 0; i < NULL_ROWS_INMEM; i++)
 	fcb->NULL_ROWS[i] = G__allocate_null_bits(fcb->cellhd.cols);
     fcb->min_null_row = (-1) * NULL_ROWS_INMEM;
-    fcb->null_work_buf = G__allocate_null_bits(fcb->cellhd.cols);
 
     /* init cell stats */
     /* now works only for int maps */
@@ -761,122 +694,6 @@
 }
 
 /*!
-  \brief allocate/enlarge the compressed data buffer needed by get_map_row()
-  and put_map_row()
-  
-  Note: compressed format is repeat, value:
-  
-  Repeat takes 1 byte, value takes up to sizeof(CELL)
-  plus 1 byte header for nbytes needed to store row
-*/
-static int allocate_compress_buf(int fd)
-{
-    struct fileinfo *fcb = &G__.fileinfo[fd];
-    int n;
-
-    n = fcb->cellhd.cols * (sizeof(CELL) + 1) + 1;
-    if (fcb->cellhd.compressed && fcb->map_type == CELL_TYPE &&
-	(n > G__.compressed_buf_size)) {
-	if (G__.compressed_buf_size <= 0)
-	    G__.compressed_buf = (unsigned char *)G_malloc(n);
-	else
-	    G__.compressed_buf =
-		(unsigned char *)G_realloc((char *)G__.compressed_buf, n);
-	G__.compressed_buf_size = n;
-    }
-
-    return 0;
-}
-
-/*!
-  \brief Allocate/enlarge the work data buffer needed by get_map_row and put_map_row()
-
-  \param bytes_per_cell number of bytes per cell
-
-  \return 0
-*/
-int G__reallocate_work_buf(int bytes_per_cell)
-{
-    int n;
-
-    n = G__.window.cols * (bytes_per_cell + 1) + 1;
-    if (n > G__.work_buf_size) {
-	if (G__.work_buf_size <= 0)
-	    G__.work_buf = (unsigned char *)G_malloc(n);
-	else
-	    G__.work_buf =
-		(unsigned char *)G_realloc((char *)G__.work_buf, n);
-	G__.work_buf_size = n;
-    }
-
-    return 0;
-}
-
-/*!
-  \brief Allocate/enlarge the null data buffer needed by get_map_row()
-  and for conversion in put_row 
-
-  \return 0
-*/
-int G__reallocate_null_buf(void)
-{
-    int n;
-    n = (G__.window.cols + 1) * sizeof(char);
-    if (n > G__.null_buf_size) {
-	if (G__.null_buf_size <= 0)
-	    G__.null_buf = (char *)G_malloc(n);
-	else
-	    G__.null_buf = (char *)G_realloc(G__.null_buf, n);
-	G__.null_buf_size = n;
-    }
-
-    return 0;
-}
-
-/*!
-  \brief Allocate/enlarge the mask buffer needed by get_map_row()
-
-  \return 0
-*/
-int G__reallocate_mask_buf(void)
-{
-    int n;
-
-    n = (G__.window.cols + 1) * sizeof(CELL);
-    if (n > G__.mask_buf_size) {
-	if (G__.mask_buf_size <= 0)
-	    G__.mask_buf = (CELL *) G_malloc(n);
-	else
-	    G__.mask_buf = (CELL *) G_realloc((char *)G__.mask_buf, n);
-	G__.mask_buf_size = n;
-    }
-
-    return 0;
-}
-
-/*!
-  \brief Allocate/enlarge the temporary buffer needed by G_get_raster_row[_nomask]
-
-  \return 0
-*/
-int G__reallocate_temp_buf(void)
-{
-    int n;
-
-    n = (G__.window.cols + 1) * sizeof(CELL);
-    if (n > G__.temp_buf_size) {
-	if (G__.temp_buf_size <= 0)
-	    G__.temp_buf = (CELL *) G_malloc(n);
-	else
-	    G__.temp_buf = (CELL *) G_realloc((char *)G__.temp_buf, n);
-	G__.temp_buf_size = n;
-    }
-
-    return 0;
-}
-
-
-/*!
   \brief Set raster map floating-point data format.
   
   This controls the storage type for floating-point maps. It affects

Modified: grass/trunk/lib/gis/put_row.c
===================================================================
--- grass/trunk/lib/gis/put_row.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/lib/gis/put_row.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -16,7 +16,7 @@
  *   Return setting values in all cases.
  *
  *   *** NOTE *** 
- *   Use only to change a default behavior for zero of G_put_map_row[_random].
+ *   Use only to change a default behavior for zero of G_put_map_row
  *
  ********************************************************************** 
  *
@@ -76,40 +76,11 @@
  *  Keeps track of the minimum and maximum cell value  for use in updating
  *  the range file upon close of the cell file.
  *
- ********************************************************************** 
- *
- *  G_put_map_row_random(fd, buf, row, col, ncells)
- *      int fd                  File descriptor where data is to be written
- *      CELL *buf               Buffer holding data
- *      int row                 Map row where data is to be written
- *      int col                 Column where data begins
- *      int ncells              Number of columns of data to be written
- *
- *   Writes parts of rows into open cell file.
- *
- *   Cell file must have been opened with G_open_cell_new_random()
- *   except it can't write null file.
- *
- *   returns:    0  if successful
- *              -1  on fail
- *
- *   behaves the same as G_put_map_row()
- *
- **********************************************************************
- *
- *  Note: there is no G_put_[c/f/d]_raster_row_random() because even though
- *  it is possible to randomly write floating and integer rows, it is not
- *  possible to rand. write null data, so the null file can't
- *  be updated correctly.
- *
  ***********************************************************************
  *
- *  G__put_null_value_row(fd, buf, row, col, ncells)
+ *  G__put_null_value_row(fd, buf)
  *      int fd                  File descriptor where data is to be written
  *      char *buf               Buffer holding null data
- *      int row                 Map row where data is to be written
- *      int col                 Column where data begins
- *      int ncells              Number of columns of data to be written
  *
  *   converts a buffer of zero's and ones to bitstream and stores this 
  *   bitstream in memory. (the null rows from memory are written into null
@@ -135,16 +106,14 @@
 
 static int _zeros_r_nulls = 1;
 
-static int put_raster_data(int, const void *, int, int, int, int,
+static int put_raster_data(int, char *, const void *, int, int, int,
 			   RASTER_MAP_TYPE);
-static int put_data(int, const CELL *, int, int, int, int);
-static int check_open(const char *, int, int);
-static int adjust(int, int *, int *);
+static int put_data(int, char *, const CELL *, int, int, int);
+static int check_open(const char *, int);
 static void write_error(int, int);
 static int same(const unsigned char *, const unsigned char *, int);
-static int seek_random(int, int, int);
 static void set_file_pointer(int, int);
-static int put_fp_data(int, const void *, int, int, int, RASTER_MAP_TYPE);
+static int put_fp_data(int, char *, const void *, int, int, RASTER_MAP_TYPE);
 static int put_null_data(int, const char *, int);
 static int convert_and_write_if(int, const CELL *);
 static int convert_and_write_id(int, const CELL *);
@@ -167,30 +136,6 @@
     return _zeros_r_nulls;
 }
 
-int G_put_map_row_random(int fd, const CELL * buf, int row, int col, int n)
-{
-    struct fileinfo *fcb = &G__.fileinfo[fd];
-
-    if (!check_open("G_put_map_row_random", fd, 1))
-	return -1;
-
-    buf += adjust(fd, &col, &n);
-    switch (put_data(fd, buf, row, col, n, _zeros_r_nulls)) {
-    case -1:
-	return -1;
-    case 0:
-	return 1;
-    }
-
-    /* only for integer maps */
-    if (fcb->want_histogram)
-	G_update_cell_stats(buf, n, &fcb->statf);
-
-    G_row_update_range(buf, n, &fcb->range);
-
-    return 1;
-}
-
 int G__put_null_value_row(int fd, const char *buf)
 {
     struct fileinfo *fcb = &G__.fileinfo[fd];
@@ -242,7 +187,7 @@
 
 /*--------------------------------------------------------------------------*/
 
-static int check_open(const char *me, int fd, int random)
+static int check_open(const char *me, int fd)
 {
     struct fileinfo *fcb = &G__.fileinfo[fd];
 
@@ -253,19 +198,8 @@
 	break;
     case OPEN_NEW_COMPRESSED:
     case OPEN_NEW_UNCOMPRESSED:
-	if (!random)
-	    return 1;
-
-	G_warning(_("%s: map [%s] not open for random write - request ignored"),
-		  me, fcb->name);
+	return 1;
 	break;
-    case OPEN_NEW_RANDOM:
-	if (random)
-	    return 1;
-
-	G_warning(_("%s: map [%s] not open for sequential write - request ignored"),
-		  me, fcb->name);
-	break;
     default:
 	G_warning(_("%s: unopened file descriptor - request ignored"), me);
 	break;
@@ -274,32 +208,6 @@
     return 0;
 }
 
-/*******************************************************
-*  adjust the column,n so that it is within the window
-*  returns the adjustment to buffer that must be made
-*  if col,n is adjusted
-*
-*  if n comes back <= zero, do not write
-*******************************************************/
-static int adjust(int fd, int *col, int *n)
-{
-    struct fileinfo *fcb = &G__.fileinfo[fd];
-    int adj = 0;
-    int last = *col + *n;
-
-    if (*col < 0) {
-	adj = -(*col);
-	*col = 0;
-    }
-
-    if (last > fcb->cellhd.cols)
-	last = fcb->cellhd.cols;
-
-    *n = last - *col;
-
-    return adj;
-}
-
 static void write_error(int fd, int row)
 {
     struct fileinfo *fcb = &G__.fileinfo[fd];
@@ -316,12 +224,12 @@
 
 /*--------------------------------------------------------------------------*/
 
-int G__write_data(int fd, int row, int n)
+static int write_data(int fd, int row, unsigned char *buf, int n)
 {
     struct fileinfo *fcb = &G__.fileinfo[fd];
     ssize_t nwrite = fcb->nbytes * n;
 
-    if (write(fd, G__.work_buf, nwrite) != nwrite) {
+    if (write(fd, buf, nwrite) != nwrite) {
 	write_error(fd, row);
 	return -1;
     }
@@ -329,12 +237,12 @@
     return 0;
 }
 
-int G__write_data_compressed(int fd, int row, int n)
+static int write_data_compressed(int fd, int row, unsigned char *buf, int n)
 {
     struct fileinfo *fcb = &G__.fileinfo[fd];
     int nwrite = fcb->nbytes * n;
 
-    if (G_zlib_write(fd, G__.work_buf, nwrite) < 0) {
+    if (G_zlib_write(fd, buf, nwrite) < 0) {
 	write_error(fd, row);
 	return -1;
     }
@@ -344,21 +252,6 @@
 
 /*--------------------------------------------------------------------------*/
 
-static int seek_random(int fd, int row, int col)
-{
-    struct fileinfo *fcb = &G__.fileinfo[fd];
-    off_t offset = ((off_t) fcb->cellhd.cols * row + col) * fcb->nbytes;
-
-    if (lseek(fd, offset, SEEK_SET) < 0) {
-	write_error(fd, row);
-	return -1;
-    }
-
-    return 0;
-}
-
-/*--------------------------------------------------------------------------*/
-
 static void set_file_pointer(int fd, int row)
 {
     struct fileinfo *fcb = &G__.fileinfo[fd];
@@ -372,8 +265,8 @@
 
 /*--------------------------------------------------------------------------*/
 
-static int convert_float(XDR * xdrs, const FCELL * rast, int row, int col,
-			 int n, int random)
+static int convert_float(XDR * xdrs, char *null_buf, const FCELL * rast,
+			 int row, int n)
 {
     int i;
 
@@ -383,8 +276,7 @@
 	/* substitute embeded null vals by 0's */
 	if (G_is_f_null_value(&rast[i])) {
 	    f = 0.;
-	    if (!random)
-		G__.null_buf[col + i] = 1;
+	    null_buf[i] = 1;
 	}
 	else
 	    f = rast[i];
@@ -398,8 +290,8 @@
     return 0;
 }
 
-static int convert_double(XDR * xdrs, const DCELL * rast, int row, int col,
-			  int n, int random)
+static int convert_double(XDR * xdrs, char *null_buf, const DCELL * rast,
+			  int row, int n)
 {
     int i;
 
@@ -409,8 +301,7 @@
 	/* substitute embeded null vals by 0's */
 	if (G_is_d_null_value(&rast[i])) {
 	    d = 0.;
-	    if (!random)
-		G__.null_buf[col + i] = 1;
+	    null_buf[i] = 1;
 	}
 	else
 	    d = rast[i];
@@ -428,13 +319,13 @@
 
 /* writes data to fcell file for either full or partial rows */
 
-static int put_fp_data(int fd, const void *rast, int row, int col, int n,
-		       RASTER_MAP_TYPE data_type)
+static int put_fp_data(int fd, char *null_buf, const void *rast,
+		       int row, int n, RASTER_MAP_TYPE data_type)
 {
     struct fileinfo *fcb = &G__.fileinfo[fd];
-    int random = (fcb->open_mode == OPEN_NEW_RANDOM);
     int compressed = (fcb->open_mode == OPEN_NEW_COMPRESSED);
     XDR *xdrs = &fcb->xdrstream;
+    char *work_buf;
 
     if (row < 0 || row >= fcb->cellhd.rows)
 	return 0;
@@ -442,35 +333,43 @@
     if (n <= 0)
 	return 0;
 
-    if (random) {
-	if (seek_random(fd, row, col) == -1)
-	    return -1;
-    }
-    else if (compressed)
+    work_buf = G__alloca(G__.window.cols * fcb->nbytes + 1);
+
+    if (compressed)
 	set_file_pointer(fd, row);
 
-    xdrmem_create(xdrs, (caddr_t) G__.work_buf,
-		  (u_int) (fcb->nbytes * fcb->cellhd.cols), XDR_ENCODE);
+    xdrmem_create(xdrs, work_buf,
+		  (unsigned int) fcb->nbytes * fcb->cellhd.cols, XDR_ENCODE);
     xdr_setpos(xdrs, 0);
 
     if (data_type == FCELL_TYPE) {
-	if (convert_float(xdrs, rast, row, col, n, random) < 0)
+	if (convert_float(xdrs, null_buf, rast, row, n) < 0) {
+	    G__freea(work_buf);
 	    return -1;
+	}
     }
     else {
-	if (convert_double(xdrs, rast, row, col, n, random) < 0)
+	if (convert_double(xdrs, null_buf, rast, row, n) < 0) {
+	    G__freea(work_buf);
 	    return -1;
+	}
     }
 
     xdr_destroy(&fcb->xdrstream);
 
     if (compressed) {
-	if (G__write_data_compressed(fd, row, n) == -1)
+	if (write_data_compressed(fd, row, work_buf, n) == -1) {
+	    G__freea(work_buf);
 	    return -1;
+	}
     }
-    else if (G__write_data(fd, row, n) == -1)
+    else if (write_data(fd, row, work_buf, n) == -1) {
+	G__freea(work_buf);
 	return -1;
+    }
 
+    G__freea(work_buf);
+
     return 1;
 }
 
@@ -480,8 +379,8 @@
 
 /*--------------------------------------------------------------------------*/
 
-static void convert_int(unsigned char *wk, const CELL * rast, int col, int n,
-			int random, int len, int zeros_r_nulls)
+static void convert_int(unsigned char *wk, char *null_buf, const CELL * rast,
+			int n, int len, int zeros_r_nulls)
 {
     int i;
 
@@ -495,11 +394,10 @@
 	/* substitute embeded null vals by 0's */
 	if (G_is_c_null_value(&v)) {
 	    v = 0;
-	    if (!random)
-		G__.null_buf[col + i] = 1;
+	    null_buf[i] = 1;
 	}
-	else if (!random && zeros_r_nulls && !v)
-	    G__.null_buf[col + i] = 1;
+	else if (zeros_r_nulls && !v)
+	    null_buf[i] = 1;
 
 	/* negatives */
 	if (v < 0) {
@@ -598,23 +496,20 @@
 			 int nbytes)
 {
     int total = nbytes * n;
-    int nwrite = G_zlib_compress(G__.work_buf + 1, total,
-				 G__.compressed_buf + 1,
-				 G__.compressed_buf_size - 1);
+    int nwrite = G_zlib_compress(src, total, dst, total);
 
     return (nwrite >= total) ? 0 : nwrite;
 }
 
 /*--------------------------------------------------------------------------*/
 
-static int put_data(int fd, const CELL * cell, int row, int col, int n,
-		    int zeros_r_nulls)
+static int put_data(int fd, char *null_buf, const CELL *cell,
+		    int row, int n, int zeros_r_nulls)
 {
     struct fileinfo *fcb = &G__.fileinfo[fd];
-    int random = (fcb->open_mode == OPEN_NEW_RANDOM);
     int compressed = fcb->cellhd.compressed;
     int len = compressed ? sizeof(CELL) : fcb->nbytes;
-    unsigned char *wk = G__.work_buf;
+    unsigned char *work_buf, *wk;
     ssize_t nwrite;
 
     if (row < 0 || row >= fcb->cellhd.rows)
@@ -623,21 +518,22 @@
     if (n <= 0)
 	return 0;
 
-    if (random) {
-	if (seek_random(fd, row, col) == -1)
-	    return -1;
-    }
-    else if (compressed)
+    work_buf = G__alloca(G__.window.cols * sizeof(CELL) + 1);
+    wk = work_buf;
+
+    if (compressed)
 	set_file_pointer(fd, row);
 
     if (compressed)
 	wk++;
 
-    convert_int(wk, cell, col, n, random, len, zeros_r_nulls);
+    convert_int(wk, null_buf, cell, n, len, zeros_r_nulls);
 
     if (compressed) {
-	unsigned char *wk = G__.work_buf + 1;
+	unsigned char *wk = work_buf + 1;
 	int nbytes = count_bytes(wk, n, len);
+	unsigned char *compressed_buf;
+	int total;
 
 	if (fcb->nbytes < nbytes)
 	    fcb->nbytes = nbytes;
@@ -646,40 +542,52 @@
 	if (nbytes < len)
 	    trim_bytes(wk, n, len, len - nbytes);
 
-	G__.compressed_buf[0] = G__.work_buf[0] = nbytes;
+	total = nbytes * n;
+	compressed_buf = G__alloca(total + 1);
 
+	compressed_buf[0] = work_buf[0] = nbytes;
+
 	/* then compress the data */
 	nwrite = compressed == 1
-	    ? rle_compress(G__.compressed_buf + 1, G__.work_buf + 1, n,
+	    ? rle_compress(compressed_buf + 1, work_buf + 1, n,
 			   nbytes)
-	    : zlib_compress(G__.compressed_buf + 1, G__.work_buf + 1, n,
+	    : zlib_compress(compressed_buf + 1, work_buf + 1, n,
 			    nbytes);
 
 	if (nwrite > 0) {
 	    nwrite++;
 
-	    if (write(fd, G__.compressed_buf, nwrite) != nwrite) {
+	    if (write(fd, compressed_buf, nwrite) != nwrite) {
 		write_error(fd, row);
+		G__freea(compressed_buf);
+		G__freea(work_buf);
 		return -1;
 	    }
 	}
 	else {
 	    nwrite = nbytes * n + 1;
-	    if (write(fd, G__.work_buf, nwrite) != nwrite) {
+	    if (write(fd, work_buf, nwrite) != nwrite) {
 		write_error(fd, row);
+		G__freea(compressed_buf);
+		G__freea(work_buf);
 		return -1;
 	    }
 	}
+
+	G__freea(compressed_buf);
     }
     else {
 	nwrite = fcb->nbytes * n;
 
-	if (write(fd, G__.work_buf, nwrite) != nwrite) {
+	if (write(fd, work_buf, nwrite) != nwrite) {
 	    write_error(fd, row);
+	    G__freea(work_buf);
 	    return -1;
 	}
     }
 
+    G__freea(work_buf);
+
     return 1;
 }
 
@@ -689,12 +597,13 @@
 
 /*--------------------------------------------------------------------------*/
 
-static int put_raster_data(int fd, const void *rast, int row, int col, int n,
+static int put_raster_data(int fd, char *null_buf, const void *rast,
+			   int row, int n,
 			   int zeros_r_nulls, RASTER_MAP_TYPE map_type)
 {
     return (map_type == CELL_TYPE)
-	? put_data(fd, rast, row, col, n, zeros_r_nulls)
-	: put_fp_data(fd, rast, row, col, n, map_type);
+	? put_data(fd, null_buf, rast, row, n, zeros_r_nulls)
+	: put_fp_data(fd, null_buf, rast, row, n, map_type);
 }
 
 /*--------------------------------------------------------------------------*/
@@ -886,30 +795,34 @@
 static int put_raster_row(int fd, const void *buf, RASTER_MAP_TYPE data_type,
 			  int zeros_r_nulls)
 {
-    struct fileinfo *fcb = &G__.fileinfo[fd];
-
     static int (*convert_and_write_FtypeOtype[3][3]) () = {
 	{
 	NULL, convert_and_write_if, convert_and_write_id}, {
 	convert_and_write_fi, NULL, convert_and_write_fd}, {
 	convert_and_write_di, convert_and_write_df, NULL}
     };
+    struct fileinfo *fcb = &G__.fileinfo[fd];
+    char *null_buf;
+    int stat;
 
-    if (!check_open("put_raster_row", fd, 0))
+    if (!check_open("put_raster_row", fd))
 	return -1;
 
     if (fcb->map_type != data_type)
 	return convert_and_write_FtypeOtype[data_type][fcb->map_type] (fd,
 								       buf);
 
-    G_zero(G__.null_buf, fcb->cellhd.cols * sizeof(char));
+    null_buf = G__alloca(fcb->cellhd.cols);
+    G_zero(null_buf, fcb->cellhd.cols);
 
-    switch (put_raster_data
-	    (fd, buf, fcb->cur_row, 0, fcb->cellhd.cols, zeros_r_nulls,
-	     data_type)) {
+    switch (put_raster_data(
+		fd, null_buf, buf, fcb->cur_row, fcb->cellhd.cols,
+		zeros_r_nulls, data_type)) {
     case -1:
+	G__freea(null_buf);
 	return -1;
     case 0:
+	G__freea(null_buf);
 	return 1;
     }
 
@@ -927,5 +840,7 @@
     fcb->cur_row++;
 
     /* write the null row for the data row */
-    return G__put_null_value_row(fd, G__.null_buf);
+    stat = G__put_null_value_row(fd, null_buf);
+    G__freea(null_buf);
+    return stat;
 }

Modified: grass/trunk/lib/gis/set_window.c
===================================================================
--- grass/trunk/lib/gis/set_window.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/lib/gis/set_window.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -30,7 +30,7 @@
 int G_get_set_window(struct Cell_head *window)
 {
     G__init_window();
-    G_copy((char *)window, (char *)&G__.window, sizeof(*window));
+    G_copy(window, &G__.window, sizeof(*window));
 
     return 1;
 }
@@ -68,13 +68,14 @@
      */
     maskfd = G__.auto_mask > 0 ? G__.mask_fd : -1;
     for (i = 0; i < G__.fileinfo_count; i++) {
-	if (G__.fileinfo[i].open_mode == OPEN_OLD) {
-	    if (G__.fileinfo[i].cellhd.zone == window->zone &&
-		G__.fileinfo[i].cellhd.proj == window->proj)
+	struct fileinfo *fcb = &G__.fileinfo[i];
+	if (fcb->open_mode == OPEN_OLD) {
+	    if (fcb->cellhd.zone == window->zone &&
+		fcb->cellhd.proj == window->proj)
 		continue;
 	    if (i != maskfd) {
 		G_warning(_("G_set_window(): projection/zone differs from that of "
-			   "currently open raster maps"));
+			    "currently open raster maps"));
 		return -1;
 	    }
 	}
@@ -99,52 +100,48 @@
      * cell files
      */
     for (i = 0; i < G__.fileinfo_count; i++) {
-	if (G__.fileinfo[i].open_mode != OPEN_OLD &&
-	    G__.fileinfo[i].open_mode != OPEN_NEW_UNCOMPRESSED &&
-	    G__.fileinfo[i].open_mode != OPEN_NEW_COMPRESSED &&
-	    G__.fileinfo[i].open_mode != OPEN_NEW_RANDOM)
+	struct fileinfo *fcb = &G__.fileinfo[i];
+
+	if (fcb->open_mode != OPEN_OLD &&
+	    fcb->open_mode != OPEN_NEW_UNCOMPRESSED &&
+	    fcb->open_mode != OPEN_NEW_COMPRESSED)
 	    continue;
 
-	if (G__.fileinfo[i].open_mode == OPEN_OLD)
+	if (fcb->open_mode == OPEN_OLD)
 	    G__create_window_mapping(i);
 	/* code commented 10/1999 due to problems */
-	/*      else */
-	/* opened for writing */
-	/*      {
-	   G_free (G__.fileinfo[i].data);
-	   G__.fileinfo[i].data = (unsigned char *) G_calloc (G__.window.cols,
-	   G_raster_size(G__.fileinfo[i].map_type));
-	   }
-	 */
+#if 0
+	else
+	{
+	    /* opened for writing */
+	    G_free (fcb->data);
+	    fcb->data = (unsigned char *) G_calloc (G__.window.cols,
+						    G_raster_size(fcb->map_type));
+	}
+
 	/* allocate null bitstream buffers for reading/writing null rows */
-	/*      for (j=0;j< NULL_ROWS_INMEM; j++)
-	   {
-	   G_free (G__.fileinfo[i].NULL_ROWS[j]);
-	   G__.fileinfo[i].NULL_ROWS[j] = G__allocate_null_bits(G__.window.cols);
-	   }
-	 */
+	for (j=0;j< NULL_ROWS_INMEM; j++)
+	{
+	    G_free (fcb->NULL_ROWS[j]);
+	    fcb->NULL_ROWS[j] = G__allocate_null_bits(G__.window.cols);
+	}
 
+
 	/* initialize : no NULL rows in memory */
-	/*      G__.fileinfo[i].min_null_row = (-1) * NULL_ROWS_INMEM;
-	   if(G__.fileinfo[i].null_cur_row > 0)
-	   {
-	   G_warning(
-	   "Calling G_set_window() in the middle of writing map %s", 
-	   G__.fileinfo[i].name);
-	   G__.fileinfo[i].null_cur_row = 0;
-	   }
-	 */
+	fcb->min_null_row = (-1) * NULL_ROWS_INMEM;
+	if(fcb->null_cur_row > 0)
+	{
+	    G_warning(
+		"Calling G_set_window() in the middle of writing map %s", 
+		fcb->name);
+	    fcb->null_cur_row = 0;
+	}
+#endif
     }
 
     /* turn masking (back) on if necessary */
     G__check_for_auto_masking();
 
-    /* reallocate/enlarge the G__. buffers for reading raster maps */
-    G__reallocate_null_buf();
-    G__reallocate_mask_buf();
-    G__reallocate_temp_buf();
-    G__reallocate_work_buf(sizeof(DCELL));
-    G__reallocate_work_buf(XDR_DOUBLE_NBYTES);
     /* we want the number of bytes per cell to be maximum
        so that there is enough memory for reading and writing rows */
 

Modified: grass/trunk/raster/r.mapcalc/evaluate.c
===================================================================
--- grass/trunk/raster/r.mapcalc/evaluate.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/raster/r.mapcalc/evaluate.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -3,7 +3,6 @@
 #include <unistd.h>
 #ifdef USE_PTHREAD
 #include <pthread.h>
-#include <signal.h>
 #endif
 
 #include <grass/gis.h>
@@ -114,8 +113,6 @@
 
 static pthread_mutex_t worker_mutex;
 
-static pthread_mutex_t map_mutex;
-
 static void *worker(void *arg)
 {
     struct worker *w = arg;
@@ -125,10 +122,10 @@
 	while (!w->exp)
 	    pthread_cond_wait(&w->cond, &w->mutex);
 	evaluate(w->exp);
-	pthread_mutex_unlock(&w->mutex);
-
 	w->exp->worker = NULL;
 	w->exp = NULL;
+	pthread_mutex_unlock(&w->mutex);
+	pthread_cond_signal(&w->cond);
     }
 
     return NULL;
@@ -151,11 +148,14 @@
 {
     struct worker *w;
  
+    if (e->worker)
+	G_fatal_error("Expression <%s> already has a worker", format_expression(e));
+
     pthread_mutex_lock(&worker_mutex);
     w = get_worker();
+    e->worker = w;
 
     if (!w) {
-	e->worker = NULL;
 	pthread_mutex_unlock(&worker_mutex);
 	evaluate(e);
 	return;
@@ -163,7 +163,6 @@
 
     pthread_mutex_lock(&w->mutex);
     w->exp = e;
-    e->worker = w;
     pthread_cond_signal(&w->cond);
     pthread_mutex_unlock(&w->mutex);
 
@@ -178,6 +177,8 @@
 	return;
 
     pthread_mutex_lock(&w->mutex);
+    while (e->worker)
+	pthread_cond_wait(&w->cond, &w->mutex);
     pthread_mutex_unlock(&w->mutex);
 }
 
@@ -186,13 +187,13 @@
     const char *p = getenv("WORKERS");
     int i;
 
-    pthread_mutex_init(&map_mutex, NULL);
-
     pthread_mutex_init(&worker_mutex, NULL);
 
     num_workers = p ? atoi(p) : 8;
     workers = G_calloc(num_workers, sizeof(struct worker));
 
+    printf("num_workers = %d\n", num_workers);
+
     for (i = 0; i < num_workers; i++) {
 	struct worker *w = &workers[i];
 	pthread_mutex_init(&w->mutex, NULL);
@@ -205,13 +206,11 @@
 {
     int i;
 
-    pthread_mutex_destroy(&map_mutex);
-
     pthread_mutex_destroy(&worker_mutex);
 
     for (i = 0; i < num_workers; i++) {
 	struct worker *w = &workers[i];
-	pthread_kill(w->thread, SIGINT);
+	pthread_cancel(w->thread);
 	pthread_mutex_destroy(&w->mutex);
 	pthread_cond_destroy(&w->cond);
     }
@@ -255,19 +254,11 @@
 
 static void evaluate_map(expression * e)
 {
-#ifdef USE_PTHREAD
-    pthread_mutex_lock(&map_mutex);
-#endif
-
     get_map_row(e->data.map.idx,
 		e->data.map.mod,
 		current_depth + e->data.map.depth,
 		current_row + e->data.map.row,
 		e->data.map.col, e->buf, e->res_type);
-
-#ifdef USE_PTHREAD
-    pthread_mutex_unlock(&map_mutex);
-#endif
 }
 
 static void evaluate_function(expression * e)
@@ -405,7 +396,6 @@
     int count, n;
 
     setup_region();
-    setup_maps();
     setup_rand();
 
     exprs = ee;
@@ -444,6 +434,8 @@
 	e->data.bind.fd = open_output_map(var, val->res_type);
     }
 
+    setup_maps();
+
     count = rows * depths;
     n = 0;
 

Modified: grass/trunk/raster/r.mapcalc/expression.c
===================================================================
--- grass/trunk/raster/r.mapcalc/expression.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/raster/r.mapcalc/expression.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -43,6 +43,7 @@
     e->type = type;
     e->res_type = res_type;
     e->buf = NULL;
+    e->worker = NULL;
     return e;
 }
 

Modified: grass/trunk/raster/r.mapcalc/map.c
===================================================================
--- grass/trunk/raster/r.mapcalc/map.c	2008-11-22 19:16:36 UTC (rev 34443)
+++ grass/trunk/raster/r.mapcalc/map.c	2008-11-22 21:52:25 UTC (rev 34444)
@@ -3,10 +3,12 @@
 #include <limits.h>
 #include <string.h>
 #include <unistd.h>
+#ifdef USE_PTHREAD
+#include <pthread.h>
+#endif
 
 #include <grass/gis.h>
 #include <grass/btree.h>
-#include <grass/rowio.h>
 #include <grass/glocale.h>
 
 #include "mapcalc.h"
@@ -28,8 +30,22 @@
 
 /****************************************************************************/
 
-typedef struct map
+struct sub_cache
 {
+    int row;
+    char *valid;
+    void **buf;
+};
+
+struct row_cache
+{
+    int fd;
+    int nrows;
+    struct sub_cache *sub[3];
+};
+
+struct map
+{
     const char *name;
     const char *mapset;
     int have_cats;
@@ -40,45 +56,149 @@
     struct Categories cats;
     struct Colors colors;
     BTREE btree;
-    ROWIO rowio;
-} map;
+    struct row_cache cache;
+#ifdef USE_PTHREAD
+    pthread_mutex_t mutex;
+#endif
+};
 
 /****************************************************************************/
 
-static map *maps;
+static struct map *maps;
 static int num_maps;
 static int max_maps;
 
-static unsigned char *red, *grn, *blu;
-static unsigned char *set;
-
 static int min_row = INT_MAX;
 static int max_row = -INT_MAX;
 static int min_col = INT_MAX;
 static int max_col = -INT_MAX;
 
-static int max_rows_in_memory = 3;
+static int max_rows_in_memory = 8;
 
-static int read_row_type;
+#ifdef USE_PTHREAD
+static pthread_mutex_t cats_mutex;
+#endif
 
 /****************************************************************************/
 
+static void cache_sub_init(struct row_cache *cache, int data_type)
+{
+    struct sub_cache *sub = G_malloc(sizeof(struct sub_cache));
+    int i;
+
+    sub->row = -cache->nrows;
+    sub->valid = G_calloc(cache->nrows, 1);
+    sub->buf = G_malloc(cache->nrows * sizeof(void *));
+    for (i = 0; i < cache->nrows; i++)
+	sub->buf[i] = G_allocate_raster_buf(data_type);
+
+    cache->sub[data_type] = sub;
+}
+
+static void cache_setup(struct row_cache *cache, int fd, int nrows)
+{
+    cache->fd = fd;
+    cache->nrows = nrows;
+    cache->sub[CELL_TYPE] = NULL;
+    cache->sub[FCELL_TYPE] = NULL;
+    cache->sub[DCELL_TYPE] = NULL;
+};
+
+static void cache_release(struct row_cache *cache)
+{
+    int t;
+
+    for (t = 0; t < 3; t++) {
+	struct sub_cache *sub = cache->sub[t];
+	int i;
+
+	if (!sub)
+	    continue;
+
+	for (i = 0; i < cache->nrows; i++)
+	    G_free(sub->buf[i]);
+
+	G_free(sub->buf);
+	G_free(sub->valid);
+
+	G_free(sub);
+    }
+};
+
+static void *cache_get_raw(struct row_cache *cache, int row, int data_type)
+{
+    struct sub_cache *sub;
+    void **tmp;
+    char *vtmp;
+    int i, j;
+    int newrow;
+
+    if (!cache->sub[data_type])
+	cache_sub_init(cache, data_type);
+    sub = cache->sub[data_type];
+
+    i = row - sub->row;
+
+    if (i >= 0 && i < cache->nrows) {
+	if (!sub->valid[i]) {
+	    G_get_raster_row(cache->fd, sub->buf[i], row + i, data_type);
+	    sub->valid[i] = 1;
+	}
+	return sub->buf[i];
+    }
+
+    if (i <= -cache->nrows || i >= cache->nrows * 2 - 1) {
+	memset(sub->valid, 0, cache->nrows);
+	sub->row = i;
+	G_get_raster_row(cache->fd, sub->buf[0], row, data_type);
+	sub->valid[0] = 1;
+	return sub->buf[0];
+    }
+
+    tmp = G__alloca(cache->nrows * sizeof(void *));
+    memcpy(tmp, sub->buf, cache->nrows * sizeof(void *));
+    vtmp = G__alloca(cache->nrows);
+    memcpy(vtmp, sub->valid, cache->nrows);
+
+    i = (i < 0)
+	? 0
+	: cache->nrows - 1;
+    newrow = row - i;
+
+    for (j = 0; j < cache->nrows; j++) {
+	int r = newrow + j;
+	int k = r - sub->row;
+	int l = (k + cache->nrows) % cache->nrows;
+
+	sub->buf[j] = tmp[l];
+	sub->valid[j] = k >= 0 && k < cache->nrows && vtmp[l];
+    }
+
+    sub->row = newrow;
+    G__freea(tmp);
+    G__freea(vtmp);
+
+    G_get_raster_row(cache->fd, sub->buf[i], row, data_type);
+    sub->valid[i] = 1;
+
+    return sub->buf[i];
+}
+
+static void cache_get(struct row_cache *cache, void *buf, int row, int res_type)
+{
+    void *p = cache_get_raw(cache, row, res_type);
+    memcpy(buf, p, columns * G_raster_size(res_type));
+};
+
+/****************************************************************************/
+
 static int compare_ints(const void *a, const void *b)
 {
     return *(const int *)a - *(const int *)b;
 }
 
-static void init_colors(map * m)
+static void init_colors(struct map *m)
 {
-    if (!red)
-	red = G_malloc(columns);
-    if (!grn)
-	grn = G_malloc(columns);
-    if (!blu)
-	blu = G_malloc(columns);
-    if (!set)
-	set = G_malloc(columns);
-
     if (G_read_colors((char *)m->name, (char *)m->mapset, &m->colors) < 0)
 	G_fatal_error(_("Unable to read color file for raster map <%s@%s>"),
 		      m->name, m->mapset);
@@ -86,7 +206,7 @@
     m->have_colors = 1;
 }
 
-static void init_cats(map * m)
+static void init_cats(struct map *m)
 {
     if (G_read_cats((char *)m->name, (char *)m->mapset, &m->cats) < 0)
 	G_fatal_error(_("Unable to read category file of raster map <%s@%s>"),
@@ -99,9 +219,13 @@
     m->have_cats = 1;
 }
 
-static void translate_from_colors(map * m, DCELL * rast, CELL * cell,
+static void translate_from_colors(struct map *m, DCELL *rast, CELL *cell,
 				  int ncols, int mod)
 {
+    unsigned char *red = G__alloca(columns);
+    unsigned char *grn = G__alloca(columns);
+    unsigned char *blu = G__alloca(columns);
+    unsigned char *set = G__alloca(columns);
     int i;
 
     G_lookup_d_raster_colors(rast, red, grn, blu, set, ncols, &m->colors);
@@ -141,6 +265,11 @@
 	G_fatal_error(_("Invalid map modifier: '%c'"), mod);
 	break;
     }
+
+    G__freea(red);
+    G__freea(grn);
+    G__freea(blu);
+    G__freea(set);
 }
 
 /* convert cell values to double based on the values in the
@@ -166,7 +295,7 @@
 #define SHIFT 6
 #define NCATS (1<<SHIFT)
 
-static void translate_from_cats(map * m, CELL * cell, DCELL * xcell,
+static void translate_from_cats(struct map *m, CELL * cell, DCELL * xcell,
 				int ncols)
 {
     struct Categories *pcats;
@@ -178,6 +307,10 @@
     void *ptr;
     char *label;
 
+#ifdef XUSE_PTHREAD
+    pthread_mutex_lock(&cats_mutex);
+#endif
+
     btree = &m->btree;
     pcats = &m->cats;
 
@@ -221,44 +354,39 @@
 	else
 	    *xcell = values[idx];
     }
-}
 
-static void set_read_row_type(int res_type)
-{
-    read_row_type = res_type;
+#ifdef XUSE_PTHREAD
+    pthread_mutex_unlock(&cats_mutex);
+#endif
 }
 
-static int read_row(int fd, void *buf, int row, int dummy)
+static void read_row(int fd, void *buf, int row, int res_type)
 {
-    if (G_get_raster_row(fd, (DCELL *) buf, row, read_row_type) < 0)
+    if (G_get_raster_row(fd, buf, row, res_type) < 0)
 	G_fatal_error(_("Unable to read raster map row %d"), row);
-
-    return 0;
 }
 
-static void setup_map(map * m)
+static void setup_map(struct map *m)
 {
     int nrows = m->max_row - m->min_row + 1;
-    int size = (sizeof(CELL) > sizeof(double))
-	? sizeof(CELL)
-	: sizeof(double);
 
+#ifdef USE_PTHREAD
+    pthread_mutex_init(&m->mutex, NULL);
+#endif
+
     if (nrows > 1 && nrows <= max_rows_in_memory) {
-	if (rowio_setup(&m->rowio, m->fd, nrows,
-			columns * size, read_row, NULL) < 0)
-	    G_fatal_error(_("Rowio_setup failed"));
+	cache_setup(&m->cache, m->fd, nrows);
 	m->use_rowio = 1;
     }
     else
 	m->use_rowio = 0;
 }
 
-static void read_map(map * m, void *buf, int res_type, int row, int col)
+static void read_map(struct map *m, void *buf, int res_type, int row, int col)
 {
     CELL *ibuf = buf;
     FCELL *fbuf = buf;
     DCELL *dbuf = buf;
-    void *bp;
 
     if (row < 0 || row >= rows) {
 	int i;
@@ -284,23 +412,16 @@
 	return;
     }
 
-    set_read_row_type(res_type);
-
-    if (m->use_rowio) {
-	bp = rowio_get(&m->rowio, row);
-	if (!bp)
-	    G_fatal_error(_("Rowio_get failed"));
-
-	G_copy(buf, bp, columns * G_raster_size(res_type));
-    }
+    if (m->use_rowio)
+	cache_get(&m->cache, buf, row, res_type);
     else
-	read_row(m->fd, buf, row, 0);
+	read_row(m->fd, buf, row, res_type);
 
     if (col)
 	column_shift(buf, res_type, col);
 }
 
-static void close_map(map * m)
+static void close_map(struct map *m)
 {
     if (m->fd < 0)
 	return;
@@ -309,6 +430,10 @@
 	G_fatal_error(_("Unable to close raster map <%s@%s>"),
 		      m->name, m->mapset);
 
+#ifdef USE_PTHREAD
+    pthread_mutex_destroy(&m->mutex);
+#endif
+
     if (m->have_cats) {
 	btree_free(&m->btree);
 	G_free_cats(&m->cats);
@@ -321,7 +446,7 @@
     }
 
     if (m->use_rowio) {
-	rowio_release(&m->rowio);
+	cache_release(&m->cache);
 	m->use_rowio = 0;
     }
 }
@@ -361,7 +486,8 @@
     char *mapset;
     int use_cats = 0;
     int use_colors = 0;
-    map *m;
+    struct map *m;
+    int fd;
 
     if (row < min_row)
 	min_row = row;
@@ -372,10 +498,14 @@
     if (col > max_col)
 	max_col = col;
 
-    mapset = G_find_cell2((char *)name, "");
+    mapset = G_find_cell2(name, "");
     if (!mapset)
 	G_fatal_error(_("Raster map <%s> not found"), name);
 
+    fd = G_open_cell_old(name, mapset);
+    if (fd < 0)
+	G_fatal_error(_("Unable to open raster map <%s@%s>"), name, mapset);
+
     switch (mod) {
     case 'M':
 	break;
@@ -418,7 +548,7 @@
 
     if (num_maps >= max_maps) {
 	max_maps += 10;
-	maps = G_realloc(maps, max_maps * sizeof(map));
+	maps = G_realloc(maps, max_maps * sizeof(struct map));
     }
 
     m = &maps[num_maps];
@@ -430,13 +560,14 @@
     m->use_rowio = 0;
     m->min_row = row;
     m->max_row = row;
+    m->fd = fd;
 
     if (use_cats)
 	init_cats(m);
     if (use_colors)
 	init_colors(m);
 
-    m->fd = G_open_cell_old((char *)name, mapset);
+    m->fd = G_open_cell_old(name, mapset);
 
     if (m->fd < 0)
 	G_fatal_error(_("Unable to open raster map <%s@%s>"), name, mapset);
@@ -448,6 +579,10 @@
 {
     int i;
 
+#ifdef USE_PTHREAD
+    pthread_mutex_init(&cats_mutex, NULL);
+#endif
+
     for (i = 0; i < num_maps; i++)
 	setup_map(&maps[i]);
 }
@@ -455,19 +590,23 @@
 void get_map_row(int idx, int mod, int depth, int row, int col, void *buf,
 		 int res_type)
 {
-    static CELL *ibuf;
-    static DCELL *fbuf;
-    map *m = &maps[idx];
+    CELL *ibuf;
+    DCELL *fbuf;
+    struct map *m = &maps[idx];
 
+#ifdef USE_PTHREAD
+    pthread_mutex_lock(&m->mutex);
+#endif
+
     switch (mod) {
     case 'M':
 	read_map(m, buf, res_type, row, col);
 	break;
     case '@':
-	if (!ibuf)
-	    ibuf = G_malloc(columns * sizeof(CELL));
+	ibuf = G__alloca(columns * sizeof(CELL));
 	read_map(m, ibuf, CELL_TYPE, row, col);
 	translate_from_cats(m, ibuf, buf, columns);
+	G__freea(ibuf);
 	break;
     case 'r':
     case 'g':
@@ -475,15 +614,19 @@
     case '#':
     case 'y':
     case 'i':
-	if (!fbuf)
-	    fbuf = G_malloc(columns * sizeof(DCELL));
+	fbuf = G__alloca(columns * sizeof(DCELL));
 	read_map(m, fbuf, DCELL_TYPE, row, col);
 	translate_from_colors(m, fbuf, buf, columns, mod);
+	G__freea(fbuf);
 	break;
     default:
 	G_fatal_error(_("Invalid map modifier: '%c'"), mod);
 	break;
     }
+
+#ifdef USE_PTHREAD
+    pthread_mutex_unlock(&m->mutex);
+#endif
 }
 
 void close_maps(void)
@@ -494,6 +637,10 @@
 	close_map(&maps[i]);
 
     num_maps = 0;
+
+#ifdef USE_PTHREAD
+    pthread_mutex_destroy(&cats_mutex);
+#endif
 }
 
 /****************************************************************************/
@@ -535,7 +682,7 @@
 
 void copy_cats(const char *dst, int idx)
 {
-    const map *m = &maps[idx];
+    const struct map *m = &maps[idx];
     struct Categories cats;
 
     if (G_read_cats((char *)m->name, (char *)m->mapset, &cats) < 0)
@@ -547,7 +694,7 @@
 
 void copy_colors(const char *dst, int idx)
 {
-    const map *m = &maps[idx];
+    const struct map *m = &maps[idx];
     struct Colors colr;
 
     if (G_read_colors((char *)m->name, (char *)m->mapset, &colr) <= 0)
@@ -559,7 +706,7 @@
 
 void copy_history(const char *dst, int idx)
 {
-    const map *m = &maps[idx];
+    const struct map *m = &maps[idx];
     struct History hist;
 
     if (G_read_history((char *)m->name, (char *)m->mapset, &hist) < 0)



More information about the grass-commit mailing list