LCOV - code coverage report
Current view: top level - frmts/grib/degrib/g2clib - g2_unpack3.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 52 100 52.0 %
Date: 2024-05-06 22:33:47 Functions: 1 1 100.0 %

          Line data    Source code
       1             : #include <stdio.h>
       2             : #include <stdlib.h>
       3             : #include "grib2.h"
       4             : 
       5             : 
       6         460 : g2int g2_unpack3(unsigned char *cgrib,g2int cgrib_length,g2int *iofst,g2int **igds,g2int **igdstmpl,
       7             :                          g2int *mapgridlen,g2int **ideflist,g2int *idefnum)
       8             : ////$$$  SUBPROGRAM DOCUMENTATION BLOCK
       9             : //                .      .    .                                       .
      10             : // SUBPROGRAM:    g2_unpack3
      11             : //   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-10-31
      12             : //
      13             : // ABSTRACT: This routine unpacks Section 3 (Grid Definition Section)
      14             : //           as defined in GRIB Edition 2.
      15             : //
      16             : // PROGRAM HISTORY LOG:
      17             : // 2002-10-31  Gilbert
      18             : //
      19             : // USAGE:    int g2_unpack3(unsigned char *cgrib,g2int *iofst,g2int **igds,
      20             : //                          g2int **igdstmpl,g2int *mapgridlen,
      21             : //                          g2int **ideflist,g2int *idefnum)
      22             : //   INPUT ARGUMENTS:
      23             : //     cgrib    - Char array containing Section 3 of the GRIB2 message.
      24             : //     iofst    - Bit offset for the beginning of Section 3 in cgrib.
      25             : //
      26             : //   OUTPUT ARGUMENTS:
      27             : //     iofst    - Bit offset at the end of Section 3, returned.
      28             : //     igds     - Contains information read from the appropriate GRIB Grid
      29             : //                Definition Section 3 for the field being returned.
      30             : //                igds[0]=Source of grid definition (see Code Table 3.0)
      31             : //                igds[1]=Number of grid points in the defined grid.
      32             : //                igds[2]=Number of octets needed for each
      33             : //                            additional grid points definition.
      34             : //                            Used to define number of
      35             : //                            points in each row ( or column ) for
      36             : //                            non-regular grids.
      37             : //                            = 0, if using regular grid.
      38             : //                igds[3]=Interpretation of list for optional points
      39             : //                            definition.  (Code Table 3.11)
      40             : //                igds[4]=Grid Definition Template Number (Code Table 3.1)
      41             : //     igdstmpl - Pointer to integer array containing the data values for
      42             : //                the specified Grid Definition
      43             : //                Template ( NN=igds[4] ).  Each element of this integer
      44             : //                array contains an entry (in the order specified) of Grid
      45             : //                Definition Template 3.NN
      46             : //     mapgridlen- Number of elements in igdstmpl[].  i.e. number of entries
      47             : //                in Grid Definition Template 3.NN  ( NN=igds[4] ).
      48             : //     ideflist - (Used if igds[2] .ne. 0)  Pointer to integer array containing
      49             : //                the number of grid points contained in each row ( or column ).
      50             : //                (part of Section 3)
      51             : //     idefnum  - (Used if igds[2] .ne. 0)  The number of entries
      52             : //                in array ideflist.  i.e. number of rows ( or columns )
      53             : //                for which optional grid points are defined.
      54             : //     ierr     - Error return code.
      55             : //                0 = no error
      56             : //                2 = Not Section 3
      57             : //                5 = "GRIB" message contains an undefined Grid Definition
      58             : //                    Template.
      59             : //                6 = memory allocation error
      60             : //
      61             : // REMARKS:
      62             : //
      63             : // ATTRIBUTES:
      64             : //   LANGUAGE: C
      65             : //   MACHINE:
      66             : //
      67             : //$$$
      68             : 
      69             : {
      70         460 :       g2int ierr,i,j,nbits,isecnum = 0;
      71         460 :       g2int lensec = 0,ibyttem=0,isign = 0,newlen;
      72         460 :       g2int *ligds,*ligdstmpl=0,*lideflist=0;
      73             :       gtemplate *mapgrid;
      74             : 
      75         460 :       ierr=0;
      76         460 :       *igds=0;       // NULL
      77         460 :       *igdstmpl=0;       // NULL
      78         460 :       *ideflist=0;       // NULL
      79             : 
      80         460 :       gbit2(cgrib,cgrib_length,&lensec,*iofst,32);        // Get Length of Section
      81         460 :       *iofst=*iofst+32;
      82         460 :       gbit2(cgrib,cgrib_length,&isecnum,*iofst,8);         // Get Section Number
      83         460 :       *iofst=*iofst+8;
      84             : 
      85         460 :       if ( isecnum != 3 ) {
      86           0 :          ierr=2;
      87           0 :          *idefnum=0;
      88           0 :          *mapgridlen=0;
      89             :         // fprintf(stderr,"g2_unpack3: Not Section 3 data.\n");
      90           0 :          return(ierr);
      91             :       }
      92             : 
      93         460 :       ligds=(g2int *)calloc(5,sizeof(g2int));
      94         460 :       *igds=ligds;
      95             : 
      96         460 :       gbit2(cgrib,cgrib_length,ligds+0,*iofst,8);     // Get source of Grid def.
      97         460 :       *iofst=*iofst+8;
      98         460 :       gbit2(cgrib,cgrib_length,ligds+1,*iofst,32);    // Get number of grid pts.
      99         460 :       *iofst=*iofst+32;
     100         460 :       gbit2(cgrib,cgrib_length,ligds+2,*iofst,8);     // Get num octets for opt. list
     101         460 :       *iofst=*iofst+8;
     102         460 :       gbit2(cgrib,cgrib_length,ligds+3,*iofst,8);     // Get interpret. for opt. list
     103         460 :       *iofst=*iofst+8;
     104         460 :       gbit2(cgrib,cgrib_length,ligds+4,*iofst,16);    // Get Grid Def Template num.
     105         460 :       *iofst=*iofst+16;
     106             : 
     107         460 :       if (ligds[4] != 65535) {
     108             :         //   Get Grid Definition Template
     109         460 :         mapgrid=getgridtemplate(ligds[4]);
     110         460 :         if (mapgrid == 0) {         // undefined template
     111           0 :           ierr=5;
     112           0 :           return(ierr);
     113             :         }
     114         460 :         *mapgridlen=mapgrid->maplen;
     115             :         //
     116             :         //   Unpack each value into array igdstmpl from the
     117             :         //   the appropriate number of octets, which are specified in
     118             :         //   corresponding entries in array mapgrid.
     119             :         //
     120         460 :         if (*mapgridlen > 0) {
     121         460 :            ligdstmpl=0;
     122         460 :            ligdstmpl=(g2int *)calloc(*mapgridlen,sizeof(g2int));
     123         460 :            if (ligdstmpl == 0) {
     124           0 :               ierr=6;
     125           0 :               *mapgridlen=0;
     126           0 :               *igdstmpl=0;    //NULL
     127           0 :               free(mapgrid);
     128           0 :               return(ierr);
     129             :            }
     130             :            else {
     131         460 :               *igdstmpl=ligdstmpl;
     132             :            }
     133             :         }
     134         460 :         ibyttem=0;
     135        9817 :         for (i=0;i<*mapgridlen;i++) {
     136        9357 :           nbits=abs(mapgrid->map[i])*8;
     137        9357 :           if ( mapgrid->map[i] >= 0 ) {
     138        7051 :             gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst,nbits);
     139             :           }
     140             :           else {
     141        2306 :             gbit2(cgrib,cgrib_length,&isign,*iofst,1);
     142        2306 :             gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst+1,nbits-1);
     143        2306 :             if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i];
     144             :           }
     145        9357 :           *iofst=*iofst+nbits;
     146        9357 :           ibyttem=ibyttem+abs(mapgrid->map[i]);
     147             :         }
     148             :         //
     149             :         //   Check to see if the Grid Definition Template needs to be
     150             :         //   extended.
     151             :         //   The number of values in a specific template may vary
     152             :         //   depending on data specified in the "static" part of the
     153             :         //   template.
     154             :         //
     155         460 :         if ( mapgrid->needext == 1 ) {
     156           0 :           free(mapgrid);
     157           0 :           mapgrid=extgridtemplate(ligds[4],ligdstmpl);
     158             :           //   Unpack the rest of the Grid Definition Template
     159           0 :           newlen=mapgrid->maplen+mapgrid->extlen;
     160           0 :           ligdstmpl=(g2int *)realloc(ligdstmpl,newlen*sizeof(g2int));
     161           0 :           *igdstmpl=ligdstmpl;
     162           0 :           j=0;
     163           0 :           for (i=*mapgridlen;i<newlen;i++) {
     164           0 :             nbits=abs(mapgrid->ext[j])*8;
     165           0 :             if ( mapgrid->ext[j] >= 0 ) {
     166           0 :               if(gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst,nbits) < 0)
     167             :               {
     168           0 :                   ierr = 6;
     169           0 :                   break;
     170             :               }
     171             :             }
     172             :             else {
     173           0 :               if( gbit2(cgrib,cgrib_length,&isign,*iofst,1) < 0 ||
     174           0 :                   gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst+1,nbits-1) < 0 )
     175             :               {
     176           0 :                   ierr = 6;
     177           0 :                   break;
     178             :               }
     179           0 :               if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i];
     180             :             }
     181           0 :             *iofst=*iofst+nbits;
     182           0 :             ibyttem=ibyttem+abs(mapgrid->ext[j]);
     183           0 :             j++;
     184             :           }
     185           0 :           *mapgridlen=newlen;
     186             :         }
     187         460 :         free(mapgrid->ext);
     188         460 :         free(mapgrid);
     189         460 :         if( ierr != 0 )
     190             :         {
     191           0 :             *idefnum=0;
     192           0 :             *ideflist=0;   //NULL
     193           0 :             return(ierr);
     194             :         }
     195             :       }
     196             :       else {              // No Grid Definition Template
     197           0 :         *mapgridlen=0;
     198           0 :         *igdstmpl=0;
     199             :       }
     200             :       //
     201             :       //   Unpack optional list of numbers defining number of points
     202             :       //   in each row or column, if included.  This is used for non regular
     203             :       //   grids.
     204             :       //
     205         460 :       if ( ligds[2] != 0 ) {
     206           0 :          nbits=ligds[2]*8;
     207           0 :          *idefnum=(lensec-14-ibyttem)/ligds[2];
     208           0 :          if (*idefnum > 0) lideflist=(g2int *)calloc(*idefnum,sizeof(g2int));
     209           0 :          if (lideflist == 0) {
     210           0 :             ierr=6;
     211           0 :             *idefnum=0;
     212           0 :             *ideflist=0;   //NULL
     213           0 :             return(ierr);
     214             :          }
     215             :          else {
     216           0 :             *ideflist=lideflist;
     217             :          }
     218           0 :          gbits(cgrib,cgrib_length,lideflist,*iofst,nbits,0,*idefnum);
     219           0 :          *iofst=*iofst+(nbits*(*idefnum));
     220             :       }
     221             :       else {
     222         460 :          *idefnum=0;
     223         460 :          *ideflist=0;    // NULL
     224             :       }
     225             : 
     226         460 :       return(ierr);    // End of Section 3 processing
     227             : }

Generated by: LCOV version 1.14