dict.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /* dict.c -- example program: how to use preset dictionaries
  2. This file is part of the LZO real-time data compression library.
  3. Copyright (C) 1996-2015 Markus Franz Xaver Johannes Oberhumer
  4. All Rights Reserved.
  5. The LZO library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of
  8. the License, or (at your option) any later version.
  9. The LZO library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with the LZO library; see the file COPYING.
  15. If not, write to the Free Software Foundation, Inc.,
  16. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. Markus F.X.J. Oberhumer
  18. <markus@oberhumer.com>
  19. http://www.oberhumer.com/opensource/lzo/
  20. */
  21. /*************************************************************************
  22. // This program shows how to use preset dictionaries.
  23. //
  24. // Please study LZO.FAQ and simple.c first.
  25. **************************************************************************/
  26. #include <lzo/lzoconf.h>
  27. #include <lzo/lzo1x.h>
  28. /* portability layer */
  29. static const char *progname = NULL;
  30. #define WANT_LZO_MALLOC 1
  31. #define WANT_LZO_FREAD 1
  32. #define WANT_LZO_WILDARGV 1
  33. #define WANT_XMALLOC 1
  34. #include "examples/portab.h"
  35. #define DICT_LEN 0xbfff
  36. static lzo_bytep dict;
  37. static lzo_uint dict_len = 0;
  38. static lzo_uint32_t dict_adler32;
  39. /*************************************************************************
  40. //
  41. **************************************************************************/
  42. static lzo_uint total_n = 0;
  43. static lzo_uint total_c_len = 0;
  44. static lzo_uint total_d_len = 0;
  45. static void print_info(const char *name, lzo_uint d_len, lzo_uint c_len)
  46. {
  47. double perc;
  48. perc = (d_len > 0) ? c_len * 100.0 / d_len : 0.0;
  49. printf(" | %-30s %9ld -> %9ld %7.2f%% |\n",
  50. name, (long) d_len, (long) c_len, perc);
  51. total_n++;
  52. total_c_len += c_len;
  53. total_d_len += d_len;
  54. }
  55. /*************************************************************************
  56. //
  57. **************************************************************************/
  58. static int do_file(const char *in_name, int compression_level)
  59. {
  60. int r;
  61. lzo_bytep in;
  62. lzo_bytep out;
  63. lzo_bytep newb;
  64. lzo_voidp wrkmem;
  65. lzo_uint in_len;
  66. lzo_uint out_len;
  67. lzo_uint new_len;
  68. long l;
  69. FILE *fp;
  70. /*
  71. * Step 1: open the input file
  72. */
  73. fp = fopen(in_name,"rb");
  74. if (fp == NULL)
  75. {
  76. printf("%s: %s: cannot open file\n", progname, in_name);
  77. return 0; /* no error */
  78. }
  79. fseek(fp, 0, SEEK_END);
  80. l = ftell(fp);
  81. fseek(fp, 0, SEEK_SET);
  82. if (l <= 0)
  83. {
  84. printf("%s: %s: empty file -- skipping\n", progname, in_name);
  85. fclose(fp); fp = NULL;
  86. return 0; /* no error */
  87. }
  88. in_len = (lzo_uint) l;
  89. if ((long) in_len != l || l > 256L * 1024L * 1024L)
  90. {
  91. printf("%s: %s: file is too big -- skipping\n", progname, in_name);
  92. fclose(fp); fp = NULL;
  93. return 0; /* no error */
  94. }
  95. /*
  96. * Step 2: allocate compression buffers and read the file
  97. */
  98. in = (lzo_bytep) xmalloc(in_len);
  99. out = (lzo_bytep) xmalloc(in_len + in_len / 16 + 64 + 3);
  100. newb = (lzo_bytep) xmalloc(in_len);
  101. wrkmem = (lzo_voidp) xmalloc(LZO1X_999_MEM_COMPRESS);
  102. if (in == NULL || out == NULL || newb == NULL || wrkmem == NULL)
  103. {
  104. printf("%s: out of memory\n", progname);
  105. exit(1);
  106. }
  107. in_len = (lzo_uint) lzo_fread(fp, in, in_len);
  108. fclose(fp); fp = NULL;
  109. /*
  110. * Step 3: compress from 'in' to 'out' with LZO1X-999
  111. */
  112. r = lzo1x_999_compress_level(in,in_len,out,&out_len,wrkmem,
  113. dict, dict_len, 0, compression_level);
  114. if (r != LZO_E_OK)
  115. {
  116. /* this should NEVER happen */
  117. printf("internal error - compression failed: %d\n", r);
  118. return 1;
  119. }
  120. print_info(in_name, in_len, out_len);
  121. /*
  122. * Step 4: decompress again, now going from 'out' to 'newb'
  123. */
  124. new_len = in_len;
  125. r = lzo1x_decompress_dict_safe(out, out_len, newb, &new_len, NULL, dict, dict_len);
  126. if (r != LZO_E_OK)
  127. {
  128. /* this should NEVER happen */
  129. printf("internal error - decompression failed: %d\n", r);
  130. return 1;
  131. }
  132. /*
  133. * Step 5: verify decompression
  134. */
  135. if (new_len != in_len || lzo_memcmp(in, newb, in_len) != 0)
  136. {
  137. /* this should NEVER happen */
  138. printf("internal error - decompression data error\n");
  139. return 1;
  140. }
  141. /* free buffers in reverse order to help malloc() */
  142. lzo_free(wrkmem);
  143. lzo_free(newb);
  144. lzo_free(out);
  145. lzo_free(in);
  146. return 0;
  147. }
  148. /*************************************************************************
  149. //
  150. **************************************************************************/
  151. int __lzo_cdecl_main main(int argc, char *argv[])
  152. {
  153. int i = 1;
  154. int r = 0;
  155. const char *dict_name;
  156. FILE *fp;
  157. time_t t_total;
  158. int compression_level = 7;
  159. lzo_wildargv(&argc, &argv);
  160. printf("\nLZO real-time data compression library (v%s, %s).\n",
  161. lzo_version_string(), lzo_version_date());
  162. printf("Copyright (C) 1996-2015 Markus Franz Xaver Johannes Oberhumer\nAll Rights Reserved.\n\n");
  163. progname = argv[0];
  164. if (i < argc && argv[i][0] == '-' && isdigit(argv[i][1]))
  165. compression_level = atoi(&argv[i++][1]);
  166. if (i + 1 >= argc || compression_level < 1 || compression_level > 9)
  167. {
  168. printf("usage: %s [-level] [ dictionary-file | -n ] file...\n", progname);
  169. exit(1);
  170. }
  171. printf("Compression level is LZO1X-999/%d\n", compression_level);
  172. /*
  173. * Step 1: initialize the LZO library
  174. */
  175. if (lzo_init() != LZO_E_OK)
  176. {
  177. printf("internal error - lzo_init() failed !!!\n");
  178. printf("(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable '-DLZO_DEBUG' for diagnostics)\n");
  179. exit(1);
  180. }
  181. /*
  182. * Step 2: prepare the dictionary
  183. */
  184. dict = (lzo_bytep) xmalloc(DICT_LEN);
  185. if (dict == NULL)
  186. {
  187. printf("%s: out of memory\n", progname);
  188. exit(1);
  189. }
  190. dict_name = argv[i++];
  191. if (strcmp(dict_name,"-n") == 0)
  192. {
  193. dict_name = "empty";
  194. dict_len = 0;
  195. }
  196. else
  197. {
  198. fp = fopen(dict_name,"rb");
  199. if (fp == NULL)
  200. {
  201. printf("%s: cannot open dictionary file %s\n", progname, dict_name);
  202. exit(1);
  203. }
  204. dict_len = (lzo_uint) lzo_fread(fp, dict, DICT_LEN);
  205. fclose(fp); fp = NULL;
  206. }
  207. dict_adler32 = lzo_adler32(0, NULL, 0);
  208. dict_adler32 = lzo_adler32(dict_adler32, dict, dict_len);
  209. printf("Using dictionary '%s', %ld bytes, ID 0x%08lx.\n",
  210. dict_name, (long) dict_len, (unsigned long) dict_adler32);
  211. /*
  212. * Step 3: process files
  213. */
  214. t_total = time(NULL);
  215. for ( ; i < argc; i++) {
  216. if (do_file(argv[i], compression_level) != 0) {
  217. r = 1;
  218. break;
  219. }
  220. }
  221. t_total = time(NULL) - t_total;
  222. lzo_free(dict);
  223. if (total_n > 1)
  224. print_info("***TOTALS***", total_d_len, total_c_len);
  225. printf("Dictionary compression test %s, execution time %lu seconds.\n",
  226. r == 0 ? "passed" : "FAILED", (unsigned long) t_total);
  227. return r;
  228. }
  229. /* vim:set ts=4 sw=4 et: */