NCEPLIBS-g2c  1.8.0
g2_addgrid.c
Go to the documentation of this file.
1 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include "grib2_int.h"
11 
69 g2int
70 g2_addgrid(unsigned char *cgrib, g2int *igds, g2int *igdstmpl, g2int *ideflist,
71  g2int idefnum)
72 {
73  static g2int one = 1, three = 3, miss = 65535;
74  g2int lensec3, iofst, ibeg, lencurr, len;
75  g2int i, j, temp, ilen, isecnum, nbits;
76  gtemplate *mapgrid = 0;
77  int ret;
78 
79  /* Check for GRIB header and terminator. Translate the error codes
80  * to the legacy G2 error codes. */
81  if ((ret = g2c_check_msg(cgrib, &lencurr, 1)))
82  {
83  if (ret == G2C_ENOTGRIB)
84  return G2_ADD_MSG_INIT;
85  if (ret == G2C_EMSGCOMPLETE)
86  return G2_ADD_MSG_COMPLETE;
87  }
88 
89  /* Loop through all current sections of the GRIB message to find
90  * the last section number. */
91  len = 16; /* length of Section 0 */
92  for (;;)
93  {
94  /* Get section number and length of next section. */
95  iofst = len * 8;
96  gbit(cgrib, &ilen, iofst, 32);
97  iofst = iofst + 32;
98  gbit(cgrib, &isecnum, iofst, 8);
99  len = len + ilen;
100 
101  /* Exit loop if last section reached. */
102  if (len == lencurr)
103  break;
104 
105  /* If byte count for each section doesn't match current total
106  * length, then there is a problem. */
107  if (len > lencurr)
108  {
109  printf("g2_addgrid: Section byte counts don''t add to total.\n");
110  printf("g2_addgrid: Sum of section byte counts = %ld\n", len);
111  printf("g2_addgrid: Total byte count in Section 0 = %ld\n", lencurr);
112  return G2_BAD_SEC_COUNTS;
113  }
114  }
115 
116  /* Section 3 can only be added after sections 1, 2 and 7. */
117  if (isecnum != 1 && isecnum != 2 && isecnum != 7)
118  {
119  printf("g2_addgrid: Section 3 can only be added after Section 1, 2 or 7.\n");
120  printf("g2_addgrid: Section ',isecnum,' was the last found in given GRIB message.\n");
121  return G2_BAD_SEC;
122  }
123 
124  /* Add Section 3 - Grid Definition Section. */
125  ibeg = lencurr * 8; /* Calculate offset for beginning of section 3 */
126  iofst = ibeg + 32; /* leave space for length of section */
127  sbit(cgrib, &three, iofst, 8); /* Store section number (3) */
128  iofst = iofst + 8;
129  sbit(cgrib, igds+0, iofst, 8); /* Store source of Grid def. */
130  iofst = iofst + 8;
131  sbit(cgrib, igds+1, iofst, 32); /* Store number of data pts. */
132  iofst = iofst + 32;
133  sbit(cgrib, igds+2, iofst, 8); /* Store number of extra octets. */
134  iofst = iofst + 8;
135  sbit(cgrib, igds+3, iofst, 8); /* Store interp. of extra octets. */
136  iofst = iofst + 8;
137 
138  /* if Octet 6 is not equal to zero, Grid Definition Template may
139  * not be supplied. */
140  if (igds[0] == 0)
141  sbit(cgrib, igds+4, iofst, 16); /* Store Grid Def Template num. */
142  else
143  sbit(cgrib, &miss, iofst, 16); /* Store missing value as Grid Def Template num. */
144  iofst = iofst + 16;
145 
146  /* Get Grid Definition Template. */
147  if (igds[0] == 0)
148  {
149  if (!(mapgrid = getgridtemplate(igds[4])))
150  return G2_ADDGRID_BAD_GDT;
151 
152  /* Extend the Grid Definition Template, if necessary. The
153  * number of values in a specific template may vary depending
154  * on data specified in the "static" part of the template. */
155  if (mapgrid->needext)
156  {
157  free(mapgrid);
158  mapgrid = extgridtemplate(igds[4], igdstmpl);
159  }
160  }
161 
162  /* Pack up each input value in array igdstmpl into the
163  * appropriate number of octets, which are specified in
164  * corresponding entries in array mapgrid. */
165  for (i = 0; i < mapgrid->maplen; i++)
166  {
167  nbits = abs(mapgrid->map[i]) * 8;
168  if ((mapgrid->map[i] >= 0) || (igdstmpl[i] >= 0))
169  sbit(cgrib, igdstmpl+i, iofst, nbits);
170  else
171  {
172  sbit(cgrib, &one, iofst, 1);
173  temp = abs(igdstmpl[i]);
174  sbit(cgrib, &temp, iofst+1, nbits-1);
175  }
176  iofst = iofst + nbits;
177  }
178 
179  /* Pack template extension, if appropriate. */
180  j = mapgrid->maplen;
181  if (mapgrid->needext && mapgrid->extlen > 0)
182  {
183  for (i = 0; i < mapgrid->extlen; i++)
184  {
185  nbits = abs(mapgrid->ext[i]) * 8;
186  if (mapgrid->ext[i] >= 0 || igdstmpl[j] >= 0)
187  sbit(cgrib, igdstmpl + j, iofst, nbits);
188  else
189  {
190  sbit(cgrib, &one, iofst, 1);
191  temp = abs(igdstmpl[j]);
192  sbit(cgrib, &temp, iofst + 1, nbits - 1);
193  }
194  iofst = iofst + nbits;
195  j++;
196  }
197  }
198  if (mapgrid->ext)
199  free(mapgrid->ext);
200  free(mapgrid);
201 
202  /* If requested, insert optional list of numbers defining number
203  * of points in each row or column. This is used for non regular
204  * grids. */
205  if (igds[2] != 0)
206  {
207  nbits = igds[2] * 8;
208  sbits(cgrib, ideflist, iofst, nbits, 0, idefnum);
209  iofst = iofst + (nbits * idefnum);
210  }
211 
212  /* Calculate length of section 3 and store it in octets 1-4 of section 3. */
213  lensec3 = (iofst - ibeg) / 8;
214  sbit(cgrib, &lensec3, ibeg, 32);
215 
216  /* Update current byte total of message in Section 0. */
217  lencurr += lensec3;
218  sbit(cgrib, &lencurr, 96, 32);
219 
220  return lencurr;
221 }
g2int g2_addgrid(unsigned char *cgrib, g2int *igds, g2int *igdstmpl, g2int *ideflist, g2int idefnum)
This routine packs up a Grid Definition Section (Section 3) and adds it to a GRIB2 message.
Definition: g2_addgrid.c:70
void gbit(unsigned char *in, g2int *iout, g2int iskip, g2int nbits)
Get bits - unpack bits: Extract arbitrary size values from a packed bit string, right justifying each...
Definition: gbits.c:20
void sbits(unsigned char *out, g2int *in, g2int iskip, g2int nbits, g2int nskip, g2int n)
Store bits - put arbitrary size values into a packed bit string, taking the low order bits from each ...
Definition: gbits.c:180
void sbit(unsigned char *out, g2int *in, g2int iskip, g2int nbits)
Store bits - put arbitrary size values into a packed bit string, taking the low order bits from each ...
Definition: gbits.c:38
#define G2_BAD_SEC_COUNTS
Sum of Section byte counts doesn't add to total byte count.
Definition: grib2.h:475
#define G2_BAD_SEC
Previous Section was unexpected.
Definition: grib2.h:463
#define G2_ADDGRID_BAD_GDT
In g2_addgrid() Could not find requested Grid Definition Template.
Definition: grib2.h:482
#define G2_ADD_MSG_COMPLETE
GRIB message already complete.
Definition: grib2.h:474
#define G2_ADD_MSG_INIT
GRIB message was not initialized - call g2_create() first.
Definition: grib2.h:473
#define G2C_ENOTGRIB
GRIB header not found.
Definition: grib2.h:493
#define G2C_EMSGCOMPLETE
GRIB message already complete.
Definition: grib2.h:494
int64_t g2int
Long integer type.
Definition: grib2.h:33
Header file with internal function prototypes NCEPLIBS-g2c library.
gtemplate * extgridtemplate(g2int number, g2int *list)
This subroutine generates the remaining octet map for a given Grid Definition Template,...
g2int * ext
Number of octets of each entry in the extension part of the template.
Definition: grib2_int.h:300
int g2c_check_msg(unsigned char *cgrib, g2int *lencurr, int verbose)
Check for 'GRIB' at the beginning of a GRIB message, and check to see if the message is already termi...
Definition: util.c:26
g2int extlen
Number of entries in the template extension.
Definition: grib2_int.h:296
g2int * map
Number of octets of each entry in the static part of the template.
Definition: grib2_int.h:290
g2int needext
Indicates whether or not the template needs to be extended.
Definition: grib2_int.h:293
g2int maplen
Number of entries in the static part of the template.
Definition: grib2_int.h:286
gtemplate * getgridtemplate(g2int number)
This subroutine returns grid template information for a specified Grid Definition Template for [Secti...
Struct for GRIB template, returned by getgridtemplate().
Definition: grib2_int.h:276