[GRASS-SVN] r45934 - in grass/branches/releasebranch_6_4: include
lib/gis raster/r.in.bin raster/r.out.bin
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Apr 13 07:19:03 EDT 2011
Author: martinl
Date: 2011-04-13 04:19:03 -0700 (Wed, 13 Apr 2011)
New Revision: 45934
Added:
grass/branches/releasebranch_6_4/lib/gis/seek.c
Modified:
grass/branches/releasebranch_6_4/include/gis.h
grass/branches/releasebranch_6_4/include/gisdefs.h
grass/branches/releasebranch_6_4/raster/r.in.bin/main.c
grass/branches/releasebranch_6_4/raster/r.out.bin/main.c
Log:
pythonlib: array.py backported from trunk
related r.in/out.bin sync'ed with trunk
G_fseek() and G_ftell() added
(merge r45467 from devbr6)
Modified: grass/branches/releasebranch_6_4/include/gis.h
===================================================================
--- grass/branches/releasebranch_6_4/include/gis.h 2011-04-13 11:11:59 UTC (rev 45933)
+++ grass/branches/releasebranch_6_4/include/gis.h 2011-04-13 11:19:03 UTC (rev 45934)
@@ -53,6 +53,12 @@
#define FALSE 0
#endif
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
+#define PRI_OFF_T "lld"
+#else
+#define PRI_OFF_T "ld"
+#endif
+
#define MAXEDLINES 50
#define RECORD_LEN 80
#define NEWLINE '\n'
Modified: grass/branches/releasebranch_6_4/include/gisdefs.h
===================================================================
--- grass/branches/releasebranch_6_4/include/gisdefs.h 2011-04-13 11:11:59 UTC (rev 45933)
+++ grass/branches/releasebranch_6_4/include/gisdefs.h 2011-04-13 11:19:03 UTC (rev 45934)
@@ -1082,6 +1082,10 @@
void G_rotate_around_point(double, double, double *, double *, double);
void G_rotate_around_point_int(int, int, int *, int *, double);
+/* seek.c */
+off_t G_ftell(FILE *);
+void G_fseek(FILE *, off_t, int);
+
/* sample.c */
DCELL G_get_raster_sample_nearest(
int, const struct Cell_head *, struct Categories *, double, double, int);
Copied: grass/branches/releasebranch_6_4/lib/gis/seek.c (from rev 45467, grass/branches/develbranch_6/lib/gis/seek.c)
===================================================================
--- grass/branches/releasebranch_6_4/lib/gis/seek.c (rev 0)
+++ grass/branches/releasebranch_6_4/lib/gis/seek.c 2011-04-13 11:19:03 UTC (rev 45934)
@@ -0,0 +1,60 @@
+/*!
+ * \file gis/seek.c
+ *
+ * \brief GIS Library - file seek routines
+ *
+ * (C) 2009-2010 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.
+ *
+ * \author Glynn Clements
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+/*!
+ \brief Get the current file position of the stream.
+
+ \param fp file descriptor
+
+ \return file position
+ \return -1 on failure
+*/
+off_t G_ftell(FILE *fp)
+{
+#ifdef HAVE_FSEEKO
+ return ftello(fp);
+#else
+ return (off_t) ftell(fp);
+#endif
+}
+
+/*!
+ \brief Change the file position of the stream.
+
+ The value of <i>whence</i> must be one of the constants `SEEK_SET',
+ `SEEK_CUR', or `SEEK_END', to indicate whether the <i>offset</i> is
+ relative to the beginning of the file, the current file position, or
+ the end of the file, respectively.
+
+ \param fp file descriptor
+ \param offset offset
+ \param whence
+*/
+void G_fseek(FILE *fp, off_t offset, int whence)
+{
+#ifdef HAVE_FSEEKO
+ if (fseeko(fp, offset, whence) != 0)
+ G_fatal_error(_("Unable to seek"));
+#else
+ long loff = (long) offset;
+ if ((off_t) loff != offset)
+ G_fatal_error(_("Seek offset out of range"));
+ if (fseek(fp, loff, whence) != 0)
+ G_fatal_error(_("Unable to seek"));
+#endif
+}
Modified: grass/branches/releasebranch_6_4/raster/r.in.bin/main.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.in.bin/main.c 2011-04-13 11:11:59 UTC (rev 45933)
+++ grass/branches/releasebranch_6_4/raster/r.in.bin/main.c 2011-04-13 11:19:03 UTC (rev 45934)
@@ -14,106 +14,218 @@
#include <unistd.h>
#include <sys/stat.h>
#include <grass/gis.h>
-#include "gmt_grd.h"
#include <grass/glocale.h>
-typedef unsigned short uint16;
-typedef unsigned int uint32;
+#include "gmt_grd.h"
-static double nul_val;
+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 SwabShort(uint16 * wp)
+static void swap_4(void *p)
{
- register char *cp = (char *)wp;
- int t;
+ 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;
+}
- t = cp[1];
- cp[1] = cp[0];
- cp[0] = 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 SwabLong(uint32 * lp)
+static void read_int(FILE *fp, int swap_flag, int *x)
{
- register char *cp = (char *)lp;
- int t;
+ if (fread(x, 4, 1, fp) != 1)
+ G_fatal_error(_("Error reading data"));
- t = cp[3];
- cp[3] = cp[0];
- cp[0] = t;
- t = cp[2];
- cp[2] = cp[1];
- cp[1] = t;
+ if (swap_flag)
+ swap_4(x);
}
-static void SwabFloat(float *fp)
+static void read_double(FILE *fp, int swap_flag, double *x)
{
- SwabLong((uint32 *) fp);
+ if (fread(x, 8, 1, fp) != 1)
+ G_fatal_error(_("Error reading data"));
+
+ if (swap_flag)
+ swap_8(x);
}
-static void SwabDouble(double *dp)
+static void read_gmt_header(struct GRD_HEADER *header, int swap_flag, FILE *fp)
{
- register char *cp = (char *)dp;
- int t;
+ read_int(fp, swap_flag, &header->nx);
+ read_int(fp, swap_flag, &header->ny);
+ read_int(fp, swap_flag, &header->node_offset);
- t = cp[7];
- cp[7] = cp[0];
- cp[0] = t;
- t = cp[6];
- cp[6] = cp[1];
- cp[1] = t;
- t = cp[5];
- cp[5] = cp[2];
- cp[2] = t;
- t = cp[4];
- cp[4] = cp[3];
- cp[3] = t;
+ read_double(fp, swap_flag, &header->x_min);
+ read_double(fp, swap_flag, &header->x_max);
+ read_double(fp, swap_flag, &header->y_min);
+ read_double(fp, swap_flag, &header->y_max);
+ read_double(fp, swap_flag, &header->z_min);
+ read_double(fp, swap_flag, &header->z_max);
+ read_double(fp, swap_flag, &header->x_inc);
+ read_double(fp, swap_flag, &header->y_inc);
+ read_double(fp, swap_flag, &header->z_scale_factor);
+ read_double(fp, swap_flag, &header->z_add_offset);
+
+ fread(&header->x_units, sizeof(char[GRD_UNIT_LEN]), 1, fp);
+ fread(&header->y_units, sizeof(char[GRD_UNIT_LEN]), 1, fp);
+ fread(&header->z_units, sizeof(char[GRD_UNIT_LEN]), 1, fp);
+ fread(&header->title, sizeof(char[GRD_TITLE_LEN]), 1, fp);
+ fread(&header->command, sizeof(char[GRD_COMMAND_LEN]), 1, fp);
+ fread(&header->remark, sizeof(char[GRD_REMARK_LEN]), 1, fp);
}
+static void get_gmt_header(const struct GRD_HEADER *header, struct Cell_head *region)
+{
+ region->cols = header->nx;
+ region->rows = header->ny;
+ region->west = header->x_min;
+ region->east = header->x_max;
+ region->south = header->y_min;
+ region->north = header->y_max;
+ region->ew_res = header->x_inc;
+ region->ns_res = header->y_inc;
+}
+
+static void convert_cell(
+ DCELL *out_cell, unsigned char *in_cell,
+ int is_fp, int is_signed, int bytes, int swap_flag)
+{
+ if (swap_flag) {
+ 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_fp) {
+ 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 convert_row(
+ DCELL *raster, unsigned char *in_buf, int ncols,
+ int is_fp, int is_signed, int bytes, int swap_flag,
+ double null_val)
+{
+ unsigned char *ptr = in_buf;
+ int i;
+
+ for (i = 0; i < ncols; i++) {
+ DCELL x;
+ convert_cell(&x, ptr, is_fp, is_signed, bytes, swap_flag);
+ if (x == null_val)
+ G_set_d_null_value(&raster[i], 1);
+ else
+ raster[i] = x;
+ ptr += bytes;
+ }
+}
+
int main(int argc, char *argv[])
{
- char *input;
- char *output;
- char *title;
- FILE *fd;
- int cf;
- struct Cell_head cellhd;
- struct History history;
- CELL *cell;
- FCELL *fcell;
- DCELL *dcell;
- RASTER_MAP_TYPE map_type;
- int row, col;
- int nrows = 0, ncols = 0;
- int grass_nrows = 0, grass_ncols = 0;
- int bytes, sflag, swap;
- int no_coord = 0, no_dim = 0;
- void *x_v;
- char *x_c;
- uint16 *x_s;
- uint32 *x_i;
- float *x_f;
- double *x_d;
- struct stat fileinfo;
- int FILE_SIZE;
- char *err;
- char dummy[2];
- struct GRD_HEADER header;
+ struct GModule *module;
struct
{
- struct Option *input, *output, *title, *bytes,
- *north, *south, *east, *west, *rows, *cols, *anull;
+ struct Option *input;
+ struct Option *output;
+ struct Option *null;
+ struct Option *bytes;
+ struct Option *order;
+ struct Option *title;
+ struct Option *north;
+ struct Option *south;
+ struct Option *east;
+ struct Option *west;
+ struct Option *rows;
+ struct Option *cols;
} parm;
struct
{
- struct Flag *s, *f, *d, *b, *gmt_hd;
+ struct Flag *float_in;
+ struct Flag *double_in;
+ struct Flag *gmt_hd;
+ struct Flag *sign;
+ struct Flag *swap;
} flag;
- struct GModule *module;
- union
- {
- int testWord;
- char testByte[4];
- } endianTest;
- int swapFlag;
+ const char *input;
+ const char *output;
+ const char *title;
+ double null_val = 0;
+ int is_fp;
+ int is_signed;
+ int bytes;
+ int order;
+ int swap_flag;
+ struct Cell_head cellhd;
+ int nrows, ncols;
+ int grass_nrows, grass_ncols;
+ unsigned char *in_buf;
+ DCELL *out_buf;
+ RASTER_MAP_TYPE map_type;
+ int fd;
+ FILE *fp;
+ off_t file_size;
+ struct GRD_HEADER header;
+ int row;
+ struct History history;
+ off_t expected;
G_gisinit(argv[0]);
@@ -121,29 +233,28 @@
module = G_define_module();
module->keywords = _("raster, import");
module->description =
- _("Import a binary raster file into a GRASS raster map layer.");
+ _("Import a binary raster file into a GRASS raster map.");
+ flag.float_in = G_define_flag();
+ flag.float_in->key = 'f';
+ flag.float_in->description =
+ _("Import as floating-point data (default: integer)");
- flag.f = G_define_flag();
- flag.f->key = 'f';
- flag.f->description =
- _("Import as Floating Point Data (default: Integer)");
+ flag.double_in = G_define_flag();
+ flag.double_in->key = 'd';
+ flag.double_in->description =
+ _("Import as double-precision floating-point data (default: integer)");
- flag.d = G_define_flag();
- flag.d->key = 'd';
- flag.d->description =
- _("Import as Double Precision Data (default: Integer)");
+ flag.sign = G_define_flag();
+ flag.sign->key = 's';
+ flag.sign->description = _("Signed data (two's complement)");
+ flag.sign->guisection = _("Settings");
- flag.s = G_define_flag();
- flag.s->key = 's';
- flag.s->description = _("Signed data (high bit means negative value)");
- flag.s->guisection = _("Settings");
+ flag.swap = G_define_flag();
+ flag.swap->key = 'b';
+ flag.swap->description = _("Byte Swap the Data During Import");
+ flag.swap->guisection = _("Settings");
- flag.b = G_define_flag();
- flag.b->key = 'b';
- flag.b->description = _("Byte Swap the Data During Import");
- flag.b->guisection = _("Settings");
-
flag.gmt_hd = G_define_flag();
flag.gmt_hd->key = 'h';
flag.gmt_hd->description = _("Get region info from GMT style header");
@@ -160,7 +271,7 @@
parm.title = G_define_option();
parm.title->key = "title";
- parm.title->key_desc = "\"phrase\"";
+ parm.title->key_desc = "phrase";
parm.title->type = TYPE_STRING;
parm.title->required = NO;
parm.title->description = _("Title for resultant raster map");
@@ -168,11 +279,19 @@
parm.bytes = G_define_option();
parm.bytes->key = "bytes";
parm.bytes->type = TYPE_INTEGER;
- parm.bytes->answer = "1";
parm.bytes->required = NO;
- parm.bytes->description = _("Number of bytes per cell (1, 2, 4)");
+ parm.bytes->options = "1,2,4,8";
+ parm.bytes->description = _("Number of bytes per cell");
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 = _("Output byte order");
+ parm.order->answer = "native";
+
parm.north = G_define_option();
parm.north->key = "north";
parm.north->type = TYPE_DOUBLE;
@@ -219,118 +338,97 @@
parm.cols->description = _("Number of columns");
parm.cols->guisection = _("Bounds");
- parm.anull = G_define_option();
- parm.anull->key = "anull";
- parm.anull->type = TYPE_DOUBLE;
- parm.anull->required = NO;
- parm.anull->description = _("Set Value to NULL");
- parm.anull->guisection = _("Settings");
+ parm.null = G_define_option();
+ parm.null->key = "anull";
+ parm.null->type = TYPE_DOUBLE;
+ parm.null->required = NO;
+ parm.null->description = _("Set Value to NULL");
+ parm.null->guisection = _("Settings");
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
input = parm.input->answer;
output = parm.output->answer;
- if (title = parm.title->answer)
- G_strip(title);
+ title = parm.title->answer;
- if (flag.f->answer)
- bytes = 4;
- else if (flag.d->answer)
- bytes = 8;
- else if (sscanf(parm.bytes->answer, "%d%1s", &bytes, dummy) != 1)
- G_fatal_error(_("Parsing bytes per cell"));
- if (bytes <= 0)
- G_fatal_error(_("Bad number of bytes per cell"));
- sflag = flag.s->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;
- swap = 0;
- if (flag.b->answer) {
- swap = 1;
- G_message(_("Byte Swapping Turned On."));
+ 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;
}
- /* Check Endian State of Host Computer */
- endianTest.testWord = 1;
- if (endianTest.testByte[0] == 1) {
- swapFlag = 1; /*true: little endian */
- if (swap == 1)
- swapFlag = 0; /* Swapping enabled */
+ swap_flag = order == (G_is_little_endian() ? 0 : 1);
+
+ is_signed = !!flag.sign->answer;
+
+ is_fp = 0;
+ bytes = 0;
+
+ if (parm.bytes->answer)
+ bytes = atoi(parm.bytes->answer);
+
+ if (flag.float_in->answer && flag.double_in->answer)
+ G_fatal_error(_("-f and -d are mutually exclusive"));
+
+ if (flag.float_in->answer) {
+ if (bytes && bytes < 4)
+ G_fatal_error(_("-f incompatible with bytes=%d; must be 4 or 8"), bytes);
+ if (!bytes)
+ bytes = 4;
+ is_fp = 1;
}
- else {
- swapFlag = 0;
- if (swap == 1)
- swapFlag = 1; /* Swapping enabled */
+
+ if (flag.double_in->answer) {
+ if (bytes && bytes != 8)
+ G_fatal_error(_("-d incompatible with bytes=%d; must be 8"), bytes);
+ if (!bytes)
+ bytes = 8;
+ is_fp = 1;
}
- cellhd.zone = G_zone();
- cellhd.proj = G_projection();
+ if (!is_fp && !bytes)
+ G_fatal_error(_("bytes= required for integer data"));
- if (!flag.gmt_hd->answer) { /* NO GMT header */
+#ifndef HAVE_LONG_LONG_INT
+ if (!is_fp && bytes > 4)
+ G_fatal_error(_("Integer input doesn't support size=8 in this build"));
+#endif
- /* Check for optional parameters */
- if (!parm.north->answer && !parm.south->answer && !parm.east->answer
- && !parm.west->answer) {
- no_coord = 1;
- /* No coordinates provided */
- }
- if (!parm.rows->answer && !parm.cols->answer) {
- no_dim = 1;
- /* No dimensions provided */
- }
- /* Done check */
+ if (bytes != 1 && bytes != 2 && bytes != 4 && bytes != 8)
+ G_fatal_error(_("bytes= must be 1, 2, 4 or 8"));
+ if (parm.null->answer)
+ null_val = atof(parm.null->answer);
- /* CASE 0 - Not enough parameters - exit */
- if (no_dim == 1 && no_coord == 1)
- G_fatal_error(_("Missing parameters ...\nMust provide at least"
- "[north= south= east= west=] OR [r= c=]"));
+ cellhd.zone = G_zone();
+ cellhd.proj = G_projection();
- /* CASE 1 - All parameters supplied */
- if (no_coord == 0 && no_dim == 0) { /* Get all parmameters */
- if (!parm.north->answer || !parm.south->answer ||
- !parm.west->answer || !parm.east->answer)
- G_fatal_error(_("You have to provide all limits of geographic region (n,s,e,w)"));
- if (!G_scan_northing(parm.north->answer, &cellhd.north, cellhd.proj))
- G_fatal_error(_("Illegal north coordinate <%s>"), parm.north->answer);
- if (!G_scan_northing(parm.south->answer, &cellhd.south, cellhd.proj))
- G_fatal_error(_("Illegal south coordinate <%s>"), parm.south->answer);
- if (!G_scan_easting(parm.east->answer, &cellhd.east, cellhd.proj))
- G_fatal_error(_("Illegal east coordinate <%s>"), parm.east->answer);
- if (!G_scan_easting(parm.west->answer, &cellhd.west, cellhd.proj))
- G_fatal_error(_("Illegal west coordinate <%s>"), parm.west->answer);
- if (sscanf(parm.rows->answer, "%d%1s", &cellhd.rows, dummy) != 1)
- G_fatal_error(_("Illegal number of rows <%s>"), parm.rows->answer);
- if (sscanf(parm.cols->answer, "%d%1s", &cellhd.cols, dummy) != 1)
- G_fatal_error(_("Illegal number of columns <%s>"), parm.cols->answer);
- }
+ if (!flag.gmt_hd->answer) {
+ /* NO GMT header */
+ int num_bounds;
- /* CASE 2 - Get only rows and columns and calculate N S E W */
- /* Only works with resolution = 1 */
- if (no_dim == 0 && no_coord == 1) { /* Get rows and cols only */
- if (sscanf(parm.rows->answer, "%d%1s", &cellhd.rows, dummy) != 1
- || cellhd.rows <= 0)
- G_fatal_error(_("Illegal number of rows <%s>"), parm.rows->answer);
- if (sscanf(parm.cols->answer, "%d%1s", &cellhd.cols, dummy) != 1
- || cellhd.cols <= 0)
- G_fatal_error(_("Illegal number of columns <%s>"), parm.cols->answer);
- cellhd.north = (double)cellhd.rows;
- cellhd.south = 0.;
- cellhd.east = (double)cellhd.cols;
- cellhd.west = 0.;
- G_message(_("Using N=%f S=%f E=%f W=%f"), cellhd.north,
- cellhd.south, cellhd.east, cellhd.west);
- }
+ if (!parm.rows->answer || !parm.cols->answer)
+ G_fatal_error(_("Either -h or rows= and cols= must be given"));
+ num_bounds = !!parm.north->answer + !!parm.south->answer +
+ !!parm.east->answer + !!parm.west->answer;
+ if (num_bounds != 0 && num_bounds != 4)
+ G_fatal_error(_("Either all or none of north=, south=, east= and west= must be given"));
- /* CASE 3 - Get only N S E & W */
- /* No rows and columns supplied - calculate from parameters */
- /* Assumes 1x1 resolution */
- if (no_coord == 0 && no_dim == 1) { /* Get n, s, e, w */
- if (!parm.north->answer || !parm.south->answer ||
- !parm.west->answer || !parm.east->answer)
- G_fatal_error(
- _("You have to provide all limits of geographic region (n,s,e,w)"));
+ cellhd.rows = atoi(parm.rows->answer);
+ cellhd.cols = atoi(parm.cols->answer);
+
+ if (num_bounds > 0) {
if (!G_scan_northing(parm.north->answer, &cellhd.north, cellhd.proj))
G_fatal_error(_("Illegal north coordinate <%s>"), parm.north->answer);
if (!G_scan_northing(parm.south->answer, &cellhd.south, cellhd.proj))
@@ -339,252 +437,90 @@
G_fatal_error(_("Illegal east coordinate <%s>"), parm.east->answer);
if (!G_scan_easting(parm.west->answer, &cellhd.west, cellhd.proj))
G_fatal_error(_("Illegal west coordinate <%s>"), parm.west->answer);
-
- /* Calculate rows and cols */
- cellhd.rows = (int)cellhd.north - cellhd.south;
- cellhd.cols = (int)cellhd.east - cellhd.west;
- G_message(_("Using rows=%d cols=%d\n"), cellhd.rows, cellhd.cols);
- } /* DONE */
+ }
}
+ fp = fopen(input, "rb");
+ if (!fp)
+ G_fatal_error(_("Unable to open <%s>"), input);
- if (parm.anull->answer != NULL)
- sscanf(parm.anull->answer, "%lf", &nul_val);
+ /* 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);
- fd = fopen(input, "r");
- if (fd == NULL) {
- perror(input);
- G_usage();
- exit(EXIT_FAILURE);
- }
-
/* Read binary GMT style header */
if (flag.gmt_hd->answer) {
- fread(&header.nx, sizeof(int), 1, fd);
- fread(&header.ny, sizeof(int), 1, fd);
- fread(&header.node_offset, sizeof(int), 1, fd);
- if (swapFlag == 0)
- fread(&header.node_offset, sizeof(int), 1, fd);
+ read_gmt_header(&header, swap_flag, fp);
+ get_gmt_header(&header, &cellhd);
+ }
- fread(&header.x_min, sizeof(double), 1, fd);
- fread(&header.x_max, sizeof(double), 1, fd);
- fread(&header.y_min, sizeof(double), 1, fd);
- fread(&header.y_max, sizeof(double), 1, fd);
- fread(&header.z_min, sizeof(double), 1, fd);
- fread(&header.z_max, sizeof(double), 1, fd);
- fread(&header.x_inc, sizeof(double), 1, fd);
- fread(&header.y_inc, sizeof(double), 1, fd);
- fread(&header.z_scale_factor, sizeof(double), 1, fd);
- fread(&header.z_add_offset, sizeof(double), 1, fd);
+ /* Adjust Cell Header to New Values */
+ G_adjust_Cell_head(&cellhd, 1, 1);
- fread(&header.x_units, sizeof(char[GRD_UNIT_LEN]), 1, fd);
- fread(&header.y_units, sizeof(char[GRD_UNIT_LEN]), 1, fd);
- fread(&header.z_units, sizeof(char[GRD_UNIT_LEN]), 1, fd);
- fread(&header.title, sizeof(char[GRD_TITLE_LEN]), 1, fd);
- fread(&header.command, sizeof(char[GRD_COMMAND_LEN]), 1, fd);
- fread(&header.remark, sizeof(char[GRD_REMARK_LEN]), 1, fd);
+ if (cellhd.proj == PROJECTION_LL && cellhd.ew_res / cellhd.ns_res > 10.)
+ /* TODO: find a reasonable value */
+ G_warning(
+ _("East-West (ewres: %f) and North-South (nwres: %f) "
+ "resolution differ significantly. "
+ "Did you assign east= and west= correctly?"),
+ cellhd.ew_res, cellhd.ns_res);
- cellhd.cols = header.nx;
- cellhd.rows = header.ny;
- cellhd.west = header.x_min;
- cellhd.east = header.x_max;
- cellhd.south = header.y_min;
- cellhd.north = header.y_max;
- cellhd.ew_res = header.x_inc;
- cellhd.ns_res = header.y_inc;
+ grass_nrows = nrows = cellhd.rows;
+ grass_ncols = ncols = cellhd.cols;
- if (swap == 1) {
- /* Swapping Header Values */
- SwabLong((uint32 *) & cellhd.cols);
- SwabLong((uint32 *) & cellhd.rows);
- SwabDouble(&cellhd.west);
- SwabDouble(&cellhd.east);
- SwabDouble(&cellhd.south);
- SwabDouble(&cellhd.north);
- SwabDouble(&cellhd.ew_res);
- SwabDouble(&cellhd.ns_res);
- }
+ G_set_window(&cellhd);
- /* Adjust Cell Header to match resolution */
- if (err = G_adjust_Cell_head(&cellhd, 0, 0)) {
- G_fatal_error("%s", err);
- exit(EXIT_FAILURE);
- }
- nrows = header.ny;
- ncols = header.nx;
- grass_nrows = cellhd.rows;
- grass_ncols = cellhd.cols;
- }
-
- if (!flag.gmt_hd->answer) {
- /* Adjust Cell Header to New Values */
- if (err = G_adjust_Cell_head(&cellhd, 1, 1)) {
- G_fatal_error("%s", err);
- exit(EXIT_FAILURE);
- }
- grass_nrows = nrows = cellhd.rows;
- grass_ncols = ncols = cellhd.cols;
- }
-
- if (G_set_window(&cellhd) < 0)
- exit(3);
-
if (grass_nrows != G_window_rows())
- G_fatal_error("rows changed from %d to %d\n", grass_nrows,
- G_window_rows());
+ G_fatal_error("rows changed from %d to %d",
+ grass_nrows, G_window_rows());
if (grass_ncols != G_window_cols())
- G_fatal_error("cols changed from %d to %d\n", grass_ncols,
- G_window_cols());
+ G_fatal_error("cols changed from %d to %d",
+ grass_ncols, G_window_cols());
+ expected = (off_t) ncols * nrows * bytes;
+ if (flag.gmt_hd->answer)
+ expected += 892;
- /* Find File Size in Byte and Check against byte size */
- if (stat(input, &fileinfo) < 0) {
- perror("fstat");
- exit(1);
+ if (file_size != expected) {
+ G_warning(_("File Size %"PRI_OFF_T" ... Total Bytes %"PRI_OFF_T),
+ file_size, expected);
+ G_fatal_error(_("Bytes do not match file size"));
}
- FILE_SIZE = fileinfo.st_size;
- if (flag.gmt_hd->answer) {
- if (swapFlag == 0) {
- if (FILE_SIZE != (896 + (ncols * nrows * bytes))) {
- G_warning(_("Bytes do not match File size"));
- G_warning(_("File Size %d ... Total Bytes %d"), FILE_SIZE,
- 896 + (ncols * nrows * bytes));
- G_warning(_("Try bytes=%d or adjusting input parameters"),
- (FILE_SIZE - 896) / (ncols * nrows));
- exit(EXIT_FAILURE);
- }
- }
- else {
- if (FILE_SIZE != (892 + (ncols * nrows * bytes))) {
- G_warning(_("Bytes do not match File size"));
- G_warning(_("File Size %d ... Total Bytes %d"), FILE_SIZE,
- 892 + (ncols * nrows * bytes));
- G_warning(_("Try bytes=%d or adjusting input parameters"),
- (FILE_SIZE - 892) / (ncols * nrows));
- exit(EXIT_FAILURE);
- }
- }
- }
- else {
- /* No Header */
- if (FILE_SIZE != (ncols * nrows * bytes)) {
- G_warning(_("Bytes do not match File size"));
- G_warning(_("File Size %d ... Total Bytes %d"), FILE_SIZE,
- ncols * nrows * bytes);
- G_warning(_("Try bytes=%d or adjusting input parameters"),
- FILE_SIZE / (ncols * nrows));
- exit(EXIT_FAILURE);
- }
- }
+ in_buf = G_malloc(ncols * bytes);
+ out_buf = G_allocate_d_raster_buf();
- if (flag.f->answer) {
- map_type = FCELL_TYPE;
- fcell = G_allocate_f_raster_buf();
- }
- else if (flag.d->answer) {
- map_type = DCELL_TYPE;
- dcell = G_allocate_d_raster_buf();
- }
- else {
- cell = G_allocate_c_raster_buf();
- map_type = CELL_TYPE;
- }
+ map_type = is_fp
+ ? (bytes > 4
+ ? DCELL_TYPE
+ : FCELL_TYPE)
+ : CELL_TYPE;
- cf = G_open_raster_new(output, map_type);
- if (cf < 0) {
- G_fatal_error(_("Unable to create raster map <%s>"), output);
- exit(EXIT_FAILURE);
- }
+ in_buf = G_malloc(ncols * bytes);
+ out_buf = G_allocate_d_raster_buf();
- x_v = G_malloc(ncols * bytes);
- x_f = (float *)x_v;
- x_d = (double *)x_v;
- x_i = (uint32 *) x_v;
- x_s = (uint16 *) x_v;
- x_c = (char *)x_v;
+ fd = G_open_raster_new(output, map_type);
- if (cellhd.proj == PROJECTION_LL && cellhd.ew_res / cellhd.ns_res > 10.) /* TODO: find a reasonable value */
- G_warning(
- _("East-West (ewres: %f) and North-South (nwres: %f) "
- "resolution differ significantly. "
- "Did you assign east= and west= correctly?"),
- cellhd.ew_res, cellhd.ns_res);
-
for (row = 0; row < grass_nrows; row++) {
- if (fread(x_v, bytes * ncols, 1, fd) != 1) {
- G_unopen_cell(cf);
- G_fatal_error(_("Conversion failed at row %d"), row);
- exit(EXIT_FAILURE);
- }
+ G_percent(row, nrows, 2);
- for (col = 0; col < grass_ncols; col++) {
- if (flag.f->answer) {
- /* Import Float */
- if (swap)
- SwabFloat(&x_f[col]);
- fcell[col] = (FCELL) x_f[col];
- }
- else if (flag.d->answer) {
- /* Import Double */
- if (swap)
- SwabDouble(&x_d[col]);
- dcell[col] = (DCELL) x_d[col];
- }
- else if (bytes == 1) {
- /* Import 1 byte Byte */
- if (sflag)
- cell[col] = (CELL) (signed char)x_c[col];
- else
- cell[col] = (CELL) (unsigned char)x_c[col];
- }
- else if (bytes == 2) {
- /* Import 2 byte Short */
- if (swap)
- SwabShort(&x_s[col]);
- if (sflag)
- cell[col] = (CELL) (signed short)x_s[col];
- else
- cell[col] = (CELL) (unsigned short)x_s[col];
- }
- else {
- /* Import 4 byte Int */
- if (swap)
- SwabLong(&x_i[col]);
- if (sflag)
- cell[col] = (CELL) (signed int)x_i[col];
- else
- cell[col] = (CELL) (unsigned int)x_i[col];
- }
- if (parm.anull->answer) {
- if (flag.d->answer) {
- if (dcell[col] == nul_val)
- G_set_d_null_value(&dcell[col], 1);
- }
- else if (flag.f->answer) {
- if (fcell[col] == (float)nul_val)
- G_set_f_null_value(&fcell[col], 1);
- }
- else {
- if (cell[col] == (int)nul_val)
- G_set_c_null_value(&cell[col], 1);
- }
- }
- }
+ if (fread(in_buf, bytes, ncols, fp) != ncols)
+ G_fatal_error(_("Error reading data"));
- if (flag.f->answer)
- G_put_f_raster_row(cf, fcell);
- else if (flag.d->answer)
- G_put_d_raster_row(cf, dcell);
- else
- G_put_c_raster_row(cf, cell);
+ convert_row(out_buf, in_buf, ncols, is_fp, is_signed,
+ bytes, swap_flag, null_val);
- G_percent(row + 1, nrows, 2);
+ G_put_d_raster_row(fd, out_buf);
}
+ G_percent(row, nrows, 2); /* finish it off */
+
+ G_close_cell(fd);
+ fclose(fp);
+
G_debug(1, "Creating support files for %s", output);
- G_close_cell(cf);
if (title)
G_put_cell_title(output, title);
@@ -593,6 +529,5 @@
G_command_history(&history);
G_write_history(output, &history);
-
- exit(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
Modified: grass/branches/releasebranch_6_4/raster/r.out.bin/main.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.out.bin/main.c 2011-04-13 11:11:59 UTC (rev 45933)
+++ grass/branches/releasebranch_6_4/raster/r.out.bin/main.c 2011-04-13 11:19:03 UTC (rev 45934)
@@ -1,8 +1,9 @@
/*
* r.out.bin
*
- * Copyright (C) 2000 by the GRASS Development Team
+ * Copyright (C) 2000,2010 by the GRASS Development Team
* Author: Bob Covill <bcovill at tekmap.ns.ca>
+ * Modified by Glynn Clements, 2010-01-10
*
* This program is free software under the GPL (>=v2)
* Read the file COPYING coming with GRASS for details.
@@ -13,55 +14,270 @@
#include <stdlib.h>
#include <string.h>
#include <grass/gis.h>
+#include <grass/raster.h>
#include <grass/glocale.h>
-#include "./gmt_grd.h"
-#include "./swab.h"
+#include "gmt_grd.h"
-int main(int argc, char *argv[])
+static void swap_2(void *p)
{
- void *raster, *ptr;
- RASTER_MAP_TYPE out_type, map_type;
- char *name;
- char outfile[GNAME_MAX];
- char *mapset;
- int null_str = 0;
- char buf[128];
- int fd;
- int row, col;
- int nrows, ncols;
- short number_i;
- int do_stdout = 0;
- int swapFlag;
- FILE *fp;
- struct GRD_HEADER header;
+ 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 write_int(FILE *fp, int swap_flag, int x)
+{
+ if (swap_flag)
+ swap_4(&x);
+
+ if (fwrite(&x, 4, 1, fp) != 1)
+ G_fatal_error(_("Error writing data"));
+}
+
+static void write_double(FILE *fp, int swap_flag, double x)
+{
+ if (swap_flag)
+ swap_8(&x);
+
+ if (fwrite(&x, 8, 1, fp) != 1)
+ G_fatal_error(_("Error writing data"));
+}
+
+static void make_gmt_header(
+ struct GRD_HEADER *header,
+ const char *name, const char *outfile,
+ const struct Cell_head *region, double null_val)
+{
struct FPRange range;
- DCELL Z_MIN, Z_MAX;
+ DCELL z_min, z_max;
- float number_f;
- double number_d;
- short null_val_i;
- float null_val_f;
- double null_val_d;
- struct Cell_head region;
+ G_read_fp_range(name, "", &range);
+ G_get_fp_range_min_max(&range, &z_min, &z_max);
+
+ header->nx = region->cols;
+ header->ny = region->rows;
+ header->node_offset = 1; /* 1 is pixel registration */
+ header->x_min = region->west;
+ header->x_max = region->east;
+ header->y_min = region->south;
+ header->y_max = region->north;
+ header->z_min = (double) z_min;
+ header->z_max = (double) z_max;
+ header->x_inc = region->ew_res;
+ header->y_inc = region->ns_res;
+ header->z_scale_factor = 1.0;
+ header->z_add_offset = 0.0;
+
+ if (region->proj == PROJECTION_LL) {
+ strcpy(header->x_units, "degrees");
+ strcpy(header->y_units, "degrees");
+ }
+ else {
+ strcpy(header->x_units, "Meters");
+ strcpy(header->y_units, "Meters");
+ }
+
+ strcpy(header->z_units, "elevation");
+ strcpy(header->title, name);
+ sprintf(header->command, "r.out.bin -h input=%s output=%s", name, outfile);
+ sprintf(header->remark, "%g used for NULL", null_val);
+}
+
+static void write_gmt_header(const struct GRD_HEADER *header, int swap_flag, FILE *fp)
+{
+ /* Write Values 1 at a time if byteswapping */
+ write_int(fp, swap_flag, header->nx);
+ write_int(fp, swap_flag, header->ny);
+ write_int(fp, swap_flag, header->node_offset);
+
+ write_double(fp, swap_flag, header->x_min);
+ write_double(fp, swap_flag, header->x_max);
+ write_double(fp, swap_flag, header->y_min);
+ write_double(fp, swap_flag, header->y_max);
+ write_double(fp, swap_flag, header->z_min);
+ write_double(fp, swap_flag, header->z_max);
+ write_double(fp, swap_flag, header->x_inc);
+ write_double(fp, swap_flag, header->y_inc);
+ write_double(fp, swap_flag, header->z_scale_factor);
+ write_double(fp, swap_flag, header->z_add_offset);
+
+ fwrite(header->x_units, sizeof(char[GRD_UNIT_LEN]), 1, fp);
+ fwrite(header->y_units, sizeof(char[GRD_UNIT_LEN]), 1, fp);
+ fwrite(header->z_units, sizeof(char[GRD_UNIT_LEN]), 1, fp);
+ fwrite(header->title, sizeof(char[GRD_TITLE_LEN]), 1, fp);
+ fwrite(header->command, sizeof(char[GRD_COMMAND_LEN]), 1, fp);
+ fwrite(header->remark, sizeof(char[GRD_REMARK_LEN]), 1, fp);
+}
+
+static void write_bil_hdr(
+ const char *outfile, const struct Cell_head *region,
+ int bytes, int order, int header, double null_val)
+{
+ char out_tmp[GPATH_MAX];
+ FILE *fp;
+
+ sprintf(out_tmp, "%s.hdr", outfile);
+ G_verbose_message(_("Header File = %s"), out_tmp);
+
+ /* Open Header File */
+ fp = fopen(out_tmp, "w");
+ if (!fp)
+ G_fatal_error(_("Unable to create file <%s>"), out_tmp);
+
+ fprintf(fp, "nrows %d\n", region->rows);
+ fprintf(fp, "ncols %d\n", region->cols);
+ fprintf(fp, "nbands 1\n");
+ fprintf(fp, "nbits %d\n", bytes * 8);
+ fprintf(fp, "byteorder %s\n", order == 0 ? "M" : "I");
+ fprintf(fp, "layout bil\n");
+ fprintf(fp, "skipbytes %d\n", header ? 892 : 0);
+ fprintf(fp, "nodata %g\n", null_val);
+
+ fclose(fp);
+}
+
+static void convert_cell(
+ unsigned char *out_cell, const DCELL in_cell,
+ int is_fp, int bytes, int swap_flag)
+{
+ if (is_fp) {
+ 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 (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 convert_row(
+ unsigned char *out_buf, const DCELL *raster, int ncols,
+ int is_fp, int bytes, int swap_flag, double null_val)
+{
+ unsigned char *ptr = out_buf;
+ int i;
+
+ for (i = 0; i < ncols; i++) {
+ DCELL x = G_is_d_null_value(&raster[i])
+ ? null_val
+ : raster[i];
+ convert_cell(ptr, x, is_fp, bytes, swap_flag);
+ ptr += bytes;
+ }
+}
+
+static void write_bil_wld(const char *outfile, const struct Cell_head *region)
+{
+ char out_tmp[GPATH_MAX];
+ FILE *fp;
+
+ sprintf(out_tmp, "%s.wld", outfile);
+ G_verbose_message(_("World File = %s"), out_tmp);
+
+ /* Open World File */
+ fp = fopen(out_tmp, "w");
+ if (!fp)
+ G_fatal_error(_("Unable to create file <%s>"), out_tmp);
+
+ fprintf(fp, "%f\n", region->ew_res);
+ fprintf(fp, "0.0\n");
+ fprintf(fp, "0.0\n");
+ fprintf(fp, "-%f\n", region->ns_res);
+ fprintf(fp, "%f\n", region->west + (region->ew_res / 2));
+ fprintf(fp, "%f\n", region->north - (region->ns_res / 2));
+
+ fclose(fp);
+}
+
+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, *gmt_hd, *BIL_hd, *swap;
+ 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();
- module->keywords = _("raster");
- module->description = _("Exports a GRASS raster to a binary array.");
+ module->keywords = _("raster, export");
+ module->description = _("Exports a GRASS raster map to a binary array.");
/* Define the different options */
@@ -81,23 +297,41 @@
parm.null = G_define_option();
parm.null->key = "null";
- parm.null->type = TYPE_INTEGER;
+ 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 =
- _("Output integer category values, not cell values");
+ 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.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';
@@ -106,313 +340,132 @@
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
- if (sscanf(parm.null->answer, "%d", &null_str) != 1)
+ 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)
- G_strncpy(outfile, parm.output->answer, sizeof(outfile) - 1);
+ outfile = parm.output->answer;
else {
- G_strncpy(outfile, name, sizeof(outfile) - 1 - 4);
- strcat(outfile, ".bin");
+ outfile = G_malloc(strlen(name) + 4 + 1);
+ sprintf(outfile, "%s.bin", name);
}
- if ((strcmp("-", outfile)) == 0)
- do_stdout = 1;
+ 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;
- G_get_window(®ion);
+ 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;
+ }
- mapset = G_find_cell(name, "");
+ swap_flag = order == (G_is_little_endian() ? 0 : 1);
- if (mapset == NULL)
- G_fatal_error(_("Raster map <%s> not found"), name);
+ do_stdout = strcmp("-", outfile) == 0;
- fd = G_open_cell_old(name, mapset);
- if (fd < 0)
- G_fatal_error(_("Unable to open raster map <%s>"), name);
+ if (flag.int_out->answer && flag.float_out->answer)
+ G_fatal_error(_("-i and -f are mutually exclusive"));
- map_type = G_get_raster_map_type(fd);
- if (!flag.int_out->answer)
- out_type = map_type;
+ fd = G_open_cell_old(name, "");
+
+ if (flag.int_out->answer)
+ is_fp = 0;
+ else if (flag.float_out->answer)
+ is_fp = 1;
else
- out_type = CELL_TYPE;
+ is_fp = G_get_raster_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(®ion);
+
/* 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);
- /* Check Endian State of Host Computer */
- if (G_is_little_endian()) {
- swapFlag = 1; /*true: little endian */
- if (flag.swap->answer)
- swapFlag = 0; /* Swapping enabled */
- }
- else {
- swapFlag = 0;
- if (flag.swap->answer)
- swapFlag = 1; /* Swapping enabled */
- }
-
-
/* Set up Parameters for GMT header */
if (flag.gmt_hd->answer) {
- G_read_fp_range(name, mapset, &range);
- G_get_fp_range_min_max(&range, &Z_MIN, &Z_MAX);
-
- header.nx = region.cols;
- header.ny = region.rows;
- header.node_offset = 1; /* 1 is pixel registration */
- header.x_min = (double)region.west;
- header.x_max = (double)region.east;
- header.y_min = (double)region.south;
- header.y_max = (double)region.north;
- header.z_min = (double)Z_MIN;
- header.z_max = (double)Z_MAX;
- header.x_inc = (double)region.ew_res;
- header.y_inc = (double)region.ns_res;
- header.z_scale_factor = (double)1.0;
- header.z_add_offset = (double)0.0;
-
- /* Swap Header if Required */
- if (flag.swap->answer) {
- G_message(_("Swapping header data"));
- TIFFSwabLong((uint32 *) & header.nx);
- TIFFSwabLong((uint32 *) & header.ny);
- TIFFSwabLong((uint32 *) & header.node_offset);
-
- TIFFSwabDouble((double *)&header.x_min);
- TIFFSwabDouble((double *)&header.x_max);
- TIFFSwabDouble((double *)&header.y_min);
- TIFFSwabDouble((double *)&header.y_max);
- TIFFSwabDouble((double *)&header.z_min);
- TIFFSwabDouble((double *)&header.z_max);
- TIFFSwabDouble((double *)&header.x_inc);
- TIFFSwabDouble((double *)&header.y_inc);
- TIFFSwabDouble((double *)&header.z_scale_factor);
- TIFFSwabDouble((double *)&header.z_add_offset);
- }
-
- if (region.proj == PROJECTION_LL) {
- strcpy(header.x_units, "degrees");
- strcpy(header.y_units, "degrees");
- }
- else {
- strcpy(header.x_units, "Meters");
- strcpy(header.y_units, "Meters");
- }
- strcpy(header.z_units, "elevation");
- strcpy(header.title, name);
- strcpy(header.command, "r.out.bin -h input=");
- strcat(header.command, name);
- strcat(header.command, " output=");
- strcat(header.command, outfile);
- if (flag.swap->answer)
- TIFFSwabLong((uint32 *) & null_str);
- sprintf(buf, "%d", null_str);
- strcpy(header.remark, buf);
- strcat(header.remark, " used for NULL");
+ if (!is_fp && bytes > 4)
+ G_fatal_error(_("GMT grid doesn't support 64-bit integers"));
+ make_gmt_header(&header, name, outfile, ®ion, null_val);
}
/* Write out BIL support files compatible with Arc-View */
- if (flag.BIL_hd->answer) {
- char out_tmp1[GPATH_MAX], out_tmp2[GPATH_MAX];
- FILE *fp_1, *fp_2;
-
- strcpy(out_tmp1, outfile);
- strcat(out_tmp1, ".hdr");
- strcpy(out_tmp2, outfile);
- strcat(out_tmp2, ".wld");
-
- /* Open Header File */
- if (NULL == (fp_1 = fopen(out_tmp1, "w")))
- G_fatal_error(_("Unable to create file <%s>"), out_tmp1);
-
- /* Open World File */
- if (NULL == (fp_2 = fopen(out_tmp2, "w")))
- G_fatal_error(_("Unable to create file <%s>"), out_tmp2);
-
-
+ if (flag.bil_hd->answer) {
G_message(_("Creating BIL support files..."));
- G_message(_("Header File = %s"), out_tmp1);
- G_message(_("World File = %s"), out_tmp2);
-
- fprintf(fp_1, "nrows %d\n", region.rows);
- fprintf(fp_1, "ncols %d\n", region.cols);
- fprintf(fp_1, "nbands 1\n");
-
- if (out_type == CELL_TYPE)
- fprintf(fp_1, "nbits 16\n");
- if (out_type == FCELL_TYPE)
- fprintf(fp_1, "nbits 32\n");
- if (out_type == DCELL_TYPE)
- fprintf(fp_1, "nbits 64\n");
- if (swapFlag == 1)
- fprintf(fp_1, "byteorder I\n"); /* Intel - little endian */
- if (swapFlag == 0)
- fprintf(fp_1, "byteorder M\n"); /* Motorola - big endian */
-
- fprintf(fp_1, "layout bil\n");
-
- if (flag.gmt_hd->answer) {
- if (swapFlag == 1)
- fprintf(fp_1, "skipbytes 892\n"); /* Real size of struct - little endian */
- else
- fprintf(fp_1, "skipbytes 896\n"); /* Pad size of struct - big endian */
- }
- else
- fprintf(fp_1, "skipbytes 0\n");
-
- fprintf(fp_1, "nodata %d\n", null_str);
-
- fclose(fp_1);
-
- fprintf(fp_2, "%f\n", region.ew_res);
- fprintf(fp_2, "0.0\n");
- fprintf(fp_2, "0.0\n");
- fprintf(fp_2, "-%f\n", region.ns_res);
- fprintf(fp_2, "%f\n", region.west + (region.ew_res / 2));
- fprintf(fp_2, "%f\n", region.north - (region.ns_res / 2));
-
- fclose(fp_2);
+ write_bil_hdr(outfile, ®ion,
+ bytes, order, flag.gmt_hd->answer, null_val);
+ write_bil_wld(outfile, ®ion);
}
- raster = G_allocate_raster_buf(out_type);
-
/* Write out GMT Header if required */
- if (flag.gmt_hd->answer) {
- /* Write Values 1 at a time if byteswapping */
- fwrite(&header.nx, sizeof(int), 1, fp);
- fwrite(&header.ny, sizeof(int), 1, fp);
- fwrite(&header.node_offset, sizeof(int), 1, fp);
- if (swapFlag == 0) /* Padding needed for big-endian */
- fwrite(&header.node_offset, sizeof(int), 1, fp);
+ if (flag.gmt_hd->answer)
+ write_gmt_header(&header, swap_flag, fp);
- fwrite(&header.x_min, sizeof(double), 1, fp);
- fwrite(&header.x_max, sizeof(double), 1, fp);
- fwrite(&header.y_min, sizeof(double), 1, fp);
- fwrite(&header.y_max, sizeof(double), 1, fp);
- fwrite(&header.z_min, sizeof(double), 1, fp);
- fwrite(&header.z_max, sizeof(double), 1, fp);
- fwrite(&header.x_inc, sizeof(double), 1, fp);
- fwrite(&header.y_inc, sizeof(double), 1, fp);
- fwrite(&header.z_scale_factor, sizeof(double), 1, fp);
- fwrite(&header.z_add_offset, sizeof(double), 1, fp);
-
- fwrite(&header.x_units, sizeof(char[GRD_UNIT_LEN]), 1, fp);
- fwrite(&header.y_units, sizeof(char[GRD_UNIT_LEN]), 1, fp);
- fwrite(&header.z_units, sizeof(char[GRD_UNIT_LEN]), 1, fp);
- fwrite(&header.title, sizeof(char[GRD_TITLE_LEN]), 1, fp);
- fwrite(&header.command, sizeof(char[GRD_COMMAND_LEN]), 1, fp);
- fwrite(&header.remark, sizeof(char[GRD_REMARK_LEN]), 1, fp);
- }
-
nrows = G_window_rows();
ncols = G_window_cols();
- if (out_type == CELL_TYPE) {
- G_message(_("Exporting raster as integer values (bytes=%d)"),
- sizeof(short));
+ in_buf = G_allocate_d_raster_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 integer format ID=2"));
+ G_message(_("Writing GMT float format ID=1"));
}
- if (out_type == FCELL_TYPE) {
- G_message(_("Exporting raster as floating values (bytes=%d)"),
- sizeof(float));
+ else {
+ G_message(_("Exporting raster as integer values (bytes=%d)"), bytes);
if (flag.gmt_hd->answer)
- G_message(_("Writing GMT float format ID=1"));
+ G_message(_("Writing GMT integer format ID=2"));
}
- if (out_type == DCELL_TYPE)
- G_message(_("Exporting raster as double values (bytes=%d)"),
- sizeof(double));
- G_message(_("Using the current region settings..."));
- G_message(_("north=%f"), region.north);
- G_message(_("south=%f"), region.south);
- G_message(_("east=%f"), region.east);
- G_message(_("west=%f"), region.west);
- G_message(_("r=%d"), region.rows);
- G_message(_("c=%d"), region.cols);
+ 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++) {
- if (G_get_raster_row(fd, raster, row, out_type) < 0)
- G_fatal_error(_("Reading map"));
G_percent(row, nrows, 2);
- for (col = 0, ptr = raster; col < ncols; col++,
- ptr = G_incr_void_ptr(ptr, G_raster_size(out_type))) {
- if (!G_is_null_value(ptr, out_type)) {
- if (out_type == CELL_TYPE) {
- number_i = *((CELL *) ptr);
- if (flag.swap->answer)
- TIFFSwabShort((uint16 *) & number_i);
- fwrite(&number_i, sizeof(short), 1, fp);
- }
- else if (out_type == FCELL_TYPE) {
- number_f = *((FCELL *) ptr);
- if (flag.swap->answer)
- TIFFSwabLong((uint32 *) & number_f);
- fwrite(&number_f, sizeof(float), 1, fp);
- }
- else if (out_type == DCELL_TYPE) {
- number_d = *((DCELL *) ptr);
- if (flag.swap->answer)
- TIFFSwabDouble((double *)&number_d);
- fwrite(&number_d, sizeof(double), 1, fp);
- }
- }
- else {
- if (out_type == CELL_TYPE) {
- null_val_i = (int)null_str;
- if (flag.swap->answer)
- TIFFSwabShort((uint16 *) & null_val_i);
- fwrite(&null_val_i, sizeof(short), 1, fp);
- }
- if (out_type == FCELL_TYPE) {
- null_val_f = (float)null_str;
- if (flag.swap->answer)
- TIFFSwabLong((uint32 *) & null_val_f);
- fwrite(&null_val_f, sizeof(float), 1, fp);
- }
- if (out_type == DCELL_TYPE) {
- null_val_d = (double)null_str;
- if (flag.swap->answer)
- TIFFSwabDouble((double *)&null_val_d);
- fwrite(&null_val_d, sizeof(double), 1, fp);
- }
+ G_get_d_raster_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 */
G_close_cell(fd);
fclose(fp);
- exit(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
-#ifdef UNUSED
-int set_type(char *str, RASTER_MAP_TYPE * out_type)
-{
- char *ch;
-
- ch = str;
- if (*ch != '%')
- G_fatal_error("wrong format: %s", str);
-
- while (*(++ch)) ;
- ch--;
- if (*ch == 'd' || *ch == 'i' || *ch == 'o' || *ch == 'u' || *ch == 'x' ||
- *ch == 'X')
- *out_type = CELL_TYPE;
- else if (*ch == 'f' || *ch == 'e' || *ch == 'E' || *ch == 'g' ||
- *ch == 'G')
- *out_type = DCELL_TYPE;
- /* *out_type = FCELL_TYPE; */
-
- return 0;
-}
-#endif
More information about the grass-commit
mailing list