+ * Called when the compressor decides to use a literal. This tallies the
+ * Huffman symbol for the literal and increment the current literal run length.
+ */
+static inline void
+lzx_choose_literal(struct lzx_compressor *c, unsigned literal, u32 *litrunlen_p)
+{
+ lzx_observe_literal(&c->split_stats, literal);
+ c->freqs.main[literal]++;
+ ++*litrunlen_p;
+}
+
+/*
+ * Called when the compressor decides to use a match. This tallies the Huffman
+ * symbol(s) for a match, saves the match data and the length of the preceding
+ * literal run, and updates the recent offsets queue.
+ */
+static inline void
+lzx_choose_match(struct lzx_compressor *c, unsigned length, u32 offset_data,
+ u32 recent_offsets[LZX_NUM_RECENT_OFFSETS], bool is_16_bit,
+ u32 *litrunlen_p, struct lzx_sequence **next_seq_p)
+{
+ u32 litrunlen = *litrunlen_p;
+ struct lzx_sequence *next_seq = *next_seq_p;
+ unsigned offset_slot;
+ unsigned v;
+
+ lzx_observe_match(&c->split_stats, length);
+
+ v = length - LZX_MIN_MATCH_LEN;
+
+ /* Save the literal run length and adjusted length. */
+ next_seq->litrunlen = litrunlen;
+ next_seq->adjusted_length = v;
+
+ /* Compute the length header, then tally the length symbol if needed. */
+ if (v >= LZX_NUM_PRIMARY_LENS) {
+ c->freqs.len[v - LZX_NUM_PRIMARY_LENS]++;
+ v = LZX_NUM_PRIMARY_LENS;
+ }
+
+ /* Compute the offset slot. */
+ offset_slot = lzx_get_offset_slot(c, offset_data, is_16_bit);
+
+ /* Compute the match header. */
+ v += offset_slot * LZX_NUM_LEN_HEADERS;
+
+ /* Save the adjusted offset and match header. */
+ next_seq->adjusted_offset_and_match_hdr = (offset_data << 9) | v;
+
+ /* Tally the main symbol. */
+ c->freqs.main[LZX_NUM_CHARS + v]++;
+
+ /* Update the recent offsets queue. */
+ if (offset_data < LZX_NUM_RECENT_OFFSETS) {
+ /* Repeat offset match. */
+ swap(recent_offsets[0], recent_offsets[offset_data]);
+ } else {
+ /* Explicit offset match. */
+
+ /* Tally the aligned offset symbol if needed. */
+ if (offset_data >= 16)
+ c->freqs.aligned[offset_data & LZX_ALIGNED_OFFSET_BITMASK]++;
+
+ recent_offsets[2] = recent_offsets[1];
+ recent_offsets[1] = recent_offsets[0];
+ recent_offsets[0] = offset_data - LZX_OFFSET_ADJUSTMENT;
+ }
+
+ /* Reset the literal run length and advance to the next sequence. */
+ *next_seq_p = next_seq + 1;
+ *litrunlen_p = 0;
+}
+
+/*
+ * Called when the compressor ends a block. This finshes the last lzx_sequence,
+ * which is just a literal run which no following match. This literal run might
+ * be empty.
+ */
+static inline void
+lzx_finish_sequence(struct lzx_sequence *last_seq, u32 litrunlen)
+{
+ last_seq->litrunlen = litrunlen;
+
+ /* Special value to mark last sequence */
+ last_seq->adjusted_offset_and_match_hdr = 0x80000000;
+}
+
+/*
+ * Find the longest repeat offset match with the current position. If a match
+ * is found, return its length and set *best_rep_idx_ret to the index of its
+ * offset in @recent_offsets. Otherwise, return 0.