doe 1.1.90

doe is a powerful Rust crate designed to enhance development workflow by providing an extensive collection of useful macros and utility functions. It not only simplifies common tasks but also offers convenient features for clipboard management,robust cryptographic functions,keyboard input, and mouse interaction.
Documentation
//! Pixel-format helpers shared by the platform backends.
//!
//! Native screen-capture APIs tend to produce BGRA buffers (Windows GDI,
//! macOS CoreGraphics) with possible per-row padding (macOS). These helpers
//! normalise that into the RGBA layout expected by the `image` crate.

use image::RgbaImage;

/// Swaps the R and B channels of a packed BGRA buffer, producing an
/// `RgbaImage` of the given dimensions.
pub fn bgra_to_rgba(width: u32, height: u32, mut buf: Vec<u8>) -> Result<RgbaImage, String> {
    let len = buf.len();
    for px in buf.chunks_exact_mut(4) {
        // BGRA -> RGBA
        px.swap(0, 2);
    }
    RgbaImage::from_vec(width, height, buf)
        .ok_or_else(|| format!("BGRA buffer length {len} does not match {width}x{height}x4", len = len))
}

/// Strips trailing padding bytes that some platforms (notably macOS) add to
/// each row so the byte stride exceeds `width * 4`.
///
/// Returns the input unchanged when `bytes_per_row` is zero, less than the
/// needed width, or already matches — preventing panics on degenerate data.
pub fn remove_row_padding(
    width: usize,
    height: usize,
    bytes_per_row: usize,
    buf: Vec<u8>,
) -> Vec<u8> {
    let needed = width * 4;
    if bytes_per_row == 0 || bytes_per_row < needed || bytes_per_row == needed {
        return buf;
    }
    let mut out = Vec::with_capacity(needed * height);
    for row in buf.chunks_exact(bytes_per_row) {
        out.extend_from_slice(&row[..needed.min(row.len())]);
    }
    out
}

/// Converts a raw byte vector (already RGBA) into an `RgbaImage`.
pub fn vec_to_rgba(width: u32, height: u32, buf: Vec<u8>) -> Result<RgbaImage, String> {
    let len = buf.len();
    RgbaImage::from_vec(width, height, buf)
        .ok_or_else(|| format!("Buffer length {len} does not match {width}x{height}x4"))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn bgra_swap() {
        // BGRA: B=1 G=2 R=3 A=4 ,  B=255 G=254 R=253 A=252
        let img = bgra_to_rgba(2, 1, vec![1, 2, 3, 4, 255, 254, 253, 252]).unwrap();
        assert_eq!(
            img.into_raw(),
            vec![3, 2, 1, 4, 253, 254, 255, 252]
        );
    }

    #[test]
    fn padding_striped() {
        let cleaned = remove_row_padding(2, 2, 9, vec![
            1, 2, 3, 4, 5, 6, 7, 8, 9,
            11, 12, 13, 14, 15, 16, 17, 18, 19,
        ]);
        assert_eq!(cleaned, vec![1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18]);
    }

    #[test]
    fn padding_passthrough_when_none() {
        let data = vec![1u8, 2, 3, 4, 5, 6, 7, 8];
        let out = remove_row_padding(2, 1, 8, data.clone());
        assert_eq!(out, data);
    }
}