source: trunk/WRF.COMMON/WRFV3/external/io_grib1/MEL_grib1/gribputgds.c @ 2759

Last change on this file since 2759 was 2759, checked in by aslmd, 2 years ago

adding unmodified code from WRFV3.0.1.1, expurged from useless data +1M size

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