NCEPLIBS-g2c 1.9.0
Loading...
Searching...
No Matches
specunpack.c
Go to the documentation of this file.
1
6#include <stdio.h>
7#include <stdlib.h>
8#include <math.h>
9#include "grib2_int.h"
10
35specunpack(unsigned char *cpack, g2int *idrstmpl, g2int ndpts, g2int JJ,
36 g2int KK, g2int MM, float *fld)
37{
38 g2int *ifld, j, iofst, nbits;
39 float ref, bscale, dscale, *unpk;
40 float *pscale, tscale;
41 g2int Js, Ks, Ms, Ts, Ns, Nm, n, m;
42 g2int inc, incu, incp;
43
44 rdieee(idrstmpl+0, &ref, 1);
45 bscale = int_power(2.0, idrstmpl[1]);
46 dscale = int_power(10.0, -idrstmpl[2]);
47 nbits = idrstmpl[3];
48 Js = idrstmpl[5];
49 Ks = idrstmpl[6];
50 Ms = idrstmpl[7];
51 Ts = idrstmpl[8];
52
53 if (idrstmpl[9] == 1)
54 { /* unpacked floats are 32-bit IEEE */
55
56 unpk = malloc(ndpts * sizeof(float));
57 ifld = malloc(ndpts * sizeof(g2int));
58
59 gbits(cpack, ifld, 0, 32, 0, Ts);
60 iofst = 32 * Ts;
61 rdieee(ifld, unpk, Ts); /* read IEEE unpacked floats */
62 gbits(cpack, ifld, iofst, nbits, 0, ndpts - Ts); /* unpack scaled data */
63
64 /* Calculate Laplacian scaling factors for each possible wave
65 * number. */
66 pscale = malloc((JJ + MM + 1) * sizeof(float));
67 tscale = idrstmpl[4] * 1E-6;
68 for (n = Js; n <= JJ + MM; n++)
69 pscale[n] = pow((float)(n * (n+1)), -tscale);
70
71 /* Assemble spectral coeffs back to original order. */
72 inc = 0;
73 incu = 0;
74 incp = 0;
75 for (m = 0; m <= MM; m++)
76 {
77 Nm = JJ; /* triangular or trapezoidal */
78 if (KK == JJ+MM)
79 Nm = JJ + m; /* rhombodial */
80 Ns = Js; /* triangular or trapezoidal */
81 if (Ks == Js + Ms)
82 Ns = Js + m; /* rhombodial */
83 for (n = m; n <= Nm; n++)
84 {
85 if (n <= Ns && m <= Ms)
86 { /* grab unpacked value */
87 fld[inc++] = unpk[incu++]; /* real part */
88 fld[inc++] = unpk[incu++]; /* imaginary part */
89 }
90 else
91 { /* Calc coeff from packed value */
92 fld[inc++] = (((float)ifld[incp++] * bscale) + ref) *
93 dscale * pscale[n]; /* real part */
94 fld[inc++] = (((float)ifld[incp++] * bscale) + ref) *
95 dscale * pscale[n]; /* imaginary part */
96 }
97 }
98 }
99
100 free(pscale);
101 free(unpk);
102 free(ifld);
103 }
104 else
105 {
106 printf("specunpack: Cannot handle 64 or 128-bit floats.\n");
107 for (j = 0; j < ndpts; j++)
108 fld[j] = 0.0;
109 return G2_SPECUNPACK_TYPE;
110 }
111
112 return G2_NO_ERROR;
113}
void gbits(unsigned char *in, g2int *iout, g2int iskip, g2int nbits, g2int nskip, g2int n)
Unpack arbitrary size values from a packed bit string, right justifying each value in the unpacked io...
Definition gbits.c:57
#define G2_NO_ERROR
Function succeeded.
Definition grib2.h:438
#define G2_SPECUNPACK_TYPE
In specunpack() Can't handle 64 or 128 bit floats.
Definition grib2.h:484
int64_t g2int
Long integer type.
Definition grib2.h:32
Header file with internal function prototypes NCEPLIBS-g2c library.
double int_power(double x, g2int y)
Function similar to C pow() power function.
Definition int_power.c:18
void rdieee(g2int *rieee, float *a, g2int num)
Read a list of real values in 32-bit IEEE floating point format.
Definition rdieee.c:20
g2int specunpack(unsigned char *cpack, g2int *idrstmpl, g2int ndpts, g2int JJ, g2int KK, g2int MM, float *fld)
Unpack a spectral data field that was packed using the complex packing algorithm for spherical harmon...
Definition specunpack.c:35