diff options
author | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2021-12-15 21:04:28 +0100 |
---|---|---|
committer | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2021-12-24 18:05:53 +0100 |
commit | c876d3bbefe0dc00c27ca0c12d29da5874946962 (patch) | |
tree | 69f468a185a369b01998314bc3ecc19b70f4fcaa /utils/rbutilqt/mspack/lzssd.c | |
parent | 6c6f0757d7a902feb293be165d1490c42bc8e7ad (diff) | |
download | rockbox-c876d3bbefe0dc00c27ca0c12d29da5874946962.tar.gz rockbox-c876d3bbefe0dc00c27ca0c12d29da5874946962.zip |
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
Diffstat (limited to 'utils/rbutilqt/mspack/lzssd.c')
-rw-r--r-- | utils/rbutilqt/mspack/lzssd.c | 93 |
1 files changed, 93 insertions, 0 deletions
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 @@ | |||
1 | /* This file is part of libmspack. | ||
2 | * (C) 2003-2010 Stuart Caie. | ||
3 | * | ||
4 | * LZSS is a derivative of LZ77 and was created by James Storer and | ||
5 | * Thomas Szymanski in 1982. Haruhiko Okumura wrote a very popular C | ||
6 | * implementation. | ||
7 | * | ||
8 | * libmspack is free software; you can redistribute it and/or modify it under | ||
9 | * the terms of the GNU Lesser General Public License (LGPL) version 2.1 | ||
10 | * | ||
11 | * For further details, see the file COPYING.LIB distributed with libmspack | ||
12 | */ | ||
13 | |||
14 | #include "system-mspack.h" | ||
15 | #include "lzss.h" | ||
16 | |||
17 | #define ENSURE_BYTES do { \ | ||
18 | if (i_ptr >= i_end) { \ | ||
19 | read = system->read(input, &inbuf[0], \ | ||
20 | input_buffer_size); \ | ||
21 | if (read <= 0) { \ | ||
22 | system->free(window); \ | ||
23 | return (read < 0) ? MSPACK_ERR_READ \ | ||
24 | : MSPACK_ERR_OK; \ | ||
25 | } \ | ||
26 | i_ptr = &inbuf[0]; i_end = &inbuf[read]; \ | ||
27 | } \ | ||
28 | } while (0) | ||
29 | |||
30 | #define WRITE_BYTE do { \ | ||
31 | if (system->write(output, &window[pos], 1) != 1) { \ | ||
32 | system->free(window); \ | ||
33 | return MSPACK_ERR_WRITE; \ | ||
34 | } \ | ||
35 | } while (0) | ||
36 | |||
37 | int lzss_decompress(struct mspack_system *system, | ||
38 | struct mspack_file *input, | ||
39 | struct mspack_file *output, | ||
40 | int input_buffer_size, | ||
41 | int mode) | ||
42 | { | ||
43 | unsigned char *window, *inbuf, *i_ptr, *i_end; | ||
44 | unsigned int pos, i, c, invert, mpos, len; | ||
45 | int read; | ||
46 | |||
47 | /* check parameters */ | ||
48 | if (!system || input_buffer_size < 1 || (mode != LZSS_MODE_EXPAND && | ||
49 | mode != LZSS_MODE_MSHELP && mode != LZSS_MODE_QBASIC)) | ||
50 | { | ||
51 | return MSPACK_ERR_ARGS; | ||
52 | } | ||
53 | |||
54 | /* allocate memory */ | ||
55 | window = (unsigned char *) system->alloc(system, LZSS_WINDOW_SIZE + input_buffer_size); | ||
56 | if (!window) return MSPACK_ERR_NOMEMORY; | ||
57 | |||
58 | /* initialise decompression */ | ||
59 | inbuf = &window[LZSS_WINDOW_SIZE]; | ||
60 | memset(window, LZSS_WINDOW_FILL, (size_t) LZSS_WINDOW_SIZE); | ||
61 | pos = LZSS_WINDOW_SIZE - ((mode == LZSS_MODE_QBASIC) ? 18 : 16); | ||
62 | invert = (mode == LZSS_MODE_MSHELP) ? ~0 : 0; | ||
63 | i_ptr = i_end = &inbuf[0]; | ||
64 | |||
65 | /* loop forever; exit condition is in ENSURE_BYTES macro */ | ||
66 | for (;;) { | ||
67 | ENSURE_BYTES; c = *i_ptr++ ^ invert; | ||
68 | for (i = 0x01; i & 0xFF; i <<= 1) { | ||
69 | if (c & i) { | ||
70 | /* literal */ | ||
71 | ENSURE_BYTES; window[pos] = *i_ptr++; | ||
72 | WRITE_BYTE; | ||
73 | pos++; pos &= LZSS_WINDOW_SIZE - 1; | ||
74 | } | ||
75 | else { | ||
76 | /* match */ | ||
77 | ENSURE_BYTES; mpos = *i_ptr++; | ||
78 | ENSURE_BYTES; mpos |= (*i_ptr & 0xF0) << 4; | ||
79 | len = (*i_ptr++ & 0x0F) + 3; | ||
80 | while (len--) { | ||
81 | window[pos] = window[mpos]; | ||
82 | WRITE_BYTE; | ||
83 | pos++; pos &= LZSS_WINDOW_SIZE - 1; | ||
84 | mpos++; mpos &= LZSS_WINDOW_SIZE - 1; | ||
85 | } | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | |||
90 | /* not reached */ | ||
91 | system->free(window); | ||
92 | return MSPACK_ERR_OK; | ||
93 | } | ||