1use std::io::{self, BufReader, Read};
4
5use flate2::read::GzDecoder;
6
7use crate::{
8 EdgeIndices, QuantizedMeshHeader, QuantizedVertices, TileMetadata, WaterMask,
9 decode_high_water_mark, decode_zigzag_delta,
10};
11
12#[derive(Debug)]
14pub enum DecodeError {
15 UnexpectedEof,
17 InvalidData(String),
19 DecompressionError(String),
21 JsonError(String),
23 IoError(io::Error),
25}
26
27impl std::fmt::Display for DecodeError {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 match self {
30 DecodeError::UnexpectedEof => write!(f, "Unexpected end of data"),
31 DecodeError::InvalidData(msg) => write!(f, "Invalid data: {}", msg),
32 DecodeError::DecompressionError(msg) => write!(f, "Decompression error: {}", msg),
33 DecodeError::JsonError(msg) => write!(f, "JSON error: {}", msg),
34 DecodeError::IoError(err) => write!(f, "IO error: {}", err),
35 }
36 }
37}
38
39impl std::error::Error for DecodeError {}
40
41impl From<io::Error> for DecodeError {
42 fn from(err: io::Error) -> Self {
43 if err.kind() == io::ErrorKind::UnexpectedEof {
44 DecodeError::UnexpectedEof
45 } else {
46 DecodeError::IoError(err)
47 }
48 }
49}
50
51pub type DecodeResult<T> = Result<T, DecodeError>;
53
54#[derive(Debug, Clone, Default)]
56pub struct DecodedExtensions {
57 pub normals: Option<Vec<[f32; 3]>>,
59 pub water_mask: Option<WaterMask>,
61 pub metadata: Option<TileMetadata>,
63}
64
65#[derive(Debug, Clone)]
67pub struct DecodedMesh {
68 pub header: QuantizedMeshHeader,
70 pub vertices: QuantizedVertices,
72 pub indices: Vec<u32>,
74 pub edge_indices: EdgeIndices,
76 pub extensions: DecodedExtensions,
78}
79
80pub struct QuantizedMeshDecoder<'a> {
84 data: &'a [u8],
85 offset: usize,
86}
87
88impl<'a> QuantizedMeshDecoder<'a> {
89 pub fn new(data: &'a [u8]) -> Self {
93 Self { data, offset: 0 }
94 }
95
96 pub fn decode(data: &[u8]) -> DecodeResult<DecodedMesh> {
100 let decompressed: Vec<u8>;
102 let data = if data.len() >= 2 && data[0] == 0x1f && data[1] == 0x8b {
103 let mut decoder = GzDecoder::new(data);
105 decompressed = Vec::new();
106 let mut buf = decompressed;
107 decoder
108 .read_to_end(&mut buf)
109 .map_err(|e| DecodeError::DecompressionError(e.to_string()))?;
110 buf
111 } else {
112 data.to_vec()
113 };
114
115 let mut decoder = QuantizedMeshDecoder::new(&data);
116 decoder.decode_internal()
117 }
118
119 pub fn decode_from<R: Read>(reader: R) -> DecodeResult<DecodedMesh> {
124 let mut reader = BufReader::new(reader);
125
126 let mut magic = [0u8; 2];
128 reader.read_exact(&mut magic)?;
129
130 let mut rest = Vec::new();
132 reader.read_to_end(&mut rest)?;
133
134 let mut data = magic.to_vec();
136 data.extend(rest);
137
138 let decompressed = if magic[0] == 0x1f && magic[1] == 0x8b {
140 let mut decoder = GzDecoder::new(data.as_slice());
142 let mut buf = Vec::new();
143 decoder
144 .read_to_end(&mut buf)
145 .map_err(|e| DecodeError::DecompressionError(e.to_string()))?;
146 buf
147 } else {
148 data
149 };
150
151 let mut decoder = QuantizedMeshDecoder::new(&decompressed);
152 decoder.decode_internal()
153 }
154
155 fn decode_internal(&mut self) -> DecodeResult<DecodedMesh> {
156 let header = self.read_header()?;
158
159 let vertex_count = self.read_u32()? as usize;
161 let use_32bit = vertex_count > 65535;
162
163 let encoded_u = self.read_u16_array(vertex_count)?;
165 let encoded_v = self.read_u16_array(vertex_count)?;
166 let encoded_height = self.read_u16_array(vertex_count)?;
167
168 let u = decode_zigzag_delta(&encoded_u);
170 let v = decode_zigzag_delta(&encoded_v);
171 let height = decode_zigzag_delta(&encoded_height);
172
173 let vertices = QuantizedVertices { u, v, height };
174
175 if use_32bit {
177 self.align_to(4);
178 } else {
179 self.align_to(2);
180 }
181
182 let triangle_count = self.read_u32()? as usize;
184 let index_count = triangle_count * 3;
185
186 let encoded_indices = if use_32bit {
188 self.read_u32_array(index_count)?
189 } else {
190 self.read_u16_array(index_count)?
191 .into_iter()
192 .map(|x| x as u32)
193 .collect()
194 };
195
196 let indices = decode_high_water_mark(&encoded_indices);
198
199 let west = self.read_edge_indices(use_32bit)?;
201 let south = self.read_edge_indices(use_32bit)?;
202 let east = self.read_edge_indices(use_32bit)?;
203 let north = self.read_edge_indices(use_32bit)?;
204
205 let edge_indices = EdgeIndices {
206 west,
207 south,
208 east,
209 north,
210 };
211
212 let extensions = self.read_extensions(vertex_count)?;
214
215 Ok(DecodedMesh {
216 header,
217 vertices,
218 indices,
219 edge_indices,
220 extensions,
221 })
222 }
223
224 fn read_header(&mut self) -> DecodeResult<QuantizedMeshHeader> {
225 if self.remaining() < 88 {
226 return Err(DecodeError::UnexpectedEof);
227 }
228
229 let header = QuantizedMeshHeader::from_bytes(&self.data[self.offset..])
230 .ok_or_else(|| DecodeError::InvalidData("Invalid header".to_string()))?;
231
232 self.offset += 88;
233 Ok(header)
234 }
235
236 fn read_u16(&mut self) -> DecodeResult<u16> {
237 if self.remaining() < 2 {
238 return Err(DecodeError::UnexpectedEof);
239 }
240 let value = u16::from_le_bytes([self.data[self.offset], self.data[self.offset + 1]]);
241 self.offset += 2;
242 Ok(value)
243 }
244
245 fn read_u32(&mut self) -> DecodeResult<u32> {
246 if self.remaining() < 4 {
247 return Err(DecodeError::UnexpectedEof);
248 }
249 let value = u32::from_le_bytes([
250 self.data[self.offset],
251 self.data[self.offset + 1],
252 self.data[self.offset + 2],
253 self.data[self.offset + 3],
254 ]);
255 self.offset += 4;
256 Ok(value)
257 }
258
259 fn read_u16_array(&mut self, count: usize) -> DecodeResult<Vec<u16>> {
260 let byte_count = count * 2;
261 if self.remaining() < byte_count {
262 return Err(DecodeError::UnexpectedEof);
263 }
264
265 let mut result = Vec::with_capacity(count);
266 for _ in 0..count {
267 result.push(self.read_u16()?);
268 }
269 Ok(result)
270 }
271
272 fn read_u32_array(&mut self, count: usize) -> DecodeResult<Vec<u32>> {
273 let byte_count = count * 4;
274 if self.remaining() < byte_count {
275 return Err(DecodeError::UnexpectedEof);
276 }
277
278 let mut result = Vec::with_capacity(count);
279 for _ in 0..count {
280 result.push(self.read_u32()?);
281 }
282 Ok(result)
283 }
284
285 fn read_edge_indices(&mut self, use_32bit: bool) -> DecodeResult<Vec<u32>> {
286 let count = self.read_u32()? as usize;
287 if use_32bit {
288 self.read_u32_array(count)
289 } else {
290 Ok(self
291 .read_u16_array(count)?
292 .into_iter()
293 .map(|x| x as u32)
294 .collect())
295 }
296 }
297
298 fn read_extensions(&mut self, vertex_count: usize) -> DecodeResult<DecodedExtensions> {
299 let mut extensions = DecodedExtensions::default();
300
301 while self.remaining() >= 5 {
302 let extension_id = self.data[self.offset];
304 self.offset += 1;
305
306 let length = self.read_u32()? as usize;
307 if self.remaining() < length {
308 break;
310 }
311
312 match extension_id {
313 1 => {
314 extensions.normals = Some(self.read_normals(vertex_count)?);
316 }
317 2 => {
318 extensions.water_mask = Some(self.read_water_mask(length)?);
320 }
321 4 => {
322 extensions.metadata = Some(self.read_metadata()?);
324 }
325 _ => {
326 self.offset += length;
328 }
329 }
330 }
331
332 Ok(extensions)
333 }
334
335 fn read_normals(&mut self, vertex_count: usize) -> DecodeResult<Vec<[f32; 3]>> {
336 let mut normals = Vec::with_capacity(vertex_count);
337 for _ in 0..vertex_count {
338 if self.remaining() < 2 {
339 return Err(DecodeError::UnexpectedEof);
340 }
341 let encoded = [self.data[self.offset], self.data[self.offset + 1]];
342 self.offset += 2;
343 normals.push(oct_decode_normal(encoded));
344 }
345 Ok(normals)
346 }
347
348 fn read_water_mask(&mut self, length: usize) -> DecodeResult<WaterMask> {
349 if length == 1 {
350 if self.remaining() < 1 {
351 return Err(DecodeError::UnexpectedEof);
352 }
353 let value = self.data[self.offset];
354 self.offset += 1;
355 Ok(WaterMask::Uniform(value))
356 } else if length == 256 * 256 {
357 if self.remaining() < 256 * 256 {
358 return Err(DecodeError::UnexpectedEof);
359 }
360 let mut grid = Box::new([0u8; 256 * 256]);
361 grid.copy_from_slice(&self.data[self.offset..self.offset + 256 * 256]);
362 self.offset += 256 * 256;
363 Ok(WaterMask::Grid(grid))
364 } else {
365 self.offset += length;
367 Ok(WaterMask::Uniform(0))
368 }
369 }
370
371 fn read_metadata(&mut self) -> DecodeResult<TileMetadata> {
372 let json_length = self.read_u32()? as usize;
373 if self.remaining() < json_length {
374 return Err(DecodeError::UnexpectedEof);
375 }
376
377 let json_bytes = &self.data[self.offset..self.offset + json_length];
378 self.offset += json_length;
379
380 let json_str =
381 std::str::from_utf8(json_bytes).map_err(|e| DecodeError::JsonError(e.to_string()))?;
382
383 serde_json::from_str(json_str).map_err(|e| DecodeError::JsonError(e.to_string()))
384 }
385
386 fn align_to(&mut self, alignment: usize) {
387 let remainder = self.offset % alignment;
388 if remainder != 0 {
389 self.offset += alignment - remainder;
390 }
391 }
392
393 fn remaining(&self) -> usize {
394 self.data.len().saturating_sub(self.offset)
395 }
396}
397
398pub fn oct_decode_normal(encoded: [u8; 2]) -> [f32; 3] {
402 let mut x = (encoded[0] as f32 / 255.0) * 2.0 - 1.0;
404 let mut y = (encoded[1] as f32 / 255.0) * 2.0 - 1.0;
405
406 let z = 1.0 - x.abs() - y.abs();
408
409 if z < 0.0 {
411 let ox = x;
412 x = (1.0 - y.abs()) * if ox >= 0.0 { 1.0 } else { -1.0 };
413 y = (1.0 - ox.abs()) * if y >= 0.0 { 1.0 } else { -1.0 };
414 }
415
416 let len = (x * x + y * y + z * z).sqrt();
418 if len > 0.0 {
419 [x / len, y / len, z / len]
420 } else {
421 [0.0, 0.0, 1.0]
422 }
423}
424
425#[cfg(test)]
426mod tests {
427 use super::*;
428 use crate::{EncodeOptions, QuantizedMeshEncoder, oct_encode_normal};
429
430 #[test]
431 fn test_oct_decode_normal_roundtrip() {
432 let test_normals = [
433 [0.0f32, 0.0, 1.0], [0.0, 0.0, -1.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.577, 0.577, 0.577], ];
439
440 for normal in test_normals {
441 let encoded = oct_encode_normal(normal);
442 let decoded = oct_decode_normal(encoded);
443
444 let dot = normal[0] * decoded[0] + normal[1] * decoded[1] + normal[2] * decoded[2];
446 assert!(
447 dot > 0.95,
448 "Normal roundtrip failed: {:?} -> {:?} -> {:?}, dot = {}",
449 normal,
450 encoded,
451 decoded,
452 dot
453 );
454 }
455 }
456
457 #[test]
458 fn test_decode_simple_mesh() {
459 let header = QuantizedMeshHeader::default();
461 let vertices = QuantizedVertices {
462 u: vec![0, 32767, 0, 32767],
463 v: vec![0, 0, 32767, 32767],
464 height: vec![0, 0, 0, 0],
465 };
466 let indices = vec![0, 1, 2, 1, 3, 2];
467 let edge_indices = EdgeIndices::from_vertices(&vertices);
468
469 let encoder = QuantizedMeshEncoder::new(
471 header,
472 vertices.clone(),
473 indices.clone(),
474 edge_indices.clone(),
475 );
476 let encoded = encoder.encode_with_options(&EncodeOptions {
477 compression_level: 0,
478 ..Default::default()
479 });
480
481 let decoded = QuantizedMeshDecoder::decode(&encoded).expect("Decoding failed");
483
484 assert_eq!(decoded.header.min_height, header.min_height);
486 assert_eq!(decoded.header.max_height, header.max_height);
487 assert_eq!(decoded.vertices.u, vertices.u);
488 assert_eq!(decoded.vertices.v, vertices.v);
489 assert_eq!(decoded.vertices.height, vertices.height);
490 assert_eq!(decoded.indices, indices);
491 assert_eq!(decoded.edge_indices.west, edge_indices.west);
492 assert_eq!(decoded.edge_indices.south, edge_indices.south);
493 assert_eq!(decoded.edge_indices.east, edge_indices.east);
494 assert_eq!(decoded.edge_indices.north, edge_indices.north);
495 }
496
497 #[test]
498 fn test_decode_compressed_mesh() {
499 let header = QuantizedMeshHeader::default();
501 let vertices = QuantizedVertices {
502 u: vec![0, 32767, 0, 32767],
503 v: vec![0, 0, 32767, 32767],
504 height: vec![0, 0, 0, 0],
505 };
506 let indices = vec![0, 1, 2, 1, 3, 2];
507 let edge_indices = EdgeIndices::from_vertices(&vertices);
508
509 let encoder = QuantizedMeshEncoder::new(
511 header,
512 vertices.clone(),
513 indices.clone(),
514 edge_indices.clone(),
515 );
516 let encoded = encoder.encode_with_options(&EncodeOptions {
517 compression_level: 6,
518 ..Default::default()
519 });
520
521 assert_eq!(&encoded[0..2], &[0x1f, 0x8b]);
523
524 let decoded = QuantizedMeshDecoder::decode(&encoded).expect("Decoding failed");
526
527 assert_eq!(decoded.vertices.u, vertices.u);
529 assert_eq!(decoded.vertices.v, vertices.v);
530 assert_eq!(decoded.indices, indices);
531 }
532
533 #[test]
534 fn test_decode_with_extensions() {
535 let header = QuantizedMeshHeader::default();
536 let vertices = QuantizedVertices {
537 u: vec![0, 32767, 0, 32767],
538 v: vec![0, 0, 32767, 32767],
539 height: vec![0, 0, 0, 0],
540 };
541 let indices = vec![0, 1, 2, 1, 3, 2];
542 let edge_indices = EdgeIndices::from_vertices(&vertices);
543 let normals = vec![[0.0, 0.0, 1.0]; 4];
544
545 let encoder = QuantizedMeshEncoder::new(header, vertices.clone(), indices, edge_indices);
547 let encoded = encoder.encode_with_options(&EncodeOptions {
548 compression_level: 0,
549 include_normals: true,
550 normals: Some(normals),
551 include_water_mask: true,
552 water_mask: Some(WaterMask::Uniform(128)),
553 ..Default::default()
554 });
555
556 let decoded = QuantizedMeshDecoder::decode(&encoded).expect("Decoding failed");
558
559 assert!(decoded.extensions.normals.is_some());
561 assert!(decoded.extensions.water_mask.is_some());
562
563 let decoded_normals = decoded.extensions.normals.unwrap();
564 assert_eq!(decoded_normals.len(), 4);
565 for normal in decoded_normals {
567 assert!(normal[2] > 0.9);
568 }
569
570 match decoded.extensions.water_mask.unwrap() {
571 WaterMask::Uniform(v) => assert_eq!(v, 128),
572 _ => panic!("Expected uniform water mask"),
573 }
574 }
575
576 #[test]
577 fn test_decode_from_reader() {
578 use std::io::Cursor;
579
580 let header = QuantizedMeshHeader::default();
582 let vertices = QuantizedVertices {
583 u: vec![0, 32767, 0, 32767],
584 v: vec![0, 0, 32767, 32767],
585 height: vec![0, 0, 0, 0],
586 };
587 let indices = vec![0, 1, 2, 1, 3, 2];
588 let edge_indices = EdgeIndices::from_vertices(&vertices);
589
590 let encoder = QuantizedMeshEncoder::new(
592 header,
593 vertices.clone(),
594 indices.clone(),
595 edge_indices.clone(),
596 );
597 let encoded = encoder.encode_with_options(&EncodeOptions {
598 compression_level: 0,
599 ..Default::default()
600 });
601
602 let reader = Cursor::new(encoded);
604 let decoded =
605 QuantizedMeshDecoder::decode_from(reader).expect("Decoding from reader failed");
606
607 assert_eq!(decoded.vertices.u, vertices.u);
609 assert_eq!(decoded.vertices.v, vertices.v);
610 assert_eq!(decoded.indices, indices);
611 }
612
613 #[test]
614 fn test_decode_from_reader_compressed() {
615 use std::io::Cursor;
616
617 let header = QuantizedMeshHeader::default();
619 let vertices = QuantizedVertices {
620 u: vec![0, 32767, 0, 32767],
621 v: vec![0, 0, 32767, 32767],
622 height: vec![0, 0, 0, 0],
623 };
624 let indices = vec![0, 1, 2, 1, 3, 2];
625 let edge_indices = EdgeIndices::from_vertices(&vertices);
626
627 let encoder = QuantizedMeshEncoder::new(
629 header,
630 vertices.clone(),
631 indices.clone(),
632 edge_indices.clone(),
633 );
634 let encoded = encoder.encode_with_options(&EncodeOptions {
635 compression_level: 6,
636 ..Default::default()
637 });
638
639 let reader = Cursor::new(encoded);
641 let decoded =
642 QuantizedMeshDecoder::decode_from(reader).expect("Decoding from reader failed");
643
644 assert_eq!(decoded.vertices.u, vertices.u);
646 assert_eq!(decoded.vertices.v, vertices.v);
647 assert_eq!(decoded.indices, indices);
648 }
649}