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