Coverage Report

Created: 2025-10-13 06:57

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
5.44k
{
41
5.44k
    lzo_bytep op;
42
5.44k
    const lzo_bytep ip;
43
5.44k
    lzo_uint t;
44
5.44k
    const lzo_bytep m_pos;
45
46
5.44k
    const lzo_bytep const ip_end = in + in_len;
47
#if defined(HAVE_ANY_OP)
48
    lzo_bytep const op_end = out + *out_len;
49
#endif
50
51
5.44k
    LZO_UNUSED(wrkmem);
52
53
5.44k
    op = out;
54
5.44k
    ip = in;
55
56
1.36M
    while (TEST_IP_AND_TEST_OP)
57
1.36M
    {
58
1.36M
        t = *ip++;      /* get marker */
59
60
1.36M
        if (t < R0MIN)      /* a literal run */
61
567k
        {
62
567k
            if (t == 0)             /* a R0 literal run */
63
66.1k
            {
64
66.1k
                NEED_IP(1);
65
66.1k
                t = *ip++;
66
66.1k
                if (t >= R0FAST - R0MIN)            /* a long R0 run */
67
19.1k
                {
68
19.1k
                    t -= R0FAST - R0MIN;
69
19.1k
                    if (t == 0)
70
7.92k
                        t = R0FAST;
71
11.2k
                    else
72
11.2k
                    {
73
#if 0
74
                        t = 256u << ((unsigned) t);
75
#else
76
                        /* help the optimizer */
77
11.2k
                        lzo_uint tt = 256;
78
22.0k
                        do tt <<= 1; while (--t > 0);
79
11.2k
                        t = tt;
80
11.2k
#endif
81
11.2k
                    }
82
83
19.1k
                    NEED_IP(t); NEED_OP(t);
84
19.1k
#if 1 && (LZO_OPT_UNALIGNED32)
85
2.82M
                    do {
86
2.82M
                        UA_COPY4(op+0, ip+0);
87
2.82M
                        UA_COPY4(op+4, ip+4);
88
2.82M
                        op += 8; ip += 8;
89
2.82M
                        t -= 8;
90
2.82M
                    } while (t > 0);
91
#else
92
                    MEMCPY8_DS(op,ip,t);
93
#endif
94
19.1k
                    continue;
95
19.1k
                }
96
46.9k
                t += R0MIN;                         /* a short R0 run */
97
46.9k
            }
98
99
548k
            NEED_IP(t); NEED_OP(t);
100
            /* copy literal run */
101
548k
#if 1 && (LZO_OPT_UNALIGNED32)
102
548k
            if (t >= 4)
103
228k
            {
104
1.56M
                do {
105
1.56M
                    UA_COPY4(op, ip);
106
1.56M
                    op += 4; ip += 4; t -= 4;
107
1.56M
                } while (t >= 4);
108
282k
                if (t > 0) do *op++ = *ip++; while (--t > 0);
109
228k
            }
110
319k
            else
111
319k
#endif
112
319k
            {
113
#if (M3O_BITS < 7)
114
145k
literal1:
115
145k
#endif
116
631k
                do *op++ = *ip++; while (--t > 0);
117
145k
            }
118
119
#if (M3O_BITS == 7)
120
literal2:
121
#endif
122
123
            /* after a literal a match must follow */
124
656k
            while (TEST_IP_AND_TEST_OP)
125
656k
            {
126
656k
                t = *ip++;          /* get R1 marker */
127
656k
                if (t >= R0MIN)
128
618k
                    goto match;
129
130
38.8k
                NEED_IP(2); NEED_OP(M2_MIN_LEN + 1);
131
132
            /* R1 match - a M2_MIN_LEN match + 1 byte literal */
133
38.8k
                assert((t & M2O_MASK) == t);
134
38.8k
                m_pos = op - M2_MIN_OFFSET;
135
38.8k
                m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS);
136
38.8k
                assert(m_pos >= out); assert(m_pos < op);
137
38.8k
                TEST_LB(m_pos);
138
38.8k
                COPY_M2;
139
38.8k
                *op++ = *ip++;
140
38.8k
            }
141
142
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
143
            break;
144
#endif
145
213k
        }
146
147
1.41M
match:
148
149
1.41M
        if (t >= M2_MARKER)             /* a M2 match */
150
921k
        {
151
            /* get match offset */
152
921k
            NEED_IP(1);
153
921k
            m_pos = op - M2_MIN_OFFSET;
154
921k
            m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS);
155
921k
            assert(m_pos >= out); assert(m_pos < op);
156
921k
            TEST_LB(m_pos);
157
158
            /* get match len */
159
921k
            t = (t >> M2O_BITS) - 1;
160
921k
            NEED_OP(t + M2_MIN_LEN - 1);
161
921k
            COPY_M2X;
162
921k
            MEMCPY_DS(op,m_pos,t);
163
921k
        }
164
493k
        else                            /* a M3 or M4 match */
165
493k
        {
166
            /* get match len */
167
493k
            t &= M3L_MASK;
168
493k
            if (t == 0)         /* a M4 match */
169
150k
            {
170
150k
                NEED_IP(1);
171
554k
                while (*ip == 0)
172
404k
                {
173
404k
                    t += 255;
174
404k
                    ip++;
175
404k
                    TEST_OV(t);
176
404k
                    NEED_IP(1);
177
404k
                }
178
150k
                t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;
179
150k
            }
180
181
            /* get match offset */
182
493k
            NEED_IP(2);
183
493k
            m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET);
184
493k
            m_pos -= *ip++ & M3O_MASK;
185
493k
            m_pos -= (lzo_uint)(*ip++) << M3O_BITS;
186
493k
#if defined(LZO_EOF_CODE)
187
493k
            if (m_pos == op)
188
5.44k
                goto eof_found;
189
488k
#endif
190
191
            /* copy match */
192
493k
            assert(m_pos >= out); assert(m_pos < op);
193
488k
            TEST_LB(m_pos); NEED_OP(t + M3_MIN_LEN - 1);
194
488k
#if (LZO_OPT_UNALIGNED32)
195
488k
            if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4)
196
367k
            {
197
367k
                UA_COPY4(op, m_pos);
198
367k
                op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1);
199
13.9M
                do {
200
13.9M
                    UA_COPY4(op, m_pos);
201
13.9M
                    op += 4; m_pos += 4; t -= 4;
202
13.9M
                } while (t >= 4);
203
506k
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
204
367k
            }
205
120k
            else
206
120k
#endif
207
120k
            {
208
120k
            COPY_M3X;
209
120k
            MEMCPY_DS(op,m_pos,t);
210
120k
            }
211
212
213
#if (M3O_BITS < 7)
214
170k
            t = ip[-2] >> M3O_BITS;
215
170k
            if (t)
216
69.5k
            {
217
69.5k
                NEED_IP(t); NEED_OP(t);
218
69.5k
                goto literal1;
219
69.5k
            }
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
488k
        }
230
1.41M
    }
231
232
233
0
#if defined(LZO_EOF_CODE)
234
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
235
    /* no EOF code was found */
236
    *out_len = pd(op, out);
237
    return LZO_E_EOF_NOT_FOUND;
238
#endif
239
240
5.44k
eof_found:
241
5.44k
    assert(t == 1);
242
5.44k
#endif
243
5.44k
    *out_len = pd(op, out);
244
5.44k
    return (ip == ip_end ? LZO_E_OK :
245
5.44k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
246
247
248
#if defined(HAVE_NEED_IP)
249
input_overrun:
250
    *out_len = pd(op, out);
251
    return LZO_E_INPUT_OVERRUN;
252
#endif
253
254
#if defined(HAVE_NEED_OP)
255
output_overrun:
256
    *out_len = pd(op, out);
257
    return LZO_E_OUTPUT_OVERRUN;
258
#endif
259
260
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
261
lookbehind_overrun:
262
    *out_len = pd(op, out);
263
    return LZO_E_LOOKBEHIND_OVERRUN;
264
#endif
265
5.44k
}
lzo1b_decompress
Line
Count
Source
40
3.46k
{
41
3.46k
    lzo_bytep op;
42
3.46k
    const lzo_bytep ip;
43
3.46k
    lzo_uint t;
44
3.46k
    const lzo_bytep m_pos;
45
46
3.46k
    const lzo_bytep const ip_end = in + in_len;
47
#if defined(HAVE_ANY_OP)
48
    lzo_bytep const op_end = out + *out_len;
49
#endif
50
51
3.46k
    LZO_UNUSED(wrkmem);
52
53
3.46k
    op = out;
54
3.46k
    ip = in;
55
56
985k
    while (TEST_IP_AND_TEST_OP)
57
985k
    {
58
985k
        t = *ip++;      /* get marker */
59
60
985k
        if (t < R0MIN)      /* a literal run */
61
416k
        {
62
416k
            if (t == 0)             /* a R0 literal run */
63
45.9k
            {
64
45.9k
                NEED_IP(1);
65
45.9k
                t = *ip++;
66
45.9k
                if (t >= R0FAST - R0MIN)            /* a long R0 run */
67
11.7k
                {
68
11.7k
                    t -= R0FAST - R0MIN;
69
11.7k
                    if (t == 0)
70
5.16k
                        t = R0FAST;
71
6.56k
                    else
72
6.56k
                    {
73
#if 0
74
                        t = 256u << ((unsigned) t);
75
#else
76
                        /* help the optimizer */
77
6.56k
                        lzo_uint tt = 256;
78
12.3k
                        do tt <<= 1; while (--t > 0);
79
6.56k
                        t = tt;
80
6.56k
#endif
81
6.56k
                    }
82
83
11.7k
                    NEED_IP(t); NEED_OP(t);
84
11.7k
#if 1 && (LZO_OPT_UNALIGNED32)
85
1.40M
                    do {
86
1.40M
                        UA_COPY4(op+0, ip+0);
87
1.40M
                        UA_COPY4(op+4, ip+4);
88
1.40M
                        op += 8; ip += 8;
89
1.40M
                        t -= 8;
90
1.40M
                    } while (t > 0);
91
#else
92
                    MEMCPY8_DS(op,ip,t);
93
#endif
94
11.7k
                    continue;
95
11.7k
                }
96
34.2k
                t += R0MIN;                         /* a short R0 run */
97
34.2k
            }
98
99
404k
            NEED_IP(t); NEED_OP(t);
100
            /* copy literal run */
101
404k
#if 1 && (LZO_OPT_UNALIGNED32)
102
404k
            if (t >= 4)
103
160k
            {
104
1.11M
                do {
105
1.11M
                    UA_COPY4(op, ip);
106
1.11M
                    op += 4; ip += 4; t -= 4;
107
1.11M
                } while (t >= 4);
108
198k
                if (t > 0) do *op++ = *ip++; while (--t > 0);
109
160k
            }
110
243k
            else
111
243k
#endif
112
243k
            {
113
#if (M3O_BITS < 7)
114
literal1:
115
#endif
116
405k
                do *op++ = *ip++; while (--t > 0);
117
243k
            }
118
119
#if (M3O_BITS == 7)
120
literal2:
121
#endif
122
123
            /* after a literal a match must follow */
124
429k
            while (TEST_IP_AND_TEST_OP)
125
429k
            {
126
429k
                t = *ip++;          /* get R1 marker */
127
429k
                if (t >= R0MIN)
128
404k
                    goto match;
129
130
25.2k
                NEED_IP(2); NEED_OP(M2_MIN_LEN + 1);
131
132
            /* R1 match - a M2_MIN_LEN match + 1 byte literal */
133
25.2k
                assert((t & M2O_MASK) == t);
134
25.2k
                m_pos = op - M2_MIN_OFFSET;
135
25.2k
                m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS);
136
25.2k
                assert(m_pos >= out); assert(m_pos < op);
137
25.2k
                TEST_LB(m_pos);
138
25.2k
                COPY_M2;
139
25.2k
                *op++ = *ip++;
140
25.2k
            }
141
142
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
143
            break;
144
#endif
145
404k
        }
146
147
973k
match:
148
149
973k
        if (t >= M2_MARKER)             /* a M2 match */
150
652k
        {
151
            /* get match offset */
152
652k
            NEED_IP(1);
153
652k
            m_pos = op - M2_MIN_OFFSET;
154
652k
            m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS);
155
652k
            assert(m_pos >= out); assert(m_pos < op);
156
652k
            TEST_LB(m_pos);
157
158
            /* get match len */
159
652k
            t = (t >> M2O_BITS) - 1;
160
652k
            NEED_OP(t + M2_MIN_LEN - 1);
161
652k
            COPY_M2X;
162
652k
            MEMCPY_DS(op,m_pos,t);
163
652k
        }
164
321k
        else                            /* a M3 or M4 match */
165
321k
        {
166
            /* get match len */
167
321k
            t &= M3L_MASK;
168
321k
            if (t == 0)         /* a M4 match */
169
86.9k
            {
170
86.9k
                NEED_IP(1);
171
318k
                while (*ip == 0)
172
231k
                {
173
231k
                    t += 255;
174
231k
                    ip++;
175
231k
                    TEST_OV(t);
176
231k
                    NEED_IP(1);
177
231k
                }
178
86.9k
                t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;
179
86.9k
            }
180
181
            /* get match offset */
182
321k
            NEED_IP(2);
183
321k
            m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET);
184
321k
            m_pos -= *ip++ & M3O_MASK;
185
321k
            m_pos -= (lzo_uint)(*ip++) << M3O_BITS;
186
321k
#if defined(LZO_EOF_CODE)
187
321k
            if (m_pos == op)
188
3.46k
                goto eof_found;
189
318k
#endif
190
191
            /* copy match */
192
321k
            assert(m_pos >= out); assert(m_pos < op);
193
318k
            TEST_LB(m_pos); NEED_OP(t + M3_MIN_LEN - 1);
194
318k
#if (LZO_OPT_UNALIGNED32)
195
318k
            if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4)
196
226k
            {
197
226k
                UA_COPY4(op, m_pos);
198
226k
                op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1);
199
8.55M
                do {
200
8.55M
                    UA_COPY4(op, m_pos);
201
8.55M
                    op += 4; m_pos += 4; t -= 4;
202
8.55M
                } while (t >= 4);
203
327k
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
204
226k
            }
205
91.5k
            else
206
91.5k
#endif
207
91.5k
            {
208
91.5k
            COPY_M3X;
209
91.5k
            MEMCPY_DS(op,m_pos,t);
210
91.5k
            }
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
318k
        }
230
973k
    }
231
232
233
0
#if defined(LZO_EOF_CODE)
234
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
235
    /* no EOF code was found */
236
    *out_len = pd(op, out);
237
    return LZO_E_EOF_NOT_FOUND;
238
#endif
239
240
3.46k
eof_found:
241
3.46k
    assert(t == 1);
242
3.46k
#endif
243
3.46k
    *out_len = pd(op, out);
244
3.46k
    return (ip == ip_end ? LZO_E_OK :
245
3.46k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
246
247
248
#if defined(HAVE_NEED_IP)
249
input_overrun:
250
    *out_len = pd(op, out);
251
    return LZO_E_INPUT_OVERRUN;
252
#endif
253
254
#if defined(HAVE_NEED_OP)
255
output_overrun:
256
    *out_len = pd(op, out);
257
    return LZO_E_OUTPUT_OVERRUN;
258
#endif
259
260
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
261
lookbehind_overrun:
262
    *out_len = pd(op, out);
263
    return LZO_E_LOOKBEHIND_OVERRUN;
264
#endif
265
3.46k
}
lzo1c_decompress
Line
Count
Source
40
1.98k
{
41
1.98k
    lzo_bytep op;
42
1.98k
    const lzo_bytep ip;
43
1.98k
    lzo_uint t;
44
1.98k
    const lzo_bytep m_pos;
45
46
1.98k
    const lzo_bytep const ip_end = in + in_len;
47
#if defined(HAVE_ANY_OP)
48
    lzo_bytep const op_end = out + *out_len;
49
#endif
50
51
1.98k
    LZO_UNUSED(wrkmem);
52
53
1.98k
    op = out;
54
1.98k
    ip = in;
55
56
379k
    while (TEST_IP_AND_TEST_OP)
57
379k
    {
58
379k
        t = *ip++;      /* get marker */
59
60
379k
        if (t < R0MIN)      /* a literal run */
61
151k
        {
62
151k
            if (t == 0)             /* a R0 literal run */
63
20.1k
            {
64
20.1k
                NEED_IP(1);
65
20.1k
                t = *ip++;
66
20.1k
                if (t >= R0FAST - R0MIN)            /* a long R0 run */
67
7.42k
                {
68
7.42k
                    t -= R0FAST - R0MIN;
69
7.42k
                    if (t == 0)
70
2.75k
                        t = R0FAST;
71
4.66k
                    else
72
4.66k
                    {
73
#if 0
74
                        t = 256u << ((unsigned) t);
75
#else
76
                        /* help the optimizer */
77
4.66k
                        lzo_uint tt = 256;
78
9.64k
                        do tt <<= 1; while (--t > 0);
79
4.66k
                        t = tt;
80
4.66k
#endif
81
4.66k
                    }
82
83
7.42k
                    NEED_IP(t); NEED_OP(t);
84
7.42k
#if 1 && (LZO_OPT_UNALIGNED32)
85
1.42M
                    do {
86
1.42M
                        UA_COPY4(op+0, ip+0);
87
1.42M
                        UA_COPY4(op+4, ip+4);
88
1.42M
                        op += 8; ip += 8;
89
1.42M
                        t -= 8;
90
1.42M
                    } while (t > 0);
91
#else
92
                    MEMCPY8_DS(op,ip,t);
93
#endif
94
7.42k
                    continue;
95
7.42k
                }
96
12.7k
                t += R0MIN;                         /* a short R0 run */
97
12.7k
            }
98
99
144k
            NEED_IP(t); NEED_OP(t);
100
            /* copy literal run */
101
144k
#if 1 && (LZO_OPT_UNALIGNED32)
102
144k
            if (t >= 4)
103
68.0k
            {
104
450k
                do {
105
450k
                    UA_COPY4(op, ip);
106
450k
                    op += 4; ip += 4; t -= 4;
107
450k
                } while (t >= 4);
108
83.6k
                if (t > 0) do *op++ = *ip++; while (--t > 0);
109
68.0k
            }
110
76.1k
            else
111
76.1k
#endif
112
76.1k
            {
113
76.1k
#if (M3O_BITS < 7)
114
145k
literal1:
115
145k
#endif
116
225k
                do *op++ = *ip++; while (--t > 0);
117
145k
            }
118
119
#if (M3O_BITS == 7)
120
literal2:
121
#endif
122
123
            /* after a literal a match must follow */
124
227k
            while (TEST_IP_AND_TEST_OP)
125
227k
            {
126
227k
                t = *ip++;          /* get R1 marker */
127
227k
                if (t >= R0MIN)
128
213k
                    goto match;
129
130
13.6k
                NEED_IP(2); NEED_OP(M2_MIN_LEN + 1);
131
132
            /* R1 match - a M2_MIN_LEN match + 1 byte literal */
133
13.6k
                assert((t & M2O_MASK) == t);
134
13.6k
                m_pos = op - M2_MIN_OFFSET;
135
13.6k
                m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS);
136
13.6k
                assert(m_pos >= out); assert(m_pos < op);
137
13.6k
                TEST_LB(m_pos);
138
13.6k
                COPY_M2;
139
13.6k
                *op++ = *ip++;
140
13.6k
            }
141
142
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
143
            break;
144
#endif
145
213k
        }
146
147
441k
match:
148
149
441k
        if (t >= M2_MARKER)             /* a M2 match */
150
269k
        {
151
            /* get match offset */
152
269k
            NEED_IP(1);
153
269k
            m_pos = op - M2_MIN_OFFSET;
154
269k
            m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS);
155
269k
            assert(m_pos >= out); assert(m_pos < op);
156
269k
            TEST_LB(m_pos);
157
158
            /* get match len */
159
269k
            t = (t >> M2O_BITS) - 1;
160
269k
            NEED_OP(t + M2_MIN_LEN - 1);
161
269k
            COPY_M2X;
162
269k
            MEMCPY_DS(op,m_pos,t);
163
269k
        }
164
172k
        else                            /* a M3 or M4 match */
165
172k
        {
166
            /* get match len */
167
172k
            t &= M3L_MASK;
168
172k
            if (t == 0)         /* a M4 match */
169
63.3k
            {
170
63.3k
                NEED_IP(1);
171
235k
                while (*ip == 0)
172
172k
                {
173
172k
                    t += 255;
174
172k
                    ip++;
175
172k
                    TEST_OV(t);
176
172k
                    NEED_IP(1);
177
172k
                }
178
63.3k
                t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;
179
63.3k
            }
180
181
            /* get match offset */
182
172k
            NEED_IP(2);
183
172k
            m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET);
184
172k
            m_pos -= *ip++ & M3O_MASK;
185
172k
            m_pos -= (lzo_uint)(*ip++) << M3O_BITS;
186
172k
#if defined(LZO_EOF_CODE)
187
172k
            if (m_pos == op)
188
1.98k
                goto eof_found;
189
170k
#endif
190
191
            /* copy match */
192
172k
            assert(m_pos >= out); assert(m_pos < op);
193
170k
            TEST_LB(m_pos); NEED_OP(t + M3_MIN_LEN - 1);
194
170k
#if (LZO_OPT_UNALIGNED32)
195
170k
            if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4)
196
140k
            {
197
140k
                UA_COPY4(op, m_pos);
198
140k
                op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1);
199
5.40M
                do {
200
5.40M
                    UA_COPY4(op, m_pos);
201
5.40M
                    op += 4; m_pos += 4; t -= 4;
202
5.40M
                } while (t >= 4);
203
179k
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
204
140k
            }
205
29.2k
            else
206
29.2k
#endif
207
29.2k
            {
208
29.2k
            COPY_M3X;
209
29.2k
            MEMCPY_DS(op,m_pos,t);
210
29.2k
            }
211
212
213
170k
#if (M3O_BITS < 7)
214
170k
            t = ip[-2] >> M3O_BITS;
215
170k
            if (t)
216
69.5k
            {
217
69.5k
                NEED_IP(t); NEED_OP(t);
218
69.5k
                goto literal1;
219
69.5k
            }
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
170k
        }
230
441k
    }
231
232
233
0
#if defined(LZO_EOF_CODE)
234
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
235
    /* no EOF code was found */
236
    *out_len = pd(op, out);
237
    return LZO_E_EOF_NOT_FOUND;
238
#endif
239
240
1.98k
eof_found:
241
1.98k
    assert(t == 1);
242
1.98k
#endif
243
1.98k
    *out_len = pd(op, out);
244
1.98k
    return (ip == ip_end ? LZO_E_OK :
245
1.98k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
246
247
248
#if defined(HAVE_NEED_IP)
249
input_overrun:
250
    *out_len = pd(op, out);
251
    return LZO_E_INPUT_OVERRUN;
252
#endif
253
254
#if defined(HAVE_NEED_OP)
255
output_overrun:
256
    *out_len = pd(op, out);
257
    return LZO_E_OUTPUT_OVERRUN;
258
#endif
259
260
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
261
lookbehind_overrun:
262
    *out_len = pd(op, out);
263
    return LZO_E_LOOKBEHIND_OVERRUN;
264
#endif
265
1.98k
}
266
267
268
/* vim:set ts=4 sw=4 et: */