num2exr 0.1.1

Creates an exr image from numbers
Documentation
use std::io::{Seek, Write};
use std::path::Path;

use exr::error::Error;
use exr::prelude::{f16, Image, SpecificChannels, WritableImage};

use crate::source::pos2val1d;

pub fn sz2height(sz: usize, width: usize) -> usize {
    let d: usize = sz / width;
    let mul: usize = d * width;
    let dlt: usize = sz - mul;
    let add: usize = match 0 < dlt {
        true => 1,
        false => 0,
    };
    add + d
}

macro_rules! slice2wtr {
    ($fname: ident, $typ: ty) => {
        pub fn $fname<W>(
            s: &[$typ],
            width: usize,
            wtr: W,
            chname: &str,
            alt: $typ,
        ) -> Result<(), Error>
        where
            W: Write + Seek,
        {
            let h: usize = sz2height(s.len(), width);
            let pixels = SpecificChannels::build()
                .with_channel(chname)
                .with_pixel_fn(|pos| {
                    let f: $typ = pos2val1d(&|ix: usize| s.get(ix).copied(), width, alt, pos);
                    (f,)
                });
            let img = Image::from_channels((width, h), pixels);
            img.write().to_buffered(wtr)
        }
    };
}

slice2wtr!(slice2wtr32f, f32);
slice2wtr!(slice2wtr16f, f16);
slice2wtr!(slice2wtr32u, u32);

macro_rules! slice2path {
    ($fname: ident, $typ: ty) => {
        pub fn $fname<P>(
            s: &[$typ],
            width: usize,
            filepath: P,
            chname: &str,
            alt: $typ,
        ) -> Result<(), Error>
        where
            P: AsRef<Path>,
        {
            let h: usize = sz2height(s.len(), width);
            let pixels = SpecificChannels::build()
                .with_channel(chname)
                .with_pixel_fn(|pos| {
                    let f: $typ = pos2val1d(&|ix: usize| s.get(ix).copied(), width, alt, pos);
                    (f,)
                });
            let img = Image::from_channels((width, h), pixels);
            img.write().to_file(filepath)
        }
    };
}

slice2path!(slice2path32f, f32);
slice2path!(slice2path16f, f16);
slice2path!(slice2path32u, u32);

#[cfg(test)]
mod test_img {

    mod sz2height {

        #[test]
        fn empty1() {
            assert_eq!(crate::img::sz2height(0, 1), 0);
        }

        #[test]
        fn empty2() {
            assert_eq!(crate::img::sz2height(0, 2), 0);
        }

        #[test]
        fn empty3() {
            assert_eq!(crate::img::sz2height(0, 3), 0);
        }

        #[test]
        fn single1() {
            assert_eq!(crate::img::sz2height(1, 1), 1);
        }

        #[test]
        fn single2() {
            assert_eq!(crate::img::sz2height(1, 2), 1);
        }

        #[test]
        fn single3() {
            assert_eq!(crate::img::sz2height(1, 3), 1);
        }

        #[test]
        fn double1() {
            assert_eq!(crate::img::sz2height(2, 1), 2);
        }

        #[test]
        fn double2() {
            assert_eq!(crate::img::sz2height(2, 2), 1);
        }

        #[test]
        fn double3() {
            assert_eq!(crate::img::sz2height(2, 3), 1);
        }

        #[test]
        fn triple1() {
            assert_eq!(crate::img::sz2height(3, 1), 3);
        }

        #[test]
        fn triple2() {
            assert_eq!(crate::img::sz2height(3, 2), 2);
        }

        #[test]
        fn triple3() {
            assert_eq!(crate::img::sz2height(3, 3), 1);
        }

        #[test]
        fn iv1() {
            assert_eq!(crate::img::sz2height(4, 1), 4);
        }

        #[test]
        fn iv2() {
            assert_eq!(crate::img::sz2height(4, 2), 2);
        }

        #[test]
        fn iv3() {
            assert_eq!(crate::img::sz2height(4, 3), 2);
        }

        #[test]
        fn iv4() {
            assert_eq!(crate::img::sz2height(4, 4), 1);
        }

        #[test]
        fn sky25() {
            assert_eq!(crate::img::sz2height(634, 25), 26);
        }

        #[test]
        fn sky42() {
            assert_eq!(crate::img::sz2height(634, 42), 16);
        }

        #[test]
        fn run205() {
            assert_eq!(crate::img::sz2height(42195, 205), 206);
        }

        #[test]
        fn fuji599() {
            assert_eq!(crate::img::sz2height(3776, 599), 7);
        }

        #[test]
        fn atm333() {
            assert_eq!(crate::img::sz2height(101325, 333), 305);
        }

        #[test]
        fn c16383() {
            assert_eq!(crate::img::sz2height(299792458, 16383), 18299);
        }
    }
}