chuda 0.1.1

CUDA-accelerated high quality truecolour ANSI image renderer
use crate::symbols::SYMBOLS;
use anyhow::{Result, bail};

#[repr(C)]
#[derive(Clone, Copy, Default)]
pub struct Choice {
    pub codepoint: u32,
    pub fg: [u8; 3],
    pub bg: [u8; 3],
    pub transparent_bg: u8,
}

unsafe extern "C" {
    fn cb_render_cuda(
        pixels: *const u8,
        cells: u32,
        masks: *const u64,
        codes: *const u32,
        symbols: u32,
        output: *mut Choice,
        transparent_threshold: f32,
        error: *mut u8,
        capacity: usize,
    ) -> i32;
}
pub fn render(pixels: &[u8], transparent_threshold: f32) -> Result<Vec<Choice>> {
    let cells = pixels.len() / 256;
    let masks: Vec<_> = SYMBOLS.iter().map(|s| s.bitmap).collect();
    let codes: Vec<_> = SYMBOLS.iter().map(|s| s.ch as u32).collect();
    let mut output = vec![Choice::default(); cells];
    let mut error = [0u8; 512];
    let status = unsafe {
        cb_render_cuda(
            pixels.as_ptr(),
            cells as u32,
            masks.as_ptr(),
            codes.as_ptr(),
            masks.len() as u32,
            output.as_mut_ptr(),
            transparent_threshold,
            error.as_mut_ptr(),
            error.len(),
        )
    };
    if status != 0 {
        let end = error.iter().position(|b| *b == 0).unwrap_or(error.len());
        bail!(
            "CUDA renderer failed: {}",
            String::from_utf8_lossy(&error[..end])
        );
    }
    Ok(output)
}