mirror of
https://github.com/cuberite/libdeflate.git
synced 2025-09-08 11:50:00 -04:00
deflate_compress: factor out deflate_write_match()
Reduce code duplication between deflate_write_sequences() and deflate_write_item_list().
This commit is contained in:
parent
90e7211d39
commit
194f6a447f
@ -1703,6 +1703,45 @@ deflate_write_literal_run(struct deflate_output_bitstream *os,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static forceinline void
|
||||||
|
deflate_write_match(struct deflate_output_bitstream * restrict os,
|
||||||
|
unsigned length, unsigned length_slot,
|
||||||
|
unsigned offset, unsigned offset_symbol,
|
||||||
|
const struct deflate_codes * restrict codes)
|
||||||
|
{
|
||||||
|
unsigned litlen_symbol = DEFLATE_FIRST_LEN_SYM + length_slot;
|
||||||
|
|
||||||
|
/* Litlen symbol */
|
||||||
|
deflate_add_bits(os, codes->codewords.litlen[litlen_symbol],
|
||||||
|
codes->lens.litlen[litlen_symbol]);
|
||||||
|
|
||||||
|
/* Extra length bits */
|
||||||
|
STATIC_ASSERT(CAN_BUFFER(MAX_LITLEN_CODEWORD_LEN +
|
||||||
|
DEFLATE_MAX_EXTRA_LENGTH_BITS));
|
||||||
|
deflate_add_bits(os, length - deflate_length_slot_base[length_slot],
|
||||||
|
deflate_extra_length_bits[length_slot]);
|
||||||
|
|
||||||
|
if (!CAN_BUFFER(MAX_LITLEN_CODEWORD_LEN +
|
||||||
|
DEFLATE_MAX_EXTRA_LENGTH_BITS +
|
||||||
|
MAX_OFFSET_CODEWORD_LEN +
|
||||||
|
DEFLATE_MAX_EXTRA_OFFSET_BITS))
|
||||||
|
deflate_flush_bits(os);
|
||||||
|
|
||||||
|
/* Offset symbol */
|
||||||
|
deflate_add_bits(os, codes->codewords.offset[offset_symbol],
|
||||||
|
codes->lens.offset[offset_symbol]);
|
||||||
|
|
||||||
|
if (!CAN_BUFFER(MAX_OFFSET_CODEWORD_LEN +
|
||||||
|
DEFLATE_MAX_EXTRA_OFFSET_BITS))
|
||||||
|
deflate_flush_bits(os);
|
||||||
|
|
||||||
|
/* Extra offset bits */
|
||||||
|
deflate_add_bits(os, offset - deflate_offset_slot_base[offset_symbol],
|
||||||
|
deflate_extra_offset_bits[offset_symbol]);
|
||||||
|
|
||||||
|
deflate_flush_bits(os);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
deflate_write_sequences(struct deflate_output_bitstream * restrict os,
|
deflate_write_sequences(struct deflate_output_bitstream * restrict os,
|
||||||
const struct deflate_codes * restrict codes,
|
const struct deflate_codes * restrict codes,
|
||||||
@ -1714,9 +1753,6 @@ deflate_write_sequences(struct deflate_output_bitstream * restrict os,
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
u32 litrunlen = seq->litrunlen_and_length & SEQ_LITRUNLEN_MASK;
|
u32 litrunlen = seq->litrunlen_and_length & SEQ_LITRUNLEN_MASK;
|
||||||
unsigned length = seq->litrunlen_and_length >> SEQ_LENGTH_SHIFT;
|
unsigned length = seq->litrunlen_and_length >> SEQ_LENGTH_SHIFT;
|
||||||
unsigned length_slot;
|
|
||||||
unsigned litlen_symbol;
|
|
||||||
unsigned offset_symbol;
|
|
||||||
|
|
||||||
if (litrunlen) {
|
if (litrunlen) {
|
||||||
deflate_write_literal_run(os, in_next, litrunlen,
|
deflate_write_literal_run(os, in_next, litrunlen,
|
||||||
@ -1727,44 +1763,10 @@ deflate_write_sequences(struct deflate_output_bitstream * restrict os,
|
|||||||
if (length == 0)
|
if (length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
deflate_write_match(os, length, seq->length_slot,
|
||||||
|
seq->offset, seq->offset_symbol, codes);
|
||||||
|
|
||||||
in_next += length;
|
in_next += length;
|
||||||
|
|
||||||
length_slot = seq->length_slot;
|
|
||||||
litlen_symbol = DEFLATE_FIRST_LEN_SYM + length_slot;
|
|
||||||
|
|
||||||
/* Litlen symbol */
|
|
||||||
deflate_add_bits(os, codes->codewords.litlen[litlen_symbol],
|
|
||||||
codes->lens.litlen[litlen_symbol]);
|
|
||||||
|
|
||||||
/* Extra length bits */
|
|
||||||
STATIC_ASSERT(CAN_BUFFER(MAX_LITLEN_CODEWORD_LEN +
|
|
||||||
DEFLATE_MAX_EXTRA_LENGTH_BITS));
|
|
||||||
deflate_add_bits(os,
|
|
||||||
length - deflate_length_slot_base[length_slot],
|
|
||||||
deflate_extra_length_bits[length_slot]);
|
|
||||||
|
|
||||||
if (!CAN_BUFFER(MAX_LITLEN_CODEWORD_LEN +
|
|
||||||
DEFLATE_MAX_EXTRA_LENGTH_BITS +
|
|
||||||
MAX_OFFSET_CODEWORD_LEN +
|
|
||||||
DEFLATE_MAX_EXTRA_OFFSET_BITS))
|
|
||||||
deflate_flush_bits(os);
|
|
||||||
|
|
||||||
/* Offset symbol */
|
|
||||||
offset_symbol = seq->offset_symbol;
|
|
||||||
deflate_add_bits(os, codes->codewords.offset[offset_symbol],
|
|
||||||
codes->lens.offset[offset_symbol]);
|
|
||||||
|
|
||||||
if (!CAN_BUFFER(MAX_OFFSET_CODEWORD_LEN +
|
|
||||||
DEFLATE_MAX_EXTRA_OFFSET_BITS))
|
|
||||||
deflate_flush_bits(os);
|
|
||||||
|
|
||||||
/* Extra offset bits */
|
|
||||||
deflate_add_bits(os, seq->offset -
|
|
||||||
deflate_offset_slot_base[offset_symbol],
|
|
||||||
deflate_extra_offset_bits[offset_symbol]);
|
|
||||||
|
|
||||||
deflate_flush_bits(os);
|
|
||||||
|
|
||||||
seq++;
|
seq++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1774,10 +1776,6 @@ deflate_write_sequences(struct deflate_output_bitstream * restrict os,
|
|||||||
* Follow the minimum-cost path in the graph of possible match/literal choices
|
* Follow the minimum-cost path in the graph of possible match/literal choices
|
||||||
* for the current block and write out the matches/literals using the specified
|
* for the current block and write out the matches/literals using the specified
|
||||||
* Huffman codes.
|
* Huffman codes.
|
||||||
*
|
|
||||||
* Note: this is slightly duplicated with deflate_write_sequences(), the reason
|
|
||||||
* being that we don't want to waste time translating between intermediate
|
|
||||||
* match/literal representations.
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
deflate_write_item_list(struct deflate_output_bitstream *os,
|
deflate_write_item_list(struct deflate_output_bitstream *os,
|
||||||
@ -1791,51 +1789,19 @@ deflate_write_item_list(struct deflate_output_bitstream *os,
|
|||||||
do {
|
do {
|
||||||
unsigned length = cur_node->item & OPTIMUM_LEN_MASK;
|
unsigned length = cur_node->item & OPTIMUM_LEN_MASK;
|
||||||
unsigned offset = cur_node->item >> OPTIMUM_OFFSET_SHIFT;
|
unsigned offset = cur_node->item >> OPTIMUM_OFFSET_SHIFT;
|
||||||
unsigned litlen_symbol;
|
|
||||||
unsigned length_slot;
|
|
||||||
unsigned offset_slot;
|
|
||||||
|
|
||||||
if (length == 1) {
|
if (length == 1) {
|
||||||
/* Literal */
|
/* Literal */
|
||||||
litlen_symbol = offset;
|
deflate_add_bits(os, codes->codewords.litlen[offset],
|
||||||
deflate_add_bits(os,
|
codes->lens.litlen[offset]);
|
||||||
codes->codewords.litlen[litlen_symbol],
|
|
||||||
codes->lens.litlen[litlen_symbol]);
|
|
||||||
deflate_flush_bits(os);
|
deflate_flush_bits(os);
|
||||||
} else {
|
} else {
|
||||||
/* Match length */
|
/* Match */
|
||||||
length_slot = deflate_length_slot[length];
|
deflate_write_match(os, length,
|
||||||
litlen_symbol = DEFLATE_FIRST_LEN_SYM + length_slot;
|
deflate_length_slot[length],
|
||||||
deflate_add_bits(os,
|
offset,
|
||||||
codes->codewords.litlen[litlen_symbol],
|
c->p.n.offset_slot_full[offset],
|
||||||
codes->lens.litlen[litlen_symbol]);
|
codes);
|
||||||
|
|
||||||
deflate_add_bits(os,
|
|
||||||
length - deflate_length_slot_base[length_slot],
|
|
||||||
deflate_extra_length_bits[length_slot]);
|
|
||||||
|
|
||||||
if (!CAN_BUFFER(MAX_LITLEN_CODEWORD_LEN +
|
|
||||||
DEFLATE_MAX_EXTRA_LENGTH_BITS +
|
|
||||||
MAX_OFFSET_CODEWORD_LEN +
|
|
||||||
DEFLATE_MAX_EXTRA_OFFSET_BITS))
|
|
||||||
deflate_flush_bits(os);
|
|
||||||
|
|
||||||
|
|
||||||
/* Match offset */
|
|
||||||
offset_slot = c->p.n.offset_slot_full[offset];
|
|
||||||
deflate_add_bits(os,
|
|
||||||
codes->codewords.offset[offset_slot],
|
|
||||||
codes->lens.offset[offset_slot]);
|
|
||||||
|
|
||||||
if (!CAN_BUFFER(MAX_OFFSET_CODEWORD_LEN +
|
|
||||||
DEFLATE_MAX_EXTRA_OFFSET_BITS))
|
|
||||||
deflate_flush_bits(os);
|
|
||||||
|
|
||||||
deflate_add_bits(os,
|
|
||||||
offset - deflate_offset_slot_base[offset_slot],
|
|
||||||
deflate_extra_offset_bits[offset_slot]);
|
|
||||||
|
|
||||||
deflate_flush_bits(os);
|
|
||||||
}
|
}
|
||||||
cur_node += length;
|
cur_node += length;
|
||||||
} while (cur_node != end_node);
|
} while (cur_node != end_node);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user