3       SUBROUTINE DECOMPRESS (IBUF, OBUF, NIN, NOUT) G C********************************************************************** D C_TITLE DECOMPRESS - Decompresses image lines stored in a compressed C                    format. C  C_ARGS       INTEGER*4       NIN B C                                       Input - number of bytes in> C                                       the compressed buffer.       INTEGER*4       NOUTE C                                       Input - known number of bytes C C                                       in decompressed output line        CHARACTER       IBUF(1) ? C                                       Input - line of data to E C                                       decompress. The first byte is C C                                       the actual pixel value, the D C                                       rest of the array is the bit> C                                       stream of coded "first; C                                       difference" values.        CHARACTER       OBUF(1) E C                                       Output - decompressed line of A C                                       data. The routine assumes D C                                       original image composed of 8@ C                                       bit pixels.  This is the= C                                       restored image line - = C                                       compression and first C C                                       differences undone - of the < C                                       line passed in ibuf. C B C_DESC  This routine decompresses Huffman encoded compressed data.B 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 andD C       Software Considerations" by Gilbert Held, John Wiley & Sons,D C       publishers.)  Huffman coding uses variable number of bits toF C       encode different values of the original data.  The compressionA C       results because the most frequently occurring values have 3 C       the smaller number of bits for their codes.  C A C       The routine, used in conjuction with DECMPINIT,  provides < C       a common data base from which to call the processingF C       subroutines. DECMPINIT builds the Huffman tree from the first-? C       difference histogram and is called only once per image. C 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 F C       DCMPRS is provided in two versions, one FORTRAN, the other VAXC C       MACRO.  The FORTRAN version is for compatability on non-VAX : C       systems so that the algorithm might be more easilyE C       understood, while the MACRO version is for speed when running ; C       on a VAX. If you intend to use the macro version of ; C       the DCMPRS routine, then remove the fortran routine D C       of the same name from the DECOMP source file before building C       the system.  C A C       An alternate version of the decompression software can be C C       found in the DECOMPS.FOR file. DECOMPS.FOR has been adapted 1 C       for the SUN fortran compiler version 3.4.  C > C_LIMS  The routines have been tested using version 4.8-276 ofD C       the VAX/VMS fortran compiler and versions V3.31 and V4.01 ofE C       the Microsoft fortran compilers. The hardware used in testing F C       the software include a VAX-750, an IBM PC/XT and a DEC RAINBOW@ C       PC.  Modifications of the code may be required for other> C       computer systems. See the DECOMPS.FOR file if you have5 C       software which will run on a SUN workstation.  C @ C_HIST  DEC87, DMcMacken, ISD, USGS, Flagstaff, Original version C  C_END H C***********************************************************************  "       INTEGER*2       TREE(5,1024)4 C                                       Huffman tree       INTEGER*2       VALUE        INTEGER*2       RIGHT        INTEGER*2       LEFT       INTEGER*2       PARENT       INTEGER*2       BRANCHD       PARAMETER       (VALUE=1, RIGHT=2, LEFT=3, PARENT=4, BRANCH=5)       COMMON /DECOM/ TREE H C*********************************************************************** C Decompress an input lineH C***********************************************************************.       CALL DCMPRS(IBUF, OBUF, NIN, NOUT, TREE)       RETURN	       END         SUBROUTINE DECMPINIT(HIST)H C***********************************************************************D C_TITLE DECMPINIT - initialize the decompression TREE from the first( C                   difference histogram C_ARGS       INTEGER*4       HIST(512) C C                                       Input, difference histogram C C                                       table. The histogram of the ? C                                       whole image after first B C                                       difference has been run on? C                                       each line.  In a "first H C                                       difference" line the first pixelE C                                       retains its actual value; all D C                                       other pixels are obtained byG C                                       subtracting the actual value of G C                                       the pixel from the actual value B C                                       of the preceding pixel and? C                                       adding 256 to provide a B C                                       positive number.  The i-thA C                                       element of the array HIST F C                                       should be the number of pixelsB C                                       in the image with value i. C @ C Some computer hardware systems may need to swap the byte orderD C of the 32-bit words which make up the first-difference historgram.F C The histogram  is configured on the CDROM in "least significant byteD 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 swapA 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 A 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 H 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) G C********************************************************************** A 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 E C_DESC  This routine creates a Huffman code tree from the input first H C       difference histogram of an image.  It starts by making all validH C       (non-zero) densities for the image leaf nodes.  These are sortedG C       in increasing order by histogram frequency.  The two nodes with D C       smallest frequencies are connected by branches to a new node> C       which is given a frequency equal to the sum of the twoF C       combining nodes. The new node takes the place of the two nodesD C       and the frequency list is resorted.  The process is repeatedA C       until the frequency set is reduced to one node.  The tree D C       consists of a double dimensioned array whose first dimensionF C       gives five parameters for each node. The first parameter givesD C       a value to the node.  This is a density value for leaf nodesF C       and a -1 for all others.  The second parameter is a pointer toC C       the next node on the right branch from this node. The third A C       points to the node on the left branch.  The fourth points D C       to the parent node from which this node branches.  The fifthA 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 A C_HIST  Fall86, DMcMacken, ISD, USGS, Flagstaff, Original version  C  C_END G C********************************************************************** #       INTEGER*4       FREQLIST(512) A C                                       Histogramm frequency list #       INTEGER*2       NODELIST(512) 6 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       NUMNODES4 C                                       Node counter       INTEGER*4       I 5 C                                       Do loop index        INTEGER*4       PTR < C                                       Current node pointer       INTEGER*4       NUMFREQ > C                                       # non-zero frequencies       INTEGER*4       INDEX > C                                       Frequency list pointerG C********************************************************************** ' C Create leaf nodes, and pointer tables G 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 CONTINUEG C********************************************************************** B C Make sure the last element is always 0. For the first difference* C histogram, there can only be 511 values.G C**********************************************************************        FREQLIST(512) = 0 G C********************************************************************** ? C Sort freqlist in increasing order; skip over zero frequencies G C**********************************************************************        NUMFREQ = 512 1       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 - 19          CALL SORTFREQ (FREQLIST(INDEX), NODELIST(INDEX),       1   NUMFREQ)           GOTO 30       ENDIF "       TREE(VALUE, 1024) = NUMNODES       RETURN	       END 6       SUBROUTINE SORTFREQ(FREQLIST, NODELIST, NUMFREQ)G C********************************************************************** 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) 9 C                                       input - node list        INTEGER*4       NUMFREQ E C                                       input - # values in freq list  C G C_DESC  This routine uses an insertion sort to reorder a frequency list E C       in order of increasing frequency.  The corresponding elements B C       of the node list are reordered to maintain correspondence. C A C_HIST  Fall86, DMcMacken, ISD, USGS, Flagstaff, Original version  C  C_END H C***********************************************************************       INTEGER*4       I 5 C                                       Do loop index        INTEGER*4       J = C                                       List position pointer        INTEGER*4       TEMP1 A C                                       Temporary storage - freq.        INTEGER*4       TEMP2 @ C                                       Temporary storage - nodeH C***********************************************************************< C Save current element - starting with second - in temporary= C storage.  Compare with all elements in first part of list - 8 C moving each up one element - until  element is larger.. C Insert current element at this point in listH 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 4       SUBROUTINE DCMPRS(IBUF, OBUF, NIN, NOUT, TREE)H 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 D C       place of this fortran code. The DCMPRS macro version is more2 C       than twice as fast as the fortran version) C  C_ARGS       INTEGER*4       NIN F C                                       Input, # bytes in input buffer       INTEGER*4       NOUTE C                                       Input, # bytes in output line "       INTEGER*2       TREE(5,1024)@ C                                       Input, Huffman code tree       CHARACTER       IBUF(1) E C                                       Input, compressed data buffer        CHARACTER       OBUF(1) A C                                       Output, decompressed line  C H C_DESC  This subroutine follows a path from the root of the Huffman treeF C       to one of its leaves.  The choice at each branch is decided byG C       the successive bits of the compressed input stream, left for 1, F C       right for 0.  Only leaf nodes have a value other than -1.  TheD C       routine traces a path through the tree until it finds a nodeE C       with a value not equal to -1 (a leaf node).  The value at the G C       leaf node is subtracted from the preceding pixel value plus 256 F C       to restore the the umcompressed pixel.  This algorithm is then: C       repeated until the entire line has been processed. C 7 C_CALLS This routine uses the VAX/VMS implicit function D 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 G C**********************************************************************        INTEGER*4       PTR C C                                       Pointer to position in tree        INTEGER*4       K 5 C                                       Do loop index        INTEGER*4       BIT F C                                       Pointer to current bit in word       INTEGER*4       NBYTE E C                                       Counter, # bytes decompressed        INTEGER*4       TEMP6 C                                       Working buffer       CHARACTER       TEMPB ; C                                       Byte working buffer        INTEGER*2       VALUE ; C                                       Value index in tree        INTEGER*2       RIGHT B C                                       Right branch index in tree       INTEGER*2       LEFTA C                                       Left branch index in tree        INTEGER*2       PARENTD C                                       Parent pointer index in tree       INTEGER*2       BRANCHC C                                       Parent branch index in tree D       PARAMETER       (VALUE=1, RIGHT=2, LEFT=3, PARENT=4, BRANCH=5)       INTEGER*2       DN= C                                       Current density value        INTEGER*2       DNL : C                                       Last density value       CHARACTER       DNB D C                                       Byte addressed density value       LOGICAL       END 8 C                                       End of line flag       LOGICAL       BTEST  C .       EQUIVALENCE     (DN, DNB), (TEMP, TEMPB)G C**********************************************************************  C Start at root of tree G C**********************************************************************        PTR = TREE(1,1024)G C********************************************************************** * C Just copy first byte it is uncompressed.G C**********************************************************************        OBUF(1) = IBUF(1) G C**********************************************************************  C Count starts here G C**********************************************************************        NBYTE = 1 G C********************************************************************** , C Initialize current and last density valuesG C**********************************************************************        DN = 0       DNB = IBUF(1)        DNL = DNG C**********************************************************************  C Reset end of line flagG C**********************************************************************        END = .FALSE. G C********************************************************************** > C K points to current input byte loop is done when k exceeds # C input bytes.G C**********************************************************************        K = 2 "       IF (K .GT. NIN) END = .TRUE.G C**********************************************************************  C This is the processing loop G C**********************************************************************     10 IF (.NOT. END) THEN           TEMPB = 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 G C********************************************************************** ) C We are at end leaf when value is not -1 G C********************************************************************** .             IF (TREE(VALUE, PTR) .NE. -1) THENG C********************************************************************** B C Compute value of pixel, reset or increment pointers and countersG C********************************************************************** $                DN = TREE(VALUE, PTR)"                DN = DNL - DN + 256                DNL = DN                  NBYTE = NBYTE + 1                 OBUF(NBYTE) = DNB"                PTR = TREE(1, 1024)0                IF (NBYTE .EQ. NOUT) END = .TRUE.             ENDIF G C**********************************************************************  C Process next bit in byteG C**********************************************************************              BIT = BIT - 1              GOTO 20           ENDIFG C**********************************************************************  C Set index to next input byteG C**********************************************************************           K = K + 1%          IF (K .GT. NIN) END = .TRUE.           GOTO 10       ENDIF G C********************************************************************** * C Go back to caller with decompressed lineG C**********************************************************************        RETURN	       END   