use super::super::build::SubBandType;
use super::state::{BitPlaneDecodeContext, HAS_MAGNITUDE_REFINEMENT_MASK};
use j2k_codec_math::classic::{
SIGN_CONTEXT_LOOKUP, ZERO_CTX_HH_LOOKUP, ZERO_CTX_HL_LOOKUP, ZERO_CTX_LL_LH_LOOKUP,
};
#[expect(
clippy::inline_always,
reason = "Tier-1 context lookup is a measured coefficient-loop hot path"
)]
#[inline(always)]
pub(super) fn context_label_sign_coding_index(
idx: usize,
y: usize,
ctx: &BitPlaneDecodeContext,
) -> (u8, u8) {
let significances = ctx.neighborhood_significance_states_index(idx, y) & 0b0101_0101;
let padded_width = ctx.padded_width as usize;
let top_sign = ctx.sign_index(idx - padded_width);
let left_sign = ctx.sign_index(idx - 1);
let right_sign = ctx.sign_index(idx + 1);
let bottom_sign = if ctx.style.vertically_causal_context && ctx.neighbor_in_next_stripe_y(y) {
0
} else {
ctx.sign_index(idx + padded_width)
};
let signs = (top_sign << 6) | (left_sign << 4) | (right_sign << 2) | bottom_sign;
let negative_significances = significances & signs;
let positive_significances = significances & !signs;
let merged_significances = (negative_significances << 1) | positive_significances;
SIGN_CONTEXT_LOOKUP[merged_significances as usize]
}
#[expect(
clippy::inline_always,
reason = "Tier-1 context lookup is a measured coefficient-loop hot path"
)]
#[inline(always)]
pub(super) fn context_label_sign_coding_index_with_neighbors<const NORMAL_NEIGHBORS: bool>(
idx: usize,
y: usize,
ctx: &BitPlaneDecodeContext,
) -> (u8, u8) {
if NORMAL_NEIGHBORS {
context_label_sign_coding_index_normal(idx, ctx)
} else {
context_label_sign_coding_index(idx, y, ctx)
}
}
#[expect(
clippy::inline_always,
reason = "Tier-1 context lookup is a measured coefficient-loop hot path"
)]
#[inline(always)]
pub(super) fn context_label_sign_coding_index_normal(
idx: usize,
ctx: &BitPlaneDecodeContext,
) -> (u8, u8) {
let significances = ctx.normal_neighborhood_significance_states_index(idx) & 0b0101_0101;
let padded_width = ctx.padded_width as usize;
let top_sign = ctx.sign_index(idx - padded_width);
let left_sign = ctx.sign_index(idx - 1);
let right_sign = ctx.sign_index(idx + 1);
let bottom_sign = ctx.sign_index(idx + padded_width);
let signs = (top_sign << 6) | (left_sign << 4) | (right_sign << 2) | bottom_sign;
let negative_significances = significances & signs;
let positive_significances = significances & !signs;
let merged_significances = (negative_significances << 1) | positive_significances;
SIGN_CONTEXT_LOOKUP[merged_significances as usize]
}
#[expect(
clippy::inline_always,
reason = "Tier-1 context lookup is a measured coefficient-loop hot path"
)]
#[inline(always)]
pub(super) fn context_label_zero_coding_from_neighbors(
neighbors: u8,
sub_band_type: SubBandType,
) -> u8 {
match sub_band_type {
SubBandType::LowLow | SubBandType::LowHigh => ZERO_CTX_LL_LH_LOOKUP[neighbors as usize],
SubBandType::HighLow => ZERO_CTX_HL_LOOKUP[neighbors as usize],
SubBandType::HighHigh => ZERO_CTX_HH_LOOKUP[neighbors as usize],
}
}
#[expect(
clippy::inline_always,
reason = "Tier-1 context lookup is a measured coefficient-loop hot path"
)]
#[inline(always)]
pub(super) fn context_label_magnitude_refinement_coding_from_state(state: u8, neighbors: u8) -> u8 {
context_label_magnitude_refinement_coding_from_state_lazy(state, || neighbors)
}
#[expect(
clippy::inline_always,
reason = "Tier-1 context lookup is a measured coefficient-loop hot path"
)]
#[inline(always)]
pub(super) fn context_label_magnitude_refinement_coding_from_state_lazy(
state: u8,
neighbors: impl FnOnce() -> u8,
) -> u8 {
if state & HAS_MAGNITUDE_REFINEMENT_MASK != 0 {
16
} else {
14 + neighbors().min(1)
}
}