ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitCommon/OptIO/src/lzo1x_9x.c
Revision: 1.1
Committed: Tue Feb 24 11:56:43 2009 UTC (16 years, 2 months ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_032, Mit_031, Mit_025c_branch2, Mit_025c_branch1, Mit_030, Mit_029c, Mit_030_pre1, Mit_029a, Mit_029, Mit_029_pre1, Mit_028a, Mit_025c_branch0, Mit_028, Mit_027a, Mit_027, Mit_026, Mit_025e, Mit_025d, Mit_025c, Mit_025b, Mit_025a, Mit_025, Mit_025pre2, Mit_024b, Mit_025pre1, Mit_024a, Mit_024, Mit_023, Mit_022a, Mit_022, Mit_020d, TMit_020d, Mit_020c, Mit_021, Mit_021pre2, Mit_021pre1, Mit_020b, Mit_020a, Mit_020, Mit_020pre1, Mit_018, Mit_017, Mit_017pre3, Mit_017pre2, Mit_017pre1, V07-05-00, Mit_016, Mit_015b, Mit_015a, Mit_015, Mit_014e, Mit_014d, Mit_014c, Mit_014b, ConvRejection-10-06-09, Mit_014a, Mit_014, Mit_014pre3, Mit_014pre2, Mit_014pre1, Mit_013d, Mit_013c, Mit_013b, Mit_013a, Mit_013, Mit_013pre1, Mit_012i, Mit_012g, Mit_012f, Mit_012e, Mit_012d, Mit_012c, Mit_012b, Mit_012a, Mit_012, Mit_011a, Mit_011, Mit_010a, Mit_010, Mit_009c, Mit_009b, Mit_009a, Mit_009, Mit_008, Mit_008pre2, Mit_008pre1, HEAD
Branch point for: Mit_025c_branch
Log Message:
Preload lib for compression improvements.

File Contents

# User Rev Content
1 loizides 1.1 /* lzo1x_9x.c -- implementation of the LZO1X-999 compression algorithm
2    
3     This file is part of the LZO real-time data compression library.
4    
5     Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
6     Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
7     Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
8     Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
9     Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
10     Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
11     Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
12     Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
13     Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
14     Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
15     Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
16     Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
17     Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
18     All Rights Reserved.
19    
20     The LZO library is free software; you can redistribute it and/or
21     modify it under the terms of the GNU General Public License as
22     published by the Free Software Foundation; either version 2 of
23     the License, or (at your option) any later version.
24    
25     The LZO library is distributed in the hope that it will be useful,
26     but WITHOUT ANY WARRANTY; without even the implied warranty of
27     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28     GNU General Public License for more details.
29    
30     You should have received a copy of the GNU General Public License
31     along with the LZO library; see the file COPYING.
32     If not, write to the Free Software Foundation, Inc.,
33     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
34    
35     Markus F.X.J. Oberhumer
36     <markus@oberhumer.com>
37     http://www.oberhumer.com/opensource/lzo/
38     */
39    
40    
41     #if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z)
42     # define LZO1X
43     #endif
44    
45     #if defined(LZO1X)
46     # include "config1x.h"
47     #elif defined(LZO1Y)
48     # include "config1y.h"
49     #elif defined(LZO1Z)
50     # include "config1z.h"
51     #else
52     # error
53     #endif
54    
55    
56     /***********************************************************************
57     //
58     ************************************************************************/
59    
60     #define N M4_MAX_OFFSET /* size of ring buffer */
61     #define THRESHOLD 1 /* lower limit for match length */
62     #define F 2048 /* upper limit for match length */
63    
64     #define SWD_BEST_OFF (LZO_MAX3( M2_MAX_LEN, M3_MAX_LEN, M4_MAX_LEN ) + 1)
65    
66     #if defined(LZO1X)
67     # define LZO_COMPRESS_T lzo1x_999_t
68     # define lzo_swd_t lzo1x_999_swd_t
69     #elif defined(LZO1Y)
70     # define LZO_COMPRESS_T lzo1y_999_t
71     # define lzo_swd_t lzo1y_999_swd_t
72     # define lzo1x_999_compress_internal lzo1y_999_compress_internal
73     # define lzo1x_999_compress_dict lzo1y_999_compress_dict
74     # define lzo1x_999_compress_level lzo1y_999_compress_level
75     # define lzo1x_999_compress lzo1y_999_compress
76     #elif defined(LZO1Z)
77     # define LZO_COMPRESS_T lzo1z_999_t
78     # define lzo_swd_t lzo1z_999_swd_t
79     # define lzo1x_999_compress_internal lzo1z_999_compress_internal
80     # define lzo1x_999_compress_dict lzo1z_999_compress_dict
81     # define lzo1x_999_compress_level lzo1z_999_compress_level
82     # define lzo1x_999_compress lzo1z_999_compress
83     #else
84     # error
85     #endif
86    
87     #if 0
88     # define HEAD3(b,p) \
89     ((((((lzo_xint)b[p]<<3)^b[p+1])<<3)^b[p+2]) & (SWD_HSIZE-1))
90     #endif
91     #if 0 && defined(LZO_UNALIGNED_OK_4) && defined(LZO_ABI_LITTLE_ENDIAN)
92     # define HEAD3(b,p) \
93     (((* (lzo_uint32p) &b[p]) ^ ((* (lzo_uint32p) &b[p])>>10)) & (SWD_HSIZE-1))
94     #endif
95    
96     #include "lzo_mchw.ch"
97    
98    
99     /* this is a public functions, but there is no prototype in a header file */
100     LZO_EXTERN(int)
101     lzo1x_999_compress_internal ( const lzo_bytep in , lzo_uint in_len,
102     lzo_bytep out, lzo_uintp out_len,
103     lzo_voidp wrkmem,
104     const lzo_bytep dict, lzo_uint dict_len,
105     lzo_callback_p cb,
106     int try_lazy,
107     lzo_uint good_length,
108     lzo_uint max_lazy,
109     lzo_uint nice_length,
110     lzo_uint max_chain,
111     lzo_uint32 flags );
112    
113    
114     /***********************************************************************
115     //
116     ************************************************************************/
117    
118     static lzo_bytep
119     code_match ( LZO_COMPRESS_T *c, lzo_bytep op, lzo_uint m_len, lzo_uint m_off )
120     {
121     lzo_uint x_len = m_len;
122     lzo_uint x_off = m_off;
123    
124     c->match_bytes += (unsigned long) m_len;
125    
126     #if 0
127     /*
128     static lzo_uint last_m_len = 0, last_m_off = 0;
129     static lzo_uint prev_m_off[4];
130     static int prev_m_off_ptr = 0;
131     int i;
132    
133     //if (m_len >= 3 && m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET)
134     if (m_len >= 3 && m_len <= M2_MAX_LEN)
135     {
136     //if (m_len == last_m_len && m_off == last_m_off)
137     //printf("last_m_len + last_m_off\n");
138     //else
139     if (m_off == last_m_off)
140     printf("last_m_off\n");
141     else
142     {
143     for (i = 0; i < 4; i++)
144     if (m_off == prev_m_off[i])
145     printf("prev_m_off %d: %5ld\n",i,(long)m_off);
146     }
147     }
148     last_m_len = m_len;
149     last_m_off = prev_m_off[prev_m_off_ptr] = m_off;
150     prev_m_off_ptr = (prev_m_off_ptr + 1) & 3;
151     */
152     #endif
153    
154     assert(op > c->out);
155     if (m_len == 2)
156     {
157     assert(m_off <= M1_MAX_OFFSET);
158     assert(c->r1_lit > 0); assert(c->r1_lit < 4);
159     m_off -= 1;
160     #if defined(LZO1Z)
161     *op++ = LZO_BYTE(M1_MARKER | (m_off >> 6));
162     *op++ = LZO_BYTE(m_off << 2);
163     #else
164     *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2));
165     *op++ = LZO_BYTE(m_off >> 2);
166     #endif
167     c->m1a_m++;
168     }
169     #if defined(LZO1Z)
170     else if (m_len <= M2_MAX_LEN && (m_off <= M2_MAX_OFFSET || m_off == c->last_m_off))
171     #else
172     else if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET)
173     #endif
174     {
175     assert(m_len >= 3);
176     #if defined(LZO1X)
177     m_off -= 1;
178     *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2));
179     *op++ = LZO_BYTE(m_off >> 3);
180     assert(op[-2] >= M2_MARKER);
181     #elif defined(LZO1Y)
182     m_off -= 1;
183     *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2));
184     *op++ = LZO_BYTE(m_off >> 2);
185     assert(op[-2] >= M2_MARKER);
186     #elif defined(LZO1Z)
187     if (m_off == c->last_m_off)
188     *op++ = LZO_BYTE(((m_len - 1) << 5) | (0x700 >> 6));
189     else
190     {
191     m_off -= 1;
192     *op++ = LZO_BYTE(((m_len - 1) << 5) | (m_off >> 6));
193     *op++ = LZO_BYTE(m_off << 2);
194     }
195     #endif
196     c->m2_m++;
197     }
198     else if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET && c->r1_lit >= 4)
199     {
200     assert(m_len == 3);
201     assert(m_off > M2_MAX_OFFSET);
202     m_off -= 1 + M2_MAX_OFFSET;
203     #if defined(LZO1Z)
204     *op++ = LZO_BYTE(M1_MARKER | (m_off >> 6));
205     *op++ = LZO_BYTE(m_off << 2);
206     #else
207     *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2));
208     *op++ = LZO_BYTE(m_off >> 2);
209     #endif
210     c->m1b_m++;
211     }
212     else if (m_off <= M3_MAX_OFFSET)
213     {
214     assert(m_len >= 3);
215     m_off -= 1;
216     if (m_len <= M3_MAX_LEN)
217     *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
218     else
219     {
220     m_len -= M3_MAX_LEN;
221     *op++ = M3_MARKER | 0;
222     while (m_len > 255)
223     {
224     m_len -= 255;
225     *op++ = 0;
226     }
227     assert(m_len > 0);
228     *op++ = LZO_BYTE(m_len);
229     }
230     #if defined(LZO1Z)
231     *op++ = LZO_BYTE(m_off >> 6);
232     *op++ = LZO_BYTE(m_off << 2);
233     #else
234     *op++ = LZO_BYTE(m_off << 2);
235     *op++ = LZO_BYTE(m_off >> 6);
236     #endif
237     c->m3_m++;
238     }
239     else
240     {
241     lzo_uint k;
242    
243     assert(m_len >= 3);
244     assert(m_off > 0x4000); assert(m_off <= 0xbfff);
245     m_off -= 0x4000;
246     k = (m_off & 0x4000) >> 11;
247     if (m_len <= M4_MAX_LEN)
248     *op++ = LZO_BYTE(M4_MARKER | k | (m_len - 2));
249     else
250     {
251     m_len -= M4_MAX_LEN;
252     *op++ = LZO_BYTE(M4_MARKER | k | 0);
253     while (m_len > 255)
254     {
255     m_len -= 255;
256     *op++ = 0;
257     }
258     assert(m_len > 0);
259     *op++ = LZO_BYTE(m_len);
260     }
261     #if defined(LZO1Z)
262     *op++ = LZO_BYTE(m_off >> 6);
263     *op++ = LZO_BYTE(m_off << 2);
264     #else
265     *op++ = LZO_BYTE(m_off << 2);
266     *op++ = LZO_BYTE(m_off >> 6);
267     #endif
268     c->m4_m++;
269     }
270    
271     c->last_m_len = x_len;
272     c->last_m_off = x_off;
273     return op;
274     }
275    
276    
277     static lzo_bytep
278     STORE_RUN ( LZO_COMPRESS_T *c, lzo_bytep op, const lzo_bytep ii, lzo_uint t )
279     {
280     c->lit_bytes += (unsigned long) t;
281    
282     if (op == c->out && t <= 238)
283     {
284     *op++ = LZO_BYTE(17 + t);
285     }
286     else if (t <= 3)
287     {
288     #if defined(LZO1Z)
289     op[-1] |= LZO_BYTE(t);
290     #else
291     op[-2] |= LZO_BYTE(t);
292     #endif
293     c->lit1_r++;
294     }
295     else if (t <= 18)
296     {
297     *op++ = LZO_BYTE(t - 3);
298     c->lit2_r++;
299     }
300     else
301     {
302     lzo_uint tt = t - 18;
303    
304     *op++ = 0;
305     while (tt > 255)
306     {
307     tt -= 255;
308     *op++ = 0;
309     }
310     assert(tt > 0);
311     *op++ = LZO_BYTE(tt);
312     c->lit3_r++;
313     }
314     do *op++ = *ii++; while (--t > 0);
315    
316     return op;
317     }
318    
319    
320     static lzo_bytep
321     code_run ( LZO_COMPRESS_T *c, lzo_bytep op, const lzo_bytep ii,
322     lzo_uint lit, lzo_uint m_len )
323     {
324     if (lit > 0)
325     {
326     assert(m_len >= 2);
327     op = STORE_RUN(c,op,ii,lit);
328     c->r1_m_len = m_len;
329     c->r1_lit = lit;
330     }
331     else
332     {
333     assert(m_len >= 3);
334     c->r1_m_len = 0;
335     c->r1_lit = 0;
336     }
337    
338     return op;
339     }
340    
341    
342     /***********************************************************************
343     //
344     ************************************************************************/
345    
346     static int
347     len_of_coded_match ( lzo_uint m_len, lzo_uint m_off, lzo_uint lit )
348     {
349     int n = 4;
350    
351     if (m_len < 2)
352     return -1;
353     if (m_len == 2)
354     return (m_off <= M1_MAX_OFFSET && lit > 0 && lit < 4) ? 2 : -1;
355     if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET)
356     return 2;
357     if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET && lit >= 4)
358     return 2;
359     if (m_off <= M3_MAX_OFFSET)
360     {
361     if (m_len <= M3_MAX_LEN)
362     return 3;
363     m_len -= M3_MAX_LEN;
364     while (m_len > 255)
365     {
366     m_len -= 255;
367     n++;
368     }
369     return n;
370     }
371     if (m_off <= M4_MAX_OFFSET)
372     {
373     if (m_len <= M4_MAX_LEN)
374     return 3;
375     m_len -= M4_MAX_LEN;
376     while (m_len > 255)
377     {
378     m_len -= 255;
379     n++;
380     }
381     return n;
382     }
383     return -1;
384     }
385    
386    
387     static lzo_int
388     min_gain(lzo_uint ahead, lzo_uint lit1, lzo_uint lit2, int l1, int l2, int l3)
389     {
390     lzo_int lazy_match_min_gain = 0;
391    
392     assert (ahead >= 1);
393     lazy_match_min_gain += ahead;
394    
395     #if 0
396     if (l3 > 0)
397     lit2 -= ahead;
398     #endif
399    
400     if (lit1 <= 3)
401     lazy_match_min_gain += (lit2 <= 3) ? 0 : 2;
402     else if (lit1 <= 18)
403     lazy_match_min_gain += (lit2 <= 18) ? 0 : 1;
404    
405     lazy_match_min_gain += (l2 - l1) * 2;
406     if (l3 > 0)
407     lazy_match_min_gain -= (ahead - l3) * 2;
408    
409     if (lazy_match_min_gain < 0)
410     lazy_match_min_gain = 0;
411    
412     #if 0
413     if (l1 == 2)
414     if (lazy_match_min_gain == 0)
415     lazy_match_min_gain = 1;
416     #endif
417    
418     return lazy_match_min_gain;
419     }
420    
421    
422     /***********************************************************************
423     //
424     ************************************************************************/
425    
426     #if !defined(NDEBUG)
427     static
428     void assert_match( const lzo_swd_p swd, lzo_uint m_len, lzo_uint m_off )
429     {
430     const LZO_COMPRESS_T *c = swd->c;
431     lzo_uint d_off;
432    
433     assert(m_len >= 2);
434     if (m_off <= (lzo_uint) (c->bp - c->in))
435     {
436     assert(c->bp - m_off + m_len < c->ip);
437     assert(lzo_memcmp(c->bp, c->bp - m_off, m_len) == 0);
438     }
439     else
440     {
441     assert(swd->dict != NULL);
442     d_off = m_off - (lzo_uint) (c->bp - c->in);
443     assert(d_off <= swd->dict_len);
444     if (m_len > d_off)
445     {
446     assert(lzo_memcmp(c->bp, swd->dict_end - d_off, d_off) == 0);
447     assert(c->in + m_len - d_off < c->ip);
448     assert(lzo_memcmp(c->bp + d_off, c->in, m_len - d_off) == 0);
449     }
450     else
451     {
452     assert(lzo_memcmp(c->bp, swd->dict_end - d_off, m_len) == 0);
453     }
454     }
455     }
456     #else
457     # define assert_match(a,b,c) ((void)0)
458     #endif
459    
460    
461     #if defined(SWD_BEST_OFF)
462    
463     static void
464     better_match ( const lzo_swd_p swd, lzo_uint *m_len, lzo_uint *m_off )
465     {
466     #if defined(LZO1Z)
467     const LZO_COMPRESS_T *c = swd->c;
468     #endif
469    
470     if (*m_len <= M2_MIN_LEN)
471     return;
472     #if defined(LZO1Z)
473     if (*m_off == c->last_m_off && *m_len <= M2_MAX_LEN)
474     return;
475     #if 1
476     if (*m_len >= M2_MIN_LEN + 1 && *m_len <= M2_MAX_LEN + 1 &&
477     c->last_m_off && swd->best_off[*m_len-1] == c->last_m_off)
478     {
479     *m_len = *m_len - 1;
480     *m_off = swd->best_off[*m_len];
481     return;
482     }
483     #endif
484     #endif
485    
486     if (*m_off <= M2_MAX_OFFSET)
487     return;
488    
489     #if 1
490     /* M3/M4 -> M2 */
491     if (*m_off > M2_MAX_OFFSET &&
492     *m_len >= M2_MIN_LEN + 1 && *m_len <= M2_MAX_LEN + 1 &&
493     swd->best_off[*m_len-1] && swd->best_off[*m_len-1] <= M2_MAX_OFFSET)
494     {
495     *m_len = *m_len - 1;
496     *m_off = swd->best_off[*m_len];
497     return;
498     }
499     #endif
500    
501     #if 1
502     /* M4 -> M2 */
503     if (*m_off > M3_MAX_OFFSET &&
504     *m_len >= M4_MAX_LEN + 1 && *m_len <= M2_MAX_LEN + 2 &&
505     swd->best_off[*m_len-2] && swd->best_off[*m_len-2] <= M2_MAX_OFFSET)
506     {
507     *m_len = *m_len - 2;
508     *m_off = swd->best_off[*m_len];
509     return;
510     }
511     #endif
512    
513     #if 1
514     /* M4 -> M3 */
515     if (*m_off > M3_MAX_OFFSET &&
516     *m_len >= M4_MAX_LEN + 1 && *m_len <= M3_MAX_LEN + 1 &&
517     swd->best_off[*m_len-1] && swd->best_off[*m_len-1] <= M3_MAX_OFFSET)
518     {
519     *m_len = *m_len - 1;
520     *m_off = swd->best_off[*m_len];
521     }
522     #endif
523     }
524    
525     #endif
526    
527    
528     /***********************************************************************
529     //
530     ************************************************************************/
531    
532     LZO_PUBLIC(int)
533     lzo1x_999_compress_internal ( const lzo_bytep in , lzo_uint in_len,
534     lzo_bytep out, lzo_uintp out_len,
535     lzo_voidp wrkmem,
536     const lzo_bytep dict, lzo_uint dict_len,
537     lzo_callback_p cb,
538     int try_lazy,
539     lzo_uint good_length,
540     lzo_uint max_lazy,
541     lzo_uint nice_length,
542     lzo_uint max_chain,
543     lzo_uint32 flags )
544     {
545     lzo_bytep op;
546     const lzo_bytep ii;
547     lzo_uint lit;
548     lzo_uint m_len, m_off;
549     LZO_COMPRESS_T cc;
550     LZO_COMPRESS_T * const c = &cc;
551     lzo_swd_p const swd = (lzo_swd_p) wrkmem;
552     int r;
553    
554     /* sanity check */
555     #if defined(LZO1X)
556     LZO_COMPILE_TIME_ASSERT(LZO1X_999_MEM_COMPRESS >= SIZEOF_LZO_SWD_T)
557     #elif defined(LZO1Y)
558     LZO_COMPILE_TIME_ASSERT(LZO1Y_999_MEM_COMPRESS >= SIZEOF_LZO_SWD_T)
559     #elif defined(LZO1Z)
560     LZO_COMPILE_TIME_ASSERT(LZO1Z_999_MEM_COMPRESS >= SIZEOF_LZO_SWD_T)
561     #else
562     # error
563     #endif
564    
565     /* setup parameter defaults */
566     /* number of lazy match tries */
567     if (try_lazy < 0)
568     try_lazy = 1;
569     /* reduce lazy match search if we already have a match with this length */
570     if (good_length <= 0)
571     good_length = 32;
572     /* do not try a lazy match if we already have a match with this length */
573     if (max_lazy <= 0)
574     max_lazy = 32;
575     /* stop searching for longer matches than this one */
576     if (nice_length <= 0)
577     nice_length = 0;
578     /* don't search more positions than this */
579     if (max_chain <= 0)
580     max_chain = SWD_MAX_CHAIN;
581    
582     c->init = 0;
583     c->ip = c->in = in;
584     c->in_end = in + in_len;
585     c->out = out;
586     c->cb = cb;
587     c->m1a_m = c->m1b_m = c->m2_m = c->m3_m = c->m4_m = 0;
588     c->lit1_r = c->lit2_r = c->lit3_r = 0;
589    
590     op = out;
591     ii = c->ip; /* point to start of literal run */
592     lit = 0;
593     c->r1_lit = c->r1_m_len = 0;
594    
595     r = init_match(c,swd,dict,dict_len,flags);
596     if (r != 0)
597     return r;
598     if (max_chain > 0)
599     swd->max_chain = max_chain;
600     if (nice_length > 0)
601     swd->nice_length = nice_length;
602    
603     r = find_match(c,swd,0,0);
604     if (r != 0)
605     return r;
606     while (c->look > 0)
607     {
608     lzo_uint ahead;
609     lzo_uint max_ahead;
610     int l1, l2, l3;
611    
612     c->codesize = pd(op, out);
613    
614     m_len = c->m_len;
615     m_off = c->m_off;
616    
617     assert(c->bp == c->ip - c->look);
618     assert(c->bp >= in);
619     if (lit == 0)
620     ii = c->bp;
621     assert(ii + lit == c->bp);
622     assert(swd->b_char == *(c->bp));
623    
624     if ( m_len < 2 ||
625     (m_len == 2 && (m_off > M1_MAX_OFFSET || lit == 0 || lit >= 4)) ||
626     #if 1
627     /* Do not accept this match for compressed-data compatibility
628     * with LZO v1.01 and before
629     * [ might be a problem for decompress() and optimize() ]
630     */
631     (m_len == 2 && op == out) ||
632     #endif
633     (op == out && lit == 0))
634     {
635     /* a literal */
636     m_len = 0;
637     }
638     else if (m_len == M2_MIN_LEN)
639     {
640     /* compression ratio improves if we code a literal in some cases */
641     if (m_off > MX_MAX_OFFSET && lit >= 4)
642     m_len = 0;
643     }
644    
645     if (m_len == 0)
646     {
647     /* a literal */
648     lit++;
649     swd->max_chain = max_chain;
650     r = find_match(c,swd,1,0);
651     assert(r == 0);
652     continue;
653     }
654    
655     /* a match */
656     #if defined(SWD_BEST_OFF)
657     if (swd->use_best_off)
658     better_match(swd,&m_len,&m_off);
659     #endif
660     assert_match(swd,m_len,m_off);
661    
662    
663    
664     /* shall we try a lazy match ? */
665     ahead = 0;
666     if (try_lazy <= 0 || m_len >= max_lazy)
667     {
668     /* no */
669     l1 = 0;
670     max_ahead = 0;
671     }
672     else
673     {
674     /* yes, try a lazy match */
675     l1 = len_of_coded_match(m_len,m_off,lit);
676     assert(l1 > 0);
677     #if 1
678     max_ahead = LZO_MIN((lzo_uint)try_lazy, (lzo_uint)l1 - 1);
679     #else
680     max_ahead = LZO_MIN3(try_lazy, l1, m_len - 1);
681     #endif
682     }
683    
684    
685     while (ahead < max_ahead && c->look > m_len)
686     {
687     lzo_int lazy_match_min_gain;
688    
689     if (m_len >= good_length)
690     swd->max_chain = max_chain >> 2;
691     else
692     swd->max_chain = max_chain;
693     r = find_match(c,swd,1,0);
694     ahead++;
695    
696     assert(r == 0);
697     assert(c->look > 0);
698     assert(ii + lit + ahead == c->bp);
699    
700     #if defined(LZO1Z)
701     if (m_off == c->last_m_off && c->m_off != c->last_m_off)
702     if (m_len >= M2_MIN_LEN && m_len <= M2_MAX_LEN)
703     c->m_len = 0;
704     #endif
705     if (c->m_len < m_len)
706     continue;
707     #if 1
708     if (c->m_len == m_len && c->m_off >= m_off)
709     continue;
710     #endif
711     #if defined(SWD_BEST_OFF)
712     if (swd->use_best_off)
713     better_match(swd,&c->m_len,&c->m_off);
714     #endif
715     l2 = len_of_coded_match(c->m_len,c->m_off,lit+ahead);
716     if (l2 < 0)
717     continue;
718     #if 0
719     if (c->m_len == m_len && l2 >= l1)
720     continue;
721     #endif
722    
723    
724     #if 1
725     /* compressed-data compatibility [see above] */
726     l3 = (op == out) ? -1 : len_of_coded_match(ahead,m_off,lit);
727     #else
728     l3 = len_of_coded_match(ahead,m_off,lit);
729     #endif
730    
731     lazy_match_min_gain = min_gain(ahead,lit,lit+ahead,l1,l2,l3);
732     if (c->m_len >= m_len + lazy_match_min_gain)
733     {
734     c->lazy++;
735     assert_match(swd,c->m_len,c->m_off);
736    
737     if (l3 > 0)
738     {
739     /* code previous run */
740     op = code_run(c,op,ii,lit,ahead);
741     lit = 0;
742     /* code shortened match */
743     op = code_match(c,op,ahead,m_off);
744     }
745     else
746     {
747     lit += ahead;
748     assert(ii + lit == c->bp);
749     }
750     goto lazy_match_done;
751     }
752     }
753    
754    
755     assert(ii + lit + ahead == c->bp);
756    
757     /* 1 - code run */
758     op = code_run(c,op,ii,lit,m_len);
759     lit = 0;
760    
761     /* 2 - code match */
762     op = code_match(c,op,m_len,m_off);
763     swd->max_chain = max_chain;
764     r = find_match(c,swd,m_len,1+ahead);
765     assert(r == 0);
766    
767     lazy_match_done: ;
768     }
769    
770    
771     /* store final run */
772     if (lit > 0)
773     op = STORE_RUN(c,op,ii,lit);
774    
775     #if defined(LZO_EOF_CODE)
776     *op++ = M4_MARKER | 1;
777     *op++ = 0;
778     *op++ = 0;
779     #endif
780    
781     c->codesize = pd(op, out);
782     assert(c->textsize == in_len);
783    
784     *out_len = pd(op, out);
785    
786     if (c->cb && c->cb->nprogress)
787     (*c->cb->nprogress)(c->cb, c->textsize, c->codesize, 0);
788    
789     #if 0
790     printf("%ld %ld -> %ld %ld: %ld %ld %ld %ld %ld %ld: %ld %ld %ld %ld\n",
791     (long) c->textsize, (long) in_len, (long) c->codesize,
792     c->match_bytes, c->m1a_m, c->m1b_m, c->m2_m, c->m3_m, c->m4_m,
793     c->lit_bytes, c->lit1_r, c->lit2_r, c->lit3_r, c->lazy);
794     #endif
795     assert(c->lit_bytes + c->match_bytes == in_len);
796    
797     return LZO_E_OK;
798     }
799    
800    
801     /***********************************************************************
802     //
803     ************************************************************************/
804    
805     LZO_PUBLIC(int)
806     lzo1x_999_compress_level ( const lzo_bytep in , lzo_uint in_len,
807     lzo_bytep out, lzo_uintp out_len,
808     lzo_voidp wrkmem,
809     const lzo_bytep dict, lzo_uint dict_len,
810     lzo_callback_p cb,
811     int compression_level )
812     {
813     static const struct
814     {
815     int try_lazy;
816     lzo_uint good_length;
817     lzo_uint max_lazy;
818     lzo_uint nice_length;
819     lzo_uint max_chain;
820     lzo_uint32 flags;
821     } c[9] = {
822     { 0, 0, 0, 8, 4, 0 }, /* faster compression */
823     { 0, 0, 0, 16, 8, 0 },
824     { 0, 0, 0, 32, 16, 0 },
825    
826     { 1, 4, 4, 16, 16, 0 },
827     { 1, 8, 16, 32, 32, 0 },
828     { 1, 8, 16, 128, 128, 0 },
829    
830     { 2, 8, 32, 128, 256, 0 },
831     { 2, 32, 128, F, 2048, 1 },
832     { 2, F, F, F, 4096, 1 } /* max. compression */
833     };
834    
835     if (compression_level < 1 || compression_level > 9)
836     return LZO_E_ERROR;
837    
838     compression_level -= 1;
839     return lzo1x_999_compress_internal(in, in_len, out, out_len, wrkmem,
840     dict, dict_len, cb,
841     c[compression_level].try_lazy,
842     c[compression_level].good_length,
843     c[compression_level].max_lazy,
844     #if 0
845     c[compression_level].nice_length,
846     #else
847     0,
848     #endif
849     c[compression_level].max_chain,
850     c[compression_level].flags);
851     }
852    
853    
854     /***********************************************************************
855     //
856     ************************************************************************/
857    
858     LZO_PUBLIC(int)
859     lzo1x_999_compress_dict ( const lzo_bytep in , lzo_uint in_len,
860     lzo_bytep out, lzo_uintp out_len,
861     lzo_voidp wrkmem,
862     const lzo_bytep dict, lzo_uint dict_len )
863     {
864     return lzo1x_999_compress_level(in, in_len, out, out_len, wrkmem,
865     dict, dict_len, 0, 8);
866     }
867    
868     LZO_PUBLIC(int)
869     lzo1x_999_compress ( const lzo_bytep in , lzo_uint in_len,
870     lzo_bytep out, lzo_uintp out_len,
871     lzo_voidp wrkmem )
872     {
873     return lzo1x_999_compress_level(in, in_len, out, out_len, wrkmem,
874     NULL, 0, (lzo_callback_p) 0, 8);
875     }
876    
877    
878     /*
879     vi:ts=4:et
880     */
881