libmspack 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/README.md +75 -0
- data/Rakefile +22 -0
- data/UNLICENSE +24 -0
- data/ext/Rakefile +16 -0
- data/ext/i386-windows/libmspack.dll +0 -0
- data/ext/libmspack/AUTHORS +12 -0
- data/ext/libmspack/COPYING.LIB +504 -0
- data/ext/libmspack/ChangeLog +491 -0
- data/ext/libmspack/Makefile.am +100 -0
- data/ext/libmspack/NEWS +0 -0
- data/ext/libmspack/README +130 -0
- data/ext/libmspack/TODO +8 -0
- data/ext/libmspack/cleanup.sh +9 -0
- data/ext/libmspack/configure.ac +50 -0
- data/ext/libmspack/debian/changelog +6 -0
- data/ext/libmspack/debian/control +14 -0
- data/ext/libmspack/debian/rules +101 -0
- data/ext/libmspack/doc/Doxyfile.in +22 -0
- data/ext/libmspack/doc/Makefile.in +14 -0
- data/ext/libmspack/doc/szdd_kwaj_format.html +331 -0
- data/ext/libmspack/libmspack.pc.in +10 -0
- data/ext/libmspack/mspack/cab.h +127 -0
- data/ext/libmspack/mspack/cabc.c +24 -0
- data/ext/libmspack/mspack/cabd.c +1444 -0
- data/ext/libmspack/mspack/chm.h +122 -0
- data/ext/libmspack/mspack/chmc.c +24 -0
- data/ext/libmspack/mspack/chmd.c +1392 -0
- data/ext/libmspack/mspack/crc32.c +95 -0
- data/ext/libmspack/mspack/crc32.h +17 -0
- data/ext/libmspack/mspack/des.h +15 -0
- data/ext/libmspack/mspack/hlp.h +33 -0
- data/ext/libmspack/mspack/hlpc.c +24 -0
- data/ext/libmspack/mspack/hlpd.c +24 -0
- data/ext/libmspack/mspack/kwaj.h +118 -0
- data/ext/libmspack/mspack/kwajc.c +24 -0
- data/ext/libmspack/mspack/kwajd.c +561 -0
- data/ext/libmspack/mspack/lit.h +35 -0
- data/ext/libmspack/mspack/litc.c +24 -0
- data/ext/libmspack/mspack/litd.c +24 -0
- data/ext/libmspack/mspack/lzss.h +66 -0
- data/ext/libmspack/mspack/lzssd.c +93 -0
- data/ext/libmspack/mspack/lzx.h +221 -0
- data/ext/libmspack/mspack/lzxc.c +18 -0
- data/ext/libmspack/mspack/lzxd.c +895 -0
- data/ext/libmspack/mspack/mspack.def +28 -0
- data/ext/libmspack/mspack/mspack.h +2353 -0
- data/ext/libmspack/mspack/mszip.h +126 -0
- data/ext/libmspack/mspack/mszipc.c +18 -0
- data/ext/libmspack/mspack/mszipd.c +514 -0
- data/ext/libmspack/mspack/oab.h +60 -0
- data/ext/libmspack/mspack/oabc.c +24 -0
- data/ext/libmspack/mspack/oabd.c +408 -0
- data/ext/libmspack/mspack/qtm.h +128 -0
- data/ext/libmspack/mspack/qtmc.c +18 -0
- data/ext/libmspack/mspack/qtmd.c +489 -0
- data/ext/libmspack/mspack/readbits.h +207 -0
- data/ext/libmspack/mspack/readhuff.h +173 -0
- data/ext/libmspack/mspack/sha.h +15 -0
- data/ext/libmspack/mspack/system.c +239 -0
- data/ext/libmspack/mspack/system.h +124 -0
- data/ext/libmspack/mspack/szdd.h +39 -0
- data/ext/libmspack/mspack/szddc.c +24 -0
- data/ext/libmspack/mspack/szddd.c +247 -0
- data/ext/libmspack/rebuild.sh +8 -0
- data/ext/libmspack/test/cabd_c10 +19 -0
- data/ext/libmspack/test/cabd_compare +34 -0
- data/ext/libmspack/test/cabd_md5.c +161 -0
- data/ext/libmspack/test/cabd_memory.c +179 -0
- data/ext/libmspack/test/cabd_test.c +386 -0
- data/ext/libmspack/test/cabrip.c +81 -0
- data/ext/libmspack/test/chmd_compare +38 -0
- data/ext/libmspack/test/chmd_find.c +95 -0
- data/ext/libmspack/test/chmd_md5.c +67 -0
- data/ext/libmspack/test/chmd_order.c +144 -0
- data/ext/libmspack/test/chminfo.c +284 -0
- data/ext/libmspack/test/chmx.c +216 -0
- data/ext/libmspack/test/error.h +22 -0
- data/ext/libmspack/test/expand.c +79 -0
- data/ext/libmspack/test/md5.c +457 -0
- data/ext/libmspack/test/md5.h +165 -0
- data/ext/libmspack/test/md5_fh.h +123 -0
- data/ext/libmspack/test/msdecompile_md5 +24 -0
- data/ext/libmspack/test/msexpand_md5 +39 -0
- data/ext/libmspack/test/multifh.c +435 -0
- data/ext/libmspack/test/oabx.c +41 -0
- data/ext/libmspack/test/test_files/cabd/1.pl +84 -0
- data/ext/libmspack/test/test_files/cabd/2.pl +75 -0
- data/ext/libmspack/test/test_files/cabd/bad_folderindex.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_nofiles.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_nofolders.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_signature.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt1.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt2.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt3.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt4.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt5.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/normal_255c_filename.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/normal_2files_1folder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nodata.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nofiles.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nofolder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortextheader.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfile1.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfile2.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfolder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortheader.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nofname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_noninfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nonname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nopinfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nopname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortfname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortninfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortnname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortpinfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortpname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_---.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_--D.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_-F-.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_-FD.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_H--.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_H-D.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_HF-.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_HFD.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/search_basic.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/search_tricky1.cab +0 -0
- data/ext/libmspack/winbuild.sh +26 -0
- data/ext/x86_64-windows/libmspack.dll +0 -0
- data/lib/libmspack/constants.rb +9 -0
- data/lib/libmspack/exceptions.rb +12 -0
- data/lib/libmspack/mscab.rb +722 -0
- data/lib/libmspack/mschm.rb +301 -0
- data/lib/libmspack/mshlp.rb +15 -0
- data/lib/libmspack/mskwaj.rb +124 -0
- data/lib/libmspack/mslit.rb +18 -0
- data/lib/libmspack/msoab.rb +36 -0
- data/lib/libmspack/mspack.rb +208 -0
- data/lib/libmspack/msszdd.rb +81 -0
- data/lib/libmspack/system.rb +84 -0
- data/lib/libmspack/version.rb +4 -0
- data/lib/libmspack.rb +121 -0
- data/libmspack.gemspec +33 -0
- data/spec/libmspack_spec.rb +26 -0
- data/spec/spec_helper.rb +5 -0
- metadata +309 -0
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
/* This file is part of libmspack.
|
|
2
|
+
* (C) 2003-2011 Stuart Caie.
|
|
3
|
+
*
|
|
4
|
+
* KWAJ is a format very similar to SZDD. KWAJ method 3 (LZH) was
|
|
5
|
+
* written by Jeff Johnson.
|
|
6
|
+
*
|
|
7
|
+
* libmspack is free software; you can redistribute it and/or modify it under
|
|
8
|
+
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
|
9
|
+
*
|
|
10
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/* KWAJ decompression implementation */
|
|
14
|
+
|
|
15
|
+
#include <system.h>
|
|
16
|
+
#include <kwaj.h>
|
|
17
|
+
#include <mszip.h>
|
|
18
|
+
|
|
19
|
+
/* prototypes */
|
|
20
|
+
static struct mskwajd_header *kwajd_open(
|
|
21
|
+
struct mskwaj_decompressor *base, const char *filename);
|
|
22
|
+
static void kwajd_close(
|
|
23
|
+
struct mskwaj_decompressor *base, struct mskwajd_header *hdr);
|
|
24
|
+
static int kwajd_read_headers(
|
|
25
|
+
struct mspack_system *sys, struct mspack_file *fh,
|
|
26
|
+
struct mskwajd_header *hdr);
|
|
27
|
+
static int kwajd_extract(
|
|
28
|
+
struct mskwaj_decompressor *base, struct mskwajd_header *hdr,
|
|
29
|
+
const char *filename);
|
|
30
|
+
static int kwajd_decompress(
|
|
31
|
+
struct mskwaj_decompressor *base, const char *input, const char *output);
|
|
32
|
+
static int kwajd_error(
|
|
33
|
+
struct mskwaj_decompressor *base);
|
|
34
|
+
|
|
35
|
+
static struct kwajd_stream *lzh_init(
|
|
36
|
+
struct mspack_system *sys, struct mspack_file *in, struct mspack_file *out);
|
|
37
|
+
static int lzh_decompress(
|
|
38
|
+
struct kwajd_stream *kwaj);
|
|
39
|
+
static void lzh_free(
|
|
40
|
+
struct kwajd_stream *kwaj);
|
|
41
|
+
static int lzh_read_lens(
|
|
42
|
+
struct kwajd_stream *kwaj,
|
|
43
|
+
unsigned int type, unsigned int numsyms,
|
|
44
|
+
unsigned char *lens, unsigned short *table);
|
|
45
|
+
static int lzh_read_input(
|
|
46
|
+
struct kwajd_stream *kwaj);
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
/***************************************
|
|
50
|
+
* MSPACK_CREATE_KWAJ_DECOMPRESSOR
|
|
51
|
+
***************************************
|
|
52
|
+
* constructor
|
|
53
|
+
*/
|
|
54
|
+
struct mskwaj_decompressor *
|
|
55
|
+
mspack_create_kwaj_decompressor(struct mspack_system *sys)
|
|
56
|
+
{
|
|
57
|
+
struct mskwaj_decompressor_p *self = NULL;
|
|
58
|
+
|
|
59
|
+
if (!sys) sys = mspack_default_system;
|
|
60
|
+
if (!mspack_valid_system(sys)) return NULL;
|
|
61
|
+
|
|
62
|
+
if ((self = (struct mskwaj_decompressor_p *) sys->alloc(sys, sizeof(struct mskwaj_decompressor_p)))) {
|
|
63
|
+
self->base.open = &kwajd_open;
|
|
64
|
+
self->base.close = &kwajd_close;
|
|
65
|
+
self->base.extract = &kwajd_extract;
|
|
66
|
+
self->base.decompress = &kwajd_decompress;
|
|
67
|
+
self->base.last_error = &kwajd_error;
|
|
68
|
+
self->system = sys;
|
|
69
|
+
self->error = MSPACK_ERR_OK;
|
|
70
|
+
}
|
|
71
|
+
return (struct mskwaj_decompressor *) self;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/***************************************
|
|
75
|
+
* MSPACK_DESTROY_KWAJ_DECOMPRESSOR
|
|
76
|
+
***************************************
|
|
77
|
+
* destructor
|
|
78
|
+
*/
|
|
79
|
+
void mspack_destroy_kwaj_decompressor(struct mskwaj_decompressor *base)
|
|
80
|
+
{
|
|
81
|
+
struct mskwaj_decompressor_p *self = (struct mskwaj_decompressor_p *) base;
|
|
82
|
+
if (self) {
|
|
83
|
+
struct mspack_system *sys = self->system;
|
|
84
|
+
sys->free(self);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/***************************************
|
|
89
|
+
* KWAJD_OPEN
|
|
90
|
+
***************************************
|
|
91
|
+
* opens a KWAJ file without decompressing, reads header
|
|
92
|
+
*/
|
|
93
|
+
static struct mskwajd_header *kwajd_open(struct mskwaj_decompressor *base,
|
|
94
|
+
const char *filename)
|
|
95
|
+
{
|
|
96
|
+
struct mskwaj_decompressor_p *self = (struct mskwaj_decompressor_p *) base;
|
|
97
|
+
struct mskwajd_header *hdr;
|
|
98
|
+
struct mspack_system *sys;
|
|
99
|
+
struct mspack_file *fh;
|
|
100
|
+
|
|
101
|
+
if (!self) return NULL;
|
|
102
|
+
sys = self->system;
|
|
103
|
+
|
|
104
|
+
fh = sys->open(sys, filename, MSPACK_SYS_OPEN_READ);
|
|
105
|
+
hdr = (struct mskwajd_header *) sys->alloc(sys, sizeof(struct mskwajd_header_p));
|
|
106
|
+
if (fh && hdr) {
|
|
107
|
+
((struct mskwajd_header_p *) hdr)->fh = fh;
|
|
108
|
+
self->error = kwajd_read_headers(sys, fh, hdr);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
if (!fh) self->error = MSPACK_ERR_OPEN;
|
|
112
|
+
if (!hdr) self->error = MSPACK_ERR_NOMEMORY;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (self->error) {
|
|
116
|
+
if (fh) sys->close(fh);
|
|
117
|
+
if (hdr) sys->free(hdr);
|
|
118
|
+
hdr = NULL;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return hdr;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/***************************************
|
|
125
|
+
* KWAJD_CLOSE
|
|
126
|
+
***************************************
|
|
127
|
+
* closes a KWAJ file
|
|
128
|
+
*/
|
|
129
|
+
static void kwajd_close(struct mskwaj_decompressor *base,
|
|
130
|
+
struct mskwajd_header *hdr)
|
|
131
|
+
{
|
|
132
|
+
struct mskwaj_decompressor_p *self = (struct mskwaj_decompressor_p *) base;
|
|
133
|
+
struct mskwajd_header_p *hdr_p = (struct mskwajd_header_p *) hdr;
|
|
134
|
+
|
|
135
|
+
if (!self || !self->system) return;
|
|
136
|
+
|
|
137
|
+
/* close the file handle associated */
|
|
138
|
+
self->system->close(hdr_p->fh);
|
|
139
|
+
|
|
140
|
+
/* free the memory associated */
|
|
141
|
+
self->system->free(hdr);
|
|
142
|
+
|
|
143
|
+
self->error = MSPACK_ERR_OK;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/***************************************
|
|
147
|
+
* KWAJD_READ_HEADERS
|
|
148
|
+
***************************************
|
|
149
|
+
* reads the headers of a KWAJ format file
|
|
150
|
+
*/
|
|
151
|
+
static int kwajd_read_headers(struct mspack_system *sys,
|
|
152
|
+
struct mspack_file *fh,
|
|
153
|
+
struct mskwajd_header *hdr)
|
|
154
|
+
{
|
|
155
|
+
unsigned char buf[16];
|
|
156
|
+
int i;
|
|
157
|
+
|
|
158
|
+
/* read in the header */
|
|
159
|
+
if (sys->read(fh, &buf[0], kwajh_SIZEOF) != kwajh_SIZEOF) {
|
|
160
|
+
return MSPACK_ERR_READ;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* check for "KWAJ" signature */
|
|
164
|
+
if (((unsigned int) EndGetI32(&buf[kwajh_Signature1]) != 0x4A41574B) ||
|
|
165
|
+
((unsigned int) EndGetI32(&buf[kwajh_Signature2]) != 0xD127F088))
|
|
166
|
+
{
|
|
167
|
+
return MSPACK_ERR_SIGNATURE;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* basic header fields */
|
|
171
|
+
hdr->comp_type = EndGetI16(&buf[kwajh_CompMethod]);
|
|
172
|
+
hdr->data_offset = EndGetI16(&buf[kwajh_DataOffset]);
|
|
173
|
+
hdr->headers = EndGetI16(&buf[kwajh_Flags]);
|
|
174
|
+
hdr->length = 0;
|
|
175
|
+
hdr->filename = NULL;
|
|
176
|
+
hdr->extra = NULL;
|
|
177
|
+
hdr->extra_length = 0;
|
|
178
|
+
|
|
179
|
+
/* optional headers */
|
|
180
|
+
|
|
181
|
+
/* 4 bytes: length of unpacked file */
|
|
182
|
+
if (hdr->headers & MSKWAJ_HDR_HASLENGTH) {
|
|
183
|
+
if (sys->read(fh, &buf[0], 4) != 4) return MSPACK_ERR_READ;
|
|
184
|
+
hdr->length = EndGetI32(&buf[0]);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* 2 bytes: unknown purpose */
|
|
188
|
+
if (hdr->headers & MSKWAJ_HDR_HASUNKNOWN1) {
|
|
189
|
+
if (sys->read(fh, &buf[0], 2) != 2) return MSPACK_ERR_READ;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* 2 bytes: length of section, then [length] bytes: unknown purpose */
|
|
193
|
+
if (hdr->headers & MSKWAJ_HDR_HASUNKNOWN2) {
|
|
194
|
+
if (sys->read(fh, &buf[0], 2) != 2) return MSPACK_ERR_READ;
|
|
195
|
+
i = EndGetI16(&buf[0]);
|
|
196
|
+
if (sys->seek(fh, (off_t)i, MSPACK_SYS_SEEK_CUR)) return MSPACK_ERR_SEEK;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* filename and extension */
|
|
200
|
+
if (hdr->headers & (MSKWAJ_HDR_HASFILENAME | MSKWAJ_HDR_HASFILEEXT)) {
|
|
201
|
+
off_t pos = sys->tell(fh);
|
|
202
|
+
char *fn = (char *) sys->alloc(sys, (size_t) 13);
|
|
203
|
+
|
|
204
|
+
/* allocate memory for maximum length filename */
|
|
205
|
+
if (! fn) return MSPACK_ERR_NOMEMORY;
|
|
206
|
+
hdr->filename = fn;
|
|
207
|
+
|
|
208
|
+
/* copy filename if present */
|
|
209
|
+
if (hdr->headers & MSKWAJ_HDR_HASFILENAME) {
|
|
210
|
+
if (sys->read(fh, &buf[0], 9) != 9) return MSPACK_ERR_READ;
|
|
211
|
+
for (i = 0; i < 9; i++, fn++) if (!(*fn = buf[i])) break;
|
|
212
|
+
pos += (i < 9) ? i+1 : 9;
|
|
213
|
+
if (sys->seek(fh, pos, MSPACK_SYS_SEEK_START))
|
|
214
|
+
return MSPACK_ERR_SEEK;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/* copy extension if present */
|
|
218
|
+
if (hdr->headers & MSKWAJ_HDR_HASFILEEXT) {
|
|
219
|
+
*fn++ = '.';
|
|
220
|
+
if (sys->read(fh, &buf[0], 4) != 4) return MSPACK_ERR_READ;
|
|
221
|
+
for (i = 0; i < 4; i++, fn++) if (!(*fn = buf[i])) break;
|
|
222
|
+
pos += (i < 4) ? i+1 : 4;
|
|
223
|
+
if (sys->seek(fh, pos, MSPACK_SYS_SEEK_START))
|
|
224
|
+
return MSPACK_ERR_SEEK;
|
|
225
|
+
}
|
|
226
|
+
*fn = '\0';
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/* 2 bytes: extra text length then [length] bytes of extra text data */
|
|
230
|
+
if (hdr->headers & MSKWAJ_HDR_HASEXTRATEXT) {
|
|
231
|
+
if (sys->read(fh, &buf[0], 2) != 2) return MSPACK_ERR_READ;
|
|
232
|
+
i = EndGetI16(&buf[0]);
|
|
233
|
+
hdr->extra = (char *) sys->alloc(sys, (size_t)i+1);
|
|
234
|
+
if (! hdr->extra) return MSPACK_ERR_NOMEMORY;
|
|
235
|
+
if (sys->read(fh, hdr->extra, i) != i) return MSPACK_ERR_READ;
|
|
236
|
+
hdr->extra[i] = '\0';
|
|
237
|
+
hdr->extra_length = i;
|
|
238
|
+
}
|
|
239
|
+
return MSPACK_ERR_OK;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/***************************************
|
|
243
|
+
* KWAJD_EXTRACT
|
|
244
|
+
***************************************
|
|
245
|
+
* decompresses a KWAJ file
|
|
246
|
+
*/
|
|
247
|
+
static int kwajd_extract(struct mskwaj_decompressor *base,
|
|
248
|
+
struct mskwajd_header *hdr, const char *filename)
|
|
249
|
+
{
|
|
250
|
+
struct mskwaj_decompressor_p *self = (struct mskwaj_decompressor_p *) base;
|
|
251
|
+
struct mspack_system *sys;
|
|
252
|
+
struct mspack_file *fh, *outfh;
|
|
253
|
+
|
|
254
|
+
if (!self) return MSPACK_ERR_ARGS;
|
|
255
|
+
if (!hdr) return self->error = MSPACK_ERR_ARGS;
|
|
256
|
+
|
|
257
|
+
sys = self->system;
|
|
258
|
+
fh = ((struct mskwajd_header_p *) hdr)->fh;
|
|
259
|
+
|
|
260
|
+
/* seek to the compressed data */
|
|
261
|
+
if (sys->seek(fh, hdr->data_offset, MSPACK_SYS_SEEK_START)) {
|
|
262
|
+
return self->error = MSPACK_ERR_SEEK;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/* open file for output */
|
|
266
|
+
if (!(outfh = sys->open(sys, filename, MSPACK_SYS_OPEN_WRITE))) {
|
|
267
|
+
return self->error = MSPACK_ERR_OPEN;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
self->error = MSPACK_ERR_OK;
|
|
271
|
+
|
|
272
|
+
/* decompress based on format */
|
|
273
|
+
if (hdr->comp_type == MSKWAJ_COMP_NONE ||
|
|
274
|
+
hdr->comp_type == MSKWAJ_COMP_XOR)
|
|
275
|
+
{
|
|
276
|
+
/* NONE is a straight copy. XOR is a copy xored with 0xFF */
|
|
277
|
+
unsigned char *buf = (unsigned char *) sys->alloc(sys, (size_t) KWAJ_INPUT_SIZE);
|
|
278
|
+
if (buf) {
|
|
279
|
+
int read, i;
|
|
280
|
+
while ((read = sys->read(fh, buf, KWAJ_INPUT_SIZE)) > 0) {
|
|
281
|
+
if (hdr->comp_type == MSKWAJ_COMP_XOR) {
|
|
282
|
+
for (i = 0; i < read; i++) buf[i] ^= 0xFF;
|
|
283
|
+
}
|
|
284
|
+
if (sys->write(outfh, buf, read) != read) {
|
|
285
|
+
self->error = MSPACK_ERR_WRITE;
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (read < 0) self->error = MSPACK_ERR_READ;
|
|
290
|
+
sys->free(buf);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
self->error = MSPACK_ERR_NOMEMORY;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else if (hdr->comp_type == MSKWAJ_COMP_SZDD) {
|
|
297
|
+
self->error = lzss_decompress(sys, fh, outfh, KWAJ_INPUT_SIZE,
|
|
298
|
+
LZSS_MODE_EXPAND);
|
|
299
|
+
}
|
|
300
|
+
else if (hdr->comp_type == MSKWAJ_COMP_LZH) {
|
|
301
|
+
struct kwajd_stream *lzh = lzh_init(sys, fh, outfh);
|
|
302
|
+
self->error = (lzh) ? lzh_decompress(lzh) : MSPACK_ERR_NOMEMORY;
|
|
303
|
+
lzh_free(lzh);
|
|
304
|
+
}
|
|
305
|
+
else if (hdr->comp_type == MSKWAJ_COMP_MSZIP) {
|
|
306
|
+
struct mszipd_stream *zip = mszipd_init(sys,fh,outfh,KWAJ_INPUT_SIZE,0);
|
|
307
|
+
self->error = (zip) ? mszipd_decompress_kwaj(zip) : MSPACK_ERR_NOMEMORY;
|
|
308
|
+
mszipd_free(zip);
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
self->error = MSPACK_ERR_DATAFORMAT;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/* close output file */
|
|
315
|
+
sys->close(outfh);
|
|
316
|
+
|
|
317
|
+
return self->error;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/***************************************
|
|
321
|
+
* KWAJD_DECOMPRESS
|
|
322
|
+
***************************************
|
|
323
|
+
* unpacks directly from input to output
|
|
324
|
+
*/
|
|
325
|
+
static int kwajd_decompress(struct mskwaj_decompressor *base,
|
|
326
|
+
const char *input, const char *output)
|
|
327
|
+
{
|
|
328
|
+
struct mskwaj_decompressor_p *self = (struct mskwaj_decompressor_p *) base;
|
|
329
|
+
struct mskwajd_header *hdr;
|
|
330
|
+
int error;
|
|
331
|
+
|
|
332
|
+
if (!self) return MSPACK_ERR_ARGS;
|
|
333
|
+
|
|
334
|
+
if (!(hdr = kwajd_open(base, input))) return self->error;
|
|
335
|
+
error = kwajd_extract(base, hdr, output);
|
|
336
|
+
kwajd_close(base, hdr);
|
|
337
|
+
return self->error = error;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/***************************************
|
|
341
|
+
* KWAJD_ERROR
|
|
342
|
+
***************************************
|
|
343
|
+
* returns the last error that occurred
|
|
344
|
+
*/
|
|
345
|
+
static int kwajd_error(struct mskwaj_decompressor *base)
|
|
346
|
+
{
|
|
347
|
+
struct mskwaj_decompressor_p *self = (struct mskwaj_decompressor_p *) base;
|
|
348
|
+
return (self) ? self->error : MSPACK_ERR_ARGS;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/***************************************
|
|
352
|
+
* LZH_INIT, LZH_DECOMPRESS, LZH_FREE
|
|
353
|
+
***************************************
|
|
354
|
+
* unpacks KWAJ method 3 files
|
|
355
|
+
*/
|
|
356
|
+
|
|
357
|
+
/* import bit-reading macros and code */
|
|
358
|
+
#define BITS_TYPE struct kwajd_stream
|
|
359
|
+
#define BITS_VAR lzh
|
|
360
|
+
#define BITS_ORDER_MSB
|
|
361
|
+
#define BITS_NO_READ_INPUT
|
|
362
|
+
#define READ_BYTES do { \
|
|
363
|
+
if (i_ptr >= i_end) { \
|
|
364
|
+
if ((err = lzh_read_input(lzh))) return err; \
|
|
365
|
+
i_ptr = lzh->i_ptr; \
|
|
366
|
+
i_end = lzh->i_end; \
|
|
367
|
+
} \
|
|
368
|
+
INJECT_BITS(*i_ptr++, 8); \
|
|
369
|
+
} while (0)
|
|
370
|
+
#include <readbits.h>
|
|
371
|
+
|
|
372
|
+
/* import huffman-reading macros and code */
|
|
373
|
+
#define TABLEBITS(tbl) KWAJ_TABLEBITS
|
|
374
|
+
#define MAXSYMBOLS(tbl) KWAJ_##tbl##_SYMS
|
|
375
|
+
#define HUFF_TABLE(tbl,idx) lzh->tbl##_table[idx]
|
|
376
|
+
#define HUFF_LEN(tbl,idx) lzh->tbl##_len[idx]
|
|
377
|
+
#define HUFF_ERROR return MSPACK_ERR_DATAFORMAT
|
|
378
|
+
#include <readhuff.h>
|
|
379
|
+
|
|
380
|
+
/* In the KWAJ LZH format, there is no special 'eof' marker, it just
|
|
381
|
+
* ends. Depending on how many bits are left in the final byte when
|
|
382
|
+
* the stream ends, that might be enough to start another literal or
|
|
383
|
+
* match. The only easy way to detect that we've come to an end is to
|
|
384
|
+
* guard all bit-reading. We allow fake bits to be read once we reach
|
|
385
|
+
* the end of the stream, but we check if we then consumed any of
|
|
386
|
+
* those fake bits, after doing the READ_BITS / READ_HUFFSYM. This
|
|
387
|
+
* isn't how the default readbits.h read_input() works (it simply lets
|
|
388
|
+
* 2 fake bytes in then stops), so we implement our own.
|
|
389
|
+
*/
|
|
390
|
+
#define READ_BITS_SAFE(val, n) do { \
|
|
391
|
+
READ_BITS(val, n); \
|
|
392
|
+
if (lzh->input_end && bits_left < lzh->input_end) \
|
|
393
|
+
return MSPACK_ERR_OK; \
|
|
394
|
+
} while (0)
|
|
395
|
+
|
|
396
|
+
#define READ_HUFFSYM_SAFE(tbl, val) do { \
|
|
397
|
+
READ_HUFFSYM(tbl, val); \
|
|
398
|
+
if (lzh->input_end && bits_left < lzh->input_end) \
|
|
399
|
+
return MSPACK_ERR_OK; \
|
|
400
|
+
} while (0)
|
|
401
|
+
|
|
402
|
+
#define BUILD_TREE(tbl, type) \
|
|
403
|
+
STORE_BITS; \
|
|
404
|
+
err = lzh_read_lens(lzh, type, MAXSYMBOLS(tbl), \
|
|
405
|
+
&HUFF_LEN(tbl,0), &HUFF_TABLE(tbl,0)); \
|
|
406
|
+
if (err) return err; \
|
|
407
|
+
RESTORE_BITS; \
|
|
408
|
+
if (make_decode_table(MAXSYMBOLS(tbl), TABLEBITS(tbl), \
|
|
409
|
+
&HUFF_LEN(tbl,0), &HUFF_TABLE(tbl,0))) \
|
|
410
|
+
return MSPACK_ERR_DATAFORMAT;
|
|
411
|
+
|
|
412
|
+
#define WRITE_BYTE do { \
|
|
413
|
+
if (lzh->sys->write(lzh->output, &lzh->window[pos], 1) != 1) \
|
|
414
|
+
return MSPACK_ERR_WRITE; \
|
|
415
|
+
} while (0)
|
|
416
|
+
|
|
417
|
+
static struct kwajd_stream *lzh_init(struct mspack_system *sys,
|
|
418
|
+
struct mspack_file *in, struct mspack_file *out)
|
|
419
|
+
{
|
|
420
|
+
struct kwajd_stream *lzh;
|
|
421
|
+
|
|
422
|
+
if (!sys || !in || !out) return NULL;
|
|
423
|
+
if (!(lzh = (struct kwajd_stream *) sys->alloc(sys, sizeof(struct kwajd_stream)))) return NULL;
|
|
424
|
+
|
|
425
|
+
lzh->sys = sys;
|
|
426
|
+
lzh->input = in;
|
|
427
|
+
lzh->output = out;
|
|
428
|
+
return lzh;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
static int lzh_decompress(struct kwajd_stream *lzh)
|
|
432
|
+
{
|
|
433
|
+
register unsigned int bit_buffer;
|
|
434
|
+
register int bits_left, i;
|
|
435
|
+
register unsigned short sym;
|
|
436
|
+
unsigned char *i_ptr, *i_end, lit_run = 0;
|
|
437
|
+
int j, pos = 0, len, offset, err;
|
|
438
|
+
unsigned int types[6];
|
|
439
|
+
|
|
440
|
+
/* reset global state */
|
|
441
|
+
INIT_BITS;
|
|
442
|
+
RESTORE_BITS;
|
|
443
|
+
memset(&lzh->window[0], LZSS_WINDOW_FILL, (size_t) LZSS_WINDOW_SIZE);
|
|
444
|
+
|
|
445
|
+
/* read 6 encoding types (for byte alignment) but only 5 are needed */
|
|
446
|
+
for (i = 0; i < 6; i++) READ_BITS_SAFE(types[i], 4);
|
|
447
|
+
|
|
448
|
+
/* read huffman table symbol lengths and build huffman trees */
|
|
449
|
+
BUILD_TREE(MATCHLEN1, types[0]);
|
|
450
|
+
BUILD_TREE(MATCHLEN2, types[1]);
|
|
451
|
+
BUILD_TREE(LITLEN, types[2]);
|
|
452
|
+
BUILD_TREE(OFFSET, types[3]);
|
|
453
|
+
BUILD_TREE(LITERAL, types[4]);
|
|
454
|
+
|
|
455
|
+
while (!lzh->input_end) {
|
|
456
|
+
if (lit_run) READ_HUFFSYM_SAFE(MATCHLEN2, len);
|
|
457
|
+
else READ_HUFFSYM_SAFE(MATCHLEN1, len);
|
|
458
|
+
|
|
459
|
+
if (len > 0) {
|
|
460
|
+
len += 2;
|
|
461
|
+
lit_run = 0; /* not the end of a literal run */
|
|
462
|
+
READ_HUFFSYM_SAFE(OFFSET, j); offset = j << 6;
|
|
463
|
+
READ_BITS_SAFE(j, 6); offset |= j;
|
|
464
|
+
|
|
465
|
+
/* copy match as output and into the ring buffer */
|
|
466
|
+
while (len-- > 0) {
|
|
467
|
+
lzh->window[pos] = lzh->window[(pos+4096-offset) & 4095];
|
|
468
|
+
WRITE_BYTE;
|
|
469
|
+
pos++; pos &= 4095;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
READ_HUFFSYM_SAFE(LITLEN, len); len++;
|
|
474
|
+
lit_run = (len == 32) ? 0 : 1; /* end of a literal run? */
|
|
475
|
+
while (len-- > 0) {
|
|
476
|
+
READ_HUFFSYM_SAFE(LITERAL, j);
|
|
477
|
+
/* copy as output and into the ring buffer */
|
|
478
|
+
lzh->window[pos] = j;
|
|
479
|
+
WRITE_BYTE;
|
|
480
|
+
pos++; pos &= 4095;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return MSPACK_ERR_OK;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
static void lzh_free(struct kwajd_stream *lzh)
|
|
488
|
+
{
|
|
489
|
+
struct mspack_system *sys;
|
|
490
|
+
if (!lzh || !lzh->sys) return;
|
|
491
|
+
sys = lzh->sys;
|
|
492
|
+
sys->free(lzh);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
static int lzh_read_lens(struct kwajd_stream *lzh,
|
|
496
|
+
unsigned int type, unsigned int numsyms,
|
|
497
|
+
unsigned char *lens, unsigned short *table)
|
|
498
|
+
{
|
|
499
|
+
register unsigned int bit_buffer;
|
|
500
|
+
register int bits_left;
|
|
501
|
+
unsigned char *i_ptr, *i_end;
|
|
502
|
+
unsigned int i, c, sel;
|
|
503
|
+
int err;
|
|
504
|
+
|
|
505
|
+
RESTORE_BITS;
|
|
506
|
+
switch (type) {
|
|
507
|
+
case 0:
|
|
508
|
+
i = numsyms; c = (i==16)?4: (i==32)?5: (i==64)?6: (i==256)?8 :0;
|
|
509
|
+
for (i = 0; i < numsyms; i++) lens[i] = c;
|
|
510
|
+
break;
|
|
511
|
+
|
|
512
|
+
case 1:
|
|
513
|
+
READ_BITS_SAFE(c, 4); lens[0] = c;
|
|
514
|
+
for (i = 1; i < numsyms; i++) {
|
|
515
|
+
READ_BITS_SAFE(sel, 1); if (sel == 0) lens[i] = c;
|
|
516
|
+
else { READ_BITS_SAFE(sel, 1); if (sel == 0) lens[i] = ++c;
|
|
517
|
+
else { READ_BITS_SAFE(c, 4); lens[i] = c; }}
|
|
518
|
+
}
|
|
519
|
+
break;
|
|
520
|
+
|
|
521
|
+
case 2:
|
|
522
|
+
READ_BITS_SAFE(c, 4); lens[0] = c;
|
|
523
|
+
for (i = 1; i < numsyms; i++) {
|
|
524
|
+
READ_BITS_SAFE(sel, 2);
|
|
525
|
+
if (sel == 3) READ_BITS_SAFE(c, 4); else c += (char) sel-1;
|
|
526
|
+
lens[i] = c;
|
|
527
|
+
}
|
|
528
|
+
break;
|
|
529
|
+
|
|
530
|
+
case 3:
|
|
531
|
+
for (i = 0; i < numsyms; i++) {
|
|
532
|
+
READ_BITS_SAFE(c, 4); lens[i] = c;
|
|
533
|
+
}
|
|
534
|
+
break;
|
|
535
|
+
}
|
|
536
|
+
STORE_BITS;
|
|
537
|
+
return MSPACK_ERR_OK;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
static int lzh_read_input(struct kwajd_stream *lzh) {
|
|
541
|
+
int read;
|
|
542
|
+
if (lzh->input_end) {
|
|
543
|
+
lzh->input_end += 8;
|
|
544
|
+
lzh->inbuf[0] = 0;
|
|
545
|
+
read = 1;
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
read = lzh->sys->read(lzh->input, &lzh->inbuf[0], KWAJ_INPUT_SIZE);
|
|
549
|
+
if (read < 0) return MSPACK_ERR_READ;
|
|
550
|
+
if (read == 0) {
|
|
551
|
+
lzh->input_end = 8;
|
|
552
|
+
lzh->inbuf[0] = 0;
|
|
553
|
+
read = 1;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/* update i_ptr and i_end */
|
|
558
|
+
lzh->i_ptr = &lzh->inbuf[0];
|
|
559
|
+
lzh->i_end = &lzh->inbuf[read];
|
|
560
|
+
return MSPACK_ERR_OK;
|
|
561
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* This file is part of libmspack.
|
|
2
|
+
* (C) 2003-2004 Stuart Caie.
|
|
3
|
+
*
|
|
4
|
+
* libmspack is free software; you can redistribute it and/or modify it under
|
|
5
|
+
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
|
6
|
+
*
|
|
7
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
#ifndef MSPACK_LIT_H
|
|
11
|
+
#define MSPACK_LIT_H 1
|
|
12
|
+
|
|
13
|
+
#include <lzx.h>
|
|
14
|
+
#include <des.h>
|
|
15
|
+
#include <sha.h>
|
|
16
|
+
|
|
17
|
+
/* generic LIT definitions */
|
|
18
|
+
|
|
19
|
+
/* LIT compression definitions */
|
|
20
|
+
|
|
21
|
+
struct mslit_compressor_p {
|
|
22
|
+
struct mslit_compressor base;
|
|
23
|
+
struct mspack_system *system;
|
|
24
|
+
/* todo */
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/* LIT decompression definitions */
|
|
28
|
+
|
|
29
|
+
struct mslit_decompressor_p {
|
|
30
|
+
struct mslit_decompressor base;
|
|
31
|
+
struct mspack_system *system;
|
|
32
|
+
/* todo */
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
#endif
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* This file is part of libmspack.
|
|
2
|
+
* (C) 2003-2004 Stuart Caie.
|
|
3
|
+
*
|
|
4
|
+
* libmspack is free software; you can redistribute it and/or modify it under
|
|
5
|
+
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
|
6
|
+
*
|
|
7
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* LIT compression implementation */
|
|
11
|
+
|
|
12
|
+
#include <system.h>
|
|
13
|
+
#include <lit.h>
|
|
14
|
+
|
|
15
|
+
struct mslit_compressor *
|
|
16
|
+
mspack_create_lit_compressor(struct mspack_system *sys)
|
|
17
|
+
{
|
|
18
|
+
/* todo */
|
|
19
|
+
return NULL;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void mspack_destroy_lit_compressor(struct mslit_compressor *self) {
|
|
23
|
+
/* todo */
|
|
24
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* This file is part of libmspack.
|
|
2
|
+
* (C) 2003-2004 Stuart Caie.
|
|
3
|
+
*
|
|
4
|
+
* libmspack is free software; you can redistribute it and/or modify it under
|
|
5
|
+
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
|
6
|
+
*
|
|
7
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* LIT decompression implementation */
|
|
11
|
+
|
|
12
|
+
#include <system.h>
|
|
13
|
+
#include <lit.h>
|
|
14
|
+
|
|
15
|
+
struct mslit_decompressor *
|
|
16
|
+
mspack_create_lit_decompressor(struct mspack_system *sys)
|
|
17
|
+
{
|
|
18
|
+
/* todo */
|
|
19
|
+
return NULL;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void mspack_destroy_lit_decompressor(struct mslit_decompressor *self) {
|
|
23
|
+
/* todo */
|
|
24
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/* This file is part of libmspack.
|
|
2
|
+
* (C) 2003-2004 Stuart Caie.
|
|
3
|
+
*
|
|
4
|
+
* libmspack is free software; you can redistribute it and/or modify it under
|
|
5
|
+
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
|
6
|
+
*
|
|
7
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
#ifndef MSPACK_LZSS_H
|
|
11
|
+
#define MSPACK_LZSS_H 1
|
|
12
|
+
|
|
13
|
+
#ifdef __cplusplus
|
|
14
|
+
extern "C" {
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
/* LZSS compression / decompression definitions */
|
|
18
|
+
|
|
19
|
+
#define LZSS_WINDOW_SIZE (4096)
|
|
20
|
+
#define LZSS_WINDOW_FILL (0x20)
|
|
21
|
+
|
|
22
|
+
#define LZSS_MODE_EXPAND (0)
|
|
23
|
+
#define LZSS_MODE_MSHELP (1)
|
|
24
|
+
#define LZSS_MODE_QBASIC (2)
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Decompresses an LZSS stream.
|
|
28
|
+
*
|
|
29
|
+
* Input bytes will be read in as necessary using the system->read()
|
|
30
|
+
* function with the input file handle given. This will continue until
|
|
31
|
+
* system->read() returns 0 bytes, or an error. Errors will be passed
|
|
32
|
+
* out of the function as MSPACK_ERR_READ errors. Input streams should
|
|
33
|
+
* convey an "end of input stream" by refusing to supply all the bytes
|
|
34
|
+
* that LZSS asks for when they reach the end of the stream, rather
|
|
35
|
+
* than return an error code.
|
|
36
|
+
*
|
|
37
|
+
* Output bytes will be passed to the system->write() function, using
|
|
38
|
+
* the output file handle given. More than one call may be made to
|
|
39
|
+
* system->write().
|
|
40
|
+
*
|
|
41
|
+
* As EXPAND.EXE (SZDD/KWAJ), Microsoft Help and QBasic have slightly
|
|
42
|
+
* different encodings for the control byte and matches, a "mode"
|
|
43
|
+
* parameter is allowed, to choose the encoding.
|
|
44
|
+
*
|
|
45
|
+
* @param system an mspack_system structure used to read from
|
|
46
|
+
* the input stream and write to the output
|
|
47
|
+
* stream, also to allocate and free memory.
|
|
48
|
+
* @param input an input stream with the LZSS data.
|
|
49
|
+
* @param output an output stream to write the decoded data to.
|
|
50
|
+
* @param input_buffer_size the number of bytes to use as an input
|
|
51
|
+
* bitstream buffer.
|
|
52
|
+
* @param mode one of #LZSS_MODE_EXPAND, #LZSS_MODE_MSHELP or
|
|
53
|
+
* #LZSS_MODE_QBASIC
|
|
54
|
+
* @return an error code, or MSPACK_ERR_OK if successful
|
|
55
|
+
*/
|
|
56
|
+
extern int lzss_decompress(struct mspack_system *system,
|
|
57
|
+
struct mspack_file *input,
|
|
58
|
+
struct mspack_file *output,
|
|
59
|
+
int input_buffer_size,
|
|
60
|
+
int mode);
|
|
61
|
+
|
|
62
|
+
#ifdef __cplusplus
|
|
63
|
+
}
|
|
64
|
+
#endif
|
|
65
|
+
|
|
66
|
+
#endif
|