diff options
author | Jens Arnold <amiconn@rockbox.org> | 2005-11-27 23:41:55 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2005-11-27 23:41:55 +0000 |
commit | 7c21a96e9afa3408ca0b459a392275aa0ae77608 (patch) | |
tree | 9933c4012631b53e72478b14db6315dfcaba5c32 /tools/ucl/src/n2_99.ch | |
parent | f04577377d879d040ef046c38f6ab18b84a51341 (diff) | |
download | rockbox-7c21a96e9afa3408ca0b459a392275aa0ae77608.tar.gz rockbox-7c21a96e9afa3408ca0b459a392275aa0ae77608.zip |
Initial check-in of (stripped-down) UCL data compression library v 1.01
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8087 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'tools/ucl/src/n2_99.ch')
-rwxr-xr-x | tools/ucl/src/n2_99.ch | 643 |
1 files changed, 643 insertions, 0 deletions
diff --git a/tools/ucl/src/n2_99.ch b/tools/ucl/src/n2_99.ch new file mode 100755 index 0000000000..5df69baaf4 --- /dev/null +++ b/tools/ucl/src/n2_99.ch | |||
@@ -0,0 +1,643 @@ | |||
1 | /* n2_99.ch -- implementation of the NRV2[BDE]-99 compression algorithms | ||
2 | |||
3 | This file is part of the UCL data compression library. | ||
4 | |||
5 | Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer | ||
6 | All Rights Reserved. | ||
7 | |||
8 | The UCL 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 UCL 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 UCL library; see the file COPYING. | ||
20 | If not, write to the Free Software Foundation, Inc., | ||
21 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | |||
23 | Markus F.X.J. Oberhumer | ||
24 | <markus@oberhumer.com> | ||
25 | http://www.oberhumer.com/opensource/ucl/ | ||
26 | */ | ||
27 | |||
28 | |||
29 | |||
30 | #include <ucl/uclconf.h> | ||
31 | #include <ucl/ucl.h> | ||
32 | #include "ucl_conf.h" | ||
33 | |||
34 | #if 0 | ||
35 | #undef UCL_DEBUG | ||
36 | #define UCL_DEBUG | ||
37 | #endif | ||
38 | |||
39 | #include <stdio.h> | ||
40 | |||
41 | #if 0 && !defined(UCL_DEBUG) | ||
42 | #undef NDEBUG | ||
43 | #include <assert.h> | ||
44 | #endif | ||
45 | |||
46 | |||
47 | /*********************************************************************** | ||
48 | // | ||
49 | ************************************************************************/ | ||
50 | |||
51 | #if 0 | ||
52 | #define N (128*1024ul) /* size of ring buffer */ | ||
53 | #else | ||
54 | #define N (1024*1024ul) /* size of ring buffer */ | ||
55 | #define SWD_USE_MALLOC | ||
56 | #define SWD_HSIZE 65536ul | ||
57 | #endif | ||
58 | #define THRESHOLD 1 /* lower limit for match length */ | ||
59 | #define F 2048 /* upper limit for match length */ | ||
60 | |||
61 | #if defined(NRV2B) | ||
62 | # define UCL_COMPRESS_T ucl_nrv2b_t | ||
63 | # define ucl_swd_t ucl_nrv2b_swd_t | ||
64 | # define ucl_nrv_99_compress ucl_nrv2b_99_compress | ||
65 | # define M2_MAX_OFFSET 0xd00 | ||
66 | #elif defined(NRV2D) | ||
67 | # define UCL_COMPRESS_T ucl_nrv2d_t | ||
68 | # define ucl_swd_t ucl_nrv2d_swd_t | ||
69 | # define ucl_nrv_99_compress ucl_nrv2d_99_compress | ||
70 | # define M2_MAX_OFFSET 0x500 | ||
71 | #elif defined(NRV2E) | ||
72 | # define UCL_COMPRESS_T ucl_nrv2e_t | ||
73 | # define ucl_swd_t ucl_nrv2e_swd_t | ||
74 | # define ucl_nrv_99_compress ucl_nrv2e_99_compress | ||
75 | # define M2_MAX_OFFSET 0x500 | ||
76 | #else | ||
77 | # error | ||
78 | #endif | ||
79 | #define ucl_swd_p ucl_swd_t * __UCL_MMODEL | ||
80 | |||
81 | #if 0 | ||
82 | # define HEAD3(b,p) \ | ||
83 | ((((((ucl_uint32)b[p]<<3)^b[p+1])<<3)^b[p+2]) & (SWD_HSIZE-1)) | ||
84 | #endif | ||
85 | #if 0 && defined(UCL_UNALIGNED_OK_4) && (UCL_BYTE_ORDER == UCL_LITTLE_ENDIAN) | ||
86 | # define HEAD3(b,p) \ | ||
87 | (((* (ucl_uint32p) &b[p]) ^ ((* (ucl_uint32p) &b[p])>>10)) & (SWD_HSIZE-1)) | ||
88 | #endif | ||
89 | |||
90 | #include "ucl_mchw.ch" | ||
91 | |||
92 | |||
93 | /*********************************************************************** | ||
94 | // | ||
95 | ************************************************************************/ | ||
96 | |||
97 | static void code_prefix_ss11(UCL_COMPRESS_T *c, ucl_uint32 i) | ||
98 | { | ||
99 | if (i >= 2) | ||
100 | { | ||
101 | ucl_uint32 t = 4; | ||
102 | i += 2; | ||
103 | do { | ||
104 | t <<= 1; | ||
105 | } while (i >= t); | ||
106 | t >>= 1; | ||
107 | do { | ||
108 | t >>= 1; | ||
109 | bbPutBit(c, (i & t) ? 1 : 0); | ||
110 | bbPutBit(c, 0); | ||
111 | } while (t > 2); | ||
112 | } | ||
113 | bbPutBit(c, (unsigned)i & 1); | ||
114 | bbPutBit(c, 1); | ||
115 | } | ||
116 | |||
117 | |||
118 | #if defined(NRV2D) || defined(NRV2E) | ||
119 | static void code_prefix_ss12(UCL_COMPRESS_T *c, ucl_uint32 i) | ||
120 | { | ||
121 | if (i >= 2) | ||
122 | { | ||
123 | ucl_uint32 t = 2; | ||
124 | do { | ||
125 | i -= t; | ||
126 | t <<= 2; | ||
127 | } while (i >= t); | ||
128 | do { | ||
129 | t >>= 1; | ||
130 | bbPutBit(c, (i & t) ? 1 : 0); | ||
131 | bbPutBit(c, 0); | ||
132 | t >>= 1; | ||
133 | bbPutBit(c, (i & t) ? 1 : 0); | ||
134 | } while (t > 2); | ||
135 | } | ||
136 | bbPutBit(c, (unsigned)i & 1); | ||
137 | bbPutBit(c, 1); | ||
138 | } | ||
139 | #endif | ||
140 | |||
141 | |||
142 | static void | ||
143 | code_match(UCL_COMPRESS_T *c, ucl_uint m_len, const ucl_uint m_off) | ||
144 | { | ||
145 | unsigned m_low = 0; | ||
146 | |||
147 | while (m_len > c->conf.max_match) | ||
148 | { | ||
149 | code_match(c, c->conf.max_match - 3, m_off); | ||
150 | m_len -= c->conf.max_match - 3; | ||
151 | } | ||
152 | |||
153 | c->match_bytes += m_len; | ||
154 | if (m_len > c->result[3]) | ||
155 | c->result[3] = m_len; | ||
156 | if (m_off > c->result[1]) | ||
157 | c->result[1] = m_off; | ||
158 | |||
159 | bbPutBit(c, 0); | ||
160 | |||
161 | #if defined(NRV2B) | ||
162 | if (m_off == c->last_m_off) | ||
163 | { | ||
164 | bbPutBit(c, 0); | ||
165 | bbPutBit(c, 1); | ||
166 | } | ||
167 | else | ||
168 | { | ||
169 | code_prefix_ss11(c, 1 + ((m_off - 1) >> 8)); | ||
170 | bbPutByte(c, (unsigned)m_off - 1); | ||
171 | } | ||
172 | m_len = m_len - 1 - (m_off > M2_MAX_OFFSET); | ||
173 | if (m_len >= 4) | ||
174 | { | ||
175 | bbPutBit(c,0); | ||
176 | bbPutBit(c,0); | ||
177 | code_prefix_ss11(c, m_len - 4); | ||
178 | } | ||
179 | else | ||
180 | { | ||
181 | bbPutBit(c, m_len > 1); | ||
182 | bbPutBit(c, (unsigned)m_len & 1); | ||
183 | } | ||
184 | #elif defined(NRV2D) | ||
185 | m_len = m_len - 1 - (m_off > M2_MAX_OFFSET); | ||
186 | assert(m_len > 0); | ||
187 | m_low = (m_len >= 4) ? 0u : (unsigned) m_len; | ||
188 | if (m_off == c->last_m_off) | ||
189 | { | ||
190 | bbPutBit(c, 0); | ||
191 | bbPutBit(c, 1); | ||
192 | bbPutBit(c, m_low > 1); | ||
193 | bbPutBit(c, m_low & 1); | ||
194 | } | ||
195 | else | ||
196 | { | ||
197 | code_prefix_ss12(c, 1 + ((m_off - 1) >> 7)); | ||
198 | bbPutByte(c, ((((unsigned)m_off - 1) & 0x7f) << 1) | ((m_low > 1) ? 0 : 1)); | ||
199 | bbPutBit(c, m_low & 1); | ||
200 | } | ||
201 | if (m_len >= 4) | ||
202 | code_prefix_ss11(c, m_len - 4); | ||
203 | #elif defined(NRV2E) | ||
204 | m_len = m_len - 1 - (m_off > M2_MAX_OFFSET); | ||
205 | assert(m_len > 0); | ||
206 | m_low = (m_len <= 2); | ||
207 | if (m_off == c->last_m_off) | ||
208 | { | ||
209 | bbPutBit(c, 0); | ||
210 | bbPutBit(c, 1); | ||
211 | bbPutBit(c, m_low); | ||
212 | } | ||
213 | else | ||
214 | { | ||
215 | code_prefix_ss12(c, 1 + ((m_off - 1) >> 7)); | ||
216 | bbPutByte(c, ((((unsigned)m_off - 1) & 0x7f) << 1) | (m_low ^ 1)); | ||
217 | } | ||
218 | if (m_low) | ||
219 | bbPutBit(c, (unsigned)m_len - 1); | ||
220 | else if (m_len <= 4) | ||
221 | { | ||
222 | bbPutBit(c, 1); | ||
223 | bbPutBit(c, (unsigned)m_len - 3); | ||
224 | } | ||
225 | else | ||
226 | { | ||
227 | bbPutBit(c, 0); | ||
228 | code_prefix_ss11(c, m_len - 5); | ||
229 | } | ||
230 | #else | ||
231 | # error | ||
232 | #endif | ||
233 | |||
234 | c->last_m_off = m_off; | ||
235 | UCL_UNUSED(m_low); | ||
236 | } | ||
237 | |||
238 | |||
239 | static void | ||
240 | code_run(UCL_COMPRESS_T *c, const ucl_byte *ii, ucl_uint lit) | ||
241 | { | ||
242 | if (lit == 0) | ||
243 | return; | ||
244 | c->lit_bytes += lit; | ||
245 | if (lit > c->result[5]) | ||
246 | c->result[5] = lit; | ||
247 | do { | ||
248 | bbPutBit(c, 1); | ||
249 | bbPutByte(c, *ii++); | ||
250 | } while (--lit > 0); | ||
251 | } | ||
252 | |||
253 | |||
254 | /*********************************************************************** | ||
255 | // | ||
256 | ************************************************************************/ | ||
257 | |||
258 | static int | ||
259 | len_of_coded_match(UCL_COMPRESS_T *c, ucl_uint m_len, ucl_uint m_off) | ||
260 | { | ||
261 | int b; | ||
262 | if (m_len < 2 || (m_len == 2 && (m_off > M2_MAX_OFFSET)) | ||
263 | || m_off > c->conf.max_offset) | ||
264 | return -1; | ||
265 | assert(m_off > 0); | ||
266 | |||
267 | m_len = m_len - 2 - (m_off > M2_MAX_OFFSET); | ||
268 | |||
269 | if (m_off == c->last_m_off) | ||
270 | b = 1 + 2; | ||
271 | else | ||
272 | { | ||
273 | #if defined(NRV2B) | ||
274 | b = 1 + 10; | ||
275 | m_off = (m_off - 1) >> 8; | ||
276 | while (m_off > 0) | ||
277 | { | ||
278 | b += 2; | ||
279 | m_off >>= 1; | ||
280 | } | ||
281 | #elif defined(NRV2D) || defined(NRV2E) | ||
282 | b = 1 + 9; | ||
283 | m_off = (m_off - 1) >> 7; | ||
284 | while (m_off > 0) | ||
285 | { | ||
286 | b += 3; | ||
287 | m_off >>= 2; | ||
288 | } | ||
289 | #else | ||
290 | # error | ||
291 | #endif | ||
292 | } | ||
293 | |||
294 | #if defined(NRV2B) || defined(NRV2D) | ||
295 | b += 2; | ||
296 | if (m_len < 3) | ||
297 | return b; | ||
298 | m_len -= 3; | ||
299 | #elif defined(NRV2E) | ||
300 | b += 2; | ||
301 | if (m_len < 2) | ||
302 | return b; | ||
303 | if (m_len < 4) | ||
304 | return b + 1; | ||
305 | m_len -= 4; | ||
306 | #else | ||
307 | # error | ||
308 | #endif | ||
309 | do { | ||
310 | b += 2; | ||
311 | m_len >>= 1; | ||
312 | } while (m_len > 0); | ||
313 | |||
314 | return b; | ||
315 | } | ||
316 | |||
317 | |||
318 | /*********************************************************************** | ||
319 | // | ||
320 | ************************************************************************/ | ||
321 | |||
322 | #if !defined(NDEBUG) | ||
323 | static | ||
324 | void assert_match( const ucl_swd_p swd, ucl_uint m_len, ucl_uint m_off ) | ||
325 | { | ||
326 | const UCL_COMPRESS_T *c = swd->c; | ||
327 | ucl_uint d_off; | ||
328 | |||
329 | assert(m_len >= 2); | ||
330 | if (m_off <= (ucl_uint) (c->bp - c->in)) | ||
331 | { | ||
332 | assert(c->bp - m_off + m_len < c->ip); | ||
333 | assert(ucl_memcmp(c->bp, c->bp - m_off, m_len) == 0); | ||
334 | } | ||
335 | else | ||
336 | { | ||
337 | assert(swd->dict != NULL); | ||
338 | d_off = m_off - (ucl_uint) (c->bp - c->in); | ||
339 | assert(d_off <= swd->dict_len); | ||
340 | if (m_len > d_off) | ||
341 | { | ||
342 | assert(ucl_memcmp(c->bp, swd->dict_end - d_off, d_off) == 0); | ||
343 | assert(c->in + m_len - d_off < c->ip); | ||
344 | assert(ucl_memcmp(c->bp + d_off, c->in, m_len - d_off) == 0); | ||
345 | } | ||
346 | else | ||
347 | { | ||
348 | assert(ucl_memcmp(c->bp, swd->dict_end - d_off, m_len) == 0); | ||
349 | } | ||
350 | } | ||
351 | } | ||
352 | #else | ||
353 | # define assert_match(a,b,c) ((void)0) | ||
354 | #endif | ||
355 | |||
356 | |||
357 | #if defined(SWD_BEST_OFF) | ||
358 | |||
359 | static void | ||
360 | better_match ( const ucl_swd_p swd, ucl_uint *m_len, ucl_uint *m_off ) | ||
361 | { | ||
362 | } | ||
363 | |||
364 | #endif | ||
365 | |||
366 | |||
367 | /*********************************************************************** | ||
368 | // | ||
369 | ************************************************************************/ | ||
370 | |||
371 | UCL_PUBLIC(int) | ||
372 | ucl_nrv_99_compress ( const ucl_bytep in, ucl_uint in_len, | ||
373 | ucl_bytep out, ucl_uintp out_len, | ||
374 | ucl_progress_callback_p cb, | ||
375 | int level, | ||
376 | const struct ucl_compress_config_p conf, | ||
377 | ucl_uintp result) | ||
378 | { | ||
379 | const ucl_byte *ii; | ||
380 | ucl_uint lit; | ||
381 | ucl_uint m_len, m_off; | ||
382 | UCL_COMPRESS_T c_buffer; | ||
383 | UCL_COMPRESS_T * const c = &c_buffer; | ||
384 | #undef swd | ||
385 | #if 1 && defined(SWD_USE_MALLOC) | ||
386 | ucl_swd_t the_swd; | ||
387 | # define swd (&the_swd) | ||
388 | #else | ||
389 | ucl_swd_p swd; | ||
390 | #endif | ||
391 | ucl_uint result_buffer[16]; | ||
392 | int r; | ||
393 | |||
394 | struct swd_config_t | ||
395 | { | ||
396 | unsigned try_lazy; | ||
397 | ucl_uint good_length; | ||
398 | ucl_uint max_lazy; | ||
399 | ucl_uint nice_length; | ||
400 | ucl_uint max_chain; | ||
401 | ucl_uint32 flags; | ||
402 | ucl_uint32 max_offset; | ||
403 | }; | ||
404 | const struct swd_config_t *sc; | ||
405 | static const struct swd_config_t swd_config[10] = { | ||
406 | /* faster compression */ | ||
407 | { 0, 0, 0, 8, 4, 0, 48*1024L }, | ||
408 | { 0, 0, 0, 16, 8, 0, 48*1024L }, | ||
409 | { 0, 0, 0, 32, 16, 0, 48*1024L }, | ||
410 | { 1, 4, 4, 16, 16, 0, 48*1024L }, | ||
411 | { 1, 8, 16, 32, 32, 0, 48*1024L }, | ||
412 | { 1, 8, 16, 128, 128, 0, 48*1024L }, | ||
413 | { 2, 8, 32, 128, 256, 0, 128*1024L }, | ||
414 | { 2, 32, 128, F, 2048, 1, 128*1024L }, | ||
415 | { 2, 32, 128, F, 2048, 1, 256*1024L }, | ||
416 | { 2, F, F, F, 4096, 1, N } | ||
417 | /* max. compression */ | ||
418 | }; | ||
419 | |||
420 | if (level < 1 || level > 10) | ||
421 | return UCL_E_INVALID_ARGUMENT; | ||
422 | sc = &swd_config[level - 1]; | ||
423 | |||
424 | memset(c, 0, sizeof(*c)); | ||
425 | c->ip = c->in = in; | ||
426 | c->in_end = in + in_len; | ||
427 | c->out = out; | ||
428 | if (cb && cb->callback) | ||
429 | c->cb = cb; | ||
430 | cb = NULL; | ||
431 | c->result = result ? result : (ucl_uintp) result_buffer; | ||
432 | memset(c->result, 0, 16*sizeof(*c->result)); | ||
433 | c->result[0] = c->result[2] = c->result[4] = UCL_UINT_MAX; | ||
434 | result = NULL; | ||
435 | memset(&c->conf, 0xff, sizeof(c->conf)); | ||
436 | if (conf) | ||
437 | memcpy(&c->conf, conf, sizeof(c->conf)); | ||
438 | conf = NULL; | ||
439 | r = bbConfig(c, 0, 8); | ||
440 | if (r == 0) | ||
441 | r = bbConfig(c, c->conf.bb_endian, c->conf.bb_size); | ||
442 | if (r != 0) | ||
443 | return UCL_E_INVALID_ARGUMENT; | ||
444 | c->bb_op = out; | ||
445 | |||
446 | ii = c->ip; /* point to start of literal run */ | ||
447 | lit = 0; | ||
448 | |||
449 | #if !defined(swd) | ||
450 | swd = (ucl_swd_p) ucl_alloc(1, ucl_sizeof(*swd)); | ||
451 | if (!swd) | ||
452 | return UCL_E_OUT_OF_MEMORY; | ||
453 | #endif | ||
454 | swd->f = UCL_MIN(F, c->conf.max_match); | ||
455 | swd->n = UCL_MIN(N, sc->max_offset); | ||
456 | if (c->conf.max_offset != UCL_UINT_MAX) | ||
457 | swd->n = UCL_MIN(N, c->conf.max_offset); | ||
458 | if (in_len >= 256 && in_len < swd->n) | ||
459 | swd->n = in_len; | ||
460 | if (swd->f < 8 || swd->n < 256) | ||
461 | return UCL_E_INVALID_ARGUMENT; | ||
462 | r = init_match(c,swd,NULL,0,sc->flags); | ||
463 | if (r != UCL_E_OK) | ||
464 | { | ||
465 | #if !defined(swd) | ||
466 | ucl_free(swd); | ||
467 | #endif | ||
468 | return r; | ||
469 | } | ||
470 | if (sc->max_chain > 0) | ||
471 | swd->max_chain = sc->max_chain; | ||
472 | if (sc->nice_length > 0) | ||
473 | swd->nice_length = sc->nice_length; | ||
474 | if (c->conf.max_match < swd->nice_length) | ||
475 | swd->nice_length = c->conf.max_match; | ||
476 | |||
477 | if (c->cb) | ||
478 | (*c->cb->callback)(0,0,-1,c->cb->user); | ||
479 | |||
480 | c->last_m_off = 1; | ||
481 | r = find_match(c,swd,0,0); | ||
482 | if (r != UCL_E_OK) | ||
483 | return r; | ||
484 | while (c->look > 0) | ||
485 | { | ||
486 | ucl_uint ahead; | ||
487 | ucl_uint max_ahead; | ||
488 | int l1, l2; | ||
489 | |||
490 | c->codesize = c->bb_op - out; | ||
491 | |||
492 | m_len = c->m_len; | ||
493 | m_off = c->m_off; | ||
494 | |||
495 | assert(c->bp == c->ip - c->look); | ||
496 | assert(c->bp >= in); | ||
497 | if (lit == 0) | ||
498 | ii = c->bp; | ||
499 | assert(ii + lit == c->bp); | ||
500 | assert(swd->b_char == *(c->bp)); | ||
501 | |||
502 | if (m_len < 2 || (m_len == 2 && (m_off > M2_MAX_OFFSET)) | ||
503 | || m_off > c->conf.max_offset) | ||
504 | { | ||
505 | /* a literal */ | ||
506 | lit++; | ||
507 | swd->max_chain = sc->max_chain; | ||
508 | r = find_match(c,swd,1,0); | ||
509 | assert(r == 0); | ||
510 | continue; | ||
511 | } | ||
512 | |||
513 | /* a match */ | ||
514 | #if defined(SWD_BEST_OFF) | ||
515 | if (swd->use_best_off) | ||
516 | better_match(swd,&m_len,&m_off); | ||
517 | #endif | ||
518 | assert_match(swd,m_len,m_off); | ||
519 | |||
520 | /* shall we try a lazy match ? */ | ||
521 | ahead = 0; | ||
522 | if (sc->try_lazy <= 0 || m_len >= sc->max_lazy || m_off == c->last_m_off) | ||
523 | { | ||
524 | /* no */ | ||
525 | l1 = 0; | ||
526 | max_ahead = 0; | ||
527 | } | ||
528 | else | ||
529 | { | ||
530 | /* yes, try a lazy match */ | ||
531 | l1 = len_of_coded_match(c,m_len,m_off); | ||
532 | assert(l1 > 0); | ||
533 | max_ahead = UCL_MIN(sc->try_lazy, m_len - 1); | ||
534 | } | ||
535 | |||
536 | while (ahead < max_ahead && c->look > m_len) | ||
537 | { | ||
538 | if (m_len >= sc->good_length) | ||
539 | swd->max_chain = sc->max_chain >> 2; | ||
540 | else | ||
541 | swd->max_chain = sc->max_chain; | ||
542 | r = find_match(c,swd,1,0); | ||
543 | ahead++; | ||
544 | |||
545 | assert(r == 0); | ||
546 | assert(c->look > 0); | ||
547 | assert(ii + lit + ahead == c->bp); | ||
548 | |||
549 | if (c->m_len < 2) | ||
550 | continue; | ||
551 | #if defined(SWD_BEST_OFF) | ||
552 | if (swd->use_best_off) | ||
553 | better_match(swd,&c->m_len,&c->m_off); | ||
554 | #endif | ||
555 | l2 = len_of_coded_match(c,c->m_len,c->m_off); | ||
556 | if (l2 < 0) | ||
557 | continue; | ||
558 | #if 1 | ||
559 | if (l1 + (int)(ahead + c->m_len - m_len) * 5 > l2 + (int)(ahead) * 9) | ||
560 | #else | ||
561 | if (l1 > l2) | ||
562 | #endif | ||
563 | { | ||
564 | c->lazy++; | ||
565 | assert_match(swd,c->m_len,c->m_off); | ||
566 | |||
567 | #if 0 | ||
568 | if (l3 > 0) | ||
569 | { | ||
570 | /* code previous run */ | ||
571 | code_run(c,ii,lit); | ||
572 | lit = 0; | ||
573 | /* code shortened match */ | ||
574 | code_match(c,ahead,m_off); | ||
575 | } | ||
576 | else | ||
577 | #endif | ||
578 | { | ||
579 | lit += ahead; | ||
580 | assert(ii + lit == c->bp); | ||
581 | } | ||
582 | goto lazy_match_done; | ||
583 | } | ||
584 | } | ||
585 | |||
586 | assert(ii + lit + ahead == c->bp); | ||
587 | |||
588 | /* 1 - code run */ | ||
589 | code_run(c,ii,lit); | ||
590 | lit = 0; | ||
591 | |||
592 | /* 2 - code match */ | ||
593 | code_match(c,m_len,m_off); | ||
594 | swd->max_chain = sc->max_chain; | ||
595 | r = find_match(c,swd,m_len,1+ahead); | ||
596 | assert(r == 0); | ||
597 | |||
598 | lazy_match_done: ; | ||
599 | } | ||
600 | |||
601 | /* store final run */ | ||
602 | code_run(c,ii,lit); | ||
603 | |||
604 | /* EOF */ | ||
605 | bbPutBit(c, 0); | ||
606 | #if defined(NRV2B) | ||
607 | code_prefix_ss11(c, UCL_UINT32_C(0x1000000)); | ||
608 | bbPutByte(c, 0xff); | ||
609 | #elif defined(NRV2D) || defined(NRV2E) | ||
610 | code_prefix_ss12(c, UCL_UINT32_C(0x1000000)); | ||
611 | bbPutByte(c, 0xff); | ||
612 | #else | ||
613 | # error | ||
614 | #endif | ||
615 | bbFlushBits(c, 0); | ||
616 | |||
617 | assert(c->textsize == in_len); | ||
618 | c->codesize = c->bb_op - out; | ||
619 | *out_len = c->bb_op - out; | ||
620 | if (c->cb) | ||
621 | (*c->cb->callback)(c->textsize,c->codesize,4,c->cb->user); | ||
622 | |||
623 | #if 0 | ||
624 | printf("%7ld %7ld -> %7ld %7ld %7ld %ld (max: %d %d %d)\n", | ||
625 | (long) c->textsize, (long) in_len, (long) c->codesize, | ||
626 | c->match_bytes, c->lit_bytes, c->lazy, | ||
627 | c->result[1], c->result[3], c->result[5]); | ||
628 | #endif | ||
629 | assert(c->lit_bytes + c->match_bytes == in_len); | ||
630 | |||
631 | swd_exit(swd); | ||
632 | #if !defined(swd) | ||
633 | ucl_free(swd); | ||
634 | #endif | ||
635 | return UCL_E_OK; | ||
636 | #undef swd | ||
637 | } | ||
638 | |||
639 | |||
640 | /* | ||
641 | vi:ts=4:et | ||
642 | */ | ||
643 | |||