Coverage Report

Created: 2026-08-14 09:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/frmts/grib/degrib/g2clib/g2_unpack3.c
Line
Count
Source
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include "grib2.h"
4
5
6
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
12.7k
{
70
12.7k
      g2int ierr,i,j,nbits,isecnum = 0;
71
12.7k
      g2int lensec = 0,ibyttem=0,isign = 0,newlen;
72
12.7k
      g2int *ligds,*ligdstmpl=0,*lideflist=0;
73
12.7k
      gtemplate *mapgrid;
74
75
12.7k
      ierr=0;
76
12.7k
      *igds=0;       // NULL
77
12.7k
      *igdstmpl=0;       // NULL
78
12.7k
      *ideflist=0;       // NULL
79
80
12.7k
      gbit2(cgrib,cgrib_length,&lensec,*iofst,32);        // Get Length of Section
81
12.7k
      *iofst=*iofst+32;
82
12.7k
      gbit2(cgrib,cgrib_length,&isecnum,*iofst,8);         // Get Section Number
83
12.7k
      *iofst=*iofst+8;
84
85
12.7k
      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
0
      }
92
93
12.7k
      ligds=(g2int *)calloc(5,sizeof(g2int));
94
12.7k
      *igds=ligds;
95
96
12.7k
      gbit2(cgrib,cgrib_length,ligds+0,*iofst,8);     // Get source of Grid def.
97
12.7k
      *iofst=*iofst+8;
98
12.7k
      gbit2(cgrib,cgrib_length,ligds+1,*iofst,32);    // Get number of grid pts.
99
12.7k
      *iofst=*iofst+32;
100
12.7k
      gbit2(cgrib,cgrib_length,ligds+2,*iofst,8);     // Get num octets for opt. list
101
12.7k
      *iofst=*iofst+8;
102
12.7k
      gbit2(cgrib,cgrib_length,ligds+3,*iofst,8);     // Get interpret. for opt. list
103
12.7k
      *iofst=*iofst+8;
104
12.7k
      gbit2(cgrib,cgrib_length,ligds+4,*iofst,16);    // Get Grid Def Template num.
105
12.7k
      *iofst=*iofst+16;
106
107
12.7k
      if (ligds[4] != 65535) {
108
        //   Get Grid Definition Template
109
12.7k
        mapgrid=getgridtemplate(ligds[4]);
110
12.7k
        if (mapgrid == 0) {         // undefined template
111
11
          ierr=5;
112
11
          return(ierr);
113
11
        }
114
12.7k
        *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
12.7k
        if (*mapgridlen > 0) {
121
12.7k
           ligdstmpl=0;
122
12.7k
           ligdstmpl=(g2int *)calloc(*mapgridlen,sizeof(g2int));
123
12.7k
           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
0
           }
130
12.7k
           else {
131
12.7k
              *igdstmpl=ligdstmpl;
132
12.7k
           }
133
12.7k
        }
134
12.7k
        ibyttem=0;
135
290k
        for (i=0;i<*mapgridlen;i++) {
136
277k
          nbits=abs(mapgrid->map[i])*8;
137
277k
          if ( mapgrid->map[i] >= 0 ) {
138
206k
            gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst,nbits);
139
206k
          }
140
70.4k
          else {
141
70.4k
            gbit2(cgrib,cgrib_length,&isign,*iofst,1);
142
70.4k
            gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst+1,nbits-1);
143
70.4k
            if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i];
144
70.4k
          }
145
277k
          *iofst=*iofst+nbits;
146
277k
          ibyttem=ibyttem+abs(mapgrid->map[i]);
147
277k
        }
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
12.7k
        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
0
              {
168
0
                  ierr = 6;
169
0
                  break;
170
0
              }
171
0
            }
172
0
            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
0
              {
176
0
                  ierr = 6;
177
0
                  break;
178
0
              }
179
0
              if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i];
180
0
            }
181
0
            *iofst=*iofst+nbits;
182
0
            ibyttem=ibyttem+abs(mapgrid->ext[j]);
183
0
            j++;
184
0
          }
185
0
          *mapgridlen=newlen;
186
0
        }
187
12.7k
        free(mapgrid->ext);
188
12.7k
        free(mapgrid);
189
12.7k
        if( ierr != 0 )
190
0
        {
191
0
            *idefnum=0;
192
0
            *ideflist=0;   //NULL
193
0
            return(ierr);
194
0
        }
195
12.7k
      }
196
0
      else {              // No Grid Definition Template
197
0
        *mapgridlen=0;
198
0
        *igdstmpl=0;
199
0
      }
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
12.7k
      if ( ligds[2] != 0 ) {
206
3
         nbits=ligds[2]*8;
207
3
         *idefnum=(lensec-14-ibyttem)/ligds[2];
208
3
         if (*idefnum > 0) lideflist=(g2int *)calloc(*idefnum,sizeof(g2int));
209
3
         if (lideflist == 0) {
210
3
            ierr=6;
211
3
            *idefnum=0;
212
3
            *ideflist=0;   //NULL
213
3
            return(ierr);
214
3
         }
215
0
         else {
216
0
            *ideflist=lideflist;
217
0
         }
218
0
         gbits(cgrib,cgrib_length,lideflist,*iofst,nbits,0,*idefnum);
219
0
         *iofst=*iofst+(nbits*(*idefnum));
220
0
      }
221
12.6k
      else {
222
12.6k
         *idefnum=0;
223
12.6k
         *ideflist=0;    // NULL
224
12.6k
      }
225
226
12.6k
      return(ierr);    // End of Section 3 processing
227
12.7k
}