gausplat_loader/source/polygon/payload/
decode.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
61
//! Polygon payload decoding implementation.

pub use super::*;

use crate::function::read_bytes;
use std::io::Read;

impl DecoderWith<&Header> for Payload {
    type Err = Error;

    fn decode_with(
        reader: &mut impl Read,
        init: &Header,
    ) -> Result<Self, Self::Err> {
        assert!(
            !init.format.is_ascii(),
            "Unimplemented: ASCII format decoding"
        );

        let should_reverse_datum = !init.format.is_binary_native_endian();

        let data = init
            .elements
            .values()
            .map(|elem| {
                let prop_count = elem.len();
                let prop_sizes = elem.property_sizes().collect::<Result<Vec<_>, _>>()?;
                let elem_size = prop_sizes.iter().sum::<usize>();

                (0..elem.count).try_fold(
                    vec![Vec::with_capacity(1 << 15); prop_count],
                    |mut props, _| {
                        let mut data = read_bytes(reader, elem_size)?;
                        props.iter_mut().zip(prop_sizes.iter()).fold(
                            0,
                            |start, (prop, size)| {
                                let end = start + size;
                                // NOTE: The index is guaranteed to be valid.
                                let datum = data.get_mut(start..end).unwrap();
                                if should_reverse_datum {
                                    datum.reverse();
                                }
                                prop.extend_from_slice(datum);
                                end
                            },
                        );
                        Ok(props)
                    },
                )
            })
            .collect::<Result<_, Self::Err>>()?;

        // NOTE: Currently, there is only scalar payload implemented.
        let payload = ScalarPayload { data }.into();

        #[cfg(all(debug_assertions, not(test)))]
        log::debug!(target: "gausplat-loader::polygon::payload", "Payload::decode_with");

        Ok(payload)
    }
}