source: trunk/WRF.COMMON/WRFV2/external/io_grib1/MEL_grib1/grib_dec.c

Last change on this file was 11, checked in by aslmd, 14 years ago

spiga@svn-planeto:ajoute le modele meso-echelle martien

File size: 7.7 KB
Line 
1#include <stdio.h>              /* standard I/O header file          */
2#include <stdlib.h>
3#include <string.h>
4#include "dprints.h"            /* for dprints & func prototype*/
5#include "gribfuncs.h"          /* prototypes */
6
7/* PROGRAMMER : Steve Lowe and Todd Kienitz, SAIC Monterey
8   DATE       : February 7, 1996
9                Oct. 1996 by Alice Nakajima, SAIC Monterey
10*
11*********************************************************************
12* A.  FUNCTION:  grib_dec
13*     decode a Gridded Binary (GRIB edition 1) format message
14*
15*    INTERFACE:
16*      int grib_dec (curr_ptr, pds, gds, bds_head, bms, ppgrib_data, errmsg)
17*
18*    ARGUMENTS (I=input, O=output, I&O=input and output):
19*      (I)  char *curr_ptr;
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;
27*      (O)  BMS_INPUT *bms;
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;
32*      (O)  char *errmsg;
33*           Empty array, Returned filled if error occurred;
34*
35*     RETURN CODE:
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***********************************************************************
43*/
44
45#if PROTOTYPE_NEEDED
46int   grib_dec (char *curr_ptr, PDS_INPUT  *pds, grid_desc_sec  *gds,
47                BDS_HEAD_INPUT *bds_head, BMS_INPUT *bms, float **ppgrib_data,
48                char *errmsg)
49#else
50int 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 */
59#endif
60{
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 */
66  int nReturn = 0;
67  unsigned long skip;
68  float *outdata;
69  int xsize;
70  int j;
71
72/*
73*
74* A.0     DEBUG printing
75*/
76 DPRINT1 ("Entering %s\n", func);
77 DPRINT6 (
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);
80/*
81*
82* A.1     IF (incoming pointer is not at 'GRIB')
83*            RETURN 1  !errmsg filled
84*         ENDIF
85*/
86if(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 */
89 }
90
91/*
92*
93* A.2     FUNCTION gbyte   !get total message length from IDS
94*/
95skip=32;
96gbyte(curr_ptr,&lMessageSize,&skip,24);
97DPRINT0 ("lMessageSize\n");
98
99/*
100*
101* A.3     IF (Message does not end with '7777')
102*            RETURN 2  !errmsg filled
103*         ENDIF
104*/
105if(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;
109  }
110
111/*
112*
113* A.4     EXTRACT the  GRIB edition out of Section 0
114*         IF (not GRIB edition 1)
115*            RETURN 3  !errmsg filled
116*         ENDIF
117*/
118edition = (long) curr_ptr[7];        /* get edition */
119pds->usEd_num = (unsigned short) edition;
120if(edition != 1) {
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;
124  }
125
126/*
127*
128* A.5     MOVE pointer to the Product Definition section
129*/
130curr_ptr = curr_ptr + 8;
131
132/*
133*
134* A.6     FUNCTION gribgetpds  !decode the PDS
135*         RETURN error code if fails  !errmsg filled
136*/
137if( nReturn= gribgetpds(curr_ptr, pds, errmsg)) {
138   DPRINT2 ("%s:  error=%d  in grib get pds;\n", func, nReturn);
139   upd_child_errmsg (func, errmsg);
140   goto BYE;
141  }
142
143/*
144*
145* A.7     MOVE pointer to the end of PDS
146*/
147curr_ptr += pds->uslength;
148
149/*
150*
151* A.8     IF (GDS is present)
152*/
153gds_flag = pds->usGds_bms_id >> 7 & 1;
154if(gds_flag)  /* grid description section present */
155  {
156/*
157* A.8.1      FUNCTION gribgetgds   !decode GDS
158*            RETURN error code if fails  !errmsg filled
159*/
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);
163      goto BYE;
164       }
165
166/*
167* A.8.2      MOVE the cursor to the next section (either BMS/BDS)
168*/
169   curr_ptr += gds->head.uslength;
170/*
171* A.8.3      SET the number of data points depending on Projection
172*/
173   switch(gds->head.usData_type)
174  {
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;       
184        break;
185
186     case MERC_PRJ:             /* Mercator Grid */
187        bds_head->ulGrid_size = gds->merc.cols * gds->merc.rows; 
188        break;
189
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; 
194        break;
195
196     case POLAR_PRJ:            /* Polar Stereographic */
197        bds_head->ulGrid_size = gds->pol.usNx * gds->pol.usNy; 
198        break;
199
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;
205     }
206  }
207/*
208* A.8     ENDIF (GDS is present)
209*/
210
211/*
212*
213* A.9     IF (bitmap Section is present)
214*/
215flag = pds->usGds_bms_id >> 6 & 1;
216if(flag)  /* bit map section present */
217  {
218/*
219* A.9.1      FUNCTION gribgetbms   !decode BMS
220*            RETURN error code if fails  !errmsg filled
221*/
222   if( nReturn=gribgetbms(curr_ptr,bms,gds_flag, bds_head->ulGrid_size,errmsg)) 
223   { 
224     DPRINT2 ("%s:  error=%d  in grib get BMS;\n",func,nReturn);
225     upd_child_errmsg (func, errmsg);
226     goto BYE;
227   } 
228
229/*
230* A.9.2      MOVE the cursor to beginning of Binary Data Section
231*/
232     curr_ptr += bms->uslength;
233
234  } /* Bms present */
235/*
236* A.9     ENDIF  !bms present
237*/
238
239
240/*
241*
242* A.10    FUNCTION  gribgetbds()
243*         RETURN error code if failed  !errmsg filled
244*/
245  if(nReturn=gribgetbds(curr_ptr, pds->sDec_sc_fctr, bms, gds, ppgrib_data, 
246                bds_head, errmsg)) 
247   { 
248     DPRINT2 ("%s:  error=%d  in grib get BDS;\n",func,nReturn);
249     upd_child_errmsg (func, errmsg);
250     goto BYE;
251    }
252 
253/*
254*
255* A.11    SET return code to 0  !no errors
256*/
257  nReturn = 0;
258
259/*
260*
261* A.12    RETURN return code;
262*/
263BYE:
264  DPRINT2  ("Exit %s, Stat=%d\n", func, nReturn);
265  return(nReturn);
266/*
267*
268* END OF FUNCTION
269*
270*
271*/
272} 
Note: See TracBrowser for help on using the repository browser.