LCOV - code coverage report
Current view: top level - frmts/grib/degrib/g2clib - g2_unpack5.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 38 70 54.3 %
Date: 2024-05-06 18:28:20 Functions: 1 1 100.0 %

          Line data    Source code
       1             : #include <limits.h>
       2             : #include <stdio.h>
       3             : #include <stdlib.h>
       4             : #include "grib2.h"
       5             : 
       6             : 
       7         460 : g2int g2_unpack5(unsigned char *cgrib,g2int cgrib_length,g2int *iofst,g2int *ndpts,g2int *idrsnum,
       8             :                g2int **idrstmpl,g2int *mapdrslen)
       9             : ////$$$  SUBPROGRAM DOCUMENTATION BLOCK
      10             : //                .      .    .                                       .
      11             : // SUBPROGRAM:    g2_unpack5
      12             : //   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-10-31
      13             : //
      14             : // ABSTRACT: This subroutine unpacks Section 5 (Data Representation Section)
      15             : //           as defined in GRIB Edition 2.
      16             : //
      17             : // PROGRAM HISTORY LOG:
      18             : // 2002-10-31  Gilbert
      19             : //
      20             : // USAGE:    int g2_unpack5(unsigned char *cgrib,g2int *iofst,g2int *ndpts,
      21             : //                          g2int *idrsnum,g2int **idrstmpl,g2int *mapdrslen)
      22             : //   INPUT ARGUMENTS:
      23             : //     cgrib    - char array containing Section 5 of the GRIB2 message
      24             : //     iofst    - Bit offset for the beginning of Section 5 in cgrib.
      25             : //
      26             : //   OUTPUT ARGUMENTS:
      27             : //     iofst    - Bit offset at the end of Section 5, returned.
      28             : //     ndpts    - Number of data points unpacked and returned.
      29             : //     idrsnum  - Data Representation Template Number ( see Code Table 5.0)
      30             : //     idrstmpl - Pointer to an integer array containing the data values for
      31             : //                the specified Data Representation
      32             : //                Template ( N=idrsnum ).  Each element of this integer
      33             : //                array contains an entry (in the order specified) of Data
      34             : //                Representation Template 5.N
      35             : //     mapdrslen- Number of elements in idrstmpl[].  i.e. number of entries
      36             : //                in Data Representation Template 5.N  ( N=idrsnum ).
      37             : //
      38             : //   RETURN VALUES:
      39             : //     ierr     - Error return code.
      40             : //                0 = no error
      41             : //                2 = Not Section 5
      42             : //                6 = memory allocation error
      43             : //                7 = "GRIB" message contains an undefined Data
      44             : //                    Representation Template.
      45             : //
      46             : // REMARKS: None
      47             : //
      48             : // ATTRIBUTES:
      49             : //   LANGUAGE: C
      50             : //   MACHINE:
      51             : //
      52             : //$$$//
      53             : {
      54         460 :       g2int ierr,needext,i,j,nbits,isecnum = 0;
      55         460 :       g2int lensec,isign = 0,newlen;
      56         460 :       g2int *lidrstmpl=0;
      57             :       gtemplate *mapdrs;
      58         460 :       int ret=0;
      59             : #ifdef GRIB_MAX_POINTS
      60             :       const int knMaxPoints = GRIB_MAX_POINTS;
      61             : #else
      62         460 :       const int knMaxPoints = INT_MAX - 1;
      63             : #endif
      64             : 
      65         460 :       ierr=0;
      66         460 :       *idrstmpl=0;       //NULL
      67             : 
      68         460 :       gbit2(cgrib,cgrib_length,&lensec,*iofst,32);        // Get Length of Section
      69         460 :       *iofst=*iofst+32;
      70         460 :       gbit2(cgrib,cgrib_length,&isecnum,*iofst,8);         // Get Section Number
      71         460 :       *iofst=*iofst+8;
      72             : 
      73         460 :       if ( isecnum != 5 ) {
      74           0 :          ierr=2;
      75           0 :          *ndpts=0;
      76           0 :          *mapdrslen=0;
      77             :         // fprintf(stderr,"g2_unpack5: Not Section 5 data.\n");
      78           0 :          return(ierr);
      79             :       }
      80             : 
      81             :       // Get num of data points.
      82         460 :       ret = gbit2(cgrib,cgrib_length,ndpts,*iofst,32);
      83             :       // Reject ndpts if it outside of 0..knMaxPoints
      84         460 :       if (*ndpts < 0 || ret != 0) {
      85           0 :          *ndpts = 0;
      86           0 :          return 6;
      87             :       }
      88         460 :       if (*ndpts > knMaxPoints) {
      89           0 :          *ndpts = knMaxPoints;
      90           0 :          return 6;
      91             :       }
      92         460 :       *iofst=*iofst+32;
      93         460 :       gbit2(cgrib,cgrib_length,idrsnum,*iofst,16);     // Get Data Rep Template Num.
      94         460 :       *iofst=*iofst+16;
      95             : 
      96             :       //   Gen Data Representation Template
      97         460 :       mapdrs=getdrstemplate(*idrsnum);
      98         460 :       if (mapdrs == 0) {
      99           0 :         ierr=7;
     100           0 :         *mapdrslen=0;
     101           0 :         return(ierr);
     102             :       }
     103         460 :       *mapdrslen=mapdrs->maplen;
     104         460 :       needext=mapdrs->needext;
     105             :       //
     106             :       //   Unpack each value into array ipdstmpl from the
     107             :       //   the appropriate number of octets, which are specified in
     108             :       //   corresponding entries in array mapdrs.
     109             :       //
     110         460 :       if (*mapdrslen > 0) lidrstmpl=(g2int *)calloc(*mapdrslen,sizeof(g2int));
     111         460 :       if (lidrstmpl == 0) {
     112           0 :          ierr=6;
     113           0 :          *mapdrslen=0;
     114           0 :          *idrstmpl=0;     //NULL
     115           0 :          free(mapdrs);
     116           0 :          return(ierr);
     117             :       }
     118             :       else {
     119         460 :          *idrstmpl=lidrstmpl;
     120             :       }
     121        3397 :       for (i=0;i<mapdrs->maplen;i++) {
     122        2937 :         nbits=abs(mapdrs->map[i])*8;
     123        2937 :         if ( mapdrs->map[i] >= 0 ) {
     124        2267 :           gbit2(cgrib,cgrib_length,lidrstmpl+i,*iofst,nbits);
     125             :         }
     126             :         else {
     127         670 :           gbit2(cgrib,cgrib_length,&isign,*iofst,1);
     128         670 :           gbit2(cgrib,cgrib_length,lidrstmpl+i,*iofst+1,nbits-1);
     129         670 :           if (isign == 1) lidrstmpl[i]=-1*lidrstmpl[i];
     130             :         }
     131        2937 :         *iofst=*iofst+nbits;
     132             :       }
     133             :       //
     134             :       //   Check to see if the Data Representation Template needs to be
     135             :       //   extended.
     136             :       //   The number of values in a specific gtemplate may vary
     137             :       //   depending on data specified in the "static" part of the
     138             :       //   gtemplate.
     139             :       //
     140         460 :       if ( needext == 1 ) {
     141           0 :         free(mapdrs);
     142           0 :         mapdrs=extdrstemplate(*idrsnum,lidrstmpl);
     143           0 :         newlen=mapdrs->maplen+mapdrs->extlen;
     144           0 :         lidrstmpl=(g2int *)realloc(lidrstmpl,newlen*sizeof(g2int));
     145           0 :         *idrstmpl=lidrstmpl;
     146             :         //   Unpack the rest of the Data Representation Template
     147           0 :         j=0;
     148           0 :         for (i=*mapdrslen;i<newlen;i++) {
     149           0 :           nbits=abs(mapdrs->ext[j])*8;
     150           0 :           if ( mapdrs->ext[j] >= 0 ) {
     151           0 :             gbit2(cgrib,cgrib_length,lidrstmpl+i,*iofst,nbits);
     152             :           }
     153             :           else {
     154           0 :             gbit2(cgrib,cgrib_length,&isign,*iofst,1);
     155           0 :             gbit2(cgrib,cgrib_length,lidrstmpl+i,*iofst+1,nbits-1);
     156           0 :             if (isign == 1) lidrstmpl[i]=-1*lidrstmpl[i];
     157             :           }
     158           0 :           *iofst=*iofst+nbits;
     159           0 :           j++;
     160             :         }
     161           0 :         *mapdrslen=newlen;
     162             :       }
     163         460 :       free(mapdrs->ext);
     164         460 :       free(mapdrs);
     165             : 
     166         460 :       return(ierr);    // End of Section 5 processing
     167             : 
     168             : }

Generated by: LCOV version 1.14