[GRASS-SVN] r39943 - grass-addons/grass7/raster/r.clump2
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Dec 8 04:57:20 EST 2009
Author: mmetz
Date: 2009-12-08 04:57:20 -0500 (Tue, 08 Dec 2009)
New Revision: 39943
Added:
grass-addons/grass7/raster/r.clump2/Makefile
grass-addons/grass7/raster/r.clump2/flag.c
grass-addons/grass7/raster/r.clump2/flag.h
grass-addons/grass7/raster/r.clump2/local_proto.h
grass-addons/grass7/raster/r.clump2/main.c
grass-addons/grass7/raster/r.clump2/pq.c
grass-addons/grass7/raster/r.clump2/r.clump2.html
grass-addons/grass7/raster/r.clump2/ramseg.c
grass-addons/grass7/raster/r.clump2/ramseg.h
Log:
adding r.clump2
Added: grass-addons/grass7/raster/r.clump2/Makefile
===================================================================
--- grass-addons/grass7/raster/r.clump2/Makefile (rev 0)
+++ grass-addons/grass7/raster/r.clump2/Makefile 2009-12-08 09:57:20 UTC (rev 39943)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.clump2
+
+LIBES = $(RASTERLIB) $(GISLIB)
+DEPENDENCIES = $(RASTERDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
Added: grass-addons/grass7/raster/r.clump2/flag.c
===================================================================
--- grass-addons/grass7/raster/r.clump2/flag.c (rev 0)
+++ grass-addons/grass7/raster/r.clump2/flag.c 2009-12-08 09:57:20 UTC (rev 39943)
@@ -0,0 +1,68 @@
+#include <grass/gis.h>
+#include "flag.h"
+
+FLAG *flag_create(int nrows, int ncols)
+{
+ unsigned char *temp;
+ FLAG *new_flag;
+ register int i;
+
+ new_flag = (FLAG *) G_malloc(sizeof(FLAG));
+ new_flag->nrows = nrows;
+ new_flag->ncols = ncols;
+ new_flag->leng = (ncols + 7) / 8;
+ new_flag->array =
+ (unsigned char **)G_malloc(nrows * sizeof(unsigned char *));
+
+ temp =
+ (unsigned char *)G_malloc(nrows * new_flag->leng *
+ sizeof(unsigned char));
+
+ for (i = 0; i < nrows; i++) {
+ new_flag->array[i] = temp;
+ temp += new_flag->leng;
+ }
+
+ return (new_flag);
+}
+
+int flag_destroy(FLAG * flags)
+{
+ G_free(flags->array[0]);
+ G_free(flags->array);
+ G_free(flags);
+
+ return 0;
+}
+
+int flag_set(FLAG * flags, int row, int col)
+{
+ flags->array[row][col >> 3] |= (1 << (col & 7));
+
+ return 0;
+}
+
+int flag_unset(FLAG * flags, int row, int col)
+{
+ flags->array[row][col >> 3] &= ~(1 << (col & 7));
+
+ return 0;
+}
+
+int flag_get(FLAG * flags, int row, int col)
+{
+ return (flags->array[row][col >> 3] & (1 << (col & 7)));
+}
+
+int flag_clear_all(FLAG * flags)
+{
+ register int r, c;
+
+ for (r = 0; r < flags->nrows; r++) {
+ for (c = 0; c < flags->leng; c++) {
+ flags->array[r][c] = 0;
+ }
+ }
+
+ return 0;
+}
Added: grass-addons/grass7/raster/r.clump2/flag.h
===================================================================
--- grass-addons/grass7/raster/r.clump2/flag.h (rev 0)
+++ grass-addons/grass7/raster/r.clump2/flag.h 2009-12-08 09:57:20 UTC (rev 39943)
@@ -0,0 +1,66 @@
+#ifndef __FLAG_H__
+#define __FLAG_H__
+
+/* flag.[ch] is a set of routines which will set up an array of bits
+ ** that allow the programmer to "flag" cells in a raster map.
+ **
+ ** FLAG *
+ ** flag_create(nrows,ncols)
+ ** int nrows, ncols;
+ ** opens the structure flag.
+ ** The flag structure will be a two dimensional array of bits the
+ ** size of nrows by ncols. Will initalize flags to zero (unset).
+ **
+ ** flag_destroy(flags)
+ ** FLAG *flags;
+ ** closes flags and gives the memory back to the system.
+ **
+ ** flag_clear_all(flags)
+ ** FLAG *flags;
+ ** sets all values in flags to zero.
+ **
+ ** flag_unset(flags, row, col)
+ ** FLAG *flags;
+ ** int row, col;
+ ** sets the value of (row, col) in flags to zero.
+ **
+ ** flag_set(flags, row, col)
+ ** FLAG *flags;
+ ** int row, col;
+ ** will set the value of (row, col) in flags to one.
+ **
+ ** int
+ ** flag_get(flags, row, col)
+ ** FLAG *flags;
+ ** int row, col;
+ ** returns the value in flags that is at (row, col).
+ **
+ ** idea by Michael Shapiro
+ ** code by Chuck Ehlschlaeger
+ ** April 03, 1989
+ */
+
+#define FLAG struct _flagsss_
+FLAG {
+ int nrows, ncols, leng;
+ unsigned char **array;
+};
+
+#define FLAG_UNSET(flags,row,col) \
+ (flags)->array[(row)][(col)>>3] &= ~(1<<((col) & 7))
+
+#define FLAG_SET(flags,row,col) \
+ (flags)->array[(row)][(col)>>3] |= (1<<((col) & 7))
+
+#define FLAG_GET(flags,row,col) \
+ (flags)->array[(row)][(col)>>3] & (1<<((col) & 7))
+
+/* flag.c */
+int flag_clear_all(FLAG *);
+FLAG *flag_create(int, int);
+int flag_destroy(FLAG *);
+int flag_get(FLAG *, int, int);
+int flag_set(FLAG *, int, int);
+int flag_unset(FLAG *, int, int);
+
+#endif /* __FLAG_H__ */
Added: grass-addons/grass7/raster/r.clump2/local_proto.h
===================================================================
--- grass-addons/grass7/raster/r.clump2/local_proto.h (rev 0)
+++ grass-addons/grass7/raster/r.clump2/local_proto.h 2009-12-08 09:57:20 UTC (rev 39943)
@@ -0,0 +1,37 @@
+
+/****************************************************************************
+ *
+ * MODULE: r.clump
+ *
+ * AUTHOR(S): Michael Shapiro - CERL
+ *
+ * PURPOSE: Recategorizes data in a raster map layer by grouping cells
+ * that form physically discrete areas into unique categories.
+ *
+ * COPYRIGHT: (C) 2006 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ***************************************************************************/
+
+#ifndef __LOCAL_PROTO_H__
+#define __LOCAL_PROTO_H__
+
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include "flag.h"
+#include "ramseg.h"
+
+extern long pqsize;
+extern CELL *clump_id;
+
+/* pq.c */
+int init_pq(int);
+int free_pq(void);
+int add_pnt(long);
+long drop_pnt(void);
+
+
+#endif /* __LOCAL_PROTO_H__ */
Added: grass-addons/grass7/raster/r.clump2/main.c
===================================================================
--- grass-addons/grass7/raster/r.clump2/main.c (rev 0)
+++ grass-addons/grass7/raster/r.clump2/main.c 2009-12-08 09:57:20 UTC (rev 39943)
@@ -0,0 +1,253 @@
+
+/****************************************************************************
+ *
+ * MODULE: r.clump2
+ *
+ * AUTHOR(S): Markus Metz
+ *
+ * PURPOSE: Recategorizes data in a raster map layer by grouping cells
+ * that form physically discrete areas into unique categories.
+ *
+ * COPYRIGHT: (C) 2009 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ***************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <math.h>
+#include "local_proto.h"
+#include <grass/glocale.h>
+
+CELL *clump_id;
+long pqsize;
+
+int main(int argc, char *argv[])
+{
+ struct Colors colr;
+ struct Range range;
+ CELL min, max;
+ int in_fd, out_fd;
+ char title[512];
+ char name[GNAME_MAX];
+ struct GModule *module;
+ struct Option *opt_in;
+ struct Option *opt_out;
+ struct Option *opt_title;
+ struct Flag *sides_flag;
+ CELL clump_no, *out_buf;
+ struct Cell_head window, cellhd;
+ int nrows, ncols, r, c;
+ long ncells, counter;
+ void *in_ptr, *in_buf;
+ int map_type, in_size;
+ FLAG *inlist;
+ int ramseg;
+ long index, index_nbr;
+ int sides, s, r_nbr, c_nbr;
+ int nextdr[8] = { 1, -1, 0, 0, -1, 1, 1, -1 };
+ int nextdc[8] = { 0, 0, -1, 1, 1, -1, 1, -1 };
+
+ G_gisinit(argv[0]);
+
+ /* Define the different options */
+
+ module = G_define_module();
+ G_add_keyword(_("raster"));
+ G_add_keyword(_("statistics"));
+ G_add_keyword(_("reclass"));
+ module->description =
+ _("Recategorizes data in a raster map by grouping cells "
+ "that form physically discrete areas into unique categories.");
+
+ opt_in = G_define_standard_option(G_OPT_R_INPUT);
+
+ opt_out = G_define_standard_option(G_OPT_R_OUTPUT);
+
+ opt_title = G_define_option();
+ opt_title->key = "title";
+ opt_title->type = TYPE_STRING;
+ opt_title->required = NO;
+ opt_title->description = _("Title");
+
+ sides_flag = G_define_flag();
+ sides_flag->key = 'e';
+ sides_flag->description = _("Ignore diagonal cells");
+
+
+ /* parse options */
+ if (G_parser(argc, argv))
+ exit(EXIT_FAILURE);
+
+ in_fd = Rast_open_old(opt_in->answer, "");
+ if (in_fd < 0)
+ G_fatal_error(_("Unable to open raster map <%s>"), opt_in->answer);
+
+ out_fd = Rast_open_c_new(opt_out->answer);
+ if (out_fd < 0)
+ G_fatal_error(_("Unable to create raster map <%s>"), opt_out->answer);
+
+ if (sides_flag->answer)
+ sides = 4;
+ else
+ sides = 8;
+
+ /* some checks */
+ G_get_set_window(&window);
+ Rast_get_cellhd(opt_in->answer, "", &cellhd);
+
+ if (fabs(window.ew_res - cellhd.ew_res) > GRASS_EPSILON ||
+ fabs(window.ns_res - cellhd.ns_res) > GRASS_EPSILON) {
+ G_warning(_("Current region resolution and raster map resolution mismatch!"));
+ G_warning(_("Real clumps may not be presented"));
+ G_warning("ew diff %e", window.ew_res - cellhd.ew_res);
+ G_warning("ns diff %e", window.ns_res - cellhd.ns_res);
+ }
+
+ nrows = window.rows;
+ ncols = window.cols;
+
+ if ((double)nrows * ncols > LONG_MAX)
+ G_fatal_error(_("Current region is too large, can't process raster map <%s>"),
+ opt_in->answer);
+
+ /* allocate space */
+ clump_id =
+ (CELL *) G_malloc(size_array(&ramseg, nrows, ncols) * sizeof(CELL));
+
+ /* read input */
+ map_type = Rast_get_map_type(in_fd);
+ in_size = Rast_cell_size(map_type);
+ in_buf = Rast_allocate_buf(map_type);
+
+ inlist = flag_create(nrows, ncols);
+
+ G_message(_("load input map ..."));
+ for (r = 0; r < nrows; r++) {
+ Rast_get_row(in_fd, in_buf, r, map_type);
+ in_ptr = in_buf;
+ G_percent(r, nrows, 2);
+ for (c = 0; c < ncols; c++) {
+ index = SEG_INDEX(ramseg, r, c);
+ if (Rast_is_null_value(in_ptr, map_type))
+ clump_id[index] = 0;
+ else
+ clump_id[index] = 1;
+
+ FLAG_UNSET(inlist, r, c);
+
+ in_ptr = G_incr_void_ptr(in_ptr, in_size);
+ }
+ }
+ G_percent(nrows, nrows, 2);
+
+ Rast_close(in_fd);
+ G_free(in_buf);
+
+ /* determine clumps */
+ G_message(_("determine clumps ..."));
+
+ ncells = nrows * ncols;
+ counter = 1;
+
+ /* initialize priority queue */
+ init_pq(nrows * ncols * 0.02);
+
+ clump_no = 1;
+ index = SEG_INDEX(ramseg, 0, 0);
+ if (clump_id[index] != 0)
+ clump_id[index] = clump_no++;
+ add_pnt(index);
+ FLAG_SET(inlist, 0, 0);
+
+ while (pqsize > 0) {
+ int start_new = 1;
+
+ G_percent(counter++, ncells, 2);
+
+ index = drop_pnt();
+ seg_index_rc(ramseg, index, &r, &c);
+
+ for (s = 0; s < sides; s++) {
+ r_nbr = r + nextdr[s];
+ c_nbr = c + nextdc[s];
+ if (r_nbr >= 0 && r_nbr < nrows && c_nbr >= 0 && c_nbr < ncols) {
+
+ if ((FLAG_GET(inlist, r_nbr, c_nbr)) == 0) {
+
+ index_nbr = SEG_INDEX(ramseg, r_nbr, c_nbr);
+
+ /* not in clump, start new clump */
+ if (clump_id[index] == 0 && clump_id[index_nbr] != 0) {
+ /* skip other neighbors of same or other clump */
+ if (start_new) {
+ clump_id[index_nbr] = clump_no++;
+ add_pnt(index_nbr);
+ FLAG_SET(inlist, r_nbr, c_nbr);
+ start_new = 0;
+ }
+ }
+ else if (clump_id[index] == 0 && clump_id[index_nbr] == 0) {
+ add_pnt(index_nbr);
+ FLAG_SET(inlist, r_nbr, c_nbr);
+ }
+ else if (clump_id[index] != 0) {
+ if (clump_id[index_nbr] != 0)
+ clump_id[index_nbr] = clump_id[index];
+
+ add_pnt(index_nbr);
+ FLAG_SET(inlist, r_nbr, c_nbr);
+ }
+ }
+ }
+ }
+ }
+ free_pq();
+
+ if (counter < ncells)
+ G_warning("missed some cells!");
+
+ flag_destroy(inlist);
+
+ /* write output */
+ G_message(_("write output map ..."));
+ out_buf = Rast_allocate_buf(CELL_TYPE);
+ for (r = 0; r < nrows; r++) {
+ G_percent(r, nrows, 2);
+ for (c = 0; c < ncols; c++) {
+ index = SEG_INDEX(ramseg, r, c);
+ if (clump_id[index] == 0)
+ Rast_set_c_null_value(&out_buf[c], 1);
+ else
+ out_buf[c] = clump_id[index];
+
+ }
+ Rast_put_row(out_fd, out_buf, CELL_TYPE);
+ }
+ G_percent(nrows, nrows, 2);
+ G_free(out_buf);
+ Rast_close(out_fd);
+ G_free(clump_id);
+
+ G_debug(1, "Creating support files...");
+
+ /* build title */
+ if (opt_title->answer != NULL)
+ strcpy(title, opt_title->answer);
+ else
+ sprintf(title, "clump of <%s@%s>", name, G_mapset());
+
+ Rast_put_cell_title(opt_out->answer, title);
+ Rast_read_range(opt_out->answer, G_mapset(), &range);
+ Rast_get_range_min_max(&range, &min, &max);
+ Rast_make_random_colors(&colr, min, max);
+ Rast_write_colors(opt_out->answer, G_mapset(), &colr);
+
+ G_done_msg(_("%d clumps."), range.max);
+
+ exit(EXIT_SUCCESS);
+}
Added: grass-addons/grass7/raster/r.clump2/pq.c
===================================================================
--- grass-addons/grass7/raster/r.clump2/pq.c (rev 0)
+++ grass-addons/grass7/raster/r.clump2/pq.c 2009-12-08 09:57:20 UTC (rev 39943)
@@ -0,0 +1,148 @@
+
+/****************************************************************************
+ *
+ * MODULE: r.clump2
+ *
+ * AUTHOR(S): Markus Metz
+ *
+ * PURPOSE: Recategorizes data in a raster map layer by grouping cells
+ * that form physically discrete areas into unique categories.
+ *
+ * COPYRIGHT: (C) 2009 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ***************************************************************************/
+
+#include <stdlib.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+#define GET_PARENT(c) (int) (((c) - 2) / 3 + 1)
+#define GET_CHILD(p) (int) (((p) * 3) - 1)
+
+static int heap_alloced = 0;
+static int heap_step;
+static long *heap_index;
+
+int init_pq(int step)
+{
+ pqsize = 0;
+ if (step < 100)
+ step = 100;
+
+ heap_alloced = heap_step = step;
+ heap_index = (long *)G_malloc(heap_alloced * sizeof(long));
+
+ return 0;
+}
+
+int free_pq(void)
+{
+ if (heap_alloced)
+ G_free(heap_index);
+
+ return 0;
+}
+
+long sift_up(long start, long child_pnt)
+{
+ register long parent, child;
+
+ child = start;
+
+ while (child > 1) {
+ parent = GET_PARENT(child);
+
+ /* child is larger */
+ if (clump_id[child_pnt] > clump_id[heap_index[parent]]) {
+ /* push parent point down */
+ heap_index[child] = heap_index[parent];
+ child = parent;
+ }
+ else
+ /* no more sifting up, found new slot for child */
+ break;
+ }
+
+ /* put point in new slot */
+ if (child < start) {
+ heap_index[child] = child_pnt;
+ }
+
+ return child;
+}
+
+int add_pnt(long index)
+{
+ pqsize++;
+ if (pqsize >= heap_alloced) {
+ heap_alloced += heap_step;
+ heap_index =
+ (long *)G_realloc((void *)heap_index,
+ heap_alloced * sizeof(long));
+ }
+
+ heap_index[pqsize] = index;
+ sift_up(pqsize, index);
+
+ return 0;
+}
+
+long drop_pnt(void)
+{
+ register long parent, child, childr, i;
+ long next_index;
+
+ if (pqsize == 0)
+ return -1;
+
+ next_index = heap_index[1];
+
+ if (pqsize == 1) {
+ pqsize--;
+
+ heap_index[1] = -1;
+
+ return next_index;
+ }
+
+ /* start with root */
+ parent = 1;
+
+ /* sift down: move hole back towards bottom of heap */
+
+ while ((child = GET_CHILD(parent)) <= pqsize) {
+ if (child < pqsize) {
+ childr = child + 1;
+ i = child + 3;
+ /* get largest child */
+ while (childr < i && childr <= pqsize) {
+ if (clump_id[heap_index[childr]] >
+ clump_id[heap_index[child]]) {
+ child = childr;
+ }
+ childr++;
+ }
+ }
+
+ /* move hole down */
+ heap_index[parent] = heap_index[child];
+ parent = child;
+ }
+
+ /* hole is in lowest layer, move to heap end */
+ if (parent < pqsize) {
+ heap_index[parent] = heap_index[pqsize];
+
+ /* sift up last swapped point, only necessary if hole moved to heap end */
+ sift_up(parent, heap_index[parent]);
+ }
+
+ /* the actual drop */
+ pqsize--;
+
+ return next_index;
+}
Added: grass-addons/grass7/raster/r.clump2/r.clump2.html
===================================================================
--- grass-addons/grass7/raster/r.clump2/r.clump2.html (rev 0)
+++ grass-addons/grass7/raster/r.clump2/r.clump2.html 2009-12-08 09:57:20 UTC (rev 39943)
@@ -0,0 +1,48 @@
+<h2>DESCRIPTION</h2>
+
+<em>r.clump2</em> finds all areas of contiguous cell category values in the
+input raster map layer <em>name.</em> It assigns a unique category value
+to each such area ("clump") in the resulting output raster map layer
+<em>name.</em>
+
+<h4>Differences to r.clump</h4>
+
+Category distinctions in the input raster map layer are NOT preserved.
+This means that if distinct category values are adjacent, they will be
+clumped together if possible.
+<p>
+Contrary to r.clump, NULL cells are ignored and not clumped.
+<p>
+<em>r.clump2</em> also consideres diagonal cells. <em>r.clump2</em> can
+be forced to consider only edge cells with the <em>e</em> flag, diagonal
+cells are now ignored.
+<p>
+Linear elements (lines that are a single cell wide) are without the
+<em>e</em> flag always clumped together.
+<p>
+
+
+<h2>NOTES</h2>
+
+A random color table and other support files are
+generated for the <em>output</em> raster map layer.
+
+<h2>SEE ALSO</h2>
+
+<em><a href="r.clump.html">r.clump</a></em><br>
+<em><a href="r.average.html">r.average</a></em><br>
+<em><a href="r.buffer.html">r.buffer</a></em><br>
+<em><a href="r.grow.html">r.grow</a></em><br>
+<em><a href="r.mapcalc.html">r.mapcalc</a></em><br>
+<em><a href="r.mfilter.html">r.mfilter</a></em><br>
+<em><a href="r.neighbors.html">r.neighbors</a></em><br>
+<em><a href="r.to.vect.html">r.to.vect</a></em><br>
+<em><a href="r.reclass.html">r.reclass</a></em><br>
+<em><a href="r.statistics.html">r.statistics</a></em><br>
+<em><a href="r.support.html">r.support</a></em>
+
+<h2>AUTHOR</h2>
+
+Markus Metz
+
+<p><i>Last changed: $Date: 2009-12-08 10:16:42 -0200 (Tue, 08 Dec 2009) $</i>
Added: grass-addons/grass7/raster/r.clump2/ramseg.c
===================================================================
--- grass-addons/grass7/raster/r.clump2/ramseg.c (rev 0)
+++ grass-addons/grass7/raster/r.clump2/ramseg.c 2009-12-08 09:57:20 UTC (rev 39943)
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include "ramseg.h"
+
+int size_array(int *ram_seg, int nrows, int ncols)
+{
+ int size, segs_in_col;
+
+ segs_in_col = ((nrows - 1) >> RAMSEGBITS) + 1;
+ *ram_seg = ((ncols - 1) >> RAMSEGBITS) + 1;
+ size = ((((nrows - 1) >> RAMSEGBITS) + 1) << RAMSEGBITS) *
+ ((((ncols - 1) >> RAMSEGBITS) + 1) << RAMSEGBITS);
+ size -= ((segs_in_col << RAMSEGBITS) - nrows) << RAMSEGBITS;
+ size -= (*ram_seg << RAMSEGBITS) - ncols;
+ return (size);
+}
+
+/* get r, c from seg_index */
+int seg_index_rc(int ramseg, int seg_index, int *r, int *c)
+{
+ int seg_no, seg_remainder;
+
+ seg_no = seg_index >> DOUBLEBITS;
+ seg_remainder = seg_index - (seg_no << DOUBLEBITS);
+ *r = ((seg_no / ramseg) << RAMSEGBITS) + (seg_remainder >> RAMSEGBITS);
+ *c = ((seg_no - ((*r) >> RAMSEGBITS) * ramseg) << RAMSEGBITS) +
+ seg_remainder - (((*r) & SEGLENLESS) << RAMSEGBITS);
+ return seg_no;
+}
Added: grass-addons/grass7/raster/r.clump2/ramseg.h
===================================================================
--- grass-addons/grass7/raster/r.clump2/ramseg.h (rev 0)
+++ grass-addons/grass7/raster/r.clump2/ramseg.h 2009-12-08 09:57:20 UTC (rev 39943)
@@ -0,0 +1,17 @@
+#ifndef __RAMSEG_H__
+#define __RAMSEG_H__
+
+
+#define RAMSEG int
+#define RAMSEGBITS 4
+#define DOUBLEBITS 8 /* 2 * ramsegbits */
+#define SEGLENLESS 15 /* 2 ^ ramsegbits - 1 */
+
+#define SEG_INDEX(s,r,c) (int) \
+ (((((r) >> RAMSEGBITS) * (s) + ((c) >> RAMSEGBITS)) << DOUBLEBITS) \
+ + (((r) & SEGLENLESS) << RAMSEGBITS) + ((c) & SEGLENLESS))
+
+int size_array(int *, int, int);
+int seg_index_rc(int, int, int *, int *);
+
+#endif /* __RAMSEG_H__ */
More information about the grass-commit
mailing list