NCEPLIBS-g2c  1.7.0
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 
34 g2int
35 specunpack(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 }
G2_NO_ERROR
#define G2_NO_ERROR
Function succeeded.
Definition: grib2.h:275
rdieee
void rdieee(g2int *rieee, float *a, g2int num)
This subroutine reads a list of real values in 32-bit IEEE floating point format.
Definition: rdieee.c:21
int_power
double int_power(double x, g2int y)
Function similar to C pow() power function.
Definition: int_power.c:18
grib2_int.h
Header file with internal function prototypes NCEPLIBS-g2c library.
g2int
int64_t g2int
Long integer type.
Definition: grib2.h:28
gbits
void gbits(unsigned char *in, g2int *iout, g2int iskip, g2int nbits, g2int nskip, g2int n)
Get bits - unpack bits: Extract arbitrary size values from a packed bit string, right justifying each...
Definition: gbits.c:57
specunpack
g2int specunpack(unsigned char *cpack, g2int *idrstmpl, g2int ndpts, g2int JJ, g2int KK, g2int MM, float *fld)
This subroutine unpacks a spectral data field that was packed using the complex packing algorithm for...
Definition: specunpack.c:35
G2_SPECUNPACK_TYPE
#define G2_SPECUNPACK_TYPE
In specunpack() Can't handle 64 or 128 bit floats.
Definition: grib2.h:321