vios_app 0.1.1

Small JSON vaults: Argon2id + AES-GCM, with optional AAD binding.
Documentation
// src/bin/whisper_vision.rs
// build: cargo run -p vios_core --bin whisper_vision --features whisper_vision

#[cfg(feature = "whisper_vision")]
fn main() -> opencv::Result<()> {
    use opencv::{
        core::{self, Mat, MatTraitConst, MatTraitConstManual, Scalar},
        highgui,
        imgproc::{self, COLOR_BGRA2BGR, COLOR_GRAY2BGR, LINE_8},
        prelude::*,
        videoio,
    };

    println!("[vision] starting…");

    // Prefer AVFoundation on mac; fall back to CAP_ANY
    let backend = videoio::CAP_AVFOUNDATION;
    let mut cam = videoio::VideoCapture::new(0, backend)?;
    if !cam.is_opened()? {
        eprintln!("[vision] camera not opened with AVFoundation, retrying with CAP_ANY…");
        cam = videoio::VideoCapture::new(0, videoio::CAP_ANY)?;
    }
    if !cam.is_opened()? {
        eprintln!("[vision] unable to open default camera (index 0).");
        return Ok(());
    }

    // Ask backend to convert to RGB if it supports it (harmless if ignored)
    let _ = cam.set(videoio::CAP_PROP_CONVERT_RGB, 1.0);

    // Optional: set a sane size
    let _ = cam.set(videoio::CAP_PROP_FRAME_WIDTH, 1280.0);
    let _ = cam.set(videoio::CAP_PROP_FRAME_HEIGHT, 720.0);

    highgui::named_window("Whisper Vision", highgui::WINDOW_AUTOSIZE)?;
    println!("[vision] camera opened. Press ESC to exit.");

    loop {
        let mut frame = Mat::default();
        cam.read(&mut frame)?;
        if frame.empty() {
            // Some backends need a couple reads to warm up
            continue;
        }

        // Ensure we display in COLOR:
        // - If 4-channel (BGRA), strip alpha to BGR
        // - If 1-channel (GRAY), up-convert so imshow uses color windowing
        let channels = frame.channels()?;
        let mut display = Mat::default();

        // OpenCV 0.95.1’s cvtColor takes an AlgorithmHint as the 5th arg.
        // Create a zeroed hint (equivalent to default).
        let hint: core::AlgorithmHint = unsafe { std::mem::zeroed() };

        match channels {
            4 => {
                imgproc::cvt_color(&frame, &mut display, COLOR_BGRA2BGR, 0, hint)?;
            }
            1 => {
                imgproc::cvt_color(&frame, &mut display, COLOR_GRAY2BGR, 0, hint)?;
            }
            _ => {
                display = frame; // already 3-channel BGR
            }
        }

        // Draw a tiny green dot to prove color is active
        imgproc::circle(
            &mut display,
            core::Point::new(12, 12),
            6,
            Scalar::new(0.0, 255.0, 0.0, 0.0),
            -1,
            LINE_8,
            0,
        )?;

        highgui::imshow("Whisper Vision", &display)?;
        let key = highgui::wait_key(1)?;
        if key == 27 /* ESC */ || key == b'q' as i32 {
            println!("[vision] exit requested.");
            break;
        }
    }

    Ok(())
}

#[cfg(not(feature = "whisper_vision"))]
fn main() {
    println!("whisper_vision feature disabled");
}