From: Eric Biggers Date: Sun, 24 Mar 2013 00:58:06 +0000 (-0500) Subject: Remove unneeded parameter from compression functions X-Git-Tag: v1.3.2~18 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=720db87557918105b17b51b03f264ddb9b89d2b9 Remove unneeded parameter from compression functions Also refer to the (now improved) documentation for compress_func_t instead of documenting xpress_compress() and lzx_compress() individually. --- diff --git a/src/lzx-compress.c b/src/lzx-compress.c index 9a654b2d..c829a427 100644 --- a/src/lzx-compress.c +++ b/src/lzx-compress.c @@ -641,23 +641,12 @@ static const struct lz_params lzx_lz_params = { /* * Performs LZX compression on a block of data. * - * @__uncompressed_data: Pointer to the data to be compressed. - * @uncompressed_len: Length, in bytes, of the data to be compressed. - * @compressed_data: Pointer to a location at least (@uncompressed_len - 1) - * bytes long into which the compressed data may be - * written. - * @compressed_len_ret: A pointer to an unsigned int into which the length of - * the compressed data may be returned. - * - * Returns zero if compression was successfully performed. In that case - * @compressed_data and @compressed_len_ret will contain the compressed data and - * its length. A return value of nonzero means that compressing the data did - * not reduce its size, and @compressed_data will not contain the full - * compressed data. + * Please see the documentation for the 'compress_func_t' type in write.c for + * the exact behavior of this function and how to call it. */ -int +unsigned lzx_compress(const void *__uncompressed_data, unsigned uncompressed_len, - void *compressed_data, unsigned *compressed_len_ret) + void *compressed_data) { struct output_bitstream ostream; u8 uncompressed_data[uncompressed_len + 8]; @@ -671,8 +660,10 @@ lzx_compress(const void *__uncompressed_data, unsigned uncompressed_len, int ret; int block_type = LZX_BLOCKTYPE_ALIGNED; + wimlib_assert(uncompressed_len <= 32768); + if (uncompressed_len < 100) - return 1; + return 0; memset(&freq_tabs, 0, sizeof(freq_tabs)); queue.R0 = 1; @@ -728,37 +719,35 @@ lzx_compress(const void *__uncompressed_data, unsigned uncompressed_len, * main tree. */ ret = lzx_write_compressed_tree(&ostream, codes.main_lens, LZX_NUM_CHARS); - if (ret != 0) - return ret; + if (ret) + return 0; /* Write the pre-tree and symbols for the rest of the main tree. */ ret = lzx_write_compressed_tree(&ostream, codes.main_lens + LZX_NUM_CHARS, LZX_MAINTREE_NUM_SYMBOLS - LZX_NUM_CHARS); - if (ret != 0) - return ret; + if (ret) + return 0; /* Write the pre-tree and symbols for the length tree. */ ret = lzx_write_compressed_tree(&ostream, codes.len_lens, LZX_LENTREE_NUM_SYMBOLS); - if (ret != 0) - return ret; + if (ret) + return 0; /* Write the compressed literals. */ ret = lzx_write_compressed_literals(&ostream, block_type, match_tab, num_matches, &codes); - if (ret != 0) - return ret; + if (ret) + return 0; ret = flush_output_bitstream(&ostream); - if (ret != 0) - return ret; + if (ret) + return 0; compressed_len = ostream.bit_output - (u8*)compressed_data; - *compressed_len_ret = compressed_len; - #ifdef ENABLE_VERIFY_COMPRESSION /* Verify that we really get the same thing back when decompressing. */ u8 buf[uncompressed_len]; @@ -778,5 +767,5 @@ lzx_compress(const void *__uncompressed_data, unsigned uncompressed_len, } } #endif - return 0; + return compressed_len; } diff --git a/src/lzx.h b/src/lzx.h index 8a396892..ed6a4d4e 100644 --- a/src/lzx.h +++ b/src/lzx.h @@ -80,7 +80,8 @@ extern const u8 lzx_extra_bits[LZX_NUM_POSITION_SLOTS]; /* Given the number of a LZX position slot, return the number of extra bits that * are needed to encode the match offset. */ -static inline unsigned lzx_get_num_extra_bits(unsigned position_slot) +static inline unsigned +lzx_get_num_extra_bits(unsigned position_slot) { #ifdef USE_LZX_EXTRA_BITS_ARRAY /* Use a table */ @@ -101,10 +102,12 @@ struct lru_queue { u32 R2; }; -extern int lzx_decompress(const void *compressed_data, unsigned compressed_len, - void *uncompressed_data, unsigned uncompressed_len); +extern int +lzx_decompress(const void *compressed_data, unsigned compressed_len, + void *uncompressed_data, unsigned uncompressed_len); -extern int lzx_compress(const void *uncompressed_data, unsigned uncompressed_len, - void *compressed_data, unsigned *compressed_len_ret); +extern unsigned +lzx_compress(const void *uncompressed_data, unsigned uncompressed_len, + void *compressed_data); #endif /* _WIMLIB_LZX_H */ diff --git a/src/write.c b/src/write.c index 633196b4..6a07c44e 100644 --- a/src/write.c +++ b/src/write.c @@ -151,21 +151,29 @@ out: } /* - * Pointer to function to compresses a chunk of a WIM resource. + * compress_func_t- Pointer to a function to compresses a chunk + * of a WIM resource. This may be either xpress_compress() + * (xpress-compress.c) or lzx_compress() (lzx-compress.c). * - * @chunk: Uncompressed data of the chunk. - * @chunk_size: Size of the uncompressed chunk in bytes. - * @compressed_chunk: Pointer to output buffer of size at least - * (@chunk_size - 1) bytes. - * @compressed_chunk_len_ret: Pointer to an unsigned int into which the size - * of the compressed chunk will be - * returned. + * @chunk: Uncompressed data of the chunk. + * @chunk_size: Size of the uncompressed chunk, in bytes. + * @out: Pointer to output buffer of size at least (@chunk_size - 1) bytes. + * + * Returns the size of the compressed data written to @out in bytes, or 0 if the + * data could not be compressed to (@chunk_size - 1) bytes or fewer. + * + * As a special requirement, the compression code is optimized for the WIM + * format and therefore requires (@chunk_size <= 32768). * - * Returns zero if compressed succeeded, and nonzero if the chunk could not be - * compressed to any smaller than @chunk_size. This function cannot fail for - * any other reasons. + * As another special requirement, the compression code will read up to 8 bytes + * off the end of the @chunk array for performance reasons. The values of these + * bytes will not affect the output of the compression, but the calling code + * must make sure that the buffer holding the uncompressed chunk is actually at + * least (@chunk_size + 8) bytes, or at least that these extra bytes are in + * mapped memory that will not cause a memory access violation if accessed. */ -typedef int (*compress_func_t)(const void *, unsigned, void *, unsigned *); +typedef unsigned (*compress_func_t)(const void *chunk, unsigned chunk_size, + void *out); compress_func_t get_compress_func(int out_ctype) @@ -198,19 +206,20 @@ write_wim_resource_chunk(const u8 chunk[], unsigned chunk_size, unsigned out_chunk_size; if (chunk_tab) { u8 *compressed_chunk = alloca(chunk_size); - int ret; - ret = compress(chunk, chunk_size, compressed_chunk, - &out_chunk_size); - if (ret == 0) { + out_chunk_size = compress(chunk, chunk_size, compressed_chunk); + if (out_chunk_size) { + /* Write compressed */ out_chunk = compressed_chunk; } else { + /* Write uncompressed */ out_chunk = chunk; out_chunk_size = chunk_size; } *chunk_tab->cur_offset_p++ = chunk_tab->cur_offset; chunk_tab->cur_offset += out_chunk_size; } else { + /* Write uncompressed */ out_chunk = chunk; out_chunk_size = chunk_size; } @@ -689,15 +698,18 @@ compress_chunks(struct message *msg, compress_func_t compress) { for (unsigned i = 0; i < msg->num_chunks; i++) { DEBUG2("compress chunk %u of %u", i, msg->num_chunks); - int ret = compress(msg->uncompressed_chunks[i], - msg->uncompressed_chunk_sizes[i], - msg->compressed_chunks[i], - &msg->compressed_chunk_sizes[i]); - if (ret == 0) { + unsigned len = compress(msg->uncompressed_chunks[i], + msg->uncompressed_chunk_sizes[i], + msg->compressed_chunks[i]); + if (len) { + /* To be written compressed */ msg->out_compressed_chunks[i] = msg->compressed_chunks[i]; + msg->compressed_chunk_sizes[i] = len; } else { + /* To be written uncompressed */ msg->out_compressed_chunks[i] = msg->uncompressed_chunks[i]; msg->compressed_chunk_sizes[i] = msg->uncompressed_chunk_sizes[i]; + } } } diff --git a/src/xpress-compress.c b/src/xpress-compress.c index 6d2836f0..548c32cb 100644 --- a/src/xpress-compress.c +++ b/src/xpress-compress.c @@ -142,23 +142,12 @@ static const struct lz_params xpress_lz_params = { /* * Performs XPRESS compression on a block of data. * - * @__uncompressed_data: Pointer to the data to be compressed. - * @uncompressed_len: Length, in bytes, of the data to be compressed. - * @__compressed_data: Pointer to a location at least (@uncompressed_len - 1) - * bytes long into which the compressed data may be - * written. - * @compressed_len_ret: A pointer to an unsigned int into which the length of - * the compressed data may be returned. - * - * Returns zero if compression was successfully performed. In that case - * @compressed_data and @compressed_len_ret will contain the compressed data and - * its length. A return value of nonzero means that compressing the data did - * not reduce its size, and @compressed_data will not contain the full - * compressed data. + * Please see the documentation for the 'compress_func_t' type in write.c for + * the exact behavior of this function and how to call it. */ -int +unsigned xpress_compress(const void *__uncompressed_data, unsigned uncompressed_len, - void *__compressed_data, unsigned *compressed_len_ret) + void *__compressed_data) { const u8 *uncompressed_data = __uncompressed_data; u8 *compressed_data = __compressed_data; @@ -172,6 +161,8 @@ xpress_compress(const void *__uncompressed_data, unsigned uncompressed_len, unsigned i; int ret; + wimlib_assert(uncompressed_len <= 32768); + /* XPRESS requires 256 bytes of overhead for the Huffman tables, so it's * impossible cannot compress 256 bytes or less of data to less than the * input size. @@ -182,7 +173,7 @@ xpress_compress(const void *__uncompressed_data, unsigned uncompressed_len, * +4 to take into account that init_output_bitstream() requires at * least 4 bytes of data. */ if (uncompressed_len < XPRESS_NUM_SYMBOLS / 2 + 1 + 4) - return 1; + return 0; ZERO_ARRAY(freq_tab); num_matches = lz_analyze_block(uncompressed_data, uncompressed_len, @@ -216,13 +207,13 @@ xpress_compress(const void *__uncompressed_data, unsigned uncompressed_len, ret = xpress_write_compressed_literals(&ostream, match_tab, num_matches, codewords, lens); - if (ret != 0) - return ret; + if (ret) + return 0; /* Flush any bits that are buffered. */ ret = flush_output_bitstream(&ostream); - if (ret != 0) - return ret; + if (ret) + return 0; /* Assert that there are no output bytes between the ostream.output * pointer and the ostream.next_bit_output pointer. This can only @@ -242,20 +233,18 @@ xpress_compress(const void *__uncompressed_data, unsigned uncompressed_len, * they may precede a number of bytes embedded into the bitstream.) */ if (ostream.bit_output > (const u8*)__compressed_data + uncompressed_len - 3) - return 1; + return 0; *(u16*)ostream.bit_output = cpu_to_le16(0); compressed_len = ostream.next_bit_output - (const u8*)__compressed_data; wimlib_assert(compressed_len <= uncompressed_len - 1); - *compressed_len_ret = compressed_len; - #ifdef ENABLE_VERIFY_COMPRESSION /* Verify that we really get the same thing back when decompressing. */ u8 buf[uncompressed_len]; ret = xpress_decompress(__compressed_data, compressed_len, buf, uncompressed_len); - if (ret != 0) { + if (ret) { ERROR("xpress_compress(): Failed to decompress data we " "compressed"); abort(); @@ -269,5 +258,5 @@ xpress_compress(const void *__uncompressed_data, unsigned uncompressed_len, } } #endif - return 0; + return compressed_len; } diff --git a/src/xpress.h b/src/xpress.h index c8bc57d8..c457a72e 100644 --- a/src/xpress.h +++ b/src/xpress.h @@ -25,10 +25,12 @@ #define XPRESS_MIN_MATCH 3 #define XPRESS_MAX_MATCH 65538 -extern int xpress_decompress(const void *__compressed_data, unsigned compressed_len, - void *__uncompressed_data, unsigned uncompressed_len); +extern int +xpress_decompress(const void *compressed_data, unsigned compressed_len, + void *uncompressed_data, unsigned uncompressed_len); -extern int xpress_compress(const void *uncompressed_data, unsigned uncompressed_len, - void *compressed_data, unsigned *compressed_len_ret); +extern unsigned +xpress_compress(const void *uncompressed_data, unsigned uncompressed_len, + void *compressed_data); #endif /* _WIMLIB_XPRESS_H */