2 * General RADTEC ingest code.
10 This is the TRMM Office Radar Software Library.
13 Space Applications Corporation
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.
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.
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.
33 #ifdef HAVE_LIBIMPLODE
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;
44 void radtec_print_header(Radtec_header *h)
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);
71 void radtec_print_ray_header(Radtec_ray_header *h)
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");
84 unsigned int CmpPhase;
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.
97 #define explode _explode
98 #define implode _implode
101 int total_bytes_read = 0;
102 int total_bytes_written = 0;
103 unsigned int ReadFile(char *Buff, unsigned int *Size, void *Param)
106 struct PassedParam *Par = (struct PassedParam *)Param;
108 Read = fread(Buff, 1, *Size, Par->InFile);
109 total_bytes_read += *Size;
111 Par->CRC = crc32(Buff, (unsigned int *)&Read, &Par->CRC);
113 return (unsigned int)Read;
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.
122 void radtec_load_rsl_ray_data(char *Buff, unsigned int *Size, void *Param)
124 struct PassedParam *Par = (struct PassedParam *)Param;
125 Radtec_ray_header ray_header;
127 static int nray_headers_seen = 0;
128 static int nrays_seen = 0;
130 static int bytes_remaining = 0;
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.
140 Par->CRC = crc32(Buff, Size, &Par->CRC);
141 total_bytes_written += *Size;
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. */
155 radtec_print_ray_header(&ray_header);
157 ray_header_array[nray_headers_seen] = ray_header;
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
168 fprintf(stderr, "Need another Buff for ray headers.\n");
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).
178 ray_size = sizeof(Radtec_ray);
179 while(i<*Size && nrays_seen < nrays_expected) {
181 fprintf(stderr, "WHILE i=%d, i+ray_size=%d\n", i, i+ray_size);
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;
188 fprintf(stderr, "Buffer overflow : i=%d ray_size=%d loading %d bytes_remaining=%d\n",
189 i, ray_size, *Size-i, bytes_remaining);
194 if (bytes_remaining > 0) {
196 fprintf(stderr,"Load remaining: i=%d ray_size=%d bytes_remaining=%d\n",
197 i, ray_size, bytes_remaining);
199 memcpy(&ray_array[nrays_seen].dbz[(ray_size-bytes_remaining)/4], &Buff[i], bytes_remaining);
204 fprintf(stderr, "Load full buff: i=%d ray_size=%d bytes_remaining=%d\n",
205 i, ray_size, bytes_remaining);
207 memcpy(&ray_array[nrays_seen].dbz, &Buff[i], ray_size);
211 ray_array[nrays_seen].h = &ray_header_array[nrays_seen];
214 fprintf(stderr, "Ray data # %d, sizeof(Radtec_ray)=%d, i=%d\n", nrays_seen, sizeof(Radtec_ray), i);
221 fprintf(stderr, "Need another Buff for ray data. i=%d *Size=%d\n", i, *Size);
229 Radtec_file *radtec_read_file(char *infile)
234 char *WorkBuff; /* buffer for compression tables */
236 struct PassedParam Param; /* Parameters passed to callback functions */
239 if (infile == NULL) {
242 if((fp = fopen(infile, "r")) == NULL) {
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);
252 /* Initialize the global for the unpacking routine. The unpacking
253 * routine is a callback for 'explode'; the second argument.
255 nray_headers_expected = rfile->h.num_rays;
256 nrays_expected = rfile->h.num_rays;
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; }
264 /* -------------- PKWARE ----------- */
265 WorkBuff = (char *)malloc(EXP_BUFFER_SIZE);
266 if (WorkBuff == NULL) {
267 perror("RADETC, unable to allocate work buffer.");
272 Param.OutFile = NULL;
276 Param.CRC = (unsigned long) -1;
278 Error = explode(ReadFile, radtec_load_rsl_ray_data, WorkBuff, &Param);
280 Param.CRC = ~Param.CRC;
282 fclose(Param.InFile);
283 fclose(Param.OutFile);
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);
289 /* -------------- PKWARE ----------- */
290 rfile->ray = ray_array;
295 void radtec_free_file(Radtec_file *rfile)