summaryrefslogtreecommitdiff
path: root/rbutil/rbutilqt/mspack/mszipd.c
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/rbutilqt/mspack/mszipd.c')
-rw-r--r--rbutil/rbutilqt/mspack/mszipd.c268
1 files changed, 154 insertions, 114 deletions
diff --git a/rbutil/rbutilqt/mspack/mszipd.c b/rbutil/rbutilqt/mspack/mszipd.c
index 3c158fbd4d..c1b02b1207 100644
--- a/rbutil/rbutilqt/mspack/mszipd.c
+++ b/rbutil/rbutilqt/mspack/mszipd.c
@@ -20,9 +20,9 @@
20#define BITS_VAR zip 20#define BITS_VAR zip
21#define BITS_ORDER_LSB 21#define BITS_ORDER_LSB
22#define BITS_LSB_TABLE 22#define BITS_LSB_TABLE
23#define READ_BYTES do { \ 23#define READ_BYTES do { \
24 READ_IF_NEEDED; \ 24 READ_IF_NEEDED; \
25 INJECT_BITS(*i_ptr++, 8); \ 25 INJECT_BITS(*i_ptr++, 8); \
26} while (0) 26} while (0)
27#include "readbits.h" 27#include "readbits.h"
28 28
@@ -34,13 +34,13 @@
34#define HUFF_ERROR return INF_ERR_HUFFSYM 34#define HUFF_ERROR return INF_ERR_HUFFSYM
35#include "readhuff.h" 35#include "readhuff.h"
36 36
37#define FLUSH_IF_NEEDED do { \ 37#define FLUSH_IF_NEEDED do { \
38 if (zip->window_posn == MSZIP_FRAME_SIZE) { \ 38 if (zip->window_posn == MSZIP_FRAME_SIZE) { \
39 if (zip->flush_window(zip, MSZIP_FRAME_SIZE)) { \ 39 if (zip->flush_window(zip, MSZIP_FRAME_SIZE)) { \
40 return INF_ERR_FLUSH; \ 40 return INF_ERR_FLUSH; \
41 } \ 41 } \
42 zip->window_posn = 0; \ 42 zip->window_posn = 0; \
43 } \ 43 } \
44} while (0) 44} while (0)
45 45
46/* match lengths for literal codes 257.. 285 */ 46/* match lengths for literal codes 257.. 285 */
@@ -181,14 +181,14 @@ static int inflate(struct mszipd_stream *zip) {
181 181
182 /* read 4 bytes of data, emptying the bit-buffer if necessary */ 182 /* read 4 bytes of data, emptying the bit-buffer if necessary */
183 for (i = 0; (bits_left >= 8); i++) { 183 for (i = 0; (bits_left >= 8); i++) {
184 if (i == 4) return INF_ERR_BITBUF; 184 if (i == 4) return INF_ERR_BITBUF;
185 lens_buf[i] = PEEK_BITS(8); 185 lens_buf[i] = PEEK_BITS(8);
186 REMOVE_BITS(8); 186 REMOVE_BITS(8);
187 } 187 }
188 if (bits_left != 0) return INF_ERR_BITBUF; 188 if (bits_left != 0) return INF_ERR_BITBUF;
189 while (i < 4) { 189 while (i < 4) {
190 READ_IF_NEEDED; 190 READ_IF_NEEDED;
191 lens_buf[i++] = *i_ptr++; 191 lens_buf[i++] = *i_ptr++;
192 } 192 }
193 193
194 /* get the length and its complement */ 194 /* get the length and its complement */
@@ -198,18 +198,18 @@ static int inflate(struct mszipd_stream *zip) {
198 198
199 /* read and copy the uncompressed data into the window */ 199 /* read and copy the uncompressed data into the window */
200 while (length > 0) { 200 while (length > 0) {
201 READ_IF_NEEDED; 201 READ_IF_NEEDED;
202 202
203 this_run = length; 203 this_run = length;
204 if (this_run > (unsigned int)(i_end - i_ptr)) this_run = i_end - i_ptr; 204 if (this_run > (unsigned int)(i_end - i_ptr)) this_run = i_end - i_ptr;
205 if (this_run > (MSZIP_FRAME_SIZE - zip->window_posn)) 205 if (this_run > (MSZIP_FRAME_SIZE - zip->window_posn))
206 this_run = MSZIP_FRAME_SIZE - zip->window_posn; 206 this_run = MSZIP_FRAME_SIZE - zip->window_posn;
207 207
208 zip->sys->copy(i_ptr, &zip->window[zip->window_posn], this_run); 208 zip->sys->copy(i_ptr, &zip->window[zip->window_posn], this_run);
209 zip->window_posn += this_run; 209 zip->window_posn += this_run;
210 i_ptr += this_run; 210 i_ptr += this_run;
211 length -= this_run; 211 length -= this_run;
212 FLUSH_IF_NEEDED; 212 FLUSH_IF_NEEDED;
213 } 213 }
214 } 214 }
215 else if ((block_type == 1) || (block_type == 2)) { 215 else if ((block_type == 1) || (block_type == 2)) {
@@ -217,92 +217,92 @@ static int inflate(struct mszipd_stream *zip) {
217 unsigned int match_posn, code; 217 unsigned int match_posn, code;
218 218
219 if (block_type == 1) { 219 if (block_type == 1) {
220 /* block with fixed Huffman codes */ 220 /* block with fixed Huffman codes */
221 i = 0; 221 i = 0;
222 while (i < 144) zip->LITERAL_len[i++] = 8; 222 while (i < 144) zip->LITERAL_len[i++] = 8;
223 while (i < 256) zip->LITERAL_len[i++] = 9; 223 while (i < 256) zip->LITERAL_len[i++] = 9;
224 while (i < 280) zip->LITERAL_len[i++] = 7; 224 while (i < 280) zip->LITERAL_len[i++] = 7;
225 while (i < 288) zip->LITERAL_len[i++] = 8; 225 while (i < 288) zip->LITERAL_len[i++] = 8;
226 for (i = 0; i < 32; i++) zip->DISTANCE_len[i] = 5; 226 for (i = 0; i < 32; i++) zip->DISTANCE_len[i] = 5;
227 } 227 }
228 else { 228 else {
229 /* block with dynamic Huffman codes */ 229 /* block with dynamic Huffman codes */
230 STORE_BITS; 230 STORE_BITS;
231 if ((i = zip_read_lens(zip))) return i; 231 if ((i = zip_read_lens(zip))) return i;
232 RESTORE_BITS; 232 RESTORE_BITS;
233 } 233 }
234 234
235 /* now huffman lengths are read for either kind of block, 235 /* now huffman lengths are read for either kind of block,
236 * create huffman decoding tables */ 236 * create huffman decoding tables */
237 if (make_decode_table(MSZIP_LITERAL_MAXSYMBOLS, MSZIP_LITERAL_TABLEBITS, 237 if (make_decode_table(MSZIP_LITERAL_MAXSYMBOLS, MSZIP_LITERAL_TABLEBITS,
238 &zip->LITERAL_len[0], &zip->LITERAL_table[0])) 238 &zip->LITERAL_len[0], &zip->LITERAL_table[0]))
239 { 239 {
240 return INF_ERR_LITERALTBL; 240 return INF_ERR_LITERALTBL;
241 } 241 }
242 242
243 if (make_decode_table(MSZIP_DISTANCE_MAXSYMBOLS,MSZIP_DISTANCE_TABLEBITS, 243 if (make_decode_table(MSZIP_DISTANCE_MAXSYMBOLS,MSZIP_DISTANCE_TABLEBITS,
244 &zip->DISTANCE_len[0], &zip->DISTANCE_table[0])) 244 &zip->DISTANCE_len[0], &zip->DISTANCE_table[0]))
245 { 245 {
246 return INF_ERR_DISTANCETBL; 246 return INF_ERR_DISTANCETBL;
247 } 247 }
248 248
249 /* decode forever until end of block code */ 249 /* decode forever until end of block code */
250 for (;;) { 250 for (;;) {
251 READ_HUFFSYM(LITERAL, code); 251 READ_HUFFSYM(LITERAL, code);
252 if (code < 256) { 252 if (code < 256) {
253 zip->window[zip->window_posn++] = (unsigned char) code; 253 zip->window[zip->window_posn++] = (unsigned char) code;
254 FLUSH_IF_NEEDED; 254 FLUSH_IF_NEEDED;
255 } 255 }
256 else if (code == 256) { 256 else if (code == 256) {
257 /* END OF BLOCK CODE: loop break point */ 257 /* END OF BLOCK CODE: loop break point */
258 break; 258 break;
259 } 259 }
260 else { 260 else {
261 code -= 257; /* codes 257-285 are matches */ 261 code -= 257; /* codes 257-285 are matches */
262 if (code >= 29) return INF_ERR_LITCODE; /* codes 286-287 are illegal */ 262 if (code >= 29) return INF_ERR_LITCODE; /* codes 286-287 are illegal */
263 READ_BITS_T(length, lit_extrabits[code]); 263 READ_BITS_T(length, lit_extrabits[code]);
264 length += lit_lengths[code]; 264 length += lit_lengths[code];
265 265
266 READ_HUFFSYM(DISTANCE, code); 266 READ_HUFFSYM(DISTANCE, code);
267 if (code > 30) return INF_ERR_DISTCODE; 267 if (code >= 30) return INF_ERR_DISTCODE;
268 READ_BITS_T(distance, dist_extrabits[code]); 268 READ_BITS_T(distance, dist_extrabits[code]);
269 distance += dist_offsets[code]; 269 distance += dist_offsets[code];
270 270
271 /* match position is window position minus distance. If distance 271 /* match position is window position minus distance. If distance
272 * is more than window position numerically, it must 'wrap 272 * is more than window position numerically, it must 'wrap
273 * around' the frame size. */ 273 * around' the frame size. */
274 match_posn = ((distance > zip->window_posn) ? MSZIP_FRAME_SIZE : 0) 274 match_posn = ((distance > zip->window_posn) ? MSZIP_FRAME_SIZE : 0)
275 + zip->window_posn - distance; 275 + zip->window_posn - distance;
276 276
277 /* copy match */ 277 /* copy match */
278 if (length < 12) { 278 if (length < 12) {
279 /* short match, use slower loop but no loop setup code */ 279 /* short match, use slower loop but no loop setup code */
280 while (length--) { 280 while (length--) {
281 zip->window[zip->window_posn++] = zip->window[match_posn++]; 281 zip->window[zip->window_posn++] = zip->window[match_posn++];
282 match_posn &= MSZIP_FRAME_SIZE - 1; 282 match_posn &= MSZIP_FRAME_SIZE - 1;
283 FLUSH_IF_NEEDED; 283 FLUSH_IF_NEEDED;
284 } 284 }
285 } 285 }
286 else { 286 else {
287 /* longer match, use faster loop but with setup expense */ 287 /* longer match, use faster loop but with setup expense */
288 unsigned char *runsrc, *rundest; 288 unsigned char *runsrc, *rundest;
289 do { 289 do {
290 this_run = length; 290 this_run = length;
291 if ((match_posn + this_run) > MSZIP_FRAME_SIZE) 291 if ((match_posn + this_run) > MSZIP_FRAME_SIZE)
292 this_run = MSZIP_FRAME_SIZE - match_posn; 292 this_run = MSZIP_FRAME_SIZE - match_posn;
293 if ((zip->window_posn + this_run) > MSZIP_FRAME_SIZE) 293 if ((zip->window_posn + this_run) > MSZIP_FRAME_SIZE)
294 this_run = MSZIP_FRAME_SIZE - zip->window_posn; 294 this_run = MSZIP_FRAME_SIZE - zip->window_posn;
295 295
296 rundest = &zip->window[zip->window_posn]; zip->window_posn += this_run; 296 rundest = &zip->window[zip->window_posn]; zip->window_posn += this_run;
297 runsrc = &zip->window[match_posn]; match_posn += this_run; 297 runsrc = &zip->window[match_posn]; match_posn += this_run;
298 length -= this_run; 298 length -= this_run;
299 while (this_run--) *rundest++ = *runsrc++; 299 while (this_run--) *rundest++ = *runsrc++;
300 if (match_posn == MSZIP_FRAME_SIZE) match_posn = 0; 300 if (match_posn == MSZIP_FRAME_SIZE) match_posn = 0;
301 FLUSH_IF_NEEDED; 301 FLUSH_IF_NEEDED;
302 } while (length > 0); 302 } while (length > 0);
303 } 303 }
304 304
305 } /* else (code >= 257) */ 305 } /* else (code >= 257) */
306 306
307 } /* for(;;) -- break point at 'code == 256' */ 307 } /* for(;;) -- break point at 'code == 256' */
308 } 308 }
@@ -328,7 +328,7 @@ static int inflate(struct mszipd_stream *zip) {
328 * is flushed, an error is raised. 328 * is flushed, an error is raised.
329 */ 329 */
330static int mszipd_flush_window(struct mszipd_stream *zip, 330static int mszipd_flush_window(struct mszipd_stream *zip,
331 unsigned int data_flushed) 331 unsigned int data_flushed)
332{ 332{
333 zip->bytes_output += data_flushed; 333 zip->bytes_output += data_flushed;
334 if (zip->bytes_output > MSZIP_FRAME_SIZE) { 334 if (zip->bytes_output > MSZIP_FRAME_SIZE) {
@@ -340,17 +340,18 @@ static int mszipd_flush_window(struct mszipd_stream *zip,
340} 340}
341 341
342struct mszipd_stream *mszipd_init(struct mspack_system *system, 342struct mszipd_stream *mszipd_init(struct mspack_system *system,
343 struct mspack_file *input, 343 struct mspack_file *input,
344 struct mspack_file *output, 344 struct mspack_file *output,
345 int input_buffer_size, 345 int input_buffer_size,
346 int repair_mode) 346 int repair_mode)
347{ 347{
348 struct mszipd_stream *zip; 348 struct mszipd_stream *zip;
349 349
350 if (!system) return NULL; 350 if (!system) return NULL;
351 351
352 /* round up input buffer size to multiple of two */
352 input_buffer_size = (input_buffer_size + 1) & -2; 353 input_buffer_size = (input_buffer_size + 1) & -2;
353 if (!input_buffer_size) return NULL; 354 if (input_buffer_size < 2) return NULL;
354 355
355 /* allocate decompression state */ 356 /* allocate decompression state */
356 if (!(zip = (struct mszipd_stream *) system->alloc(system, sizeof(struct mszipd_stream)))) { 357 if (!(zip = (struct mszipd_stream *) system->alloc(system, sizeof(struct mszipd_stream)))) {
@@ -426,19 +427,19 @@ int mszipd_decompress(struct mszipd_stream *zip, off_t out_bytes) {
426 if ((error = inflate(zip))) { 427 if ((error = inflate(zip))) {
427 D(("inflate error %d", error)) 428 D(("inflate error %d", error))
428 if (zip->repair_mode) { 429 if (zip->repair_mode) {
429 /* recover partially-inflated buffers */ 430 /* recover partially-inflated buffers */
430 if (zip->bytes_output == 0 && zip->window_posn > 0) { 431 if (zip->bytes_output == 0 && zip->window_posn > 0) {
431 zip->flush_window(zip, zip->window_posn); 432 zip->flush_window(zip, zip->window_posn);
432 } 433 }
433 zip->sys->message(NULL, "MSZIP error, %u bytes of data lost.", 434 zip->sys->message(NULL, "MSZIP error, %u bytes of data lost.",
434 MSZIP_FRAME_SIZE - zip->bytes_output); 435 MSZIP_FRAME_SIZE - zip->bytes_output);
435 for (i = zip->bytes_output; i < MSZIP_FRAME_SIZE; i++) { 436 for (i = zip->bytes_output; i < MSZIP_FRAME_SIZE; i++) {
436 zip->window[i] = '\0'; 437 zip->window[i] = '\0';
437 } 438 }
438 zip->bytes_output = MSZIP_FRAME_SIZE; 439 zip->bytes_output = MSZIP_FRAME_SIZE;
439 } 440 }
440 else { 441 else {
441 return zip->error = (error > 0) ? error : MSPACK_ERR_DECRUNCH; 442 return zip->error = (error > 0) ? error : MSPACK_ERR_DECRUNCH;
442 } 443 }
443 } 444 }
444 zip->o_ptr = &zip->window[0]; 445 zip->o_ptr = &zip->window[0];
@@ -465,6 +466,45 @@ int mszipd_decompress(struct mszipd_stream *zip, off_t out_bytes) {
465 return MSPACK_ERR_OK; 466 return MSPACK_ERR_OK;
466} 467}
467 468
469int mszipd_decompress_kwaj(struct mszipd_stream *zip) {
470 /* for the bit buffer */
471 register unsigned int bit_buffer;
472 register int bits_left;
473 unsigned char *i_ptr, *i_end;
474
475 int i, error, block_len;
476
477 /* unpack blocks until block_len == 0 */
478 for (;;) {
479 RESTORE_BITS;
480
481 /* align to bytestream, read block_len */
482 i = bits_left & 7; REMOVE_BITS(i);
483 READ_BITS(block_len, 8);
484 READ_BITS(i, 8); block_len |= i << 8;
485
486 if (block_len == 0) break;
487
488 /* read "CK" header */
489 READ_BITS(i, 8); if (i != 'C') return MSPACK_ERR_DATAFORMAT;
490 READ_BITS(i, 8); if (i != 'K') return MSPACK_ERR_DATAFORMAT;
491
492 /* inflate block */
493 zip->window_posn = 0;
494 zip->bytes_output = 0;
495 STORE_BITS;
496 if ((error = inflate(zip))) {
497 D(("inflate error %d", error))
498 return zip->error = (error > 0) ? error : MSPACK_ERR_DECRUNCH;
499 }
500
501 /* write inflated block */
502 if (zip->sys->write(zip->output, &zip->window[0], zip->bytes_output)
503 != zip->bytes_output) return zip->error = MSPACK_ERR_WRITE;
504 }
505 return MSPACK_ERR_OK;
506}
507
468void mszipd_free(struct mszipd_stream *zip) { 508void mszipd_free(struct mszipd_stream *zip) {
469 struct mspack_system *sys; 509 struct mspack_system *sys;
470 if (zip) { 510 if (zip) {