- *compressed_data++ = (lens[i] & 0xf) | (lens[i + 1] << 4);
-
- init_output_bitstream(&ostream, compressed_data,
- uncompressed_len - XPRESS_NUM_SYMBOLS / 2 - 1);
-
- ret = xpress_write_compressed_literals(&ostream, match_tab,
- num_matches, codewords, lens);
- if (ret != 0)
- return ret;
-
- /* Flush any bits that are buffered. */
- ret = flush_output_bitstream(&ostream);
- if (ret != 0)
- return ret;
-
- /* Assert that there are no output bytes between the ostream.output
- * pointer and the ostream.next_bit_output pointer. This can only
- * happen if bytes had been written at the ostream.output pointer before
- * the last bit word was written to the stream. But, this does not
- * occur since xpress_write_match() always finishes by writing some bits
- * (a Huffman symbol), and the bitstream was just flushed. */
- wimlib_assert(ostream.output - ostream.next_bit_output == 2);
-
- /* The length of the compressed data is supposed to be the value of the
- * ostream.output pointer before flushing, which is now the
- * output.next_bit_output pointer after flushing.
- *
- * There will be an extra 2 bytes at the ostream.bit_output pointer,
- * which is zeroed out. (These 2 bytes may be either the last bytes in
- * the compressed data, in which case they are actually unnecessary, or
- * they may precede a number of bytes embedded into the bitstream.) */
- if (ostream.bit_output >
- (const u8*)__compressed_data + uncompressed_len - 3)
- return 1;
- *(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) {
- ERROR("xpress_compress(): Failed to decompress data we "
- "compressed");
- abort();
- }
- for (i = 0; i < uncompressed_len; i++) {
- if (buf[i] != uncompressed_data[i]) {
- ERROR("xpress_compress(): Data we compressed didn't "
- "decompress to the original data (difference at "
- "byte %u of %u)", i + 1, uncompressed_len);
- abort();
+ *cptr++ = (c->lens[i] & 0xf) | (c->lens[i + 1] << 4);
+
+ /* Output the encoded matches/literals. */
+ init_output_bitstream(&ostream, cptr,
+ compressed_size_avail - XPRESS_NUM_SYMBOLS / 2 - 1);
+
+ xpress_write_matches_and_literals(&ostream, c->matches,
+ num_matches, c->codewords, c->lens);
+
+ /* Flush any pending data and get the length of the compressed data. */
+ compressed_size = flush_output_bitstream(&ostream);
+ if (compressed_size == ~(input_idx_t)0)
+ return 0;
+
+ compressed_size += XPRESS_NUM_SYMBOLS / 2;
+
+#if defined(ENABLE_XPRESS_DEBUG) || defined(ENABLE_VERIFY_COMPRESSION)
+ /* Verify that we really get the same thing back when decompressing. */
+ {
+ struct wimlib_decompressor *decompressor;
+
+ if (0 == wimlib_create_decompressor(WIMLIB_COMPRESSION_TYPE_XPRESS,
+ c->max_window_size,
+ NULL,
+ &decompressor))
+ {
+ int ret;
+ ret = wimlib_decompress(compressed_data,
+ compressed_size,
+ c->window,
+ uncompressed_size,
+ decompressor);
+ wimlib_free_decompressor(decompressor);
+
+ if (ret) {
+ ERROR("Failed to decompress data we "
+ "compressed using XPRESS algorithm");
+ wimlib_assert(0);
+ return 0;
+ }
+ if (memcmp(uncompressed_data, c->window,
+ uncompressed_size))
+ {
+ ERROR("Data we compressed using XPRESS algorithm "
+ "didn't decompress to original");
+ wimlib_assert(0);
+ return 0;
+ }
+ } else {
+ WARNING("Failed to create decompressor for "
+ "data verification!");