home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / FREEZE-2.ZIP / encode.c < prev    next >
C/C++ Source or Header  |  1992-07-18  |  4KB  |  188 lines

  1. #include "freeze.h"
  2. #include "lz.h"
  3. #include "huf.h"
  4. #include "bitio.h"
  5.  
  6. /* for future versions ?... */
  7.  
  8. #define LENGTH_OFFSET   256
  9. #define EncodeLiteral(l)        EncodeChar(l)
  10. #define EncodeLength(l)         EncodeChar(l + LENGTH_OFFSET)
  11.  
  12. /*
  13.  * Freezes stdin to stdout
  14.  */
  15.  
  16. void freeze ()
  17. {
  18.     register us_t i, len, r, s;
  19.     register short c;
  20.     putchar(MAGIC1);
  21.     putchar(MAGIC2_2);
  22.  
  23. /* Huffman-dependent part */
  24.     write_header();
  25.     StartHuff(N_CHAR2);
  26.     init(Table2);
  27. /* end of Huffman-dependent part */
  28.  
  29.     InitTree();     /* LZ dependent */
  30.     InitIO();
  31.  
  32.     s = 0;
  33.     r = N2 - F2;
  34.     for (i = s; i < r; i++)
  35.         text_buf[i] = ' ';
  36.     for (len = 0; len < F2 && (c = getchar()) != EOF; len++)
  37.         text_buf[r + len] = c;
  38.  
  39.     /* check for magic header */
  40.     if(!topipe && !force && text_buf[r] == MAGIC1 &&
  41.         text_buf[r + 1] >= MAGIC2_1) {
  42.         if (quiet != 1)
  43.             fprintf(stderr, " already frozen ");
  44.         exit_stat = 2;
  45.         return;
  46.     }
  47.  
  48.     in_count = len;
  49.     for (i = 0; i <= F2; i++)
  50.         InsertNode(r + i - F2);
  51.  
  52.     while (len != 0) {
  53.         match_length = THRESHOLD;
  54.         Get_Next_Match(r,1);
  55.         if (match_length > len)
  56.             match_length = len;
  57.  
  58.         if (match_length <= THRESHOLD) {
  59.             match_length = 1;
  60.             EncodeLiteral(text_buf[r]);
  61. #ifdef DEBUG
  62.             symbols_out ++;
  63.             if (verbose)
  64.                 fprintf(stderr, "'%s'\n",
  65.                     pr_char(text_buf[r]));
  66. #endif /* DEBUG */
  67.         } else if (greedy) {
  68. /* GREEDY parsing (compression rate 1.5% worse, but 40% faster) */
  69.  
  70.             EncodeLength((us_t) (match_length - THRESHOLD));
  71.             EncodePosition((us_t)match_position);
  72.  
  73.         } else {
  74.             register us_t orig_length, orig_position, oldchar;
  75.  
  76. /* This fragment (delayed coding, non-greedy) is due to ideas of
  77.     Jan Mark Wams' <jms@cs.vu.nl> COMIC:
  78. */
  79.             oldchar = text_buf[r];
  80.             orig_length = match_length;
  81.             orig_position = match_position;
  82.  
  83.             DeleteNode(s);
  84.             Next_Char(N2, F2);
  85.             Get_Next_Match(r,2);
  86.  
  87.             if (match_length > len) match_length = len;
  88.  
  89.             if (orig_length >= match_length) {
  90.                 EncodeLength((us_t)
  91.                     (orig_length - THRESHOLD));
  92.                 EncodePosition((us_t)orig_position);
  93. #ifdef DEBUG
  94.                 match_position = orig_position;
  95. #endif  /* DEBUG */
  96.                 match_length = orig_length - 1;
  97.             } else {
  98.                 EncodeLiteral(oldchar);
  99. #ifdef DEBUG
  100.                 symbols_out ++;
  101.                 if (verbose)
  102.                     fprintf(stderr, "'%s'\n",
  103.                         pr_char(oldchar));
  104. #endif  /* DEBUG */
  105.                 EncodeLength(match_length - THRESHOLD);
  106.                 EncodePosition(match_position);
  107.             }
  108. #ifdef DEBUG
  109.             refers_out ++;
  110.             if (verbose) {
  111.                 register short pos =
  112.                     (r - 1 - match_position) & (N2 - 1),
  113.                 leng = match_length;
  114.                 fputc('"', stderr);
  115.                 for(; leng; leng--, pos++)
  116.                     fprintf(stderr, "%s",
  117.                         pr_char(text_buf[pos]));
  118.                 fprintf(stderr, "\"\n");
  119.             }
  120. #endif /* DEBUG */
  121.         }
  122.  
  123. /* Process the rest of the matched sequence (insertion in the list
  124.     only, without any matching !!!)
  125. */
  126.  
  127.         for (i = 0; i < match_length &&
  128.                 (c = getchar()) != EOF; i++) {
  129.             DeleteNode(s);
  130.             text_buf[s] = c;
  131.             if (s < F2 - 1)
  132.                 text_buf[s + N2] = c;
  133.             s = (s + 1) & (N2 - 1);
  134.             r = (r + 1) & (N2 - 1);
  135.             InsertNode(r);
  136.         }
  137.  
  138.         in_count += i;
  139.  
  140.         INDICATOR
  141.  
  142.         while (i++ < match_length) {
  143.             DeleteNode(s);
  144.             s = (s + 1) & (N2 - 1);
  145.             r = (r + 1) & (N2 - 1);
  146.             if (--len) InsertNode(r);
  147.         }
  148.     }
  149.  
  150.     /* to flush literals */
  151.     EncodeLength((short)ENDOF - LENGTH_OFFSET);
  152. #ifdef DEBUG
  153.     symbols_out ++;
  154. #endif
  155.     EncodeEnd();
  156.     /*
  157.      * Print out stats on stderr
  158.      */
  159.     if(quiet != 1) {
  160. #ifdef GATHER_STAT
  161.     fprintf(stderr, "Average number of steps: ");
  162.     prratio(stderr, node_steps, node_matches);
  163.     fprintf(stderr, "\n");
  164. #endif
  165. #ifdef DEBUG
  166.     fprintf( stderr,
  167.         "%ld chars in, %ld codes (%ld bytes) out, freezing factor: ",
  168.         in_count, symbols_out + refers_out, bytes_out);
  169.     prratio( stderr, in_count, bytes_out );
  170.     fprintf( stderr, "\n");
  171.     fprintf( stderr, "\tFreezing as in compact: " );
  172.     prratio( stderr, in_count-bytes_out, in_count );
  173.     prbits( stderr, in_count, bytes_out);
  174.     fprintf( stderr, "\n");
  175.     fprintf( stderr, "\tSymbols: %ld; references: %ld.\n",
  176.         symbols_out, refers_out);
  177. #else /* !DEBUG */
  178.     fprintf( stderr, " Freezing: " );
  179.     prratio( stderr, in_count-bytes_out, in_count );
  180.     prbits( stderr, in_count, bytes_out);
  181. #endif /* DEBUG */
  182.     }
  183.     if(bytes_out >= in_count)    /* exit(2) if no savings */
  184.     exit_stat = 2;
  185.     return;
  186. }
  187.  
  188.