source: lmdz_wrf/WRFV3/external/io_grib1/MEL_grib1/gribputgds.c @ 1

Last change on this file since 1 was 1, checked in by lfita, 10 years ago
  • -- --- Opening of the WRF+LMDZ coupling repository --- -- -

WRF: version v3.3
LMDZ: version v1818

More details in:

File size: 47.7 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#ifdef XT3_Catamount
5#include <features.h>
6#undef htonl
7#define htonl(x)     swap_byte4(x)
8#elif defined(_WIN32)
9#include <Winsock2.h>
10#else
11#include <netinet/in.h>
12#endif
13#include "dprints.h"            /* for dprints */
14#include "gribfuncs.h"          /* prototypes */
15#include <math.h>
16
17/*
18************************************************************************
19* A. FUNCTION  gribputgds
20*      used to decode Grib's Grid Defn Section.  It returns with both
21*      internal structures GDS_HEAD_INPUT and VOID* projblock filled,
22*      and also with true GDS already appended to GribHeader's Entire_Msg;
23*
24*    INTERFACE:
25*      int   gribputgds (Geom_In, pGDS_Head_Input, ppvGDS_Proj_Input,
26*                        ppgrib_hdr, errmsg)
27*
28*    ARGUMENTS (I=input, O=output, I&O=input and output):
29*      (I)  GEOM_IN  Geom_In
30*           Geometry information used as input;
31*      (O)  GDS_HEAD_INPUT *pGDS_Head_Input
32*           this is the internal GDS structure.  Attributes (uslength,
33*           usData_type, chData_type, usNum_v and usPl_Pv) gets updated;
34*      (O)  void  **ppvGDS_Proj_Input; 
35*           This is a pre-alloced storage of type Void and has length of
36*           MAX_INP_PROJ_SIZE bytes long.  How this block is filled depends
37*           on the type of Projection it is.  Projections currently supported
38*           are Spherical, Lambert, and Polar Stereographic.
39*     (I&O) GRIB_HDR  **ppgrib_hdr
40*           may already have one or more of the other Grib Sections
41*           (IDS, PDS, BMS, BDS, or EDS).   Upon successful exit, will
42*           also contain a GDS section.
43*      (O)  char  *errmsg               
44*           empty array, returned filled if error occurred;
45*
46*      RETURN CODE:
47*      0>  no errors;  GDS appended to GRIB_HDR's entire_msg, its info
48*          stored in bds_len & bds_ptr;  msg_length updated too;
49*      1>  error, grib hdr is null; errmsg filled;
50************************************************************************
51*/
52
53/*
54NCAR AIX does not have lrint, make one up.
55*/
56#ifdef NCARIBM_NOC99
57#define lrint(dbl) ((long)rint(dbl))
58#endif
59
60#ifdef _WIN32
61#define lrint(x) (floor(x+(x>0) ? 0.5 : -0.5))
62#endif
63
64#if PROTOTYPE_NEEDED
65int   gribputgds ( GEOM_IN  Geom_In, GDS_HEAD_INPUT *pGDS_Head_Input,
66                void  **ppvGDS_Proj_Input, GRIB_HDR  **ppgrib_hdr,
67                char  *errmsg)
68#else
69int   gribputgds ( Geom_In, pGDS_Head_Input, ppvGDS_Proj_Input, 
70                                                ppgrib_hdr, errmsg)
71                GEOM_IN  Geom_In; 
72                GDS_HEAD_INPUT *pGDS_Head_Input;
73                void  **ppvGDS_Proj_Input; 
74                GRIB_HDR  **ppgrib_hdr;
75                char  *errmsg;
76#endif
77{
78/*
79* A.0       DEFAULT to err stat 1
80*/
81  char            *func= "gribputgds";
82  char            *pgds=0;       /* true grib, GDS_HEAD + Proj block */
83  GDS_HEAD        *pGDS_Head=0;  /* first 6 bytes of PGDS */
84  void            *pvGDS_Proj=0;  /* projection info, PGDS 7th byte and on... */
85  long            lProj_sz ;     /* size of True-Grib projection block  */
86  long            new_msgsz;     /* size after adding GDS */
87  GRIB_HDR        *gh=0;         /* temp ptr to struct */
88  unsigned char   ucflag;
89  int             tempsz, stat=  1;
90
91GDS_LATLON_INPUT *mp;
92
93
94  DPRINT0 ("\nEntering  gribputgds .....\n");
95/*
96*
97* A.1       IF (Grib Hdr is null) THEN
98*               RETURN error Stat !null ptrs msg in errmsg
99*           ENDIF
100*/
101   gh = *ppgrib_hdr; 
102   if (!gh || !gh->entire_msg) {
103        DPRINT1("%s: grib header is null\n", func);
104        sprintf(errmsg,"%s: grib header is null\n", func);
105        goto BYE;
106        }
107
108/*
109*
110* A.3       ALLOCATE space for True Grib Structs GDS_HEAD & VOID *proj;
111*           IF (fails) THEN
112*              RETURN with bad Stat !errmsg filled
113*           ELSE 
114*              CLEAR out structs
115*           ENDIF
116*/
117
118   if (! (pgds= (char *) malloc(sizeof (GDS_HEAD) + MAX_PROJ_SIZE))) { 
119        DPRINT1 ("%s: MALloced true Grib struct failed\n",func);
120        sprintf(errmsg,"%s: MALloced true Grib struct failed\n",func);
121        goto BYE; 
122        }
123   else memset ((void *)pgds, '\0', sizeof(GDS_HEAD) + MAX_PROJ_SIZE);
124
125/*
126*
127* A.4       ASSIGN (GDS_HEAD *pGDS_Head) to be beginning of local PGDS block
128*           ASSIGN (void *pvGDS_Proj) to byte #7 of local PGDS block
129*/
130   pGDS_Head  = (GDS_HEAD *) pgds;
131   pvGDS_Proj = (void *) (pgds + sizeof(GDS_HEAD));
132         
133/*
134*
135* A.5       INIT some fields of GDS_HEAD & GDS_HEAD_INPUT structs
136*/
137   pGDS_Head->chNV          = ( unsigned char ) 0;
138   pGDS_Head->chPV          = ( unsigned char ) 255;
139   pGDS_Head_Input->usNum_v = 0;    /* INPUT NOT USED AT THIS TIME */
140   pGDS_Head_Input->usPl_Pv = 255;   
141
142 
143/*
144*
145*           !now fill true GRIB Grid Defn Sect depending on Projection type
146* A.6.a     IF (projection is Spherical) THEN
147*/
148   if ((strcmp(Geom_In.prjn_name,"spherical")==0) || 
149       (strcmp(Geom_In.prjn_name,"gaussian") == 0)){
150/*
151* A.6.a.1      FUNCTION create_inpLatlon !create internal Latlon struct
152*                                        !using GEOM_IN & USER_INPUT
153* A.6.a.2      FUNCTION inp2grib_Latlon  !use internal Latlon struct to
154*                                        !make true Latlon Grib Gds
155* A.6.a.3      IF (either failed) THEN
156*                  FUNCTION upd_child_errmsg   !tack funcname to errmsg
157*                  RETURN with error     !errmsg filled
158*              ENDIF
159*/
160
161     if ( create_inpLatlon(Geom_In, ppvGDS_Proj_Input,errmsg)
162          || inp2grib_Latlon (ppvGDS_Proj_Input, 
163                       (LATLON *)(pgds+sizeof(GDS_HEAD)),&lProj_sz, errmsg))
164         { 
165          upd_child_errmsg (func, errmsg); goto BYE; 
166         }
167
168/*
169* A.6.a.4      STORE Gds len, DataType=0 into internal GDS struct
170*/
171     pGDS_Head_Input->uslength = sizeof(GDS_HEAD) + lProj_sz;
172     if (strcmp(Geom_In.prjn_name,"spherical")==0) {
173       pGDS_Head_Input->usData_type = LATLON_PRJ;
174       pGDS_Head->chData_type = 0;
175     } else {
176       pGDS_Head_Input->usData_type = GAUSS_PRJ;
177       pGDS_Head->chData_type = 4;
178     }
179   }
180
181/*
182* A.6.b     ELSE IF (projection is Lambert) THEN
183*/
184   else if (strcmp(Geom_In.prjn_name,"lambert")==0)
185   {
186 /*
187* A.6.b.1      FUNCTION create_inpLambert !create internal Lambert struct
188*                                         !using GEOM_IN & USER_INPUT
189* A.6.b.2      FUNCTION inp2grib_Lambert  !use internal Lambert struct to
190*                                         !make true Lambert Grib Gds
191* A.6.b.3      IF (either failed) THEN
192*                  FUNCTION upd_child_errmsg   !tack funcname to errmsg
193*                  RETURN with error           !errmsg filled
194*              ENDIF
195*/
196    if ( create_inpLambert(Geom_In,ppvGDS_Proj_Input,errmsg)
197        || inp2grib_Lambert( ppvGDS_Proj_Input, 
198                    (LAMBERT *)(pgds+sizeof(GDS_HEAD)), &lProj_sz, errmsg))
199         { 
200           upd_child_errmsg (func, errmsg); goto BYE; 
201         }
202
203/*
204* A.6.b.4      STORE Gds len, DataType=3 into internal GDS struct
205*/
206     pGDS_Head_Input->uslength = sizeof(GDS_HEAD) + lProj_sz;
207     pGDS_Head_Input->usData_type = LAMB_PRJ; 
208     pGDS_Head->chData_type = 3;
209   }
210
211/*
212* A.6.c     ELSE if (projection is Polar_Stereo) THEN
213*/
214   else if (strcmp(Geom_In.prjn_name,"polar_stereo")==0)
215   {
216/*
217* A.6.c.1      FUNCTION create_inpPolar
218*              !create internal Polar struct using GEOM_IN & USER_INPUT
219* A.6.c.2      FUNCTION inp2grib_PolarSt
220*              !use internal PolarSt struct to make true PolarSt Grib Gds
221* A.6.c.3      IF (either failed) THEN
222*                  FUNCTION upd_child_errmsg   !tack funcname to errmsg
223*                  RETURN with error           !errmsg filled
224*              ENDIF
225*/
226/* make True Grib PPVGDS_PROJ & SIZE using internal ppvGds_proj_input :  */
227
228     if (create_inpPolar(Geom_In, ppvGDS_Proj_Input,errmsg)
229         || inp2grib_PolarSt(ppvGDS_Proj_Input, 
230                (void *)(pgds+sizeof(GDS_HEAD)),&lProj_sz, errmsg) )
231         { 
232           upd_child_errmsg (func, errmsg); goto BYE; 
233         }
234
235/*
236* A.6.c.4      STORE Gds len, DataType=5 into internal GDS struct
237*/
238     pGDS_Head_Input->uslength = sizeof(GDS_HEAD) + lProj_sz;
239     pGDS_Head_Input->usData_type = POLAR_PRJ; 
240     pGDS_Head->chData_type = 5;
241   }
242
243/*
244* A.6.c     ELSE if (projection is Mercator) THEN
245*/
246   else if (strcmp(Geom_In.prjn_name,"mercator")==0)
247   {
248/*
249* A.6.c.1      FUNCTION create_inpMercator
250*              !create internal Mercator struct using GEOM_IN & USER_INPUT
251* A.6.c.2      FUNCTION inp2grib_Mercator
252*              !use internal Mercator struct to make true PolarSt Grib Gds
253* A.6.c.3      IF (either failed) THEN
254*                  FUNCTION upd_child_errmsg   !tack funcname to errmsg
255*                  RETURN with error           !errmsg filled
256*              ENDIF
257*/
258/* make True Grib PPVGDS_PROJ & SIZE using internal ppvGds_proj_input :  */
259
260     if (create_inpMercator(Geom_In, ppvGDS_Proj_Input,errmsg)
261         || inp2grib_Mercator(ppvGDS_Proj_Input, 
262                (void *)(pgds+sizeof(GDS_HEAD)),&lProj_sz, errmsg) )
263         { 
264           upd_child_errmsg (func, errmsg); goto BYE; 
265         }
266
267/*
268* A.6.c.4      STORE Gds len, DataType=5 into internal GDS struct
269*/
270     pGDS_Head_Input->uslength = sizeof(GDS_HEAD) + lProj_sz;
271     pGDS_Head_Input->usData_type = MERC_PRJ; 
272     pGDS_Head->chData_type = 1;
273   }
274
275/*
276* A.6.d     ELSE   ! Projection unknown
277*/
278   else {
279/*
280*              RETURN with error           !errmsg filled
281*/
282     DPRINT2 ("%s: Projection '%s' unknown\n",func,Geom_In.prjn_name);
283     sprintf (errmsg,"%s: Projection '%s' unknown\n",func,Geom_In.prjn_name);
284     goto BYE;
285/*
286* A.6.d     ENDIF
287*/
288   }
289
290/*
291*
292* A.7       STORE ptr to Gds and its Length in Grib hdr
293*/
294  gh->gds_ptr     = gh->entire_msg + gh->msg_length;
295  gh->gds_len     = sizeof(GDS_HEAD) + lProj_sz;
296  DPRINT3 ("Gds length= (%ld + %ld)= %ld \n", 
297  sizeof(GDS_HEAD), lProj_sz, gh->gds_len);
298
299/*
300*
301* A.8       STORE Gds length in the True Grib GDS block too
302*/
303  set_bytes(gh->gds_len, 3, pGDS_Head->achGDS_length);
304
305/*
306*
307* A.9       IF gribhdr's buffer is too small AND
308*               FUCTION Expand_gribhdr failed
309*           THEN
310*               RETURN with error   !errmsg filled
311*           ENDIF
312*/
313  new_msgsz= gh->msg_length + gh->gds_len;
314
315      if (new_msgsz  > gh->abs_size
316        && Expand_gribhdr (gh, new_msgsz, errmsg) !=0)
317        {
318        upd_child_errmsg (func, errmsg);
319        goto BYE;
320        }
321
322/*
323*
324* A.10      UPDATE Grib Header Struct
325*           !copy true BDS block into Grib Header's Entire_Msg array;
326*           !add gds length to Message length
327*/
328   memcpy ((void *)gh->gds_ptr, (void *)pgds, gh->gds_len);
329   gh->msg_length += gh->gds_len;
330   DPRINT1 ("copying %ld bytes from PGDS to gh->GDS_PTR \n", gh->gds_len);
331/*
332*
333* A.11      CHANGE return Status to no errors
334*/
335   stat = 0;
336
337BYE:
338/*
339*
340* A.12      FREE up storage
341*
342* A.13      RETURN Status
343*/
344   if (pgds) free (pgds);
345   DPRINT3 ("Leaving %s, stat=%d, errmsg='%s'\n", func,stat,errmsg);
346   return stat;
347/*
348*
349* END OF FUNCTION
350*
351*
352*/
353}
354
355/*
356*
357*********************************************************************
358* B. FUNCTION:  create_inpLambert
359*       Fills Lambert Projection structure.
360*
361*    INTERFACE:
362*       int create_inpLambert ( geom_in, ppvGDS_Proj_Input, errmsg)
363*
364*    ARGUMENTS (I=input, O=output, I&O=input and output):
365*     (I)  GEOM_IN geom_in            Holds info to fill local Lambert block
366*     (O)  void **ppvGDS_Proj_Input   pre-allocated block to be filled;
367*     (O)  char *errmsg               returns filled if error occurred
368*
369*     RETURN CODE
370*      0> success, ppvGDS_Proj_Input holds Lambert projection information;
371*      1> the input pre-MAlloced projection block is null;  errmsg filled;
372**********************************************************************/
373
374#if PROTOTYPE_NEEDED
375int create_inpLambert (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg)
376#else
377int create_inpLambert (geom_in, ppvGDS_Proj_Input, errmsg)
378                GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg;
379#endif
380{
381char *func= "create_inpLambert";
382/*
383*
384* B.1       DEFAULT status of 0
385*/
386   int            nStatus = 0;
387   double         cut1, cut2, tmp;
388   GDS_LAM_INPUT  *pGDS_Lam_Input;
389
390   DPRINT1 ( "   Entering %s.....\n", func );
391/*
392*
393* B.2       IF (incoming projection block is Null)
394*           THEN
395*              FILL errmsg
396*              SET return status to error
397*/
398   if (!(pGDS_Lam_Input= (GDS_LAM_INPUT *) *ppvGDS_Proj_Input) )
399     {
400      DPRINT1 ( "%s: ppvGDS_Proj_Input is null\n", func);
401      sprintf(errmsg, "%s: ppvGDS_Proj_Input is null\n", func);
402      nStatus = 1;
403      }
404/*
405* B.2.b     ELSE
406*               USE info from GEOM_IN to fill the Lambert GDS struct
407*/
408   else
409   {
410   pGDS_Lam_Input->usData_type = LAMB_PRJ; /* data type flag (Tbl  ) */
411   pGDS_Lam_Input->iNx = (int) geom_in.nx; /* #pts along x-axis */
412   pGDS_Lam_Input->iNy = (int) geom_in.ny;/* #pts along y-axis */ 
413  /* latitude & lon of 1st grid point */
414   pGDS_Lam_Input->lLat1 = lrint(geom_in.first_lat *1000.); 
415   pGDS_Lam_Input->lLon1 = lrint((geom_in.first_lon) *1000.); 
416   pGDS_Lam_Input->usRes_flag = geom_in.usRes_flag;/*Resolution flags Tbl7*/
417   pGDS_Lam_Input->lLon_orient=lrint(geom_in.parm_3 *1000.);/*grid orient */
418   pGDS_Lam_Input->ulDx=(unsigned long)lrint(geom_in.x_int_dis*1000.);/*Xdir gridlen*/
419   pGDS_Lam_Input->ulDy=(unsigned long)lrint(geom_in.y_int_dis*1000.);/*Ydir gridlen*/
420   if ((geom_in.y_int_dis != 0) && (geom_in.x_int_dis != 0))
421         pGDS_Lam_Input->usRes_flag = pGDS_Lam_Input->usRes_flag + 0x88;
422   if (geom_in.parm_1 > 0) 
423     pGDS_Lam_Input->usProj_flag = 0;              /* projection flag */
424   else
425     pGDS_Lam_Input->usProj_flag = 1<<7;              /* projection flag */
426   pGDS_Lam_Input->usScan_mode = geom_in.scan; /* order of grid points (Tbl8)*/
427  /*  Make sure CUT1 is closest to Pole  */
428   cut1 = geom_in.parm_1;
429   cut2 = geom_in.parm_2;
430   if (cut1 >= 0.) {
431      if (cut2 > cut1) { tmp = cut1; cut1 = cut2; cut2 = tmp; }
432      }
433   else {
434      if (cut2 < cut1) { tmp = cut1; cut1 = cut2; cut2 = tmp; }
435      }
436   
437   pGDS_Lam_Input->lLat_cut1=lrint(cut1 *1000.);/* 1stlat fr pole secant cuts*/
438   pGDS_Lam_Input->lLat_cut2=lrint(cut2 *1000.);/* 2ndlat fr pole secant cuts*/
439   pGDS_Lam_Input->lLat_southpole = -90000; /* lat of southern pole (millidegrees) */
440   pGDS_Lam_Input->lLon_southpole = 0; /* lon of souther pole (millidegrees) */
441   pGDS_Lam_Input->usZero = 0;         /* filler zeroes */
442
443/*
444*               DEBUG print
445*/
446   DPRINT3("\t%s: usData_type = %u (%s)\n",
447   func,pGDS_Lam_Input->usData_type, prjn_name[pGDS_Lam_Input->usData_type] );
448   DPRINT2("\t%s: iNx = %d\n", func,pGDS_Lam_Input->iNx );
449   DPRINT2("\t%s: iNy = %d\n", func,pGDS_Lam_Input->iNy );
450   DPRINT2("\t%s: lLat1 = %d\n", func,pGDS_Lam_Input->lLat1 );
451   DPRINT2("\t%s: lLon1 = %d\n", func,pGDS_Lam_Input->lLon1 );
452   DPRINT2("\t%s: lLon_orient = %d\n", func,pGDS_Lam_Input->lLon_orient);
453   DPRINT2("\t%s: ulDx = %u\n", func, pGDS_Lam_Input->ulDx );
454   DPRINT2("\t%s: ulDy = %u\n", func, pGDS_Lam_Input->ulDy );
455   DPRINT2("\t%s: lLat_cut1 = %d\n", func, pGDS_Lam_Input->lLat_cut1);
456   DPRINT2("\t%s: lLat_cut2 = %d\n", func, pGDS_Lam_Input->lLat_cut2);
457   DPRINT2("\t%s: usRes_flag = %u\n", func,pGDS_Lam_Input->usRes_flag);
458   DPRINT2("\t%s: usProj_flag = %u\n", func,pGDS_Lam_Input->usProj_flag);
459   DPRINT2("\t%s: usScan_mode = %u\n", func,pGDS_Lam_Input->usScan_mode);
460/*
461* B.2       ENDIF
462*/
463   }
464
465   DPRINT1("   Exiting %s.......\n" ,func); 
466/*
467*
468* B.3       RETURN status
469*/
470   return ( nStatus );
471/*
472*
473* END OF FUNCTION
474*
475*
476*/
477}
478
479/*
480*
481*********************************************************************
482* C. FUNCTION:  create_inpPolar
483*      Fills Polar Stereographic Projection structure. 
484*
485*    INTERFACE:
486*      int create_inpPolar (geom_in, ppvGDS_Proj_Input, errmsg)
487*
488*    ARGUMENTS (I=input, O=output, I&O=input and output):
489*      (I) GEOM_IN geom_in          holds info to fill local Polar block
490*      (O) void **ppvGDS_Proj_Input  block to filled with Polar Stereo info
491*      (O) char *errmsg              empty array filled if error occurs
492*
493*    RETURN CODE:
494*       0> success, ppvGDS_Proj_Input holds Polar projection info;
495*       1> the input pre-Malloced projection block is null; errmsg filled;
496**********************************************************************/
497
498#if PROTOTYPE_NEEDED
499int create_inpPolar (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg)
500#else
501int create_inpPolar (geom_in, ppvGDS_Proj_Input, errmsg)
502                GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg;
503#endif
504{
505char    *func="create_inpPolar";
506/*
507*
508* C.1       DEFAULT status of 0
509*/
510   GDS_PS_INPUT   *pGDS_PS_Input;
511   int            nStatus = 0;
512
513   DPRINT1 ("   Entering %s.....\n",func );
514/*
515*
516* C.2       IF (incoming projection block is Null)
517* C.2.a     THEN
518*              FILL errmsg
519*              CHANGE return Status to error
520*/
521   if (!(pGDS_PS_Input= (GDS_PS_INPUT *) *ppvGDS_Proj_Input) )
522     {
523      DPRINT1  ("%s: ppvGDS_Proj_Input is null\n", func);
524      sprintf(errmsg,"%s: ppvGDS_Proj_Input is null\n", func);
525      nStatus = 1;
526      }
527
528   else {
529/*
530* C.2.b     ELSE
531* C.2.b.1      FILL elements of Polar Stereo structure
532*/
533   pGDS_PS_Input->usData_type = POLAR_PRJ;   /* data type flag (Tbl  ) */
534   pGDS_PS_Input->usNx = (unsigned short) geom_in.nx;/* #pts along x-axis*/
535   pGDS_PS_Input->usNy = (unsigned short) geom_in.ny;/* #pts along y-axiz*/ 
536   pGDS_PS_Input->lLat1 = lrint(geom_in.first_lat *1000.);/*lat of 1st gridpt*/
537   pGDS_PS_Input->lLon1 = lrint(geom_in.first_lon *1000.);/*lon of 1st gridpt*/
538   pGDS_PS_Input->usRes_flag = geom_in.usRes_flag;/* resolution flags Tbl7 */
539   pGDS_PS_Input->lLon_orient = lrint(geom_in.parm_2 *1000.);/*grid orient*/
540   pGDS_PS_Input->ulDx=(unsigned long)lrint(geom_in.x_int_dis*1000.);/*Xdir gridlen*/
541   pGDS_PS_Input->ulDy=(unsigned long)lrint(geom_in.y_int_dis*1000.);/*Ydir gridlen*/
542   if ((geom_in.y_int_dis != 0) && (geom_in.x_int_dis != 0))
543         pGDS_PS_Input->usRes_flag = pGDS_PS_Input->usRes_flag + 0x88;
544   if (geom_in.first_lat > 0) 
545     pGDS_PS_Input->usProj_flag = 0;  /* projection flag */
546   else 
547     pGDS_PS_Input->usProj_flag = 1<<7;  /* projection flag */
548
549   pGDS_PS_Input->usScan_mode = geom_in.scan; /* order of grid points (Tbl 8) */
550   pGDS_PS_Input->usZero = 0;       /* filler zeroes */
551
552/*
553* C.2.b.2      DEBUG print
554*/
555   DPRINT3 ("\t%s: usData_type = %u (%s)\n",func,pGDS_PS_Input->usData_type,
556   prjn_name [pGDS_PS_Input->usData_type] );
557   DPRINT2("\t%s: usNx = %u\n", func,pGDS_PS_Input->usNx );
558   DPRINT2("\t%s: usNy = %u\n", func,pGDS_PS_Input->usNy );
559   DPRINT2("\t%s: lLat1 = %d\n", func,pGDS_PS_Input->lLat1 );
560   DPRINT2("\t%s: lLon1 = %d\n", func,pGDS_PS_Input->lLon1 );
561   DPRINT2("\t%s: lLon_orient = %d\n", func,pGDS_PS_Input->lLon_orient);
562   DPRINT2("\t%s: ulDx = %u\n", func,pGDS_PS_Input->ulDx);
563   DPRINT2("\t%s: ulDy = %u\n", func,pGDS_PS_Input->ulDy);
564   DPRINT2("\t%s: usRes_flag = %u\n", func,pGDS_PS_Input->usRes_flag);
565   DPRINT2("\t%s: usProj_flag = %u\n", func,pGDS_PS_Input->usProj_flag);
566   DPRINT2("\t%s: usScan_mode = %u\n", func,pGDS_PS_Input->usScan_mode);
567/*
568* C.2.b     ENDIF
569*/
570   }
571
572   DPRINT1("   Exiting %s.......\n" ,func); 
573/*
574*
575* C.3       RETURN status
576*/
577   return ( nStatus );
578/*
579*
580* END OF FUNCTION
581*
582*
583*/
584}
585
586
587/*
588*
589*********************************************************************
590* D. FUNCTION:  create_inpLatlon
591*       Fills Latitude Longitude Projection structure. 
592*
593*    INTERFACE:
594*       int create_inpLatlon ( geom_in, ppvGDS_Proj_Input, errmsg)
595*
596*    ARGUMENTS (I=input, O=output, I&O=input and output):
597*      (I) GEOM_IN geom_in           holds geom info to fill local Lat/Lon block
598*      (O) void **ppvGDS_Proj_Input  to be filled with LatLon projection info
599*      (O) char *errmsg              empty array, filled if error occurred
600*
601*     OUTPUT:
602*       0> success, ppGDS_Proj_Input filled with Lat/Lon projection info
603*       1> pre-Malloced Projection block is null;  errmsg filled;
604**********************************************************************/
605
606#if PROTOTYPE_NEEDED
607int create_inpLatlon (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg)
608#else
609int create_inpLatlon (geom_in, ppvGDS_Proj_Input, errmsg)
610                GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg;
611#endif
612{
613char *func= "Create_InpLatLon";
614/*
615*
616* D.0       DEFAULT to return status of 0
617*/
618   GDS_LATLON_INPUT  *pGDS_Latlon_Input;
619   int            nStatus = 0;
620
621   DPRINT1 ("  Entering %s......\n" ,func);
622/*
623*
624* D.2       IF (incoming projection block is Null)
625*           THEN
626*              FILL errmsg
627*              CHANGE stat to 1
628*/
629   if (!(pGDS_Latlon_Input= (GDS_LATLON_INPUT *) *ppvGDS_Proj_Input) )
630     {
631      DPRINT1 (" %s: ppvGDS_Proj_Input is null\n", func);
632      sprintf(errmsg," %s: ppvGDS_Proj_Input is null\n", func);
633      nStatus = 1; 
634        } 
635/*
636* D.2.b     ELSE
637* D.2.b.1      FILL elements of the Lat/Lon GDS block
638*/
639   else
640   {
641   
642   pGDS_Latlon_Input->usData_type = LATLON_PRJ;  /* data type flag (Tbl  )*/
643   pGDS_Latlon_Input->usNi=(unsigned short)geom_in.nx;/*#pts along x-axis 109*/
644   pGDS_Latlon_Input->usNj=(unsigned short)geom_in.ny;/* #pts along y-axiz 82*/
645   pGDS_Latlon_Input->lLat1=lrint(geom_in.first_lat*1000.);/*lat of 1stgridpt*/
646   pGDS_Latlon_Input->lLon1=lrint(geom_in.first_lon*1000.);/*lon of 1stgridpt*/
647   pGDS_Latlon_Input->usRes_flag=geom_in.usRes_flag;/*resolution flags Tbl7*/
648   pGDS_Latlon_Input->lLat2 =lrint(geom_in.last_lat*1000.);/*lat of 2ndgridpt*/
649   pGDS_Latlon_Input->lLon2 =lrint(geom_in.last_lon*1000.);/*lon of 2ndgridpt*/
650   pGDS_Latlon_Input->iDi = lrint(geom_in.parm_2 *1000.);/* i-dir incr*/
651   pGDS_Latlon_Input->iDj = lrint(geom_in.parm_1 *1000.);/* j-dir incr*/
652   if ((geom_in.parm_1 != 0) && (geom_in.parm_2 != 0))
653         pGDS_Latlon_Input->usRes_flag = pGDS_Latlon_Input->usRes_flag + 0x88;
654   pGDS_Latlon_Input->usScan_mode = geom_in.scan; /* order ofgridpts (Tbl 8)*/
655   pGDS_Latlon_Input->usZero = 0;  /* filler zeroes*/
656   pGDS_Latlon_Input->lLat_southpole= -90000;/* lat of southern pole (millidegrees)*/
657   pGDS_Latlon_Input->lLon_southpole= 0;/* lon of southern pole (millidegrees)*/
658   pGDS_Latlon_Input->lRotate = 0;/* angle of rotation*/
659   pGDS_Latlon_Input->lPole_lat = 0;/* lat of pole of stretching (mdeg)*/
660   pGDS_Latlon_Input->lPole_lon = 0; /* lon of pole of stretching*/
661   pGDS_Latlon_Input->lStretch = 0;/* stretching factor*/
662
663/*
664* D.2.b.2      DEBUG print
665*/
666   DPRINT3("\t%s: usData_type = %u (%s)\n", func,pGDS_Latlon_Input->usData_type,
667        prjn_name[pGDS_Latlon_Input->usData_type] );
668   DPRINT2("\t%s: usNi = %u\n",func,pGDS_Latlon_Input->usNi );
669   DPRINT2("\t%s: usNj = %u\n",func,pGDS_Latlon_Input->usNj );
670   DPRINT2("\t%s: lLat1 = %d\n",func,pGDS_Latlon_Input->lLat1 );
671   DPRINT2("\t%s: lLon1 = %d\n",func,pGDS_Latlon_Input->lLon1 );
672   DPRINT2("\t%s: lLat2 = %d\n",func,pGDS_Latlon_Input->lLat2 );
673   DPRINT2("\t%s: lLon2 = %d\n",func,pGDS_Latlon_Input->lLon2 );
674   DPRINT2("\t%s: iDi = %u\n",func,pGDS_Latlon_Input->iDi );
675   DPRINT2("\t%s: iDj = %u\n",func,pGDS_Latlon_Input->iDj );
676   DPRINT2("\t%s: usRes_flag = %u\n",func,pGDS_Latlon_Input->usRes_flag );
677   DPRINT2("\t%s: usScan_mode = %u\n",func,pGDS_Latlon_Input->usScan_mode );
678   DPRINT2("\t%s: lLat_southpole = %ld\n",func,pGDS_Latlon_Input->lLat_southpole);
679   DPRINT2("\t%s: lLon_southpole = %ld\n",func,pGDS_Latlon_Input->lLon_southpole);
680   DPRINT2("\t%s: lRotate = %ld\n",func,pGDS_Latlon_Input->lRotate );
681   DPRINT2("\t%s: lPole_lat = %ld\n",func,pGDS_Latlon_Input->lPole_lat );
682   DPRINT2("\t%s: lPole_lon = %ld\n",func,pGDS_Latlon_Input->lPole_lon );
683   DPRINT2("\t%s: lStretch = %ld\n",func,pGDS_Latlon_Input->lStretch );
684/*
685* D.2.b    ENDIF
686*/
687   }
688/*
689*
690* D.3      RET2URN status
691*/
692   DPRINT1("   Exiting %s.......\n" ,func); 
693   return ( nStatus );
694/*
695* END OF FUNCTION
696*
697*/ 
698}
699
700/*
701*
702*********************************************************************
703* FUNCTION:  create_inpMercator
704*      Fills Mercator Projection structure. 
705*
706*    INTERFACE:
707*      int create_inpMercator (geom_in, ppvGDS_Proj_Input, errmsg)
708*
709*    ARGUMENTS (I=input, O=output, I&O=input and output):
710*      (I) GEOM_IN geom_in          holds info to fill local Mercator block
711*      (O) void **ppvGDS_Proj_Input  block to filled with Mercator info
712*      (O) char *errmsg              empty array filled if error occurs
713*
714*    RETURN CODE:
715*       0> success, ppvGDS_Proj_Input holds Mercator projection info;
716*       1> the input pre-Malloced projection block is null; errmsg filled;
717**********************************************************************/
718
719#if PROTOTYPE_NEEDED
720int create_inpMercator (GEOM_IN geom_in, void **ppvGDS_Proj_Input, char *errmsg)
721#else
722int create_inpMercator (geom_in, ppvGDS_Proj_Input, errmsg)
723                GEOM_IN geom_in; void **ppvGDS_Proj_Input; char *errmsg;
724#endif
725{
726char    *func="create_inpMercator";
727/*
728*
729* C.1       DEFAULT status of 0
730*/
731   mercator       *pGDS_mercator_Input;
732   int            nStatus = 0;
733
734   DPRINT1 ("   Entering %s.....\n",func );
735/*
736*
737* C.2       IF (incoming projection block is Null)
738* C.2.a     THEN
739*              FILL errmsg
740*              CHANGE return Status to error
741*/
742   if (!(pGDS_mercator_Input= (mercator *) *ppvGDS_Proj_Input) )
743     {
744      DPRINT1  ("%s: ppvGDS_Proj_Input is null\n", func);
745      sprintf(errmsg,"%s: ppvGDS_Proj_Input is null\n", func);
746      nStatus = 1;
747      }
748
749   else {
750/*
751* C.2.b     ELSE
752* C.2.b.1      FILL elements of Polar Stereo structure
753*/
754   pGDS_mercator_Input->usData_type = MERC_PRJ;   /* data type flag (Tbl  ) */
755   pGDS_mercator_Input->cols = (unsigned short) geom_in.nx;/* #pts along x-axis*/
756   pGDS_mercator_Input->rows = (unsigned short) geom_in.ny;/* #pts along y-axiz*/ 
757   pGDS_mercator_Input->first_lat = lrint(geom_in.first_lat *1000.);/*lat of 1st gridpt*/
758   pGDS_mercator_Input->first_lon = lrint(geom_in.first_lon *1000.);/*lon of 1st gridpt*/
759   pGDS_mercator_Input->usRes_flag = geom_in.usRes_flag;/* resolution flags Tbl7 */
760   pGDS_mercator_Input->La2 = lrint(geom_in.last_lat *1000.);/*lat of last gridpt*/
761   pGDS_mercator_Input->Lo2 = lrint(geom_in.last_lon *1000.);/*lon of last gridpt*/
762   pGDS_mercator_Input->latin = lrint(geom_in.parm_1 *1000.);/*reference latitude*/
763   pGDS_mercator_Input->usZero1 = 0; /* filler zeroes */
764   pGDS_mercator_Input->usScan_mode = geom_in.scan; /* order of grid points (Tbl 8) */
765   pGDS_mercator_Input->lon_inc = lrint(geom_in.parm_2 *1000.);/*longitude increment*/
766   pGDS_mercator_Input->lat_inc = lrint(geom_in.parm_3 *1000.);/*latitude increment*/
767   pGDS_mercator_Input->usZero = 0;  /* filler zeroes */
768
769/*
770* C.2.b.2      DEBUG print
771*/
772   DPRINT3 ("\t%s: usData_type = %u (%s)\n",func,pGDS_mercator_Input->usData_type,
773   prjn_name [pGDS_mercator_Input->usData_type] );
774   DPRINT2("\t%s: cols = %u\n", func,pGDS_mercator_Input->cols );
775   DPRINT2("\t%s: rows = %u\n", func,pGDS_mercator_Input->rows );
776   DPRINT2("\t%s: first_lat = %d\n", func,pGDS_mercator_Input->first_lat );
777   DPRINT2("\t%s: first_lon = %d\n", func,pGDS_mercator_Input->first_lon );
778   DPRINT2("\t%s: usRes_flag = %d\n", func,pGDS_mercator_Input->usRes_flag);
779   DPRINT2("\t%s: La2 = %d\n", func,pGDS_mercator_Input->La2);
780   DPRINT2("\t%s: Lo2 = %d\n", func,pGDS_mercator_Input->Lo2);
781   DPRINT2("\t%s: latin = %d\n", func,pGDS_mercator_Input->latin);
782   DPRINT2("\t%s: usZero1 = %d\n", func,pGDS_mercator_Input->usZero1);
783   DPRINT2("\t%s: usScan_mode = %d\n", func,pGDS_mercator_Input->usScan_mode);
784   DPRINT2("\t%s: lon_inc = %f\n", func,pGDS_mercator_Input->lon_inc);
785   DPRINT2("\t%s: lat_inc = %f\n", func,pGDS_mercator_Input->lat_inc);
786/*
787* C.2.b     ENDIF
788*/
789   }
790
791   DPRINT1("   Exiting %s.......\n" ,func); 
792/*
793*
794* C.3       RETURN status
795*/
796   return ( nStatus );
797/*
798*
799* END OF FUNCTION
800*
801*
802*/
803}
804
805
806
807
808
809
810
811
812/*
813*
814****************************************************************************
815* E. FUNCTION:  inp2gribLambert
816*      This routine fills the special Lambert Projection structure for
817*      the GDS.
818*
819*    INTERFACE:
820*       int inp2grib_Lambert (ppvGDS_Proj_Input, pLambert, lProj_size, errmsg)
821*
822*    ARGUMENTS (I=input, O=output, I&O=input and output):
823*      (I) void  **ppvGDS_Proj_Input;
824*          pointer to struct holds Input Projection data
825*      (O) LAMBERT *pLambert;
826*          block to be filled with Lambert Projection information
827*      (O) long  *lProj_size;
828*          to be filled with size of LAMBERT struct;
829*      (O) char *errmsg;
830*          empty array, filled if error occurred;
831*
832*    RETURN CODE:
833*      0> success,  pLambert and lProj_size filled;
834*      1> got null pointers; errmsg filled;
835****************************************************************************/
836
837#if PROTOTYPE_NEEDED
838int   inp2grib_Lambert (void **ppvGDS_Proj_Input, LAMBERT  *pLambert,
839                        long *lProj_size, char *errmsg)
840#else
841int   inp2grib_Lambert (ppvGDS_Proj_Input, pLambert, lProj_size, errmsg)
842                        void **ppvGDS_Proj_Input; LAMBERT  *pLambert;
843                        long *lProj_size; char *errmsg;
844#endif
845{
846/*
847* E.1       INIT status to success
848*
849* E.2       DEBUG printing
850*/
851   GDS_LAM_INPUT     *vProjInp = 0;
852   long              lTemp = 0;
853   int               nStatus = 0;
854   char              *func= "inp2grib_Lambert";
855   long              tmp_byte4;
856   DPRINT1 ("   Entering %s.....\n",func);
857
858/*
859*
860* E.3       MAKE local ptr vProjInp point to Input Projection data block arg
861*/
862   vProjInp = ( GDS_LAM_INPUT * ) *ppvGDS_Proj_Input;    /* read fr this */
863
864/*
865*
866* E.4       IF (either of the user's struct pointers are NUL) THEN
867*              SET status = 1
868*              RETURN
869*           ENDIF
870*/
871   if (!vProjInp || !pLambert)   {
872        DPRINT1 ("%s: the VOID *ppvGDS_Proj_Input block is null\n",func);
873        sprintf(errmsg, "%s: the VOID *ppvGDS_Proj_Input block is null\n",func);
874        nStatus=  1; 
875        goto BYE; 
876        }
877
878/*
879* E.5       FILL local block type LAMBERT
880*/
881 
882      set_bytes(vProjInp->iNx, 2, pLambert->achNx);
883     
884      set_bytes(vProjInp->iNy, 2, pLambert->achNy);
885
886/* convert lLat1 to 3chars */
887      set_bytes(vProjInp->lLat1, 3, pLambert->achLat1);
888
889/* convert lLon1 to 3chars */
890      set_bytes(vProjInp->lLon1, 3, pLambert->achLon1);
891
892      pLambert->chRes_flag = ( unsigned char ) vProjInp->usRes_flag;
893
894/* convert lLon_orient to 3 bytes */
895      set_bytes(vProjInp->lLon_orient, 3, pLambert->achLon_orient);
896
897/* convert ulDx to 3 bytes */
898      set_bytes(vProjInp->ulDx, 3, pLambert->achDx);
899   
900/* convert ulDy to 3 bytes */
901      set_bytes(vProjInp->ulDy, 3, pLambert->achDy);
902
903      pLambert->chProj_flag = ( unsigned char ) vProjInp->usProj_flag;
904      pLambert->chScan_mode = ( unsigned char ) vProjInp->usScan_mode;
905
906/* convert lLat_cut1 to 3 chars */
907      set_bytes(vProjInp->lLat_cut1, 3, pLambert->achLat_cut1);
908
909/* convert lLat_cut2 to 3 chars */
910      set_bytes(vProjInp->lLat_cut2, 3, pLambert->achLat_cut2);
911
912/* convert lLat_southpole to 3chars */
913      set_bytes(vProjInp->lLat_southpole, 3, pLambert->achLat_southpole);
914
915/* convert lLon_southpole to 3 chars */
916      set_bytes(vProjInp->lLon_southpole, 3, pLambert->achLon_southpole);
917
918      set_bytes(vProjInp->usZero, 2, pLambert->achZero);
919
920/*
921*
922* E.6       DEBUG print Grib LAMBERT block
923*/
924  DPRINT3("\t%s: achNx [%02d,%02d]\n", func,
925  pLambert->achNx[0],pLambert->achNx[1]);
926  DPRINT3("\t%s: achNy [%02d,%02d]\n", func, 
927  pLambert->achNy[0],pLambert->achNy[1]);
928  DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n", func, 
929  pLambert->achLat1[0], pLambert->achLat1[1], pLambert->achLat1[2]);
930  DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n", func,
931  pLambert->achLon1[0], pLambert->achLon1[1], pLambert->achLon1[2]);
932  DPRINT2("\t%s: chRes_flag [%02d]\n", func, pLambert->chRes_flag);
933  DPRINT4("\t%s: achLon_orient [%02d,%02d,%02d]\n", func, 
934  pLambert->achLon_orient[0], pLambert->achLon_orient[1], 
935  pLambert->achLon_orient[2]);
936  DPRINT4("\t%s: achDx [%02d,%02d,%02d]\n", func,
937  pLambert->achDx[0], pLambert->achDx[1], pLambert->achDx[2]);
938  DPRINT4("\t%s: achDy [%02d,%02d,%02d]\n", func, 
939  pLambert->achDy[0], pLambert->achDy[1], pLambert->achDy[2]);
940  DPRINT2("\t%s: chProj_flag [%02d]\n", func, pLambert->chProj_flag);
941  DPRINT2("\t%s: chScan_mode [%02d]\n", func, pLambert->chScan_mode);
942  DPRINT4("\t%s: achLat_cut1 [%02d,%02d,%02d]\n", func, 
943  pLambert->achLat_cut1[0], 
944  pLambert->achLat_cut1[1], pLambert->achLat_cut1[2]);
945  DPRINT4("\t%s: achLat_cut2 [%02d,%02d,%02d]\n", func, 
946  pLambert->achLat_cut2[0], 
947  pLambert->achLat_cut2[1], pLambert->achLat_cut2[2]);
948  DPRINT4("\t%s: achLat_southpole [%02d,%02d,%02d]\n",func,
949  pLambert->achLat_southpole[0], 
950  pLambert->achLat_southpole[1], pLambert->achLat_southpole[2] );
951  DPRINT4("\t%s: achLon_southpole [%02d,%02d,%02d]\n",func,
952  pLambert->achLon_southpole[0], 
953  pLambert->achLon_southpole[1], pLambert->achLon_southpole[2] );
954  DPRINT3("\t%s: achZero [%02d,%02d]\n", func, 
955  pLambert->achZero[0], pLambert->achZero[1]);
956/*******/
957
958/*
959*
960* E.7       STORE proj size of LAMBERT struct in  lProj_size
961*/
962     
963      *lProj_size = sizeof (LAMBERT);
964
965BYE:
966      DPRINT3 ("   Exiting %s (lProj_size=%ld), stat=%d\n", func,
967      *lProj_size, nStatus);
968/*
969*
970* E.9       RETURN status
971*/
972   return ( nStatus );
973/*
974*
975* END OF FUNCTION
976*/ 
977}
978
979/*
980*
981****************************************************************************
982* F. FUNCTION:  inp2grib_PolarSt
983*      This routine fills the special Polar Stereo Projection structure for
984*      the GDS.
985*
986*    INTERFACE:
987*       int inp2grib_PolarSt ( ppvGDS_Proj_Input, Polar, lProj_size ,errmsg)
988*
989*    ARGUMENTS (I=input, O=output, I&O=input and output):
990*      (I) void **ppvGDS_Proj_Input; 
991*          holds input projection data
992*      (O) POLAR *Polar;               
993*          to be filled with Polar Stereographic projection info
994*      (O) long *lProj_size;       
995*          to be filled with size of structure POLAR
996*      (O) char *errmsg             
997*          empty array, filled if error occurred
998*
999*   RETURN CODE:
1000*      0> success, Polar and lProj_size filled;
1001*      1> pointers are null, errmsg filled;
1002****************************************************************************/
1003
1004#if PROTOTYPE_NEEDED
1005int   inp2grib_PolarSt  (void **ppvGDS_Proj_Input, POLAR *Polar, 
1006                        long *lProj_size , char *errmsg)
1007#else
1008int   inp2grib_PolarSt  (ppvGDS_Proj_Input, Polar, lProj_size , errmsg)
1009                        void **ppvGDS_Proj_Input; POLAR *Polar; 
1010                        long *lProj_size ; char *errmsg;
1011#endif
1012{
1013/*
1014*
1015* F.1       INIT variables !default stat=good
1016*/
1017   GDS_PS_INPUT      *pProjInp = 0;
1018   int               lTemp = 0;
1019   int               nStatus = 0;
1020   char              *func="inp2grib_PolarSt";
1021
1022   DPRINT1 ("\t Entering %s.....\n", func);
1023/*
1024*
1025* F.2       POINT local pProjInp to incoming ppvGDS_Proj_Input
1026*/
1027   pProjInp = ( GDS_PS_INPUT *) *ppvGDS_Proj_Input;
1028
1029/*
1030*
1031* F.3       IF (true grib Polar proj block OR input Polar block is null) THEN
1032*               SET Status=  1
1033*               RETURN;
1034*           ENDIF
1035*/
1036    if (!Polar || !pProjInp ) 
1037        {
1038        DPRINT1 ( "%s:  Polar or pProjInp is null\n", func);
1039        sprintf(errmsg,"%s:  Polar or pProjInp is null\n", func);
1040        nStatus=  1; goto BYE; 
1041        }
1042
1043/*
1044*
1045* F.4        FILL local struct from pProjInp
1046*/
1047/* convert usNx to 2 chars */
1048      set_bytes(pProjInp->usNx, 2, Polar->achNx);
1049   
1050/* convert usNy to 2 chars */
1051      set_bytes(pProjInp->usNy, 2, Polar->achNy);
1052
1053/* convert lLat1 to 3 chars */
1054      set_bytes(pProjInp->lLat1, 3, Polar->achLat1);
1055
1056/* convert lLon1 to 3 chars */
1057      set_bytes(pProjInp->lLon1, 3, Polar->achLon1);
1058
1059      Polar->chRes_flag = ( unsigned char ) pProjInp->usRes_flag;
1060
1061/* convert lLon_orient to 3 chars */
1062      set_bytes(pProjInp->lLon_orient, 3, Polar->achLon_orient);
1063
1064/* convert ulDx to 3 char */
1065      set_bytes(pProjInp->ulDx, 3, Polar->achDx);
1066   
1067/* convert ulDy to 3chars */
1068      set_bytes(pProjInp->ulDy, 3, Polar->achDy);
1069
1070      Polar->chProj_flag = ( unsigned char ) pProjInp->usProj_flag;
1071      Polar->chScan_mode = ( unsigned char ) pProjInp->usScan_mode;
1072
1073/* 4 bytes of zero */
1074      memset((void*) Polar->achZero, '\0', 4);
1075
1076/*
1077*
1078* F.5       DEBUG print GRIB Projection block
1079*/
1080  DPRINT3("\t%s: achNx [%02d,%02d]\n",func, Polar->achNx[0],Polar->achNx[1]);
1081  DPRINT3("\t%s: achNy [%02d,%02d]\n",func, Polar->achNy[0],Polar->achNy[1]);
1082  DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n",func, Polar->achLat1[0],
1083  Polar->achLat1[1], Polar->achLat1[2]);
1084  DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n",func, Polar->achLon1[0],
1085   Polar->achLon1[1] , Polar->achLon1[2]);
1086  DPRINT2("\t%s: chRes_flag [%02d]\n",func, Polar->chRes_flag);
1087  DPRINT4("\t%s: achLon_orient [%02d,%02d,%02d]\n",func, 
1088  Polar->achLon_orient[0], Polar->achLon_orient[1], Polar->achLon_orient[2]);
1089  DPRINT4("\t%s: achDx [%02d,%02d,%02d]\n",func, Polar->achDx[0],
1090  Polar->achDx[1], Polar->achDx[2]);
1091  DPRINT4("\t%s: achDy [%02d,%02d,%02d]\n",func, Polar->achDy[0],
1092  Polar->achDy[1], Polar->achDy[2]);
1093  DPRINT2("\t%s: chProj_flag [%02d]\n",func, Polar->chProj_flag);
1094  DPRINT2("\t%s: chScan_mode [%02d]\n",func, Polar->chScan_mode);
1095  DPRINT5("\t%s: achZero [%02d,%02d,%02d,%02d]\n",func, Polar->achZero[0],
1096  Polar->achZero[1],  Polar->achZero[2],  Polar->achZero[3]);
1097/*******/
1098
1099/*
1100*
1101* F.7        STORE size of POLAR struct in lProj_size
1102*/
1103      *lProj_size = sizeof (POLAR);
1104
1105BYE:
1106   DPRINT3 ("   Exiting %s (lProj_size=%ld), stat=%d\n", func,
1107      *lProj_size, nStatus);
1108/*
1109*
1110* F.8       RETURN Stat  ! 0 or  1
1111*/
1112   return ( nStatus );
1113/*
1114*
1115* END OF FUNCTION
1116*
1117*
1118*/ 
1119}
1120
1121/*
1122*
1123****************************************************************************
1124* G. FUNCTION:  inp2grib_Latlon
1125*      This routine fills the Latitude Longitude Projection structure for
1126*      the GDS.
1127*
1128*    INTERFACE:
1129*       int inp2grib_Latlon ( ppvGDS_Proj_Input, pLatlon, lProj_size ,errmsg)
1130*
1131*    ARGUMENTS (I=input, O=output, I&O=input and output):
1132*      (I) void **ppvGDS_Proj_Input; 
1133*          holds input projection data
1134*      (O) LATLON *pLatlon;
1135*          to be filled with Lat/Lon projection info
1136*      (O) long *lProj_size;       
1137*          to be filled with size of structure LATLON
1138*      (O) char *errmsg;
1139*          empty array, filled if error occurred
1140*
1141*    RETURN CODE:
1142*      0>  success, pLatlon and lProj_size filled;
1143*      1>  got null pointers, errmsg filled;
1144****************************************************************************/
1145#if PROTOTYPE_NEEDED
1146int    inp2grib_Latlon  (void **ppvGDS_Proj_Input, LATLON *pLatlon,
1147                        long *lProj_size, char *errmsg)
1148#else
1149int    inp2grib_Latlon  (ppvGDS_Proj_Input, pLatlon, lProj_size, errmsg)
1150                        void **ppvGDS_Proj_Input; LATLON *pLatlon;
1151                        long *lProj_size; char *errmsg;
1152#endif
1153{
1154   GDS_LATLON_INPUT  *Inp = 0;
1155   int               lTemp = 0;
1156   char         *func= "inp2grib_Latlon";
1157/*
1158*
1159* G.1       INIT status to success
1160*/
1161   int               nStatus = 0;
1162   DPRINT1 ( "   Entering %s.....\n", func );
1163/*
1164*
1165* G.2        ASSIGN arguments to local pointers
1166*/
1167  Inp  = (GDS_LATLON_INPUT *) *ppvGDS_Proj_Input;
1168/*
1169   DPRINT3("\n%s: usData_type = %u (%s)\n", func, Inp->usData_type,
1170   prjn_name[Inp->usData_type] );
1171   DPRINT2("\t%s: usNi = %u\n",func, Inp->usNi );
1172   DPRINT2("\t%s: usNj = %u\n",func, Inp->usNj );
1173   DPRINT2("\t%s: lLat1 = %d\n",func, Inp->lLat1 );
1174   DPRINT2("\t%s: lLon1 = %d\n",func, Inp->lLon1 );
1175   DPRINT2("\t%s: lLat2 = %d\n",func, Inp->lLat2 );
1176   DPRINT2("\t%s: lLon2 = %d\n",func, Inp->lLon2 );
1177   DPRINT2("\t%s: iDi = %u\n",func, Inp->iDi );
1178   DPRINT2("\t%s: iDj = %u\n",func, Inp->iDj );
1179   DPRINT2("\t%s: usRes_flag = %u\n",func, Inp->usRes_flag );
1180   DPRINT2("\t%s: usScan_mode = %u\n",func, Inp->usScan_mode );
1181   DPRINT2("\t%s: lLat_southpole = %ld\n",func, Inp->lLat_southpole);
1182   DPRINT2("\t%s: lLon_southpole = %ld\n",func, Inp->lLon_southpole);
1183   DPRINT2("\t%s: lRotate = %ld\n",func, Inp->lRotate );
1184   DPRINT2("\t%s: lPole_lat = %ld\n",func, Inp->lPole_lat );
1185   DPRINT2("\t%s: lPole_lon = %ld\n",func, Inp->lPole_lon );
1186   DPRINT2("\t%s: lStretch = %ld\n",func, Inp->lStretch );
1187*/
1188
1189/*
1190*
1191* G.3        IF (pointers passed in are null) THEN
1192*                SET status to  1
1193*                RETURN
1194*            ENDIF
1195*/
1196  if ( !Inp || !pLatlon) { 
1197           DPRINT1 ("%s:  lLatlon_inp || pLatlon is null\n",func);
1198           sprintf(errmsg, "%s:  lLatlon_inp || pLatlon is null\n", func);
1199           nStatus =  1; 
1200           goto BYE; 
1201         }
1202
1203/*
1204*
1205* G.4       FILL local struct from Inp
1206*/
1207/* convert usNi & usNj to 2 chars */
1208      set_bytes(Inp->usNi, 2, pLatlon->achNi);
1209
1210      set_bytes(Inp->usNj, 2, pLatlon->achNj);
1211   
1212/* convert lLat1 to 3chars */
1213      set_bytes(Inp->lLat1, 3, pLatlon->achLat1);
1214
1215/* convert lLon1 to 3chars */
1216      set_bytes(Inp->lLon1, 3, pLatlon->achLon1);
1217
1218      pLatlon->chRes_flag = ( unsigned char ) Inp->usRes_flag;
1219
1220/* convert lLat2 to 3chars */
1221      set_bytes(Inp->lLat2, 3, pLatlon->achLat2);
1222
1223/* convert lLon2 to 3chars */
1224      set_bytes(Inp->lLon2, 3, pLatlon->achLon2);
1225
1226/* convert lon increment to 2chars */
1227      set_bytes(Inp->iDi, 2, pLatlon->achDi);
1228
1229/* convert lat increment to 2chars */
1230      set_bytes(Inp->iDj, 2, pLatlon->achDj);
1231
1232/* 1 byte scan mode */
1233      pLatlon->chScan_mode = ( unsigned char ) Inp->usScan_mode;
1234
1235/* 4 bytes of reserved zero */
1236      memset ((void*)pLatlon->achZero, '\0', 4);
1237
1238/* convert lLat_southpole to 3chars */
1239      set_bytes(Inp->lLat_southpole, 3, pLatlon->achLat_southpole);
1240
1241/* convert lLon_southpole to 3chars */
1242      set_bytes(Inp->lLon_southpole, 3, pLatlon->achLon_southpole);
1243
1244/* convert lRotate to 4chars */
1245      set_bytes(Inp->lRotate, 4, pLatlon->achRotate);
1246
1247/* convert lPole_lat to 3chars */
1248      set_bytes(Inp->lPole_lat, 3, pLatlon->achPole_lat);
1249
1250/* convert lPole_lon to 3chars */
1251      set_bytes(Inp->lPole_lon, 3, pLatlon->achPole_lon);
1252
1253/* convert lStretch to 4 chars */
1254      set_bytes(Inp->lStretch, 4, pLatlon->achStretch);
1255
1256/*
1257*
1258* G.5       DEBUG print Input Proj Block & their equivalence in the Char array;
1259*/
1260  DPRINT3("\t%s: achNi [%02d,%02d]\n",func,pLatlon->achNi[0],pLatlon->achNi[1]);
1261  DPRINT3("\t%s: achNj [%02d,%02d]\n",func,pLatlon->achNj[0],pLatlon->achNj[1]);
1262  DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n", 
1263        func, pLatlon->achLat1[0],pLatlon->achLat1[1],pLatlon->achLat1[2]);
1264  DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n", func, 
1265        pLatlon->achLon1[0],pLatlon->achLon1[1],pLatlon->achLon1[2]);
1266  DPRINT2("\t%s: chRes_flag [%02d]\n", func, pLatlon->chRes_flag        );
1267  DPRINT4("\t%s: achLat2 [%02d,%02d,%02d]\n", 
1268        func, pLatlon->achLat2[0], pLatlon->achLat2[1], pLatlon->achLat2[2]);
1269  DPRINT4("\t%s: achLon2 [%02d,%02d,%02d]\n", 
1270        func, pLatlon->achLon2[0], pLatlon->achLon2[1], pLatlon->achLon2[2]);
1271  DPRINT3("\t%s: achDi [%02d,%02d]\n",func,pLatlon->achDi[0],pLatlon->achDi[1]);
1272  DPRINT3("\t%s: achDj [%02d,%02d]\n",func,pLatlon->achDj[0],pLatlon->achDj[1]);
1273  DPRINT2("\t%s: chScan_mode [%02d]\n", func, pLatlon->chScan_mode);
1274  DPRINT5("\t%s: achZero [%02d,%02d,%02d,%02d]\n", 
1275        func, pLatlon->achZero[0],pLatlon->achZero[1],pLatlon->achZero[2],
1276        pLatlon->achZero[3]);
1277  DPRINT4("\t%s achLat_southpole [%02d,%02d,%02d]\n",
1278        func, pLatlon->achLat_southpole[0],pLatlon->achLat_southpole[1],
1279        pLatlon->achLat_southpole[2]);
1280  DPRINT4("\t%s achLon_southpole [%02d,%02d,%02d]\n",
1281        func, pLatlon->achLon_southpole[0],pLatlon->achLon_southpole[1],
1282        pLatlon->achLon_southpole[2]);
1283  DPRINT5("\t%s achRotate [%02d,%02d,%02d,%02d]\n",
1284        func, pLatlon->achRotate[0],pLatlon->achRotate[1],
1285        pLatlon->achRotate[2], pLatlon->achRotate[3]);
1286  DPRINT4("\t%s achPole_lat [%02d,%02d,%02d]\n",
1287        func, pLatlon->achPole_lat[0],pLatlon->achPole_lat[1],
1288        pLatlon->achPole_lat[2]);
1289  DPRINT4("\t%s achPole_lon [%02d,%02d,%02d]\n",
1290        func, pLatlon->achPole_lon[0],pLatlon->achPole_lon[1],
1291        pLatlon->achPole_lon[2]);
1292  DPRINT5("\t%s achStretch [%02d,%02d,%02d,%02d]\n",
1293        func, pLatlon->achStretch[0],pLatlon->achStretch[1],
1294        pLatlon->achStretch[2], pLatlon->achStretch[3]);
1295/*******/
1296/*
1297*
1298* G.6       STORE size of LATLON struct in lProj_size
1299*/
1300      *lProj_size = sizeof (LATLON);
1301
1302
1303BYE:
1304   DPRINT3 ("   Exiting %s (lProj_size=%ld), stat=%d\n", func,
1305      *lProj_size, nStatus);
1306/*
1307*
1308* G.7       RETURN stat
1309*/
1310   return ( nStatus );
1311/*
1312*
1313* END OF FUNCTION
1314*
1315*
1316*/ 
1317}
1318/*
1319*
1320****************************************************************************
1321* F. FUNCTION:  inp2grib_Mercator
1322*      This routine fills the special Mercator Projection structure for
1323*      the GDS.
1324*
1325*    INTERFACE:
1326*       int inp2grib_Mercator ( ppvGDS_Proj_Input, Polar, lProj_size ,errmsg)
1327*
1328*    ARGUMENTS (I=input, O=output, I&O=input and output):
1329*      (I) void **ppvGDS_Proj_Input; 
1330*          holds input projection data
1331*      (O) MERCATOR *Mercator;         
1332*          to be filled with Polar Stereographic projection info
1333*      (O) long *lProj_size;       
1334*          to be filled with size of structure POLAR
1335*      (O) char *errmsg             
1336*          empty array, filled if error occurred
1337*
1338*   RETURN CODE:
1339*      0> success, Mercator and lProj_size filled;
1340*      1> pointers are null, errmsg filled;
1341****************************************************************************/
1342
1343#if PROTOTYPE_NEEDED
1344int   inp2grib_Mercator (void **ppvGDS_Proj_Input, MERCATOR *Mercator, 
1345                        long *lProj_size , char *errmsg)
1346#else
1347int   inp2grib_Mercator (ppvGDS_Proj_Input, Mercator, lProj_size , errmsg)
1348                        void **ppvGDS_Proj_Input; MERCATOR *Mercator; 
1349                        long *lProj_size ; char *errmsg;
1350#endif
1351{
1352/*
1353*
1354* F.1       INIT variables !default stat=good
1355*/
1356   mercator          *ProjInp = 0;
1357   int               lTemp = 0;
1358   int               nStatus = 0;
1359   char              *func="inp2grib_PolarSt";
1360
1361   DPRINT1 ("\t Entering %s.....\n", func);
1362/*
1363*
1364* F.2       POINT local pProjInp to incoming ppvGDS_Proj_Input
1365*/
1366   ProjInp = ( mercator *) *ppvGDS_Proj_Input;
1367
1368/*
1369*
1370* F.3       IF (true grib Mercator proj block OR input Polar block is null) THEN
1371*               SET Status=  1
1372*               RETURN;
1373*           ENDIF
1374*/
1375    if (!Mercator || !ProjInp ) 
1376        {
1377        DPRINT1 ( "%s:  Mercator or ProjInp is null\n", func);
1378        sprintf(errmsg,"%s: Mercator or ProjInp is null\n", func);
1379        nStatus=  1; goto BYE; 
1380        }
1381
1382/*
1383*
1384* F.4        FILL local struct from pProjInp
1385*/
1386/* convert cols to 2 chars */
1387      set_bytes(ProjInp->cols, 2, Mercator->achNi);
1388   
1389/* convert rows to 2 chars */
1390      set_bytes(ProjInp->rows, 2, Mercator->achNj);
1391
1392/* convert first_lat to 3 chars */
1393      set_bytes(ProjInp->first_lat, 3, Mercator->achLat1);
1394
1395/* convert first_lon to 3 chars */
1396      set_bytes(ProjInp->first_lon, 3, Mercator->achLon1);
1397
1398      Mercator->chRes_flag = ( unsigned char ) ProjInp->usRes_flag;
1399
1400/* convert La2 to 3 chars */
1401      set_bytes(ProjInp->La2, 3, Mercator->achLat2);
1402
1403/* convert Lo2 to 3 chars */
1404      set_bytes(ProjInp->Lo2, 3, Mercator->achLon2);
1405
1406/* convert lLon_orient to 3 chars */
1407      set_bytes(ProjInp->latin, 3, Mercator->achLatin);
1408
1409/* convert zero fill */
1410      Mercator->achZero1 = ( unsigned char ) ProjInp->usZero1;
1411
1412      Mercator->chScan_mode = ( unsigned char ) ProjInp->usScan_mode;
1413
1414/* convert ulDx to 3 char */
1415      set_bytes((int)(ProjInp->lon_inc + 0.5), 3, Mercator->achDi);
1416
1417/* convert ulDy to 3chars */
1418      set_bytes((int)(ProjInp->lat_inc + 0.5), 3, Mercator->achDj);
1419
1420      Mercator->chScan_mode = ( unsigned char ) ProjInp->usScan_mode;
1421
1422/* 8 bytes of zero */
1423      memset((void*) Mercator->achZero2, '\0', 8);
1424
1425/*
1426*
1427* F.5       DEBUG print GRIB Projection block
1428*/
1429  DPRINT3("\t%s: achNi [%02d,%02d]\n",func,Mercator->achNi[0],Mercator->achNi[1]);
1430  DPRINT3("\t%s: achNj [%02d,%02d]\n",func, Mercator->achNj[0],Mercator->achNj[1]);
1431  DPRINT4("\t%s: achLat1 [%02d,%02d,%02d]\n",func, Mercator->achLat1[0],
1432  Mercator->achLat1[1], Mercator->achLat1[2]);
1433  DPRINT4("\t%s: achLon1 [%02d,%02d,%02d]\n",func, Mercator->achLon1[0],
1434   Mercator->achLon1[1] , Mercator->achLon1[2]);
1435  DPRINT2("\t%s: chRes_flag [%02d]\n",func, Mercator->chRes_flag);
1436  DPRINT4("\t%s: achLatint [%02d,%02d,%02d]\n",func, 
1437  Mercator->achLatin[0], Mercator->achLatin[1], Mercator->achLatin[2]);
1438  DPRINT4("\t%s: achDi [%02d,%02d,%02d]\n",func, Mercator->achDi[0],
1439  Mercator->achDi[1], Mercator->achDi[2]);
1440  DPRINT4("\t%s: achDj [%02d,%02d,%02d]\n",func, Mercator->achDj[0],
1441  Mercator->achDj[1], Mercator->achDj[2]);
1442  DPRINT5("\t%s: achZero2 [%02d,%02d,%02d,%02d]\n",func, Mercator->achZero2[0],
1443  Mercator->achZero2[1],  Mercator->achZero2[2],  Mercator->achZero2[3]);
1444/*******/
1445
1446/*
1447*
1448* F.7        STORE size of POLAR struct in lProj_size
1449*/
1450      *lProj_size = sizeof (MERCATOR);
1451
1452BYE:
1453   DPRINT3 ("   Exiting %s (lProj_size=%ld), stat=%d\n", func,
1454      *lProj_size, nStatus);
1455/*
1456*
1457* F.8       RETURN Stat  ! 0 or  1
1458*/
1459   return ( nStatus );
1460/*
1461*
1462* END OF FUNCTION
1463*
1464*
1465*/ 
1466}
1467/*
1468Old round--this is different from standard gnu round (gnu round returns a
1469float).  Depending on compile options, sometimes gnu round was used, other
1470times this function was used.  Removed and replaced by lrint by T. Hutchinson,
1471WSI.  4/14/05.
1472long round(double value)
1473{
1474  long retval;
1475  retval=lrint(value);
1476  return retval;
1477}
1478*/
Note: See TracBrowser for help on using the repository browser.