Coverage Report

Created: 2026-01-09 06:15

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
6.20k
{
41
6.20k
    lzo_bytep op;
42
6.20k
    const lzo_bytep ip;
43
6.20k
    lzo_uint t;
44
6.20k
    const lzo_bytep m_pos;
45
46
6.20k
    const lzo_bytep const ip_end = in + in_len;
47
#if defined(HAVE_ANY_OP)
48
704
    lzo_bytep const op_end = out + *out_len;
49
#endif
50
51
6.20k
    LZO_UNUSED(wrkmem);
52
53
6.20k
    op = out;
54
6.20k
    ip = in;
55
56
1.55M
    while (TEST_IP_AND_TEST_OP)
57
1.80M
    {
58
1.80M
        t = *ip++;      /* get marker */
59
60
1.80M
        if (t < R0MIN)      /* a literal run */
61
726k
        {
62
726k
            if (t == 0)             /* a R0 literal run */
63
85.1k
            {
64
85.1k
                NEED_IP(1);
65
12.6k
                t = *ip++;
66
85.1k
                if (t >= R0FAST - R0MIN)            /* a long R0 run */
67
23.5k
                {
68
23.5k
                    t -= R0FAST - R0MIN;
69
23.5k
                    if (t == 0)
70
9.75k
                        t = R0FAST;
71
13.8k
                    else
72
13.8k
                    {
73
#if 0
74
                        t = 256u << ((unsigned) t);
75
#else
76
                        /* help the optimizer */
77
13.8k
                        lzo_uint tt = 256;
78
27.1k
                        do tt <<= 1; while (--t > 0);
79
13.8k
                        t = tt;
80
13.8k
#endif
81
13.8k
                    }
82
83
23.5k
                    NEED_IP(t); NEED_OP(t);
84
2.58k
#if 1 && (LZO_OPT_UNALIGNED32)
85
3.41M
                    do {
86
3.41M
                        UA_COPY4(op+0, ip+0);
87
3.41M
                        UA_COPY4(op+4, ip+4);
88
3.41M
                        op += 8; ip += 8;
89
3.41M
                        t -= 8;
90
3.41M
                    } while (t > 0);
91
#else
92
                    MEMCPY8_DS(op,ip,t);
93
#endif
94
2.58k
                    continue;
95
2.59k
                }
96
61.5k
                t += R0MIN;                         /* a short R0 run */
97
61.5k
            }
98
99
702k
            NEED_IP(t); NEED_OP(t);
100
            /* copy literal run */
101
49.0k
#if 1 && (LZO_OPT_UNALIGNED32)
102
702k
            if (t >= 4)
103
301k
            {
104
1.89M
                do {
105
1.89M
                    UA_COPY4(op, ip);
106
1.89M
                    op += 4; ip += 4; t -= 4;
107
1.89M
                } while (t >= 4);
108
376k
                if (t > 0) do *op++ = *ip++; while (--t > 0);
109
301k
            }
110
400k
            else
111
400k
#endif
112
400k
            {
113
#if (M3O_BITS < 7)
114
192k
literal1:
115
192k
#endif
116
835k
                do *op++ = *ip++; while (--t > 0);
117
192k
            }
118
119
#if (M3O_BITS == 7)
120
literal2:
121
#endif
122
123
            /* after a literal a match must follow */
124
808k
            while (TEST_IP_AND_TEST_OP)
125
1.27M
            {
126
1.27M
                t = *ip++;          /* get R1 marker */
127
1.27M
                if (t >= R0MIN)
128
814k
                    goto match;
129
130
460k
                NEED_IP(2); NEED_OP(M2_MIN_LEN + 1);
131
132
            /* R1 match - a M2_MIN_LEN match + 1 byte literal */
133
402k
                assert((t & M2O_MASK) == t);
134
460k
                m_pos = op - M2_MIN_OFFSET;
135
460k
                m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS);
136
402k
                assert(m_pos >= out); assert(m_pos < op);
137
460k
                TEST_LB(m_pos);
138
460k
                COPY_M2;
139
402k
                *op++ = *ip++;
140
402k
            }
141
142
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
143
51
            break;
144
#endif
145
277k
        }
146
147
1.89M
match:
148
149
1.89M
        if (t >= M2_MARKER)             /* a M2 match */
150
1.22M
        {
151
            /* get match offset */
152
1.22M
            NEED_IP(1);
153
1.22M
            m_pos = op - M2_MIN_OFFSET;
154
1.22M
            m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS);
155
202k
            assert(m_pos >= out); assert(m_pos < op);
156
1.22M
            TEST_LB(m_pos);
157
158
            /* get match len */
159
1.22M
            t = (t >> M2O_BITS) - 1;
160
1.22M
            NEED_OP(t + M2_MIN_LEN - 1);
161
1.22M
            COPY_M2X;
162
1.22M
            MEMCPY_DS(op,m_pos,t);
163
202k
        }
164
663k
        else                            /* a M3 or M4 match */
165
663k
        {
166
            /* get match len */
167
663k
            t &= M3L_MASK;
168
663k
            if (t == 0)         /* a M4 match */
169
188k
            {
170
188k
                NEED_IP(1);
171
2.89M
                while (*ip == 0)
172
2.70M
                {
173
2.70M
                    t += 255;
174
2.70M
                    ip++;
175
2.70M
                    TEST_OV(t);
176
2.70M
                    NEED_IP(1);
177
2.26M
                }
178
187k
                t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;
179
4.60k
            }
180
181
            /* get match offset */
182
663k
            NEED_IP(2);
183
663k
            m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET);
184
663k
            m_pos -= *ip++ & M3O_MASK;
185
663k
            m_pos -= (lzo_uint)(*ip++) << M3O_BITS;
186
54.1k
#if defined(LZO_EOF_CODE)
187
663k
            if (m_pos == op)
188
5.54k
                goto eof_found;
189
658k
#endif
190
191
            /* copy match */
192
658k
            assert(m_pos >= out); assert(m_pos < op);
193
658k
            TEST_LB(m_pos); NEED_OP(t + M3_MIN_LEN - 1);
194
53.9k
#if (LZO_OPT_UNALIGNED32)
195
658k
            if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4)
196
507k
            {
197
507k
                UA_COPY4(op, m_pos);
198
507k
                op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1);
199
19.3M
                do {
200
19.3M
                    UA_COPY4(op, m_pos);
201
19.3M
                    op += 4; m_pos += 4; t -= 4;
202
19.3M
                } while (t >= 4);
203
741k
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
204
507k
            }
205
150k
            else
206
150k
#endif
207
150k
            {
208
150k
            COPY_M3X;
209
150k
            MEMCPY_DS(op,m_pos,t);
210
150k
            }
211
212
213
#if (M3O_BITS < 7)
214
227k
            t = ip[-2] >> M3O_BITS;
215
227k
            if (t)
216
112k
            {
217
112k
                NEED_IP(t); NEED_OP(t);
218
14.7k
                goto literal1;
219
14.7k
            }
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
53.9k
        }
230
1.89M
    }
231
232
233
111
#if defined(LZO_EOF_CODE)
234
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
235
    /* no EOF code was found */
236
111
    *out_len = pd(op, out);
237
111
    return LZO_E_EOF_NOT_FOUND;
238
0
#endif
239
240
5.54k
eof_found:
241
5.54k
    assert(t == 1);
242
5.54k
#endif
243
5.54k
    *out_len = pd(op, out);
244
5.54k
    return (ip == ip_end ? LZO_E_OK :
245
5.54k
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
246
247
248
#if defined(HAVE_NEED_IP)
249
319
input_overrun:
250
319
    *out_len = pd(op, out);
251
319
    return LZO_E_INPUT_OVERRUN;
252
0
#endif
253
254
#if defined(HAVE_NEED_OP)
255
59
output_overrun:
256
59
    *out_len = pd(op, out);
257
59
    return LZO_E_OUTPUT_OVERRUN;
258
0
#endif
259
260
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
261
174
lookbehind_overrun:
262
174
    *out_len = pd(op, out);
263
174
    return LZO_E_LOOKBEHIND_OVERRUN;
264
#endif
265
6.20k
}
lzo1b_decompress
Line
Count
Source
40
3.47k
{
41
3.47k
    lzo_bytep op;
42
3.47k
    const lzo_bytep ip;
43
3.47k
    lzo_uint t;
44
3.47k
    const lzo_bytep m_pos;
45
46
3.47k
    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.47k
    LZO_UNUSED(wrkmem);
52
53
3.47k
    op = out;
54
3.47k
    ip = in;
55
56
1.17M
    while (TEST_IP_AND_TEST_OP)
57
1.17M
    {
58
1.17M
        t = *ip++;      /* get marker */
59
60
1.17M
        if (t < R0MIN)      /* a literal run */
61
523k
        {
62
523k
            if (t == 0)             /* a R0 literal run */
63
52.6k
            {
64
52.6k
                NEED_IP(1);
65
52.6k
                t = *ip++;
66
52.6k
                if (t >= R0FAST - R0MIN)            /* a long R0 run */
67
13.7k
                {
68
13.7k
                    t -= R0FAST - R0MIN;
69
13.7k
                    if (t == 0)
70
5.70k
                        t = R0FAST;
71
8.03k
                    else
72
8.03k
                    {
73
#if 0
74
                        t = 256u << ((unsigned) t);
75
#else
76
                        /* help the optimizer */
77
8.03k
                        lzo_uint tt = 256;
78
15.5k
                        do tt <<= 1; while (--t > 0);
79
8.03k
                        t = tt;
80
8.03k
#endif
81
8.03k
                    }
82
83
13.7k
                    NEED_IP(t); NEED_OP(t);
84
13.7k
#if 1 && (LZO_OPT_UNALIGNED32)
85
1.74M
                    do {
86
1.74M
                        UA_COPY4(op+0, ip+0);
87
1.74M
                        UA_COPY4(op+4, ip+4);
88
1.74M
                        op += 8; ip += 8;
89
1.74M
                        t -= 8;
90
1.74M
                    } while (t > 0);
91
#else
92
                    MEMCPY8_DS(op,ip,t);
93
#endif
94
13.7k
                    continue;
95
13.7k
                }
96
38.8k
                t += R0MIN;                         /* a short R0 run */
97
38.8k
            }
98
99
509k
            NEED_IP(t); NEED_OP(t);
100
            /* copy literal run */
101
509k
#if 1 && (LZO_OPT_UNALIGNED32)
102
509k
            if (t >= 4)
103
207k
            {
104
1.29M
                do {
105
1.29M
                    UA_COPY4(op, ip);
106
1.29M
                    op += 4; ip += 4; t -= 4;
107
1.29M
                } while (t >= 4);
108
267k
                if (t > 0) do *op++ = *ip++; while (--t > 0);
109
207k
            }
110
302k
            else
111
302k
#endif
112
302k
            {
113
#if (M3O_BITS < 7)
114
literal1:
115
#endif
116
509k
                do *op++ = *ip++; while (--t > 0);
117
302k
            }
118
119
#if (M3O_BITS == 7)
120
literal2:
121
#endif
122
123
            /* after a literal a match must follow */
124
553k
            while (TEST_IP_AND_TEST_OP)
125
553k
            {
126
553k
                t = *ip++;          /* get R1 marker */
127
553k
                if (t >= R0MIN)
128
509k
                    goto match;
129
130
43.6k
                NEED_IP(2); NEED_OP(M2_MIN_LEN + 1);
131
132
            /* R1 match - a M2_MIN_LEN match + 1 byte literal */
133
43.6k
                assert((t & M2O_MASK) == t);
134
43.6k
                m_pos = op - M2_MIN_OFFSET;
135
43.6k
                m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS);
136
43.6k
                assert(m_pos >= out); assert(m_pos < op);
137
43.6k
                TEST_LB(m_pos);
138
43.6k
                COPY_M2;
139
43.6k
                *op++ = *ip++;
140
43.6k
            }
141
142
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
143
            break;
144
#endif
145
509k
        }
146
147
1.16M
match:
148
149
1.16M
        if (t >= M2_MARKER)             /* a M2 match */
150
751k
        {
151
            /* get match offset */
152
751k
            NEED_IP(1);
153
751k
            m_pos = op - M2_MIN_OFFSET;
154
751k
            m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS);
155
751k
            assert(m_pos >= out); assert(m_pos < op);
156
751k
            TEST_LB(m_pos);
157
158
            /* get match len */
159
751k
            t = (t >> M2O_BITS) - 1;
160
751k
            NEED_OP(t + M2_MIN_LEN - 1);
161
751k
            COPY_M2X;
162
751k
            MEMCPY_DS(op,m_pos,t);
163
751k
        }
164
412k
        else                            /* a M3 or M4 match */
165
412k
        {
166
            /* get match len */
167
412k
            t &= M3L_MASK;
168
412k
            if (t == 0)         /* a M4 match */
169
101k
            {
170
101k
                NEED_IP(1);
171
355k
                while (*ip == 0)
172
253k
                {
173
253k
                    t += 255;
174
253k
                    ip++;
175
253k
                    TEST_OV(t);
176
253k
                    NEED_IP(1);
177
253k
                }
178
101k
                t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;
179
101k
            }
180
181
            /* get match offset */
182
412k
            NEED_IP(2);
183
412k
            m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET);
184
412k
            m_pos -= *ip++ & M3O_MASK;
185
412k
            m_pos -= (lzo_uint)(*ip++) << M3O_BITS;
186
412k
#if defined(LZO_EOF_CODE)
187
412k
            if (m_pos == op)
188
3.47k
                goto eof_found;
189
409k
#endif
190
191
            /* copy match */
192
412k
            assert(m_pos >= out); assert(m_pos < op);
193
409k
            TEST_LB(m_pos); NEED_OP(t + M3_MIN_LEN - 1);
194
409k
#if (LZO_OPT_UNALIGNED32)
195
409k
            if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4)
196
295k
            {
197
295k
                UA_COPY4(op, m_pos);
198
295k
                op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1);
199
9.57M
                do {
200
9.57M
                    UA_COPY4(op, m_pos);
201
9.57M
                    op += 4; m_pos += 4; t -= 4;
202
9.57M
                } while (t >= 4);
203
423k
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
204
295k
            }
205
114k
            else
206
114k
#endif
207
114k
            {
208
114k
            COPY_M3X;
209
114k
            MEMCPY_DS(op,m_pos,t);
210
114k
            }
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
409k
        }
230
1.16M
    }
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.47k
eof_found:
241
3.47k
    assert(t == 1);
242
3.47k
#endif
243
3.47k
    *out_len = pd(op, out);
244
3.47k
    return (ip == ip_end ? LZO_E_OK :
245
3.47k
           (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.47k
}
lzo1c_decompress
Line
Count
Source
40
2.02k
{
41
2.02k
    lzo_bytep op;
42
2.02k
    const lzo_bytep ip;
43
2.02k
    lzo_uint t;
44
2.02k
    const lzo_bytep m_pos;
45
46
2.02k
    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
2.02k
    LZO_UNUSED(wrkmem);
52
53
2.02k
    op = out;
54
2.02k
    ip = in;
55
56
381k
    while (TEST_IP_AND_TEST_OP)
57
381k
    {
58
381k
        t = *ip++;      /* get marker */
59
60
381k
        if (t < R0MIN)      /* a literal run */
61
150k
        {
62
150k
            if (t == 0)             /* a R0 literal run */
63
19.8k
            {
64
19.8k
                NEED_IP(1);
65
19.8k
                t = *ip++;
66
19.8k
                if (t >= R0FAST - R0MIN)            /* a long R0 run */
67
7.14k
                {
68
7.14k
                    t -= R0FAST - R0MIN;
69
7.14k
                    if (t == 0)
70
2.62k
                        t = R0FAST;
71
4.52k
                    else
72
4.52k
                    {
73
#if 0
74
                        t = 256u << ((unsigned) t);
75
#else
76
                        /* help the optimizer */
77
4.52k
                        lzo_uint tt = 256;
78
9.38k
                        do tt <<= 1; while (--t > 0);
79
4.52k
                        t = tt;
80
4.52k
#endif
81
4.52k
                    }
82
83
7.14k
                    NEED_IP(t); NEED_OP(t);
84
7.14k
#if 1 && (LZO_OPT_UNALIGNED32)
85
1.39M
                    do {
86
1.39M
                        UA_COPY4(op+0, ip+0);
87
1.39M
                        UA_COPY4(op+4, ip+4);
88
1.39M
                        op += 8; ip += 8;
89
1.39M
                        t -= 8;
90
1.39M
                    } while (t > 0);
91
#else
92
                    MEMCPY8_DS(op,ip,t);
93
#endif
94
7.14k
                    continue;
95
7.14k
                }
96
12.7k
                t += R0MIN;                         /* a short R0 run */
97
12.7k
            }
98
99
143k
            NEED_IP(t); NEED_OP(t);
100
            /* copy literal run */
101
143k
#if 1 && (LZO_OPT_UNALIGNED32)
102
143k
            if (t >= 4)
103
70.0k
            {
104
448k
                do {
105
448k
                    UA_COPY4(op, ip);
106
448k
                    op += 4; ip += 4; t -= 4;
107
448k
                } while (t >= 4);
108
87.3k
                if (t > 0) do *op++ = *ip++; while (--t > 0);
109
70.0k
            }
110
73.3k
            else
111
73.3k
#endif
112
73.3k
            {
113
73.3k
#if (M3O_BITS < 7)
114
170k
literal1:
115
170k
#endif
116
251k
                do *op++ = *ip++; while (--t > 0);
117
170k
            }
118
119
#if (M3O_BITS == 7)
120
literal2:
121
#endif
122
123
            /* after a literal a match must follow */
124
255k
            while (TEST_IP_AND_TEST_OP)
125
255k
            {
126
255k
                t = *ip++;          /* get R1 marker */
127
255k
                if (t >= R0MIN)
128
240k
                    goto match;
129
130
14.4k
                NEED_IP(2); NEED_OP(M2_MIN_LEN + 1);
131
132
            /* R1 match - a M2_MIN_LEN match + 1 byte literal */
133
14.4k
                assert((t & M2O_MASK) == t);
134
14.4k
                m_pos = op - M2_MIN_OFFSET;
135
14.4k
                m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS);
136
14.4k
                assert(m_pos >= out); assert(m_pos < op);
137
14.4k
                TEST_LB(m_pos);
138
14.4k
                COPY_M2;
139
14.4k
                *op++ = *ip++;
140
14.4k
            }
141
142
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
143
            break;
144
#endif
145
240k
        }
146
147
471k
match:
148
149
471k
        if (t >= M2_MARKER)             /* a M2 match */
150
274k
        {
151
            /* get match offset */
152
274k
            NEED_IP(1);
153
274k
            m_pos = op - M2_MIN_OFFSET;
154
274k
            m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS);
155
274k
            assert(m_pos >= out); assert(m_pos < op);
156
274k
            TEST_LB(m_pos);
157
158
            /* get match len */
159
274k
            t = (t >> M2O_BITS) - 1;
160
274k
            NEED_OP(t + M2_MIN_LEN - 1);
161
274k
            COPY_M2X;
162
274k
            MEMCPY_DS(op,m_pos,t);
163
274k
        }
164
196k
        else                            /* a M3 or M4 match */
165
196k
        {
166
            /* get match len */
167
196k
            t &= M3L_MASK;
168
196k
            if (t == 0)         /* a M4 match */
169
81.6k
            {
170
81.6k
                NEED_IP(1);
171
270k
                while (*ip == 0)
172
188k
                {
173
188k
                    t += 255;
174
188k
                    ip++;
175
188k
                    TEST_OV(t);
176
188k
                    NEED_IP(1);
177
188k
                }
178
81.6k
                t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;
179
81.6k
            }
180
181
            /* get match offset */
182
196k
            NEED_IP(2);
183
196k
            m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET);
184
196k
            m_pos -= *ip++ & M3O_MASK;
185
196k
            m_pos -= (lzo_uint)(*ip++) << M3O_BITS;
186
196k
#if defined(LZO_EOF_CODE)
187
196k
            if (m_pos == op)
188
2.02k
                goto eof_found;
189
194k
#endif
190
191
            /* copy match */
192
196k
            assert(m_pos >= out); assert(m_pos < op);
193
194k
            TEST_LB(m_pos); NEED_OP(t + M3_MIN_LEN - 1);
194
194k
#if (LZO_OPT_UNALIGNED32)
195
194k
            if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4)
196
167k
            {
197
167k
                UA_COPY4(op, m_pos);
198
167k
                op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1);
199
6.65M
                do {
200
6.65M
                    UA_COPY4(op, m_pos);
201
6.65M
                    op += 4; m_pos += 4; t -= 4;
202
6.65M
                } while (t >= 4);
203
253k
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
204
167k
            }
205
27.7k
            else
206
27.7k
#endif
207
27.7k
            {
208
27.7k
            COPY_M3X;
209
27.7k
            MEMCPY_DS(op,m_pos,t);
210
27.7k
            }
211
212
213
194k
#if (M3O_BITS < 7)
214
194k
            t = ip[-2] >> M3O_BITS;
215
194k
            if (t)
216
97.2k
            {
217
97.2k
                NEED_IP(t); NEED_OP(t);
218
97.2k
                goto literal1;
219
97.2k
            }
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
194k
        }
230
471k
    }
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
2.02k
eof_found:
241
2.02k
    assert(t == 1);
242
2.02k
#endif
243
2.02k
    *out_len = pd(op, out);
244
2.02k
    return (ip == ip_end ? LZO_E_OK :
245
2.02k
           (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
2.02k
}
lzo1b_decompress_safe
Line
Count
Source
40
332
{
41
332
    lzo_bytep op;
42
332
    const lzo_bytep ip;
43
332
    lzo_uint t;
44
332
    const lzo_bytep m_pos;
45
46
332
    const lzo_bytep const ip_end = in + in_len;
47
332
#if defined(HAVE_ANY_OP)
48
332
    lzo_bytep const op_end = out + *out_len;
49
332
#endif
50
51
332
    LZO_UNUSED(wrkmem);
52
53
332
    op = out;
54
332
    ip = in;
55
56
332
    while (TEST_IP_AND_TEST_OP)
57
128k
    {
58
128k
        t = *ip++;      /* get marker */
59
60
128k
        if (t < R0MIN)      /* a literal run */
61
27.7k
        {
62
27.7k
            if (t == 0)             /* a R0 literal run */
63
3.81k
            {
64
3.81k
                NEED_IP(1);
65
3.80k
                t = *ip++;
66
3.80k
                if (t >= R0FAST - R0MIN)            /* a long R0 run */
67
1.17k
                {
68
1.17k
                    t -= R0FAST - R0MIN;
69
1.17k
                    if (t == 0)
70
712
                        t = R0FAST;
71
463
                    else
72
463
                    {
73
#if 0
74
                        t = 256u << ((unsigned) t);
75
#else
76
                        /* help the optimizer */
77
463
                        lzo_uint tt = 256;
78
928
                        do tt <<= 1; while (--t > 0);
79
463
                        t = tt;
80
463
#endif
81
463
                    }
82
83
1.17k
                    NEED_IP(t); NEED_OP(t);
84
1.13k
#if 1 && (LZO_OPT_UNALIGNED32)
85
132k
                    do {
86
132k
                        UA_COPY4(op+0, ip+0);
87
132k
                        UA_COPY4(op+4, ip+4);
88
132k
                        op += 8; ip += 8;
89
132k
                        t -= 8;
90
132k
                    } while (t > 0);
91
#else
92
                    MEMCPY8_DS(op,ip,t);
93
#endif
94
1.13k
                    continue;
95
1.13k
                }
96
2.63k
                t += R0MIN;                         /* a short R0 run */
97
2.63k
            }
98
99
26.5k
            NEED_IP(t); NEED_OP(t);
100
            /* copy literal run */
101
26.5k
#if 1 && (LZO_OPT_UNALIGNED32)
102
26.5k
            if (t >= 4)
103
8.73k
            {
104
50.8k
                do {
105
50.8k
                    UA_COPY4(op, ip);
106
50.8k
                    op += 4; ip += 4; t -= 4;
107
50.8k
                } while (t >= 4);
108
8.73k
                if (t > 0) do *op++ = *ip++; while (--t > 0);
109
8.73k
            }
110
17.7k
            else
111
17.7k
#endif
112
17.7k
            {
113
#if (M3O_BITS < 7)
114
literal1:
115
#endif
116
35.2k
                do *op++ = *ip++; while (--t > 0);
117
17.7k
            }
118
119
#if (M3O_BITS == 7)
120
literal2:
121
#endif
122
123
            /* after a literal a match must follow */
124
26.5k
            while (TEST_IP_AND_TEST_OP)
125
318k
            {
126
318k
                t = *ip++;          /* get R1 marker */
127
318k
                if (t >= R0MIN)
128
26.4k
                    goto match;
129
130
291k
                NEED_IP(2); NEED_OP(M2_MIN_LEN + 1);
131
132
            /* R1 match - a M2_MIN_LEN match + 1 byte literal */
133
291k
                assert((t & M2O_MASK) == t);
134
291k
                m_pos = op - M2_MIN_OFFSET;
135
291k
                m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS);
136
291k
                assert(m_pos >= out); assert(m_pos < op);
137
291k
                TEST_LB(m_pos);
138
291k
                COPY_M2;
139
291k
                *op++ = *ip++;
140
291k
            }
141
142
15
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
143
15
            break;
144
26.5k
#endif
145
26.5k
        }
146
147
127k
match:
148
149
127k
        if (t >= M2_MARKER)             /* a M2 match */
150
106k
        {
151
            /* get match offset */
152
106k
            NEED_IP(1);
153
106k
            m_pos = op - M2_MIN_OFFSET;
154
106k
            m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS);
155
106k
            assert(m_pos >= out); assert(m_pos < op);
156
106k
            TEST_LB(m_pos);
157
158
            /* get match len */
159
106k
            t = (t >> M2O_BITS) - 1;
160
106k
            NEED_OP(t + M2_MIN_LEN - 1);
161
106k
            COPY_M2X;
162
106k
            MEMCPY_DS(op,m_pos,t);
163
106k
        }
164
20.9k
        else                            /* a M3 or M4 match */
165
20.9k
        {
166
            /* get match len */
167
20.9k
            t &= M3L_MASK;
168
20.9k
            if (t == 0)         /* a M4 match */
169
2.95k
            {
170
2.95k
                NEED_IP(1);
171
995k
                while (*ip == 0)
172
992k
                {
173
992k
                    t += 255;
174
992k
                    ip++;
175
992k
                    TEST_OV(t);
176
992k
                    NEED_IP(1);
177
992k
                }
178
2.93k
                t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;
179
2.93k
            }
180
181
            /* get match offset */
182
20.9k
            NEED_IP(2);
183
20.9k
            m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET);
184
20.9k
            m_pos -= *ip++ & M3O_MASK;
185
20.9k
            m_pos -= (lzo_uint)(*ip++) << M3O_BITS;
186
20.9k
#if defined(LZO_EOF_CODE)
187
20.9k
            if (m_pos == op)
188
23
                goto eof_found;
189
20.9k
#endif
190
191
            /* copy match */
192
20.9k
            assert(m_pos >= out); assert(m_pos < op);
193
20.9k
            TEST_LB(m_pos); NEED_OP(t + M3_MIN_LEN - 1);
194
20.8k
#if (LZO_OPT_UNALIGNED32)
195
20.8k
            if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4)
196
18.4k
            {
197
18.4k
                UA_COPY4(op, m_pos);
198
18.4k
                op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1);
199
1.28M
                do {
200
1.28M
                    UA_COPY4(op, m_pos);
201
1.28M
                    op += 4; m_pos += 4; t -= 4;
202
1.28M
                } while (t >= 4);
203
26.6k
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
204
18.4k
            }
205
2.46k
            else
206
2.46k
#endif
207
2.46k
            {
208
2.46k
            COPY_M3X;
209
2.46k
            MEMCPY_DS(op,m_pos,t);
210
2.46k
            }
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
20.8k
        }
230
127k
    }
231
232
233
40
#if defined(LZO_EOF_CODE)
234
40
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
235
    /* no EOF code was found */
236
40
    *out_len = pd(op, out);
237
40
    return LZO_E_EOF_NOT_FOUND;
238
0
#endif
239
240
23
eof_found:
241
23
    assert(t == 1);
242
23
#endif
243
23
    *out_len = pd(op, out);
244
23
    return (ip == ip_end ? LZO_E_OK :
245
23
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
246
247
248
0
#if defined(HAVE_NEED_IP)
249
153
input_overrun:
250
153
    *out_len = pd(op, out);
251
153
    return LZO_E_INPUT_OVERRUN;
252
0
#endif
253
254
0
#if defined(HAVE_NEED_OP)
255
28
output_overrun:
256
28
    *out_len = pd(op, out);
257
28
    return LZO_E_OUTPUT_OVERRUN;
258
0
#endif
259
260
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
261
88
lookbehind_overrun:
262
88
    *out_len = pd(op, out);
263
88
    return LZO_E_LOOKBEHIND_OVERRUN;
264
332
#endif
265
332
}
lzo1c_decompress_safe
Line
Count
Source
40
372
{
41
372
    lzo_bytep op;
42
372
    const lzo_bytep ip;
43
372
    lzo_uint t;
44
372
    const lzo_bytep m_pos;
45
46
372
    const lzo_bytep const ip_end = in + in_len;
47
372
#if defined(HAVE_ANY_OP)
48
372
    lzo_bytep const op_end = out + *out_len;
49
372
#endif
50
51
372
    LZO_UNUSED(wrkmem);
52
53
372
    op = out;
54
372
    ip = in;
55
56
372
    while (TEST_IP_AND_TEST_OP)
57
116k
    {
58
116k
        t = *ip++;      /* get marker */
59
60
116k
        if (t < R0MIN)      /* a literal run */
61
24.0k
        {
62
24.0k
            if (t == 0)             /* a R0 literal run */
63
8.83k
            {
64
8.83k
                NEED_IP(1);
65
8.82k
                t = *ip++;
66
8.82k
                if (t >= R0FAST - R0MIN)            /* a long R0 run */
67
1.49k
                {
68
1.49k
                    t -= R0FAST - R0MIN;
69
1.49k
                    if (t == 0)
70
715
                        t = R0FAST;
71
783
                    else
72
783
                    {
73
#if 0
74
                        t = 256u << ((unsigned) t);
75
#else
76
                        /* help the optimizer */
77
783
                        lzo_uint tt = 256;
78
1.22k
                        do tt <<= 1; while (--t > 0);
79
783
                        t = tt;
80
783
#endif
81
783
                    }
82
83
1.49k
                    NEED_IP(t); NEED_OP(t);
84
1.45k
#if 1 && (LZO_OPT_UNALIGNED32)
85
140k
                    do {
86
140k
                        UA_COPY4(op+0, ip+0);
87
140k
                        UA_COPY4(op+4, ip+4);
88
140k
                        op += 8; ip += 8;
89
140k
                        t -= 8;
90
140k
                    } while (t > 0);
91
#else
92
                    MEMCPY8_DS(op,ip,t);
93
#endif
94
1.45k
                    continue;
95
1.45k
                }
96
7.32k
                t += R0MIN;                         /* a short R0 run */
97
7.32k
            }
98
99
22.5k
            NEED_IP(t); NEED_OP(t);
100
            /* copy literal run */
101
22.4k
#if 1 && (LZO_OPT_UNALIGNED32)
102
22.4k
            if (t >= 4)
103
15.6k
            {
104
102k
                do {
105
102k
                    UA_COPY4(op, ip);
106
102k
                    op += 4; ip += 4; t -= 4;
107
102k
                } while (t >= 4);
108
15.6k
                if (t > 0) do *op++ = *ip++; while (--t > 0);
109
15.6k
            }
110
6.81k
            else
111
6.81k
#endif
112
6.81k
            {
113
6.81k
#if (M3O_BITS < 7)
114
21.5k
literal1:
115
21.5k
#endif
116
39.4k
                do *op++ = *ip++; while (--t > 0);
117
21.5k
            }
118
119
#if (M3O_BITS == 7)
120
literal2:
121
#endif
122
123
            /* after a literal a match must follow */
124
37.2k
            while (TEST_IP_AND_TEST_OP)
125
147k
            {
126
147k
                t = *ip++;          /* get R1 marker */
127
147k
                if (t >= R0MIN)
128
37.1k
                    goto match;
129
130
110k
                NEED_IP(2); NEED_OP(M2_MIN_LEN + 1);
131
132
            /* R1 match - a M2_MIN_LEN match + 1 byte literal */
133
110k
                assert((t & M2O_MASK) == t);
134
110k
                m_pos = op - M2_MIN_OFFSET;
135
110k
                m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS);
136
110k
                assert(m_pos >= out); assert(m_pos < op);
137
110k
                TEST_LB(m_pos);
138
110k
                COPY_M2;
139
110k
                *op++ = *ip++;
140
110k
            }
141
142
36
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
143
36
            break;
144
37.2k
#endif
145
37.2k
        }
146
147
129k
match:
148
149
129k
        if (t >= M2_MARKER)             /* a M2 match */
150
96.2k
        {
151
            /* get match offset */
152
96.2k
            NEED_IP(1);
153
96.2k
            m_pos = op - M2_MIN_OFFSET;
154
96.2k
            m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS);
155
96.2k
            assert(m_pos >= out); assert(m_pos < op);
156
96.2k
            TEST_LB(m_pos);
157
158
            /* get match len */
159
96.1k
            t = (t >> M2O_BITS) - 1;
160
96.1k
            NEED_OP(t + M2_MIN_LEN - 1);
161
96.1k
            COPY_M2X;
162
96.1k
            MEMCPY_DS(op,m_pos,t);
163
96.1k
        }
164
33.1k
        else                            /* a M3 or M4 match */
165
33.1k
        {
166
            /* get match len */
167
33.1k
            t &= M3L_MASK;
168
33.1k
            if (t == 0)         /* a M4 match */
169
1.68k
            {
170
1.68k
                NEED_IP(1);
171
1.27M
                while (*ip == 0)
172
1.27M
                {
173
1.27M
                    t += 255;
174
1.27M
                    ip++;
175
1.27M
                    TEST_OV(t);
176
1.27M
                    NEED_IP(1);
177
1.27M
                }
178
1.66k
                t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;
179
1.66k
            }
180
181
            /* get match offset */
182
33.1k
            NEED_IP(2);
183
33.1k
            m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET);
184
33.1k
            m_pos -= *ip++ & M3O_MASK;
185
33.1k
            m_pos -= (lzo_uint)(*ip++) << M3O_BITS;
186
33.1k
#if defined(LZO_EOF_CODE)
187
33.1k
            if (m_pos == op)
188
18
                goto eof_found;
189
33.1k
#endif
190
191
            /* copy match */
192
33.1k
            assert(m_pos >= out); assert(m_pos < op);
193
33.1k
            TEST_LB(m_pos); NEED_OP(t + M3_MIN_LEN - 1);
194
33.0k
#if (LZO_OPT_UNALIGNED32)
195
33.0k
            if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4)
196
26.6k
            {
197
26.6k
                UA_COPY4(op, m_pos);
198
26.6k
                op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1);
199
1.80M
                do {
200
1.80M
                    UA_COPY4(op, m_pos);
201
1.80M
                    op += 4; m_pos += 4; t -= 4;
202
1.80M
                } while (t >= 4);
203
37.2k
                if (t > 0) do *op++ = *m_pos++; while (--t > 0);
204
26.6k
            }
205
6.43k
            else
206
6.43k
#endif
207
6.43k
            {
208
6.43k
            COPY_M3X;
209
6.43k
            MEMCPY_DS(op,m_pos,t);
210
6.43k
            }
211
212
213
33.0k
#if (M3O_BITS < 7)
214
33.0k
            t = ip[-2] >> M3O_BITS;
215
33.0k
            if (t)
216
14.7k
            {
217
14.7k
                NEED_IP(t); NEED_OP(t);
218
14.7k
                goto literal1;
219
14.7k
            }
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
33.0k
        }
230
129k
    }
231
232
233
71
#if defined(LZO_EOF_CODE)
234
71
#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
235
    /* no EOF code was found */
236
71
    *out_len = pd(op, out);
237
71
    return LZO_E_EOF_NOT_FOUND;
238
0
#endif
239
240
18
eof_found:
241
18
    assert(t == 1);
242
18
#endif
243
18
    *out_len = pd(op, out);
244
18
    return (ip == ip_end ? LZO_E_OK :
245
18
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
246
247
248
0
#if defined(HAVE_NEED_IP)
249
166
input_overrun:
250
166
    *out_len = pd(op, out);
251
166
    return LZO_E_INPUT_OVERRUN;
252
0
#endif
253
254
0
#if defined(HAVE_NEED_OP)
255
31
output_overrun:
256
31
    *out_len = pd(op, out);
257
31
    return LZO_E_OUTPUT_OVERRUN;
258
0
#endif
259
260
0
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
261
86
lookbehind_overrun:
262
86
    *out_len = pd(op, out);
263
86
    return LZO_E_LOOKBEHIND_OVERRUN;
264
372
#endif
265
372
}
266
267
268
/* vim:set ts=4 sw=4 et: */