LZSS.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System.Collections.Generic;
  2. using System.IO;
  3. using System.Linq;
  4. namespace OpenVIII
  5. {
  6. public class LZSS
  7. {
  8. //NEW LZSS
  9. #region License
  10. /**************************************************************
  11. LZSS.C -- A Data Compression Program
  12. (tab = 4 spaces)
  13. ***************************************************************
  14. 4/6/1989 Haruhiko Okumura
  15. Use, distribute, and modify this program freely.
  16. Please send me your improved versions.
  17. PC-VAN SCIENCE
  18. NIFTY-Serve PAF01022
  19. CompuServe 74050,1022
  20. **************************************************************/
  21. #endregion License
  22. private static readonly int N = 4096;
  23. private static readonly int F = 18;
  24. private static readonly int THRESHOLD = 2;
  25. private static readonly int EOF = -1;
  26. public static byte[] DecompressAllNew(byte[] data, bool skip = false)
  27. {
  28. byte[] outfilearray;
  29. using (MemoryStream infile = new MemoryStream(!skip?data:data.Skip(4).ToArray()))
  30. {
  31. Decode(infile, out outfilearray);
  32. }
  33. return outfilearray;
  34. }
  35. //Code borrowed from Java's implementation of LZSS by antiquechrono
  36. private static void Decode(MemoryStream infile, out byte[] outfilearray)
  37. {
  38. int i, j, k, r, c;
  39. List<byte> outfile = new List<byte>();
  40. int[] text_buf = new int[N + F - 1]; /* ring buffer of size N, with extra F-1 bytes to facilitate string comparison */
  41. //unsigned int flags;
  42. int flags;
  43. for (i = 0; i < N - F; i++) text_buf[i] = 0;
  44. r = N - F; flags = 0;
  45. for (; ; )
  46. {
  47. if (((flags >>= 1) & 256) == 0)
  48. {
  49. if ((c = infile.ReadByte()) == EOF) break;
  50. flags = c | 0xff00; /* uses higher byte cleverly */
  51. } /* to count eight */
  52. // if (flags & 1) {
  53. if ((flags & 1) == 1)
  54. {
  55. if ((c = infile.ReadByte()) == EOF) break;
  56. outfile.Add((byte)c);
  57. text_buf[r++] = c;
  58. r &= (N - 1);
  59. }
  60. else
  61. {
  62. if ((i = infile.ReadByte()) == EOF) break;
  63. if ((j = infile.ReadByte()) == EOF) break;
  64. i |= ((j & 0xf0) << 4); j = (j & 0x0f) + THRESHOLD;
  65. for (k = 0; k <= j; k++)
  66. {
  67. c = text_buf[(i + k) & (N - 1)];
  68. outfile.Add((byte)c);
  69. text_buf[r++] = c;
  70. r &= (N - 1);
  71. }
  72. }
  73. }
  74. outfilearray = outfile.ToArray();
  75. }
  76. }
  77. }