X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Flzx-compress.c;h=b23c2df088642ce2d9001ebeba130d8fbba504d8;hp=9a654b2d796586d1177adf234ff04b785e0d268f;hb=2a94ebd67e2a341208c4849a92442ecd511fb716;hpb=a3bb2e86f2640f5d593d00250a627d3dcc9747a2 diff --git a/src/lzx-compress.c b/src/lzx-compress.c index 9a654b2d..b23c2df0 100644 --- a/src/lzx-compress.c +++ b/src/lzx-compress.c @@ -27,8 +27,8 @@ /* - * This file provides lzx_compress(), a function to compress an in-memory buffer - * of data using LZX compression, as used in the WIM file format. + * This file provides wimlib_lzx_compress(), a function to compress an in-memory + * buffer of data using LZX compression, as used in the WIM file format. * * Please see the comments in lzx-decompress.c for more information about this * compression format. @@ -57,6 +57,7 @@ * blocks from one input chunk is not yet implemented. */ +#include "wimlib.h" #include "lzx.h" #include "compress.h" #include @@ -566,7 +567,7 @@ lzx_write_compressed_tree(struct output_bitstream *out, /* Builds the canonical Huffman code for the main tree, the length tree, and the * aligned offset tree. */ -static void +static void lzx_make_huffman_codes(const struct lzx_freq_tables *freq_tabs, struct lzx_codes *codes) { @@ -638,26 +639,10 @@ static const struct lz_params lzx_lz_params = { .too_far = 4096, }; -/* - * 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. - */ -int -lzx_compress(const void *__uncompressed_data, unsigned uncompressed_len, - void *compressed_data, unsigned *compressed_len_ret) +/* Documented in wimlib.h */ +WIMLIBAPI unsigned +wimlib_lzx_compress(const void *__uncompressed_data, unsigned uncompressed_len, + void *compressed_data) { struct output_bitstream ostream; u8 uncompressed_data[uncompressed_len + 8]; @@ -671,8 +656,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; @@ -682,6 +669,7 @@ lzx_compress(const void *__uncompressed_data, unsigned uncompressed_len, /* The input data must be preprocessed. To avoid changing the original * input, copy it to a temporary buffer. */ memcpy(uncompressed_data, __uncompressed_data, uncompressed_len); + memset(uncompressed_data + uncompressed_len, 0, 8); /* Before doing any actual compression, do the call instruction (0xe8 * byte) translation on the uncompressed data. */ @@ -728,55 +716,55 @@ 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]; - ret = lzx_decompress(compressed_data, compressed_len, buf, - uncompressed_len); - if (ret != 0) { - ERROR("lzx_compress(): Failed to decompress data we compressed"); - abort(); - } - - for (i = 0; i < uncompressed_len; i++) { - if (buf[i] != *((u8*)__uncompressed_data + i)) { - ERROR("lzx_compress(): Data we compressed didn't " - "decompress to the original data (difference at " - "byte %u of %u)", i + 1, uncompressed_len); + { + u8 buf[uncompressed_len]; + ret = wimlib_lzx_decompress(compressed_data, compressed_len, + buf, uncompressed_len); + if (ret != 0) { + ERROR("lzx_compress(): Failed to decompress data we compressed"); abort(); } + + for (i = 0; i < uncompressed_len; i++) { + if (buf[i] != *((u8*)__uncompressed_data + i)) { + ERROR("lzx_compress(): Data we compressed didn't " + "decompress to the original data (difference at " + "byte %u of %u)", i + 1, uncompressed_len); + abort(); + } + } } #endif - return 0; + return compressed_len; }