home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume17 / freeze / part01 / encode.c < prev    next >
C/C++ Source or Header  |  1991-03-25  |  4KB  |  169 lines

  1. #include "freeze.h"
  2.  
  3. #include "lz.h"
  4.  
  5. extern hash_t prev[];
  6. #ifdef __XENIX__
  7. extern u_short *next[];
  8. #else
  9. extern u_short next[];
  10. #endif
  11.  
  12. /*
  13.  * freeze stdin to stdout
  14.  */
  15.  
  16. freeze ()
  17. {
  18.     register u_short i, len, r, s;
  19.     register short c;
  20.     putchar((int)(magic_header[0]));
  21. #ifdef COMPAT
  22.     putchar((int)(magic_header[1] | 1));
  23. #else
  24.     putchar((int)(magic_header[1]));
  25. #endif
  26.     write_header();
  27.     StartHuff();
  28.     InitTree();
  29.     s = 0;
  30.     r = N - _F;
  31.     for (i = s; i < r; i++)
  32.         text_buf[i] = ' ';
  33.     for (len = 0; len < _F && (c = getchar()) != EOF; len++)
  34.         text_buf[r + len] = c;
  35.     if(!topipe && text_buf[r] == magic_header[0] &&
  36.         (text_buf[r + 1] ^ magic_header[1]) <= 1) {
  37.         if (!quiet)
  38.             fprintf(stderr, " already frozen ");
  39.         exit_stat = 2;
  40.         return;
  41.     }
  42.  
  43.     in_count = len;
  44.     for (i = 0; i <= _F; i++)
  45.         InsertNode(r + i - _F);
  46.     while (len != 0) {
  47.         Get_Next_Match(r);
  48.  
  49.         if (match_length > len)
  50.             match_length = len;
  51.  
  52.         if (match_length <= THRESHOLD) {
  53.             match_length = 1;
  54.             EncodeChar(text_buf[r]);
  55. #ifdef DEBUG
  56.             symbols_out ++;
  57.             if (verbose)
  58.                 fprintf(stderr, "'%s'\n",
  59.                     pr_char(text_buf[r]));
  60. #endif /* DEBUG */
  61.         } else {
  62.             register u_short orig_length, orig_position, oldchar;
  63.  
  64. /* This fragment (delayed coding, non-greedy) is due to ideas of
  65.     Jan Mark Wams' <jms@cs.vu.nl> COMIC:
  66. */
  67.             oldchar = text_buf[r];
  68.             orig_length = match_length;
  69.             orig_position = match_position;
  70.  
  71.             DeleteNode(s);
  72.             Next_Char();
  73.             Get_Next_Match(r);
  74.  
  75.             if (match_length > len) match_length = len;
  76.  
  77.             if (orig_length > match_length) {
  78.                 EncodeChar((u_short)
  79.                     (256 - THRESHOLD + orig_length));
  80.                 EncodePosition((u_short)orig_position);
  81. #ifdef DEBUG
  82.                 match_position = orig_position;
  83. #endif  /* DEBUG */
  84.                 match_length = orig_length - 1;
  85.             } else {
  86.                 EncodeChar(oldchar);
  87. #ifdef DEBUG
  88.                 symbols_out ++;
  89.                 if (verbose)
  90.                     fprintf(stderr, "'%s'\n",
  91.                         pr_char(oldchar));
  92. #endif  /* DEBUG */
  93.                 EncodeChar(256 - THRESHOLD + match_length);
  94.                 EncodePosition(match_position);
  95.             }
  96. #ifdef DEBUG
  97.             refers_out ++;
  98.             if (verbose) {
  99.                 register short pos =
  100.                     (r - 1 - match_position) & (N - 1),
  101.                 len = match_length;
  102.                 fputc('"', stderr);
  103.                 for(;len;len--, pos++)
  104.                     fprintf(stderr, "%s",
  105.                         pr_char(text_buf[pos]));
  106.                 fprintf(stderr, "\"\n");
  107.             }
  108. #endif /* DEBUG */
  109.         }
  110.         for (i = 0; i < match_length &&
  111.                 (c = getchar()) != EOF; i++) {
  112.             DeleteNode(s);
  113.             text_buf[s] = c;
  114.             if (s < _F - 1)
  115.                 text_buf[s + N] = c;
  116.             s = (s + 1) & (N - 1);
  117.             r = (r + 1) & (N - 1);
  118.             InsertNode(r);
  119.         }
  120.  
  121.         in_count += i;
  122.         if ((in_count > indicator_count) && !quiet) {
  123.             fprintf(stderr, "%5dK\b\b\b\b\b\b", in_count / 1024);
  124.             fflush (stderr);
  125.             indicator_count += indicator_threshold;
  126.             indicator_threshold += 1024;
  127.         }
  128.         while (i++ < match_length) {
  129.             DeleteNode(s);
  130.             s = (s + 1) & (N - 1);
  131.             r = (r + 1) & (N - 1);
  132.             if (--len) InsertNode(r);
  133.         }
  134.     }
  135.     EncodeChar((short)ENDOF);
  136. #ifdef DEBUG
  137.     symbols_out ++;
  138. #endif
  139.     EncodeEnd();
  140.     /*
  141.      * Print out stats on stderr
  142.      */
  143.     if(!quiet) {
  144. #ifdef GATHER_STAT
  145.     fprintf(stderr, "Average number of steps: ");
  146.     prratio(stderr, node_steps, node_matches);
  147.     fprintf(stderr, "\n");
  148. #endif
  149. #ifdef DEBUG
  150.     fprintf( stderr,
  151.         "%ld chars in, %ld codes (%ld bytes) out, freezing factor: ",
  152.         in_count, symbols_out + refers_out, bytes_out);
  153.     prratio( stderr, in_count, bytes_out );
  154.     fprintf( stderr, "\n");
  155.     fprintf( stderr, "\tFreezing as in compact: " );
  156.     prratio( stderr, in_count-bytes_out, in_count );
  157.     fprintf( stderr, "\n");
  158.     fprintf( stderr, "\tSymbols: %ld; references: %ld.\n",
  159.         symbols_out, refers_out);
  160. #else /* !DEBUG */
  161.     fprintf( stderr, "Freezing: " );
  162.     prratio( stderr, in_count-bytes_out, in_count );
  163. #endif /* DEBUG */
  164.     }
  165.     if(bytes_out >= in_count)    /* exit(2) if no savings */
  166.     exit_stat = 2;
  167.     return;
  168. }
  169.