use std::path::{Path, PathBuf};
use crate::common::error::{BioFormatsError, Result};
use crate::common::metadata::ImageMetadata;
use crate::common::reader::FormatReader;
const OPUS_UNSUPPORTED: &str =
"Bruker OPUS spectral image decoding is not implemented; refusing guessed header metadata";
const ISS_UNSUPPORTED: &str =
"ISS Vista FLIM decoding is not implemented; refusing guessed header metadata";
pub struct BrukerOpusReader {
path: Option<PathBuf>,
meta: Option<ImageMetadata>,
}
impl BrukerOpusReader {
pub fn new() -> Self {
BrukerOpusReader {
path: None,
meta: None,
}
}
}
impl Default for BrukerOpusReader {
fn default() -> Self {
Self::new()
}
}
impl FormatReader for BrukerOpusReader {
fn is_this_type_by_name(&self, path: &Path) -> bool {
let ext = path
.extension()
.and_then(|e| e.to_str())
.map(|e| e.to_ascii_lowercase());
match ext.as_deref() {
Some("abs") | Some("dpt") | Some("spa") => true,
Some(e) => e.chars().all(|c| c.is_ascii_digit()),
None => false,
}
}
fn is_this_type_by_bytes(&self, header: &[u8]) -> bool {
header.len() >= 2 && header[0] == 0x0A && header[1] <= 0x02
}
fn set_id(&mut self, path: &Path) -> Result<()> {
self.meta = None;
self.path = Some(path.to_path_buf());
Err(BioFormatsError::UnsupportedFormat(
OPUS_UNSUPPORTED.to_string(),
))
}
fn close(&mut self) -> Result<()> {
self.path = None;
self.meta = None;
Ok(())
}
fn series_count(&self) -> usize {
1
}
fn set_series(&mut self, s: usize) -> Result<()> {
if s != 0 {
Err(BioFormatsError::SeriesOutOfRange(s))
} else {
Ok(())
}
}
fn series(&self) -> usize {
0
}
fn metadata(&self) -> &ImageMetadata {
self.meta.as_ref().expect("set_id not called")
}
fn open_bytes(&mut self, plane_index: u32) -> Result<Vec<u8>> {
let meta = self.meta.as_ref().ok_or(BioFormatsError::NotInitialized)?;
if plane_index >= meta.image_count {
return Err(BioFormatsError::PlaneOutOfRange(plane_index));
}
Err(BioFormatsError::UnsupportedFormat(
OPUS_UNSUPPORTED.to_string(),
))
}
fn open_bytes_region(&mut self, p: u32, x: u32, y: u32, w: u32, h: u32) -> Result<Vec<u8>> {
let full = self.open_bytes(p)?;
let meta = self.meta.as_ref().unwrap();
let row = meta.size_x as usize * 4;
let out_row = w as usize * 4;
let mut out = Vec::with_capacity(h as usize * out_row);
for r in 0..h as usize {
let src = &full[(y as usize + r) * row..];
out.extend_from_slice(&src[x as usize * 4..x as usize * 4 + out_row]);
}
Ok(out)
}
fn open_thumb_bytes(&mut self, p: u32) -> Result<Vec<u8>> {
let meta = self.meta.as_ref().ok_or(BioFormatsError::NotInitialized)?;
let (tw, th) = (meta.size_x.min(256), meta.size_y.min(256));
let (tx, ty) = ((meta.size_x - tw) / 2, (meta.size_y - th) / 2);
self.open_bytes_region(p, tx, ty, tw, th)
}
}
pub struct IssFlimReader {
path: Option<PathBuf>,
meta: Option<ImageMetadata>,
}
impl IssFlimReader {
pub fn new() -> Self {
IssFlimReader {
path: None,
meta: None,
}
}
}
impl Default for IssFlimReader {
fn default() -> Self {
Self::new()
}
}
impl FormatReader for IssFlimReader {
fn is_this_type_by_name(&self, path: &Path) -> bool {
path.extension()
.and_then(|e| e.to_str())
.map(|e| e.eq_ignore_ascii_case("iss"))
.unwrap_or(false)
}
fn is_this_type_by_bytes(&self, _: &[u8]) -> bool {
false
}
fn set_id(&mut self, path: &Path) -> Result<()> {
self.meta = None;
self.path = Some(path.to_path_buf());
Err(BioFormatsError::UnsupportedFormat(
ISS_UNSUPPORTED.to_string(),
))
}
fn close(&mut self) -> Result<()> {
self.path = None;
self.meta = None;
Ok(())
}
fn series_count(&self) -> usize {
1
}
fn set_series(&mut self, s: usize) -> Result<()> {
if s != 0 {
Err(BioFormatsError::SeriesOutOfRange(s))
} else {
Ok(())
}
}
fn series(&self) -> usize {
0
}
fn metadata(&self) -> &ImageMetadata {
self.meta.as_ref().expect("set_id not called")
}
fn open_bytes(&mut self, plane_index: u32) -> Result<Vec<u8>> {
let meta = self.meta.as_ref().ok_or(BioFormatsError::NotInitialized)?;
if plane_index >= meta.image_count {
return Err(BioFormatsError::PlaneOutOfRange(plane_index));
}
Err(BioFormatsError::UnsupportedFormat(
ISS_UNSUPPORTED.to_string(),
))
}
fn open_bytes_region(&mut self, p: u32, x: u32, y: u32, w: u32, h: u32) -> Result<Vec<u8>> {
let full = self.open_bytes(p)?;
let meta = self.meta.as_ref().unwrap();
let row = meta.size_x as usize * 4;
let out_row = w as usize * 4;
let mut out = Vec::with_capacity(h as usize * out_row);
for r in 0..h as usize {
let src = &full[(y as usize + r) * row..];
out.extend_from_slice(&src[x as usize * 4..x as usize * 4 + out_row]);
}
Ok(out)
}
fn open_thumb_bytes(&mut self, p: u32) -> Result<Vec<u8>> {
let meta = self.meta.as_ref().ok_or(BioFormatsError::NotInitialized)?;
let (tw, th) = (meta.size_x.min(256), meta.size_y.min(256));
let (tx, ty) = ((meta.size_x - tw) / 2, (meta.size_y - th) / 2);
self.open_bytes_region(p, tx, ty, tw, th)
}
}