home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)grdimage.c 2.42 22 Jun 1995
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /*
- * grdimage will read a grdfile and image the area using the PostScript
- * image command. If non-linear scaling is chosen, we first resample the data
- * onto the new grid before calling the image command. THe output image
- * will be 1-, 8-, or 24-bit depending on colors used.
- *
- * Author: Paul Wessel
- * Date: 21-MAY-1991-1995
- * Ver: 3.0 based on old 2.x
- */
-
- #include "gmt.h"
-
- #define YIQ(r, g, b) rint (0.299 * (r) + 0.587 * (g) + 0.114 * (b)) /* How B/W TV's convert RGB to Gray */
-
- float *tmp1, *tmp2, *map, *intensity;
- unsigned char *bitimage_8, *bitimage_24;
-
- char *c_method[3] = {
- "colorimage",
- "colortiles",
- "RGB-separation"
- };
-
- main (argc, argv)
- int argc;
- char **argv; {
- int i, j, k, kk, r, g, b, nm, nm2, byte, off, nx_f, ny_f, grid_type;
- int nx, ny, pad[4], dpi = 0, nx_proj = 0, ny_proj = 0, node;
-
- BOOLEAN error = FALSE, intens = FALSE, monochrome = FALSE;
- BOOLEAN mapped = FALSE, set_dpi = FALSE;
-
- double dx, dy, x_side, y_side, x0 = 0.0, y0 = 0.0;
- double west, east, south, north, data_west, data_east, data_south, data_north;
-
- char *grdfile, *intensfile, *cpt_file;
-
- struct GRD_HEADER g_head, r_head, i_head, j_head;
-
- argc = gmt_begin (argc, argv);
-
- grd_init (&g_head, argc, argv, FALSE);
- grd_init (&r_head, argc, argv, FALSE);
-
- grdfile = intensfile = cpt_file = CNULL;
- west = east = south = north = 0.0;
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
- /* Common parameters */
-
- case 'B':
- case 'J':
- case 'K':
- case 'O':
- case 'P':
- case 'R':
- case 'U':
- case 'V':
- case 'X':
- case 'x':
- case 'Y':
- case 'y':
- case 'c':
- case '\0':
- error += get_common_args (argv[i], &west, &east, &south, &north);
- break;
-
- /* Supplemental parameters */
-
- case 'C':
- cpt_file = &argv[i][2];
- break;
- case 'E':
- dpi = atoi (&argv[i][2]);
- set_dpi = TRUE;
- break;
- case 'F':
- if (gmt_getrgb (&argv[i][2], &gmtdefs.basemap_frame_rgb[0], &gmtdefs.basemap_frame_rgb[1], &gmtdefs.basemap_frame_rgb[2])) {
- gmt_pen_syntax ('F');
- error++;
- }
- break;
- case 'I':
- intens = TRUE;
- intensfile = &argv[i][2];
- break;
- case 'M':
- monochrome = TRUE;
- break;
- case '0':
- gmtdefs.color_image = 0;
- break;
- case '1':
- gmtdefs.color_image = 1;
- break;
- case '2':
- gmtdefs.color_image = 2;
- break;
- default:
- error = TRUE;
- gmt_default_error (argv[i][1]);
- break;
- }
- }
- else
- grdfile = argv[i];
- }
-
- if (argc == 1 || gmt_quick) {
- fprintf (stderr,"grdimage %s - Plot grdfiles in 2-D\n\n", GMT_VERSION);
- fprintf (stderr, "usage: grdimage <grdfile> -C<cpt_file> -J<params> [-B<tickinfo>] [-E<dpi>] [-F<r/g/b>]\n");
- fprintf (stderr, " [-I<intensity_file>] [-K] [-M] [-O] [-P] [-R<w/e/s/n>] [-U] [-V] [-X<x_shift>]\n");
- fprintf (stderr, " [-Y<y_shift>] [-0 -1 -2] [-c<ncopies>]\n\n");
-
- if (gmt_quick) exit (-1);
-
- fprintf (stderr," <grdfile> is data set to be plotted\n");
- fprintf (stderr," -C color palette file\n");
- explain_option ('j');
- fprintf (stderr,"\n\tOPTIONS:\n");
- explain_option ('b');
- fprintf(stderr, " -E sets dpi for the projected grid which must be constructed\n");
- fprintf(stderr, " if -Jx or -Jm is not selected [Default gives same size as input grid]\n");
- fprintf (stderr, " -F Set color used for Frame and anotation [%d/%d/%d]\n",
- gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
- fprintf (stderr," -I use illumination. Append name of intensity grd file\n");
- explain_option ('K');
- fprintf (stderr, " -M force monochrome image\n");
- explain_option ('O');
- explain_option ('P');
- explain_option ('R');
- explain_option ('U');
- explain_option ('V');
- explain_option ('X');
- fprintf (stderr," -0 plot color image using colorimage.\n");
- fprintf (stderr," -1 plot color image using tiles.\n");
- fprintf (stderr," -2 plot color image using psto24.\n");
- fprintf (stderr," [Default = %d]\n", gmtdefs.color_image);
- explain_option ('c');
- explain_option ('.');
- exit(-1);
- }
-
- if (!grdfile) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify input file\n", gmt_program);
- error++;
- }
- if (!cpt_file) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify color palette table\n", gmt_program);
- error++;
- }
- if (intens && !intensfile) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -I option: Must specify intensity file\n", gmt_program);
- error++;
- }
- if (set_dpi && dpi <= 0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -E option: dpi must be positive\n", gmt_program);
- error++;
- }
- if (error) exit (-1);
-
- /* Get color palette file */
-
- read_cpt (cpt_file);
-
- /* Check limits and get data file */
-
- if (gmtdefs.verbose) fprintf (stderr, "grdimage: Allocates memory and read data file\n");
-
- if (read_grd_info (grdfile, &g_head)) {
- fprintf (stderr, "grdimage: Error opening file %s\n", grdfile);
- exit (-1);
- }
- off = (g_head.node_offset) ? 0 : 1;
-
- /* Determine what wesn to pass to map_setup */
-
- if (west == east && south == north) {
- west = g_head.x_min;
- east = g_head.x_max;
- south = g_head.y_min;
- north = g_head.y_max;
- }
-
- map_setup (west, east, south, north);
-
- /* Determine the wesn to be used to read the grdfile */
-
- grd_setregion (&g_head, &data_west, &data_east, &data_south, &data_north);
-
- nx_f = g_head.nx;
- ny_f = g_head.ny;
- pad[0] = pad[1] = pad[2] = pad[3] = 0;
-
- /* Read data */
-
- nx = rint ( (data_east - data_west) / g_head.x_inc) + off;
- ny = rint ( (data_north - data_south) / g_head.y_inc) + off;
- nm = nx * ny;
- tmp1 = (float *) memory (CNULL, nm, sizeof (float), "grdimage");
- if (read_grd (grdfile, &g_head, tmp1, data_west, data_east, data_south, data_north, pad, FALSE)) {
- fprintf (stderr, "grdcontour: Error reading file %s\n", grdfile);
- exit (-1);
- }
-
- /* If given, get intensity file or compute intensities */
-
- if (intens) { /* Illumination wanted */
-
- if (gmtdefs.verbose) fprintf (stderr, "grdimage: Allocates memory and read intensity file\n");
-
- grd_init (&i_head, argc, argv, FALSE);
- grd_init (&j_head, argc, argv, FALSE);
-
- if (read_grd_info (intensfile, &i_head)) {
- fprintf (stderr, "grdimage: Error opening file %s\n", intensfile);
- exit (-1);
- }
-
- if (i_head.nx != nx_f || i_head.ny != ny_f) {
- fprintf (stderr, "grdimage: Intensity file has improper dimensions!\n");
- exit (-1);
- }
- tmp2 = (float *) memory (CNULL, nm, sizeof (float), "grdimage");
-
- if (read_grd (intensfile, &i_head, tmp2, data_west, data_east, data_south, data_north, pad, FALSE)) {
- fprintf (stderr, "grdimage: Error reading file %s\n", intensfile);
- exit (-1);
- }
- }
-
- r_head.x_min = project_info.xmin; r_head.x_max = project_info.xmax;
- r_head.y_min = project_info.ymin; r_head.y_max = project_info.ymax;
-
- if (dpi > 0 || (project_info.projection > 5)) { /* Need to resample the grd file */
-
- mapped = TRUE;
-
- if (gmtdefs.verbose) fprintf (stderr, "grdimage: project grdfiles\n");
-
- if (dpi == 0) { /* Use input # of nodes as # of projected nodes */
- nx_proj = g_head.nx;
- ny_proj = g_head.ny;
- }
- grid_type = (dpi > 0) ? 1 : g_head.node_offset; /* Force pixel if dpi is set */
- grdproject_init (&r_head, 0.0, 0.0, nx_proj, ny_proj, dpi, grid_type);
- nm2 = r_head.nx * r_head.ny;
- map = (float *) memory (CNULL, nm2, sizeof (float), "grdproject");
-
- grd_forward (tmp1, &g_head, map, &r_head, 0.0, FALSE);
-
- free ((char *)tmp1);
- if (intens) {
- j_head.x_min = r_head.x_min; j_head.x_max = r_head.x_max;
- j_head.y_min = r_head.y_min; j_head.y_max = r_head.y_max;
-
- if (dpi == 0) { /* Use input # of nodes as # of projected nodes */
- nx_proj = i_head.nx;
- ny_proj = i_head.ny;
- }
- grdproject_init (&j_head, 0.0, 0.0, nx_proj, ny_proj, dpi, grid_type);
- intensity = (float *) memory (CNULL, nm2, sizeof (float), "grdproject");
- grd_forward (tmp2, &i_head, intensity, &j_head, 0.0, FALSE);
- free ((char *)tmp2);
- }
- nm = nm2;
- }
- else { /* Simply copy g_head info to r_head */
- map = tmp1;
- r_head.nx = g_head.nx; r_head.ny = g_head.ny;
- r_head.x_inc = g_head.x_inc; r_head.y_inc = g_head.y_inc;
- if (intens) {
- j_head.nx = i_head.nx; j_head.ny = i_head.ny;
- j_head.x_inc = i_head.x_inc; j_head.y_inc = i_head.y_inc;
- intensity = tmp2;
- }
- grid_type = g_head.node_offset;
- }
-
- ps_plotinit (CNULL, gmtdefs.overlay, gmtdefs.page_orientation, gmtdefs.x_origin, gmtdefs.y_origin,
- gmtdefs.global_x_scale, gmtdefs.global_y_scale, gmtdefs.n_copies,
- gmtdefs.dpi, gmtdefs.measure_unit , gmtdefs.paper_width, gmtdefs.page_rgb, gmt_epsinfo (argv[0]));
- echo_command (argc, argv);
- if (gmtdefs.unix_time) timestamp (argc, argv);
-
- if (gmtdefs.verbose) fprintf (stderr, "grdimage: Evaluate pixel colors\n");
-
- if (monochrome || gmt_gray)
- bitimage_8 = (unsigned char *) memory (CNULL, nm, sizeof (char), "grdimage");
- else
- bitimage_24 = (unsigned char *) memory (CNULL, 3 * nm, sizeof (char), "grdimage");
-
- nm2 = 2 * nm;
-
- for (j = byte = 0; j < r_head.ny; j++) {
- kk = r_head.nx * (project_info.xyz_pos[1] ? j : r_head.ny - j - 1);
- for (i = 0; i < r_head.nx; i++) { /* Compute rgb for each pixel */
- node = kk + (project_info.xyz_pos[0] ? i : r_head.nx - i - 1);
- get_rgb24 (map[node], &r, &g, &b);
- if (intens) illuminate (intensity[node], &r, &g, &b);
-
- if (gmt_gray) /* Color table only has grays, pick r */
- bitimage_8[byte++] = (unsigned char) r;
- else if (monochrome) /* Convert rgb to gray using the YIQ transformation */
- bitimage_8[byte++] = (unsigned char) YIQ (r, g, b);
- else if (gmtdefs.color_image == 2) { /* RGB separation */
- bitimage_24[byte] = r;
- bitimage_24[byte+nm] = g;
- bitimage_24[byte+nm2] = b;
- byte++;
- }
- else {
- bitimage_24[byte++] = r;
- bitimage_24[byte++] = g;
- bitimage_24[byte++] = b;
- }
- }
- }
-
- free ((char *)map);
- if (intens) free ((char *)intensity);
-
- dx = (r_head.x_max - r_head.x_min) / (r_head.nx - off);
- dy = (r_head.y_max - r_head.y_min) / (r_head.ny - off);
-
- x0 = r_head.x_min; y0 = r_head.y_min;
- if (mapped || grid_type == 0) { /* Grid registration */
- x0 -= 0.5 * dx;
- y0 -= 0.5 * dy;
- map_clip_on (-1, -1, -1, 3);
- }
- x_side = dx * r_head.nx;
- y_side = dy * r_head.ny;
-
- if (gmtdefs.verbose) fprintf (stderr, "grdimage: Creating PostScript image ");
-
- if (gmt_gray) for (k = 0; gmt_b_and_w && k < nm; k++) if (!(bitimage_8[k] == 0 || bitimage_8[k] == 255)) gmt_b_and_w = FALSE;
-
- if (gmt_b_and_w) { /* Can get away with 1 bit image */
- int nx8, shift, byte, b_or_w, k8;
- unsigned char *bit;
-
- if (gmtdefs.verbose) fprintf (stderr, "[1-bit B/W image]\n");
- nx8 = ceil (r_head.nx / 8.0);
- bit = (unsigned char *) memory (CNULL, (int)(nx8 * r_head.ny), sizeof (char), "grdimage");
-
- for (j = k = k8 = 0; j < r_head.ny; j++) {
- shift = byte = 0;
- for (i = 0; i < r_head.nx; i++, k++) {
- b_or_w = (bitimage_8[k] == 255);
- byte |= b_or_w;
- shift++;
- if (shift == 8) { /* Time to dump out byte */
- bit[k8++] = byte;
- byte = shift = 0;
- }
- else
- byte <<= 1;
- }
- if (shift) {
- byte |= 1;
- shift++;
- while (shift < 8) {
- byte <<= 1;
- byte |= 1;
- shift++;
- }
- bit[k8++] = byte;
- }
- }
- free ((char *)bitimage_8);
-
- x_side = nx8 * 8.0 * dx;
- if ((nx8 * 8) > r_head.nx && grid_type == 1) { /* must clip since 1-bit image is wider */
- map_clip_on (-1, -1, -1, 3);
- mapped = TRUE;
- }
- ps_image (x0, y0, x_side, y_side, bit, nx8, r_head.ny, 1);
- free ((char *)bit);
- }
- else if (gmt_gray || monochrome) {
- if (gmtdefs.verbose) fprintf (stderr, "[8-bit grayshade image]\n");
- ps_image (x0, y0, x_side, y_side, bitimage_8, r_head.nx, r_head.ny, 8);
- free ((char *)bitimage_8);
- }
- else {
- if (gmtdefs.verbose) fprintf (stderr, "24-bit [%s]\n", c_method[gmtdefs.color_image]);
- if (gmtdefs.color_image == 2)
- fprintf (stderr, "%s: GMT Warning: PostScript output may only be processed with psto24!\n", gmt_program);
- color_image (x0, y0, x_side, y_side, bitimage_24, r_head.nx, r_head.ny);
- free ((char *)bitimage_24);
- }
-
- if (mapped || grid_type == 0) map_clip_off();
-
- if (frame_info.plot) {
- ps_setpaint (gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
- map_basemap ();
- ps_setpaint (0, 0, 0);
- }
- ps_plotend (gmtdefs.last_page);
-
- gmt_end (argc, argv);
- }
-