grib/decoder/
png.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crate::{
    decoder::{
        param::SimplePackingParam,
        simple::{SimplePackingDecodeIterator, SimplePackingDecodeIteratorWrapper},
        stream::{FixedValueIterator, NBitwiseIterator},
    },
    DecodeError, Grib2SubmessageDecoder, GribError,
};

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum PngDecodeError {
    NotSupported,
    PngError(String),
}

pub(crate) fn decode(
    target: &Grib2SubmessageDecoder,
) -> Result<SimplePackingDecodeIteratorWrapper<impl Iterator<Item = u32> + '_>, GribError> {
    let sect5_data = &target.sect5_payload;
    let param = SimplePackingParam::from_buf(&sect5_data[6..16])?;

    let buf = read_image_buffer(&target.sect7_payload).map_err(|e| {
        GribError::DecodeError(DecodeError::PngDecodeError(PngDecodeError::PngError(
            e.to_string(),
        )))
    })?;

    if param.nbit == 0 {
        eprintln!(
            "WARNING: nbit = 0 for PNG decoder is not tested.
            Please report your data and help us develop the library."
        );
        let decoder = SimplePackingDecodeIteratorWrapper::FixedValue(FixedValueIterator::new(
            param.zero_bit_reference_value(),
            target.num_points_encoded,
        ));
        return Ok(decoder);
    };

    if param.nbit != 16 {
        eprintln!(
            "WARNING: nbit != 16 for PNG decoder is not tested.
            Please report your data and help us develop the library."
        );
    }

    let iter = NBitwiseIterator::new(buf, usize::from(param.nbit));
    let iter = SimplePackingDecodeIterator::new(iter, &param);
    let iter = SimplePackingDecodeIteratorWrapper::SimplePacking(iter);
    Ok(iter)
}

fn read_image_buffer(buf: &[u8]) -> Result<Vec<u8>, png::DecodingError> {
    let reader = std::io::Cursor::new(&buf);
    let decoder = png::Decoder::new(reader);
    let mut reader = decoder.read_info()?;
    let mut out_buf = vec![0; reader.output_buffer_size()];
    let _info = reader.next_frame(&mut out_buf)?;
    Ok(out_buf)
}