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
189 let bitmap_slice = &self.sect6_bytes[6..];
190 bitmap::check_consistency(
191 self.num_points_total,
192 self.num_encoded_points(),
193 bitmap_slice,
194 )?;
195 let decoder =
196 BitmapDecodeIterator::new(bitmap_slice.iter(), decoder, self.num_points_total);
197 Ok(Grib2DecodedValues(decoder))
198 }
199
200 pub(crate) fn num_encoded_points(&self) -> usize {
201 self.sect5_param.payload.num_encoded_points as usize
202 }
203
204 pub(crate) fn sect7_payload(&self) -> &[u8] {
205 &self.sect7_bytes[5..]
206 }
207
208 pub fn section5(&self) -> &Section5 {
249 &self.sect5_param
250 }
251}
252
253pub(crate) fn orig_field_type_is_supported(orig_field_type: u8) -> Result<(), DecodeError> {
254 if orig_field_type != 0 {
255 return Err(DecodeError::NotSupported(
256 "GRIB2 code table 5.1 (type of original field values)",
257 orig_field_type.into(),
258 ));
259 }
260 Ok(())
261}
262
263pub struct Grib2DecodedValues<'b, I>(BitmapDecodeIterator<std::slice::Iter<'b, u8>, I>);
264
265impl<I> Iterator for Grib2DecodedValues<'_, I>
266where
267 I: Iterator<Item = f32>,
268{
269 type Item = f32;
270
271 fn next(&mut self) -> Option<Self::Item> {
272 let Self(inner) = self;
273 inner.next()
274 }
275
276 fn size_hint(&self) -> (usize, Option<usize>) {
277 let Self(inner) = self;
278 inner.size_hint()
279 }
280}
281
282enum Grib2ValueIterator<'d> {
283 SigSTNS(SimplePackingDecoder<std::iter::Take<NBitwiseIterator<&'d [u8]>>>),
284 SigSC(SimplePackingDecoder<ComplexPackingDecoded<'d>>),
285 SigSSCI(
286 SimplePackingDecoder<
287 complex::SpatialDifferencingDecodeIterator<ComplexPackingDecoded<'d>, IntoIter<i32>>,
288 >,
289 ),
290 #[allow(dead_code)]
291 SigSI(SimplePackingDecoder<IntoIter<i32>>),
292 #[cfg(feature = "jpeg2000-unpack-with-openjpeg")]
293 SigSIm(SimplePackingDecoder<self::jpeg2000::ImageIntoIter>),
294 #[allow(dead_code)]
295 SigSNV(SimplePackingDecoder<NBitwiseIterator<Vec<u8>>>),
296 SigI(IntoIter<f32>),
297}
298
299impl<'d> Iterator for Grib2ValueIterator<'d> {
300 type Item = f32;
301
302 fn next(&mut self) -> Option<Self::Item> {
303 match self {
304 Self::SigSTNS(inner) => inner.next(),
305 Self::SigSC(inner) => inner.next(),
306 Self::SigSSCI(inner) => inner.next(),
307 Self::SigSI(inner) => inner.next(),
308 #[cfg(feature = "jpeg2000-unpack-with-openjpeg")]
309 Self::SigSIm(inner) => inner.next(),
310 Self::SigSNV(inner) => inner.next(),
311 Self::SigI(inner) => inner.next(),
312 }
313 }
314
315 fn size_hint(&self) -> (usize, Option<usize>) {
316 match self {
317 Self::SigSTNS(inner) => inner.size_hint(),
318 Self::SigSC(inner) => inner.size_hint(),
319 Self::SigSSCI(inner) => inner.size_hint(),
320 Self::SigSI(inner) => inner.size_hint(),
321 #[cfg(feature = "jpeg2000-unpack-with-openjpeg")]
322 Self::SigSIm(inner) => inner.size_hint(),
323 Self::SigSNV(inner) => inner.size_hint(),
324 Self::SigI(inner) => inner.size_hint(),
325 }
326 }
327}
328
329#[derive(Debug, Clone, PartialEq, Eq, Hash)]
330pub enum DecodeError {
331 NotSupported(&'static str, u16),
332 LengthMismatch,
333 UnclassifiedError(String),
334}
335
336impl From<String> for DecodeError {
337 fn from(value: String) -> Self {
338 Self::UnclassifiedError(value)
339 }
340}
341
342impl From<&str> for DecodeError {
343 fn from(value: &str) -> Self {
344 Self::UnclassifiedError(value.to_owned())
345 }
346}
347
348pub(crate) trait Grib2GpvUnpack {
349 type Iter<'a>: Iterator<Item = f32>
350 where
351 Self: 'a;
352
353 fn iter<'a>(&'a self) -> Result<Self::Iter<'a>, DecodeError>;
354}
355
356mod bitmap;
357#[cfg(feature = "ccsds-unpack-with-libaec")]
358mod ccsds;
359mod complex;
360mod helpers;
361#[cfg(feature = "jpeg2000-unpack-with-openjpeg")]
362mod jpeg2000;
363#[cfg(feature = "png-unpack-with-png-crate")]
364mod png;
365mod run_length;
366mod simple;
367mod stream;