home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / macutils.lzh / MACUTILS / MACUNPACK / de_huffman.c < prev    next >
C/C++ Source or Header  |  1995-09-18  |  3KB  |  155 lines

  1. #include "macunpack.h"
  2. #ifdef JDW
  3. #define DEHUFFMAN
  4. #endif /* JDW */
  5. #ifdef STF
  6. #define DEHUFFMAN
  7. #endif /* STF */
  8. #ifdef PIT
  9. #define DEHUFFMAN
  10. #endif /* PIT */
  11. #ifdef SIT
  12. #define DEHUFFMAN
  13. #endif /* SIT */
  14. #ifdef CPT
  15. #define DEHUFFMAN
  16. #endif /* CPT */
  17. #ifdef DEHUFFMAN
  18. #include "globals.h"
  19. #include "../util/masks.h"
  20. #include "../fileio/wrfile.h"
  21. #include "huffman.h"
  22. #include "../util/util.h"
  23.  
  24. int (*get_bit)();
  25. int bytesread;
  26. /* 515 because StuffIt Classic needs more than the needed 511 */
  27. struct node nodelist[515];
  28. static int getbit_be();
  29. static int getbit_le();
  30. static int getdecodebyte();
  31.  
  32. static node *nodeptr, *read_sub_tree();
  33.  
  34. static int bit;
  35.  
  36. void de_huffman(obytes)
  37. unsigned long obytes;
  38. {
  39.     while(obytes != 0) {
  40.     *out_ptr++ = gethuffbyte(nodelist);
  41.     obytes--;
  42.     }
  43.     return;
  44. }
  45.  
  46. void de_huffman_end(term)
  47. unsigned int term;
  48. {
  49.     int c;
  50.  
  51.     while((c = gethuffbyte(nodelist)) != term) {
  52.     *out_ptr++ = c;
  53.     }
  54. }
  55.  
  56. void set_huffman(endian)
  57. int endian;
  58. {
  59.     if(endian == HUFF_LE) {
  60.     get_bit = getbit_le;
  61.     } else if(endian == HUFF_BE) {
  62.     get_bit = getbit_be;
  63.     }
  64. }
  65.  
  66. void read_tree()
  67. {
  68.     nodeptr = nodelist;
  69.     bit = 0;        /* put us on a boundary */
  70.     (void)read_sub_tree();
  71. }
  72.  
  73. /* This routine recursively reads the Huffman encoding table and builds
  74.    a decoding tree. */
  75. static node *read_sub_tree()
  76. {
  77.     node *np;
  78.  
  79.     np = nodeptr++;
  80.     if((*get_bit)() == 1) {
  81.     np->flag = 1;
  82.     np->byte = getdecodebyte();
  83.     } else {
  84.     np->flag = 0;
  85.     np->zero = read_sub_tree();
  86.     np->one  = read_sub_tree();
  87.     }
  88.     return np;
  89. }
  90.  
  91. /* This routine returns the next bit in the input stream (MSB first) */
  92. static int getbit_be()
  93. {
  94.     static int b;
  95.  
  96.     if(bit == 0) {
  97.     b = getb(infp) & BYTEMASK;
  98.     bit = 8;
  99.     bytesread++;
  100.     }
  101.     bit--;
  102.     return (b >> bit) & 1;
  103. }
  104.  
  105. /* This routine returns the next bit in the input stream (LSB first) */
  106. static int getbit_le()
  107. {
  108.     static int b;
  109.  
  110.     if(bit == 0) {
  111.     b = getb(infp) & BYTEMASK;
  112.     bit = 8;
  113.     bytesread++;
  114.     }
  115.     bit--;
  116.     return (b >> (7 - bit)) & 1;
  117. }
  118.  
  119. void clrhuff()
  120. {
  121.     bit = 0;
  122. }
  123.  
  124. int gethuffbyte(l_nodelist)
  125. node *l_nodelist;
  126. {
  127.     register node *np;
  128.  
  129.     np = l_nodelist;
  130.     while(np->flag == 0) {
  131.     np = (*get_bit)() ? np->one : np->zero;
  132.     }
  133.     return np->byte;
  134. }
  135.  
  136. int getihuffbyte()
  137. {
  138.     return gethuffbyte(nodelist);
  139. }
  140.  
  141. static int getdecodebyte()
  142. {
  143.     register int i, b;
  144.  
  145.     b = 0;
  146.     for(i = 8; i > 0; i--) {
  147.     b = (b << 1) + (*get_bit)();
  148.     }
  149.     return b;
  150. }
  151. #else /* DEHUFFMAN */
  152. int dehuffman; /* keep lint and some compilers happy */
  153. #endif /* DEHUFFMAN */
  154.  
  155.