LZO1X_D.CPP 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. ** Command & Conquer Red Alert(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* lzo1x_d.c -- standalone LZO1X decompressor
  19. This file is part of the LZO real-time data compression library.
  20. Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
  21. The LZO library is free software; you can redistribute it and/or
  22. modify it under the terms of the GNU Library General Public
  23. License as published by the Free Software Foundation; either
  24. version 2 of the License, or (at your option) any later version.
  25. The LZO library is distributed in the hope that it will be useful,
  26. but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  28. Library General Public License for more details.
  29. You should have received a copy of the GNU Library General Public
  30. License along with the LZO library; see the file COPYING.LIB.
  31. If not, write to the Free Software Foundation, Inc.,
  32. 675 Mass Ave, Cambridge, MA 02139, USA.
  33. Markus F.X.J. Oberhumer
  34. [email protected]
  35. */
  36. #include "lzo1x.h"
  37. #define NDEBUG
  38. #include <assert.h>
  39. #if !defined(LZO1X) && !defined(LZO1Y)
  40. # define LZO1X
  41. #endif
  42. #if 1
  43. # define TEST_IP 1
  44. #else
  45. # define TEST_IP (ip < ip_end)
  46. #endif
  47. /***********************************************************************
  48. // decompress a block of data.
  49. ************************************************************************/
  50. int lzo1x_decompress ( const lzo_byte *in , lzo_uint in_len,
  51. lzo_byte *out, lzo_uint *out_len,
  52. lzo_voidp )
  53. {
  54. register lzo_byte *op;
  55. register const lzo_byte *ip;
  56. register lzo_uint t;
  57. register const lzo_byte *m_pos;
  58. const lzo_byte * const ip_end = in + in_len;
  59. *out_len = 0;
  60. op = out;
  61. ip = in;
  62. if (*ip > 17)
  63. {
  64. t = *ip++ - 17;
  65. goto first_literal_run;
  66. }
  67. while (TEST_IP)
  68. {
  69. t = *ip++;
  70. if (t >= 16)
  71. goto match;
  72. /* a literal run */
  73. if (t == 0)
  74. {
  75. t = 15;
  76. while (*ip == 0)
  77. t += 255, ip++;
  78. t += *ip++;
  79. }
  80. /* copy literals */
  81. *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
  82. first_literal_run:
  83. do *op++ = *ip++; while (--t > 0);
  84. t = *ip++;
  85. if (t >= 16)
  86. goto match;
  87. #if defined(LZO1X)
  88. m_pos = op - 1 - 0x800;
  89. #elif defined(LZO1Y)
  90. m_pos = op - 1 - 0x400;
  91. #endif
  92. m_pos -= t >> 2;
  93. m_pos -= *ip++ << 2;
  94. *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++;
  95. goto match_done;
  96. /* handle matches */
  97. while (TEST_IP)
  98. {
  99. if (t < 16) /* a M1 match */
  100. {
  101. m_pos = op - 1;
  102. m_pos -= t >> 2;
  103. m_pos -= *ip++ << 2;
  104. *op++ = *m_pos++; *op++ = *m_pos++;
  105. }
  106. else
  107. {
  108. match:
  109. if (t >= 64) /* a M2 match */
  110. {
  111. m_pos = op - 1;
  112. #if defined(LZO1X)
  113. m_pos -= (t >> 2) & 7;
  114. m_pos -= *ip++ << 3;
  115. t = (t >> 5) - 1;
  116. #elif defined(LZO1Y)
  117. m_pos -= (t >> 2) & 3;
  118. m_pos -= *ip++ << 2;
  119. t = (t >> 4) - 3;
  120. #endif
  121. }
  122. else if (t >= 32) /* a M3 match */
  123. {
  124. t &= 31;
  125. if (t == 0)
  126. {
  127. t = 31;
  128. while (*ip == 0)
  129. t += 255, ip++;
  130. t += *ip++;
  131. }
  132. m_pos = op - 1;
  133. m_pos -= *ip++ >> 2;
  134. m_pos -= *ip++ << 6;
  135. }
  136. else /* a M4 match */
  137. {
  138. m_pos = op;
  139. m_pos -= (t & 8) << 11;
  140. t &= 7;
  141. if (t == 0)
  142. {
  143. t = 7;
  144. while (*ip == 0)
  145. t += 255, ip++;
  146. t += *ip++;
  147. }
  148. m_pos -= *ip++ >> 2;
  149. m_pos -= *ip++ << 6;
  150. if (m_pos == op)
  151. goto eof_found;
  152. m_pos -= 0x4000;
  153. }
  154. *op++ = *m_pos++; *op++ = *m_pos++;
  155. do *op++ = *m_pos++; while (--t > 0);
  156. }
  157. match_done:
  158. t = ip[-2] & 3;
  159. if (t == 0)
  160. break;
  161. /* copy literals */
  162. do *op++ = *ip++; while (--t > 0);
  163. t = *ip++;
  164. }
  165. }
  166. /* ip == ip_end and no EOF code was found */
  167. //Unreachable - ST 9/5/96 5:07PM
  168. //*out_len = op - out;
  169. //return (ip == ip_end ? LZO_E_EOF_NOT_FOUND : LZO_E_ERROR);
  170. eof_found:
  171. assert(t == 1);
  172. *out_len = op - out;
  173. return (ip == ip_end ? LZO_E_OK : LZO_E_ERROR);
  174. }
  175. /*
  176. vi:ts=4
  177. */