From c876d3bbefe0dc00c27ca0c12d29da5874946962 Mon Sep 17 00:00:00 2001 From: Dominik Riebeling Date: Wed, 15 Dec 2021 21:04:28 +0100 Subject: rbutil: Merge rbutil with utils folder. rbutil uses several components from the utils folder, and can be considered part of utils too. Having it in a separate folder is an arbitrary split that doesn't help anymore these days, so merge them. This also allows other utils to easily use libtools.make without the need to navigate to a different folder. Change-Id: I3fc2f4de19e3e776553efb5dea5f779dfec0dc21 --- utils/rbutilqt/mspack/lzssd.c | 93 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 utils/rbutilqt/mspack/lzssd.c (limited to 'utils/rbutilqt/mspack/lzssd.c') diff --git a/utils/rbutilqt/mspack/lzssd.c b/utils/rbutilqt/mspack/lzssd.c new file mode 100644 index 0000000000..63716d414a --- /dev/null +++ b/utils/rbutilqt/mspack/lzssd.c @@ -0,0 +1,93 @@ +/* This file is part of libmspack. + * (C) 2003-2010 Stuart Caie. + * + * LZSS is a derivative of LZ77 and was created by James Storer and + * Thomas Szymanski in 1982. Haruhiko Okumura wrote a very popular C + * implementation. + * + * libmspack is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License (LGPL) version 2.1 + * + * For further details, see the file COPYING.LIB distributed with libmspack + */ + +#include "system-mspack.h" +#include "lzss.h" + +#define ENSURE_BYTES do { \ + if (i_ptr >= i_end) { \ + read = system->read(input, &inbuf[0], \ + input_buffer_size); \ + if (read <= 0) { \ + system->free(window); \ + return (read < 0) ? MSPACK_ERR_READ \ + : MSPACK_ERR_OK; \ + } \ + i_ptr = &inbuf[0]; i_end = &inbuf[read]; \ + } \ +} while (0) + +#define WRITE_BYTE do { \ + if (system->write(output, &window[pos], 1) != 1) { \ + system->free(window); \ + return MSPACK_ERR_WRITE; \ + } \ +} while (0) + +int lzss_decompress(struct mspack_system *system, + struct mspack_file *input, + struct mspack_file *output, + int input_buffer_size, + int mode) +{ + unsigned char *window, *inbuf, *i_ptr, *i_end; + unsigned int pos, i, c, invert, mpos, len; + int read; + + /* check parameters */ + if (!system || input_buffer_size < 1 || (mode != LZSS_MODE_EXPAND && + mode != LZSS_MODE_MSHELP && mode != LZSS_MODE_QBASIC)) + { + return MSPACK_ERR_ARGS; + } + + /* allocate memory */ + window = (unsigned char *) system->alloc(system, LZSS_WINDOW_SIZE + input_buffer_size); + if (!window) return MSPACK_ERR_NOMEMORY; + + /* initialise decompression */ + inbuf = &window[LZSS_WINDOW_SIZE]; + memset(window, LZSS_WINDOW_FILL, (size_t) LZSS_WINDOW_SIZE); + pos = LZSS_WINDOW_SIZE - ((mode == LZSS_MODE_QBASIC) ? 18 : 16); + invert = (mode == LZSS_MODE_MSHELP) ? ~0 : 0; + i_ptr = i_end = &inbuf[0]; + + /* loop forever; exit condition is in ENSURE_BYTES macro */ + for (;;) { + ENSURE_BYTES; c = *i_ptr++ ^ invert; + for (i = 0x01; i & 0xFF; i <<= 1) { + if (c & i) { + /* literal */ + ENSURE_BYTES; window[pos] = *i_ptr++; + WRITE_BYTE; + pos++; pos &= LZSS_WINDOW_SIZE - 1; + } + else { + /* match */ + ENSURE_BYTES; mpos = *i_ptr++; + ENSURE_BYTES; mpos |= (*i_ptr & 0xF0) << 4; + len = (*i_ptr++ & 0x0F) + 3; + while (len--) { + window[pos] = window[mpos]; + WRITE_BYTE; + pos++; pos &= LZSS_WINDOW_SIZE - 1; + mpos++; mpos &= LZSS_WINDOW_SIZE - 1; + } + } + } + } + + /* not reached */ + system->free(window); + return MSPACK_ERR_OK; +} -- cgit v1.2.3