1use std::vec::IntoIter;
2
3use grib_template_helpers::TryFromSlice as _;
4
5use crate::{
6 context::{SectionBody, SubMessage},
7 decoder::{
8 bitmap::{BitmapDecodeIterator, dummy_bitmap_for_nonnullable_data},
9 complex::ComplexPackingDecoded,
10 simple::SimplePackingDecoder,
11 stream::NBitwiseIterator,
12 },
13 def::grib2::{DataRepresentationTemplate, Section5},
14 error::*,
15 reader::Grib2Read,
16};
17
18pub struct Grib2SubmessageDecoder {
88 num_points_total: usize,
89 sect5_param: Section5,
90 sect6_bytes: Vec<u8>,
91 sect7_bytes: Vec<u8>,
92}
93
94impl Grib2SubmessageDecoder {
95 pub fn new(
100 num_points_total: usize,
101 sect5_bytes: Vec<u8>,
102 sect6_bytes: Vec<u8>,
103 sect7_bytes: Vec<u8>,
104 ) -> Result<Self, GribError> {
105 let mut pos = 0;
106 let sect5_param = Section5::try_from_slice(§5_bytes, &mut pos)
107 .map_err(|e| GribError::DecodeError(DecodeError::from(e)))?;
108 let sect6_bytes = match sect6_bytes[5] {
109 0x00 => sect6_bytes,
110 0xff => {
111 let mut sect6_bytes = sect6_bytes;
112 sect6_bytes.append(&mut dummy_bitmap_for_nonnullable_data(num_points_total));
113 sect6_bytes
114 }
115 n => {
116 return Err(GribError::DecodeError(DecodeError::NotSupported(
117 "GRIB2 code table 6.0 (bit map indicator)",
118 n.into(),
119 )));
120 }
121 };
122
123 Ok(Self {
124 num_points_total,
125 sect5_param,
126 sect6_bytes,
127 sect7_bytes,
128 })
129 }
130
131 pub fn from<R: Grib2Read>(submessage: SubMessage<R>) -> Result<Self, GribError> {
133 let mut reader = submessage.9;
134 let sect5 = submessage.5.body;
135 let sect6 = submessage.6.body;
136 let sect7 = submessage.7.body;
137 let sect3_body = match submessage.3.body.body.as_ref() {
138 Some(SectionBody::Section3(b3)) => b3,
139 _ => return Err(GribError::InternalDataError),
140 };
141 let sect3_num_points = sect3_body.num_points() as usize;
142
143 Self::new(
144 sect3_num_points,
145 reader.read_sect_as_slice(sect5)?,
146 reader.read_sect_as_slice(sect6)?,
147 reader.read_sect_as_slice(sect7)?,
148 )
149 }
150
151 pub fn dispatch(
153 &self,
154 ) -> Result<Grib2DecodedValues<'_, impl Iterator<Item = f32> + '_>, GribError> {
155 let decoder = match &self.sect5_param.payload.template {
156 DataRepresentationTemplate::_5_0(template) => {
157 Grib2ValueIterator::SigSTNS(simple::Simple(self, template).iter()?)
158 }
159 DataRepresentationTemplate::_5_2(template) => {
160 Grib2ValueIterator::SigSC(complex::Complex(self, template).iter()?)
161 }
162 DataRepresentationTemplate::_5_3(template) => {
163 Grib2ValueIterator::SigSSCI(complex::ComplexSpatial(self, template).iter()?)
164 }
165 #[cfg(feature = "jpeg2000-unpack-with-openjpeg")]
166 DataRepresentationTemplate::_5_40(template) => {
167 Grib2ValueIterator::SigSIm(jpeg2000::Jpeg2000(self, template).iter()?)
168 }
169 #[cfg(feature = "png-unpack-with-png-crate")]
170 DataRepresentationTemplate::_5_41(template) => {
171 Grib2ValueIterator::SigSNV(png::Png(self, template).iter()?)
172 }
173 #[cfg(feature = "ccsds-unpack-with-libaec")]
174 DataRepresentationTemplate::_5_42(template) => {
175 Grib2ValueIterator::SigSNV(ccsds::Ccsds(self, template).iter()?)
176 }
177 DataRepresentationTemplate::_5_200(template) => {
178 Grib2ValueIterator::SigI(run_length::RunLength(self, template).iter()?)
179 }
180 #[allow(unreachable_patterns)]
181 _ => {
182 return Err(GribError::DecodeError(DecodeError::NotSupported(
183 "GRIB2 code table 5.0 (data representation template number)",
184 self.sect5_param.payload.template_num,
185 )));
186 }
187 };
188 let decoder = BitmapDecodeIterator::new(
189 self.sect6_bytes[6..].iter(),
190 decoder,
191 self.num_points_total,
192 )?;
193 Ok(Grib2DecodedValues(decoder))
194 }
195
196 pub(crate) fn num_encoded_points(&self) -> usize {
197 self.sect5_param.payload.num_encoded_points as usize
198 }
199
200 pub(crate) fn sect7_payload(&self) -> &[u8] {
201 &self.sect7_bytes[5..]
202 }
203
204 pub fn section5(&self) -> &Section5 {
245 &self.sect5_param
246 }
247}
248
249pub(crate) fn orig_field_type_is_supported(orig_field_type: u8) -> Result<(), DecodeError> {
250 if orig_field_type != 0 {
251 return Err(DecodeError::NotSupported(
252 "GRIB2 code table 5.1 (type of original field values)",
253 orig_field_type.into(),
254 ));
255 }
256 Ok(())
257}
258
259pub struct Grib2DecodedValues<'b, I>(BitmapDecodeIterator<std::slice::Iter<'b, u8>, I>);
260
261impl<I> Iterator for Grib2DecodedValues<'_, I>
262where
263 I: Iterator<Item = f32>,
264{
265 type Item = f32;
266
267 fn next(&mut self) -> Option<Self::Item> {
268 let Self(inner) = self;
269 inner.next()
270 }
271
272 fn size_hint(&self) -> (usize, Option<usize>) {
273 let Self(inner) = self;
274 inner.size_hint()
275 }
276}
277
278enum Grib2ValueIterator<'d> {
279 SigSTNS(SimplePackingDecoder<std::iter::Take<NBitwiseIterator<&'d [u8]>>>),
280 SigSC(SimplePackingDecoder<ComplexPackingDecoded<'d>>),
281 SigSSCI(
282 SimplePackingDecoder<
283 complex::SpatialDifferencingDecodeIterator<ComplexPackingDecoded<'d>, IntoIter<i32>>,
284 >,
285 ),
286 #[allow(dead_code)]
287 SigSI(SimplePackingDecoder<IntoIter<i32>>),
288 #[cfg(feature = "jpeg2000-unpack-with-openjpeg")]
289 SigSIm(SimplePackingDecoder<self::jpeg2000::ImageIntoIter>),
290 #[allow(dead_code)]
291 SigSNV(SimplePackingDecoder<NBitwiseIterator<Vec<u8>>>),
292 SigI(IntoIter<f32>),
293}
294
295impl<'d> Iterator for Grib2ValueIterator<'d> {
296 type Item = f32;
297
298 fn next(&mut self) -> Option<Self::Item> {
299 match self {
300 Self::SigSTNS(inner) => inner.next(),
301 Self::SigSC(inner) => inner.next(),
302 Self::SigSSCI(inner) => inner.next(),
303 Self::SigSI(inner) => inner.next(),
304 #[cfg(feature = "jpeg2000-unpack-with-openjpeg")]
305 Self::SigSIm(inner) => inner.next(),
306 Self::SigSNV(inner) => inner.next(),
307 Self::SigI(inner) => inner.next(),
308 }
309 }
310
311 fn size_hint(&self) -> (usize, Option<usize>) {
312 match self {
313 Self::SigSTNS(inner) => inner.size_hint(),
314 Self::SigSC(inner) => inner.size_hint(),
315 Self::SigSSCI(inner) => inner.size_hint(),
316 Self::SigSI(inner) => inner.size_hint(),
317 #[cfg(feature = "jpeg2000-unpack-with-openjpeg")]
318 Self::SigSIm(inner) => inner.size_hint(),
319 Self::SigSNV(inner) => inner.size_hint(),
320 Self::SigI(inner) => inner.size_hint(),
321 }
322 }
323}
324
325#[derive(Debug, Clone, PartialEq, Eq, Hash)]
326pub enum DecodeError {
327 NotSupported(&'static str, u16),
328 LengthMismatch,
329 UnclassifiedError(String),
330}
331
332impl From<String> for DecodeError {
333 fn from(value: String) -> Self {
334 Self::UnclassifiedError(value)
335 }
336}
337
338impl From<&str> for DecodeError {
339 fn from(value: &str) -> Self {
340 Self::UnclassifiedError(value.to_owned())
341 }
342}
343
344pub(crate) trait Grib2GpvUnpack {
345 type Iter<'a>: Iterator<Item = f32>
346 where
347 Self: 'a;
348
349 fn iter<'a>(&'a self) -> Result<Self::Iter<'a>, DecodeError>;
350}
351
352mod bitmap;
353#[cfg(feature = "ccsds-unpack-with-libaec")]
354mod ccsds;
355mod complex;
356mod helpers;
357#[cfg(feature = "jpeg2000-unpack-with-openjpeg")]
358mod jpeg2000;
359#[cfg(feature = "png-unpack-with-png-crate")]
360mod png;
361mod run_length;
362mod simple;
363mod stream;