/src/gdal/frmts/grib/degrib/g2clib/g2_getfld.c
Line | Count | Source |
1 | | #include <stdio.h> |
2 | | #include <stdlib.h> |
3 | | #include <assert.h> |
4 | | #include "grib2.h" |
5 | | |
6 | | g2int g2_getfld(unsigned char *cgrib,g2int cgrib_length, g2int ifldnum,g2int unpack,g2int expand, |
7 | | gribfield **gfld) |
8 | | //$$$ SUBPROGRAM DOCUMENTATION BLOCK |
9 | | // . . . . |
10 | | // SUBPROGRAM: g2_getfld |
11 | | // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-28 |
12 | | // |
13 | | // ABSTRACT: This subroutine returns all the metadata, template values, |
14 | | // Bit-map ( if applicable ), and the unpacked data for a given data |
15 | | // field. All of the information returned is stored in a gribfield |
16 | | // structure, which is defined in file grib2.h. |
17 | | // Users of this routine will need to include "grib2.h" in their source |
18 | | // code that calls this routine. Each component of the gribfield |
19 | | // struct is also described in the OUTPUT ARGUMENTS section below. |
20 | | // |
21 | | // Since there can be multiple data fields packed into a GRIB2 |
22 | | // message, the calling routine indicates which field is being requested |
23 | | // with the ifldnum argument. |
24 | | // |
25 | | // PROGRAM HISTORY LOG: |
26 | | // 2002-10-28 Gilbert |
27 | | // |
28 | | // USAGE: #include "grib2.h" |
29 | | // int g2_getfld(unsigned char *cgrib,g2int ifldnum,g2int unpack, |
30 | | // g2int expand,gribfield **gfld) |
31 | | // INPUT ARGUMENTS: |
32 | | // cgrib - Character pointer to the GRIB2 message |
33 | | // ifldnum - Specifies which field in the GRIB2 message to return. |
34 | | // unpack - Boolean value indicating whether to unpack bitmap/data field |
35 | | // 1 = unpack bitmap (if present) and data values |
36 | | // 0 = do not unpack bitmap and data values |
37 | | // expand - Boolean value indicating whether the data points should be |
38 | | // expanded to the correspond grid, if a bit-map is present. |
39 | | // 1 = if possible, expand data field to grid, inserting zero |
40 | | // values at gridpoints that are bitmapped out. |
41 | | // (SEE REMARKS2) |
42 | | // 0 = do not expand data field, leaving it an array of |
43 | | // consecutive data points for each "1" in the bitmap. |
44 | | // This argument is ignored if unpack == 0 OR if the |
45 | | // returned field does not contain a bit-map. |
46 | | // |
47 | | // OUTPUT ARGUMENT: |
48 | | // gribfield gfld; - pointer to structure gribfield containing |
49 | | // all decoded data for the data field. |
50 | | // |
51 | | // gfld->version = GRIB edition number ( currently 2 ) |
52 | | // gfld->discipline = Message Discipline ( see Code Table 0.0 ) |
53 | | // gfld->idsect = Contains the entries in the Identification |
54 | | // Section ( Section 1 ) |
55 | | // This element is a pointer to an array |
56 | | // that holds the data. |
57 | | // gfld->idsect[0] = Identification of originating Centre |
58 | | // ( see Common Code Table C-1 ) |
59 | | // 7 - US National Weather Service |
60 | | // gfld->idsect[1] = Identification of originating Sub-centre |
61 | | // gfld->idsect[2] = GRIB Master Tables Version Number |
62 | | // ( see Code Table 1.0 ) |
63 | | // 0 - Experimental |
64 | | // 1 - Initial operational version number |
65 | | // gfld->idsect[3] = GRIB Local Tables Version Number |
66 | | // ( see Code Table 1.1 ) |
67 | | // 0 - Local tables not used |
68 | | // 1-254 - Number of local tables version used |
69 | | // gfld->idsect[4] = Significance of Reference Time (Code Table 1.2) |
70 | | // 0 - Analysis |
71 | | // 1 - Start of forecast |
72 | | // 2 - Verifying time of forecast |
73 | | // 3 - Observation time |
74 | | // gfld->idsect[5] = Year ( 4 digits ) |
75 | | // gfld->idsect[6] = Month |
76 | | // gfld->idsect[7) = Day |
77 | | // gfld->idsect[8] = Hour |
78 | | // gfld->idsect[9] = Minute |
79 | | // gfld->idsect[10] = Second |
80 | | // gfld->idsect[11] = Production status of processed data |
81 | | // ( see Code Table 1.3 ) |
82 | | // 0 - Operational products |
83 | | // 1 - Operational test products |
84 | | // 2 - Research products |
85 | | // 3 - Re-analysis products |
86 | | // gfld->idsect[12] = Type of processed data ( see Code Table 1.4 ) |
87 | | // 0 - Analysis products |
88 | | // 1 - Forecast products |
89 | | // 2 - Analysis and forecast products |
90 | | // 3 - Control forecast products |
91 | | // 4 - Perturbed forecast products |
92 | | // 5 - Control and perturbed forecast products |
93 | | // 6 - Processed satellite observations |
94 | | // 7 - Processed radar observations |
95 | | // gfld->idsectlen = Number of elements in gfld->idsect[]. |
96 | | // gfld->local = Pointer to character array containing contents |
97 | | // of Local Section 2, if included |
98 | | // gfld->locallen = length of array gfld->local[] |
99 | | // gfld->ifldnum = field number within GRIB message |
100 | | // gfld->griddef = Source of grid definition (see Code Table 3.0) |
101 | | // 0 - Specified in Code table 3.1 |
102 | | // 1 - Predetermined grid Defined by originating centre |
103 | | // gfld->ngrdpts = Number of grid points in the defined grid. |
104 | | // gfld->numoct_opt = Number of octets needed for each |
105 | | // additional grid points definition. |
106 | | // Used to define number of |
107 | | // points in each row ( or column ) for |
108 | | // non-regular grids. |
109 | | // = 0, if using regular grid. |
110 | | // gfld->interp_opt = Interpretation of list for optional points |
111 | | // definition. (Code Table 3.11) |
112 | | // gfld->igdtnum = Grid Definition Template Number (Code Table 3.1) |
113 | | // gfld->igdtmpl = Contains the data values for the specified Grid |
114 | | // Definition Template ( NN=gfld->igdtnum ). Each |
115 | | // element of this integer array contains an entry (in |
116 | | // the order specified) of Grid Definition Template 3.NN |
117 | | // This element is a pointer to an array |
118 | | // that holds the data. |
119 | | // gfld->igdtlen = Number of elements in gfld->igdtmpl[]. i.e. number of |
120 | | // entries in Grid Definition Template 3.NN |
121 | | // ( NN=gfld->igdtnum ). |
122 | | // gfld->list_opt = (Used if gfld->numoct_opt .ne. 0) This array |
123 | | // contains the number of grid points contained in |
124 | | // each row ( or column ). (part of Section 3) |
125 | | // This element is a pointer to an array |
126 | | // that holds the data. This pointer is nullified |
127 | | // if gfld->numoct_opt=0. |
128 | | // gfld->num_opt = (Used if gfld->numoct_opt .ne. 0) |
129 | | // The number of entries |
130 | | // in array ideflist. i.e. number of rows ( or columns ) |
131 | | // for which optional grid points are defined. This value |
132 | | // is set to zero, if gfld->numoct_opt=0. |
133 | | // gfdl->ipdtnum = Product Definition Template Number(see Code Table 4.0) |
134 | | // gfld->ipdtmpl = Contains the data values for the specified Product |
135 | | // Definition Template ( N=gfdl->ipdtnum ). Each element |
136 | | // of this integer array contains an entry (in the |
137 | | // order specified) of Product Definition Template 4.N. |
138 | | // This element is a pointer to an array |
139 | | // that holds the data. |
140 | | // gfld->ipdtlen = Number of elements in gfld->ipdtmpl[]. i.e. number of |
141 | | // entries in Product Definition Template 4.N |
142 | | // ( N=gfdl->ipdtnum ). |
143 | | // gfld->coord_list = Real array containing floating point values |
144 | | // intended to document the vertical discretisation |
145 | | // associated to model data on hybrid coordinate |
146 | | // vertical levels. (part of Section 4) |
147 | | // This element is a pointer to an array |
148 | | // that holds the data. |
149 | | // gfld->num_coord = number of values in array gfld->coord_list[]. |
150 | | // gfld->ndpts = Number of data points unpacked and returned. |
151 | | // gfld->idrtnum = Data Representation Template Number |
152 | | // ( see Code Table 5.0) |
153 | | // gfld->idrtmpl = Contains the data values for the specified Data |
154 | | // Representation Template ( N=gfld->idrtnum ). Each |
155 | | // element of this integer array contains an entry |
156 | | // (in the order specified) of Product Definition |
157 | | // Template 5.N. |
158 | | // This element is a pointer to an array |
159 | | // that holds the data. |
160 | | // gfld->idrtlen = Number of elements in gfld->idrtmpl[]. i.e. number |
161 | | // of entries in Data Representation Template 5.N |
162 | | // ( N=gfld->idrtnum ). |
163 | | // gfld->unpacked = logical value indicating whether the bitmap and |
164 | | // data values were unpacked. If false, |
165 | | // gfld->bmap and gfld->fld pointers are nullified. |
166 | | // gfld->expanded = Logical value indicating whether the data field |
167 | | // was expanded to the grid in the case where a |
168 | | // bit-map is present. If true, the data points in |
169 | | // gfld->fld match the grid points and zeros were |
170 | | // inserted at grid points where data was bit-mapped |
171 | | // out. If false, the data values in gfld->fld were |
172 | | // not expanded to the grid and are just a consecutive |
173 | | // array of data points corresponding to each value of |
174 | | // "1" in gfld->bmap. |
175 | | // gfld->ibmap = Bitmap indicator ( see Code Table 6.0 ) |
176 | | // 0 = bitmap applies and is included in Section 6. |
177 | | // 1-253 = Predefined bitmap applies |
178 | | // 254 = Previously defined bitmap applies to this field |
179 | | // 255 = Bit map does not apply to this product. |
180 | | // gfld->bmap = integer array containing decoded bitmap, |
181 | | // if gfld->ibmap=0 or gfld->ibap=254. Otherwise nullified |
182 | | // This element is a pointer to an array |
183 | | // that holds the data. |
184 | | // gfld->fld = Array of gfld->ndpts unpacked data points. |
185 | | // This element is a pointer to an array |
186 | | // that holds the data. |
187 | | // |
188 | | // |
189 | | // RETURN VALUES: |
190 | | // ierr - Error return code. |
191 | | // 0 = no error |
192 | | // 1 = Beginning characters "GRIB" not found. |
193 | | // 2 = GRIB message is not Edition 2. |
194 | | // 3 = The data field request number was not positive. |
195 | | // 4 = End string "7777" found, but not where expected. |
196 | | // 6 = GRIB message did not contain the requested number of |
197 | | // data fields. |
198 | | // 7 = End string "7777" not found at end of message. |
199 | | // 8 = Unrecognized Section encountered. |
200 | | // 9 = Data Representation Template 5.NN not yet implemented. |
201 | | // 15 = Error unpacking Section 1. |
202 | | // 16 = Error unpacking Section 2. |
203 | | // 10 = Error unpacking Section 3. |
204 | | // 11 = Error unpacking Section 4. |
205 | | // 12 = Error unpacking Section 5. |
206 | | // 13 = Error unpacking Section 6. |
207 | | // 14 = Error unpacking Section 7. |
208 | | // 17 = Previous bitmap specified, yet none exists. |
209 | | // |
210 | | // REMARKS: Note that struct gribfield is allocated by this routine and it |
211 | | // also contains pointers to many arrays of data that were allocated |
212 | | // during decoding. Users are encouraged to free up this memory, |
213 | | // when it is no longer needed, by an explicit call to routine g2_free. |
214 | | // EXAMPLE: |
215 | | // #include "grib2.h" |
216 | | // gribfield *gfld; |
217 | | // ret=g2_getfld(cgrib,1,1,1,&gfld); |
218 | | // ... |
219 | | // g2_free(gfld); |
220 | | // |
221 | | // Routine g2_info can be used to first determine |
222 | | // how many data fields exist in a given GRIB message. |
223 | | // |
224 | | // REMARKS2: It may not always be possible to expand a bit-mapped data field. |
225 | | // If a pre-defined bit-map is used and not included in the GRIB2 |
226 | | // message itself, this routine would not have the necessary |
227 | | // information to expand the data. In this case, gfld->expanded would |
228 | | // would be set to 0 (false), regardless of the value of input |
229 | | // argument expand. |
230 | | // |
231 | | // ATTRIBUTES: |
232 | | // LANGUAGE: C |
233 | | // MACHINE: |
234 | | // |
235 | | //$$$ |
236 | 15.8k | { |
237 | | |
238 | 15.8k | g2int have3,have4,have5,have6,have7,ierr,jerr; |
239 | 15.8k | g2int numfld,j,n,istart,iofst,ipos; |
240 | 15.8k | g2int disc,ver,lensec0,lengrib,lensec,isecnum; |
241 | 15.8k | g2int *igds; |
242 | 15.8k | g2int *bmpsave; |
243 | 15.8k | g2float *newfld; |
244 | 15.8k | gribfield *lgfld; |
245 | 15.8k | int iofst_last_sect6 = -1; |
246 | | |
247 | 15.8k | have3=0; |
248 | 15.8k | have4=0; |
249 | 15.8k | have5=0; |
250 | 15.8k | have6=0; |
251 | 15.8k | have7=0; |
252 | 15.8k | ierr=0; |
253 | 15.8k | numfld=0; |
254 | | |
255 | 15.8k | lgfld=(gribfield *)malloc(sizeof(gribfield)); |
256 | 15.8k | *gfld=lgfld; |
257 | | |
258 | 15.8k | lgfld->locallen=0; |
259 | 15.8k | lgfld->idsect=0; |
260 | 15.8k | lgfld->local=0; |
261 | 15.8k | lgfld->list_opt=0; |
262 | 15.8k | lgfld->igdtmpl=0; |
263 | 15.8k | lgfld->ipdtmpl=0; |
264 | 15.8k | lgfld->idrtmpl=0; |
265 | 15.8k | lgfld->coord_list=0; |
266 | 15.8k | lgfld->bmap=0; |
267 | 15.8k | lgfld->fld=0; |
268 | 15.8k | lgfld->ngrdpts=0; |
269 | | // |
270 | | // Check for valid request number |
271 | | // |
272 | 15.8k | if (ifldnum <= 0) { |
273 | 0 | printf("g2_getfld: Request for field number must be positive.\n"); |
274 | 0 | ierr=3; |
275 | 0 | return(ierr); |
276 | 0 | } |
277 | | // |
278 | | // Check for beginning of GRIB message in the first 100 bytes |
279 | | // |
280 | 15.8k | istart=-1; |
281 | 15.8k | for (j=0;j<100;j++) { |
282 | 15.8k | if (cgrib[j]=='G' && cgrib[j+1]=='R' &&cgrib[j+2]=='I' && |
283 | 15.8k | cgrib[j+3]=='B') { |
284 | 15.8k | istart=j; |
285 | 15.8k | break; |
286 | 15.8k | } |
287 | 15.8k | } |
288 | 15.8k | if (istart == -1) { |
289 | 0 | printf("g2_getfld: Beginning characters GRIB not found.\n"); |
290 | 0 | ierr=1; |
291 | 0 | return(ierr); |
292 | 0 | } |
293 | | // |
294 | | // Unpack Section 0 - Indicator Section |
295 | | // |
296 | 15.8k | iofst=8*(istart+6); |
297 | 15.8k | gbit(cgrib,&disc,iofst,8); // Discipline |
298 | 15.8k | iofst=iofst+8; |
299 | 15.8k | gbit(cgrib,&ver,iofst,8); // GRIB edition number |
300 | 15.8k | iofst=iofst+8; |
301 | 15.8k | iofst=iofst+32; |
302 | 15.8k | gbit(cgrib,&lengrib,iofst,32); // Length of GRIB message |
303 | 15.8k | iofst=iofst+32; |
304 | 15.8k | lensec0=16; |
305 | 15.8k | ipos=istart+lensec0; |
306 | | // |
307 | | // Currently handles only GRIB Edition 2. |
308 | | // |
309 | 15.8k | if (ver != 2) { |
310 | 0 | printf("g2_getfld: can only decode GRIB edition 2.\n"); |
311 | 0 | ierr=2; |
312 | 0 | return(ierr); |
313 | 0 | } |
314 | | // |
315 | | // Loop through the remaining sections keeping track of the |
316 | | // length of each. Also keep the latest Grid Definition Section info. |
317 | | // Unpack the requested field number. |
318 | | // |
319 | 92.4k | for (;;) { |
320 | | // Check to see if we are at end of GRIB message |
321 | 92.4k | if (cgrib[ipos]=='7' && cgrib[ipos+1]=='7' && cgrib[ipos+2]=='7' && |
322 | 0 | cgrib[ipos+3]=='7') { |
323 | 0 | ipos=ipos+4; |
324 | | // If end of GRIB message not where expected, issue error |
325 | 0 | if (ipos != (istart+lengrib)) { |
326 | 0 | printf("g2_getfld: '7777' found, but not where expected.\n"); |
327 | 0 | ierr=4; |
328 | 0 | return(ierr); |
329 | 0 | } |
330 | 0 | break; |
331 | 0 | } |
332 | | // Get length of Section and Section number |
333 | | //iofst=(ipos-1)*8; |
334 | 92.4k | iofst=ipos*8; |
335 | 92.4k | gbit(cgrib,&lensec,iofst,32); // Get Length of Section |
336 | 92.4k | iofst=iofst+32; |
337 | 92.4k | gbit(cgrib,&isecnum,iofst,8); // Get Section number |
338 | 92.4k | iofst=iofst+8; |
339 | | //printf(" lensec= %ld secnum= %ld \n",lensec,isecnum); |
340 | | // |
341 | | // Check to see if section number is valid |
342 | | // |
343 | 92.4k | if ( isecnum<1 || isecnum>7 ) { |
344 | 0 | printf("g2_getfld: Unrecognized Section Encountered=%d\n",isecnum); |
345 | 0 | ierr=8; |
346 | 0 | return(ierr); |
347 | 0 | } |
348 | | // |
349 | | // If found Section 1, decode elements in Identification Section |
350 | | // |
351 | 92.4k | if (isecnum == 1) { |
352 | 15.8k | iofst=iofst-40; // reset offset to beginning of section |
353 | 15.8k | jerr=g2_unpack1(cgrib,&iofst,&lgfld->idsect,&lgfld->idsectlen); |
354 | 15.8k | if (jerr !=0 ) { |
355 | 0 | ierr=15; |
356 | 0 | return(ierr); |
357 | 0 | } |
358 | 15.8k | } |
359 | | // |
360 | | // If found Section 2, Grab local section |
361 | | // Save in case this is the latest one before the requested field. |
362 | | // |
363 | 92.4k | if (isecnum == 2) { |
364 | 6.94k | iofst=iofst-40; // reset offset to beginning of section |
365 | 6.94k | if (lgfld->local!=0) free(lgfld->local); |
366 | 6.94k | jerr=g2_unpack2(cgrib,&iofst,&lgfld->locallen,&lgfld->local); |
367 | 6.94k | if (jerr != 0) { |
368 | 0 | ierr=16; |
369 | 0 | return(ierr); |
370 | 0 | } |
371 | 6.94k | } |
372 | | // |
373 | | // If found Section 3, unpack the GDS info using the |
374 | | // appropriate template. Save in case this is the latest |
375 | | // grid before the requested field. |
376 | | // |
377 | 92.4k | if (isecnum == 3) { |
378 | 15.8k | iofst=iofst-40; // reset offset to beginning of section |
379 | 15.8k | if (lgfld->igdtmpl!=0) free(lgfld->igdtmpl); |
380 | 15.8k | if (lgfld->list_opt!=0) free(lgfld->list_opt); |
381 | 15.8k | jerr=g2_unpack3(cgrib,cgrib_length,&iofst,&igds,&lgfld->igdtmpl, |
382 | 15.8k | &lgfld->igdtlen,&lgfld->list_opt,&lgfld->num_opt); |
383 | 15.8k | if (jerr == 0) { |
384 | 15.8k | have3=1; |
385 | 15.8k | lgfld->griddef=igds[0]; |
386 | 15.8k | lgfld->ngrdpts=igds[1]; |
387 | 15.8k | lgfld->numoct_opt=igds[2]; |
388 | 15.8k | lgfld->interp_opt=igds[3]; |
389 | 15.8k | lgfld->igdtnum=igds[4]; |
390 | 15.8k | free(igds); |
391 | 15.8k | } |
392 | 24 | else { |
393 | 24 | ierr=10; |
394 | 24 | free( igds ); |
395 | 24 | return(ierr); |
396 | 24 | } |
397 | 15.8k | } |
398 | | // |
399 | | // If found Section 4, check to see if this field is the |
400 | | // one requested. |
401 | | // |
402 | 92.4k | if (isecnum == 4) { |
403 | 15.8k | numfld=numfld+1; |
404 | 15.8k | if (numfld == ifldnum) { |
405 | 15.8k | lgfld->discipline=disc; |
406 | 15.8k | lgfld->version=ver; |
407 | 15.8k | lgfld->ifldnum=ifldnum; |
408 | 15.8k | lgfld->unpacked=unpack; |
409 | 15.8k | lgfld->expanded=0; |
410 | 15.8k | iofst=iofst-40; // reset offset to beginning of section |
411 | 15.8k | jerr=g2_unpack4(cgrib,cgrib_length,&iofst,&lgfld->ipdtnum, |
412 | 15.8k | &lgfld->ipdtmpl,&lgfld->ipdtlen,&lgfld->coord_list, |
413 | 15.8k | &lgfld->num_coord); |
414 | 15.8k | if (jerr == 0 || jerr == 5 ) |
415 | 15.8k | have4=1; |
416 | 0 | else { |
417 | 0 | ierr=11; |
418 | 0 | return(ierr); |
419 | 0 | } |
420 | 15.8k | } |
421 | 15.8k | } |
422 | | // |
423 | | // If found Section 5, check to see if this field is the |
424 | | // one requested. |
425 | | // |
426 | 92.4k | if (isecnum == 5 && numfld == ifldnum) { |
427 | 15.8k | iofst=iofst-40; // reset offset to beginning of section |
428 | 15.8k | jerr=g2_unpack5(cgrib,cgrib_length,&iofst,&lgfld->ndpts,&lgfld->idrtnum, |
429 | 15.8k | &lgfld->idrtmpl,&lgfld->idrtlen); |
430 | 15.8k | if (jerr == 0) |
431 | 15.8k | have5=1; |
432 | 0 | else { |
433 | 0 | ierr=12; |
434 | 0 | return(ierr); |
435 | 0 | } |
436 | 15.8k | } |
437 | | // |
438 | | // If found Section 6, Unpack bitmap. |
439 | | // Save in case this is the latest |
440 | | // bitmap before the requested field. |
441 | | // |
442 | 92.4k | if (isecnum == 6) { |
443 | 15.8k | if (numfld==ifldnum && unpack) { // unpack bitmap |
444 | 6.44k | iofst=iofst-40; // reset offset to beginning of section |
445 | 6.44k | bmpsave=lgfld->bmap; // save pointer to previous bitmap |
446 | 6.44k | jerr=g2_unpack6(cgrib,cgrib_length,&iofst,lgfld->ngrdpts,&lgfld->ibmap, |
447 | 6.44k | &lgfld->bmap); |
448 | 6.44k | if (jerr == 0) { |
449 | 6.44k | have6=1; |
450 | 6.44k | if (lgfld->ibmap == 254) // use previously specified bitmap |
451 | 28 | if( bmpsave!=0 ) |
452 | 0 | lgfld->bmap=bmpsave; |
453 | 28 | else { |
454 | | |
455 | 28 | if( ifldnum > 1 && iofst_last_sect6 > 0 ) |
456 | 0 | { |
457 | | /* Unpack the last valid section 6 we read before */ |
458 | 0 | int iofst_backup = iofst; |
459 | 0 | iofst = iofst_last_sect6 - 40; |
460 | 0 | jerr=g2_unpack6(cgrib,cgrib_length,&iofst,lgfld->ngrdpts,&lgfld->ibmap, |
461 | 0 | &lgfld->bmap); |
462 | 0 | lgfld->ibmap = 254; |
463 | 0 | iofst = iofst_backup; |
464 | 0 | if( jerr != 0 ) { |
465 | 0 | ierr=13; |
466 | 0 | return(ierr); |
467 | 0 | } |
468 | 0 | } |
469 | 28 | else |
470 | 28 | { |
471 | 28 | printf("g2_getfld: Prev bit-map specified, but none exist.\n"); |
472 | 28 | ierr=17; |
473 | 28 | return(ierr); |
474 | 28 | } |
475 | 28 | } |
476 | 6.42k | else // get rid of it |
477 | 6.42k | if( bmpsave!=0 ) free(bmpsave); |
478 | 6.44k | } |
479 | 0 | else { |
480 | 0 | ierr=13; |
481 | 0 | return(ierr); |
482 | 0 | } |
483 | 6.44k | } |
484 | 9.35k | else { // do not unpack bitmap |
485 | 9.35k | gbit(cgrib,&lgfld->ibmap,iofst,8); // Get BitMap Indicator |
486 | 9.35k | have6=1; |
487 | 9.35k | if( lgfld->ibmap == 0 ) { |
488 | | /* Save the offset of this section in case we might need to unpack it later for a later subfield */ |
489 | 0 | iofst_last_sect6 = iofst; |
490 | 0 | } |
491 | 9.35k | } |
492 | 15.8k | } |
493 | | // |
494 | | // If found Section 7, check to see if this field is the |
495 | | // one requested. |
496 | | // |
497 | 92.4k | if (isecnum==7 && numfld==ifldnum && unpack) { |
498 | 6.42k | iofst=iofst-40; // reset offset to beginning of section |
499 | | |
500 | | /* If expand is requested and we cannot do it, then early exit */ |
501 | | /* to avoid useless operations */ |
502 | | /* Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2183 */ |
503 | | /* See grib2api.c : */ |
504 | | /* Check if NCEP had problems expanding the data. If so we currently |
505 | | * abort. May need to revisit this behavior. */ |
506 | 6.42k | if( expand ) |
507 | 6.42k | { |
508 | 6.42k | if ( lgfld->ibmap != 255 && lgfld->bmap != 0 ) |
509 | 0 | { |
510 | 0 | if( lgfld->ngrdpts < lgfld->ndpts ) |
511 | 0 | { |
512 | | /* There are more points in the data section than in */ |
513 | | /* the bitmap, that doesn't make sense (bitmap only */ |
514 | | /* makes sense if it saves the encoding of points in */ |
515 | | /* the data section) */ |
516 | 0 | ierr=14; |
517 | 0 | return(ierr); |
518 | 0 | } |
519 | 0 | } |
520 | 6.42k | else if( lgfld->ngrdpts != lgfld->ndpts ) |
521 | 368 | { |
522 | 368 | ierr=14; |
523 | 368 | return(ierr); |
524 | 368 | } |
525 | 6.42k | } |
526 | | |
527 | 6.05k | jerr=g2_unpack7(cgrib,cgrib_length,&iofst,lgfld->igdtnum,lgfld->igdtmpl, |
528 | 6.05k | lgfld->idrtnum,lgfld->idrtmpl,lgfld->ndpts, |
529 | 6.05k | &lgfld->fld); |
530 | 6.05k | if (jerr == 0) { |
531 | 5.67k | have7=1; |
532 | | // If bitmap is used with this field, expand data field |
533 | | // to grid, if possible. |
534 | 5.67k | if ( lgfld->ibmap != 255 && lgfld->bmap != 0 ) { |
535 | 0 | if ( expand == 1 ) { |
536 | 0 | n=0; |
537 | 0 | newfld=(g2float *)calloc(lgfld->ngrdpts,sizeof(g2float)); |
538 | 0 | for (j=0;j<lgfld->ngrdpts;j++) { |
539 | 0 | if (lgfld->bmap[j]==1) |
540 | 0 | { |
541 | 0 | if( n >= lgfld->ndpts ) |
542 | 0 | { |
543 | 0 | printf("g2_getfld: overflow of lgfld->fld array\n"); |
544 | 0 | ierr=14; |
545 | 0 | free(newfld); |
546 | 0 | return(ierr); |
547 | 0 | } |
548 | 0 | newfld[j]=lgfld->fld[n++]; |
549 | 0 | } |
550 | 0 | } |
551 | 0 | free(lgfld->fld); |
552 | 0 | lgfld->fld=newfld; |
553 | 0 | lgfld->expanded=1; |
554 | 0 | } |
555 | 0 | else { |
556 | 0 | lgfld->expanded=0; |
557 | 0 | } |
558 | 0 | } |
559 | 5.67k | else { |
560 | 5.67k | if( lgfld->ngrdpts != lgfld->ndpts ) |
561 | 0 | { |
562 | | /* Added by E. Rouault to fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2070 */ |
563 | 0 | lgfld->expanded=0; |
564 | 0 | } |
565 | 5.67k | else |
566 | 5.67k | { |
567 | 5.67k | lgfld->expanded=1; |
568 | 5.67k | } |
569 | 5.67k | } |
570 | 5.67k | } |
571 | 380 | else { |
572 | 380 | printf("g2_getfld: return from g2_unpack7 = %d \n",(int)jerr); |
573 | 380 | ierr=14; |
574 | 380 | return(ierr); |
575 | 380 | } |
576 | 6.05k | } |
577 | | // |
578 | | // Check to see if we read pass the end of the GRIB |
579 | | // message and missed the terminator string '7777'. |
580 | | // |
581 | 91.6k | ipos=ipos+lensec; // Update beginning of section pointer |
582 | 91.6k | if (ipos > (istart+lengrib)) { |
583 | 0 | printf("g2_getfld: '7777' not found at end of GRIB message.\n"); |
584 | 0 | ierr=7; |
585 | 0 | return(ierr); |
586 | 0 | } |
587 | | // |
588 | | // If unpacking requested, return when all sections have been |
589 | | // processed |
590 | | // |
591 | 91.6k | if (unpack && have3 && have4 && have5 && have6 && have7) |
592 | 5.67k | return(ierr); |
593 | | // |
594 | | // If unpacking is not requested, return when sections |
595 | | // 3 through 6 have been processed |
596 | | // |
597 | 85.9k | if ((! unpack) && have3 && have4 && have5 && have6) |
598 | 9.35k | return(ierr); |
599 | | |
600 | 85.9k | } |
601 | | |
602 | | // |
603 | | // If exited from above loop, the end of the GRIB message was reached |
604 | | // before the requested field was found. |
605 | | // |
606 | 0 | printf("g2_getfld: GRIB message contained %d different fields.\n",numfld); |
607 | 0 | printf("g2_getfld: The request was for field %d.\n",ifldnum); |
608 | 0 | ierr=6; |
609 | |
|
610 | 0 | return(ierr); |
611 | | |
612 | 15.8k | } |