home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / pascal / LZRW.ZIP / LZRW3.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-19  |  39.7 KB  |  712 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /*                                    LZRW3.C                                 */
  4. /*                                                                            */
  5. /******************************************************************************/
  6. /*                                                                            */
  7. /* Author  : Ross Williams.                                                   */
  8. /* Date    : 30-Jun-1991.                                                     */
  9. /* Release : 1.                                                               */
  10. /*                                                                            */
  11. /******************************************************************************/
  12. /*                                                                            */
  13. /* This file contains an implementation of the LZRW3 data compression         */
  14. /* algorithm in C.                                                            */
  15. /*                                                                            */
  16. /* The algorithm is a general purpose compression algorithm that runs fast    */
  17. /* and gives reasonable compression. The algorithm is a member of the Lempel  */
  18. /* Ziv family of algorithms and bases its compression on the presence in the  */
  19. /* data of repeated substrings.                                               */
  20. /*                                                                            */
  21. /* This algorithm is unpatented and the code is public domain. As the         */
  22. /* algorithm is based on the LZ77 class of algorithms, it is unlikely to be   */
  23. /* the subject of a patent challenge.                                         */
  24. /*                                                                            */
  25. /* Unlike the LZRW1 and LZRW1-A algorithms, the LZRW3 algorithm is            */
  26. /* deterministic and is guaranteed to yield the same compressed               */
  27. /* representation for a given file each time it is run.                       */
  28. /*                                                                            */
  29. /* The LZRW3 algorithm was originally designed and implemented                */
  30. /* by Ross Williams on 31-Dec-1990.                                           */
  31. /*                                                                            */
  32. /* Here are the results of applying this code, compiled under THINK C 4.0     */
  33. /* and running on a Mac-SE (8MHz 68000), to the standard calgary corpus.      */
  34. /*                                                                            */
  35. /*    +----------------------------------------------------------------+      */
  36. /*    | DATA COMPRESSION TEST                                          |      */
  37. /*    | =====================                                          |      */
  38. /*    | Time of run     : Sun 30-Jun-1991 09:31PM                      |      */
  39. /*    | Timing accuracy : One part in 100                              |      */
  40. /*    | Context length  : 262144 bytes (= 256.0000K)                   |      */
  41. /*    | Test suite      : Calgary Corpus Suite                         |      */
  42. /*    | Files in suite  : 14                                           |      */
  43. /*    | Algorithm       : LZRW3                                        |      */
  44. /*    | Note: All averages are calculated from the un-rounded values.  |      */
  45. /*    +----------------------------------------------------------------+      */
  46. /*    | File Name   Length  CxB  ComLen  %Remn  Bits  Com K/s  Dec K/s |      */
  47. /*    | ----------  ------  ---  ------  -----  ----  -------  ------- |      */
  48. /*    | rpus:Bib.D  111261    1   55033   49.5  3.96    19.46    32.27 |      */
  49. /*    | us:Book1.D  768771    3  467962   60.9  4.87    17.03    31.07 |      */
  50. /*    | us:Book2.D  610856    3  317102   51.9  4.15    19.39    34.15 |      */
  51. /*    | rpus:Geo.D  102400    1   82424   80.5  6.44    11.65    18.18 |      */
  52. /*    | pus:News.D  377109    2  205670   54.5  4.36    17.14    27.47 |      */
  53. /*    | pus:Obj1.D   21504    1   13027   60.6  4.85    13.40    18.95 |      */
  54. /*    | pus:Obj2.D  246814    1  116286   47.1  3.77    19.31    30.10 |      */
  55. /*    | s:Paper1.D   53161    1   27522   51.8  4.14    18.60    31.15 |      */
  56. /*    | s:Paper2.D   82199    1   45160   54.9  4.40    18.45    32.84 |      */
  57. /*    | rpus:Pic.D  513216    2  122388   23.8  1.91    35.29    51.05 |      */
  58. /*    | us:Progc.D   39611    1   19669   49.7  3.97    18.87    30.64 |      */
  59. /*    | us:Progl.D   71646    1   28247   39.4  3.15    24.34    40.66 |      */
  60. /*    | us:Progp.D   49379    1   19377   39.2  3.14    23.91    39.23 |      */
  61. /*    | us:Trans.D   93695    1   33481   35.7  2.86    25.48    40.37 |      */
  62. /*    +----------------------------------------------------------------+      */
  63. /*    | Average     224401    1  110953   50.0  4.00    20.17    32.72 |      */
  64. /*    +----------------------------------------------------------------+      */
  65. /*                                                                            */
  66. /******************************************************************************/
  67.  
  68.                             /* INCLUDE FILES                                  */
  69.                             /* =============                                  */
  70. #include "port.h"           /* Defines symbols for the non portable stuff.    */
  71. #include "compress.h"       /* Defines single exported function "compress".   */
  72. #include "fast_copy.h"      /* Fast memory copy routine.                      */
  73.  
  74. /******************************************************************************/
  75.  
  76. /* The following structure is returned by the "compress" function below when  */
  77. /* the user asks the function to return identifying information.              */
  78. /* The most important field in the record is the working memory field which   */
  79. /* tells the calling program how much working memory should be passed to      */
  80. /* "compress" when it is called to perform a compression or decompression.    */
  81. /* LZRW3 uses the same amount of memory during compression and decompression. */
  82. /* For more information on this structure see "compress.h".                   */
  83.   
  84. #define U(X)            ((ULONG) X)
  85. #define SIZE_P_BYTE     (U(sizeof(UBYTE *)))
  86. #define SIZE_WORD       (U(sizeof(UWORD  )))
  87. #define ALIGNMENT_FUDGE (U(16))
  88. #define MEM_REQ ( U(4096)*(SIZE_P_BYTE) + ALIGNMENT_FUDGE )
  89.  
  90. static struct compress_identity identity =
  91. {
  92.  U(0x032DDEA8),                           /* Algorithm identification number. */
  93.  MEM_REQ,                                 /* Working memory (bytes) required. */
  94.  "LZRW3",                                 /* Name of algorithm.               */
  95.  "1.0",                                   /* Version number of algorithm.     */
  96.  "31-Dec-1990",                           /* Date of algorithm.               */
  97.  "Public Domain",                         /* Copyright notice.                */
  98.  "Ross N. Williams",                      /* Author of algorithm.             */
  99.  "Renaissance Software",                  /* Affiliation of author.           */
  100.  "Public Domain"                          /* Vendor of algorithm.             */
  101. };
  102.  
  103. void compress_compress  (UBYTE *,UBYTE *,ULONG,UBYTE *,ULONG *);
  104. void compress_decompress(UBYTE *,UBYTE *,ULONG,UBYTE *,ULONG *);
  105.  
  106. /******************************************************************************/
  107.  
  108. /* This function is the only function exported by this module.                */
  109. /* Depending on its first parameter, the function can be requested to         */
  110. /* compress a block of memory, decompress a block of memory, or to identify   */
  111. /* itself. For more information, see the specification file "compress.h".     */
  112.  
  113. EXPORT void compress(action,wrk_mem,src_adr,src_len,dst_adr,p_dst_len)
  114. UWORD     action;      /* Action to be performed.                             */
  115. UBYTE   *wrk_mem;      /* Address of working memory we can use.               */
  116. UBYTE   *src_adr;      /* Address of input data.                              */
  117. ULONG    src_len;      /* Length  of input data.                              */
  118. UBYTE   *dst_adr;      /* Address to put output data.                         */
  119. ULONG *p_dst_len;      /* Address of longword for length of output data.      */
  120. {
  121.  switch (action)
  122.    {
  123.     case COMPRESS_ACTION_IDENTITY:
  124.        *p_dst_len=(ULONG) &identity;
  125.        break;
  126.     case COMPRESS_ACTION_COMPRESS:
  127.        compress_compress(wrk_mem,src_adr,src_len,dst_adr,p_dst_len);
  128.        break;
  129.     case COMPRESS_ACTION_DECOMPRESS:
  130.        compress_decompress(wrk_mem,src_adr,src_len,dst_adr,p_dst_len);
  131.        break;
  132.    }
  133. }
  134.  
  135. /******************************************************************************/
  136. /*                                                                            */
  137. /* BRIEF DESCRIPTION OF THE LZRW3 ALGORITHM                                   */
  138. /* ========================================                                   */
  139. /* The LZRW3 algorithm is identical to the LZRW1-A algorithm except that      */
  140. /* instead of transmitting history offsets, it transmits hash table indexes.  */
  141. /* In order to decode the indexes, the decompressor must maintain an          */
  142. /* identical hash table. Copy items are straightforward:when the decompressor */
  143. /* receives a copy item, it simply looks up the hash table to translate the   */
  144. /* index into a pointer into the data already decompressed. To update the     */
  145. /* hash table, it replaces the same table entry with a pointer to the start   */
  146. /* of the newly decoded phrase. The tricky part is with literal items, for at */
  147. /* the time that the decompressor receives a literal item the decompressor    */
  148. /* does not have the three bytes in the Ziv (that the compressor has) to      */
  149. /* perform the three-byte hash. To solve this problem, in LZRW3, both the     */
  150. /* compressor and decompressor are wired up so that they "buffer" these       */
  151. /* literals and update their hash tables only when three bytes are available. */
  152. /* This makes the maximum buffering 2 bytes.                                  */
  153. /*                                                                            */
  154. /* Replacement of offsets by hash table indexes yields a few percent extra    */
  155. /* compression at the cost of some speed. LZRW3 is slower than LZRW1, LZRW1-A */
  156. /* and LZRW2, but yields better compression.                                  */
  157. /*                                                                            */
  158. /* Extra compression could be obtained by using a hash table of depth two.    */
  159. /* However, increasing the depth above one incurs a significant decrease in   */
  160. /* compression speed which was not considered worthwhile. Another reason for  */
  161. /* keeping the depth down to one was to allow easy comparison with the        */
  162. /* LZRW1-A and LZRW2 algorithms so as to demonstrate the exact effect of the  */
  163. /* use of direct hash indexes.                                                */
  164. /*                                                                            */
  165. /*                                  +---+                                     */
  166. /*                                  |___|4095                                 */
  167. /*                                  |___|                                     */
  168. /*              +---------------------*_|<---+   /----+---\                   */
  169. /*              |                   |___|    +---|Hash    |                   */
  170. /*              |                   |___|        |Function|                   */
  171. /*              |                   |___|        \--------/                   */
  172. /*              |                   |___|0            ^                       */
  173. /*              |                   +---+             |                       */
  174. /*              |                   Hash        +-----+                       */
  175. /*              |                   Table       |                             */
  176. /*              |                              ---                            */
  177. /*              v                              ^^^                            */
  178. /*      +-------------------------------------|----------------+              */
  179. /*      ||||||||||||||||||||||||||||||||||||||||||||||||||||||||              */
  180. /*      +-------------------------------------|----------------+              */
  181. /*      |                                     |1......18|      |              */
  182. /*      |<------- Lempel=History ------------>|<--Ziv-->|      |              */
  183. /*      |     (=bytes already processed)      |<-Still to go-->|              */
  184. /*      |<-------------------- INPUT BLOCK ------------------->|              */
  185. /*                                                                            */
  186. /* The diagram above for LZRW3 looks almost identical to the diagram for      */
  187. /* LZRW1. The difference is that in LZRW3, the compressor transmits hash      */
  188. /* table indices instead of Lempel offsets. For this to work, the             */
  189. /* decompressor must maintain a hash table as well as the compressor and both */
  190. /* compressor and decompressor must "buffer" literals, as the decompressor    */
  191. /* cannot hash phrases commencing with a literal until another two bytes have */
  192. /* arrived.                                                                   */
  193. /*                                                                            */
  194. /*  LZRW3 Algorithm Execution Summary                                         */
  195. /*  ---------------------------------                                         */
  196. /*  1. Hash the first three bytes of the Ziv to yield a hash table index h.   */
  197. /*  2. Look up the hash table yielding history pointer p.                     */
  198. /*  3. Match where p points with the Ziv. If there is a match of three or     */
  199. /*     more bytes, code those bytes (in the Ziv) as a copy item, otherwise    */
  200. /*     code the next byte in the Ziv as a literal item.                       */
  201. /*  4. Update the hash table as possible subject to the constraint that only  */
  202. /*     phrases commencing three bytes back from the Ziv can be hashed and     */
  203. /*     entered into the hash table. (This enables the decompressor to keep    */
  204. /*     pace). See the description and code for more details.                  */
  205. /*                                                                            */
  206. /******************************************************************************/
  207. /*                                                                            */
  208. /*                     DEFINITION OF COMPRESSED FILE FORMAT                   */
  209. /*                     ====================================                   */
  210. /*  * A compressed file consists of a COPY FLAG followed by a REMAINDER.      */
  211. /*  * The copy flag CF uses up four bytes with the first byte being the       */
  212. /*    least significant.                                                      */
  213. /*  * If CF=1, then the compressed file represents the remainder of the file  */
  214. /*    exactly. Otherwise CF=0 and the remainder of the file consists of zero  */
  215. /*    or more GROUPS, each of which represents one or more bytes.             */
  216. /*  * Each group consists of two bytes of CONTROL information followed by     */
  217. /*    sixteen ITEMs except for the last group which can contain from one      */
  218. /*    to sixteen items.                                                       */
  219. /*  * An item can be either a LITERAL item or a COPY item.                    */
  220. /*  * Each item corresponds to a bit in the control bytes.                    */
  221. /*  * The first control byte corresponds to the first 8 items in the group    */
  222. /*    with bit 0 corresponding to the first item in the group and bit 7 to    */
  223. /*    the eighth item in the group.                                           */
  224. /*  * The second control byte corresponds to the second 8 items in the group  */
  225. /*    with bit 0 corresponding to the ninth item in the group and bit 7 to    */
  226. /*    the sixteenth item in the group.                                        */
  227. /*  * A zero bit in a control word means that the corresponding item is a     */
  228. /*    literal item. A one bit corresponds to a copy item.                     */
  229. /*  * A literal item consists of a single byte which represents itself.       */
  230. /*  * A copy item consists of two bytes that represent from 3 to 18 bytes.    */
  231. /*  * The first  byte in a copy item will be denoted C1.                      */
  232. /*  * The second byte in a copy item will be denoted C2.                      */
  233. /*  * Bits will be selected using square brackets.                            */
  234. /*    For example: C1[0..3] is the low nibble of the first control byte.      */
  235. /*    of copy item C1.                                                        */
  236. /*  * The LENGTH of a copy item is defined to be C1[0..3]+3 which is a number */
  237. /*    in the range [3,18].                                                    */
  238. /*  * The INDEX of a copy item is defined to be C1[4..7]*256+C2[0..8] which   */
  239. /*    is a number in the range [0,4095].                                      */
  240. /*  * A copy item represents the sequence of bytes                            */
  241. /*       text[POS-OFFSET..POS-OFFSET+LENGTH-1] where                          */
  242. /*          text   is the entire text of the uncompressed string.             */
  243. /*          POS    is the index in the text of the character following the    */
  244. /*                   string represented by all the items preceeding the item  */
  245. /*                   being defined.                                           */
  246. /*          OFFSET is obtained from INDEX by looking up the hash table.       */
  247. /*                                                                            */
  248. /******************************************************************************/
  249.  
  250. /* The following #define defines the length of the copy flag that appears at  */
  251. /* the start of the compressed file. The value of four bytes was chosen       */
  252. /* because the fast_copy routine on my Macintosh runs faster if the source    */
  253. /* and destination blocks are relatively longword aligned.                    */
  254. /* The actual flag data appears in the first byte. The rest are zeroed so as  */
  255. /* to normalize the compressed representation (i.e. not non-deterministic).   */
  256. #define FLAG_BYTES 4
  257.  
  258. /* The following #defines define the meaning of the values of the copy        */
  259. /* flag at the start of the compressed file.                                  */
  260. #define FLAG_COMPRESS 0     /* Signals that output was result of compression. */
  261. #define FLAG_COPY     1     /* Signals that output was simply copied over.    */
  262.  
  263. /* The 68000 microprocessor (on which this algorithm was originally developed */
  264. /* is fussy about non-aligned arrays of words. To avoid these problems the    */
  265. /* following macro can be used to "waste" from 0 to 3 bytes so as to align    */
  266. /* the argument pointer.                                                      */
  267. #define ULONG_ALIGN_UP(X) ((((ULONG)X)+3)&~3)
  268.  
  269. /* The following constant defines the maximum length of an uncompressed item. */
  270. /* This definition must not be changed; its value is hardwired into the code. */
  271. /* The longest number of bytes that can be spanned by a single item is 18     */
  272. /* for the longest copy item.                                                 */
  273. #define MAX_RAW_ITEM (18)
  274.  
  275. /* The following constant defines the maximum length of an uncompressed group.*/
  276. /* This definition must not be changed; its value is hardwired into the code. */
  277. /* A group contains at most 16 items which explains this definition.          */
  278. #define MAX_RAW_GROUP (16*MAX_RAW_ITEM)
  279.  
  280. /* The following constant defines the maximum length of a compressed group.   */
  281. /* This definition must not be changed; its value is hardwired into the code. */
  282. /* A compressed group consists of two control bytes followed by up to 16      */
  283. /* compressed items each of which can have a maximum length of two bytes.     */
  284. #define MAX_CMP_GROUP (2+16*2)
  285.  
  286. /* The following constant defines the number of entries in the hash table.    */
  287. /* This definition must not be changed; its value is hardwired into the code. */
  288. #define HASH_TABLE_LENGTH (4096)
  289.  
  290. /* LZRW3, unlike LZRW1(-A), must initialize its hash table so as to enable    */
  291. /* the compressor and decompressor to stay in step maintaining identical hash */
  292. /* tables. In an early version of the algorithm, the tables were simply       */
  293. /* initialized to zero and a check for zero was included just before the      */
  294. /* matching code. However, this test costs time. A better solution is to      */
  295. /* initialize all the entries in the hash table to point to a constant        */
  296. /* string. The decompressor does the same. This solution requires no extra    */
  297. /* test. The contents of the string do not matter so long as the string is    */
  298. /* the same for the compressor and decompressor and contains at least         */
  299. /* MAX_RAW_ITEM bytes. I chose consecutive decimal digits because they do not */
  300. /* have white space problems (e.g. there is no chance that the compiler will  */
  301. /* replace more than one space by a TAB) and because they make the length of  */
  302. /* the string obvious by inspection.                                          */
  303. #define START_STRING_18 ((UBYTE *) "123456789012345678")
  304.  
  305. /* In this algorithm, hash values have to be calculated at more than one      */
  306. /* point. The following macro neatens the code up for this.                   */
  307. #define HASH(PTR) \
  308.    (((40543*(((*(PTR))<<8)^((*((PTR)+1))<<4)^(*((PTR)+2))))>>4) & 0xFFF)
  309.  
  310. /******************************************************************************/
  311.                             
  312. LOCAL void compress_compress
  313.            (p_wrk_mem,p_src_first,src_len,p_dst_first,p_dst_len)
  314. /* Input  : Hand over the required amount of working memory in p_wrk_mem.     */
  315. /* Input  : Specify input block using p_src_first and src_len.                */
  316. /* Input  : Point p_dst_first to the start of the output zone (OZ).           */
  317. /* Input  : Point p_dst_len to a ULONG to receive the output length.          */
  318. /* Input  : Input block and output zone must not overlap.                     */
  319. /* Output : Length of output block written to *p_dst_len.                     */
  320. /* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. May   */
  321. /* Output : write in OZ=Mem[p_dst_first..p_dst_first+src_len+MAX_CMP_GROUP-1].*/
  322. /* Output : Upon completion guaranteed *p_dst_len<=src_len+FLAG_BYTES.        */
  323. UBYTE *p_wrk_mem;
  324. UBYTE *p_src_first;
  325. ULONG  src_len;
  326. UBYTE *p_dst_first;
  327. ULONG *p_dst_len;
  328. {
  329.  /* p_src and p_dst step through the source and destination blocks.           */
  330.  register UBYTE *p_src = p_src_first;
  331.  register UBYTE *p_dst = p_dst_first;
  332.  
  333.  /* The following variables are never modified and are used in the            */
  334.  /* calculations that determine when the main loop terminates.                */
  335.  UBYTE *p_src_post  = p_src_first+src_len;
  336.  UBYTE *p_dst_post  = p_dst_first+src_len;
  337.  UBYTE *p_src_max1  = p_src_first+src_len-MAX_RAW_ITEM;
  338.  UBYTE *p_src_max16 = p_src_first+src_len-MAX_RAW_ITEM*16;
  339.  
  340.  /* The variables 'p_control' and 'control' are used to buffer control bits.  */
  341.  /* Before each group is processed, the next two bytes of the output block    */
  342.  /* are set aside for the control word for the group about to be processed.   */
  343.  /* 'p_control' is set to point to the first byte of that word. Meanwhile,    */
  344.  /* 'control' buffers the control bits being generated during the processing  */
  345.  /* of the group. Instead of having a counter to keep track of how many items */
  346.  /* have been processed (=the number of bits in the control word), at the     */
  347.  /* start of each group, the top word of 'control' is filled with 1 bits.     */
  348.  /* As 'control' is shifted for each item, the 1 bits in the top word are     */
  349.  /* absorbed or destroyed. When they all run out (i.e. when the top word is   */
  350.  /* all zero bits, we know that we are at the end of a group.                 */
  351.  #define TOPWORD 0xFFFF0000
  352.  UBYTE *p_control;
  353.  register ULONG control=TOPWORD;
  354.  
  355.  /* THe variable 'hash' always points to the first element of the hash table. */
  356.  UBYTE **hash= (UBYTE **)  ULONG_ALIGN_UP(p_wrk_mem);
  357.  
  358.  /* The following two variables represent the literal buffer. p_h1 points to  */
  359.  /* the hash table entry corresponding to the youngest literal. p_h2 points   */
  360.  /* to the hash table entry corresponding to the second youngest literal.     */
  361.  /* Note: p_h1=0=>p_h2=0 because zero values denote absence of a pending      */
  362.  /* literal. The variables are initialized to zero meaning an empty "buffer". */
  363.  UBYTE **p_h1=0;
  364.  UBYTE **p_h2=0;
  365.   
  366.  /* To start, we write the flag bytes. Being optimistic, we set the flag to   */
  367.  /* FLAG_COMPRESS. The remaining flag bytes are zeroed so as to keep the      */
  368.  /* algorithm deterministic.                                                  */
  369.  *p_dst++=FLAG_COMPRESS;
  370.  {UWORD i; for (i=2;i<=FLAG_BYTES;i++) *p_dst++=0;}
  371.  
  372.  /* Reserve the first word of output as the control word for the first group. */
  373.  /* Note: This is undone at the end if the input block is empty.              */
  374.  p_control=p_dst; p_dst+=2;
  375.  
  376.  /* Initialize all elements of the hash table to point to a constant string.  */
  377.  /* Use of an unrolled loop speeds this up considerably.                      */
  378.  {UWORD i; UBYTE **p_h=hash;
  379.   #define ZH *p_h++=START_STRING_18
  380.   for (i=0;i<256;i++)     /* 256=HASH_TABLE_LENGTH/16. */
  381.     {ZH;ZH;ZH;ZH;
  382.      ZH;ZH;ZH;ZH;
  383.      ZH;ZH;ZH;ZH;
  384.      ZH;ZH;ZH;ZH;}
  385.  }
  386.  
  387.  /* The main loop processes either 1 or 16 items per iteration. As its        */
  388.  /* termination logic is complicated, I have opted for an infinite loop       */
  389.  /* structure containing 'break' and 'goto' statements.                       */
  390.  while (TRUE)
  391.    {/* Begin main processing loop. */
  392.    
  393.     /* Note: All the variables here except unroll should be defined within    */
  394.     /*       the inner loop. Unfortunately the loop hasn't got a block.       */
  395.      register UBYTE *p;         /* Scans through targ phrase during matching. */
  396.      register UBYTE *p_ziv;     /* Points to first byte of current Ziv.       */
  397.      register UWORD unroll;     /* Loop counter for unrolled inner loop.      */
  398.      register UWORD index;      /* Index of current hash table entry.         */
  399.      register UBYTE **p_h0;     /* Pointer to current hash table entry.       */
  400.      
  401.     /* Test for overrun and jump to overrun code if necessary.                */
  402.     if (p_dst>p_dst_post)
  403.        goto overrun;
  404.        
  405.     /* The following cascade of if statements efficiently catches and deals   */
  406.     /* with varying degrees of closeness to the end of the input block.       */
  407.     /* When we get very close to the end, we stop updating the table and      */
  408.     /* code the remaining bytes as literals. This makes the code simpler.     */
  409.     unroll=16;
  410.     if (p_src>p_src_max16)
  411.       {
  412.        unroll=1;
  413.        if (p_src>p_src_max1)
  414.          {
  415.           if (p_src==p_src_post)
  416.              break;
  417.           else
  418.              goto literal;
  419.          }
  420.       }
  421.          
  422.     /* This inner unrolled loop processes 'unroll' (whose value is either 1   */
  423.     /* or 16) items. I have chosen to implement this loop with labels and     */
  424.     /* gotos to heighten the ease with which the loop may be implemented with */
  425.     /* a single decrement and branch instruction in assembly language and     */
  426.     /* also because the labels act as highly readable place markers.          */
  427.     /* (Also because we jump into the loop for endgame literals (see above)). */
  428.     
  429.     begin_unrolled_loop:
  430.     
  431.        /* To process the next phrase, we hash the next three bytes and use    */
  432.        /* the resultant hash table index to look up the hash table. A pointer */
  433.        /* to the entry is stored in p_h0 so as to avoid an array lookup. The  */
  434.        /* hash table entry *p_h0 is looked up yielding a pointer p to a       */
  435.        /* potential match of the Ziv in the history.                          */
  436.        index=HASH(p_src);
  437.        p_h0=&hash[index];
  438.        p=*p_h0;
  439.        
  440.        /* Having looked up the candidate position, we are in a position to    */
  441.        /* attempt a match. The match loop has been unrolled using the PS      */
  442.        /* macro so that failure within the first three bytes automatically    */
  443.        /* results in the literal branch being taken. The coding is simple.    */
  444.        /* p_ziv saves p_src so we can let p_src wander.                       */
  445.        #define PS *p++!=*p_src++
  446.        p_ziv=p_src;
  447.        if (PS || PS || PS)
  448.          {
  449.           /* Literal. */
  450.           
  451.           /* Code the literal byte as itself and a zero control bit.          */
  452.           p_src=p_ziv; literal: *p_dst++=*p_src++; control&=0xFFFEFFFF;
  453.           
  454.           /* We have just coded a literal. If we had two pending ones, that   */
  455.           /* makes three and we can update the hash table.                    */
  456.           if (p_h2!=0)
  457.              {*p_h2=p_ziv-2;}
  458.              
  459.           /* In any case, rotate the hash table pointers for next time. */
  460.           p_h2=p_h1; p_h1=p_h0;
  461.           
  462.          }
  463.        else
  464.          {
  465.           /* Copy */
  466.           
  467.           /* Match up to 15 remaining bytes using an unrolled loop and code. */
  468.           PS || PS || PS || PS || PS || PS || PS || PS ||
  469.           PS || PS || PS || PS || PS || PS || PS || p_src++;
  470.           *p_dst++=((index&0xF00)>>4)|(--p_src-p_ziv-3);
  471.           *p_dst++=index&0xFF;
  472.           
  473.           /* As we have just coded three bytes, we are now in a position to   */
  474.           /* update the hash table with the literal bytes that were pending   */
  475.           /* upon the arrival of extra context bytes.                         */
  476.           if (p_h1!=0)
  477.             {
  478.              if (p_h2!=0)
  479.                {*p_h2=p_ziv-2; p_h2=0;}
  480.              *p_h1=p_ziv-1; p_h1=0;
  481.             }
  482.             
  483.           /* In any case, we can update the hash table based on the current   */
  484.           /* position as we just coded at least three bytes in a copy items.  */
  485.           *p_h0=p_ziv;
  486.           
  487.          }
  488.        control>>=1;
  489.                 
  490.        /* This loop is all set up for a decrement and jump instruction! */
  491.     end_unrolled_loop: if (--unroll) goto begin_unrolled_loop;
  492.  
  493.     /* At this point it will nearly always be the end of a group in which     */
  494.     /* case, we have to do some control-word processing. However, near the    */
  495.     /* end of the input block, the inner unrolled loop is only executed once. */
  496.     /* This necessitates the 'if' test.                                       */
  497.     if ((control&TOPWORD)==0)
  498.       {
  499.        /* Write the control word to the place we saved for it in the output. */
  500.        *p_control++=  control     &0xFF;
  501.        *p_control  = (control>>8) &0xFF;
  502.  
  503.        /* Reserve the next word in the output block for the control word */
  504.        /* for the group about to be processed.                           */
  505.        p_control=p_dst; p_dst+=2;
  506.        
  507.        /* Reset the control bits buffer. */
  508.        control=TOPWORD;
  509.       }
  510.           
  511.    } /* End main processing loop. */
  512.    
  513.  /* After the main processing loop has executed, all the input bytes have     */
  514.  /* been processed. However, the control word has still to be written to the  */
  515.  /* word reserved for it in the output at the start of the most recent group. */
  516.  /* Before writing, the control word has to be shifted so that all the bits   */
  517.  /* are in the right place. The "empty" bit positions are filled with 1s      */
  518.  /* which partially fill the top word.                                        */
  519.  while(control&TOPWORD) control>>=1;
  520.  *p_control++= control     &0xFF;
  521.  *p_control++=(control>>8) &0xFF;
  522.  
  523.  /* If the last group contained no items, delete the control word too.        */
  524.  if (p_control==p_dst) p_dst-=2;
  525.  
  526.  /* Write the length of the output block to the dst_len parameter and return. */
  527.  *p_dst_len=p_dst-p_dst_first;                           
  528.  return;
  529.  
  530.  /* Jump here as soon as an overrun is detected. An overrun is defined to     */
  531.  /* have occurred if p_dst>p_dst_first+src_len. That is, the moment the       */
  532.  /* length of the output written so far exceeds the length of the input block.*/
  533.  /* The algorithm checks for overruns at least at the end of each group       */
  534.  /* which means that the maximum overrun is MAX_CMP_GROUP bytes.              */
  535.  /* Once an overrun occurs, the only thing to do is to set the copy flag and  */
  536.  /* copy the input over.                                                      */
  537.  overrun:
  538.  *p_dst_first=FLAG_COPY;
  539.  fast_copy(p_src_first,p_dst_first+FLAG_BYTES,src_len);
  540.  *p_dst_len=src_len+FLAG_BYTES;
  541. }
  542.  
  543. /******************************************************************************/
  544.  
  545. LOCAL void compress_decompress
  546.            (p_wrk_mem,p_src_first,src_len,p_dst_first,p_dst_len)
  547. /* Input  : Hand over the required amount of working memory in p_wrk_mem.     */
  548. /* Input  : Specify input block using p_src_first and src_len.                */
  549. /* Input  : Point p_dst_first to the start of the output zone.                */
  550. /* Input  : Point p_dst_len to a ULONG to receive the output length.          */
  551. /* Input  : Input block and output zone must not overlap. User knows          */
  552. /* Input  : upperbound on output block length from earlier compression.       */
  553. /* Input  : In any case, maximum expansion possible is nine times.            */
  554. /* Output : Length of output block written to *p_dst_len.                     */
  555. /* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1].       */
  556. /* Output : Writes only  in Mem[p_dst_first..p_dst_first+*p_dst_len-1].       */
  557. UBYTE *p_wrk_mem;
  558. UBYTE *p_src_first;
  559. ULONG  src_len;
  560. UBYTE *p_dst_first;
  561. ULONG *p_dst_len;
  562. {
  563.  /* Byte pointers p_src and p_dst scan through the input and output blocks.   */
  564.  register UBYTE *p_src = p_src_first+FLAG_BYTES;
  565.  register UBYTE *p_dst = p_dst_first;
  566.  
  567.  /* The following two variables are never modified and are used to control    */
  568.  /* the main loop.                                                            */
  569.  UBYTE *p_src_post  = p_src_first+src_len;
  570.  UBYTE *p_src_max16 = p_src_first+src_len-(MAX_CMP_GROUP-2);
  571.  
  572.  /* The hash table is the only resident of the working memory. The hash table */
  573.  /* contains HASH_TABLE_LENGTH=4096 pointers to positions in the history. To  */
  574.  /* keep Macintoshes happy, it is longword aligned.                           */
  575.  UBYTE **hash = (UBYTE **) ULONG_ALIGN_UP(p_wrk_mem);
  576.  
  577.  /* The variable 'control' is used to buffer the control bits which appear in */
  578.  /* groups of 16 bits (control words) at the start of each compressed group.  */
  579.  /* When each group is read, bit 16 of the register is set to one. Whenever   */
  580.  /* a new bit is needed, the register is shifted right. When the value of the */
  581.  /* register becomes 1, we know that we have reached the end of a group.      */
  582.  /* Initializing the register to 1 thus instructs the code to follow that it  */
  583.  /* should read a new control word immediately.                               */
  584.  register ULONG control=1;
  585.  
  586.  /* The value of 'literals' is always in the range 0..3. It is the number of  */
  587.  /* consecutive literal items just seen. We have to record this number so as  */
  588.  /* to know when to update the hash table. When literals gets to 3, there     */
  589.  /* have been three consecutive literals and we can update at the position of */
  590.  /* the oldest of the three.                                                  */
  591.  register UWORD literals=0;
  592.  
  593.  /* Check the leading copy flag to see if the compressor chose to use a copy  */
  594.  /* operation instead of a compression operation. If a copy operation was     */
  595.  /* used, then all we need to do is copy the data over, set the output length */
  596.  /* and return.                                                               */
  597.  if (*p_src_first==FLAG_COPY)
  598.    {
  599.     fast_copy(p_src_first+FLAG_BYTES,p_dst_first,src_len-FLAG_BYTES);
  600.     *p_dst_len=src_len-FLAG_BYTES;
  601.     return;
  602.    }
  603.    
  604.  /* Initialize all elements of the hash table to point to a constant string.  */
  605.  /* Use of an unrolled loop speeds this up considerably.                      */
  606.  {UWORD i; UBYTE **p_h=hash;
  607.   #define ZJ *p_h++=START_STRING_18
  608.   for (i=0;i<256;i++)     /* 256=HASH_TABLE_LENGTH/16. */
  609.     {ZJ;ZJ;ZJ;ZJ;
  610.      ZJ;ZJ;ZJ;ZJ;
  611.      ZJ;ZJ;ZJ;ZJ;
  612.      ZJ;ZJ;ZJ;ZJ;}
  613.  }
  614.  
  615.  /* The outer loop processes either 1 or 16 items per iteration depending on  */
  616.  /* how close p_src is to the end of the input block.                         */
  617.  while (p_src!=p_src_post)
  618.    {/* Start of outer loop */
  619.    
  620.     register UWORD unroll;   /* Counts unrolled loop executions.              */
  621.     
  622.     /* When 'control' has the value 1, it means that the 16 buffered control  */
  623.     /* bits that were read in at the start of the current group have all been */
  624.     /* shifted out and that all that is left is the 1 bit that was injected   */
  625.     /* into bit 16 at the start of the current group. When we reach the end   */
  626.     /* of a group, we have to load a new control word and inject a new 1 bit. */
  627.     if (control==1)
  628.       {
  629.        control=0x10000|*p_src++;
  630.        control|=(*p_src++)<<8;
  631.       }
  632.  
  633.     /* If it is possible that we are within 16 groups from the end of the     */
  634.     /* input, execute the unrolled loop only once, else process a whole group */
  635.     /* of 16 items by looping 16 times.                                       */
  636.     unroll= p_src<=p_src_max16 ? 16 : 1;
  637.  
  638.     /* This inner loop processes one phrase (item) per iteration. */
  639.     while (unroll--)
  640.       { /* Begin unrolled inner loop. */
  641.       
  642.        /* Process a literal or copy item depending on the next control bit. */
  643.        if (control&1)
  644.          {
  645.           /* Copy item. */
  646.           
  647.           register UBYTE *p;           /* Points to place from which to copy. */
  648.           register UWORD lenmt;        /* Length of copy item minus three.    */
  649.           register UBYTE **p_hte;      /* Pointer to current hash table entry.*/
  650.           register UBYTE *p_ziv=p_dst; /* Pointer to start of current Ziv.    */
  651.           
  652.           /* Read and dismantle the copy word. Work out from where to copy.   */
  653.           lenmt=*p_src++;
  654.           p_hte=&hash[((lenmt&0xF0)<<4)|*p_src++];
  655.           p=*p_hte;
  656.           lenmt&=0xF;
  657.           
  658.           /* Now perform the copy using a half unrolled loop. */
  659.           *p_dst++=*p++;
  660.           *p_dst++=*p++;
  661.           *p_dst++=*p++;
  662.           while (lenmt--)
  663.              *p_dst++=*p++;
  664.                  
  665.           /* Because we have just received 3 or more bytes in a copy item     */
  666.           /* (whose bytes we have just installed in the output), we are now   */
  667.           /* in a position to flush all the pending literal hashings that had */
  668.           /* been postponed for lack of bytes.                                */
  669.           if (literals>0)
  670.             {
  671.              register UBYTE *r=p_ziv-literals;;
  672.              hash[HASH(r)]=r;
  673.              if (literals==2)
  674.                 {r++; hash[HASH(r)]=r;}
  675.              literals=0;
  676.             }
  677.             
  678.           /* In any case, we can immediately update the hash table with the   */
  679.           /* current position. We don't need to do a HASH(...) to work out    */
  680.           /* where to put the pointer, as the compressor just told us!!!      */
  681.           *p_hte=p_ziv;
  682.           
  683.          }
  684.        else
  685.          {
  686.           /* Literal item. */
  687.           
  688.           /* Copy over the literal byte. */
  689.           *p_dst++=*p_src++;
  690.           
  691.           /* If we now have three literals waiting to be hashed into the hash */
  692.           /* table, we can do one of them now (because there are three).      */
  693.           if (++literals == 3)
  694.              {register UBYTE *p=p_dst-3; hash[HASH(p)]=p; literals=2;}
  695.          }
  696.           
  697.        /* Shift the control buffer so the next control bit is in bit 0. */
  698.        control>>=1;
  699.        
  700.       } /* End unrolled inner loop. */
  701.                
  702.    } /* End of outer loop */
  703.    
  704.  /* Write the length of the decompressed data before returning. */
  705.  *p_dst_len=p_dst-p_dst_first;
  706. }
  707.  
  708. /******************************************************************************/
  709. /*                               End of LZRW3.C                               */
  710. /******************************************************************************/
  711.  
  712.