]> Pileus Git - ~andy/rsl/blob - radtec.c
Changes from Bart (2009-10-28)
[~andy/rsl] / radtec.c
1 /*
2  * General RADTEC ingest code.
3  *
4  * By John H. Merritt
5  *
6  * May 21, 1998
7  */
8 /*
9     NASA/TRMM, Code 910.1.
10     This is the TRMM Office Radar Software Library.
11     Copyright (C) 1998
12             John H. Merritt
13             Space Applications Corporation
14             Vienna, Virginia
15
16     This library is free software; you can redistribute it and/or
17     modify it under the terms of the GNU Library General Public
18     License as published by the Free Software Foundation; either
19     version 2 of the License, or (at your option) any later version.
20
21     This library is distributed in the hope that it will be useful,
22     but WITHOUT ANY WARRANTY; without even the implied warranty of
23     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24     Library General Public License for more details.
25
26     You should have received a copy of the GNU Library General Public
27     License along with this library; if not, write to the Free
28     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33 #ifdef HAVE_LIBIMPLODE
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include "radtec.h"
37 #include <implode.h>
38
39 static int nray_headers_expected = 0;
40 static int nrays_expected        = 0;
41 Radtec_ray_header *ray_header_array;
42 Radtec_ray *ray_array;
43
44 void radtec_print_header(Radtec_header *h)
45 {
46   printf("version = %d\n", h->version);
47   printf("scan_type = %d\n", h->scan_type);
48   printf("scan_mode = %d\n", h->scan_mode);
49   printf("seqno = %d\n", h->seqno);
50   printf("month = %d\n", h->month);
51   printf("day = %d\n", h->day);
52   printf("year = %d\n", h->year);
53   printf("hour = %d\n", h->hour);
54   printf("min = %d\n", h->min);
55   printf("sec = %d\n", h->sec);
56   printf("az_el = %f\n", h->az_el);
57   printf("azim_resolution = %f\n", h->azim_resolution);
58   printf("azim_offset = %f\n", h->azim_offset);
59   printf("elev_resolution = %f\n", h->elev_resolution);
60   printf("elev_offset = %f\n", h->elev_offset);
61   printf("site_elevation = %f\n", h->site_elevation);
62   printf("site_latitude = %f\n", h->site_latitude);
63   printf("site_longitude = %f\n", h->site_longitude);
64   printf("skip = %f\n", h->skip);
65   printf("range_bin_size = %f\n", h->range_bin_size);
66   printf("num_range_bins = %d\n", h->num_range_bins);
67   printf("num_integrations = %d\n", h->num_integrations);
68   printf("num_rays = %d\n", h->num_rays);
69 }       
70
71 void radtec_print_ray_header(Radtec_ray_header *h)
72 {
73   fprintf(stderr, "ray_num    = %d\n", h->ray_num);
74   fprintf(stderr, "azim_angle = %f\n", h->azim_angle);
75   fprintf(stderr, "elev_angle = %f\n", h->elev_angle);
76   fprintf(stderr, "hour       = %d\n", h->hour);
77   fprintf(stderr, "min        = %d\n", h->min);
78   fprintf(stderr, "sec        = %d\n", h->sec);
79   fprintf(stderr, "\n");
80 }
81
82 struct PassedParam
83 {
84    unsigned int CmpPhase;
85    FILE *InFile;
86    FILE *OutFile;
87    unsigned long CRC;
88 };
89
90 /*-------------------------------------------------------------------
91    Routine to supply data to the implode() or explode() routines.
92    When this routine returns 0 bytes read, the implode() or explode()
93    routines will terminate.  Also calculate the CRC-32 on the original
94    uncompressed data during the implode() call.
95 */
96
97 #define explode _explode
98 #define implode _implode
99 #define crc32 _crc32
100
101 int total_bytes_read = 0;
102 int total_bytes_written = 0;
103 unsigned int ReadFile(char *Buff, unsigned int *Size, void *Param)
104 {
105    size_t Read;
106    struct PassedParam *Par = (struct PassedParam *)Param;
107
108    Read = fread(Buff, 1, *Size, Par->InFile);
109    total_bytes_read += *Size;
110    if (Par->CmpPhase)
111       Par->CRC = crc32(Buff, (unsigned int *)&Read, &Par->CRC);
112
113    return (unsigned int)Read;
114 }
115
116 /*-------------------------------------------------------------------
117    Routine to write compressed data output from implode() or
118    uncompressed data from explode().  Also calculate the CRC on
119    the uncompressed data during the explode() call.
120 */
121
122 void radtec_load_rsl_ray_data(char *Buff, unsigned int *Size, void *Param)
123 {
124    struct PassedParam *Par = (struct PassedParam *)Param;
125    Radtec_ray_header ray_header;
126    static int i = 0;
127    static int nray_headers_seen = 0;
128    static int nrays_seen = 0;
129    int ray_size;
130    static int bytes_remaining = 0;
131
132
133    /*   fwrite(Buff, 1, *Size, Par->OutFile); */
134    /* Buff  -- Contains the data.
135     * *Size -- Contains the length of data.
136     * Par   -- Contains CRC, and FILE* information.
137     */
138
139    if (!Par->CmpPhase)
140       Par->CRC = crc32(Buff, Size, &Par->CRC);
141    total_bytes_written += *Size;
142
143    while(i<*Size && nray_headers_seen < nray_headers_expected) {
144          /* Because of word alignment problems, use this painful memcpy approach. */
145          memcpy(&ray_header.ray_num,    &Buff[i], sizeof(short)); i+=sizeof(short);
146          memcpy(&ray_header.azim_angle, &Buff[i], sizeof(float)); i+=sizeof(float);
147          memcpy(&ray_header.elev_angle, &Buff[i], sizeof(float)); i+=sizeof(float);
148          memcpy(&ray_header.hour,       &Buff[i], sizeof(short)); i+=sizeof(short);
149          memcpy(&ray_header.min,        &Buff[i], sizeof(short)); i+=sizeof(short);
150          memcpy(&ray_header.sec,        &Buff[i], sizeof(short)); i+=sizeof(short);
151          i+=4; /* Fill to 20 bytes. */
152 #define RSL_DEBUG
153 #undef  RSL_DEBUG
154 #ifdef RSL_DEBUG
155          radtec_print_ray_header(&ray_header);
156 #endif
157          ray_header_array[nray_headers_seen] = ray_header;
158          nray_headers_seen++;
159    }
160    /* Ok, whenever 'i' exceeds *Size, we must return to the explode routine
161     * so that we get another buffer 'Buff'.  This new 'Buff' will pick
162     * up where explode left off, and therefore, we must also pick up where
163     * we left off.
164         */
165    if (i >= *Size) {
166          i = 0;
167 #ifdef RSL_DEBUG
168          fprintf(stderr, "Need another Buff for ray headers.\n");
169 #endif
170          return;
171    }
172
173    /* Getting to this point means that i < *Size and we have seen
174     * all the expected number of ray headers.  Now, we must collect
175     * the expected number of rays (the data). 
176     */
177
178    ray_size = sizeof(Radtec_ray);
179    while(i<*Size && nrays_seen < nrays_expected) {
180 #ifdef RSL_DEBUG
181                  fprintf(stderr, "WHILE i=%d, i+ray_size=%d\n", i, i+ray_size);
182 #endif
183          if (i+ray_size > *Size) { /* Possible over flow. */
184            /* Load what we can. */
185            memcpy(&ray_array[nrays_seen].dbz, &Buff[i], *Size-i);
186            bytes_remaining =  ray_size - *Size + i;
187 #ifdef RSL_DEBUG
188                    fprintf(stderr, "Buffer overflow : i=%d ray_size=%d loading %d bytes_remaining=%d\n", 
189                           i, ray_size, *Size-i, bytes_remaining);
190 #endif
191            i=*Size;
192            break;
193          } else {
194            if (bytes_remaining > 0) {
195 #ifdef RSL_DEBUG
196                  fprintf(stderr,"Load remaining: i=%d ray_size=%d bytes_remaining=%d\n", 
197                                 i, ray_size, bytes_remaining);
198 #endif
199                  memcpy(&ray_array[nrays_seen].dbz[(ray_size-bytes_remaining)/4], &Buff[i], bytes_remaining);
200                  i+=bytes_remaining;
201                  bytes_remaining = 0;
202            } else {
203 #ifdef RSL_DEBUG
204                  fprintf(stderr, "Load full buff: i=%d ray_size=%d bytes_remaining=%d\n", 
205                                 i, ray_size, bytes_remaining);
206 #endif
207                  memcpy(&ray_array[nrays_seen].dbz, &Buff[i], ray_size);
208                  i+=ray_size;
209            }
210          }
211          ray_array[nrays_seen].h = &ray_header_array[nrays_seen];
212          nrays_seen++;
213 #ifdef RSL_DEBUG
214          fprintf(stderr, "Ray data # %d, sizeof(Radtec_ray)=%d, i=%d\n",  nrays_seen, sizeof(Radtec_ray), i);
215 #endif
216    }
217
218    if (i >= *Size) {
219          i = 0;
220 #ifdef RSL_DEBUG
221          fprintf(stderr, "Need another Buff for ray data. i=%d *Size=%d\n", i, *Size);
222 #endif
223          return;
224    }
225
226
227 }
228
229 Radtec_file *radtec_read_file(char *infile)
230 {
231   FILE *fp;
232   Radtec_file *rfile;
233
234   char *WorkBuff;               /* buffer for compression tables */
235   unsigned int Error;
236   struct PassedParam Param;     /* Parameters passed to callback functions */
237   
238
239   if (infile == NULL) {
240         fp = stdin;
241   } else {
242         if((fp = fopen(infile, "r")) == NULL) {
243           perror(infile);
244           return NULL;
245         }
246   }
247
248   rfile = (Radtec_file *)calloc(1, sizeof(Radtec_file));
249   if (rfile == NULL) { perror("calloc Radtec_file"); return NULL; }
250   fread(&rfile->h, sizeof(Radtec_header), 1, fp);
251
252   /* Initialize the global for the unpacking routine. The unpacking
253    * routine is a callback for 'explode'; the second argument.
254    */
255   nray_headers_expected = rfile->h.num_rays;
256   nrays_expected        = rfile->h.num_rays;
257
258   /* Allocate space for all the headers and rays expected. */
259   ray_header_array = (Radtec_ray_header *)calloc(rfile->h.num_rays, sizeof(Radtec_ray_header));
260   if (ray_header_array == NULL) { perror("calloc Radtec_ray_header"); return NULL; }
261   ray_array = (Radtec_ray *)calloc(rfile->h.num_rays, sizeof(Radtec_ray));
262   if (ray_array == NULL) { perror("calloc Radtec_ray"); return NULL; }
263
264   /* -------------- PKWARE ----------- */
265   WorkBuff = (char *)malloc(EXP_BUFFER_SIZE);
266   if (WorkBuff == NULL) {
267         perror("RADETC, unable to allocate work buffer.");
268         return NULL;
269   }
270   
271   Param.InFile  = fp;
272   Param.OutFile = NULL;
273   
274   /* Initialize CRC */
275   Param.CmpPhase = 0;
276   Param.CRC = (unsigned long) -1;
277   
278   Error = explode(ReadFile, radtec_load_rsl_ray_data, WorkBuff, &Param);
279   
280   Param.CRC = ~Param.CRC;
281   free(WorkBuff);
282   fclose(Param.InFile);
283   fclose(Param.OutFile);
284   if (Error != 0) {
285         fprintf(stderr, "RADTEC: uncompression completed - Error %d\n", Error);
286         fprintf(stderr, "RADTEC: Total bytes read    = %d\n", total_bytes_read);
287         fprintf(stderr, "RADTEC: Total bytes written = %d\n", total_bytes_written);
288   }
289   /* -------------- PKWARE ----------- */
290   rfile->ray   = ray_array;
291
292   return rfile;
293 }
294
295 void radtec_free_file(Radtec_file *rfile)
296 {
297   free(rfile->ray);
298   free(rfile);
299 }
300 #endif