lzo1x_d.cpp 6.4 KB

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