1use crate::color::DeviceColor;
12use crate::device::{ShadingPatch, ShadingTriangle, ShadingVertex};
13
14pub struct BitReader<'a> {
16 data: &'a [u8],
17 bit_pos: usize,
18}
19
20impl<'a> BitReader<'a> {
21 pub fn new(data: &'a [u8]) -> Self {
23 Self { data, bit_pos: 0 }
24 }
25
26 pub fn read(&mut self, n: usize) -> Option<u32> {
28 if n == 0 {
29 return Some(0);
30 }
31 if n > 32 {
32 return None;
33 }
34 let end_bit = self.bit_pos + n;
35 if end_bit > self.data.len() * 8 {
36 return None;
37 }
38
39 let bit_offset = self.bit_pos & 7;
40 let byte_idx = self.bit_pos >> 3;
41
42 if bit_offset == 0 {
44 let val = match n {
45 8 => {
46 self.bit_pos = end_bit;
47 return Some(self.data[byte_idx] as u32);
48 }
49 16 => {
50 let v = ((self.data[byte_idx] as u32) << 8) | (self.data[byte_idx + 1] as u32);
51 self.bit_pos = end_bit;
52 return Some(v);
53 }
54 24 => {
55 let v = ((self.data[byte_idx] as u32) << 16)
56 | ((self.data[byte_idx + 1] as u32) << 8)
57 | (self.data[byte_idx + 2] as u32);
58 self.bit_pos = end_bit;
59 return Some(v);
60 }
61 32 => {
62 let v = ((self.data[byte_idx] as u32) << 24)
63 | ((self.data[byte_idx + 1] as u32) << 16)
64 | ((self.data[byte_idx + 2] as u32) << 8)
65 | (self.data[byte_idx + 3] as u32);
66 self.bit_pos = end_bit;
67 return Some(v);
68 }
69 _ => None,
70 };
71 if let Some(v) = val {
72 return Some(v);
73 }
74 }
75
76 let end_byte = (end_bit + 7) >> 3;
78 let mut accum: u64 = 0;
79 for &b in &self.data[byte_idx..end_byte] {
80 accum = (accum << 8) | b as u64;
81 }
82 let total_bits = (end_byte - byte_idx) * 8;
84 let shift = total_bits - bit_offset - n;
86 let mask = (1u64 << n) - 1;
87 let result = ((accum >> shift) & mask) as u32;
88
89 self.bit_pos = end_bit;
90 Some(result)
91 }
92
93 pub fn exhausted(&self) -> bool {
95 self.bit_pos >> 3 >= self.data.len()
96 }
97}
98
99#[inline]
102fn decode_value(raw: u32, scale: f64, min: f64) -> f64 {
103 min + raw as f64 * scale
104}
105
106#[inline]
108fn decode_scale(bits: usize, min: f64, max: f64) -> f64 {
109 let max_val = ((1u64 << bits) - 1) as f64;
110 if max_val == 0.0 {
111 0.0
112 } else {
113 (max - min) / max_val
114 }
115}
116
117fn components_to_color(comps: &[f64]) -> (DeviceColor, Vec<f64>) {
120 let raw = comps.to_vec();
121 let color = match comps.len() {
122 1 => DeviceColor::from_gray(comps[0].clamp(0.0, 1.0)),
123 3 => DeviceColor::from_rgb(
124 comps[0].clamp(0.0, 1.0),
125 comps[1].clamp(0.0, 1.0),
126 comps[2].clamp(0.0, 1.0),
127 ),
128 4 => DeviceColor::from_cmyk(
129 comps[0].clamp(0.0, 1.0),
130 comps[1].clamp(0.0, 1.0),
131 comps[2].clamp(0.0, 1.0),
132 comps[3].clamp(0.0, 1.0),
133 ),
134 _ => {
135 if comps.len() >= 3 {
136 DeviceColor::from_rgb(
137 comps[0].clamp(0.0, 1.0),
138 comps[1].clamp(0.0, 1.0),
139 comps[2].clamp(0.0, 1.0),
140 )
141 } else {
142 DeviceColor::from_gray(0.0)
143 }
144 }
145 };
146 (color, raw)
147}
148
149pub fn parse_type4_mesh(
159 data: &[u8],
160 bpc: usize,
161 bpco: usize,
162 bpfl: usize,
163 decode: &[f64],
164 n_comps: usize,
165) -> Vec<ShadingTriangle> {
166 let mut reader = BitReader::new(data);
167 let mut triangles = Vec::new();
168
169 let x_min = decode[0];
171 let x_scale = decode_scale(bpc, decode[0], decode[1]);
172 let y_min = decode[2];
173 let y_scale = decode_scale(bpc, decode[2], decode[3]);
174
175 let mut color_params: Vec<(f64, f64)> = Vec::with_capacity(n_comps);
176 for i in 0..n_comps {
177 let idx = 4 + i * 2;
178 let c_min = decode.get(idx).copied().unwrap_or(0.0);
179 let c_max = decode.get(idx + 1).copied().unwrap_or(1.0);
180 color_params.push((c_min, decode_scale(bpco, c_min, c_max)));
181 }
182
183 let read_vertex = |reader: &mut BitReader| -> Option<(u32, ShadingVertex)> {
184 let flag = reader.read(bpfl)?;
185 let raw_x = reader.read(bpc)?;
186 let raw_y = reader.read(bpc)?;
187 let x = decode_value(raw_x, x_scale, x_min);
188 let y = decode_value(raw_y, y_scale, y_min);
189 let mut comps = vec![0.0f64; n_comps];
190 for (i, comp) in comps.iter_mut().enumerate() {
191 let raw = reader.read(bpco)?;
192 *comp = decode_value(raw, color_params[i].1, color_params[i].0);
193 }
194 let (color, raw_components) = components_to_color(&comps);
195 Some((
196 flag,
197 ShadingVertex {
198 x,
199 y,
200 color,
201 raw_components,
202 },
203 ))
204 };
205
206 let mut prev_a: Option<ShadingVertex> = None;
209 let mut prev_b: Option<ShadingVertex> = None;
210 let mut prev_c: Option<ShadingVertex> = None;
211
212 while !reader.exhausted() {
213 let Some((flag, vertex)) = read_vertex(&mut reader) else {
214 break;
215 };
216
217 match flag {
218 0 => {
219 let a = vertex;
221 let Some((_, b)) = read_vertex(&mut reader) else {
222 break;
223 };
224 let Some((_, c)) = read_vertex(&mut reader) else {
225 break;
226 };
227 triangles.push(ShadingTriangle {
228 v0: a.clone(),
229 v1: b.clone(),
230 v2: c.clone(),
231 });
232 prev_a = Some(a);
233 prev_b = Some(b);
234 prev_c = Some(c);
235 }
236 1 => {
237 if let (Some(b), Some(c)) = (&prev_b, &prev_c) {
239 let d = vertex;
240 triangles.push(ShadingTriangle {
241 v0: b.clone(),
242 v1: c.clone(),
243 v2: d.clone(),
244 });
245 prev_a = Some(b.clone());
246 prev_b = Some(c.clone());
247 prev_c = Some(d);
248 }
249 }
250 2 => {
251 if let (Some(a), Some(c)) = (&prev_a, &prev_c) {
253 let d = vertex;
254 triangles.push(ShadingTriangle {
255 v0: a.clone(),
256 v1: c.clone(),
257 v2: d.clone(),
258 });
259 prev_a = Some(a.clone());
260 prev_b = Some(c.clone());
261 prev_c = Some(d);
262 }
263 }
264 _ => {}
265 }
266 }
267
268 triangles
269}
270
271pub fn parse_type5_mesh(
281 data: &[u8],
282 bpc: usize,
283 bpco: usize,
284 decode: &[f64],
285 n_comps: usize,
286 verts_per_row: usize,
287) -> Vec<ShadingTriangle> {
288 let mut reader = BitReader::new(data);
289 let mut all_vertices = Vec::new();
290
291 let x_min = decode[0];
293 let x_scale = decode_scale(bpc, decode[0], decode[1]);
294 let y_min = decode[2];
295 let y_scale = decode_scale(bpc, decode[2], decode[3]);
296
297 let mut color_params: Vec<(f64, f64)> = Vec::with_capacity(n_comps);
298 for i in 0..n_comps {
299 let idx = 4 + i * 2;
300 let c_min = decode.get(idx).copied().unwrap_or(0.0);
301 let c_max = decode.get(idx + 1).copied().unwrap_or(1.0);
302 color_params.push((c_min, decode_scale(bpco, c_min, c_max)));
303 }
304
305 while !reader.exhausted() {
307 let Some(raw_x) = reader.read(bpc) else {
308 break;
309 };
310 let Some(raw_y) = reader.read(bpc) else {
311 break;
312 };
313 let x = decode_value(raw_x, x_scale, x_min);
314 let y = decode_value(raw_y, y_scale, y_min);
315 let mut comps = vec![0.0f64; n_comps];
316 let mut ok = true;
317 for (i, comp) in comps.iter_mut().enumerate() {
318 let Some(raw) = reader.read(bpco) else {
319 ok = false;
320 break;
321 };
322 *comp = decode_value(raw, color_params[i].1, color_params[i].0);
323 }
324 if !ok {
325 break;
326 }
327 let (color, raw_components) = components_to_color(&comps);
328 all_vertices.push(ShadingVertex {
329 x,
330 y,
331 color,
332 raw_components,
333 });
334 }
335
336 let mut triangles = Vec::new();
338 if verts_per_row < 2 {
339 return triangles;
340 }
341 let num_rows = all_vertices.len() / verts_per_row;
342 if num_rows < 2 {
343 return triangles;
344 }
345
346 for row in 0..num_rows - 1 {
347 for col in 0..verts_per_row - 1 {
348 let i00 = row * verts_per_row + col;
349 let i10 = i00 + 1;
350 let i01 = i00 + verts_per_row;
351 let i11 = i01 + 1;
352 if i11 >= all_vertices.len() {
353 break;
354 }
355 triangles.push(ShadingTriangle {
357 v0: all_vertices[i00].clone(),
358 v1: all_vertices[i10].clone(),
359 v2: all_vertices[i01].clone(),
360 });
361 triangles.push(ShadingTriangle {
363 v0: all_vertices[i10].clone(),
364 v1: all_vertices[i11].clone(),
365 v2: all_vertices[i01].clone(),
366 });
367 }
368 }
369
370 triangles
371}
372
373pub fn parse_type6_patches(
375 data: &[u8],
376 bpc: usize,
377 bpco: usize,
378 bpfl: usize,
379 decode: &[f64],
380 n_comps: usize,
381) -> Vec<ShadingPatch> {
382 let mut reader = BitReader::new(data);
383 let mut patches = Vec::new();
384
385 let x_min = decode[0];
386 let x_scale = decode_scale(bpc, decode[0], decode[1]);
387 let y_min = decode[2];
388 let y_scale = decode_scale(bpc, decode[2], decode[3]);
389
390 let mut color_params: Vec<(f64, f64)> = Vec::with_capacity(n_comps);
391 for i in 0..n_comps {
392 let idx = 4 + i * 2;
393 let c_min = decode.get(idx).copied().unwrap_or(0.0);
394 let c_max = decode.get(idx + 1).copied().unwrap_or(1.0);
395 color_params.push((c_min, decode_scale(bpco, c_min, c_max)));
396 }
397
398 let read_point = |reader: &mut BitReader| -> Option<(f64, f64)> {
399 let raw_x = reader.read(bpc)?;
400 let raw_y = reader.read(bpc)?;
401 Some((
402 decode_value(raw_x, x_scale, x_min),
403 decode_value(raw_y, y_scale, y_min),
404 ))
405 };
406
407 let read_color = |reader: &mut BitReader| -> Option<(DeviceColor, Vec<f64>)> {
408 let mut comps = vec![0.0f64; n_comps];
409 for (i, comp) in comps.iter_mut().enumerate() {
410 let raw = reader.read(bpco)?;
411 *comp = decode_value(raw, color_params[i].1, color_params[i].0);
412 }
413 Some(components_to_color(&comps))
414 };
415
416 while !reader.exhausted() {
417 let Some(flag) = reader.read(bpfl) else {
418 break;
419 };
420
421 match flag {
422 0 => {
423 let mut points = Vec::with_capacity(12);
425 let mut colors = Vec::with_capacity(4);
426 let mut raw_colors_vec = Vec::with_capacity(4);
427 let mut ok = true;
428 for _ in 0..12 {
429 if let Some(pt) = read_point(&mut reader) {
430 points.push(pt);
431 } else {
432 ok = false;
433 break;
434 }
435 }
436 if ok {
437 for _ in 0..4 {
438 if let Some((c, rc)) = read_color(&mut reader) {
439 colors.push(c);
440 raw_colors_vec.push(rc);
441 } else {
442 ok = false;
443 break;
444 }
445 }
446 }
447 if ok && points.len() == 12 && colors.len() == 4 {
448 patches.push(ShadingPatch {
449 points,
450 colors: [
451 colors[0].clone(),
452 colors[1].clone(),
453 colors[2].clone(),
454 colors[3].clone(),
455 ],
456 raw_colors: [
457 raw_colors_vec[0].clone(),
458 raw_colors_vec[1].clone(),
459 raw_colors_vec[2].clone(),
460 raw_colors_vec[3].clone(),
461 ],
462 });
463 }
464 }
465 1..=3 => {
466 if patches.is_empty() {
468 break;
469 }
470 let prev = patches.last().unwrap().clone();
471
472 let (inherited_pts, inherited_colors, inherited_raw) = match flag {
480 1 => (
481 prev.points[3..7].to_vec(),
482 [prev.colors[1].clone(), prev.colors[2].clone()],
483 [prev.raw_colors[1].clone(), prev.raw_colors[2].clone()],
484 ),
485 2 => (
486 prev.points[6..10].to_vec(),
487 [prev.colors[2].clone(), prev.colors[3].clone()],
488 [prev.raw_colors[2].clone(), prev.raw_colors[3].clone()],
489 ),
490 3 => (
491 vec![
492 prev.points[9],
493 prev.points[10],
494 prev.points[11],
495 prev.points[0],
496 ],
497 [prev.colors[3].clone(), prev.colors[0].clone()],
498 [prev.raw_colors[3].clone(), prev.raw_colors[0].clone()],
499 ),
500 _ => unreachable!(),
501 };
502
503 let mut points = inherited_pts;
505 let mut ok = true;
506 for _ in 0..8 {
507 if let Some(pt) = read_point(&mut reader) {
508 points.push(pt);
509 } else {
510 ok = false;
511 break;
512 }
513 }
514 let mut colors = vec![inherited_colors[0].clone(), inherited_colors[1].clone()];
515 let mut raw_colors_vec = vec![inherited_raw[0].clone(), inherited_raw[1].clone()];
516 if ok {
517 for _ in 0..2 {
518 if let Some((c, rc)) = read_color(&mut reader) {
519 colors.push(c);
520 raw_colors_vec.push(rc);
521 } else {
522 ok = false;
523 break;
524 }
525 }
526 }
527 if ok && points.len() == 12 && colors.len() == 4 {
528 patches.push(ShadingPatch {
529 points,
530 colors: [
531 colors[0].clone(),
532 colors[1].clone(),
533 colors[2].clone(),
534 colors[3].clone(),
535 ],
536 raw_colors: [
537 raw_colors_vec[0].clone(),
538 raw_colors_vec[1].clone(),
539 raw_colors_vec[2].clone(),
540 raw_colors_vec[3].clone(),
541 ],
542 });
543 }
544 }
545 _ => break,
546 }
547 }
548
549 patches
550}
551
552pub fn parse_type7_patches(
554 data: &[u8],
555 bpc: usize,
556 bpco: usize,
557 bpfl: usize,
558 decode: &[f64],
559 n_comps: usize,
560) -> Vec<ShadingPatch> {
561 let mut reader = BitReader::new(data);
562 let mut patches = Vec::new();
563
564 let x_min = decode[0];
565 let x_scale = decode_scale(bpc, decode[0], decode[1]);
566 let y_min = decode[2];
567 let y_scale = decode_scale(bpc, decode[2], decode[3]);
568
569 let mut color_params: Vec<(f64, f64)> = Vec::with_capacity(n_comps);
570 for i in 0..n_comps {
571 let idx = 4 + i * 2;
572 let c_min = decode.get(idx).copied().unwrap_or(0.0);
573 let c_max = decode.get(idx + 1).copied().unwrap_or(1.0);
574 color_params.push((c_min, decode_scale(bpco, c_min, c_max)));
575 }
576
577 let read_point = |reader: &mut BitReader| -> Option<(f64, f64)> {
578 let raw_x = reader.read(bpc)?;
579 let raw_y = reader.read(bpc)?;
580 Some((
581 decode_value(raw_x, x_scale, x_min),
582 decode_value(raw_y, y_scale, y_min),
583 ))
584 };
585
586 let read_color = |reader: &mut BitReader| -> Option<(DeviceColor, Vec<f64>)> {
587 let mut comps = vec![0.0f64; n_comps];
588 for (i, comp) in comps.iter_mut().enumerate() {
589 let raw = reader.read(bpco)?;
590 *comp = decode_value(raw, color_params[i].1, color_params[i].0);
591 }
592 Some(components_to_color(&comps))
593 };
594
595 while !reader.exhausted() {
596 let Some(flag) = reader.read(bpfl) else {
597 break;
598 };
599
600 match flag {
601 0 => {
602 let mut points = Vec::with_capacity(16);
604 let mut colors = Vec::with_capacity(4);
605 let mut raw_colors_vec = Vec::with_capacity(4);
606 let mut ok = true;
607 for _ in 0..16 {
608 if let Some(pt) = read_point(&mut reader) {
609 points.push(pt);
610 } else {
611 ok = false;
612 break;
613 }
614 }
615 if ok {
616 for _ in 0..4 {
617 if let Some((c, rc)) = read_color(&mut reader) {
618 colors.push(c);
619 raw_colors_vec.push(rc);
620 } else {
621 ok = false;
622 break;
623 }
624 }
625 }
626 if ok && points.len() == 16 && colors.len() == 4 {
627 patches.push(ShadingPatch {
628 points,
629 colors: [
630 colors[0].clone(),
631 colors[1].clone(),
632 colors[2].clone(),
633 colors[3].clone(),
634 ],
635 raw_colors: [
636 raw_colors_vec[0].clone(),
637 raw_colors_vec[1].clone(),
638 raw_colors_vec[2].clone(),
639 raw_colors_vec[3].clone(),
640 ],
641 });
642 }
643 }
644 1..=3 => {
645 if patches.is_empty() {
649 break;
650 }
651 let prev = patches.last().unwrap().clone();
652 let (inherited_pts, inherited_colors, inherited_raw) = match flag {
657 1 => (
658 prev.points[3..7].to_vec(),
659 [prev.colors[1].clone(), prev.colors[2].clone()],
660 [prev.raw_colors[1].clone(), prev.raw_colors[2].clone()],
661 ),
662 2 => (
663 prev.points[6..10].to_vec(),
664 [prev.colors[2].clone(), prev.colors[3].clone()],
665 [prev.raw_colors[2].clone(), prev.raw_colors[3].clone()],
666 ),
667 3 => (
668 vec![
669 prev.points[9],
670 prev.points[10],
671 prev.points[11],
672 prev.points[0],
673 ],
674 [prev.colors[3].clone(), prev.colors[0].clone()],
675 [prev.raw_colors[3].clone(), prev.raw_colors[0].clone()],
676 ),
677 _ => unreachable!(),
678 };
679
680 let mut points = inherited_pts; let mut ok = true;
683 for _ in 0..12 {
684 if let Some(pt) = read_point(&mut reader) {
685 points.push(pt);
686 } else {
687 ok = false;
688 break;
689 }
690 }
691 let mut colors = vec![inherited_colors[0].clone(), inherited_colors[1].clone()];
692 let mut raw_colors_vec = vec![inherited_raw[0].clone(), inherited_raw[1].clone()];
693 if ok {
694 for _ in 0..2 {
695 if let Some((c, rc)) = read_color(&mut reader) {
696 colors.push(c);
697 raw_colors_vec.push(rc);
698 } else {
699 ok = false;
700 break;
701 }
702 }
703 }
704 if ok && points.len() == 16 && colors.len() == 4 {
705 patches.push(ShadingPatch {
706 points,
707 colors: [
708 colors[0].clone(),
709 colors[1].clone(),
710 colors[2].clone(),
711 colors[3].clone(),
712 ],
713 raw_colors: [
714 raw_colors_vec[0].clone(),
715 raw_colors_vec[1].clone(),
716 raw_colors_vec[2].clone(),
717 raw_colors_vec[3].clone(),
718 ],
719 });
720 }
721 }
722 _ => break,
723 }
724 }
725
726 patches
727}
728
729pub fn build_type4_from_array(values: &[f64], n_comps: usize) -> Vec<ShadingTriangle> {
732 let stride = 3 + n_comps; let mut triangles = Vec::new();
734 let mut vertices: Vec<ShadingVertex> = Vec::new();
735 let mut pos = 0;
736
737 while pos + stride <= values.len() {
738 let flag = values[pos] as u32;
739 let x = values[pos + 1];
740 let y = values[pos + 2];
741 let comps: Vec<f64> = values[pos + 3..pos + 3 + n_comps].to_vec();
742 let (color, raw_components) = components_to_color(&comps);
743 let vertex = ShadingVertex {
744 x,
745 y,
746 color,
747 raw_components,
748 };
749 pos += stride;
750
751 match flag {
752 0 => {
753 vertices.clear();
754 vertices.push(vertex);
755 for _ in 0..2 {
756 if pos + stride > values.len() {
757 break;
758 }
759 let x2 = values[pos + 1];
760 let y2 = values[pos + 2];
761 let comps2: Vec<f64> = values[pos + 3..pos + 3 + n_comps].to_vec();
762 let (color2, raw2) = components_to_color(&comps2);
763 vertices.push(ShadingVertex {
764 x: x2,
765 y: y2,
766 color: color2,
767 raw_components: raw2,
768 });
769 pos += stride;
770 }
771 if vertices.len() == 3 {
772 triangles.push(ShadingTriangle {
773 v0: vertices[0].clone(),
774 v1: vertices[1].clone(),
775 v2: vertices[2].clone(),
776 });
777 }
778 }
779 1 => {
780 if vertices.len() >= 2 {
781 let len = vertices.len();
782 let v0 = vertices[len - 2].clone();
783 let v1 = vertices[len - 1].clone();
784 vertices.push(vertex);
785 let v2 = vertices.last().unwrap().clone();
786 triangles.push(ShadingTriangle { v0, v1, v2 });
787 }
788 }
789 2 => {
790 if vertices.len() >= 3 {
791 let len = vertices.len();
792 let v0 = vertices[len - 3].clone();
793 let v1 = vertices[len - 1].clone();
794 vertices.push(vertex);
795 let v2 = vertices.last().unwrap().clone();
796 triangles.push(ShadingTriangle { v0, v1, v2 });
797 }
798 }
799 _ => {}
800 }
801 }
802
803 triangles
804}
805
806pub fn build_type5_from_array(
809 values: &[f64],
810 n_comps: usize,
811 verts_per_row: usize,
812) -> Vec<ShadingTriangle> {
813 let stride = 2 + n_comps; let mut all_vertices = Vec::new();
815
816 let mut pos = 0;
817 while pos + stride <= values.len() {
818 let x = values[pos];
819 let y = values[pos + 1];
820 let comps: Vec<f64> = values[pos + 2..pos + 2 + n_comps].to_vec();
821 let (color, raw_components) = components_to_color(&comps);
822 all_vertices.push(ShadingVertex {
823 x,
824 y,
825 color,
826 raw_components,
827 });
828 pos += stride;
829 }
830
831 let mut triangles = Vec::new();
832 if verts_per_row < 2 {
833 return triangles;
834 }
835 let num_rows = all_vertices.len() / verts_per_row;
836 if num_rows < 2 {
837 return triangles;
838 }
839
840 for row in 0..num_rows - 1 {
841 for col in 0..verts_per_row - 1 {
842 let i00 = row * verts_per_row + col;
843 let i10 = i00 + 1;
844 let i01 = i00 + verts_per_row;
845 let i11 = i01 + 1;
846 if i11 >= all_vertices.len() {
847 break;
848 }
849 triangles.push(ShadingTriangle {
850 v0: all_vertices[i00].clone(),
851 v1: all_vertices[i10].clone(),
852 v2: all_vertices[i01].clone(),
853 });
854 triangles.push(ShadingTriangle {
855 v0: all_vertices[i10].clone(),
856 v1: all_vertices[i11].clone(),
857 v2: all_vertices[i01].clone(),
858 });
859 }
860 }
861
862 triangles
863}
864
865pub fn build_type6_from_array(values: &[f64], n_comps: usize) -> Vec<ShadingPatch> {
868 let full_stride = 1 + 24 + 4 * n_comps;
870 let cont_stride = 1 + 16 + 2 * n_comps;
872 let mut patches = Vec::new();
873 let mut pos = 0;
874
875 while pos < values.len() {
876 let flag = values[pos] as u32;
877 pos += 1;
878
879 match flag {
880 0 => {
881 if pos + 24 + 4 * n_comps > values.len() {
882 break;
883 }
884 let mut points = Vec::with_capacity(12);
885 for i in 0..12 {
886 points.push((values[pos + i * 2], values[pos + i * 2 + 1]));
887 }
888 pos += 24;
889 let mut colors = Vec::with_capacity(4);
890 let mut raw_colors_vec = Vec::with_capacity(4);
891 for _ in 0..4 {
892 let comps: Vec<f64> = values[pos..pos + n_comps].to_vec();
893 let (c, rc) = components_to_color(&comps);
894 colors.push(c);
895 raw_colors_vec.push(rc);
896 pos += n_comps;
897 }
898 let _ = full_stride; patches.push(ShadingPatch {
900 points,
901 colors: [
902 colors[0].clone(),
903 colors[1].clone(),
904 colors[2].clone(),
905 colors[3].clone(),
906 ],
907 raw_colors: [
908 raw_colors_vec[0].clone(),
909 raw_colors_vec[1].clone(),
910 raw_colors_vec[2].clone(),
911 raw_colors_vec[3].clone(),
912 ],
913 });
914 }
915 1..=3 => {
916 if patches.is_empty() {
917 break;
918 }
919 let prev = patches.last().unwrap().clone();
920 let (inherited_pts, inherited_colors, inherited_raw) = match flag {
926 1 => (
927 prev.points[3..7].to_vec(),
928 [prev.colors[1].clone(), prev.colors[2].clone()],
929 [prev.raw_colors[1].clone(), prev.raw_colors[2].clone()],
930 ),
931 2 => (
932 prev.points[6..10].to_vec(),
933 [prev.colors[2].clone(), prev.colors[3].clone()],
934 [prev.raw_colors[2].clone(), prev.raw_colors[3].clone()],
935 ),
936 3 => (
937 vec![
938 prev.points[9],
939 prev.points[10],
940 prev.points[11],
941 prev.points[0],
942 ],
943 [prev.colors[3].clone(), prev.colors[0].clone()],
944 [prev.raw_colors[3].clone(), prev.raw_colors[0].clone()],
945 ),
946 _ => unreachable!(),
947 };
948
949 if pos + 16 + 2 * n_comps > values.len() {
950 break;
951 }
952 let mut points = inherited_pts;
953 for i in 0..8 {
954 points.push((values[pos + i * 2], values[pos + i * 2 + 1]));
955 }
956 pos += 16;
957 let mut colors = vec![inherited_colors[0].clone(), inherited_colors[1].clone()];
958 let mut raw_colors_vec = vec![inherited_raw[0].clone(), inherited_raw[1].clone()];
959 for _ in 0..2 {
960 let comps: Vec<f64> = values[pos..pos + n_comps].to_vec();
961 let (c, rc) = components_to_color(&comps);
962 colors.push(c);
963 raw_colors_vec.push(rc);
964 pos += n_comps;
965 }
966 let _ = cont_stride;
967 patches.push(ShadingPatch {
968 points,
969 colors: [
970 colors[0].clone(),
971 colors[1].clone(),
972 colors[2].clone(),
973 colors[3].clone(),
974 ],
975 raw_colors: [
976 raw_colors_vec[0].clone(),
977 raw_colors_vec[1].clone(),
978 raw_colors_vec[2].clone(),
979 raw_colors_vec[3].clone(),
980 ],
981 });
982 }
983 _ => break,
984 }
985 }
986
987 patches
988}
989
990pub fn build_type7_from_array(values: &[f64], n_comps: usize) -> Vec<ShadingPatch> {
992 let full_stride = 1 + 32 + 4 * n_comps;
994 let _cont_stride = 1 + 24 + 2 * n_comps;
996 let mut patches = Vec::new();
997 let mut pos = 0;
998
999 while pos < values.len() {
1000 let flag = values[pos] as u32;
1001 pos += 1;
1002
1003 match flag {
1004 0 => {
1005 if pos + 32 + 4 * n_comps > values.len() {
1006 break;
1007 }
1008 let mut points = Vec::with_capacity(16);
1009 for i in 0..16 {
1010 points.push((values[pos + i * 2], values[pos + i * 2 + 1]));
1011 }
1012 pos += 32;
1013 let mut colors = Vec::with_capacity(4);
1014 let mut raw_colors_vec = Vec::with_capacity(4);
1015 for _ in 0..4 {
1016 let comps: Vec<f64> = values[pos..pos + n_comps].to_vec();
1017 let (c, rc) = components_to_color(&comps);
1018 colors.push(c);
1019 raw_colors_vec.push(rc);
1020 pos += n_comps;
1021 }
1022 let _ = full_stride;
1023 patches.push(ShadingPatch {
1024 points,
1025 colors: [
1026 colors[0].clone(),
1027 colors[1].clone(),
1028 colors[2].clone(),
1029 colors[3].clone(),
1030 ],
1031 raw_colors: [
1032 raw_colors_vec[0].clone(),
1033 raw_colors_vec[1].clone(),
1034 raw_colors_vec[2].clone(),
1035 raw_colors_vec[3].clone(),
1036 ],
1037 });
1038 }
1039 1..=3 => {
1040 if patches.is_empty() {
1041 break;
1042 }
1043 let prev = patches.last().unwrap().clone();
1044 let (inherited_pts, inherited_colors, inherited_raw) = match flag {
1047 1 => (
1048 vec![
1049 prev.points[3],
1050 prev.points[7],
1051 prev.points[11],
1052 prev.points[15],
1053 ],
1054 [prev.colors[1].clone(), prev.colors[2].clone()],
1055 [prev.raw_colors[1].clone(), prev.raw_colors[2].clone()],
1056 ),
1057 2 => (
1058 vec![
1059 prev.points[12],
1060 prev.points[8],
1061 prev.points[4],
1062 prev.points[0],
1063 ],
1064 [prev.colors[3].clone(), prev.colors[0].clone()],
1065 [prev.raw_colors[3].clone(), prev.raw_colors[0].clone()],
1066 ),
1067 3 => (
1068 vec![
1069 prev.points[15],
1070 prev.points[14],
1071 prev.points[13],
1072 prev.points[12],
1073 ],
1074 [prev.colors[2].clone(), prev.colors[3].clone()],
1075 [prev.raw_colors[2].clone(), prev.raw_colors[3].clone()],
1076 ),
1077 _ => unreachable!(),
1078 };
1079
1080 if pos + 24 + 2 * n_comps > values.len() {
1081 break;
1082 }
1083 let mut points = inherited_pts; for i in 0..12 {
1085 points.push((values[pos + i * 2], values[pos + i * 2 + 1]));
1086 }
1087 pos += 24;
1088 let mut colors = vec![inherited_colors[0].clone(), inherited_colors[1].clone()];
1089 let mut raw_colors_vec = vec![inherited_raw[0].clone(), inherited_raw[1].clone()];
1090 for _ in 0..2 {
1091 let comps: Vec<f64> = values[pos..pos + n_comps].to_vec();
1092 let (c, rc) = components_to_color(&comps);
1093 colors.push(c);
1094 raw_colors_vec.push(rc);
1095 pos += n_comps;
1096 }
1097 patches.push(ShadingPatch {
1098 points,
1099 colors: [
1100 colors[0].clone(),
1101 colors[1].clone(),
1102 colors[2].clone(),
1103 colors[3].clone(),
1104 ],
1105 raw_colors: [
1106 raw_colors_vec[0].clone(),
1107 raw_colors_vec[1].clone(),
1108 raw_colors_vec[2].clone(),
1109 raw_colors_vec[3].clone(),
1110 ],
1111 });
1112 }
1113 _ => break,
1114 }
1115 }
1116
1117 patches
1118}
1119
1120#[cfg(test)]
1121mod tests {
1122 use super::*;
1123
1124 #[test]
1125 fn test_bit_reader_aligned() {
1126 let data = [0xAB, 0xCD, 0xEF, 0x01];
1127 let mut reader = BitReader::new(&data);
1128 assert_eq!(reader.read(8), Some(0xAB));
1129 assert_eq!(reader.read(8), Some(0xCD));
1130 assert_eq!(reader.read(16), Some(0xEF01));
1131 assert!(reader.exhausted());
1132 }
1133
1134 #[test]
1135 fn test_bit_reader_unaligned() {
1136 let data = [0b10110100, 0b11010010];
1137 let mut reader = BitReader::new(&data);
1138 assert_eq!(reader.read(4), Some(0b1011));
1139 assert_eq!(reader.read(4), Some(0b0100));
1140 assert_eq!(reader.read(4), Some(0b1101));
1141 assert_eq!(reader.read(4), Some(0b0010));
1142 assert!(reader.exhausted());
1143 }
1144
1145 #[test]
1146 fn test_bit_reader_cross_byte() {
1147 let data = [0b11110000, 0b10101010];
1148 let mut reader = BitReader::new(&data);
1149 assert_eq!(reader.read(6), Some(0b111100));
1150 assert_eq!(reader.read(6), Some(0b001010));
1151 assert_eq!(reader.read(4), Some(0b1010));
1152 assert!(reader.exhausted());
1153 }
1154
1155 #[test]
1156 fn test_decode_scale_8bit() {
1157 let scale = decode_scale(8, 0.0, 1.0);
1158 assert!((scale - 1.0 / 255.0).abs() < 1e-10);
1159 let val = decode_value(128, scale, 0.0);
1160 assert!((val - 128.0 / 255.0).abs() < 1e-10);
1161 }
1162
1163 #[test]
1164 fn test_type5_lattice_simple() {
1165 #[rustfmt::skip]
1169 let data = [
1170 0, 0, 0, 255, 0, 128, 0, 255, 0, 255, 255, 255, ];
1175 let decode = [0.0, 255.0, 0.0, 255.0, 0.0, 1.0];
1176 let triangles = parse_type5_mesh(&data, 8, 8, &decode, 1, 2);
1177 assert_eq!(triangles.len(), 2);
1178 }
1179}