C+ C NAME: C ice_read C PURPOSE: C Reads a compressed file written by href=ice_write= into an integer array C CATEGORY: C Bits and bytes C CALLING SEQUENCE: function ice_read(iAct0, cFile, nOrig, Orig, nPack, Pack, cExtra, cVersion) C INPUTS: C cFile character*(*) file name of compressed file C nOrig integer # elements in Orig C C nPack integer # elements in Pack C Pack integer scratch array (needed to store the compressed data) C OUTPUTS: C ice_read integer 0: failure (an error message is displayed) C 1: success C nOrig integer # elements in Orig filled with decompressed data C Orig(nOrig) integer decompressed integer array C Only the first nOrig elements contain useful information. C cExtra character*(*) optional string extracted from end of file C cExtra=' ' if no trailer was found. C cVersion character*8 Version string in form 'ice 000n' C (currently n=2) C CALLS: C bOpenFile, iFreeLun, ice_unpack, Say, Int2Str, Str2Str, ArrI4Copy C INCLUDE: include 'openfile.h' C SEE ALSO: C ice_write C PROCEDURE: C See href=ice_pack= for information on the compression algorithm. C MODIFICATION HISTORY: C AUG-2000, Paul Hick (UCSD/CASS; pphick@ucsd.edu) C- integer iAct0 character cFile*(*) integer nOrig integer Orig(nOrig) integer nPack integer Pack(nPack) character cExtra*(*) character cVersion*(*) parameter (nbit = 32) parameter (nbit1 = nbit-1) parameter (nByte = 512) parameter (nRecl = nByte/4) ! Read 512 bytes records integer kperm(0:nbit1) integer nStore (nRecl) character cStore*(nByte) equivalence (nStore, cStore) integer iVers(2) character cVers*8 equivalence (iVers, cVers) character cSay*8 /'ice_read'/ character cStr*200 integer Str2Str logical bOpenFile ice_read = 0 iRecl = nRecl if (bOpenFile(iAct0+OPN__READONLY,iU,cFile,iRecl)) then iR = 1 read (iU, rec=iR) nStore call ArrI4Copy(2, nStore, iVers) ! Version number in 1st 8 bytes cVersion = cVers iOrig0 = nStore(3) ! Original array length ibit0 = nStore(4) ! # bits in compressed file iPack = 1+(ibit0-1)/nbit if (iOrig0 .gt. nOrig) then call Say(cSay,'W','Data','array for unpacked data not large enough') else if (iPack .gt. nPack) then call Say(cSay,'W','Scratch','array for packed data not large enough') else kmax = nStore(5) kshift = nStore(6) klenbit = nStore(7) ksign = nStore(8) nExtra = nStore(9) I = kmax-kshift+1 call ArrI4Copy(I, nStore(9+1), kperm) ! Permutation table nR = iPack/nRecl do I=0,nR-1 iR = iR+1 read (iU, rec=iR) (Pack(I*nRecl+J), J=1,nRecl) end do I = nR*nRecl if (iPack .gt. I) then ! Remaining elements (< nRecl) iR = iR+1 read (iU, rec=iR) nStore call ArrI4Copy(iPack-I, nStore, Pack(I+1)) end if I = 0 do while (I+nByte .le. nExtra) iR = iR+1 read (iU, rec=iR) cExtra(I+1:I+nByte) I = I+nByte end do if (nExtra .gt. I) then iR = iR+1 read (iU, rec=iR) cStore cExtra(I+1:) = cStore(:nExtra-I) end if iU = iFreeLun(iU) ibit1 = ice_unpack(ibit0, kmax, kshift, klenbit, ksign, kperm, nOrig, Orig, iPack, Pack, iOrig1) L = len(cStr) I = 0 I = I+Str2Str('max =' , cStr(I+1:))+1 I = I+Int2Str(kmax , cStr(I+1:)) I = I+Str2Str('; shift =' , cStr(I+1:))+1 I = I+Int2Str(kshift , cStr(I+1:)) I = I+Str2Str('; lenbit =' , cStr(I+1:))+1 I = I+Int2Str(klenbit , cStr(I+1:)) I = I+Str2Str('; sign =' , cStr(I+1:))+1 I = I+Int2Str(ksign , cStr(I+1:)) I = I+Str2Str('#perm =' , cStr(I+1:)) do J=0,kmax-kshift I = I+1 if (I .lt. L) I = I+Int2Str(kperm(J), cStr(I+1:)) end do call Say(cSay,'I','Unpack',cStr) if (ibit1 .eq. ibit0 .and. iOrig1 .eq. iOrig0) then nOrig = iOrig0 ice_read = 1 else I = 0 I = I+Str2Str('Unpacked' , cStr(I+1:))+1 I = I+Int2Str(ibit1 , cStr(I+1:))+1 I = I+Str2Str('bits into' , cStr(I+1:))+1 I = I+Int2Str(iOrig1 , cStr(I+1:))+1 I = I+Str2Str('long integers#', cStr(I+1:)) I = I+Str2Str('Expected' , cStr(I+1:))+1 I = I+Int2Str(ibit0 , cStr(I+1:))+1 I = I+Str2Str('bits into' , cStr(I+1:))+1 I = I+Int2Str(iOrig0 , cStr(I+1:))+1 I = I+Str2Str('long integers', cStr(I+1:)) call Say(cSay,'W','Error',cStr) end if end if end if return end