Update version info for release v4.6.1 (#2122)
[WRF.git] / external / io_grib1 / MEL_grib1 / gribputbds.c
blob7daee370a7526fde3da7e4c37472f7824e298b49
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "dprints.h" /* for dprints */
5 #include "gribfuncs.h" /* prototypes */
7 /*
8 ******************************************************************************
9 * A. FUNCTION: gribputbds
10 * Use the information provided to create a Binary Data Section of
11 * the GRIB format and store it in the GRIB_HDR structure;
13 * INTERFACE:
14 * int gribputbds (user_input, lgrid_size, sDec_sc_fctr, pfData_Array,
15 * pBDS_Head_Input, pgrib_hdr, errmsg)
17 * ARGUMENTS (I=input, O=output, I&O=input and output):
18 * (I) USER_INPUT user_input;
19 * Structure containing encoder configuration data
20 * (I) long lgrid_size;
21 * number of datapoints expected for this projection
22 * (I) short sDec_sc_fctr;
23 * Decimal Scle Factor used when packing up data
24 * (I&O) float *pfData_Array;
25 * float array to be packed up. Returned scaled up by Dec Scale Fctr.
26 * (O) BDS_HEAD_INPUT *pBDS_Head_Input
27 * returned filled;
28 * (I&O) GRIB_HDR **pgrib_hdr;
29 * structure to hold encoded BDS and its info
30 * (O) char *errmsg
31 * empty array, returned filled if error occurred;
33 * RETURN CODE:
34 * 0> no errors; GRIB_HDR now has a valid Binary Data Section;
35 * BDS_HEAD_INPUT filled also;
36 * 1> error occurred, errmsg filled;
37 * either GRIB_HDR structure is corrupted, or
38 * non-shuffle mode but the Data array is Null, or
39 * failed to pack the Data array up, or
40 * failed to expand 'entire_msg' in GRIB_HDR to support encoded BDS;
41 ******************************************************************************
43 #if PROTOTYPE_NEEDED
44 int gribputbds ( USER_INPUT user_input, long lgrid_size,
45 short sDec_sc_fctr, float *pfData_Array,
46 BDS_HEAD_INPUT *pBDS_Head_Input, GRIB_HDR **pgrib_hdr,
47 char *errmsg)
48 #else
49 int gribputbds ( user_input, lgrid_size, sDec_sc_fctr, pfData_Array,
50 pBDS_Head_Input, pgrib_hdr, errmsg)
52 USER_INPUT user_input; /* input */
53 long lgrid_size; /* input */
54 short sDec_sc_fctr; /* input */
55 float *pfData_Array; /* input */
56 BDS_HEAD_INPUT *pBDS_Head_Input; /* output */
57 GRIB_HDR **pgrib_hdr; /* input & output */
58 char *errmsg; /* output */
60 #endif
64 * A.0 DEFAULT to Error Stat
66 char *func= "gribputbds";
67 long lBDS_length= 0; /* Rnd2_len bytes */
68 void *pvbstr= 0; /* remains null until after Inp2true_bds */
69 GRIB_HDR *gh; /* working var */
70 long newsize; /* working var */
71 void create_inpBDS();
72 int n, stat=1;
74 DPRINT1 ("\nEntering %s() ...\n",func);
77 * A.1 ASSIGN the GRIB_HDR pointer to local ptr;
78 * IF (it's null OR entire_msg is null) THEN
79 * RETURN error !errmsg filled
80 * ENDIF
82 gh= *pgrib_hdr;
83 if (!gh || !gh->entire_msg) {
84 DPRINT1( "%s: Grib Header or its Entire_msg is NULL\n", func);
85 sprintf(errmsg,"%s: Grib Header or its Entire_msg is NULL\n", func);
86 goto BYE;
91 * A.2 IF (the floating point array is null) THEN
93 if (pfData_Array == NULL) {
96 * A.2.1 IF (creating all sections mode)
97 * A.2.1.a THEN
98 * RETURN error !cannot go on w/o float array
100 if (! gh->shuffled) {
101 DPRINT1 ("%s: Float array is Null, cannot proceed;\n",func);
102 sprintf(errmsg,
103 "%s: Float array is Null, cannot proceed;\n",func);
104 goto BYE;
107 * A.2.1.b ELSE /# Create all sections mode #/
108 * !bds must already exist & has non-zero length, else error;
110 * IF (bds is null or bdslen <=0) THEN
111 * RETURN error !errmsg filled
112 * ELSE
113 * RETURN no error !bds already defined & has nonzero len
114 * ENDIF
116 else { /* create all mode */
117 if (gh->bds_ptr== NULL || gh->bds_len<=0)
119 DPRINT3 ( "%s: No FloatData avail and GribHdr "\
120 "has no BDS yet (ptr=%ld len=%ld)\n"
121 ,func,gh->bds_ptr,gh->bds_len);
122 sprintf(errmsg,
123 "%s: No FloatData avail and GribHdr has no BDS yet"\
124 "(ptr=%ld len=%ld)\n",func,gh->bds_ptr,gh->bds_len);
126 else {
127 stat= 0;
128 DPRINT2 ("%s: No need to proceed, GribHdr already "\
129 "has a BDS (len=%ld)\n", func, gh->bds_len);
132 * A.2.1 ENDIF
134 } /* if */
137 * A.2.2 RETURN with Stat !not decoding anything
139 goto BYE; /* quit */
142 * A.2 ENDIF !no float data
144 } /* no flt data */
147 DPRINT0 ("Need to pack Float Data & Store in (Char*);\n");
151 * A.3 FILL the BDS Head Input struct;
153 pBDS_Head_Input->Bin_sc_fctr = 0; /* INPUT NOT USED AT THIS TIME */
154 pBDS_Head_Input->fReference = 0.0; /* INPUT NOT USED AT THIS TIME */
155 pBDS_Head_Input->usBit_pack_num = user_input.usBit_pack_num;
156 /* #bits used for packing, 0=default*/
157 pBDS_Head_Input->ulGrid_size = (unsigned long) lgrid_size; /* Grid size */
158 pBDS_Head_Input->fPack_null = 1e10; /* Pack null value */
160 DPRINT3 ("\t bds_head_input->usBit_pack_num = %u\n" \
161 "\t bds_head_input->ulGrid_size = %u\n" \
162 "\t bds_head_input->fPack_null = %f\n",
163 pBDS_Head_Input->usBit_pack_num, pBDS_Head_Input->ulGrid_size,
164 pBDS_Head_Input->fPack_null );
168 * A.4 FUNCTION pack_spatial !packs data into binary bitstream
169 * IF (error in pack grid routine)
170 * THEN
171 * RETURN with error !errmsg filled
172 * ENDIF
174 if ((n= pack_spatial ( (long *)&(pBDS_Head_Input->ulGrid_size),
175 &(pBDS_Head_Input->usBit_pack_num),
176 &(pBDS_Head_Input->fPack_null),
177 pfData_Array,
178 (unsigned long **) &pvbstr,
179 sDec_sc_fctr, &lBDS_length, errmsg)) )
181 DPRINT2 ("%s: Pack Spatial returned err=%d\n", func, n);
182 upd_child_errmsg (func, errmsg);
183 goto BYE;
188 * A.5 CALCULATE new message length including new BDS
189 * (Include 4 bytes for EDS to avoid another realloc)
191 newsize= gh->msg_length + lBDS_length + 4;
195 * A.6 IF gribhdr's buffer is too small AND
196 * FUCTION Expand_gribhdr failed
197 * THEN
198 * RETURN with error !errmsg filled
199 * ENDIF
201 if (newsize > gh->abs_size
202 && Expand_gribhdr (gh, newsize, errmsg) !=0)
204 upd_child_errmsg (func, errmsg);
205 goto BYE;
210 * A.7 STORE bds & its info into Grib Hdr
211 * !copy true BDS struct over into entire message array
212 * !update message length also in Grib Hdr
213 * !save length of bds into Internal Struct too
215 gh->bds_ptr= gh->entire_msg + gh->msg_length;
216 memcpy ((void *) gh->bds_ptr, pvbstr, lBDS_length);
217 gh->bds_len = lBDS_length;
218 gh->msg_length += gh->bds_len;
220 /* Added by Todd Hutchinson, TASC 4/16/99*/
221 /* This stops a memory leak */
222 free(pvbstr);
224 pBDS_Head_Input->length = lBDS_length; /* update the Input struct too */
226 DPRINT2("%s: copied %ld bytes from pvbstr to BDSPTR\n", func, lBDS_length);
230 * A.8 CHANGE status to no errors
232 stat = 0;
234 BYE:
237 * A.9 RETURN w/ Stat
239 DPRINT2 ("Leaving %s, Stat=%d\n", func , stat);
240 return (stat);
243 * END OF FUNCTION