NCEPLIBS-g2c 1.9.0
Loading...
Searching...
No Matches
jpcpack.c
Go to the documentation of this file.
1
14#include <stdlib.h>
15#include <math.h>
16#include "grib2_int.h"
17
53static int
54jpcpack_int(void *fld, int fld_is_double, g2int width, g2int height, g2int *idrstmpl,
55 unsigned char *cpack, g2int *lcpack, int verbose)
56{
57 g2int *ifld = NULL;
58 static float alog2 = ALOG2; /* ln(2.0) */
59 g2int j, nbits, imin, imax, maxdif;
60 g2int ndpts, nbytes, nsize, retry;
61 float bscale, dscale, rmax, rmin, temp;
62 double rmaxd, rmind;
63 unsigned char *ctemp;
64 float *ffld = fld;
65 double *dfld = fld;
66 int ret = G2C_NOERROR;
67
68 LOG((2, "jpcpack_int() fld_is_double %d width %ld height %ld idrstmpl[1] %d *lcpack %ld",
69 fld_is_double, width, height, idrstmpl[1], *lcpack));
70 LOG((3, "idrstmpl: %ld %ld %ld %ld %ld %ld %ld", idrstmpl[0], idrstmpl[1], idrstmpl[2],
71 idrstmpl[3], idrstmpl[4], idrstmpl[5], idrstmpl[6]));
72
73 ndpts = width * height;
74 bscale = int_power(2.0, -idrstmpl[1]);
75 dscale = int_power(10.0, idrstmpl[2]);
76 LOG((3, "ndpts %ld bscale %g dscale %g", ndpts, bscale, dscale));
77
78 /* Find max and min values in the data. */
79 rmaxd = dfld[0];
80 rmind = dfld[0];
81 rmax = ffld[0];
82 rmin = ffld[0];
83 if (fld_is_double)
84 {
85 for (j = 1; j < ndpts; j++)
86 {
87 if (dfld[j] > rmaxd)
88 rmaxd = dfld[j];
89 if (dfld[j] < rmind)
90 rmind = dfld[j];
91 }
92 if (idrstmpl[1] == 0)
93 maxdif = (g2int)(rint(rmaxd * dscale) - rint(rmind * dscale));
94 else
95 maxdif = (g2int)rint((rmaxd - rmind) * dscale * bscale);
96 }
97 else
98 {
99 for (j = 1; j < ndpts; j++)
100 {
101 if (ffld[j] > rmax)
102 rmax = ffld[j];
103 if (ffld[j] < rmin)
104 rmin = ffld[j];
105 }
106 if (idrstmpl[1] == 0)
107 maxdif = (g2int)(rint(rmax * dscale) - rint(rmin * dscale));
108 else
109 maxdif = (g2int)rint((rmax - rmin) * dscale * bscale);
110 }
111 LOG((3, "rmax %g rmaxd %g rmin %g rmind %g", rmax, rmaxd, rmin, rmind));
112
113 /* If max and min values are not equal, pack up field. If they are
114 * equal, we have a constant field, and the reference value (rmin)
115 * is the value for each point in the field and set nbits to 0. */
116 if (((fld_is_double && rmind != rmaxd) || (!fld_is_double && rmin != rmax)) && maxdif != 0)
117 {
118 ifld = malloc(ndpts * sizeof(g2int));
119
120 /* Determine which algorithm to use based on user-supplied
121 * binary scale factor and number of bits. */
122 if (idrstmpl[1] == 0)
123 {
124 /* No binary scaling and calculate minumum number of bits
125 * in which the data will fit. */
126 imin = (g2int)rint((fld_is_double ? rmind : rmin) * dscale);
127 imax = (g2int)rint((fld_is_double ? rmaxd : rmax) * dscale);
128 maxdif = imax - imin;
129 temp = log((double)(maxdif + 1)) / alog2;
130 nbits = (g2int)ceil(temp);
131 /* scale data */
132 if (fld_is_double)
133 {
134 rmind = (float)imin;
135 for(j = 0; j < ndpts; j++)
136 ifld[j] = (g2int)rint(dfld[j] * dscale) - imin;
137 }
138 else
139 {
140 rmin = (float)imin;
141 for(j = 0; j < ndpts; j++)
142 ifld[j] = (g2int)rint(ffld[j] * dscale) - imin;
143 }
144 }
145 else
146 {
147 /* Use binary scaling factor and calculate minumum number
148 * of bits in which the data will fit. */
149 if (fld_is_double)
150 {
151 rmind = rmind * dscale;
152 rmaxd = rmaxd * dscale;
153 maxdif = (g2int)rint((rmaxd - rmind) * bscale);
154 }
155 else
156 {
157 rmin = rmin * dscale;
158 rmax = rmax * dscale;
159 maxdif = (g2int)rint((rmax - rmin) * bscale);
160 }
161
162 temp = log((double)(maxdif + 1)) / alog2;
163 nbits = (g2int)ceil(temp);
164 /* scale data */
165 if (fld_is_double)
166 {
167 for (j = 0; j < ndpts; j++)
168 ifld[j] = (g2int)rint(((dfld[j] * dscale) - rmind) * bscale);
169 }
170 else
171 {
172 for (j = 0; j < ndpts; j++)
173 ifld[j] = (g2int)rint(((ffld[j] * dscale) - rmin) * bscale);
174 }
175 }
176
177 /* Pack data into full octets, then do JPEG 2000 encode and
178 * calculate the length of the packed data in bytes. */
179 retry = 0;
180 nbytes = (nbits + 7) / 8;
181 nsize = *lcpack; /* needed for input to enc_jpeg2000 */
182 ctemp = calloc(ndpts, nbytes);
183 sbits(ctemp, ifld, 0, nbytes * 8, 0, ndpts);
184 if ((*lcpack = (g2int)enc_jpeg2000(ctemp, width, height, nbits, idrstmpl[5],
185 idrstmpl[6], retry, (char *)cpack, nsize)) <= 0)
186 {
187 if (verbose)
188 printf("jpcpack: ERROR Packing JPC = %d\n", (int)*lcpack);
189 ret = G2C_EJPEG;
190 if (*lcpack == -3)
191 {
192 retry = 1;
193 if ((*lcpack = (g2int)enc_jpeg2000(ctemp, width, height, nbits, idrstmpl[5],
194 idrstmpl[6], retry, (char *)cpack, nsize)) <= 0)
195 {
196 if (verbose)
197 printf("jpcpack: Retry Failed.\n");
198 ret = G2C_EJPEG;
199 }
200 else
201 {
202 if (verbose)
203 printf("jpcpack: Retry Successful.\n");
204 ret = G2C_NOERROR;
205 }
206 }
207 }
208 free(ctemp);
209 }
210 else
211 {
212 nbits = 0;
213 *lcpack = 0;
214 }
215
216 /* Fill in ref value and number of bits in Template 5.0. */
217 if (fld_is_double)
218 rmin = (float)rmind;
219 mkieee(&rmin, idrstmpl, 1); /* ensure reference value is IEEE format. */
220 idrstmpl[3] = nbits;
221 idrstmpl[4] = 0; /* original data were reals */
222 if (idrstmpl[5] == 0)
223 idrstmpl[6] = 255; /* lossy not used */
224 if (ifld)
225 free(ifld);
226
227 return ret;
228}
229
268void
269jpcpack(float *fld, g2int width, g2int height, g2int *idrstmpl,
270 unsigned char *cpack, g2int *lcpack)
271{
272 jpcpack_int(fld, 0, width, height, idrstmpl, cpack, lcpack, 1);
273}
274
319int
320g2c_jpcpackf(float *fld, size_t width, size_t height, int *idrstmpl,
321 unsigned char *cpack, size_t *lcpack)
322{
323 g2int width8 = width, height8 = height, lcpack8 = *lcpack;
325 int i, ret;
326
327 for (i = 0; i < G2C_JPEG_DRS_TEMPLATE_LEN; i++)
328 idrstmpl8[i] = idrstmpl[i];
329
330 ret = jpcpack_int(fld, 0, width8, height8, idrstmpl8, cpack, &lcpack8, 0);
331
332 if (!ret)
333 {
334 for (i = 0; i < G2C_JPEG_DRS_TEMPLATE_LEN; i++)
335 idrstmpl[i] = (int)idrstmpl8[i];
336 *lcpack = (g2int)lcpack8;
337 }
338 return ret;
339}
340
385int
386g2c_jpcpackd(double *fld, size_t width, size_t height, int *idrstmpl,
387 unsigned char *cpack, size_t *lcpack)
388{
389 g2int width8 = width, height8 = height, lcpack8 = *lcpack;
391 int i, ret;
392
393 for (i = 0; i < G2C_JPEG_DRS_TEMPLATE_LEN; i++)
394 idrstmpl8[i] = idrstmpl[i];
395
396 ret = jpcpack_int(fld, 1, width8, height8, idrstmpl8, cpack, &lcpack8, 0);
397
398 if (!ret)
399 {
400 for (i = 0; i < G2C_JPEG_DRS_TEMPLATE_LEN; i++)
401 idrstmpl[i] = (int)idrstmpl8[i];
402 *lcpack = (g2int)lcpack8;
403 }
404 return ret;
405}
int enc_jpeg2000(unsigned char *cin, g2int width, g2int height, g2int nbits, g2int ltype, g2int ratio, g2int retry, char *outjpc, g2int jpclen)
Encode a grayscale image into a JPEG2000 code stream specified in the JPEG2000 Part-1 standard (i....
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
#define G2C_JPEG_DRS_TEMPLATE_LEN
Length of the idrstmpl array for JPEG packing.
Definition grib2.h:420
#define G2C_EJPEG
Error encoding/decoding JPEG data.
Definition grib2.h:510
int64_t g2int
Long integer type.
Definition grib2.h:32
#define G2C_NOERROR
No error.
Definition grib2.h:491
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:426
#define ALOG2
ln(2.0)
Definition grib2_int.h:30
int g2c_jpcpackd(double *fld, size_t width, size_t height, int *idrstmpl, unsigned char *cpack, size_t *lcpack)
This function packs up a double array into a JPEG2000 code stream.
Definition jpcpack.c:386
int g2c_jpcpackf(float *fld, size_t width, size_t height, int *idrstmpl, unsigned char *cpack, size_t *lcpack)
This function packs up a float array into a JPEG2000 code stream.
Definition jpcpack.c:320
void jpcpack(float *fld, g2int width, g2int height, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack)
This function packs up a float array into a JPEG2000 code stream.
Definition jpcpack.c:269
static int jpcpack_int(void *fld, int fld_is_double, g2int width, g2int height, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack, int verbose)
Packs a float or double array into a JPEG2000 code stream.
Definition jpcpack.c:54