use std::fs::File;
use std::io::{Result, Seek};
use crate::io::Header;
use crate::io::hdus::image::ImageData;
use crate::io::hdus::image::image::ImageParser;
use crate::io::header::card::Card;
const MANDATORY_KEYWORDS: [&str; 3] = [
"SIMPLE",
"BITPIX",
"NAXIS",
];
pub struct PrimaryHDU{
pub header: Header,
pub data: ImageData,
}
impl PrimaryHDU {
pub fn new(header: Header, data: ImageData) -> Self {
Self {
header,
data,
}
}
pub fn default() -> Self {
let mut header = Header::new();
header.add_card(&Card::new("SIMPLE".to_string(), "T".to_string(), Some("Primary HDU".to_string())));
header.add_card(&Card::new("BITPIX".to_string(), "8".to_string(), Some("Number of bits per data pixel".to_string())));
header.add_card(&Card::new("NAXIS".to_string(), "0".to_string(), Some("Number of data axes".to_string())));
Self {
header,
data: ImageData::new(),
}
}
pub fn read_from_file(f: &mut File) -> Result<Self> {
let mut header = Header::new();
header.read_from_file(f)?;
if !header.are_mandatory_keywords_first(&MANDATORY_KEYWORDS) {
panic!("Header corrupted");
}
if header["NAXIS"].value.as_int().unwrap_or(0) == 0 {
Ok(Self::new(header, ImageData::EMPTY))
}
else {
let data: ImageData = ImageParser::read_from_buffer(f, &mut header)?;
Ok(Self::new(header, data))
}
}
pub fn get_end_byte_position(f: &mut File) -> usize {
let first_pos = f.stream_position().unwrap();
let mut header = Header::new();
header.read_from_file(f).unwrap();
if header["NAXIS"].value.as_int().unwrap_or(0) == 0 {
return f.stream_position().unwrap() as usize;
}
let current = f.stream_position().unwrap();
let image_size = ImageParser::calculate_image_bytes(&header);
let mut end = current + image_size as u64;
if end % 2880 != 0{
end = end + 2880 - (end % 2880);
}
f.seek(std::io::SeekFrom::Start(first_pos)).unwrap();
end as usize
}
pub fn write_to_file(&mut self, mut f: &mut File) -> Result<()> {
self.header.fix_header_w_mandatory_order(&MANDATORY_KEYWORDS);
ImageParser::write_image_header(&mut self.header, &self.data);
self.header.write_to_buffer(&mut f)?;
if self.data.get_shape()[0] == 0 {
return Ok(());
}
ImageParser::ndarray_to_buffer(&self.data, f)?;
Ok(())
}
}