]> Pileus Git - ~andy/rsl/blob - image_gen.c
Fix lots of unused-result warnings
[~andy/rsl] / image_gen.c
1 /*
2     NASA/TRMM, Code 910.1.
3     This is the TRMM Office Radar Software Library.
4     Copyright (C) 1996, 1997
5             John H. Merritt
6             Space Applications Corporation
7             Vienna, Virginia
8
9     This library is free software; you can redistribute it and/or
10     modify it under the terms of the GNU Library General Public
11     License as published by the Free Software Foundation; either
12     version 2 of the License, or (at your option) any later version.
13
14     This library is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17     Library General Public License for more details.
18
19     You should have received a copy of the GNU Library General Public
20     License along with this library; if not, write to the Free
21     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 /*
25  *---------------------------------------------------------------------
26  * Image generation functions:
27  *
28  *   void RSL_load_color_table(char *infile, char buffer[256], int *ncolors);
29  *   void RSL_load_red_table(char *infile);
30  *   void RSL_load_green_table(char *infile);
31  *   void RSL_load_blue_table(char *infile);
32  *   void RSL_load_refl_color_table();
33  *   void RSL_load_vel_color_table();
34  *   void RSL_load_sw_color_table();
35  *   void RSL_load_height_color_table();
36  *   void RSL_load_rainfall_color_table();
37  *   void RSL_bscan_ray(FILE *fp, Ray *r);
38  *   void RSL_bscan_sweep(Sweep *s, char *outfile);
39  *   void RSL_bscan_volume(Volume *v, char *basename);
40  *   unsigned char *RSL_sweep_to_cart(Sweep *s, int xdim, int ydim, float range);
41  *   unsigned char *RSL_rhi_sweep_to_cart(Sweep *s, int xdim, int ydim, float range, int vert_scale);
42  *   void RSL_write_gif(char *outfile, unsigned char *image, int xdim, int ydim, char c_table[256][3]);
43  *   void RSL_write_pict(char *outfile, unsigned char *image, int xdim, int ydim, char c_table[256][3]);
44  *   void RSL_write_ppm(char *outfile, unsigned char *image, int xdim, int ydim, char c_table[256][3]);
45  *   void RSL_write_pgm(char *outfile, unsigned char *image, int xdim, int ydim);
46  *   void RSL_sweep_to_gif(Sweep *s, char *outfile, int xdim, int ydim, float range);
47  *   void RSL_rhi_sweep_to_gif(Sweep *s, char *outfile, int xdim, int ydim, float range, int vert_scale);
48  *   void RSL_sweep_to_pict(Sweep *s, char *outfile, int xdim, int ydim, float range);
49  *   void RSL_sweep_to_ppm(Sweep *s, char *outfile, int xdim, int ydim, float range);
50  *   void RSL_sweep_to_pgm(Sweep *s, char *outfile, int xdim, int ydim, float range);
51  *   void RSL_volume_to_gif(Volume *v, char *basename, int xdim, int ydim, float range);
52  *   void RSL_volume_to_pict(Volume *v, char *basename, int xdim, int ydim, float range);
53  *   void RSL_volume_to_ppm(Volume *v, char *basename, int xdim, int ydim, float range);
54  *   void RSL_volume_to_pgm(Volume *v, char *basename, int xdim, int ydim, float range);
55  *   void RSL_rebin_velocity_ray(Ray *r);
56  *   void RSL_rebin_velocity_sweep(Sweep *s);
57  *   void RSL_rebin_velocity_volume(Volume *v);
58  *   void RSL_rebin_zdr_ray(Ray *r);
59  *   void RSL_rebin_zdr_sweep(Sweep *s);
60  *   void RSL_rebin_zdr_volume(Volume *v);
61  */
62 #include <stdio.h>
63 #include <stdlib.h>
64 #include "rsl.h"
65 extern FILE *popen(const char *, const char *);
66 extern int pclose(FILE *stream);
67 extern int radar_verbose_flag;
68
69 static char color_table[256][3];
70 static int ncolors = 0;
71
72
73 /**********************************************************************/
74 /*                                                                    */
75 /*                  RSL_load_color_table                              */
76 /*                                                                    */
77 /*  By: John Merritt                                                  */
78 /*      Space Applications Corporation                                */
79 /*      April 7, 1994                                                 */
80 /**********************************************************************/
81 void RSL_load_color_table(char *infile, char buffer[256], int *num_colors)
82 {
83   FILE *fp;
84
85   fp = fopen(infile, "r");
86   if (fp == NULL) {
87         perror(infile);
88         exit(-1);
89   }
90   *num_colors = fread(buffer, sizeof(char), 256, fp);
91
92   (void)fclose(fp);
93 }
94
95 /**********************************************************************/
96 /*                                                                    */
97 /*                      RSL_set_color_table                           */
98 /*                                                                    */
99 /*  By: John Merritt                                                  */
100 /*      SM&A Corporation                                              */
101 /*      Jan 21, 1999                                                  */
102 /**********************************************************************/
103 void RSL_set_color_table(int icolor, char buffer[256], int ncolors)
104 {
105   int i;
106   /* In RSL: Red table=RSL_RED_TABLE,
107    *       green table=RSL_GREEN_TABLE,
108    *        blue table=RSL_BLUE_TABLE.
109    */
110   for (i=0; i<ncolors; i++) color_table[i][icolor] = buffer[i];
111 }
112
113 /**********************************************************************/
114 /*                                                                    */
115 /*                      RSL_get_color_table                           */
116 /*                                                                    */
117 /*  By: John Merritt                                                  */
118 /*      SM&A Corporation                                              */
119 /*      Jan 21, 1999                                                  */
120 /**********************************************************************/
121 void RSL_get_color_table(int icolor, char buffer[256], int *ncolors)
122 {
123   int i;
124   /* In RSL: Red table=RSL_RED_TABLE,
125    *       green table=RSL_GREEN_TABLE,
126    *        blue table=RSL_BLUE_TABLE.
127    */
128   *ncolors = 256;
129   for (i=0; i<*ncolors; i++) buffer[i] = color_table[i][icolor];
130 }
131
132 /**********************************************************************/
133 /*                                                                    */
134 /*                      RSL_load_red_table                            */
135 /*                      RSL_load_green_table                          */
136 /*                      RSL_load_blue_table                           */
137 /*                                                                    */
138 /*  By: John Merritt                                                  */
139 /*      Space Applications Corporation                                */
140 /*      April 7, 1994                                                 */
141 /**********************************************************************/
142 void RSL_load_red_table(char *infile)
143 {
144   char buffer[256];
145   /* Red only. */
146   RSL_load_color_table(infile, buffer, &ncolors);
147   RSL_set_color_table(RSL_RED_TABLE, buffer, ncolors);
148 }
149 void RSL_load_green_table(char *infile)
150 {
151   char buffer[256];
152   /* Green only. */
153   RSL_load_color_table(infile, buffer, &ncolors);
154   RSL_set_color_table(RSL_GREEN_TABLE, buffer, ncolors);
155 }
156 void RSL_load_blue_table(char *infile)
157 {
158   char buffer[256];
159   /* Blue only. */
160   RSL_load_color_table(infile, buffer, &ncolors);
161   RSL_set_color_table(RSL_BLUE_TABLE, buffer, ncolors);
162 }
163
164 #include <string.h>
165 /**********************************************************************/
166 /*                                                                    */
167 /*                      RSL_load_refl_color_table                     */
168 /*                      RSL_load_vel_color_table                      */
169 /*                      RSL_load_sw_color_table                       */
170 /*                      RSL_load_zdr_color_table                      */
171 /*                      RSL_load_rainfall_color_table                 */
172 /*                                                                    */
173 /*  By: John Merritt                                                  */
174 /*      Space Applications Corporation                                */
175 /*      April 7, 1994                                                 */
176 /**********************************************************************/
177 void RSL_load_refl_color_table()
178 {
179   char buffer[256];
180   char *fnames[3] = { REFL_RED_FILE, REFL_GREEN_FILE, REFL_BLUE_FILE };
181
182   int i, igun;
183
184   for (igun=0; igun<3; igun++) {
185         RSL_load_color_table(fnames[igun], buffer, &ncolors);
186         for (i=0; i<ncolors; i++) color_table[i][igun] = buffer[i];
187   }
188 }
189 void RSL_load_vel_color_table()
190 {
191   char buffer[256];
192   char *fnames[] = { VEL_RED_FILE, VEL_GREEN_FILE, VEL_BLUE_FILE };
193
194   int i, igun;
195
196   for (igun=0; igun<3; igun++) {
197         RSL_load_color_table(fnames[igun], buffer, &ncolors);
198         for (i=0; i<ncolors; i++) color_table[i][igun] = buffer[i];
199   }
200 }
201 void RSL_load_sw_color_table()
202 {
203   char buffer[256];
204   char *fnames[] = { SW_RED_FILE, SW_GREEN_FILE, SW_BLUE_FILE };
205
206   int i, igun;
207
208   for (igun=0; igun<3; igun++) {
209         RSL_load_color_table(fnames[igun], buffer, &ncolors);
210         for (i=0; i<ncolors; i++) color_table[i][igun] = buffer[i];
211   }
212 }
213
214 void RSL_load_height_color_table()
215 {
216   char buffer[256];
217   char *fnames[] = { HEIGHT_RED_FILE, HEIGHT_GREEN_FILE, HEIGHT_BLUE_FILE };
218
219   int i, igun;
220
221   for (igun=0; igun<3; igun++) {
222         RSL_load_color_table(fnames[igun], buffer, &ncolors);
223         for (i=0; i<ncolors; i++) color_table[i][igun] = buffer[i];
224   }
225 }
226
227 void RSL_load_zdr_color_table()
228 {
229   char buffer[256];
230   char *fnames[] = { ZDR_RED_FILE, ZDR_GREEN_FILE, ZDR_BLUE_FILE };
231
232   int i, igun;
233
234   for (igun=0; igun<3; igun++) {
235         RSL_load_color_table(fnames[igun], buffer, &ncolors);
236         for (i=0; i<ncolors; i++) color_table[i][igun] = buffer[i];
237   }
238 }
239
240 void RSL_load_rainfall_color_table()
241 {
242   char buffer[256];
243   char *fnames[] = { RAINFALL_RED_FILE, RAINFALL_GREEN_FILE, RAINFALL_BLUE_FILE };
244
245   int i, igun;
246
247   for (igun=0; igun<3; igun++) {
248         RSL_load_color_table(fnames[igun], buffer, &ncolors);
249         for (i=0; i<ncolors; i++) color_table[i][igun] = buffer[i];
250   }
251 }
252 /**********************************************************************/
253 /*                                                                    */
254 /*                        Volume to BSCAN GIF                         */
255 /*                     (simple dump of rays)                          */
256 /*               RSL_bscan_ray                                        */
257 /*               RSL_bscan_sweep                                      */
258 /*               RSL_bscan_volume                                     */
259 /*                                                                    */
260 /*  By: John Merritt                                                  */
261 /*      Space Applications Corporation                                */
262 /*      March 22, 1994                                                */
263 /**********************************************************************/
264 static unsigned char *outvect;
265
266 void RSL_bscan_ray(Ray *r, FILE *fp)
267 {
268   int i;
269   float (*f)(Range x);
270
271   if (r == NULL) return;
272   memset(outvect, 0, r->h.nbins);
273   f = r->h.f;
274   for (i=0; i<r->h.nbins; i++)
275         if (f(r->range[i]) != BADVAL) {
276           if (f(r->range[i]) >= 0) outvect[i] = (unsigned char) f(r->range[i]);
277         }
278         else
279           outvect[i] = (unsigned char) (255 + f(r->range[i]));
280   
281   for(i=0; i<r->h.nbins; i++)
282         if (fwrite(color_table[outvect[i]], sizeof(char), 3, fp) != 3)
283                 fprintf(stderr, "RSL_bscan_ray: short write\n");
284   
285 }
286 void RSL_bscan_sweep(Sweep *s, char *outfile)
287 {
288   int i, j, nrecs, nbins;
289   Ray *first_ray;
290   FILE *fp;
291   if (s == NULL) return;
292   
293   fp = fopen(outfile,"w");
294   if (fp == NULL) {
295         perror(outfile);
296         return;
297   }
298   first_ray = RSL_get_first_ray_of_sweep(s);
299   nrecs = s->h.nrays;
300   nbins = first_ray->h.nbins;
301   fprintf(fp, "P6\n# %s\n%d %d\n255\n",outfile, nbins, nrecs);
302   outvect = NULL;
303   outvect = (unsigned char *) calloc(nbins, sizeof(unsigned char));
304   if (outvect == NULL) {
305         perror((char *)outvect);
306         return;
307   }
308
309 /* Now, write the bscan. */
310   for (j=0; j<s->h.nrays; j++) {
311         if (s->ray[j]) RSL_bscan_ray(s->ray[j], fp);
312         else {
313           memset(outvect, 0, nbins);
314           for(i=0; i<nbins; i++)
315                 if (fwrite(color_table[outvect[i]], sizeof(char), 3, fp) != 3)
316                         fprintf(stderr, "RSL_bscan_sweep: short write\n");
317         }
318   }
319   
320   free(outvect);
321   fclose(fp);
322 }
323 void RSL_bscan_volume(Volume *v, char *basename)
324 {
325   int i;
326   char *outfile;
327   
328   RSL_load_refl_color_table();
329   outfile = (char *)calloc(strlen(basename)+7, sizeof(char));
330   for (i=0; i<v->h.nsweeps; i++) { 
331         (void)sprintf(outfile,"bscan.%2.2d.ppm", i);
332
333         RSL_bscan_sweep(v->sweep[i], outfile);
334         if (radar_verbose_flag)
335           fprintf(stderr,"Output: %s\n", outfile);
336   }
337   free (outfile);
338 }
339
340
341 /**********************************************************************/
342 /**********************************************************************/
343 /*                                                                    */
344 /*                    Volume to cartesean GIF                         */
345 /*                     (polar to cartesean)                           */
346 /*                                                                    */
347 /*  By: John Merritt                                                  */
348 /*      Space Applications Corporation                                */
349 /*      April 7, 1994                                                 */
350 /**********************************************************************/
351 /**********************************************************************/
352 #include <math.h>
353
354
355 /**********************************************************************/
356 /*                                                                    */
357 /*                    RSL_sweep_to_cart                               */
358 /*                                                                    */
359 /*  By: John Merritt                                                  */
360 /*      Space Applications Corporation                                */
361 /*      April 7, 1994                                                 */
362 /**********************************************************************/
363 unsigned char *RSL_sweep_to_cart(Sweep *s, int xdim, int ydim, float range)
364 {
365  /* Range specifies the maximum range to load that points into the image. */
366
367   int x, y;
368   float azim, r;
369   float val;
370   int the_index;
371   Ray *ray;
372   float beam_width;
373   
374
375   static unsigned char *cart_image = NULL;
376
377   if (s == NULL) return NULL;
378   if (xdim != ydim || ydim < 0 || xdim < 0) {
379         fprintf(stderr, "(xdim=%d) != (ydim=%d) or either negative.\n", xdim, ydim);
380         return NULL;
381   }
382   cart_image = (unsigned char *) calloc(xdim*ydim, sizeof(unsigned char));
383
384   beam_width = s->h.beam_width/2.0 * 1.2;
385   if (beam_width == 0) beam_width = 1.2;  /* Sane image generation. */
386
387   for (y=-ydim/2; y<ydim/2; y++)
388         for (x=-xdim/2; x<xdim/2; x++){/* Find azimuth and range, then search Volume. */
389           if (x !=0 ) 
390                 azim = (float)atan((double)y/(double)x)*180.0/3.14159;
391           else
392                 if (y < 0) azim = -90.0;
393                 else azim = 90.0;
394           if (y<0 && x<0) /* Quadrant 3 (math notation). */
395                 azim -= 180;
396           else if (y>=0 && x<0) /* Quad: 2 */
397                 azim += 180;
398           
399           /* Radar is clockwise increasing. */
400           azim = -azim;
401           
402           azim -= 90.0;
403           if (azim < 0) azim += 360.0;
404
405           r = (float)sqrt((double)x*x + (double)y*y);
406           if (ydim < xdim) r *= range/(.5*ydim);
407           else r *= range/(.5*xdim);
408           if (r > range) val = BADVAL;
409           else {
410                 ray = RSL_get_closest_ray_from_sweep(s, azim, beam_width);
411                 val = RSL_get_value_from_ray(ray, r);
412           }
413           the_index =  (y+ydim/2)*ydim + (xdim-1)-(x+xdim/2);
414           if (val == BADVAL || val == NOTFOUND_V || val == NOTFOUND_H)
415                 cart_image[the_index] = (unsigned char) 0;
416           else if (val >= 0)
417             cart_image[the_index] = (unsigned char) val;
418           else 
419                 cart_image[the_index] = (unsigned char) (256+val);
420
421         }
422   return cart_image;
423 }
424
425 /**********************************************************************/
426 /*                                                                    */
427 /*                    RSL_rhi_sweep_to_cart                           */
428 /*                                                                    */
429 /*  A modified version of RSL_sweep_to_cart()                         */
430 /*  -> Handles rhi (vertical) sweeps                                  */
431 /*      Kolander                                                      */
432 /*      Space Applications Corporation                                */
433 /*      July 27, 1995                                                 */
434 /**********************************************************************/
435 unsigned char *RSL_rhi_sweep_to_cart(Sweep *s, int xdim, int ydim, 
436                                                                          float range, int vert_scale)
437 {
438   int x, y, xx, yy, i, j;
439   float angle, r;
440   float val;
441   int the_index;
442
443   static unsigned char *rhi_cart_image = NULL;
444   static unsigned char *buffer = NULL;
445
446   if (s == NULL) return NULL;
447   if (buffer == NULL)
448      buffer = (unsigned char *)calloc(xdim*ydim, sizeof(unsigned char));
449   if (rhi_cart_image == NULL)
450      rhi_cart_image = (unsigned char *)calloc(xdim*ydim, sizeof(unsigned char));
451   memset(buffer, (unsigned char)0, xdim*ydim);
452   memset(rhi_cart_image, (unsigned char)0, xdim*ydim);
453   
454   for (y=0; y<xdim; y++)
455         for (x=0; x<ydim; x++){
456           if (x != 0) 
457                 angle = (float)atan((double)y/(double)x)*180.0/3.14159;
458           else
459                 angle = 90.0;
460
461           angle = 90.0 - angle;
462           r = (float)sqrt((double)x*x + (double)y*y);
463           if (r > range) 
464              val = BADVAL;
465           else 
466              val = RSL_get_value_from_sweep(s, angle, r);
467
468           /* A vertical sweep extends from 0 deg to perhaps 25 deg in
469                  elevation. For proper orientation of a displayed rhi 
470                  vertical sweep:
471                  1. reflect image about the line y=x .
472                  2. translate image downward so that radar site is located
473                     at the bottom left corner of the image. The sweep will
474                         then extend upward from the bottom of the image.
475           */
476           xx = y;    /* reflection about line y=x */
477           yy = x;    /* reflection about line y=x */
478           the_index =  (ydim - 1 - yy)*xdim + xx;
479           if (val == BADVAL || val == NOTFOUND_V || val == NOTFOUND_H)
480                 buffer[the_index] = (unsigned char) 0;
481           else if (val >= 0)
482                 buffer[the_index] = (unsigned char) val;
483           else 
484                 buffer[the_index] = (unsigned char) (256+val);
485         }
486
487   /* To see details in the sweep, it is customary to scale the image
488          so that the scale of the vertical axis is 5 or 10 times the scale
489          of the horizontal axis. 
490          Copy each row of pixel values from buffer[] a constant multiple 
491          number of times into rhi_cart_image[], in order to vertically
492          expand the image.
493   */
494   for (j=0; j<ydim/vert_scale; j++)
495          for (i=1; i<=vert_scale; i++)
496                 memcpy(&rhi_cart_image[(ydim - i - vert_scale*j)*xdim], 
497                            &buffer[(ydim - 1 - j)*xdim], xdim);
498   
499   return rhi_cart_image;
500 }
501
502 #include <signal.h>
503 /**********************************************************************/
504 /*                                                                    */
505 /*                    RSL_write_gif                                   */
506 /*                                                                    */
507 /*  By: John Merritt                                                  */
508 /*      Space Applications Corporation                                */
509 /*      April 7, 1994                                                 */
510 /**********************************************************************/
511 void RSL_write_gif(char *outfile, unsigned char *image, int xdim, int ydim, char c_table[256][3])
512 {
513   int i;
514   int nbytes;
515   char pipecmd[300];
516   FILE *fpipe;
517
518   if (image == NULL) {
519         fprintf(stderr, "No image for file %s\n", outfile);
520     return;
521   }
522   fpipe = NULL;
523   nbytes = xdim*ydim;
524   (void)sprintf(pipecmd, "ppmtogif > %s 2>/dev/null", outfile);
525   fpipe = popen(pipecmd, "w");  /* Global FILE * */
526   if (fpipe == NULL) {
527         perror("RSL_write_gif1");
528         return;
529   }
530   if (fprintf(fpipe, "P6\n# %s\n%d %d\n255\n",outfile, xdim, ydim) < 0) {
531         perror("RSL_write_gif2");
532         pclose(fpipe);
533         return;
534   }
535   
536   for (i=0; i<nbytes; i++)
537         if (fwrite(c_table[image[i]], sizeof(char), 3, fpipe) != 3) {
538           perror("RSL_write_gif3");
539           pclose(fpipe);
540           return;
541         }
542
543   if(pclose(fpipe) != 0) perror("RSL_write_gif4");
544 }
545 /**********************************************************************/
546 /*                                                                    */
547 /*                    RSL_write_pict                                  */
548 /*                                                                    */
549 /*  By: John Merritt                                                  */
550 /*      Space Applications Corporation                                */
551 /*      April 7, 1994                                                 */
552 /**********************************************************************/
553 void RSL_write_pict(char *outfile, unsigned char *image, int xdim, int ydim, char c_table[256][3])
554 {
555   int i;
556   int nbytes;
557   char pipecmd[100];
558   FILE *fpipe;
559
560   if (image == NULL) {
561         fprintf(stderr, "No image for file %s\n", outfile);
562     return;
563   }
564   nbytes = xdim*ydim;
565   (void)sprintf(pipecmd, "ppmtopict > %s 2>/dev/null", outfile);
566   fpipe = popen(pipecmd, "w");  /* Global FILE * */
567   fprintf(fpipe, "P6\n# %s\n%d %d\n255\n",outfile, xdim, ydim);
568   for (i=0; i<nbytes; i++)
569           if (fwrite(c_table[image[i]], sizeof(char), 3, fpipe) != 3)
570                 fprintf(stderr, "RSL_write_pict: short write\n");
571   (void)pclose(fpipe);
572 }
573 /**********************************************************************/
574 /*                                                                    */
575 /*                    RSL_write_ppm                                   */
576 /*                                                                    */
577 /*  By: John Merritt                                                  */
578 /*      Space Applications Corporation                                */
579 /*      April 7, 1994                                                 */
580 /**********************************************************************/
581 void RSL_write_ppm(char *outfile, unsigned char *image, int xdim, int ydim, char c_table[256][3])
582 {
583   int i;
584   int nbytes;
585   FILE *fpipe;
586
587   if (image == NULL) {
588         fprintf(stderr, "No image for file %s\n", outfile);
589     return;
590   }
591   nbytes = xdim*ydim;
592   fpipe = fopen(outfile, "w");  /* Global FILE * */
593   fprintf(fpipe, "P6\n# %s\n%d %d\n255\n",outfile, xdim, ydim);
594   for (i=0; i<nbytes; i++)
595           if (fwrite(c_table[image[i]], sizeof(char), 3, fpipe) != 3)
596                 fprintf(stderr, "RSL_write_ppm: short write\n");
597   (void)fclose(fpipe);
598 }
599 /**********************************************************************/
600 /*                                                                    */
601 /*                    RSL_write_pgm                                   */
602 /*                                                                    */
603 /*  By: John Merritt                                                  */
604 /*      Space Applications Corporation                                */
605 /*      April 7, 1994                                                 */
606 /**********************************************************************/
607 void RSL_write_pgm(char *outfile, unsigned char *image, int xdim, int ydim)
608 {
609   int nbytes;
610   char pipecmd[100];
611   FILE *fpipe;
612
613   if (image == NULL) {
614         fprintf(stderr, "No image for file %s\n", outfile);
615     return;
616   }
617   nbytes = xdim*ydim;
618   (void)sprintf(pipecmd, "gzip > %s.gz 2>/dev/null", outfile);
619   fpipe = popen(pipecmd, "w");  /* Global FILE * */
620   fprintf(fpipe, "P5\n# %s\n%d %d\n255\n",outfile, xdim, ydim);
621   if (fwrite(image, sizeof(char), nbytes, fpipe) != nbytes)
622         fprintf(stderr, "RSL_write_pgm: short write\n");
623   (void)pclose(fpipe);
624
625 /*  The following is commented and is for non compressed. */
626 #ifdef COMPILE
627   nbytes = xdim*ydim;
628   fpipe = fopen(outfile, "w");  /* Global FILE * */
629   fprintf(fpipe, "P5\n# %s\n%d %d\n255\n",outfile, xdim, ydim);
630   (void)fwrite(image, sizeof(char), nbytes, fpipe);
631   (void)fclose(fpipe);
632 #endif
633 }
634
635 /**********************************************************************/
636 /*                                                                    */
637 /*                    RSL_sweep_to_gif                                */
638 /*                                                                    */
639 /*  By: John Merritt                                                  */
640 /*      Space Applications Corporation                                */
641 /*      April 7, 1994                                                 */
642 /**********************************************************************/
643 void RSL_sweep_to_gif(Sweep *s, char *outfile, int xdim, int ydim, float range)
644 {
645   /* Currently range is not used. */
646   unsigned char *cart_image;
647
648   /* Assumes the color table is already loaded. */
649   if (s == NULL) return;
650   if (ncolors == 0) {
651         fprintf(stderr, "No colors in color table.  Load color table first.\n");
652         return;
653   }
654   cart_image = RSL_sweep_to_cart(s, xdim, ydim, range);
655   RSL_write_gif(outfile, cart_image, xdim, ydim, color_table);
656   free(cart_image);
657 }
658
659 /**********************************************************************/
660 /*                                                                    */
661 /*                    RSL_rhi_sweep_to_gif                            */
662 /*                                                                    */
663 /* Slightly modified version of RSL_sweep_to_gif()                    */
664 /*                                                                    */
665 /*  By: Kolander                                                      */
666 /*      Space Applications Corporation                                */
667 /*      July 27, 1995                                                 */
668 /**********************************************************************/
669 void RSL_rhi_sweep_to_gif(Sweep *s, char *outfile, int xdim, int ydim, 
670                                                   float range, int vert_scale)
671 {
672   unsigned char *cart_image;
673
674   /* Assumes the color table is already loaded. */
675   if (s == NULL) return;
676   if (ncolors == 0) {
677         fprintf(stderr, "No colors in color table.  Load color table first.\n");
678         return;
679   }
680   cart_image = RSL_rhi_sweep_to_cart(s, xdim, ydim, range, vert_scale);
681   RSL_write_gif(outfile, cart_image, xdim, ydim, color_table);
682   free(cart_image);
683 }
684
685 /**********************************************************************/
686 /*                                                                    */
687 /*                    RSL_sweep_to_pict                               */
688 /*                                                                    */
689 /*  By: John Merritt                                                  */
690 /*      Space Applications Corporation                                */
691 /*      April 7, 1994                                                 */
692 /**********************************************************************/
693 void RSL_sweep_to_pict(Sweep *s, char *outfile, int xdim, int ydim, float range)
694 {
695   /* Currently range is not used. */
696   unsigned char *cart_image;
697
698   /* Assumes the color table is already loaded. */
699   if (s == NULL) return;
700   if (ncolors == 0) {
701         fprintf(stderr, "No colors in color table.  Load color table first.\n");
702         return;
703   }
704   cart_image = RSL_sweep_to_cart(s, xdim, ydim, range);
705   RSL_write_pict(outfile, cart_image, xdim, ydim, color_table);
706   free(cart_image);
707 }
708 /**********************************************************************/
709 /*                                                                    */
710 /*                    RSL_sweep_to_ppm                                */
711 /*                                                                    */
712 /*  By: John Merritt                                                  */
713 /*      Space Applications Corporation                                */
714 /*      April 7, 1994                                                 */
715 /**********************************************************************/
716 void RSL_sweep_to_ppm(Sweep *s, char *outfile, int xdim, int ydim, float range)
717 {
718   /* Currently range is not used. */
719   unsigned char *cart_image;
720
721   /* Assumes the color table is already loaded. */
722   if (s == NULL) return;
723   if (ncolors == 0) {
724         fprintf(stderr, "No colors in color table.  Load color table first.\n");
725         return;
726   }
727   cart_image = RSL_sweep_to_cart(s, xdim, ydim, range);
728   RSL_write_ppm(outfile, cart_image, xdim, ydim, color_table);
729   free(cart_image);
730 }
731 /**********************************************************************/
732 /*                                                                    */
733 /*                    RSL_sweep_to_pgm                                */
734 /*                                                                    */
735 /*  By: John Merritt                                                  */
736 /*      Space Applications Corporation                                */
737 /*      April 7, 1994                                                 */
738 /**********************************************************************/
739 void RSL_sweep_to_pgm(Sweep *s, char *outfile, int xdim, int ydim, float range)
740 {
741   /* Currently range is not used. */
742   unsigned char *cart_image;
743
744   if (s == NULL) return;
745   cart_image = RSL_sweep_to_cart(s, xdim, ydim, range);
746   RSL_write_pgm(outfile, cart_image, xdim, ydim);
747   free(cart_image);
748 }
749
750 /**********************************************************************/
751 /*                                                                    */
752 /*                    RSL_volume_to_gif                               */
753 /*                                                                    */
754 /*  By: John Merritt                                                  */
755 /*      Space Applications Corporation                                */
756 /*      April 7, 1994                                                 */
757 /**********************************************************************/
758 void RSL_volume_to_gif(Volume *v, char *basename, int xdim, int ydim, float range)
759 {
760 /*
761  * Make a xdim by ydim cartesean image.  Center of radar is xdim/2,ydim/2.
762  */
763   int i;
764   char outfile[100];
765   unsigned char *cart_image;
766
767   if (v == NULL) return;
768   if (ncolors == 0) {
769         fprintf(stderr, "No colors in color table.  Load color table first.\n");
770         return;
771   }
772 /*
773  * Sweep 0 has Reflectivity only.
774  * Sweep 1 has Velocity and Spectrum width, No Reflectivity.
775  * Sweep > 1 any.
776  *
777  */
778   for (i=0; i<v->h.nsweeps; i++) {
779         (void)sprintf(outfile,"%s.%2.2d.gif", basename, i); /* File name: sweep.[0-10] */
780         if (v->sweep[i] == NULL) continue;
781         cart_image = RSL_sweep_to_cart(v->sweep[i], xdim, ydim, range);
782         if (radar_verbose_flag)
783           fprintf(stderr,"==> Sweep %d of %d\n",i, v->h.nsweeps);
784         if (cart_image != NULL) {
785           RSL_write_gif(outfile, cart_image, xdim, ydim, color_table);
786           printf("%s\n", outfile);
787           free (cart_image);
788         } else {
789           if (radar_verbose_flag)
790                 fprintf(stderr,"No image.  cart_image for sweep %d is NULL.\n", i);
791         }
792   }
793 }
794
795 /**********************************************************************/
796 /*                                                                    */
797 /*                    RSL_volume_to_pict                              */
798 /*                                                                    */
799 /*  By: John Merritt                                                  */
800 /*      Space Applications Corporation                                */
801 /*      April 7, 1994                                                 */
802 /**********************************************************************/
803 void RSL_volume_to_pict(Volume *v, char *basename, int xdim, int ydim, float range)
804 {
805 /*
806  * Make a xdim by ydim cartesean image.  Center of radar is xdim/2,ydim/2.
807  */
808   int i;
809   char outfile[100];
810   unsigned char *cart_image;
811
812   if (v == NULL) return;
813   if (ncolors == 0) {
814         fprintf(stderr, "No colors in color table.  Load color table first.\n");
815         return;
816   }
817 /*
818  * Sweep 0 has Reflectivity only.
819  * Sweep 1 has Velocity and Spectrum width, No Reflectivity.
820  * Sweep > 1 any.
821  *
822  */
823   for (i=0; i<v->h.nsweeps; i++) {
824         cart_image = RSL_sweep_to_cart(v->sweep[i], xdim, ydim, range);
825         if (radar_verbose_flag)
826           fprintf(stderr,"==> Sweep %d of %d\n",i, v->h.nsweeps);
827         (void)sprintf(outfile,"%s.%2.2d.pict", basename, i); /* File name: sweep.[0-10] */
828         if (cart_image != NULL) {
829           RSL_write_pict(outfile, cart_image, xdim, ydim, color_table);
830           if (radar_verbose_flag)
831                 fprintf(stderr,"Wrote: %s\n", outfile);
832           free (cart_image);
833         } else {
834           if (radar_verbose_flag)
835                 fprintf(stderr,"No image.  cart_image for sweep %d is NULL.\n", i);
836         }
837   }
838 }
839
840 /**********************************************************************/
841 /*                                                                    */
842 /*                    RSL_volume_to_ppm                               */
843 /*                                                                    */
844 /*  By: John Merritt                                                  */
845 /*      Space Applications Corporation                                */
846 /*      April 7, 1994                                                 */
847 /**********************************************************************/
848 void RSL_volume_to_ppm(Volume *v, char *basename, int xdim, int ydim, float range)
849 {
850 /*
851  * Make a xdim by ydim cartesean image.  Center of radar is xdim/2,ydim/2.
852  */
853   int i;
854   char outfile[100];
855   unsigned char *cart_image;
856
857   if (v == NULL) return;
858   if (ncolors == 0) {
859         fprintf(stderr, "No colors in color table.  Load color table first.\n");
860         return;
861   }
862 /*
863  * Sweep 0 has Reflectivity only.
864  * Sweep 1 has Velocity and Spectrum width, No Reflectivity.
865  * Sweep > 1 any.
866  *
867  */
868   for (i=0; i<v->h.nsweeps; i++) {
869         cart_image = RSL_sweep_to_cart(v->sweep[i], xdim, ydim, range);
870         if (radar_verbose_flag)
871           fprintf(stderr,"==> Sweep %d of %d\n",i, v->h.nsweeps);
872         (void)sprintf(outfile,"%s.%2.2d.ppm", basename, i); /* File name: sweep.[0-10] */
873         if (cart_image != NULL) {
874           RSL_write_ppm(outfile, cart_image, xdim, ydim, color_table);
875           if (radar_verbose_flag)
876                 fprintf(stderr,"Wrote: %s\n", outfile);
877           free (cart_image);
878         } else {
879           if (radar_verbose_flag)
880                 fprintf(stderr,"No image.  cart_image for sweep %d is NULL.\n", i);
881         }
882   }
883 }
884 /**********************************************************************/
885 /*                                                                    */
886 /*                    RSL_volume_to_pgm                               */
887 /*                                                                    */
888 /*  By: John Merritt                                                  */
889 /*      Space Applications Corporation                                */
890 /*      April 7, 1994                                                 */
891 /**********************************************************************/
892 void RSL_volume_to_pgm(Volume *v, char *basename, int xdim, int ydim, float range)
893 {
894 /*
895  * Make a xdim by ydim cartesean image.  Center of radar is xdim/2,ydim/2.
896  */
897   int i;
898   char outfile[100];
899   unsigned char *cart_image;
900
901 /*
902  * Sweep 0 has Reflectivity only.
903  * Sweep 1 has Velocity and Spectrum width, No Reflectivity.
904  * Sweep > 1 any.
905  *
906  */
907   if (v == NULL) return;
908   for (i=0; i<v->h.nsweeps; i++) {
909         cart_image = RSL_sweep_to_cart(v->sweep[i], xdim, ydim, range);
910         if (radar_verbose_flag)
911           fprintf(stderr,"==> Sweep %d of %d\n",i, v->h.nsweeps);
912         (void)sprintf(outfile,"%s.%2.2d.pgm", basename, i); /* File name: sweep.[0-10] */
913         if (cart_image != NULL) {
914           RSL_write_pgm(outfile, cart_image, xdim, ydim);
915           if (radar_verbose_flag)
916                 fprintf(stderr,"Wrote: %s\n", outfile);
917           free (cart_image);
918         } else {
919           if (radar_verbose_flag)
920                 fprintf(stderr,"No image.  cart_image for sweep %d is NULL.\n", i);
921         }
922   }
923 }
924
925
926 /***********************************************************************/
927 /*                                                                     */
928 /*                  RSL_rebin_velocity_ray                             */
929 /*                  RSL_rebin_velocity_sweep                           */
930 /*                  RSL_rebin_velocity_volume                          */
931 /*                                                                     */
932 /*  By: John Merritt                                                   */
933 /*      Space Applications Corporation                                 */
934 /*      April 30, 1994                                                 */
935 /*                                                                     */
936 /***********************************************************************/
937 void RSL_rebin_velocity_ray(Ray *r)
938 {
939   /* Rebin the velocity data to the range -nyquist, +nyquist.
940    * 14 bins are created centered at 0.  It sets the proper color look up
941    * indexes.  This function modifies Ray r.
942    */
943   int i;
944   float nyquist;
945   float val /*  val1 */;
946
947   int ncbins = 15; /* Number of color bins */
948   float (*f)(Range x);
949   Range (*invf)(float x);
950
951   if (r == NULL) return;
952
953   nyquist = r->h.nyq_vel;
954   if (nyquist == 0.0) {
955         fprintf(stderr, "RSL_rebin_velocity_ray: nyquist == 0.0\n");
956         fprintf(stderr, "RSL_rebin_velocity_ray: Unable to rebin.\n");
957         return;
958   }
959   f = r->h.f;
960   invf = r->h.invf;
961   for (i=0; i<r->h.nbins; i++) {
962         val = f(r->range[i]);
963         if (val == RFVAL) {
964                 val = 16;
965         } else if (val != BADVAL) {
966 /*
967           Okay, we want to shift the data to positive values
968           then we re-scale them by the number of color bins/nyquist
969 */
970           val = (int)(val/nyquist*(ncbins/2) + 1.0 + ncbins/2);
971
972         } else {
973                 val = 0;
974         }
975
976         r->range[i] = invf(val);
977   }
978 }
979
980
981 void RSL_rebin_velocity_sweep(Sweep *s)
982 {
983   /* Rebin the velocity data to the range -nyquist, +nyquist.
984    * 14 bins are created centered at 0. It sets the proper color look up
985    * indexes.  This function modifies Sweep s.  Use this function prior
986    * RSL_sweep_to_cart.  The binning is done in RSL_rebin_velocity_ray.
987    */
988
989   int i;
990   
991   if (s == NULL) return;
992
993   for (i=0; i<s->h.nrays; i++)
994         RSL_rebin_velocity_ray(s->ray[i]);
995
996 }
997
998 void RSL_rebin_velocity_volume(Volume *v)
999 {
1000   /* Rebin the velocity data to the range -nyquist, +nyquist.
1001    * 14 bins are created centered at 0. It sets the proper color look up
1002    * indexes.  This function modifies Volume v.  Use this function prior
1003    * RSL_sweep_to_cart.  The binning is done in RSL_rebin_velocity_ray.
1004    */
1005
1006   int i;
1007   
1008   if (v == NULL) return;
1009
1010   for (i=0; i<v->h.nsweeps; i++)
1011         RSL_rebin_velocity_sweep(v->sweep[i]);
1012
1013 }
1014
1015
1016 /**********************************************************************/
1017 /*                                                                    */
1018 /*                    RSL_carpi_to_cart                               */
1019 /*                                                                    */
1020 /*      Space Applications Corporation                                */
1021 /*      17 Mar 1997                                                   */
1022 /**********************************************************************/
1023 unsigned char *RSL_carpi_to_cart(Carpi *carpi, int xdim, int ydim, float range)
1024 {
1025         /* Converts carpi data from the native RSL 1_ or 2_byte format to 
1026                  unsigned char format for image generation. Also reverses the
1027                  row order of the data so that displayed images come out right side up.
1028   */
1029         int i, j, cart_index;
1030   unsigned char *cart_image = NULL;
1031         float val;
1032         
1033   if (carpi == NULL) return NULL;
1034   cart_image = (unsigned char *) calloc(xdim*ydim, sizeof(unsigned char));
1035         
1036         for (j=0; j<ydim; j++)
1037           for (i=0; i<xdim; i++)
1038                 {
1039                         cart_index = (ydim-1-j)*xdim + i;  /* Reverse the row order. */
1040                         val = carpi->f(carpi->data[j][i]);
1041                         if (val == BADVAL || val == NOTFOUND_V || val == NOTFOUND_H) 
1042                           cart_image[cart_index] = (unsigned char) 0;
1043                         else if (val >= 0) 
1044                           cart_image[cart_index] = (unsigned char) val;
1045                         else 
1046                           cart_image[cart_index] = (unsigned char) (256+val); /*2's complement.*/
1047                 }
1048         return(cart_image);
1049 }
1050
1051 /**********************************************************************/
1052 /*                                                                    */
1053 /*                    RSL_carpi_to_gif                                */
1054 /*                                                                    */
1055 /*      Space Applications Corporation                                */
1056 /*      17 Mar 1997                                                   */
1057 /**********************************************************************/
1058 void RSL_carpi_to_gif(Carpi *carpi, char *outfile, int xdim, int ydim, float range)
1059 {
1060   /* Currently range is not used. */
1061   unsigned char *cart_image;
1062
1063   /* Assumes the color table is already loaded. */
1064   if (carpi == NULL) return;
1065   if (ncolors == 0) {
1066                 fprintf(stderr, "No colors in color table.  Load color table first.\n");
1067                 return;
1068   }
1069   cart_image = RSL_carpi_to_cart(carpi, xdim, ydim, range);
1070   RSL_write_gif(outfile, cart_image, xdim, ydim, color_table);
1071   free(cart_image);
1072 }
1073
1074 /**********************************************************************/
1075 /*                                                                    */
1076 /*                    RSL_carpi_to_pict                               */
1077 /*                                                                    */
1078 /*      Space Applications Corporation                                */
1079 /*      17 Mar 1997                                                   */
1080 /**********************************************************************/
1081 void RSL_carpi_to_pict(Carpi *carpi, char *outfile, int xdim, int ydim, float range)
1082 {
1083   /* Currently range is not used. */
1084   unsigned char *cart_image;
1085
1086   /* Assumes the color table is already loaded. */
1087   if (carpi == NULL) return;
1088   if (ncolors == 0) {
1089                 fprintf(stderr, "No colors in color table.  Load color table first.\n");
1090                 return;
1091   }
1092   cart_image = RSL_carpi_to_cart(carpi, xdim, ydim, range);
1093   RSL_write_pict(outfile, cart_image, xdim, ydim, color_table);
1094   free(cart_image);
1095 }
1096
1097 /**********************************************************************/
1098 /*                                                                    */
1099 /*                    RSL_carpi_to_ppm                                */
1100 /*                                                                    */
1101 /*      Space Applications Corporation                                */
1102 /*      17 Mar 1997                                                   */
1103 /**********************************************************************/
1104 void RSL_carpi_to_ppm(Carpi *carpi, char *outfile, int xdim, int ydim, float range)
1105 {
1106   /* Currently range is not used. */
1107   unsigned char *cart_image;
1108
1109   /* Assumes the color table is already loaded. */
1110   if (carpi == NULL) return;
1111   if (ncolors == 0) {
1112                 fprintf(stderr, "No colors in color table.  Load color table first.\n");
1113                 return;
1114   }
1115   cart_image = RSL_carpi_to_cart(carpi, xdim, ydim, range);
1116   RSL_write_ppm(outfile, cart_image, xdim, ydim, color_table);
1117   free(cart_image);
1118 }
1119
1120 /**********************************************************************/
1121 /*                                                                    */
1122 /*                    RSL_carpi_to_pgm                                */
1123 /*                                                                    */
1124 /*      Space Applications Corporation                                */
1125 /*      17 Mar 1997                                                   */
1126 /**********************************************************************/
1127 void RSL_carpi_to_pgm(Carpi *carpi, char *outfile, int xdim, int ydim, float range)
1128 {
1129   /* Currently range is not used. */
1130   unsigned char *cart_image;
1131
1132   /* Assumes the color table is already loaded. */
1133   if (carpi == NULL) return;
1134   if (ncolors == 0) {
1135                 fprintf(stderr, "No colors in color table.  Load color table first.\n");
1136                 return;
1137   }
1138   cart_image = RSL_carpi_to_cart(carpi, xdim, ydim, range);
1139   RSL_write_pgm(outfile, cart_image, xdim, ydim);
1140   free(cart_image);
1141 }
1142
1143 /**********************************************************************/
1144 /*                    RSL_rebin_volume                                */
1145 /* More generic version of RSL_rebin_velocity. Allows for centering   */
1146 /* +/- field like zdr or vel around zero. Width is the 1/2 width of   */
1147 /* what is to be centered; e.g., +/- 5, width=5.                      */
1148 /* Space Applications Corporation                                     */
1149 /* July 13, 1997                                                      */
1150 /**********************************************************************/
1151 void RSL_rebin_ray(Ray *r, int width)
1152 {
1153   int i;
1154   float nyquist, val; 
1155   int ncbins = 15; /* Number of color bins */
1156   float (*f)(Range x);
1157   Range (*invf)(float x);
1158
1159   if (r == NULL) return;
1160
1161   nyquist = width;
1162   if (nyquist == 0.0) {
1163         fprintf(stderr, "RSL_rebin_ray: nyquist == 0.0\n");
1164         fprintf(stderr, "RSL_rebin_ray: Unable to rebin.\n");
1165         return;
1166   }
1167   f = r->h.f;
1168   invf = r->h.invf;
1169   for (i=0; i<r->h.nbins; i++) {
1170         val = f(r->range[i]);
1171         if (val == width+1) {
1172                 val = ncbins + 1;
1173         } else if (val != BADVAL) {
1174 /*
1175           Okay, we want to shift the data to positive values
1176           then we re-scale them by the number of color bins/nyquist
1177 */
1178           val = (int)(val/nyquist*(ncbins/2) + 1.0 + ncbins/2); 
1179         } else {
1180                 val = 0;
1181         }
1182
1183         r->range[i] = invf(val);
1184   }
1185 }
1186
1187 void RSL_rebin_sweep(Sweep *s, int width)
1188 {
1189   int i;  
1190   if (s == NULL) return;
1191   for (i=0; i<s->h.nrays; i++)
1192         RSL_rebin_ray(s->ray[i], width);
1193 }
1194
1195 void RSL_rebin_volume(Volume *v, int width)
1196 {
1197   int i;
1198   if (v == NULL) return;
1199   for (i=0; i<v->h.nsweeps; i++)
1200         RSL_rebin_sweep(v->sweep[i], width);
1201 }
1202
1203 /**********************************************************************/
1204 /*                                                                    */
1205 /*                 RSL_rebin_zdr_volume, _sweep, _ray                 */
1206 /*                                                                    */
1207 /*      Space Applications Corporation                                */
1208 /**********************************************************************/
1209 /*
1210          Maps valid zdr values from the real set [-6.0, 10.0] onto the set of
1211          integers {0, 1, 2, ..., 35}, which forms the set of indices into
1212          the zdr color table. Used in conjunction with gif image generation
1213          of zdr sweeps.
1214
1215               Color coding:
1216                                 -------------
1217          -6.0 <= zdr < -4.0  --> black
1218          -4.0 <= zdr < -2.0  --> gray
1219          -2.0 <= zdr <  0.0  --> blue
1220     0.0 <= zdr <  2.0  --> green
1221                 2.0 <= zdr <  4.0  --> orange
1222                 4.0 <= zdr <  6.0  --> red
1223                 6.0 <= zdr <  8.0  --> pink
1224                 8.0 <= zdr < 10.0  --> white
1225
1226                 Space Applications Corporation
1227                 July 13, 1997
1228 */
1229
1230 void RSL_rebin_zdr_ray(Ray *r)
1231 {
1232   int i;
1233   float val; 
1234   float (*f)(Range x);
1235   Range (*invf)(float x);
1236
1237   if (r == NULL) return;
1238   f = r->h.f;
1239   invf = r->h.invf;
1240   for (i=0; i<r->h.nbins; i++)
1241         {
1242                 val = f(r->range[i]);
1243                 if ((val >= -6.0) && (val < 8.4)) val = (floor) ((val + 6.0) * 2.5);
1244                 else if (val < 10.0) val = 35.0;  /* Make all these white. */
1245                 else val = 0;  /* invalid zdr value */
1246                 r->range[i] = invf(val);
1247   }
1248 }
1249
1250 void RSL_rebin_zdr_sweep(Sweep *s)
1251 {
1252   int i;  
1253   if (s == NULL) return;
1254   for (i=0; i<s->h.nrays; i++) RSL_rebin_zdr_ray(s->ray[i]);
1255 }
1256
1257 void RSL_rebin_zdr_volume(Volume *v)
1258 {
1259   int i;
1260   if (v == NULL) return;
1261   for (i=0; i<v->h.nsweeps; i++) RSL_rebin_zdr_sweep(v->sweep[i]);
1262 }