1 subroutine pngpack(fld,width,height,idrstmpl,cpack,lcpack)
2 !$$$ SUBPROGRAM DOCUMENTATION BLOCK
5 ! PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-21
7 ! ABSTRACT: This subroutine packs up a data field into PNG image format.
8 ! After the data field is scaled, and the reference value is subtracted out,
9 ! it is treated as a grayscale image and passed to a PNG encoder.
10 ! It also fills in GRIB2 Data Representation Template 5.41 or 5.40010 with the
13 ! PROGRAM HISTORY LOG:
16 ! USAGE: CALL pngpack(fld,width,height,idrstmpl,cpack,lcpack)
17 ! INPUT ARGUMENT LIST:
18 ! fld() - Contains the data values to pack
19 ! width - number of points in the x direction
20 ! height - number of points in the y direction
21 ! idrstmpl - Contains the array of values for Data Representation
22 ! Template 5.41 or 5.40010
23 ! (1) = Reference value - ignored on input
24 ! (2) = Binary Scale Factor
25 ! (3) = Decimal Scale Factor
26 ! (4) = number of bits for each data value - ignored on input
27 ! (5) = Original field type - currently ignored on input
28 ! Data values assumed to be reals.
30 ! OUTPUT ARGUMENT LIST:
31 ! idrstmpl - Contains the array of values for Data Representation
32 ! Template 5.41 or 5.40010
33 ! (1) = Reference value - set by pngpack routine.
34 ! (2) = Binary Scale Factor - unchanged from input
35 ! (3) = Decimal Scale Factor - unchanged from input
36 ! (4) = Number of bits containing each grayscale pixel value
37 ! (5) = Original field type - currently set = 0 on output.
38 ! Data values assumed to be reals.
39 ! cpack - The packed data field (character*1 array)
40 ! lcpack - length of packed field cpack().
45 ! LANGUAGE: XL Fortran 90
50 integer,intent(in) :: width,height
51 real,intent(in) :: fld(width*height)
52 character(len=1),intent(out) :: cpack(*)
53 integer,intent(inout) :: idrstmpl(*)
54 integer,intent(out) :: lcpack
58 integer :: ifld(width*height)
59 integer,parameter :: zero=0
61 character(len=1),allocatable :: ctemp(:)
64 bscale=2.0**real(-idrstmpl(2))
65 dscale=10.0**real(idrstmpl(3))
67 ! Find max and min values in the data
72 if (fld(j).gt.rmax) rmax=fld(j)
73 if (fld(j).lt.rmin) rmin=fld(j)
75 maxdif=nint((rmax-rmin)*dscale*bscale)
77 ! If max and min values are not equal, pack up field.
78 ! If they are equal, we have a constant field, and the reference
79 ! value (rmin) is the value for each point in the field and
82 if (rmin.ne.rmax .AND. maxdif.ne.0) then
84 ! Determine which algorithm to use based on user-supplied
85 ! binary scale factor and number of bits.
87 if (idrstmpl(2).eq.0) then
89 ! No binary scaling and calculate minimum number of
90 ! bits in which the data will fit.
92 imin=nint(rmin*dscale)
93 imax=nint(rmax*dscale)
95 temp=alog(real(maxdif+1))/alog(2.0)
100 ifld(j)=nint(fld(j)*dscale)-imin
104 ! Use binary scaling factor and calculate minimum number of
105 ! bits in which the data will fit.
109 maxdif=nint((rmax-rmin)*bscale)
110 temp=alog(real(maxdif+1))/alog(2.0)
114 ifld(j)=nint(((fld(j)*dscale)-rmin)*bscale)
118 ! Pack data into full octets, then do PNG encode.
119 ! and calculate the length of the packed data in bytes
123 elseif (nbits.le.16) then
125 elseif (nbits.le.24) then
130 nbytes=(nbits/8)*ndpts
131 allocate(ctemp(nbytes))
132 call g2lib_sbytes(ctemp,ifld,0,nbits,0,ndpts)
134 ! Encode data into PNG Format.
136 lcpack=enc_png(ctemp,width,height,nbits,cpack)
137 if (lcpack.le.0) then
138 print *,'pngpack: ERROR Encoding PNG = ',lcpack
148 ! Fill in ref value and number of bits in Template 5.0
150 call mkieee(rmin,ref,1) ! ensure reference value is IEEE format
151 ! call g2lib_gbyte(ref,idrstmpl(1),0,32)
152 iref=transfer(ref,iref)
155 idrstmpl(5)=0 ! original data were reals