Coverage Report

Created: 2025-12-10 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/lzo-2.10/src/lzo1b_d.ch
Line
Count
Source
1
/* lzo1b_d.ch -- implementation of the LZO1B decompression algorithm
2
3
   This file is part of the LZO real-time data compression library.
4
5
   Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
6
   All Rights Reserved.
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
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22
23
   Markus F.X.J. Oberhumer
24
   <markus@oberhumer.com>
25
   http://www.oberhumer.com/opensource/lzo/
26
 */
27
28
29
#include "lzo1_d.ch"
30
31
32
/***********************************************************************
33
// decompress a block of data.
34
************************************************************************/
35
36
LZO_PUBLIC(int)
37
DO_DECOMPRESS    ( const lzo_bytep in , lzo_uint  in_len,
38
                         lzo_bytep out, lzo_uintp out_len,
39
                         lzo_voidp wrkmem )
40
931
{
41
931
    lzo_bytep op;
42
931
    const lzo_bytep ip;
43
931
    lzo_uint t;
44
931
    const lzo_bytep m_pos;
45
46
931
    const lzo_bytep const ip_end = in + in_len;
47
931
#if defined(HAVE_ANY_OP)
48
931
    lzo_bytep const op_end = out + *out_len;
49
931
#endif
50
51
931
    LZO_UNUSED(wrkmem);
52
53
931
    op = out;
54
931
    ip = in;
55
56
931
    while (TEST_IP_AND_TEST_OP)
57
145k
    {
58
145k
        t = *ip++;      /* get marker */
59
60
145k
        if (t < R0MIN)      /* a literal run */
61
34.1k
        {
62
34.1k
            if (t == 0)             /* a R0 literal run */
63
8.10k
            {
64
8.10k
                NEED_IP(1);
65
8.09k
                t = *ip++;
66
8.09k
                if (t >= R0FAST - R0MIN)            /* a long R0 run */
67
2.33k
                {
68
2.33k
                    t -= R0FAST - R0MIN;
69
2.33k
                    if (t == 0)
70
1.49k
                        t = R0FAST;
71
840
                    else
72
840
                    {
73
#if 0
74
                        t = 256u << ((unsigned) t);
75
#else
76
                        /* help the optimizer */
77
840
                        lzo_uint tt = 256;
78
1.67k
                        do tt <<= 1; while (--t > 0);
79
840
                        t = tt;
80
840
#endif
81
840
                    }
82
83
2.33k
                    NEED_IP(t); NEED_OP(t);
84
2.23k
#if 1 && (LZO_OPT_UNALIGNED32)
85
276k
                    do {
86
276k
                        UA_COPY4(op+0, ip+0);
87
276k
                        UA_COPY4(op+4, ip+4);
88
276k
                        op += 8; ip += 8;
89
276k
                        t -= 8;
90
276k
                    } while (t > 0);
91
#else
92
                    MEMCPY8_DS(op,ip,t);
93
#endif
94
2.23k
                    continue;
95
2.24k
                }
96
5.75k
                t += R0MIN;                         /* a short R0 run */
97
5.75k
            }
98
99
31.7k
            NEED_IP(t); NEED_OP(t);
100
            /* copy literal run */
101
31.6k
#if 1 && (LZO_OPT_UNALIGNED32)
102
31.6k
            if (t >= 4)
103
23.2k
            {
104
107k
                do {
105
107k
                    UA_COPY4(op, ip);
106
107k
                    op += 4; ip += 4; t -= 4;
107
107k
                } while (t >= 4);
108
23.8k
                if (t > 0) do *op++ = *ip++; while (--t > 0);
109
23.2k
            }
110
8.42k
            else
111
8.42k
#endif
112
8.42k
            {
113
#if (M3O_BITS < 7)
114
15.1k
literal1:
115
15.1k
#endif
116
34.7k
                do *op++ = *ip++; while (--t > 0);
117
15.1k
            }
118
119
#if (M3O_BITS == 7)
120
literal2:
121
#endif
122
123
            /* after a literal a match must follow */
124
31.6k
            while (TEST_IP_AND_TEST_OP)
125
411k
            {
126
411k
                t = *ip++;          /* get R1 marker */
127
411k
                if (t >= R0MIN)
128
42.4k
                    goto match;
129
130
369k
                NEED_IP(2); NEED_OP(M2_MIN_LEN + 1);
131
132
            /* R1 match - a M2_MIN_LEN match + 1 byte literal */
133
369k
                assert((t & M2O_MASK) == t);
134
369k
                m_pos = op - M2_MIN_OFFSET;
135
369k
                m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS);
136
369k
                assert(m_pos >= out); assert(m_pos < op);
137
369k
                TEST_LB(m_pos);
138
369k
                COPY_M2;
139
369k
                *op++ = *ip++;
140
369k
            }
141
142
62
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
143
62
            break;
144
30.7k
#endif
145
30.7k
        }
146
147
153k
match:
148
149
153k
        if (t >= M2_MARKER)             /* a M2 match */
150
113k
        {
151
            /* get match offset */
152
113k
            NEED_IP(1);
153
113k
            m_pos = op - M2_MIN_OFFSET;
154
113k
            m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS);
155
113k
            assert(m_pos >= out); assert(m_pos < op);
156
113k
            TEST_LB(m_pos);
157
158
            /* get match len */
159
113k
            t = (t >> M2O_BITS) - 1;
160
113k
            NEED_OP(t + M2_MIN_LEN - 1);
161
113k
            COPY_M2X;
162
113k
            MEMCPY_DS(op,m_pos,t);
163
113k
        }
164
39.9k
        else                            /* a M3 or M4 match */
165
39.9k
        {
166
            /* get match len */
167
39.9k
            t &= M3L_MASK;
168
39.9k
            if (t == 0)         /* a M4 match */
169
9.30k
            {
170
9.30k
                NEED_IP(1);
171
2.61M
                while (*ip == 0)
172
2.60M
                {
173
2.60M
                    t += 255;
174
2.60M
                    ip++;
175
2.60M
                    TEST_OV(t);
176
2.60M
                    NEED_IP(1);
177
2.60M
                }
178
9.26k
                t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;
179
9.26k
            }
180
181
            /* get match offset */
182
39.8k
            NEED_IP(2);
183
39.8k
            m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET);
184
39.8k
            m_pos -= *ip++ & M3O_MASK;
185
39.8k
            m_pos -= (lzo_uint)(*ip++) << M3O_BITS;
186
39.8k
#if defined(LZO_EOF_CODE)
187
39.8k
            if (m_pos == op)
188
46
                goto eof_found;
189
39.7k
#endif
190
191
            /* copy match */
192
39.8k
            assert(m_pos >= out); assert(m_pos < op);
193
39.7k
            TEST_LB(m_pos); NEED_OP(t + M3_MIN_LEN - 1);
194
39.6k
#if (LZO_OPT_UNALIGNED32)
195
39.6k
            if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4)
196
32.7k
            {
197
32.7k
                UA_COPY4(op, m_pos);
198
32.7k
                op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1);
199
3.16M
                do {
200
3.16M
                    UA_COPY4(op, m_pos);
201
3.16M
                    op += 4; m_pos += 4; t -= 4;
202
3.16M
                } while (t >= 4);
203
45.1k
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
204
32.7k
            }
205
6.91k
            else
206
6.91k
#endif
207
6.91k
            {
208
6.91k
            COPY_M3X;
209
6.91k
            MEMCPY_DS(op,m_pos,t);
210
6.91k
            }
211
212
213
#if (M3O_BITS < 7)
214
30.1k
            t = ip[-2] >> M3O_BITS;
215
30.1k
            if (t)
216
10.9k
            {
217
10.9k
                NEED_IP(t); NEED_OP(t);
218
10.9k
                goto literal1;
219
10.9k
            }
220
#elif (M3O_BITS == 7)
221
            /* optimized version */
222
            if (ip[-2] & (1 << M3O_BITS))
223
            {
224
                NEED_IP(1); NEED_OP(1);
225
                *op++ = *ip++;
226
                goto literal2;
227
            }
228
#endif
229
39.6k
        }
230
153k
    }
231
232
233
162
#if defined(LZO_EOF_CODE)
234
162
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
235
    /* no EOF code was found */
236
162
    *out_len = pd(op, out);
237
162
    return LZO_E_EOF_NOT_FOUND;
238
0
#endif
239
240
46
eof_found:
241
46
    assert(t == 1);
242
46
#endif
243
46
    *out_len = pd(op, out);
244
46
    return (ip == ip_end ? LZO_E_OK :
245
46
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
246
247
248
0
#if defined(HAVE_NEED_IP)
249
425
input_overrun:
250
425
    *out_len = pd(op, out);
251
425
    return LZO_E_INPUT_OVERRUN;
252
0
#endif
253
254
0
#if defined(HAVE_NEED_OP)
255
55
output_overrun:
256
55
    *out_len = pd(op, out);
257
55
    return LZO_E_OUTPUT_OVERRUN;
258
0
#endif
259
260
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
261
243
lookbehind_overrun:
262
243
    *out_len = pd(op, out);
263
243
    return LZO_E_LOOKBEHIND_OVERRUN;
264
931
#endif
265
931
}
lzo1b_decompress_safe
Line
Count
Source
40
440
{
41
440
    lzo_bytep op;
42
440
    const lzo_bytep ip;
43
440
    lzo_uint t;
44
440
    const lzo_bytep m_pos;
45
46
440
    const lzo_bytep const ip_end = in + in_len;
47
440
#if defined(HAVE_ANY_OP)
48
440
    lzo_bytep const op_end = out + *out_len;
49
440
#endif
50
51
440
    LZO_UNUSED(wrkmem);
52
53
440
    op = out;
54
440
    ip = in;
55
56
440
    while (TEST_IP_AND_TEST_OP)
57
64.3k
    {
58
64.3k
        t = *ip++;      /* get marker */
59
60
64.3k
        if (t < R0MIN)      /* a literal run */
61
13.0k
        {
62
13.0k
            if (t == 0)             /* a R0 literal run */
63
2.47k
            {
64
2.47k
                NEED_IP(1);
65
2.46k
                t = *ip++;
66
2.46k
                if (t >= R0FAST - R0MIN)            /* a long R0 run */
67
1.07k
                {
68
1.07k
                    t -= R0FAST - R0MIN;
69
1.07k
                    if (t == 0)
70
660
                        t = R0FAST;
71
418
                    else
72
418
                    {
73
#if 0
74
                        t = 256u << ((unsigned) t);
75
#else
76
                        /* help the optimizer */
77
418
                        lzo_uint tt = 256;
78
806
                        do tt <<= 1; while (--t > 0);
79
418
                        t = tt;
80
418
#endif
81
418
                    }
82
83
1.07k
                    NEED_IP(t); NEED_OP(t);
84
1.02k
#if 1 && (LZO_OPT_UNALIGNED32)
85
122k
                    do {
86
122k
                        UA_COPY4(op+0, ip+0);
87
122k
                        UA_COPY4(op+4, ip+4);
88
122k
                        op += 8; ip += 8;
89
122k
                        t -= 8;
90
122k
                    } while (t > 0);
91
#else
92
                    MEMCPY8_DS(op,ip,t);
93
#endif
94
1.02k
                    continue;
95
1.03k
                }
96
1.39k
                t += R0MIN;                         /* a short R0 run */
97
1.39k
            }
98
99
11.9k
            NEED_IP(t); NEED_OP(t);
100
            /* copy literal run */
101
11.8k
#if 1 && (LZO_OPT_UNALIGNED32)
102
11.8k
            if (t >= 4)
103
7.62k
            {
104
35.1k
                do {
105
35.1k
                    UA_COPY4(op, ip);
106
35.1k
                    op += 4; ip += 4; t -= 4;
107
35.1k
                } while (t >= 4);
108
8.34k
                if (t > 0) do *op++ = *ip++; while (--t > 0);
109
7.62k
            }
110
4.27k
            else
111
4.27k
#endif
112
4.27k
            {
113
#if (M3O_BITS < 7)
114
literal1:
115
#endif
116
8.21k
                do *op++ = *ip++; while (--t > 0);
117
4.27k
            }
118
119
#if (M3O_BITS == 7)
120
literal2:
121
#endif
122
123
            /* after a literal a match must follow */
124
11.8k
            while (TEST_IP_AND_TEST_OP)
125
148k
            {
126
148k
                t = *ip++;          /* get R1 marker */
127
148k
                if (t >= R0MIN)
128
11.8k
                    goto match;
129
130
137k
                NEED_IP(2); NEED_OP(M2_MIN_LEN + 1);
131
132
            /* R1 match - a M2_MIN_LEN match + 1 byte literal */
133
137k
                assert((t & M2O_MASK) == t);
134
137k
                m_pos = op - M2_MIN_OFFSET;
135
137k
                m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS);
136
137k
                assert(m_pos >= out); assert(m_pos < op);
137
137k
                TEST_LB(m_pos);
138
137k
                COPY_M2;
139
137k
                *op++ = *ip++;
140
137k
            }
141
142
21
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
143
21
            break;
144
11.8k
#endif
145
11.8k
        }
146
147
63.1k
match:
148
149
63.1k
        if (t >= M2_MARKER)             /* a M2 match */
150
53.5k
        {
151
            /* get match offset */
152
53.5k
            NEED_IP(1);
153
53.5k
            m_pos = op - M2_MIN_OFFSET;
154
53.5k
            m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS);
155
53.5k
            assert(m_pos >= out); assert(m_pos < op);
156
53.5k
            TEST_LB(m_pos);
157
158
            /* get match len */
159
53.4k
            t = (t >> M2O_BITS) - 1;
160
53.4k
            NEED_OP(t + M2_MIN_LEN - 1);
161
53.4k
            COPY_M2X;
162
53.4k
            MEMCPY_DS(op,m_pos,t);
163
53.4k
        }
164
9.62k
        else                            /* a M3 or M4 match */
165
9.62k
        {
166
            /* get match len */
167
9.62k
            t &= M3L_MASK;
168
9.62k
            if (t == 0)         /* a M4 match */
169
733
            {
170
733
                NEED_IP(1);
171
1.21M
                while (*ip == 0)
172
1.21M
                {
173
1.21M
                    t += 255;
174
1.21M
                    ip++;
175
1.21M
                    TEST_OV(t);
176
1.21M
                    NEED_IP(1);
177
1.21M
                }
178
716
                t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;
179
716
            }
180
181
            /* get match offset */
182
9.60k
            NEED_IP(2);
183
9.58k
            m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET);
184
9.58k
            m_pos -= *ip++ & M3O_MASK;
185
9.58k
            m_pos -= (lzo_uint)(*ip++) << M3O_BITS;
186
9.58k
#if defined(LZO_EOF_CODE)
187
9.58k
            if (m_pos == op)
188
19
                goto eof_found;
189
9.56k
#endif
190
191
            /* copy match */
192
9.58k
            assert(m_pos >= out); assert(m_pos < op);
193
9.56k
            TEST_LB(m_pos); NEED_OP(t + M3_MIN_LEN - 1);
194
9.49k
#if (LZO_OPT_UNALIGNED32)
195
9.49k
            if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4)
196
7.24k
            {
197
7.24k
                UA_COPY4(op, m_pos);
198
7.24k
                op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1);
199
1.42M
                do {
200
1.42M
                    UA_COPY4(op, m_pos);
201
1.42M
                    op += 4; m_pos += 4; t -= 4;
202
1.42M
                } while (t >= 4);
203
10.2k
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
204
7.24k
            }
205
2.24k
            else
206
2.24k
#endif
207
2.24k
            {
208
2.24k
            COPY_M3X;
209
2.24k
            MEMCPY_DS(op,m_pos,t);
210
2.24k
            }
211
212
213
#if (M3O_BITS < 7)
214
            t = ip[-2] >> M3O_BITS;
215
            if (t)
216
            {
217
                NEED_IP(t); NEED_OP(t);
218
                goto literal1;
219
            }
220
#elif (M3O_BITS == 7)
221
            /* optimized version */
222
            if (ip[-2] & (1 << M3O_BITS))
223
            {
224
                NEED_IP(1); NEED_OP(1);
225
                *op++ = *ip++;
226
                goto literal2;
227
            }
228
#endif
229
9.49k
        }
230
63.1k
    }
231
232
233
73
#if defined(LZO_EOF_CODE)
234
73
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
235
    /* no EOF code was found */
236
73
    *out_len = pd(op, out);
237
73
    return LZO_E_EOF_NOT_FOUND;
238
0
#endif
239
240
19
eof_found:
241
19
    assert(t == 1);
242
19
#endif
243
19
    *out_len = pd(op, out);
244
19
    return (ip == ip_end ? LZO_E_OK :
245
19
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
246
247
248
0
#if defined(HAVE_NEED_IP)
249
202
input_overrun:
250
202
    *out_len = pd(op, out);
251
202
    return LZO_E_INPUT_OVERRUN;
252
0
#endif
253
254
0
#if defined(HAVE_NEED_OP)
255
26
output_overrun:
256
26
    *out_len = pd(op, out);
257
26
    return LZO_E_OUTPUT_OVERRUN;
258
0
#endif
259
260
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
261
120
lookbehind_overrun:
262
120
    *out_len = pd(op, out);
263
120
    return LZO_E_LOOKBEHIND_OVERRUN;
264
440
#endif
265
440
}
lzo1c_decompress_safe
Line
Count
Source
40
491
{
41
491
    lzo_bytep op;
42
491
    const lzo_bytep ip;
43
491
    lzo_uint t;
44
491
    const lzo_bytep m_pos;
45
46
491
    const lzo_bytep const ip_end = in + in_len;
47
491
#if defined(HAVE_ANY_OP)
48
491
    lzo_bytep const op_end = out + *out_len;
49
491
#endif
50
51
491
    LZO_UNUSED(wrkmem);
52
53
491
    op = out;
54
491
    ip = in;
55
56
491
    while (TEST_IP_AND_TEST_OP)
57
80.7k
    {
58
80.7k
        t = *ip++;      /* get marker */
59
60
80.7k
        if (t < R0MIN)      /* a literal run */
61
21.0k
        {
62
21.0k
            if (t == 0)             /* a R0 literal run */
63
5.63k
            {
64
5.63k
                NEED_IP(1);
65
5.62k
                t = *ip++;
66
5.62k
                if (t >= R0FAST - R0MIN)            /* a long R0 run */
67
1.25k
                {
68
1.25k
                    t -= R0FAST - R0MIN;
69
1.25k
                    if (t == 0)
70
834
                        t = R0FAST;
71
422
                    else
72
422
                    {
73
#if 0
74
                        t = 256u << ((unsigned) t);
75
#else
76
                        /* help the optimizer */
77
422
                        lzo_uint tt = 256;
78
864
                        do tt <<= 1; while (--t > 0);
79
422
                        t = tt;
80
422
#endif
81
422
                    }
82
83
1.25k
                    NEED_IP(t); NEED_OP(t);
84
1.20k
#if 1 && (LZO_OPT_UNALIGNED32)
85
153k
                    do {
86
153k
                        UA_COPY4(op+0, ip+0);
87
153k
                        UA_COPY4(op+4, ip+4);
88
153k
                        op += 8; ip += 8;
89
153k
                        t -= 8;
90
153k
                    } while (t > 0);
91
#else
92
                    MEMCPY8_DS(op,ip,t);
93
#endif
94
1.20k
                    continue;
95
1.20k
                }
96
4.36k
                t += R0MIN;                         /* a short R0 run */
97
4.36k
            }
98
99
19.8k
            NEED_IP(t); NEED_OP(t);
100
            /* copy literal run */
101
19.7k
#if 1 && (LZO_OPT_UNALIGNED32)
102
19.7k
            if (t >= 4)
103
15.6k
            {
104
72.6k
                do {
105
72.6k
                    UA_COPY4(op, ip);
106
72.6k
                    op += 4; ip += 4; t -= 4;
107
72.6k
                } while (t >= 4);
108
15.6k
                if (t > 0) do *op++ = *ip++; while (--t > 0);
109
15.6k
            }
110
4.14k
            else
111
4.14k
#endif
112
4.14k
            {
113
4.14k
#if (M3O_BITS < 7)
114
15.1k
literal1:
115
15.1k
#endif
116
26.5k
                do *op++ = *ip++; while (--t > 0);
117
15.1k
            }
118
119
#if (M3O_BITS == 7)
120
literal2:
121
#endif
122
123
            /* after a literal a match must follow */
124
30.7k
            while (TEST_IP_AND_TEST_OP)
125
262k
            {
126
262k
                t = *ip++;          /* get R1 marker */
127
262k
                if (t >= R0MIN)
128
30.6k
                    goto match;
129
130
232k
                NEED_IP(2); NEED_OP(M2_MIN_LEN + 1);
131
132
            /* R1 match - a M2_MIN_LEN match + 1 byte literal */
133
232k
                assert((t & M2O_MASK) == t);
134
232k
                m_pos = op - M2_MIN_OFFSET;
135
232k
                m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS);
136
232k
                assert(m_pos >= out); assert(m_pos < op);
137
232k
                TEST_LB(m_pos);
138
232k
                COPY_M2;
139
232k
                *op++ = *ip++;
140
232k
            }
141
142
41
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
143
41
            break;
144
30.7k
#endif
145
30.7k
        }
146
147
90.3k
match:
148
149
90.3k
        if (t >= M2_MARKER)             /* a M2 match */
150
59.9k
        {
151
            /* get match offset */
152
59.9k
            NEED_IP(1);
153
59.9k
            m_pos = op - M2_MIN_OFFSET;
154
59.9k
            m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS);
155
59.9k
            assert(m_pos >= out); assert(m_pos < op);
156
59.9k
            TEST_LB(m_pos);
157
158
            /* get match len */
159
59.9k
            t = (t >> M2O_BITS) - 1;
160
59.9k
            NEED_OP(t + M2_MIN_LEN - 1);
161
59.9k
            COPY_M2X;
162
59.9k
            MEMCPY_DS(op,m_pos,t);
163
59.9k
        }
164
30.3k
        else                            /* a M3 or M4 match */
165
30.3k
        {
166
            /* get match len */
167
30.3k
            t &= M3L_MASK;
168
30.3k
            if (t == 0)         /* a M4 match */
169
8.57k
            {
170
8.57k
                NEED_IP(1);
171
1.39M
                while (*ip == 0)
172
1.38M
                {
173
1.38M
                    t += 255;
174
1.38M
                    ip++;
175
1.38M
                    TEST_OV(t);
176
1.38M
                    NEED_IP(1);
177
1.38M
                }
178
8.54k
                t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;
179
8.54k
            }
180
181
            /* get match offset */
182
30.2k
            NEED_IP(2);
183
30.2k
            m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET);
184
30.2k
            m_pos -= *ip++ & M3O_MASK;
185
30.2k
            m_pos -= (lzo_uint)(*ip++) << M3O_BITS;
186
30.2k
#if defined(LZO_EOF_CODE)
187
30.2k
            if (m_pos == op)
188
27
                goto eof_found;
189
30.2k
#endif
190
191
            /* copy match */
192
30.2k
            assert(m_pos >= out); assert(m_pos < op);
193
30.2k
            TEST_LB(m_pos); NEED_OP(t + M3_MIN_LEN - 1);
194
30.1k
#if (LZO_OPT_UNALIGNED32)
195
30.1k
            if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4)
196
25.5k
            {
197
25.5k
                UA_COPY4(op, m_pos);
198
25.5k
                op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1);
199
1.73M
                do {
200
1.73M
                    UA_COPY4(op, m_pos);
201
1.73M
                    op += 4; m_pos += 4; t -= 4;
202
1.73M
                } while (t >= 4);
203
34.9k
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
204
25.5k
            }
205
4.66k
            else
206
4.66k
#endif
207
4.66k
            {
208
4.66k
            COPY_M3X;
209
4.66k
            MEMCPY_DS(op,m_pos,t);
210
4.66k
            }
211
212
213
30.1k
#if (M3O_BITS < 7)
214
30.1k
            t = ip[-2] >> M3O_BITS;
215
30.1k
            if (t)
216
10.9k
            {
217
10.9k
                NEED_IP(t); NEED_OP(t);
218
10.9k
                goto literal1;
219
10.9k
            }
220
#elif (M3O_BITS == 7)
221
            /* optimized version */
222
            if (ip[-2] & (1 << M3O_BITS))
223
            {
224
                NEED_IP(1); NEED_OP(1);
225
                *op++ = *ip++;
226
                goto literal2;
227
            }
228
#endif
229
30.1k
        }
230
90.3k
    }
231
232
233
89
#if defined(LZO_EOF_CODE)
234
89
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
235
    /* no EOF code was found */
236
89
    *out_len = pd(op, out);
237
89
    return LZO_E_EOF_NOT_FOUND;
238
0
#endif
239
240
27
eof_found:
241
27
    assert(t == 1);
242
27
#endif
243
27
    *out_len = pd(op, out);
244
27
    return (ip == ip_end ? LZO_E_OK :
245
27
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
246
247
248
0
#if defined(HAVE_NEED_IP)
249
223
input_overrun:
250
223
    *out_len = pd(op, out);
251
223
    return LZO_E_INPUT_OVERRUN;
252
0
#endif
253
254
0
#if defined(HAVE_NEED_OP)
255
29
output_overrun:
256
29
    *out_len = pd(op, out);
257
29
    return LZO_E_OUTPUT_OVERRUN;
258
0
#endif
259
260
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
261
123
lookbehind_overrun:
262
123
    *out_len = pd(op, out);
263
123
    return LZO_E_LOOKBEHIND_OVERRUN;
264
491
#endif
265
491
}
266
267
268
/* vim:set ts=4 sw=4 et: */