/src/lzo-2.10/src/lzo2a_d.ch
Line | Count | Source (jump to first uncovered line) |
1 | | /* lzo2a_d.ch -- implementation of the LZO2A 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 | 356k | #define _NEEDBYTE NEED_IP(1) |
37 | 356k | #define _NEXTBYTE (*ip++) |
38 | | |
39 | | LZO_PUBLIC(int) |
40 | | DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, |
41 | | lzo_bytep out, lzo_uintp out_len, |
42 | | lzo_voidp wrkmem ) |
43 | 871 | { |
44 | 871 | lzo_bytep op; |
45 | 871 | const lzo_bytep ip; |
46 | 871 | const lzo_bytep m_pos; |
47 | | |
48 | 871 | lzo_uint t; |
49 | 871 | const lzo_bytep const ip_end = in + in_len; |
50 | | #if defined(HAVE_ANY_OP) |
51 | 191 | lzo_bytep const op_end = out + *out_len; |
52 | | #endif |
53 | | |
54 | 871 | lzo_uint32_t b = 0; /* bit buffer */ |
55 | 871 | unsigned k = 0; /* bits in bit buffer */ |
56 | | |
57 | 871 | LZO_UNUSED(wrkmem); |
58 | | |
59 | 871 | op = out; |
60 | 871 | ip = in; |
61 | | |
62 | 2.31M | while (TEST_IP_AND_TEST_OP) |
63 | 2.49M | { |
64 | 2.49M | NEEDBITS(1); |
65 | 2.49M | if (MASKBITS(1) == 0) |
66 | 2.33M | { |
67 | 2.33M | DUMPBITS(1); |
68 | | /* a literal */ |
69 | 2.33M | NEED_IP(1); NEED_OP(1); |
70 | 169k | *op++ = *ip++; |
71 | 169k | continue; |
72 | 169k | } |
73 | 163k | DUMPBITS(1); |
74 | | |
75 | 163k | NEEDBITS(1); |
76 | 163k | if (MASKBITS(1) == 0) |
77 | 93.1k | { |
78 | 93.1k | DUMPBITS(1); |
79 | | /* a M1 match */ |
80 | 93.1k | NEEDBITS(2); |
81 | 93.1k | t = M1_MIN_LEN + (lzo_uint) MASKBITS(2); |
82 | 93.1k | DUMPBITS(2); |
83 | 93.1k | NEED_IP(1); NEED_OP(t); |
84 | 5.16k | m_pos = op - 1 - *ip++; |
85 | 5.16k | assert(m_pos >= out); assert(m_pos < op); |
86 | 93.1k | TEST_LB(m_pos); |
87 | 93.1k | MEMCPY_DS(op,m_pos,t); |
88 | 5.14k | continue; |
89 | 5.16k | } |
90 | 69.8k | DUMPBITS(1); |
91 | | |
92 | 69.8k | NEED_IP(2); |
93 | 6.18k | t = *ip++; |
94 | 6.18k | m_pos = op; |
95 | 6.18k | m_pos -= (t & 31) | (((lzo_uint) *ip++) << 5); |
96 | 6.18k | t >>= 5; |
97 | 69.8k | if (t == 0) |
98 | 29.5k | { |
99 | | #if (SWD_N >= 8192) |
100 | | NEEDBITS(1); |
101 | | t = MASKBITS(1); |
102 | | DUMPBITS(1); |
103 | | if (t == 0) |
104 | | t = 10 - 1; |
105 | | else |
106 | | { |
107 | | /* a M3 match */ |
108 | | m_pos -= 8192; /* t << 13 */ |
109 | | t = M3_MIN_LEN - 1; |
110 | | } |
111 | | #else |
112 | 29.5k | t = 10 - 1; |
113 | 29.5k | #endif |
114 | 29.5k | NEED_IP(1); |
115 | 1.71M | while (*ip == 0) |
116 | 1.68M | { |
117 | 1.68M | t += 255; |
118 | 1.68M | ip++; |
119 | 1.68M | TEST_OV(t); |
120 | 1.68M | NEED_IP(1); |
121 | 1.67M | } |
122 | 4.22k | t += *ip++; |
123 | 4.22k | } |
124 | 40.3k | else |
125 | 40.3k | { |
126 | 40.3k | #if defined(LZO_EOF_CODE) |
127 | 40.3k | if (m_pos == op) |
128 | 685 | goto eof_found; |
129 | 39.6k | #endif |
130 | 39.6k | t += 2; |
131 | 39.6k | } |
132 | 69.1k | assert(m_pos >= out); assert(m_pos < op); |
133 | 69.1k | TEST_LB(m_pos); |
134 | 69.1k | NEED_OP(t); |
135 | 69.1k | MEMCPY_DS(op,m_pos,t); |
136 | 6.09k | } |
137 | | |
138 | | |
139 | 51 | #if defined(LZO_EOF_CODE) |
140 | | #if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) |
141 | | /* no EOF code was found */ |
142 | 51 | *out_len = pd(op, out); |
143 | 51 | return LZO_E_EOF_NOT_FOUND; |
144 | 0 | #endif |
145 | | |
146 | 685 | eof_found: |
147 | 685 | assert(t == 1); |
148 | 685 | #endif |
149 | 685 | *out_len = pd(op, out); |
150 | 685 | return (ip == ip_end ? LZO_E_OK : |
151 | 685 | (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); |
152 | | |
153 | | |
154 | | #if defined(HAVE_NEED_IP) |
155 | 38 | input_overrun: |
156 | 38 | *out_len = pd(op, out); |
157 | 38 | return LZO_E_INPUT_OVERRUN; |
158 | 0 | #endif |
159 | | |
160 | | #if defined(HAVE_NEED_OP) |
161 | 9 | output_overrun: |
162 | 9 | *out_len = pd(op, out); |
163 | 9 | return LZO_E_OUTPUT_OVERRUN; |
164 | 0 | #endif |
165 | | |
166 | | #if defined(LZO_TEST_OVERRUN_LOOKBEHIND) |
167 | 88 | lookbehind_overrun: |
168 | 88 | *out_len = pd(op, out); |
169 | 88 | return LZO_E_LOOKBEHIND_OVERRUN; |
170 | | #endif |
171 | 871 | } Line | Count | Source | 43 | 680 | { | 44 | 680 | lzo_bytep op; | 45 | 680 | const lzo_bytep ip; | 46 | 680 | const lzo_bytep m_pos; | 47 | | | 48 | 680 | lzo_uint t; | 49 | 680 | const lzo_bytep const ip_end = in + in_len; | 50 | | #if defined(HAVE_ANY_OP) | 51 | | lzo_bytep const op_end = out + *out_len; | 52 | | #endif | 53 | | | 54 | 680 | lzo_uint32_t b = 0; /* bit buffer */ | 55 | 680 | unsigned k = 0; /* bits in bit buffer */ | 56 | | | 57 | 680 | LZO_UNUSED(wrkmem); | 58 | | | 59 | 680 | op = out; | 60 | 680 | ip = in; | 61 | | | 62 | 2.31M | while (TEST_IP_AND_TEST_OP) | 63 | 2.31M | { | 64 | 2.31M | NEEDBITS(1); | 65 | 2.31M | if (MASKBITS(1) == 0) | 66 | 2.16M | { | 67 | 2.16M | DUMPBITS(1); | 68 | | /* a literal */ | 69 | 2.16M | NEED_IP(1); NEED_OP(1); | 70 | 2.16M | *op++ = *ip++; | 71 | 2.16M | continue; | 72 | 2.16M | } | 73 | 151k | DUMPBITS(1); | 74 | | | 75 | 151k | NEEDBITS(1); | 76 | 151k | if (MASKBITS(1) == 0) | 77 | 87.9k | { | 78 | 87.9k | DUMPBITS(1); | 79 | | /* a M1 match */ | 80 | 87.9k | NEEDBITS(2); | 81 | 87.9k | t = M1_MIN_LEN + (lzo_uint) MASKBITS(2); | 82 | 87.9k | DUMPBITS(2); | 83 | 87.9k | NEED_IP(1); NEED_OP(t); | 84 | 87.9k | m_pos = op - 1 - *ip++; | 85 | 87.9k | assert(m_pos >= out); assert(m_pos < op); | 86 | 87.9k | TEST_LB(m_pos); | 87 | 87.9k | MEMCPY_DS(op,m_pos,t); | 88 | 87.9k | continue; | 89 | 87.9k | } | 90 | 63.6k | DUMPBITS(1); | 91 | | | 92 | 63.6k | NEED_IP(2); | 93 | 63.6k | t = *ip++; | 94 | 63.6k | m_pos = op; | 95 | 63.6k | m_pos -= (t & 31) | (((lzo_uint) *ip++) << 5); | 96 | 63.6k | t >>= 5; | 97 | 63.6k | if (t == 0) | 98 | 25.3k | { | 99 | | #if (SWD_N >= 8192) | 100 | | NEEDBITS(1); | 101 | | t = MASKBITS(1); | 102 | | DUMPBITS(1); | 103 | | if (t == 0) | 104 | | t = 10 - 1; | 105 | | else | 106 | | { | 107 | | /* a M3 match */ | 108 | | m_pos -= 8192; /* t << 13 */ | 109 | | t = M3_MIN_LEN - 1; | 110 | | } | 111 | | #else | 112 | 25.3k | t = 10 - 1; | 113 | 25.3k | #endif | 114 | 25.3k | NEED_IP(1); | 115 | 42.5k | while (*ip == 0) | 116 | 17.2k | { | 117 | 17.2k | t += 255; | 118 | 17.2k | ip++; | 119 | 17.2k | TEST_OV(t); | 120 | 17.2k | NEED_IP(1); | 121 | 17.2k | } | 122 | 25.3k | t += *ip++; | 123 | 25.3k | } | 124 | 38.3k | else | 125 | 38.3k | { | 126 | 38.3k | #if defined(LZO_EOF_CODE) | 127 | 38.3k | if (m_pos == op) | 128 | 680 | goto eof_found; | 129 | 37.7k | #endif | 130 | 37.7k | t += 2; | 131 | 37.7k | } | 132 | 63.0k | assert(m_pos >= out); assert(m_pos < op); | 133 | 63.0k | TEST_LB(m_pos); | 134 | 63.0k | NEED_OP(t); | 135 | 63.0k | MEMCPY_DS(op,m_pos,t); | 136 | 63.0k | } | 137 | | | 138 | | | 139 | 0 | #if defined(LZO_EOF_CODE) | 140 | | #if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) | 141 | | /* no EOF code was found */ | 142 | | *out_len = pd(op, out); | 143 | | return LZO_E_EOF_NOT_FOUND; | 144 | | #endif | 145 | | | 146 | 680 | eof_found: | 147 | 680 | assert(t == 1); | 148 | 680 | #endif | 149 | 680 | *out_len = pd(op, out); | 150 | 680 | return (ip == ip_end ? LZO_E_OK : | 151 | 680 | (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); | 152 | | | 153 | | | 154 | | #if defined(HAVE_NEED_IP) | 155 | | input_overrun: | 156 | | *out_len = pd(op, out); | 157 | | return LZO_E_INPUT_OVERRUN; | 158 | | #endif | 159 | | | 160 | | #if defined(HAVE_NEED_OP) | 161 | | output_overrun: | 162 | | *out_len = pd(op, out); | 163 | | return LZO_E_OUTPUT_OVERRUN; | 164 | | #endif | 165 | | | 166 | | #if defined(LZO_TEST_OVERRUN_LOOKBEHIND) | 167 | | lookbehind_overrun: | 168 | | *out_len = pd(op, out); | 169 | | return LZO_E_LOOKBEHIND_OVERRUN; | 170 | | #endif | 171 | 680 | } |
Line | Count | Source | 43 | 191 | { | 44 | 191 | lzo_bytep op; | 45 | 191 | const lzo_bytep ip; | 46 | 191 | const lzo_bytep m_pos; | 47 | | | 48 | 191 | lzo_uint t; | 49 | 191 | const lzo_bytep const ip_end = in + in_len; | 50 | 191 | #if defined(HAVE_ANY_OP) | 51 | 191 | lzo_bytep const op_end = out + *out_len; | 52 | 191 | #endif | 53 | | | 54 | 191 | lzo_uint32_t b = 0; /* bit buffer */ | 55 | 191 | unsigned k = 0; /* bits in bit buffer */ | 56 | | | 57 | 191 | LZO_UNUSED(wrkmem); | 58 | | | 59 | 191 | op = out; | 60 | 191 | ip = in; | 61 | | | 62 | 191 | while (TEST_IP_AND_TEST_OP) | 63 | 181k | { | 64 | 181k | NEEDBITS(1); | 65 | 181k | if (MASKBITS(1) == 0) | 66 | 169k | { | 67 | 169k | DUMPBITS(1); | 68 | | /* a literal */ | 69 | 169k | NEED_IP(1); NEED_OP(1); | 70 | 169k | *op++ = *ip++; | 71 | 169k | continue; | 72 | 169k | } | 73 | 11.3k | DUMPBITS(1); | 74 | | | 75 | 11.3k | NEEDBITS(1); | 76 | 11.3k | if (MASKBITS(1) == 0) | 77 | 5.17k | { | 78 | 5.17k | DUMPBITS(1); | 79 | | /* a M1 match */ | 80 | 5.17k | NEEDBITS(2); | 81 | 5.17k | t = M1_MIN_LEN + (lzo_uint) MASKBITS(2); | 82 | 5.17k | DUMPBITS(2); | 83 | 5.17k | NEED_IP(1); NEED_OP(t); | 84 | 5.16k | m_pos = op - 1 - *ip++; | 85 | 5.16k | assert(m_pos >= out); assert(m_pos < op); | 86 | 5.16k | TEST_LB(m_pos); | 87 | 5.14k | MEMCPY_DS(op,m_pos,t); | 88 | 5.14k | continue; | 89 | 5.16k | } | 90 | 6.19k | DUMPBITS(1); | 91 | | | 92 | 6.19k | NEED_IP(2); | 93 | 6.18k | t = *ip++; | 94 | 6.18k | m_pos = op; | 95 | 6.18k | m_pos -= (t & 31) | (((lzo_uint) *ip++) << 5); | 96 | 6.18k | t >>= 5; | 97 | 6.18k | if (t == 0) | 98 | 4.23k | { | 99 | | #if (SWD_N >= 8192) | 100 | | NEEDBITS(1); | 101 | | t = MASKBITS(1); | 102 | | DUMPBITS(1); | 103 | | if (t == 0) | 104 | | t = 10 - 1; | 105 | | else | 106 | | { | 107 | | /* a M3 match */ | 108 | | m_pos -= 8192; /* t << 13 */ | 109 | | t = M3_MIN_LEN - 1; | 110 | | } | 111 | | #else | 112 | 4.23k | t = 10 - 1; | 113 | 4.23k | #endif | 114 | 4.23k | NEED_IP(1); | 115 | 1.67M | while (*ip == 0) | 116 | 1.67M | { | 117 | 1.67M | t += 255; | 118 | 1.67M | ip++; | 119 | 1.67M | TEST_OV(t); | 120 | 1.67M | NEED_IP(1); | 121 | 1.67M | } | 122 | 4.22k | t += *ip++; | 123 | 4.22k | } | 124 | 1.95k | else | 125 | 1.95k | { | 126 | 1.95k | #if defined(LZO_EOF_CODE) | 127 | 1.95k | if (m_pos == op) | 128 | 5 | goto eof_found; | 129 | 1.94k | #endif | 130 | 1.94k | t += 2; | 131 | 1.94k | } | 132 | 6.16k | assert(m_pos >= out); assert(m_pos < op); | 133 | 6.16k | TEST_LB(m_pos); | 134 | 6.09k | NEED_OP(t); | 135 | 6.09k | MEMCPY_DS(op,m_pos,t); | 136 | 6.09k | } | 137 | | | 138 | | | 139 | 51 | #if defined(LZO_EOF_CODE) | 140 | 51 | #if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) | 141 | | /* no EOF code was found */ | 142 | 51 | *out_len = pd(op, out); | 143 | 51 | return LZO_E_EOF_NOT_FOUND; | 144 | 0 | #endif | 145 | | | 146 | 5 | eof_found: | 147 | 5 | assert(t == 1); | 148 | 5 | #endif | 149 | 5 | *out_len = pd(op, out); | 150 | 5 | return (ip == ip_end ? LZO_E_OK : | 151 | 5 | (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); | 152 | | | 153 | | | 154 | 0 | #if defined(HAVE_NEED_IP) | 155 | 38 | input_overrun: | 156 | 38 | *out_len = pd(op, out); | 157 | 38 | return LZO_E_INPUT_OVERRUN; | 158 | 0 | #endif | 159 | | | 160 | 0 | #if defined(HAVE_NEED_OP) | 161 | 9 | output_overrun: | 162 | 9 | *out_len = pd(op, out); | 163 | 9 | return LZO_E_OUTPUT_OVERRUN; | 164 | 0 | #endif | 165 | | | 166 | 0 | #if defined(LZO_TEST_OVERRUN_LOOKBEHIND) | 167 | 88 | lookbehind_overrun: | 168 | 88 | *out_len = pd(op, out); | 169 | 88 | return LZO_E_LOOKBEHIND_OVERRUN; | 170 | 191 | #endif | 171 | 191 | } |
|
172 | | |
173 | | |
174 | | /* vim:set ts=4 sw=4 et: */ |