LCOV - code coverage report
Current view: top level - frmts/grib/degrib/g2clib - g2_unpack4.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 57 80 71.2 %
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 <limits.h>
       4             : #include "grib2.h"
       5             : 
       6             : 
       7         806 : g2int g2_unpack4(unsigned char *cgrib,g2int cgrib_length,g2int *iofst,g2int *ipdsnum,g2int **ipdstmpl,
       8             :                g2int *mappdslen,g2float **coordlist,g2int *numcoord)
       9             : ////$$$  SUBPROGRAM DOCUMENTATION BLOCK
      10             : //                .      .    .                                       .
      11             : // SUBPROGRAM:    g2_unpack4
      12             : //   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-10-31
      13             : //
      14             : // ABSTRACT: This subroutine unpacks Section 4 (Product Definition Section)
      15             : //           as defined in GRIB Edition 2.
      16             : //
      17             : // PROGRAM HISTORY LOG:
      18             : // 2002-10-31  Gilbert
      19             : // 2009-01-14  Vuong     Changed structure name template to gtemplate
      20             : //
      21             : // USAGE:    int g2_unpack4(unsigned char *cgrib,g2int *iofst,g2int *ipdsnum,
      22             : //                          g2int **ipdstmpl,g2int *mappdslen,
      23             : //                          g2float **coordlist,g2int *numcoord)
      24             : //   INPUT ARGUMENTS:
      25             : //     cgrib    - Char array containing Section 4 of the GRIB2 message
      26             : //     iofst    - Bit offset of the beginning of Section 4 in cgrib.
      27             : //
      28             : //   OUTPUT ARGUMENTS:
      29             : //     iofst    - Bit offset of the end of Section 4, returned.
      30             : //     ipdsnum  - Product Definition Template Number ( see Code Table 4.0)
      31             : //     ipdstmpl - Pointer to integer array containing the data values for
      32             : //                the specified Product Definition
      33             : //                Template ( N=ipdsnum ).  Each element of this integer
      34             : //                array contains an entry (in the order specified) of Product
      35             : //                Definition Template 4.N
      36             : //     mappdslen- Number of elements in ipdstmpl[].  i.e. number of entries
      37             : //                in Product Definition Template 4.N  ( N=ipdsnum ).
      38             : //     coordlist- Pointer to real array containing floating point values
      39             : //                intended to document
      40             : //                the vertical discretisation associated to model data
      41             : //                on hybrid coordinate vertical levels.  (part of Section 4)
      42             : //     numcoord - number of values in array coordlist.
      43             : //
      44             : //   RETURN VALUES:
      45             : //     ierr     - Error return code.
      46             : //                0 = no error
      47             : //                2 = Not section 4
      48             : //                5 = "GRIB" message contains an undefined Product Definition
      49             : //                    Template.
      50             : //                6 = memory allocation error
      51             : //
      52             : // REMARKS:
      53             : //
      54             : // ATTRIBUTES:
      55             : //   LANGUAGE: C
      56             : //   MACHINE:
      57             : //
      58             : //$$$//
      59             : {
      60             : 
      61         806 :       g2int ierr,needext,i,j,nbits,isecnum = 0;
      62         806 :       g2int lensec,isign = 0,newlen;
      63             :       g2int *coordieee;
      64         806 :       g2int *lipdstmpl=0;
      65             :       g2float *lcoordlist;
      66             :       gtemplate *mappds;
      67             : 
      68         806 :       ierr=0;
      69         806 :       *ipdstmpl=0;    // NULL
      70         806 :       *coordlist=0;    // NULL
      71             : 
      72         806 :       gbit2(cgrib,cgrib_length,&lensec,*iofst,32);        // Get Length of Section
      73         806 :       *iofst=*iofst+32;
      74         806 :       gbit2(cgrib,cgrib_length,&isecnum,*iofst,8);         // Get Section Number
      75         806 :       *iofst=*iofst+8;
      76             : 
      77         806 :       if ( isecnum != 4 ) {
      78           0 :          ierr=2;
      79           0 :          *numcoord=0;
      80           0 :          *mappdslen=0;
      81             :         // fprintf(stderr,"g2_unpack4: Not Section 4 data.\n");
      82           0 :          return(ierr);
      83             :       }
      84             : 
      85         806 :       gbit2(cgrib,cgrib_length,numcoord,*iofst,16);    // Get num of coordinate values
      86         806 :       *iofst=*iofst+16;
      87         806 :       gbit2(cgrib,cgrib_length,ipdsnum,*iofst,16);    // Get Prod. Def Template num.
      88         806 :       *iofst=*iofst+16;
      89             : 
      90             :       //   Get Product Definition Template
      91         806 :       mappds=getpdstemplate(*ipdsnum);
      92         806 :       if (mappds == 0) {       // undefine template
      93           4 :         ierr=5;
      94           4 :         *mappdslen=0;
      95           4 :         return(ierr);
      96             :       }
      97         802 :       *mappdslen=mappds->maplen;
      98         802 :       needext=mappds->needext;
      99             :       //
     100             :       //   Unpack each value into array ipdstmpl from the
     101             :       //   the appropriate number of octets, which are specified in
     102             :       //   corresponding entries in array mappds.
     103             :       //
     104         802 :       if (*mappdslen > 0) lipdstmpl=(g2int *)calloc(*mappdslen,sizeof(g2int));
     105         802 :       if (lipdstmpl == 0) {
     106           0 :          ierr=6;
     107           0 :          *mappdslen=0;
     108           0 :          *ipdstmpl=0;     //NULL
     109           0 :          free(mappds);
     110           0 :          return(ierr);
     111             :       }
     112             :       else {
     113         802 :          *ipdstmpl=lipdstmpl;
     114             :       }
     115       13998 :       for (i=0;i<mappds->maplen;i++) {
     116       13196 :         nbits=abs(mappds->map[i])*8;
     117       13196 :         if ( mappds->map[i] >= 0 ) {
     118        9241 :           gbit2(cgrib,cgrib_length,lipdstmpl+i,*iofst,nbits);
     119             :         }
     120             :         else {
     121        3955 :           gbit2(cgrib,cgrib_length,&isign,*iofst,1);
     122        3955 :           gbit2(cgrib,cgrib_length,lipdstmpl+i,*iofst+1,nbits-1);
     123        3955 :           if (isign == 1) lipdstmpl[i]=-1*lipdstmpl[i];
     124             :         }
     125       13196 :         *iofst=*iofst+nbits;
     126             :       }
     127             :       //
     128             :       //   Check to see if the Product Definition Template needs to be
     129             :       //   extended.
     130             :       //   The number of values in a specific template may vary
     131             :       //   depending on data specified in the "static" part of the
     132             :       //   template.
     133             :       //
     134         802 :       if ( needext ==1 ) {
     135         102 :         free(mappds);
     136         102 :         mappds=extpdstemplate(*ipdsnum,lipdstmpl);
     137         102 :         newlen=mappds->maplen+mappds->extlen;
     138         102 :         lipdstmpl=(g2int *)realloc(lipdstmpl,newlen*sizeof(g2int));
     139         102 :         *ipdstmpl=lipdstmpl;
     140             :         //   Unpack the rest of the Product Definition Template
     141         102 :         j=0;
     142         247 :         for (i=*mappdslen;i<newlen;i++) {
     143             : #ifdef notneeded
     144             :           if( mappds->ext[j] < INT_MIN / 8 || mappds->ext[j] > INT_MAX / 8 )
     145             :           {
     146             :               ierr=6;
     147             :               *numcoord=0;
     148             :               *mappdslen=0;
     149             :               *coordlist=0;    // NULL
     150             :               *ipdstmpl=0;
     151             :               free(mappds->ext);
     152             :               free(mappds);
     153             :               free(lipdstmpl);
     154             :               return(ierr);
     155             :           }
     156             : #endif
     157         145 :           nbits=abs(mappds->ext[j])*8;
     158         145 :           lipdstmpl[i] = 0;
     159         145 :           if ( mappds->ext[j] >= 0 ) {
     160          87 :             gbit2(cgrib,cgrib_length,lipdstmpl+i,*iofst,nbits);
     161             :           }
     162             :           else {
     163          58 :             gbit2(cgrib,cgrib_length,&isign,*iofst,1);
     164          58 :             gbit2(cgrib,cgrib_length,lipdstmpl+i,*iofst+1,nbits-1);
     165          58 :             if (isign == 1) lipdstmpl[i]=-1*lipdstmpl[i];
     166             :           }
     167         145 :           *iofst=*iofst+nbits;
     168         145 :           j++;
     169             :         }
     170         102 :         *mappdslen=newlen;
     171             :       }
     172         802 :       free(mappds->ext);
     173         802 :       free(mappds);
     174             :       //
     175             :       //   Get Optional list of vertical coordinate values
     176             :       //   after the Product Definition Template, if necessary.
     177             :       //
     178         802 :       *coordlist=0;    // NULL
     179         802 :       if ( *numcoord != 0 ) {
     180           0 :          coordieee=(g2int *)calloc(*numcoord,sizeof(g2int));
     181           0 :          lcoordlist=(g2float *)calloc(*numcoord,sizeof(g2float));
     182           0 :          if (coordieee == 0 || lcoordlist == 0) {
     183           0 :             ierr=6;
     184           0 :             *numcoord=0;
     185           0 :             *coordlist=0;    // NULL
     186           0 :             if( coordieee != 0 ) free(coordieee);
     187           0 :             if( lcoordlist != 0 ) free(lcoordlist);
     188           0 :             return(ierr);
     189             :          }
     190             :          else {
     191           0 :             *coordlist=lcoordlist;
     192             :          }
     193           0 :         gbits(cgrib,cgrib_length,coordieee,*iofst,32,0,*numcoord);
     194           0 :         rdieee(coordieee,*coordlist,*numcoord);
     195           0 :         free(coordieee);
     196           0 :         *iofst=*iofst+(32*(*numcoord));
     197             :       }
     198             : 
     199         802 :       return(ierr);    // End of Section 4 processing
     200             : 
     201             : }

Generated by: LCOV version 1.14