… | |
… | |
22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
23 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
23 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- |
24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- |
25 | * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
25 | * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
26 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
27 | * |
|
|
28 | * Alternatively, the contents of this file may be used under the terms of |
|
|
29 | * the GNU General Public License version 2 (the "GPL"), in which case the |
|
|
30 | * provisions of the GPL are applicable instead of the above. If you wish to |
|
|
31 | * allow the use of your version of this file only under the terms of the |
|
|
32 | * GPL and not to allow others to use your version of this file under the |
|
|
33 | * BSD license, indicate your decision by deleting the provisions above and |
|
|
34 | * replace them with the notice and other provisions required by the GPL. If |
|
|
35 | * you do not delete the provisions above, a recipient may use your version |
|
|
36 | * of this file under either the BSD or the GPL. |
27 | */ |
37 | */ |
28 | |
38 | |
29 | #include "lzfP.h" |
39 | #include "lzfP.h" |
30 | |
40 | |
31 | #define HSIZE (1 << (HLOG)) |
41 | #define HSIZE (1 << (HLOG)) |
… | |
… | |
67 | */ |
77 | */ |
68 | |
78 | |
69 | unsigned int |
79 | unsigned int |
70 | lzf_compress (const void *const in_data, unsigned int in_len, |
80 | lzf_compress (const void *const in_data, unsigned int in_len, |
71 | void *out_data, unsigned int out_len |
81 | void *out_data, unsigned int out_len |
72 | #if !LZF_STATE_ARG |
82 | #if LZF_STATE_ARG |
73 | , LZF_STATE *htab |
83 | , LZF_STATE *htab |
74 | #endif |
84 | #endif |
75 | ) |
85 | ) |
76 | { |
86 | { |
77 | #if LZF_STATE_ARG |
87 | #if !LZF_STATE_ARG |
78 | LZF_STATE htab; |
88 | LZF_STATE htab; |
79 | #endif |
89 | #endif |
80 | const u8 **hslot; |
90 | const u8 **hslot; |
81 | const u8 *ip = (const u8 *)in_data; |
91 | const u8 *ip = (const u8 *)in_data; |
82 | u8 *op = (u8 *)out_data; |
92 | u8 *op = (u8 *)out_data; |
… | |
… | |
95 | for (hslot = htab; hslot < htab + HSIZE; hslot++) |
105 | for (hslot = htab; hslot < htab + HSIZE; hslot++) |
96 | *hslot++ = ip; |
106 | *hslot++ = ip; |
97 | # endif |
107 | # endif |
98 | #endif |
108 | #endif |
99 | |
109 | |
100 | do |
110 | for (;;) |
101 | { |
111 | { |
|
|
112 | if (ip < in_end - 2) |
|
|
113 | { |
102 | hval = NEXT (hval, ip); |
114 | hval = NEXT (hval, ip); |
103 | hslot = htab + IDX (hval); |
115 | hslot = htab + IDX (hval); |
104 | ref = *hslot; *hslot = ip; |
116 | ref = *hslot; *hslot = ip; |
105 | |
117 | |
106 | if (1 |
118 | if (1 |
107 | #if INIT_HTAB && !USE_MEMCPY |
119 | #if INIT_HTAB && !USE_MEMCPY |
108 | && ref < ip /* the next test will actually take care of this, but it is faster */ |
120 | && ref < ip /* the next test will actually take care of this, but this is faster */ |
109 | #endif |
121 | #endif |
110 | && (off = ip - ref - 1) < MAX_OFF |
122 | && (off = ip - ref - 1) < MAX_OFF |
111 | && ip + 4 < in_end |
123 | && ip + 4 < in_end |
112 | && ref > (u8 *)in_data |
124 | && ref > (u8 *)in_data |
113 | #if STRICT_ALIGN |
125 | #if STRICT_ALIGN |
114 | && ref[0] == ip[0] |
126 | && ref[0] == ip[0] |
115 | && ref[1] == ip[1] |
127 | && ref[1] == ip[1] |
116 | && ref[2] == ip[2] |
128 | && ref[2] == ip[2] |
117 | #else |
129 | #else |
118 | && *(u16 *)ref == *(u16 *)ip |
130 | && *(u16 *)ref == *(u16 *)ip |
119 | && ref[2] == ip[2] |
131 | && ref[2] == ip[2] |
120 | #endif |
132 | #endif |
121 | ) |
133 | ) |
122 | { |
134 | { |
123 | /* match found at *ref++ */ |
135 | /* match found at *ref++ */ |
124 | unsigned int len = 2; |
136 | unsigned int len = 2; |
125 | unsigned int maxlen = in_end - ip - len; |
137 | unsigned int maxlen = in_end - ip - len; |
126 | maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; |
138 | maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; |
127 | |
139 | |
128 | do |
140 | do |
129 | len++; |
141 | len++; |
130 | while (len < maxlen && ref[len] == ip[len]); |
142 | while (len < maxlen && ref[len] == ip[len]); |
131 | |
143 | |
132 | if (op + lit + 1 + 3 >= out_end) |
144 | if (op + lit + 1 + 3 >= out_end) |
133 | return 0; |
145 | return 0; |
134 | |
146 | |
135 | if (lit) |
147 | if (lit) |
136 | { |
148 | { |
137 | *op++ = lit - 1; |
149 | *op++ = lit - 1; |
138 | lit = -lit; |
150 | lit = -lit; |
139 | do |
151 | do |
140 | *op++ = ip[lit]; |
152 | *op++ = ip[lit]; |
141 | while (++lit); |
153 | while (++lit); |
142 | } |
154 | } |
143 | |
155 | |
144 | len -= 2; |
156 | len -= 2; |
145 | ip++; |
157 | ip++; |
146 | |
158 | |
147 | if (len < 7) |
159 | if (len < 7) |
148 | { |
160 | { |
149 | *op++ = (off >> 8) + (len << 5); |
161 | *op++ = (off >> 8) + (len << 5); |
150 | } |
162 | } |
151 | else |
163 | else |
152 | { |
164 | { |
153 | *op++ = (off >> 8) + ( 7 << 5); |
165 | *op++ = (off >> 8) + ( 7 << 5); |
154 | *op++ = len - 7; |
166 | *op++ = len - 7; |
155 | } |
167 | } |
156 | |
168 | |
157 | *op++ = off; |
169 | *op++ = off; |
158 | |
170 | |
159 | #if ULTRA_FAST |
171 | #if ULTRA_FAST |
160 | ip += len; |
172 | ip += len; |
161 | hval = FRST (ip); |
173 | hval = FRST (ip); |
162 | hval = NEXT (hval, ip); |
174 | hval = NEXT (hval, ip); |
163 | htab[IDX (hval)] = ip; |
175 | htab[IDX (hval)] = ip; |
164 | ip++; |
176 | ip++; |
165 | #else |
177 | #else |
166 | do |
178 | do |
167 | { |
179 | { |
168 | hval = NEXT (hval, ip); |
180 | hval = NEXT (hval, ip); |
169 | htab[IDX (hval)] = ip; |
181 | htab[IDX (hval)] = ip; |
|
|
182 | ip++; |
|
|
183 | } |
|
|
184 | while (len--); |
|
|
185 | #endif |
|
|
186 | continue; |
|
|
187 | } |
|
|
188 | } |
|
|
189 | else if (ip == in_end) |
|
|
190 | break; |
|
|
191 | |
|
|
192 | /* one more literal byte we must copy */ |
|
|
193 | lit++; |
170 | ip++; |
194 | ip++; |
171 | } |
|
|
172 | while (len--); |
|
|
173 | #endif |
|
|
174 | } |
|
|
175 | else |
|
|
176 | { |
|
|
177 | /* one more literal byte we must copy */ |
|
|
178 | lit++; |
|
|
179 | ip++; |
|
|
180 | |
195 | |
181 | if (lit == MAX_LIT) |
196 | if (lit == MAX_LIT) |
182 | { |
197 | { |
183 | if (op + 1 + MAX_LIT >= out_end) |
198 | if (op + 1 + MAX_LIT >= out_end) |
184 | return 0; |
199 | return 0; |
185 | |
200 | |
186 | *op++ = MAX_LIT - 1; |
201 | *op++ = MAX_LIT - 1; |
187 | #if USE_MEMCPY |
202 | #if USE_MEMCPY |
188 | memcpy (op, ip - MAX_LIT, MAX_LIT); |
203 | memcpy (op, ip - MAX_LIT, MAX_LIT); |
189 | op += MAX_LIT; |
204 | op += MAX_LIT; |
190 | lit = 0; |
205 | lit = 0; |
191 | #else |
206 | #else |
192 | lit = -lit; |
207 | lit = -lit; |
193 | do |
208 | do |
194 | *op++ = ip[lit]; |
209 | *op++ = ip[lit]; |
195 | while (++lit); |
210 | while (++lit); |
196 | #endif |
211 | #endif |
197 | } |
212 | } |
198 | } |
|
|
199 | } |
213 | } |
200 | while (ip < in_end); |
|
|
201 | |
214 | |
202 | if (lit) |
215 | if (lit) |
203 | { |
216 | { |
204 | if (op + lit + 1 >= out_end) |
217 | if (op + lit + 1 >= out_end) |
205 | return 0; |
218 | return 0; |