… | |
… | |
67 | */ |
67 | */ |
68 | |
68 | |
69 | unsigned int |
69 | unsigned int |
70 | lzf_compress (const void *const in_data, unsigned int in_len, |
70 | lzf_compress (const void *const in_data, unsigned int in_len, |
71 | void *out_data, unsigned int out_len |
71 | void *out_data, unsigned int out_len |
72 | #if !LZF_STATE_ARG |
72 | #if LZF_STATE_ARG |
73 | , LZF_STATE *htab |
73 | , LZF_STATE *htab |
74 | #endif |
74 | #endif |
75 | ) |
75 | ) |
76 | { |
76 | { |
77 | #if LZF_STATE_ARG |
77 | #if !LZF_STATE_ARG |
78 | LZF_STATE htab; |
78 | LZF_STATE htab; |
79 | #endif |
79 | #endif |
80 | const u8 **hslot; |
80 | const u8 **hslot; |
81 | const u8 *ip = (const u8 *)in_data; |
81 | const u8 *ip = (const u8 *)in_data; |
82 | u8 *op = (u8 *)out_data; |
82 | u8 *op = (u8 *)out_data; |
… | |
… | |
95 | for (hslot = htab; hslot < htab + HSIZE; hslot++) |
95 | for (hslot = htab; hslot < htab + HSIZE; hslot++) |
96 | *hslot++ = ip; |
96 | *hslot++ = ip; |
97 | # endif |
97 | # endif |
98 | #endif |
98 | #endif |
99 | |
99 | |
100 | do |
100 | for (;;) |
101 | { |
101 | { |
|
|
102 | if (ip < in_end - 2) |
|
|
103 | { |
102 | hval = NEXT (hval, ip); |
104 | hval = NEXT (hval, ip); |
103 | hslot = htab + IDX (hval); |
105 | hslot = htab + IDX (hval); |
104 | ref = *hslot; *hslot = ip; |
106 | ref = *hslot; *hslot = ip; |
105 | |
107 | |
106 | if (1 |
108 | if (1 |
107 | #if INIT_HTAB && !USE_MEMCPY |
109 | #if INIT_HTAB && !USE_MEMCPY |
108 | && ref < ip /* the next test will actually take care of this, but it is faster */ |
110 | && ref < ip /* the next test will actually take care of this, but this is faster */ |
109 | #endif |
111 | #endif |
110 | && (off = ip - ref - 1) < MAX_OFF |
112 | && (off = ip - ref - 1) < MAX_OFF |
111 | && ip + 4 < in_end |
113 | && ip + 4 < in_end |
112 | && ref > (u8 *)in_data |
114 | && ref > (u8 *)in_data |
113 | #if STRICT_ALIGN |
115 | #if STRICT_ALIGN |
114 | && ref[0] == ip[0] |
116 | && ref[0] == ip[0] |
115 | && ref[1] == ip[1] |
117 | && ref[1] == ip[1] |
116 | && ref[2] == ip[2] |
118 | && ref[2] == ip[2] |
117 | #else |
119 | #else |
118 | && *(u16 *)ref == *(u16 *)ip |
120 | && *(u16 *)ref == *(u16 *)ip |
119 | && ref[2] == ip[2] |
121 | && ref[2] == ip[2] |
120 | #endif |
122 | #endif |
121 | ) |
123 | ) |
122 | { |
124 | { |
123 | /* match found at *ref++ */ |
125 | /* match found at *ref++ */ |
124 | unsigned int len = 2; |
126 | unsigned int len = 2; |
125 | unsigned int maxlen = in_end - ip - len; |
127 | unsigned int maxlen = in_end - ip - len; |
126 | maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; |
128 | maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; |
127 | |
129 | |
128 | do |
130 | do |
129 | len++; |
131 | len++; |
130 | while (len < maxlen && ref[len] == ip[len]); |
132 | while (len < maxlen && ref[len] == ip[len]); |
131 | |
133 | |
132 | if (op + lit + 1 + 3 >= out_end) |
134 | if (op + lit + 1 + 3 >= out_end) |
133 | return 0; |
135 | return 0; |
134 | |
136 | |
135 | if (lit) |
137 | if (lit) |
136 | { |
138 | { |
137 | *op++ = lit - 1; |
139 | *op++ = lit - 1; |
138 | lit = -lit; |
140 | lit = -lit; |
139 | do |
141 | do |
140 | *op++ = ip[lit]; |
142 | *op++ = ip[lit]; |
141 | while (++lit); |
143 | while (++lit); |
142 | } |
144 | } |
143 | |
145 | |
144 | len -= 2; |
146 | len -= 2; |
145 | ip++; |
147 | ip++; |
146 | |
148 | |
147 | if (len < 7) |
149 | if (len < 7) |
148 | { |
150 | { |
149 | *op++ = (off >> 8) + (len << 5); |
151 | *op++ = (off >> 8) + (len << 5); |
150 | } |
152 | } |
151 | else |
153 | else |
152 | { |
154 | { |
153 | *op++ = (off >> 8) + ( 7 << 5); |
155 | *op++ = (off >> 8) + ( 7 << 5); |
154 | *op++ = len - 7; |
156 | *op++ = len - 7; |
155 | } |
157 | } |
156 | |
158 | |
157 | *op++ = off; |
159 | *op++ = off; |
158 | |
160 | |
159 | #if ULTRA_FAST |
161 | #if ULTRA_FAST |
160 | ip += len; |
162 | ip += len; |
161 | hval = FRST (ip); |
163 | hval = FRST (ip); |
162 | hval = NEXT (hval, ip); |
164 | hval = NEXT (hval, ip); |
163 | htab[IDX (hval)] = ip; |
165 | htab[IDX (hval)] = ip; |
164 | ip++; |
166 | ip++; |
165 | #else |
167 | #else |
166 | do |
168 | do |
167 | { |
169 | { |
168 | hval = NEXT (hval, ip); |
170 | hval = NEXT (hval, ip); |
169 | htab[IDX (hval)] = ip; |
171 | htab[IDX (hval)] = ip; |
|
|
172 | ip++; |
|
|
173 | } |
|
|
174 | while (len--); |
|
|
175 | #endif |
|
|
176 | continue; |
|
|
177 | } |
|
|
178 | } |
|
|
179 | else if (ip == in_end) |
|
|
180 | break; |
|
|
181 | |
|
|
182 | /* one more literal byte we must copy */ |
|
|
183 | lit++; |
170 | ip++; |
184 | ip++; |
171 | } |
|
|
172 | while (len--); |
|
|
173 | #endif |
|
|
174 | } |
|
|
175 | else |
|
|
176 | { |
|
|
177 | /* one more literal byte we must copy */ |
|
|
178 | lit++; |
|
|
179 | ip++; |
|
|
180 | |
185 | |
181 | if (lit == MAX_LIT) |
186 | if (lit == MAX_LIT) |
182 | { |
187 | { |
183 | if (op + 1 + MAX_LIT >= out_end) |
188 | if (op + 1 + MAX_LIT >= out_end) |
184 | return 0; |
189 | return 0; |
185 | |
190 | |
186 | *op++ = MAX_LIT - 1; |
191 | *op++ = MAX_LIT - 1; |
187 | #if USE_MEMCPY |
192 | #if USE_MEMCPY |
188 | memcpy (op, ip - MAX_LIT, MAX_LIT); |
193 | memcpy (op, ip - MAX_LIT, MAX_LIT); |
189 | op += MAX_LIT; |
194 | op += MAX_LIT; |
190 | lit = 0; |
195 | lit = 0; |
191 | #else |
196 | #else |
192 | lit = -lit; |
197 | lit = -lit; |
193 | do |
198 | do |
194 | *op++ = ip[lit]; |
199 | *op++ = ip[lit]; |
195 | while (++lit); |
200 | while (++lit); |
196 | #endif |
201 | #endif |
197 | } |
202 | } |
198 | } |
|
|
199 | } |
203 | } |
200 | while (ip < in_end); |
|
|
201 | |
204 | |
202 | if (lit) |
205 | if (lit) |
203 | { |
206 | { |
204 | if (op + lit + 1 >= out_end) |
207 | if (op + lit + 1 >= out_end) |
205 | return 0; |
208 | return 0; |