From 371b264bddbe53f1312a97dc8f328a3261abd1e6 Mon Sep 17 00:00:00 2001 From: Daveo Date: Wed, 4 Jul 2001 15:34:35 +0000 Subject: [PATCH] --- source/utils/lznp.H | 1 + source/utils/lznp.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 source/utils/lznp.H create mode 100644 source/utils/lznp.cpp diff --git a/source/utils/lznp.H b/source/utils/lznp.H new file mode 100644 index 000000000..32465f1ba --- /dev/null +++ b/source/utils/lznp.H @@ -0,0 +1 @@ +int LZNP_Decode(unsigned char *in, unsigned char *out); diff --git a/source/utils/lznp.cpp b/source/utils/lznp.cpp new file mode 100644 index 000000000..13a245b5e --- /dev/null +++ b/source/utils/lznp.cpp @@ -0,0 +1,93 @@ +/* + Program: unlznp.c + Author: Nick Pelling + Function: Decompresses an LZNP-compressed file + Note: Copyright (c) 1993-1994 Nick Pelling. All rights reserved. +*/ + +/* + Notes: + + The basic procedure is: + + (a) Read a control byte, and examine each bit in turn, LSB...MSB + (b) if bit is clear, copy a byte from input stream + (c) ...else read another byte in. + if >= 0x60, this means "copy a pair from nearby" + (d) ...else split it up into a length, and high 4 bits of offset + (e) read the low order 8 bits, and merge to form (-ve) offset + (f) if (offset == 0), then exit: this terminates decompression + (g) if length is maximum length, read superlength from next byte + (h) copy length bytes from (-ve) offset. Note: this may overlap! + (i) If no more bits in control byte, read another control byte + (j) Loop. + + ...and that's it. +*/ + +#include "lznp.h" + +#define SMALLEST_LEN 2 /* smallest len usable at all */ +#define MIN_LEN 3 /* smallest short length encodable */ +#define MAX_LEN (MIN_LEN + 6-2) /* largest short length encodable */ +#define MIN_SUPERLEN (MIN_LEN + 6-1) /* shortest long length encodable */ +#define MAX_SUPERLEN (MIN_SUPERLEN + 254) /* largest long length encodable */ +#define SUPERLEN_CODE (MIN_SUPERLEN - MIN_LEN) /* means "read superlength" */ + + +typedef unsigned char UBYTE; /* just for convenience */ + + +int LZNP_Decode(UBYTE *in, UBYTE *out) +{ + int i, j; + unsigned int flags; /* now works with 16-bit ints */ + UBYTE * OriginalOut=out; + + for (flags=0;;) + { + if (((flags >>= 1) & 0xff00) == 0) + { + flags = (*in++) | 0xff00; /* uses higher byte cleverly */ + } /* (to count eight) */ + + if (!(flags & 1)) + { + *out++ = *in++; + } + else + { + i = *in++; + + if (i >= 0x60) + { + i = 0x100 - i; /* i = copy offset */ + j = SMALLEST_LEN; /* j = copy length */ + } + else + { + j = i >> 4; + i = (i & 0x0F) << 8; + i |= *in++; + + if (i == 0) /* offset of zero terminates LZNP data */ + break; + + if (j != SUPERLEN_CODE) + j += MIN_LEN; + else + j = MIN_SUPERLEN + (*in++); + } + + for (i=-i,j++; --j; out++) + { + out[0] = out[i]; + } + } + } + + /* Return size */ + return(out-OriginalOut); +} + +