use std::{
fs::File,
io::{BufReader, Cursor, Read},
path::Path,
};
use dicom::object::{self as dicom_object, DefaultDicomObject};
use snafu::{ResultExt, Snafu};
#[derive(Debug, Snafu)]
#[snafu(visibility(pub))]
pub enum Error {
#[snafu(display("Could not read Dicom object: {}", source))]
Io { source: std::io::Error },
#[snafu(display("Could not parse Dicom object: {}", source))]
Dcm { source: dicom_object::ReadError },
}
pub fn read_dcm_file<P: AsRef<Path>>(path: P) -> Result<DefaultDicomObject, Error> {
let path = path.as_ref();
let input = BufReader::new(File::open(path).context(IoSnafu)?);
read_dcm_stream(input)
}
pub fn read_dcm_stream<F: Read>(mut input: F) -> Result<DefaultDicomObject, Error> {
let mut buf = Vec::with_capacity(132);
input
.by_ref()
.take(132)
.read_to_end(&mut buf)
.context(IoSnafu)?;
if buf.len() == 132 && &buf[128..132] == b"DICM" {
let reader = Cursor::new(&buf[128..]).chain(input);
dicom_object::OpenFileOptions::new()
.read_until(dicom::dictionary_std::tags::PIXEL_DATA)
.read_preamble(dicom_object::file::ReadPreamble::Never)
.from_reader(reader)
.context(DcmSnafu)
} else {
let reader = Cursor::new(buf).chain(input);
dicom_object::OpenFileOptions::new()
.read_until(dicom::dictionary_std::tags::PIXEL_DATA)
.read_preamble(dicom_object::file::ReadPreamble::Never)
.from_reader(reader)
.context(DcmSnafu)
}
}