home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / c / 16561 < prev    next >
Encoding:
Text File  |  1992-11-15  |  3.9 KB  |  78 lines

  1. Newsgroups: comp.lang.c
  2. Path: sparky!uunet!utcsri!newsflash.concordia.ca!sifon!thunder.mcrcim.mcgill.edu!mouse
  3. From: mouse@thunder.mcrcim.mcgill.edu (der Mouse)
  4. Subject: Re: LZW Compression algorithm
  5. Message-ID: <1992Nov15.200257.20378@thunder.mcrcim.mcgill.edu>
  6. Organization: McGill Research Centre for Intelligent Machines
  7. References: <BxMAwz.D6C@willamette.edu>
  8. Date: Sun, 15 Nov 92 20:02:57 GMT
  9. Lines: 68
  10.  
  11. In article <BxMAwz.D6C@willamette.edu>, bbrown@willamette.edu (Brian Brown) writes:
  12.  
  13. > Does anybody have any information on how to implement LZW
  14. > compression/decompression?
  15.  
  16. It's fairly simple.  I will outline a 16-bit compress compressing a
  17. stream of 8-bit bytes.  This is for simplicity, so that I don't have to
  18. keep using roundabout language to describe sizes - it's fairly clear
  19. how to alter the sizes anyway.  I'll describe the essential core
  20. algorithm first, then some refinements.
  21.  
  22. You have a table of 65536 (2^16) entries.  Each table entry
  23. conceptually contains a string of bytes, or is empty.  Initially, 256
  24. of the entries contain the 256 possible single-byte strings, with the
  25. rest empty.  Initialize the algorithm by reading the first byte of
  26. input into a working variable which conceptually contains a string of
  27. bytes.
  28.  
  29. While the current working string of bytes is listed in the table, read
  30. another byte.  As soon as the string is not listed in the table, output
  31. the table index corresponding to the last string that was in the table,
  32. add the working string to the table, and reset the working string so it
  33. contains just the last byte.  Then go back to the beginning of this
  34. paragraph.  Dealing with EOF on input complicates this slightly, but
  35. only slightly.  Dealing with a full table is fairly easy: just skip the
  36. "add the working string to the table" step.
  37.  
  38. Now for the refinements I mentioned above.
  39.  
  40. Note that the decoder must keep a similar table, and must use the same
  41. algorithm for choosing unused slots that the encoder uses (so that
  42. table indices match).  One of the simplest ways of doing this is to
  43. make the table an array, with a single variable marking the point up to
  44. which the table is filled, with the preloaded entries at the bottom.
  45. When this is done, there is an additional advantage: the first 256
  46. output codes will all be 511 or less, and both the encoder and decoder
  47. know this, so only nine bits per code need to actually be emitted.
  48. Similarly, the next 512 will need only ten bits each, etc.
  49.  
  50. At least one implementation - compress(1) - has an additional feature:
  51. in addition to the 256 preloaded entries I described above, there is a
  52. 257th code that is reserved.  Once the table is full, the program
  53. continually monitors the compression ratio it's achieving, and if it
  54. drops too low, it emits this code and clears its table back to the 257
  55. preloaded entries.  (The decoder program must of course take similar
  56. action upon seeing this code in the compressed stream.)
  57.  
  58. An additional idea I have experimented with is to replace the compress
  59. technique for dealing with a full table with another one: when the
  60. table fills up, scan all table entries, and free up any whose strings
  61. are such that when any character is appended to them, the result is not
  62. in the table.  (That is, the "leaves" of the tree.  Of course, the
  63. predefined entries can never be freed.)  In my (minimal) tests, this
  64. had comparable effect to compress(1)'s strategy.
  65.  
  66. If you wish to be compatible with any existing implementation (eg,
  67. compress(1), or the compression used by GIFs), you will have to be
  68. careful to make sure that your table sizes and code choice algorithms
  69. and so on are all identical to those used by what you're trying to be
  70. compatible with.  The best way to do this is probably to find source
  71. code that implements it.  In the case of GIFs, this is easy; pbmplus
  72. contains a ppmtogif filter.  I think some version of compress is
  73. available free, but I'm not sure.
  74.  
  75.                     der Mouse
  76.  
  77.                 mouse@larry.mcrcim.mcgill.edu
  78.