home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lzo100.zip / lzo-1.00 / lzo_test.c < prev    next >
C/C++ Source or Header  |  1997-07-13  |  64KB  |  2,232 lines

  1. /* lzo_test.c -- very comprehensive test driver for the LZO library
  2.  
  3.    This file is part of the LZO real-time data compression library.
  4.  
  5.    Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
  6.    Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
  7.  
  8.    The LZO library is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU General Public License as
  10.    published by the Free Software Foundation; either version 2 of
  11.    the License, or (at your option) any later version.
  12.  
  13.    The LZO library is distributed in the hope that it will be useful,
  14.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    GNU General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with the LZO library; see the file COPYING.
  20.    If not, write to the Free Software Foundation, Inc.,
  21.    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22.  
  23.    Markus F.X.J. Oberhumer
  24.    markus.oberhumer@jk.uni-linz.ac.at
  25.  */
  26.  
  27.  
  28. #include <lzoconf.h>
  29.  
  30. #if defined(LZO_HAVE_CONFIG_H)
  31. #  include <config.h>
  32. #  include <sys/types.h>
  33. #endif
  34.  
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <stdarg.h>
  38. #include <string.h>
  39. #include <ctype.h>
  40. #include <limits.h>
  41. #include <assert.h>
  42. #if defined(__DJGPP__) || defined(__BORLANDC__)
  43. #  include <dir.h>
  44. #endif
  45. #if defined(HAVE_UNISTD_H) || defined(__DJGPP__) || defined(__EMX__)
  46. #  include <unistd.h>
  47. #endif
  48.  
  49. #if 0
  50. #  define is_digit(x)    (isdigit((unsigned char)(x)))
  51. #  define is_space(x)    (isspace((unsigned char)(x)))
  52. #else
  53. #  define is_digit(x)    ((x) >= '0' && (x) <= '9')
  54. #  define is_space(x)    ((x)==' ' || (x)=='\t' || (x)=='\r' || (x)=='\n')
  55. #endif
  56.  
  57.  
  58. /*************************************************************************
  59. // high resolution timer
  60. **************************************************************************/
  61.  
  62. #if defined(TIME_WITH_SYS_TIME)
  63. #  include <sys/time.h>
  64. #  include <time.h>
  65. #else
  66. #  include <time.h>
  67. #endif
  68. #if !defined(CLOCKS_PER_SEC) && defined(CLK_TCK)
  69. #  define CLOCKS_PER_SEC        CLK_TCK
  70. #endif
  71.  
  72.  
  73. #if defined(TIME_WITH_SYS_TIME) && defined(HAVE_GETTIMEOFDAY)
  74. static double my_clock(void)
  75. {
  76.     struct timeval tv;
  77.     if (gettimeofday(&tv, 0) != 0)
  78.         return 0;
  79.     return tv.tv_sec * 1000000.0 + tv.tv_usec;
  80. }
  81. #  define my_clock_t            double
  82. #  define MY_CLOCKS_PER_SEC        1000000
  83. #  define my_clock_desc            "gettimeofday()"
  84. #else
  85. #  if defined(UCLOCKS_PER_SEC)
  86. #    define my_clock()            uclock()
  87. #    define my_clock_t            uclock_t
  88. #    define MY_CLOCKS_PER_SEC    UCLOCKS_PER_SEC
  89. #    define my_clock_desc        "uclock()"
  90. #  else
  91. #    define my_clock()            clock()
  92. #    define my_clock_t            clock_t
  93. #    define MY_CLOCKS_PER_SEC    CLOCKS_PER_SEC
  94. #    define my_clock_desc        "clock()"
  95. #  endif
  96. #endif
  97.  
  98.  
  99. /*************************************************************************
  100. // compression include section
  101. **************************************************************************/
  102.  
  103. #define HAVE_LZO1_H
  104. #define HAVE_LZO1A_H
  105. #define HAVE_LZO1B_H
  106. #define HAVE_LZO1C_H
  107. #define HAVE_LZO1F_H
  108. #define HAVE_LZO1X_H
  109. #define HAVE_LZO1Y_H
  110. #define HAVE_LZO2A_H
  111.  
  112. #if 1 && defined(MFX) && !defined(LZO_HAVE_CONFIG_H) && !defined(HAVE_ZLIB_H)
  113. #define HAVE_ZLIB_H
  114. #endif
  115.  
  116. #if defined(__LZO_DOS16)
  117. /* don't make this test program too big */
  118. #undef HAVE_LZO1_H
  119. #undef HAVE_LZO1A_H
  120. #undef HAVE_LZO1C_H
  121. #undef HAVE_LZO2A_H
  122. #undef HAVE_LZO2B_H
  123. #undef HAVE_ZLIB_H
  124. #endif
  125.  
  126.  
  127. /* LZO algorithms */
  128. #if defined(HAVE_LZO1_H)
  129. #  include <lzo1.h>
  130. #endif
  131. #if defined(HAVE_LZO1A_H)
  132. #  include <lzo1a.h>
  133. #endif
  134. #if defined(HAVE_LZO1B_H)
  135. #  include <lzo1b.h>
  136. #endif
  137. #if defined(HAVE_LZO1C_H)
  138. #  include <lzo1c.h>
  139. #endif
  140. #if defined(HAVE_LZO1F_H)
  141. #  include <lzo1f.h>
  142. #endif
  143. #if defined(HAVE_LZO1X_H)
  144. #  include <lzo1x.h>
  145. #endif
  146. #if defined(HAVE_LZO1Y_H)
  147. #  include <lzo1y.h>
  148. #endif
  149. #if defined(HAVE_LZO2A_H)
  150. #  include <lzo2a.h>
  151. #endif
  152. #if defined(HAVE_LZO2B_H)
  153. #  include <lzo2b.h>
  154. #endif
  155.  
  156. /* other compressors */
  157. #if defined(HAVE_ZLIB_H)
  158. #  include <zlib.h>
  159. #endif
  160. #if defined(MFX)
  161. #  include "contrib/t_config.ch"
  162. #endif
  163.  
  164.  
  165. /*************************************************************************
  166. // enumerate all methods
  167. **************************************************************************/
  168.  
  169. enum {
  170. /* compression algorithms */
  171.     M_LZO1B_1     =     1,
  172.     M_LZO1B_2, M_LZO1B_3, M_LZO1B_4, M_LZO1B_5,
  173.     M_LZO1B_6, M_LZO1B_7, M_LZO1B_8, M_LZO1B_9,
  174.  
  175.     M_LZO1C_1     =    11,
  176.     M_LZO1C_2, M_LZO1C_3, M_LZO1C_4, M_LZO1C_5,
  177.     M_LZO1C_6, M_LZO1C_7, M_LZO1C_8, M_LZO1C_9,
  178.  
  179.     M_LZO1        =    21,
  180.     M_LZO1A       =    31,
  181.  
  182.     M_LZO1B_99    =   901,
  183.     M_LZO1B_999   =   902,
  184.     M_LZO1C_99    =   911,
  185.     M_LZO1C_999   =   912,
  186.     M_LZO1_99     =   921,
  187.     M_LZO1A_99    =   931,
  188.  
  189.     M_LZO1F_1     =    61,
  190.     M_LZO1F_999   =   962,
  191.     M_LZO1X_1     =    71,
  192.     M_LZO1X_1_11  =   111,
  193.     M_LZO1X_1_15  =   115,
  194.     M_LZO1X_999   =   972,
  195.     M_LZO1Y_1     =    81,
  196.     M_LZO1Y_999   =   982,
  197.  
  198.     M_LZO2A_999   =   942,
  199.     M_LZO2B_999   =   952,
  200.  
  201.     M_LAST_LZO_COMPRESSOR = 998,
  202.  
  203. /* other compressors */
  204.     M_ZLIB_8_1 =  1101,
  205.     M_ZLIB_8_2, M_ZLIB_8_3, M_ZLIB_8_4, M_ZLIB_8_5,
  206.     M_ZLIB_8_6, M_ZLIB_8_7, M_ZLIB_8_8, M_ZLIB_8_9,
  207.  
  208. /* dummy compressor - for speed comparision */
  209.     M_MEMCPY      =   999,
  210.  
  211.     M_LAST_COMPRESSOR = 4999,
  212.  
  213. /* dummy algorithms - for speed comparision */
  214.     M_MEMSET      =  5001,
  215.  
  216. /* checksum algorithms - for speed comparision */
  217.     M_ADLER32     =  6001,
  218.     M_CRC32       =  6002,
  219. #if defined(HAVE_ZLIB_H)
  220.     M_Z_ADLER32   =  6011,
  221.     M_Z_CRC32     =  6012,
  222. #endif
  223.  
  224.     M_UNUSED
  225. };
  226.  
  227.  
  228. #if defined(LZO_99_UNSUPPORTED)
  229. #define M_LZO1_99        (-1)
  230. #define M_LZO1A_99        (-1)
  231. #define M_LZO1B_99        (-1)
  232. #define M_LZO1C_99        (-1)
  233. #endif
  234. #if defined(LZO_999_UNSUPPORTED)
  235. #define M_LZO1B_999        (-1)
  236. #define M_LZO1C_999        (-1)
  237. #define M_LZO1F_999        (-1)
  238. #define M_LZO1X_999        (-1)
  239. #define M_LZO1Y_999        (-1)
  240. #define M_LZO2A_999        (-1)
  241. #define M_LZO2B_999        (-1)
  242. #endif
  243.  
  244.  
  245. /*************************************************************************
  246. // test driver options
  247. **************************************************************************/
  248.  
  249. int opt_verbose = 2;
  250.  
  251. lzo_bool opt_use_safe_decompressor = 0;
  252. lzo_bool opt_use_asm_decompressor = 0;
  253. lzo_bool opt_use_asm_fast_decompressor = 0;
  254. lzo_bool opt_optimize_compressed_data = 0;
  255.  
  256. lzo_bool opt_read_from_stdin = 0;
  257.  
  258. /* set these to 1 to measure the speed impact of a checksum (see options) */
  259. lzo_bool opt_compute_adler32 = 0;
  260. lzo_bool opt_compute_crc32 = 0;
  261.  
  262. lzo_bool try_to_compress_0_bytes = 1;
  263.  
  264. static lzo_uint32 adler_in, adler_out;
  265. static lzo_uint32 crc_in, crc_out;
  266.  
  267.  
  268. #if defined(HAVE_LZO1X_H)
  269. int default_method = M_LZO1X_1;
  270. #elif defined(HAVE_LZO1B_H)
  271. int default_method = M_LZO1B_1;
  272. #elif defined(HAVE_LZO1C_H)
  273. int default_method = M_LZO1C_1;
  274. #elif defined(HAVE_LZO1F_H)
  275. int default_method = M_LZO1F_1;
  276. #elif defined(HAVE_LZO1Y_H)
  277. int default_method = M_LZO1Y_1;
  278. #else
  279. int default_method = 0;
  280. #endif
  281.  
  282.  
  283. static const short all_methods[] = {
  284.     M_LZO1,
  285.     M_LZO1A,
  286.     M_LZO1B_1, M_LZO1B_2, M_LZO1B_3, M_LZO1B_4, M_LZO1B_5,
  287.     M_LZO1B_6, M_LZO1B_7, M_LZO1B_8, M_LZO1B_9,
  288.     M_LZO1C_1, M_LZO1C_2, M_LZO1C_3, M_LZO1C_4, M_LZO1C_5,
  289.     M_LZO1C_6, M_LZO1C_7, M_LZO1C_8, M_LZO1C_9,
  290.     M_LZO1F_1,
  291.     M_LZO1X_1,
  292.     M_LZO1Y_1,
  293.     M_LZO1X_1_11, M_LZO1X_1_15,
  294.     M_LZO1_99, M_LZO1A_99, M_LZO1B_99, M_LZO1C_99,
  295.     M_LZO1B_999, M_LZO1C_999, M_LZO1F_999, M_LZO1X_999, M_LZO1Y_999,
  296.     M_LZO2A_999,
  297.     0
  298. };
  299.  
  300. static const short benchmark_methods[] = {
  301.     M_LZO1B_1, M_LZO1B_9,
  302.     M_LZO1C_1, M_LZO1C_9,
  303.     M_LZO1F_1,
  304.     M_LZO1X_1,
  305.     0
  306. };
  307.  
  308. static const short x1_methods[] = {
  309.     M_LZO1, M_LZO1A, M_LZO1B_1, M_LZO1C_1, M_LZO1F_1, M_LZO1X_1, M_LZO1Y_1,
  310.     0
  311. };
  312.  
  313. static const short x99_methods[] = {
  314.     M_LZO1_99, M_LZO1A_99, M_LZO1B_99, M_LZO1C_99,
  315.     0
  316. };
  317.  
  318. static const short x999_methods[] = {
  319.     M_LZO1B_999, M_LZO1C_999, M_LZO1F_999, M_LZO1X_999, M_LZO1Y_999,
  320.     M_LZO2A_999,
  321.     0
  322. };
  323.  
  324. static const short zlib_methods[] = {
  325.     M_ZLIB_8_1, M_ZLIB_8_2, M_ZLIB_8_3, M_ZLIB_8_4, M_ZLIB_8_5,
  326.     M_ZLIB_8_6, M_ZLIB_8_7, M_ZLIB_8_8, M_ZLIB_8_9,
  327.     0
  328. };
  329.  
  330. static const short avail_methods[] = {
  331.     0
  332. };
  333.  
  334. static const short lzo_methods[] = {
  335.     0
  336. };
  337.  
  338.  
  339. /* exit codes of this test program */
  340. #define EXIT_OK            0
  341. #define EXIT_USAGE        1
  342. #define EXIT_FILE        2
  343. #define EXIT_MEM        3
  344. #define EXIT_ADLER        4
  345. #define EXIT_LZO_ERROR    5
  346. #define EXIT_LZO_INIT    6
  347. #define EXIT_INTERNAL    7
  348.  
  349.  
  350. /*************************************************************************
  351. // memory setup
  352. **************************************************************************/
  353.  
  354. #if 0 && (UINT_MAX >= 0xffffffffL)
  355. #define USE_MALLOC
  356. #endif
  357.  
  358.  
  359. #if (UINT_MAX >= 0xffffffffL)        /* 32 bit or more */
  360.  
  361. #define BLOCK_SIZE        (256*1024l)
  362. #define MAX_BLOCK_SIZE    (5*256*1024l)
  363. #define DATA_LEN        (5*256*1024l)
  364. #if (UINT_MAX > 0xffffffffL)        /* 64 bit or more */
  365. #define WORK_LEN        (768*1024l * sizeof(long) / 4)
  366. #else
  367. #define WORK_LEN        (768*1024l)
  368. #endif
  369.  
  370. #elif defined(__LZO_TOS16) || defined(__LZO_WIN16)
  371.  
  372. /* adjust memory so that it works on a 4 meg machine */
  373. #define BLOCK_SIZE        (256*1024l)
  374. #define MAX_BLOCK_SIZE    (1*BLOCK_SIZE)
  375. #define DATA_LEN        (1024*1024l)
  376. #define WORK_LEN        (768*1024l)
  377.  
  378. #else
  379.  
  380. /* DOS 16 bit - have to squeeze everything into ~600 kB  */
  381. #define BLOCK_SIZE        32000u
  382. #define MAX_BLOCK_SIZE    32000u
  383. #define DATA_LEN        (64*1024l)
  384. #define WORK_LEN        (64*1024l)
  385.  
  386. #endif
  387.  
  388.  
  389. static lzo_uint block_size = BLOCK_SIZE;
  390.  
  391. #ifndef LZO_MEMALLOC_T
  392. #define LZO_MEMALLOC_T    lzo_byte
  393. #endif
  394. static LZO_MEMALLOC_T    _block1[MAX_BLOCK_SIZE * 9L / 8 + 256 + 1024];
  395. static LZO_MEMALLOC_T    _block2[MAX_BLOCK_SIZE * 9L / 8 + 256 + 1024];
  396. static LZO_MEMALLOC_T    _wrkmem[16 + WORK_LEN + 256 + 16];
  397. #ifdef USE_MALLOC
  398. #undef DATA_LEN
  399. static LZO_MEMALLOC_T    *_data = NULL;
  400. #else
  401. static LZO_MEMALLOC_T    _data[DATA_LEN + 256];
  402. #endif
  403.  
  404. /* align memory blocks (cache issues) */
  405. static lzo_byte *block1 = NULL;
  406. static lzo_byte *block2 = NULL;
  407. static lzo_byte *wrkmem = NULL;
  408. static lzo_byte *data   = NULL;
  409.  
  410. static void align_mem(void)
  411. {
  412.     block1 = LZO_ALIGN(_block1,256);
  413.     block2 = LZO_ALIGN(_block2,256);
  414.     wrkmem = LZO_ALIGN(_wrkmem+16,256);
  415. }
  416.  
  417.  
  418. /*************************************************************************
  419. // library assembler functions
  420. **************************************************************************/
  421.  
  422. #if !defined(__LZO_NO_ASM)
  423. #  if defined(__LZO_i386) && (UINT_MAX == 0xffffffffL)
  424. #    if defined(__GNUC__) || defined(__WATCOMC__)
  425. #      define LZO1C_HAVE_i386_DECOMPRESS_ASM
  426. #      define LZO1F_HAVE_i386_DECOMPRESS_ASM
  427. #      define LZO1X_HAVE_i386_DECOMPRESS_ASM
  428. #      define LZO1Y_HAVE_i386_DECOMPRESS_ASM
  429. #    endif
  430. #  endif
  431. #endif
  432.  
  433. #if 1
  434. #  define lzo1b_decompress_asm                0
  435. #  define lzo1b_decompress_asm_safe            0
  436. #  define lzo1b_decompress_asm_fast            0
  437. #  define lzo1b_decompress_asm_fast_safe    0
  438. #endif
  439.  
  440. #if defined(LZO1C_HAVE_i386_DECOMPRESS_ASM)
  441. LZO_EXTERN(int)
  442. lzo1c_decompress_asm
  443.                         ( const lzo_byte *src, lzo_uint  src_len,
  444.                                 lzo_byte *dst, lzo_uint *dst_len,
  445.                                 lzo_voidp wrkmem /* NOT USED */ );
  446. LZO_EXTERN(int)
  447. lzo1c_decompress_asm_safe
  448.                          (const lzo_byte *src, lzo_uint  src_len,
  449.                                 lzo_byte *dst, lzo_uint *dst_len,
  450.                                 lzo_voidp wrkmem /* NOT USED */ );
  451. #  define lzo1c_decompress_asm_fast            0
  452. #  define lzo1c_decompress_asm_fast_safe    0
  453. #else
  454. #  define lzo1c_decompress_asm                0
  455. #  define lzo1c_decompress_asm_safe            0
  456. #  define lzo1c_decompress_asm_fast            0
  457. #  define lzo1c_decompress_asm_fast_safe    0
  458. #endif
  459.  
  460. #if defined(LZO1F_HAVE_i386_DECOMPRESS_ASM)
  461. #  define lzo1f_decompress_asm                0
  462. #  define lzo1f_decompress_asm_safe            0
  463. LZO_EXTERN(int)
  464. lzo1f_decompress_asm_fast
  465.                         ( const lzo_byte *src, lzo_uint  src_len,
  466.                                 lzo_byte *dst, lzo_uint *dst_len,
  467.                                 lzo_voidp wrkmem /* NOT USED */ );
  468. LZO_EXTERN(int)
  469. lzo1f_decompress_asm_fast_safe
  470.                          (const lzo_byte *src, lzo_uint  src_len,
  471.                                 lzo_byte *dst, lzo_uint *dst_len,
  472.                                 lzo_voidp wrkmem /* NOT USED */ );
  473. #else
  474. #  define lzo1f_decompress_asm                0
  475. #  define lzo1f_decompress_asm_safe            0
  476. #  define lzo1f_decompress_asm_fast            0
  477. #  define lzo1f_decompress_asm_fast_safe    0
  478. #endif
  479.  
  480. #if defined(LZO1X_HAVE_i386_DECOMPRESS_ASM)
  481. LZO_EXTERN(int)
  482. lzo1x_decompress_asm    ( const lzo_byte *src, lzo_uint  src_len,
  483.                                 lzo_byte *dst, lzo_uint *dst_len,
  484.                                 lzo_voidp wrkmem /* NOT USED */ );
  485. LZO_EXTERN(int)
  486. lzo1x_decompress_asm_safe
  487.                         ( const lzo_byte *src, lzo_uint  src_len,
  488.                                 lzo_byte *dst, lzo_uint *dst_len,
  489.                                 lzo_voidp wrkmem /* NOT USED */ );
  490. LZO_EXTERN(int)
  491. lzo1x_decompress_asm_fast
  492.                         ( const lzo_byte *src, lzo_uint  src_len,
  493.                                 lzo_byte *dst, lzo_uint *dst_len,
  494.                                 lzo_voidp wrkmem /* NOT USED */ );
  495. LZO_EXTERN(int)
  496. lzo1x_decompress_asm_fast_safe
  497.                          (const lzo_byte *src, lzo_uint  src_len,
  498.                                 lzo_byte *dst, lzo_uint *dst_len,
  499.                                 lzo_voidp wrkmem /* NOT USED */ );
  500. #else
  501. #  define lzo1x_decompress_asm                0
  502. #  define lzo1x_decompress_asm_safe            0
  503. #  define lzo1x_decompress_asm_fast            0
  504. #  define lzo1x_decompress_asm_fast_safe    0
  505. #endif
  506.  
  507. #if defined(LZO1Y_HAVE_i386_DECOMPRESS_ASM)
  508. LZO_EXTERN(int)
  509. lzo1y_decompress_asm    ( const lzo_byte *src, lzo_uint  src_len,
  510.                                 lzo_byte *dst, lzo_uint *dst_len,
  511.                                 lzo_voidp wrkmem /* NOT USED */ );
  512. LZO_EXTERN(int)
  513. lzo1y_decompress_asm_safe
  514.                         ( const lzo_byte *src, lzo_uint  src_len,
  515.                                 lzo_byte *dst, lzo_uint *dst_len,
  516.                                 lzo_voidp wrkmem /* NOT USED */ );
  517. LZO_EXTERN(int)
  518. lzo1y_decompress_asm_fast
  519.                         ( const lzo_byte *src, lzo_uint  src_len,
  520.                                 lzo_byte *dst, lzo_uint *dst_len,
  521.                                 lzo_voidp wrkmem /* NOT USED */ );
  522. LZO_EXTERN(int)
  523. lzo1y_decompress_asm_fast_safe
  524.                          (const lzo_byte *src, lzo_uint  src_len,
  525.                                 lzo_byte *dst, lzo_uint *dst_len,
  526.                                 lzo_voidp wrkmem /* NOT USED */ );
  527. #else
  528. #  define lzo1y_decompress_asm                0
  529. #  define lzo1y_decompress_asm_safe            0
  530. #  define lzo1y_decompress_asm_fast            0
  531. #  define lzo1y_decompress_asm_fast_safe    0
  532. #endif
  533.  
  534.  
  535. /*************************************************************************
  536. // zlib wrapper
  537. **************************************************************************/
  538.  
  539. #if defined(HAVE_ZLIB_H)
  540.  
  541. #if (UINT_MAX > 0xffffffffL)        /* 64 bit or more */
  542. #define ZLIB_MEM_COMPRESS        600000
  543. #define ZLIB_MEM_DECOMPRESS        100000
  544. #else
  545. #define ZLIB_MEM_COMPRESS        300000
  546. #define ZLIB_MEM_DECOMPRESS         50000
  547. #endif
  548.  
  549. static lzo_byte *zlib_heap_ptr = NULL;
  550. static lzo_uint32 zlib_heap_used = 0;
  551. static lzo_uint32 zlib_heap_size = WORK_LEN;
  552.  
  553. static
  554. voidpf zlib_zalloc ( voidpf opaque, unsigned items, unsigned size )
  555. {
  556.     lzo_uint32 bytes = (lzo_uint32) items * size;
  557.     voidpf ptr = (voidpf) zlib_heap_ptr;
  558.  
  559.     bytes = (bytes + 15) & ~15;
  560.     if (zlib_heap_used + bytes > zlib_heap_size)
  561.         return 0;
  562.  
  563.     zlib_heap_ptr  += bytes;
  564.     zlib_heap_used += bytes;
  565.     opaque = 0;
  566.     return ptr;
  567. }
  568.  
  569. static
  570. void zlib_zfree ( voidpf opaque, voidpf ptr )
  571. {
  572.     opaque = 0;
  573.     ptr = 0;
  574. }
  575.  
  576. static
  577. void zlib_alloc_init ( z_stream *strm, lzo_bytep wrkmem )
  578. {
  579.     zlib_heap_ptr  = wrkmem;
  580.     zlib_heap_used = 0;
  581.  
  582.     strm->zalloc = (alloc_func)zlib_zalloc;
  583.     strm->zfree = (free_func)zlib_zfree;
  584. }
  585.  
  586.  
  587. int zlib_compress       ( const lzo_byte *src, lzo_uint  src_len,
  588.                                 lzo_byte *dst, lzo_uint *dst_len,
  589.                                 lzo_voidp wrkmem,
  590.                                 int c, int level )
  591. {
  592.     /* use the undocumented feature to suppress the zlib header */
  593.     z_stream stream;
  594.     int err;
  595.  
  596.     stream.next_in = (lzo_byte *) src;        /* UNCONST */
  597.     stream.avail_in = src_len;
  598.     stream.next_out = dst;
  599.     stream.avail_out = *dst_len;
  600.  
  601.     zlib_alloc_init(&stream,wrkmem);
  602.     *dst_len = 0;
  603. #if 0
  604.     err = deflateInit(&stream, level);
  605. #else
  606.     err = deflateInit2(&stream, level, c, -MAX_WBITS,
  607.                        MAX_MEM_LEVEL > 8 ? 8 : MAX_MEM_LEVEL,
  608.                        Z_DEFAULT_STRATEGY);
  609. #endif
  610.     if (err == Z_OK)
  611.     {
  612.         err = deflate(&stream, Z_FINISH);
  613.         if (err != Z_STREAM_END)
  614.         {
  615.             deflateEnd(&stream);
  616.             err = (err == Z_OK) ? Z_BUF_ERROR : err;
  617.         }
  618.         else
  619.         {
  620.             *dst_len = (lzo_uint) stream.total_out;
  621.             err = deflateEnd(&stream);
  622.         }
  623.     }
  624.     return (err == Z_OK) ? 0 : -1;
  625. }
  626.  
  627.  
  628. LZO_PRIVATE(int)
  629. zlib_decompress         ( const lzo_byte *src, lzo_uint  src_len,
  630.                                 lzo_byte *dst, lzo_uint *dst_len,
  631.                                 lzo_voidp wrkmem )
  632. {
  633.     /* use the undocumented feature to suppress the zlib header */
  634.     z_stream stream;
  635.     int err;
  636.  
  637.     stream.next_in = (lzo_byte *) src;        /* UNCONST */
  638.     stream.avail_in = src_len;
  639.     stream.next_out = dst;
  640.     stream.avail_out = *dst_len;
  641.  
  642.     zlib_alloc_init(&stream,wrkmem);
  643.     *dst_len = 0;
  644. #if 0
  645.     err = inflateInit(&stream);
  646. #else
  647.     err = inflateInit2(&stream, -MAX_WBITS);
  648. #endif
  649.     if (err == Z_OK)
  650.     {
  651.         err = inflate(&stream, Z_FINISH);
  652.         if (err == Z_OK)        /* sometimes returns Z_OK !!! */
  653.         {
  654.             *dst_len = (lzo_uint) stream.total_out;
  655.             err = inflateEnd(&stream);
  656.         }
  657.         else if (err == Z_STREAM_END)
  658.         {
  659.             *dst_len = (lzo_uint) stream.total_out;
  660.             err = inflateEnd(&stream);
  661.         }
  662.         else
  663.             inflateEnd(&stream);
  664.     }
  665.     return (err == Z_OK) ? 0 : -1;
  666. }
  667.  
  668.  
  669. LZO_PRIVATE(int)
  670. zlib_8_1_compress       ( const lzo_byte *src, lzo_uint  src_len,
  671.                                 lzo_byte *dst, lzo_uint *dst_len,
  672.                                 lzo_voidp wrkmem )
  673. { return zlib_compress(src,src_len,dst,dst_len,wrkmem,Z_DEFLATED,1); }
  674.  
  675. LZO_PRIVATE(int)
  676. zlib_8_2_compress       ( const lzo_byte *src, lzo_uint  src_len,
  677.                                 lzo_byte *dst, lzo_uint *dst_len,
  678.                                 lzo_voidp wrkmem )
  679. { return zlib_compress(src,src_len,dst,dst_len,wrkmem,Z_DEFLATED,2); }
  680.  
  681. LZO_PRIVATE(int)
  682. zlib_8_3_compress       ( const lzo_byte *src, lzo_uint  src_len,
  683.                                 lzo_byte *dst, lzo_uint *dst_len,
  684.                                 lzo_voidp wrkmem )
  685. { return zlib_compress(src,src_len,dst,dst_len,wrkmem,Z_DEFLATED,3); }
  686.  
  687. LZO_PRIVATE(int)
  688. zlib_8_4_compress       ( const lzo_byte *src, lzo_uint  src_len,
  689.                                 lzo_byte *dst, lzo_uint *dst_len,
  690.                                 lzo_voidp wrkmem )
  691. { return zlib_compress(src,src_len,dst,dst_len,wrkmem,Z_DEFLATED,4); }
  692.  
  693. LZO_PRIVATE(int)
  694. zlib_8_5_compress       ( const lzo_byte *src, lzo_uint  src_len,
  695.                                 lzo_byte *dst, lzo_uint *dst_len,
  696.                                 lzo_voidp wrkmem )
  697. { return zlib_compress(src,src_len,dst,dst_len,wrkmem,Z_DEFLATED,5); }
  698.  
  699. LZO_PRIVATE(int)
  700. zlib_8_6_compress       ( const lzo_byte *src, lzo_uint  src_len,
  701.                                 lzo_byte *dst, lzo_uint *dst_len,
  702.                                 lzo_voidp wrkmem )
  703. { return zlib_compress(src,src_len,dst,dst_len,wrkmem,Z_DEFLATED,6); }
  704.  
  705. LZO_PRIVATE(int)
  706. zlib_8_7_compress       ( const lzo_byte *src, lzo_uint  src_len,
  707.                                 lzo_byte *dst, lzo_uint *dst_len,
  708.                                 lzo_voidp wrkmem )
  709. { return zlib_compress(src,src_len,dst,dst_len,wrkmem,Z_DEFLATED,7); }
  710.  
  711. LZO_PRIVATE(int)
  712. zlib_8_8_compress       ( const lzo_byte *src, lzo_uint  src_len,
  713.                                 lzo_byte *dst, lzo_uint *dst_len,
  714.                                 lzo_voidp wrkmem )
  715. { return zlib_compress(src,src_len,dst,dst_len,wrkmem,Z_DEFLATED,8); }
  716.  
  717. LZO_PRIVATE(int)
  718. zlib_8_9_compress       ( const lzo_byte *src, lzo_uint  src_len,
  719.                                 lzo_byte *dst, lzo_uint *dst_len,
  720.                                 lzo_voidp wrkmem )
  721. { return zlib_compress(src,src_len,dst,dst_len,wrkmem,Z_DEFLATED,9); }
  722.  
  723.  
  724. #endif /* HAVE_ZLIB_H */
  725.  
  726.  
  727. /*************************************************************************
  728. // other wrappers
  729. **************************************************************************/
  730.  
  731. LZO_PRIVATE(int)
  732. memcpy_x_compress       ( const lzo_byte *src, lzo_uint  src_len,
  733.                                 lzo_byte *dst, lzo_uint *dst_len,
  734.                                 lzo_voidp wrkmem )
  735. {
  736.     lzo_memcpy(dst,src,src_len);
  737.     *dst_len = src_len;
  738.     if (wrkmem) wrkmem = 0;    /* avoid warning */
  739.     return 0;
  740. }
  741.  
  742.  
  743. LZO_PRIVATE(int)
  744. memset_x_compress       ( const lzo_byte *src, lzo_uint  src_len,
  745.                                 lzo_byte *dst, lzo_uint *dst_len,
  746.                                 lzo_voidp wrkmem )
  747. {
  748.     lzo_memset(dst,0,src_len);
  749.     *dst_len = src_len;
  750.     if (src) src = 0;        /* avoid warning */
  751.     if (wrkmem) wrkmem = 0;    /* avoid warning */
  752.     return 0;
  753. }
  754.  
  755.  
  756. LZO_PRIVATE(int)
  757. adler32_x_compress      ( const lzo_byte *src, lzo_uint  src_len,
  758.                                 lzo_byte *dst, lzo_uint *dst_len,
  759.                                 lzo_voidp wrkmem )
  760. {
  761.     lzo_uint32 adler;
  762.     adler = lzo_adler32(0, NULL, 0);
  763.     adler = lzo_adler32(adler, dst, src_len);
  764.     *dst_len = src_len;
  765.     if (src) src = 0;        /* avoid warning */
  766.     if (wrkmem) wrkmem = 0;    /* avoid warning */
  767.     return 0;
  768. }
  769.  
  770.  
  771. LZO_PRIVATE(int)
  772. crc32_x_compress        ( const lzo_byte *src, lzo_uint  src_len,
  773.                                 lzo_byte *dst, lzo_uint *dst_len,
  774.                                 lzo_voidp wrkmem )
  775. {
  776.     lzo_uint32 crc;
  777.     crc = lzo_crc32(0, NULL, 0);
  778.     crc = lzo_crc32(crc, dst, src_len);
  779.     *dst_len = src_len;
  780.     if (src) src = 0;        /* avoid warning */
  781.     if (wrkmem) wrkmem = 0;    /* avoid warning */
  782.     return 0;
  783. }
  784.  
  785.  
  786. #if defined(HAVE_ZLIB_H)
  787.  
  788. LZO_PRIVATE(int)
  789. zlib_adler32_x_compress ( const lzo_byte *src, lzo_uint  src_len,
  790.                                 lzo_byte *dst, lzo_uint *dst_len,
  791.                                 lzo_voidp wrkmem )
  792. {
  793.     uLong adler;
  794.     adler = adler32(0L, Z_NULL, 0);
  795.     adler = adler32(adler, dst, src_len);
  796.     *dst_len = src_len;
  797.     if (src) src = 0;        /* avoid warning */
  798.     if (wrkmem) wrkmem = 0;    /* avoid warning */
  799.     return 0;
  800. }
  801.  
  802.  
  803. LZO_PRIVATE(int)
  804. zlib_crc32_x_compress   ( const lzo_byte *src, lzo_uint  src_len,
  805.                                 lzo_byte *dst, lzo_uint *dst_len,
  806.                                 lzo_voidp wrkmem )
  807. {
  808.     uLong crc;
  809.     crc = crc32(0L, Z_NULL, 0);
  810.     crc = crc32(crc, dst, src_len);
  811.     *dst_len = src_len;
  812.     if (src) src = 0;        /* avoid warning */
  813.     if (wrkmem) wrkmem = 0;    /* avoid warning */
  814.     return 0;
  815. }
  816.  
  817. #endif
  818.  
  819.  
  820. #if defined(MFX)
  821. #  include "contrib/t_wrap.ch"
  822. #endif
  823.  
  824.  
  825. /*************************************************************************
  826. // compression database
  827. **************************************************************************/
  828.  
  829. typedef struct
  830. {
  831.     const char *        name;
  832.     int                 id;
  833.     lzo_uint            mem_compress;
  834.     lzo_uint            mem_decompress;
  835.     lzo_compress_t        compress;
  836.     lzo_optimize_t        optimize;
  837.     lzo_decompress_t    decompress;
  838.     lzo_decompress_t    decompress_safe;
  839.     lzo_decompress_t    decompress_asm;
  840.     lzo_decompress_t    decompress_asm_safe;
  841.     lzo_decompress_t    decompress_asm_fast;
  842.     lzo_decompress_t    decompress_asm_fast_safe;
  843. }
  844. compress_t;
  845.  
  846.  
  847. static const compress_t compress_database[] = {
  848.  
  849. #if defined(HAVE_LZO1_H)
  850. { "LZO1-1", M_LZO1, LZO1_MEM_COMPRESS, LZO1_MEM_DECOMPRESS,
  851.   lzo1_compress,                0,
  852.   lzo1_decompress,              0,
  853.   0,                            0,
  854.   0,                            0 },
  855. #if !defined(LZO_99_UNSUPPORTED)
  856. { "LZO1-99", M_LZO1_99, LZO1_99_MEM_COMPRESS, LZO1_MEM_DECOMPRESS,
  857.   lzo1_99_compress,             0,
  858.   lzo1_decompress,              0,
  859.   0,                            0,
  860.   0,                            0 },
  861. #endif
  862. #endif
  863.  
  864. #if defined(HAVE_LZO1A_H)
  865. { "LZO1A-1", M_LZO1A, LZO1A_MEM_COMPRESS, LZO1A_MEM_DECOMPRESS,
  866.   lzo1a_compress,               0,
  867.   lzo1a_decompress,             0,
  868.   0,                            0,
  869.   0,                            0 },
  870. #if !defined(LZO_99_UNSUPPORTED)
  871. { "LZO1A-99", M_LZO1A_99, LZO1A_99_MEM_COMPRESS, LZO1A_MEM_DECOMPRESS,
  872.   lzo1a_99_compress,            0,
  873.   lzo1a_decompress,             0,
  874.   0,                            0,
  875.   0,                            0 },
  876. #endif
  877. #endif
  878.  
  879. #if defined(HAVE_LZO1B_H)
  880. { "LZO1B-1", M_LZO1B_1, LZO1B_MEM_COMPRESS, LZO1B_MEM_DECOMPRESS,
  881.   lzo1b_1_compress,             0,
  882.   lzo1b_decompress,             lzo1b_decompress_safe,
  883.   lzo1b_decompress_asm,         lzo1b_decompress_asm_safe,
  884.   lzo1b_decompress_asm_fast,    lzo1b_decompress_asm_fast_safe },
  885. { "LZO1B-2", M_LZO1B_2, LZO1B_MEM_COMPRESS, LZO1B_MEM_DECOMPRESS,
  886.   lzo1b_2_compress,             0,
  887.   lzo1b_decompress,             lzo1b_decompress_safe,
  888.   lzo1b_decompress_asm,         lzo1b_decompress_asm_safe,
  889.   lzo1b_decompress_asm_fast,    lzo1b_decompress_asm_fast_safe },
  890. { "LZO1B-3", M_LZO1B_3, LZO1B_MEM_COMPRESS, LZO1B_MEM_DECOMPRESS,
  891.   lzo1b_3_compress,             0,
  892.   lzo1b_decompress,             lzo1b_decompress_safe,
  893.   lzo1b_decompress_asm,         lzo1b_decompress_asm_safe,
  894.   lzo1b_decompress_asm_fast,    lzo1b_decompress_asm_fast_safe },
  895. { "LZO1B-4", M_LZO1B_4, LZO1B_MEM_COMPRESS, LZO1B_MEM_DECOMPRESS,
  896.   lzo1b_4_compress,             0,
  897.   lzo1b_decompress,             lzo1b_decompress_safe,
  898.   lzo1b_decompress_asm,         lzo1b_decompress_asm_safe,
  899.   lzo1b_decompress_asm_fast,    lzo1b_decompress_asm_fast_safe },
  900. { "LZO1B-5", M_LZO1B_5, LZO1B_MEM_COMPRESS, LZO1B_MEM_DECOMPRESS,
  901.   lzo1b_5_compress,             0,
  902.   lzo1b_decompress,             lzo1b_decompress_safe,
  903.   lzo1b_decompress_asm,         lzo1b_decompress_asm_safe,
  904.   lzo1b_decompress_asm_fast,    lzo1b_decompress_asm_fast_safe },
  905. { "LZO1B-6", M_LZO1B_6, LZO1B_MEM_COMPRESS, LZO1B_MEM_DECOMPRESS,
  906.   lzo1b_6_compress,             0,
  907.   lzo1b_decompress,             lzo1b_decompress_safe,
  908.   lzo1b_decompress_asm,         lzo1b_decompress_asm_safe,
  909.   lzo1b_decompress_asm_fast,    lzo1b_decompress_asm_fast_safe },
  910. { "LZO1B-7", M_LZO1B_7, LZO1B_MEM_COMPRESS, LZO1B_MEM_DECOMPRESS,
  911.   lzo1b_7_compress,             0,
  912.   lzo1b_decompress,             lzo1b_decompress_safe,
  913.   lzo1b_decompress_asm,         lzo1b_decompress_asm_safe,
  914.   lzo1b_decompress_asm_fast,    lzo1b_decompress_asm_fast_safe },
  915. { "LZO1B-8", M_LZO1B_8, LZO1B_MEM_COMPRESS, LZO1B_MEM_DECOMPRESS,
  916.   lzo1b_8_compress,             0,
  917.   lzo1b_decompress,             lzo1b_decompress_safe,
  918.   lzo1b_decompress_asm,         lzo1b_decompress_asm_safe,
  919.   lzo1b_decompress_asm_fast,    lzo1b_decompress_asm_fast_safe },
  920. { "LZO1B-9", M_LZO1B_9, LZO1B_MEM_COMPRESS, LZO1B_MEM_DECOMPRESS,
  921.   lzo1b_9_compress,             0,
  922.   lzo1b_decompress,             lzo1b_decompress_safe,
  923.   lzo1b_decompress_asm,         lzo1b_decompress_asm_safe,
  924.   lzo1b_decompress_asm_fast,    lzo1b_decompress_asm_fast_safe },
  925. #if !defined(LZO_99_UNSUPPORTED)
  926. { "LZO1B-99", M_LZO1B_99, LZO1B_99_MEM_COMPRESS, LZO1B_MEM_DECOMPRESS,
  927.   lzo1b_99_compress,            0,
  928.   lzo1b_decompress,             lzo1b_decompress_safe,
  929.   lzo1b_decompress_asm,         lzo1b_decompress_asm_safe,
  930.   lzo1b_decompress_asm_fast,    lzo1b_decompress_asm_fast_safe },
  931. #endif
  932. #if !defined(LZO_999_UNSUPPORTED)
  933. { "LZO1B-999", M_LZO1B_999, LZO1B_999_MEM_COMPRESS, LZO1B_MEM_DECOMPRESS,
  934.   lzo1b_999_compress,           0,
  935.   lzo1b_decompress,             lzo1b_decompress_safe,
  936.   lzo1b_decompress_asm,         lzo1b_decompress_asm_safe,
  937.   lzo1b_decompress_asm_fast,    lzo1b_decompress_asm_fast_safe },
  938. #endif
  939. #endif
  940.  
  941. #if defined(HAVE_LZO1C_H)
  942. { "LZO1C-1", M_LZO1C_1, LZO1C_MEM_COMPRESS, LZO1C_MEM_DECOMPRESS,
  943.   lzo1c_1_compress,             0,
  944.   lzo1c_decompress,             lzo1c_decompress_safe,
  945.   lzo1c_decompress_asm,         lzo1c_decompress_asm_safe,
  946.   lzo1c_decompress_asm_fast,    lzo1c_decompress_asm_fast_safe },
  947. { "LZO1C-2", M_LZO1C_2, LZO1C_MEM_COMPRESS, LZO1C_MEM_DECOMPRESS,
  948.   lzo1c_2_compress,             0,
  949.   lzo1c_decompress,             lzo1c_decompress_safe,
  950.   lzo1c_decompress_asm,         lzo1c_decompress_asm_safe,
  951.   lzo1c_decompress_asm_fast,    lzo1c_decompress_asm_fast_safe },
  952. { "LZO1C-3", M_LZO1C_3, LZO1C_MEM_COMPRESS, LZO1C_MEM_DECOMPRESS,
  953.   lzo1c_3_compress,             0,
  954.   lzo1c_decompress,             lzo1c_decompress_safe,
  955.   lzo1c_decompress_asm,         lzo1c_decompress_asm_safe,
  956.   lzo1c_decompress_asm_fast,    lzo1c_decompress_asm_fast_safe },
  957. { "LZO1C-4", M_LZO1C_4, LZO1C_MEM_COMPRESS, LZO1C_MEM_DECOMPRESS,
  958.   lzo1c_4_compress,             0,
  959.   lzo1c_decompress,             lzo1c_decompress_safe,
  960.   lzo1c_decompress_asm,         lzo1c_decompress_asm_safe,
  961.   lzo1c_decompress_asm_fast,    lzo1c_decompress_asm_fast_safe },
  962. { "LZO1C-5", M_LZO1C_5, LZO1C_MEM_COMPRESS, LZO1C_MEM_DECOMPRESS,
  963.   lzo1c_5_compress,             0,
  964.   lzo1c_decompress,             lzo1c_decompress_safe,
  965.   lzo1c_decompress_asm,         lzo1c_decompress_asm_safe,
  966.   lzo1c_decompress_asm_fast,    lzo1c_decompress_asm_fast_safe },
  967. { "LZO1C-6", M_LZO1C_6, LZO1C_MEM_COMPRESS, LZO1C_MEM_DECOMPRESS,
  968.   lzo1c_6_compress,             0,
  969.   lzo1c_decompress,             lzo1c_decompress_safe,
  970.   lzo1c_decompress_asm,         lzo1c_decompress_asm_safe,
  971.   lzo1c_decompress_asm_fast,    lzo1c_decompress_asm_fast_safe },
  972. { "LZO1C-7", M_LZO1C_7, LZO1C_MEM_COMPRESS, LZO1C_MEM_DECOMPRESS,
  973.   lzo1c_7_compress,             0,
  974.   lzo1c_decompress,             lzo1c_decompress_safe,
  975.   lzo1c_decompress_asm,         lzo1c_decompress_asm_safe,
  976.   lzo1c_decompress_asm_fast,    lzo1c_decompress_asm_fast_safe },
  977. { "LZO1C-8", M_LZO1C_8, LZO1C_MEM_COMPRESS, LZO1C_MEM_DECOMPRESS,
  978.   lzo1c_8_compress,             0,
  979.   lzo1c_decompress,             lzo1c_decompress_safe,
  980.   lzo1c_decompress_asm,         lzo1c_decompress_asm_safe,
  981.   lzo1c_decompress_asm_fast,    lzo1c_decompress_asm_fast_safe },
  982. { "LZO1C-9", M_LZO1C_9, LZO1C_MEM_COMPRESS, LZO1C_MEM_DECOMPRESS,
  983.   lzo1c_9_compress,             0,
  984.   lzo1c_decompress,             lzo1c_decompress_safe,
  985.   lzo1c_decompress_asm,         lzo1c_decompress_asm_safe,
  986.   lzo1c_decompress_asm_fast,    lzo1c_decompress_asm_fast_safe },
  987. #if !defined(LZO_99_UNSUPPORTED)
  988. { "LZO1C-99", M_LZO1C_99, LZO1C_99_MEM_COMPRESS, LZO1C_MEM_DECOMPRESS,
  989.   lzo1c_99_compress,            0,
  990.   lzo1c_decompress,             lzo1c_decompress_safe,
  991.   lzo1c_decompress_asm,         lzo1c_decompress_asm_safe,
  992.   lzo1c_decompress_asm_fast,    lzo1c_decompress_asm_fast_safe },
  993. #endif
  994. #if !defined(LZO_999_UNSUPPORTED)
  995. { "LZO1C-999", M_LZO1C_999, LZO1C_999_MEM_COMPRESS, LZO1C_MEM_DECOMPRESS,
  996.   lzo1c_999_compress,           0,
  997.   lzo1c_decompress,             lzo1c_decompress_safe,
  998.   lzo1c_decompress_asm,         lzo1c_decompress_asm_safe,
  999.   lzo1c_decompress_asm_fast,    lzo1c_decompress_asm_fast_safe },
  1000. #endif
  1001. #endif
  1002.  
  1003. #if defined(HAVE_LZO1F_H)
  1004. { "LZO1F-1", M_LZO1F_1, LZO1F_MEM_COMPRESS, LZO1F_MEM_DECOMPRESS,
  1005.   lzo1f_1_compress,             0,
  1006.   lzo1f_decompress,             lzo1f_decompress_safe,
  1007.   lzo1f_decompress_asm,         lzo1f_decompress_asm_safe,
  1008.   lzo1f_decompress_asm_fast,    lzo1f_decompress_asm_fast_safe },
  1009. #if !defined(LZO_999_UNSUPPORTED)
  1010. { "LZO1F-999", M_LZO1F_999, LZO1F_999_MEM_COMPRESS, LZO1F_MEM_DECOMPRESS,
  1011.   lzo1f_999_compress,           0,
  1012.   lzo1f_decompress,             lzo1f_decompress_safe,
  1013.   lzo1f_decompress_asm,         lzo1f_decompress_asm_safe,
  1014.   lzo1f_decompress_asm_fast,    lzo1f_decompress_asm_fast_safe },
  1015. #endif
  1016. #endif
  1017.  
  1018. #if defined(HAVE_LZO1X_H)
  1019. { "LZO1X-1", M_LZO1X_1, LZO1X_MEM_COMPRESS, LZO1X_MEM_DECOMPRESS,
  1020.   lzo1x_1_compress,             lzo1x_optimize,
  1021.   lzo1x_decompress,             lzo1x_decompress_safe,
  1022.   lzo1x_decompress_asm,         lzo1x_decompress_asm_safe,
  1023.   lzo1x_decompress_asm_fast,    lzo1x_decompress_asm_fast_safe },
  1024. { "LZO1X-1(11)", M_LZO1X_1_11, LZO1X_1_11_MEM_COMPRESS, LZO1X_MEM_DECOMPRESS,
  1025.   lzo1x_1_11_compress,          lzo1x_optimize,
  1026.   lzo1x_decompress,             lzo1x_decompress_safe,
  1027.   lzo1x_decompress_asm,         lzo1x_decompress_asm_safe,
  1028.   lzo1x_decompress_asm_fast,    lzo1x_decompress_asm_fast_safe },
  1029. { "LZO1X-1(15)", M_LZO1X_1_15, LZO1X_1_15_MEM_COMPRESS, LZO1X_MEM_DECOMPRESS,
  1030.   lzo1x_1_15_compress,          lzo1x_optimize,
  1031.   lzo1x_decompress,             lzo1x_decompress_safe,
  1032.   lzo1x_decompress_asm,         lzo1x_decompress_asm_safe,
  1033.   lzo1x_decompress_asm_fast,    lzo1x_decompress_asm_fast_safe },
  1034. #if !defined(LZO_999_UNSUPPORTED)
  1035. { "LZO1X-999", M_LZO1X_999, LZO1X_999_MEM_COMPRESS, LZO1X_MEM_DECOMPRESS,
  1036.   lzo1x_999_compress,           lzo1x_optimize,
  1037.   lzo1x_decompress,             lzo1x_decompress_safe,
  1038.   lzo1x_decompress_asm,         lzo1x_decompress_asm_safe,
  1039.   lzo1x_decompress_asm_fast,    lzo1x_decompress_asm_fast_safe },
  1040. #endif
  1041. #endif
  1042.  
  1043. #if defined(HAVE_LZO1Y_H)
  1044. { "LZO1Y-1", M_LZO1Y_1, LZO1Y_MEM_COMPRESS, LZO1Y_MEM_DECOMPRESS,
  1045.   lzo1y_1_compress,             lzo1y_optimize,
  1046.   lzo1y_decompress,             lzo1y_decompress_safe,
  1047.   lzo1y_decompress_asm,         lzo1y_decompress_asm_safe,
  1048.   lzo1y_decompress_asm_fast,    lzo1y_decompress_asm_fast_safe },
  1049. #if !defined(LZO_999_UNSUPPORTED)
  1050. { "LZO1Y-999", M_LZO1Y_999, LZO1Y_999_MEM_COMPRESS, LZO1Y_MEM_DECOMPRESS,
  1051.   lzo1y_999_compress,           lzo1y_optimize,
  1052.   lzo1y_decompress,             lzo1y_decompress_safe,
  1053.   lzo1y_decompress_asm,         lzo1y_decompress_asm_safe,
  1054.   lzo1y_decompress_asm_fast,    lzo1y_decompress_asm_fast_safe },
  1055. #endif
  1056. #endif
  1057.  
  1058. #if defined(HAVE_LZO2A_H)
  1059. #if !defined(LZO_999_UNSUPPORTED)
  1060. { "LZO2A-999", M_LZO2A_999, LZO2A_999_MEM_COMPRESS, LZO2A_MEM_DECOMPRESS,
  1061.   lzo2a_999_compress,           0,
  1062.   lzo2a_decompress,             lzo2a_decompress_safe,
  1063.   0,                            0,
  1064.   0,                            0 },
  1065. #endif
  1066. #endif
  1067.  
  1068. #if defined(HAVE_LZO2B_H)
  1069. #if !defined(LZO_999_UNSUPPORTED)
  1070. { "LZO2B-999", M_LZO2B_999, LZO2B_999_MEM_COMPRESS, LZO2B_MEM_DECOMPRESS,
  1071.   lzo2b_999_compress,           0,
  1072.   memcpy_x_compress,            0,
  1073.   0,                            0,
  1074.   0,                            0 },
  1075. #endif
  1076. #endif
  1077.  
  1078. #if defined(HAVE_ZLIB_H)
  1079. { "zlib-8/1", M_ZLIB_8_1, ZLIB_MEM_COMPRESS, ZLIB_MEM_DECOMPRESS,
  1080.                                 zlib_8_1_compress, 0,
  1081.                                 zlib_decompress, 0, 0, 0, 0, 0 },
  1082. { "zlib-8/2", M_ZLIB_8_2, ZLIB_MEM_COMPRESS, ZLIB_MEM_DECOMPRESS,
  1083.                                 zlib_8_2_compress, 0,
  1084.                                 zlib_decompress, 0, 0, 0, 0, 0 },
  1085. { "zlib-8/3", M_ZLIB_8_3, ZLIB_MEM_COMPRESS, ZLIB_MEM_DECOMPRESS,
  1086.                                 zlib_8_3_compress, 0,
  1087.                                 zlib_decompress, 0, 0, 0, 0, 0 },
  1088. { "zlib-8/4", M_ZLIB_8_4, ZLIB_MEM_COMPRESS, ZLIB_MEM_DECOMPRESS,
  1089.                                 zlib_8_4_compress, 0,
  1090.                                 zlib_decompress, 0, 0, 0, 0, 0 },
  1091. { "zlib-8/5", M_ZLIB_8_5, ZLIB_MEM_COMPRESS, ZLIB_MEM_DECOMPRESS,
  1092.                                 zlib_8_5_compress, 0,
  1093.                                 zlib_decompress, 0, 0, 0, 0, 0 },
  1094. { "zlib-8/6", M_ZLIB_8_6, ZLIB_MEM_COMPRESS, ZLIB_MEM_DECOMPRESS,
  1095.                                 zlib_8_6_compress, 0,
  1096.                                 zlib_decompress, 0, 0, 0, 0, 0 },
  1097. { "zlib-8/7", M_ZLIB_8_7, ZLIB_MEM_COMPRESS, ZLIB_MEM_DECOMPRESS,
  1098.                                 zlib_8_7_compress, 0,
  1099.                                 zlib_decompress, 0, 0, 0, 0, 0 },
  1100. { "zlib-8/8", M_ZLIB_8_8, ZLIB_MEM_COMPRESS, ZLIB_MEM_DECOMPRESS,
  1101.                                 zlib_8_8_compress, 0,
  1102.                                 zlib_decompress, 0, 0, 0, 0, 0 },
  1103. { "zlib-8/9", M_ZLIB_8_9, ZLIB_MEM_COMPRESS, ZLIB_MEM_DECOMPRESS,
  1104.                                 zlib_8_9_compress, 0,
  1105.                                 zlib_decompress, 0, 0, 0, 0, 0 },
  1106. #endif
  1107.  
  1108. { "memcpy()", M_MEMCPY, 0, 0,   memcpy_x_compress, 0,
  1109.                                 memcpy_x_compress, 0, 0, 0, 0, 0 },
  1110. { "memset()", M_MEMSET, 0, 0,   memset_x_compress, 0,
  1111.                                 memset_x_compress, 0, 0, 0, 0, 0 },
  1112. { "adler32()", M_ADLER32, 0, 0, adler32_x_compress, 0,
  1113.                                 adler32_x_compress, 0, 0, 0, 0, 0 },
  1114. { "crc32()", M_CRC32, 0, 0,     crc32_x_compress, 0,
  1115.                                 crc32_x_compress, 0, 0, 0, 0, 0 },
  1116. #if defined(HAVE_ZLIB_H)
  1117. { "z_adler32()", M_Z_ADLER32, 0, 0, zlib_adler32_x_compress, 0,
  1118.                                 zlib_adler32_x_compress, 0, 0, 0, 0, 0 },
  1119. { "z_crc32()", M_Z_CRC32, 0, 0, zlib_crc32_x_compress, 0,
  1120.                                 zlib_crc32_x_compress, 0, 0, 0, 0, 0 },
  1121. #endif
  1122.  
  1123. #if defined(MFX)
  1124. #  include "contrib/t_db.ch"
  1125. #endif
  1126.  
  1127. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
  1128. };
  1129.  
  1130.  
  1131. /*************************************************************************
  1132. // method info
  1133. **************************************************************************/
  1134.  
  1135. static
  1136. lzo_decompress_t get_decomp_info ( const compress_t *c, const char **nn )
  1137. {
  1138.     lzo_decompress_t d = 0;
  1139.     const char *n = NULL;
  1140.  
  1141.     /* safe has priority over asm/fast */
  1142.     if (!d && opt_use_safe_decompressor && opt_use_asm_fast_decompressor)
  1143.     {
  1144.         d = c->decompress_asm_fast_safe;
  1145.         n = " [fs]";
  1146.     }
  1147.     if (!d && opt_use_safe_decompressor && opt_use_asm_decompressor)
  1148.     {
  1149.         d = c->decompress_asm_safe;
  1150.         n = " [as]";
  1151.     }
  1152.     if (!d && opt_use_safe_decompressor)
  1153.     {
  1154.         d = c->decompress_safe;
  1155.         n = " [s]";
  1156.     }
  1157.     if (!d && opt_use_asm_fast_decompressor)
  1158.     {
  1159.         d = c->decompress_asm_fast;
  1160.         n = " [f]";
  1161.     }
  1162.     if (!d && opt_use_asm_decompressor)
  1163.     {
  1164.         d = c->decompress_asm;
  1165.         n = " [a]";
  1166.     }
  1167.     if (!d)
  1168.     {
  1169.         d = c->decompress;
  1170.         n = "";
  1171.     }
  1172.     if (!d)
  1173.         n = "(null)";
  1174.  
  1175.     if (nn)
  1176.         *nn = n;
  1177.     return d;
  1178. }
  1179.  
  1180.  
  1181. static
  1182. const compress_t *info ( int method, FILE *f )
  1183. {
  1184.     const compress_t *c = NULL;
  1185.     const compress_t *db = compress_database;
  1186.     size_t size = sizeof(compress_database) / sizeof(*(compress_database));
  1187.     size_t i;
  1188.  
  1189.     if (method > 0)
  1190.     {
  1191.         for (i = 0; i < size && db->name != NULL; i++, db++)
  1192.         {
  1193.             if (method == db->id &&
  1194.                 WORK_LEN >= db->mem_compress &&
  1195.                 WORK_LEN >= db->mem_decompress)
  1196.             {
  1197.                 c = db;
  1198.                 break;
  1199.             }
  1200.         }
  1201.     }
  1202.  
  1203.     if (f != NULL)
  1204.     {
  1205.         if (c == NULL)
  1206.         {
  1207.             fprintf(f,"invalid method %d !\n",method);
  1208.             exit(EXIT_USAGE);
  1209.         }
  1210.         else
  1211.         {
  1212.             const char *n;
  1213.             get_decomp_info(c,&n);
  1214.             fprintf(f,"%s%s",c->name,n);
  1215.         }
  1216.     }
  1217.     return c;
  1218. }
  1219.  
  1220.  
  1221. /*************************************************************************
  1222. // check that memory gets accessed within bounds
  1223. **************************************************************************/
  1224.  
  1225. static const lzo_bool do_check_mem = 0;
  1226.  
  1227. void init_mem_checker ( lzo_byte *mem, lzo_byte *mem_base,
  1228.                         lzo_uint len, unsigned char random_byte )
  1229. {
  1230.     lzo_uint i;
  1231.  
  1232.     if (do_check_mem && mem && mem_base)
  1233.     {
  1234.         for (i = 0; i < 16; i++)
  1235.             mem[len+i] = random_byte++;
  1236.         for (i = 0; i < 16 && mem - i > mem_base; i++)
  1237.             mem[-1-i] = random_byte++;
  1238. #if 0 || defined(LZO_DEBUG)
  1239.         /* fill in garbage */
  1240.         random_byte |= 1;
  1241.         for (i = 0; i < len; i++, random_byte += 2)
  1242.             mem[i] = random_byte;
  1243. #endif
  1244.     }
  1245. }
  1246.  
  1247.  
  1248. int check_mem ( lzo_byte *mem, lzo_byte *mem_base,
  1249.                 lzo_uint len, unsigned char random_byte )
  1250. {
  1251.     lzo_uint i;
  1252.  
  1253.     if (do_check_mem && mem && mem_base)
  1254.     {
  1255.         for (i = 0; i < 16; i++)
  1256.             if (mem[len+i] != random_byte++)
  1257.                 return -1;
  1258.         for (i = 0; i < 16 && mem - i > mem_base; i++)
  1259.             if (mem[-1-i] != random_byte++)
  1260.                 return -1;
  1261.     }
  1262.     return 0;
  1263. }
  1264.  
  1265.  
  1266. /*************************************************************************
  1267. // compress a block
  1268. **************************************************************************/
  1269.  
  1270. static
  1271. int do_compress ( const compress_t *c,
  1272.                   const lzo_byte *src, lzo_uint  src_len,
  1273.                         lzo_byte *dst, lzo_uint *dst_len )
  1274. {
  1275.     int r = -100;
  1276.  
  1277.     if (c && c->compress && WORK_LEN >= c->mem_compress)
  1278.     {
  1279.         unsigned char random_byte = (unsigned char) src_len;
  1280.         init_mem_checker(wrkmem,_wrkmem,c->mem_compress,random_byte);
  1281.  
  1282.         r = c->compress(src,src_len,dst,dst_len,wrkmem);
  1283.  
  1284.         if (check_mem(wrkmem,_wrkmem,c->mem_compress,random_byte) != 0)
  1285.             printf("WARNING: wrkmem overwrite error (compress) !!!\n");
  1286.     }
  1287.  
  1288.     if (r == 0 && opt_compute_adler32)
  1289.     {
  1290.         lzo_uint32 adler;
  1291.         adler = lzo_adler32(0, NULL, 0);
  1292.         adler = lzo_adler32(adler, src, src_len);
  1293.         adler_in = adler;
  1294.     }
  1295.     if (r == 0 && opt_compute_crc32)
  1296.     {
  1297.         lzo_uint32 crc;
  1298.         crc = lzo_crc32(0, NULL, 0);
  1299.         crc = lzo_crc32(crc, src, src_len);
  1300.         crc_in = crc;
  1301.     }
  1302.  
  1303.     return r;
  1304. }
  1305.  
  1306.  
  1307. /*************************************************************************
  1308. // decompress a block
  1309. **************************************************************************/
  1310.  
  1311. static
  1312. int do_decompress ( const compress_t *c, lzo_decompress_t d,
  1313.                     const lzo_byte *src, lzo_uint  src_len,
  1314.                           lzo_byte *dst, lzo_uint *dst_len )
  1315. {
  1316.     int r = -100;
  1317.  
  1318.        if (c && d && WORK_LEN >= c->mem_decompress)
  1319.     {
  1320.         unsigned char random_byte = (unsigned char) src_len;
  1321.         init_mem_checker(wrkmem,_wrkmem,c->mem_compress,random_byte);
  1322.  
  1323.         r = d(src,src_len,dst,dst_len,wrkmem);
  1324.  
  1325.         if (check_mem(wrkmem,_wrkmem,c->mem_compress,random_byte) != 0)
  1326.             printf("WARNING: wrkmem overwrite error (decompress) !!!\n");
  1327.     }
  1328.  
  1329.     if (r == 0 && opt_compute_adler32)
  1330.     {
  1331.         lzo_uint32 adler;
  1332.         adler = lzo_adler32(0, NULL, 0);
  1333.         adler = lzo_adler32(adler, dst, *dst_len);
  1334.         adler_out = adler;
  1335.     }
  1336.     if (r == 0 && opt_compute_crc32)
  1337.     {
  1338.         lzo_uint32 crc;
  1339.         crc = lzo_crc32(0, NULL, 0);
  1340.         crc = lzo_crc32(crc, dst, *dst_len);
  1341.         crc_out = crc;
  1342.     }
  1343.  
  1344.     return r;
  1345. }
  1346.  
  1347.  
  1348. /*************************************************************************
  1349. // optimize a block
  1350. **************************************************************************/
  1351.  
  1352. static
  1353. int do_optimize  ( const compress_t *c,
  1354.                          lzo_byte *src, lzo_uint  src_len,
  1355.                          lzo_byte *dst, lzo_uint *dst_len )
  1356. {
  1357.     if (c && c->optimize && WORK_LEN >= c->mem_decompress)
  1358.         return c->optimize(src,src_len,dst,dst_len,wrkmem);
  1359.     else
  1360.         return 0;
  1361. }
  1362.  
  1363.  
  1364. /***********************************************************************
  1365. // portable fread
  1366. ************************************************************************/
  1367.  
  1368. lzo_uint my_fread ( FILE *f, lzo_voidp s, lzo_uint len )
  1369. {
  1370. #if (LZO_UINT_MAX <= UINT_MAX) || defined(__LZO_TOS16)
  1371.     return fread(s,1,len,f);
  1372. #else
  1373.     lzo_byte *p = (lzo_byte *) s;
  1374.     lzo_uint l = 0;
  1375.     size_t k;
  1376.     unsigned char buf[512], *b;        /* don't use much stack on 16 bit systems */
  1377.  
  1378.     while (l < len)
  1379.     {
  1380.         k = len - l > sizeof(buf) ? sizeof(buf) : (size_t) (len - l);
  1381.         k = fread(buf,1,k,f);
  1382.         if (k <= 0)
  1383.             break;
  1384.         l += k;
  1385.         b = buf;
  1386.         do *p++ = *b++; while (--k > 0);
  1387.     }
  1388.     return l;
  1389. #endif
  1390. }
  1391.  
  1392.  
  1393. static const char *last_file = NULL;
  1394. static lzo_uint last_len = 0;
  1395.  
  1396. static void unload_file(void)
  1397. {
  1398.     last_file = NULL;
  1399. #ifdef USE_MALLOC
  1400.     if (_data)
  1401.     {
  1402.         free(_data);
  1403.         _data = NULL;
  1404.     }
  1405. #endif
  1406. }
  1407.  
  1408.  
  1409. int read_file ( const char *file_name, lzo_uint *len )
  1410. {
  1411.     FILE *f;
  1412.     long ll = -1;
  1413.     unsigned long ul;
  1414.     lzo_uint l;
  1415.     int r;
  1416.  
  1417. #if 0
  1418.     if (last_file && strcmp(file_name,last_file) == 0)
  1419.     {
  1420.         *len = last_len;
  1421.         return EXIT_OK;
  1422.     }
  1423. #endif
  1424.  
  1425.     *len = 0;
  1426.     unload_file();
  1427.  
  1428.     f = fopen(file_name,"rb");
  1429.     if (f == NULL)
  1430.     {
  1431.         fprintf(stderr,"%s: ",file_name);
  1432.         perror("fopen");
  1433.         fflush(stderr);
  1434.         return -1;            /* do not raise an error */
  1435.     }
  1436.     r = fseek(f,0,SEEK_END);
  1437.     if (r == 0)
  1438.     {
  1439.         ll = ftell(f);
  1440.         r = fseek(f,0,SEEK_SET);
  1441.     }
  1442.     if (r != 0 || ll < 0)
  1443.     {
  1444.         fprintf(stderr,"%s: ",file_name);
  1445.         perror("fseek");
  1446.         fflush(stderr);
  1447.         return EXIT_FILE;
  1448.     }
  1449.     ul = ll;
  1450.  
  1451. #ifdef USE_MALLOC
  1452.     l = (ul >= LZO_UINT_MAX - 512 ? LZO_UINT_MAX - 512 : (lzo_uint) ul);
  1453.     _data = malloc (l + 256);
  1454.     if (_data == NULL)
  1455.     {
  1456.         perror("malloc");
  1457.         fflush(stderr);
  1458.         return EXIT_MEM;
  1459.     }
  1460. #else
  1461.     l = (ul >= DATA_LEN ? DATA_LEN : (lzo_uint) ul);
  1462. #endif
  1463.     data = LZO_ALIGN(_data,256);
  1464.     l = my_fread(f,data,l);
  1465.     if (fclose(f) != 0)
  1466.     {
  1467.         unload_file();
  1468.         fprintf(stderr,"%s: ",file_name);
  1469.         perror("fclose");
  1470.         fflush(stderr);
  1471.         return EXIT_FILE;
  1472.     }
  1473.  
  1474.     last_file = file_name;
  1475.     last_len = l;
  1476.     *len = l;
  1477.     return EXIT_OK;
  1478. }
  1479.  
  1480.  
  1481. /***********************************************************************
  1482. // print some compression statistics
  1483. ************************************************************************/
  1484.  
  1485. static
  1486. void print_stats ( const char *method_name, const char *file_name,
  1487.                    int t_loops, int c_loops, int d_loops,
  1488.                    my_clock_t t_time, my_clock_t c_time, my_clock_t d_time,
  1489.                    unsigned long l, unsigned long t_len, unsigned blocks )
  1490. {
  1491.     unsigned long t_bytes, c_bytes, d_bytes;
  1492.     double t_secs, c_secs, d_secs;
  1493.     double t_kbs, c_kbs, d_kbs;
  1494.     double perc, bits;
  1495.  
  1496.     perc = (l > 0) ? t_len * 100.0 / l : 0;
  1497.     bits = perc * 0.08;
  1498.     t_secs = t_time / (double)(MY_CLOCKS_PER_SEC);
  1499.     t_bytes = (l * c_loops + l * d_loops) * t_loops;
  1500.     t_kbs = (t_secs > 0.001) ? (t_bytes / t_secs) / 1000.0 : 0;
  1501.     c_secs = c_time / (double)(MY_CLOCKS_PER_SEC);
  1502.     c_bytes = l * c_loops * t_loops;
  1503.     c_kbs = (c_secs > 0.001) ? (c_bytes / c_secs) / 1000.0 : 0;
  1504.     d_secs = d_time / (double)(MY_CLOCKS_PER_SEC);
  1505.     d_bytes = l * d_loops * t_loops;
  1506.     d_kbs = (d_secs > 0.001) ? (d_bytes / d_secs) / 1000.0 : 0;
  1507.  
  1508.     if (opt_verbose >= 2)
  1509.     {
  1510.         printf("  compressed into %lu bytes, %.2f%%   %.3f\n",
  1511.             (long) t_len, perc, bits);
  1512.  
  1513.         printf("%-15s %5d: ","overall", t_loops);
  1514.         printf("%10lu bytes, %8.2f secs, %10.2f KB/sec\n",
  1515.                 t_bytes, t_secs, t_kbs);
  1516.         printf("%-15s %5d: ","compress", c_loops);
  1517.         printf("%10lu bytes, %8.2f secs, %10.2f KB/sec\n",
  1518.                 c_bytes, c_secs, c_kbs);
  1519.         printf("%-15s %5d: ","decompress", d_loops);
  1520.         printf("%10lu bytes, %8.2f secs, %10.2f KB/sec\n",
  1521.                 d_bytes, d_secs, d_kbs);
  1522.         printf("\n");
  1523.     }
  1524.  
  1525.     /* create a line for util/table.pl */
  1526.     if (opt_verbose >= 1)
  1527.     {
  1528.         /* get basename */
  1529.         const char *n, *nn;
  1530.         for (nn = n = file_name; *nn; nn++)
  1531.             if (*nn == '/' || *nn == '\\' || *nn == ':')
  1532.                 n = nn + 1;
  1533.  
  1534.         printf("%-12s | %-14s %7ld %4d %7ld %6.1f %9.2f %9.2f |\n",
  1535.             method_name,
  1536.             n, (long) l, blocks, (long) t_len, perc, c_kbs, d_kbs);
  1537.     }
  1538.  
  1539.     if (opt_verbose >= 2)
  1540.         printf("\n");
  1541. }
  1542.  
  1543.  
  1544. /*************************************************************************
  1545. // compress and decompress a file
  1546. **************************************************************************/
  1547.  
  1548. static
  1549. int do_file ( int method, const char *file_name,
  1550.               int c_loops, int d_loops,
  1551.               lzo_uint32 *p_adler, lzo_uint32 *p_crc )
  1552. {
  1553.     const compress_t *c;
  1554.     lzo_decompress_t decompress;
  1555.     int i;
  1556.     const int t_loops = 1;
  1557.     unsigned blocks = 0;
  1558.     lzo_uint l;
  1559.     unsigned long t_len = 0;
  1560.     my_clock_t t_time = 0, c_time = 0, d_time = 0;
  1561.     my_clock_t t_start, c_start, d_start;
  1562.     lzo_uint32 adler, crc;
  1563.     char method_name[32];
  1564.     const char *n;
  1565.  
  1566.     adler_in = adler_out = 0;
  1567.     crc_in = crc_out = 0;
  1568.     if (p_adler)
  1569.         *p_adler = 0;
  1570.     if (p_crc)
  1571.         *p_crc = 0;
  1572.  
  1573.     c = info(method,NULL);
  1574.     if (c == NULL || c->name == NULL || c->compress == NULL)
  1575.         return EXIT_INTERNAL;
  1576.     decompress = get_decomp_info(c,&n);
  1577.     if (!decompress || n == NULL || WORK_LEN < c->mem_decompress)
  1578.         return EXIT_INTERNAL;
  1579.     strcpy(method_name,c->name);
  1580.     strcat(method_name,n);
  1581.  
  1582.     if (c_loops < 1)  c_loops = 1;
  1583.     if (d_loops < 1)  d_loops = 1;
  1584.  
  1585.     fflush(stdout); fflush(stderr);
  1586.  
  1587.     /* read the whole file */
  1588.     i = read_file(file_name,&l);
  1589.     if (i < 0)
  1590.         return 0;
  1591.     if (i > 0)
  1592.         return i;
  1593.  
  1594.     adler = lzo_adler32(0, NULL, 0);
  1595.     adler = lzo_adler32(adler, data, l);
  1596.     if (p_adler)
  1597.         *p_adler = adler;
  1598.     crc = lzo_crc32(0, NULL, 0);
  1599.     crc = lzo_crc32(crc, data, l);
  1600.     if (p_crc)
  1601.         *p_crc = crc;
  1602.  
  1603. #if 0 && defined(HAVE_ZLIB_H)
  1604.     {
  1605.         uLong x;
  1606.         x = adler32(0, Z_NULL, 0);
  1607.         x = adler32(x, data, l);
  1608.         if (x != adler)
  1609.             return EXIT_LZO_ERROR;
  1610.         x = crc32(0, Z_NULL, 0);
  1611.         x = crc32(x, data, l);
  1612.         if (x != crc)
  1613.             return EXIT_LZO_ERROR;
  1614.     }
  1615. #endif
  1616.  
  1617.     if (opt_verbose >= 2)
  1618.     {
  1619.         printf("File %s: %lu bytes   (0x%08lx, 0x%08lx)\n",
  1620.                 file_name, (long) l, (long) adler, (long) crc);
  1621.         printf("  compressing %lu bytes (%d/%d/%d loops, %lu block-size)\n",
  1622.                 (long) l, t_loops, c_loops, d_loops, (long) block_size);
  1623.         printf("  %s\n", method_name);
  1624.     }
  1625.  
  1626.     /* compress the file */
  1627.  
  1628.     t_start = my_clock();
  1629.     for (i = 0; i < t_loops; i++)
  1630.     {
  1631.         lzo_uint len, c_len, c_len_max, d_len;
  1632.         lzo_byte *d = data;
  1633.  
  1634.         len = l;
  1635.         t_len = 0;
  1636.         blocks = 0;
  1637.         if (len > 0 || try_to_compress_0_bytes) do
  1638.         {
  1639.             int j;
  1640.             int r;
  1641.  
  1642.             const lzo_uint bl = len > block_size ? block_size : len;
  1643.             lzo_uint bl_overwrite = bl;
  1644. #if !defined(__BOUNDS_CHECKING_ON)
  1645.             lzo_byte * const dd = d;
  1646.             lzo_byte * const b1 = block1;
  1647.             lzo_byte * const b2 = block2;
  1648.             unsigned char random_byte;
  1649.             random_byte = (unsigned char) my_clock();
  1650. #else
  1651.             lzo_byte *dd = d;
  1652.             lzo_byte *b1 = block1;
  1653.             lzo_byte *b2 = block2;
  1654. #endif
  1655.  
  1656.             if (opt_use_asm_fast_decompressor)
  1657.                 bl_overwrite += 3;        /* may overwrite 3 bytes past the end */
  1658.  
  1659.             blocks++;
  1660.  
  1661. #if defined(__BOUNDS_CHECKING_ON)
  1662.             /* malloc a block of the exact block size to detect
  1663.              * any overun.
  1664.              */
  1665.             dd = malloc(bl_overwrite);
  1666.             if (dd == NULL)
  1667.                 return EXIT_MEM;
  1668.             memcpy(dd,d,bl);
  1669.             b2 = dd;
  1670. #endif
  1671.  
  1672.         /* compress a block */
  1673.             c_len = c_len_max = 0;
  1674.             c_start = my_clock();
  1675.             for (j = r = 0; r == 0 && j < c_loops; j++)
  1676.             {
  1677.                 c_len = sizeof(_block1) - 256;
  1678.                 r = do_compress(c,dd,bl,b1,&c_len);
  1679.                 if (r == 0 && c_len > c_len_max)
  1680.                     c_len_max = c_len;
  1681.             }
  1682.             c_time += my_clock() - c_start;
  1683.             if (r != 0)
  1684.             {
  1685.                 printf("  compression failed in block %d (%d) (%lu %lu)\n",
  1686.                     blocks, r, (long)c_len, (long)bl);
  1687.                 return EXIT_LZO_ERROR;
  1688.             }
  1689.  
  1690.         /* optimize the block */
  1691.             if (opt_optimize_compressed_data)
  1692.             {
  1693.                 d_len = bl;
  1694.                 r = do_optimize(c,b1,c_len,b2,&d_len);
  1695.                 if (r != 0 || d_len != bl)
  1696.                 {
  1697.                     printf("  optimization failed in block %d (%d) "
  1698.                         "(%lu %lu %lu)\n", blocks, r,
  1699.                         (long)c_len, (long)d_len, (long)bl);
  1700.                     return EXIT_LZO_ERROR;
  1701.                 }
  1702.             }
  1703.  
  1704.         /* decompress the block and verify */
  1705. #if !defined(__BOUNDS_CHECKING_ON)
  1706.             init_mem_checker(b2,_block2,bl_overwrite,random_byte);
  1707. #else
  1708.             lzo_memset(b2,0,bl_overwrite);
  1709. #endif
  1710.             d_start = my_clock();
  1711.             for (j = r = 0; r == 0 && j < d_loops; j++)
  1712.             {
  1713.                 d_len = bl;
  1714.                 r = do_decompress(c,decompress,b1,c_len,b2,&d_len);
  1715.                 if (d_len != bl)
  1716.                     break;
  1717.             }
  1718.             d_time += my_clock() - d_start;
  1719.             if (r != 0)
  1720.             {
  1721.                 printf("  decompression failed in block %d (%d) "
  1722.                     "(%lu %lu %lu)\n", blocks, r,
  1723.                     (long)c_len, (long)d_len, (long)bl);
  1724.                 return EXIT_LZO_ERROR;
  1725.             }
  1726.             if (d_len != bl)
  1727.             {
  1728.                 printf("  decompression size error in block %d (%lu %lu %lu)\n",
  1729.                     blocks, (long)c_len, (long)d_len, (long)bl);
  1730.                 return EXIT_LZO_ERROR;
  1731.             }
  1732.             if (method <= M_LAST_COMPRESSOR)
  1733.             {
  1734.                 if (lzo_memcmp(d,b2,bl) != 0)
  1735.                 {
  1736.                     lzo_uint x = 0;
  1737.                     while (x < bl && b2[x] == d[x])
  1738.                         x++;
  1739.                     printf("  decompression data error in block %d at offset "
  1740.                         "%lu (%lu %lu)\n", blocks, (long)x,
  1741.                         (long)c_len, (long)d_len);
  1742.                     if (opt_compute_adler32)
  1743.                         printf("      checksum: 0x%08lx 0x%08lx\n",
  1744.                             (long)adler_in, (long)adler_out);
  1745. #if 0
  1746.                     printf("Orig:  ");
  1747.                     for (j = (x >= 10 ? -10 : 0); j <= 10 && x + j < bl; j++)
  1748.                         printf(" %02x", (int)b2[x+j]);
  1749.                     printf("\nDecomp:");
  1750.                     for (j = (x >= 10 ? -10 : 0); j <= 10 && x + j < bl; j++)
  1751.                         printf(" %02x", (int)d[x+j]);
  1752.                     printf("\n");
  1753. #endif
  1754.                     return EXIT_LZO_ERROR;
  1755.                 }
  1756.                 if ((opt_compute_adler32 && adler_in != adler_out) ||
  1757.                     (opt_compute_crc32 && crc_in != crc_out))
  1758.                 {
  1759.                     printf("  checksum error in block %d (%lu %lu)\n",
  1760.                         blocks, (long)c_len, (long)d_len);
  1761.                     printf("      adler32: 0x%08lx 0x%08lx\n",
  1762.                         (long)adler_in, (long)adler_out);
  1763.                     printf("      crc32: 0x%08lx 0x%08lx\n",
  1764.                         (long)crc_in, (long)crc_out);
  1765.                     return EXIT_LZO_ERROR;
  1766.                 }
  1767.             }
  1768. #if !defined(__BOUNDS_CHECKING_ON)
  1769.             if (check_mem(b2,_block2,bl_overwrite,random_byte) != 0)
  1770.             {
  1771.                 printf("  decompression overwrite error in block %d "
  1772.                     "(%lu %lu %lu)\n",
  1773.                     blocks, (long)c_len, (long)d_len, (long)bl);
  1774.                 return EXIT_LZO_ERROR;
  1775.             }
  1776. #endif
  1777.  
  1778. #if defined(__BOUNDS_CHECKING_ON)
  1779.             if (dd != d)
  1780.                 free(dd);
  1781. #endif
  1782.             d += bl;
  1783.             len -= bl;
  1784.             t_len += c_len_max;
  1785.         }
  1786.         while (len > 0);
  1787.     }
  1788.     t_time += my_clock() - t_start;
  1789.  
  1790.     print_stats(method_name, file_name,
  1791.                 t_loops, c_loops, d_loops,
  1792.                 t_time, c_time, d_time,
  1793.                 l, t_len, blocks);
  1794.  
  1795.     return EXIT_OK;
  1796. }
  1797.  
  1798.  
  1799. /*************************************************************************
  1800. // Calgary Corpus test suite driver
  1801. **************************************************************************/
  1802.  
  1803. static const struct
  1804. {
  1805.     const char *name;
  1806.     int loops;
  1807.     lzo_uint32 adler;
  1808.     lzo_uint32 crc;
  1809. }
  1810. corpus[] =
  1811. {
  1812.     { "bib",       8,  0x4bd09e98L, 0xb856ebe8L },
  1813.     { "book1",     1,  0xd4d3613eL, 0x24e19972L },
  1814.     { "book2",     1,  0x6fe14cc3L, 0xba0f3f26L },
  1815.     { "geo",       6,  0xf3cc5be0L, 0x4d3a6ed0L },
  1816.     { "news",      2,  0x2ed405b8L, 0xcafac853L },
  1817.     { "obj1",     35,  0x3887dd2cL, 0xc7b0cd26L },
  1818.     { "obj2",      4,  0xf89407c4L, 0x3ae33007L },
  1819.     { "paper1",   17,  0xfe65ce62L, 0x2b6baca0L },
  1820.     { "paper2",   11,  0x1238b7c2L, 0xf76cba72L },
  1821.     { "pic",       4,  0xf61a5702L, 0x4b17e59cL },
  1822.     { "progc",    25,  0x4c00ba45L, 0x6fb16094L },
  1823.     { "progl",    20,  0x4cba738eL, 0xddbf6baaL },
  1824.     { "progp",    28,  0x7495b92bL, 0x493a1809L },
  1825.     { "trans",    15,  0x52a2cec8L, 0xcdec06a6L },
  1826.     { NULL,        0,  0x00000000L, 0x00000000L },
  1827.     { "paper3",   30,  0x50b727a9L, 0x00000000L },
  1828.     { "paper4",   30,  0xcb4a305fL, 0x00000000L },
  1829.     { "paper5",   30,  0x2ca8a6f3L, 0x00000000L },
  1830.     { "paper6",   30,  0x9ddbcfa4L, 0x00000000L },
  1831.     { NULL,        0,  0x00000000L, 0x00000000L }
  1832. };
  1833.  
  1834.  
  1835. static
  1836. int do_corpus ( int method, const char *path, int c_loops, int d_loops )
  1837. {
  1838.     size_t i, n, size;
  1839.     char name[256];
  1840.  
  1841.     if (path == NULL || strlen(path) >= sizeof(name) - 12)
  1842.         return EXIT_USAGE;
  1843.  
  1844.     strcpy(name,path);
  1845.     n = strlen(name);
  1846.     if (n > 0 && name[n-1] != '/' && name[n-1] != '\\' && name[n-1] != ':')
  1847.     {
  1848.         strcat(name,"/");
  1849.         n++;
  1850.     }
  1851.  
  1852.     size = sizeof(corpus) / sizeof(*(corpus));
  1853.     for (i = 0; i < size && corpus[i].name != NULL; i++)
  1854.     {
  1855.         lzo_uint32 adler, crc;
  1856.         int c = c_loops * corpus[i].loops;
  1857.         int d = d_loops * corpus[i].loops;
  1858.         int r;
  1859.  
  1860.         strcpy(name+n,corpus[i].name);
  1861.         r = do_file(method, name, c, d, &adler, &crc);
  1862.         if (r != 0)
  1863.             return r;
  1864.         if (adler != corpus[i].adler)
  1865.         {
  1866.             printf("  invalid test suite\n");
  1867.             return EXIT_ADLER;
  1868.         }
  1869.         if (corpus[i].crc && crc != corpus[i].crc)
  1870.         {
  1871.             printf("  internal checksum error !!  (0x%08lx 0x%08lx)\n",
  1872.                     (long) crc, (long) corpus[i].crc);
  1873.             return EXIT_INTERNAL;
  1874.         }
  1875.     }
  1876.     return EXIT_OK;
  1877. }
  1878.  
  1879.  
  1880. /*************************************************************************
  1881. // usage
  1882. **************************************************************************/
  1883.  
  1884. static
  1885. void usage ( const char *name, int exit_code, lzo_bool show_methods )
  1886. {
  1887.     FILE *f;
  1888.     int i;
  1889.  
  1890.     f = stdout;
  1891.  
  1892.     fflush(stdout); fflush(stderr);
  1893.  
  1894.     fprintf(f,"Usage: %s [option..] file...\n", name);
  1895.     fprintf(f,"\n");
  1896.     fprintf(f,"Options:\n");
  1897.     fprintf(f,"  -m#     compression method\n");
  1898.     fprintf(f,"  -b#     set input block size (default %ld, max %ld)\n",
  1899.         (long) block_size, (long) MAX_BLOCK_SIZE);
  1900.     fprintf(f,"  -n#     number of compression/decompression runs\n");
  1901.     fprintf(f,"  -c#     number of compression runs\n");
  1902.     fprintf(f,"  -d#     number of decompression runs\n");
  1903.     fprintf(f,"  -S      use safe decompressor (if available)\n");
  1904.     fprintf(f,"  -A      use assembler decompressor (if available)\n");
  1905.     fprintf(f,"  -F      use fast assembler decompressor (if available)\n");
  1906.     fprintf(f,"  -O      optimize compressed data (if available)\n");
  1907.     fprintf(f,"  -s dir  process Calgary Corpus test suite in directory 'dir'\n");
  1908.     fprintf(f,"  -@      read list of files to compress from stdin\n");
  1909.     fprintf(f,"  -q      be quiet\n");
  1910.     fprintf(f,"  -Q      be very quiet\n");
  1911.     fprintf(f,"  -L      display software license\n");
  1912.  
  1913.     if (show_methods)
  1914.     {
  1915. #if defined(my_clock_desc)
  1916.         fprintf(f,"\nAll timings are recorded using %s.\n",my_clock_desc);
  1917. #endif
  1918.         fprintf(f,"\n\n");
  1919.         fprintf(f,"The following compression methods are available:\n");
  1920.         fprintf(f,"\n");
  1921.         fprintf(f,"  usage   name           memory          available extras\n");
  1922.         fprintf(f,"  -----   ----           ------          ----------------\n");
  1923.  
  1924.         for (i = 0; i <= M_LAST_COMPRESSOR; i++)
  1925.         {
  1926.             const compress_t *c;
  1927.             c = info(i,NULL);
  1928.             if (c)
  1929.             {
  1930.                 char n[16];
  1931.                 static const char * const s[3] = {"          ", ", ", ""};
  1932.                 int j = 0;
  1933.  
  1934.                 sprintf(n,"-m%d",i);
  1935.                 fprintf(f,"  %-6s  %-12s",n,c->name);
  1936.                 fprintf(f,"%6ld kB",((long)c->mem_compress + 1023) / 1024);
  1937.  
  1938.                 if (c->decompress_safe)
  1939.                     fprintf(f, "%s%s", j++ == 0 ? s[0] : s[1], "safe");
  1940.                 if (c->decompress_asm)
  1941.                     fprintf(f, "%s%s", j++ == 0 ? s[0] : s[1], "asm");
  1942.                 if (c->decompress_asm_safe)
  1943.                     fprintf(f, "%s%s", j++ == 0 ? s[0] : s[1], "asm+safe");
  1944.                 if (c->decompress_asm_fast)
  1945.                     fprintf(f, "%s%s", j++ == 0 ? s[0] : s[1], "fastasm");
  1946.                 if (c->decompress_asm_fast_safe)
  1947.                     fprintf(f, "%s%s", j++ == 0 ? s[0] : s[1], "fastasm+safe");
  1948.                 if (c->optimize)
  1949.                     fprintf(f, "%s%s", j++ == 0 ? s[0] : s[1], "optimize");
  1950.                 if (j > 0)
  1951.                     fprintf(f, s[2]);
  1952.                 fprintf(f,"\n");
  1953.             }
  1954.         }
  1955.     }
  1956.     else
  1957.     {
  1958.         fprintf(f,"\n");
  1959.         fprintf(f,"Type '%s -m' to list all available methods.\n", name);
  1960.     }
  1961.  
  1962.     fflush(f);
  1963.     if (exit_code < 0)
  1964.         exit_code = EXIT_USAGE;
  1965.     exit(exit_code);
  1966. }
  1967.  
  1968.  
  1969. static
  1970. void license(void)
  1971. {
  1972.     FILE *f;
  1973.  
  1974.     f = stdout;
  1975.  
  1976.     fflush(stdout); fflush(stderr);
  1977.  
  1978. fprintf(f,
  1979. "   The LZO library is free software; you can redistribute it and/or\n"
  1980. "   modify it under the terms of the GNU General Public License as\n"
  1981. "   published by the Free Software Foundation; either version 2 of\n"
  1982. "   the License, or (at your option) any later version.\n"
  1983. "\n"
  1984. "   The LZO library is distributed in the hope that it will be useful,\n"
  1985. "   but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
  1986. "   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
  1987. "   GNU General Public License for more details.\n"
  1988. "\n"
  1989. "   You should have received a copy of the GNU General Public License\n"
  1990. "   along with the LZO library; see the file COPYING.\n"
  1991. "   If not, write to the Free Software Foundation, Inc.,\n"
  1992. "   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"
  1993. "\n"
  1994. "   Markus F.X.J. Oberhumer\n"
  1995. "   <markus.oberhumer@jk.uni-linz.ac.at>\n"
  1996. "   http://www.infosys.tuwien.ac.at/Staff/lux/marco/lzo.html\n"
  1997. "\n"
  1998.     );
  1999.  
  2000.     fflush(f);
  2001.     exit(EXIT_OK);
  2002. }
  2003.  
  2004.  
  2005. /*************************************************************************
  2006. // main
  2007. **************************************************************************/
  2008.  
  2009. int main(int argc, char *argv[])
  2010. {
  2011.     int i = 1, ii, j = 0;
  2012.     int c_loops = 0;
  2013.     int d_loops = 0;
  2014.     int r = EXIT_OK;
  2015.     int method = default_method;
  2016.     const short *methods = NULL;
  2017.     const char *corpus_path = NULL;
  2018.     int a_method = 0;
  2019.     const char *argv0 = "";
  2020.     time_t t_total;
  2021.  
  2022. #if defined(__EMX__)
  2023.     _response(&argc,&argv);
  2024.     _wildcard(&argc,&argv);
  2025. #endif
  2026.  
  2027.     argv0 = argv[0];
  2028.     align_mem();
  2029.  
  2030.     printf("\nLZO real-time data compression library (v%s, %s).\n",
  2031.             LZO_VERSION_STRING, LZO_VERSION_DATE);
  2032.     printf("Copyright (C) 1996, 1997 Markus Franz Xaver Johannes Oberhumer\n\n");
  2033.  
  2034.     if (lzo_init() != LZO_E_OK)
  2035.     {
  2036.         printf("lzo_init() failed !!!\n");
  2037.         exit(EXIT_LZO_INIT);
  2038.     }
  2039.  
  2040.     if (argc < 2)
  2041.         usage(argv0,-1,0);
  2042.  
  2043.     if (i < argc && is_digit(argv[i][0]) && argv[i][0] > '0')
  2044.         method = atoi(&argv[i++][0]), methods = NULL;
  2045.  
  2046.     for ( ; i < argc && argv[i][0] == '-'; i++)
  2047.     {
  2048.         const char *p = argv[i];
  2049.  
  2050.         if (strcmp(p,"--") == 0)
  2051.         {
  2052.             i++;
  2053.             break;
  2054.         }
  2055.         else if (is_digit(p[1]))
  2056.             method = atoi(p+1), methods = NULL;
  2057.         else if (strncmp(p,"-m",2) == 0)
  2058.         {
  2059.             if (is_digit(p[2]))
  2060.                 method = atoi(p+2), methods = NULL;
  2061.             else if (strcmp(p,"-mall") == 0)
  2062.                 methods = all_methods;
  2063.             else if (strcmp(p,"-mavail") == 0)
  2064.                 methods = avail_methods;
  2065.             else if (strcmp(p,"-mbench") == 0)
  2066.                 methods = benchmark_methods;
  2067.             else if (strcmp(p,"-mlzo") == 0)
  2068.                 methods = lzo_methods;
  2069.             else if (strcmp(p,"-mx1") == 0)
  2070.                 methods = x1_methods;
  2071.             else if (strcmp(p,"-mx99") == 0)
  2072.                 methods = x99_methods;
  2073.             else if (strcmp(p,"-mx999") == 0)
  2074.                 methods = x999_methods;
  2075.             else if (strcmp(p,"-mzlib") == 0)
  2076.                 methods = zlib_methods;
  2077. #if defined(MFX)
  2078. #  include "contrib/t_opt_m.ch"
  2079. #endif
  2080.             else
  2081.                 usage(argv0,-1,1);
  2082.         }
  2083.         else if (strcmp(p,"-A") == 0)
  2084.             opt_use_asm_decompressor = 1;
  2085.         else if (strncmp(p,"--adler",7) == 0)
  2086.             opt_compute_adler32 = 1;
  2087.         else if (strncmp(p,"--crc",5) == 0)
  2088.             opt_compute_crc32 = 1;
  2089.         else if (strncmp(p,"-b",2) == 0)
  2090.         {
  2091.             if (is_digit(p[2]))
  2092.                 block_size = atoi(p+2);
  2093.             else
  2094.                 block_size = MAX_BLOCK_SIZE;
  2095.         }
  2096.         else if (strncmp(p,"-c",2) == 0 && is_digit(p[2]))
  2097.             c_loops = atoi(p+2);
  2098.         else if (strncmp(p,"-d",2) == 0 && is_digit(p[2]))
  2099.             d_loops = atoi(p+2);
  2100.         else if (strcmp(p,"-F") == 0)
  2101.             opt_use_asm_fast_decompressor = 1;
  2102.         else if (strcmp(p,"-h") == 0 || strcmp(p,"-?") == 0)
  2103.             usage(argv0,EXIT_OK,0);
  2104.         else if (strcmp(p,"--help") == 0)
  2105.             usage(argv0,EXIT_OK,0);
  2106.         else if (strcmp(p,"-L") == 0 || strcmp(p,"--license") == 0)
  2107.             license();
  2108.         else if (strncmp(p,"-n",2) == 0 && is_digit(p[2]))
  2109.             c_loops = atoi(p+2), d_loops = c_loops;
  2110.         else if (strcmp(p,"-O") == 0)
  2111.             opt_optimize_compressed_data = 1;
  2112.         else if (strcmp(p,"-q") == 0)
  2113.             opt_verbose = 1;
  2114.         else if (strcmp(p,"-Q") == 0)
  2115.             opt_verbose = 0;
  2116.         else if (strncmp(p,"-s",2) == 0 && i + 1 < argc)
  2117.         {
  2118.             if (is_digit(p[2]))
  2119.                 c_loops = atoi(p+2), d_loops = c_loops;
  2120.             corpus_path = argv[++i];
  2121.         }
  2122.         else if (strcmp(p,"-S") == 0)
  2123.             opt_use_safe_decompressor = 1;
  2124.         else if (strcmp(p,"-V") == 0 || strcmp(p,"--version") == 0)
  2125.             exit(EXIT_OK);
  2126.         else if (strcmp(p,"-@") == 0)
  2127.             opt_read_from_stdin = 1;
  2128.         else
  2129.         {
  2130.             printf("%s: invalid option '%s'\n\n",argv0,p);
  2131.             exit(EXIT_USAGE);
  2132.         }
  2133.     }
  2134.  
  2135.     if (methods != NULL && opt_read_from_stdin)
  2136.     {
  2137.         printf("%s: cannot use multiple methods and '-@'\n", argv0);
  2138.         exit(EXIT_USAGE);
  2139.     }
  2140.  
  2141.     if (block_size < 16)
  2142.         block_size = 16;
  2143.     if (block_size > MAX_BLOCK_SIZE)
  2144.         block_size = MAX_BLOCK_SIZE;
  2145.  
  2146.     t_total = time(NULL);
  2147.     ii = i;
  2148.     do {
  2149.         i = ii;
  2150.         if (i >= argc && corpus_path == NULL && !opt_read_from_stdin)
  2151.             usage(argv0,-1,0);
  2152.         if (methods != NULL && j == 0 && opt_verbose >= 1)
  2153.             printf("%lu block-size\n\n", (long) block_size);
  2154.  
  2155.         if (methods == avail_methods || methods == lzo_methods)
  2156.         {
  2157.             lzo_bool found = 0;
  2158.             int last = M_LAST_COMPRESSOR;
  2159.             if (methods == lzo_methods)
  2160.                 last = M_MEMCPY;
  2161.             while (!found && a_method <= last)
  2162.             {
  2163.                 method = a_method++;
  2164.                 found = (info(method,NULL) != NULL);
  2165.             }
  2166.             if (!found)
  2167.                 break;
  2168.         }
  2169.         else if (methods != NULL)
  2170.         {
  2171.             while ((method = *methods++) < 0)
  2172.                 ;
  2173.             if (method == 0)
  2174.                 break;
  2175.             if (!info(method,NULL))
  2176.                 info(method,stdout);
  2177.         }
  2178.         else
  2179.         {
  2180.             if (!info(method,NULL))
  2181.                 info(method,stdout);
  2182.             if (opt_verbose >= 1)
  2183.             {
  2184.                 info(method,stdout);
  2185.                 printf(" algorithm   %lu block-size\n\n", (long) block_size);
  2186.             }
  2187.         }
  2188.  
  2189.         if (corpus_path != NULL)
  2190.             r = do_corpus(method,corpus_path,c_loops,d_loops);
  2191.         else
  2192.         {
  2193.             for ( ; i < argc && r == EXIT_OK; i++)
  2194.                 r = do_file(method,argv[i],c_loops,d_loops,NULL,NULL);
  2195.             if (opt_read_from_stdin)
  2196.             {
  2197.                 char buf[512], *p;
  2198.  
  2199.                 while (r == EXIT_OK && fgets(buf,sizeof(buf)-1,stdin) != NULL)
  2200.                 {
  2201.                     buf[sizeof(buf)-1] = 0;
  2202.                     p = buf + strlen(buf);
  2203.                     if (p > buf)
  2204.                         while (--p > buf && is_space(*p))
  2205.                             *p = 0;
  2206.                     p = buf;
  2207.                     while (*p && is_space(*p))
  2208.                         p++;
  2209.                     if (*p)
  2210.                         r = do_file(method,p,c_loops,d_loops,NULL,NULL);
  2211.                 }
  2212.                 opt_read_from_stdin = 0;
  2213.             }
  2214.         }
  2215.         j++;
  2216.     }
  2217.     while (r == EXIT_OK && methods != NULL);
  2218.  
  2219.     if (r == EXIT_OK && methods != NULL && opt_verbose >= 1)
  2220.     {
  2221.         t_total = time(NULL) - t_total;
  2222.         printf("\nexecution time: %lu seconds\n", (long) t_total);
  2223.     }
  2224.  
  2225.     return r;
  2226. }
  2227.  
  2228. /*
  2229. vi:ts=4
  2230. */
  2231.  
  2232.