fits_io/fits_slice.rs
1use crate::fits::Fits;
2use crate::hdu::ExtensionHDU;
3use crate::header::{BayerPattern, Bitpix};
4use crate::image::{Image, ImageData};
5use crate::slice_ascii_table_hdu::SliceAsciiTableHDU;
6use crate::slice_bin_table_hdu::SliceBinTableHDU;
7use crate::slice_image_hdu::SliceImageHDU;
8use alloc::boxed::Box;
9use alloc::vec;
10use alloc::vec::Vec;
11use std::error::Error;
12
13/// A Fits file created from a buffer
14#[derive(Debug, Clone)]
15pub struct FitsSlice {
16 primary_hdu: SliceImageHDU,
17 extension_hdus: Vec<ExtensionHDU<Self>>,
18}
19
20impl FitsSlice {
21 /// Creates a new empty fits file
22 pub fn from_slice(_data: &[u8]) -> Self {
23 Self {
24 primary_hdu: SliceImageHDU {},
25 extension_hdus: vec![],
26 }
27 }
28
29 // pub(crate) fn parse_extension_hdus(data: &[u8]) -> Result<Vec<ExtensionHDU>, Box<dyn Error + Send + Sync>> {
30 // let mut offset = 0;
31 // let mut extension_hdus = vec![];
32 // while offset < data.len() {
33 // let header = Header::from_u8(data)?;
34 // let bytes_len = header.data_block_len();
35 // offset += header.bytes_len();
36 // let extension_type = header.extension().ok_or_else(|| "Missing extension type".to_string())?;
37 //
38 // match extension_type {
39 // ExtensionType::Image => {
40 // if bytes_len == 0 {
41 // extension_hdus.push(ExtensionHDU::Image(ImageHDU::new(header, vec![])));
42 // } else {
43 // offset += bytes_len;
44 // let bitpix = header.bitpix();
45 // let bzero = header.bzero().unwrap();
46 // let bscale = header.bscale().unwrap();
47 //
48 // let width = header.naxis_n(1).unwrap();
49 // let height = header.naxis_n(2).unwrap();
50 //
51 // let bayer_pattern = header.bayer_pattern();
52 //
53 // let image = Self::read_image(&data, header.bytes_len(), bitpix, bscale, bzero, bayer_pattern, width as usize, height as usize)?;
54 //
55 // extension_hdus.push(ExtensionHDU::Image(ImageHDU::new(header, vec![image])));
56 // }
57 // }
58 // ExtensionType::BinTable => {
59 // extension_hdus.push(ExtensionHDU::BinTable(BinTableHDU::from_u8(header, data[offset..(bytes_len + offset)].to_vec())?));
60 // offset += bytes_len;
61 // }
62 // ExtensionType::AsciiTable => {}
63 // }
64 // }
65 //
66 // Ok(extension_hdus)
67 // }
68
69 fn read_image(
70 data: &[u8],
71 offset: usize,
72 bitpix: Bitpix,
73 bscale: f64,
74 bzero: f64,
75 bayer_pattern: Option<BayerPattern>,
76 width: usize,
77 height: usize,
78 ) -> Result<Image, Box<dyn Error + Send + Sync>> {
79 let bytes = bitpix.byte_size() * width * height;
80
81 let data = &data[offset..(bytes + offset)];
82
83 match bitpix {
84 Bitpix::F64 => {
85 let data = data
86 .as_chunks::<8>()
87 .0
88 .iter()
89 .map(|i| f64::from_be_bytes(*i))
90 .collect();
91 Ok(Image::F64(ImageData::from_data(
92 width,
93 height,
94 bzero,
95 bscale,
96 bayer_pattern,
97 data,
98 )?))
99 }
100 Bitpix::F32 => {
101 let data = data
102 .as_chunks::<4>()
103 .0
104 .iter()
105 .map(|i| f32::from_be_bytes(*i))
106 .collect();
107 Ok(Image::F32(ImageData::from_data(
108 width,
109 height,
110 bzero,
111 bscale,
112 bayer_pattern,
113 data,
114 )?))
115 }
116 Bitpix::U8 => {
117 let data = data.to_vec();
118 Ok(Image::U8(ImageData::from_data(
119 width,
120 height,
121 bzero,
122 bscale,
123 bayer_pattern,
124 data,
125 )?))
126 }
127 Bitpix::I16 => {
128 let data = data
129 .as_chunks::<2>()
130 .0
131 .iter()
132 .map(|i| i16::from_be_bytes(*i))
133 .collect();
134 Ok(Image::I16(ImageData::from_data(
135 width,
136 height,
137 bzero,
138 bscale,
139 bayer_pattern,
140 data,
141 )?))
142 }
143 Bitpix::I32 => {
144 let data = data
145 .as_chunks::<4>()
146 .0
147 .iter()
148 .map(|i| i32::from_be_bytes(*i))
149 .collect();
150 Ok(Image::I32(ImageData::from_data(
151 width,
152 height,
153 bzero,
154 bscale,
155 bayer_pattern,
156 data,
157 )?))
158 }
159 }
160 }
161}
162
163impl Fits for FitsSlice {
164 type ImageHDU = SliceImageHDU;
165 type BinTableHDU = SliceBinTableHDU;
166 type AsciiTableHDU = SliceAsciiTableHDU;
167
168 fn primary_hdu(&self) -> &Self::ImageHDU {
169 &self.primary_hdu
170 }
171
172 fn primary_hdu_mut(&mut self) -> &mut Self::ImageHDU {
173 &mut self.primary_hdu
174 }
175
176 fn extension_count(&mut self) -> usize {
177 self.extension_hdus.len()
178 }
179
180 fn extension_hdu(&self, index: usize) -> Option<&ExtensionHDU<Self>> {
181 self.extension_hdus.get(index)
182 }
183
184 fn extension_hdu_mut(&mut self, index: usize) -> Option<&mut ExtensionHDU<Self>> {
185 self.extension_hdus.get_mut(index)
186 }
187
188 fn extension_hdus(&self) -> impl Iterator<Item = &ExtensionHDU<Self>> {
189 self.extension_hdus.iter()
190 }
191
192 fn extension_hdus_mut(&mut self) -> impl Iterator<Item = &mut ExtensionHDU<Self>> {
193 self.extension_hdus.iter_mut()
194 }
195
196 fn to_vec(&self) -> Vec<u8> {
197 todo!()
198 }
199}