NCEPLIBS-g2 3.5.1
Loading...
Searching...
No Matches
g2png.F90
Go to the documentation of this file.
1
6
33subroutine 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
149end subroutine pngpack
150
167subroutine 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
214end 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