NCEPLIBS-g2c 2.0.0
Loading...
Searching...
No Matches
aecunpack.c
Go to the documentation of this file.
1
6#include "grib2_int.h"
7#include <stdio.h>
8#include <stdlib.h>
9
42static int
43aecunpack_int(unsigned char *cpack, g2int len, g2int *idrstmpl, g2int ndpts,
44 void *fld, int fld_is_double, int verbose)
45{
46 g2int *ifld;
47 g2int j, ctemplen = 0, nbits;
48 g2int ccsds_flags, ccsds_block_size, ccsds_rsi;
49 //g2int ifld1 = 0;
50 int ret = 0;
51 float ref, bscale, dscale;
52 float *ffld = fld;
53 double *dfld = fld;
54 unsigned char *ctemp;
55 size_t nbytes = 0;
56
57 LOG((2, "aecunpack_int len %ld ndpts %ld fld_is_double %d", len, ndpts, fld_is_double));
58
59 /* Get compression parameters from data representation template array. */
60 rdieee(idrstmpl, &ref, 1);
61 bscale = int_power(2.0, idrstmpl[1]);
62 dscale = int_power(10.0, -idrstmpl[2]);
63 nbits = idrstmpl[3];
64 ccsds_flags = idrstmpl[5];
65 ccsds_block_size = idrstmpl[6];
66 ccsds_rsi = idrstmpl[7];
67
68 /* If nbits equals 0, we have a constant field where the reference
69 * value is the data value at each gridpoint. */
70 if (nbits != 0)
71 {
72 if (!(ifld = calloc(ndpts, sizeof(g2int))))
73 {
74 if (verbose)
75 fprintf(stderr, "Could not allocate space in aecunpack.\n Data field NOT upacked.\n");
76 return G2C_ENOMEM;
77 }
78
79 /* Determine the number of bytes needed for each value, then allocate the
80 * buffer for the decoded AEC stream. */
81 nbytes = (nbits + 7) / 8;
82 if (nbytes == 3)
83 nbytes = 4;
84 ctemplen = nbytes * ndpts;
85 if ((ctemp = (unsigned char *)malloc(ctemplen)) == NULL)
86 {
87 if (verbose)
88 fprintf(stderr, "Allocation error.\n");
89 return G2C_ENOMEM;
90 }
91
92 /* Decode the AEC stream. */
93 ret = dec_aec(cpack, len, nbits, ccsds_flags, ccsds_block_size, ccsds_rsi, ctemp, ctemplen);
94 if (ret < 0)
95 return ret;
96
97 /* IMPORTANT: The decoded AEC stream is byte-aligned (not bit), so when extracting the data
98 * values from the buffer via gbits, we need to pass the byte size in bits, not nbits. */
99 gbits(ctemp, ifld, 0, nbytes * 8, 0, ndpts);
100
101 /* Zero out all higher-order bits, preserving nbits. NOTE: This might be unecessary. */
102 //for (j = 0; j < ndpts; j++)
103 // ifld1 = ifld[j];
104 // ifld1 = ifld1 << (sizeof(ifld1)*8-nbits);
105 // ifld1 = ifld1 >> (sizeof(ifld1)*8-nbits);
106 // ifld[j] = ifld1;
107
108 /* Unscale data. */
109 if (fld_is_double)
110 {
111 for (j = 0; j < ndpts; j++)
112 dfld[j] = (((float)ifld[j] * bscale) + ref) * dscale;
113 }
114 else
115 {
116 for (j = 0; j < ndpts; j++)
117 ffld[j] = (((float)ifld[j] * bscale) + ref) * dscale;
118 }
119
120 /* Clean up. */
121 free(ctemp);
122 free(ifld);
123 }
124 else
125 {
126 if (fld_is_double)
127 {
128 for (j = 0; j < ndpts; j++)
129 dfld[j] = ref;
130 }
131 else
132 {
133 for (j = 0; j < ndpts; j++)
134 ffld[j] = ref;
135 }
136 }
137
138 return G2C_NOERROR;
139}
140
160g2int
161aecunpack(unsigned char *cpack, g2int len, g2int *idrstmpl, g2int ndpts,
162 float *fld)
163{
164 int ret;
165
166 LOG((2, "g2c_aecunpack len %lld ndpts %lld", len, ndpts));
167
168 ret = aecunpack_int(cpack, len, idrstmpl, ndpts, fld, 0, 1);
169
170 return ret;
171}
172
193int
194g2c_aecunpackf(unsigned char *cpack, size_t len, int *idrstmpl, size_t ndpts,
195 float *fld)
196{
198 g2int len8 = len, ndpts8 = ndpts;
199 int i;
200
201 LOG((2, "g2c_aecunpackf len %d ndpts %lld", len, ndpts));
202
203 for (i = 0; i < G2C_AEC_DRS_TEMPLATE_LEN; i++)
204 idrstmpl8[i] = idrstmpl[i];
205
206 return aecunpack_int(cpack, len8, idrstmpl8, ndpts8, fld, 0, 0);
207}
208
231int
232g2c_aecunpackd(unsigned char *cpack, size_t len, int *idrstmpl, size_t ndpts,
233 double *fld)
234{
236 g2int len8 = len, ndpts8 = ndpts;
237 int i;
238
239 LOG((2, "g2c_aecunpackd len %lld ndpts %lld", len, ndpts));
240
241 for (i = 0; i < G2C_AEC_DRS_TEMPLATE_LEN; i++)
242 idrstmpl8[i] = idrstmpl[i];
243
244 return aecunpack_int(cpack, len8, idrstmpl8, ndpts8, fld, 1, 0);
245}
int g2c_aecunpackd(unsigned char *cpack, size_t len, int *idrstmpl, size_t ndpts, double *fld)
Unpack AEC compressed data into an array of doubles, using info from the GRIB2 Data Representation Te...
Definition aecunpack.c:232
g2int aecunpack(unsigned char *cpack, g2int len, g2int *idrstmpl, g2int ndpts, float *fld)
Unpack AEC compressed data into an array of floats, using info from the GRIB2 Data Representation Tem...
Definition aecunpack.c:161
static int aecunpack_int(unsigned char *cpack, g2int len, g2int *idrstmpl, g2int ndpts, void *fld, int fld_is_double, int verbose)
Unpack AEC compressed data into an array of floats or doubles, using info from the GRIB2 Data Represe...
Definition aecunpack.c:43
int g2c_aecunpackf(unsigned char *cpack, size_t len, int *idrstmpl, size_t ndpts, float *fld)
Unpack AEC compressed data into an array of floats, using info from the GRIB2 Data Representation Tem...
Definition aecunpack.c:194
int dec_aec(unsigned char *cpack, g2int len, g2int nbits, g2int flags, g2int block_size, g2int rsi, unsigned char *cfld, g2int cfldlen)
Decode an AEC code stream specified in the CCSDS 121.0-B-3 Blue Book.
Definition decenc_aec.c:38
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 G2C_ENOMEM
Out of memory.
Definition grib2.h:485
#define G2C_AEC_DRS_TEMPLATE_LEN
Length of the idrstmpl array for AEC packing.
Definition grib2.h:407
int64_t g2int
Long integer type.
Definition grib2.h:32
#define G2C_NOERROR
No error.
Definition grib2.h:476
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
#define LOG(e)
Ignore logging to stdout.
Definition grib2_int.h:428
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