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