Пример #1
0
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 *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(_("raster3d"));
	G_add_keyword(_("import"));
	G_add_keyword(_("voxel"));
	module->description =
			_("Imports a binary raster file into a GRASS 3D raster map.");

	parm.input = G_define_standard_option(G_OPT_F_BIN_INPUT);
	parm.input->description = _("Name of 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.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");

	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)");

	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;

	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;
}
Пример #2
0
int main(int argc, char *argv[])
{

    int i, row, col;		/* counters */
    unsigned long filesize;

    int endianness;		/* 0=little, 1=big */
    int data_format;		/* 0=double  1=float  2=32bit signed int  5=8bit unsigned int (ie text) */
    int data_type;		/* 0=numbers  1=text */
    int format_block;		/* combo of endianness, 0, data_format, and type */
    int realflag = 0;		/* 0=only real values used */

    /* should type be specifically uint32 ??? */

    char array_name[32];	/* variable names must start with a letter (case 
				   sensitive) followed by letters, numbers, or 
				   underscores. 31 chars max. */
    int name_len;
    int mrows, ncols;		/* text/data/map array dimensions */

    int val_i;			/* for misc use */
    float val_f;		/* for misc use */
    double val_d;		/* for misc use */

    char *infile, *outfile, *maptitle, *basename;
    struct Cell_head region;
    void *raster, *ptr;
    RASTER_MAP_TYPE map_type;

    struct Option *inputfile, *outputfile;
    struct GModule *module;

    int fd;
    FILE *fp1;


    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("export"));
    module->description = _("Exports a GRASS raster to a binary MAT-File.");

    /* Define the different options */

    inputfile = G_define_standard_option(G_OPT_R_INPUT);

    outputfile = G_define_option();
    outputfile->key = "output";
    outputfile->type = TYPE_STRING;
    outputfile->required = YES;
    outputfile->gisprompt = "new_file,file,output";
    outputfile->description = _("Name for the output binary MAT-File");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    infile = inputfile->answer;
    basename = G_store(outputfile->answer);
    G_basename(basename, "mat");
    outfile = G_malloc(strlen(basename) + 5);
    sprintf(outfile, "%s.mat", basename);

    fd = Rast_open_old(infile, "");

    map_type = Rast_get_map_type(fd);

    /* open bin file for writing */
    fp1 = fopen(outfile, "wb");
    if (NULL == fp1)
	G_fatal_error(_("Unable to open output file <%s>"), outfile);


    /* Check Endian State of Host Computer */
    if (G_is_little_endian())
	endianness = 0;		/* ie little endian */
    else
	endianness = 1;		/* ie big endian */
    G_debug(1, "Machine is %s endian.\n", endianness ? "big" : "little");

    G_get_window(&region);


    /********** Write map **********/

    /** write text element (map name) **/
    strncpy(array_name, "map_name", 31);
    mrows = 1;
    ncols = strlen(infile);
    data_format = 5;		/* 0=double  1=float  2=32bit signed int  5=8bit unsigned int(text) */
    data_type = 1;		/* 0=numbers  1=text */

    G_verbose_message(_("Exporting <%s>"), infile);

    /* 4 byte data format */
    format_block = endianness * 1000 + data_format * 10 + data_type;
    fwrite(&format_block, sizeof(int), 1, fp1);
    /* fprintf(stderr, "name data format is [%04ld]\n", format_block); */

    /* 4 byte number of rows & columns */
    fwrite(&mrows, sizeof(int), 1, fp1);
    fwrite(&ncols, sizeof(int), 1, fp1);

    /* 4 byte real/imag flag   0=real vals only */
    fwrite(&realflag, sizeof(int), 1, fp1);

    /* length of array_name+1 */
    name_len = strlen(array_name) + 1;
    fwrite(&name_len, sizeof(int), 1, fp1);

    /* array name */
    fprintf(fp1, "%s%c", array_name, '\0');

    /* array data */
    fprintf(fp1, "%s", infile);


    /********** Write title (if there is one) **********/
    maptitle = Rast_get_cell_title(infile, "");
    if (strlen(maptitle) >= 1) {

	/** write text element (map title) **/
	strncpy(array_name, "map_title", 31);
	mrows = 1;
	ncols = strlen(maptitle);
	data_format = 5;	/* 0=double  1=float  2=32bit signed int  5=8bit unsigned int(text) */
	data_type = 1;		/* 0=numbers  1=text */

	/* 4 byte data format */
	format_block = endianness * 1000 + data_format * 10 + data_type;
	fwrite(&format_block, sizeof(int), 1, fp1);

	/* 4 byte number of rows & columns */
	fwrite(&mrows, sizeof(int), 1, fp1);
	fwrite(&ncols, sizeof(int), 1, fp1);

	/* 4 byte real/imag flag   0=real vals only */
	fwrite(&realflag, sizeof(int), 1, fp1);

	/* length of array_name+1 */
	name_len = strlen(array_name) + 1;
	fwrite(&name_len, sizeof(int), 1, fp1);

	/* array name */
	fprintf(fp1, "%s%c", array_name, '\0');

	/* array data */
	fprintf(fp1, "%s", maptitle);
    }

    /***** Write bounds *****/
    G_verbose_message("");
    G_verbose_message(_("Using the Current Region settings:"));
    G_verbose_message(_("northern edge=%f"), region.north);
    G_verbose_message(_("southern edge=%f"), region.south);
    G_verbose_message(_("eastern edge=%f"), region.east);
    G_verbose_message(_("western edge=%f"), region.west);
    G_verbose_message(_("nsres=%f"), region.ns_res);
    G_verbose_message(_("ewres=%f"), region.ew_res);
    G_verbose_message(_("rows=%d"), region.rows);
    G_verbose_message(_("cols=%d"), region.cols);
    G_verbose_message("");

    for (i = 0; i < 4; i++) {
	switch (i) {
	case 0:
	    strncpy(array_name, "map_northern_edge", 31);
	    val_d = region.north;
	    break;
	case 1:
	    strncpy(array_name, "map_southern_edge", 31);
	    val_d = region.south;
	    break;
	case 2:
	    strncpy(array_name, "map_eastern_edge", 31);
	    val_d = region.east;
	    break;
	case 3:
	    strncpy(array_name, "map_western_edge", 31);
	    val_d = region.west;
	    break;
	default:
	    fclose(fp1);
	    G_fatal_error("please contact development team");
	    break;
	}

	/** write data element **/
	data_format = 0;	/* 0=double  1=float  2=32bit signed int  5=8bit unsigned int(text) */
	data_type = 0;		/* 0=numbers  1=text */
	mrows = 1;
	ncols = 1;

	/* 4 byte data format */
	format_block = endianness * 1000 + data_format * 10 + data_type;
	fwrite(&format_block, sizeof(int), 1, fp1);
	/* fprintf(stderr, "bounds data format is [%04ld]\n", format_block); */

	/* 4 byte number of rows , 4 byte number of colums */
	fwrite(&mrows, sizeof(int), 1, fp1);
	fwrite(&ncols, sizeof(int), 1, fp1);

	/* 4 byte real/imag flag   0=only real */
	fwrite(&realflag, sizeof(int), 1, fp1);

	/* length of array_name+1 */
	name_len = strlen(array_name) + 1;
	fwrite(&name_len, sizeof(int), 1, fp1);

	/* array name */
	fprintf(fp1, "%s%c", array_name, '\0');

	/* write array data, by increasing column */
	fwrite(&val_d, sizeof(double), 1, fp1);

	/** end of data element **/
    }



    /***** Write map data *****/
    strncpy(array_name, "map_data", 31);

    switch (map_type) {		/* data_format: 0=double  1=float  2=32bit signed int  5=8bit unsigned int (ie text) */

    case CELL_TYPE:
	data_format = 2;
	G_verbose_message(_("Exporting raster as integer values"));
	break;

    case FCELL_TYPE:
	data_format = 1;
	G_verbose_message(_("Exporting raster as floating point values"));
	break;

    case DCELL_TYPE:
	data_format = 0;
	G_verbose_message(_("Exporting raster as double FP values"));
	break;

    default:
	fclose(fp1);
	G_fatal_error("Please contact development team");
	break;
    }

    data_type = 0;		/* 0=numbers  1=text */

    mrows = region.rows;
    ncols = region.cols;

    /* 4 byte data format */
    format_block = (endianness * 1000) + (data_format * 10) + data_type;
    fwrite(&format_block, sizeof(int), 1, fp1);

    G_debug(3, "map data format is [%04d]\n", format_block);

    /* 4 byte number of rows & columns */
    fwrite(&mrows, sizeof(int), 1, fp1);
    fwrite(&ncols, sizeof(int), 1, fp1);

    /* 4 byte real/imag flag   0=only real */
    fwrite(&realflag, sizeof(int), 1, fp1);

    /* length of array_name+1 */
    name_len = strlen(array_name) + 1;
    fwrite(&name_len, sizeof(int), 1, fp1);

    /* array name */
    fprintf(fp1, "%s%c", array_name, '\0');

    /* data array, by increasing column */
    raster =
	G_calloc((Rast_window_rows() + 1) * (Rast_window_cols() + 1),
		 Rast_cell_size(map_type));

    G_debug(1, "mem alloc is %d bytes\n",	/* I think _cols()+1 is unneeded? */
	    Rast_cell_size(map_type) * (Rast_window_rows() +
				       1) * (Rast_window_cols() + 1));

    G_verbose_message(_("Reading in map ... "));

    /* load entire map into memory */
    for (row = 0, ptr = raster; row < mrows; row++,
	 ptr =
	 G_incr_void_ptr(ptr,
			 (Rast_window_cols() + 1) * Rast_cell_size(map_type))) {
	Rast_get_row(fd, ptr, row, map_type);
	G_percent(row, mrows, 2);
    }
    G_percent(row, mrows, 2);	/* finish it off */


    G_verbose_message(_("Writing out map..."));

    /* then write it to disk */
    /* NoGood: fwrite(raster, Rast_cell_size(map_type), mrows*ncols, fp1); */
    for (col = 0; col < ncols; col++) {
	for (row = 0; row < mrows; row++) {

	    ptr = raster;
	    ptr =
		G_incr_void_ptr(ptr,
				(col +
				 row * (ncols +
					1)) * Rast_cell_size(map_type));

	    if (!Rast_is_null_value(ptr, map_type)) {
		if (map_type == CELL_TYPE) {
		    val_i = *((CELL *) ptr);
		    fwrite(&val_i, sizeof(int), 1, fp1);
		}
		else if (map_type == FCELL_TYPE) {
		    val_f = *((FCELL *) ptr);
		    fwrite(&val_f, sizeof(float), 1, fp1);
		}
		else if (map_type == DCELL_TYPE) {
		    val_d = *((DCELL *) ptr);
		    fwrite(&val_d, sizeof(double), 1, fp1);
		}
	    }
	    else {		/* ie if NULL cell -> write IEEE NaN value */
		if (map_type == CELL_TYPE) {
		    val_i = *((CELL *) ptr);	/* int has no NaN value, so use whatever GRASS uses */
		    fwrite(&val_i, sizeof(int), 1, fp1);
		}
		else if (map_type == FCELL_TYPE) {
		    if (endianness)	/* ie big */
			fprintf(fp1, "%c%c%c%c", 0xff, 0xf8, 0, 0);
		    else	/* ie little */
			fprintf(fp1, "%c%c%c%c", 0, 0, 0xf8, 0xff);
		}
		else if (map_type == DCELL_TYPE) {
		    if (endianness)
			fprintf(fp1, "%c%c%c%c%c%c%c%c", 0xff, 0xf8, 0, 0, 0,
				0, 0, 0);
		    else
			fprintf(fp1, "%c%c%c%c%c%c%c%c", 0, 0, 0, 0, 0, 0,
				0xf8, 0xff);
		}
	    }
	}
	G_percent(col, ncols, 2);
    }
    G_percent(col, ncols, 2);	/* finish it off */

    /*** end of data element ***/


    /* done! */
    filesize = G_ftell(fp1);
    fclose(fp1);

    G_verbose_message(_("%ld bytes written to '%s'"), filesize, outfile);

    G_done_msg("");

    G_free(basename);
    G_free(outfile);

    exit(EXIT_SUCCESS);
}
Пример #3
0
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;
    } parm;
    struct
    {
	struct Flag *int_out;
	struct Flag *float_out;
	struct Flag *gmt_hd;
	struct Flag *bil_hd;
	struct Flag *swap;
    } flag;
    char *name;
    char *outfile;
    double null_val;
    int do_stdout;
    int is_fp;
    int bytes;
    int order;
    int swap_flag;
    struct Cell_head region;
    int nrows, ncols;
    DCELL *in_buf;
    unsigned char *out_buf;
    int fd;
    FILE *fp;
    struct GRD_HEADER header;
    int row;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("export"));
    module->description = _("Exports a GRASS raster to a binary array.");

    /* Define the different options */

    parm.input = G_define_option();
    parm.input->key = "input";
    parm.input->type = TYPE_STRING;
    parm.input->required = YES;
    parm.input->gisprompt = "old,cell,raster";
    parm.input->description = _("Name of input raster map");

    parm.output = G_define_option();
    parm.output->key = "output";
    parm.output->type = TYPE_STRING;
    parm.output->required = NO;
    parm.output->description =
	_("Name for output binary map (use output=- for stdout)");

    parm.null = G_define_option();
    parm.null->key = "null";
    parm.null->type = TYPE_DOUBLE;
    parm.null->required = NO;
    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 = NO;
    parm.bytes->options = "1,2,4,8";
    parm.bytes->description = _("Number of bytes per cell");

    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 = _("Output byte order");
    parm.order->answer = "native";

    flag.int_out = G_define_flag();
    flag.int_out->key = 'i';
    flag.int_out->description = _("Generate integer output");

    flag.float_out = G_define_flag();
    flag.float_out->key = 'f';
    flag.float_out->description = _("Generate floating-point output");

    flag.gmt_hd = G_define_flag();
    flag.gmt_hd->key = 'h';
    flag.gmt_hd->description = _("Export array with GMT compatible header");

    flag.bil_hd = G_define_flag();
    flag.bil_hd->key = 'b';
    flag.bil_hd->description = _("Generate BIL world and header files");

    flag.swap = G_define_flag();
    flag.swap->key = 's';
    flag.swap->description = _("Byte swap output");

    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)"));

    name = parm.input->answer;

    if (parm.output->answer)
	outfile = parm.output->answer;
    else {
	outfile = G_malloc(strlen(name) + 4 + 1);
	sprintf(outfile, "%s.bin", name);
    }

    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 -s are mutually exclusive"));
	order = G_is_little_endian() ? 0 : 1;
    }

    swap_flag = order == (G_is_little_endian() ? 0 : 1);

    do_stdout = strcmp("-", outfile) == 0;

    if (flag.int_out->answer && flag.float_out->answer)
	G_fatal_error(_("-i and -f are mutually exclusive"));

    fd = Rast_open_old(name, "");

    if (flag.int_out->answer)
	is_fp = 0;
    else if (flag.float_out->answer)
	is_fp = 1;
    else
	is_fp = Rast_get_map_type(fd) != CELL_TYPE;

    if (parm.bytes->answer)
	bytes = atoi(parm.bytes->answer);
    else if (is_fp)
	bytes = 4;
    else
	bytes = 2;

    if (is_fp && bytes < 4)
	G_fatal_error(_("Floating-point output requires bytes=4 or bytes=8"));

#ifndef HAVE_LONG_LONG_INT
    if (!is_fp && bytes > 4)
	G_fatal_error(_("Integer output doesn't support bytes=8 in this build"));
#endif

    G_get_window(&region);

    /* open bin file for writing */
    if (do_stdout)
	fp = stdout;
    else if (NULL == (fp = fopen(outfile, "w")))
	G_fatal_error(_("Unable to create file <%s>"), outfile);

    /* Set up Parameters for GMT header */
    if (flag.gmt_hd->answer) {
	if (!is_fp && bytes > 4)
	    G_fatal_error(_("GMT grid doesn't support 64-bit integers"));
	make_gmt_header(&header, name, outfile, &region, null_val);
    }

    /* Write out BIL support files compatible with Arc-View */
    if (flag.bil_hd->answer) {
	G_message(_("Creating BIL support files..."));
	write_bil_hdr(outfile, &region,
		      bytes, order, flag.gmt_hd->answer, null_val);
	write_bil_wld(outfile, &region);
    }

    /* Write out GMT Header if required */
    if (flag.gmt_hd->answer)
	write_gmt_header(&header, swap_flag, fp);

    nrows = Rast_window_rows();
    ncols = Rast_window_cols();

    in_buf = Rast_allocate_d_buf();
    out_buf = G_malloc(ncols * bytes);

    if (is_fp) {
	G_message(_("Exporting raster as floating values (bytes=%d)"), bytes);
	if (flag.gmt_hd->answer)
	    G_message(_("Writing GMT float format ID=1"));
    }
    else {
	G_message(_("Exporting raster as integer values (bytes=%d)"), bytes);
	if (flag.gmt_hd->answer)
	    G_message(_("Writing GMT integer format ID=2"));
    }

    G_verbose_message(_("Using the current region settings..."));
    G_verbose_message(_("north=%f"), region.north);
    G_verbose_message(_("south=%f"), region.south);
    G_verbose_message(_("east=%f"), region.east);
    G_verbose_message(_("west=%f"), region.west);
    G_verbose_message(_("r=%d"), region.rows);
    G_verbose_message(_("c=%d"), region.cols);

    for (row = 0; row < nrows; row++) {
	G_percent(row, nrows, 2);

	Rast_get_d_row(fd, in_buf, row);

	convert_row(out_buf, in_buf, ncols, is_fp, bytes, swap_flag, null_val);

	if (fwrite(out_buf, bytes, ncols, fp) != ncols)
	    G_fatal_error(_("Error writing data"));
    }

    G_percent(row, nrows, 2);	/* finish it off */

    Rast_close(fd);
    fclose(fp);

    return EXIT_SUCCESS;
}