Lz4.cs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using System;
  2. namespace Ryujinx.Core.Loaders.Compression
  3. {
  4. static class Lz4
  5. {
  6. public static byte[] Decompress(byte[] Cmp, int DecLength)
  7. {
  8. byte[] Dec = new byte[DecLength];
  9. int CmpPos = 0;
  10. int DecPos = 0;
  11. int GetLength(int Length)
  12. {
  13. byte Sum;
  14. if (Length == 0xf)
  15. {
  16. do
  17. {
  18. Length += (Sum = Cmp[CmpPos++]);
  19. }
  20. while (Sum == 0xff);
  21. }
  22. return Length;
  23. }
  24. do
  25. {
  26. byte Token = Cmp[CmpPos++];
  27. int EncCount = (Token >> 0) & 0xf;
  28. int LitCount = (Token >> 4) & 0xf;
  29. //Copy literal chunck
  30. LitCount = GetLength(LitCount);
  31. Buffer.BlockCopy(Cmp, CmpPos, Dec, DecPos, LitCount);
  32. CmpPos += LitCount;
  33. DecPos += LitCount;
  34. if (CmpPos >= Cmp.Length)
  35. {
  36. break;
  37. }
  38. //Copy compressed chunck
  39. int Back = Cmp[CmpPos++] << 0 |
  40. Cmp[CmpPos++] << 8;
  41. EncCount = GetLength(EncCount) + 4;
  42. int EncPos = DecPos - Back;
  43. if (EncCount <= Back)
  44. {
  45. Buffer.BlockCopy(Dec, EncPos, Dec, DecPos, EncCount);
  46. DecPos += EncCount;
  47. }
  48. else
  49. {
  50. while (EncCount-- > 0)
  51. {
  52. Dec[DecPos++] = Dec[EncPos++];
  53. }
  54. }
  55. }
  56. while (CmpPos < Cmp.Length &&
  57. DecPos < Dec.Length);
  58. return Dec;
  59. }
  60. }
  61. }