NCEPLIBS-g2c  1.6.4
pngpack.c
Go to the documentation of this file.
1 
5 #include <stdlib.h>
6 #include <math.h>
7 #include "grib2.h"
8 
9 int enc_png(char *, g2int, g2int, g2int, char *);
10 
37 void
38 pngpack(g2float *fld, g2int width, g2int height, g2int *idrstmpl,
39  unsigned char *cpack, g2int *lcpack)
40 {
41  g2int *ifld;
42  static g2float alog2 = 0.69314718; /* ln(2.0) */
43  g2int j, nbits, imin, imax, maxdif;
44  g2int ndpts, nbytes;
45  g2float bscale, dscale, rmax, rmin, temp;
46  unsigned char *ctemp;
47 
48  ifld = 0;
49  ndpts = width * height;
50  bscale = int_power(2.0, -idrstmpl[1]);
51  dscale = int_power(10.0, idrstmpl[2]);
52 
53  /* Find max and min values in the data. */
54  rmax = fld[0];
55  rmin = fld[0];
56  for (j = 1; j < ndpts; j++)
57  {
58  if (fld[j] > rmax)
59  rmax = fld[j];
60  if (fld[j] < rmin)
61  rmin = fld[j];
62  }
63  maxdif = (g2int)rint((rmax-rmin) * dscale * bscale);
64 
65  /* If max and min values are not equal, pack up field. If they are
66  * equal, we have a constant field, and the reference value (rmin)
67  * is the value for each point in the field and set nbits to 0. */
68  if (rmin != rmax && maxdif != 0)
69  {
70  ifld = malloc(ndpts * sizeof(g2int));
71 
72  /* Determine which algorithm to use based on user-supplied
73  * binary scale factor and number of bits. */
74  if (idrstmpl[1] == 0)
75  {
76  /* No binary scaling and calculate minumum number of bits
77  * in which the data will fit. */
78  imin = (g2int)rint(rmin * dscale);
79  imax = (g2int)rint(rmax * dscale);
80  maxdif = imax - imin;
81  temp = log((double)(maxdif + 1)) / alog2;
82  nbits = (g2int)ceil(temp);
83  rmin = (g2float)imin;
84  /* scale data */
85  for(j = 0; j < ndpts; j++)
86  ifld[j] = (g2int)rint(fld[j] * dscale) - imin;
87  }
88  else
89  {
90  /* Use binary scaling factor and calculate minumum number
91  * of bits in which the data will fit. */
92  rmin = rmin * dscale;
93  rmax = rmax * dscale;
94  maxdif = (g2int)rint((rmax - rmin) * bscale);
95  temp = log((double)(maxdif + 1)) / alog2;
96  nbits = (g2int)ceil(temp);
97  /* scale data */
98  for (j = 0; j < ndpts; j++)
99  ifld[j] = (g2int)rint(((fld[j] * dscale) - rmin) * bscale);
100  }
101 
102  /* Pack data into full octets, then do PNG encode and
103  * calculate the length of the packed data in bytes. */
104  if (nbits <= 8)
105  nbits = 8;
106  else if (nbits <= 16)
107  nbits = 16;
108  else if (nbits <= 24)
109  nbits = 24;
110  else
111  nbits = 32;
112 
113  nbytes = (nbits / 8) * ndpts;
114  ctemp = calloc(nbytes, 1);
115  sbits(ctemp, ifld, 0, nbits, 0, ndpts);
116 
117  /* Encode data into PNG Format. */
118  if ((*lcpack = (g2int)enc_png((char *)ctemp, width, height, nbits, (char *)cpack)) <= 0)
119  printf("pngpack: ERROR Packing PNG = %d\n", (int)*lcpack);
120  free(ctemp);
121  }
122  else
123  {
124  nbits = 0;
125  *lcpack = 0;
126  }
127 
128  /* Fill in ref value and number of bits in Template 5.0. */
129  mkieee(&rmin, idrstmpl, 1); /* ensure reference value is IEEE format */
130  idrstmpl[3] = nbits;
131  idrstmpl[4] = 0; /* original data were reals */
132  if (ifld)
133  free(ifld);
134 }
void sbits(unsigned char *out, g2int *in, g2int iskip, g2int nbyte, 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
Header file for NCEPLIBS-g2c library.
float g2float
Float type.
Definition: grib2.h:22
int64_t g2int
Long integer type.
Definition: grib2.h:20
double int_power(double x, g2int y)
Function similar to C pow() power function.
Definition: int_power.c:17
void mkieee(g2float *a, g2int *rieee, g2int num)
This subroutine stores a list of real values in 32-bit IEEE floating point format.
Definition: mkieee.c:21
int enc_png(char *, g2int, g2int, g2int, char *)
Encode PNG.
Definition: enc_png.c:81
void pngpack(g2float *fld, g2int width, g2int height, g2int *idrstmpl, unsigned char *cpack, g2int *lcpack)
This subroutine packs up a data field into PNG image format.
Definition: pngpack.c:38