/*
* Copyright (C) 2012, 2013, 2014 Eric Biggers
*
- * This file is part of wimlib, a library for working with WIM files.
+ * This file is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option) any
+ * later version.
*
- * wimlib is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option)
- * any later version.
- *
- * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- * A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * This file is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
- * You should have received a copy of the GNU General Public License
- * along with wimlib; if not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this file; if not, see http://www.gnu.org/licenses/.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
+#include "wimlib/bitops.h"
#include "wimlib/compress_common.h"
#include "wimlib/compressor_ops.h"
#include "wimlib/endianness.h"
#include "wimlib/error.h"
#include "wimlib/lz_mf.h"
+#include "wimlib/unaligned.h"
#include "wimlib/util.h"
#include "wimlib/xpress.h"
*/
u32 mc_item_data;
#define MC_OFFSET_SHIFT 16
-#define MC_LEN_MASK ((1 << MC_OFFSET_SHIFT) - 1)
+#define MC_LEN_MASK (((u32)1 << MC_OFFSET_SHIFT) - 1)
};
if (os->bitcount > 16) {
os->bitcount -= 16;
if (os->end - os->next_byte >= 2) {
- *(le16 *)os->next_bits = cpu_to_le16(os->bitbuf >> os->bitcount);
+ put_unaligned_u16_le(os->bitbuf >> os->bitcount, os->next_bits);
os->next_bits = os->next_bits2;
os->next_bits2 = os->next_byte;
os->next_byte += 2;
if (unlikely(os->end - os->next_byte < 2))
return 0;
- *(le16 *)os->next_bits = cpu_to_le16(os->bitbuf << (16 - os->bitcount));
- *(le16 *)os->next_bits2 = cpu_to_le16(0);
+ put_unaligned_u16_le(os->bitbuf << (16 - os->bitcount), os->next_bits);
+ put_unaligned_u16_le(0, os->next_bits2);
return os->next_byte - os->start;
}
{
unsigned adjusted_len = len - XPRESS_MIN_MATCH_LEN;
unsigned len_hdr = min(adjusted_len, 0xf);
- unsigned offset_bsr = bsr32(offset);
- unsigned sym = XPRESS_NUM_CHARS + ((offset_bsr << 4) | len_hdr);
+ unsigned offset_high_bit = fls32(offset);
+ unsigned sym = XPRESS_NUM_CHARS + ((offset_high_bit << 4) | len_hdr);
c->freqs[sym]++;
*(*next_chosen_item)++ = (struct xpress_item) {
.data = (u64)sym |
((u64)adjusted_len << 9) |
- ((u64)offset_bsr << 25) |
- ((u64)(offset ^ (1U << offset_bsr)) << 29),
+ ((u64)offset_high_bit << 25) |
+ ((u64)(offset ^ (1U << offset_high_bit)) << 29),
};
}
}
* @matches must be sorted by strictly increasing length and strictly
* increasing offset. This is guaranteed by the match-finder.
*
- * We consider each length from the minimum (2) to the longest
+ * We consider each length from the minimum (3) to the longest
* (matches[num_matches - 1].len). For each length, we consider only
* the smallest offset for which that length is available. Although
* this is not guaranteed to be optimal due to the possibility of a
u32 cost;
u32 position_cost;
unsigned offset;
- unsigned offset_bsr;
+ unsigned offset_high_bit;
unsigned adjusted_len;
unsigned len_hdr;
unsigned sym;
/* All lengths are small. Optimize accordingly. */
do {
offset = matches[i].offset;
- offset_bsr = bsr32(offset);
+ offset_high_bit = fls32(offset);
len_hdr = len - XPRESS_MIN_MATCH_LEN;
- sym = XPRESS_NUM_CHARS + ((offset_bsr << 4) | len_hdr);
+ sym = XPRESS_NUM_CHARS + ((offset_high_bit << 4) | len_hdr);
- position_cost = cur_optimum_ptr->cost + offset_bsr;
+ position_cost = cur_optimum_ptr->cost + offset_high_bit;
do {
cost = position_cost + c->costs[sym];
if (cost < (cur_optimum_ptr + len)->cost) {
/* Some lengths are big. */
do {
offset = matches[i].offset;
- offset_bsr = bsr32(offset);
- position_cost = cur_optimum_ptr->cost + offset_bsr;
+ offset_high_bit = fls32(offset);
+ position_cost = cur_optimum_ptr->cost + offset_high_bit;
do {
adjusted_len = len - XPRESS_MIN_MATCH_LEN;
len_hdr = min(adjusted_len, 0xf);
- sym = XPRESS_NUM_CHARS + ((offset_bsr << 4) | len_hdr);
+ sym = XPRESS_NUM_CHARS + ((offset_high_bit << 4) | len_hdr);
cost = position_cost + c->costs[sym];
if (adjusted_len >= 0xf) {
* XPRESS_OPTIM_ARRAY_LENGTH is high enough that on most
* inputs this limit is never reached.
*
- * Note: no check for end-of-block is needed because
- * end-of-block will trigger condition (1).
+ * Note: no check for end-of-window is needed because
+ * end-of-window will trigger condition (1).
*/
if (cur_optimum_ptr == end_optimum_ptr ||
cur_optimum_ptr == &c->optimum[XPRESS_OPTIM_ARRAY_LENGTH])
c->cur_window_size = uncompressed_size;
lz_mf_load_window(c->mf, c->cur_window, c->cur_window_size);
memset(c->freqs, 0, sizeof(c->freqs));
+
num_chosen_items = xpress_choose_items(c);
+
c->freqs[XPRESS_END_OF_DATA]++;
xpress_make_huffman_code(c);
/* Output the Huffman code as a series of 512 4-bit lengths. */
cptr = compressed_data;
for (unsigned i = 0; i < XPRESS_NUM_SYMBOLS; i += 2)
- *cptr++ = (c->lens[i] & 0xf) | (c->lens[i + 1] << 4);
+ *cptr++ = (c->lens[i + 1] << 4) | c->lens[i];
/* Output the encoded matches/literals. */
xpress_init_output(&os, cptr,
if (c) {
lz_mf_free(c->mf);
- FREE(c->cached_matches);
FREE(c->optimum);
+ FREE(c->cached_matches);
FREE(c->chosen_items);
FREE(c);
}