Skip to main content

ithmb_core/
pixel_utils.rs

1//! Shared pixel-manipulation helpers for encoding and decoding.
2//!
3//! These functions are used across multiple decoders and encoders to avoid
4//! code duplication. They cover MSB replication, value clamping, and
5//! cancellation-check boilerplate.
6
7use crate::error::DecodeError;
8use std::sync::atomic::{AtomicBool, Ordering};
9
10/// Replicates a 5-bit value to 8 bits: `(v << 3) | (v >> 2)`.
11#[inline]
12#[must_use]
13#[allow(clippy::cast_possible_truncation)]
14pub(crate) fn msb_replicate_5(v: u32) -> u8 {
15    ((v << 3) | (v >> 2)) as u8
16}
17
18/// Replicates a 6-bit value to 8 bits: `(v << 2) | (v >> 4)`.
19#[inline]
20#[must_use]
21#[allow(clippy::cast_possible_truncation)]
22pub(crate) fn msb_replicate_6(v: u32) -> u8 {
23    ((v << 2) | (v >> 4)) as u8
24}
25
26/// Clamp an `i32` to the 0..255 u8 range.
27#[inline]
28#[must_use]
29#[allow(clippy::cast_sign_loss)]
30pub(crate) fn clamp_u8(v: i32) -> u8 {
31    v.clamp(0, 255) as u8
32}
33
34/// Check whether the operation has been canceled.
35///
36/// Returns `Err(DecodeError::Canceled)` if `canceled` is `true`, allowing the
37/// caller to short-circuit the decode loop.
38#[inline]
39pub(crate) fn check_canceled(canceled: &AtomicBool, name: &str) -> Result<(), DecodeError> {
40    if canceled.load(Ordering::Acquire) {
41        return Err(DecodeError::Canceled(name.into()));
42    }
43    Ok(())
44}