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}