wsi-rs 0.4.0

wsi-rs whole-slide image reader
Documentation
use super::*;

pub(super) struct VmsSlide {
    pub(super) dataset: Dataset,
    pub(super) levels: Vec<VmsLevel>,
    pub(super) associated_paths: HashMap<String, PathBuf>,
    pub(super) associated_cache: Mutex<LruCache<String, Arc<CpuTile>>>,
}

pub(super) struct VmsLevel {
    pub(super) scale_denom: u32,
    pub(super) jpegs: Vec<Arc<VmsJpeg>>,
    pub(super) jpegs_across: u32,
    pub(super) base_tiles_across: u32,
    pub(super) base_tiles_down: u32,
}

pub(super) struct VmsJpeg {
    pub(super) path: PathBuf,
    pub(super) file: Mutex<File>,
    pub(super) header: Vec<u8>,
    pub(super) sof_dimensions_offset: usize,
    pub(super) file_len: u64,
    pub(super) width: u32,
    pub(super) height: u32,
    pub(super) tile_width: u32,
    pub(super) tile_height: u32,
    pub(super) tiles_across: u32,
    pub(super) tiles_down: u32,
    pub(super) mcu_starts: Mutex<Vec<Option<u64>>>,
    pub(super) unreliable_mcu_starts: Vec<Option<u64>>,
    pub(super) decoded_tile_cache: Mutex<LruCache<(usize, u32), Arc<CpuTile>>>,
    pub(super) comment: Option<String>,
}

impl VmsLevel {
    pub(super) fn new(
        jpegs: Vec<Arc<VmsJpeg>>,
        jpegs_across: u32,
        _jpegs_down: u32,
        scale_denom: u32,
    ) -> Result<Self, WsiError> {
        let first = jpegs
            .first()
            .ok_or_else(|| WsiError::InvalidSlide {
                path: PathBuf::new(),
                message: "VMS level has no JPEG shards".into(),
            })?
            .clone();
        Ok(Self {
            scale_denom,
            jpegs,
            jpegs_across,
            base_tiles_across: first.tiles_across,
            base_tiles_down: first.tiles_down,
        })
    }
}

pub(super) fn invalid_slide(path: &Path, message: impl Into<String>) -> WsiError {
    WsiError::InvalidSlide {
        path: path.to_path_buf(),
        message: message.into(),
    }
}

pub(super) fn dataset_id_from_quickhash(
    path: &Path,
    quickhash: &str,
) -> Result<DatasetId, WsiError> {
    if quickhash.len() < 32 {
        return Err(invalid_slide(path, "quickhash too short"));
    }
    let value = u128::from_str_radix(&quickhash[..32], 16)
        .map_err(|_| invalid_slide(path, "quickhash is not valid hex"))?;
    Ok(DatasetId::new(value))
}