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.
Files changed (150) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/README.md +75 -0
  7. data/Rakefile +22 -0
  8. data/UNLICENSE +24 -0
  9. data/ext/Rakefile +16 -0
  10. data/ext/i386-windows/libmspack.dll +0 -0
  11. data/ext/libmspack/AUTHORS +12 -0
  12. data/ext/libmspack/COPYING.LIB +504 -0
  13. data/ext/libmspack/ChangeLog +491 -0
  14. data/ext/libmspack/Makefile.am +100 -0
  15. data/ext/libmspack/NEWS +0 -0
  16. data/ext/libmspack/README +130 -0
  17. data/ext/libmspack/TODO +8 -0
  18. data/ext/libmspack/cleanup.sh +9 -0
  19. data/ext/libmspack/configure.ac +50 -0
  20. data/ext/libmspack/debian/changelog +6 -0
  21. data/ext/libmspack/debian/control +14 -0
  22. data/ext/libmspack/debian/rules +101 -0
  23. data/ext/libmspack/doc/Doxyfile.in +22 -0
  24. data/ext/libmspack/doc/Makefile.in +14 -0
  25. data/ext/libmspack/doc/szdd_kwaj_format.html +331 -0
  26. data/ext/libmspack/libmspack.pc.in +10 -0
  27. data/ext/libmspack/mspack/cab.h +127 -0
  28. data/ext/libmspack/mspack/cabc.c +24 -0
  29. data/ext/libmspack/mspack/cabd.c +1444 -0
  30. data/ext/libmspack/mspack/chm.h +122 -0
  31. data/ext/libmspack/mspack/chmc.c +24 -0
  32. data/ext/libmspack/mspack/chmd.c +1392 -0
  33. data/ext/libmspack/mspack/crc32.c +95 -0
  34. data/ext/libmspack/mspack/crc32.h +17 -0
  35. data/ext/libmspack/mspack/des.h +15 -0
  36. data/ext/libmspack/mspack/hlp.h +33 -0
  37. data/ext/libmspack/mspack/hlpc.c +24 -0
  38. data/ext/libmspack/mspack/hlpd.c +24 -0
  39. data/ext/libmspack/mspack/kwaj.h +118 -0
  40. data/ext/libmspack/mspack/kwajc.c +24 -0
  41. data/ext/libmspack/mspack/kwajd.c +561 -0
  42. data/ext/libmspack/mspack/lit.h +35 -0
  43. data/ext/libmspack/mspack/litc.c +24 -0
  44. data/ext/libmspack/mspack/litd.c +24 -0
  45. data/ext/libmspack/mspack/lzss.h +66 -0
  46. data/ext/libmspack/mspack/lzssd.c +93 -0
  47. data/ext/libmspack/mspack/lzx.h +221 -0
  48. data/ext/libmspack/mspack/lzxc.c +18 -0
  49. data/ext/libmspack/mspack/lzxd.c +895 -0
  50. data/ext/libmspack/mspack/mspack.def +28 -0
  51. data/ext/libmspack/mspack/mspack.h +2353 -0
  52. data/ext/libmspack/mspack/mszip.h +126 -0
  53. data/ext/libmspack/mspack/mszipc.c +18 -0
  54. data/ext/libmspack/mspack/mszipd.c +514 -0
  55. data/ext/libmspack/mspack/oab.h +60 -0
  56. data/ext/libmspack/mspack/oabc.c +24 -0
  57. data/ext/libmspack/mspack/oabd.c +408 -0
  58. data/ext/libmspack/mspack/qtm.h +128 -0
  59. data/ext/libmspack/mspack/qtmc.c +18 -0
  60. data/ext/libmspack/mspack/qtmd.c +489 -0
  61. data/ext/libmspack/mspack/readbits.h +207 -0
  62. data/ext/libmspack/mspack/readhuff.h +173 -0
  63. data/ext/libmspack/mspack/sha.h +15 -0
  64. data/ext/libmspack/mspack/system.c +239 -0
  65. data/ext/libmspack/mspack/system.h +124 -0
  66. data/ext/libmspack/mspack/szdd.h +39 -0
  67. data/ext/libmspack/mspack/szddc.c +24 -0
  68. data/ext/libmspack/mspack/szddd.c +247 -0
  69. data/ext/libmspack/rebuild.sh +8 -0
  70. data/ext/libmspack/test/cabd_c10 +19 -0
  71. data/ext/libmspack/test/cabd_compare +34 -0
  72. data/ext/libmspack/test/cabd_md5.c +161 -0
  73. data/ext/libmspack/test/cabd_memory.c +179 -0
  74. data/ext/libmspack/test/cabd_test.c +386 -0
  75. data/ext/libmspack/test/cabrip.c +81 -0
  76. data/ext/libmspack/test/chmd_compare +38 -0
  77. data/ext/libmspack/test/chmd_find.c +95 -0
  78. data/ext/libmspack/test/chmd_md5.c +67 -0
  79. data/ext/libmspack/test/chmd_order.c +144 -0
  80. data/ext/libmspack/test/chminfo.c +284 -0
  81. data/ext/libmspack/test/chmx.c +216 -0
  82. data/ext/libmspack/test/error.h +22 -0
  83. data/ext/libmspack/test/expand.c +79 -0
  84. data/ext/libmspack/test/md5.c +457 -0
  85. data/ext/libmspack/test/md5.h +165 -0
  86. data/ext/libmspack/test/md5_fh.h +123 -0
  87. data/ext/libmspack/test/msdecompile_md5 +24 -0
  88. data/ext/libmspack/test/msexpand_md5 +39 -0
  89. data/ext/libmspack/test/multifh.c +435 -0
  90. data/ext/libmspack/test/oabx.c +41 -0
  91. data/ext/libmspack/test/test_files/cabd/1.pl +84 -0
  92. data/ext/libmspack/test/test_files/cabd/2.pl +75 -0
  93. data/ext/libmspack/test/test_files/cabd/bad_folderindex.cab +0 -0
  94. data/ext/libmspack/test/test_files/cabd/bad_nofiles.cab +0 -0
  95. data/ext/libmspack/test/test_files/cabd/bad_nofolders.cab +0 -0
  96. data/ext/libmspack/test/test_files/cabd/bad_signature.cab +0 -0
  97. data/ext/libmspack/test/test_files/cabd/multi_basic_pt1.cab +0 -0
  98. data/ext/libmspack/test/test_files/cabd/multi_basic_pt2.cab +0 -0
  99. data/ext/libmspack/test/test_files/cabd/multi_basic_pt3.cab +0 -0
  100. data/ext/libmspack/test/test_files/cabd/multi_basic_pt4.cab +0 -0
  101. data/ext/libmspack/test/test_files/cabd/multi_basic_pt5.cab +0 -0
  102. data/ext/libmspack/test/test_files/cabd/normal_255c_filename.cab +0 -0
  103. data/ext/libmspack/test/test_files/cabd/normal_2files_1folder.cab +0 -0
  104. data/ext/libmspack/test/test_files/cabd/partial_nodata.cab +0 -0
  105. data/ext/libmspack/test/test_files/cabd/partial_nofiles.cab +0 -0
  106. data/ext/libmspack/test/test_files/cabd/partial_nofolder.cab +0 -0
  107. data/ext/libmspack/test/test_files/cabd/partial_shortextheader.cab +0 -0
  108. data/ext/libmspack/test/test_files/cabd/partial_shortfile1.cab +0 -0
  109. data/ext/libmspack/test/test_files/cabd/partial_shortfile2.cab +0 -0
  110. data/ext/libmspack/test/test_files/cabd/partial_shortfolder.cab +0 -0
  111. data/ext/libmspack/test/test_files/cabd/partial_shortheader.cab +0 -0
  112. data/ext/libmspack/test/test_files/cabd/partial_str_nofname.cab +0 -0
  113. data/ext/libmspack/test/test_files/cabd/partial_str_noninfo.cab +0 -0
  114. data/ext/libmspack/test/test_files/cabd/partial_str_nonname.cab +0 -0
  115. data/ext/libmspack/test/test_files/cabd/partial_str_nopinfo.cab +0 -0
  116. data/ext/libmspack/test/test_files/cabd/partial_str_nopname.cab +0 -0
  117. data/ext/libmspack/test/test_files/cabd/partial_str_shortfname.cab +0 -0
  118. data/ext/libmspack/test/test_files/cabd/partial_str_shortninfo.cab +0 -0
  119. data/ext/libmspack/test/test_files/cabd/partial_str_shortnname.cab +0 -0
  120. data/ext/libmspack/test/test_files/cabd/partial_str_shortpinfo.cab +0 -0
  121. data/ext/libmspack/test/test_files/cabd/partial_str_shortpname.cab +0 -0
  122. data/ext/libmspack/test/test_files/cabd/reserve_---.cab +0 -0
  123. data/ext/libmspack/test/test_files/cabd/reserve_--D.cab +0 -0
  124. data/ext/libmspack/test/test_files/cabd/reserve_-F-.cab +0 -0
  125. data/ext/libmspack/test/test_files/cabd/reserve_-FD.cab +0 -0
  126. data/ext/libmspack/test/test_files/cabd/reserve_H--.cab +0 -0
  127. data/ext/libmspack/test/test_files/cabd/reserve_H-D.cab +0 -0
  128. data/ext/libmspack/test/test_files/cabd/reserve_HF-.cab +0 -0
  129. data/ext/libmspack/test/test_files/cabd/reserve_HFD.cab +0 -0
  130. data/ext/libmspack/test/test_files/cabd/search_basic.cab +0 -0
  131. data/ext/libmspack/test/test_files/cabd/search_tricky1.cab +0 -0
  132. data/ext/libmspack/winbuild.sh +26 -0
  133. data/ext/x86_64-windows/libmspack.dll +0 -0
  134. data/lib/libmspack/constants.rb +9 -0
  135. data/lib/libmspack/exceptions.rb +12 -0
  136. data/lib/libmspack/mscab.rb +722 -0
  137. data/lib/libmspack/mschm.rb +301 -0
  138. data/lib/libmspack/mshlp.rb +15 -0
  139. data/lib/libmspack/mskwaj.rb +124 -0
  140. data/lib/libmspack/mslit.rb +18 -0
  141. data/lib/libmspack/msoab.rb +36 -0
  142. data/lib/libmspack/mspack.rb +208 -0
  143. data/lib/libmspack/msszdd.rb +81 -0
  144. data/lib/libmspack/system.rb +84 -0
  145. data/lib/libmspack/version.rb +4 -0
  146. data/lib/libmspack.rb +121 -0
  147. data/libmspack.gemspec +33 -0
  148. data/spec/libmspack_spec.rb +26 -0
  149. data/spec/spec_helper.rb +5 -0
  150. 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