diff options
author | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2020-06-08 21:44:02 +0200 |
---|---|---|
committer | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2020-08-07 22:18:41 +0200 |
commit | 729b6e4f33419489415a6111bb98e5d95221a338 (patch) | |
tree | 87e83604959f7d848e80287aa799900cd0a9f989 /rbutil/rbutilqt/mspack/mszipd.c | |
parent | b0f22620a2dbfb991b10a8e1e8b0c8db5e3ee117 (diff) | |
download | rockbox-729b6e4f33.tar.gz rockbox-729b6e4f33.zip |
rbutil: Update libmspack to 0.10.1alpha.
Update to the most recent release. Fix name / include clashes, as has
been done before.
Change-Id: Ia712bb2b5f4b9018b65a46b8bdd04ba42363be8b
Diffstat (limited to 'rbutil/rbutilqt/mspack/mszipd.c')
-rw-r--r-- | rbutil/rbutilqt/mspack/mszipd.c | 268 |
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 @@ #define BITS_VAR zip #define BITS_ORDER_LSB #define BITS_LSB_TABLE -#define READ_BYTES do { \ - READ_IF_NEEDED; \ - INJECT_BITS(*i_ptr++, 8); \ +#define READ_BYTES do { \ + READ_IF_NEEDED; \ + INJECT_BITS(*i_ptr++, 8); \ } while (0) #include "readbits.h" @@ -34,13 +34,13 @@ #define HUFF_ERROR return INF_ERR_HUFFSYM #include "readhuff.h" -#define FLUSH_IF_NEEDED do { \ - if (zip->window_posn == MSZIP_FRAME_SIZE) { \ - if (zip->flush_window(zip, MSZIP_FRAME_SIZE)) { \ - return INF_ERR_FLUSH; \ - } \ - zip->window_posn = 0; \ - } \ +#define FLUSH_IF_NEEDED do { \ + if (zip->window_posn == MSZIP_FRAME_SIZE) { \ + if (zip->flush_window(zip, MSZIP_FRAME_SIZE)) { \ + return INF_ERR_FLUSH; \ + } \ + zip->window_posn = 0; \ + } \ } while (0) /* match lengths for literal codes 257.. 285 */ @@ -181,14 +181,14 @@ static int inflate(struct mszipd_stream *zip) { /* read 4 bytes of data, emptying the bit-buffer if necessary */ for (i = 0; (bits_left >= 8); i++) { - if (i == 4) return INF_ERR_BITBUF; - lens_buf[i] = PEEK_BITS(8); - REMOVE_BITS(8); + if (i == 4) return INF_ERR_BITBUF; + lens_buf[i] = PEEK_BITS(8); + REMOVE_BITS(8); } if (bits_left != 0) return INF_ERR_BITBUF; while (i < 4) { - READ_IF_NEEDED; - lens_buf[i++] = *i_ptr++; + READ_IF_NEEDED; + lens_buf[i++] = *i_ptr++; } /* get the length and its complement */ @@ -198,18 +198,18 @@ static int inflate(struct mszipd_stream *zip) { /* read and copy the uncompressed data into the window */ while (length > 0) { - READ_IF_NEEDED; - - this_run = length; - if (this_run > (unsigned int)(i_end - i_ptr)) this_run = i_end - i_ptr; - if (this_run > (MSZIP_FRAME_SIZE - zip->window_posn)) - this_run = MSZIP_FRAME_SIZE - zip->window_posn; - - zip->sys->copy(i_ptr, &zip->window[zip->window_posn], this_run); - zip->window_posn += this_run; - i_ptr += this_run; - length -= this_run; - FLUSH_IF_NEEDED; + READ_IF_NEEDED; + + this_run = length; + if (this_run > (unsigned int)(i_end - i_ptr)) this_run = i_end - i_ptr; + if (this_run > (MSZIP_FRAME_SIZE - zip->window_posn)) + this_run = MSZIP_FRAME_SIZE - zip->window_posn; + + zip->sys->copy(i_ptr, &zip->window[zip->window_posn], this_run); + zip->window_posn += this_run; + i_ptr += this_run; + length -= this_run; + FLUSH_IF_NEEDED; } } else if ((block_type == 1) || (block_type == 2)) { @@ -217,92 +217,92 @@ static int inflate(struct mszipd_stream *zip) { unsigned int match_posn, code; if (block_type == 1) { - /* block with fixed Huffman codes */ - i = 0; - while (i < 144) zip->LITERAL_len[i++] = 8; - while (i < 256) zip->LITERAL_len[i++] = 9; - while (i < 280) zip->LITERAL_len[i++] = 7; - while (i < 288) zip->LITERAL_len[i++] = 8; - for (i = 0; i < 32; i++) zip->DISTANCE_len[i] = 5; + /* block with fixed Huffman codes */ + i = 0; + while (i < 144) zip->LITERAL_len[i++] = 8; + while (i < 256) zip->LITERAL_len[i++] = 9; + while (i < 280) zip->LITERAL_len[i++] = 7; + while (i < 288) zip->LITERAL_len[i++] = 8; + for (i = 0; i < 32; i++) zip->DISTANCE_len[i] = 5; } else { - /* block with dynamic Huffman codes */ - STORE_BITS; - if ((i = zip_read_lens(zip))) return i; - RESTORE_BITS; + /* block with dynamic Huffman codes */ + STORE_BITS; + if ((i = zip_read_lens(zip))) return i; + RESTORE_BITS; } /* now huffman lengths are read for either kind of block, * create huffman decoding tables */ if (make_decode_table(MSZIP_LITERAL_MAXSYMBOLS, MSZIP_LITERAL_TABLEBITS, - &zip->LITERAL_len[0], &zip->LITERAL_table[0])) + &zip->LITERAL_len[0], &zip->LITERAL_table[0])) { - return INF_ERR_LITERALTBL; + return INF_ERR_LITERALTBL; } if (make_decode_table(MSZIP_DISTANCE_MAXSYMBOLS,MSZIP_DISTANCE_TABLEBITS, - &zip->DISTANCE_len[0], &zip->DISTANCE_table[0])) + &zip->DISTANCE_len[0], &zip->DISTANCE_table[0])) { - return INF_ERR_DISTANCETBL; + return INF_ERR_DISTANCETBL; } /* decode forever until end of block code */ for (;;) { - READ_HUFFSYM(LITERAL, code); - if (code < 256) { - zip->window[zip->window_posn++] = (unsigned char) code; - FLUSH_IF_NEEDED; - } - else if (code == 256) { - /* END OF BLOCK CODE: loop break point */ - break; - } - else { - code -= 257; /* codes 257-285 are matches */ - if (code >= 29) return INF_ERR_LITCODE; /* codes 286-287 are illegal */ - READ_BITS_T(length, lit_extrabits[code]); - length += lit_lengths[code]; - - READ_HUFFSYM(DISTANCE, code); - if (code > 30) return INF_ERR_DISTCODE; - READ_BITS_T(distance, dist_extrabits[code]); - distance += dist_offsets[code]; - - /* match position is window position minus distance. If distance - * is more than window position numerically, it must 'wrap - * around' the frame size. */ - match_posn = ((distance > zip->window_posn) ? MSZIP_FRAME_SIZE : 0) - + zip->window_posn - distance; - - /* copy match */ - if (length < 12) { - /* short match, use slower loop but no loop setup code */ - while (length--) { - zip->window[zip->window_posn++] = zip->window[match_posn++]; - match_posn &= MSZIP_FRAME_SIZE - 1; - FLUSH_IF_NEEDED; - } - } - else { - /* longer match, use faster loop but with setup expense */ - unsigned char *runsrc, *rundest; - do { - this_run = length; - if ((match_posn + this_run) > MSZIP_FRAME_SIZE) - this_run = MSZIP_FRAME_SIZE - match_posn; - if ((zip->window_posn + this_run) > MSZIP_FRAME_SIZE) - this_run = MSZIP_FRAME_SIZE - zip->window_posn; - - rundest = &zip->window[zip->window_posn]; zip->window_posn += this_run; - runsrc = &zip->window[match_posn]; match_posn += this_run; - length -= this_run; - while (this_run--) *rundest++ = *runsrc++; - if (match_posn == MSZIP_FRAME_SIZE) match_posn = 0; - FLUSH_IF_NEEDED; - } while (length > 0); - } - - } /* else (code >= 257) */ + READ_HUFFSYM(LITERAL, code); + if (code < 256) { + zip->window[zip->window_posn++] = (unsigned char) code; + FLUSH_IF_NEEDED; + } + else if (code == 256) { + /* END OF BLOCK CODE: loop break point */ + break; + } + else { + code -= 257; /* codes 257-285 are matches */ + if (code >= 29) return INF_ERR_LITCODE; /* codes 286-287 are illegal */ + READ_BITS_T(length, lit_extrabits[code]); + length += lit_lengths[code]; + + READ_HUFFSYM(DISTANCE, code); + if (code >= 30) return INF_ERR_DISTCODE; + READ_BITS_T(distance, dist_extrabits[code]); + distance += dist_offsets[code]; + + /* match position is window position minus distance. If distance + * is more than window position numerically, it must 'wrap + * around' the frame size. */ + match_posn = ((distance > zip->window_posn) ? MSZIP_FRAME_SIZE : 0) + + zip->window_posn - distance; + + /* copy match */ + if (length < 12) { + /* short match, use slower loop but no loop setup code */ + while (length--) { + zip->window[zip->window_posn++] = zip->window[match_posn++]; + match_posn &= MSZIP_FRAME_SIZE - 1; + FLUSH_IF_NEEDED; + } + } + else { + /* longer match, use faster loop but with setup expense */ + unsigned char *runsrc, *rundest; + do { + this_run = length; + if ((match_posn + this_run) > MSZIP_FRAME_SIZE) + this_run = MSZIP_FRAME_SIZE - match_posn; + if ((zip->window_posn + this_run) > MSZIP_FRAME_SIZE) + this_run = MSZIP_FRAME_SIZE - zip->window_posn; + + rundest = &zip->window[zip->window_posn]; zip->window_posn += this_run; + runsrc = &zip->window[match_posn]; match_posn += this_run; + length -= this_run; + while (this_run--) *rundest++ = *runsrc++; + if (match_posn == MSZIP_FRAME_SIZE) match_posn = 0; + FLUSH_IF_NEEDED; + } while (length > 0); + } + + } /* else (code >= 257) */ } /* for(;;) -- break point at 'code == 256' */ } @@ -328,7 +328,7 @@ static int inflate(struct mszipd_stream *zip) { * is flushed, an error is raised. */ static int mszipd_flush_window(struct mszipd_stream *zip, - unsigned int data_flushed) + unsigned int data_flushed) { zip->bytes_output += data_flushed; if (zip->bytes_output > MSZIP_FRAME_SIZE) { @@ -340,17 +340,18 @@ static int mszipd_flush_window(struct mszipd_stream *zip, } struct mszipd_stream *mszipd_init(struct mspack_system *system, - struct mspack_file *input, - struct mspack_file *output, - int input_buffer_size, - int repair_mode) + struct mspack_file *input, + struct mspack_file *output, + int input_buffer_size, + int repair_mode) { struct mszipd_stream *zip; if (!system) return NULL; + /* round up input buffer size to multiple of two */ input_buffer_size = (input_buffer_size + 1) & -2; - if (!input_buffer_size) return NULL; + if (input_buffer_size < 2) return NULL; /* allocate decompression state */ 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) { if ((error = inflate(zip))) { D(("inflate error %d", error)) if (zip->repair_mode) { - /* recover partially-inflated buffers */ - if (zip->bytes_output == 0 && zip->window_posn > 0) { - zip->flush_window(zip, zip->window_posn); - } - zip->sys->message(NULL, "MSZIP error, %u bytes of data lost.", - MSZIP_FRAME_SIZE - zip->bytes_output); - for (i = zip->bytes_output; i < MSZIP_FRAME_SIZE; i++) { - zip->window[i] = '\0'; - } - zip->bytes_output = MSZIP_FRAME_SIZE; + /* recover partially-inflated buffers */ + if (zip->bytes_output == 0 && zip->window_posn > 0) { + zip->flush_window(zip, zip->window_posn); + } + zip->sys->message(NULL, "MSZIP error, %u bytes of data lost.", + MSZIP_FRAME_SIZE - zip->bytes_output); + for (i = zip->bytes_output; i < MSZIP_FRAME_SIZE; i++) { + zip->window[i] = '\0'; + } + zip->bytes_output = MSZIP_FRAME_SIZE; } else { - return zip->error = (error > 0) ? error : MSPACK_ERR_DECRUNCH; + return zip->error = (error > 0) ? error : MSPACK_ERR_DECRUNCH; } } zip->o_ptr = &zip->window[0]; @@ -465,6 +466,45 @@ int mszipd_decompress(struct mszipd_stream *zip, off_t out_bytes) { return MSPACK_ERR_OK; } +int mszipd_decompress_kwaj(struct mszipd_stream *zip) { + /* for the bit buffer */ + register unsigned int bit_buffer; + register int bits_left; + unsigned char *i_ptr, *i_end; + + int i, error, block_len; + + /* unpack blocks until block_len == 0 */ + for (;;) { + RESTORE_BITS; + + /* align to bytestream, read block_len */ + i = bits_left & 7; REMOVE_BITS(i); + READ_BITS(block_len, 8); + READ_BITS(i, 8); block_len |= i << 8; + + if (block_len == 0) break; + + /* read "CK" header */ + READ_BITS(i, 8); if (i != 'C') return MSPACK_ERR_DATAFORMAT; + READ_BITS(i, 8); if (i != 'K') return MSPACK_ERR_DATAFORMAT; + + /* inflate block */ + zip->window_posn = 0; + zip->bytes_output = 0; + STORE_BITS; + if ((error = inflate(zip))) { + D(("inflate error %d", error)) + return zip->error = (error > 0) ? error : MSPACK_ERR_DECRUNCH; + } + + /* write inflated block */ + if (zip->sys->write(zip->output, &zip->window[0], zip->bytes_output) + != zip->bytes_output) return zip->error = MSPACK_ERR_WRITE; + } + return MSPACK_ERR_OK; +} + void mszipd_free(struct mszipd_stream *zip) { struct mspack_system *sys; if (zip) { |