4 #include "dprints.h" /* for dprints */
5 #include "gribfuncs.h" /* prototypes */
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;
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
28 * (I&O) GRIB_HDR **pgrib_hdr;
29 * structure to hold encoded BDS and its info
31 * empty array, returned filled if error occurred;
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 ******************************************************************************
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
,
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 */
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 */
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
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
);
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)
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
);
103 "%s: Float array is Null, cannot proceed;\n",func
);
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
113 * RETURN no error !bds already defined & has nonzero len
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
);
123 "%s: No FloatData avail and GribHdr has no BDS yet"\
124 "(ptr=%ld len=%ld)\n",func
,gh
->bds_ptr
,gh
->bds_len
);
128 DPRINT2 ("%s: No need to proceed, GribHdr already "\
129 "has a BDS (len=%ld)\n", func
, gh
->bds_len
);
137 * A.2.2 RETURN with Stat !not decoding anything
142 * A.2 ENDIF !no float 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)
171 * RETURN with error !errmsg filled
174 if ((n
= pack_spatial ( (long *)&(pBDS_Head_Input
->ulGrid_size
),
175 &(pBDS_Head_Input
->usBit_pack_num
),
176 &(pBDS_Head_Input
->fPack_null
),
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
);
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
198 * RETURN with error !errmsg filled
201 if (newsize
> gh
->abs_size
202 && Expand_gribhdr (gh
, newsize
, errmsg
) !=0)
204 upd_child_errmsg (func
, errmsg
);
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 */
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
239 DPRINT2 ("Leaving %s, Stat=%d\n", func
, stat
);