C+ C NAME: C ice_unpack C PURPOSE: C Deompresses an integer array compressed using href=ice_pack= C CATEGORY: C gen/for/lib C CALLING SEQUENCE: function ice_unpack(ibit, kmax, kshift, nlenbit, nsign, nperm, nOrig, Orig, nPack, Pack, iOrig) C INPUTS: C ibit integer # bits in Pack containing compressed data. C C kmax integer cutoff for applying compression C kshift integer minimum # bits copied for each difference C C nlenbit integer # bits encoded when the full value instead C of a difference is used C nsign integer -1: all values in Orig are < zero C +1: all values in Orig are >= zero C 0: both positive and negative values are present C nperm(0:kmax) integer permutation table C (if not available use nperm(i) = i [i=0,kmax]) C nPack integer # of elements in Pack containing compressed data C Pack(nPack) integer compressed data C OUTPUTS: C ice_unpack integer # bits in Pack used to hold the compressed data C as determined during the decompression. This value C msut match the input value ibit. C C On failure jbit = 0 is returned (happens only if the array C Orig is not big enough to hold the decompressed data). C nOrig integer # elements in Orig C Orig(nOrig) integer array to receive decompressed data C This array is updated only up to element iOrig. C iOrig integer # elements in Orig filled with decompressed data. C SEE ALSO: C ice_pack, ice_analyze, ice_write, ice_read C PROCEDURE: C > Inverts the compression of href=ice_pack=. C > The input values for ibit, kmax, nlenbit, nsign, nperm must be the same as for C the ice_pack call that created the compressed array Pack. C MODIFICATION HISTORY: C AUG-2000, Paul Hick (UCSD/CASS; pphick@ucsd.edu) C- integer ibit integer kmax integer kshift integer nlenbit integer nsign integer nperm(0:kmax-kshift) ! Permutation table integer nOrig integer Orig(0:nOrig-1) integer nPack integer Pack(0:nPack-1) integer iOrig parameter (nbit = 32) parameter (nbit1 = nbit-1) itopbit = nlenbit-1 nOrig1 = nOrig-1 iprev = 0 ib = -1 ! Last bit in Pack processed iOrig = -1 do while (ib .lt. ibit-1) ib = ib+1 ! First bit of new element ipad = ib do while (.not. btest(Pack(ib/nbit), mod(ib,nbit))) ib = ib+1 ! Look for the terminating 1-bit end do ipad = nperm(ib-ipad) ! i-ipad is # leading 0-bits if (ipad .eq. kmax-kshift) then ! Full value encoded itop = itopbit isgn = itop+abs(nsign) ! No sign bit; pretend it is at itop+1 else !------- ! The following are correct only for kshift = 0. This is taken into account below. itop = kshift+ipad-1 isgn = itop end if if (iOrig .eq. nOrig1) then ice_unpack = 0 return end if !------- ! The next itop+1 bits (0....itop) make up the encoded value. ! Copy these into Orig(iOrig). Bit itop is the sign bit. ! (itop = -1 refers to a zero difference (no encoded bits at all). iOrig = iOrig+1 ! Next decoded element Orig(iOrig) = 0 !------- ! For kshift > 0, if there are no leading zeros then the terminating ! 1-bit is followed by a single bit used to identify zero differences. ! This bit is used to update itop and isgn. if (kshift .gt. 0 .and. ipad .eq. 0) then ib = ib+1 if (btest(Pack(ib/nbit), mod(ib,nbit))) then ib = ib+1 ! Non-zero diff, next bit is the sign if (btest(Pack(ib/nbit), mod(ib,nbit))) then ksgn = -1 else ksgn = 1 end if else ! Zero difference itop = -1 end if end if !------- ! For zero differences we are done if (itop .ne. -1) then !------- ! Pick up all bits except the sign bit. do i=0,max(kshift,isgn)-1 ib = ib+1 if (btest(Pack(ib/nbit), mod(ib,nbit))) Orig(iOrig) = ibset(Orig(iOrig),i) end do if (ipad .eq. kmax-kshift .and. nsign .ne. 0) then !------- ! All encoded full values are positive. ! The sign is established by the input nsign (+/-1) ksgn = nsign else if (ipad .gt. 0) then !------- ! Set bit itop in Orig(iOrig) if a difference was encoded. ! Now Orig(iOrig) contains the absolute difference. if (ipad .lt. kmax-kshift) Orig(iOrig) = ibset(Orig(iOrig), itop) !------- ! The next bit in Pack is the sign bit. Use it to set ksgn to +1 or -1 ib = ib+1 if (btest(Pack(ib/nbit), mod(ib,nbit))) then ksgn = -1 else ksgn = 1 end if end if Orig(iOrig) = ksgn*Orig(iOrig) end if !------- ! If a difference was encoded then add the previous element. if (ipad .lt. kmax-kshift) Orig(iOrig) = iprev+Orig(iOrig) iprev = Orig(iOrig) ! Update previous element value end do iOrig = iOrig+1 ! # elements in Orig updated ice_unpack = ib+1 ! # bits of compressed data return end