[GRASS-SVN] r53806 - in grass/trunk/raster3d: . r3.in.bin r3.in.bin/test_suite r3.out.bin

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Nov 14 07:09:32 PST 2012


Author: huhabla
Date: 2012-11-14 07:09:32 -0800 (Wed, 14 Nov 2012)
New Revision: 53806

Added:
   grass/trunk/raster3d/r3.in.bin/
   grass/trunk/raster3d/r3.in.bin/Makefile
   grass/trunk/raster3d/r3.in.bin/main.c
   grass/trunk/raster3d/r3.in.bin/r3.in.bin.html
   grass/trunk/raster3d/r3.in.bin/test_suite/
   grass/trunk/raster3d/r3.in.bin/test_suite/test.r3.in.bin.sh
   grass/trunk/raster3d/r3.in.bin/test_suite/test_out_bin_double.ref
   grass/trunk/raster3d/r3.in.bin/test_suite/test_out_bin_float.ref
Modified:
   grass/trunk/raster3d/Makefile
   grass/trunk/raster3d/r3.out.bin/main.c
Log:
New module to import 3D raster binary data as 3D raster maps.


Modified: grass/trunk/raster3d/Makefile
===================================================================
--- grass/trunk/raster3d/Makefile	2012-11-14 14:58:01 UTC (rev 53805)
+++ grass/trunk/raster3d/Makefile	2012-11-14 15:09:32 UTC (rev 53806)
@@ -4,6 +4,7 @@
 	r3.cross.rast \
 	r3.gwflow \
 	r3.in.ascii \
+	r3.in.bin \
 	r3.in.v5d \
 	r3.info \
 	r3.mask \

Added: grass/trunk/raster3d/r3.in.bin/Makefile
===================================================================
--- grass/trunk/raster3d/r3.in.bin/Makefile	                        (rev 0)
+++ grass/trunk/raster3d/r3.in.bin/Makefile	2012-11-14 15:09:32 UTC (rev 53806)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = r3.in.bin
+
+LIBES = $(RASTERLIB) $(RASTER3DLIB) $(GISLIB)
+DEPENDENCIES = $(RASTERDEP) $(RASTER3DDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd

Added: grass/trunk/raster3d/r3.in.bin/main.c
===================================================================
--- grass/trunk/raster3d/r3.in.bin/main.c	                        (rev 0)
+++ grass/trunk/raster3d/r3.in.bin/main.c	2012-11-14 15:09:32 UTC (rev 53806)
@@ -0,0 +1,491 @@
+/*
+ *   r.in.bin
+ *
+ *   Copyright (C) 2000 by the GRASS Development Team
+ *   Author: Bob Covill <bcovill tekmap.ns.ca>
+ *
+ *   This program is free software under the GPL (>=v2)
+ *   Read the file COPYING coming with GRASS for details.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/raster3d.h>
+#include <grass/glocale.h>
+
+/* Some global variables */
+RASTER3D_Map *map;
+RASTER3D_Region region;
+FILE *fp;
+unsigned char *in_cell;
+
+static void swap_2(void *p) {
+	unsigned char *q = p;
+	unsigned char t;
+	t = q[0];
+	q[0] = q[1];
+	q[1] = t;
+}
+
+static void swap_4(void *p) {
+	unsigned char *q = p;
+	unsigned char t;
+	t = q[0];
+	q[0] = q[3];
+	q[3] = t;
+	t = q[1];
+	q[1] = q[2];
+	q[2] = t;
+}
+
+static void swap_8(void *p) {
+	unsigned char *q = p;
+	unsigned char t;
+	t = q[0];
+	q[0] = q[7];
+	q[7] = t;
+	t = q[1];
+	q[1] = q[6];
+	q[6] = t;
+	t = q[2];
+	q[2] = q[5];
+	q[5] = t;
+	t = q[3];
+	q[3] = q[4];
+	q[4] = t;
+}
+
+static void read_cell(DCELL *out_cell, int is_integer, int is_signed, int bytes,
+		int byte_swap) {
+
+	if (fread(in_cell, bytes, 1, fp) != 1)
+		G_fatal_error(_("Error reading binary data"));
+
+	if (byte_swap) {
+		switch (bytes) {
+		case 1:
+			break;
+		case 2:
+			swap_2(in_cell);
+			break;
+		case 4:
+			swap_4(in_cell);
+			break;
+		case 8:
+			swap_8(in_cell);
+			break;
+		}
+	}
+
+	if (!is_integer) {
+		switch (bytes) {
+		case 4:
+			*out_cell = (DCELL) *(float *) in_cell;
+			break;
+		case 8:
+			*out_cell = (DCELL) *(double *) in_cell;
+			break;
+		}
+	} else if (is_signed) {
+		switch (bytes) {
+		case 1:
+			*out_cell = (DCELL) *(signed char *) in_cell;
+			break;
+		case 2:
+			*out_cell = (DCELL) *(short *) in_cell;
+			break;
+		case 4:
+			*out_cell = (DCELL) *(int *) in_cell;
+			break;
+#ifdef HAVE_LONG_LONG_INT
+		case 8:
+			*out_cell = (DCELL) *(long long *) in_cell;
+			break;
+#endif
+		}
+	} else {
+		switch (bytes) {
+		case 1:
+			*out_cell = (DCELL) *(unsigned char *) in_cell;
+			break;
+		case 2:
+			*out_cell = (DCELL) *(unsigned short *) in_cell;
+			break;
+		case 4:
+			*out_cell = (DCELL) *(unsigned int *) in_cell;
+			break;
+#ifdef HAVE_LONG_LONG_INT
+		case 8:
+			*out_cell = (DCELL) *(unsigned long long *) in_cell;
+			break;
+#endif
+		}
+	}
+}
+
+static void bin_to_raster3d(char *null, int map_type, int is_integer,
+		int is_signed, int bytes, int byte_swap, int row_swap, int depth_swap) {
+	int x, y, z;
+	int col, row, depth;
+	DCELL value;
+	FCELL fvalue;
+	DCELL null_value;
+	int tileX, tileY, tileZ;
+
+	if (null)
+		null_value = atof(null);
+
+	Rast3d_get_tile_dimensions_map(map, &tileX, &tileY, &tileZ);
+	Rast3d_min_unlocked(map, RASTER3D_USE_CACHE_X);
+
+	Rast3d_autolock_on(map);
+	Rast3d_unlock_all(map);
+	G_message(_("Loading %s data with %i  bytes ...  (%dx%dx%d)"),
+			(is_integer? "integer":"floating point "), bytes, region.cols,
+			region.rows, region.depths);
+
+	for (z = 0; z < region.depths; z++) {
+		G_percent(z, region.depths, 1);
+
+		if ((z % tileZ) == 0)
+			Rast3d_unlock_all(map);
+
+		for (y = 0; y < region.rows; y++) {/* go south to north */
+			for (x = 0; x < region.cols; x++) {
+
+				/* From west to east */
+				col = x;
+				/* The default is to read rows from north to south */
+				row = y;
+				/* From bottom to the top */
+				depth = z;
+
+				/* Read rows as from south to north */
+				if (row_swap)
+					row = region.rows - y - 1;
+
+				/* Read XY layer from top to bottom */
+				if (depth_swap)
+					depth = region.depths - z - 1;
+
+				/* Read value from binary file */
+				read_cell(&value, is_integer, is_signed, bytes, byte_swap);
+
+				/* Write value to the 3D raster map */
+				if (map_type == DCELL_TYPE) {
+					if (null && value == null_value)
+						Rast3d_set_null_value(&value, 1, DCELL_TYPE);
+					Rast3d_put_double(map, col, row, depth, value);
+				} else {
+					fvalue = (FCELL) value;
+					if (null && value == null_value)
+						Rast3d_set_null_value(&fvalue, 1, FCELL_TYPE);
+					Rast3d_put_double(map, col, row, depth, fvalue);
+
+				}
+			}
+		}
+	}
+
+	if (!Rast3d_flush_all_tiles(map))
+		G_fatal_error(_("Error flushing tiles"));
+
+	Rast3d_autolock_off(map);
+	Rast3d_unlock_all(map);
+
+	G_percent(1, 1, 1);
+}
+
+int main(int argc, char *argv[]) {
+	struct GModule *module;
+	struct {
+		struct Option *input;
+		struct Option *output;
+		struct Option *null;
+		struct Option *bytes;
+		struct Option *order;
+		struct Option *north;
+		struct Option *south;
+		struct Option *top;
+		struct Option *bottom;
+		struct Option *east;
+		struct Option *west;
+		struct Option *rows;
+		struct Option *cols;
+		struct Option *depths;
+	} parm;
+	struct {
+		struct Flag *integer_in;
+		struct Flag *sign;
+		struct Flag *swap;
+		struct Flag *depth;
+		struct Flag *row;
+	} flag;
+	const char *input;
+	const char *output;
+	int is_integer;
+	int is_signed;
+	int bytes;
+	int order;
+	int byte_swap;
+	RASTER_MAP_TYPE map_type;
+	off_t file_size;
+	struct History history;
+	off_t expected;
+	/* Need to be allocated later */
+	in_cell = NULL;
+
+	G_gisinit(argv[0]);
+
+	/* Set description */
+	module = G_define_module();
+	G_add_keyword(_("raster"));
+	G_add_keyword(_("import"));
+	module->description =
+			_("Import a binary raster file into a GRASS 3D raster map layer.");
+
+	parm.input = G_define_standard_option(G_OPT_F_INPUT);
+	parm.input->description = _("Binary 3D raster file to be imported");
+
+	parm.output = G_define_standard_option(G_OPT_R3_OUTPUT);
+
+	parm.bytes = G_define_option();
+	parm.bytes->key = "bytes";
+	parm.bytes->type = TYPE_INTEGER;
+	parm.bytes->required = YES;
+	parm.bytes->options = "1,2,4,8";
+	parm.bytes->description = _("Number of bytes per cell in binary file");
+	parm.bytes->guisection = _("Settings");
+
+	parm.order = G_define_option();
+	parm.order->key = "order";
+	parm.order->type = TYPE_STRING;
+	parm.order->required = NO;
+	parm.order->options = "big,little,native,swap";
+	parm.order->description = _("Byte order in binary file");
+	parm.order->answer = "native";
+
+	parm.north = G_define_option();
+	parm.north->key = "north";
+	parm.north->type = TYPE_DOUBLE;
+	parm.north->required = YES;
+	parm.north->description =
+			_("Northern limit of geographic region (outer edge)");
+	parm.north->guisection = _("Bounds");
+
+	parm.south = G_define_option();
+	parm.south->key = "south";
+	parm.south->type = TYPE_DOUBLE;
+	parm.south->required = YES;
+	parm.south->description =
+			_("Southern limit of geographic region (outer edge)");
+	parm.south->guisection = _("Bounds");
+
+	parm.east = G_define_option();
+	parm.east->key = "east";
+	parm.east->type = TYPE_DOUBLE;
+	parm.east->required = YES;
+	parm.east->description =
+			_("Eastern limit of geographic region (outer edge)");
+	parm.east->guisection = _("Bounds");
+
+	parm.west = G_define_option();
+	parm.west->key = "west";
+	parm.west->type = TYPE_DOUBLE;
+	parm.west->required = YES;
+	parm.west->description =
+			_("Western limit of geographic region (outer edge)");
+	parm.west->guisection = _("Bounds");
+
+	parm.bottom = G_define_option();
+	parm.bottom->key = "bottom";
+	parm.bottom->type = TYPE_DOUBLE;
+	parm.bottom->required = YES;
+	parm.bottom->description =
+			_("Bottom limit of geographic region (outer edge)");
+	parm.bottom->guisection = _("Bounds");
+
+	parm.top = G_define_option();
+	parm.top->key = "top";
+	parm.top->type = TYPE_DOUBLE;
+	parm.top->required = YES;
+	parm.top->description = _("Top limit of geographic region (outer edge)");
+	parm.top->guisection = _("Bounds");
+
+	parm.rows = G_define_option();
+	parm.rows->key = "rows";
+	parm.rows->type = TYPE_INTEGER;
+	parm.rows->required = YES;
+	parm.rows->description = _("Number of rows");
+	parm.rows->guisection = _("Bounds");
+
+	parm.cols = G_define_option();
+	parm.cols->key = "cols";
+	parm.cols->type = TYPE_INTEGER;
+	parm.cols->required = YES;
+	parm.cols->description = _("Number of columns");
+	parm.cols->guisection = _("Bounds");
+
+	parm.depths = G_define_option();
+	parm.depths->key = "depths";
+	parm.depths->type = TYPE_INTEGER;
+	parm.depths->required = YES;
+	parm.depths->description = _("Number of depths");
+	parm.depths->guisection = _("Bounds");
+
+	parm.null = G_define_option();
+	parm.null->key = "null";
+	parm.null->type = TYPE_DOUBLE;
+	parm.null->required = NO;
+	parm.null->description = _("Set Value to NULL");
+	parm.null->guisection = _("Settings");
+
+	flag.row = G_define_flag();
+	flag.row->key = 'r';
+	flag.row->description = _("Switch the row order in output from "
+			"north->south to south->north");
+
+	flag.depth = G_define_flag();
+	flag.depth->key = 'd';
+	flag.depth->description = _("Switch the depth order in output "
+			"from bottom->top to top->bottom");
+
+	flag.integer_in = G_define_flag();
+	flag.integer_in->key = 'i';
+	flag.integer_in->description =
+			_("Binary data is of type integer");
+
+	flag.sign = G_define_flag();
+	flag.sign->key = 's';
+	flag.sign->description = _("Signed data (two's complement)");
+	flag.sign->guisection = _("Settings");
+
+	flag.swap = G_define_flag();
+	flag.swap->key = 'b';
+	flag.swap->description = _("Byte Swap the Data During Import");
+	flag.swap->guisection = _("Settings");
+
+	if (G_parser(argc, argv))
+		exit(EXIT_FAILURE);
+
+	input = parm.input->answer;
+	output = parm.output->answer;
+
+	if (G_strcasecmp(parm.order->answer, "big") == 0)
+		order = 0;
+	else if (G_strcasecmp(parm.order->answer, "little") == 0)
+		order = 1;
+	else if (G_strcasecmp(parm.order->answer, "native") == 0)
+		order = G_is_little_endian() ? 1 : 0;
+	else if (G_strcasecmp(parm.order->answer, "swap") == 0)
+		order = G_is_little_endian() ? 0 : 1;
+
+	if (flag.swap->answer) {
+		if (strcmp(parm.order->answer, "native") != 0)
+			G_fatal_error(_("order= and -b are mutually exclusive"));
+		order = G_is_little_endian() ? 0 : 1;
+	}
+
+	byte_swap = order == (G_is_little_endian() ? 0 : 1);
+
+	is_signed = !!flag.sign->answer;
+
+	is_integer = 0;
+	bytes = 8;
+
+	if (parm.bytes->answer)
+		bytes = atoi(parm.bytes->answer);
+
+	if (!flag.integer_in->answer) {
+		if (bytes && bytes < 4)
+			G_fatal_error(
+					_("bytes=%d; must be 4 or 8 in case of floating point input"),
+					bytes);
+		if (!bytes)
+			bytes = 4;
+	} else {
+		is_integer = 1;
+	}
+
+#ifndef HAVE_LONG_LONG_INT
+	if (is_integer && bytes > 4)
+	G_fatal_error(_("Integer input doesn't support size=8 in this build"));
+#endif
+
+	if (bytes != 1 && bytes != 2 && bytes != 4 && bytes != 8)
+		G_fatal_error(_("bytes= must be 1, 2, 4 or 8"));
+
+	region.zone = G_zone();
+	region.proj = G_projection();
+	region.rows = atoi(parm.rows->answer);
+	region.cols = atoi(parm.cols->answer);
+	region.depths = atoi(parm.depths->answer);
+	region.top = atof(parm.top->answer);
+	region.bottom = atof(parm.bottom->answer);
+
+	if (!G_scan_northing(parm.north->answer, &region.north, region.proj))
+		G_fatal_error(_("Illegal north coordinate <%s>"), parm.north->answer);
+	if (!G_scan_northing(parm.south->answer, &region.south, region.proj))
+		G_fatal_error(_("Illegal south coordinate <%s>"), parm.south->answer);
+	if (!G_scan_easting(parm.east->answer, &region.east, region.proj))
+		G_fatal_error(_("Illegal east coordinate <%s>"), parm.east->answer);
+	if (!G_scan_easting(parm.west->answer, &region.west, region.proj))
+		G_fatal_error(_("Illegal west coordinate <%s>"), parm.west->answer);
+
+	Rast3d_adjust_region(&region);
+
+	expected = (off_t) region.rows * region.cols * region.depths * bytes;
+
+	fp = fopen(input, "rb");
+	if (!fp)
+		G_fatal_error(_("Unable to open <%s>"), input);
+
+	/* Find File Size in Byte and Check against byte size */
+	G_fseek(fp, 0, SEEK_END);
+	file_size = G_ftell(fp);
+	G_fseek(fp, 0, SEEK_SET);
+
+	if (file_size != expected) {
+		G_warning(_("File Size %lld ... Total Bytes %lld"),
+				(long long int) file_size, (long long int) expected);
+		G_fatal_error(_("Bytes do not match file size"));
+	}
+
+	map_type = (bytes > 4 ? DCELL_TYPE : FCELL_TYPE);
+
+	if(is_integer && bytes >= 4)
+		map_type = DCELL_TYPE;
+
+	Rast3d_init_defaults();
+
+	/*Open the new 3D raster map */
+	map = Rast3d_open_new_opt_tile_size(output, RASTER3D_USE_CACHE_DEFAULT,
+			&region, map_type, 32);
+
+	if (map == NULL)
+		G_fatal_error(_("Unable to open 3D raster map"));
+
+	in_cell = G_malloc(bytes);
+
+	bin_to_raster3d(parm.null->answer, map_type, is_integer, is_signed, bytes,
+			byte_swap, flag.row->answer, flag.depth->answer);
+
+	if (!Rast3d_close(map))
+		G_fatal_error(_("Unable to close 3D raster map"));
+
+	/* write input name to map history */
+	Rast3d_read_history(output, G_mapset(), &history);
+	Rast_set_history(&history, HIST_DATSRC_1, input);
+	Rast3d_write_history(output, &history);
+
+	fclose(fp);
+	if (in_cell)
+		G_free(in_cell);
+
+	return EXIT_SUCCESS;
+}

Added: grass/trunk/raster3d/r3.in.bin/r3.in.bin.html
===================================================================
--- grass/trunk/raster3d/r3.in.bin/r3.in.bin.html	                        (rev 0)
+++ grass/trunk/raster3d/r3.in.bin/r3.in.bin.html	2012-11-14 15:09:32 UTC (rev 53806)
@@ -0,0 +1,23 @@
+<h2>DESCRIPTION</h2>
+
+<em>r3.in.bin</em> allows a user to create a GRASS 3D raster map 
+from a variety of binary 3D raster data formats. 
+
+<p>The top, bottom, north, south, east, and west field values entered 
+are the coordinates of the edges of the geographic region. 
+The depths, rows and cols field values entered describe the dimensions 
+of the matrix of data to follow. 
+If the bytes field is entered incorrectly an error will be generated
+suggesting a closer bytes value. 
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="r3.out.bin.html">r3.out.bin</a>,
+<a href="r3.in.ascii.html">r3.in.ascii</a>, 
+<a href="r3.out.ascii.html">r3.out.ascii</a>
+</em>
+
+<h2>AUTHORS</h2>
+
+Soren Gebbert, based on r.in.bin from Jacques Bouchard and Bob Covill
\ No newline at end of file

Added: grass/trunk/raster3d/r3.in.bin/test_suite/test.r3.in.bin.sh
===================================================================
--- grass/trunk/raster3d/r3.in.bin/test_suite/test.r3.in.bin.sh	                        (rev 0)
+++ grass/trunk/raster3d/r3.in.bin/test_suite/test.r3.in.bin.sh	2012-11-14 15:09:32 UTC (rev 53806)
@@ -0,0 +1,123 @@
+#!/bin/sh
+
+g.region w=0 e=180 s=0 n=90 b=0 t=100 res3=10
+
+r3.mapcalc --o expr="test_out_bin_float = float(if(row() == 2, null(), row()))"
+r3.mapcalc --o expr="test_out_bin_double = double(if(row() == 2, null(), row()))"
+r3.out.ascii --o dp=0 input=test_out_bin_float output=test_out_bin_float.ref; 
+r3.out.ascii --o dp=0 input=test_out_bin_double output=test_out_bin_double.ref; 
+
+# @test
+
+r3.out.bin --o input=test_out_bin_float byte=4 null=-9999 \
+    output=test_out_bin_float_native_b4.bin order=native
+
+r3.out.bin --o input=test_out_bin_float byte=8 null=-9999 \
+    output=test_out_bin_float_native_b8.bin order=native
+
+r3.out.bin --o -s input=test_out_bin_float byte=4 null=-9999 \
+    output=test_out_bin_float_native_s_b4.bin order=native
+
+r3.out.bin --o -r input=test_out_bin_float byte=4 null=-9999 \
+    output=test_out_bin_float_native_r_b4.bin order=native
+
+r3.out.bin --o -d input=test_out_bin_float byte=4 null=-9999 \
+    output=test_out_bin_float_native_d_b4.bin order=native
+
+r3.out.bin --o -rd input=test_out_bin_float byte=4 null=-9999 \
+    output=test_out_bin_float_native_rd_b4.bin order=native
+
+# Test little and big endian
+
+r3.out.bin --o input=test_out_bin_float byte=4 null=-9999 \
+    output=test_out_bin_float_little_b4.bin order=little
+
+r3.out.bin --o input=test_out_bin_float byte=4 null=-9999 \
+    output=test_out_bin_float_big_b4.bin order=big
+
+# Write float map as integer array
+
+r3.out.bin --o -i input=test_out_bin_float byte=1 null=-9999 \
+    output=test_out_bin_float_native_b1_as_integer.bin order=native
+
+r3.out.bin --o -i input=test_out_bin_float byte=2 null=-9999 \
+    output=test_out_bin_float_native_b2_as_integer.bin order=native
+
+r3.out.bin --o -i input=test_out_bin_float byte=4 null=-9999 \
+    output=test_out_bin_float_native_b4_as_integer.bin order=native
+
+r3.out.bin --o -i input=test_out_bin_float byte=8 null=-9999 \
+    output=test_out_bin_float_native_b8_as_integer.bin order=native
+
+# Double precision
+
+r3.out.bin --o input=test_out_bin_double byte=4 null=-9999 \
+    output=test_out_bin_double_native_b4.bin order=native
+
+r3.out.bin --o input=test_out_bin_double byte=8 null=-9999 \
+    output=test_out_bin_double_native_b8.bin order=native
+
+# Import test floating point
+
+r3.in.bin --o output=test_in_bin_float_1 byte=4 null=-9999 \
+    input=test_out_bin_float_native_b4.bin order=native \
+    bottom=0 top=100 west=0 east=180 south=0 north=90 \
+    cols=18 rows=9 depths=10
+
+r3.in.bin --o output=test_in_bin_float_2 byte=8 null=-9999 \
+    input=test_out_bin_float_native_b8.bin order=native \
+    bottom=0 top=100 west=0 east=180 south=0 north=90 \
+    cols=18 rows=9 depths=10
+
+#r3.in.bin --o output=test_in_bin_float_3 byte=4 null=-9999 \
+#    input=test_out_bin_float_native_s_b4.bin order=native \
+#    bottom=0 top=100 west=0 east=180 south=0 north=90 \
+#    cols=18 rows=9 depths=10 -s
+
+r3.in.bin --o output=test_in_bin_float_4 byte=4 null=-9999 \
+    input=test_out_bin_float_native_d_b4.bin order=native \
+    bottom=0 top=100 west=0 east=180 south=0 north=90 \
+    cols=18 rows=9 depths=10 -d
+
+r3.in.bin --o output=test_in_bin_float_5 byte=4 null=-9999 \
+    input=test_out_bin_float_native_r_b4.bin order=native \
+    bottom=0 top=100 west=0 east=180 south=0 north=90 \
+    cols=18 rows=9 depths=10 -r
+
+r3.in.bin --o output=test_in_bin_float_6 byte=4 null=-9999 \
+    input=test_out_bin_float_native_rd_b4.bin order=native \
+    bottom=0 top=100 west=0 east=180 south=0 north=90 \
+    cols=18 rows=9 depths=10 -rd
+
+r3.in.bin --o output=test_in_bin_float_7 byte=1 null=-9999 \
+    input=test_out_bin_float_native_b1_as_integer.bin order=native \
+    bottom=0 top=100 west=0 east=180 south=0 north=90 \
+    cols=18 rows=9 depths=10 -i
+
+r3.in.bin --o output=test_in_bin_float_8 byte=2 null=-9999 \
+    input=test_out_bin_float_native_b2_as_integer.bin order=native \
+    bottom=0 top=100 west=0 east=180 south=0 north=90 \
+    cols=18 rows=9 depths=10 -i
+
+r3.in.bin --o output=test_in_bin_float_9 byte=4 null=-9999 \
+    input=test_out_bin_float_native_b4_as_integer.bin order=native \
+    bottom=0 top=100 west=0 east=180 south=0 north=90 \
+    cols=18 rows=9 depths=10 -i
+
+r3.in.bin --o output=test_in_bin_float_10 byte=8 null=-9999 \
+    input=test_out_bin_float_native_b8_as_integer.bin order=native \
+    bottom=0 top=100 west=0 east=180 south=0 north=90 \
+    cols=18 rows=9 depths=10 -i
+
+
+for map in `g.mlist type=rast3d pattern=test_in_bin_float*` ; do
+  r3.out.ascii input=${map} output=${map}.txt dp=0
+done
+
+for i in `ls test_in_bin_float_*.txt` ; do 
+    diff $i test_out_bin_float.ref
+done
+
+g.mremove -f rast3d=*
+rm *.txt
+rm *.bin

Added: grass/trunk/raster3d/r3.in.bin/test_suite/test_out_bin_double.ref
===================================================================
--- grass/trunk/raster3d/r3.in.bin/test_suite/test_out_bin_double.ref	                        (rev 0)
+++ grass/trunk/raster3d/r3.in.bin/test_suite/test_out_bin_double.ref	2012-11-14 15:09:32 UTC (rev 53806)
@@ -0,0 +1,101 @@
+version: grass7
+order: nsbt
+north: 90.000000
+south: 0.000000
+east: 180.000000
+west: 0.000000
+top: 100.000000
+bottom: 0.000000
+rows: 9
+cols: 18
+levels: 10
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 

Added: grass/trunk/raster3d/r3.in.bin/test_suite/test_out_bin_float.ref
===================================================================
--- grass/trunk/raster3d/r3.in.bin/test_suite/test_out_bin_float.ref	                        (rev 0)
+++ grass/trunk/raster3d/r3.in.bin/test_suite/test_out_bin_float.ref	2012-11-14 15:09:32 UTC (rev 53806)
@@ -0,0 +1,101 @@
+version: grass7
+order: nsbt
+north: 90.000000
+south: 0.000000
+east: 180.000000
+west: 0.000000
+top: 100.000000
+bottom: 0.000000
+rows: 9
+cols: 18
+levels: 10
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
+* * * * * * * * * * * * * * * * * * 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
+5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 
+6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 
+7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 
+8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 

Modified: grass/trunk/raster3d/r3.out.bin/main.c
===================================================================
--- grass/trunk/raster3d/r3.out.bin/main.c	2012-11-14 14:58:01 UTC (rev 53805)
+++ grass/trunk/raster3d/r3.out.bin/main.c	2012-11-14 15:09:32 UTC (rev 53806)
@@ -1,4 +1,3 @@
-
 /****************************************************************************
  *
  * MODULE:       r3.out.bin
@@ -24,10 +23,18 @@
 #include <grass/raster3d.h>
 #include <grass/glocale.h>
 
-
 RASTER3D_Map *map;
 RASTER3D_Region region;
+unsigned char *out_cell;
 
+static void swap_2(void *p) {
+	unsigned char *q = p;
+	unsigned char t;
+	t = q[0];
+	q[0] = q[1];
+	q[1] = t;
+}
+
 static void swap_4(void *p) {
 	unsigned char *q = p;
 	unsigned char t;
@@ -56,24 +63,58 @@
 	q[4] = t;
 }
 
-static void write_float(FILE *fp, int swap_flag, float x) {
-	if (swap_flag)
-		swap_4(&x);
+static void write_cell(FILE *fp, const DCELL in_cell, int as_integer, int bytes,
+		int swap_flag) {
+	if (!as_integer) {
+		switch (bytes) {
+		case 4:
+			*(float *) out_cell = (float) in_cell;
+			break;
+		case 8:
+			*(double *) out_cell = (double) in_cell;
+			break;
+		}
+	} else {
+		switch (bytes) {
+		case 1:
+			*(unsigned char *) out_cell = (unsigned char) in_cell;
+			break;
+		case 2:
+			*(short *) out_cell = (short) in_cell;
+			break;
+		case 4:
+			*(int *) out_cell = (int) in_cell;
+			break;
+#ifdef HAVE_LONG_LONG_INT
+		case 8:
+			*(long long *) out_cell = (long long) in_cell;
+			break;
+#endif
+		}
+	}
 
-	if (fwrite(&x, 4, 1, fp) != 1)
-		G_fatal_error(_("Error writing data"));
-}
+	if (swap_flag) {
+		switch (bytes) {
+		case 1:
+			break;
+		case 2:
+			swap_2(out_cell);
+			break;
+		case 4:
+			swap_4(out_cell);
+			break;
+		case 8:
+			swap_8(out_cell);
+			break;
+		}
+	}
 
-static void write_double(FILE *fp, int swap_flag, double x) {
-	if (swap_flag)
-		swap_8(&x);
-
-	if (fwrite(&x, 8, 1, fp) != 1)
+	if (fwrite(out_cell, bytes, 1, fp) != 1)
 		G_fatal_error(_("Error writing data"));
 }
 
-void raster3d_to_bin(FILE * fp, DCELL null_value, int byte_swap, int row_swap,
-		int depth_swap) {
+static void raster3d_to_bin(FILE * fp, DCELL null_value, int as_integer,
+		int bytes, int byte_swap, int row_swap, int depth_swap) {
 	DCELL dvalue;
 	FCELL fvalue;
 	int x, y, z;
@@ -88,13 +129,12 @@
 
 	for (z = 0; z < depths; z++) {
 		G_percent(z, depths, 1);
-		for (y = 0; y < rows; y++) { /* g3d rows count from south to north */
+		for (y = 0; y < rows; y++) {
 			for (x = 0; x < cols; x++) {
 
 				/* From west to east */
 				col = x;
 				/* The default is to write rows from north to south
-				 to be r.in.ascii compatible
 				 */
 				row = y;
 				/* From bottom to the top */
@@ -113,17 +153,20 @@
 					Rast3d_get_value(map, col, row, depth, &fvalue, FCELL_TYPE);
 
 					if (Rast3d_is_null_value_num(&fvalue, FCELL_TYPE))
-						write_float(fp, byte_swap, (float)null_value);
+						write_cell(fp, null_value, as_integer, bytes,
+								byte_swap);
 					else
-						write_float(fp, byte_swap, fvalue);
+						write_cell(fp, (DCELL) fvalue, as_integer, bytes,
+								byte_swap);
 				} else {
 
 					Rast3d_get_value(map, col, row, depth, &dvalue, DCELL_TYPE);
 
 					if (Rast3d_is_null_value_num(&dvalue, DCELL_TYPE))
-						write_double(fp, byte_swap, null_value);
+						write_cell(fp, null_value, as_integer, bytes,
+								byte_swap);
 					else
-						write_double(fp, byte_swap, dvalue);
+						write_cell(fp, dvalue, as_integer, bytes, byte_swap);
 				}
 			}
 		}
@@ -139,9 +182,10 @@
 		struct Option *output;
 		struct Option *null;
 		struct Option *order;
+		struct Option *bytes;
 	} parm;
 	struct {
-		struct Flag *swap, *row, *depth;
+		struct Flag *swap, *row, *depth, *integer;
 	} flag;
 	char *name;
 	char *outfile;
@@ -149,8 +193,12 @@
 	int do_stdout;
 	int order;
 	int swap_flag;
+	int bytes;
+	int as_integer = 0;
 	FILE *fp;
 
+	out_cell = NULL;
+
 	G_gisinit(argv[0]);
 
 	module = G_define_module();
@@ -171,6 +219,14 @@
 	parm.null->answer = "0";
 	parm.null->description = _("Value to write out for null");
 
+	parm.bytes = G_define_option();
+	parm.bytes->key = "bytes";
+	parm.bytes->type = TYPE_INTEGER;
+	parm.bytes->required = YES;
+	parm.bytes->options = "1,2,4,8";
+	parm.bytes->description = _("Number of bytes per cell in binary file");
+	parm.bytes->guisection = _("Settings");
+
 	parm.order = G_define_option();
 	parm.order->key = "order";
 	parm.order->type = TYPE_STRING;
@@ -193,14 +249,34 @@
 	flag.depth->description = _("Switch the depth order in output "
 			"from bottom->top to top->bottom");
 
+	flag.integer = G_define_flag();
+	flag.integer->key = 'i';
+	flag.integer->description = _("Write data as integer");
+
 	if (G_parser(argc, argv))
 		exit(EXIT_FAILURE);
 
 	if (sscanf(parm.null->answer, "%lf", &null_val) != 1)
 		G_fatal_error(_("Invalid value for null (integers only)"));
 
+	as_integer = flag.integer->answer;
 	name = parm.input->answer;
 
+	if (parm.bytes->answer)
+		bytes = atoi(parm.bytes->answer);
+	else if (as_integer)
+		bytes = 4;
+	else
+		bytes = 8;
+
+	if (!as_integer && bytes < 4)
+		G_fatal_error(_("Floating-point output requires bytes=4 or bytes=8"));
+
+#ifndef HAVE_LONG_LONG_INT
+	if (as_integer && bytes > 4)
+	G_fatal_error(_("Integer output doesn't support bytes=8 in this build"));
+#endif
+
 	if (parm.output->answer)
 		outfile = parm.output->answer;
 	else {
@@ -227,6 +303,8 @@
 
 	do_stdout = strcmp("-", outfile) == 0;
 
+	out_cell = G_malloc(bytes);
+
 	if (NULL == G_find_raster3d(parm.input->answer, ""))
 		Rast3d_fatal_error(_("3D raster map <%s> not found"),
 				parm.input->answer);
@@ -263,13 +341,16 @@
 	G_verbose_message(_("cols=%d"), region.cols);
 	G_verbose_message(_("depths=%d"), region.depths);
 
-	raster3d_to_bin(fp, null_val, swap_flag, flag.row->answer,
-			flag.depth->answer);
+	raster3d_to_bin(fp, null_val, as_integer, bytes, swap_flag,
+			flag.row->answer, flag.depth->answer);
 
 	Rast3d_close(map);
 
 	fclose(fp);
 
+	if(out_cell)
+		G_free(out_cell);
+
 	return EXIT_SUCCESS;
 }
 



More information about the grass-commit mailing list