home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume34 / freeze / part02 < prev    next >
Encoding:
Text File  |  1993-01-18  |  54.6 KB  |  2,204 lines

  1. Newsgroups: comp.sources.misc
  2. From: leo@ipmce.su (Leonid A. Broukhis)
  3. Subject: v34i126:  freeze - Freeze/melt compression program vers. 2.4, Part02/03
  4. Message-ID: <1993Jan19.043553.29582@sparky.imd.sterling.com>
  5. X-Md4-Signature: 2a34590838e1849d96027d7eafecafe3
  6. Date: Tue, 19 Jan 1993 04:35:53 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: leo@ipmce.su (Leonid A. Broukhis)
  10. Posting-number: Volume 34, Issue 126
  11. Archive-name: freeze/part02
  12. Environment: ISC, Xenix, SunOS, MS-DOS
  13. Supersedes: freeze: Volume 25, Issue 12-13
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # Contents:  Makefile.in config.h.in config.msc config.tur default.c
  20. #   freeze.1 freeze.h huf.c lz.c lz.h statist.1 statist.c
  21. # Wrapped by kent@sparky on Mon Jan 18 22:27:48 1993
  22. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 2 (of 3)."'
  25. if test -f 'Makefile.in' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'Makefile.in'\"
  27. else
  28.   echo shar: Extracting \"'Makefile.in'\" \(3683 characters\)
  29.   sed "s/^X//" >'Makefile.in' <<'END_OF_FILE'
  30. XSHELL         = /bin/sh
  31. X
  32. XCC            = @CC@
  33. XCFLAGS        =         # -O2   # for gcc 2.2.2
  34. X
  35. XINSTALL       = @INSTALL@
  36. XINSTALL_PROGRAM = @INSTALL_PROGRAM@ -s
  37. XINSTALL_DATA  = @INSTALL_DATA@
  38. X
  39. XLIBS          = @LIBS@
  40. XOBJ           = o
  41. XEXE           =
  42. X
  43. Xdefault:        prog
  44. X
  45. X# Added the prefix macro, so that it was easier to change installation place.
  46. Xprefix        = /usr/local
  47. XDEST          = $(prefix)/bin
  48. XMANDEST       = $(prefix)/man/man1
  49. XSEC           = 1
  50. X
  51. XHDRS          = bitio.h\
  52. X        compat.h\
  53. X        freeze.h\
  54. X        huf.h\
  55. X        lz.h\
  56. X        patchlevel.h
  57. X
  58. X# define DEFFILE as a filename with freeze's default Huffman values
  59. X# e.g. -DDEFFILE=\"/etc/default/freeze\"
  60. X# !!!! NOTE !!!! default is now $(prefix)/lib/freeze.cnf !!!!!
  61. X
  62. XOPTIONS       = -DDEFFILE=\"$(prefix)/lib/freeze.cnf\"
  63. X
  64. XLINTFLAGS     = -DCOMPAT -DDEBUG -DGATHER_STAT -x -h
  65. X
  66. XMAKEFILE      = makefile
  67. X
  68. XOBJS          = bitio.$(OBJ)\
  69. X        debug.$(OBJ)\
  70. X        decode.$(OBJ)\
  71. X        default.$(OBJ)\
  72. X        encode.$(OBJ)\
  73. X        freeze.$(OBJ)\
  74. X        huf.$(OBJ)\
  75. X        lz.$(OBJ)
  76. X
  77. XCATMAN        = freeze.man statist.man
  78. X
  79. XMAN           = freeze.1 statist.1
  80. X
  81. XSRCS          = bitio.c\
  82. X        debug.c\
  83. X        decode.c\
  84. X        default.c\
  85. X        encode.c\
  86. X        freeze.c\
  87. X        huf.c\
  88. X        lz.c
  89. X
  90. X.SUFFIXES:       .man .1 .$(suffix)
  91. X
  92. X.1.man:
  93. X        nroff -man < $< > $@
  94. X
  95. X.c.$(OBJ):
  96. X        $(CC) -c $(CFLAGS) $(OPTIONS) $<
  97. X
  98. Xprog:           freeze$(EXE) statist$(EXE) showhuf$(EXE)
  99. X
  100. Xman:            $(CATMAN)
  101. X
  102. Xlint:           $(SRCS)
  103. X        lint $(LINTFLAGS) $(SRCS) > lint.out
  104. X
  105. Xfreeze$(EXE):   $(OBJS)
  106. X        $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
  107. X
  108. Xstatist$(EXE):  statist.$(OBJ) lz.$(OBJ)
  109. X        $(CC) $(LDFLAGS) -o $@ statist.$(OBJ) lz.$(OBJ) $(LIBS)
  110. X
  111. Xshowhuf$(EXE):  showhuf.$(OBJ)
  112. X        $(CC) $(LDFLAGS) -o $@ showhuf.$(OBJ) $(LIBS)
  113. X
  114. Xclobber:        clean
  115. X        rm -f freeze$(EXE) statist$(EXE) showhuf$(EXE) *.man \#* *~ config.h
  116. X
  117. Xclean:;         rm -f *.$(OBJ) *.b .,* core *.out
  118. X
  119. Xinstall:        $(DEST)/freeze $(DEST)/statist $(MANDEST)/freeze.$(SEC) $(MANDEST)/statist.$(SEC)
  120. X
  121. Xpatch:;         rm -f patch.out
  122. X        -for i in distribution/*.[ch1] Makefile.in configure ; do \
  123. X        (diff -c $$i `basename $$i` >> patch.out); \
  124. X        done
  125. X
  126. X$(DEST)/freeze: freeze
  127. X        $(INSTALL_PROGRAM) freeze $@
  128. X        -ln -f $@ $(DEST)/melt
  129. X        -ln -f $@ $(DEST)/unfreeze
  130. X        -ln -f $@ $(DEST)/fcat
  131. X
  132. X$(DEST)/statist: statist
  133. X        $(INSTALL_PROGRAM) statist $@
  134. X
  135. X$(MANDEST)/freeze.$(SEC): freeze.1
  136. X        $(INSTALL_DATA) freeze.1 $@
  137. X        -ln -f $@ $(MANDEST)/melt.$(SEC)
  138. X        -ln -f $@ $(MANDEST)/unfreeze.$(SEC)
  139. X        -ln -f $@ $(MANDEST)/fcat.$(SEC)
  140. X# This is much better for places which keep preformated manpages.
  141. X#        echo ".so man1/freeze.$(SEC)" > $(MANDEST)/melt.$(SEC)
  142. X#        echo ".so man1/freeze.$(SEC)" > $(MANDEST)/unfreeze.$(SEC)
  143. X#        echo ".so man1/freeze.$(SEC)" > $(MANDEST)/fcat.$(SEC)
  144. X
  145. X
  146. X$(MANDEST)/statist.$(SEC): statist.1
  147. X        $(INSTALL_DATA) statist.1 $@
  148. X
  149. Xx286:
  150. X        $(MAKE) prog "CC=cc -LARGE" CFLAGS="-Ox -Ml2" LDFLAGS="-Ml2"
  151. X
  152. Xx286install:
  153. X        $(MAKE) install MANDEST=/usr/man/man.C SEC=C
  154. X
  155. Xmsc:
  156. X        if not exist config.h copy config.msc config.h
  157. X        $(MAKE) prog EXE=.exe OBJ=obj CC="cl" CFLAGS="-Ms -Ox" LDFLAGS="-Ml" LIBS=""
  158. X
  159. Xturbo:
  160. X        if not exist config.h copy config.tur config.h
  161. X        $(MAKE) prog EXE=.exe OBJ=obj CC="tcc" CFLAGS="-O -ms" LIBS=""
  162. X
  163. Xborland:
  164. X        if not exist config.h copy config.tur config.h
  165. X        $(MAKE) prog EXE=.exe OBJ=obj CC="bcc" CFLAGS="-O -ms" LIBS=""
  166. X
  167. X###
  168. Xbitio.$(OBJ): freeze.h compat.h bitio.h
  169. Xdebug.$(OBJ): freeze.h compat.h huf.h bitio.h
  170. Xdecode.$(OBJ): freeze.h compat.h huf.h bitio.h
  171. Xdefault.$(OBJ): freeze.h compat.h
  172. Xencode.$(OBJ): freeze.h compat.h lz.h huf.h bitio.h
  173. Xfreeze.$(OBJ): freeze.h compat.h patchlev.h
  174. Xhuf.$(OBJ): freeze.h compat.h huf.h bitio.h
  175. Xlz.$(OBJ): freeze.h compat.h lz.h
  176. Xstatist.$(OBJ): freeze.h compat.h lz.h
  177. Xshowhuf.$(OBJ): freeze.h huf.h
  178. END_OF_FILE
  179.   if test 3683 -ne `wc -c <'Makefile.in'`; then
  180.     echo shar: \"'Makefile.in'\" unpacked with wrong size!
  181.   fi
  182.   # end of 'Makefile.in'
  183. fi
  184. if test -f 'config.h.in' -a "${1}" != "-c" ; then 
  185.   echo shar: Will not clobber existing file \"'config.h.in'\"
  186. else
  187.   echo shar: Extracting \"'config.h.in'\" \(2522 characters\)
  188.   sed "s/^X//" >'config.h.in' <<'END_OF_FILE'
  189. X/* This is a configuration file prototype, copy it to config.h and      */
  190. X/* "#define" appropriate macros if you have problems with "configure".  */
  191. X
  192. X/* define as "int" or "void"; default (undefined) means "void"          */
  193. X#undef RETSIGTYPE
  194. X
  195. X/* define if your computer/system allows unaligned word access          */
  196. X#undef ALLOW_MISALIGN
  197. X
  198. X/* define if sizeof(int) == 2                                           */
  199. X#undef INT_16_BITS
  200. X
  201. X/* define if your computer cannot handle data items of more than 64K    */
  202. X#undef SEGMENTED
  203. X
  204. X/* define if filenames can be of more than 14 chars                     */
  205. X#undef HAVE_LONG_FILE_NAMES
  206. X
  207. X/* define no more than one, according to your standard #include's       */
  208. X/* if you have <dirent.h>                                               */
  209. X#undef DIRENT
  210. X/* if you have <sys/ndir.h>                                             */
  211. X#undef SYSNDIR
  212. X/* if you have <sys/dir.h>                                              */
  213. X#undef SYSDIR
  214. X
  215. X/* define if you have <sys/stdtypes.h>                                  */
  216. X#undef HAVE_SYS_STDTYPES_H
  217. X
  218. X/* define if you have "rindex" and "setlinebuf" correspondingly         */
  219. X#undef HAVE_RINDEX
  220. X#undef HAVE_SETLINEBUF
  221. X
  222. X/* define no more than one, according to your standard #include's       */
  223. X/* if you have <utime.h>                                                */
  224. X#undef UTIME
  225. X/* if you have <sys/utime.h>                                            */
  226. X#undef SYSUTIME
  227. X/* if you have "struct timeval" in <sys/time.h>                         */
  228. X#undef SYSTIME
  229. X
  230. X/* define if you want to have freeze compatible with vers. 1.0          */
  231. X#undef COMPAT
  232. X
  233. X/* define if your system has multibyte NEWLINE (as in MS-DOS) and       */
  234. X/* you want to do text conversion by default                            */
  235. X#undef TEXT_DEFAULT
  236. X
  237. X/* define if you want to build freeze in small model  (64K data)        */
  238. X/* (segmented architectures only)                                       */
  239. X#undef TINY
  240. X
  241. X/* define if you want to decrease the amount of memory but without      */
  242. X/* 64K restriction                                                      */
  243. X#undef SMALL
  244. X
  245. X/* define to increase the compression speed by about 10% at the cost    */
  246. X/* of some tenths of % compression rate                                 */
  247. X#undef FASTHASH
  248. X
  249. X/* default Huffman values, define if you don't like the default        */
  250. X/* 0,0,1,2,6,19,34,0. These below are reasonably good also.            */
  251. X/* #define HUFVALUES 0,1,1,1,4,10,27,18                                */
  252. END_OF_FILE
  253.   if test 2522 -ne `wc -c <'config.h.in'`; then
  254.     echo shar: \"'config.h.in'\" unpacked with wrong size!
  255.   fi
  256.   # end of 'config.h.in'
  257. fi
  258. if test -f 'config.msc' -a "${1}" != "-c" ; then 
  259.   echo shar: Will not clobber existing file \"'config.msc'\"
  260. else
  261.   echo shar: Extracting \"'config.msc'\" \(2490 characters\)
  262.   sed "s/^X//" >'config.msc' <<'END_OF_FILE'
  263. X/* This is a configuration file prototype, copy it to config.h and      */
  264. X/* "#define" appropriate macros if you have problems with "configure".  */
  265. X
  266. X/* define as "int" or "void" */
  267. X#define RETSIGTYPE void
  268. X
  269. X/* define if your computer/system allows unaligned word access          */
  270. X#define ALLOW_MISALIGN
  271. X
  272. X/* define if sizeof(int) == 2                                           */
  273. X#define INT_16_BITS
  274. X
  275. X/* define if your computer cannot handle data items of more than 64K    */
  276. X#define SEGMENTED
  277. X
  278. X/* define if filenames can be of more than 14 chars                     */
  279. X#undef HAVE_LONG_FILE_NAMES
  280. X
  281. X/* define no more than one of, according to your standard #include's    */
  282. X/* if you have <dirent.h>                                               */
  283. X#undef DIRENT
  284. X/* if you have <sys/ndir.h>                                             */
  285. X#undef SYSNDIR
  286. X/* if you have <sys/dir.h>                                              */
  287. X#undef SYSDIR
  288. X
  289. X/* define if you have <sys/stdtypes.h>                                  */
  290. X#undef HAVE_SYS_STDTYPES_H
  291. X
  292. X/* define if you have "rindex" and "setlinebuf" correspondingly         */
  293. X#undef HAVE_RINDEX
  294. X#undef HAVE_SETLINEBUF
  295. X
  296. X/* define no more than one of, according to your standard #include's    */
  297. X/* if you have <utime.h>                                                */
  298. X#define UTIME
  299. X/* if you have <sys/utime.h>                                            */
  300. X#undef SYSUTIME
  301. X/* if you have "struct timeval" in <sys/time.h>                         */
  302. X#undef SYSTIME
  303. X
  304. X/* define if you want to have freeze compatible with vers. 1.0          */
  305. X#undef COMPAT
  306. X
  307. X/* define if your system has multibyte NEWLINE (as in MS-DOS) and       */
  308. X/* you want to do text conversion by default                            */
  309. X#undef TEXT_DEFAULT
  310. X
  311. X/* define if you want to build freeze in small model  (64K data)        */
  312. X/* (segmented architectures only)                                       */
  313. X#define TINY
  314. X
  315. X/* define if you want to decrease the amount of memory but without      */
  316. X/* 64K restriction                                                      */
  317. X#undef SMALL
  318. X
  319. X/* define to increase the compression speed by about 10% at the cost    */
  320. X/* of some tenths of % compression rate                                 */
  321. X#undef FASTHASH
  322. X
  323. X/* default Huffman values, define if you don't like the default        */
  324. X/* 0,0,1,2,6,19,34,0. These below are reasonably good also.            */
  325. X/* #define HUFVALUES 0,1,1,1,4,10,27,18                                */
  326. END_OF_FILE
  327.   if test 2490 -ne `wc -c <'config.msc'`; then
  328.     echo shar: \"'config.msc'\" unpacked with wrong size!
  329.   fi
  330.   # end of 'config.msc'
  331. fi
  332. if test -f 'config.tur' -a "${1}" != "-c" ; then 
  333.   echo shar: Will not clobber existing file \"'config.tur'\"
  334. else
  335.   echo shar: Extracting \"'config.tur'\" \(2584 characters\)
  336.   sed "s/^X//" >'config.tur' <<'END_OF_FILE'
  337. X/* This is a configuration file prototype, copy it to config.h and      */
  338. X/* "#define" appropriate macros if you have problems with "configure".  */
  339. X
  340. X/* define as "int" or "void" */
  341. X#define RETSIGTYPE void
  342. X
  343. X/* define if your computer/system allows unaligned word access          */
  344. X#define ALLOW_MISALIGN
  345. X
  346. X/* define if sizeof(int) == 2                                           */
  347. X#define INT_16_BITS
  348. X
  349. X/* define if your computer cannot handle data items of more than 64K    */
  350. X#define SEGMENTED
  351. X
  352. X/* define if filenames can be of more than 14 chars                     */
  353. X#undef HAVE_LONG_FILE_NAMES
  354. X
  355. X/* define no more than one of, according to your standard #include's    */
  356. X/* if you have <dirent.h>                                               */
  357. X#undef DIRENT
  358. X/* if you have <sys/ndir.h>                                             */
  359. X#undef SYSNDIR
  360. X/* if you have <sys/dir.h>                                              */
  361. X#undef SYSDIR
  362. X
  363. X/* define if you have <sys/stdtypes.h>                                  */
  364. X#undef HAVE_SYS_STDTYPES_H
  365. X
  366. X/* define if you have "rindex" and "setlinebuf" correspondingly         */
  367. X#undef HAVE_RINDEX
  368. X#undef HAVE_SETLINEBUF
  369. X
  370. X/* define no more than one of, according to your standard #include's    */
  371. X/* if you have <utime.h>                                                */
  372. X#undef UTIME
  373. X/* if you have <sys/utime.h>                                            */
  374. X#undef SYSUTIME
  375. X/* if you have "struct timeval" in <sys/time.h>                         */
  376. X#undef SYSTIME
  377. X
  378. X/* BORLAND C has no off_t definition in <sys/types.h>                   */
  379. X#define off_t long
  380. X
  381. X/* define if you want to have freeze compatible with vers. 1.0          */
  382. X#undef COMPAT
  383. X
  384. X/* define if your system has multibyte NEWLINE (as in MS-DOS) and       */
  385. X/* you want to do text conversion by default                            */
  386. X#undef TEXT_DEFAULT
  387. X
  388. X/* define if you want to build freeze in small model  (64K data)        */
  389. X/* (segmented architectures only)                                       */
  390. X#define TINY
  391. X
  392. X/* define if you want to decrease the amount of memory but without      */
  393. X/* 64K restriction                                                      */
  394. X#undef SMALL
  395. X
  396. X/* define to increase the compression speed by about 10% at the cost    */
  397. X/* of some tenths of % compression rate                                 */
  398. X#undef FASTHASH
  399. X
  400. X/* default Huffman values, define if you don't like the default        */
  401. X/* 0,0,1,2,6,19,34,0. These below are reasonably good also.            */
  402. X/* #define HUFVALUES 0,1,1,1,4,10,27,18                                */
  403. END_OF_FILE
  404.   if test 2584 -ne `wc -c <'config.tur'`; then
  405.     echo shar: \"'config.tur'\" unpacked with wrong size!
  406.   fi
  407.   # end of 'config.tur'
  408. fi
  409. if test -f 'default.c' -a "${1}" != "-c" ; then 
  410.   echo shar: Will not clobber existing file \"'default.c'\"
  411. else
  412.   echo shar: Extracting \"'default.c'\" \(1274 characters\)
  413.   sed "s/^X//" >'default.c' <<'END_OF_FILE'
  414. X#include "freeze.h"
  415. X#include <errno.h>
  416. X
  417. X        /*-------------------------------*/
  418. X        /*     DEFAULTS FILE HANDLING    */
  419. X        /*-------------------------------*/
  420. X
  421. X#define OK      0
  422. X#define FAIL    NULL
  423. X#define NOFILE  ((FILE *) 0)
  424. X#define MAXLINE 128
  425. X
  426. Xchar            *strchr();
  427. Xstatic FILE     *defd = NOFILE;  /* defaults file stream */
  428. X
  429. Xint     defopen(fname)          /* open | reopen | close defaults file */
  430. X    char    *fname;
  431. X{
  432. X    register FILE   *fd;
  433. X
  434. X    if (!fname) {
  435. X        if (defd)
  436. X            (void) fclose(defd);
  437. X        defd = NOFILE;
  438. X        return OK;
  439. X    }
  440. X
  441. X    if (!(fd = fopen(fname, "r")))
  442. X        return errno;                   /* problems opening file */
  443. X
  444. X    defd = fd;
  445. X    return OK;
  446. X}
  447. X
  448. Xstatic char     defline[MAXLINE + 1];
  449. X
  450. Xchar    *defread(pattern)
  451. X    register char   *pattern;
  452. X{
  453. X    register        sz_patt;
  454. X    register char   *cp;
  455. X
  456. X    if (!defd)
  457. X        return FAIL;            /* defaults file not opened */
  458. X
  459. X    rewind(defd);
  460. X    sz_patt = strlen(pattern);
  461. X
  462. X    while (fgets(defline, MAXLINE, defd)) {
  463. X        if (!(cp = strchr(defline, '\n')))
  464. X            return FAIL;     /* line too long  */
  465. X        if (cp - defline < sz_patt)
  466. X            continue;       /* line too short */
  467. X        *cp = '\0';
  468. X        if (!strncmp(pattern, defline, sz_patt))
  469. X            return defline + sz_patt;       /* match found */
  470. X    }
  471. X
  472. X    return FAIL;                    /* no matching lines */
  473. X}
  474. END_OF_FILE
  475.   if test 1274 -ne `wc -c <'default.c'`; then
  476.     echo shar: \"'default.c'\" unpacked with wrong size!
  477.   fi
  478.   # end of 'default.c'
  479. fi
  480. if test -f 'freeze.1' -a "${1}" != "-c" ; then 
  481.   echo shar: Will not clobber existing file \"'freeze.1'\"
  482. else
  483.   echo shar: Extracting \"'freeze.1'\" \(7193 characters\)
  484.   sed "s/^X//" >'freeze.1' <<'END_OF_FILE'
  485. X.PU
  486. X.TH FREEZE 1 local
  487. X.SH NAME
  488. Xfreeze, unfreeze, melt, fcat  \-  compress and uncompress files
  489. X.SH SYNOPSIS
  490. X.ll +8
  491. X.B freeze
  492. X[
  493. X.B \-cdfvVgx
  494. X] [
  495. X.I "filename | type \&..."
  496. X]
  497. X.ll -8
  498. X.br
  499. X.B unfreeze
  500. X[
  501. X.B \-cfvV
  502. X] [
  503. X.I "filename \&..."
  504. X]
  505. X.br
  506. X.B melt
  507. X[
  508. X.B \-cfvV
  509. X] [
  510. X.I "filename \&..."
  511. X]
  512. X.br
  513. X.B fcat
  514. X[
  515. X.I "filename \&..."
  516. X]
  517. X.SH DESCRIPTION
  518. XCompresses the specified files or standard input.
  519. XEach file is replaced by a file with the extension
  520. X.B "\&.F,"
  521. Xbut only if the file got smaller. If no files are specified,
  522. Xthe compression is applied to the standard input
  523. Xand is written to standard output regardless of the results.
  524. XCompressed files can be restored to their original form by specifying the
  525. X.B \-d
  526. Xoption, or by running
  527. X.I melt
  528. Xor
  529. X.I unfreeze
  530. X(both linked to
  531. X.IR freeze ),
  532. Xon the 
  533. X.B "\&.F"
  534. Xfiles or the standard input.
  535. X.PP
  536. XIf the output file exists, it will not be overwritten unless the
  537. X.B \-f
  538. Xflag is given.  If
  539. X.B \-f
  540. Xis not specified and
  541. X.I freeze
  542. Xis run in the foreground,
  543. Xthe user is prompted
  544. Xas to whether the file should be overwritten.
  545. X.PP
  546. XIf the
  547. X.B \-g
  548. Xflag is given, a slightly less powerful (compression
  549. Xrate is 1.5% less), but somewhat faster heuristic is used. This flag can be
  550. Xused more than once (this mode is quite useful when freezing bitmaps) for
  551. Xadditional speedup.
  552. X.PP
  553. XIf you want to improve compression rate at the cost of speed, use
  554. X.B \-x
  555. Xflag. Like
  556. X.B \-g,
  557. Xthis flag can be used more than once, thus increasing compression rate.
  558. XNote that usually it isn't worth to use it more than twice.
  559. X.PP
  560. XIf the
  561. X.B \-f
  562. Xflag is given, all files specified are replaced with
  563. X.B "\&.F"
  564. Xfiles \- even if the file didn't get smaller.
  565. X.PP
  566. XWhen file names are given, the ownership (if run by root), modes, accessed
  567. Xand modified times are maintained between the file and its 
  568. X.B "\&.F"
  569. Xversion.  In this respect,
  570. X.I freeze
  571. Xcan be used for archival purposes, yet can still be used with
  572. X.IR make "(1)"
  573. Xafter melting.
  574. X.PP
  575. XThe
  576. X.B \-c
  577. Xoption causes the results of the freeze/melt operation to be written
  578. Xto stdout; no files are changed.  The
  579. X.I fcat
  580. Xprogram is the same as specifying
  581. X.B \-c
  582. Xto
  583. X.I melt
  584. X(all files are unpacked and written to stdout).
  585. X.PP
  586. XThe
  587. X.B \-v
  588. X(verbose) option causes the diagnostics (at the end of each file processing)
  589. Xto be printed to stderr, and the
  590. X.B \-vv
  591. Xoption causes the progress indicator to be drawn to the same place.
  592. X.PP
  593. X.I Type
  594. Xis a token preceded by a '+' or a '--', which defines the type
  595. Xof following files in the command string. An explicite definition
  596. Xof the file's type can give up to 2% of additional compression.
  597. XThe list of types is stored in file
  598. X.IR /usr/local/lib/freeze.cnf .
  599. XTypes may be abbreviated while not ambigious. You can also determine
  600. Xvalues for the static Huffman table by using a list of 8 numbers
  601. Xseparated by commas instead of
  602. X.I type.
  603. X.PP
  604. X.I Freeze
  605. Xuses the Lempel-Ziv algorithm on the first pass and the dynamic
  606. XHuffman algorithm on the second one. The size of sliding window
  607. Xis 8K, and the maximum length of matched string is 256.
  608. XThe positions on the window are coded using a static Huffman table.
  609. X.PP
  610. XA two byte magic number is prepended to the file
  611. Xto ensure that neither melting of random text nor refreezing of
  612. Xalready frozen text are attempted.  In addition, the characteristics
  613. Xof the static Huffman table being used during
  614. X.I freeze
  615. Xis written to the file so that these characteristics may be adapted
  616. Xto concrete conditions.
  617. X.PP
  618. X.ne 8
  619. XThe amount of compression obtained depends on the size of the
  620. Xinput file and the distribution of character substrings and their
  621. Xprobabilities.
  622. XTypically, text files, such as C programs,
  623. Xare reduced by 60\-75%, executable files are reduced by 50%.
  624. XCompression is generally much better than that achieved by
  625. XLZW coding (as used in
  626. X.IR compress ),
  627. Xor Huffman coding
  628. X.RI ( pack ),
  629. Xthough takes more time to compute.
  630. X.PP
  631. XIf the
  632. X.B \-V
  633. X(version) flag is given, the program's version number and compilation
  634. Xoptions are printed.
  635. X.PP
  636. XThe exit status is normally 0;
  637. Xif the last file gets bigger after freezing, the exit status is 2;
  638. Xif an error occurs, the exit status is 1.
  639. X.SH "SEE ALSO"
  640. Xcompact(1), pack(1), compress(1)
  641. X.SH "DIAGNOSTICS"
  642. XUnknown flag: 
  643. X.I "\'x\';"
  644. XUsage: freeze [-cdfvVg] [file|+type ...]
  645. X.in +8
  646. XInvalid options were specified on the command line.
  647. X.in -8
  648. X.IR file :
  649. Xnot in frozen format
  650. X.in +8
  651. XThe specified file has not been frozen.
  652. X.in -8
  653. X.IR file :
  654. Xalready has .F suffix -- no change
  655. X.in +8
  656. XCannot compress a file that has a ".F" suffix.
  657. X.IR mv "(1)"
  658. Xthe file to a different name and try again.
  659. X.in -8
  660. X.IR file :
  661. Xfilename too long to tack on .F
  662. X.in +8
  663. XThe specified file cannot be compressed because its filename is longer than
  664. X12 characters.
  665. X.IR mv "(1)"
  666. Xthe file to a different name and try again.  This message does not occur on
  667. X4.XBSD systems.
  668. X.in -8
  669. X.I file
  670. Xalready exists; do you wish to overwrite (y or n)?
  671. X.in +8
  672. XRespond "y" if you want the output file to be replaced; "n" if you want it
  673. Xto be left alone.
  674. X.in -8
  675. X.IR file :
  676. X.IR xx %
  677. X.in +8
  678. Xor
  679. X.in -8
  680. X.IR xxx K
  681. X.in +8
  682. XThese message fragments are written during the processing of a file, if
  683. X.B \-vv
  684. Xoption was given in the command line (in percents, if the length of file
  685. Xbeing processed is known; in Kbytes otherwise).
  686. X.in -8
  687. XFreezing:
  688. X.I "xx.xx% (y.yy"
  689. Xbits)
  690. X.in +8
  691. XThis message fragment gives the percentage of the input file that has been
  692. Xsaved by freezing and the number of remaining bits per byte of original file.
  693. X.in -8
  694. X-- not a regular file: unchanged
  695. X.in +8
  696. XThis message fragment is written when the input file is not a regular file.
  697. XThe input file is left unchanged.
  698. X.in -8
  699. X-- has 
  700. X.I xx 
  701. Xother links: unchanged
  702. X.in +8
  703. XThis message fragment is written when the input file has links.  The input
  704. Xfile is left unchanged.  See
  705. X.IR ln "(1)"
  706. Xfor more information.
  707. X.in -8
  708. X-- file unchanged
  709. X.in +8
  710. XThis message fragment is written when no savings are achieved by
  711. Xfreezing.  The input file is left unchanged.
  712. X.in -8
  713. X-- replaced with 
  714. X.I file
  715. X.in +8
  716. XThis message fragment is written when a file has been sucessfully
  717. Xfrozen/melt.
  718. X.in -8
  719. XUsing "
  720. X.I type
  721. X" type
  722. X.in +8
  723. XThis message indicates a successful switching to
  724. Xposition table for mentioned file type.
  725. X.in -8
  726. X"
  727. X.I xxx
  728. X" - no such file type
  729. X.in +8
  730. Xor
  731. X.in -8
  732. X.I xxx
  733. X- a list of 8 numbers expected
  734. X.in +8
  735. XThis message means the given file type does not exist or
  736. Xthe given string contains a comma, but is not a valid list
  737. Xof values for static Huffman table.
  738. X.in -8
  739. Xmelt: corrupt input
  740. X.in +8
  741. XThis message fragment is written when an error in header or
  742. Xunexpected end of frozen file is detected. Partial
  743. X(or empty, is there was an error in the header) file is created.
  744. X.in -8
  745. Xalready frozen -- file unchanged
  746. X.in +8
  747. XThis message fragment is written when an input file already has
  748. XFreeze's magic header.
  749. X.in -8
  750. XInvalid position table
  751. X.in +8
  752. Xor
  753. X.in -8
  754. X"
  755. X.I type
  756. X" - invalid entry
  757. X.in +8
  758. XThese messages appear only if Freeze has been made with incorrect
  759. Xdata for static Huffman table. It does never appear when freeze
  760. Xis called from a public access directory.
  761. X.in -8
  762. XUnknown header format
  763. X.in +8
  764. XUnknown values of flag bits were discovered in the header
  765. Xof frozen file.
  766. X.in -8
  767. X.SH "BUGS"
  768. XFound bugs descriptions, incompatibilities, etc.  please send to
  769. Xleo@ipmce.su.
  770. END_OF_FILE
  771.   if test 7193 -ne `wc -c <'freeze.1'`; then
  772.     echo shar: \"'freeze.1'\" unpacked with wrong size!
  773.   fi
  774.   # end of 'freeze.1'
  775. fi
  776. if test -f 'freeze.h' -a "${1}" != "-c" ; then 
  777.   echo shar: Will not clobber existing file \"'freeze.h'\"
  778. else
  779.   echo shar: Extracting \"'freeze.h'\" \(4101 characters\)
  780.   sed "s/^X//" >'freeze.h' <<'END_OF_FILE'
  781. X#include <stdio.h>
  782. X#include "config.h"
  783. X
  784. X#ifdef HAVE_SYS_STDTYPES_H
  785. X# include <sys/stdtypes.h>
  786. X#endif
  787. X
  788. X#ifndef getc
  789. X# ifdef m88k                   /* Green Hill C library bug. */
  790. X#  define getc(p)         (--(p)->_cnt < 0 ? __filbuf(p) : (int) *(p)->_ptr++)
  791. X# else
  792. X#  define getc(p)         (--(p)->_cnt < 0 ? _filbuf(p) : (int) *(p)->_ptr++)
  793. X# endif
  794. X#endif
  795. X#ifndef putc
  796. X# ifdef m88k                   /* Green Hill C library bug. */
  797. X#  define putc(x, p)      (--(p)->_cnt < 0 ? __flsbuf((unsigned char) (x), (p)) : (int) (*(p)->_ptr++ = (unsigned char) (x)))
  798. X# else
  799. X#  define putc(x, p)      (--(p)->_cnt < 0 ? _flsbuf((unsigned char) (x), (p)) : (int) (*(p)->_ptr++ = (unsigned char) (x)))
  800. X# endif
  801. X#endif
  802. X
  803. X#if !defined(MSDOS) && defined(__MSDOS__)
  804. X# define MSDOS
  805. X#endif
  806. X
  807. X#ifdef MSDOS
  808. X# define DOS
  809. X# include <fcntl.h>
  810. X#endif  /* MSDOS */
  811. X
  812. X#ifdef TOS
  813. X# define DOS
  814. X# define O_TEXT          0x01
  815. X# define O_BINARY        0x02
  816. X#endif
  817. X
  818. X#include <ctype.h>
  819. X#include <signal.h>
  820. X
  821. X#ifndef RETSIGTYPE
  822. X# define RETSIGTYPE void
  823. X#endif /* RETSIGTYPE */
  824. X
  825. X#ifndef TOS
  826. X# include <sys/types.h>
  827. X# include <sys/stat.h>
  828. X#else
  829. X# include <tos.h>
  830. X# include <types.h>
  831. X#endif
  832. X
  833. X#ifdef SYSTIME
  834. X# include <sys/time.h>
  835. X# define UTIMES
  836. X#else
  837. X# ifdef UTIME
  838. X#  include <utime.h>
  839. X# else
  840. X#  ifdef SYSUTIME
  841. X#   include <sys/utime.h>
  842. X#  else
  843. X#   ifdef unix
  844. X/*      UNIX without any declaration of utimbuf .... Strange! */
  845. Xstruct utimbuf {
  846. X    time_t actime;
  847. X    time_t modtime;
  848. X};
  849. Xextern int utime();
  850. X#   else
  851. X#    ifndef DOS
  852. X#     define BITS no_utimbuf_definition_on_unknown_system
  853. X#    endif
  854. X#   endif
  855. X#  endif
  856. X# endif
  857. X#endif
  858. X
  859. X/* for MAXNAMLEN only !!! */
  860. X#ifdef DIRENT
  861. X# include <dirent.h>
  862. X#else
  863. X# ifdef SYSNDIR
  864. X#  include <sys/ndir.h>
  865. X# else
  866. X#  ifdef SYSDIR
  867. X#   include <sys/dir.h>
  868. X#  endif
  869. X# endif
  870. X#endif
  871. X
  872. X#ifndef MAXNAMLEN
  873. X# define MAXNAMLEN       255
  874. X#endif
  875. X
  876. X#if MAXNAMLEN < 255
  877. X# undef MAXNAMLEN
  878. X# define MAXNAMLEN       255
  879. X#endif
  880. X
  881. X#ifdef DEBUG
  882. X# include <assert.h>
  883. X#endif  /* DEBUG */
  884. X
  885. X#ifdef DOS
  886. X# include <stdlib.h>
  887. X#endif  /* DOS */
  888. X
  889. X#ifdef __TURBOC__
  890. X# ifdef MSDOS
  891. X#  include <io.h>
  892. X#  include <alloc.h>
  893. X# else /* TOS */
  894. X#  include <ext.h>
  895. X# endif  /* MSDOS */
  896. X#endif /* __TURBOC__ */
  897. X
  898. Xtypedef unsigned short us_t;
  899. Xtypedef unsigned char uc_t;
  900. Xtypedef unsigned long ul_t;
  901. X
  902. X#define LOOKAHEAD       256     /* pre-sence buffer size */
  903. X#define MAXDIST         7936
  904. X#define WINSIZE         (MAXDIST + LOOKAHEAD)   /* must be a power of 2 */
  905. X#define WINMASK         (WINSIZE - 1)
  906. X
  907. X#define THRESHOLD    2
  908. X
  909. X#define N_CHAR2         (256 - THRESHOLD + LOOKAHEAD + 1) /* code: 0 .. N_CHARi - 1 */
  910. X#define T2              (N_CHAR2 * 2 - 1)       /* size of table */
  911. X
  912. X#define ENDOF           256                     /* pseudo-literal */
  913. X
  914. Xextern uc_t    Table2[];
  915. X
  916. Xextern long     in_count, bytes_out;
  917. Xextern off_t    file_length;
  918. X
  919. Xextern uc_t      text_buf[];
  920. X
  921. Xextern long     indc_threshold, indc_count;
  922. X
  923. Xextern short    do_melt, topipe, greedy, quiet, force;  /* useful flags */
  924. X
  925. X#define MAGIC1          ((uc_t)'\037')
  926. X#define MAGIC2_1        ((uc_t)'\236')          /* freeze vers. 1.X */
  927. X#define MAGIC2_2        ((uc_t)'\237')
  928. X
  929. Xextern int exit_stat;
  930. X
  931. X#ifdef DEBUG
  932. Xextern short debug;
  933. Xextern short verbose;
  934. Xextern char * pr_char();
  935. X#endif /* DEBUG */
  936. X
  937. X#if defined(GATHER_STAT) || defined(DEBUG)
  938. Xextern long refers_out, symbols_out;
  939. X#endif
  940. X
  941. Xextern short DecodeChar(), DecodePosition(), GetNBits();
  942. Xextern void melt2(), (*meltfunc)(), writeerr(), prratio(), prbits(), freeze();
  943. X
  944. X#ifdef COMPAT
  945. X#include "compat.h"
  946. X#endif
  947. X
  948. X#define INDICATOR \
  949. Xif (quiet < 0 && (in_count > indc_count)) {\
  950. X    if (ferror(stdout))\
  951. X        writeerr();\
  952. X    if (file_length) {\
  953. X        static int percents, old_percents = -1;\
  954. X        if ((percents = ftell(stdin) * 100 / file_length) !=\
  955. X            old_percents) {\
  956. X            fprintf(stderr, " %2d%%\b\b\b\b", percents);\
  957. X            old_percents = percents;\
  958. X        }\
  959. X        indc_count += indc_threshold;\
  960. X    } else {\
  961. X        fprintf(stderr, " %5ldK\b\b\b\b\b\b\b", in_count / 1024);\
  962. X        indc_count += indc_threshold;\
  963. X        indc_threshold += 1024;\
  964. X    }\
  965. X    fflush (stderr);\
  966. X}
  967. X
  968. X#ifdef HAVE_RINDEX
  969. X#define strchr index
  970. X#define strrchr rindex
  971. X#endif
  972. X
  973. Xextern char *strchr(), *strrchr();
  974. X
  975. END_OF_FILE
  976.   if test 4101 -ne `wc -c <'freeze.h'`; then
  977.     echo shar: \"'freeze.h'\" unpacked with wrong size!
  978.   fi
  979.   # end of 'freeze.h'
  980. fi
  981. if test -f 'huf.c' -a "${1}" != "-c" ; then 
  982.   echo shar: Will not clobber existing file \"'huf.c'\"
  983. else
  984.   echo shar: Extracting \"'huf.c'\" \(7717 characters\)
  985.   sed "s/^X//" >'huf.c' <<'END_OF_FILE'
  986. X#include "freeze.h"
  987. X#include "huf.h"
  988. X#include "bitio.h"
  989. X
  990. X/*----------------------------------------------------------------------*/
  991. X/*                                    */
  992. X/*        HUFFMAN ENCODING                    */
  993. X/*                                    */
  994. X/*----------------------------------------------------------------------*/
  995. X
  996. X/* TABLES OF ENCODE/DECODE for upper 6 bits position information */
  997. X
  998. X/* The contents of `Table' are used for freezing only, so we use
  999. X * it freely when melting.
  1000. X */
  1001. X
  1002. X#ifndef HUFVALUES
  1003. X#define HUFVALUES 0,0,1,2,6,19,34,0
  1004. X#endif
  1005. X
  1006. Xuc_t Table2[9] = { 0, HUFVALUES };
  1007. X
  1008. Xuc_t p_len[64];        /* These arrays are built accordingly to values */
  1009. Xuc_t d_len[256];       /* of `Table' above which are default, from the */
  1010. X              /* command line or from the header of frozen file */
  1011. X
  1012. Xuc_t code[256];
  1013. X
  1014. Xus_t freq[T2 + 1];           /* frequency table */
  1015. Xshort   son[T2];                /* points to son node (son[i],son[i+1]) */
  1016. Xshort   prnt[T2 + N_CHAR2];     /* points to parent node */
  1017. X
  1018. Xstatic  short t, r, chars;
  1019. X
  1020. X/* notes :
  1021. X   prnt[Tx .. Tx + N_CHARx - 1] used by
  1022. X   indicates leaf position that corresponding to code.
  1023. X*/
  1024. X
  1025. X/* Initializes Huffman tree, bit I/O variables, etc.
  1026. X   Static array is initialized with `table', dynamic Huffman tree
  1027. X   has `n_char' leaves.
  1028. X*/
  1029. X
  1030. Xvoid StartHuff (n_char)
  1031. X    int n_char;
  1032. X{
  1033. X    register short i, j;
  1034. X    t = n_char * 2 - 1;
  1035. X    r = t - 1;
  1036. X    chars = n_char;
  1037. X
  1038. X/* A priori frequences are 1 */
  1039. X
  1040. X    for (i = 0; i < n_char; i++) {
  1041. X        freq[i] = 1;
  1042. X        son[i] = i + t;
  1043. X        prnt[i + t] = i;
  1044. X    }
  1045. X    i = 0; j = n_char;
  1046. X
  1047. X/* Building the balanced tree */
  1048. X
  1049. X    while (j <= r) {
  1050. X        freq[j] = freq[i] + freq[i + 1];
  1051. X        son[j] = i;
  1052. X        prnt[i] = prnt[i + 1] = j;
  1053. X        i += 2; j++;
  1054. X    }
  1055. X    freq[t] = 0xffff;
  1056. X    prnt[r] = 0;
  1057. X    in_count = 1;
  1058. X    bytes_out = 5;
  1059. X#if defined(DEBUG) || defined (GATHER_STAT)
  1060. X    symbols_out = refers_out = 0;
  1061. X#endif
  1062. X}
  1063. X
  1064. X/* Reconstructs tree with `chars' leaves */
  1065. X
  1066. Xvoid reconst ()
  1067. X{
  1068. X    register int i, j, k;
  1069. X    register int f;
  1070. X
  1071. X#ifdef DEBUG
  1072. X    if (quiet < 0)
  1073. X      fprintf(stderr,
  1074. X        "Reconstructing Huffman tree: symbols: %ld, references: %ld\n",
  1075. X        symbols_out, refers_out);
  1076. X#endif
  1077. X
  1078. X/* correct leaf node into of first half,
  1079. X   and set these freqency to (freq+1)/2
  1080. X*/
  1081. X    j = 0;
  1082. X    for (i = 0; i < t; i++) {
  1083. X        if (son[i] >= t) {
  1084. X            freq[j] = (freq[i] + 1) / 2;
  1085. X            son[j] = son[i];
  1086. X            j++;
  1087. X        }
  1088. X    }
  1089. X/* Build tree.  Link sons first */
  1090. X
  1091. X    for (i = 0, j = chars; j < t; i += 2, j++) {
  1092. X        k = i + 1;
  1093. X        f = freq[j] = freq[i] + freq[k];
  1094. X        for (k = j - 1; f < freq[k]; k--);
  1095. X        k++;
  1096. X        {       register us_t *p, *e;
  1097. X            for (p = &freq[j], e = &freq[k]; p > e; p--)
  1098. X                p[0] = p[-1];
  1099. X            freq[k] = f;
  1100. X        }
  1101. X        {       register short *p, *e;
  1102. X            for (p = &son[j], e = &son[k]; p > e; p--)
  1103. X                p[0] = p[-1];
  1104. X            son[k] = i;
  1105. X        }
  1106. X    }
  1107. X
  1108. X/* Link parents */
  1109. X    for (i = 0; i < t; i++) {
  1110. X        if ((k = son[i]) >= t) {
  1111. X            prnt[k] = i;
  1112. X        } else {
  1113. X            prnt[k] = prnt[k + 1] = i;
  1114. X        }
  1115. X    }
  1116. X}
  1117. X
  1118. X
  1119. X/* Updates given code's frequency, and updates tree */
  1120. X
  1121. Xvoid update (c)
  1122. X    register int c;
  1123. X{
  1124. X    register us_t *p;
  1125. X    register int i, j, k, l;
  1126. X
  1127. X    if (freq[r] == MAX_FREQ) {
  1128. X        reconst();
  1129. X    }
  1130. X    c = prnt[c + t];
  1131. X    do {
  1132. X        k = ++freq[c];
  1133. X
  1134. X        /* swap nodes when become wrong frequency order. */
  1135. X        if (k > freq[l = c + 1]) {
  1136. X            for (p = freq+l+1; k > *p++; ) ;
  1137. X            l = p - freq - 2;
  1138. X            freq[c] = p[-2];
  1139. X            p[-2] = k;
  1140. X
  1141. X            i = son[c];
  1142. X            prnt[i] = l;
  1143. X            if (i < t) prnt[i + 1] = l;
  1144. X
  1145. X            j = son[l];
  1146. X            son[l] = i;
  1147. X
  1148. X            prnt[j] = c;
  1149. X            if (j < t) prnt[j + 1] = c;
  1150. X            son[c] = j;
  1151. X
  1152. X            c = l;
  1153. X        }
  1154. X    } while ((c = prnt[c]) != 0);    /* loop until reach to root */
  1155. X}
  1156. X
  1157. X/* Encodes the literal or the length information */
  1158. X
  1159. Xvoid EncodeChar (c)
  1160. X    int c;
  1161. X{
  1162. X    ul_t i;
  1163. X    register int j, k;
  1164. X
  1165. X    i = 0;
  1166. X    j = 0;
  1167. X    k = prnt[c + t];
  1168. X
  1169. X/* trace links from leaf node to root */
  1170. X
  1171. X    do {
  1172. X        i >>= 1;
  1173. X
  1174. X/* if node index is odd, trace larger of sons */
  1175. X        if (k & 1) i += 0x80000000;
  1176. X
  1177. X        j++;
  1178. X    } while ((k = prnt[k]) != r) ;
  1179. X
  1180. X/* `j' never reaches the value of 32 ! */
  1181. X
  1182. X    if (j > 16) {
  1183. X        Putcode(16, (us_t)(i >> 16));
  1184. X        Putcode(j - 16, (us_t)i);
  1185. X    } else {
  1186. X        Putcode(j, (us_t)(i >> 16));
  1187. X    }
  1188. X    update(c);
  1189. X}
  1190. X
  1191. X/* Encodes the position information */
  1192. X
  1193. Xvoid EncodePosition (c)
  1194. X    register int c;
  1195. X{
  1196. X    register us_t i;
  1197. X
  1198. X    /* output upper 6 bit from table */
  1199. X    i = c >> 7;
  1200. X    Putcode((int)p_len[i], (us_t)(code[i]) << 8);
  1201. X
  1202. X    /* output lower 7 bit */
  1203. X    Putcode(7, (us_t)(c & 0x7f) << 9);
  1204. X}
  1205. X
  1206. X
  1207. X/* Decodes the literal or length info and returns its value.
  1208. X    Returns ENDOF, if the file is corrupt.
  1209. X*/
  1210. X
  1211. Xshort DecodeChar ()
  1212. X{
  1213. X    register int c;
  1214. X    c = son[r];
  1215. X
  1216. X    /* trace from root to leaf,
  1217. X       got bit is 0 to small(son[]), 1 to large (son[]+1) son node */
  1218. X
  1219. X    while (c < t) {
  1220. X        c += GetBit();
  1221. X        c = son[c];
  1222. X    }
  1223. X    c -= t;
  1224. X    update(c);
  1225. X    if (crpt_flag) {
  1226. X        crpt_message();
  1227. X        return ENDOF;
  1228. X    }
  1229. X    crpt_flag = feof(stdin);
  1230. X    return c;
  1231. X}
  1232. X
  1233. X/* Decodes the position info and returns it */
  1234. X
  1235. Xshort DecodePosition ()
  1236. X{
  1237. X    register us_t i, j, c;
  1238. X
  1239. X    /* decode upper 6 bits from the table */
  1240. X
  1241. X    i = GetByte();
  1242. X    crpt_flag = feof(stdin);
  1243. X
  1244. X    c = (us_t)code[i] << 7;
  1245. X    j = d_len[i] - 1;
  1246. X
  1247. X    /* get lower 7 bits literally */
  1248. X
  1249. X    return c | (((i << j) | GetNBits (j)) & 0x7f);
  1250. X}
  1251. X
  1252. X
  1253. X/* Initializes static Huffman arrays */
  1254. X
  1255. Xvoid init(table) uc_t * table; {
  1256. X    short i, j, k, num;
  1257. X    num = 0;
  1258. X
  1259. X/* There are `table[i]' `i'-bits Huffman codes */
  1260. X
  1261. X    for(i = 1, j = 0; i <= 8; i++) {
  1262. X        num += table[i] << (8 - i);
  1263. X        for(k = table[i]; k; j++, k--)
  1264. X            p_len[j] = i;
  1265. X    }
  1266. X    if (num != 256) {
  1267. X        fprintf(stderr, "Invalid position table\n");
  1268. X        exit(1);
  1269. X    }
  1270. X    num = j;
  1271. X    if (do_melt == 0)
  1272. X
  1273. X/* Freezing: building the table for encoding */
  1274. X
  1275. X        for(i = j = 0;;) {
  1276. X            code[j] = i << (8 - p_len[j]);
  1277. X            i++;
  1278. X            j++;
  1279. X            if (j == num) break;
  1280. X            i <<= p_len[j] - p_len[j-1];
  1281. X        }
  1282. X    else {
  1283. X
  1284. X/* Melting: building the table for decoding */
  1285. X
  1286. X        for(k = j = 0; j < num; j ++)
  1287. X            for(i = 1 << (8 - p_len[j]); i--;)
  1288. X                code[k++] = j;
  1289. X
  1290. X        for(k = j = 0; j < num; j ++)
  1291. X            for(i = 1 << (8 - p_len[j]); i--;)
  1292. X                d_len[k++] =  p_len[j];
  1293. X    }
  1294. X}
  1295. X
  1296. X/* Writes a 3-byte header into the frozen form of file; Table[7] and
  1297. X    Table[8] aren't necessary, see `read_header'.
  1298. X*/
  1299. X
  1300. Xvoid write_header() {
  1301. X    us_t i;
  1302. X
  1303. X    i = Table2[5] & 0x1F; i <<= 4;
  1304. X    i |= Table2[4] & 0xF; i <<= 3;
  1305. X    i |= Table2[3] & 7;   i <<= 2;
  1306. X    i |= Table2[2] & 3;   i <<= 1;
  1307. X    i |= Table2[1] & 1;
  1308. X
  1309. X    putchar((int)(i & 0xFF));
  1310. X    putchar((int)((i >> 8)));
  1311. X    putchar((int)(Table2[6] & 0x3F));
  1312. X    if (ferror(stdout))
  1313. X        writeerr();
  1314. X}
  1315. X
  1316. X/* Reconstructs `Table' from the header of the frozen file and checks
  1317. X    its correctness. Returns 0 if OK, EOF otherwise.
  1318. X*/
  1319. X
  1320. Xint read_header() {
  1321. X    short i, j;
  1322. X    i = getchar() & 0xFF;
  1323. X    i |= (getchar() & 0xFF) << 8;
  1324. X    Table2[1] = i & 1; i >>= 1;
  1325. X    Table2[2] = i & 3; i >>= 2;
  1326. X    Table2[3] = i & 7; i >>= 3;
  1327. X    Table2[4] = i & 0xF; i >>= 4;
  1328. X    Table2[5] = i & 0x1F; i >>= 5;
  1329. X
  1330. X    if (i & 1 || (i = getchar()) & 0xC0) {
  1331. X        fprintf(stderr, "Unknown header format.\n");
  1332. X        crpt_message();
  1333. X        return EOF;
  1334. X    }
  1335. X
  1336. X    Table2[6] = i & 0x3F;
  1337. X
  1338. X    i = Table2[1] + Table2[2] + Table2[3] + Table2[4] +
  1339. X    Table2[5] + Table2[6];
  1340. X
  1341. X    i = 62 - i;     /* free variable length codes for 7 & 8 bits */
  1342. X
  1343. X    j = 128 * Table2[1] + 64 * Table2[2] + 32 * Table2[3] +
  1344. X    16 * Table2[4] + 8 * Table2[5] + 4 * Table2[6];
  1345. X
  1346. X    j = 256 - j;    /* free byte images for these codes */
  1347. X
  1348. X/*      Equation:
  1349. X        Table[7] + Table[8] = i
  1350. X    2 * Table[7] + Table[8] = j
  1351. X*/
  1352. X    j -= i;
  1353. X    if (j < 0 || i < j) {
  1354. X        crpt_message();
  1355. X        return EOF;
  1356. X    }
  1357. X    Table2[7] = j;
  1358. X    Table2[8] = i - j;
  1359. X
  1360. X#ifdef DEBUG
  1361. X    fprintf(stderr, "Codes: %d %d %d %d %d %d %d %d\n",
  1362. X        Table2[1], Table2[2], Table2[3], Table2[4],
  1363. X        Table2[5], Table2[6], Table2[7], Table2[8]);
  1364. X#endif
  1365. X    return 0;
  1366. X}
  1367. X
  1368. X#ifdef COMPAT
  1369. X
  1370. Xuc_t Table1[9] = { 0, 0, 0, 1, 3, 8, 12, 24, 16 };
  1371. X
  1372. X/* Old version of a routine above for handling files made by
  1373. X    the 1st version of Freeze.
  1374. X*/
  1375. X
  1376. Xshort DecodePOld ()
  1377. X{
  1378. X    register us_t i, j, c;
  1379. X
  1380. X    i = GetByte();
  1381. X    crpt_flag = feof(stdin);
  1382. X
  1383. X    c = (us_t)code[i] << 6;
  1384. X    j = d_len[i] - 2;
  1385. X
  1386. X    return c | (((i << j) | GetNBits (j)) & 0x3f);
  1387. X}
  1388. X#endif
  1389. END_OF_FILE
  1390.   if test 7717 -ne `wc -c <'huf.c'`; then
  1391.     echo shar: \"'huf.c'\" unpacked with wrong size!
  1392.   fi
  1393.   # end of 'huf.c'
  1394. fi
  1395. if test -f 'lz.c' -a "${1}" != "-c" ; then 
  1396.   echo shar: Will not clobber existing file \"'lz.c'\"
  1397. else
  1398.   echo shar: Extracting \"'lz.c'\" \(3906 characters\)
  1399.   sed "s/^X//" >'lz.c' <<'END_OF_FILE'
  1400. X#include "freeze.h"
  1401. X#include "lz.h"
  1402. X
  1403. X/*----------------------------------------------------------------------*/
  1404. X/*                                                                      */
  1405. X/*                          LZSS ENCODING                               */
  1406. X/*                                                                      */
  1407. X/*----------------------------------------------------------------------*/
  1408. X
  1409. Xuc_t    text_buf[WINSIZE + LOOKAHEAD - 1];/* cyclic buffer with an overlay */
  1410. Xint     match_position;                 /* current position of
  1411. X                        matched pattern */
  1412. Xint     chain_length;                   /* max_chain_length ==
  1413. X                        CHAIN_THRESHOLD >> greedy */
  1414. X
  1415. X/*      next[N+1..] is used as hash table,
  1416. X    the rest of next is a link down,
  1417. X*/
  1418. X
  1419. Xhash_t hashtab[array_size];        /* a VERY large array :-) */
  1420. Xhash_t next[WINSIZE];
  1421. X
  1422. X#ifdef GATHER_STAT
  1423. Xlong node_matches, node_compares, node_prolongations;
  1424. X#endif  /* GATHER_STAT */
  1425. X
  1426. X/* Initialize the data structures and allocate memory, if needed.
  1427. X    Although there is no more trees in the LZ algorithm
  1428. X    implementation, routine name is kept intact :-)
  1429. X*/
  1430. X
  1431. Xvoid InitTree ()
  1432. X{
  1433. X
  1434. X#if BITS == 16
  1435. X    ul_t    i;
  1436. X#else
  1437. X    unsigned i;
  1438. X#endif
  1439. X
  1440. X#ifdef GATHER_STAT
  1441. X    node_matches = node_compares = node_prolongations = 0;
  1442. X#endif  /* GATHER_STAT */
  1443. X
  1444. X    for (i = 0; i < array_size; i++ )
  1445. X        hashtab[i] = 0;
  1446. X
  1447. X    if (greedy >= 0)
  1448. X        chain_length = ((CHAIN_THRESHOLD - 1) >> greedy) + 1;
  1449. X    else
  1450. X        chain_length = ((CHAIN_THRESHOLD - 1) << -greedy) + 1;
  1451. X}
  1452. X
  1453. X/* Get the longest (longer than `match_length' when entering in function)
  1454. X    nearest match of the string beginning in text_buf[r]
  1455. X    to the cyclic buffer. Result (length & position) is returned
  1456. X    as the result and in global variable
  1457. X    `match_position'). Unchanged `match_length' denotes failure and
  1458. X    `match_position' contains garbage !!
  1459. X    In order to achieve faster operation, `match_length' is shifted
  1460. X    down to LOOKAHEAD. Ideas of Andrew Cadach <kadach@isi.itfs.nsk.su>
  1461. X    have been used (lastbyte).
  1462. X*/
  1463. X
  1464. Xint get_next_match (match_length, r)
  1465. X    register hash_t r; int match_length;
  1466. X{
  1467. X    register int p = r & WINMASK;
  1468. X    register int m;
  1469. X#ifdef ALLOW_MISALIGN
  1470. X    register us_t lastbyte;
  1471. X#else
  1472. X    register uc_t lastbyte;
  1473. X#endif
  1474. X    register uc_t  *key FIX_SI, *pattern FIX_DI;
  1475. X    int     chain_count = chain_length;
  1476. X
  1477. X#ifdef GATHER_STAT
  1478. X    node_matches++;
  1479. X#endif
  1480. X    key = text_buf + (r & WINMASK) + LOOKAHEAD;
  1481. X    r -= MAXDIST;           /* `r' is now a "barrier value" */
  1482. X
  1483. X    for(;;) {
  1484. X        lastbyte = FETCH(key, match_length);
  1485. X        do {
  1486. X            if(chain_count <= 0)
  1487. X                /* chain length exceeded, simple return */
  1488. X                return match_length;
  1489. X
  1490. X            pattern = text_buf + match_length + LOOKAHEAD;
  1491. X
  1492. X            do {
  1493. X                if ((p = next[p]) < r)
  1494. X                    return match_length;
  1495. X            } while (FETCH(pattern, p &= WINMASK) != lastbyte);
  1496. X
  1497. X            chain_count--;  /* successful lastbyte match, cost = 1 */
  1498. X            pattern = text_buf + p + LOOKAHEAD;
  1499. X
  1500. X#ifdef GATHER_STAT
  1501. X        node_compares++;
  1502. X#endif
  1503. X
  1504. X#ifdef ALLOW_MISALIGN
  1505. X            for (m = -LOOKAHEAD;
  1506. X            *(unsigned*)&key[m] == *(unsigned*)&pattern[m] &&
  1507. X                (m += sizeof(unsigned)) < 0;);
  1508. X#ifndef INT_16_BITS
  1509. X            if (m < 0 && *(us_t*)&key[m] == *(us_t*)&pattern[m])
  1510. X                m += sizeof(us_t);
  1511. X#endif
  1512. X            if (m < 0 && key[m] == pattern[m])
  1513. X                ++m;
  1514. X#else
  1515. X            for (m = -LOOKAHEAD; key[m] == pattern[m] && ++m < 0;);
  1516. X#endif
  1517. X        } while (m < match_length);
  1518. X
  1519. X        match_position = p;     /* remember new results */
  1520. X        if (m == 0)
  1521. X            return 0;
  1522. X        match_length = m;
  1523. X
  1524. X#ifdef GATHER_STAT
  1525. X        node_prolongations++;
  1526. X#endif
  1527. X        chain_count -= 2;       /* yet another match found, cost = 2 */
  1528. X    }
  1529. X}
  1530. X
  1531. Xhash_t
  1532. Xrehash(r)
  1533. Xhash_t r;
  1534. X{
  1535. X#if BITS == 16
  1536. X  ul_t     i;
  1537. X#else
  1538. X  unsigned i;
  1539. X#endif
  1540. X  r += WINSIZE;
  1541. X  for (i = 0; i < WINSIZE; i++)
  1542. X    /* zero must remain zero */
  1543. X    if (next[i] && (next[i] += WINSIZE) > r) {
  1544. X        next[i] = 0;
  1545. X    }
  1546. X  for (i = 0; i < array_size; i++)
  1547. X    /* zero must remain zero */
  1548. X    if (hashtab[i] && (hashtab[i] += WINSIZE) > r) {
  1549. X        hashtab[i] = 0;
  1550. X    }
  1551. X  return r;
  1552. X}
  1553. END_OF_FILE
  1554.   if test 3906 -ne `wc -c <'lz.c'`; then
  1555.     echo shar: \"'lz.c'\" unpacked with wrong size!
  1556.   fi
  1557.   # end of 'lz.c'
  1558. fi
  1559. if test -f 'lz.h' -a "${1}" != "-c" ; then 
  1560.   echo shar: Will not clobber existing file \"'lz.h'\"
  1561. else
  1562.   echo shar: Extracting \"'lz.h'\" \(2916 characters\)
  1563.   sed "s/^X//" >'lz.h' <<'END_OF_FILE'
  1564. Xextern void InitTree();
  1565. X
  1566. X#ifndef SEGMENTED
  1567. X# define MAXBITS 16
  1568. X#else
  1569. X# ifdef INT_16_BITS
  1570. X#  define MAXBITS 15
  1571. X# else
  1572. X#  define MAXBITS 14
  1573. X# endif
  1574. X#endif
  1575. X
  1576. X#ifdef SEGMENTED
  1577. X# ifdef TINY
  1578. X#  undef MAXBITS
  1579. X#  define MAXBITS 13
  1580. X# endif
  1581. X#endif
  1582. X
  1583. X#ifndef BITS
  1584. X# define BITS    MAXBITS
  1585. X#endif
  1586. X
  1587. X#if BITS < 13
  1588. X# undef BITS
  1589. X# define BITS    13      /* 1:1 hash */
  1590. X#endif
  1591. X
  1592. X#if BITS > 16
  1593. X# undef BITS
  1594. X# define BITS    16
  1595. X#endif
  1596. X
  1597. X/* The following hash-function isn't optimal but it is very fast:
  1598. X
  1599. X    HASH =      ((first + (second << LEN0) +
  1600. X            (third << LEN1)) & ((1L << BITS) - 1);
  1601. X
  1602. X  The difference of LENs is no more than one bit.
  1603. X*/
  1604. X
  1605. X#define LEN0    ((BITS-8)/2)
  1606. X#define LEN1    (BITS-8)
  1607. X
  1608. X/* `array_size' is the size of array `next', which contains
  1609. X    the heads of linked lists and the references to
  1610. X    next members of these lists.
  1611. X*/
  1612. X
  1613. X#define array_size      (1L << BITS)
  1614. X
  1615. X/* If native size of integer is 16 bits, don't use longs */
  1616. X
  1617. X#if defined(INT_16_BITS) || defined(SMALL) || defined(TINY)
  1618. Xtypedef us_t hash_t;
  1619. X#else
  1620. Xtypedef ul_t hash_t;
  1621. X#endif  /* INT_16_BITS */
  1622. X
  1623. Xextern int       match_position, chain_length;
  1624. X
  1625. Xextern hash_t hashtab[], next[];
  1626. X
  1627. X/* Some defines to eliminate function-call overhead */
  1628. X
  1629. X/* Hash function (no more than 16 bits, so we don't need longs */
  1630. X
  1631. X#define hash(p)\
  1632. X    ((unsigned)(p)[0] + ((unsigned)(p)[1] << LEN0) +\
  1633. X    ((unsigned)(p)[2] << LEN1))
  1634. X
  1635. X#ifdef FASTHASH
  1636. X#define hashof(p)\
  1637. X    (((p)[0] != (p)[1] ? hash(p) : hash(p) + hash((p) + 3)) &\
  1638. X    ((1L << BITS) - 1))
  1639. X#else
  1640. X#define hashof(p)\
  1641. X    (hash(p) & ((1L << BITS) - 1))
  1642. X#endif
  1643. X
  1644. X/* Inserting of a node `r' into hashed linked list: `r' becomes
  1645. X    the head of list.
  1646. X*/
  1647. X
  1648. X#define InsertNode()\
  1649. X{\
  1650. X    register uc_t  *key = &text_buf[r & WINMASK];\
  1651. X    register unsigned p = hashof(key);\
  1652. X    if (r < MAXDIST) /* wraparound occured */\
  1653. X        r = rehash(r);\
  1654. X    next[r & WINMASK] = hashtab[p];\
  1655. X    hashtab[p] = r;\
  1656. X}
  1657. X
  1658. X/* This routine inputs the char from stdin and does some other
  1659. X    actions depending of this char's presence.
  1660. X*/
  1661. X
  1662. X#define Next_Char(N,F)\
  1663. X{\
  1664. X    if ((c = getchar()) != EOF) {\
  1665. X        text_buf[s] = c;\
  1666. X        if (s < F - 1)\
  1667. X            text_buf[s + N] = c;\
  1668. X        s = (s + 1) & (N - 1);\
  1669. X        in_count++;\
  1670. X    } else\
  1671. X        len--;\
  1672. X    r++;\
  1673. X    InsertNode();\
  1674. X}
  1675. X
  1676. X#if defined(__GNUC__)
  1677. X#if defined(__i386__)
  1678. X/* Optimizer cannot allocate these registers correctly :( (v1.39) */
  1679. X#define FIX_SI  asm("si")
  1680. X#define FIX_DI  asm("di")
  1681. X#else
  1682. X
  1683. X/* GNU-style register allocations for other processors are welcome! */
  1684. X
  1685. X#define FIX_SI
  1686. X#define FIX_DI
  1687. X#endif
  1688. X#else
  1689. X
  1690. X/* Dummy defines for non-GNU compilers */
  1691. X
  1692. X#define FIX_SI
  1693. X#define FIX_DI
  1694. X#endif
  1695. X
  1696. X/* some heuristic to avoid necessity of "-ggg..." */
  1697. X#define CHAIN_THRESHOLD (LOOKAHEAD >> (BITS - 12))
  1698. X
  1699. Xextern int get_next_match();
  1700. Xextern hash_t rehash();
  1701. X
  1702. X#ifdef GATHER_STAT
  1703. Xextern long node_matches, node_compares, node_prolongations;
  1704. X#endif
  1705. X
  1706. X#ifdef ALLOW_MISALIGN
  1707. X#define FETCH(array,index) *(us_t*)(&array[index]-1)
  1708. X#else
  1709. X#define FETCH(array,index) array[index]
  1710. X#endif
  1711. END_OF_FILE
  1712.   if test 2916 -ne `wc -c <'lz.h'`; then
  1713.     echo shar: \"'lz.h'\" unpacked with wrong size!
  1714.   fi
  1715.   # end of 'lz.h'
  1716. fi
  1717. if test -f 'statist.1' -a "${1}" != "-c" ; then 
  1718.   echo shar: Will not clobber existing file \"'statist.1'\"
  1719. else
  1720.   echo shar: Extracting \"'statist.1'\" \(3300 characters\)
  1721.   sed "s/^X//" >'statist.1' <<'END_OF_FILE'
  1722. X.PU
  1723. X.TH STATIST 1 local
  1724. X.SH NAME
  1725. Xstatist  \-  calculate Huffman distribution for
  1726. X.IR freeze "(1)"
  1727. X.SH SYNOPSIS
  1728. X.ll +8
  1729. X.B statist
  1730. X[
  1731. X.B \-gx...
  1732. X]
  1733. X.ll -8
  1734. X.br
  1735. X.SH DESCRIPTION
  1736. XThe default table is tuned for both C texts and executable files (as in
  1737. XLHARC). If you will freeze any other files (natural language texts,
  1738. Xdatabases, images, fonts, etc.) you can calculate the matching
  1739. Xpositions distribution using the
  1740. X.B "`statist'"
  1741. Xprogram, which calculates and displays the mentioned
  1742. Xdistribution for the given file. It is useful for large (100K or more)
  1743. Xfiles.
  1744. X
  1745. XThough the built-in position table is polyvalent, the tuning can increase
  1746. Xthe compression rate up to one additional percent. (Observed mainly on
  1747. Xtext files.)
  1748. X.SH USAGE
  1749. X.br
  1750. X.B statist [\-g...] < sample_file
  1751. X.in +8
  1752. Xor
  1753. X.in -8
  1754. X.B gensample | statist [\-g...]
  1755. X.br
  1756. Xwhere
  1757. X.B "`gensample'"
  1758. Xis a program generating some sample stream of
  1759. Xbytes similar to files to be frozen.
  1760. X.PP
  1761. XThe
  1762. X.B \-g
  1763. Xand
  1764. X.B \-x
  1765. Xswitches have the same meaning as for
  1766. X.IR freeze "(1)"
  1767. Xand may be repeated.
  1768. X.PP
  1769. XYou can also see the intermediate values
  1770. Xand watch their changes by pressing INTR key when you wish.
  1771. X.PP
  1772. XNote: If you use 
  1773. X.B "gensample | statist"
  1774. X, remember that INTR influence BOTH
  1775. Xprocesses !!
  1776. X.br
  1777. XThe results have the following format:
  1778. X.br
  1779. X.I "n1 n2 n3 n4 n5 n6 n7 n8"
  1780. X(uncertainty =
  1781. X.I x)
  1782. X.br
  1783. XAverage match length:
  1784. X.I xx.yy
  1785. X.br
  1786. XPercentile 99.9:
  1787. X.I p999
  1788. X.br
  1789. XPercentile 99.5:
  1790. X.I p995
  1791. X.br
  1792. XPercentile 99.0:
  1793. X.I p990
  1794. X.br
  1795. XPercentile 97.0:
  1796. X.I p970
  1797. X.br
  1798. XPercentile 95.0:
  1799. X.I p950
  1800. X.br
  1801. XPercentile 90.0:
  1802. X.I p900
  1803. X.br
  1804. XPercentile 80.0:
  1805. X.I p800
  1806. X.br
  1807. XPercentile 70.0:
  1808. X.I p700
  1809. X.br
  1810. XPercentile 50.0:
  1811. X.I p500
  1812. X.br
  1813. XSigma:
  1814. X.I xx.yy
  1815. X.br
  1816. X.PP
  1817. XHere
  1818. X.I n1 \- n8
  1819. Xare values of the calculated position table elements,
  1820. Xuncertainty is a number which denotes validity of given results
  1821. X(non-zero values of uncertainty indicate that the
  1822. Xresults may be unusable). Other values (average match length,
  1823. Xpercentiles and sigma) are FYI only.
  1824. X.PP
  1825. XYou may create the 
  1826. X.IR /etc/default/freeze
  1827. Xfile (if you don't like
  1828. X.IR /etc/default/
  1829. Xdirectory, choose another - in MS-DOS it is FREEZE.CNF in
  1830. Xthe directory of FREEZE.EXE), which has the following format:
  1831. X.in +8
  1832. X.I name
  1833. X=
  1834. X.I "n1 n2 n3 n4 n5 n6 n7 n8"
  1835. X.in -8
  1836. X.I (name
  1837. Xmust start in column 1). For example:
  1838. X.ll +8
  1839. X.br
  1840. X---------- cut here -----------
  1841. X.br
  1842. X# This is freeze's defaults file
  1843. X.br
  1844. Xrussian=0 0 1 2 6 20 31 2   # The sample was mailx.lp (Russian)
  1845. X.br
  1846. Xenglish=0 0 1 2 7 16 36 0   # The sample was gcc.lp (English)
  1847. X.br
  1848. X# End of file
  1849. X.br
  1850. X---------- cut here -----------
  1851. X.ll -8
  1852. X.PP
  1853. XIf you find values, which are better THAN DEFAULT both for text (C
  1854. Xprograms) and binary (executable) files, please send them to me.
  1855. X
  1856. XImportant note: statist.c is NOT a part of freeze package, it is an
  1857. Xaditional feature.
  1858. X
  1859. X.SH "SEE ALSO"
  1860. Xfreeze(1), melt(1), fcat(1)
  1861. X.SH "DIAGNOSTICS"
  1862. XHuffman tree has more than 8 levels, reducing...
  1863. X.in +8
  1864. XSelf-explanatory, but sometimes reducing falls into infinite loop.
  1865. X.in -8
  1866. X.IR xxx K
  1867. X.in +8
  1868. XProgress indicator is written after each 4K of a file processed.
  1869. X.in -8
  1870. X.SH "BUGS"
  1871. XSometimes use of the results with uncertainty = 1 (on a file)
  1872. Xgives compression rate worse than default but use of the results
  1873. Xwith uncertainty = 13 (on other file) works quite good.
  1874. X.PP
  1875. XFound bugs descriptions, incompatibilities, etc.  please send to
  1876. Xleo@s514.ipmce.su.
  1877. X
  1878. END_OF_FILE
  1879.   if test 3300 -ne `wc -c <'statist.1'`; then
  1880.     echo shar: \"'statist.1'\" unpacked with wrong size!
  1881.   fi
  1882.   # end of 'statist.1'
  1883. fi
  1884. if test -f 'statist.c' -a "${1}" != "-c" ; then 
  1885.   echo shar: Will not clobber existing file \"'statist.c'\"
  1886. else
  1887.   echo shar: Extracting \"'statist.c'\" \(6376 characters\)
  1888.   sed "s/^X//" >'statist.c' <<'END_OF_FILE'
  1889. X#include "freeze.h"
  1890. X#include "lz.h"
  1891. X
  1892. X/* This program calculates the distribution of the matched strings'
  1893. Xpositions and lengths using nearly the same code as `freeze'.
  1894. X*/
  1895. X
  1896. X#define N_POS 62
  1897. X#define T (N_POS * 2 - 1)
  1898. X#define R (T - 1)
  1899. X
  1900. X#define update(c) (/* fprintf(stderr, "%d\n", c), */ freq[c]++)
  1901. X
  1902. Xlong in_count, refers = 0;
  1903. X
  1904. Xlong indc_count;
  1905. Xshort reduceflag = 0, greedy = 0;
  1906. X
  1907. Xint lens[LOOKAHEAD+1];
  1908. X
  1909. Xus_t bits[9];
  1910. X
  1911. Xshort   prnt[T];
  1912. Xul_t freq[T];
  1913. Xshort used[T];
  1914. X
  1915. Xvoid freeze(), StartHuff();
  1916. X
  1917. XRETSIGTYPE giveres();
  1918. X
  1919. Xint main(argc, argv) char ** argv; {
  1920. X    argv++;
  1921. X    while (argc > 1) {
  1922. X        if (**argv == '-') {
  1923. X            while (*++(*argv) == 'g' || **argv == 'x')
  1924. X                greedy += ((**argv == 'g') << 1) - 1;
  1925. X            if (**argv)
  1926. X                goto usage;
  1927. X            argc--; argv++;
  1928. X        } else
  1929. X            break;
  1930. X    }
  1931. X    usage:
  1932. X    if(argc != 1) {
  1933. X        fprintf(stderr, "Usage: statist [-gx...] < sample_file\n");
  1934. X        fprintf(stderr, "Press INTR to display current values\n");
  1935. X        exit(0);
  1936. X    }
  1937. X    signal(SIGINT, giveres);
  1938. X
  1939. X#ifdef DOS
  1940. X    setmode(fileno(stdin), O_BINARY);       /* Oh this MS-DOS ... */
  1941. X#endif  /* DOS */
  1942. X
  1943. X    freeze();
  1944. X    giveres();
  1945. X    return 0;
  1946. X}
  1947. X
  1948. Xul_t isqrt(val)
  1949. Xul_t val;
  1950. X{
  1951. X  ul_t result = 0;
  1952. X  ul_t side = 0;
  1953. X  ul_t left = 0;
  1954. X  int digit = 0;
  1955. X  int i;
  1956. X  for (i=0; i<sizeof(ul_t)*4; i++)
  1957. X  {
  1958. X    left = (left << 2) + (val >> (sizeof(ul_t) * 8 - 2));
  1959. X    val <<= 2;
  1960. X    if (left >= side*2 + 1)
  1961. X    {
  1962. X      left -= side*2+1;
  1963. X      side = (side+1)*2;
  1964. X      result <<= 1;
  1965. X      result |= 1;
  1966. X    }
  1967. X    else
  1968. X    {
  1969. X      side *= 2;
  1970. X      result <<= 1;
  1971. X    }
  1972. X  }
  1973. X  return result;
  1974. X}
  1975. X
  1976. X
  1977. X/* Prints the (current) values of tunable parameters. Uncertainty is
  1978. Xthe number of missequencings (algorithm assumes the probabilities
  1979. Xof references decrease uniformly when distance increases). Ideally
  1980. Xit should be 0, but somewhat about 5 or less denotes the given 8 values
  1981. Xcould improve the compression rate when using them.
  1982. X*/
  1983. X
  1984. XRETSIGTYPE giveres() {
  1985. X    us_t c;
  1986. X    register int i, j, k, pr, f, average, sum;
  1987. X    ul_t cumul, sigma2;
  1988. X    short r, percent;
  1989. X    signal(SIGINT, giveres);
  1990. X    newtry:
  1991. X    StartHuff(N_POS);
  1992. X    pr = f = 0;
  1993. X    i = N_POS;
  1994. X    r = N_POS * 2 - 2;
  1995. X    while (i <= r) {
  1996. X        j = findmin(i);
  1997. X        k = findmin(i);
  1998. X        freq[i] = freq[j] + freq[k];
  1999. X        prnt[j] = prnt[k] = i++;
  2000. X    }
  2001. X
  2002. X    for (c = 1; c <= 6; c++) bits[c] = 0;
  2003. X
  2004. X    printf("Non-monotonities are in: ");
  2005. X
  2006. X    for(c = 0; c < N_POS; c++) {
  2007. X        j = 0;
  2008. X        k = c;
  2009. X        do j++; while ((k = prnt[k]) != r);
  2010. X        if (j <= 6)
  2011. X            bits[j]++;
  2012. X        if (j < pr) {
  2013. X            f += pr - j;
  2014. X            printf("%d, ", c);
  2015. X
  2016. X        } else
  2017. X            pr = j;
  2018. X    }
  2019. X    if(f == 0)
  2020. X        printf("\b\b\b\babsent.\n");
  2021. X    else
  2022. X        printf("\b\b.\n");
  2023. X
  2024. X    k = bits[1] + bits[2] + bits[3] + bits[4] +
  2025. X    bits[5] + bits[6];
  2026. X
  2027. X    k = N_POS - k;  /* free variable length codes for 7 & 8 bits */
  2028. X
  2029. X    j = 128 * bits[1] + 64 * bits[2] + 32 * bits[3] +
  2030. X    16 * bits[4] + 8 * bits[5] + 4 * bits[6];
  2031. X
  2032. X    j = 256 - j;    /* free byte images for these codes */
  2033. X
  2034. X/*      Equation:
  2035. X        bits[7] + bits[8] = k
  2036. X    2 * bits[7] + bits[8] = j
  2037. X*/
  2038. X    j -= k;
  2039. X    if (j < 0 || k < j) {
  2040. X        printf("Huffman tree has more than 8 levels, reducing...\n");
  2041. X        for (i = 0; i < N_POS; i++)
  2042. X            if (!freq[i])
  2043. X                freq[i] = 1;
  2044. X            else if (reduceflag)
  2045. X                freq[i] = (freq[i] + 1) / 2;
  2046. X        reduceflag = 1;
  2047. X        goto newtry;
  2048. X    } else {
  2049. X        bits[7] = j;
  2050. X        bits[8] = k - j;
  2051. X        printf("%d,%d,%d,%d,%d,%d,%d,%d (uncertainty = %d)\n",
  2052. X            bits[1], bits[2], bits[3], bits[4],
  2053. X            bits[5], bits[6], bits[7], bits[8], f);
  2054. X    }
  2055. X    sum = 0; cumul = 0;
  2056. X    for(i = 3; i <= LOOKAHEAD; i++) {
  2057. X        cumul += (ul_t) i * lens[i];
  2058. X        sum += lens[i];
  2059. X    }
  2060. X    sum || sum++;
  2061. X    printf("Average match length: %d.%02d\n",
  2062. X        average = cumul / sum, i = cumul * 100 / sum % 100);
  2063. X    if (i >= 50) average++;
  2064. X    j = sum;
  2065. X    percent = 0;
  2066. X    for (i = LOOKAHEAD; i >= 3; i--) {
  2067. X        static pcs[] = { 999, 995, 990, 970, 950, 900, 800, 700, 500 };
  2068. X        j -= lens[i];
  2069. X        newpcs:
  2070. X        if (j <= sum * pcs[percent] / 1000) {
  2071. X            printf("Percentile %d.%d: %d\n",
  2072. X                pcs[percent] / 10, pcs[percent] % 10, i);
  2073. X            if (percent == sizeof(pcs)/sizeof(int) - 1)
  2074. X                break;
  2075. X            else {
  2076. X                percent++;
  2077. X                goto newpcs;
  2078. X            }
  2079. X        }
  2080. X    }
  2081. X    for (sigma2 = 0, i = 3; i <= LOOKAHEAD; i++)
  2082. X        sigma2 += (ul_t)(i - average)*(i - average)*lens[i];
  2083. X    sigma2 = sigma2 * 100 / sum;
  2084. X    j = (int)isqrt(sigma2);
  2085. X    printf("Sigma: %d.%1d\n", j / 10, j % 10);
  2086. X    printf("References: %ld\n", refers);
  2087. X    fflush(stdout);
  2088. X}
  2089. X
  2090. X
  2091. Xvoid freeze ()
  2092. X{
  2093. X    register int i, len, s, c;
  2094. X    register hash_t r;
  2095. X    int match_length;
  2096. X
  2097. X    StartHuff(0);
  2098. X    InitTree();
  2099. X    r = MAXDIST + 1;
  2100. X    s = (r + LOOKAHEAD) & WINMASK;
  2101. X    for (len = 0; len < LOOKAHEAD && (c = getchar()) != EOF; len++)
  2102. X      text_buf[r + len] = c;
  2103. X
  2104. X    in_count = len;
  2105. X    for (i = r - LOOKAHEAD; i < MAXDIST; i++)
  2106. X      text_buf[i] = ' ';
  2107. X    for (i = r - LOOKAHEAD; i <= r; i++) {
  2108. X        register uc_t  *key = &text_buf[i];
  2109. X        register unsigned p = hashof(key);
  2110. X        next[i] = hashtab[p];
  2111. X        hashtab[p] = i;
  2112. X    }
  2113. X    while (len != 0) {
  2114. X        match_length = LOOKAHEAD + get_next_match(THRESHOLD - LOOKAHEAD, r);
  2115. X        if (match_length > len)
  2116. X            match_length = len;
  2117. X        if (match_length <= THRESHOLD) {
  2118. X            match_length = 1;
  2119. X        } else if (match_length >= chain_length) {
  2120. X            lens[match_length] ++;
  2121. X            update((((r - match_position) & WINMASK) - 1) >> 7);
  2122. X            refers ++;
  2123. X        } else {
  2124. X            register us_t orig_length, orig_position;
  2125. X            orig_length = match_length;
  2126. X            orig_position = match_position;
  2127. X            Next_Char(WINSIZE, LOOKAHEAD);
  2128. X            match_length = LOOKAHEAD + get_next_match(match_length - LOOKAHEAD, r);
  2129. X            if (match_length > len)
  2130. X                match_length = len;
  2131. X            if (orig_length >= match_length) {
  2132. X                lens[orig_length] ++;
  2133. X                update((((r - 1 - orig_position) & WINMASK) - 1) >> 7);
  2134. X                match_length = orig_length - 1;
  2135. X            } else  {
  2136. X                lens[match_length] ++;
  2137. X                update((((r - match_position) & WINMASK) - 1) >> 7);
  2138. X            }
  2139. X            refers ++;
  2140. X        }
  2141. X        for (i = 0; i < match_length &&
  2142. X                (c = getchar()) != EOF; i++) {
  2143. X            text_buf[s] = c;
  2144. X            if (s < LOOKAHEAD - 1)
  2145. X                text_buf[s + WINSIZE] = c;
  2146. X            s = (s + 1) & WINMASK;
  2147. X            r++;
  2148. X            InsertNode();
  2149. X        }
  2150. X        in_count += i;
  2151. X        if ((in_count > indc_count)) {
  2152. X            fprintf(stderr, "%5dK\b\b\b\b\b\b", in_count / 1024);
  2153. X            fflush (stderr);
  2154. X            indc_count += 4096;
  2155. X        }
  2156. X        while (i++ < match_length) {
  2157. X            len--;
  2158. X            r++;
  2159. X            InsertNode();
  2160. X        }
  2161. X    }
  2162. X}
  2163. X
  2164. Xvoid StartHuff(beg) {
  2165. X    int i;
  2166. X    for (i = beg; i < N_POS * 2 - 1; i++)
  2167. X        freq[i] = 0;
  2168. X    for (i = 0; i < N_POS * 2 - 1; i++)
  2169. X        used[i] = prnt[i] = 0;
  2170. X}
  2171. X
  2172. Xint findmin(range) {
  2173. X    long min = (1 << 30) - 1, argmin = -1, i;
  2174. X    for (i = 0; i < range; i++) {
  2175. X        if(!used[i] && freq[i] < min)
  2176. X            min = freq[argmin = i];
  2177. X    }
  2178. X    used[argmin] = 1;
  2179. X    return argmin;
  2180. X}
  2181. END_OF_FILE
  2182.   if test 6376 -ne `wc -c <'statist.c'`; then
  2183.     echo shar: \"'statist.c'\" unpacked with wrong size!
  2184.   fi
  2185.   # end of 'statist.c'
  2186. fi
  2187. echo shar: End of archive 2 \(of 3\).
  2188. cp /dev/null ark2isdone
  2189. MISSING=""
  2190. for I in 1 2 3 ; do
  2191.     if test ! -f ark${I}isdone ; then
  2192.     MISSING="${MISSING} ${I}"
  2193.     fi
  2194. done
  2195. if test "${MISSING}" = "" ; then
  2196.     echo You have unpacked all 3 archives.
  2197.     rm -f ark[1-9]isdone
  2198. else
  2199.     echo You still must unpack the following archives:
  2200.     echo "        " ${MISSING}
  2201. fi
  2202. exit 0
  2203. exit 0 # Just in case...
  2204.