LCOV - code coverage report
Current view: top level - frmts/grib/degrib/g2clib - g2_getfld.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 137 195 70.3 %
Date: 2024-05-06 13:02:59 Functions: 1 1 100.0 %

          Line data    Source code
       1             : #include <stdio.h>
       2             : #include <stdlib.h>
       3             : #include <assert.h>
       4             : #include "grib2.h"
       5             : 
       6         460 : 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             : {
     237             : 
     238             :       g2int have3,have4,have5,have6,have7,ierr,jerr;
     239             :       g2int numfld,j,n,istart,iofst,ipos;
     240             :       g2int disc,ver,lensec0,lengrib,lensec,isecnum;
     241             :       g2int  *igds;
     242             :       g2int *bmpsave;
     243             :       g2float *newfld;
     244             :       gribfield  *lgfld;
     245         460 :       int iofst_last_sect6 = -1;
     246             : 
     247         460 :       have3=0;
     248         460 :       have4=0;
     249         460 :       have5=0;
     250         460 :       have6=0;
     251         460 :       have7=0;
     252         460 :       ierr=0;
     253         460 :       numfld=0;
     254             : 
     255         460 :       lgfld=(gribfield *)malloc(sizeof(gribfield));
     256         460 :       *gfld=lgfld;
     257             : 
     258         460 :       lgfld->locallen=0;
     259         460 :       lgfld->idsect=0;
     260         460 :       lgfld->local=0;
     261         460 :       lgfld->list_opt=0;
     262         460 :       lgfld->igdtmpl=0;
     263         460 :       lgfld->ipdtmpl=0;
     264         460 :       lgfld->idrtmpl=0;
     265         460 :       lgfld->coord_list=0;
     266         460 :       lgfld->bmap=0;
     267         460 :       lgfld->fld=0;
     268         460 :       lgfld->ngrdpts=0;
     269             : //
     270             : //  Check for valid request number
     271             : //
     272         460 :       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             :       }
     277             : //
     278             : //  Check for beginning of GRIB message in the first 100 bytes
     279             : //
     280         460 :       istart=-1;
     281         460 :       for (j=0;j<100;j++) {
     282         460 :         if (cgrib[j]=='G' && cgrib[j+1]=='R' &&cgrib[j+2]=='I' &&
     283         460 :             cgrib[j+3]=='B') {
     284         460 :           istart=j;
     285         460 :           break;
     286             :         }
     287             :       }
     288         460 :       if (istart == -1) {
     289           0 :         printf("g2_getfld:  Beginning characters GRIB not found.\n");
     290           0 :         ierr=1;
     291           0 :         return(ierr);
     292             :       }
     293             : //
     294             : //  Unpack Section 0 - Indicator Section
     295             : //
     296         460 :       iofst=8*(istart+6);
     297         460 :       gbit(cgrib,&disc,iofst,8);     // Discipline
     298         460 :       iofst=iofst+8;
     299         460 :       gbit(cgrib,&ver,iofst,8);     // GRIB edition number
     300         460 :       iofst=iofst+8;
     301         460 :       iofst=iofst+32;
     302         460 :       gbit(cgrib,&lengrib,iofst,32);        // Length of GRIB message
     303         460 :       iofst=iofst+32;
     304         460 :       lensec0=16;
     305         460 :       ipos=istart+lensec0;
     306             : //
     307             : //  Currently handles only GRIB Edition 2.
     308             : //
     309         460 :       if (ver != 2) {
     310           0 :         printf("g2_getfld: can only decode GRIB edition 2.\n");
     311           0 :         ierr=2;
     312           0 :         return(ierr);
     313             :       }
     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             :       for (;;) {
     320             :         //    Check to see if we are at end of GRIB message
     321        2893 :         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             :           }
     330           0 :           break;
     331             :         }
     332             :         //     Get length of Section and Section number
     333             :         //iofst=(ipos-1)*8;
     334        2893 :         iofst=ipos*8;
     335        2893 :         gbit(cgrib,&lensec,iofst,32);        // Get Length of Section
     336        2893 :         iofst=iofst+32;
     337        2893 :         gbit(cgrib,&isecnum,iofst,8);         // Get Section number
     338        2893 :         iofst=iofst+8;
     339             :         //printf(" lensec= %ld    secnum= %ld \n",lensec,isecnum);
     340             :         //
     341             :         //  Check to see if section number is valid
     342             :         //
     343        2893 :         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             :         }
     348             :         //
     349             :         //   If found Section 1, decode elements in Identification Section
     350             :         //
     351        2893 :         if (isecnum == 1) {
     352         460 :           iofst=iofst-40;       // reset offset to beginning of section
     353         460 :           jerr=g2_unpack1(cgrib,&iofst,&lgfld->idsect,&lgfld->idsectlen);
     354         460 :           if (jerr !=0 ) {
     355           0 :             ierr=15;
     356           0 :             return(ierr);
     357             :           }
     358             :         }
     359             :         //
     360             :         //   If found Section 2, Grab local section
     361             :         //   Save in case this is the latest one before the requested field.
     362             :         //
     363        2893 :         if (isecnum == 2) {
     364         424 :           iofst=iofst-40;       // reset offset to beginning of section
     365         424 :           if (lgfld->local!=0) free(lgfld->local);
     366         424 :           jerr=g2_unpack2(cgrib,&iofst,&lgfld->locallen,&lgfld->local);
     367         424 :           if (jerr != 0) {
     368           0 :             ierr=16;
     369           0 :             return(ierr);
     370             :           }
     371             :         }
     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        2893 :         if (isecnum == 3) {
     378         460 :           iofst=iofst-40;       // reset offset to beginning of section
     379         460 :           if (lgfld->igdtmpl!=0) free(lgfld->igdtmpl);
     380         460 :           if (lgfld->list_opt!=0) free(lgfld->list_opt);
     381         460 :           jerr=g2_unpack3(cgrib,cgrib_length,&iofst,&igds,&lgfld->igdtmpl,
     382             :                           &lgfld->igdtlen,&lgfld->list_opt,&lgfld->num_opt);
     383         460 :           if (jerr == 0) {
     384         460 :             have3=1;
     385         460 :             lgfld->griddef=igds[0];
     386         460 :             lgfld->ngrdpts=igds[1];
     387         460 :             lgfld->numoct_opt=igds[2];
     388         460 :             lgfld->interp_opt=igds[3];
     389         460 :             lgfld->igdtnum=igds[4];
     390         460 :             free(igds);
     391             :           }
     392             :           else {
     393           0 :             ierr=10;
     394           0 :             free( igds );
     395           0 :             return(ierr);
     396             :           }
     397             :         }
     398             :         //
     399             :         //   If found Section 4, check to see if this field is the
     400             :         //   one requested.
     401             :         //
     402        2893 :         if (isecnum == 4) {
     403         463 :           numfld=numfld+1;
     404         463 :           if (numfld == ifldnum) {
     405         460 :             lgfld->discipline=disc;
     406         460 :             lgfld->version=ver;
     407         460 :             lgfld->ifldnum=ifldnum;
     408         460 :             lgfld->unpacked=unpack;
     409         460 :             lgfld->expanded=0;
     410         460 :             iofst=iofst-40;       // reset offset to beginning of section
     411         460 :             jerr=g2_unpack4(cgrib,cgrib_length,&iofst,&lgfld->ipdtnum,
     412             :                             &lgfld->ipdtmpl,&lgfld->ipdtlen,&lgfld->coord_list,
     413             :                             &lgfld->num_coord);
     414         460 :             if (jerr == 0 || jerr == 5 )
     415         460 :               have4=1;
     416             :             else {
     417           0 :               ierr=11;
     418           0 :               return(ierr);
     419             :             }
     420             :           }
     421             :         }
     422             :         //
     423             :         //   If found Section 5, check to see if this field is the
     424             :         //   one requested.
     425             :         //
     426        2893 :         if (isecnum == 5 && numfld == ifldnum) {
     427         460 :           iofst=iofst-40;       // reset offset to beginning of section
     428         460 :           jerr=g2_unpack5(cgrib,cgrib_length,&iofst,&lgfld->ndpts,&lgfld->idrtnum,
     429             :                           &lgfld->idrtmpl,&lgfld->idrtlen);
     430         460 :           if (jerr == 0)
     431         460 :             have5=1;
     432             :           else {
     433           0 :             ierr=12;
     434           0 :             return(ierr);
     435             :           }
     436             :         }
     437             :         //
     438             :         //   If found Section 6, Unpack bitmap.
     439             :         //   Save in case this is the latest
     440             :         //   bitmap before the requested field.
     441             :         //
     442        2893 :         if (isecnum == 6) {
     443         463 :           if (numfld==ifldnum && unpack) {   // unpack bitmap
     444         157 :             iofst=iofst-40;           // reset offset to beginning of section
     445         157 :             bmpsave=lgfld->bmap;      // save pointer to previous bitmap
     446         157 :             jerr=g2_unpack6(cgrib,cgrib_length,&iofst,lgfld->ngrdpts,&lgfld->ibmap,
     447             :                          &lgfld->bmap);
     448         157 :             if (jerr == 0) {
     449         157 :               have6=1;
     450         157 :               if (lgfld->ibmap == 254)     // use previously specified bitmap
     451           1 :                  if( bmpsave!=0 )
     452           0 :                     lgfld->bmap=bmpsave;
     453             :                  else {
     454             : 
     455           1 :                     if( ifldnum > 1 && iofst_last_sect6 > 0 )
     456           1 :                     {
     457             :                         /* Unpack the last valid section 6 we read before */
     458           1 :                         int iofst_backup = iofst;
     459           1 :                         iofst = iofst_last_sect6 - 40;
     460           1 :                         jerr=g2_unpack6(cgrib,cgrib_length,&iofst,lgfld->ngrdpts,&lgfld->ibmap,
     461             :                                         &lgfld->bmap);
     462           1 :                         lgfld->ibmap = 254;
     463           1 :                         iofst = iofst_backup;
     464           1 :                         if( jerr != 0 ) {
     465           0 :                             ierr=13;
     466           0 :                             return(ierr);
     467             :                         }
     468             :                     }
     469             :                     else
     470             :                     {
     471           0 :                         printf("g2_getfld: Prev bit-map specified, but none exist.\n");
     472           0 :                         ierr=17;
     473           0 :                         return(ierr);
     474             :                     }
     475             :                  }
     476             :               else                         // get rid of it
     477         156 :                  if( bmpsave!=0 ) free(bmpsave);
     478             :             }
     479             :             else {
     480           0 :               ierr=13;
     481           0 :               return(ierr);
     482             :             }
     483             :           }
     484             :           else {    // do not unpack bitmap
     485         306 :             gbit(cgrib,&lgfld->ibmap,iofst,8);      // Get BitMap Indicator
     486         306 :             have6=1;
     487         306 :             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           8 :                 iofst_last_sect6 = iofst;
     490             :             }
     491             :           }
     492             :         }
     493             :         //
     494             :         //   If found Section 7, check to see if this field is the
     495             :         //   one requested.
     496             :         //
     497        2893 :         if (isecnum==7 && numfld==ifldnum && unpack) {
     498         157 :           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         157 :           if( expand )
     507             :           {
     508         157 :               if ( lgfld->ibmap != 255 && lgfld->bmap != 0 )
     509             :               {
     510           2 :                   if( lgfld->ngrdpts < lgfld->ndpts )
     511             :                   {
     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             :                   }
     519             :               }
     520         155 :               else if( lgfld->ngrdpts != lgfld->ndpts )
     521             :               {
     522           0 :                   ierr=14;
     523           0 :                   return(ierr);
     524             :               }
     525             :           }
     526             : 
     527         157 :           jerr=g2_unpack7(cgrib,cgrib_length,&iofst,lgfld->igdtnum,lgfld->igdtmpl,
     528             :                           lgfld->idrtnum,lgfld->idrtmpl,lgfld->ndpts,
     529             :                           &lgfld->fld);
     530         157 :           if (jerr == 0) {
     531         157 :             have7=1;
     532             :             //  If bitmap is used with this field, expand data field
     533             :             //  to grid, if possible.
     534         157 :             if ( lgfld->ibmap != 255 && lgfld->bmap != 0 ) {
     535           2 :                if ( expand == 1 ) {
     536           2 :                   n=0;
     537           2 :                   newfld=(g2float *)calloc(lgfld->ngrdpts,sizeof(g2float));
     538         802 :                   for (j=0;j<lgfld->ngrdpts;j++) {
     539         800 :                       if (lgfld->bmap[j]==1)
     540             :                       {
     541         800 :                           if( n >= lgfld->ndpts )
     542             :                           {
     543           0 :                               printf("g2_getfld: overflow of lgfld->fld array\n");
     544           0 :                               ierr=14;
     545           0 :                               free(newfld);
     546           0 :                               return(ierr);
     547             :                           }
     548         800 :                           newfld[j]=lgfld->fld[n++];
     549             :                       }
     550             :                   }
     551           2 :                   free(lgfld->fld);
     552           2 :                   lgfld->fld=newfld;
     553           2 :                   lgfld->expanded=1;
     554             :                }
     555             :                else {
     556           0 :                   lgfld->expanded=0;
     557             :                }
     558             :             }
     559             :             else {
     560         155 :                if( lgfld->ngrdpts != lgfld->ndpts )
     561             :                {
     562             :                    /* Added by E. Rouault to fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2070 */
     563           0 :                    lgfld->expanded=0;
     564             :                }
     565             :                else 
     566             :                {
     567         155 :                     lgfld->expanded=1;
     568             :                }
     569             :             }
     570             :           }
     571             :           else {
     572           0 :             printf("g2_getfld: return from g2_unpack7 = %d \n",(int)jerr);
     573           0 :             ierr=14;
     574           0 :             return(ierr);
     575             :           }
     576             :         }
     577             :         //
     578             :         //   Check to see if we read pass the end of the GRIB
     579             :         //   message and missed the terminator string '7777'.
     580             :         //
     581        2893 :         ipos=ipos+lensec;                // Update beginning of section pointer
     582        2893 :         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             :         }
     587             :         //
     588             :         //  If unpacking requested, return when all sections have been
     589             :         //  processed
     590             :         //
     591        2893 :         if (unpack && have3 && have4 && have5 && have6 && have7)
     592         157 :             return(ierr);
     593             :         //
     594             :         //  If unpacking is not requested, return when sections
     595             :         //  3 through 6 have been processed
     596             :         //
     597        2736 :         if ((! unpack) && have3 && have4 && have5 && have6)
     598         303 :             return(ierr);
     599             : 
     600             :       }
     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             : }

Generated by: LCOV version 1.14