NCEPLIBS-g2c  1.8.0
simpack.c
Go to the documentation of this file.
1 
6 #include <stdlib.h>
7 #include <math.h>
8 #include "grib2_int.h"
9 
33 void
34 simpack(float *fld, g2int ndpts, g2int *idrstmpl,
35  unsigned char *cpack, g2int *lcpack)
36 {
37  static g2int zero = 0;
38  g2int *ifld;
39  g2int j, nbits, imin, imax, maxdif, nbittot, left;
40  float bscale, dscale, rmax, rmin, temp;
41  double maxnum;
42  static float alog2 = ALOG2; /* ln(2.0) */
43 
44  LOG((3, "simpack ndpts %ld", ndpts));
45 
46  bscale = int_power(2.0, -idrstmpl[1]);
47  dscale = int_power(10.0, idrstmpl[2]);
48  if (idrstmpl[3] <= 0 || idrstmpl[3] > 31)
49  nbits = 0;
50  else
51  nbits = idrstmpl[3];
52 
53  /* Find max and min values in the data. */
54  rmax = fld[0];
55  rmin = fld[0];
56  for (j = 1; j < ndpts; j++) {
57  if (fld[j] > rmax)
58  rmax = fld[j];
59  if (fld[j] < rmin)
60  rmin = fld[j];
61  }
62 
63  ifld = calloc(ndpts, sizeof(g2int));
64 
65  /* If max and min values are not equal, pack up field. If they are
66  * equal, we have a constant field, and the reference value (rmin)
67  * is the value for each point in the field and set nbits to 0. */
68  if (rmin != rmax) {
69 
70  /* Determine which algorithm to use based on user-supplied
71  * binary scale factor and number of bits. */
72  if (nbits == 0 && idrstmpl[1] == 0) {
73 
74  /* No binary scaling and calculate minumum number of bits
75  * in which the data will fit. */
76  imin = (g2int)rint(rmin * dscale);
77  imax = (g2int)rint(rmax * dscale);
78  maxdif = imax - imin;
79  temp = log((double)(maxdif + 1)) / alog2;
80  nbits = (g2int)ceil(temp);
81  rmin = (float)imin;
82  /* scale data */
83  for(j = 0; j < ndpts; j++)
84  ifld[j] = (g2int)rint(fld[j] * dscale) - imin;
85  }
86  else if (nbits != 0 && idrstmpl[1] == 0) {
87 
88  /* Use minimum number of bits specified by user and adjust
89  * binary scaling factor to accomodate data. */
90  rmin = rmin * dscale;
91  rmax = rmax * dscale;
92  maxnum = int_power(2.0, nbits) - 1;
93  temp = log(maxnum / (rmax - rmin)) / alog2;
94  idrstmpl[1] = (g2int)ceil(-1.0 * temp);
95  bscale = int_power(2.0, -idrstmpl[1]);
96  /* scale data */
97  for (j = 0; j < ndpts; j++)
98  ifld[j] = (g2int)rint(((fld[j] * dscale) - rmin) * bscale);
99  }
100  else if (nbits == 0 && idrstmpl[1] != 0) {
101 
102  /* Use binary scaling factor and calculate minumum number
103  * of bits in which the data will fit. */
104  rmin = rmin * dscale;
105  rmax = rmax * dscale;
106  maxdif = (g2int)rint((rmax - rmin) * bscale);
107  temp = log((double)(maxdif + 1)) / alog2;
108  nbits = (g2int)ceil(temp);
109  /* scale data */
110  for (j = 0; j < ndpts; j++)
111  ifld[j] = (g2int)rint(((fld[j] * dscale) - rmin) * bscale);
112  }
113  else if (nbits != 0 && idrstmpl[1] != 0) {
114 
115  /* Use binary scaling factor and use minumum number of
116  * bits specified by user. Dangerous - may loose
117  * information if binary scale factor and nbits not set
118  * properly by user. */
119  rmin = rmin * dscale;
120  /* scale data */
121  for (j = 0; j < ndpts; j++)
122  ifld[j] = (g2int)rint(((fld[j] * dscale) - rmin) * bscale);
123  }
124 
125  /* Pack data, Pad last octet with Zeros, if necessary, and
126  * calculate the length of the packed data in bytes. */
127  sbits(cpack, ifld, 0, nbits, 0, ndpts);
128  nbittot = nbits * ndpts;
129  left = 8 - (nbittot % 8);
130  if (left != 8) {
131  sbit(cpack, &zero, nbittot, left); /* Pad with zeros to fill Octet. */
132  nbittot = nbittot + left;
133  }
134  *lcpack = nbittot / 8;
135  }
136  else {
137  nbits = 0;
138  *lcpack = 0;
139  }
140 
141  /* Fill in ref value and number of bits in Template 5.0. */
142  mkieee(&rmin, idrstmpl, 1); /* ensure reference value is IEEE format. */
143  idrstmpl[3] = nbits;
144  idrstmpl[4] = 0; /* original data were reals. */
145 
146  free(ifld);
147 }
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
int64_t g2int
Long integer type.
Definition: grib2.h:33
Header file with internal function prototypes NCEPLIBS-g2c library.
void mkieee(float *a, g2int *rieee, g2int num)
This subroutine stores a list of real values in 32-bit IEEE floating point format.
Definition: mkieee.c:22
double int_power(double x, g2int y)
Function similar to C pow() power function.
Definition: int_power.c:18
#define LOG(e)
Ignore logging to stdout.
Definition: grib2_int.h:426
#define ALOG2
ln(2.0)
Definition: grib2_int.h:30
void simpack(float *fld, g2int ndpts, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack)
This subroutine packs up a data field using the simple packing algorithm as defined in the GRIB2 docu...
Definition: simpack.c:34