Skip to main content

ithmb_core/enc/
cl.rs

1// SPDX-License-Identifier: MIT
2// Encoder: CL — per-pixel nibble chroma, 2 bytes per pixel
3
4use crate::enc::helpers::{bt601_cb, bt601_cr, bt601_y};
5use crate::pixel_utils::clamp_u8;
6
7/// Encode BGRA pixels to CL per-pixel nibble chroma format.
8///
9/// Output layout (2 Bpp):
10///   Y plane: `w × h` bytes (full 8-bit luma)
11///   CbCr plane: `w × h` bytes (Cr in high nibble, Cb in low nibble)
12#[must_use]
13pub fn encode_cl(bgra: &[u8], w: i32, h: i32) -> Vec<u8> {
14    let wu = w as usize;
15    let hu = h as usize;
16    let n = wu * hu;
17    let mut out = vec![0u8; n * 2];
18
19    for i in 0..n {
20        let px = i * 4;
21        let r = i32::from(bgra[px + 2]);
22        let g = i32::from(bgra[px + 1]);
23        let b = i32::from(bgra[px]);
24
25        // Y
26        out[i] = clamp_u8(bt601_y(r, g, b));
27
28        // CbCr byte: high nibble = Cr, low nibble = Cb
29        let cb_nibble = (clamp_u8(bt601_cb(r, g, b)) >> 4) & 0x0F;
30        let cr_nibble = (clamp_u8(bt601_cr(r, g, b)) >> 4) & 0x0F;
31        out[n + i] = (cr_nibble << 4) | cb_nibble;
32    }
33
34    out
35}