Line data Source code
1 : #include <limits.h>
2 : #include <stdio.h>
3 : #include <stdlib.h>
4 : #include "grib2.h"
5 :
6 :
7 472 : 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 472 : g2int ierr,needext,i,j,nbits,isecnum = 0;
55 472 : g2int lensec,isign = 0,newlen;
56 472 : g2int *lidrstmpl=0;
57 : gtemplate *mapdrs;
58 472 : int ret=0;
59 : #ifdef GRIB_MAX_POINTS
60 : const int knMaxPoints = GRIB_MAX_POINTS;
61 : #else
62 472 : const int knMaxPoints = INT_MAX - 1;
63 : #endif
64 :
65 472 : ierr=0;
66 472 : *idrstmpl=0; //NULL
67 :
68 472 : gbit2(cgrib,cgrib_length,&lensec,*iofst,32); // Get Length of Section
69 472 : *iofst=*iofst+32;
70 472 : gbit2(cgrib,cgrib_length,&isecnum,*iofst,8); // Get Section Number
71 472 : *iofst=*iofst+8;
72 :
73 472 : 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 472 : ret = gbit2(cgrib,cgrib_length,ndpts,*iofst,32);
83 : // Reject ndpts if it outside of 0..knMaxPoints
84 472 : if (*ndpts < 0 || ret != 0) {
85 0 : *ndpts = 0;
86 0 : return 6;
87 : }
88 472 : if (*ndpts > knMaxPoints) {
89 0 : *ndpts = knMaxPoints;
90 0 : return 6;
91 : }
92 472 : *iofst=*iofst+32;
93 472 : gbit2(cgrib,cgrib_length,idrsnum,*iofst,16); // Get Data Rep Template Num.
94 472 : *iofst=*iofst+16;
95 :
96 : // Gen Data Representation Template
97 472 : mapdrs=getdrstemplate(*idrsnum);
98 472 : if (mapdrs == 0) {
99 0 : ierr=7;
100 0 : *mapdrslen=0;
101 0 : return(ierr);
102 : }
103 472 : *mapdrslen=mapdrs->maplen;
104 472 : 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 472 : if (*mapdrslen > 0) lidrstmpl=(g2int *)calloc(*mapdrslen,sizeof(g2int));
111 472 : 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 472 : *idrstmpl=lidrstmpl;
120 : }
121 3421 : for (i=0;i<mapdrs->maplen;i++) {
122 2949 : nbits=abs(mapdrs->map[i])*8;
123 2949 : if ( mapdrs->map[i] >= 0 ) {
124 2279 : 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 2949 : *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 472 : 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 472 : free(mapdrs->ext);
164 472 : free(mapdrs);
165 :
166 472 : return(ierr); // End of Section 5 processing
167 :
168 : }
|