lz32/tests: Non-op cosmetics for LZOpenFile[AW] operations.
[wine.git] / dlls / itss / lzx.c
blobcfafea09c010f7628ed1d5266c382e8d1565c422
1 /***************************************************************************
2 * lzx.c - LZX decompression routines *
3 * ------------------- *
4 * *
5 * maintainer: Jed Wing <jedwin@ugcs.caltech.edu> *
6 * source: modified lzx.c from cabextract v0.5 *
7 * notes: This file was taken from cabextract v0.5, which was, *
8 * itself, a modified version of the lzx decompression code *
9 * from unlzx. *
10 * *
11 * platforms: In its current incarnation, this file has been tested on *
12 * two different Linux platforms (one, redhat-based, with a *
13 * 2.1.2 glibc and gcc 2.95.x, and the other, Debian, with *
14 * 2.2.4 glibc and both gcc 2.95.4 and gcc 3.0.2). Both were *
15 * Intel x86 compatible machines. *
16 ***************************************************************************/
18 /***************************************************************************
19 * *
20 * Copyright(C) Stuart Caie *
21 * *
22 * This library is free software; you can redistribute it and/or modify *
23 * it under the terms of the GNU Lesser General Public License as *
24 * published by the Free Software Foundation; either version 2.1 of the *
25 * License, or (at your option) any later version. *
26 * *
27 ***************************************************************************/
29 #include "lzx.h"
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
34 /* sized types */
35 typedef unsigned char UBYTE; /* 8 bits exactly */
36 typedef unsigned short UWORD; /* 16 bits (or more) */
37 typedef unsigned int ULONG; /* 32 bits (or more) */
38 typedef signed int LONG; /* 32 bits (or more) */
40 /* some constants defined by the LZX specification */
41 #define LZX_MIN_MATCH (2)
42 #define LZX_MAX_MATCH (257)
43 #define LZX_NUM_CHARS (256)
44 #define LZX_BLOCKTYPE_INVALID (0) /* also blocktypes 4-7 invalid */
45 #define LZX_BLOCKTYPE_VERBATIM (1)
46 #define LZX_BLOCKTYPE_ALIGNED (2)
47 #define LZX_BLOCKTYPE_UNCOMPRESSED (3)
48 #define LZX_PRETREE_NUM_ELEMENTS (20)
49 #define LZX_ALIGNED_NUM_ELEMENTS (8) /* aligned offset tree #elements */
50 #define LZX_NUM_PRIMARY_LENGTHS (7) /* this one missing from spec! */
51 #define LZX_NUM_SECONDARY_LENGTHS (249) /* length tree #elements */
53 /* LZX huffman defines: tweak tablebits as desired */
54 #define LZX_PRETREE_MAXSYMBOLS (LZX_PRETREE_NUM_ELEMENTS)
55 #define LZX_PRETREE_TABLEBITS (6)
56 #define LZX_MAINTREE_MAXSYMBOLS (LZX_NUM_CHARS + 50*8)
57 #define LZX_MAINTREE_TABLEBITS (12)
58 #define LZX_LENGTH_MAXSYMBOLS (LZX_NUM_SECONDARY_LENGTHS+1)
59 #define LZX_LENGTH_TABLEBITS (12)
60 #define LZX_ALIGNED_MAXSYMBOLS (LZX_ALIGNED_NUM_ELEMENTS)
61 #define LZX_ALIGNED_TABLEBITS (7)
63 #define LZX_LENTABLE_SAFETY (64) /* we allow length table decoding overruns */
65 #define LZX_DECLARE_TABLE(tbl) \
66 UWORD tbl##_table[(1<<LZX_##tbl##_TABLEBITS) + (LZX_##tbl##_MAXSYMBOLS<<1)];\
67 UBYTE tbl##_len [LZX_##tbl##_MAXSYMBOLS + LZX_LENTABLE_SAFETY]
69 struct LZXstate
71 UBYTE *window; /* the actual decoding window */
72 ULONG window_size; /* window size (32Kb through 2Mb) */
73 ULONG actual_size; /* window size when it was first allocated */
74 ULONG window_posn; /* current offset within the window */
75 ULONG R0, R1, R2; /* for the LRU offset system */
76 UWORD main_elements; /* number of main tree elements */
77 int header_read; /* have we started decoding at all yet? */
78 UWORD block_type; /* type of this block */
79 ULONG block_length; /* uncompressed length of this block */
80 ULONG block_remaining; /* uncompressed bytes still left to decode */
81 ULONG frames_read; /* the number of CFDATA blocks processed */
82 LONG intel_filesize; /* magic header value used for transform */
83 LONG intel_curpos; /* current offset in transform space */
84 int intel_started; /* have we seen any translatable data yet? */
86 LZX_DECLARE_TABLE(PRETREE);
87 LZX_DECLARE_TABLE(MAINTREE);
88 LZX_DECLARE_TABLE(LENGTH);
89 LZX_DECLARE_TABLE(ALIGNED);
92 /* LZX decruncher */
94 /* Microsoft's LZX document and their implementation of the
95 * com.ms.util.cab Java package do not concur.
97 * In the LZX document, there is a table showing the correlation between
98 * window size and the number of position slots. It states that the 1MB
99 * window = 40 slots and the 2MB window = 42 slots. In the implementation,
100 * 1MB = 42 slots, 2MB = 50 slots. The actual calculation is 'find the
101 * first slot whose position base is equal to or more than the required
102 * window size'. This would explain why other tables in the document refer
103 * to 50 slots rather than 42.
105 * The constant NUM_PRIMARY_LENGTHS used in the decompression pseudocode
106 * is not defined in the specification.
108 * The LZX document does not state the uncompressed block has an
109 * uncompressed length field. Where does this length field come from, so
110 * we can know how large the block is? The implementation has it as the 24
111 * bits following after the 3 blocktype bits, before the alignment
112 * padding.
114 * The LZX document states that aligned offset blocks have their aligned
115 * offset huffman tree AFTER the main and length trees. The implementation
116 * suggests that the aligned offset tree is BEFORE the main and length
117 * trees.
119 * The LZX document decoding algorithm states that, in an aligned offset
120 * block, if an extra_bits value is 1, 2 or 3, then that number of bits
121 * should be read and the result added to the match offset. This is
122 * correct for 1 and 2, but not 3, where just a huffman symbol (using the
123 * aligned tree) should be read.
125 * Regarding the E8 preprocessing, the LZX document states 'No translation
126 * may be performed on the last 6 bytes of the input block'. This is
127 * correct. However, the pseudocode provided checks for the *E8 leader*
128 * up to the last 6 bytes. If the leader appears between -10 and -7 bytes
129 * from the end, this would cause the next four bytes to be modified, at
130 * least one of which would be in the last 6 bytes, which is not allowed
131 * according to the spec.
133 * The specification states that the huffman trees must always contain at
134 * least one element. However, many CAB files contain blocks where the
135 * length tree is completely empty (because there are no matches), and
136 * this is expected to succeed.
140 /* LZX uses what it calls 'position slots' to represent match offsets.
141 * What this means is that a small 'position slot' number and a small
142 * offset from that slot are encoded instead of one large offset for
143 * every match.
144 * - position_base is an index to the position slot bases
145 * - extra_bits states how many bits of offset-from-base data is needed.
147 static const UBYTE extra_bits[51] = {
148 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
149 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
150 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
151 17, 17, 17
154 static const ULONG position_base[51] = {
155 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
156 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152,
157 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360, 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936,
158 1835008, 1966080, 2097152
161 struct LZXstate *LZXinit(int window)
163 struct LZXstate *pState=NULL;
164 ULONG wndsize = 1 << window;
165 int i, posn_slots;
167 /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
168 /* if a previously allocated window is big enough, keep it */
169 if (window < 15 || window > 21) return NULL;
171 /* allocate state and associated window */
172 pState = malloc(sizeof(struct LZXstate));
173 if (!(pState->window = malloc(wndsize)))
175 free(pState);
176 return NULL;
178 pState->actual_size = wndsize;
179 pState->window_size = wndsize;
181 /* calculate required position slots */
182 if (window == 20) posn_slots = 42;
183 else if (window == 21) posn_slots = 50;
184 else posn_slots = window << 1;
186 /** alternatively **/
187 /* posn_slots=i=0; while (i < wndsize) i += 1 << extra_bits[posn_slots++]; */
189 /* initialize other state */
190 pState->R0 = pState->R1 = pState->R2 = 1;
191 pState->main_elements = LZX_NUM_CHARS + (posn_slots << 3);
192 pState->header_read = 0;
193 pState->frames_read = 0;
194 pState->block_remaining = 0;
195 pState->block_type = LZX_BLOCKTYPE_INVALID;
196 pState->intel_curpos = 0;
197 pState->intel_started = 0;
198 pState->window_posn = 0;
200 /* initialise tables to 0 (because deltas will be applied to them) */
201 for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS; i++) pState->MAINTREE_len[i] = 0;
202 for (i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++) pState->LENGTH_len[i] = 0;
204 return pState;
207 void LZXteardown(struct LZXstate *pState)
209 if (pState)
211 free(pState->window);
212 free(pState);
216 int LZXreset(struct LZXstate *pState)
218 int i;
220 pState->R0 = pState->R1 = pState->R2 = 1;
221 pState->header_read = 0;
222 pState->frames_read = 0;
223 pState->block_remaining = 0;
224 pState->block_type = LZX_BLOCKTYPE_INVALID;
225 pState->intel_curpos = 0;
226 pState->intel_started = 0;
227 pState->window_posn = 0;
229 for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS + LZX_LENTABLE_SAFETY; i++) pState->MAINTREE_len[i] = 0;
230 for (i = 0; i < LZX_LENGTH_MAXSYMBOLS + LZX_LENTABLE_SAFETY; i++) pState->LENGTH_len[i] = 0;
232 return DECR_OK;
236 /* Bitstream reading macros:
238 * INIT_BITSTREAM should be used first to set up the system
239 * READ_BITS(var,n) takes N bits from the buffer and puts them in var
241 * ENSURE_BITS(n) ensures there are at least N bits in the bit buffer
242 * PEEK_BITS(n) extracts (without removing) N bits from the bit buffer
243 * REMOVE_BITS(n) removes N bits from the bit buffer
245 * These bit access routines work by using the area beyond the MSB and the
246 * LSB as a free source of zeroes. This avoids having to mask any bits.
247 * So we have to know the bit width of the bitbuffer variable. This is
248 * sizeof(ULONG) * 8, also defined as ULONG_BITS
251 /* number of bits in ULONG. Note: This must be at multiple of 16, and at
252 * least 32 for the bitbuffer code to work (ie, it must be able to ensure
253 * up to 17 bits - that's adding 16 bits when there's one bit left, or
254 * adding 32 bits when there are no bits left. The code should work fine
255 * for machines where ULONG >= 32 bits.
257 #define ULONG_BITS (sizeof(ULONG)<<3)
259 #define INIT_BITSTREAM do { bitsleft = 0; bitbuf = 0; } while (0)
261 #define ENSURE_BITS(n) \
262 while (bitsleft < (n)) { \
263 bitbuf |= ((inpos[1]<<8)|inpos[0]) << (ULONG_BITS-16 - bitsleft); \
264 bitsleft += 16; inpos+=2; \
267 #define PEEK_BITS(n) (bitbuf >> (ULONG_BITS - (n)))
268 #define REMOVE_BITS(n) ((bitbuf <<= (n)), (bitsleft -= (n)))
270 #define READ_BITS(v,n) do { \
271 ENSURE_BITS(n); \
272 (v) = PEEK_BITS(n); \
273 REMOVE_BITS(n); \
274 } while (0)
277 /* Huffman macros */
279 #define TABLEBITS(tbl) (LZX_##tbl##_TABLEBITS)
280 #define MAXSYMBOLS(tbl) (LZX_##tbl##_MAXSYMBOLS)
281 #define SYMTABLE(tbl) (pState->tbl##_table)
282 #define LENTABLE(tbl) (pState->tbl##_len)
284 /* BUILD_TABLE(tablename) builds a huffman lookup table from code lengths.
285 * In reality, it just calls make_decode_table() with the appropriate
286 * values - they're all fixed by some #defines anyway, so there's no point
287 * writing each call out in full by hand.
289 #define BUILD_TABLE(tbl) \
290 if (make_decode_table( \
291 MAXSYMBOLS(tbl), TABLEBITS(tbl), LENTABLE(tbl), SYMTABLE(tbl) \
292 )) { return DECR_ILLEGALDATA; }
295 /* READ_HUFFSYM(tablename, var) decodes one huffman symbol from the
296 * bitstream using the stated table and puts it in var.
298 #define READ_HUFFSYM(tbl,var) do { \
299 ENSURE_BITS(16); \
300 hufftbl = SYMTABLE(tbl); \
301 if ((i = hufftbl[PEEK_BITS(TABLEBITS(tbl))]) >= MAXSYMBOLS(tbl)) { \
302 j = 1 << (ULONG_BITS - TABLEBITS(tbl)); \
303 do { \
304 j >>= 1; i <<= 1; i |= (bitbuf & j) ? 1 : 0; \
305 if (!j) { return DECR_ILLEGALDATA; } \
306 } while ((i = hufftbl[i]) >= MAXSYMBOLS(tbl)); \
308 j = LENTABLE(tbl)[(var) = i]; \
309 REMOVE_BITS(j); \
310 } while (0)
313 /* READ_LENGTHS(tablename, first, last) reads in code lengths for symbols
314 * first to last in the given table. The code lengths are stored in their
315 * own special LZX way.
317 #define READ_LENGTHS(tbl,first,last) do { \
318 lb.bb = bitbuf; lb.bl = bitsleft; lb.ip = inpos; \
319 if (lzx_read_lens(pState, LENTABLE(tbl),(first),(last),&lb)) { \
320 return DECR_ILLEGALDATA; \
322 bitbuf = lb.bb; bitsleft = lb.bl; inpos = lb.ip; \
323 } while (0)
326 /* make_decode_table(nsyms, nbits, length[], table[])
328 * This function was coded by David Tritscher. It builds a fast huffman
329 * decoding table out of just a canonical huffman code lengths table.
331 * nsyms = total number of symbols in this huffman tree.
332 * nbits = any symbols with a code length of nbits or less can be decoded
333 * in one lookup of the table.
334 * length = A table to get code lengths from [0 to syms-1]
335 * table = The table to fill up with decoded symbols and pointers.
337 * Returns 0 for OK or 1 for error
340 static int make_decode_table(ULONG nsyms, ULONG nbits, UBYTE *length, UWORD *table) {
341 register UWORD sym;
342 register ULONG leaf;
343 register UBYTE bit_num = 1;
344 ULONG fill;
345 ULONG pos = 0; /* the current position in the decode table */
346 ULONG table_mask = 1 << nbits;
347 ULONG bit_mask = table_mask >> 1; /* don't do 0 length codes */
348 ULONG next_symbol = bit_mask; /* base of allocation for long codes */
350 /* fill entries for codes short enough for a direct mapping */
351 while (bit_num <= nbits) {
352 for (sym = 0; sym < nsyms; sym++) {
353 if (length[sym] == bit_num) {
354 leaf = pos;
356 if((pos += bit_mask) > table_mask) return 1; /* table overrun */
358 /* fill all possible lookups of this symbol with the symbol itself */
359 fill = bit_mask;
360 while (fill-- > 0) table[leaf++] = sym;
363 bit_mask >>= 1;
364 bit_num++;
367 /* if there are any codes longer than nbits */
368 if (pos != table_mask) {
369 /* clear the remainder of the table */
370 for (sym = pos; sym < table_mask; sym++) table[sym] = 0;
372 /* give ourselves room for codes to grow by up to 16 more bits */
373 pos <<= 16;
374 table_mask <<= 16;
375 bit_mask = 1 << 15;
377 while (bit_num <= 16) {
378 for (sym = 0; sym < nsyms; sym++) {
379 if (length[sym] == bit_num) {
380 leaf = pos >> 16;
381 for (fill = 0; fill < bit_num - nbits; fill++) {
382 /* if this path hasn't been taken yet, 'allocate' two entries */
383 if (table[leaf] == 0) {
384 table[(next_symbol << 1)] = 0;
385 table[(next_symbol << 1) + 1] = 0;
386 table[leaf] = next_symbol++;
388 /* follow the path and select either left or right for next bit */
389 leaf = table[leaf] << 1;
390 if ((pos >> (15-fill)) & 1) leaf++;
392 table[leaf] = sym;
394 if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
397 bit_mask >>= 1;
398 bit_num++;
402 /* full table? */
403 if (pos == table_mask) return 0;
405 /* either erroneous table, or all elements are 0 - let's find out. */
406 for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1;
407 return 0;
410 struct lzx_bits {
411 ULONG bb;
412 int bl;
413 UBYTE *ip;
416 static int lzx_read_lens(struct LZXstate *pState, UBYTE *lens, ULONG first, ULONG last, struct lzx_bits *lb) {
417 ULONG i,j, x,y;
418 int z;
420 register ULONG bitbuf = lb->bb;
421 register int bitsleft = lb->bl;
422 UBYTE *inpos = lb->ip;
423 UWORD *hufftbl;
425 for (x = 0; x < 20; x++) {
426 READ_BITS(y, 4);
427 LENTABLE(PRETREE)[x] = y;
429 BUILD_TABLE(PRETREE);
431 for (x = first; x < last; ) {
432 READ_HUFFSYM(PRETREE, z);
433 if (z == 17) {
434 READ_BITS(y, 4); y += 4;
435 while (y--) lens[x++] = 0;
437 else if (z == 18) {
438 READ_BITS(y, 5); y += 20;
439 while (y--) lens[x++] = 0;
441 else if (z == 19) {
442 READ_BITS(y, 1); y += 4;
443 READ_HUFFSYM(PRETREE, z);
444 z = lens[x] - z; if (z < 0) z += 17;
445 while (y--) lens[x++] = z;
447 else {
448 z = lens[x] - z; if (z < 0) z += 17;
449 lens[x++] = z;
453 lb->bb = bitbuf;
454 lb->bl = bitsleft;
455 lb->ip = inpos;
456 return 0;
459 int LZXdecompress(struct LZXstate *pState, unsigned char *inpos, unsigned char *outpos, int inlen, int outlen) {
460 UBYTE *endinp = inpos + inlen;
461 UBYTE *window = pState->window;
462 UBYTE *runsrc, *rundest;
463 UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
465 ULONG window_posn = pState->window_posn;
466 ULONG window_size = pState->window_size;
467 ULONG R0 = pState->R0;
468 ULONG R1 = pState->R1;
469 ULONG R2 = pState->R2;
471 register ULONG bitbuf;
472 register int bitsleft;
473 ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
474 struct lzx_bits lb; /* used in READ_LENGTHS macro */
476 int togo = outlen, this_run, main_element, aligned_bits;
477 int match_length, length_footer, extra, verbatim_bits;
478 int copy_length;
480 INIT_BITSTREAM;
482 /* read header if necessary */
483 if (!pState->header_read) {
484 i = j = 0;
485 READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
486 pState->intel_filesize = (i << 16) | j; /* or 0 if not encoded */
487 pState->header_read = 1;
490 /* main decoding loop */
491 while (togo > 0) {
492 /* last block finished, new block expected */
493 if (pState->block_remaining == 0) {
494 if (pState->block_type == LZX_BLOCKTYPE_UNCOMPRESSED) {
495 if (pState->block_length & 1) inpos++; /* realign bitstream to word */
496 INIT_BITSTREAM;
499 READ_BITS(pState->block_type, 3);
500 READ_BITS(i, 16);
501 READ_BITS(j, 8);
502 pState->block_remaining = pState->block_length = (i << 8) | j;
504 switch (pState->block_type) {
505 case LZX_BLOCKTYPE_ALIGNED:
506 for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
507 BUILD_TABLE(ALIGNED);
508 /* rest of aligned header is same as verbatim */
510 case LZX_BLOCKTYPE_VERBATIM:
511 READ_LENGTHS(MAINTREE, 0, 256);
512 READ_LENGTHS(MAINTREE, 256, pState->main_elements);
513 BUILD_TABLE(MAINTREE);
514 if (LENTABLE(MAINTREE)[0xE8] != 0) pState->intel_started = 1;
516 READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS);
517 BUILD_TABLE(LENGTH);
518 break;
520 case LZX_BLOCKTYPE_UNCOMPRESSED:
521 pState->intel_started = 1; /* because we can't assume otherwise */
522 ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
523 if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
524 R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
525 R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
526 R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
527 break;
529 default:
530 return DECR_ILLEGALDATA;
534 /* buffer exhaustion check */
535 if (inpos > endinp) {
536 /* it's possible to have a file where the next run is less than
537 * 16 bits in size. In this case, the READ_HUFFSYM() macro used
538 * in building the tables will exhaust the buffer, so we should
539 * allow for this, but not allow those accidentally read bits to
540 * be used (so we check that there are at least 16 bits
541 * remaining - in this boundary case they aren't really part of
542 * the compressed data)
544 if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;
547 while ((this_run = pState->block_remaining) > 0 && togo > 0) {
548 if (this_run > togo) this_run = togo;
549 togo -= this_run;
550 pState->block_remaining -= this_run;
552 /* apply 2^x-1 mask */
553 window_posn &= window_size - 1;
554 /* runs can't straddle the window wraparound */
555 if ((window_posn + this_run) > window_size)
556 return DECR_DATAFORMAT;
558 switch (pState->block_type) {
560 case LZX_BLOCKTYPE_VERBATIM:
561 while (this_run > 0) {
562 READ_HUFFSYM(MAINTREE, main_element);
564 if (main_element < LZX_NUM_CHARS) {
565 /* literal: 0 to LZX_NUM_CHARS-1 */
566 window[window_posn++] = main_element;
567 this_run--;
569 else {
570 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
571 main_element -= LZX_NUM_CHARS;
573 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
574 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
575 READ_HUFFSYM(LENGTH, length_footer);
576 match_length += length_footer;
578 match_length += LZX_MIN_MATCH;
580 match_offset = main_element >> 3;
582 if (match_offset > 2) {
583 /* not repeated offset */
584 if (match_offset != 3) {
585 extra = extra_bits[match_offset];
586 READ_BITS(verbatim_bits, extra);
587 match_offset = position_base[match_offset] - 2 + verbatim_bits;
589 else {
590 match_offset = 1;
593 /* update repeated offset LRU queue */
594 R2 = R1; R1 = R0; R0 = match_offset;
596 else if (match_offset == 0) {
597 match_offset = R0;
599 else if (match_offset == 1) {
600 match_offset = R1;
601 R1 = R0; R0 = match_offset;
603 else /* match_offset == 2 */ {
604 match_offset = R2;
605 R2 = R0; R0 = match_offset;
608 rundest = window + window_posn;
609 this_run -= match_length;
611 /* copy any wrapped around source data */
612 if (window_posn >= match_offset) {
613 /* no wrap */
614 runsrc = rundest - match_offset;
615 } else {
616 runsrc = rundest + (window_size - match_offset);
617 copy_length = match_offset - window_posn;
618 if (copy_length < match_length) {
619 match_length -= copy_length;
620 window_posn += copy_length;
621 while (copy_length-- > 0) *rundest++ = *runsrc++;
622 runsrc = window;
625 window_posn += match_length;
627 /* copy match data - no worries about destination wraps */
628 while (match_length-- > 0) *rundest++ = *runsrc++;
632 break;
634 case LZX_BLOCKTYPE_ALIGNED:
635 while (this_run > 0) {
636 READ_HUFFSYM(MAINTREE, main_element);
638 if (main_element < LZX_NUM_CHARS) {
639 /* literal: 0 to LZX_NUM_CHARS-1 */
640 window[window_posn++] = main_element;
641 this_run--;
643 else {
644 /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
645 main_element -= LZX_NUM_CHARS;
647 match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
648 if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
649 READ_HUFFSYM(LENGTH, length_footer);
650 match_length += length_footer;
652 match_length += LZX_MIN_MATCH;
654 match_offset = main_element >> 3;
656 if (match_offset > 2) {
657 /* not repeated offset */
658 extra = extra_bits[match_offset];
659 match_offset = position_base[match_offset] - 2;
660 if (extra > 3) {
661 /* verbatim and aligned bits */
662 extra -= 3;
663 READ_BITS(verbatim_bits, extra);
664 match_offset += (verbatim_bits << 3);
665 READ_HUFFSYM(ALIGNED, aligned_bits);
666 match_offset += aligned_bits;
668 else if (extra == 3) {
669 /* aligned bits only */
670 READ_HUFFSYM(ALIGNED, aligned_bits);
671 match_offset += aligned_bits;
673 else if (extra > 0) { /* extra==1, extra==2 */
674 /* verbatim bits only */
675 READ_BITS(verbatim_bits, extra);
676 match_offset += verbatim_bits;
678 else /* extra == 0 */ {
679 /* ??? */
680 match_offset = 1;
683 /* update repeated offset LRU queue */
684 R2 = R1; R1 = R0; R0 = match_offset;
686 else if (match_offset == 0) {
687 match_offset = R0;
689 else if (match_offset == 1) {
690 match_offset = R1;
691 R1 = R0; R0 = match_offset;
693 else /* match_offset == 2 */ {
694 match_offset = R2;
695 R2 = R0; R0 = match_offset;
698 rundest = window + window_posn;
699 this_run -= match_length;
701 /* copy any wrapped around source data */
702 if (window_posn >= match_offset) {
703 /* no wrap */
704 runsrc = rundest - match_offset;
705 } else {
706 runsrc = rundest + (window_size - match_offset);
707 copy_length = match_offset - window_posn;
708 if (copy_length < match_length) {
709 match_length -= copy_length;
710 window_posn += copy_length;
711 while (copy_length-- > 0) *rundest++ = *runsrc++;
712 runsrc = window;
715 window_posn += match_length;
717 /* copy match data - no worries about destination wraps */
718 while (match_length-- > 0) *rundest++ = *runsrc++;
722 break;
724 case LZX_BLOCKTYPE_UNCOMPRESSED:
725 if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;
726 memcpy(window + window_posn, inpos, (size_t) this_run);
727 inpos += this_run; window_posn += this_run;
728 break;
730 default:
731 return DECR_ILLEGALDATA; /* might as well */
737 if (togo != 0) return DECR_ILLEGALDATA;
738 memcpy(outpos, window + ((!window_posn) ? window_size : window_posn) - outlen, (size_t) outlen);
740 pState->window_posn = window_posn;
741 pState->R0 = R0;
742 pState->R1 = R1;
743 pState->R2 = R2;
745 /* intel E8 decoding */
746 if ((pState->frames_read++ < 32768) && pState->intel_filesize != 0) {
747 if (outlen <= 6 || !pState->intel_started) {
748 pState->intel_curpos += outlen;
750 else {
751 UBYTE *data = outpos;
752 UBYTE *dataend = data + outlen - 10;
753 LONG curpos = pState->intel_curpos;
754 LONG filesize = pState->intel_filesize;
755 LONG abs_off, rel_off;
757 pState->intel_curpos = curpos + outlen;
759 while (data < dataend) {
760 if (*data++ != 0xE8) { curpos++; continue; }
761 abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
762 if ((abs_off >= -curpos) && (abs_off < filesize)) {
763 rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
764 data[0] = (UBYTE) rel_off;
765 data[1] = (UBYTE) (rel_off >> 8);
766 data[2] = (UBYTE) (rel_off >> 16);
767 data[3] = (UBYTE) (rel_off >> 24);
769 data += 4;
770 curpos += 5;
774 return DECR_OK;
777 #ifdef LZX_CHM_TESTDRIVER
778 int main(int c, char **v)
780 FILE *fin, *fout;
781 struct LZXstate state;
782 UBYTE ibuf[16384];
783 UBYTE obuf[32768];
784 int ilen, olen;
785 int status;
786 int i;
787 int count=0;
788 int w = atoi(v[1]);
789 LZXinit(&state, w);
790 fout = fopen(v[2], "wb");
791 for (i=3; i<c; i++)
793 fin = fopen(v[i], "rb");
794 ilen = fread(ibuf, 1, 16384, fin);
795 status = LZXdecompress(&state, ibuf, obuf, ilen, 32768);
796 switch (status)
798 case DECR_OK:
799 printf("ok\n");
800 fwrite(obuf, 1, 32768, fout);
801 break;
802 case DECR_DATAFORMAT:
803 printf("bad format\n");
804 break;
805 case DECR_ILLEGALDATA:
806 printf("illegal data\n");
807 break;
808 case DECR_NOMEMORY:
809 printf("no memory\n");
810 break;
811 default:
812 break;
814 fclose(fin);
815 if (++count == 2)
817 count = 0;
818 LZXreset(&state);
821 fclose(fout);
823 #endif