;+ ; NAME: ; ice_unpack ; PURPOSE: ; Deompresses an integer array compressed using href=ice_pack= ; CATEGORY: ; Bits and bytes ; CALLING SEQUENCE: FUNCTION ice_unpack, ibit, Pack, Orig, kmax=kmax, kshift=kshift, lenbit=lenbit, sign=sign, perm=perm ; INPUTS: ; ibit scalar; type: integer ; # bits in Pack containing compressed data. ; ; OPTIONAL INPUTS: ; kmax scalar; type: integer; default: 8 ; cutoff for applying compression ; kshift scalar; type: integer; default: 0 ; minimum # bits copied for each difference ; lenbit scalar: type: integer; default: 16 ; # bits encoded when the full value instead ; of a difference is used ; sign scalar; type: integer ; -1: all values in Orig are < zero ; +1: all values in Orig are >= zero ; 0: both positive and negative values are present ; perm array[0:kmax-kshift]; type: integer; default: lindgen(kmax-kshift+1) ; permutation table ; Pack array; type:long integer ; compressed data ; OUTPUTS: ; Result scalar; type: long integer ; # bits in Pack used to hold the compressed data ; as determined during the decompression. This ; should match the input value ibit. ; Orig array; long integer ; decompressed array ; INCLUDE: @compile_opt.pro ; On error, return to caller ; CALLS: ; ibtestf, ibsetf ; SEE ALSO: ; ice_pack ; PROCEDURE: ; > The input values for ibit, kmax, lenbit, sign, perm must be the same as for ; the ice_pack call that created the compressed array Pack. ; > Inverts the compression of href=ice_pack=. ; MODIFICATION HISTORY: ; AUG-2000, Paul Hick (UCSD; pphick@ucsd.edu) ;- InitVar, kmax , 8 InitVar, kshift , 0 InitVar, lenbit , 16 InitVar, sign , 1 InitVar, perm , lindgen(kmax-kshift+1) nOrig = n_elements(Pack) Orig = lonarr(nOrig) nbit = 32L nbit1 = nbit - 1L topbit = lenbit- 1L nOrig1 = nOrig - 1L iprev = 0L ib = -1L ;Last bit in Pack processed iOrig = -1L WHILE ib LT ibit-1 DO BEGIN ib += 1L ;First bit of new element ipad = ib WHILE NOT ibtestf(Pack[ib/nbit], ib mod nbit) DO ib += 1L ;Look for the terminating 1-bit ipad = perm[ib - ipad] IF ipad EQ kmax - kshift THEN BEGIN ;Full value encoded itop = topbit isgn = itop+abs(sign) ;No sign bit; pretend it is at itop+1 ;------- ;The following are correct only for kshift = 0. This is taken into account below. ENDIF ELSE BEGIN itop = kshift + ipad -1L isgn = itop ENDELSE ;------- ; If array Orig is filled up then make it bigger. IF iOrig EQ nOrig1 THEN BEGIN Orig = [Orig, lonarr(nOrig)] nOrig1 += nOrig ENDIF ;------- ;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 += 1L ;Next decoded element Orig[iOrig] = 0L ;------- ;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 0L AND ipad EQ 0L THEN BEGIN ib += 1L ;Non-zero diff, next bit is the sign IF ibtestf(Pack[ib/nbit], ib mod nbit) THEN BEGIN ib += 1L IF ibtestf(Pack[ib/nbit], ib mod nbit) THEN ksgn = -1L ELSE ksgn = 1L ENDIF ELSE itop = -1L ;Zero difference ENDIF ;------- ;For zero differences we are done IF itop NE -1L THEN BEGIN ;------- ;Pick up all bits except the sign bit. FOR i = 0L, (kshift > isgn) - 1L DO BEGIN ib += 1L IF ibtestf(Pack[ib/nbit], ib mod nbit) THEN Orig[iOrig] = ibsetf(Orig(iOrig), i) ENDFOR IF ipad EQ kmax - kshift AND sign NE 0L THEN ksgn = sign ELSE $ ;------- ;All encoded full values are positive. The sign is established by the input sign (+/-1) IF ipad GT 0L THEN BEGIN ;------- ;Set bit itop in Orig(iOrig) if a difference was encoded. Now Orig(iOrig) contains the ;absolute difference. IF ipad LT kmax - kshift THEN Orig[iOrig] = ibsetf(Orig[iOrig], itop) ;------- ;The next bit in Pack is the sign bit. Use it to set ksgn to +1 or -1 ib += 1L IF ibtestf(Pack[ib/nbit], ib mod nbit) THEN ksgn = -1L ELSE ksgn = 1L ENDIF Orig[iOrig] = ksgn*Orig[iOrig] ENDIF ;------- ;If a difference was encoded then add the previous element. IF ipad LT kmax - kshift THEN Orig[iOrig] = iprev + Orig[iOrig] iprev = Orig[iOrig] ; Update previous element value ENDWHILE Orig = Orig[0:iOrig] ; Drop unused elements in Orig RETURN, ib + 1L & END ; Return # bits of compressed data