1use crate::decoder::ascii::AsciiReader;
16use crate::decoder::binary::BinaryReader;
17#[cfg(feature = "rayon")]
18use crate::decoder::binary_par::BinaryParallelDecoder;
19use crate::decoder::compressed::CompressedReader;
20use crate::error::Result;
21use crate::header::{DataFormat, PcdHeader, parse_header};
22use crate::layout::PcdLayout;
23use crate::storage::PointBlock;
24
25#[cfg(feature = "memmap2")]
26use memmap2::Mmap;
27use std::fs::File;
28use std::io::Cursor;
29use std::io::{BufRead, BufReader};
30use std::path::Path;
31
32pub enum InputSource<R: BufRead> {
33 Reader(R),
34 #[cfg(feature = "memmap2")]
35 Mmap(Mmap),
36}
37
38pub struct PcdReader<R: BufRead> {
39 source: InputSource<R>,
40 header: PcdHeader,
41 layout: PcdLayout,
42 #[cfg(feature = "memmap2")]
43 start_offset: usize, }
45
46impl<R: BufRead> PcdReader<R> {
47 pub fn new(mut reader: R) -> Result<Self> {
48 let header = parse_header(&mut reader)?;
49 let layout = PcdLayout::from_header(&header)?;
50
51 Ok(PcdReader {
52 source: InputSource::Reader(reader),
53 header,
54 layout,
55 #[cfg(feature = "memmap2")]
56 start_offset: 0,
57 })
58 }
59}
60
61impl<'a> PcdReader<BufReader<Cursor<&'a [u8]>>> {
64 pub fn from_bytes(data: &'a [u8]) -> Result<Self> {
65 let cursor = Cursor::new(data);
66 let reader = BufReader::new(cursor);
67 Self::new(reader)
68 }
69}
70
71impl PcdReader<BufReader<File>> {
72 pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self> {
73 let file = File::open(path)?;
74 let reader = BufReader::new(file);
75 Self::new(reader)
76 }
77
78 #[cfg(feature = "memmap2")]
79 pub fn from_path_mmap<P: AsRef<Path>>(path: P) -> Result<Self> {
80 let file = File::open(path)?;
81 let mmap = unsafe { Mmap::map(&file)? };
83
84 let mut cursor = Cursor::new(&mmap[..]);
86 let header = parse_header(&mut cursor)?;
87 let pos = cursor.position() as usize; let layout = PcdLayout::from_header(&header)?;
90
91 Ok(PcdReader {
92 source: InputSource::Mmap(mmap),
93 header,
94 layout,
95 start_offset: pos,
96 })
97 }
98}
99
100impl<R: BufRead> PcdReader<R> {
101 pub fn header(&self) -> &PcdHeader {
102 &self.header
103 }
104
105 pub fn read_all(mut self) -> Result<PointBlock> {
106 let points = self.header.points;
107 let mut block = PointBlock::new(
108 &self
109 .layout
110 .fields
111 .iter()
112 .map(|f| (f.name.clone(), f.type_))
113 .collect(),
114 points,
115 );
116
117 match &mut self.source {
118 InputSource::Reader(reader) => match self.header.data {
119 DataFormat::Binary => {
120 let mut decoder = BinaryReader::new(reader, &self.layout, points);
121 decoder.decode(&mut block)?;
122 }
123 DataFormat::BinaryCompressed => {
124 let mut decoder = CompressedReader::new(reader, &self.layout, points);
125 decoder.decode(&mut block)?;
126 }
127 DataFormat::Ascii => {
128 let mut decoder = AsciiReader::new(reader, &self.layout, points);
129 decoder.decode(&mut block)?;
130 }
131 },
132 #[cfg(feature = "memmap2")]
133 InputSource::Mmap(mmap) => {
134 let data_slice = &mmap[self.start_offset..];
135
136 match self.header.data {
137 DataFormat::Binary => {
138 #[cfg(feature = "rayon")]
139 {
140 let decoder = BinaryParallelDecoder::new(&self.layout, points);
142 decoder.decode_par(data_slice, &mut block)?;
143 }
144 #[cfg(not(feature = "rayon"))]
145 {
146 let mut cursor = Cursor::new(data_slice);
148 let mut decoder = BinaryReader::new(&mut cursor, &self.layout, points);
149 decoder.decode(&mut block)?;
150 }
151 }
152 DataFormat::BinaryCompressed => {
153 let mut cursor = Cursor::new(data_slice);
156 let mut decoder = CompressedReader::new(&mut cursor, &self.layout, points);
157 decoder.decode(&mut block)?;
158 }
159 DataFormat::Ascii => {
160 let mut cursor = Cursor::new(data_slice);
161 let mut decoder = AsciiReader::new(&mut cursor, &self.layout, points);
162 decoder.decode(&mut block)?;
163 }
164 }
165 }
166 }
167 Ok(block)
168 }
169}
170
171pub fn read_pcd_file<P: AsRef<Path>>(path: P) -> Result<PointBlock> {
172 let file = File::open(path)?;
173 let reader = BufReader::new(file);
174 let pcd_reader = PcdReader::new(reader)?;
175 pcd_reader.read_all()
176}