source: trunk/WRF.COMMON/WRFV3/external/io_grib1/MEL_grib1/grib_enc.c

Last change on this file was 2759, checked in by aslmd, 2 years ago

adding unmodified code from WRFV3.0.1.1, expurged from useless data +1M size

File size: 19.6 KB
Line 
1/*
2 REVISIONS:
3 10/15/96 A. Nakajima, SAIC:  removed 'write_grib' call; make combined lib;
4 11/03/97 /ATN  -Realloc
5*/
6#include <stdio.h>
7#include <string.h>
8#include <stdlib.h>
9#ifdef XT3_Catamount
10#include <features.h>
11#undef htonl
12#define htonl(x)     swap_byte4(x)
13#else
14#include <netinet/in.h>
15#endif
16#include "dprints.h"            /* for dprints */
17#include "grib_lookup.h"        /* parm/model/lvl defn */
18#include "gribfuncs.h"          /* prototypes */
19
20/*
21*
22****************************************************************************
23* A.  FUNCTION:  grib_enc
24*        to encode a GRIB Edition 1 message using the three
25*        input internal structures (DATA_INPUT, USER_INPUT, GEOM_IN),
26*        and the Floating point data array; 
27*        It's ok for Float array to be null if Grib Hdr shows that
28*        it contains a predefined BDS;  that case, just exits w/ no errs;
29*
30*    INTERFACE:
31*      int grib_enc (Data_Input, User_Input, Geom_In, pfData_Array, gh, errmsg)
32*     
33*    ARGUMENTS (I=input, O=output, I&O=input and output):
34*      (I)  DATA_INPUT Data_Input;
35*           Structure containing input field information. 
36*      (I)  USER_INPUT User_Input;
37*           Structure containing encoder configuration data.
38*      (I)  GEOM_IN Geom_In;
39*           Structure containing grid geometry description.
40*    (I&O)  float *pfData_Array;
41*           array of float data to be packed and stored in the Binary Data
42*           Section.  Float array may be Null if the Grib Header already
43*           contains a Binary Data Section in its attribute 'entire_msg'.
44*           That case is referred to as the 'Shuffle Mode' which results
45*           in the encoder to only create the sections which are not already
46*           in entire_msg; 
47*           Note: non-null data array will be returned with the data being
48*           scaled up by the Decimal Scale Factor.
49*    (I&O)  GRIB_HDR *gh;
50*           Pre-malloced structure used to hold the encoded GRIB message
51*           and its info.  It contains a large array to hold the encoded
52*           message, pointers to each of the Section along with their length,
53*           and a flag 'shuffled' which determines how the message is encoded.
54*           If 'shuffled' is zero upon entry, all 6 sections will be created
55*           and array (float *pfData_Array) must contain the float data.
56*           If 'shuffled' is set upon entry, there is already one or more
57*           sections in Entire_msg;  Each of these pre-included sections
58*           sections will have a Non-Null pointer & a non-Zero length.
59*           The encoder will then only create the missing sections and
60*           append them at the end of the existing sections in array
61*           'entire_msg', hence these sections may not be in the proper
62*           order expected by GRIB.
63*      (O)  char *errmsg
64*           Empty array, returned filled if error occurred;
65*
66*    RETURN VALUE: 
67*       0>  no errors;   
68*           GRIB_HDR is returned with the encoded message in 'entire_msg',
69*           w/ total message length in msg_length,
70*           w/ pointers to each defined Grib Header Sections in
71*           ids_ptr, pds_ptr, gds_ptr, bms_ptr, gds_ptr, eds_ptr,
72*           and each section length in ids_len, pds_len, gds_len, bms_len,
73*           bds_len, eds_len;  Note that the sections may not be in order if
74*           the 'shuffled' bit is set;
75*       1>  failed,  msg in errmsg;
76****************************************************************************/
77#if PROTOTYPE_NEEDED
78int grib_enc   (DATA_INPUT Data_Input, USER_INPUT User_Input, GEOM_IN Geom_In,
79                float *pfData_Array, GRIB_HDR *gh, char *errmsg)
80#else
81int grib_enc   (Data_Input, User_Input, Geom_In, pfData_Array, gh, errmsg)
82                DATA_INPUT Data_Input; 
83                USER_INPUT User_Input; 
84                GEOM_IN Geom_In;
85                float *pfData_Array; 
86                GRIB_HDR *gh; 
87                char *errmsg;
88#endif
89{
90   PDS_INPUT            *pPDS_Input= 0;         /* internal Pds struc */
91   GDS_HEAD_INPUT       *pGDS_Head_Input = 0;   /* Internal Gds struc */
92   void                 *pvGDS_Proj_Input = 0;  /* depends on Projection*/
93   BDS_HEAD_INPUT       *pBDS_Head_Input = 0;   /* Internal Bds struc */
94   char                 *func= "grib_enc";
95   char                 *Sevens= "7777";
96   int                  gdsbms_flag= 0;         /* whether to include them */
97   unsigned char        *px;                    /* working ptr w/in EntireMsg */
98   long                 lTemp;                  /* working var */
99   int                  n,Stat= 1;              /* default to error */
100
101   DPRINT1 ("Entering %s...\n", func);
102/*
103*
104* A.1          IF (ptr is null or if the Entire_msg buffer is null) THEN
105*                 RETURN 1 !errmsg filled
106*              ENDIF
107*/
108   if (!gh || !gh->entire_msg) 
109        { 
110        sprintf (errmsg, "%s: expecting non-null GRIB_HDR struct\n", func);
111        goto BYE; 
112        }
113
114/*
115*
116* A.2          CREATE storage for the Internal structures;
117*                  ! PDS_INPUT
118*                  ! GDS_HEAD_INPUT
119*                  ! GDS_Proj_Input set to MAX_INP_PROJ_SIZE defined in grib.h
120*                  ! BDS_HEAD_INPUT
121*              RETURN with Malloc Err in errmsg if fails;
122*              INITIALIZE Internal structures
123*/
124   if (! (pPDS_Input= (PDS_INPUT *)malloc(sizeof(PDS_INPUT))) ||
125       ! (pGDS_Head_Input =(GDS_HEAD_INPUT*)malloc(sizeof(GDS_HEAD_INPUT))) ||
126       ! (pvGDS_Proj_Input= (void *) malloc (MAX_INP_PROJ_SIZE))  ||
127       ! (pBDS_Head_Input =(BDS_HEAD_INPUT*)malloc(sizeof(BDS_HEAD_INPUT))))
128        {
129        sprintf(errmsg,"%s:  failed to make storage for Internal Structs\n",
130        func);
131        goto BYE; 
132        }
133   memset ((void *) pPDS_Input, '\0', sizeof(PDS_INPUT));
134   memset ((void *) pGDS_Head_Input, '\0', sizeof (GDS_HEAD_INPUT));
135   memset ((void *) pvGDS_Proj_Input,'\0', MAX_INP_PROJ_SIZE);
136   memset ((void *) pBDS_Head_Input, '\0', sizeof (BDS_HEAD_INPUT));
137
138/*
139*
140* A.3          IF (creating all sections)
141*              ! ** (shuffled == 0) **
142*              ! user passed Float data in, and the GribHdr's
143*              ! Entire_Msg array has no valid data in it;
144*              ! Must 'put' all Sections 0 thru 5 into Grib Hdr in that order;
145* A.3.a        THEN
146*/
147   if (! gh->shuffled) 
148        { 
149        /* Create All Sections mode:  user must send float data */
150        DPRINT0 ("(SHUFFLE=0)  Create ALL sections mode\n");
151
152/*
153* A.3.a.1          RETURN if Float array is Null;  !errmsg filled
154*/
155        if ( !pfData_Array) 
156          {
157           sprintf(errmsg,
158          "%s: <Create-All mode>  No DataArray avail to encode\n",func);
159           goto BYE;
160           }
161
162/*
163* A.3.a.2          CLEAR out the length and section ptrs
164*                  ASSIGN beginning of Entire Msg to 'px', as location to
165*                  append things to;
166*/
167        gh->msg_length= gh->eds_len= gh->pds_len= gh->gds_len= 0;
168        gh->bms_len= gh->bds_len= gh->eds_len= 0;
169        gh->eds_ptr= gh->pds_ptr= gh->gds_ptr= NULL;
170        gh->bms_ptr= gh->bds_ptr= gh->eds_ptr= NULL;
171        px = gh->entire_msg; /* append from here on */
172/*
173*
174* A.3.a.3          BUILD IDS SECTION
175*                  SET up pointer to IDS
176*                  SET up IDS length  (8 for Edition 1)
177*                  WRITE the Ident Data Section to Grib Hdr
178*                  UPDATE 'px' to end of IDS !where to write next section
179*/
180        gh->ids_len = 8; 
181        gh->msg_length += 8L;
182        gh->ids_ptr = px;
183        memcpy  ((void *) gh->ids_ptr, (void *)"GRIB....", 8);
184        px = gh->entire_msg + gh->msg_length;
185        DPRINT3 ("%s: 'putting' IDS (%ld), msg_len=%ld\n",
186        func, gh->ids_len,gh->msg_length);
187
188/*
189*
190* A.3.a.4          FUNCTION gribputpds   !Build PDS Section into GRIB_HDR
191*                  IF failed
192*                  THEN return with error !errmsg filled
193*                  ELSE  bump 'px' to end of this section
194*/
195        if (n= gribputpds (Data_Input, User_Input, pPDS_Input, &gh, errmsg)) 
196         { 
197           upd_child_errmsg (func, errmsg);
198           goto BYE; 
199         }
200        else   px = gh->entire_msg + gh->msg_length;
201
202        DPRINT3("%s: Encoding PDS (%ld), msg_len=%ld\n",
203        func, gh->pds_len,gh->msg_length);
204
205/*
206*
207* A.3.a.5          FUNCTION gribputgds  !Build GDS Section into GRIB_HDR
208*                  IF failed
209*                  THEN return with error !errmsg filled
210*                  ELSE  bump 'px' to end of this section
211*/
212 if ((int) (User_Input.usGds_bms_id) >= 128)
213      {
214           if ( n = gribputgds (Geom_In, 
215                       pGDS_Head_Input, &pvGDS_Proj_Input, &gh, errmsg) )
216             { 
217               upd_child_errmsg (func, errmsg);
218               goto BYE; 
219             }
220           else   px = gh->entire_msg + gh->msg_length;
221
222           DPRINT3 ("%s: Encoding  GDS (%ld), msg_len=%ld\n",
223            func, gh->gds_len,gh->msg_length);
224      }
225        else DPRINT1 ("%s: SKIPPING GDS!\n", func);
226
227/*
228*
229* A.3.a.6          Force no BMS by default
230*/
231        gh->bms_ptr=0; gh->bms_len= 0; 
232        DPRINT1 ("%s: Skipping BMS by default\n", func);
233
234/*
235*
236* A.3.a.7          FUNCTION gribputbds  Build BDS Section into GRIB_HDR
237*                  IF failed
238*                  THEN return with error !errmsg filled
239*                  ELSE  bump 'px' to end of this section
240*/
241        if (n= gribputbds (User_Input, Geom_In.nx*Geom_In.ny, 
242                        pPDS_Input->sDec_sc_fctr, 
243                        pfData_Array, 
244                        pBDS_Head_Input, &gh, errmsg)) 
245         { 
246           upd_child_errmsg (func, errmsg);
247           goto BYE; 
248         }
249       else   px = gh->entire_msg + gh->msg_length;
250
251       DPRINT3 ("%s: Encoding BDS (%ld), msg_len=%ld\n",
252                func, gh->bds_len,gh->msg_length);
253
254/*
255*
256* A.3.a.8          IF (Entire Msg buffer isn't big enough to hold EDS)
257*                  THEN
258*                     FUNCTION Expand_gribhdr    !make it 4 bytes larger
259*                     RETURN with Error if fails !errmsg filled
260*                  ENDIF
261*                  SET up pointer to EDS
262*                  WRITE Grib EDS section to the end of Data !"7777"
263*                  UPDATE Grib Hdr's Eds_Ptr, Eds_Len
264*/
265       if (gh->msg_length > gh->abs_size
266        && Expand_gribhdr (gh, gh->msg_length, errmsg) != 0)
267         { 
268           upd_child_errmsg (func, errmsg); 
269           goto BYE; 
270         }
271
272       gh->eds_ptr= px;
273       gh->eds_len= 4;
274       gh->msg_length += gh->eds_len;
275       memcpy ((void *)gh->eds_ptr, (void*)Sevens, 4);
276       DPRINT3 ("%s: 'putting' EDS (%ld), msg_len=%ld\n",
277       func, gh->eds_len,gh->msg_length);
278
279  } /* END SHUFFLED == 0 SECTION */
280
281/*
282* A.3.b        ELSE
283*              ! ** (shuffled == 1) **
284*              ! means that user has already put 1/more GRIB sections
285*              ! in GRIB_HDR struct's Entire_Msg;  The already included
286*              ! Sections may not be in proper GRIB-format order, and have
287*              ! non-null Pointers and non-zero length;  Msg_Length also
288*              ! reflects total length of all included sections; 
289*              ! -if the Float data is Null, the Bds must already be included
290*              ! in the Grib Hdr;  Func will return error if the Bds pointer
291*              ! is Null or the Bds Len is zero; 
292*              ! -if the incoming Float data has data and the Grib hdr shows
293*              ! that BMS is already defined then the func will Ignore the
294*              ! float data;
295*              ! otherwise, the float data will be used to create a new
296*              ! Binary Data Section;
297*              ! Only need to 'put' the Sections that have not already been
298*              ! included in the Grib Header; 
299*/
300   else {  /* Shuffle Mode:  Create Missing Sections mode */
301
302/*
303* A.3.b.1          IF (there is discrepency in section pointers and length)
304*                      RETURN 1  !errmsg filled
305*                  ENDIF
306*/
307        if (  (gh->ids_ptr && !gh->ids_len) || (gh->ids_len && !gh->ids_ptr)
308           || (gh->pds_ptr && !gh->pds_len) || (gh->pds_len && !gh->pds_ptr)
309           || (gh->gds_ptr && !gh->gds_len) || (gh->gds_len && !gh->gds_ptr)
310           || (gh->bms_ptr && !gh->bms_len) || (gh->bms_len && !gh->bms_ptr)
311           || (gh->bds_ptr && !gh->bds_len) || (gh->bds_len && !gh->bds_ptr)
312           || (gh->eds_ptr && !gh->eds_len) || (gh->eds_len && !gh->eds_ptr)
313           || (gh->entire_msg && !gh->msg_length) 
314           || (gh->msg_length && !gh->entire_msg)  )
315            {
316            sprintf (errmsg,
317            "%s:  GribHdr Length/Ptr to sections are not consistent\n", func); 
318            goto BYE; 
319            }
320
321/*
322* A.3.b.2          IF (no float array was passed in AND
323*                      Grib Hdr shows BDS is undefined) THEN
324*                      RETURN 1 !errmsg filed
325*                  ENDIF
326*/
327        if ( !pfData_Array && !gh->bds_ptr) {
328           sprintf(errmsg, 
329           "%s: <Create Missing Sect mode> No DataArray avail to encode Bds\n",
330           func);
331           goto BYE;
332           }
333
334/*
335* A.3.b.3          IF (user did send in float array AND
336*                      Grib Hdr shows BDS is already defined) THEN
337*                      PRINT warning   !won't encode float array
338*                  ENDIF
339*/
340        if ( pfData_Array && gh->bds_ptr && gh->bds_len>0) {
341           DPRINT2 ("%s: GribHdr already has a BDS (Len=%ld), " \
342           " not going to encode the Float Data\n" , func, gh->bds_len);
343         }
344
345        DPRINT7 ("(SHUFFLE=1)  gribhdr contains msg with totlen=%ld\n" \
346                "   IDS(%d), PDS(%d), GDS(%d), BMS(%d), BDS(%d), EDS(%d)\n",
347                gh->msg_length, gh->ids_len, gh->pds_len, gh->gds_len,
348                gh->bms_len, gh->bds_len, gh->eds_len);
349
350/*
351* A.3.b.4          ASSIGN to local ptr 'px' the address of Msg_length bytes
352*                  away from Entire Msg, as location to append things to;
353*/
354         px = gh->entire_msg + gh->msg_length; /* append from here */
355         
356/*
357*
358* A.3.b.5          IF (GribHdr has no IDS yet)
359*                  THEN
360*                      SET up pointer to IDS
361*                      SET up IDS length  (8 for Edition 1)
362*                      WRITE the Ident Data Section to Grib Hdr
363*                      !use dummy message length for now
364*                      UPDATE 'px' to end of IDS !where to write next section
365*                  ENDIF
366*/
367   if ( gh->ids_ptr==NULL ) 
368     {
369        gh->ids_len = 8; 
370        gh->msg_length += 8L;
371        gh->ids_ptr = px;
372        memcpy  ((void *) gh->ids_ptr, (void *)"GRIB....", 8);
373        px = gh->entire_msg + gh->msg_length;
374        DPRINT3 ("%s: 'putting' IDS (%ld), msg_len=%ld\n",
375        func, gh->ids_len,gh->msg_length);
376    }
377  else DPRINT1 ("%s: skip writing IDS\n", func);
378
379/*
380*
381* A.3.b.6          IF (GribHdr has no PDS yet)
382*                  THEN
383*                      FUNCTION gribputpds  !Build PDS Section into GRIB_HDR
384*                      IF failed
385*                      THEN return with error !errmsg filled
386*                      ELSE  bump 'px' to end of this section
387*                  ENDIF
388*/
389   if ( gh->pds_ptr==NULL) 
390     {
391        if (n= gribputpds (Data_Input, User_Input, pPDS_Input, &gh, errmsg)) 
392         { 
393           DPRINT2 ("%s:  got err=%d in Grib Put Pds()\n",func,n);
394           upd_child_errmsg (func, errmsg);
395           goto BYE; 
396         }
397        else   px = gh->entire_msg + gh->msg_length;
398
399        DPRINT3("%s: 'putting' PDS (%ld), msg_len=%ld\n",
400        func, gh->pds_len,gh->msg_length);
401     }
402  else DPRINT1("%s:  skip writing PDS\n", func);
403
404/*
405*
406* A.3.b.7          IF (GribHdr has no GDS yet)
407*                  THEN
408*                      FUNCTION gribputgds  !Build GDS Section into GRIB_HDR
409*                      IF failed
410*                      THEN return with error !errmsg filled
411*                      ELSE  bump 'px' to end of this section
412*                  ENDIF
413*/
414
415   if ((gh->gds_ptr==NULL) && (User_Input.usGds_bms_id >= 128))
416    {
417       if ( n = gribputgds (Geom_In, 
418                   pGDS_Head_Input, &pvGDS_Proj_Input, &gh, errmsg) )
419         { 
420           DPRINT2 ("%s:  got err=%d in Grib Put Gds()\n",func,n);
421           upd_child_errmsg (func, errmsg);
422           goto BYE; 
423         }
424       else   px = gh->entire_msg + gh->msg_length;
425
426       DPRINT3 ("%s: 'putting' GDS (%ld), msg_len=%ld\n",
427        func, gh->gds_len,gh->msg_length);
428    }
429  else DPRINT1 ("%s:  skip writing GDS\n", func);
430
431/*
432*
433* A.3.b.8          CHECK consistency on Gds/Bms flag
434*                  IF (GDS is included)
435*                  THEN SET the GdsPresent bit
436*                  ELSE CLEAR the GdsPresent bit
437*                  ENDIF
438*/
439  gdsbms_flag = (int)gh->pds_ptr[7] & 0x000000FF;
440  DPRINT1 ("orig gds/bms flag, pds[7] = 0x%x\n", gdsbms_flag);
441
442  if (gh->gds_ptr == NULL) {
443         gdsbms_flag &= ~(0x00000080); 
444         DPRINT2 ("%s: GDS missing, so CLEAR 0x80;  newFLG=0x%x, \n", 
445         func, gdsbms_flag);
446        }
447  else { 
448         gdsbms_flag |= (0x00000080); 
449         DPRINT2 ("%s: GDS Present, so SET 0x80;  newFLG=0x%x, \n", 
450         func, gdsbms_flag);
451         /*
452            DONOT set grid id to 255, since it is possible for user to
453            define a new grid with id w/in range, and still include GDS;
454          */
455        }
456
457/*
458*
459* A.3.b.9          IF (BMS is there) THEN
460*                      SET the BmsPresent bit
461*                  ELSE
462*                      CLEAR the BmsPresent bit
463*                  ENDIF
464*/
465  if (gh->bms_ptr == NULL) {
466         gdsbms_flag &= ~(0x00000040);
467         DPRINT2 ("%s: no BMS, so CLEAR 0x40; new FLG=0x%x",func,gdsbms_flag);
468        }
469  else { gdsbms_flag |= (0x00000040);
470         DPRINT2("%s: BMS Present, so SET 0x40; new FLG=0x%x",func,gdsbms_flag);
471        }
472
473   gh->pds_ptr[7] = (unsigned char)gdsbms_flag;
474   DPRINT1 ("; PDS_ptr[7]= %x\n",gh->pds_ptr[7]);
475
476/*
477*
478* A.3.b.10         IF (GribHdr has no BDS yet) THEN
479*                      FUNCTION gribputBds  !Build BDS Section into GRIB_HDR
480*                      !**NOT doing anything to Data even if BMS is included ***
481*                      IF failed
482*                      THEN return with error !errmsg filled
483*                      ELSE  bump 'px' to end of this section
484*                  ENDIF
485*/
486   if ( gh->bds_ptr==NULL )
487    {
488        if (n= gribputbds (User_Input, Geom_In.nx*Geom_In.ny, 
489                        pPDS_Input->sDec_sc_fctr, 
490                        pfData_Array, 
491                        pBDS_Head_Input, &gh, errmsg)) 
492         { 
493           DPRINT2 ("%s:  got err=%d in Grib Put BDS()\n",func,n);
494           upd_child_errmsg (func, errmsg);
495           goto BYE; 
496         }
497       else   px = gh->entire_msg + gh->msg_length;
498
499       DPRINT3 ("%s: 'putting' BDS (%ld), msg_len=%ld\n",
500                func, gh->bds_len,gh->msg_length);
501    }
502  else DPRINT1("%s: skip writing BDS\n", func);
503
504/*
505*
506* A.3.b.11         IF (GribHdr has no EDS yet)
507*                  THEN
508*                    IF (Entire Msg buffer isn't big enough to hold EDS)
509*                     FUNCTION Expand_gribhdr    !make it 4 bytes larger
510*                     RETURN with Error if fails !errmsg filled
511*                  ENDIF
512*                  SET up pointer to EDS
513*                  WRITE Grib EDS section to the end of Data !"7777"
514*                  UPDATE Grib Hdr's Eds_Ptr, Eds_Len
515*/
516   if ( gh->eds_ptr==NULL ) 
517   {
518       if (gh->msg_length+5L > gh->abs_size ) {
519          DPRINT1 ("Need to expand gribhdr (%ld) to hold EDS\n", 
520          gh->abs_size);         
521          /*if (NULL == (realloc (gh->entire_msg, gh->msg_length))) */
522
523          if (Expand_gribhdr (gh, gh->msg_length+5L, errmsg) ) {
524             upd_child_errmsg (func, errmsg);
525             goto BYE;
526          }
527          DPRINT1("gribhdr now has abs_size of %ld\n",
528          gh->abs_size);
529
530        }  /* size changed */
531
532       gh->eds_ptr= px;
533       gh->eds_len= 4;
534       gh->msg_length += gh->eds_len;
535       memcpy ((void *)gh->eds_ptr, (void*)Sevens, 4);
536       DPRINT3 ("%s: 'putting' EDS (%ld), msg_len=%ld\n",
537       func, gh->eds_len,gh->msg_length);
538  }
539  else DPRINT1 ("%s:  skip writing EDS\n", func);
540
541/*
542* A.3          ENDIF
543*/
544        } /* END SHUFFLED == 1 SECTION */
545
546/*
547*
548* A.4          UPDATE Total Msg Length in Grib Hdr's Ident Data Sect
549*/
550   set_bytes(gh->msg_length, 3, gh->ids_ptr+4);
551   
552   /* 1 is for the Edition  1 */   
553   set_bytes(1,1,gh->ids_ptr+7);
554
555/*
556*
557* A.5          SET status to 0  ! no errors
558*/
559   Stat = 0;
560   
561
562BYE:
563/*
564*
565* A.6          PRINT message if error occurred
566*/
567  if (errmsg[0]!='\0') DPRINT1("%s\n", errmsg);
568/*
569*
570* A.7          FREE up space of local Input structures
571*
572* A.8          RETURN stat
573*/
574  /*
575   * Changed by Todd Hutchinson, TASC
576   * With this original code, not all memory was being freed
577   */
578  /* Original
579  if (! pPDS_Input)  free(pPDS_Input);
580  if (! pGDS_Head_Input) free(pGDS_Head_Input);
581  if (! pvGDS_Proj_Input) free(pvGDS_Proj_Input);
582  if (! pBDS_Head_Input) free(pBDS_Head_Input);
583  */
584  /* New: */
585  free(pPDS_Input);
586  free(pGDS_Head_Input);
587  free(pvGDS_Proj_Input);
588  free(pBDS_Head_Input);
589
590  DPRINT3 ("Leaving %s (Msglen=%ld), stat=%d\n", func, gh->msg_length,Stat);
591  return Stat;
592
593/*
594*
595* END OF FUNCTION
596*
597*
598*/ 
599}
Note: See TracBrowser for help on using the repository browser.