1 : #include <stdio.h>
2 : #include <stdlib.h>
3 : #include <memory.h>
4 : #include <string.h>
5 : #include "grib2.h"
6 :
7 : g2int simunpack(unsigned char *,g2int *, g2int,g2float *);
8 : int comunpack(unsigned char *,g2int,g2int,g2int *,g2int,g2float *);
9 : g2int specunpack(unsigned char *,g2int *,g2int,g2int,g2int, g2int, g2float *);
10 : g2int jpcunpack(unsigned char *,g2int,g2int *,g2int, g2float *);
11 :
12 : #ifdef USE_PNG
13 : g2int pngunpack(unsigned char *,g2int,g2int *,g2int, g2float *);
14 : #endif /* USE_PNG */
15 :
16 :
17 :
18 2 : g2int g2_unpack7(unsigned char *cgrib,g2int *iofst,g2int igdsnum,g2int *igdstmpl,
19 : g2int idrsnum,g2int *idrstmpl,g2int ndpts,g2float **fld)
20 : //$$$ SUBPROGRAM DOCUMENTATION BLOCK
21 : // . . . .
22 : // SUBPROGRAM: g2_unpack7
23 : // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-31
24 : //
25 : // ABSTRACT: This subroutine unpacks Section 7 (Data Section)
26 : // as defined in GRIB Edition 2.
27 : //
28 : // PROGRAM HISTORY LOG:
29 : // 2002-10-31 Gilbert
30 : // 2002-12-20 Gilbert - Added GDT info to arguments
31 : // and added 5.51 processing.
32 : // 2003-08-29 Gilbert - Added support for new templates using
33 : // PNG and JPEG2000 algorithms/templates.
34 : // 2004-11-29 Gilbert - JPEG2000 now allowed to use WMO Template no. 5.40
35 : // PNG now allowed to use WMO Template no. 5.41
36 : // 2004-12-16 Taylor - Added check on comunpack return code.
37 : //
38 : // USAGE: int g2_unpack7(unsigned char *cgrib,g2int *iofst,g2int igdsnum,
39 : // g2int *igdstmpl, g2int idrsnum,
40 : // g2int *idrstmpl, g2int ndpts,g2float **fld)
41 : // INPUT ARGUMENTS:
42 : // cgrib - char array containing Section 7 of the GRIB2 message
43 : // iofst - Bit offset of the beginning of Section 7 in cgrib.
44 : // igdsnum - Grid Definition Template Number ( see Code Table 3.0)
45 : // ( Only used for DRS Template 5.51 )
46 : // igdstmpl - Pointer to an integer array containing the data values for
47 : // the specified Grid Definition
48 : // Template ( N=igdsnum ). Each element of this integer
49 : // array contains an entry (in the order specified) of Grid
50 : // Definition Template 3.N
51 : // ( Only used for DRS Template 5.51 )
52 : // idrsnum - Data Representation Template Number ( see Code Table 5.0)
53 : // idrstmpl - Pointer to an integer array containing the data values for
54 : // the specified Data Representation
55 : // Template ( N=idrsnum ). Each element of this integer
56 : // array contains an entry (in the order specified) of Data
57 : // Representation Template 5.N
58 : // ndpts - Number of data points unpacked and returned.
59 : //
60 : // OUTPUT ARGUMENTS:
61 : // iofst - Bit offset at the end of Section 7, returned.
62 : // fld - Pointer to a float array containing the unpacked data field.
63 : //
64 : // RETURN VALUES:
65 : // ierr - Error return code.
66 : // 0 = no error
67 : // 2 = Not section 7
68 : // 4 = Unrecognized Data Representation Template
69 : // 5 = need one of GDT 3.50 through 3.53 to decode DRT 5.51
70 : // 6 = memory allocation error
71 : // 7 = corrupt section 7.
72 : //
73 : // REMARKS: None
74 : //
75 : // ATTRIBUTES:
76 : // LANGUAGE: C
77 : // MACHINE:
78 : //
79 : //$$$//
80 : {
81 : g2int ierr,isecnum;
82 : g2int ipos,lensec;
83 : g2float *lfld;
84 :
85 2 : ierr=0;
86 2 : *fld=0; //NULL
87 :
88 2 : gbit(cgrib,&lensec,*iofst,32); // Get Length of Section
89 2 : *iofst=*iofst+32;
90 2 : gbit(cgrib,&isecnum,*iofst,8); // Get Section Number
91 2 : *iofst=*iofst+8;
92 :
93 2 : if ( isecnum != 7 ) {
94 0 : ierr=2;
95 : //fprintf(stderr,"g2_unpack7: Not Section 7 data.\n");
96 0 : return(ierr);
97 : }
98 :
99 2 : ipos=(*iofst/8);
100 2 : lfld=(g2float *)calloc(ndpts,sizeof(g2float));
101 2 : if (lfld == 0) {
102 0 : ierr=6;
103 0 : return(ierr);
104 : }
105 : else {
106 2 : *fld=lfld;
107 : }
108 :
109 2 : if (idrsnum == 0)
110 0 : simunpack(cgrib+ipos,idrstmpl,ndpts,lfld);
111 4 : else if (idrsnum == 2 || idrsnum == 3) {
112 2 : if (comunpack(cgrib+ipos,lensec,idrsnum,idrstmpl,ndpts,lfld) != 0) {
113 0 : return 7;
114 : }
115 : }
116 0 : else if (idrsnum == 50) { // Spectral Simple
117 0 : simunpack(cgrib+ipos,idrstmpl,ndpts-1,lfld+1);
118 0 : rdieee(idrstmpl+4,lfld+0,1);
119 : }
120 0 : else if (idrsnum == 51) // Spectral complex
121 0 : if ( igdsnum>=50 && igdsnum <=53 )
122 0 : specunpack(cgrib+ipos,idrstmpl,ndpts,igdstmpl[0],igdstmpl[2],igdstmpl[2],lfld);
123 : else {
124 0 : fprintf(stderr,"g2_unpack7: Cannot use GDT 3.%d to unpack Data Section 5.51.\n",(int)igdsnum);
125 0 : ierr=5;
126 0 : if ( lfld != 0 ) free(lfld);
127 0 : *fld=0; //NULL
128 0 : return(ierr);
129 : }
130 0 : else if (idrsnum == 40 || idrsnum == 40000) {
131 0 : jpcunpack(cgrib+ipos,lensec-5,idrstmpl,ndpts,lfld);
132 : }
133 : #ifdef USE_PNG
134 : else if (idrsnum == 41 || idrsnum == 40010) {
135 : pngunpack(cgrib+ipos,lensec-5,idrstmpl,ndpts,lfld);
136 : }
137 : #endif /* USE_PNG */
138 : else {
139 0 : fprintf(stderr,"g2_unpack7: Data Representation Template 5.%d not yet implemented.\n",(int)idrsnum);
140 0 : ierr=4;
141 0 : if ( lfld != 0 ) free(lfld);
142 0 : *fld=0; //NULL
143 0 : return(ierr);
144 : }
145 :
146 2 : *iofst=*iofst+(8*lensec);
147 :
148 2 : return(ierr); // End of Section 7 processing
149 :
150 : }
|