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