ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitCommon/OptIO/src/lzo1x_oo.ch
Revision: 1.1
Committed: Tue Feb 24 11:56:43 2009 UTC (16 years, 2 months ago) by loizides
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_oo.ch -- LZO1X compressed data optimizer
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     #define TEST_IP (ip < ip_end)
42     #define TEST_OP (op <= op_end)
43    
44     #define NO_LIT LZO_UINT_MAX
45    
46    
47     /***********************************************************************
48     //
49     ************************************************************************/
50    
51     static void copy2(lzo_bytep ip, const lzo_bytep m_pos, lzo_uint off)
52     {
53     assert(off > 0);
54     ip[0] = m_pos[0];
55     if (off == 1)
56     ip[1] = m_pos[0];
57     else
58     ip[1] = m_pos[1];
59     }
60    
61    
62     static void copy3(lzo_bytep ip, const lzo_bytep m_pos, lzo_uint off)
63     {
64     assert(off > 0);
65     ip[0] = m_pos[0];
66     if (off == 1)
67     {
68     ip[2] = ip[1] = m_pos[0];
69     }
70     else if (off == 2)
71     {
72     ip[1] = m_pos[1];
73     ip[2] = m_pos[0];
74     }
75     else
76     {
77     ip[1] = m_pos[1];
78     ip[2] = m_pos[2];
79     }
80     }
81    
82    
83     /***********************************************************************
84     // optimize a block of data.
85     ************************************************************************/
86    
87     LZO_PUBLIC(int)
88     DO_OPTIMIZE ( lzo_bytep in , lzo_uint in_len,
89     lzo_bytep out, lzo_uintp out_len,
90     lzo_voidp wrkmem )
91     {
92     lzo_bytep op;
93     lzo_bytep ip;
94     lzo_uint t;
95     lzo_bytep m_pos;
96     lzo_bytep const ip_end = in + in_len;
97     lzo_bytep const op_end = out + *out_len;
98     lzo_bytep litp = NULL;
99     lzo_uint lit = 0;
100     lzo_uint next_lit = NO_LIT;
101     lzo_uint nl;
102     unsigned long o_m1_a = 0, o_m1_b = 0, o_m2 = 0, o_m3_a = 0, o_m3_b = 0;
103    
104     LZO_UNUSED(wrkmem);
105    
106     *out_len = 0;
107    
108     op = out;
109     ip = in;
110    
111     assert(in_len >= 3);
112     if (*ip > 17)
113     {
114     t = *ip++ - 17;
115     if (t < 4)
116     goto match_next;
117     goto first_literal_run;
118     }
119     assert(*ip < 16 || (*ip == 17 && in_len == 3));
120    
121     while (TEST_IP && TEST_OP)
122     {
123     t = *ip++;
124     if (t >= 16)
125     goto match;
126     /* a literal run */
127     litp = ip - 1;
128     if (t == 0)
129     {
130     t = 15;
131     while (*ip == 0)
132     t += 255, ip++;
133     t += *ip++;
134     }
135     lit = t + 3;
136     /* copy literals */
137     copy_literal_run:
138     *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
139     first_literal_run:
140     do *op++ = *ip++; while (--t > 0);
141    
142    
143     t = *ip++;
144    
145     if (t >= 16)
146     goto match;
147     #if defined(LZO1X)
148     m_pos = op - 1 - 0x800;
149     #elif defined(LZO1Y)
150     m_pos = op - 1 - 0x400;
151     #endif
152     m_pos -= t >> 2;
153     m_pos -= *ip++ << 2;
154     *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++;
155     lit = 0;
156     goto match_done;
157    
158    
159     /* handle matches */
160     do {
161     if (t < 16) /* a M1 match */
162     {
163     m_pos = op - 1;
164     m_pos -= t >> 2;
165     m_pos -= *ip++ << 2;
166    
167     if (litp == NULL)
168     goto copy_m1;
169    
170     /* assert that there was a match just before */
171     assert(lit >= 1 && lit <= 3);
172     assert(litp == ip - 2 - lit - 2);
173     assert((lzo_uint)(*litp & 3) == lit);
174     nl = ip[-2] & 3;
175     /* test if a match follows */
176     if (nl == 0 && lit == 1 && ip[0] >= 16)
177     {
178     next_lit = nl;
179     /* adjust length of previous short run */
180     lit += 2;
181     *litp = LZO_BYTE((*litp & ~3) | lit);
182     /* copy over the 2 literals that replace the match */
183     copy2(ip-2,m_pos,pd(op,m_pos));
184     o_m1_a++;
185     }
186     /* test if a literal run follows */
187     else if (nl == 0 && ip[0] < 16 && ip[0] != 0 &&
188     (lit + 2 + ip[0] < 16))
189     {
190     t = *ip++;
191     /* remove short run */
192     *litp &= ~3;
193     /* copy over the 2 literals that replace the match */
194     copy2(ip-3+1,m_pos,pd(op,m_pos));
195     /* move literals 1 byte ahead */
196     litp += 2;
197     if (lit > 0)
198     lzo_memmove(litp+1,litp,lit);
199     /* insert new length of long literal run */
200     lit += 2 + t + 3; assert(lit <= 18);
201     *litp = LZO_BYTE(lit - 3);
202    
203     o_m1_b++;
204     *op++ = *m_pos++; *op++ = *m_pos++;
205     goto copy_literal_run;
206     }
207     copy_m1:
208     *op++ = *m_pos++; *op++ = *m_pos++;
209     }
210     else
211     {
212     match:
213     if (t >= 64) /* a M2 match */
214     {
215     m_pos = op - 1;
216     #if defined(LZO1X)
217     m_pos -= (t >> 2) & 7;
218     m_pos -= *ip++ << 3;
219     t = (t >> 5) - 1;
220     #elif defined(LZO1Y)
221     m_pos -= (t >> 2) & 3;
222     m_pos -= *ip++ << 2;
223     t = (t >> 4) - 3;
224     #endif
225     if (litp == NULL)
226     goto copy_m;
227    
228     nl = ip[-2] & 3;
229     /* test if in beetween two long literal runs */
230     if (t == 1 && lit > 3 && nl == 0 &&
231     ip[0] < 16 && ip[0] != 0 && (lit + 3 + ip[0] < 16))
232     {
233     assert(*litp == lit - 3);
234     t = *ip++;
235     /* copy over the 3 literals that replace the match */
236     copy3(ip-1-2,m_pos,pd(op,m_pos));
237     /* set new length of previous literal run */
238     lit += 3 + t + 3; assert(lit <= 18);
239     *litp = LZO_BYTE(lit - 3);
240     o_m2++;
241     *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++;
242     goto copy_literal_run;
243     }
244     }
245     else
246     {
247     if (t >= 32) /* a M3 match */
248     {
249     t &= 31;
250     if (t == 0)
251     {
252     t = 31;
253     while (*ip == 0)
254     t += 255, ip++;
255     t += *ip++;
256     }
257     m_pos = op - 1;
258     m_pos -= *ip++ >> 2;
259     m_pos -= *ip++ << 6;
260     }
261     else /* a M4 match */
262     {
263     m_pos = op;
264     m_pos -= (t & 8) << 11;
265     t &= 7;
266     if (t == 0)
267     {
268     t = 7;
269     while (*ip == 0)
270     t += 255, ip++;
271     t += *ip++;
272     }
273     m_pos -= *ip++ >> 2;
274     m_pos -= *ip++ << 6;
275     if (m_pos == op)
276     goto eof_found;
277     m_pos -= 0x4000;
278     }
279     if (litp == NULL)
280     goto copy_m;
281    
282     nl = ip[-2] & 3;
283     /* test if in beetween two matches */
284     if (t == 1 && lit == 0 && nl == 0 && ip[0] >= 16)
285     {
286     assert(litp == ip - 3 - lit - 2);
287     assert((lzo_uint)(*litp & 3) == lit);
288     next_lit = nl;
289     /* make a previous short run */
290     lit += 3;
291     *litp = LZO_BYTE((*litp & ~3) | lit);
292     /* copy over the 3 literals that replace the match */
293     copy3(ip-3,m_pos,pd(op,m_pos));
294     o_m3_a++;
295     }
296     /* test if a literal run follows */
297     else if (t == 1 && lit <= 3 && nl == 0 &&
298     ip[0] < 16 && ip[0] != 0 && (lit + 3 + ip[0] < 16))
299     {
300     assert(litp == ip - 3 - lit - 2);
301     assert((lzo_uint)(*litp & 3) == lit);
302     t = *ip++;
303     /* remove short run */
304     *litp &= ~3;
305     /* copy over the 3 literals that replace the match */
306     copy3(ip-4+1,m_pos,pd(op,m_pos));
307     /* move literals 1 byte ahead */
308     litp += 2;
309     if (lit > 0)
310     lzo_memmove(litp+1,litp,lit);
311     /* insert new length of long literal run */
312     lit += 3 + t + 3; assert(lit <= 18);
313     *litp = LZO_BYTE(lit - 3);
314    
315     o_m3_b++;
316     *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos++;
317     goto copy_literal_run;
318     }
319     }
320     copy_m:
321     *op++ = *m_pos++; *op++ = *m_pos++;
322     do *op++ = *m_pos++; while (--t > 0);
323     }
324    
325     match_done:
326     if (next_lit == NO_LIT)
327     {
328     t = ip[-2] & 3;
329     lit = t;
330     litp = ip - 2;
331     }
332     else
333     t = next_lit;
334     assert(t <= 3);
335     next_lit = NO_LIT;
336     if (t == 0)
337     break;
338     /* copy literals */
339     match_next:
340     do *op++ = *ip++; while (--t > 0);
341     t = *ip++;
342     } while (TEST_IP && TEST_OP);
343     }
344    
345     /* no EOF code was found */
346     *out_len = pd(op, out);
347     return LZO_E_EOF_NOT_FOUND;
348    
349     eof_found:
350     assert(t == 1);
351     #if 0
352     printf("optimize: %5lu %5lu %5lu %5lu %5lu\n",
353     o_m1_a, o_m1_b, o_m2, o_m3_a, o_m3_b);
354     #endif
355     LZO_UNUSED(o_m1_a); LZO_UNUSED(o_m1_b); LZO_UNUSED(o_m2);
356     LZO_UNUSED(o_m3_a); LZO_UNUSED(o_m3_b);
357     *out_len = pd(op, out);
358     return (ip == ip_end ? LZO_E_OK :
359     (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
360     }
361    
362    
363     /*
364     vi:ts=4:et
365     */
366