home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / sources / misc / 3818 < prev    next >
Encoding:
Text File  |  1992-08-18  |  28.8 KB  |  1,126 lines

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: leo@ipmce.su (Leonid A. Broukhis)
  4. Subject:  v31i089:  freeze - Freeze/melt compression program 2.3, Patch05
  5. Message-ID: <1992Aug18.215658.29273@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: d64313176f1e0ff48b0941206b3eb8e6
  8. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  9. Organization: Sterling Software
  10. Date: Tue, 18 Aug 1992 21:56:58 GMT
  11. Approved: kent@sparky.imd.sterling.com
  12. Lines: 1112
  13.  
  14. Submitted-by: leo@ipmce.su (Leonid A. Broukhis)
  15. Posting-number: Volume 31, Issue 89
  16. Archive-name: freeze/patch05
  17. Environment: ISC, Xenix, SunOS, MS-DOS
  18. Patch-To: freeze: Volume 25, Issue 12-13
  19.  
  20. Main enhancements:
  21.  - compression speed (without reducing compression rate)
  22.    was significantly increased;
  23.  - other small contributed patches.
  24.  
  25. *** distribution/README    Thu Jul 16 15:20:51 1992
  26. --- README    Mon Aug 17 17:02:12 1992
  27. ***************
  28. *** 12,29 ****
  29.       o M_XENIX & !M_I386     Makes arrays < 65536 bytes each
  30.       o BSD                   Allow long filenames ( > 14 characters) &
  31.                   Call setlinebuf(stderr)
  32. !     o INT_SIG               signal is int (*)() unstead of void
  33.       o MSDOS                 Turns off some UNIX-dependencies
  34. !                 and MSDOS' ones - vice versa
  35. !                 !!! It's important !!!
  36. !                 If your MSDOS' C compiler does support
  37. !                 inline functions, define DO_INLINE.
  38. !                 This will cause the main loop to be
  39. !                 replaced with a call of memcmp, which
  40. !                 will be represented as 'repz cmpsb'.
  41.       o FAST                  Forces the Get_Next_Match routine
  42.                   to be inline. This gives additional
  43. !                 percents of speedup.
  44.       o __TURBOC__            For compiling under TURBO C
  45.       o __i386__              When compiling under GNU C causes
  46.                   some fixed register allocations,
  47. --- 12,31 ----
  48.       o M_XENIX & !M_I386     Makes arrays < 65536 bytes each
  49.       o BSD                   Allow long filenames ( > 14 characters) &
  50.                   Call setlinebuf(stderr)
  51. !     o SIGTYPE               The type that is returned by signal
  52. !                 handlers.  Defaults to void.
  53.       o MSDOS                 Turns off some UNIX-dependencies
  54. !                 and MSDOS' ones - vice versa.
  55. !     o FASTHASH              Uses another hash function which gives
  56. !                 some speedup, thus reducing the compression
  57. !                 rate (!)
  58.       o FAST                  Forces the Get_Next_Match routine
  59.                   to be inline. This gives additional
  60. !                 percents of speedup on some machines
  61. !                 using some compilers (depends on
  62. !                 the number of registers, register
  63. !                 allocation strategy and subroutine call
  64. !                 overhead).
  65.       o __TURBOC__            For compiling under TURBO C
  66.       o __i386__              When compiling under GNU C causes
  67.                   some fixed register allocations,
  68. ***************
  69. *** 38,46 ****
  70.                   4.3).
  71.   
  72.   Please! If your computer supports the string operations, try to write
  73. ! "asm" instructions (GNU style) which realize the right-to-left memory
  74. ! comparison (s1, s2, length) in minimum number of clock cycles.
  75. ! If a noticeable (5% or more) speedup is gained, please send me a message.
  76.   
  77.   Other preprocessor symbols (DEBUG, GATHER_STAT) are for internal use
  78.   only.
  79. --- 40,49 ----
  80.                   4.3).
  81.   
  82.   Please! If your computer supports the string operations, try to write
  83. ! "asm" instructions (GNU style) which realize the memory comparison
  84. ! "(s1, s2, maxlength) --> matched length" in the minimum number of clock
  85. ! cycles.  If a noticeable (5% or more) speedup is gained, please send
  86. ! me a message.
  87.   
  88.   Other preprocessor symbols (DEBUG, GATHER_STAT) are for internal use
  89.   only.
  90. ***************
  91. *** 126,131 ****
  92. --- 129,136 ----
  93.   gif =   0 0 0 0 2 60 0 0        # This is NOT! optimal data
  94.                   # for GIF files
  95.   doc=0 0 1 2 7 16 36 0           # The sample was gcc.lp
  96. + greedy2=0 1 1 2 5 8 11 34       #
  97.   # End of file
  98.   ---------- cut here -----------
  99.   
  100. ***************
  101. *** 144,150 ****
  102.   ------------------- BUGS ----------------------------
  103.   
  104.   Please send descriptions of found bugs, incompatibilities, etc.  to
  105. ! leo@s514.ipmce.su.  MS-DOS version will not be supported in future
  106.   versions !!  (If they will be :-) )
  107.   
  108.   ------------ SPEED & COMPRESSION RATE ---------------
  109. --- 149,155 ----
  110.   ------------------- BUGS ----------------------------
  111.   
  112.   Please send descriptions of found bugs, incompatibilities, etc.  to
  113. ! leo@ipmce.su.  MS-DOS version might not be supported in future
  114.   versions !!  (If they will be :-) )
  115.   
  116.   ------------ SPEED & COMPRESSION RATE ---------------
  117. *** distribution/encode.c    Thu Jul 16 15:20:58 1992
  118. --- encode.c    Thu Jul 30 13:19:42 1992
  119. ***************
  120. *** 6,13 ****
  121.   /* for future versions ?... */
  122.   
  123.   #define LENGTH_OFFSET   256
  124. ! #define EncodeLiteral(l)        EncodeChar(l)
  125. ! #define EncodeLength(l)         EncodeChar(l + LENGTH_OFFSET)
  126.   
  127.   /*
  128.    * Freezes stdin to stdout
  129. --- 6,13 ----
  130.   /* for future versions ?... */
  131.   
  132.   #define LENGTH_OFFSET   256
  133. ! #define EncodeLiteral(l)        EncodeChar((int)l)
  134. ! #define EncodeLength(l)         EncodeChar((int)l + LENGTH_OFFSET)
  135.   
  136.   /*
  137.    * Freezes stdin to stdout
  138. ***************
  139. *** 15,23 ****
  140.   
  141.   void freeze ()
  142.   {
  143. !     register us_t i, len, r, s;
  144. !     register short c;
  145. !     int greedy_threshold = CHAIN_THRESHOLD / (3 * greedy + 3);
  146.       putchar(MAGIC1);
  147.       putchar(MAGIC2_2);
  148.   
  149. --- 15,21 ----
  150.   
  151.   void freeze ()
  152.   {
  153. !     register int i, len, r, s, c;
  154.       putchar(MAGIC1);
  155.       putchar(MAGIC2_2);
  156.   
  157. ***************
  158. *** 65,78 ****
  159.                   fprintf(stderr, "'%s'\n",
  160.                       pr_char(text_buf[r]));
  161.   #endif /* DEBUG */
  162. !         } else if (match_length >= greedy_threshold) {
  163.   /* GREEDY parsing (compression rate 1.5% worse, but 40% faster) */
  164.   
  165. !             EncodeLength((us_t) (match_length - THRESHOLD));
  166. !             EncodePosition((us_t)match_position);
  167.   
  168.           } else {
  169. !             register us_t orig_length, orig_position, oldchar;
  170.   
  171.   /* This fragment (delayed coding, non-greedy) is due to ideas of
  172.       Jan Mark Wams' <jms@cs.vu.nl> COMIC:
  173. --- 63,77 ----
  174.                   fprintf(stderr, "'%s'\n",
  175.                       pr_char(text_buf[r]));
  176.   #endif /* DEBUG */
  177. !         } else if (greedy) {
  178.   /* GREEDY parsing (compression rate 1.5% worse, but 40% faster) */
  179.   
  180. !             EncodeLength(match_length - THRESHOLD);
  181. !             EncodePosition(match_position);
  182.   
  183.           } else {
  184. !             register int orig_length, orig_position;
  185. !             register us_t oldchar;
  186.   
  187.   /* This fragment (delayed coding, non-greedy) is due to ideas of
  188.       Jan Mark Wams' <jms@cs.vu.nl> COMIC:
  189. ***************
  190. *** 88,96 ****
  191.               if (match_length > len) match_length = len;
  192.   
  193.               if (orig_length >= match_length) {
  194. !                 EncodeLength((us_t)
  195. !                     (orig_length - THRESHOLD));
  196. !                 EncodePosition((us_t)orig_position);
  197.   #ifdef DEBUG
  198.                   match_position = orig_position;
  199.   #endif  /* DEBUG */
  200. --- 87,94 ----
  201.               if (match_length > len) match_length = len;
  202.   
  203.               if (orig_length >= match_length) {
  204. !                 EncodeLength(orig_length - THRESHOLD);
  205. !                 EncodePosition(orig_position);
  206.   #ifdef DEBUG
  207.                   match_position = orig_position;
  208.   #endif  /* DEBUG */
  209. ***************
  210. *** 106,113 ****
  211.                   EncodeLength(match_length - THRESHOLD);
  212.                   EncodePosition(match_position);
  213.               }
  214. ! #ifdef DEBUG
  215.               refers_out ++;
  216.               if (verbose) {
  217.                   register short pos =
  218.                       (r - 1 - match_position) & (N2 - 1),
  219. --- 104,114 ----
  220.                   EncodeLength(match_length - THRESHOLD);
  221.                   EncodePosition(match_position);
  222.               }
  223. ! #if defined(GATHER_STAT) || defined (DEBUG)
  224.               refers_out ++;
  225. + #endif
  226. + #ifdef DEBUG
  227.               if (verbose) {
  228.                   register short pos =
  229.                       (r - 1 - match_position) & (N2 - 1),
  230. ***************
  231. *** 159,167 ****
  232.        */
  233.       if(quiet != 1) {
  234.   #ifdef GATHER_STAT
  235. !     fprintf(stderr, "Average number of steps: ");
  236. !     fprintf(stderr, "%d.%02d\n", (int) (node_steps / node_matches),
  237. !             (int)((node_steps * 100 / node_matches) % 100));
  238.   #endif
  239.   #ifdef DEBUG
  240.       fprintf( stderr,
  241. --- 160,171 ----
  242.        */
  243.       if(quiet != 1) {
  244.   #ifdef GATHER_STAT
  245. !     fprintf(stderr, "Average number of compares per matching: %d.%02d\n",
  246. !         (int) (node_compares / node_matches),
  247. !         (int)((node_compares * 100 / node_matches) % 100));
  248. !     fprintf(stderr, "Average number of prolongations per compare: %d.%02d\n",
  249. !         (int) (node_prolongations / node_compares),
  250. !         (int)((node_prolongations * 100 / node_compares) % 100));
  251.   #endif
  252.   #ifdef DEBUG
  253.       fprintf( stderr,
  254. *** distribution/freeze.1    Wed Feb 26 14:40:06 1992
  255. --- freeze.1    Mon Aug 17 17:02:13 1992
  256. ***************
  257. *** 62,70 ****
  258.   If the
  259.   .B \-g
  260.   flag is given, a slightly less powerful (compression
  261. ! rate is 1.5% less), but 40% faster heuristic is used. The more times this
  262. ! flag is present, the faster program works and the less compression
  263. ! rate is. This flag is quite useful when freezing bitmaps.
  264.   .PP
  265.   If the
  266.   .B \-f
  267. --- 62,70 ----
  268.   If the
  269.   .B \-g
  270.   flag is given, a slightly less powerful (compression
  271. ! rate is 1.5% less), but 40% faster heuristic is used. This flag may be
  272. ! used twice (this mode is quite useful when freezing bitmaps) for
  273. ! additional speedup.
  274.   .PP
  275.   If the
  276.   .B \-f
  277. *** distribution/freeze.c    Thu Jul 16 15:20:59 1992
  278. --- freeze.c    Thu Jul 30 13:27:11 1992
  279. ***************
  280. *** 95,102 ****
  281.   short debug = 0;
  282.   short verbose = 0;
  283.   char * pr_char();
  284. ! long symbols_out = 0, refers_out = 0;
  285.   #endif /* DEBUG */
  286.   
  287.   /* Do not sleep when freeze works :-) */
  288.   long indc_count, indc_threshold;
  289. --- 95,106 ----
  290.   short debug = 0;
  291.   short verbose = 0;
  292.   char * pr_char();
  293. ! long symbols_out = 0;
  294.   #endif /* DEBUG */
  295. + #if defined(GATHER_STAT) || defined(DEBUG)
  296. + long refers_out = 0;
  297. + #endif
  298.   
  299.   /* Do not sleep when freeze works :-) */
  300.   long indc_count, indc_threshold;
  301. *** distribution/freeze.h    Thu Jul 16 15:20:59 1992
  302. --- freeze.h    Wed Jul 29 21:54:52 1992
  303. ***************
  304. *** 4,13 ****
  305. --- 4,21 ----
  306.   #include <sys/stdtypes.h>
  307.   #else   /* SUN4 */
  308.   # ifndef getc
  309. + #  ifdef m88k            /* Green Hill C library bug. */
  310. + #   define getc(p)         (--(p)->_cnt < 0 ? __filbuf(p) : (int) *(p)->_ptr++)
  311. + #  else
  312.   #   define getc(p)         (--(p)->_cnt < 0 ? _filbuf(p) : (int) *(p)->_ptr++)
  313. + #  endif
  314.   # endif
  315.   # ifndef putc
  316. + #  ifdef m88k            /* Green Hill C library bug. */
  317. + #   define putc(x, p)      (--(p)->_cnt < 0 ? __flsbuf((unsigned char) (x), (p)) : (int) (*(p)->_ptr++ = (unsigned char) (x)))
  318. + #  else
  319.   #   define putc(x, p)      (--(p)->_cnt < 0 ? _flsbuf((unsigned char) (x), (p)) : (int) (*(p)->_ptr++ = (unsigned char) (x)))
  320. + #  endif
  321.   # endif
  322.   #endif  /* SUN4 */
  323.   
  324. ***************
  325. *** 87,95 ****
  326.   # else /* TOS */
  327.   #  include <ext.h>
  328.   # endif  /* MSDOS */
  329. - #if !defined(SIGTYPE)
  330. - #define SIGTYPE void
  331. - #endif
  332.   #endif /* __TURBOC__ */
  333.   
  334.   typedef unsigned short us_t;
  335. --- 95,100 ----
  336. ***************
  337. *** 136,146 ****
  338.   extern short debug;
  339.   extern short verbose;
  340.   extern char * pr_char();
  341. ! extern long symbols_out, refers_out;
  342.   #endif /* DEBUG */
  343.   
  344. ! #ifdef GATHER_STAT
  345. ! extern long node_steps, node_matches;
  346.   #endif
  347.   
  348.   extern short DecodeChar(), DecodePosition(), GetNBits();
  349. --- 141,151 ----
  350.   extern short debug;
  351.   extern short verbose;
  352.   extern char * pr_char();
  353. ! extern long symbols_out;
  354.   #endif /* DEBUG */
  355.   
  356. ! #if defined(GATHER_STAT) || defined(DEBUG)
  357. ! extern long refers_out;
  358.   #endif
  359.   
  360.   extern short DecodeChar(), DecodePosition(), GetNBits();
  361. ***************
  362. *** 177,179 ****
  363. --- 182,188 ----
  364.   #endif
  365.   
  366.   extern char *strchr(), *strrchr();
  367. + #ifndef SIGTYPE
  368. + #define SIGTYPE void
  369. + #endif
  370. *** distribution/huf.c    Wed Feb 26 14:39:48 1992
  371. --- huf.c    Thu Jul 30 17:55:36 1992
  372. ***************
  373. *** 76,83 ****
  374.   
  375.   void reconst ()
  376.   {
  377. !     register us_t i, j, k;
  378. !     register us_t f;
  379.   
  380.   #ifdef DEBUG
  381.       if (quiet < 0)
  382. --- 76,83 ----
  383.   
  384.   void reconst ()
  385.   {
  386. !     register int i, j, k;
  387. !     register int f;
  388.   
  389.   #ifdef DEBUG
  390.       if (quiet < 0)
  391. ***************
  392. *** 130,139 ****
  393.   /* Updates given code's frequency, and updates tree */
  394.   
  395.   void update (c)
  396. !     us_t c;
  397.   {
  398.       register us_t *p;
  399. !     register us_t i, j, k, l;
  400.   
  401.       if (freq[r] == MAX_FREQ) {
  402.           reconst();
  403. --- 130,139 ----
  404.   /* Updates given code's frequency, and updates tree */
  405.   
  406.   void update (c)
  407. !     register int c;
  408.   {
  409.       register us_t *p;
  410. !     register int i, j, k, l;
  411.   
  412.       if (freq[r] == MAX_FREQ) {
  413.           reconst();
  414. ***************
  415. *** 168,177 ****
  416.   /* Encodes the literal or the length information */
  417.   
  418.   void EncodeChar (c)
  419. !     us_t c;
  420.   {
  421.       ul_t i;
  422. !     register us_t j, k;
  423.   
  424.       i = 0;
  425.       j = 0;
  426. --- 168,177 ----
  427.   /* Encodes the literal or the length information */
  428.   
  429.   void EncodeChar (c)
  430. !     int c;
  431.   {
  432.       ul_t i;
  433. !     register int j, k;
  434.   
  435.       i = 0;
  436.       j = 0;
  437. ***************
  438. *** 202,208 ****
  439.   /* Encodes the position information */
  440.   
  441.   void EncodePosition (c)
  442. !     register us_t c;
  443.   {
  444.       register us_t i;
  445.   
  446. --- 202,208 ----
  447.   /* Encodes the position information */
  448.   
  449.   void EncodePosition (c)
  450. !     register int c;
  451.   {
  452.       register us_t i;
  453.   
  454. ***************
  455. *** 221,227 ****
  456.   
  457.   short DecodeChar ()
  458.   {
  459. !     register us_t c;
  460.       c = son[r];
  461.   
  462.       /* trace from root to leaf,
  463. --- 221,227 ----
  464.   
  465.   short DecodeChar ()
  466.   {
  467. !     register int c;
  468.       c = son[r];
  469.   
  470.       /* trace from root to leaf,
  471. *** distribution/lz.c    Thu Jul 16 15:20:59 1992
  472. --- lz.c    Thu Aug  6 18:16:58 1992
  473. ***************
  474. *** 8,16 ****
  475.   /*----------------------------------------------------------------------*/
  476.   
  477.   uc_t    text_buf[N2 + F2 - 1];          /* cyclic buffer with an overlay */
  478. ! us_t    match_position, match_length;   /* current characteristics of a
  479.                           matched pattern */
  480. ! us_t    chain_length;                   /* max_chain_length ==
  481.                           CHAIN_THRESHOLD / greedy */
  482.   
  483.   
  484. --- 8,16 ----
  485.   /*----------------------------------------------------------------------*/
  486.   
  487.   uc_t    text_buf[N2 + F2 - 1];          /* cyclic buffer with an overlay */
  488. ! int     match_position, match_length;   /* current characteristics of a
  489.                           matched pattern */
  490. ! int     chain_length;                   /* max_chain_length ==
  491.                           CHAIN_THRESHOLD / greedy */
  492.   
  493.   
  494. ***************
  495. *** 45,51 ****
  496.   #endif  /* __XENIX__ */
  497.   
  498.   #ifdef GATHER_STAT
  499. ! long node_steps, node_matches;
  500.   #endif  /* GATHER_STAT */
  501.   
  502.   /* Initialize the data structures and allocate memory, if needed.
  503. --- 45,51 ----
  504.   #endif  /* __XENIX__ */
  505.   
  506.   #ifdef GATHER_STAT
  507. ! long node_matches, node_compares, node_prolongations;
  508.   #endif  /* GATHER_STAT */
  509.   
  510.   /* Initialize the data structures and allocate memory, if needed.
  511. ***************
  512. *** 57,63 ****
  513.   {
  514.       hash_t i;
  515.   #ifdef GATHER_STAT
  516. !     node_steps = node_matches = 0;
  517.   #endif  /* GATHER_STAT */
  518.   
  519.   #ifdef __TURBOC__
  520. --- 57,63 ----
  521.   {
  522.       hash_t i;
  523.   #ifdef GATHER_STAT
  524. !     node_matches = node_compares = node_prolongations = 0;
  525.   #endif  /* GATHER_STAT */
  526.   
  527.   #ifdef __TURBOC__
  528. ***************
  529. *** 74,80 ****
  530.           nextof(i) = NIL;
  531.       for (i = 0; i < sizeof(prev)/sizeof(*prev); i++ )
  532.           prev[i] = NIL;
  533. !     chain_length = greedy ? CHAIN_THRESHOLD / greedy : 0;
  534.   }
  535.   
  536.   /* Get the longest (longer than `match_length' when entering in subroutine)
  537. --- 74,89 ----
  538.           nextof(i) = NIL;
  539.       for (i = 0; i < sizeof(prev)/sizeof(*prev); i++ )
  540.           prev[i] = NIL;
  541. !     switch (greedy) {
  542. !     case 0:
  543. !         chain_length = CHAIN_THRESHOLD;
  544. !         break;
  545. !     case 1:
  546. !         chain_length = 3;
  547. !         break;
  548. !     default:
  549. !         chain_length = 1;
  550. !     }
  551.   }
  552.   
  553.   /* Get the longest (longer than `match_length' when entering in subroutine)
  554. ***************
  555. *** 81,138 ****
  556.       nearest match of the string beginning in text_buf[r]
  557.       to the cyclic buffer. Result (length & position) is returned
  558.       in correspondent global variables (`match_length' &
  559. !     `match_position'). Unchanged `match_length' denotes failure.
  560.   */
  561.   
  562.   #ifndef FAST
  563.   void get_next_match (r)
  564. !     us_t r;
  565.   {
  566. !     register us_t p = r;
  567.       register int m;
  568.       register uc_t  *key FIX_SI, *pattern FIX_DI;
  569.       int     chain_count = chain_length;
  570.   #ifdef GATHER_STAT
  571.       node_matches++;
  572.   #endif
  573. !     key = text_buf + r;
  574. !     do {
  575.           do {
  576. !             /* From ZIP 1.0 by J.-L. Gailly et al. */
  577.   
  578. !             if ((p = nextof(p)) == NIL ||
  579. !                 (greedy && !chain_count--))
  580. !                 return;
  581.   
  582. !             pattern = text_buf + p;
  583.   
  584.   #ifdef GATHER_STAT
  585. !         node_steps++;
  586.   #endif
  587.   
  588. !             MATCHING;
  589.   
  590. !         } while NOT_YET;
  591.   
  592. !         for (m = match_length;
  593. !             ++m < F2 && key[m] == pattern[m]; );
  594.   
  595. -         match_length = m;
  596. -         match_position = ((r - p) & (N2 - 1)) - 1;
  597. -     } while (m < F2);
  598.   /* There are two equal F-char sequences, the oldest one must be
  599.       deleted from the list.
  600.   */
  601.   
  602.   #ifdef DEBUG
  603.       if (verbose)
  604.           fprintf(stderr, "Replacing node: %d -> %d\n", p, r);
  605.   #endif
  606. !     nextof(prev[p]) = nextof(p);
  607. !     prev[nextof(p)] = prev[p];
  608. !     prev[p] = NIL;  /* remove p, it is further than r */
  609. !     return;
  610.   }
  611.   #endif
  612. --- 90,172 ----
  613.       nearest match of the string beginning in text_buf[r]
  614.       to the cyclic buffer. Result (length & position) is returned
  615.       in correspondent global variables (`match_length' &
  616. !     `match_position'). Unchanged `match_length' denotes failure and
  617. !     `match_position' contains garbage !!
  618. !     In order to achieve faster operation, `match_length' is shifted
  619. !     down to F2.
  620.   */
  621.   
  622.   #ifndef FAST
  623.   void get_next_match (r)
  624. !     int r;
  625.   {
  626. !     register int p = r;
  627.       register int m;
  628. +     register uc_t lastbyte;
  629.       register uc_t  *key FIX_SI, *pattern FIX_DI;
  630.       int     chain_count = chain_length;
  631.   #ifdef GATHER_STAT
  632.       node_matches++;
  633.   #endif
  634. !     key = text_buf + r + F2;
  635. !     match_length -= F2;
  636. !     for(;chain_count--;) {
  637. !         lastbyte = key[match_length];
  638.           do {
  639. !             pattern = text_buf + match_length + F2;
  640.   
  641. !             do {
  642. !                 if ((p = nextof(p)) == NIL) {
  643. !                     match_length += F2;
  644. !                     match_position = ((r - match_position) & (N2 - 1)) - 1;
  645. !                     return;
  646. !                 }
  647. !             } while (pattern[p] != lastbyte);
  648.   
  649. !             pattern = text_buf + p + F2;
  650.   
  651.   #ifdef GATHER_STAT
  652. !         node_compares++;
  653.   #endif
  654.   
  655. !             for (m = -F2; key[m] == pattern[m] && ++m < 0;);
  656.   
  657. !         } while (m < match_length);
  658.   
  659. !         if (m == 0) {
  660.   
  661.   /* There are two equal F-char sequences, the oldest one must be
  662.       deleted from the list.
  663.   */
  664.   
  665.   #ifdef DEBUG
  666.       if (verbose)
  667.           fprintf(stderr, "Replacing node: %d -> %d\n", p, r);
  668.   #endif
  669. !             nextof(prev[p]) = nextof(p);
  670. !             prev[nextof(p)] = prev[p];
  671. !             prev[p] = NIL;  /* remove p, it is further than r */
  672. !             match_length = F2;
  673. !             match_position = ((r - p) & (N2 - 1)) - 1;
  674. !             return;
  675. !         }
  676. !         match_length = m;       /* remember new results */
  677. !         match_position = p;
  678. ! #ifdef GATHER_STAT
  679. !         node_prolongations++;
  680. ! #endif
  681. !     }
  682. !     /* chain length exceeded */
  683. !     match_length += F2;
  684. !     match_position = ((r - match_position) & (N2 - 1)) - 1;
  685.   }
  686.   #endif
  687. *** distribution/lz.h    Thu Jul 16 15:20:59 1992
  688. --- lz.h    Mon Aug 17 17:02:11 1992
  689. ***************
  690. *** 39,45 ****
  691.   #define array_size      (N2 + 1 + (1L << BITS))
  692.   
  693.   extern hash_t prev[];
  694. ! extern us_t      match_position, match_length, chain_length;
  695.   
  696.   #ifndef __XENIX__
  697.   #define nextof(i)       next[i]
  698. --- 39,45 ----
  699.   #define array_size      (N2 + 1 + (1L << BITS))
  700.   
  701.   extern hash_t prev[];
  702. ! extern int       match_position, match_length, chain_length;
  703.   
  704.   #ifndef __XENIX__
  705.   #define nextof(i)       next[i]
  706. ***************
  707. *** 75,81 ****
  708. --- 75,95 ----
  709.          nextof(prev[n]) = NIL;\
  710.          prev[n] = NIL;\
  711.   }
  712. + /* Hash function */
  713.   
  714. + #define hash(p)\
  715. +     ((hash_t)(p)[0] + ((hash_t)(p)[1] << LEN0) +\
  716. +     ((hash_t)(p)[2] << LEN1))
  717. + #ifdef FASTHASH
  718. + #define hashof(p)\
  719. +     (((p)[0] != (p)[1] ? hash(p) : hash(p) + hash((p) + 3)) &\
  720. +     ((1L << BITS) - 1))
  721. + #else
  722. + #define hashof(p)\
  723. +     (hash(p) & ((1L << BITS) - 1))
  724. + #endif
  725.   /* Inserting of a node `r' into hashed linked list: `r' becomes
  726.       the head of list.
  727.   */
  728. ***************
  729. *** 85,92 ****
  730.       register hash_t p; register us_t first_son;\
  731.       register uc_t  *key;\
  732.       key = &text_buf[r];\
  733. !     p = N2 + 1 + (((hash_t)key[0] + ((hash_t)key[1] << LEN0) +\
  734. !             ((hash_t)key[2] << LEN1)) & ((1L << BITS) - 1));\
  735.       first_son = nextof(p);\
  736.       nextof(r) = first_son;\
  737.       nextof(p) = r;\
  738. --- 99,105 ----
  739.       register hash_t p; register us_t first_son;\
  740.       register uc_t  *key;\
  741.       key = &text_buf[r];\
  742. !     p = N2 + 1 + hashof(key);\
  743.       first_son = nextof(p);\
  744.       nextof(r) = first_son;\
  745.       nextof(p) = r;\
  746. ***************
  747. *** 133,161 ****
  748.   #define FIX_DI
  749.   #endif
  750.   
  751. ! #ifndef DO_INLINE
  752.   
  753. ! /* This statement is due to ideas of Boyer and Moore: */
  754. ! /* Is somewhere an optimizing compiler which can vectorize this? ;-) */
  755.   
  756. ! #define MATCHING for (m = match_length; m >= 0 && key[m] == pattern[m]; m--)
  757. ! #define NOT_YET (m >= 0)
  758. ! #else
  759. ! /* Hope that memcmp will be intrinsic (Microsoft C).
  760.   */
  761. - #define MATCHING
  762. - #define NOT_YET (key[match_length] != pattern[match_length] || memcmp(key, pattern, match_length))
  763.   
  764. - #endif
  765. - #define CHAIN_THRESHOLD (F2 * 3)
  766. - #ifdef  FAST
  767. - /* Simple inline replacement for get_next_match; they match
  768. - literally except return --> goto quote(leave)l. No obfuscations !! */
  769.   #if defined(__STDC__) || defined (__TURBOC__)
  770.   #define LEAVE(num) leave##num
  771.   #else
  772. --- 146,159 ----
  773.   #define FIX_DI
  774.   #endif
  775.   
  776. ! #define CHAIN_THRESHOLD F2
  777.   
  778. ! #ifdef  FAST
  779.   
  780. ! /* Simple inline replacement for get_next_match; they match almost
  781. ! literally except return --> goto quote(leave)l. No obfuscations !!
  782.   */
  783.   
  784.   #if defined(__STDC__) || defined (__TURBOC__)
  785.   #define LEAVE(num) leave##num
  786.   #else
  787. ***************
  788. *** 163,178 ****
  789.   #define LEAVE(num) quote(leave)num
  790.   #endif
  791.   
  792. ! #define Get_Next_Match(r,l) {register us_t p=r;register int m;\
  793. ! register uc_t *key FIX_SI, *pattern FIX_DI;int chain_count=chain_length;\
  794. ! key=text_buf+r;do{ do{ if((p=nextof(p))==NIL||(greedy &&\
  795. ! !chain_count--))goto LEAVE(l);pattern=text_buf+p;MATCHING;}while NOT_YET;\
  796. ! for(m=match_length;++m<F2&&key[m]==pattern[m];);\
  797. ! match_length=m;match_position=((r-p)&(N2-1))-1;}while(m<F2);\
  798. ! nextof(prev[p])=nextof(p);prev[nextof(p)]=prev[p];prev[p]=NIL;LEAVE(l):;}
  799.   
  800.   #else
  801.   
  802.   #define Get_Next_Match(r,l)     get_next_match(r)
  803.   
  804.   #endif
  805. --- 161,187 ----
  806.   #define LEAVE(num) quote(leave)num
  807.   #endif
  808.   
  809. ! #define m_l match_length
  810. ! #define t_b text_buf
  811. ! #define m_p match_position
  812.   
  813. + #define Get_Next_Match(r,l) {register p=r;register m;register uc_t lb;\
  814. + register uc_t *key FIX_SI, *pat FIX_DI;int cc=chain_length;\
  815. + key=t_b+r+F2;m_l-=F2;for(;cc--;){lb=key[m_l];do{pat=t_b+m_l+F2;do{\
  816. + if((p=nextof(p))==NIL){m_p=((r-m_p)&(N2-1))-1;m_l+=F2;goto LEAVE(l);}\
  817. + }while(pat[p]!=lb);pat=t_b+p+F2;for(m= -F2;key[m]==pat[m]&&++m<0;);\
  818. + }while(m<m_l);if(m==0){nextof(prev[p])=nextof(p);prev[nextof(p)]=prev[p];\
  819. + prev[p]=NIL;m_l=F2;m_p=((r-p)&(N2-1))-1;goto LEAVE(l);}m_l=m;m_p=p;}\
  820. + m_p=((r-m_p)&(N2-1))-1;m_l+=F2;LEAVE(l):;}
  821.   #else
  822.   
  823.   #define Get_Next_Match(r,l)     get_next_match(r)
  824. + extern void get_next_match();
  825.   
  826.   #endif
  827. + #ifdef GATHER_STAT
  828. + extern long node_matches, node_compares, node_prolongations;
  829. + #endif
  830. *** distribution/makefile    Thu Jul 16 15:21:00 1992
  831. --- makefile    Thu Jul 30 13:27:39 1992
  832. ***************
  833. *** 4,14 ****
  834.       @echo ''
  835.       @echo 'Please indicate the system to make Freeze for.'
  836.       @echo 'Possible choices are: bsd, sysv, x286, sun4, hpux,'
  837. !     @echo 'generic.'
  838.       @echo ''
  839.   
  840. ! DEST          = /usr/local/bin
  841. ! MANDEST       = /usr/local/man/man1
  842.   SEC           = 1
  843.   
  844.   HDRS          = bitio.h\
  845. --- 4,19 ----
  846.       @echo ''
  847.       @echo 'Please indicate the system to make Freeze for.'
  848.       @echo 'Possible choices are: bsd, sysv, x286, sun4, hpux,'
  849. !     @echo 'm88k, sysv-longnames, generic.'
  850.       @echo ''
  851. +     @echo 'sysv-longnames is a target for SysV machines which allow'
  852. +     @echo 'filenames to be more than 14 characters long.'
  853. +     @echo ''
  854.   
  855. ! # Added the prefix macro, so that it was easier to change installation place.
  856. ! prefix        = /usr/local
  857. ! DEST          = $(prefix)/bin
  858. ! MANDEST       = $(prefix)/man/man1
  859.   SEC           = 1
  860.   
  861.   HDRS          = bitio.h\
  862. ***************
  863. *** 24,30 ****
  864.   OPTIONS       = -DCOMPAT
  865.   
  866.   LINTFLAGS     = -DBITS=15 -DSIGTYPE=void -DCOMPAT -DDEBUG\
  867. !         -DGATHER_STAT -x -DFAST
  868.   
  869.   MAKEFILE      = makefile
  870.   
  871. --- 29,35 ----
  872.   OPTIONS       = -DCOMPAT
  873.   
  874.   LINTFLAGS     = -DBITS=15 -DSIGTYPE=void -DCOMPAT -DDEBUG\
  875. !         -DGATHER_STAT -DUTIMES -x
  876.   
  877.   MAKEFILE      = makefile
  878.   
  879. ***************
  880. *** 74,80 ****
  881.           $(CC) $(CFLAGS) $(LDFLAGS) -o statist statist.o lz.o $(LIBS)
  882.   
  883.   clobber:        clean
  884. !         rm -f $(PROGRAM) statist *.man
  885.   
  886.   clean:;         rm -f *.o *.b .,* core *.out
  887.   
  888. --- 79,85 ----
  889.           $(CC) $(CFLAGS) $(LDFLAGS) -o statist statist.o lz.o $(LIBS)
  890.   
  891.   clobber:        clean
  892. !         rm -f $(PROGRAM) statist *.man \#* *~
  893.   
  894.   clean:;         rm -f *.o *.b .,* core *.out
  895.   
  896. ***************
  897. *** 91,96 ****
  898. --- 96,102 ----
  899.           -strip $@
  900.           -mcs -d $@
  901.           -ln -f $@ $(DEST)/melt
  902. +         -ln -f $@ $(DEST)/unfreeze
  903.           -ln -f $@ $(DEST)/fcat
  904.   
  905.   $(DEST)/statist: statist
  906. ***************
  907. *** 103,110 ****
  908. --- 109,122 ----
  909.           cp freeze.1 $@
  910.           chmod +r $@
  911.           -ln -f $@ $(MANDEST)/melt.$(SEC)
  912. +         -ln -f $@ $(MANDEST)/unfreeze.$(SEC)
  913.           -ln -f $@ $(MANDEST)/fcat.$(SEC)
  914. + # This is much better for places which keep preformated manpages.
  915. + #        echo ".so man1/freeze.$(SEC)" > $(MANDEST)/melt.$(SEC)
  916. + #        echo ".so man1/freeze.$(SEC)" > $(MANDEST)/unfreeze.$(SEC)
  917. + #        echo ".so man1/freeze.$(SEC)" > $(MANDEST)/fcat.$(SEC)
  918.   
  919.   $(MANDEST)/statist.$(SEC): statist.1
  920.           cp statist.1 $@
  921.           chmod +r $@
  922. ***************
  923. *** 111,125 ****
  924.   
  925.   bsd:
  926.           make prog CFLAGS="-O -DBSD -DUTIMES -DBITS=16\
  927. !         -DFAST -DSIGTYPE=void" CC=$(CC)
  928.   
  929. ! hpux:
  930.           make prog CFLAGS="-O -DLONGNAMES -DBITS=16\
  931. !         -DFAST -DSIGTYPE=void" CC=$(CC)
  932.   
  933.   sysv:
  934.           make prog CFLAGS="-O -DBITS=16 -DFAST -DSIGTYPE=void"\
  935. !         LIBS="-lc_s" CC=$(CC)
  936.   
  937.   x286:
  938.           make prog CC=cc CFLAGS="-Ox -Ml2 -DBITS=16 -DFAST\
  939. --- 123,141 ----
  940.   
  941.   bsd:
  942.           make prog CFLAGS="-O -DBSD -DUTIMES -DBITS=16\
  943. !         -DFAST -DSIGTYPE=void" CC="$(CC)"
  944.   
  945. ! sysv-longnames:
  946.           make prog CFLAGS="-O -DLONGNAMES -DBITS=16\
  947. !         -DFAST -DSIGTYPE=void" CC="$(CC)"
  948.   
  949. + hpux:        sysv-longnames
  950. + m88k:        sysv-longnames
  951.   sysv:
  952.           make prog CFLAGS="-O -DBITS=16 -DFAST -DSIGTYPE=void"\
  953. !         LIBS="-lc_s" CC="$(CC)"
  954.   
  955.   x286:
  956.           make prog CC=cc CFLAGS="-Ox -Ml2 -DBITS=16 -DFAST\
  957. ***************
  958. *** 129,140 ****
  959.           make install MANDEST=/usr/man/man.C SEC=C
  960.   
  961.   generic:
  962. !         make prog CFLAGS="-O -DBITS=16 -DFAST -DSIGTYPE=int" CC=$(CC)
  963.   
  964.   sun4:
  965. !         make prog CC=cc CFLAGS="-O4 -DBSD -DSUN4 -DSIGTYPE=void\
  966. !         -DUTIMES -DBITS=16 -DFAST"
  967.   
  968.   ###
  969.   bitio.o: freeze.h compat.h bitio.h
  970. --- 145,155 ----
  971.           make install MANDEST=/usr/man/man.C SEC=C
  972.   
  973.   generic:
  974. !         make prog CFLAGS="-O -DBITS=16 -DFAST -DSIGTYPE=int" CC="$(CC)"
  975.   
  976.   sun4:
  977. !         make prog CC="cc" CFLAGS="-O4 -DBSD -DSUN4 -DSIGTYPE=void\
  978. !         -DUTIMES -DBITS=16"
  979.   
  980.   ###
  981.   bitio.o: freeze.h compat.h bitio.h
  982. *** distribution/patchlevel.h    Thu Jul 16 15:21:00 1992
  983. --- patchlevel.h    Mon Aug 17 16:48:47 1992
  984. ***************
  985. *** 1,2 ****
  986. ! #define PATCHLEVEL 4
  987. ! #define PATCHDATE "6/3/92"
  988. --- 1,2 ----
  989. ! #define PATCHLEVEL 5
  990. ! #define PATCHDATE "17/8/92"
  991. *** distribution/statist.c    Thu Jul 16 15:20:52 1992
  992. --- statist.c    Thu Jul 30 13:43:21 1992
  993. ***************
  994. *** 113,118 ****
  995. --- 113,120 ----
  996.   
  997.       for (c = 1; c <= 6; c++) bits[c] = 0;
  998.   
  999. +     printf("Non-monotonities are in: ");
  1000.       for(c = 0; c < N_POS; c++) {
  1001.           j = 0;
  1002.           k = c;
  1003. ***************
  1004. *** 119,134 ****
  1005.           do j++; while ((k = prnt[k]) != r);
  1006.           if (j <= 6)
  1007.               bits[j]++;
  1008. !         if (j < pr)
  1009.               f += pr - j;
  1010. !         else
  1011.               pr = j;
  1012.       }
  1013.   
  1014.       k = bits[1] + bits[2] + bits[3] + bits[4] +
  1015.       bits[5] + bits[6];
  1016.   
  1017. !     k = 62 - k;     /* free variable length codes for 7 & 8 bits */
  1018.   
  1019.       j = 128 * bits[1] + 64 * bits[2] + 32 * bits[3] +
  1020.       16 * bits[4] + 8 * bits[5] + 4 * bits[6];
  1021. --- 121,142 ----
  1022.           do j++; while ((k = prnt[k]) != r);
  1023.           if (j <= 6)
  1024.               bits[j]++;
  1025. !         if (j < pr) {
  1026.               f += pr - j;
  1027. !             printf("%d, ", c);
  1028. !         } else
  1029.               pr = j;
  1030.       }
  1031. +     if(f == 0)
  1032. +         printf("\b\b\b\babsent.\n");
  1033. +     else
  1034. +         printf("\b\b.\n");
  1035.   
  1036.       k = bits[1] + bits[2] + bits[3] + bits[4] +
  1037.       bits[5] + bits[6];
  1038.   
  1039. !     k = N_POS - k;  /* free variable length codes for 7 & 8 bits */
  1040.   
  1041.       j = 128 * bits[1] + 64 * bits[2] + 32 * bits[3] +
  1042.       16 * bits[4] + 8 * bits[5] + 4 * bits[6];
  1043. ***************
  1044. *** 216,222 ****
  1045.               match_length = 1;
  1046.           } else if (greedy) {
  1047.               lens[match_length] ++;
  1048. !             update((us_t)match_position >> 7);
  1049.               refers ++;
  1050.           } else {
  1051.               register us_t orig_length, orig_position;
  1052. --- 224,233 ----
  1053.               match_length = 1;
  1054.           } else if (greedy) {
  1055.               lens[match_length] ++;
  1056. !         if (match_position < 0 || match_position >= 8192 - 256)
  1057. !             printf("%d\n", match_position);
  1058. !             update(match_position >> 7);
  1059.               refers ++;
  1060.           } else {
  1061.               register us_t orig_length, orig_position;
  1062. ***************
  1063. *** 226,237 ****
  1064.               Next_Char(N2, F2);
  1065.               Get_Next_Match(r,2);
  1066.               if (match_length > len) match_length = len;
  1067. !             if (orig_length > match_length) {
  1068.                   lens[orig_length] ++;
  1069. !                 update((us_t)orig_position >> 7);
  1070.                   match_length = orig_length - 1;
  1071.               } else  {
  1072.                   lens[match_length] ++;
  1073.                   update(match_position >> 7);
  1074.               }
  1075.               refers ++;
  1076. --- 237,251 ----
  1077.               Next_Char(N2, F2);
  1078.               Get_Next_Match(r,2);
  1079.               if (match_length > len) match_length = len;
  1080. !             if (orig_length >= match_length) {
  1081.                   lens[orig_length] ++;
  1082. !                 update(orig_position >> 7);
  1083.                   match_length = orig_length - 1;
  1084.               } else  {
  1085.                   lens[match_length] ++;
  1086. +             if (match_position < 0 || match_position >= 8192 - 256)
  1087. +                 printf("%d\n", match_position);
  1088.                   update(match_position >> 7);
  1089.               }
  1090.               refers ++;
  1091.  
  1092. exit 0 # Just in case...
  1093.