NCEPLIBS-g2  3.5.0
g2png.F90
Go to the documentation of this file.
1 
6 
33 subroutine pngpack(fld, width, height, idrstmpl, cpack, lcpack)
34  implicit none
35 
36  integer, intent(in) :: width, height
37  real, intent(in) :: fld(width * height)
38  character(len = 1), intent(out) :: cpack(*)
39  integer, intent(inout) :: idrstmpl(*)
40  integer, intent(out) :: lcpack
41 
42  real(4) :: ref, rmin4
43  real(8) :: rmin, rmax
44  integer(4) :: iref
45  integer :: ifld(width * height), nbits
46  integer, parameter :: zero = 0
47  character(len = 1), allocatable :: ctemp(:)
48  real :: bscale, dscale, temp
49  integer :: imax, imin, j, maxdif, nbytes, ndpts
50 
51  interface
52  function enc_png(data, width, height, nbits, pngbuf) bind(c, name="enc_png")
53  use iso_c_binding
54  character(kind = c_char), intent(in) :: data(*)
55  integer(c_int), intent(in) :: width, height
56  integer(c_int), intent(inout) :: nbits
57  character(kind = c_char), intent(out) :: pngbuf(*)
58  integer(c_int) :: enc_png
59  end function enc_png
60  end interface
61 
62  ndpts = width * height
63  bscale = 2.0**real(-idrstmpl(2))
64  dscale = 10.0**real(idrstmpl(3))
65 
66  ! Find max and min values in the data
67  if(ndpts > 0) then
68  rmax = fld(1)
69  rmin = fld(1)
70  else
71  rmax = 1.0
72  rmin = 1.0
73  endif
74  do j = 2, ndpts
75  if (fld(j) .gt. rmax) rmax = fld(j)
76  if (fld(j) .lt. rmin) rmin = fld(j)
77  enddo
78  maxdif = nint((rmax - rmin) * dscale * bscale)
79 
80  ! If max and min values are not equal, pack up field. If they are
81  ! equal, we have a constant field, and the reference value (rmin) is
82  ! the value for each point in the field and set nbits to 0.
83  if (rmin .ne. rmax .AND. maxdif .ne. 0) then
84 
85  ! Determine which algorithm to use based on user-supplied binary
86  ! scale factor and number of bits.
87  if (idrstmpl(2) .eq. 0) then
88  ! No binary scaling and calculate minimum number of bits in
89  ! which the data will fit.
90  imin = nint(rmin * dscale)
91  imax = nint(rmax * dscale)
92  maxdif = imax - imin
93  temp = alog(real(maxdif + 1)) / alog(2.0)
94  nbits = ceiling(temp)
95  rmin = real(imin)
96  ! scale data
97  do j = 1, ndpts
98  ifld(j) = nint(fld(j) * dscale) - imin
99  enddo
100  else
101  ! Use binary scaling factor and calculate minimum number of
102  ! bits in which the data will fit.
103  rmin = rmin * dscale
104  rmax = rmax * dscale
105  maxdif = nint((rmax - rmin) * bscale)
106  temp = alog(real(maxdif + 1)) / alog(2.0)
107  nbits = ceiling(temp)
108  ! scale data
109  do j = 1, ndpts
110  ifld(j) = max(0, nint(((fld(j) * dscale) - rmin) * bscale))
111  enddo
112  endif
113 
114  ! Pack data into full octets, then do PNG encode. and calculate
115  ! the length of the packed data in bytes.
116  if (nbits .le. 8) then
117  nbits = 8
118  elseif (nbits .le. 16) then
119  nbits = 16
120  elseif (nbits .le. 24) then
121  nbits = 24
122  else
123  nbits = 32
124  endif
125  nbytes = (nbits / 8) * ndpts
126  allocate(ctemp(nbytes))
127  call g2_sbytesc(ctemp, ifld, 0, nbits, 0, ndpts)
128 
129  ! Encode data into PNG Format.
130  lcpack = enc_png(ctemp, width, height, nbits, cpack)
131  if (lcpack .le. 0) then
132  print *, 'pngpack: ERROR Encoding PNG = ', lcpack
133  endif
134  deallocate(ctemp)
135 
136  else
137  nbits = 0
138  lcpack = 0
139  endif
140 
141  ! Fill in ref value and number of bits in Template 5.0.
142  rmin4 = real(rmin, 4)
143  call mkieee(rmin4, ref, 1) ! ensure reference value is IEEE format
144  iref = transfer(ref, iref)
145  idrstmpl(1) = iref
146  idrstmpl(4) = nbits
147  idrstmpl(5) = 0 ! original data were reals
148 
149 end subroutine pngpack
150 
167 subroutine pngunpack(cpack, len, idrstmpl, ndpts, fld)
168  implicit none
169 
170  character(len = 1), intent(in) :: cpack(len)
171  integer, intent(in) :: ndpts, len
172  integer, intent(in) :: idrstmpl(*)
173  real, intent(out) :: fld(ndpts)
174 
175  integer :: ifld(ndpts)
176  character(len = 1), allocatable :: ctemp(:)
177  integer(4) :: ieee
178  real :: ref, bscale, dscale
179  integer :: width, height
180  integer :: iret, itype, j, nbits
181 
182  interface
183  function dec_png(pngbuf, width, height, cout) bind(c, name="dec_png")
184  use iso_c_binding
185  character(kind = c_char), intent(in) :: pngbuf(*)
186  integer(c_int), intent(in) :: width, height
187  character(kind = c_char), intent(out) :: cout(*)
188  integer(c_int) :: dec_png
189  end function dec_png
190  end interface
191 
192  ieee = idrstmpl(1)
193  call rdieee(ieee, ref, 1)
194  bscale = 2.0**real(idrstmpl(2))
195  dscale = 10.0**real(-idrstmpl(3))
196  nbits = idrstmpl(4)
197  itype = idrstmpl(5)
198 
199  ! If nbits equals 0, we have a constant field where the reference value
200  ! is the data value at each gridpoint.
201  if (nbits .ne. 0) then
202  allocate(ctemp(ndpts * 4))
203  iret = dec_png(cpack, width, height, ctemp)
204  call g2_gbytesc(ctemp, ifld, 0, nbits, 0, ndpts)
205  deallocate(ctemp)
206  do j = 1, ndpts
207  fld(j) = ((real(ifld(j)) * bscale) + ref) * dscale
208  enddo
209  else
210  do j = 1, ndpts
211  fld(j) = ref
212  enddo
213  endif
214 end subroutine pngunpack
subroutine g2_gbytesc(in, iout, iskip, nbits, nskip, n)
Extract arbitrary size big-endian integer values (up to 32 bits each) from a packed bit string.
Definition: g2bytes.F90:120
subroutine rdieee(rieee, a, num)
Copy array of 32-bit IEEE floating point values to local floating point representation.
Definition: g2bytes.F90:637
subroutine mkieee(a, rieee, num)
Copy an array of real to an array of 32-bit IEEE floating points.
Definition: g2bytes.F90:685
subroutine g2_sbytesc(out, in, iskip, nbits, nskip, n)
Put arbitrary size (up to 32 bits each) integer values into a packed bit string in big-endian order.
Definition: g2bytes.F90:402
int enc_png(char *data, g2int *width, g2int *height, g2int *nbits, char *pngbuf)
create png_structs to write png stream into memory.
Definition: g2cpng.c:74
int dec_png(unsigned char *pngbuf, g2int *width, g2int *height, char *cout)
Decode some PNG compressed data.
Definition: g2cpng.c:188
subroutine pngunpack(cpack, len, idrstmpl, ndpts, fld)
Unpack a data field with PNG, defined in [Data Representation Template 5.40](https://www....
Definition: g2png.F90:168
subroutine pngpack(fld, width, height, idrstmpl, cpack, lcpack)
Pack a data field into PNG image format, defined in [Data Representation Template 5....
Definition: g2png.F90:34