Home | History | Annotate | Download | only in util
      1 /**************************************************************
      2     Form adapted from lzhuf.c
      3     written by Haruyasu Yoshizaki 11/20/1988
      4     some minor changes 4/6/1989
      5     comments translated by Haruhiko Okumura 4/7/1989
      6 
      7     minor beautifications and adjustments for compiling under Linux
      8     by Markus Gutschke <gutschk (at) math.uni-muenster.de>
      9     						1997-01-27
     10 
     11     Modifications to allow use as a filter by Ken Yap
     12     <ken_yap (at) users.sourceforge.net>.
     13 
     14 						1997-07-01
     15 
     16     Small mod to cope with running on big-endian machines
     17     by Jim Hague <jim.hague (at) acm.org)
     18 						1998-02-06
     19 
     20     Make compression statistics report shorter
     21     by Ken Yap <ken_yap (at) users.sourceforge.net>.
     22 						2001-04-25
     23 
     24     Replaced algorithm with nrv2b from ucl the compression
     25     library from upx.  That code is:
     26     Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer
     27     And is distributed under the terms of the GPL.
     28     The conversion was performed
     29     by Eric Biederman <ebiederman (at) lnxi.com>.
     30                                              20 August 2002
     31 
     32 **************************************************************/
     33 #define UCLPACK_COMPAT 0
     34 #define NDEBUG 1
     35 #include <stdio.h>
     36 #include <stdlib.h>
     37 #include <string.h>
     38 #include <ctype.h>
     39 #include <errno.h>
     40 #ifdef __FreeBSD__
     41 #include <inttypes.h>
     42 #else
     43 #include <stdint.h>
     44 #endif
     45 #include <limits.h>
     46 #include <assert.h>
     47 #if UCLPACK_COMPAT
     48 #include <netinet/in.h>
     49 #endif
     50 
     51 #ifndef VERBOSE
     52 #define Fprintf(x)
     53 #define wterr     0
     54 #else
     55 #define Fprintf(x) fprintf x
     56 #endif
     57 
     58 #ifndef MAIN
     59 extern
     60 #endif
     61 FILE  *infile, *outfile;
     62 
     63 #if defined(ENCODE) || defined(DECODE)
     64 
     65 #ifndef ENDIAN
     66 #define ENDIAN   0
     67 #endif
     68 #ifndef BITSIZE
     69 #define BITSIZE 32
     70 #endif
     71 
     72 static __inline__ void Error(char *message)
     73 {
     74 	Fprintf((stderr, "\n%s\n", message));
     75 	exit(EXIT_FAILURE);
     76 }
     77 
     78 /* These will be a complete waste of time on a lo-endian */
     79 /* system, but it only gets done once so WTF. */
     80 static unsigned long i86ul_to_host(unsigned long ul)
     81 {
     82 	unsigned long res = 0;
     83 	int i;
     84 	union
     85 	{
     86 		unsigned char c[4];
     87 		unsigned long ul;
     88 	} u;
     89 
     90 	u.ul = ul;
     91 	for (i = 3; i >= 0; i--)
     92 		res = (res << 8) + u.c[i];
     93 	return res;
     94 }
     95 
     96 static unsigned long host_to_i86ul(unsigned long ul)
     97 {
     98 	int i;
     99 	union
    100 	{
    101 		unsigned char c[4];
    102 		unsigned long ul;
    103 	} u;
    104 
    105 	for (i = 0; i < 4; i++)
    106 	{
    107 		u.c[i] = ul & 0xff;
    108 		ul >>= 8;
    109 	}
    110 	return u.ul;
    111 }
    112 #endif
    113 
    114 
    115 
    116 #if UCLPACK_COMPAT
    117 /* magic file header for compressed files */
    118 static const unsigned char magic[8] =
    119 { 0x00, 0xe9, 0x55, 0x43, 0x4c, 0xff, 0x01, 0x1a };
    120 
    121 #endif
    122 
    123 #ifdef ENCODE
    124 /********** NRV2B_99 compression **********/
    125 
    126 /* Note by limiting the ring buffer I have limited the maximum
    127  * offset to 64K.  Since etherboot rarely gets that big it
    128  * is not a problem and it gives me a firm guarantee
    129  * that I will never get a 3 byte string match that is encodes
    130  * to more than 9/8 it's original size.
    131  * That guaranteee is important to for the inplace decompressor.
    132  * There are better ways to do this if a larger offset and buffer
    133  * would give better compression.
    134  */
    135 #define N       (65536ul)           /* size of ring buffer */
    136 #define THRESHOLD       1           /* lower limit for match length */
    137 #define F            2048           /* upper limit for match length */
    138 #define M2_MAX_OFFSET                 0xd00
    139 
    140 /* note: to use default values pass -1, i.e. initialize
    141  * this struct by a memset(x,0xff,sizeof(x)) */
    142 struct ucl_compress_config
    143 {
    144 	int bb_endian;
    145 	int bb_size;
    146 	unsigned int max_offset;
    147 	unsigned int max_match;
    148 	int s_level;
    149 	int h_level;
    150 	int p_level;
    151 	int c_flags;
    152 	unsigned int m_size;
    153 };
    154 
    155 struct ucl_compress
    156 {
    157 	int init;
    158 
    159 	unsigned int look;          /* bytes in lookahead buffer */
    160 
    161 	unsigned int m_len;
    162 	unsigned int m_off;
    163 
    164 	unsigned int last_m_len;
    165 	unsigned int last_m_off;
    166 
    167 	const unsigned char *bp;
    168 	const unsigned char *ip;
    169 	const unsigned char *in;
    170 	const unsigned char *in_end;
    171 	unsigned char *out;
    172 
    173 	uint64_t bb_b;
    174 	unsigned bb_k;
    175 	unsigned bb_c_endian;
    176 	unsigned bb_c_s;
    177 	unsigned bb_c_s8;
    178 	unsigned char *bb_p;
    179 	unsigned char *bb_op;
    180 
    181 	struct ucl_compress_config conf;
    182 	unsigned int *result;
    183 
    184 	unsigned int textsize;      /* text size counter */
    185 	unsigned int codesize;      /* code size counter */
    186 	unsigned int printcount; /* counter for reporting progress every 1K
    187 				    bytes */
    188 
    189 
    190 	/* some stats */
    191 	unsigned long lit_bytes;
    192 	unsigned long match_bytes;
    193 	unsigned long rep_bytes;
    194 	unsigned long lazy;
    195 };
    196 
    197 
    198 
    199 #define getbyte(c)  ((c).ip < (c).in_end ? *((c).ip)++ : (-1))
    200 
    201 #define UCL_E_OK               0
    202 #define UCL_E_INVALID_ARGUMENT 1
    203 #define UCL_E_OUT_OF_MEMORY    2
    204 #define UCL_E_ERROR            3
    205 
    206 /***********************************************************************
    207 //
    208 ************************************************************************/
    209 
    210 #define SWD_HSIZE	16384
    211 #define SWD_MAX_CHAIN	2048
    212 #define SWD_BEST_OFF    1
    213 
    214 #define HEAD3(b,p) \
    215     (((0x9f5f*(((((uint32_t)b[p]<<5)^b[p+1])<<5)^b[p+2]))>>5) & (SWD_HSIZE-1))
    216 
    217 #define HEAD2(b,p)      (b[p] ^ ((unsigned)b[p+1]<<8))
    218 #define NIL2              UINT_MAX
    219 
    220 struct ucl_swd
    221 {
    222 /* public - "built-in" */
    223 	unsigned int n;
    224 	unsigned int f;
    225 	unsigned int threshold;
    226 
    227 /* public - configuration */
    228 	unsigned int max_chain;
    229 	unsigned int nice_length;
    230 	int use_best_off;
    231 	unsigned int lazy_insert;
    232 
    233 /* public - output */
    234 	unsigned int m_len;
    235 	unsigned int m_off;
    236 	unsigned int look;
    237 	int b_char;
    238 #if defined(SWD_BEST_OFF)
    239 	unsigned int best_off[ SWD_BEST_OFF ];
    240 #endif
    241 
    242 /* semi public */
    243 	struct ucl_compress *c;
    244 	unsigned int m_pos;
    245 #if defined(SWD_BEST_OFF)
    246 	unsigned int best_pos[ SWD_BEST_OFF ];
    247 #endif
    248 
    249 /* private */
    250 	const uint8_t *dict;
    251 	const uint8_t *dict_end;
    252 	unsigned int dict_len;
    253 
    254 /* private */
    255 	unsigned int ip;                /* input pointer (lookahead) */
    256 	unsigned int bp;                /* buffer pointer */
    257 	unsigned int rp;                /* remove pointer */
    258 	unsigned int b_size;
    259 
    260 	unsigned char *b_wrap;
    261 
    262 	unsigned int node_count;
    263 	unsigned int first_rp;
    264 
    265 	unsigned char b [ N + F + F ];
    266 	unsigned int head3 [ SWD_HSIZE ];
    267 	unsigned int succ3 [ N + F ];
    268 	unsigned int best3 [ N + F ];
    269 	unsigned int llen3 [ SWD_HSIZE ];
    270 	unsigned int head2 [ 65536U ];
    271 };
    272 
    273 #define s_head3(s,key)        s->head3[key]
    274 
    275 
    276 #if !defined( NDEBUG)
    277 static void assert_match(const struct ucl_swd * swd, unsigned int m_len,
    278 	unsigned int m_off )
    279 
    280 {
    281 	const struct ucl_compress *c = swd->c;
    282 	unsigned int d_off;
    283 
    284 	assert(m_len >= 2);
    285 	if (m_off <= (unsigned int) (c->bp - c->in))
    286 	{
    287 		assert(c->bp - m_off + m_len < c->ip);
    288 		assert(memcmp(c->bp, c->bp - m_off, m_len) == 0);
    289 	}
    290 	else
    291 	{
    292 		assert(swd->dict != NULL);
    293 		d_off = m_off - (unsigned int) (c->bp - c->in);
    294 		assert(d_off <= swd->dict_len);
    295 		if (m_len > d_off)
    296 		{
    297 			assert(memcmp(c->bp, swd->dict_end - d_off, d_off) ==
    298 				0);
    299 
    300 			assert(c->in + m_len - d_off < c->ip);
    301 			assert(memcmp(c->bp + d_off, c->in, m_len - d_off) ==
    302 				0);
    303 
    304 		}
    305 		else
    306 		{
    307 			assert(memcmp(c->bp, swd->dict_end - d_off, m_len) ==
    308 				0);
    309 
    310 		}
    311 	}
    312 }
    313 #else
    314 #  define assert_match(a,b,c)   ((void)0)
    315 #endif
    316 
    317 /***********************************************************************
    318 //
    319 ************************************************************************/
    320 
    321 
    322 static
    323 void swd_initdict(struct ucl_swd *s, const uint8_t *dict, unsigned int dict_len)
    324 
    325 {
    326 	s->dict = s->dict_end = NULL;
    327 	s->dict_len = 0;
    328 
    329 	if (!dict || dict_len <= 0)
    330 		return;
    331 	if (dict_len > s->n)
    332 	{
    333 		dict += dict_len - s->n;
    334 		dict_len = s->n;
    335 	}
    336 
    337 	s->dict = dict;
    338 	s->dict_len = dict_len;
    339 	s->dict_end = dict + dict_len;
    340 	memcpy(s->b,dict,dict_len);
    341 	s->ip = dict_len;
    342 }
    343 
    344 
    345 static
    346 void swd_insertdict(struct ucl_swd *s, unsigned int node, unsigned int len)
    347 {
    348 	unsigned int key;
    349 
    350 	s->node_count = s->n - len;
    351 	s->first_rp = node;
    352 
    353 	while (len-- > 0)
    354 	{
    355 		key = HEAD3(s->b,node);
    356 		s->succ3[node] = s_head3(s,key);
    357 		s->head3[key] = (unsigned int)(node);
    358 		s->best3[node] = (unsigned int)(s->f + 1);
    359 		s->llen3[key]++;
    360 		assert(s->llen3[key] <= s->n);
    361 
    362 		key = HEAD2(s->b,node);
    363 		s->head2[key] = (unsigned int)(node);
    364 
    365 		node++;
    366 	}
    367 }
    368 
    369 /***********************************************************************
    370 //
    371 ************************************************************************/
    372 
    373 
    374 static
    375 int swd_init(struct ucl_swd *s, const uint8_t *dict, unsigned int dict_len)
    376 {
    377 	unsigned int i = 0;
    378 	int c = 0;
    379 
    380 	if (s->n == 0)
    381 		s->n = N;
    382 	if (s->f == 0)
    383 		s->f = F;
    384 	s->threshold = THRESHOLD;
    385 	if (s->n > N || s->f > F)
    386 		return UCL_E_INVALID_ARGUMENT;
    387 
    388 	/* defaults */
    389 	s->max_chain = SWD_MAX_CHAIN;
    390 	s->nice_length = s->f;
    391 	s->use_best_off = 0;
    392 	s->lazy_insert = 0;
    393 
    394 	s->b_size = s->n + s->f;
    395 	if (s->b_size + s->f >= UINT_MAX)
    396 		return UCL_E_ERROR;
    397 	s->b_wrap = s->b + s->b_size;
    398 	s->node_count = s->n;
    399 
    400 	memset(s->llen3, 0, sizeof(s->llen3[0]) * SWD_HSIZE);
    401 	for (i = 0; i < 65536U; i++)
    402 		s->head2[i] = NIL2;
    403 
    404 	s->ip = 0;
    405 	swd_initdict(s,dict,dict_len);
    406 	s->bp = s->ip;
    407 	s->first_rp = s->ip;
    408 
    409 	assert(s->ip + s->f <= s->b_size);
    410 
    411 	s->look = (unsigned int) (s->c->in_end - s->c->ip);
    412 	if (s->look > 0)
    413 	{
    414 		if (s->look > s->f)
    415 			s->look = s->f;
    416 		memcpy(&s->b[s->ip],s->c->ip,s->look);
    417 		s->c->ip += s->look;
    418 		s->ip += s->look;
    419 	}
    420 	if (s->ip == s->b_size)
    421 		s->ip = 0;
    422 
    423 	if (s->look >= 2 && s->dict_len > 0)
    424 		swd_insertdict(s,0,s->dict_len);
    425 
    426 	s->rp = s->first_rp;
    427 	if (s->rp >= s->node_count)
    428 		s->rp -= s->node_count;
    429 	else
    430 		s->rp += s->b_size - s->node_count;
    431 
    432 	/* unused i */
    433 	/* unused c */
    434 	return UCL_E_OK;
    435 }
    436 
    437 
    438 static
    439 void swd_exit(struct ucl_swd *s)
    440 {
    441 	/* unused s */
    442 
    443 }
    444 
    445 #define swd_pos2off(s,pos) \
    446 	(s->bp > (pos) ? s->bp - (pos) : s->b_size - ((pos) - s->bp))
    447 
    448 /***********************************************************************
    449 //
    450 ************************************************************************/
    451 
    452 static __inline__
    453 void swd_getbyte(struct ucl_swd *s)
    454 {
    455 	int c;
    456 
    457 	if ((c = getbyte(*(s->c))) < 0)
    458 	{
    459 		if (s->look > 0)
    460 			--s->look;
    461 	}
    462 	else
    463 	{
    464 		s->b[s->ip] = (uint8_t)(c);
    465 		if (s->ip < s->f)
    466 			s->b_wrap[s->ip] = (uint8_t)(c);
    467 	}
    468 	if (++s->ip == s->b_size)
    469 		s->ip = 0;
    470 	if (++s->bp == s->b_size)
    471 		s->bp = 0;
    472 	if (++s->rp == s->b_size)
    473 		s->rp = 0;
    474 }
    475 /***********************************************************************
    476 // remove node from lists
    477 ************************************************************************/
    478 
    479 static __inline__
    480 void swd_remove_node(struct ucl_swd *s, unsigned int node)
    481 {
    482 	if (s->node_count == 0)
    483 	{
    484 		unsigned int key;
    485 
    486 #ifdef UCL_DEBUG
    487 		if (s->first_rp != UINT_MAX)
    488 		{
    489 			if (node != s->first_rp)
    490 				printf("Remove %5d: %5d %5d %5d %5d %6d %6d\n",
    491 
    492 					node, s->rp, s->ip, s->bp, s->first_rp,
    493 					s->ip - node, s->ip - s->bp);
    494 			assert(node == s->first_rp);
    495 			s->first_rp = UINT_MAX;
    496 		}
    497 #endif
    498 
    499 		key = HEAD3(s->b,node);
    500 		assert(s->llen3[key] > 0);
    501 		--s->llen3[key];
    502 
    503 		key = HEAD2(s->b,node);
    504 		assert(s->head2[key] != NIL2);
    505 		if ((unsigned int) s->head2[key] == node)
    506 			s->head2[key] = NIL2;
    507 	}
    508 	else
    509 		--s->node_count;
    510 }
    511 
    512 
    513 /***********************************************************************
    514 //
    515 ************************************************************************/
    516 
    517 
    518 static
    519 void swd_accept(struct ucl_swd *s, unsigned int n)
    520 {
    521 	assert(n <= s->look);
    522 
    523 	if (n > 0) do
    524 	{
    525 		unsigned int key;
    526 
    527 		swd_remove_node(s,s->rp);
    528 
    529 		/* add bp into HEAD3 */
    530 		key = HEAD3(s->b,s->bp);
    531 		s->succ3[s->bp] = s_head3(s,key);
    532 		s->head3[key] = (unsigned int)(s->bp);
    533 		s->best3[s->bp] = (unsigned int)(s->f + 1);
    534 		s->llen3[key]++;
    535 		assert(s->llen3[key] <= s->n);
    536 
    537 		/* add bp into HEAD2 */
    538 		key = HEAD2(s->b,s->bp);
    539 		s->head2[key] = (unsigned int)(s->bp);
    540 
    541 		swd_getbyte(s);
    542 	} while (--n > 0);
    543 }
    544 
    545 /***********************************************************************
    546 //
    547 ************************************************************************/
    548 
    549 static
    550 void swd_search(struct ucl_swd *s, unsigned int node, unsigned int cnt)
    551 {
    552 	const unsigned char *p1;
    553 	const unsigned char *p2;
    554 	const unsigned char *px;
    555 
    556 	unsigned int m_len = s->m_len;
    557 	const unsigned char * b  = s->b;
    558 	const unsigned char * bp = s->b + s->bp;
    559 	const unsigned char * bx = s->b + s->bp + s->look;
    560 	unsigned char scan_end1;
    561 
    562 	assert(s->m_len > 0);
    563 
    564 	scan_end1 = bp[m_len - 1];
    565 	for ( ; cnt-- > 0; node = s->succ3[node])
    566 	{
    567 		p1 = bp;
    568 		p2 = b + node;
    569 		px = bx;
    570 
    571 		assert(m_len < s->look);
    572 
    573 		if (
    574 			p2[m_len - 1] == scan_end1 &&
    575 			p2[m_len] == p1[m_len] &&
    576 			p2[0] == p1[0] &&
    577 			p2[1] == p1[1])
    578 		{
    579 			unsigned int i;
    580 			assert(memcmp(bp,&b[node],3) == 0);
    581 
    582 			p1 += 2; p2 += 2;
    583 			do {} while (++p1 < px && *p1 == *++p2);
    584 			i = p1 - bp;
    585 
    586 #ifdef UCL_DEBUG
    587 			if (memcmp(bp,&b[node],i) != 0)
    588 				printf("%5ld %5ld %02x%02x %02x%02x\n",
    589 					(long)s->bp, (long) node,
    590 					bp[0], bp[1], b[node], b[node+1]);
    591 #endif
    592 			assert(memcmp(bp,&b[node],i) == 0);
    593 
    594 #if defined(SWD_BEST_OFF)
    595 			if (i < SWD_BEST_OFF)
    596 			{
    597 				if (s->best_pos[i] == 0)
    598 					s->best_pos[i] = node + 1;
    599 			}
    600 #endif
    601 			if (i > m_len)
    602 			{
    603 				s->m_len = m_len = i;
    604 				s->m_pos = node;
    605 				if (m_len == s->look)
    606 					return;
    607 				if (m_len >= s->nice_length)
    608 					return;
    609 				if (m_len > (unsigned int) s->best3[node])
    610 					return;
    611 				scan_end1 = bp[m_len - 1];
    612 			}
    613 		}
    614 	}
    615 }
    616 
    617 static int swd_search2(struct ucl_swd *s)
    618 {
    619 	unsigned int key;
    620 
    621 	assert(s->look >= 2);
    622 	assert(s->m_len > 0);
    623 
    624 	key = s->head2[ HEAD2(s->b,s->bp) ];
    625 	if (key == NIL2)
    626 		return 0;
    627 #ifdef UCL_DEBUG
    628 	if (memcmp(&s->b[s->bp],&s->b[key],2) != 0)
    629 		printf("%5ld %5ld %02x%02x %02x%02x\n", (long)s->bp, (long)key,
    630 			s->b[s->bp], s->b[s->bp+1], s->b[key], s->b[key+1]);
    631 #endif
    632 	assert(memcmp(&s->b[s->bp],&s->b[key],2) == 0);
    633 #if defined(SWD_BEST_OFF)
    634 	if (s->best_pos[2] == 0)
    635 		s->best_pos[2] = key + 1;
    636 #endif
    637 
    638 	if (s->m_len < 2)
    639 	{
    640 		s->m_len = 2;
    641 		s->m_pos = key;
    642 	}
    643 	return 1;
    644 }
    645 
    646 /***********************************************************************
    647 //
    648 ************************************************************************/
    649 
    650 static
    651 void swd_findbest(struct ucl_swd *s)
    652 {
    653 	unsigned int key;
    654 	unsigned int cnt, node;
    655 	unsigned int len;
    656 
    657 	assert(s->m_len > 0);
    658 
    659 	/* get current head, add bp into HEAD3 */
    660 	key = HEAD3(s->b,s->bp);
    661 	node = s->succ3[s->bp] = s_head3(s,key);
    662 	cnt = s->llen3[key]++;
    663 	assert(s->llen3[key] <= s->n + s->f);
    664 	if (cnt > s->max_chain && s->max_chain > 0)
    665 		cnt = s->max_chain;
    666 	s->head3[key] = (unsigned int)(s->bp);
    667 
    668 	s->b_char = s->b[s->bp];
    669 	len = s->m_len;
    670 	if (s->m_len >= s->look)
    671 	{
    672 		if (s->look == 0)
    673 			s->b_char = -1;
    674 		s->m_off = 0;
    675 		s->best3[s->bp] = (unsigned int)(s->f + 1);
    676 	}
    677 	else
    678 	{
    679 		if (swd_search2(s))
    680 			if (s->look >= 3)
    681 				swd_search(s,node,cnt);
    682 		if (s->m_len > len)
    683 			s->m_off = swd_pos2off(s,s->m_pos);
    684 		s->best3[s->bp] = (unsigned int)(s->m_len);
    685 
    686 #if defined(SWD_BEST_OFF)
    687 		if (s->use_best_off)
    688 		{
    689 			int i;
    690 			for (i = 2; i < SWD_BEST_OFF; i++)
    691 				if (s->best_pos[i] > 0)
    692 					s->best_off[i] =
    693 						swd_pos2off(s,s->best_pos[i]-1);
    694 
    695 				else
    696 					s->best_off[i] = 0;
    697 		}
    698 #endif
    699 	}
    700 
    701 	swd_remove_node(s,s->rp);
    702 
    703 	/* add bp into HEAD2 */
    704 	key = HEAD2(s->b,s->bp);
    705 	s->head2[key] = (unsigned int)(s->bp);
    706 }
    707 
    708 
    709 /***********************************************************************
    710 //
    711 ************************************************************************/
    712 
    713 static int
    714 init_match ( struct ucl_compress *c, struct ucl_swd *s,
    715 	const uint8_t *dict, unsigned int dict_len,
    716 	uint32_t flags )
    717 {
    718 	int r;
    719 
    720 	assert(!c->init);
    721 	c->init = 1;
    722 
    723 	s->c = c;
    724 
    725 	c->last_m_len = c->last_m_off = 0;
    726 
    727 	c->textsize = c->codesize = c->printcount = 0;
    728 	c->lit_bytes = c->match_bytes = c->rep_bytes = 0;
    729 	c->lazy = 0;
    730 
    731 	r = swd_init(s,dict,dict_len);
    732 	if (r != UCL_E_OK)
    733 	{
    734 		swd_exit(s);
    735 		return r;
    736 	}
    737 
    738 	s->use_best_off = (flags & 1) ? 1 : 0;
    739 	return UCL_E_OK;
    740 }
    741 
    742 static int
    743 find_match ( struct ucl_compress *c, struct ucl_swd *s,
    744 	unsigned int this_len, unsigned int skip )
    745 {
    746 	assert(c->init);
    747 
    748 	if (skip > 0)
    749 	{
    750 		assert(this_len >= skip);
    751 		swd_accept(s, this_len - skip);
    752 		c->textsize += this_len - skip + 1;
    753 	}
    754 	else
    755 	{
    756 		assert(this_len <= 1);
    757 		c->textsize += this_len - skip;
    758 	}
    759 
    760 	s->m_len = THRESHOLD;
    761 #ifdef SWD_BEST_OFF
    762 	if (s->use_best_off)
    763 		memset(s->best_pos,0,sizeof(s->best_pos));
    764 #endif
    765 	swd_findbest(s);
    766 	c->m_len = s->m_len;
    767 	c->m_off = s->m_off;
    768 
    769 	swd_getbyte(s);
    770 
    771 	if (s->b_char < 0)
    772 	{
    773 		c->look = 0;
    774 		c->m_len = 0;
    775 		swd_exit(s);
    776 	}
    777 	else
    778 	{
    779 		c->look = s->look + 1;
    780 	}
    781 	c->bp = c->ip - c->look;
    782 
    783 #if 0
    784 	/* brute force match search */
    785 	if (c->m_len > THRESHOLD && c->m_len + 1 <= c->look)
    786 	{
    787 		const uint8_t *ip = c->bp;
    788 		const uint8_t *m  = c->bp - c->m_off;
    789 		const uint8_t *in = c->in;
    790 
    791 		if (ip - in > N)
    792 			in = ip - N;
    793 		for (;;)
    794 		{
    795 			while (*in != *ip)
    796 				in++;
    797 			if (in == ip)
    798 				break;
    799 			if (in != m)
    800 				if (memcmp(in,ip,c->m_len+1) == 0)
    801 					printf("%p %p %p %5d\n",in,ip,m,c->m_len);
    802 
    803 			in++;
    804 		}
    805 	}
    806 #endif
    807 
    808 	return UCL_E_OK;
    809 }
    810 
    811 
    812 static int bbConfig(struct ucl_compress *c, int endian, int bitsize)
    813 {
    814 	if (endian != -1)
    815 	{
    816 		if (endian != 0)
    817 			return UCL_E_ERROR;
    818 		c->bb_c_endian = endian;
    819 	}
    820 	if (bitsize != -1)
    821 	{
    822 		if (bitsize != 8 && bitsize != 16 && bitsize != 32 && bitsize != 64)
    823 			return UCL_E_ERROR;
    824 		c->bb_c_s = bitsize;
    825 		c->bb_c_s8 = bitsize / 8;
    826 	}
    827 	c->bb_b = 0; c->bb_k = 0;
    828 	c->bb_p = NULL;
    829 	c->bb_op = NULL;
    830 	return UCL_E_OK;
    831 }
    832 
    833 static void bbWriteBits(struct ucl_compress *c)
    834 {
    835 	uint8_t *p = c->bb_p;
    836 	uint64_t b = c->bb_b;
    837 
    838 	p[0] = (uint8_t)(b >>  0);
    839 	if (c->bb_c_s >= 16)
    840 	{
    841 		p[1] = (uint8_t)(b >>  8);
    842 		if (c->bb_c_s >= 32)
    843 		{
    844 			p[2] = (uint8_t)(b >> 16);
    845 			p[3] = (uint8_t)(b >> 24);
    846 			if (c->bb_c_s == 64)
    847 			{
    848 				p[4] = (uint8_t)(b >> 32);
    849 				p[5] = (uint8_t)(b >> 40);
    850 				p[6] = (uint8_t)(b >> 48);
    851 				p[7] = (uint8_t)(b >> 56);
    852 			}
    853 		}
    854 	}
    855 }
    856 
    857 
    858 static void bbPutBit(struct ucl_compress *c, unsigned bit)
    859 {
    860 	assert(bit == 0 || bit == 1);
    861 	assert(c->bb_k <= c->bb_c_s);
    862 
    863 	if (c->bb_k < c->bb_c_s)
    864 	{
    865 		if (c->bb_k == 0)
    866 		{
    867 			assert(c->bb_p == NULL);
    868 			c->bb_p = c->bb_op;
    869 			c->bb_op += c->bb_c_s8;
    870 		}
    871 		assert(c->bb_p != NULL);
    872 		assert(c->bb_p + c->bb_c_s8 <= c->bb_op);
    873 
    874 		c->bb_b = (c->bb_b << 1) + bit;
    875 		c->bb_k++;
    876 	}
    877 	else
    878 	{
    879 		assert(c->bb_p != NULL);
    880 		assert(c->bb_p + c->bb_c_s8 <= c->bb_op);
    881 
    882 		bbWriteBits(c);
    883 		c->bb_p = c->bb_op;
    884 		c->bb_op += c->bb_c_s8;
    885 		c->bb_b = bit;
    886 		c->bb_k = 1;
    887 	}
    888 }
    889 
    890 
    891 static void bbPutByte(struct ucl_compress *c, unsigned b)
    892 {
    893 	/**printf("putbyte %p %p %x  (%d)\n", op, bb_p, x, bb_k);*/
    894 	assert(c->bb_p == NULL || c->bb_p + c->bb_c_s8 <= c->bb_op);
    895 	*c->bb_op++ = (uint8_t)(b);
    896 }
    897 
    898 static void bbFlushBits(struct ucl_compress *c, unsigned filler_bit)
    899 {
    900 	if (c->bb_k > 0)
    901 	{
    902 		assert(c->bb_k <= c->bb_c_s);
    903 		while (c->bb_k != c->bb_c_s)
    904 			bbPutBit(c, filler_bit);
    905 		bbWriteBits(c);
    906 		c->bb_k = 0;
    907 	}
    908 	c->bb_p = NULL;
    909 }
    910 
    911 
    912 
    913 /***********************************************************************
    914 //
    915 ************************************************************************/
    916 
    917 
    918 static void code_prefix_ss11(struct ucl_compress *c, uint32_t i)
    919 {
    920 	if (i >= 2)
    921 	{
    922 		uint32_t t = 4;
    923 		i += 2;
    924 		do {
    925 			t <<= 1;
    926 		} while (i >= t);
    927 		t >>= 1;
    928 		do {
    929 			t >>= 1;
    930 			bbPutBit(c, (i & t) ? 1 : 0);
    931 			bbPutBit(c, 0);
    932 		} while (t > 2);
    933 	}
    934 	bbPutBit(c, (unsigned)i & 1);
    935 	bbPutBit(c, 1);
    936 }
    937 
    938 static void
    939 code_match(struct ucl_compress *c, unsigned int m_len, const unsigned int m_off)
    940 
    941 {
    942 	while (m_len > c->conf.max_match)
    943 	{
    944 		code_match(c, c->conf.max_match - 3, m_off);
    945 		m_len -= c->conf.max_match - 3;
    946 	}
    947 
    948 	c->match_bytes += m_len;
    949 	if (m_len > c->result[3])
    950 		c->result[3] = m_len;
    951 	if (m_off > c->result[1])
    952 		c->result[1] = m_off;
    953 
    954 	bbPutBit(c, 0);
    955 
    956 	if (m_off == c->last_m_off)
    957 	{
    958 		bbPutBit(c, 0);
    959 		bbPutBit(c, 1);
    960 	}
    961 	else
    962 	{
    963 		code_prefix_ss11(c, 1 + ((m_off - 1) >> 8));
    964 		bbPutByte(c, (unsigned)m_off - 1);
    965 	}
    966 	m_len = m_len - 1 - (m_off > M2_MAX_OFFSET);
    967 	if (m_len >= 4)
    968 	{
    969 		bbPutBit(c,0);
    970 		bbPutBit(c,0);
    971 		code_prefix_ss11(c, m_len - 4);
    972 	}
    973 	else
    974 	{
    975 		bbPutBit(c, m_len > 1);
    976 		bbPutBit(c, (unsigned)m_len & 1);
    977 	}
    978 
    979 	c->last_m_off = m_off;
    980 }
    981 
    982 static void
    983 code_run(struct ucl_compress *c, const uint8_t *ii, unsigned int lit)
    984 {
    985 	if (lit == 0)
    986 		return;
    987 	c->lit_bytes += lit;
    988 	if (lit > c->result[5])
    989 		c->result[5] = lit;
    990 	do {
    991 		bbPutBit(c, 1);
    992 		bbPutByte(c, *ii++);
    993 	} while (--lit > 0);
    994 }
    995 
    996 /***********************************************************************
    997 //
    998 ************************************************************************/
    999 
   1000 static int
   1001 len_of_coded_match(struct ucl_compress *c, unsigned int m_len, unsigned int
   1002 	m_off)
   1003 
   1004 {
   1005 	int b;
   1006 	if (m_len < 2 || (m_len == 2 && (m_off > M2_MAX_OFFSET))
   1007 		|| m_off > c->conf.max_offset)
   1008 		return -1;
   1009 	assert(m_off > 0);
   1010 
   1011 	m_len = m_len - 2 - (m_off > M2_MAX_OFFSET);
   1012 
   1013 	if (m_off == c->last_m_off)
   1014 		b = 1 + 2;
   1015 	else
   1016 	{
   1017 		b = 1 + 10;
   1018 		m_off = (m_off - 1) >> 8;
   1019 		while (m_off > 0)
   1020 		{
   1021 			b += 2;
   1022 			m_off >>= 1;
   1023 		}
   1024 	}
   1025 
   1026 	b += 2;
   1027 	if (m_len < 3)
   1028 		return b;
   1029 	m_len -= 3;
   1030 
   1031 	do {
   1032 		b += 2;
   1033 		m_len >>= 1;
   1034 	} while (m_len > 0);
   1035 
   1036 	return b;
   1037 }
   1038 
   1039 int ucl_nrv2b_99_compress(
   1040 	const uint8_t *in, unsigned long in_len,
   1041 	uint8_t *out, unsigned long *out_len,
   1042 	unsigned int *result)
   1043 {
   1044 	const uint8_t *ii;
   1045 	unsigned int lit;
   1046 	unsigned int m_len, m_off;
   1047 	struct ucl_compress c_buffer;
   1048 	struct ucl_compress * const c = &c_buffer;
   1049 	struct ucl_swd *swd;
   1050 	unsigned int result_buffer[16];
   1051 	int r;
   1052 
   1053 /* max compression */
   1054 #define SC_TRY_LAZY    2
   1055 #define SC_GOOD_LENGTH F
   1056 #define SC_MAX_LAZY    F
   1057 #define SC_NICE_LENGTH F
   1058 #define SC_MAX_CHAIN   4096
   1059 #define SC_FLAGS       1
   1060 #define SC_MAX_OFFSET  N
   1061 
   1062 	memset(c, 0, sizeof(*c));
   1063 	c->ip = c->in = in;
   1064 	c->in_end = in + in_len;
   1065 	c->out = out;
   1066 	c->result = result ? result : result_buffer;
   1067 	memset(c->result, 0, 16*sizeof(*c->result));
   1068 	c->result[0] = c->result[2] = c->result[4] = UINT_MAX;
   1069 	result = NULL;
   1070 	memset(&c->conf, 0xff, sizeof(c->conf));
   1071 	r = bbConfig(c, ENDIAN, BITSIZE);
   1072 	if (r == 0)
   1073 		r = bbConfig(c, c->conf.bb_endian, c->conf.bb_size);
   1074 	if (r != 0)
   1075 		return UCL_E_INVALID_ARGUMENT;
   1076 	c->bb_op = out;
   1077 
   1078 	ii = c->ip;             /* point to start of literal run */
   1079 	lit = 0;
   1080 
   1081 
   1082 	swd = (struct ucl_swd *) malloc(sizeof(*swd));
   1083 	if (!swd)
   1084 		return UCL_E_OUT_OF_MEMORY;
   1085 
   1086 	swd->f = F;
   1087 	swd->n = N;
   1088 	if (in_len >= 256 && in_len < swd->n)
   1089 		swd->n = in_len;
   1090 	if (swd->f < 8 || swd->n < 256)
   1091 		return UCL_E_INVALID_ARGUMENT;
   1092 
   1093 	r = init_match(c,swd,NULL,0, SC_FLAGS);
   1094 	if (r != UCL_E_OK)
   1095 	{
   1096 		free(swd);
   1097 		return r;
   1098 	}
   1099 	if (SC_MAX_CHAIN > 0)
   1100 		swd->max_chain = SC_MAX_CHAIN;
   1101 	if (SC_NICE_LENGTH > 0)
   1102 		swd->nice_length = SC_NICE_LENGTH;
   1103 	if (c->conf.max_match < swd->nice_length)
   1104 		swd->nice_length = c->conf.max_match;
   1105 
   1106 	c->last_m_off = 1;
   1107 	r = find_match(c,swd,0,0);
   1108 	if (r != UCL_E_OK)
   1109 		return r;
   1110 	while (c->look > 0)
   1111 	{
   1112 		unsigned int ahead;
   1113 		unsigned int max_ahead;
   1114 		int l1, l2;
   1115 
   1116 		c->codesize = c->bb_op - out;
   1117 
   1118 		m_len = c->m_len;
   1119 		m_off = c->m_off;
   1120 
   1121 		assert(c->bp == c->ip - c->look);
   1122 		assert(c->bp >= in);
   1123 		if (lit == 0)
   1124 			ii = c->bp;
   1125 		assert(ii + lit == c->bp);
   1126 		assert(swd->b_char == *(c->bp));
   1127 
   1128 		if (m_len < 2 || (m_len == 2 && (m_off > M2_MAX_OFFSET))
   1129 			|| m_off > c->conf.max_offset)
   1130 		{
   1131 			/* a literal */
   1132 			lit++;
   1133 			swd->max_chain = SC_MAX_CHAIN;
   1134 			r = find_match(c,swd,1,0);
   1135 			assert(r == 0);
   1136 			continue;
   1137 		}
   1138 
   1139 		/* a match */
   1140 		assert_match(swd,m_len,m_off);
   1141 
   1142 		/* shall we try a lazy match ? */
   1143 		ahead = 0;
   1144 		if (SC_TRY_LAZY <= 0 || m_len >= SC_MAX_LAZY || m_off ==
   1145 			c->last_m_off)
   1146 
   1147 		{
   1148 			/* no */
   1149 			l1 = 0;
   1150 			max_ahead = 0;
   1151 		}
   1152 		else
   1153 		{
   1154 			/* yes, try a lazy match */
   1155 			l1 = len_of_coded_match(c,m_len,m_off);
   1156 			assert(l1 > 0);
   1157 			max_ahead = SC_TRY_LAZY;
   1158 			if ((m_len - 1) < max_ahead) {
   1159 				max_ahead = m_len -1;
   1160 			}
   1161 		}
   1162 
   1163 		while (ahead < max_ahead && c->look > m_len)
   1164 		{
   1165 			if (m_len >= SC_GOOD_LENGTH)
   1166 				swd->max_chain = SC_MAX_CHAIN >> 2;
   1167 			else
   1168 				swd->max_chain = SC_MAX_CHAIN;
   1169 			r = find_match(c,swd,1,0);
   1170 			ahead++;
   1171 
   1172 			assert(r == 0);
   1173 			assert(c->look > 0);
   1174 			assert(ii + lit + ahead == c->bp);
   1175 
   1176 			if (c->m_len < 2)
   1177 				continue;
   1178 			l2 = len_of_coded_match(c,c->m_len,c->m_off);
   1179 			if (l2 < 0)
   1180 				continue;
   1181 			if (l1 + (int)(ahead + c->m_len - m_len) * 5 > l2 +
   1182 				(int)(ahead) * 9)
   1183 			{
   1184 				c->lazy++;
   1185 				assert_match(swd,c->m_len,c->m_off);
   1186 				lit += ahead;
   1187 				assert(ii + lit == c->bp);
   1188 				goto lazy_match_done;
   1189 			}
   1190 		}
   1191 
   1192 		assert(ii + lit + ahead == c->bp);
   1193 
   1194 		/* 1 - code run */
   1195 		code_run(c,ii,lit);
   1196 		lit = 0;
   1197 
   1198 		/* 2 - code match */
   1199 		code_match(c,m_len,m_off);
   1200 		swd->max_chain = SC_MAX_CHAIN;
   1201 		r = find_match(c,swd,m_len,1+ahead);
   1202 		assert(r == 0);
   1203 
   1204 	lazy_match_done: ;
   1205 	}
   1206 
   1207 	/* store final run */
   1208 	code_run(c,ii,lit);
   1209 
   1210 	/* EOF */
   1211 	bbPutBit(c, 0);
   1212 	code_prefix_ss11(c, 0x1000000U);
   1213 	bbPutByte(c, 0xff);
   1214 
   1215 	bbFlushBits(c, 0);
   1216 
   1217 	assert(c->textsize == in_len);
   1218 	c->codesize = c->bb_op - out;
   1219 	*out_len = c->bb_op - out;
   1220 
   1221 #if 0
   1222 	printf("%7ld %7ld -> %7ld   %7ld %7ld   %ld  (max: %d %d %d)\n",
   1223 		(long) c->textsize, (long) in_len, (long) c->codesize,
   1224 		c->match_bytes, c->lit_bytes,  c->lazy,
   1225 		c->result[1], c->result[3], c->result[5]);
   1226 #endif
   1227 	assert(c->lit_bytes + c->match_bytes == in_len);
   1228 
   1229 	swd_exit(swd);
   1230 	free(swd);
   1231 
   1232 	return UCL_E_OK;
   1233 }
   1234 
   1235 
   1236 void Encode(void)  /* compression */
   1237 {
   1238 	uint8_t *in, *out;
   1239 	unsigned long in_len, out_len;
   1240 	uint32_t tw;
   1241 	int r;
   1242 	fseek(infile, 0, SEEK_END);
   1243 	in_len = ftell(infile);
   1244 #ifdef VERBOSE
   1245 	if ((signed long)in_len < 0)
   1246 		Fprintf((stderr, "Errno: %d", errno));
   1247 #endif
   1248 #if UCLPACK_COMPAT
   1249 	{
   1250 		uint8_t byte;
   1251 		if (fwrite(magic, sizeof(magic), 1, outfile) != 1)
   1252 			Error("Can't write.");
   1253 		tw = htonl(0); /* flags */
   1254 		if (fwrite(&tw, sizeof(tw), 1, outfile) != 1)
   1255 			Error("Can't write.");
   1256 		byte = 0x2b;		/* method */
   1257 		if (fwrite(&byte, sizeof(byte), 1, outfile) != 1)
   1258 			Error("Can't write.");
   1259 		byte = 10;		/* level */
   1260 		if (fwrite(&byte, sizeof(byte), 1, outfile) != 1)
   1261 			Error("Can't write.");
   1262 		tw = htonl(256*1024);		/* block_size */
   1263 		if (fwrite(&tw, sizeof(tw), 1, outfile) != 1)
   1264 			Error("Can't write.");
   1265 		tw = htonl(in_len);
   1266 		if (fwrite(&tw, sizeof(tw), 1, outfile) != 1)
   1267 			Error("Can't write.");	/* output size of text */
   1268 	}
   1269 #else
   1270 	tw = host_to_i86ul(in_len);
   1271 	if (fwrite(&tw, sizeof(tw), 1, outfile) != 1)
   1272 		Error("Can't write.");	/* output size of text */
   1273 #endif
   1274 	if (in_len == 0)
   1275 		return;
   1276 	rewind(infile);
   1277 
   1278 	in = malloc(in_len);
   1279 	out_len = in_len + (in_len/8) + 256;
   1280 	out = malloc(out_len);
   1281 	if (!in || !out) {
   1282 		Error("Can't malloc");
   1283 	}
   1284 	if (fread(in, in_len, 1, infile) != 1) {
   1285 		Error("Can't read");
   1286 	}
   1287 	r = ucl_nrv2b_99_compress(in, in_len, out, &out_len, 0 );
   1288 	if (r != UCL_E_OK)
   1289 		Error("Compression failure\n");
   1290 #if UCLPACK_COMPAT
   1291 	tw = htonl(out_len);
   1292 	if (fwrite(&tw, sizeof(tw), 1, outfile) != 1)
   1293 		Error("Can't write.");	/* file size of text */
   1294 
   1295 #endif
   1296 	if (fwrite(out, out_len, 1, outfile) != 1) {
   1297 		Error("Write error\n");
   1298 	}
   1299 #if UCLPACK_COMPAT
   1300 	tw = htonl(0); /* EOF marker */
   1301 	if (fwrite(&tw, sizeof(tw), 1, outfile) != 1)
   1302 		Error("Can't write.");
   1303 
   1304 #endif
   1305 
   1306 #ifdef	LONG_REPORT
   1307 	Fprintf((stdout, "input size    %ld bytes\n", in_len));
   1308 	Fprintf((stdout, "output size   %ld bytes\n", out_len));
   1309 	Fprintf((stdout, "input/output  %.3f\n", (double)in_len / out_len));
   1310 #else
   1311 	Fprintf((stdout, "input/output = %ld/%ld = %.3f\n", in_len, out_len,
   1312 		(double)in_len / out_len));
   1313 #endif
   1314 
   1315 }
   1316 
   1317 #endif
   1318 
   1319 #ifdef DECODE
   1320 
   1321 #define GETBIT_8(bb, src, ilen) \
   1322     (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1)
   1323 
   1324 #define GETBIT_LE16(bb, src, ilen) \
   1325     (bb*=2,bb&0xffff ? (bb>>16)&1 : (ilen+=2,((bb=(src[ilen-2]+src[ilen-1]*256u)*2+1)>>16)&1))
   1326 
   1327 #define GETBIT_LE32(bb, src, ilen) \
   1328     (bc > 0 ? ((bb>>--bc)&1) : (bc=31,\
   1329     bb=*(const uint32_t *)((src)+ilen),ilen+=4,(bb>>31)&1))
   1330 
   1331 #define GETBIT_LE64(bb, src, ilen) \
   1332     (bc > 0 ? ((bb>>--bc)&1) : (bc=63, \
   1333     bb=*(const uint64_t *)((src)+ilen),ilen+=8,(bb>>63)&1))
   1334 
   1335 #if ENDIAN == 0 && BITSIZE == 8
   1336 #define GETBIT(bb, src, ilen) GETBIT_8(bb, src, ilen)
   1337 #endif
   1338 #if ENDIAN == 0 && BITSIZE == 16
   1339 #define GETBIT(bb, src, ilen) GETBIT_LE16(bb, src, ilen)
   1340 #endif
   1341 #if ENDIAN == 0 && BITSIZE == 32
   1342 #define GETBIT(bb, src, ilen) GETBIT_LE32(bb, src, ilen)
   1343 #endif
   1344 #if ENDIAN == 0 && BITSIZE == 64
   1345 #define GETBIT(bb, src, ilen) GETBIT_LE64(bb, src, ilen)
   1346 #endif
   1347 #ifndef GETBIT
   1348 #error "Bad Combination of ENDIAN and BITSIZE values specified"
   1349 #endif
   1350 
   1351 #undef SAFE
   1352 
   1353 #ifdef SAFE
   1354 #define FAIL(x,r)   if (x) { Error(r); }
   1355 #else
   1356 #define FAIL(x,r)
   1357 #endif
   1358 
   1359 void Decode(void)  /* recover */
   1360 {
   1361 	uint32_t tw;
   1362 	uint8_t *src, *dst;
   1363 	unsigned long max_src_len, src_len, dst_len;
   1364 	unsigned long ilen = 0, olen = 0, last_m_off =  1;
   1365 #if BITSIZE <= 32
   1366 	uint32_t bb = 0;
   1367 #elif BITSIZE == 64
   1368 	uint64_t bb = 0;
   1369 #endif
   1370 	unsigned bc = 0;
   1371 #if UCLPACK_COMPAT
   1372 	if (fseek(infile, sizeof(magic) + sizeof(tw) + 1 + 1 + sizeof(tw),
   1373 		SEEK_SET) != 0)
   1374 
   1375 		Error("Seek Error");
   1376 	if (fread(&tw, sizeof(tw), 1, infile) < 1)
   1377 		Error("Can't read"); /* read size of text */
   1378 	dst_len = ntohl(tw);
   1379 	if (fread(&tw, sizeof(tw), 1, infile) < 1)
   1380 		Error("Can't read"); /* read size of file */
   1381 	max_src_len = ntohl(tw);
   1382 #else
   1383 	if (fread(&tw, sizeof(tw), 1, infile) < 1)
   1384 		Error("Can't read"); /* read size of text */
   1385 	dst_len = i86ul_to_host(tw);
   1386 	max_src_len = dst_len + (dst_len/8) + 256;
   1387 #endif
   1388 	if (dst_len == 0)
   1389 		return;
   1390 	dst = malloc(dst_len);
   1391 	if (!dst)
   1392 		Error("Can't malloc");
   1393 	src = malloc(max_src_len);
   1394 	if (!src)
   1395 		Error("Can't malloc");
   1396 	src_len = fread(src, 1, max_src_len, infile);
   1397 	if (src_len <= 0)
   1398 		Error("Can't read");
   1399 
   1400 	for(;;) {
   1401 		unsigned int m_off, m_len;
   1402 		while(GETBIT(bb, src, ilen)) {
   1403 			FAIL(ilen >= src_len, "input overrun");
   1404 			FAIL(olen >= dst_len, "output  overrun");
   1405 			dst[olen++] = src[ilen++];
   1406 		}
   1407 		m_off = 1;
   1408 		do {
   1409 			m_off = m_off*2 + GETBIT(bb, src, ilen);
   1410 			FAIL(ilen >= src_len, "input overrun");
   1411 			FAIL(m_off > 0xffffffU +3, "lookbehind overrun");
   1412 		} while (!GETBIT(bb, src, ilen));
   1413 		if (m_off == 2)
   1414 		{
   1415 			m_off = last_m_off;
   1416 		}
   1417 		else
   1418 		{
   1419 			FAIL(ilen >= src_len, "input overrun");
   1420 			m_off = (m_off - 3)*256 + src[ilen++];
   1421 			if (m_off == 0xffffffffU)
   1422 				break;
   1423 			last_m_off = ++m_off;
   1424 		}
   1425 		m_len = GETBIT(bb, src, ilen);
   1426 		m_len = m_len*2 + GETBIT(bb, src, ilen);
   1427 		if (m_len == 0)
   1428 		{
   1429 			m_len++;
   1430 			do {
   1431 				m_len = m_len*2 + GETBIT(bb, src, ilen);
   1432 				FAIL(ilen >= src_len, "input overrun");
   1433 				FAIL(m_len >= dst_len, "output overrun");
   1434 			} while(!GETBIT(bb, src, ilen));
   1435 			m_len += 2;
   1436 		}
   1437 		m_len += (m_off > 0xd00);
   1438 		FAIL(olen + m_len > dst_len, "output overrun");
   1439 		FAIL(m_off > olen, "lookbeind overrun");
   1440 		{
   1441 			const uint8_t *m_pos;
   1442 			m_pos = dst + olen - m_off;
   1443 			dst[olen++] = *m_pos++;
   1444 			do {
   1445 				dst[olen++] = *m_pos++;
   1446 			} while(--m_len > 0);
   1447 		}
   1448 	}
   1449 	FAIL(ilen < src_len, "input not consumed");
   1450 	FAIL(ilen > src_len, "input overrun");
   1451 	assert(ilen == src_len);
   1452 	Fprintf((stderr, "%12ld\n", olen));
   1453 	if (dst_len != olen) {
   1454 		fprintf(stderr, "length != expected length\n");
   1455 	}
   1456 	if (fwrite(dst, olen, 1, outfile) != 1)
   1457 		Error("Write error\n");
   1458 	free(src);
   1459 	free(dst);
   1460 }
   1461 #endif
   1462 
   1463 #ifdef MAIN
   1464 int main(int argc, char *argv[])
   1465 {
   1466 	char  *s;
   1467 	FILE  *f;
   1468 	int    c;
   1469 
   1470 	if (argc == 2) {
   1471 		outfile = stdout;
   1472 		if ((f = tmpfile()) == NULL) {
   1473 			perror("tmpfile");
   1474 			return EXIT_FAILURE;
   1475 		}
   1476 		while ((c = getchar()) != EOF)
   1477 			fputc(c, f);
   1478 		rewind(infile = f);
   1479 	}
   1480 	else if (argc != 4) {
   1481 		Fprintf((stderr, "'nrv2b e file1 file2' encodes file1 into file2.\n"
   1482 			"'nrv2b d file2 file1' decodes file2 into file1.\n"));
   1483 		return EXIT_FAILURE;
   1484 	}
   1485 	if (argc == 4) {
   1486 		if ((s = argv[1], s[1] || strpbrk(s, "DEde") == NULL)
   1487 			|| (s = argv[2], (infile  = fopen(s, "rb")) == NULL)
   1488 			|| (s = argv[3], (outfile = fopen(s, "wb")) == NULL)) {
   1489 			Fprintf((stderr, "??? %s\n", s));
   1490 			return EXIT_FAILURE;
   1491 		}
   1492 	}
   1493 	if (toupper(*argv[1]) == 'E')
   1494 		Encode();
   1495 	else
   1496 		Decode();
   1497 	fclose(infile);
   1498 	fclose(outfile);
   1499 	return EXIT_SUCCESS;
   1500 }
   1501 #endif
   1502