home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)gmt_customio.c 2.9 5/25/95
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /*
- *
- * G M T _ C U S T O M I O . C R O U T I N E S
- *
- * Takes care of all custom format gridfile input/output. The
- * industrious user may supply his/her own code to read specific data
- * formats. Four functions must be supplied, and they must conform
- * to the GMT standard and return the same arguments as the generic
- * GMT grdio functions. See gmt_cdf.c for details.
- *
- * To add another data format:
- *
- * 1. Write the four required routines (see below).
- * 2. increment parameter N_GRD_FORMATS in file gmt_grdio.h
- * 3. Append another entry in the gmt_customio.h file.
- * 4. Provide another entry in the lib/gmtformats.d file
- *
- * Author: Paul Wessel
- * Date: 9-SEP-1992
- * Modified: 27-JUN-1995
- * Version: 3.0
- *
- * Functions include:
- *
- * *_read_grd_info : Read header from file
- * *_read_grd : Read header and data set from file
- * *_write_grd_info : Update header in existing file
- * *_write_grd : Write header and data set to new file
- *
- * where * is a prefix specific to a particular data format
- *
- * NOTE: 1. GMT assumes that read_grd_info has been called before calls
- * to read_grd.
- * 2. Some formats may permit pipes to be used. In that case GMT
- * expects the filename to be "=" (the equal sign). It is the
- * responsibility of the custom routines to test for "=" and
- * give error messages if piping is not supported for this format
- * (e.g., netcdf uses fseek and can therefore not use pipes; other
- * formats may have similar limitations)
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
-
- #include "gmt.h"
-
- int grdio_init () {
- int id;
-
- /* FORMAT # 0: Default GMT netcdf-based grdio LEAVE THIS AS IS! */
-
- gmtio_readinfo[0] = (PFI) cdf_read_grd_info;
- gmtio_writeinfo[0] = (PFI) cdf_write_grd_info;
- gmtio_readgrd[0] = (PFI) cdf_read_grd;
- gmtio_writegrd[0] = (PFI) cdf_write_grd;
-
- /*
- * ----------------------------------------------
- * ADD CUSTOM FORMATS BELOW AS THEY ARE NEEDED */
-
-
- /* FORMAT # 1: GMT native binary (float) grdio */
-
- id = 1;
- gmtio_readinfo[id] = (PFI) bin_read_grd_info;
- gmtio_writeinfo[id] = (PFI) bin_read_grd_info;
- gmtio_readgrd[id] = (PFI) bin_read_grd;
- gmtio_writegrd[id] = (PFI) bin_write_grd;
-
- /* FORMAT # 2: GMT native binary (short) grdio */
-
- id = 2;
- gmtio_readinfo[id] = (PFI) short_read_grd_info;
- gmtio_writeinfo[id] = (PFI) short_read_grd_info;
- gmtio_readgrd[id] = (PFI) short_read_grd;
- gmtio_writegrd[id] = (PFI) short_write_grd;
-
- /* FORMAT # 3: SUN 8-bit standard rasterfile grdio */
-
- id = 3;
- gmtio_readinfo[id] = (PFI) ras_read_grd_info;
- gmtio_writeinfo[id] = (PFI) ras_read_grd_info;
- gmtio_readgrd[id] = (PFI) ras_read_grd;
- gmtio_writegrd[id] = (PFI) ras_write_grd;
-
- /* FORMAT # 4: */
- id = 4;
-
- }
-
- /* CUSTOM I/O FUNCTIONS FOR GRIDDED DATA FILES */
-
- /*-----------------------------------------------------------
- * Format # : 1
- * Type : Native binary (float) C file
- * Prefix : bin_
- * Author : Paul Wessel, SOEST
- * Date : 27-JUN-1994
- * Purpose: The native binary output format is used
- * primarily for piped i/o between programs
- * that otherwise would use temporary, large
- * intermediate grdfiles. Note that not all
- * programs can support piping (they may have
- * to re-read the file or accept more than one
- * grdfile).
- * Functions : bin_read_grd_info, bin_write_grd_info,
- * bin_read_grd, bin_write_grd
- *-----------------------------------------------------------*/
-
- int bin_read_grd_info (file, header)
- char *file;
- struct GRD_HEADER *header; {
- FILE *fp;
-
- if (!strcmp (file, "="))
- fp = stdin;
- else if ((fp = fopen (file, "r")) == NULL) {
- fprintf (stderr, "GMT Fatal Error: Could not open file %s!\n", file);
- exit (-1);
- }
-
- if (fread ((char *)header, sizeof (struct GRD_HEADER), 1, fp) != 1) {
- fprintf (stderr, "GMT Fatal Error: Error reading file %s!\n", file);
- exit (-1);
- }
-
- if (fp != stdin) fclose (fp);
-
- return (FALSE);
- }
-
- int bin_write_grd_info (file, header)
- char *file;
- struct GRD_HEADER *header; {
- FILE *fp;
-
- if (!strcmp (file, "="))
- fp = stdout;
- else if ((fp = fopen (file, "w")) == NULL) {
- fprintf (stderr, "GMT Fatal Error: Could not create file %s!\n", file);
- exit (-1);
- }
-
- if (fwrite ((char *)header, sizeof (struct GRD_HEADER), 1, fp) != 1) {
- fprintf (stderr, "GMT Fatal Error: Error reading file %s!\n", file);
- exit (-1);
- }
-
- if (fp != stdout) fclose (fp);
-
- return (FALSE);
- }
-
- int bin_read_grd (file, header, grid, w, e, s, n, pad, complex)
- char *file;
- struct GRD_HEADER *header;
- float *grid;
- double w, e, s, n; /* Sub-region to extract [Use entire file if 0,0,0,0] */
- int pad[]; /* padding (# of empty rows/columns) on w, e, s, n of grid, respectively */
- BOOLEAN complex; /* TRUE if array is to hold real and imaginary parts */
- {
- int first_col, last_col, first_row, last_row, nm, one_or_zero;
- int i, j, j2, ij, width_in, width_out, height_in, i_0_out, inc = 1;
- FILE *fp;
- BOOLEAN piping = FALSE, geo = FALSE;
- float *tmp;
- double off, half_or_zero, x, small;
-
- if (!strcmp (file, "=")) {
- fp = stdin;
- piping = TRUE;
- }
- else if ((fp = fopen (file, "r")) != NULL) /* Skip header */
- fseek (fp, (long) sizeof (struct GRD_HEADER), 0);
- else {
- fprintf (stderr, "GMT Fatal Error: Could not open file %s!\n", file);
- exit (-1);
- }
-
- if (w == 0.0 && e == 0.0) { /* Get entire file and return */
- nm = header->nx * header->ny;
- if (fread ((char *)grid, sizeof (float), nm, fp) != nm) {
- fprintf (stderr, "GMT Fatal Error: Error reading file %s!\n", file);
- exit (-1);
- }
- return (FALSE);
- }
-
- /* Must deal with a subregion */
-
- if (w < header->x_min || e > header->x_max) geo = TRUE; /* Dealing with periodic grid */
-
- one_or_zero = (header->node_offset) ? 0 : 1;
- off = (header->node_offset) ? 0.0 : 0.5;
-
- /* Get dimension of subregion */
-
- width_in = rint ((e - w) / header->x_inc) + one_or_zero;
- height_in = rint ((n - s) / header->y_inc) + one_or_zero;
-
- /* Get first and last row and column numbers */
-
- small = 0.1 * header->x_inc;
- first_col = floor ((w - header->x_min + small) / header->x_inc);
- last_col = ceil ((e - header->x_min - small) / header->x_inc) - 1 + one_or_zero;
- small = 0.1 * header->y_inc;
- first_row = floor ((header->y_max - n + small) / header->y_inc);
- last_row = ceil ((header->y_max - s - small) / header->y_inc) - 1 + one_or_zero;
-
- if ((last_col - first_col + 1) > width_in) last_col--;
- if ((last_row - first_row + 1) > height_in) last_row--;
- if ((last_col - first_col + 1) > width_in) first_col++;
- if ((last_row - first_row + 1) > height_in) first_row++;
-
- width_out = width_in; /* Width of output array */
- if (pad[0] > 0) width_out += pad[0];
- if (pad[1] > 0) width_out += pad[1];
-
- i_0_out = pad[0]; /* Edge offset in output */
- if (complex) { /* Need twice as much space and load every 2nd cell */
- width_out *= 2;
- i_0_out *= 2;
- inc = 2;
- }
-
- if (geo) { /* Must rollover in longitudes */
- int *k;
- tmp = (float *) memory (CNULL, header->nx, sizeof (float), "bin_read_grd");
- k = (int *) memory (CNULL, width_in, sizeof (int), "bin_read_grd");
-
- half_or_zero = (header->node_offset) ? 0.5 : 0.0;
- small = 0.1 * header->x_inc; /* Anything smaller than 0.5 dx will do */
- for (i = 0; i < width_in; i++) {
- x = w + (i + half_or_zero) * header->x_inc;
- if ((header->x_min - x) > small)
- x += 360.0;
- else if ((x - header->x_max) > small)
- x -= 360.0;
- k[i] = (int) floor (((x - header->x_min) / header->x_inc) + off);
- }
- if (piping) /* Skip data by reading it */
- for (j = 0; j < first_row; j++) fread ((char *) tmp, sizeof (float), header->nx, fp);
- else /* Simply seek by it */
- fseek (fp, (long) (first_row * header->nx * sizeof (float)), 1);
-
- for (j = first_row, j2 = 0; j <= last_row; j++, j2++) {
- fread ((char *) tmp, sizeof (float), header->nx, fp); /* Get one row */
- ij = (j2 + pad[3]) * width_out + i_0_out;
- for (i = 0; i < width_in; i++) grid[ij+i*inc] = tmp[k[i]];
- }
- if (piping) /* Skip data by reading it */
- for (j = last_row + 1; j < header->ny; j++) fread ((char *) tmp, sizeof (float), header->nx, fp);
-
- free ((char *)k);
- }
- else { /* A bit easier here */
- tmp = (float *) memory (CNULL, width_in, sizeof (float), "bin_read_grd");
- if (piping) /* Skip data by reading it */
- for (j = 0; j < first_row; j++) fread ((char *) tmp, sizeof (float), header->nx, fp);
- else /* Simply seek by it */
- fseek (fp, (long) (first_row * header->nx * sizeof (float)), 1);
- for (j = first_row, j2 = 0; j <= last_row; j++, j2++) {
- ij = (j2 + pad[3]) * width_out + i_0_out;
- fread ((char *) tmp, sizeof (float), header->nx, fp);
- if (complex)
- for (i = 0; i < width_in; i++) grid[ij+2*i] = tmp[first_col+i];
- else
- for (i = 0; i < width_in; i++) grid[ij+i] = tmp[first_col+i];
- }
- if (piping) /* Skip data by reading it */
- for (j = last_row + 1; j < header->ny; j++) fread ((char *) tmp, sizeof (float), header->nx, fp);
- }
-
- header->nx = width_in;
- header->ny = height_in;
- header->x_min = w;
- header->x_max = e;
- header->y_min = s;
- header->y_max = n;
-
- header->z_min = MAXDOUBLE; header->z_max = -MAXDOUBLE;
- for (j = 0; j < header->ny; j++) {
- for (i = 0; i < header->nx; i++) {
- j2 = (complex) ? 2 * (i + pad[0]) : i + pad[0];
- ij = (j + pad[3]) * width_out + j2;
- if (bad_float ((double)grid[ij])) continue;
- header->z_min = MIN (header->z_min, grid[ij]);
- header->z_max = MAX (header->z_max, grid[ij]);
- }
- }
- if (fp != stdin) fclose (fp);
-
- free ((char *)tmp);
- return (FALSE);
- }
-
- int bin_write_grd (file, header, grid, w, e, s, n, pad, complex)
- char *file;
- struct GRD_HEADER *header;
- float *grid;
- double w, e, s, n; /* Sub-region to write out */
- int pad[]; /* padding on w, e, s, n of grid, respectively */
- BOOLEAN complex; /* TRUE if array is to hold real and imaginary parts */
- {
- int i, i2, nm, inc = 1, *k;
- int j, ij, j2, width_in, width_out, height_out, one_or_zero;
- int first_col, last_col, first_row, last_row;
-
- BOOLEAN geo = FALSE;
- double off, half_or_zero, small, x;
-
- float *tmp;
-
- FILE *fp;
-
- if (!strcmp (file, "=")) {
- fp = stdout;
- }
- else if ((fp = fopen (file, "w")) == NULL) {
- fprintf (stderr, "GMT Fatal Error: Could not create file %s!\n", file);
- exit (-1);
- }
-
- if (w == 0.0 && e == 0.0) { /* Write entire file and return */
- /* Find min/max of data */
-
- nm = header->nx * header->ny;
- header->z_min = MAXDOUBLE; header->z_max = -MAXDOUBLE;
-
- for (i = 0; i < nm; i++) {
- ij = (complex) ? 2 * i : i;
- if (bad_float ((double)grid[ij])) continue;
- header->z_min = MIN (header->z_min, grid[ij]);
- header->z_max = MAX (header->z_max, grid[ij]);
- }
-
- if (fwrite ((char *)header, sizeof (struct GRD_HEADER), 1, fp) != 1) {
- fprintf (stderr, "GMT Fatal Error: Error writing file %s!\n", file);
- exit (-1);
- }
-
- nm = header->nx * header->ny;
- if (fwrite ((char *)grid, sizeof (float), nm, fp) != nm) {
- fprintf (stderr, "GMT Fatal Error: Error writing file %s!\n", file);
- exit (-1);
- }
- return (FALSE);
- }
-
- if (w < header->x_min || e > header->x_max) geo = TRUE; /* Dealing with periodic grid */
-
- one_or_zero = (header->node_offset) ? 0 : 1;
- off = (header->node_offset) ? 0.0 : 0.5;
-
- /* Get dimension of subregion to write */
-
- width_out = rint ((e - w) / header->x_inc) + one_or_zero;
- height_out = rint ((n - s) / header->y_inc) + one_or_zero;
-
- /* Get first and last row and column numbers */
-
- small = 0.1 * header->x_inc;
- first_col = floor ((w - header->x_min + small) / header->x_inc);
- last_col = ceil ((e - header->x_min - small) / header->x_inc) -1 + one_or_zero;
- small = 0.1 * header->y_inc;
- first_row = floor ((header->y_max - n + small) / header->y_inc);
- last_row = ceil ((header->y_max - s - small) / header->y_inc) -1 + one_or_zero;
-
- if ((last_col - first_col + 1) > width_out) last_col--;
- if ((last_row - first_row + 1) > height_out) last_row--;
- if ((last_col - first_col + 1) > width_out) first_col++;
- if ((last_row - first_row + 1) > height_out) first_row++;
-
- width_in = width_out; /* Physical width of input array */
- if (pad[0] > 0) width_in += pad[0];
- if (pad[1] > 0) width_in += pad[1];
-
- if (complex) inc = 2;
-
- header->x_min = w;
- header->x_max = e;
- header->y_min = s;
- header->y_max = n;
-
- /* Find xmin/zmax */
-
- header->z_min = MAXDOUBLE; header->z_max = -MAXDOUBLE;
- for (j = first_row, j2 = pad[3]; j <= last_row; j++, j2++) {
- for (i = first_col, i2 = pad[0]; i <= last_col; i++, i2++) {
- ij = (j2 * width_in + i2) * inc;
- if (bad_float ((double)grid[ij])) continue;
- header->z_min = MIN (header->z_min, grid[ij]);
- header->z_max = MAX (header->z_max, grid[ij]);
- }
- }
-
- /* store header information and array */
-
- if (fwrite ((char *)header, sizeof (struct GRD_HEADER), 1, fp) != 1) {
- fprintf (stderr, "GMT Fatal Error: Error writing file %s!\n", file);
- exit (-1);
- }
-
- if (geo) {
- tmp = (float *) memory (CNULL, width_in, sizeof (float), "bin_write_grd");
- k = (int *) memory (CNULL, width_out, sizeof (int), "bin_write_grd");
-
- half_or_zero = (header->node_offset) ? 0.5 : 0.0;
- small = 0.1 * header->x_inc; /* Anything smaller than 0.5 dx will do */
- for (i = 0; i < width_out; i++) {
- x = w + (i + half_or_zero) * header->x_inc;
- if ((header->x_min - x) > small)
- x += 360.0;
- else if ((x - header->x_max) > small)
- x -= 360.0;
- k[i] = (int) floor (((x - header->x_min) / header->x_inc) + off);
- }
- i2 = first_col + pad[0];
- for (j = 0, j2 = first_row + pad[3]; j < height_out; j++, j2++) {
- ij = j2 * width_in + i2;
- for (i = 0; i < width_out; i++) tmp[i] = grid[inc * (ij+k[i])];
- fwrite ((char *)tmp, sizeof (float), width_out, fp);
- }
- free ((char *)k);
- }
- else {
- if (complex) tmp = (float *) memory (CNULL, width_in, sizeof (float), "bin_write_grd");
- i2 = first_col + pad[0];
- for (j = 0, j2 = first_row + pad[3]; j < height_out; j++, j2++) {
- ij = j2 * width_in + i2;
- if (complex) {
- for (i = 0; i < width_out; i++) tmp[i] = grid[2*(ij+i)];
- fwrite ((char *)tmp, sizeof (float), width_out, fp);
- }
- else
- fwrite ((char *)&grid[ij], sizeof (float), width_out, fp);
- }
- }
- if (fp != stdout) fclose (fp);
-
- if (complex || geo) free ((char *)tmp);
-
- return (FALSE);
-
- }
-
- /*-----------------------------------------------------------
- * Format # : 2
- * Type : Native binary (short) C file
- * Prefix : bin_
- * Author : Paul Wessel, SOEST
- * Date : 27-JUN-1994
- * Purpose: The native binary output format is used
- * primarily for piped i/o between programs
- * that otherwise would use temporary, large
- * intermediate grdfiles. Note that not all
- * programs can support piping (they may have
- * to re-read the file or accept more than one
- * grdfile). Datasets with limited range may
- * be stored using 2-byte integers which will
- * reduce storage space and improve throughput.
- * Functions : short_read_grd_info, short_write_grd_info,
- * short_read_grd, short_write_grd
- *-----------------------------------------------------------*/
-
- int short_read_grd_info (file, header)
- char *file;
- struct GRD_HEADER *header; {
- return (bin_read_grd_info (file, header));
- }
-
- int short_write_grd_info (file, header)
- char *file;
- struct GRD_HEADER *header; {
- return (bin_write_grd_info (file, header));
- }
-
- int short_read_grd (file, header, grid, w, e, s, n, pad, complex)
- char *file;
- struct GRD_HEADER *header;
- float *grid;
- double w, e, s, n; /* Sub-region to extract [Use entire file if 0,0,0,0] */
- int pad[]; /* padding (# of empty rows/columns) on w, e, s, n of grid, respectively */
- BOOLEAN complex; /* TRUE if array is to hold real and imaginary parts */
- {
- int first_col, last_col, first_row, last_row, nm, kk, one_or_zero;
- int i, j, j2, ij, width_in, width_out, height_in, i_0_out, inc = 1;
- FILE *fp;
- BOOLEAN piping = FALSE, geo = FALSE, check = FALSE;
- short *tmp;
- double off, half_or_zero, x, small;
-
- if (complex) {
- fprintf (stderr, "GMT Fatal Error: short int grdfile %s cannot hold complex data!\n", file);
- exit (-1);
- }
- if (!strcmp (file, "=")) {
- fp = stdin;
- piping = TRUE;
- }
- else if ((fp = fopen (file, "r")) != NULL) /* Skip header */
- fseek (fp, (long) sizeof (struct GRD_HEADER), 0);
- else {
- fprintf (stderr, "GMT Fatal Error: Could not open file %s!\n", file);
- exit (-1);
- }
-
- check = !bad_float (grd_in_nan_value);
-
- if (w == 0.0 && e == 0.0) { /* Get entire file and return */
- nm = header->nx * header->ny;
- tmp = (short *) memory (CNULL, nm, sizeof (short), "short_read_grd");
- if (fread ((char *)tmp, sizeof (short), nm, fp) != nm) {
- fprintf (stderr, "GMT Fatal Error: Error reading file %s!\n", file);
- exit (-1);
- }
- for (i = 0; i < nm; i++) {
- grid[i] = tmp[i];
- if (check && grid[i] == grd_in_nan_value) grid[i] = gmt_NaN;
- }
- free ((char *)tmp);
- return (FALSE);
- }
-
- /* Must deal with a subregion */
-
- if (w < header->x_min || e > header->x_max) geo = TRUE; /* Dealing with periodic grid */
-
- one_or_zero = (header->node_offset) ? 0 : 1;
- off = (header->node_offset) ? 0.0 : 0.5;
-
- /* Get dimension of subregion */
-
- width_in = rint ((e - w) / header->x_inc) + one_or_zero;
- height_in = rint ((n - s) / header->y_inc) + one_or_zero;
-
- /* Get first and last row and column numbers */
-
- small = 0.1 * header->x_inc;
- first_col = floor ((w - header->x_min + small) / header->x_inc);
- last_col = ceil ((e - header->x_min - small) / header->x_inc) - 1 + one_or_zero;
- small = 0.1 * header->y_inc;
- first_row = floor ((header->y_max - n + small) / header->y_inc);
- last_row = ceil ((header->y_max - s - small) / header->y_inc) - 1 + one_or_zero;
-
- if ((last_col - first_col + 1) > width_in) last_col--;
- if ((last_row - first_row + 1) > height_in) last_row--;
- if ((last_col - first_col + 1) > width_in) first_col++;
- if ((last_row - first_row + 1) > height_in) first_row++;
-
- width_out = width_in; /* Width of output array */
- if (pad[0] > 0) width_out += pad[0];
- if (pad[1] > 0) width_out += pad[1];
-
- i_0_out = pad[0]; /* Edge offset in output */
-
- if (geo) { /* Must rollover in longitudes */
- int *k;
- tmp = (short *) memory (CNULL, header->nx, sizeof (short), "short_read_grd");
- k = (int *) memory (CNULL, width_in, sizeof (int), "short_read_grd");
-
- half_or_zero = (header->node_offset) ? 0.5 : 0.0;
- small = 0.1 * header->x_inc; /* Anything smaller than 0.5 dx will do */
- for (i = 0; i < width_in; i++) {
- x = w + (i + half_or_zero) * header->x_inc;
- if ((header->x_min - x) > small)
- x += 360.0;
- else if ((x - header->x_max) > small)
- x -= 360.0;
- k[i] = (int) floor (((x - header->x_min) / header->x_inc) + off);
- }
- if (piping) /* Skip data by reading it */
- for (j = 0; j < first_row; j++) fread ((char *) tmp, sizeof (short), header->nx, fp);
- else /* Simply seek by it */
- fseek (fp, (long) (first_row * header->nx * sizeof (short)), 1);
-
- for (j = first_row, j2 = 0; j <= last_row; j++, j2++) {
- fread ((char *) tmp, sizeof (short), header->nx, fp); /* Get one row */
- ij = (j2 + pad[3]) * width_out + i_0_out;
- for (i = 0; i < width_in; i++) {
- kk = ij+i*inc;
- grid[kk] = tmp[k[i]];
- if (check && grid[kk] == grd_in_nan_value) grid[kk] = gmt_NaN;
- }
- }
- if (piping) /* Skip data by reading it */
- for (j = last_row + 1; j < header->ny; j++) fread ((char *) tmp, sizeof (short), header->nx, fp);
-
- free ((char *)k);
- }
- else { /* A bit easier here */
- tmp = (short *) memory (CNULL, width_in, sizeof (short), "short_read_grd");
- if (piping) /* Skip data by reading it */
- for (j = 0; j < first_row; j++) fread ((char *) tmp, sizeof (short), header->nx, fp);
- else /* Simply seek by it */
- fseek (fp, (long) (first_row * header->nx * sizeof (short)), 1);
- for (j = first_row, j2 = 0; j <= last_row; j++, j2++) {
- ij = (j2 + pad[3]) * width_out + i_0_out;
- fread ((char *) tmp, sizeof (short), header->nx, fp);
- for (i = 0; i < width_in; i++) {
- kk = ij+i;
- grid[kk] = tmp[first_col+i];
- if (check && grid[kk] == grd_in_nan_value) grid[kk] = gmt_NaN;
- }
- }
- if (piping) /* Skip data by reading it */
- for (j = last_row + 1; j < header->ny; j++) fread ((char *) tmp, sizeof (short), header->nx, fp);
- }
-
- header->nx = width_in;
- header->ny = height_in;
- header->x_min = w;
- header->x_max = e;
- header->y_min = s;
- header->y_max = n;
-
- header->z_min = MAXDOUBLE; header->z_max = -MAXDOUBLE;
- for (j = 0; j < header->ny; j++) {
- for (i = 0; i < header->nx; i++) {
- ij = (j + pad[3]) * width_out + i + pad[0];
- if (bad_float ((double) grid[ij])) continue;
- header->z_min = MIN (header->z_min, grid[ij]);
- header->z_max = MAX (header->z_max, grid[ij]);
- }
- }
- if (fp != stdin) fclose (fp);
-
- free ((char *)tmp);
- return (FALSE);
- }
-
- int short_write_grd (file, header, grid, w, e, s, n, pad, complex)
- char *file;
- struct GRD_HEADER *header;
- float *grid;
- double w, e, s, n; /* Sub-region to write out */
- int pad[]; /* padding on w, e, s, n of grid, respectively */
- BOOLEAN complex; /* TRUE if array is to hold real and imaginary parts */
- {
- int i, i2, nm, kk, *k;
- int j, ij, j2, width_in, width_out, height_out, one_or_zero;
- int first_col, last_col, first_row, last_row, check = FALSE;
-
- BOOLEAN geo = FALSE;
- double off, half_or_zero, small, x;
-
- short *tmp;
-
- FILE *fp;
-
- if (complex) {
- fprintf (stderr, "GMT Fatal Error: short int grdfile %s cannot hold complex data!\n", file);
- exit (-1);
- }
- if (!strcmp (file, "=")) {
- fp = stdout;
- }
- else if ((fp = fopen (file, "w")) == NULL) {
- fprintf (stderr, "GMT Fatal Error: Could not create file %s!\n", file);
- exit (-1);
- }
-
- check = !bad_float (grd_out_nan_value);
-
- if (w == 0.0 && e == 0.0) { /* Write entire file and return */
- /* Find min/max of data */
-
- nm = header->nx * header->ny;
- header->z_min = MAXDOUBLE; header->z_max = -MAXDOUBLE;
- for (i = 0; i < nm; i++) {
- ij = (complex) ? 2 * i : i;
- if (bad_float ((double)grid[ij])) continue;
- header->z_min = MIN (header->z_min, grid[ij]);
- header->z_max = MAX (header->z_max, grid[ij]);
- }
- if (fwrite ((char *)header, sizeof (struct GRD_HEADER), 1, fp) != 1) {
- fprintf (stderr, "GMT Fatal Error: Error writing file %s!\n", file);
- exit (-1);
- }
-
- tmp = (short *) memory (CNULL, nm, sizeof (short), "short_read_grd");
- for (i = 0; i < nm; i++) {
- if (check && bad_float ((double)grid[i])) grid[i] = grd_out_nan_value;
- tmp[i] = rint ((double)grid[i]);
- }
- if (fwrite ((char *)tmp, sizeof (short), nm, fp) != nm) {
- fprintf (stderr, "GMT Fatal Error: Error writing file %s!\n", file);
- exit (-1);
- }
- free ((char *)tmp);
- return (FALSE);
- }
-
- if (w < header->x_min || e > header->x_max) geo = TRUE; /* Dealing with periodic grid */
-
- one_or_zero = (header->node_offset) ? 0 : 1;
- off = (header->node_offset) ? 0.0 : 0.5;
-
- /* Get dimension of subregion to write */
-
- width_out = rint ((e - w) / header->x_inc) + one_or_zero;
- height_out = rint ((n - s) / header->y_inc) + one_or_zero;
-
- /* Get first and last row and column numbers */
-
- small = 0.1 * header->x_inc;
- first_col = floor ((w - header->x_min + small) / header->x_inc);
- last_col = ceil ((e - header->x_min - small) / header->x_inc) -1 + one_or_zero;
- small = 0.1 * header->y_inc;
- first_row = floor ((header->y_max - n + small) / header->y_inc);
- last_row = ceil ((header->y_max - s - small) / header->y_inc) -1 + one_or_zero;
-
- if ((last_col - first_col + 1) > width_out) last_col--;
- if ((last_row - first_row + 1) > height_out) last_row--;
- if ((last_col - first_col + 1) > width_out) first_col++;
- if ((last_row - first_row + 1) > height_out) first_row++;
-
- width_in = width_out; /* Physical width of input array */
- if (pad[0] > 0) width_in += pad[0];
- if (pad[1] > 0) width_in += pad[1];
-
- header->x_min = w;
- header->x_max = e;
- header->y_min = s;
- header->y_max = n;
-
- /* Find xmin/zmax */
-
- header->z_min = MAXDOUBLE; header->z_max = -MAXDOUBLE;
- for (j = first_row, j2 = pad[3]; j <= last_row; j++, j2++) {
- for (i = first_col, i2 = pad[0]; i <= last_col; i++, i2++) {
- ij = j2 * width_in + i2;
- if (bad_float ((double)grid[ij])) continue;
- header->z_min = MIN (header->z_min, grid[ij]);
- header->z_max = MAX (header->z_max, grid[ij]);
- }
- }
-
- /* store header information and array */
-
- if (fwrite ((char *)header, sizeof (struct GRD_HEADER), 1, fp) != 1) {
- fprintf (stderr, "GMT Fatal Error: Error writing file %s!\n", file);
- exit (-1);
- }
-
- tmp = (short *) memory (CNULL, width_in, sizeof (short), "short_write_grd");
- if (geo) {
- k = (int *) memory (CNULL, width_out, sizeof (int), "short_write_grd");
-
- half_or_zero = (header->node_offset) ? 0.5 : 0.0;
- small = 0.1 * header->x_inc; /* Anything smaller than 0.5 dx will do */
- for (i = 0; i < width_out; i++) {
- x = w + (i + half_or_zero) * header->x_inc;
- if ((header->x_min - x) > small)
- x += 360.0;
- else if ((x - header->x_max) > small)
- x -= 360.0;
- k[i] = (int) floor (((x - header->x_min) / header->x_inc) + off);
- }
- i2 = first_col + pad[0];
- for (j = 0, j2 = first_row + pad[3]; j < height_out; j++, j2++) {
- ij = j2 * width_in + i2;
- for (i = 0; i < width_out; i++) {
- kk = ij+k[i];
- if (check && bad_float ((double)grid[kk])) grid[kk] = grd_out_nan_value;
- tmp[i] = rint ((double)grid[kk]);
- }
- fwrite ((char *)tmp, sizeof (short), width_out, fp);
- }
- free ((char *)k);
- }
- else {
- i2 = first_col + pad[0];
- for (j = 0, j2 = first_row + pad[3]; j < height_out; j++, j2++) {
- ij = j2 * width_in + i2;
- for (i = 0; i < width_out; i++) {
- kk = ij+i;
- if (check && bad_float ((double)grid[kk])) grid[kk] = grd_out_nan_value;
- tmp[i] = rint ((double)grid[kk]);
- }
- fwrite ((char *)tmp, sizeof (short), width_out, fp);
- }
- }
- if (fp != stdout) fclose (fp);
-
- free ((char *)tmp);
-
- return (FALSE);
-
- }
-
- /*-----------------------------------------------------------
- * Format # : 3
- * Type : Standard 8-bit Sun rasterfiles
- * Prefix : ras_
- * Author : Paul Wessel, SOEST
- * Date : 4-DEC-1994
- * Purpose: Rasterfiles may often be used to store
- * datasets of limited dynamic range where
- * 8-bits is all that is needed. Since the
- * usual information like w,e,s,n is not part
- * of a rasterfile's header, we assign default
- * values as follows:
- * w = s = 0.
- * e = ras_width;
- * n = ras_height;
- * dx = dy = 1
- * Such files are always pixel registrered
- *
- * Functions : ras_read_grd_info, ras_write_grd_info,
- * ras_read_grd, ras_write_grd
- *-----------------------------------------------------------*/
-
- struct rasterfile {
- int ras_magic;
- int ras_width;
- int ras_height;
- int ras_depth;
- int ras_length;
- int ras_type;
- int ras_maptype;
- int ras_maplength;
- };
-
- int ras_read_grd_info (file, header)
- char *file;
- struct GRD_HEADER *header; {
- FILE *fp;
- struct rasterfile h;
- unsigned char u;
- int i;
-
- if (!strcmp (file, "="))
- fp = stdin;
- else if ((fp = fopen (file, "r")) == NULL) {
- fprintf (stderr, "GMT Fatal Error: Could not open file %s!\n", file);
- exit (-1);
- }
-
- if (fread ((char *)&h, sizeof (struct rasterfile), 1, fp) != 1) {
- fprintf (stderr, "GMT Fatal Error: Error reading file %s!\n", file);
- exit (-1);
- }
- if (h.ras_type != 1 || h.ras_depth != 8) {
- fprintf (stderr, "GMT Fatal Error: file %s not 8-bit standard Sun rasterfile!\n", file);
- exit (-1);
- }
-
- for (i = 0; i < h.ras_maplength; i++) fread ((char *)&u, sizeof (unsigned char *), 1, fp); /* Skip colormap */
-
- if (fp != stdin) fclose (fp);
-
- grd_init (header, 0, (char **)NULL, FALSE);
-
- header->x_min = header->y_min = 0.0;
- header->x_max = header->nx = h.ras_width;
- header->y_max = header->ny = h.ras_height;
- header->x_inc = header->y_inc = 1.0;
- header->node_offset = 1;
-
- return (FALSE);
- }
-
- int ras_write_grd_info (file, header)
- char *file;
- struct GRD_HEADER *header; {
- FILE *fp;
- struct rasterfile h;
-
- if (!strcmp (file, "="))
- fp = stdout;
- else if ((fp = fopen (file, "w")) == NULL) {
- fprintf (stderr, "GMT Fatal Error: Could not create file %s!\n", file);
- exit (-1);
- }
-
- h.ras_magic = 0x59a66a95;
- h.ras_width = header->nx;
- h.ras_height = header->ny;
- h.ras_depth = 8;
- h.ras_length = header->ny * (int) ceil (header->nx/2.0) * 2;
- h.ras_type = 1;
- h.ras_maptype = 0;
- h.ras_maplength = 0;
-
- if (fwrite ((char *)&h, sizeof (struct rasterfile), 1, fp) != 1) {
- fprintf (stderr, "GMT Fatal Error: Error reading file %s!\n", file);
- exit (-1);
- }
-
- if (fp != stdout) fclose (fp);
-
- return (FALSE);
- }
-
- int ras_read_grd (file, header, grid, w, e, s, n, pad, complex)
- char *file;
- struct GRD_HEADER *header;
- float *grid;
- double w, e, s, n; /* Sub-region to extract [Use entire file if 0,0,0,0] */
- int pad[]; /* padding (# of empty rows/columns) on w, e, s, n of grid, respectively */
- BOOLEAN complex; /* Must be FALSE for rasterfiles */
- {
- int first_col, last_col, first_row, last_row, one_or_zero;
- int i, j, j2, ij, width_in, width_out, height_in, i_0_out, n2;
- FILE *fp;
- BOOLEAN piping = FALSE, check;
- unsigned char *tmp;
- double small;
- struct rasterfile h;
-
- if (complex) {
- fprintf (stderr, "GMT Fatal Error: Rasterfile %s cannot hold complex data!\n", file);
- exit (-1);
- }
- if (!strcmp (file, "=")) {
- fp = stdin;
- piping = TRUE;
- }
- else if ((fp = fopen (file, "r")) != NULL) { /* Skip header */
- if (fread ((char *)&h, sizeof (struct rasterfile), 1, fp) != 1) {
- fprintf (stderr, "GMT Fatal Error: Error reading file %s!\n", file);
- exit (-1);
- }
- if (h.ras_maplength) fseek (fp, (long) h.ras_maplength, 1);
- }
- else {
- fprintf (stderr, "GMT Fatal Error: Could not open file %s!\n", file);
- exit (-1);
- }
-
- n2 = (int) ceil (header->nx / 2.0) * 2;
- tmp = (unsigned char *) memory (CNULL, n2, sizeof (unsigned char), "ras_read_grd");
-
- header->z_min = MAXDOUBLE; header->z_max = -MAXDOUBLE;
-
- check = !bad_float (grd_in_nan_value);
-
- if (w == 0.0 && e == 0.0) { /* Get entire file and return */
- for (j = ij = 0; j < header->ny; j++) {
- if (fread ((char *)tmp, sizeof (unsigned char), n2, fp) != n2) {
- fprintf (stderr, "GMT Fatal Error: Error reading file %s!\n", file);
- exit (-1);
- }
- for (i = 0; i < header->nx; i++, ij++) {
- grid[ij] = tmp[i];
- if (check && grid[ij] == grd_in_nan_value) grid[ij] = gmt_NaN;
- if (bad_float ((double)grid[ij])) continue;
- header->z_min = MIN (header->z_min, grid[ij]);
- header->z_max = MAX (header->z_max, grid[ij]);
- }
- }
- free ((char *)tmp);
- return (FALSE);
- }
-
- /* Must deal with a subregion */
-
- one_or_zero = (header->node_offset) ? 0 : 1;
-
- /* Get dimension of subregion */
-
- width_in = rint ((e - w) / header->x_inc) + one_or_zero;
- height_in = rint ((n - s) / header->y_inc) + one_or_zero;
-
- /* Get first and last row and column numbers */
-
- small = 0.1 * header->x_inc;
- first_col = floor ((w - header->x_min + small) / header->x_inc);
- last_col = ceil ((e - header->x_min - small) / header->x_inc) - 1 + one_or_zero;
- small = 0.1 * header->y_inc;
- first_row = floor ((header->y_max - n + small) / header->y_inc);
- last_row = ceil ((header->y_max - s - small) / header->y_inc) - 1 + one_or_zero;
-
- if ((last_col - first_col + 1) > width_in) last_col--;
- if ((last_row - first_row + 1) > height_in) last_row--;
- if ((last_col - first_col + 1) > width_in) first_col++;
- if ((last_row - first_row + 1) > height_in) first_row++;
-
- width_out = width_in; /* Width of output array */
- if (pad[0] > 0) width_out += pad[0];
- if (pad[1] > 0) width_out += pad[1];
-
- i_0_out = pad[0]; /* Edge offset in output */
-
- if (piping) /* Skip data by reading it */
- for (j = 0; j < first_row; j++) fread ((char *) tmp, sizeof (unsigned char), n2, fp);
- else /* Simply seek by it */
- fseek (fp, (long) (first_row * n2 * sizeof (unsigned char)), 1);
- for (j = first_row, j2 = 0; j <= last_row; j++, j2++) {
- ij = (j2 + pad[3]) * width_out + i_0_out;
- fread ((char *) tmp, sizeof (unsigned char), n2, fp);
- for (i = 0; i < width_in; i++, ij++) {
- grid[ij] = tmp[first_col+i];
- if (check && grid[ij] == grd_in_nan_value) grid[ij] = gmt_NaN;
- if (bad_float ((double)grid[ij])) continue;
- header->z_min = MIN (header->z_min, grid[ij]);
- header->z_max = MAX (header->z_max, grid[ij]);
- }
- }
- if (piping) /* Skip data by reading it */
- for (j = last_row + 1; j < header->ny; j++) fread ((char *) tmp, sizeof (unsigned char), n2, fp);
-
- header->nx = width_in;
- header->ny = height_in;
- header->x_min = w;
- header->x_max = e;
- header->y_min = s;
- header->y_max = n;
-
- if (fp != stdin) fclose (fp);
-
- free ((char *)tmp);
- return (FALSE);
- }
-
- int ras_write_grd (file, header, grid, w, e, s, n, pad, complex)
- char *file;
- struct GRD_HEADER *header;
- float *grid;
- double w, e, s, n; /* Sub-region to write out */
- int pad[]; /* padding on w, e, s, n of grid, respectively */
- BOOLEAN complex; /* TRUE if array is to hold real and imaginary parts */
- {
- int i, i2, k, nm;
- int j, ij, j2, width_in, width_out, height_out, one_or_zero, n2;
- int first_col, last_col, first_row, last_row;
-
- BOOLEAN check;
- double small;
-
- unsigned char *tmp;
-
- FILE *fp;
-
- struct rasterfile h;
-
- if (complex) {
- fprintf (stderr, "GMT Fatal Error: Rasterfile %s cannot hold complex data!\n", file);
- exit (-1);
- }
- if (!strcmp (file, "=")) {
- fp = stdout;
- }
- else if ((fp = fopen (file, "w")) == NULL) {
- fprintf (stderr, "GMT Fatal Error: Could not create file %s!\n", file);
- exit (-1);
- }
-
- h.ras_magic = 0x59a66a95;
- h.ras_width = header->nx;
- h.ras_height = header->ny;
- h.ras_depth = 8;
- h.ras_length = header->ny * (int) ceil (header->nx/2.0) * 2;
- h.ras_type = 1;
- h.ras_maptype = 0;
- h.ras_maplength = 0;
-
- n2 = (int) ceil (header->nx / 2.0) * 2;
- tmp = (unsigned char *) memory (CNULL, n2, sizeof (unsigned char), "ras_write_grd");
-
- check = !bad_float (grd_out_nan_value);
-
- if (w == 0.0 && e == 0.0) { /* Write entire file and return */
- nm = header->nx * header->ny;
- header->z_min = MAXDOUBLE; header->z_max = -MAXDOUBLE;
-
- for (i = 0; i < nm; i++) {
- ij = (complex) ? 2 * i : i;
- if (bad_float ((double)grid[ij])) continue;
- header->z_min = MIN (header->z_min, grid[ij]);
- header->z_max = MAX (header->z_max, grid[ij]);
- }
-
- if (fwrite ((char *)&h, sizeof (struct rasterfile), 1, fp) != 1) {
- fprintf (stderr, "GMT Fatal Error: Error reading file %s!\n", file);
- exit (-1);
- }
-
- for (j = ij = 0; j < header->ny; j++) {
- for (i = 0; i < header->nx; i++, ij++) {
- if (check && bad_float ((double)grid[ij])) grid[ij] = grd_out_nan_value;
- tmp[i] = grid[ij];
- }
- if (fwrite ((char *)tmp, sizeof (unsigned char), n2, fp) != n2) {
- fprintf (stderr, "GMT Fatal Error: Error writing file %s!\n", file);
- exit (-1);
- }
- }
- return (FALSE);
- }
-
- one_or_zero = (header->node_offset) ? 0 : 1;
-
- /* Get dimension of subregion to write */
-
- width_out = rint ((e - w) / header->x_inc) + one_or_zero;
- height_out = rint ((n - s) / header->y_inc) + one_or_zero;
-
- /* Get first and last row and column numbers */
-
- small = 0.1 * header->x_inc;
- first_col = floor ((w - header->x_min + small) / header->x_inc);
- last_col = ceil ((e - header->x_min - small) / header->x_inc) -1 + one_or_zero;
- small = 0.1 * header->y_inc;
- first_row = floor ((header->y_max - n + small) / header->y_inc);
- last_row = ceil ((header->y_max - s - small) / header->y_inc) -1 + one_or_zero;
-
- if ((last_col - first_col + 1) > width_out) last_col--;
- if ((last_row - first_row + 1) > height_out) last_row--;
- if ((last_col - first_col + 1) > width_out) first_col++;
- if ((last_row - first_row + 1) > height_out) first_row++;
-
- width_in = width_out; /* Physical width of input array */
- if (pad[0] > 0) width_in += pad[0];
- if (pad[1] > 0) width_in += pad[1];
-
- header->x_min = w;
- header->x_max = e;
- header->y_min = s;
- header->y_max = n;
-
- h.ras_width = header->nx;
- h.ras_height = header->ny;
- h.ras_length = header->ny * (int) ceil (header->nx/2.0) * 2;
-
- /* store header information and array */
-
- if (fwrite ((char *)&h, sizeof (struct rasterfile), 1, fp) != 1) {
- fprintf (stderr, "GMT Fatal Error: Error writing file %s!\n", file);
- exit (-1);
- }
-
- i2 = first_col + pad[0];
- for (j = 0, j2 = first_row + pad[3]; j < height_out; j++, j2++) {
- ij = j2 * width_in + i2;
- for (i = 0; i < width_out; i++) {
- k = ij + i;
- if (check && bad_float ((double)grid[k])) grid[k] = grd_out_nan_value;
- tmp[i] = grid[k];
- }
- fwrite ((char *)tmp, sizeof (unsigned char), width_out, fp);
- }
- if (fp != stdout) fclose (fp);
-
- free ((char *)tmp);
-
- return (FALSE);
-
- }
- /* Add custom code here */
-
- /*-----------------------------------------------------------
- * Format # : 4
- * Type :
- * Prefix :
- * Author :
- * Date :
- * Purpose:
- * Functions :
- *
- *-----------------------------------------------------------*/
-