///|
/// A decoded Brotli command. Fields are mutable so the meta-block loop can
/// reuse a single instance across every command (filling it in place via
/// `read_into`) instead of heap-allocating one per command — the decode loop
/// runs this once per match, so eliminating the per-command allocation removes
/// a `malloc`/GC cost from the hot path.
priv struct BrotliCommand {
mut insert_length : Int
mut copy_length : Int
mut distance_code : Int
mut distance_context : Int
}
///|
/// Decode one command from `command_tree` into `self`, overwriting all four
/// fields. The caller reuses the same `BrotliCommand` every iteration, so this
/// performs no allocation.
fn BrotliCommand::read_into(
self : BrotliCommand,
reader : BrotliBitReader,
command_tree : FixedArray[Int],
) -> Unit raise @common.FbrError {
let symbol = brotli_read_symbol(
reader, command_tree, @common.brotli_huffman_table_bits,
)
let info = @common.brotli_command_info_table[symbol]
let insert_extra = if info.insert_len_extra_bits == 0 {
0
} else {
reader.take_bits(info.insert_len_extra_bits).reinterpret_as_int()
}
let copy_extra = if info.copy_len_extra_bits == 0 {
0
} else {
reader.take_bits(info.copy_len_extra_bits).reinterpret_as_int()
}
self.insert_length = info.insert_len_offset + insert_extra
self.copy_length = info.copy_len_offset + copy_extra
self.distance_code = info.distance_code
self.distance_context = info.distance_context
}
///|
fn brotli_decode_compressed_metablock_body(
reader : BrotliBitReader,
header : BrotliCompressedMetablockHeader,
output : BrotliOutputBuilder,
length : Int,
state : BrotliDecoderState,
) -> Unit raise @common.FbrError {
let literal_blocks = BrotliBlockTracker::new_with_length(
header.literal_block.num_types,
header.literal_block.first_length,
)
let command_blocks = BrotliBlockTracker::new_with_length(
header.command_block.num_types,
header.command_block.first_length,
)
let distance_blocks = BrotliBlockTracker::new_with_length(
header.distance_block.num_types,
header.distance_block.first_length,
)
// When the literal context map resolves to a single Huffman tree, every
// literal decodes from that one tree regardless of context. Detect this once
// per meta-block so the inner loop can skip the per-literal context-id and
// context-map work entirely (the dominant cost for low-quality streams, which
// are literal-heavy and almost always single-tree). `tree(0)` is always valid
// because the tree group is built with at least one tree.
let single_literal_tree = header.literal_context_map.num_trees == 1
let literal_tree0 = header.literal_trees.tree(0)
// When the literal side also has a single block type there are no literal
// block-switch commands in the stream, so the inner loop can drop the
// per-byte `ensure_ready` call and `remaining` bookkeeping entirely. This is
// the dominant shape for literal-heavy low-quality streams.
let single_literal_block = single_literal_tree &&
header.literal_block.num_types == 1
// Reuse one command record for the whole meta-block; `read_into` overwrites
// every field each iteration, so the loop performs no per-command allocation.
let command = BrotliCommand::{
insert_length: 0,
copy_length: 0,
distance_code: 0,
distance_context: 0,
}
let mut remaining = length
while remaining > 0 {
command_blocks.ensure_ready(reader, header.command_block)
command.read_into(
reader,
header.command_trees.tree(command_blocks.current_type),
)
command_blocks.remaining -= 1
if command.insert_length > remaining {
raise @common.fbr_err(
BrotliInvalidMetablock,
msg="Brotli insert length exceeds meta-block",
)
}
output.ensure(command.insert_length)
if single_literal_tree {
// Fast path: the literal context map has a single tree, so every literal
// decodes from `literal_tree0` regardless of context. Skip the per-byte
// context-id, context-map lookup and tree indexing entirely, and write
// straight into the buffer through locals (`ensure` reserved the run).
let buf = output.buf
let mut pos = output.len
if single_literal_block {
// Tightest path: one tree and one block type, so there are no literal
// block-switch commands to consume — drop the per-byte `ensure_ready`
// call and `remaining` decrement.
for _ in 0.. 255 {
raise @common.fbr_err(
BrotliInvalidMetablock,
msg="Brotli literal out of byte range",
)
}
buf[pos] = literal.to_byte()
pos += 1
}
} else {
for _ in 0.. 255 {
raise @common.fbr_err(
BrotliInvalidMetablock,
msg="Brotli literal out of byte range",
)
}
buf[pos] = literal.to_byte()
pos += 1
literal_blocks.remaining -= 1
}
}
output.len = pos
} else {
// General path: multiple literal trees. Track the two context bytes in
// registers and index the context map directly. The explicit bounds
// checks in `brotli_context_map_tree_index` are dead here because header
// parsing guarantees `current_type < num_types`, the context fits in
// `literal_context_bits`, and every map value was validated `< num_trees`;
// `tree()` still bounds-checks the resulting index.
let buf = output.buf
let mut pos = output.len
let lit_map = header.literal_context_map.map
let mut prev1 = if pos > 0 { buf[pos - 1].to_int() } else { 0 }
let mut prev2 = if pos > 1 { buf[pos - 2].to_int() } else { 0 }
for _ in 0.. 255 {
raise @common.fbr_err(
BrotliInvalidMetablock,
msg="Brotli literal out of byte range",
)
}
buf[pos] = literal.to_byte()
pos += 1
prev2 = prev1
prev1 = literal
literal_blocks.remaining -= 1
}
output.len = pos
}
remaining -= command.insert_length
if remaining == 0 {
return
}
let distance = if command.distance_code >= 0 {
brotli_take_short_code_validated(
state.distance_ring,
command.distance_code,
)
} else {
distance_blocks.ensure_ready(reader, header.distance_block)
let distance_tree_index = brotli_context_map_tree_index(
header.distance_context_map,
distance_blocks.current_type,
@common.brotli_distance_context_bits,
command.distance_context,
)
let distance_tree = header.distance_trees.tree(distance_tree_index)
distance_blocks.remaining -= 1
brotli_read_distance(
reader,
distance_tree,
state.distance_ring,
header.distance_postfix_bits,
header.num_direct_distance_codes,
)
}
let output_before_copy = output.len
let max_distance = state.max_distance(output.len)
if distance <= max_distance {
output.copy_from_distance(distance, command.copy_length)
state.distance_ring.record(distance)
} else {
state.distance_ring.compensate_dictionary_copy()
output.copy_from_dictionary_after_max_distance(
distance,
command.copy_length,
max_distance,
)
}
let copied = output.len - output_before_copy
if copied > remaining {
raise @common.fbr_err(
BrotliInvalidMetablock,
msg="Brotli copy length exceeds meta-block",
)
}
remaining -= copied
}
}