Coverage Report

Created: 2025-06-09 08:44

/src/gdal/frmts/grib/degrib/g2clib/g2_unpack3.c
Line
Count
Source (jump to first uncovered line)
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
31.5k
{
70
31.5k
      g2int ierr,i,j,nbits,isecnum = 0;
71
31.5k
      g2int lensec = 0,ibyttem=0,isign = 0,newlen;
72
31.5k
      g2int *ligds,*ligdstmpl=0,*lideflist=0;
73
31.5k
      gtemplate *mapgrid;
74
75
31.5k
      ierr=0;
76
31.5k
      *igds=0;       // NULL
77
31.5k
      *igdstmpl=0;       // NULL
78
31.5k
      *ideflist=0;       // NULL
79
80
31.5k
      gbit2(cgrib,cgrib_length,&lensec,*iofst,32);        // Get Length of Section
81
31.5k
      *iofst=*iofst+32;
82
31.5k
      gbit2(cgrib,cgrib_length,&isecnum,*iofst,8);         // Get Section Number
83
31.5k
      *iofst=*iofst+8;
84
85
31.5k
      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
31.5k
      ligds=(g2int *)calloc(5,sizeof(g2int));
94
31.5k
      *igds=ligds;
95
96
31.5k
      gbit2(cgrib,cgrib_length,ligds+0,*iofst,8);     // Get source of Grid def.
97
31.5k
      *iofst=*iofst+8;
98
31.5k
      gbit2(cgrib,cgrib_length,ligds+1,*iofst,32);    // Get number of grid pts.
99
31.5k
      *iofst=*iofst+32;
100
31.5k
      gbit2(cgrib,cgrib_length,ligds+2,*iofst,8);     // Get num octets for opt. list
101
31.5k
      *iofst=*iofst+8;
102
31.5k
      gbit2(cgrib,cgrib_length,ligds+3,*iofst,8);     // Get interpret. for opt. list
103
31.5k
      *iofst=*iofst+8;
104
31.5k
      gbit2(cgrib,cgrib_length,ligds+4,*iofst,16);    // Get Grid Def Template num.
105
31.5k
      *iofst=*iofst+16;
106
107
31.5k
      if (ligds[4] != 65535) {
108
        //   Get Grid Definition Template
109
31.5k
        mapgrid=getgridtemplate(ligds[4]);
110
31.5k
        if (mapgrid == 0) {         // undefined template
111
15
          ierr=5;
112
15
          return(ierr);
113
15
        }
114
31.5k
        *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
31.5k
        if (*mapgridlen > 0) {
121
31.5k
           ligdstmpl=0;
122
31.5k
           ligdstmpl=(g2int *)calloc(*mapgridlen,sizeof(g2int));
123
31.5k
           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
31.5k
           else {
131
31.5k
              *igdstmpl=ligdstmpl;
132
31.5k
           }
133
31.5k
        }
134
31.5k
        ibyttem=0;
135
733k
        for (i=0;i<*mapgridlen;i++) {
136
701k
          nbits=abs(mapgrid->map[i])*8;
137
701k
          if ( mapgrid->map[i] >= 0 ) {
138
526k
            gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst,nbits);
139
526k
          }
140
175k
          else {
141
175k
            gbit2(cgrib,cgrib_length,&isign,*iofst,1);
142
175k
            gbit2(cgrib,cgrib_length,ligdstmpl+i,*iofst+1,nbits-1);
143
175k
            if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i];
144
175k
          }
145
701k
          *iofst=*iofst+nbits;
146
701k
          ibyttem=ibyttem+abs(mapgrid->map[i]);
147
701k
        }
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
31.5k
        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
31.5k
        free(mapgrid->ext);
188
31.5k
        free(mapgrid);
189
31.5k
        if( ierr != 0 )
190
0
        {
191
0
            *idefnum=0;
192
0
            *ideflist=0;   //NULL
193
0
            return(ierr);
194
0
        }
195
31.5k
      }
196
3
      else {              // No Grid Definition Template
197
3
        *mapgridlen=0;
198
3
        *igdstmpl=0;
199
3
      }
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
31.5k
      if ( ligds[2] != 0 ) {
206
2
         nbits=ligds[2]*8;
207
2
         *idefnum=(lensec-14-ibyttem)/ligds[2];
208
2
         if (*idefnum > 0) lideflist=(g2int *)calloc(*idefnum,sizeof(g2int));
209
2
         if (lideflist == 0) {
210
2
            ierr=6;
211
2
            *idefnum=0;
212
2
            *ideflist=0;   //NULL
213
2
            return(ierr);
214
2
         }
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
31.5k
      else {
222
31.5k
         *idefnum=0;
223
31.5k
         *ideflist=0;    // NULL
224
31.5k
      }
225
226
31.5k
      return(ierr);    // End of Section 3 processing
227
31.5k
}