*/
/*
- * Copyright (C) 2012, 2013 Eric Biggers
+ * Copyright (C) 2012, 2013, 2014 Eric Biggers
*
* This file is part of wimlib, a library for working with WIM files.
*
#include <string.h>
struct xpress_record_ctx {
- input_idx_t freqs[XPRESS_NUM_SYMBOLS];
- struct xpress_match *matches;
+ u32 freqs[XPRESS_NUM_SYMBOLS];
+ struct xpress_item *chosen_items;
};
struct xpress_compressor {
u8 *window;
u32 max_window_size;
- struct xpress_match *matches;
- input_idx_t *prev_tab;
+ struct xpress_item *chosen_items;
+ u32 *prev_tab;
u32 codewords[XPRESS_NUM_SYMBOLS];
u8 lens[XPRESS_NUM_SYMBOLS];
struct xpress_record_ctx record_ctx;
};
/* Intermediate XPRESS match/literal representation. */
-struct xpress_match {
+struct xpress_item {
u16 adjusted_len; /* Match length minus XPRESS_MIN_MATCH_LEN */
u16 offset; /* Match offset */
/* For literals, offset == 0 and adjusted_len is the literal. */
* @codewords and @lens provide the Huffman code that is being used.
*/
static void
-xpress_write_match(struct xpress_match match,
+xpress_write_match(struct xpress_item match,
struct output_bitstream *restrict ostream,
const u32 codewords[restrict],
const u8 lens[restrict])
}
static void
-xpress_write_matches_and_literals(struct output_bitstream *ostream,
- const struct xpress_match matches[restrict],
- input_idx_t num_matches,
- const u32 codewords[restrict],
- const u8 lens[restrict])
+xpress_write_items(struct output_bitstream *ostream,
+ const struct xpress_item items[restrict],
+ u32 num_items,
+ const u32 codewords[restrict],
+ const u8 lens[restrict])
{
- for (input_idx_t i = 0; i < num_matches; i++) {
- if (matches[i].offset) {
- /* Real match */
- xpress_write_match(matches[i], ostream, codewords, lens);
+ for (u32 i = 0; i < num_items; i++) {
+ if (items[i].offset) {
+ /* Match */
+ xpress_write_match(items[i], ostream, codewords, lens);
} else {
- /* Literal byte */
- u8 lit = matches[i].adjusted_len;
+ /* Literal */
+ u8 lit = items[i].adjusted_len;
bitstream_put_bits(ostream, codewords[lit], lens[lit]);
}
}
{
struct xpress_record_ctx *ctx = _ctx;
ctx->freqs[lit]++;
- *(ctx->matches++) = (struct xpress_match) { .offset = 0, .adjusted_len = lit };
+ *(ctx->chosen_items++) =
+ (struct xpress_item) { .offset = 0, .adjusted_len = lit };
}
static void
XPRESS_ASSERT(sym < XPRESS_NUM_SYMBOLS);
ctx->freqs[sym]++;
- *(ctx->matches++) = (struct xpress_match) { .offset = offset,
- .adjusted_len = adjusted_len };
+ *(ctx->chosen_items++) =
+ (struct xpress_item) { .offset = offset,
+ .adjusted_len = adjusted_len };
}
static const struct lz_params xpress_lz_params = {
struct xpress_compressor *c = _c;
u8 *cptr = compressed_data;
struct output_bitstream ostream;
- input_idx_t num_matches;
- input_idx_t i;
+ u32 num_chosen_items;
+ u32 i;
size_t compressed_size;
/* XPRESS requires 256 bytes of overhead for the Huffman code, so it's
/* Determine match/literal sequence to divide the data into. */
memset(c->record_ctx.freqs, 0, sizeof(c->record_ctx.freqs));
- c->record_ctx.matches = c->matches;
+ c->record_ctx.chosen_items = c->chosen_items;
lz_analyze_block(c->window,
uncompressed_size,
xpress_record_match,
&xpress_lz_params,
c->prev_tab);
- num_matches = (c->record_ctx.matches - c->matches);
+ num_chosen_items = (c->record_ctx.chosen_items - c->chosen_items);
/* Account for end of data symbol. */
c->record_ctx.freqs[XPRESS_END_OF_DATA]++;
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);
+ xpress_write_items(&ostream, c->chosen_items, num_chosen_items,
+ 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)
+ if (compressed_size == (u32)~0UL)
return 0;
compressed_size += XPRESS_NUM_SYMBOLS / 2;
if (c) {
FREE(c->window);
- FREE(c->matches);
+ FREE(c->chosen_items);
FREE(c->prev_tab);
FREE(c);
}
c->max_window_size = max_window_size;
- c->matches = MALLOC(max_window_size * sizeof(c->matches[0]));
- if (c->matches == NULL)
+ c->chosen_items = MALLOC(max_window_size * sizeof(c->chosen_items[0]));
+ if (c->chosen_items == NULL)
goto oom;
c->prev_tab = MALLOC(max_window_size * sizeof(c->prev_tab[0]));
size += sizeof(struct xpress_compressor);
size += max_window_size + 8;
- size += max_window_size * sizeof(((struct xpress_compressor*)0)->matches[0]);
+ size += max_window_size * sizeof(((struct xpress_compressor*)0)->chosen_items[0]);
size += max_window_size * sizeof(((struct xpress_compressor*)0)->prev_tab[0]);
return size;