1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39#include "libbb.h"
40
41
42#define LZO_UNALIGNED_OK_2
43#define LZO_UNALIGNED_OK_4
44
45#include "liblzo.h"
46
47#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b))
48#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b))
49#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c))
50
51
52
53
54#define SWD_N M4_MAX_OFFSET
55#define SWD_F 2048
56
57#define SWD_BEST_OFF (LZO_MAX3(M2_MAX_LEN, M3_MAX_LEN, M4_MAX_LEN) + 1)
58
59typedef struct {
60 int init;
61
62 unsigned look;
63
64 unsigned m_len;
65 unsigned m_off;
66
67 const uint8_t *bp;
68 const uint8_t *ip;
69 const uint8_t *in;
70 const uint8_t *in_end;
71 uint8_t *out;
72
73 unsigned r1_lit;
74} lzo1x_999_t;
75
76#define getbyte(c) ((c).ip < (c).in_end ? *((c).ip)++ : (-1))
77
78
79
80
81
82
83#define SWD_UINT_MAX USHRT_MAX
84
85#ifndef SWD_HSIZE
86# define SWD_HSIZE 16384
87#endif
88#ifndef SWD_MAX_CHAIN
89# define SWD_MAX_CHAIN 2048
90#endif
91
92#define HEAD3(b, p) \
93 ( ((0x9f5f * ((((b[p]<<5)^b[p+1])<<5) ^ b[p+2])) >> 5) & (SWD_HSIZE-1) )
94
95#if defined(LZO_UNALIGNED_OK_2)
96# define HEAD2(b,p) (* (bb__aliased_uint16_t *) &(b[p]))
97#else
98# define HEAD2(b,p) (b[p] ^ ((unsigned)b[p+1]<<8))
99#endif
100#define NIL2 SWD_UINT_MAX
101
102typedef struct lzo_swd {
103
104
105
106 unsigned max_chain;
107 int use_best_off;
108
109
110 unsigned m_len;
111 unsigned m_off;
112 unsigned look;
113 int b_char;
114#if defined(SWD_BEST_OFF)
115 unsigned best_off[SWD_BEST_OFF];
116#endif
117
118
119 lzo1x_999_t *c;
120 unsigned m_pos;
121#if defined(SWD_BEST_OFF)
122 unsigned best_pos[SWD_BEST_OFF];
123#endif
124
125
126 unsigned ip;
127 unsigned bp;
128 unsigned rp;
129
130 unsigned node_count;
131 unsigned first_rp;
132
133 uint8_t b[SWD_N + SWD_F];
134 uint8_t b_wrap[SWD_F];
135 uint16_t head3[SWD_HSIZE];
136 uint16_t succ3[SWD_N + SWD_F];
137 uint16_t best3[SWD_N + SWD_F];
138 uint16_t llen3[SWD_HSIZE];
139#ifdef HEAD2
140 uint16_t head2[65536L];
141#endif
142} lzo_swd_t, *lzo_swd_p;
143
144#define SIZEOF_LZO_SWD_T (sizeof(lzo_swd_t))
145
146
147
148
149
150#define s_get_head3(s,key) s->head3[key]
151
152
153
154
155
156#define B_SIZE (SWD_N + SWD_F)
157
158static int swd_init(lzo_swd_p s)
159{
160
161 s->node_count = SWD_N;
162
163 memset(s->llen3, 0, sizeof(s->llen3[0]) * (unsigned)SWD_HSIZE);
164#ifdef HEAD2
165 memset(s->head2, 0xff, sizeof(s->head2[0]) * 65536L);
166 assert(s->head2[0] == NIL2);
167#endif
168
169 s->ip = 0;
170 s->bp = s->ip;
171 s->first_rp = s->ip;
172
173 assert(s->ip + SWD_F <= B_SIZE);
174 s->look = (unsigned) (s->c->in_end - s->c->ip);
175 if (s->look > 0) {
176 if (s->look > SWD_F)
177 s->look = SWD_F;
178 memcpy(&s->b[s->ip], s->c->ip, s->look);
179 s->c->ip += s->look;
180 s->ip += s->look;
181 }
182 if (s->ip == B_SIZE)
183 s->ip = 0;
184
185 s->rp = s->first_rp;
186 if (s->rp >= s->node_count)
187 s->rp -= s->node_count;
188 else
189 s->rp += B_SIZE - s->node_count;
190
191 return LZO_E_OK;
192}
193
194#define swd_pos2off(s,pos) \
195 (s->bp > (pos) ? s->bp - (pos) : B_SIZE - ((pos) - s->bp))
196
197
198
199
200
201static void swd_getbyte(lzo_swd_p s)
202{
203 int c;
204
205 if ((c = getbyte(*(s->c))) < 0) {
206 if (s->look > 0)
207 --s->look;
208 } else {
209 s->b[s->ip] = c;
210 if (s->ip < SWD_F)
211 s->b_wrap[s->ip] = c;
212 }
213 if (++s->ip == B_SIZE)
214 s->ip = 0;
215 if (++s->bp == B_SIZE)
216 s->bp = 0;
217 if (++s->rp == B_SIZE)
218 s->rp = 0;
219}
220
221
222
223
224
225static void swd_remove_node(lzo_swd_p s, unsigned node)
226{
227 if (s->node_count == 0) {
228 unsigned key;
229
230 key = HEAD3(s->b,node);
231 assert(s->llen3[key] > 0);
232 --s->llen3[key];
233
234#ifdef HEAD2
235 key = HEAD2(s->b,node);
236 assert(s->head2[key] != NIL2);
237 if ((unsigned) s->head2[key] == node)
238 s->head2[key] = NIL2;
239#endif
240 } else
241 --s->node_count;
242}
243
244
245
246
247
248static void swd_accept(lzo_swd_p s, unsigned n)
249{
250 assert(n <= s->look);
251
252 while (n--) {
253 unsigned key;
254
255 swd_remove_node(s,s->rp);
256
257
258 key = HEAD3(s->b, s->bp);
259 s->succ3[s->bp] = s_get_head3(s, key);
260 s->head3[key] = s->bp;
261 s->best3[s->bp] = SWD_F + 1;
262 s->llen3[key]++;
263 assert(s->llen3[key] <= SWD_N);
264
265#ifdef HEAD2
266
267 key = HEAD2(s->b, s->bp);
268 s->head2[key] = s->bp;
269#endif
270
271 swd_getbyte(s);
272 }
273}
274
275
276
277
278
279static void swd_search(lzo_swd_p s, unsigned node, unsigned cnt)
280{
281 const uint8_t *p1;
282 const uint8_t *p2;
283 const uint8_t *px;
284 unsigned m_len = s->m_len;
285 const uint8_t *b = s->b;
286 const uint8_t *bp = s->b + s->bp;
287 const uint8_t *bx = s->b + s->bp + s->look;
288 unsigned char scan_end1;
289
290 assert(s->m_len > 0);
291
292 scan_end1 = bp[m_len - 1];
293 for ( ; cnt-- > 0; node = s->succ3[node]) {
294 p1 = bp;
295 p2 = b + node;
296 px = bx;
297
298 assert(m_len < s->look);
299
300 if (p2[m_len - 1] == scan_end1
301 && p2[m_len] == p1[m_len]
302 && p2[0] == p1[0]
303 && p2[1] == p1[1]
304 ) {
305 unsigned i;
306 assert(lzo_memcmp(bp, &b[node], 3) == 0);
307
308 p1 += 2; p2 += 2;
309 do {} while (++p1 < px && *p1 == *++p2);
310 i = p1-bp;
311
312 assert(lzo_memcmp(bp, &b[node], i) == 0);
313
314#if defined(SWD_BEST_OFF)
315 if (i < SWD_BEST_OFF) {
316 if (s->best_pos[i] == 0)
317 s->best_pos[i] = node + 1;
318 }
319#endif
320 if (i > m_len) {
321 s->m_len = m_len = i;
322 s->m_pos = node;
323 if (m_len == s->look)
324 return;
325 if (m_len >= SWD_F)
326 return;
327 if (m_len > (unsigned) s->best3[node])
328 return;
329 scan_end1 = bp[m_len - 1];
330 }
331 }
332 }
333}
334
335
336
337
338
339#ifdef HEAD2
340
341static int swd_search2(lzo_swd_p s)
342{
343 unsigned key;
344
345 assert(s->look >= 2);
346 assert(s->m_len > 0);
347
348 key = s->head2[HEAD2(s->b, s->bp)];
349 if (key == NIL2)
350 return 0;
351 assert(lzo_memcmp(&s->b[s->bp], &s->b[key], 2) == 0);
352#if defined(SWD_BEST_OFF)
353 if (s->best_pos[2] == 0)
354 s->best_pos[2] = key + 1;
355#endif
356
357 if (s->m_len < 2) {
358 s->m_len = 2;
359 s->m_pos = key;
360 }
361 return 1;
362}
363
364#endif
365
366
367
368
369
370static void swd_findbest(lzo_swd_p s)
371{
372 unsigned key;
373 unsigned cnt, node;
374 unsigned len;
375
376 assert(s->m_len > 0);
377
378
379 key = HEAD3(s->b,s->bp);
380 node = s->succ3[s->bp] = s_get_head3(s, key);
381 cnt = s->llen3[key]++;
382 assert(s->llen3[key] <= SWD_N + SWD_F);
383 if (cnt > s->max_chain)
384 cnt = s->max_chain;
385 s->head3[key] = s->bp;
386
387 s->b_char = s->b[s->bp];
388 len = s->m_len;
389 if (s->m_len >= s->look) {
390 if (s->look == 0)
391 s->b_char = -1;
392 s->m_off = 0;
393 s->best3[s->bp] = SWD_F + 1;
394 } else {
395#ifdef HEAD2
396 if (swd_search2(s))
397#endif
398 if (s->look >= 3)
399 swd_search(s, node, cnt);
400 if (s->m_len > len)
401 s->m_off = swd_pos2off(s,s->m_pos);
402 s->best3[s->bp] = s->m_len;
403
404#if defined(SWD_BEST_OFF)
405 if (s->use_best_off) {
406 int i;
407 for (i = 2; i < SWD_BEST_OFF; i++) {
408 if (s->best_pos[i] > 0)
409 s->best_off[i] = swd_pos2off(s, s->best_pos[i]-1);
410 else
411 s->best_off[i] = 0;
412 }
413 }
414#endif
415 }
416
417 swd_remove_node(s,s->rp);
418
419#ifdef HEAD2
420
421 key = HEAD2(s->b, s->bp);
422 s->head2[key] = s->bp;
423#endif
424}
425
426#undef HEAD3
427#undef HEAD2
428#undef s_get_head3
429
430
431
432
433
434static int init_match(lzo1x_999_t *c, lzo_swd_p s, uint32_t use_best_off)
435{
436 int r;
437
438 assert(!c->init);
439 c->init = 1;
440
441 s->c = c;
442
443 r = swd_init(s);
444 if (r != 0)
445 return r;
446
447 s->use_best_off = use_best_off;
448 return r;
449}
450
451
452
453
454
455static int find_match(lzo1x_999_t *c, lzo_swd_p s,
456 unsigned this_len, unsigned skip)
457{
458 assert(c->init);
459
460 if (skip > 0) {
461 assert(this_len >= skip);
462 swd_accept(s, this_len - skip);
463 } else {
464 assert(this_len <= 1);
465 }
466
467 s->m_len = 1;
468#ifdef SWD_BEST_OFF
469 if (s->use_best_off)
470 memset(s->best_pos, 0, sizeof(s->best_pos));
471#endif
472 swd_findbest(s);
473 c->m_len = s->m_len;
474 c->m_off = s->m_off;
475
476 swd_getbyte(s);
477
478 if (s->b_char < 0) {
479 c->look = 0;
480 c->m_len = 0;
481 } else {
482 c->look = s->look + 1;
483 }
484 c->bp = c->ip - c->look;
485
486 return LZO_E_OK;
487}
488
489
490static int lzo1x_999_compress_internal(const uint8_t *in, unsigned in_len,
491 uint8_t *out, unsigned *out_len,
492 void *wrkmem,
493 unsigned good_length,
494 unsigned max_lazy,
495 unsigned max_chain,
496 uint32_t use_best_off);
497
498
499
500
501
502static uint8_t *code_match(lzo1x_999_t *c,
503 uint8_t *op, unsigned m_len, unsigned m_off)
504{
505 assert(op > c->out);
506 if (m_len == 2) {
507 assert(m_off <= M1_MAX_OFFSET);
508 assert(c->r1_lit > 0);
509 assert(c->r1_lit < 4);
510 m_off -= 1;
511 *op++ = M1_MARKER | ((m_off & 3) << 2);
512 *op++ = m_off >> 2;
513 } else if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) {
514 assert(m_len >= 3);
515 m_off -= 1;
516 *op++ = ((m_len - 1) << 5) | ((m_off & 7) << 2);
517 *op++ = m_off >> 3;
518 assert(op[-2] >= M2_MARKER);
519 } else if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET && c->r1_lit >= 4) {
520 assert(m_len == 3);
521 assert(m_off > M2_MAX_OFFSET);
522 m_off -= 1 + M2_MAX_OFFSET;
523 *op++ = M1_MARKER | ((m_off & 3) << 2);
524 *op++ = m_off >> 2;
525 } else if (m_off <= M3_MAX_OFFSET) {
526 assert(m_len >= 3);
527 m_off -= 1;
528 if (m_len <= M3_MAX_LEN)
529 *op++ = M3_MARKER | (m_len - 2);
530 else {
531 m_len -= M3_MAX_LEN;
532 *op++ = M3_MARKER | 0;
533 while (m_len > 255) {
534 m_len -= 255;
535 *op++ = 0;
536 }
537 assert(m_len > 0);
538 *op++ = m_len;
539 }
540 *op++ = m_off << 2;
541 *op++ = m_off >> 6;
542 } else {
543 unsigned k;
544
545 assert(m_len >= 3);
546 assert(m_off > 0x4000);
547 assert(m_off <= 0xbfff);
548 m_off -= 0x4000;
549 k = (m_off & 0x4000) >> 11;
550 if (m_len <= M4_MAX_LEN)
551 *op++ = M4_MARKER | k | (m_len - 2);
552 else {
553 m_len -= M4_MAX_LEN;
554 *op++ = M4_MARKER | k | 0;
555 while (m_len > 255) {
556 m_len -= 255;
557 *op++ = 0;
558 }
559 assert(m_len > 0);
560 *op++ = m_len;
561 }
562 *op++ = m_off << 2;
563 *op++ = m_off >> 6;
564 }
565
566 return op;
567}
568
569
570static uint8_t *STORE_RUN(lzo1x_999_t *c, uint8_t *op,
571 const uint8_t *ii, unsigned t)
572{
573 if (op == c->out && t <= 238) {
574 *op++ = 17 + t;
575 } else if (t <= 3) {
576 op[-2] |= t;
577 } else if (t <= 18) {
578 *op++ = t - 3;
579 } else {
580 unsigned tt = t - 18;
581
582 *op++ = 0;
583 while (tt > 255) {
584 tt -= 255;
585 *op++ = 0;
586 }
587 assert(tt > 0);
588 *op++ = tt;
589 }
590 do *op++ = *ii++; while (--t > 0);
591
592 return op;
593}
594
595
596static uint8_t *code_run(lzo1x_999_t *c, uint8_t *op, const uint8_t *ii,
597 unsigned lit)
598{
599 if (lit > 0) {
600 assert(m_len >= 2);
601 op = STORE_RUN(c, op, ii, lit);
602 } else {
603 assert(m_len >= 3);
604 }
605 c->r1_lit = lit;
606
607 return op;
608}
609
610
611
612
613
614static int len_of_coded_match(unsigned m_len, unsigned m_off, unsigned lit)
615{
616 int n = 4;
617
618 if (m_len < 2)
619 return -1;
620 if (m_len == 2)
621 return (m_off <= M1_MAX_OFFSET && lit > 0 && lit < 4) ? 2 : -1;
622 if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET)
623 return 2;
624 if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET && lit >= 4)
625 return 2;
626 if (m_off <= M3_MAX_OFFSET) {
627 if (m_len <= M3_MAX_LEN)
628 return 3;
629 m_len -= M3_MAX_LEN;
630 } else if (m_off <= M4_MAX_OFFSET) {
631 if (m_len <= M4_MAX_LEN)
632 return 3;
633 m_len -= M4_MAX_LEN;
634 } else
635 return -1;
636 while (m_len > 255) {
637 m_len -= 255;
638 n++;
639 }
640 return n;
641}
642
643
644static int min_gain(unsigned ahead, unsigned lit1,
645 unsigned lit2, int l1, int l2, int l3)
646{
647 int lazy_match_min_gain = 0;
648
649 assert (ahead >= 1);
650 lazy_match_min_gain += ahead;
651
652 if (lit1 <= 3)
653 lazy_match_min_gain += (lit2 <= 3) ? 0 : 2;
654 else if (lit1 <= 18)
655 lazy_match_min_gain += (lit2 <= 18) ? 0 : 1;
656
657 lazy_match_min_gain += (l2 - l1) * 2;
658 if (l3 > 0)
659 lazy_match_min_gain -= (ahead - l3) * 2;
660
661 if (lazy_match_min_gain < 0)
662 lazy_match_min_gain = 0;
663
664 return lazy_match_min_gain;
665}
666
667
668
669
670
671#if defined(SWD_BEST_OFF)
672
673static void better_match(const lzo_swd_p swd,
674 unsigned *m_len, unsigned *m_off)
675{
676 if (*m_len <= M2_MIN_LEN)
677 return;
678
679 if (*m_off <= M2_MAX_OFFSET)
680 return;
681
682
683 if (*m_off > M2_MAX_OFFSET
684 && *m_len >= M2_MIN_LEN + 1 && *m_len <= M2_MAX_LEN + 1
685 && swd->best_off[*m_len-1] && swd->best_off[*m_len-1] <= M2_MAX_OFFSET
686 ) {
687 *m_len = *m_len - 1;
688 *m_off = swd->best_off[*m_len];
689 return;
690 }
691
692
693 if (*m_off > M3_MAX_OFFSET
694 && *m_len >= M4_MAX_LEN + 1 && *m_len <= M2_MAX_LEN + 2
695 && swd->best_off[*m_len-2] && swd->best_off[*m_len-2] <= M2_MAX_OFFSET
696 ) {
697 *m_len = *m_len - 2;
698 *m_off = swd->best_off[*m_len];
699 return;
700 }
701
702 if (*m_off > M3_MAX_OFFSET
703 && *m_len >= M4_MAX_LEN + 1 && *m_len <= M3_MAX_LEN + 1
704 && swd->best_off[*m_len-1] && swd->best_off[*m_len-1] <= M3_MAX_OFFSET
705 ) {
706 *m_len = *m_len - 1;
707 *m_off = swd->best_off[*m_len];
708 }
709}
710
711#endif
712
713
714
715
716
717static int lzo1x_999_compress_internal(const uint8_t *in, unsigned in_len,
718 uint8_t *out, unsigned *out_len,
719 void *wrkmem,
720 unsigned good_length,
721 unsigned max_lazy,
722 unsigned max_chain,
723 uint32_t use_best_off)
724{
725 uint8_t *op;
726 const uint8_t *ii;
727 unsigned lit;
728 unsigned m_len, m_off;
729 lzo1x_999_t cc;
730 lzo1x_999_t *const c = &cc;
731 const lzo_swd_p swd = (lzo_swd_p) wrkmem;
732 int r;
733
734 c->init = 0;
735 c->ip = c->in = in;
736 c->in_end = in + in_len;
737 c->out = out;
738
739 op = out;
740 ii = c->ip;
741 lit = 0;
742 c->r1_lit = 0;
743
744 r = init_match(c, swd, use_best_off);
745 if (r != 0)
746 return r;
747 swd->max_chain = max_chain;
748
749 r = find_match(c, swd, 0, 0);
750 if (r != 0)
751 return r;
752
753 while (c->look > 0) {
754 unsigned ahead;
755 unsigned max_ahead;
756 int l1, l2, l3;
757
758 m_len = c->m_len;
759 m_off = c->m_off;
760
761 assert(c->bp == c->ip - c->look);
762 assert(c->bp >= in);
763 if (lit == 0)
764 ii = c->bp;
765 assert(ii + lit == c->bp);
766 assert(swd->b_char == *(c->bp));
767
768 if (m_len < 2
769 || (m_len == 2 && (m_off > M1_MAX_OFFSET || lit == 0 || lit >= 4))
770
771
772
773
774 || (m_len == 2 && op == out)
775 || (op == out && lit == 0)
776 ) {
777
778 m_len = 0;
779 }
780 else if (m_len == M2_MIN_LEN) {
781
782 if (m_off > MX_MAX_OFFSET && lit >= 4)
783 m_len = 0;
784 }
785
786 if (m_len == 0) {
787
788 lit++;
789 swd->max_chain = max_chain;
790 r = find_match(c, swd, 1, 0);
791 assert(r == 0);
792 continue;
793 }
794
795
796#if defined(SWD_BEST_OFF)
797 if (swd->use_best_off)
798 better_match(swd, &m_len, &m_off);
799#endif
800
801
802 ahead = 0;
803 if (m_len >= max_lazy) {
804
805 l1 = 0;
806 max_ahead = 0;
807 } else {
808
809 l1 = len_of_coded_match(m_len, m_off, lit);
810 assert(l1 > 0);
811 max_ahead = LZO_MIN(2, (unsigned)l1 - 1);
812 }
813
814
815 while (ahead < max_ahead && c->look > m_len) {
816 int lazy_match_min_gain;
817
818 if (m_len >= good_length)
819 swd->max_chain = max_chain >> 2;
820 else
821 swd->max_chain = max_chain;
822 r = find_match(c, swd, 1, 0);
823 ahead++;
824
825 assert(r == 0);
826 assert(c->look > 0);
827 assert(ii + lit + ahead == c->bp);
828
829 if (c->m_len < m_len)
830 continue;
831 if (c->m_len == m_len && c->m_off >= m_off)
832 continue;
833#if defined(SWD_BEST_OFF)
834 if (swd->use_best_off)
835 better_match(swd, &c->m_len, &c->m_off);
836#endif
837 l2 = len_of_coded_match(c->m_len, c->m_off, lit+ahead);
838 if (l2 < 0)
839 continue;
840
841
842 l3 = (op == out) ? -1 : len_of_coded_match(ahead, m_off, lit);
843
844 lazy_match_min_gain = min_gain(ahead, lit, lit+ahead, l1, l2, l3);
845 if (c->m_len >= m_len + lazy_match_min_gain) {
846 if (l3 > 0) {
847
848 op = code_run(c, op, ii, lit);
849 lit = 0;
850
851 op = code_match(c, op, ahead, m_off);
852 } else {
853 lit += ahead;
854 assert(ii + lit == c->bp);
855 }
856 goto lazy_match_done;
857 }
858 }
859
860 assert(ii + lit + ahead == c->bp);
861
862
863 op = code_run(c, op, ii, lit);
864 lit = 0;
865
866
867 op = code_match(c, op, m_len, m_off);
868 swd->max_chain = max_chain;
869 r = find_match(c, swd, m_len, 1+ahead);
870 assert(r == 0);
871
872 lazy_match_done: ;
873 }
874
875
876 if (lit > 0)
877 op = STORE_RUN(c, op, ii, lit);
878
879#if defined(LZO_EOF_CODE)
880 *op++ = M4_MARKER | 1;
881 *op++ = 0;
882 *op++ = 0;
883#endif
884
885 *out_len = op - out;
886
887 return LZO_E_OK;
888}
889
890
891
892
893
894int lzo1x_999_compress_level(const uint8_t *in, unsigned in_len,
895 uint8_t *out, unsigned *out_len,
896 void *wrkmem,
897 int compression_level)
898{
899 static const struct {
900 uint16_t good_length;
901 uint16_t max_lazy;
902 uint16_t max_chain;
903 uint16_t use_best_off;
904 } c[3] = {
905 { 8, 32, 256, 0 },
906 { 32, 128, 2048, 1 },
907 { SWD_F, SWD_F, 4096, 1 }
908 };
909
910 if (compression_level < 7 || compression_level > 9)
911 return LZO_E_ERROR;
912
913 compression_level -= 7;
914 return lzo1x_999_compress_internal(in, in_len, out, out_len, wrkmem,
915 c[compression_level].good_length,
916 c[compression_level].max_lazy,
917 c[compression_level].max_chain,
918 c[compression_level].use_best_off);
919}
920