1 #include <stdio.h> /* standard I/O header file */
4 #include "dprints.h" /* for dprints & func prototype*/
5 #include "gribfuncs.h" /* prototypes */
7 /* PROGRAMMER : Steve Lowe and Todd Kienitz, SAIC Monterey
8 DATE : February 7, 1996
9 Oct. 1996 by Alice Nakajima, SAIC Monterey
11 *********************************************************************
12 * A. FUNCTION: grib_dec
13 * decode a Gridded Binary (GRIB edition 1) format message
16 * int grib_dec (curr_ptr, pds, gds, bds_head, bms, ppgrib_data, errmsg)
18 * ARGUMENTS (I=input, O=output, I&O=input and output):
20 * pointer to block containing GRIB message to decode;
21 * (O) PDS_INPUT *pds ;
22 * to be filled with decoded Product Defn Section info;
23 * (O) grid_desc_sec *gds;
24 * to be filled with decoded Binary Data Section info;
25 * (O) BDS_HEAD_INPUT *bds_head;
26 * to be filled with decoded Binary Data Section info;
28 * to be filled with decoded Bitmap Section info;
29 * (O) float **ppgrib_data;
30 * points to NULL upon entry; upon successful exit, points to newly
31 * malloced Float array filled with unpacked and restored data;
33 * Empty array, Returned filled if error occurred;
36 * 0> Success, **ppgrib_data now points to a block containing
37 * the unpacked & restored data (float);
38 * 1> Fail: first 4 bytes of curr_ptr is not 'GRIB'
39 * 2> Fail: last 4 bytes of curr_ptr is not '7777'
40 * 3> Fail: not Grib Edition 1
41 * 4> Fail: unknown projection type;
42 ***********************************************************************
46 int grib_dec (char *curr_ptr
, PDS_INPUT
*pds
, grid_desc_sec
*gds
,
47 BDS_HEAD_INPUT
*bds_head
, BMS_INPUT
*bms
, float **ppgrib_data
,
50 int grib_dec (curr_ptr
, pds
, gds
, bds_head
, bms
, ppgrib_data
, errmsg
)
51 char *curr_ptr
; /*input= ptr to 1st byte of GRIB message block*/
52 PDS_INPUT
*pds
; /* output=ptr to Internal PDS struct*/
53 grid_desc_sec
*gds
; /* output=ptr to Internal GDS struct*/
54 BDS_HEAD_INPUT
*bds_head
; /*out=ptr to Internal BDS header struct*/
55 BMS_INPUT
*bms
; /*output=ptr to Internal bitmap section struct*/
56 float **ppgrib_data
; /*outp=ptr to nothing upon entry; upon exit, */
57 /* points to a newly malloced array of floats; */
58 char *errmsg
; /* output= empty unless Error happens */
61 char *func
="grib_dec";
62 unsigned long lMessageSize
; /* message and section size */
63 long edition
; /* GRIB edition number */
64 int flag
; /* tests if a condition has happened */
65 int gds_flag
; /* set if Gds present */
76 DPRINT1 ("Entering %s\n", func
);
78 "curr_ptr=%ld, pds=%ld, gds=%ld\nbds_head=%ld, bms=%ld, ppgrib_data=%ld\n",
79 curr_ptr
, pds
, gds
, bds_head
, bms
, ppgrib_data
);
82 * A.1 IF (incoming pointer is not at 'GRIB')
83 * RETURN 1 !errmsg filled
86 if(strncmp(curr_ptr
,"GRIB",4) != 0) {
87 sprintf (errmsg
,"%s: no 'GRIB' at beg. of this msg\n", func
);
88 nReturn
= (1); /* GRIB not found */
93 * A.2 FUNCTION gbyte !get total message length from IDS
96 gbyte(curr_ptr
,&lMessageSize
,&skip
,24);
97 DPRINT0 ("lMessageSize\n");
101 * A.3 IF (Message does not end with '7777')
102 * RETURN 2 !errmsg filled
105 if(strncmp((curr_ptr
+ lMessageSize
- 4),"7777",4)!=0) {
106 DPRINT1 ("%s: no '7777' at end of this msg\n", func
);
107 sprintf (errmsg
,"%s: no '7777' at end of this msg\n", func
);
108 nReturn
= 2; goto BYE
;
113 * A.4 EXTRACT the GRIB edition out of Section 0
114 * IF (not GRIB edition 1)
115 * RETURN 3 !errmsg filled
118 edition
= (long) curr_ptr
[7]; /* get edition */
119 pds
->usEd_num
= (unsigned short) edition
;
121 DPRINT1 ("%s: error, not Grib Edition 1 \n", func
);
122 sprintf (errmsg
,"%s: not Grib Edition 1 \n", func
);
123 nReturn
=(3); goto BYE
;
128 * A.5 MOVE pointer to the Product Definition section
130 curr_ptr
= curr_ptr
+ 8;
134 * A.6 FUNCTION gribgetpds !decode the PDS
135 * RETURN error code if fails !errmsg filled
137 if( nReturn
= gribgetpds(curr_ptr
, pds
, errmsg
)) {
138 DPRINT2 ("%s: error=%d in grib get pds;\n", func
, nReturn
);
139 upd_child_errmsg (func
, errmsg
);
145 * A.7 MOVE pointer to the end of PDS
147 curr_ptr
+= pds
->uslength
;
151 * A.8 IF (GDS is present)
153 gds_flag
= pds
->usGds_bms_id
>> 7 & 1;
154 if(gds_flag
) /* grid description section present */
157 * A.8.1 FUNCTION gribgetgds !decode GDS
158 * RETURN error code if fails !errmsg filled
160 if( nReturn
=gribgetgds(curr_ptr
, gds
, errmsg
)) {
161 DPRINT2 ("%s: error=%d in grib get GDS;\n", func
, nReturn
);
162 upd_child_errmsg (func
, errmsg
);
167 * A.8.2 MOVE the cursor to the next section (either BMS/BDS)
169 curr_ptr
+= gds
->head
.uslength
;
171 * A.8.3 SET the number of data points depending on Projection
173 switch(gds
->head
.usData_type
)
175 case LATLON_PRJ
: /* Lat/Lon Grid */
176 case GAUSS_PRJ
: /* Gaussian Latitude/Longitude grid */
177 case ROT_LATLON_PRJ
: /* Rotated Lat/Lon */
178 case ROT_GAUSS_PRJ
: /* Rotated Gaussian */
179 case STR_LATLON_PRJ
: /* Stretched Lat/Lon */
180 case STR_GAUSS_PRJ
: /* Stretched Gaussian */
181 case STR_ROT_LATLON_PRJ
: /* Stretched and Rotated Lat/Lon */
182 case STR_ROT_GAUSS_PRJ
: /* Stretched and Rotated Gaussian */
183 bds_head
->ulGrid_size
= gds
->llg
.usNi
* gds
->llg
.usNj
;
186 case MERC_PRJ
: /* Mercator Grid */
187 bds_head
->ulGrid_size
= gds
->merc
.cols
* gds
->merc
.rows
;
190 case LAMB_PRJ
: /* Lambert Conformal */
191 case ALBERS_PRJ
: /* Albers equal-area */
192 case OBLIQ_LAMB_PRJ
: /* Oblique Lambert Conformal */
193 bds_head
->ulGrid_size
= gds
->lam
.iNx
* gds
->lam
.iNy
;
196 case POLAR_PRJ
: /* Polar Stereographic */
197 bds_head
->ulGrid_size
= gds
->pol
.usNx
* gds
->pol
.usNy
;
200 default: /* unknown */
201 DPRINT2 ("%s: unknown usData_type=%d\n",func
,gds
->head
.usData_type
);
202 sprintf(errmsg
,"%s: unknown usData_type=%d\n",
203 func
, gds
->head
.usData_type
);
204 nReturn
= (4); goto BYE
;
208 * A.8 ENDIF (GDS is present)
213 * A.9 IF (bitmap Section is present)
215 flag
= pds
->usGds_bms_id
>> 6 & 1;
216 if(flag
) /* bit map section present */
219 * A.9.1 FUNCTION gribgetbms !decode BMS
220 * RETURN error code if fails !errmsg filled
222 if( nReturn
=gribgetbms(curr_ptr
,bms
,gds_flag
, bds_head
->ulGrid_size
,errmsg
))
224 DPRINT2 ("%s: error=%d in grib get BMS;\n",func
,nReturn
);
225 upd_child_errmsg (func
, errmsg
);
230 * A.9.2 MOVE the cursor to beginning of Binary Data Section
232 curr_ptr
+= bms
->uslength
;
236 * A.9 ENDIF !bms present
242 * A.10 FUNCTION gribgetbds()
243 * RETURN error code if failed !errmsg filled
245 if(nReturn
=gribgetbds(curr_ptr
, pds
->sDec_sc_fctr
, bms
, gds
, ppgrib_data
,
248 DPRINT2 ("%s: error=%d in grib get BDS;\n",func
,nReturn
);
249 upd_child_errmsg (func
, errmsg
);
255 * A.11 SET return code to 0 !no errors
261 * A.12 RETURN return code;
264 DPRINT2 ("Exit %s, Stat=%d\n", func
, nReturn
);