]> Pileus Git - ~andy/rsl/blob - image_gen.c
RSL v1.42
[~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         (void)fwrite(color_table[outvect[i]], sizeof(char), 3, fp);
283   
284 }
285 void RSL_bscan_sweep(Sweep *s, char *outfile)
286 {
287   int i, j, nrecs, nbins;
288   Ray *first_ray;
289   FILE *fp;
290   if (s == NULL) return;
291   
292   fp = fopen(outfile,"w");
293   if (fp == NULL) {
294         perror(outfile);
295         return;
296   }
297   first_ray = RSL_get_first_ray_of_sweep(s);
298   nrecs = s->h.nrays;
299   nbins = first_ray->h.nbins;
300   fprintf(fp, "P6\n# %s\n%d %d\n255\n",outfile, nbins, nrecs);
301   outvect = NULL;
302   outvect = (unsigned char *) calloc(nbins, sizeof(unsigned char));
303   if (outvect == NULL) {
304         perror((char *)outvect);
305         return;
306   }
307
308 /* Now, write the bscan. */
309   for (j=0; j<s->h.nrays; j++) {
310         if (s->ray[j]) RSL_bscan_ray(s->ray[j], fp);
311         else {
312           memset(outvect, 0, nbins);
313           for(i=0; i<nbins; i++)
314                 (void)fwrite(color_table[outvect[i]], sizeof(char), 3, fp);
315         }
316   }
317   
318   free(outvect);
319   fclose(fp);
320 }
321 void RSL_bscan_volume(Volume *v, char *basename)
322 {
323   int i;
324   char *outfile;
325   
326   RSL_load_refl_color_table();
327   outfile = (char *)calloc(strlen(basename)+7, sizeof(char));
328   for (i=0; i<v->h.nsweeps; i++) { 
329         (void)sprintf(outfile,"bscan.%2.2d.ppm", i);
330
331         RSL_bscan_sweep(v->sweep[i], outfile);
332         if (radar_verbose_flag)
333           fprintf(stderr,"Output: %s\n", outfile);
334   }
335   free (outfile);
336 }
337
338
339 /**********************************************************************/
340 /**********************************************************************/
341 /*                                                                    */
342 /*                    Volume to cartesean GIF                         */
343 /*                     (polar to cartesean)                           */
344 /*                                                                    */
345 /*  By: John Merritt                                                  */
346 /*      Space Applications Corporation                                */
347 /*      April 7, 1994                                                 */
348 /**********************************************************************/
349 /**********************************************************************/
350 #include <math.h>
351
352
353 /**********************************************************************/
354 /*                                                                    */
355 /*                    RSL_sweep_to_cart                               */
356 /*                                                                    */
357 /*  By: John Merritt                                                  */
358 /*      Space Applications Corporation                                */
359 /*      April 7, 1994                                                 */
360 /**********************************************************************/
361 unsigned char *RSL_sweep_to_cart(Sweep *s, int xdim, int ydim, float range)
362 {
363  /* Range specifies the maximum range to load that points into the image. */
364
365   int x, y;
366   float azim, r;
367   float val;
368   int the_index;
369   Ray *ray;
370   float beam_width;
371   
372
373   static unsigned char *cart_image = NULL;
374
375   if (s == NULL) return NULL;
376   if (xdim != ydim || ydim < 0 || xdim < 0) {
377         fprintf(stderr, "(xdim=%d) != (ydim=%d) or either negative.\n", xdim, ydim);
378         return NULL;
379   }
380   cart_image = (unsigned char *) calloc(xdim*ydim, sizeof(unsigned char));
381
382   beam_width = s->h.beam_width/2.0 * 1.2;
383   if (beam_width == 0) beam_width = 1.2;  /* Sane image generation. */
384
385   for (y=-ydim/2; y<ydim/2; y++)
386         for (x=-xdim/2; x<xdim/2; x++){/* Find azimuth and range, then search Volume. */
387           if (x !=0 ) 
388                 azim = (float)atan((double)y/(double)x)*180.0/3.14159;
389           else
390                 if (y < 0) azim = -90.0;
391                 else azim = 90.0;
392           if (y<0 && x<0) /* Quadrant 3 (math notation). */
393                 azim -= 180;
394           else if (y>=0 && x<0) /* Quad: 2 */
395                 azim += 180;
396           
397           /* Radar is clockwise increasing. */
398           azim = -azim;
399           
400           azim -= 90.0;
401           if (azim < 0) azim += 360.0;
402
403           r = (float)sqrt((double)x*x + (double)y*y);
404           if (ydim < xdim) r *= range/(.5*ydim);
405           else r *= range/(.5*xdim);
406           if (r > range) val = BADVAL;
407           else {
408                 ray = RSL_get_closest_ray_from_sweep(s, azim, beam_width);
409                 val = RSL_get_value_from_ray(ray, r);
410           }
411           the_index =  (y+ydim/2)*ydim + (xdim-1)-(x+xdim/2);
412           if (val == BADVAL || val == NOTFOUND_V || val == NOTFOUND_H)
413                 cart_image[the_index] = (unsigned char) 0;
414           else if (val >= 0)
415             cart_image[the_index] = (unsigned char) val;
416           else 
417                 cart_image[the_index] = (unsigned char) (256+val);
418
419         }
420   return cart_image;
421 }
422
423 /**********************************************************************/
424 /*                                                                    */
425 /*                    RSL_rhi_sweep_to_cart                           */
426 /*                                                                    */
427 /*  A modified version of RSL_sweep_to_cart()                         */
428 /*  -> Handles rhi (vertical) sweeps                                  */
429 /*      Kolander                                                      */
430 /*      Space Applications Corporation                                */
431 /*      July 27, 1995                                                 */
432 /**********************************************************************/
433 unsigned char *RSL_rhi_sweep_to_cart(Sweep *s, int xdim, int ydim, 
434                                                                          float range, int vert_scale)
435 {
436   int x, y, xx, yy, i, j;
437   float angle, r;
438   float val;
439   int the_index;
440
441   static unsigned char *rhi_cart_image = NULL;
442   static unsigned char *buffer = NULL;
443
444   if (s == NULL) return NULL;
445   if (buffer == NULL)
446      buffer = (unsigned char *)calloc(xdim*ydim, sizeof(unsigned char));
447   if (rhi_cart_image == NULL)
448      rhi_cart_image = (unsigned char *)calloc(xdim*ydim, sizeof(unsigned char));
449   memset(buffer, (unsigned char)0, xdim*ydim);
450   memset(rhi_cart_image, (unsigned char)0, xdim*ydim);
451   
452   for (y=0; y<xdim; y++)
453         for (x=0; x<ydim; x++){
454           if (x != 0) 
455                 angle = (float)atan((double)y/(double)x)*180.0/3.14159;
456           else
457                 angle = 90.0;
458
459           angle = 90.0 - angle;
460           r = (float)sqrt((double)x*x + (double)y*y);
461           if (r > range) 
462              val = BADVAL;
463           else 
464              val = RSL_get_value_from_sweep(s, angle, r);
465
466           /* A vertical sweep extends from 0 deg to perhaps 25 deg in
467                  elevation. For proper orientation of a displayed rhi 
468                  vertical sweep:
469                  1. reflect image about the line y=x .
470                  2. translate image downward so that radar site is located
471                     at the bottom left corner of the image. The sweep will
472                         then extend upward from the bottom of the image.
473           */
474           xx = y;    /* reflection about line y=x */
475           yy = x;    /* reflection about line y=x */
476           the_index =  (ydim - 1 - yy)*xdim + xx;
477           if (val == BADVAL || val == NOTFOUND_V || val == NOTFOUND_H)
478                 buffer[the_index] = (unsigned char) 0;
479           else if (val >= 0)
480                 buffer[the_index] = (unsigned char) val;
481           else 
482                 buffer[the_index] = (unsigned char) (256+val);
483         }
484
485   /* To see details in the sweep, it is customary to scale the image
486          so that the scale of the vertical axis is 5 or 10 times the scale
487          of the horizontal axis. 
488          Copy each row of pixel values from buffer[] a constant multiple 
489          number of times into rhi_cart_image[], in order to vertically
490          expand the image.
491   */
492   for (j=0; j<ydim/vert_scale; j++)
493          for (i=1; i<=vert_scale; i++)
494                 memcpy(&rhi_cart_image[(ydim - i - vert_scale*j)*xdim], 
495                            &buffer[(ydim - 1 - j)*xdim], xdim);
496   
497   return rhi_cart_image;
498 }
499
500 #include <signal.h>
501 /**********************************************************************/
502 /*                                                                    */
503 /*                    RSL_write_gif                                   */
504 /*                                                                    */
505 /*  By: John Merritt                                                  */
506 /*      Space Applications Corporation                                */
507 /*      April 7, 1994                                                 */
508 /**********************************************************************/
509 void RSL_write_gif(char *outfile, unsigned char *image, int xdim, int ydim, char c_table[256][3])
510 {
511   int i;
512   int nbytes;
513   char pipecmd[300];
514   FILE *fpipe;
515
516   if (image == NULL) {
517         fprintf(stderr, "No image for file %s\n", outfile);
518     return;
519   }
520   fpipe = NULL;
521   nbytes = xdim*ydim;
522   (void)sprintf(pipecmd, "ppmtogif > %s 2>/dev/null", outfile);
523   fpipe = popen(pipecmd, "w");  /* Global FILE * */
524   if (fpipe == NULL) {
525         perror("RSL_write_gif1");
526         return;
527   }
528   if (fprintf(fpipe, "P6\n# %s\n%d %d\n255\n",outfile, xdim, ydim) < 0) {
529         perror("RSL_write_gif2");
530         pclose(fpipe);
531         return;
532   }
533   
534   for (i=0; i<nbytes; i++)
535         if (fwrite(c_table[image[i]], sizeof(char), 3, fpipe) != 3) {
536           perror("RSL_write_gif3");
537           pclose(fpipe);
538           return;
539         }
540
541   if(pclose(fpipe) != 0) perror("RSL_write_gif4");
542 }
543 /**********************************************************************/
544 /*                                                                    */
545 /*                    RSL_write_pict                                  */
546 /*                                                                    */
547 /*  By: John Merritt                                                  */
548 /*      Space Applications Corporation                                */
549 /*      April 7, 1994                                                 */
550 /**********************************************************************/
551 void RSL_write_pict(char *outfile, unsigned char *image, int xdim, int ydim, char c_table[256][3])
552 {
553   int i;
554   int nbytes;
555   char pipecmd[100];
556   FILE *fpipe;
557
558   if (image == NULL) {
559         fprintf(stderr, "No image for file %s\n", outfile);
560     return;
561   }
562   nbytes = xdim*ydim;
563   (void)sprintf(pipecmd, "ppmtopict > %s 2>/dev/null", outfile);
564   fpipe = popen(pipecmd, "w");  /* Global FILE * */
565   fprintf(fpipe, "P6\n# %s\n%d %d\n255\n",outfile, xdim, ydim);
566   for (i=0; i<nbytes; i++) (void)fwrite(c_table[image[i]], sizeof(char), 3, fpipe);
567   (void)pclose(fpipe);
568 }
569 /**********************************************************************/
570 /*                                                                    */
571 /*                    RSL_write_ppm                                   */
572 /*                                                                    */
573 /*  By: John Merritt                                                  */
574 /*      Space Applications Corporation                                */
575 /*      April 7, 1994                                                 */
576 /**********************************************************************/
577 void RSL_write_ppm(char *outfile, unsigned char *image, int xdim, int ydim, char c_table[256][3])
578 {
579   int i;
580   int nbytes;
581   FILE *fpipe;
582
583   if (image == NULL) {
584         fprintf(stderr, "No image for file %s\n", outfile);
585     return;
586   }
587   nbytes = xdim*ydim;
588   fpipe = fopen(outfile, "w");  /* Global FILE * */
589   fprintf(fpipe, "P6\n# %s\n%d %d\n255\n",outfile, xdim, ydim);
590   for (i=0; i<nbytes; i++) (void)fwrite(c_table[image[i]], sizeof(char), 3, fpipe);
591   (void)fclose(fpipe);
592 }
593 /**********************************************************************/
594 /*                                                                    */
595 /*                    RSL_write_pgm                                   */
596 /*                                                                    */
597 /*  By: John Merritt                                                  */
598 /*      Space Applications Corporation                                */
599 /*      April 7, 1994                                                 */
600 /**********************************************************************/
601 void RSL_write_pgm(char *outfile, unsigned char *image, int xdim, int ydim)
602 {
603   int nbytes;
604   char pipecmd[100];
605   FILE *fpipe;
606
607   if (image == NULL) {
608         fprintf(stderr, "No image for file %s\n", outfile);
609     return;
610   }
611   nbytes = xdim*ydim;
612   (void)sprintf(pipecmd, "gzip > %s.gz 2>/dev/null", outfile);
613   fpipe = popen(pipecmd, "w");  /* Global FILE * */
614   fprintf(fpipe, "P5\n# %s\n%d %d\n255\n",outfile, xdim, ydim);
615   (void)fwrite(image, sizeof(char), nbytes, fpipe);
616   (void)pclose(fpipe);
617
618 /*  The following is commented and is for non compressed. */
619 #ifdef COMPILE
620   nbytes = xdim*ydim;
621   fpipe = fopen(outfile, "w");  /* Global FILE * */
622   fprintf(fpipe, "P5\n# %s\n%d %d\n255\n",outfile, xdim, ydim);
623   (void)fwrite(image, sizeof(char), nbytes, fpipe);
624   (void)fclose(fpipe);
625 #endif
626 }
627
628 /**********************************************************************/
629 /*                                                                    */
630 /*                    RSL_sweep_to_gif                                */
631 /*                                                                    */
632 /*  By: John Merritt                                                  */
633 /*      Space Applications Corporation                                */
634 /*      April 7, 1994                                                 */
635 /**********************************************************************/
636 void RSL_sweep_to_gif(Sweep *s, char *outfile, int xdim, int ydim, float range)
637 {
638   /* Currently range is not used. */
639   unsigned char *cart_image;
640
641   /* Assumes the color table is already loaded. */
642   if (s == NULL) return;
643   if (ncolors == 0) {
644         fprintf(stderr, "No colors in color table.  Load color table first.\n");
645         return;
646   }
647   cart_image = RSL_sweep_to_cart(s, xdim, ydim, range);
648   RSL_write_gif(outfile, cart_image, xdim, ydim, color_table);
649   free(cart_image);
650 }
651
652 /**********************************************************************/
653 /*                                                                    */
654 /*                    RSL_rhi_sweep_to_gif                            */
655 /*                                                                    */
656 /* Slightly modified version of RSL_sweep_to_gif()                    */
657 /*                                                                    */
658 /*  By: Kolander                                                      */
659 /*      Space Applications Corporation                                */
660 /*      July 27, 1995                                                 */
661 /**********************************************************************/
662 void RSL_rhi_sweep_to_gif(Sweep *s, char *outfile, int xdim, int ydim, 
663                                                   float range, int vert_scale)
664 {
665   unsigned char *cart_image;
666
667   /* Assumes the color table is already loaded. */
668   if (s == NULL) return;
669   if (ncolors == 0) {
670         fprintf(stderr, "No colors in color table.  Load color table first.\n");
671         return;
672   }
673   cart_image = RSL_rhi_sweep_to_cart(s, xdim, ydim, range, vert_scale);
674   RSL_write_gif(outfile, cart_image, xdim, ydim, color_table);
675   free(cart_image);
676 }
677
678 /**********************************************************************/
679 /*                                                                    */
680 /*                    RSL_sweep_to_pict                               */
681 /*                                                                    */
682 /*  By: John Merritt                                                  */
683 /*      Space Applications Corporation                                */
684 /*      April 7, 1994                                                 */
685 /**********************************************************************/
686 void RSL_sweep_to_pict(Sweep *s, char *outfile, int xdim, int ydim, float range)
687 {
688   /* Currently range is not used. */
689   unsigned char *cart_image;
690
691   /* Assumes the color table is already loaded. */
692   if (s == NULL) return;
693   if (ncolors == 0) {
694         fprintf(stderr, "No colors in color table.  Load color table first.\n");
695         return;
696   }
697   cart_image = RSL_sweep_to_cart(s, xdim, ydim, range);
698   RSL_write_pict(outfile, cart_image, xdim, ydim, color_table);
699   free(cart_image);
700 }
701 /**********************************************************************/
702 /*                                                                    */
703 /*                    RSL_sweep_to_ppm                                */
704 /*                                                                    */
705 /*  By: John Merritt                                                  */
706 /*      Space Applications Corporation                                */
707 /*      April 7, 1994                                                 */
708 /**********************************************************************/
709 void RSL_sweep_to_ppm(Sweep *s, char *outfile, int xdim, int ydim, float range)
710 {
711   /* Currently range is not used. */
712   unsigned char *cart_image;
713
714   /* Assumes the color table is already loaded. */
715   if (s == NULL) return;
716   if (ncolors == 0) {
717         fprintf(stderr, "No colors in color table.  Load color table first.\n");
718         return;
719   }
720   cart_image = RSL_sweep_to_cart(s, xdim, ydim, range);
721   RSL_write_ppm(outfile, cart_image, xdim, ydim, color_table);
722   free(cart_image);
723 }
724 /**********************************************************************/
725 /*                                                                    */
726 /*                    RSL_sweep_to_pgm                                */
727 /*                                                                    */
728 /*  By: John Merritt                                                  */
729 /*      Space Applications Corporation                                */
730 /*      April 7, 1994                                                 */
731 /**********************************************************************/
732 void RSL_sweep_to_pgm(Sweep *s, char *outfile, int xdim, int ydim, float range)
733 {
734   /* Currently range is not used. */
735   unsigned char *cart_image;
736
737   if (s == NULL) return;
738   cart_image = RSL_sweep_to_cart(s, xdim, ydim, range);
739   RSL_write_pgm(outfile, cart_image, xdim, ydim);
740   free(cart_image);
741 }
742
743 /**********************************************************************/
744 /*                                                                    */
745 /*                    RSL_volume_to_gif                               */
746 /*                                                                    */
747 /*  By: John Merritt                                                  */
748 /*      Space Applications Corporation                                */
749 /*      April 7, 1994                                                 */
750 /**********************************************************************/
751 void RSL_volume_to_gif(Volume *v, char *basename, int xdim, int ydim, float range)
752 {
753 /*
754  * Make a xdim by ydim cartesean image.  Center of radar is xdim/2,ydim/2.
755  */
756   int i;
757   char outfile[100];
758   unsigned char *cart_image;
759
760   if (v == NULL) return;
761   if (ncolors == 0) {
762         fprintf(stderr, "No colors in color table.  Load color table first.\n");
763         return;
764   }
765 /*
766  * Sweep 0 has Reflectivity only.
767  * Sweep 1 has Velocity and Spectrum width, No Reflectivity.
768  * Sweep > 1 any.
769  *
770  */
771   for (i=0; i<v->h.nsweeps; i++) {
772         (void)sprintf(outfile,"%s.%2.2d.gif", basename, i); /* File name: sweep.[0-10] */
773         if (v->sweep[i] == NULL) continue;
774         cart_image = RSL_sweep_to_cart(v->sweep[i], xdim, ydim, range);
775         if (radar_verbose_flag)
776           fprintf(stderr,"==> Sweep %d of %d\n",i, v->h.nsweeps);
777         if (cart_image != NULL) {
778           RSL_write_gif(outfile, cart_image, xdim, ydim, color_table);
779           printf("%s\n", outfile);
780           free (cart_image);
781         } else {
782           if (radar_verbose_flag)
783                 fprintf(stderr,"No image.  cart_image for sweep %d is NULL.\n", i);
784         }
785   }
786 }
787
788 /**********************************************************************/
789 /*                                                                    */
790 /*                    RSL_volume_to_pict                              */
791 /*                                                                    */
792 /*  By: John Merritt                                                  */
793 /*      Space Applications Corporation                                */
794 /*      April 7, 1994                                                 */
795 /**********************************************************************/
796 void RSL_volume_to_pict(Volume *v, char *basename, int xdim, int ydim, float range)
797 {
798 /*
799  * Make a xdim by ydim cartesean image.  Center of radar is xdim/2,ydim/2.
800  */
801   int i;
802   char outfile[100];
803   unsigned char *cart_image;
804
805   if (v == NULL) return;
806   if (ncolors == 0) {
807         fprintf(stderr, "No colors in color table.  Load color table first.\n");
808         return;
809   }
810 /*
811  * Sweep 0 has Reflectivity only.
812  * Sweep 1 has Velocity and Spectrum width, No Reflectivity.
813  * Sweep > 1 any.
814  *
815  */
816   for (i=0; i<v->h.nsweeps; i++) {
817         cart_image = RSL_sweep_to_cart(v->sweep[i], xdim, ydim, range);
818         if (radar_verbose_flag)
819           fprintf(stderr,"==> Sweep %d of %d\n",i, v->h.nsweeps);
820         (void)sprintf(outfile,"%s.%2.2d.pict", basename, i); /* File name: sweep.[0-10] */
821         if (cart_image != NULL) {
822           RSL_write_pict(outfile, cart_image, xdim, ydim, color_table);
823           if (radar_verbose_flag)
824                 fprintf(stderr,"Wrote: %s\n", outfile);
825           free (cart_image);
826         } else {
827           if (radar_verbose_flag)
828                 fprintf(stderr,"No image.  cart_image for sweep %d is NULL.\n", i);
829         }
830   }
831 }
832
833 /**********************************************************************/
834 /*                                                                    */
835 /*                    RSL_volume_to_ppm                               */
836 /*                                                                    */
837 /*  By: John Merritt                                                  */
838 /*      Space Applications Corporation                                */
839 /*      April 7, 1994                                                 */
840 /**********************************************************************/
841 void RSL_volume_to_ppm(Volume *v, char *basename, int xdim, int ydim, float range)
842 {
843 /*
844  * Make a xdim by ydim cartesean image.  Center of radar is xdim/2,ydim/2.
845  */
846   int i;
847   char outfile[100];
848   unsigned char *cart_image;
849
850   if (v == NULL) return;
851   if (ncolors == 0) {
852         fprintf(stderr, "No colors in color table.  Load color table first.\n");
853         return;
854   }
855 /*
856  * Sweep 0 has Reflectivity only.
857  * Sweep 1 has Velocity and Spectrum width, No Reflectivity.
858  * Sweep > 1 any.
859  *
860  */
861   for (i=0; i<v->h.nsweeps; i++) {
862         cart_image = RSL_sweep_to_cart(v->sweep[i], xdim, ydim, range);
863         if (radar_verbose_flag)
864           fprintf(stderr,"==> Sweep %d of %d\n",i, v->h.nsweeps);
865         (void)sprintf(outfile,"%s.%2.2d.ppm", basename, i); /* File name: sweep.[0-10] */
866         if (cart_image != NULL) {
867           RSL_write_ppm(outfile, cart_image, xdim, ydim, color_table);
868           if (radar_verbose_flag)
869                 fprintf(stderr,"Wrote: %s\n", outfile);
870           free (cart_image);
871         } else {
872           if (radar_verbose_flag)
873                 fprintf(stderr,"No image.  cart_image for sweep %d is NULL.\n", i);
874         }
875   }
876 }
877 /**********************************************************************/
878 /*                                                                    */
879 /*                    RSL_volume_to_pgm                               */
880 /*                                                                    */
881 /*  By: John Merritt                                                  */
882 /*      Space Applications Corporation                                */
883 /*      April 7, 1994                                                 */
884 /**********************************************************************/
885 void RSL_volume_to_pgm(Volume *v, char *basename, int xdim, int ydim, float range)
886 {
887 /*
888  * Make a xdim by ydim cartesean image.  Center of radar is xdim/2,ydim/2.
889  */
890   int i;
891   char outfile[100];
892   unsigned char *cart_image;
893
894 /*
895  * Sweep 0 has Reflectivity only.
896  * Sweep 1 has Velocity and Spectrum width, No Reflectivity.
897  * Sweep > 1 any.
898  *
899  */
900   if (v == NULL) return;
901   for (i=0; i<v->h.nsweeps; i++) {
902         cart_image = RSL_sweep_to_cart(v->sweep[i], xdim, ydim, range);
903         if (radar_verbose_flag)
904           fprintf(stderr,"==> Sweep %d of %d\n",i, v->h.nsweeps);
905         (void)sprintf(outfile,"%s.%2.2d.pgm", basename, i); /* File name: sweep.[0-10] */
906         if (cart_image != NULL) {
907           RSL_write_pgm(outfile, cart_image, xdim, ydim);
908           if (radar_verbose_flag)
909                 fprintf(stderr,"Wrote: %s\n", outfile);
910           free (cart_image);
911         } else {
912           if (radar_verbose_flag)
913                 fprintf(stderr,"No image.  cart_image for sweep %d is NULL.\n", i);
914         }
915   }
916 }
917
918
919 /***********************************************************************/
920 /*                                                                     */
921 /*                  RSL_rebin_velocity_ray                             */
922 /*                  RSL_rebin_velocity_sweep                           */
923 /*                  RSL_rebin_velocity_volume                          */
924 /*                                                                     */
925 /*  By: John Merritt                                                   */
926 /*      Space Applications Corporation                                 */
927 /*      April 30, 1994                                                 */
928 /*                                                                     */
929 /***********************************************************************/
930 void RSL_rebin_velocity_ray(Ray *r)
931 {
932   /* Rebin the velocity data to the range -nyquist, +nyquist.
933    * 14 bins are created centered at 0.  It sets the proper color look up
934    * indexes.  This function modifies Ray r.
935    */
936   int i;
937   float nyquist;
938   float val /*  val1 */;
939
940   int ncbins = 15; /* Number of color bins */
941   float (*f)(Range x);
942   Range (*invf)(float x);
943
944   if (r == NULL) return;
945
946   nyquist = r->h.nyq_vel;
947   if (nyquist == 0.0) {
948         fprintf(stderr, "RSL_rebin_velocity_ray: nyquist == 0.0\n");
949         fprintf(stderr, "RSL_rebin_velocity_ray: Unable to rebin.\n");
950         return;
951   }
952   f = r->h.f;
953   invf = r->h.invf;
954   for (i=0; i<r->h.nbins; i++) {
955         val = f(r->range[i]);
956         if (val == RFVAL) {
957                 val = 16;
958         } else if (val != BADVAL) {
959 /*
960           Okay, we want to shift the data to positive values
961           then we re-scale them by the number of color bins/nyquist
962 */
963           val = (int)(val/nyquist*(ncbins/2) + 1.0 + ncbins/2);
964
965         } else {
966                 val = 0;
967         }
968
969         r->range[i] = invf(val);
970   }
971 }
972
973
974 void RSL_rebin_velocity_sweep(Sweep *s)
975 {
976   /* Rebin the velocity data to the range -nyquist, +nyquist.
977    * 14 bins are created centered at 0. It sets the proper color look up
978    * indexes.  This function modifies Sweep s.  Use this function prior
979    * RSL_sweep_to_cart.  The binning is done in RSL_rebin_velocity_ray.
980    */
981
982   int i;
983   
984   if (s == NULL) return;
985
986   for (i=0; i<s->h.nrays; i++)
987         RSL_rebin_velocity_ray(s->ray[i]);
988
989 }
990
991 void RSL_rebin_velocity_volume(Volume *v)
992 {
993   /* Rebin the velocity data to the range -nyquist, +nyquist.
994    * 14 bins are created centered at 0. It sets the proper color look up
995    * indexes.  This function modifies Volume v.  Use this function prior
996    * RSL_sweep_to_cart.  The binning is done in RSL_rebin_velocity_ray.
997    */
998
999   int i;
1000   
1001   if (v == NULL) return;
1002
1003   for (i=0; i<v->h.nsweeps; i++)
1004         RSL_rebin_velocity_sweep(v->sweep[i]);
1005
1006 }
1007
1008
1009 /**********************************************************************/
1010 /*                                                                    */
1011 /*                    RSL_carpi_to_cart                               */
1012 /*                                                                    */
1013 /*      Space Applications Corporation                                */
1014 /*      17 Mar 1997                                                   */
1015 /**********************************************************************/
1016 unsigned char *RSL_carpi_to_cart(Carpi *carpi, int xdim, int ydim, float range)
1017 {
1018         /* Converts carpi data from the native RSL 1_ or 2_byte format to 
1019                  unsigned char format for image generation. Also reverses the
1020                  row order of the data so that displayed images come out right side up.
1021   */
1022         int i, j, cart_index;
1023   unsigned char *cart_image = NULL;
1024         float val;
1025         
1026   if (carpi == NULL) return NULL;
1027   cart_image = (unsigned char *) calloc(xdim*ydim, sizeof(unsigned char));
1028         
1029         for (j=0; j<ydim; j++)
1030           for (i=0; i<xdim; i++)
1031                 {
1032                         cart_index = (ydim-1-j)*xdim + i;  /* Reverse the row order. */
1033                         val = carpi->f(carpi->data[j][i]);
1034                         if (val == BADVAL || val == NOTFOUND_V || val == NOTFOUND_H) 
1035                           cart_image[cart_index] = (unsigned char) 0;
1036                         else if (val >= 0) 
1037                           cart_image[cart_index] = (unsigned char) val;
1038                         else 
1039                           cart_image[cart_index] = (unsigned char) (256+val); /*2's complement.*/
1040                 }
1041         return(cart_image);
1042 }
1043
1044 /**********************************************************************/
1045 /*                                                                    */
1046 /*                    RSL_carpi_to_gif                                */
1047 /*                                                                    */
1048 /*      Space Applications Corporation                                */
1049 /*      17 Mar 1997                                                   */
1050 /**********************************************************************/
1051 void RSL_carpi_to_gif(Carpi *carpi, char *outfile, int xdim, int ydim, float range)
1052 {
1053   /* Currently range is not used. */
1054   unsigned char *cart_image;
1055
1056   /* Assumes the color table is already loaded. */
1057   if (carpi == NULL) return;
1058   if (ncolors == 0) {
1059                 fprintf(stderr, "No colors in color table.  Load color table first.\n");
1060                 return;
1061   }
1062   cart_image = RSL_carpi_to_cart(carpi, xdim, ydim, range);
1063   RSL_write_gif(outfile, cart_image, xdim, ydim, color_table);
1064   free(cart_image);
1065 }
1066
1067 /**********************************************************************/
1068 /*                                                                    */
1069 /*                    RSL_carpi_to_pict                               */
1070 /*                                                                    */
1071 /*      Space Applications Corporation                                */
1072 /*      17 Mar 1997                                                   */
1073 /**********************************************************************/
1074 void RSL_carpi_to_pict(Carpi *carpi, char *outfile, int xdim, int ydim, float range)
1075 {
1076   /* Currently range is not used. */
1077   unsigned char *cart_image;
1078
1079   /* Assumes the color table is already loaded. */
1080   if (carpi == NULL) return;
1081   if (ncolors == 0) {
1082                 fprintf(stderr, "No colors in color table.  Load color table first.\n");
1083                 return;
1084   }
1085   cart_image = RSL_carpi_to_cart(carpi, xdim, ydim, range);
1086   RSL_write_pict(outfile, cart_image, xdim, ydim, color_table);
1087   free(cart_image);
1088 }
1089
1090 /**********************************************************************/
1091 /*                                                                    */
1092 /*                    RSL_carpi_to_ppm                                */
1093 /*                                                                    */
1094 /*      Space Applications Corporation                                */
1095 /*      17 Mar 1997                                                   */
1096 /**********************************************************************/
1097 void RSL_carpi_to_ppm(Carpi *carpi, char *outfile, int xdim, int ydim, float range)
1098 {
1099   /* Currently range is not used. */
1100   unsigned char *cart_image;
1101
1102   /* Assumes the color table is already loaded. */
1103   if (carpi == NULL) return;
1104   if (ncolors == 0) {
1105                 fprintf(stderr, "No colors in color table.  Load color table first.\n");
1106                 return;
1107   }
1108   cart_image = RSL_carpi_to_cart(carpi, xdim, ydim, range);
1109   RSL_write_ppm(outfile, cart_image, xdim, ydim, color_table);
1110   free(cart_image);
1111 }
1112
1113 /**********************************************************************/
1114 /*                                                                    */
1115 /*                    RSL_carpi_to_pgm                                */
1116 /*                                                                    */
1117 /*      Space Applications Corporation                                */
1118 /*      17 Mar 1997                                                   */
1119 /**********************************************************************/
1120 void RSL_carpi_to_pgm(Carpi *carpi, char *outfile, int xdim, int ydim, float range)
1121 {
1122   /* Currently range is not used. */
1123   unsigned char *cart_image;
1124
1125   /* Assumes the color table is already loaded. */
1126   if (carpi == NULL) return;
1127   if (ncolors == 0) {
1128                 fprintf(stderr, "No colors in color table.  Load color table first.\n");
1129                 return;
1130   }
1131   cart_image = RSL_carpi_to_cart(carpi, xdim, ydim, range);
1132   RSL_write_pgm(outfile, cart_image, xdim, ydim);
1133   free(cart_image);
1134 }
1135
1136 /**********************************************************************/
1137 /*                    RSL_rebin_volume                                */
1138 /* More generic version of RSL_rebin_velocity. Allows for centering   */
1139 /* +/- field like zdr or vel around zero. Width is the 1/2 width of   */
1140 /* what is to be centered; e.g., +/- 5, width=5.                      */
1141 /* Space Applications Corporation                                     */
1142 /* July 13, 1997                                                      */
1143 /**********************************************************************/
1144 void RSL_rebin_ray(Ray *r, int width)
1145 {
1146   int i;
1147   float nyquist, val; 
1148   int ncbins = 15; /* Number of color bins */
1149   float (*f)(Range x);
1150   Range (*invf)(float x);
1151
1152   if (r == NULL) return;
1153
1154   nyquist = width;
1155   if (nyquist == 0.0) {
1156         fprintf(stderr, "RSL_rebin_ray: nyquist == 0.0\n");
1157         fprintf(stderr, "RSL_rebin_ray: Unable to rebin.\n");
1158         return;
1159   }
1160   f = r->h.f;
1161   invf = r->h.invf;
1162   for (i=0; i<r->h.nbins; i++) {
1163         val = f(r->range[i]);
1164         if (val == width+1) {
1165                 val = ncbins + 1;
1166         } else if (val != BADVAL) {
1167 /*
1168           Okay, we want to shift the data to positive values
1169           then we re-scale them by the number of color bins/nyquist
1170 */
1171           val = (int)(val/nyquist*(ncbins/2) + 1.0 + ncbins/2); 
1172         } else {
1173                 val = 0;
1174         }
1175
1176         r->range[i] = invf(val);
1177   }
1178 }
1179
1180 void RSL_rebin_sweep(Sweep *s, int width)
1181 {
1182   int i;  
1183   if (s == NULL) return;
1184   for (i=0; i<s->h.nrays; i++)
1185         RSL_rebin_ray(s->ray[i], width);
1186 }
1187
1188 void RSL_rebin_volume(Volume *v, int width)
1189 {
1190   int i;
1191   if (v == NULL) return;
1192   for (i=0; i<v->h.nsweeps; i++)
1193         RSL_rebin_sweep(v->sweep[i], width);
1194 }
1195
1196 /**********************************************************************/
1197 /*                                                                    */
1198 /*                 RSL_rebin_zdr_volume, _sweep, _ray                 */
1199 /*                                                                    */
1200 /*      Space Applications Corporation                                */
1201 /**********************************************************************/
1202 /*
1203          Maps valid zdr values from the real set [-6.0, 10.0] onto the set of
1204          integers {0, 1, 2, ..., 35}, which forms the set of indices into
1205          the zdr color table. Used in conjunction with gif image generation
1206          of zdr sweeps.
1207
1208               Color coding:
1209                                 -------------
1210          -6.0 <= zdr < -4.0  --> black
1211          -4.0 <= zdr < -2.0  --> gray
1212          -2.0 <= zdr <  0.0  --> blue
1213     0.0 <= zdr <  2.0  --> green
1214                 2.0 <= zdr <  4.0  --> orange
1215                 4.0 <= zdr <  6.0  --> red
1216                 6.0 <= zdr <  8.0  --> pink
1217                 8.0 <= zdr < 10.0  --> white
1218
1219                 Space Applications Corporation
1220                 July 13, 1997
1221 */
1222
1223 void RSL_rebin_zdr_ray(Ray *r)
1224 {
1225   int i;
1226   float val; 
1227   float (*f)(Range x);
1228   Range (*invf)(float x);
1229
1230   if (r == NULL) return;
1231   f = r->h.f;
1232   invf = r->h.invf;
1233   for (i=0; i<r->h.nbins; i++)
1234         {
1235                 val = f(r->range[i]);
1236                 if ((val >= -6.0) && (val < 8.4)) val = (floor) ((val + 6.0) * 2.5);
1237                 else if (val < 10.0) val = 35.0;  /* Make all these white. */
1238                 else val = 0;  /* invalid zdr value */
1239                 r->range[i] = invf(val);
1240   }
1241 }
1242
1243 void RSL_rebin_zdr_sweep(Sweep *s)
1244 {
1245   int i;  
1246   if (s == NULL) return;
1247   for (i=0; i<s->h.nrays; i++) RSL_rebin_zdr_ray(s->ray[i]);
1248 }
1249
1250 void RSL_rebin_zdr_volume(Volume *v)
1251 {
1252   int i;
1253   if (v == NULL) return;
1254   for (i=0; i<v->h.nsweeps; i++) RSL_rebin_zdr_sweep(v->sweep[i]);
1255 }