NCEPLIBS-g2c  1.7.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 
56 static void
57 jpcpack_int(void *fld, int fld_is_double, g2int width, g2int height, g2int *idrstmpl,
58  unsigned char *cpack, g2int *lcpack)
59 {
60  g2int *ifld = NULL;
61  static float alog2 = ALOG2; /* ln(2.0) */
62  g2int j, nbits, imin, imax, maxdif;
63  g2int ndpts, nbytes, nsize, retry;
64  float bscale, dscale, rmax, rmin, temp;
65  double rmaxd, rmind;
66  unsigned char *ctemp;
67  float *ffld = fld;
68  double *dfld = fld;
69 
70  LOG((2, "jpcpack_int() fld_is_double %d width %ld height %ld idrstmpl[1] %ld *lcpack %ld",
71  fld_is_double, width, height, idrstmpl[1], *lcpack));
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  printf("jpcpack: ERROR Packing JPC = %d\n", (int)*lcpack);
188  if (*lcpack == -3)
189  {
190  retry = 1;
191  if ((*lcpack = (g2int)enc_jpeg2000(ctemp, width, height, nbits, idrstmpl[5],
192  idrstmpl[6], retry, (char *)cpack, nsize)) <= 0)
193  printf("jpcpack: Retry Failed.\n");
194  else
195  printf("jpcpack: Retry Successful.\n");
196  }
197  }
198  free(ctemp);
199  }
200  else
201  {
202  nbits = 0;
203  *lcpack = 0;
204  }
205 
206  /* Fill in ref value and number of bits in Template 5.0. */
207  if (fld_is_double)
208  rmin = (float)rmind;
209  mkieee(&rmin, idrstmpl, 1); /* ensure reference value is IEEE format. */
210  idrstmpl[3] = nbits;
211  idrstmpl[4] = 0; /* original data were reals */
212  if (idrstmpl[5] == 0)
213  idrstmpl[6] = 255; /* lossy not used */
214  if (ifld)
215  free(ifld);
216 }
217 
252 void
253 jpcpack(float *fld, g2int width, g2int height, g2int *idrstmpl,
254  unsigned char *cpack, g2int *lcpack)
255 {
256  jpcpack_int(fld, 0, width, height, idrstmpl, cpack, lcpack);
257 }
258 
293 void
294 jpcpackd(double *fld, g2int width, g2int height, g2int *idrstmpl,
295  unsigned char *cpack, g2int *lcpack)
296 {
297  jpcpack_int(fld, 1, width, height, idrstmpl, cpack, lcpack);
298 }
jpcpack_int
static void jpcpack_int(void *fld, int fld_is_double, g2int width, g2int height, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack)
This subroutine packs up a float or double array into a JPEG2000 code stream.
Definition: jpcpack.c:57
int_power
double int_power(double x, g2int y)
Function similar to C pow() power function.
Definition: int_power.c:18
LOG
#define LOG(e)
Ignore logging to stdout.
Definition: grib2_int.h:138
grib2_int.h
Header file with internal function prototypes NCEPLIBS-g2c library.
sbits
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:114
mkieee
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
g2int
int64_t g2int
Long integer type.
Definition: grib2.h:28
enc_jpeg2000
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:51
ALOG2
#define ALOG2
ln(2.0)
Definition: grib2_int.h:21
jpcpackd
void jpcpackd(double *fld, g2int width, g2int height, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack)
This subroutine packs up a data field into a JPEG2000 code stream.
Definition: jpcpack.c:294
jpcpack
void jpcpack(float *fld, g2int width, g2int height, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack)
This subroutine packs up a data field into a JPEG2000 code stream.
Definition: jpcpack.c:253