      SUBROUTINE DECOMPRESS (IBUF, OBUF, NIN, NOUT)C**********************************************************************C_TITLE DECOMPRESS - Decompresses image lines stored in a compressedC                    format. (alternate fortran souce code which willC                    run on a SUN workstation)CC_ARGS      INTEGER*4       NINC                                       Input - number of bytes inC                                       the compressed buffer.      INTEGER*4       NOUTC                                       Input - known number of bytesC                                       in decompressed output line      CHARACTER       IBUF(1)C                                       Input - line of data toC                                       decompress. The first byte isC                                       the actual pixel value, theC                                       rest of the array is the bitC                                       stream of coded "firstC                                       difference" values.      CHARACTER       OBUF(1)C                                       Output - decompressed line ofC                                       data. The routine assumesC                                       original image composed of 8C                                       bit pixels.  This is theC                                       restored image line -C                                       compression and firstC                                       differences undone - of theC                                       line passed in ibuf.CC_DESC  This routine decompresses Huffman encoded compressed data.C       (Huffman compression encoding can be found in any standardC       data compression reference.  One such book is: "DataC       Compression, Techniques and Applications, Hardware andC       Software Considerations" by Gilbert Held, John Wiley & Sons,C       publishers.)  Huffman coding uses variable number of bits toC       encode different values of the original data.  The compressionC       results because the most frequently occurring values haveC       the smaller number of bits for their codes.CC       The routine, used in conjuction with DECMPINIT,  providesC       a common data base from which to call the processingC       subroutines. DECMPINIT builds the Huffman tree from the first-C       difference histogram and is called only once per image.C       DECOMPRESS processes one compressed input line per call andC       returns it completely restored.CC_CALLS This routine calls two subroutines DCMPRS and HUFFTREE.CCC_LIMS  The fortran code found in the DECOMPS.FOR file was adaptedC       to run on a SUN work station using fortran version 3.4CC_HIST  DEC87, DMcMacken, ISD, USGS, Flagstaff, Original versionCC_ENDC***********************************************************************      INTEGER*2       TREE(5,1024)C                                       Huffman tree      INTEGER*2       VALUE      INTEGER*2       RIGHT      INTEGER*2       LEFT      INTEGER*2       PARENT      INTEGER*2       BRANCH      PARAMETER       (VALUE=1, RIGHT=2, LEFT=3, PARENT=4, BRANCH=5)      COMMON /DECOM/ TREEC***********************************************************************C Decompress an input lineC***********************************************************************      CALL DCMPRS(IBUF, OBUF, NIN, NOUT, TREE)      RETURN      END      SUBROUTINE DECMPINIT(HIST)C***********************************************************************C_TITLE DECMPINIT - initialize the decompression TREE from the firstC                   difference histogramC_ARGS      INTEGER*4       HIST(512)C                                       Input, difference histogramC                                       table. The histogram of theC                                       whole image after firstC                                       difference has been run onC                                       each line.  In a "firstC                                       difference" line the first pixelC                                       retains its actual value; allC                                       other pixels are obtained byC                                       subtracting the actual value ofC                                       the pixel from the actual valueC                                       of the preceding pixel andC                                       adding 256 to provide aC                                       positive number.  The i-thC                                       element of the array HISTC                                       should be the number of pixelsC                                       in the image with value i.CC Some computer hardware systems may need to swap the byte orderC of the 32-bit words which make up the first-difference historgram.C The histogram  is configured on the CDROM in "least significant byteC first" order. This is the order for integer values used by VAX andC IBM PC computer systems. Users of other computer architecturesC (IBM Mainframes, MacIntosh, SUN, and Apollo) will need to swapC byte pairs 1 and 4, and 2 and 3 before passing the histogram toC the DECMPINIT subroutine.CCC_DESC This routine initializes the Huffman tree using the firstC      difference histogram passed by the calling program. ThisC      subroutine must be called before the DECOMPRESS subroutineC      can be utilized.CC_HIST DEC87, DMcMacken, ISD, USGS, Flagstaff, Original VersionCC_ENDC***********************************************************************      INTEGER*2       TREE(5,1024)      COMMON /DECOM/ TREE      DO 10 I = 1,1024      DO 20 J = 1,5      TREE(J,I) = 0   20 CONTINUE   10 CONTINUE      CALL HUFFTREE (HIST, TREE)      RETURN      END      SUBROUTINE HUFFTREE(HIST, TREE)C**********************************************************************C_TITLE HUFFTREE creates a Huffman code tree from input histogramCC_ARGS      INTEGER*4       HIST(512)C                                       In - image histogram      INTEGER*2       TREE(5,1024)C                                       Out - Huffman code treeCC_DESC  This routine creates a Huffman code tree from the input firstC       difference histogram of an image.  It starts by making all validC       (non-zero) densities for the image leaf nodes.  These are sortedC       in increasing order by histogram frequency.  The two nodes withC       smallest frequencies are connected by branches to a new nodeC       which is given a frequency equal to the sum of the twoC       combining nodes. The new node takes the place of the two nodesC       and the frequency list is resorted.  The process is repeatedC       until the frequency set is reduced to one node.  The treeC       consists of a double dimensioned array whose first dimensionC       gives five parameters for each node. The first parameter givesC       a value to the node.  This is a density value for leaf nodesC       and a -1 for all others.  The second parameter is a pointer toC       the next node on the right branch from this node. The thirdC       points to the node on the left branch.  The fourth pointsC       to the parent node from which this node branches.  The fifthC       parameter notes whether this node is on the right or leftC       branch of the parent node.CC_CALLS This routine calls the specially provided sort routineC               SORTFREQ.CC_HIST  Fall86, DMcMacken, ISD, USGS, Flagstaff, Original versionCC_ENDC**********************************************************************      INTEGER*4       FREQLIST(512)C                                       Histogramm frequency list      INTEGER*2       NODELIST(512)C                                       Tree node list      INTEGER*2       VALUE      INTEGER*2       RIGHT      INTEGER*2       LEFT      INTEGER*2       PARENT      INTEGER*2       BRANCH      PARAMETER       (VALUE=1,RIGHT=2,LEFT=3,PARENT=4,BRANCH=5)      INTEGER*4       NUMNODESC                                       Node counter      INTEGER*4       IC                                       Do loop index      INTEGER*4       PTRC                                       Current node pointer      INTEGER*4       NUMFREQC                                       # non-zero frequencies      INTEGER*4       INDEXC                                       Frequency list pointerC**********************************************************************C Create leaf nodes, and pointer tablesC**********************************************************************      NUMNODES = 0      DO 10 I = 1, 512         FREQLIST(I) = HIST(I)         NUMNODES = NUMNODES + 1         PTR = NUMNODES         NODELIST(I) = PTR         TREE(VALUE, PTR) = I         TREE(PARENT, PTR) = 0   10 CONTINUEC**********************************************************************C Make sure the last element is always 0. For the first differenceC histogram, there can only be 511 values.C**********************************************************************      FREQLIST(512) = 0C**********************************************************************C Sort freqlist in increasing order; skip over zero frequenciesC**********************************************************************      NUMFREQ = 512      CALL SORTFREQ (FREQLIST, NODELIST, NUMFREQ)      INDEX = 1   20 IF (FREQLIST(INDEX) .EQ. 0) THEN         INDEX = INDEX + 1         GOTO 20      ENDIF      NUMFREQ = NUMFREQ - INDEX + 1   30 IF (NUMFREQ .GT. 1) THEN         NUMNODES = NUMNODES + 1         PTR = NUMNODES         TREE(RIGHT, PTR) = NODELIST(INDEX)         TREE(LEFT, PTR) = NODELIST(INDEX+1)         TREE(PARENT, TREE(RIGHT, PTR)) = PTR         TREE(BRANCH, TREE(RIGHT, PTR)) = RIGHT         TREE(PARENT, TREE(LEFT, PTR)) = PTR         TREE(BRANCH, TREE(LEFT, PTR)) = LEFT         TREE(VALUE, PTR) = -1         FREQLIST(INDEX + 1) = FREQLIST(INDEX)     1   + FREQLIST(INDEX + 1)         NODELIST(INDEX + 1) = PTR         FREQLIST(INDEX) = 0         INDEX = INDEX + 1         NUMFREQ = NUMFREQ - 1         CALL SORTFREQ (FREQLIST(INDEX), NODELIST(INDEX),     1   NUMFREQ)         GOTO 30      ENDIF      TREE(VALUE, 1024) = NUMNODES      RETURN      END      SUBROUTINE SORTFREQ(FREQLIST, NODELIST, NUMFREQ)C**********************************************************************C_TITLE SORTFREQ sorts frequency and node lists in increasing freq.C       order.CC_ARGS      INTEGER*4       FREQLIST(512)C                                       input - frequency list      INTEGER*2       NODELIST(512)C                                       input - node list      INTEGER*4       NUMFREQC                                       input - # values in freq listCC_DESC  This routine uses an insertion sort to reorder a frequency listC       in order of increasing frequency.  The corresponding elementsC       of the node list are reordered to maintain correspondence.CC_HIST  Fall86, DMcMacken, ISD, USGS, Flagstaff, Original versionCC_ENDC***********************************************************************      INTEGER*4       IC                                       Do loop index      INTEGER*4       JC                                       List position pointer      INTEGER*4       TEMP1C                                       Temporary storage - freq.      INTEGER*4       TEMP2C                                       Temporary storage - nodeC***********************************************************************C Save current element - starting with second - in temporaryC storage.  Compare with all elements in first part of list -C moving each up one element - until  element is larger.C Insert current element at this point in listC***********************************************************************      DO 20 I = 2, NUMFREQ         TEMP1 = FREQLIST(I)         TEMP2 = NODELIST(I)         J = I   10    IF (FREQLIST(J-1) .GT. TEMP1) THEN            FREQLIST(J) = FREQLIST(J-1)            NODELIST(J) = NODELIST(J-1)            J = J - 1            IF (J .GT. 1) GOTO 10         ENDIF         FREQLIST(J) = TEMP1         NODELIST(J) = TEMP2   20 CONTINUE      RETURN      END      SUBROUTINE DCMPRS(IBUF, OBUF, NIN, NOUT, TREE)C***********************************************************************C_TITLE DCMPRS decompresses Huffman coded compressed image linesC       (Remove this subroutine from the source code if you areC       planning to use the VAX/VMS DCMPRS.MAR macro routine inC       place of this fortran code. The DCMPRS macro version is moreC       than twice as fast as the fortran version)CC_ARGS      INTEGER*4       NINC                                       Input, # bytes in input buffer      INTEGER*4       NOUTC                                       Input, # bytes in output line      INTEGER*2       TREE(5,1024)C                                       Input, Huffman code tree      CHARACTER       IBUF(1)C                                       Input, compressed data buffer      CHARACTER       OBUF(1)C                                       Output, decompressed lineCC_DESC  This subroutine follows a path from the root of the Huffman treeC       to one of its leaves.  The choice at each branch is decided byC       the successive bits of the compressed input stream, left for 1,C       right for 0.  Only leaf nodes have a value other than -1.  TheC       routine traces a path through the tree until it finds a nodeC       with a value not equal to -1 (a leaf node).  The value at theC       leaf node is subtracted from the preceding pixel value plus 256C       to restore the the umcompressed pixel.  This algorithm is thenC       repeated until the entire line has been processed.CC_CALLS This routine uses the VAX/VMS implicit functionC       BTEST (VAR, IBIT) to test whether the bit number IBIT is setC       in the variable VAR. A fortran version of this routineC       is available for BTEST.CC_HIST  DEC86, DMcMacken, ISD, USGS, Flagstaff, Original versionCC_ENDC**********************************************************************      INTEGER*4       PTRC                                       Pointer to position in tree      INTEGER*4       KC                                       Do loop index      INTEGER*4       BITC                                       Pointer to current bit in word      INTEGER*4       NBYTEC                                       Counter, # bytes decompressed      INTEGER*4       TEMPC                                       Working variable      INTEGER*2       VALUEC                                       Value index in tree      INTEGER*2       RIGHTC                                       Right branch index in tree      INTEGER*2       LEFTC                                       Left branch index in tree      INTEGER*2       PARENTC                                       Parent pointer index in tree      INTEGER*2       BRANCHC                                       Parent branch index in tree      PARAMETER       (VALUE=1, RIGHT=2, LEFT=3, PARENT=4, BRANCH=5)C      INTEGER*2       DNC                                       Current density value      INTEGER*2       DNLC                                       Last density value      LOGICAL       ENDC                                       End of line flag      LOGICAL       BTESTCC**********************************************************************C Start at root of treeC**********************************************************************      PTR = TREE(1,1024)C**********************************************************************C Just copy first byte it is uncompressed.C**********************************************************************      OBUF(1) = IBUF(1)C**********************************************************************C Count starts hereC**********************************************************************      NBYTE = 1C**********************************************************************C Initialize current and last density valuesC**********************************************************************      DN = ICHAR(IBUF(1))      IF (DN.LT.0) DN = 256 + DN      DNL = DNC**********************************************************************C Reset end of line flagC**********************************************************************      END = .FALSE.C**********************************************************************C K points to current input byte loop is done when k exceeds #C input bytes.C**********************************************************************      K = 2      IF (K .GT. NIN) END = .TRUE.C**********************************************************************C This is the processing loopC**********************************************************************   10 IF (.NOT. END) THEN         TEMP = ICHAR(IBUF(K))         BIT = 7   20    IF (BIT .GE. 0 .AND. .NOT. END) THEN            IF (BTEST(TEMP, BIT)) THEN               PTR = TREE(LEFT, PTR)            ELSE               PTR = TREE(RIGHT, PTR)            ENDIFC**********************************************************************C We are at end leaf when value is not -1C**********************************************************************            IF (TREE(VALUE, PTR) .NE. -1) THENC**********************************************************************C Compute value of pixel, reset or increment pointers and countersC**********************************************************************               DN = TREE(VALUE, PTR)               DN = DNL - DN + 256               DNL = DN               NBYTE = NBYTE + 1               OBUF(NBYTE) = CHAR(DN)               PTR = TREE(1, 1024)               IF (NBYTE .EQ. NOUT) END = .TRUE.            ENDIFC**********************************************************************C Process next bit in byteC**********************************************************************            BIT = BIT - 1            GOTO 20         ENDIFC**********************************************************************C Set index to next input byteC**********************************************************************         K = K + 1         IF (K .GT. NIN) END = .TRUE.         GOTO 10      ENDIFC**********************************************************************C Go back to caller with decompressed lineC**********************************************************************      RETURN      END