-/*
- * Output an LZX match.
- *
- * @out: The bitstream to write the match to.
- * @block_type: The type of the LZX block (LZX_BLOCKTYPE_ALIGNED or LZX_BLOCKTYPE_VERBATIM)
- * @match: The match.
- * @codes: Pointer to a structure that contains the codewords for the
- * main, length, and aligned offset Huffman codes.
- */
-static void
-lzx_write_match(struct output_bitstream *out, int block_type,
- struct lzx_match match, const struct lzx_codes *codes)
-{
- /* low 8 bits are the match length minus 2 */
- unsigned match_len_minus_2 = match.data & 0xff;
- /* Next 17 bits are the position footer */
- unsigned position_footer = (match.data >> 8) & 0x1ffff; /* 17 bits */
- /* Next 6 bits are the position slot. */
- unsigned position_slot = (match.data >> 25) & 0x3f; /* 6 bits */
- unsigned len_header;
- unsigned len_footer;
- unsigned main_symbol;
- unsigned num_extra_bits;
- unsigned verbatim_bits;
- unsigned aligned_bits;
-
- /* If the match length is less than MIN_MATCH_LEN (= 2) +
- * NUM_PRIMARY_LENS (= 7), the length header contains
- * the match length minus MIN_MATCH_LEN, and there is no
- * length footer.
- *
- * Otherwise, the length header contains
- * NUM_PRIMARY_LENS, and the length footer contains
- * the match length minus NUM_PRIMARY_LENS minus
- * MIN_MATCH_LEN. */
- if (match_len_minus_2 < LZX_NUM_PRIMARY_LENS) {
- len_header = match_len_minus_2;
- /* No length footer-- mark it with a special
- * value. */
- len_footer = (unsigned)(-1);
- } else {
- len_header = LZX_NUM_PRIMARY_LENS;
- len_footer = match_len_minus_2 - LZX_NUM_PRIMARY_LENS;
- }
-
- /* Combine the position slot with the length header into a single symbol
- * that will be encoded with the main code.
- *
- * The actual main symbol is offset by LZX_NUM_CHARS because values
- * under LZX_NUM_CHARS are used to indicate a literal byte rather than a
- * match. */
- main_symbol = ((position_slot << 3) | len_header) + LZX_NUM_CHARS;
-
- /* Output main symbol. */
- bitstream_put_bits(out, codes->codewords.main[main_symbol],
- codes->lens.main[main_symbol]);
-
- /* If there is a length footer, output it using the
- * length Huffman code. */
- if (len_footer != (unsigned)(-1)) {
- bitstream_put_bits(out, codes->codewords.len[len_footer],
- codes->lens.len[len_footer]);
- }
-
- num_extra_bits = lzx_get_num_extra_bits(position_slot);
-
- /* For aligned offset blocks with at least 3 extra bits, output the
- * verbatim bits literally, then the aligned bits encoded using the
- * aligned offset code. Otherwise, only the verbatim bits need to be
- * output. */
- if ((block_type == LZX_BLOCKTYPE_ALIGNED) && (num_extra_bits >= 3)) {
-
- verbatim_bits = position_footer >> 3;
- bitstream_put_bits(out, verbatim_bits,
- num_extra_bits - 3);
-
- aligned_bits = (position_footer & 7);
- bitstream_put_bits(out,
- codes->codewords.aligned[aligned_bits],
- codes->lens.aligned[aligned_bits]);
- } else {
- /* verbatim bits is the same as the position
- * footer, in this case. */
- bitstream_put_bits(out, position_footer, num_extra_bits);
- }
-}
-