home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Science / Science.zip / gmt_os2.zip / src / psscale.c < prev    next >
C/C++ Source or Header  |  1995-07-27  |  13KB  |  388 lines

  1. /*--------------------------------------------------------------------
  2.  *    The GMT-system:    @(#)psscale.c    2.27  27 Jul 1995
  3.  *
  4.  *    Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
  5.  *    See README file for copying and redistribution conditions.
  6.  *--------------------------------------------------------------------*/
  7. /*
  8.  * psscale draws a grayscale or colorscale either vertically or
  9.  * horizontally.  psscale will interpolate colors if the lower
  10.  * and upper rgb values for an interval are different.  The
  11.  * resolution for this interpolation can be set on the command line.
  12.  * If the scale is to be used with illumninated 2-D and 3-D plots
  13.  * then options for intensities are available.
  14.  *
  15.  * Author:    Paul Wessel
  16.  * Created:    10-MAY-1991
  17.  * Modified:    1-FEB-1995
  18.  *
  19.  */
  20.  
  21. #include "gmt.h"
  22.  
  23. int bit_dpi = 50;
  24.  
  25. main(argc, argv)
  26. int argc;
  27. char *argv[]; {
  28.     int i;
  29.     
  30.     BOOLEAN horizontal = FALSE, equi = FALSE, intens = FALSE, error = FALSE;
  31.     
  32.     double xpos, ypos, length, width, max_intens = 1.0;
  33.     double *z_width;
  34.     
  35.     char flag, *cpt_file = NULL, *z_file = NULL, line[512];
  36.     
  37.     FILE *fp = NULL;
  38.     
  39.     argc = gmt_begin (argc, argv);
  40.  
  41.     length = width = xpos = ypos = 0.0;
  42.     
  43.     /* Check and interpret the command line arguments */
  44.     
  45.     for (i = 1; i < argc; i++) {
  46.         if (argv[i][0] == '-') {
  47.             switch(argv[i][1]) {
  48.         
  49.                 /* Common parameters */
  50.  
  51.                 case 'B':
  52.                 case 'K':
  53.                 case 'O':
  54.                 case 'P':
  55.                 case 'U':
  56.                 case 'V':
  57.                 case 'X':
  58.                 case 'x':
  59.                 case 'Y':
  60.                 case 'y':
  61.                 case 'c':
  62.                 case '\0':
  63.                     error += get_common_args (argv[i], 0, 0, 0, 0);
  64.                     break;
  65.                 
  66.                 /* Supplemental parameters */
  67.             
  68.                 case 'C':
  69.                     cpt_file = &argv[i][2];
  70.                     break;
  71.                 case 'D':
  72.                     sscanf (&argv[i][2], "%lf/%lf/%lf/%lf", &xpos, &ypos, &length, &width);
  73.                     flag = argv[i][strlen(argv[i])-1];
  74.                     horizontal = (flag == 'h' || flag == 'H');
  75.                     break;
  76.                 case 'F':
  77.                     if (gmt_getrgb (&argv[i][2], &gmtdefs.basemap_frame_rgb[0], &gmtdefs.basemap_frame_rgb[1], &gmtdefs.basemap_frame_rgb[2])) {
  78.                         gmt_pen_syntax ('F');
  79.                         error++;
  80.                     }
  81.                     break;
  82.                 case 'I':
  83.                     intens = TRUE;
  84.                     if (argv[i][2]) max_intens = atof (&argv[i][2]);
  85.                     break;
  86.                 case 'N':
  87.                     if (argv[i][2]) bit_dpi = atoi (&argv[i][2]);
  88.                     break;
  89.                 case 'L':
  90.                     equi = TRUE;
  91.                     break;
  92.                 case 'Z':
  93.                     z_file = &argv[i][2];
  94.                     break;
  95.                     
  96.                 case '0':
  97.                     gmtdefs.color_image = 0;
  98.                     break;
  99.                 case '1':
  100.                     gmtdefs.color_image = 1;
  101.                     break;
  102.                 case '2':
  103.                     gmtdefs.color_image = 2;
  104.                     break;
  105.  
  106.                 /* Options not recognized */
  107.                         
  108.                 default:
  109.                     error = TRUE;
  110.                     gmt_default_error (argv[i][1]);
  111.                     break;
  112.             }
  113.         }
  114.     }
  115.     
  116.     if (argc == 1 || gmt_quick) {
  117.         fprintf (stderr,"psscale %s - To create grayscale or colorscale for maps\n\n", GMT_VERSION);
  118.         fprintf(stderr,"usage: psscale -C<cpt_file>  -D<xpos/ypos/length/width[h]> [-B<tickinfo>] [-F<r>/<g>/<b>] [-I[<intens>]\n");
  119.         fprintf(stderr,"    [-K] [-L] [-N<dpi>] [-O] [-P] [-U] [-V] [-X<x_shift>] [-Y<y_shift>] [-Zzfile] [-0 -1 -2] [-c<ncopies>]\n\n");
  120.         if (gmt_quick) exit(-1);
  121.         
  122.         fprintf (stderr,"    -B Set header label as :.\"label\":\n");
  123.         fprintf (stderr,"    -C Color palette file\n");
  124.         fprintf (stderr,"       By default all color changes are anotated.  To use a subset,\n");
  125.         fprintf (stderr,"       add an extra column to the cpt-file with a L, U, or B\n");
  126.         fprintf (stderr,"       to anotate Lower, Upper, or Both color segment boundaries\n");
  127.         fprintf (stderr,"    -D set mid-point position and length/width for scale.\n");
  128.         fprintf (stderr,"       Append h for horizontal scale\n");
  129.         fprintf (stderr, "    -F Set color used for Frame and anotation [%d/%d/%d]\n",
  130.             gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
  131.         fprintf (stderr,"    -I add illumination for +- <max_intens> [1.0]\n");
  132.         explain_option ('K');
  133.         fprintf (stderr,"    -L For equal-sized color rectangles\n");
  134.         fprintf (stderr,"    -N effective dots-per-inch for color scale [50]\n");
  135.         explain_option ('O');
  136.         explain_option ('P');
  137.         explain_option ('U');
  138.         explain_option ('V');
  139.         explain_option ('X');
  140.         fprintf (stderr,"    -Z give colorbar-width (in %s) per color entry\n", gmt_unit_names[gmtdefs.measure_unit]);
  141.         fprintf (stderr,"       By default, width of entry is scaled to color range\n");
  142.         fprintf (stderr,"       i.e., z = 0-100 gives twice the width as z = 100-150.\n");
  143.         fprintf (stderr,"    -0 plot color scale using colorimage.\n");
  144.         fprintf (stderr,"    -1 plot color scale using tiles.\n");
  145.         fprintf (stderr,"    -2 plot color scale using psto24.\n");
  146.         fprintf (stderr,"       [Default = %d]\n", gmtdefs.color_image);
  147.         explain_option ('c');
  148.         explain_option ('.');
  149.         exit(-1);
  150.     }
  151.  
  152.     /* Check that the options selected are mutually consistant */
  153.     
  154.     if (!cpt_file) {
  155.         fprintf (stderr, "%s: GMT SYNTAX ERROR -C option:  Must specify color palette table\n", gmt_program);
  156.         error++;
  157.     }
  158.     if (z_project.view_azimuth > 360.0 || z_project.view_elevation <= 0.0 || z_project.view_elevation > 90.0) {
  159.         fprintf (stderr, "%s: GMT SYNTAX ERROR -E option:  Enter azimuth in 0-360 range, elevation in 0-90 range\n", gmt_program);
  160.         error++;
  161.     }
  162.     if (length <= 0.0 ) {
  163.         fprintf (stderr, "%s: GMT SYNTAX ERROR -D option: scale length must be nonzero\n", gmt_program);
  164.         error++;
  165.     }
  166.     if (width <= 0.0) {
  167.         fprintf (stderr, "%s: GMT SYNTAX ERROR -D option: scale width must be nonzero\n", gmt_program);
  168.         error++;
  169.     }
  170.     if (bit_dpi < 1) {
  171.         fprintf (stderr, "%s: GMT SYNTAX ERROR -N option: dpi must be nonzero\n", gmt_program);
  172.         error++;
  173.     }
  174.           
  175.     if (error) exit (-1);
  176.  
  177.     read_cpt (cpt_file);
  178.     z_width = (double *) memory (CNULL, gmt_n_colors, sizeof (double), "psscale");
  179.     
  180.     if (z_file && (fp = fopen (z_file, "r")) == NULL) {
  181.         fprintf (stderr, "psscale: Unable to open file %s\n", z_file);
  182.         exit (-1);
  183.     }
  184.     else if (z_file) {
  185.         for (i = 0; i < gmt_n_colors; i++) {
  186.             fgets (line, 512, fp);
  187.             if (line[0] == '#') continue;
  188.             sscanf (line, "%lf", &z_width[i]);
  189.         }
  190.         fclose (fp);
  191.     }
  192.     else if (equi) {
  193.         for (i = 0; i < gmt_n_colors; i++) z_width[i] = length / gmt_n_colors;
  194.     }
  195.     else {
  196.         for (i = 0; i < gmt_n_colors; i++) z_width[i] = length * (gmt_lut[i].z_high - gmt_lut[i].z_low) / (gmt_lut[gmt_n_colors-1].z_high - gmt_lut[0].z_low);
  197.     }
  198.         
  199.     if (!project_info.x_off_supplied && gmtdefs.overlay) gmtdefs.x_origin = 0.0;    /* Since map_setup is not called here */
  200.     if (!project_info.y_off_supplied && gmtdefs.overlay) gmtdefs.y_origin = 0.0;
  201.  
  202.     ps_plotinit (CNULL, gmtdefs.overlay, gmtdefs.page_orientation, gmtdefs.x_origin, gmtdefs.y_origin,
  203.         gmtdefs.global_x_scale, gmtdefs.global_y_scale, gmtdefs.n_copies,
  204.         gmtdefs.dpi, gmtdefs.measure_unit, gmtdefs.paper_width, gmtdefs.page_rgb, gmt_epsinfo (argv[0]));
  205.         
  206.     echo_command (argc, argv);
  207.     if (gmtdefs.unix_time) timestamp (argc, argv);
  208.     
  209.     ps_setpaint (gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
  210.     
  211.     draw_colorbar (xpos, ypos, length, width, z_width, horizontal, intens, max_intens);
  212.  
  213.     ps_plotend (gmtdefs.last_page);
  214.     
  215.     gmt_end (argc, argv);
  216. }
  217.  
  218. int draw_colorbar (xpos, ypos, length, width, z_width, horizontal, intens, max_intens)
  219. double xpos, ypos;
  220. double length, width, z_width[], max_intens;
  221. BOOLEAN horizontal, intens; {
  222.     int i, j, ndec = -1, dec, r, g, b, rr, gg, bb;
  223.     int nx, ny, nm, nm2, barmem, k, all = TRUE;
  224.     char format[50], text[50], test[50];
  225.     unsigned char *bar;
  226.     double off, anot_off, label_off, len, len2, size, x0, x1;
  227.     double z, xleft, inc_i, inc_j, get_z();
  228.     
  229.     ps_setfont (gmtdefs.anot_font);
  230.  
  231.     /* Find max decimals needed */
  232.     
  233.     for (i = 0; i < gmt_n_colors; i++) {
  234.         dec = get_format (gmt_lut[i].z_low, text);
  235.         if (dec > ndec) {
  236.             strcpy (format, text);
  237.             ndec = dec;
  238.         }
  239.         if (gmt_lut[i].anot) all = FALSE;
  240.     }
  241.     dec = get_format (gmt_lut[gmt_n_colors-1].z_high, text);
  242.     if (dec > ndec) {
  243.         strcpy (format, text);
  244.         ndec = dec;
  245.     }
  246.     
  247.     len = (gmtdefs.tick_length > 0.0) ? gmtdefs.tick_length : 0.0;
  248.     len2 = 0.5 * len;
  249.     xleft = x0 = -0.5 * length;
  250.     
  251.     /* Make bitimage for colorbar using bit_dpi */
  252.     
  253.     nx = length * bit_dpi;
  254.     ny = width * bit_dpi;
  255.     nm = nx * ny;
  256.     nm2 = 2 * nm;
  257.     inc_i = 1.0 / bit_dpi;
  258.     inc_j = (intens) ? 2.0 * max_intens / (ny - 1) : 0.0;
  259.     barmem = (gmt_gray) ? nm : 3 * nm;
  260.     bar = (unsigned char *) memory (CNULL, barmem, sizeof (char), "psscale");
  261.     
  262.     /* Load bar image */
  263.     
  264.     for (i = 0; i < nx; i++) {
  265.         z = get_z (i * inc_i, z_width, gmt_n_colors);
  266.         get_rgb24 (z, &rr, &gg, &bb);
  267.         for (j = 0; j < ny; j++) {
  268.             r = rr;    g = gg;    b = bb;
  269.             k = j * nx + i;
  270.             if (intens) illuminate (max_intens - j * inc_j, &r, &g, &b);
  271.             if (gmt_gray)    /* Convert to gray using the YIQ transformation */
  272.                 bar[k] = (unsigned char) rint (0.299 * r + 0.587 * g + 0.114 * b);
  273.             else if (gmtdefs.color_image == 2) {    /* RGB separation */
  274.                 bar[k] = r;
  275.                 bar[k+nm] = g;
  276.                 bar[k+nm2] = b;
  277.             }
  278.             else {
  279.                 k *= 3;
  280.                 bar[k++] = r;
  281.                 bar[k++] = g;
  282.                 bar[k++] = b;
  283.             }
  284.         }
  285.     }
  286.     
  287.     ps_setline (gmtdefs.frame_pen);
  288.     if (horizontal) {
  289.         ps_transrotate (xpos, ypos, 0.0);
  290.         if (gmt_gray)
  291.             ps_image (x0, -width, length, width, bar, nx, ny, 8);
  292.         else 
  293.             color_image (x0, -width, length, width, bar, nx, ny);
  294.             
  295.         anot_off = -(width + len + gmtdefs.anot_offset);
  296.         label_off = -(width + len + 2.5 * gmtdefs.anot_offset + (gmtdefs.anot_font_size / gmt_ppu[gmtdefs.measure_unit]) * font_height[gmtdefs.anot_font]);
  297.         
  298.         ps_plot (xleft, 0.0, 3);    ps_plotr (length, 0.0, 2);
  299.         ps_plot (xleft, -width, 3);    ps_plotr (length, 0.0, 2);
  300.         x1 = xleft;
  301.         for (i = 0; i < gmt_n_colors; i++) {
  302.             ps_plot (x1, 0.0, 3);
  303.             if (all || (gmt_lut[i].anot & 1)) {
  304.                 ps_plotr (0.0, -width - len, 2);
  305.                 sprintf (text, format, gmt_lut[i].z_low);
  306.                 ps_text (x1, anot_off, gmtdefs.anot_font_size, text, 0.0, 10, 0);
  307.             }
  308.             else
  309.                 ps_plotr (0.0, -width - len2, 2);
  310.             x1 += z_width[i];
  311.         }
  312.         ps_plot (-xleft, 0.0, 3);
  313.         if (all || (gmt_lut[gmt_n_colors-1].anot & 2)) {
  314.             ps_plotr (0.0, -width - len, 2);
  315.             sprintf (text, format, gmt_lut[gmt_n_colors-1].z_high);
  316.             ps_text (-xleft, anot_off, gmtdefs.anot_font_size, text, 0.0, 10, 0);
  317.         }
  318.         else
  319.             ps_plotr (0.0, -width - len2, 2);
  320.  
  321.         ps_setfont (gmtdefs.header_font);
  322.  
  323.         if (frame_info.label[3][0]) ps_text (0.0, label_off, gmtdefs.header_font_size, frame_info.label[3], 0.0, 10, 0);
  324.         if (frame_info.label[0][0]) ps_text (xleft+length+gmtdefs.anot_offset, -0.5*width, gmtdefs.label_font_size, frame_info.label[0], 0.0, 5, 0);
  325.         ps_rotatetrans (-xpos, -ypos, 0.0);
  326.     }
  327.     else {    /* Vertical scale */
  328.         ps_transrotate (xpos, ypos, 90.0);
  329.         if (gmt_gray)
  330.             ps_image (x0, -width, length, width, bar, nx, ny, 8);
  331.         else 
  332.             color_image (x0, -width, length, width, bar, nx, ny);
  333.         sprintf (text, "%d\0", (int)fabs (floor (gmt_lut[0].z_low)));
  334.         sprintf (test, "%d\0", (int)fabs (ceil (gmt_lut[gmt_n_colors-1].z_high)));
  335.         off = ((MAX (strlen (text), strlen (test)) + ndec) * 0.55 + ((ndec > 0) ? 0.3 : 0.0) + ((gmt_lut[0].z_low < 0.0) ? 0.3 : 0.0))
  336.             * gmtdefs.anot_font_size / gmt_ppu[gmtdefs.measure_unit];
  337.         anot_off = -(width + len + gmtdefs.anot_offset + off);
  338.         label_off = anot_off - 0.7 * gmtdefs.anot_font_size / gmt_ppu[gmtdefs.measure_unit] - 1.5 * gmtdefs.anot_offset;
  339.         ps_plot (xleft, 0.0, 3);    ps_plotr (length, 0.0, 2);
  340.         ps_plot (xleft, -width, 3);    ps_plotr (length, 0.0, 2);
  341.         x1 = xleft;
  342.         for (i = 0; i < gmt_n_colors; i++) {
  343.             ps_plot (x1, 0.0, 3);
  344.             if (all || (gmt_lut[i].anot & 1)) {
  345.                 ps_plotr (0.0, -width - len, 2);
  346.                 sprintf (text, format, gmt_lut[i].z_low);
  347.                 ps_text (x1, anot_off, gmtdefs.anot_font_size, text, -90.0, 7, 0);
  348.             }
  349.             else
  350.                 ps_plotr (0.0, -width - len2, 2);
  351.             x1 += z_width[i];
  352.         }
  353.         ps_plot (-xleft, 0.0, 3);
  354.         if (all || (gmt_lut[gmt_n_colors-1].anot & 2)) {
  355.             ps_plotr (0.0, -width - len, 2);
  356.             sprintf (text, format, gmt_lut[gmt_n_colors-1].z_high);
  357.             ps_text (-xleft, anot_off, gmtdefs.anot_font_size, text, -90.0, 7, 0);
  358.         }
  359.         else
  360.             ps_plotr (0.0, -width - len2, 2);
  361.             
  362.         ps_setfont (gmtdefs.header_font);
  363.         size = 0.9 * gmtdefs.header_font_size / gmt_ppu[gmtdefs.measure_unit];
  364.         x0 = 0.5 * (strlen (frame_info.label[3]) -1) * size ;
  365.         text[1] = 0;
  366.         for (i = 0; i < strlen (frame_info.label[3]); i++) {
  367.             x1 = x0 - i * size;
  368.             text[0] = frame_info.label[3][i];
  369.             ps_text (x1, label_off, gmtdefs.header_font_size, text, -90.0, 6, 0);
  370.         }
  371.         if (frame_info.label[0][0]) ps_text (-xleft + 2.0 * len, -0.5 * width, gmtdefs.label_font_size, frame_info.label[0], -90.0, 2, 0);
  372.         ps_rotatetrans (-xpos, -ypos, -90.0);
  373.  
  374.     }
  375. }
  376.  
  377. double get_z (x, width, n)
  378. double x, width[];
  379. int n; {
  380.     int i = 0;
  381.     double tmp;
  382.     
  383.     tmp = width[0];
  384.     while (i < n && x > tmp) tmp += width[++i];
  385.     if (i == n) return (gmt_lut[gmt_n_colors-1].z_high);
  386.     return (gmt_lut[i].z_low + (x - tmp + width[i]) * (gmt_lut[i].z_high - gmt_lut[i].z_low) / width[i]);
  387. }
  388.