1use crate::codec::compressed::fenwick::context_switching::FenwickModel;
2use crate::codec::compressed::source_model::cabac_contexts::{
3 Contexts, BITSHIFT_ENCODE_FULL, D_RESIDUAL_OFFSET,
4};
5use crate::codec::compressed::source_model::event_structure::BLOCK_SIZE;
6use crate::codec::compressed::source_model::{ComponentCompression, HandleEvent};
7use crate::codec::compressed::{DResidual, TResidual, DRESIDUAL_NO_EVENT, DRESIDUAL_SKIP_CUBE};
8use crate::codec::CodecError;
9use crate::{AbsoluteT, Coord, DeltaT, Event, EventCoordless, PixelAddress, D, D_EMPTY};
10use arithmetic_coding_adder_dep::{Decoder, Encoder};
11use bitstream_io::{BigEndian, BitReader, BitWriter};
12use std::cmp::{max, min};
13use std::collections::VecDeque;
14use std::io::Cursor;
15use std::mem::size_of;
16
17type Pixel = Vec<EventCoordless>;
18
19type EventLists = [[[Pixel; BLOCK_SIZE]; BLOCK_SIZE]; 3];
20
21#[derive(PartialEq, Debug, Clone, Default)]
22pub struct EventCube {
23 pub(crate) start_y: PixelAddress,
25
26 pub(crate) start_x: PixelAddress,
28
29 num_channels: usize,
30
31 pub(crate) raw_event_lists: EventLists,
33
34 pub(crate) start_t: AbsoluteT,
37
38 dt_ref: DeltaT,
40
41 num_intervals: usize,
43
44 raw_event_memory: [[[EventCoordless; BLOCK_SIZE]; BLOCK_SIZE]; 3],
45
46 skip_cube: bool,
47
48 decompressed_event_queue: VecDeque<Event>,
49}
50
51impl EventCube {
52 pub fn new(
53 start_y: PixelAddress,
54 start_x: PixelAddress,
55 num_channels: usize,
56 start_t: AbsoluteT,
57 dt_ref: DeltaT,
58 num_intervals: usize,
59 ) -> Self {
60 let row: [Pixel; BLOCK_SIZE] = vec![Vec::with_capacity(num_intervals); BLOCK_SIZE]
61 .try_into()
62 .unwrap();
63 let square: [[Pixel; BLOCK_SIZE]; BLOCK_SIZE] = vec![row; BLOCK_SIZE].try_into().unwrap();
64 let lists = [square.clone(), square.clone(), square];
65
66 Self {
67 start_y,
68 start_x,
69 num_channels,
70 raw_event_lists: lists,
71 start_t,
72 dt_ref,
73 num_intervals,
74 raw_event_memory: [[[EventCoordless::default(); BLOCK_SIZE]; BLOCK_SIZE]; 3],
75 skip_cube: true,
76 decompressed_event_queue: Default::default(),
77 }
78 }
79}
80
81fn generate_t_prediction(
82 idx: usize,
83 mut d_residual: DResidual,
84 last_delta_t: DeltaT,
85 prev_event: &EventCoordless,
86 num_intervals: usize,
87 dt_ref: DeltaT,
88 start_t: AbsoluteT,
89) -> AbsoluteT {
90 if idx == 1 {
91 start_t + last_delta_t as AbsoluteT
93 } else {
94 if d_residual.abs() > 14 {
95 d_residual = 0;
96 }
97 if prev_event.d == D_EMPTY {
98 d_residual = -1;
99 }
100 let delta_t_prediction: DeltaT = if d_residual < 0 {
103 last_delta_t >> -d_residual
104 } else {
105 last_delta_t << d_residual
106 };
107 max(
108 prev_event.t,
109 prev_event.t
110 + min(delta_t_prediction, (num_intervals as u8) as u32 * dt_ref) as AbsoluteT,
111 )
112 }
113}
114
115impl HandleEvent for EventCube {
116 fn ingest_event(&mut self, mut event: Event) -> bool {
122 event.coord.y -= self.start_y;
123 event.coord.x -= self.start_x;
124
125 let item = EventCoordless::from(event);
126
127 if self.raw_event_lists[event.coord.c_usize()][event.coord.y_usize()][event.coord.x_usize()]
128 .len()
129 > 1
130 {
131 let last = self.raw_event_lists[event.coord.c_usize()][event.coord.y_usize()]
132 [event.coord.x_usize()][self.raw_event_lists[event.coord.c_usize()]
133 [event.coord.y_usize()][event.coord.x_usize()]
134 .len()
135 - 1];
136 if event.t <= last.t {
137 return false;
139 }
140 debug_assert!(event.t >= last.t);
141 }
142
143 self.raw_event_lists[event.coord.c_usize()][event.coord.y_usize()][event.coord.x_usize()]
144 .push(item);
145
146 self.raw_event_memory[event.coord.c_usize()][event.coord.y_usize()]
147 [event.coord.x_usize()] = EventCoordless::from(event);
148
149 if self.skip_cube {
150 self.skip_cube = false;
151 true
152 } else {
153 false
154 }
155 }
156
157 fn digest_event(&mut self) -> Result<Event, CodecError> {
158 if self.skip_cube {
159 return Err(CodecError::NoMoreEvents);
160 } else if self.decompressed_event_queue.is_empty() {
164 for c in 0..self.num_channels {
166 for y in 0..BLOCK_SIZE {
167 for x in 0..BLOCK_SIZE {
168 if !self.raw_event_lists[c][y][x].is_empty() {
169 for event in self.raw_event_lists[c][y][x].iter() {
170 let event = Event {
171 coord: Coord {
172 x: x as PixelAddress + self.start_x,
173 y: y as PixelAddress + self.start_y,
174 c: if self.num_channels == 1 {
175 None
176 } else {
177 Some(c as u8)
178 },
179 },
180 d: event.d,
181 t: event.t,
182 };
183 self.decompressed_event_queue.push_back(event);
184 }
185 }
186 }
187 }
188 }
189 }
190
191 if let Some(event) = self.decompressed_event_queue.pop_front() {
192 if self.decompressed_event_queue.is_empty() {
193 self.skip_cube = true;
194 }
195 Ok(event)
196 } else {
197 Err(CodecError::NoMoreEvents)
198 }
199 }
200
201 fn clear_compression(&mut self) {
203 for c in 0..3 {
204 for y in 0..BLOCK_SIZE {
205 for x in 0..BLOCK_SIZE {
206 self.raw_event_lists[c][y][x].clear();
207 }
208 }
209 }
210 self.start_t += self.num_intervals as AbsoluteT * self.dt_ref;
211 self.skip_cube = true;
212 }
213 fn clear_decompression(&mut self) {
214 for c in 0..3 {
215 for y in 0..BLOCK_SIZE {
216 for x in 0..BLOCK_SIZE {
217 self.raw_event_lists[c][y][x].clear();
218 }
219 }
220 }
221 self.start_t += self.num_intervals as AbsoluteT * self.dt_ref;
222 self.skip_cube = true;
223 }
224}
225
226#[cfg(test)]
227mod build_tests {
228 use super::EventCube;
229 use crate::codec::compressed::source_model::HandleEvent;
230 use crate::{Coord, Event};
231
232 #[test]
234 fn create_cube() -> Result<(), Box<dyn std::error::Error>> {
235 let cube = EventCube::new(16, 16, 1, 255, 255, 2550);
236 assert_eq!(cube.start_y, 16);
237 assert_eq!(cube.start_x, 16);
238
239 Ok(())
240 }
241
242 fn fill_cube() -> Result<EventCube, Box<dyn std::error::Error>> {
244 let mut cube = EventCube::new(16, 16, 1, 255, 255, 2550);
245 assert_eq!(cube.start_y, 16);
246 assert_eq!(cube.start_x, 16);
247
248 cube.ingest_event(Event {
249 coord: Coord {
250 x: 27,
251 y: 17,
252 c: None,
253 },
254 t: 280,
255 d: 7,
256 });
257
258 cube.ingest_event(Event {
259 coord: Coord {
260 x: 27,
261 y: 17,
262 c: None,
263 },
264 t: 285,
265 d: 7,
266 });
267
268 cube.ingest_event(Event {
269 coord: Coord {
270 x: 29,
271 y: 17,
272 c: None,
273 },
274 t: 290,
275 d: 7,
276 });
277
278 Ok(cube)
279 }
280 #[test]
281 fn test_fill_cube() -> Result<(), Box<dyn std::error::Error>> {
282 let cube = fill_cube()?;
283 assert!(cube.raw_event_lists[0][0][0].is_empty());
284 assert_eq!(cube.raw_event_lists[0][1][13].len(), 1);
285
286 Ok(())
287 }
288
289 #[test]
290 fn fill_second_cube() -> Result<(), Box<dyn std::error::Error>> {
291 let mut cube = fill_cube()?;
292 cube.clear_compression();
293 assert_eq!(cube.raw_event_lists[0][1][13].len(), 0);
294 cube.ingest_event(Event {
295 coord: Coord {
296 x: 29,
297 y: 17,
298 c: None,
299 },
300 t: 500,
301 d: 7,
302 });
303 assert_eq!(cube.raw_event_lists[0][1][13].len(), 1);
304 Ok(())
305 }
306}
307
308impl ComponentCompression for EventCube {
309 fn compress_intra(
310 &mut self,
311 encoder: &mut Encoder<FenwickModel, BitWriter<Vec<u8>, BigEndian>>,
312 contexts: &Contexts,
313 stream: &mut BitWriter<Vec<u8>, BigEndian>,
314 _: Option<u8>,
315 ) -> Result<(), CodecError> {
316 encoder.model.set_context(contexts.d_context);
317 if self.skip_cube {
318 let tmp = (DRESIDUAL_SKIP_CUBE + D_RESIDUAL_OFFSET) as usize;
320 encoder.encode(Some(&tmp), stream).unwrap();
321 return Ok(()); }
326
327 let mut init_event: Option<EventCoordless> = None;
328 let mut d_residual = 0;
329
330 for c in 0..self.num_channels {
332 self.raw_event_lists[c].iter_mut().for_each(|row| {
333 row.iter_mut().for_each(|pixel| {
334 encoder.model.set_context(contexts.d_context);
335
336 if !pixel.is_empty() {
337 let event = pixel.first_mut().unwrap();
338
339 if let Some(init) = &mut init_event {
340 d_residual = event.d as DResidual - init.d as DResidual;
341 let tmp = (d_residual + D_RESIDUAL_OFFSET) as usize;
344 encoder.encode(Some(&tmp), stream).unwrap();
345 } else {
349 let tmp = (event.d as DResidual + D_RESIDUAL_OFFSET) as usize;
351 encoder.encode(Some(&tmp), stream).unwrap();
352 init_event = Some(EventCoordless {
358 d: event.d,
359 t: self.start_t,
360 })
361 }
362
363 if let Some(init) = &mut init_event {
364 let t_residual_i64 = event.t as i64 - init.t as i64;
366 let (bitshift_amt, t_residual) =
367 contexts.residual_to_bitshift(t_residual_i64);
368 encoder.model.set_context(contexts.bitshift_context);
377 for byte in bitshift_amt.to_be_bytes().iter() {
378 encoder.encode(Some(&(*byte as usize)), stream).unwrap();
379 }
380
381 encoder.model.set_context(contexts.t_context);
382
383 if bitshift_amt == BITSHIFT_ENCODE_FULL {
384 for byte in t_residual.to_be_bytes().iter() {
385 encoder.encode(Some(&(*byte as usize)), stream).unwrap();
386 }
387 event.t = (init.t as i64 + t_residual) as AbsoluteT;
388 } else {
389 let t_residual = t_residual as TResidual;
390 for byte in t_residual.to_be_bytes().iter() {
391 encoder.encode(Some(&(*byte as usize)), stream).unwrap();
392 }
393 event.t = (init.t as i64
396 + ((t_residual as i64) << bitshift_amt as i64))
397 as AbsoluteT;
398 }
399 debug_assert!(event.t < 2_u32.pow(31));
400
401 *init = *event;
402 } else {
403 panic!("No init event");
404 }
405 } else {
406 let tmp = (DRESIDUAL_NO_EVENT + D_RESIDUAL_OFFSET) as usize;
408 encoder.encode(Some(&tmp), stream).unwrap();
409 }
413 })
414 })
415 }
416 Ok(())
417 }
418
419 fn compress_inter(
420 &mut self,
421 encoder: &mut Encoder<FenwickModel, BitWriter<Vec<u8>, BigEndian>>,
422 contexts: &Contexts,
423 stream: &mut BitWriter<Vec<u8>, BigEndian>,
424 c_thresh_max: Option<u8>,
425 ) -> Result<(), CodecError> {
426 if self.skip_cube {
427 return Ok(());
428 }
429 let c_thresh_max = c_thresh_max.unwrap_or(7);
430 for c in 0..self.num_channels {
431 self.raw_event_lists[c].iter_mut().for_each(|row| {
432 row.iter_mut().for_each(|pixel| {
433 if !pixel.is_empty() {
434 let mut idx = 1;
435 let mut last_delta_t: DeltaT = 0;
436 loop {
437 encoder.model.set_context(contexts.d_context);
438
439 if idx < pixel.len() {
440 let prev_event = pixel[idx - 1]; let event = &mut pixel[idx];
443
444 let d_residual = event.d as DResidual - prev_event.d as DResidual;
446 for byte in d_residual.to_be_bytes().iter() {
448 encoder.encode(Some(&(*byte as usize)), stream).unwrap();
449 }
450
451 let t_prediction = generate_t_prediction(
452 idx,
453 d_residual,
454 last_delta_t,
455 &prev_event,
456 self.num_intervals,
457 self.dt_ref,
458 self.start_t,
459 );
460
461 let t_residual_i64 = event.t as i64 - t_prediction as i64;
463 let (bitshift_amt, t_residual) = contexts.residual_to_bitshift2(
464 t_prediction as i64,
465 t_residual_i64,
466 event,
467 &prev_event,
468 self.dt_ref,
469 c_thresh_max as f64,
470 );
471
472 encoder.model.set_context(contexts.bitshift_context);
473 for byte in bitshift_amt.to_be_bytes().iter() {
474 encoder.encode(Some(&(*byte as usize)), stream).unwrap();
475 }
476
477 encoder.model.set_context(contexts.t_context);
478
479 if bitshift_amt == BITSHIFT_ENCODE_FULL {
480 for byte in t_residual.to_be_bytes().iter() {
481 encoder.encode(Some(&(*byte as usize)), stream).unwrap();
482 }
483 event.t = (t_prediction as i64 + t_residual) as AbsoluteT;
484 } else {
486 let t_residual = t_residual as TResidual;
487 for byte in t_residual.to_be_bytes().iter() {
488 encoder.encode(Some(&(*byte as usize)), stream).unwrap();
489 }
490 event.t = (t_prediction as i64
493 + ((t_residual as i64) << bitshift_amt as i64))
494 as AbsoluteT;
495 }
497
498 event.t = max(event.t, prev_event.t);
499 debug_assert!(event.t >= prev_event.t);
500 last_delta_t = (event.t - prev_event.t) as DeltaT;
501 } else {
502 encoder.model.set_context(contexts.d_context);
503 for byte in (DRESIDUAL_NO_EVENT).to_be_bytes().iter() {
505 encoder.encode(Some(&(*byte as usize)), stream).unwrap();
506 }
507
508 break;
509 }
510 idx += 1;
511 }
512 }
513 })
514 })
515 }
516 Ok(())
517 }
518
519 fn decompress_intra(
520 &mut self,
521 decoder: &mut Decoder<FenwickModel, BitReader<Cursor<Vec<u8>>, BigEndian>>,
522 contexts: &Contexts,
523 stream: &mut BitReader<Cursor<Vec<u8>>, BigEndian>,
524 start_t: AbsoluteT,
525 ) {
526 let mut bitshift_buffer = [0u8; 1];
527 let mut t_residual_buffer = [0u8; size_of::<TResidual>()];
528 let mut t_residual_full_buffer = [0u8; size_of::<i64>()];
529 let mut init_event: Option<EventCoordless> = None;
530
531 for c in 0..self.num_channels {
532 for y in 0..BLOCK_SIZE {
533 for x in 0..BLOCK_SIZE {
534 let pixel = &mut self.raw_event_lists[c][y][x];
535
536 decoder.model.set_context(contexts.d_context);
537
538 let tmp = decoder.decode(stream).unwrap().unwrap();
539 let d_residual = tmp as i16 - D_RESIDUAL_OFFSET;
540
541 if d_residual == DRESIDUAL_SKIP_CUBE {
542 pixel.clear(); self.skip_cube = true;
544 return;
545 } else if d_residual == DRESIDUAL_NO_EVENT {
546 pixel.clear(); } else {
548 let d = if let Some(init) = &mut init_event {
549 (init.d as DResidual + d_residual) as D
550 } else {
551 init_event = Some(EventCoordless { d: 0, t: start_t });
553 self.skip_cube = false;
554 d_residual as D
555 };
556
557 if let Some(init) = &mut init_event {
558 decoder.model.set_context(contexts.bitshift_context);
565 for byte in bitshift_buffer.iter_mut() {
566 *byte = decoder.decode(stream).unwrap().unwrap() as u8;
567 }
568 let bitshift_amt = bitshift_buffer[0];
569
570 decoder.model.set_context(contexts.t_context);
571 let t_residual = if bitshift_amt == BITSHIFT_ENCODE_FULL {
572 for byte in t_residual_full_buffer.iter_mut() {
573 *byte = decoder.decode(stream).unwrap().unwrap() as u8;
574 }
575 i64::from_be_bytes(t_residual_full_buffer)
576 } else {
577 for byte in t_residual_buffer.iter_mut() {
578 *byte = decoder.decode(stream).unwrap().unwrap() as u8;
579 }
580 let t_residual = TResidual::from_be_bytes(t_residual_buffer) as i64;
581 (t_residual) << bitshift_amt as i64
582 };
583
584 init.d = (init.d as DResidual + d_residual) as D;
585
586 debug_assert!(init.t as i64 + t_residual >= 0);
587 init.t = (init.t as i64 + t_residual) as AbsoluteT;
588
589 pixel.push(EventCoordless { d, t: init.t });
591 } else {
592 panic!("No init event");
593 }
594 }
595 }
596 }
597 }
598 }
599
600 fn decompress_inter(
601 &mut self,
602 decoder: &mut Decoder<FenwickModel, BitReader<Cursor<Vec<u8>>, BigEndian>>,
603 contexts: &Contexts,
604 stream: &mut BitReader<Cursor<Vec<u8>>, BigEndian>,
605 ) {
606 if self.skip_cube {
607 return;
608 }
609 let mut d_residual_buffer = [0u8; size_of::<DResidual>()];
610 let mut t_residual_buffer = [0u8; size_of::<TResidual>()];
611 let mut t_residual_full_buffer = [0u8; size_of::<i64>()];
612 let mut bitshift_buffer = [0u8; 1];
613
614 for c in 0..self.num_channels {
615 self.raw_event_lists[c].iter_mut().for_each(|row| {
616 row.iter_mut().for_each(|pixel| {
617 if !pixel.is_empty() {
618 let mut idx = 1;
620 let mut last_delta_t = 0;
621 loop {
622 decoder.model.set_context(contexts.d_context);
623
624 for byte in d_residual_buffer.iter_mut() {
625 *byte = decoder.decode(stream).unwrap().unwrap() as u8;
626 }
627 let d_residual = DResidual::from_be_bytes(d_residual_buffer);
628
629 if d_residual == DRESIDUAL_NO_EVENT {
630 break; }
632 debug_assert!(idx - 1 < pixel.len());
633 let prev_event = pixel[idx - 1];
634
635 let d = (prev_event.d as DResidual + d_residual) as D;
636
637 let t_prediction = generate_t_prediction(
638 idx,
639 d_residual,
640 last_delta_t,
641 &prev_event,
642 self.num_intervals,
643 self.dt_ref,
644 self.start_t,
645 );
646
647 decoder.model.set_context(contexts.bitshift_context);
648 for byte in bitshift_buffer.iter_mut() {
649 *byte = decoder.decode(stream).unwrap().unwrap() as u8;
650 }
651 let bitshift_amt = bitshift_buffer[0];
652
653 decoder.model.set_context(contexts.t_context);
654 let t_residual = if bitshift_amt == BITSHIFT_ENCODE_FULL {
655 for byte in t_residual_full_buffer.iter_mut() {
656 *byte = decoder.decode(stream).unwrap().unwrap() as u8;
657 }
658 i64::from_be_bytes(t_residual_full_buffer)
659 } else {
660 for byte in t_residual_buffer.iter_mut() {
661 *byte = decoder.decode(stream).unwrap().unwrap() as u8;
662 }
663 let t_residual = TResidual::from_be_bytes(t_residual_buffer) as i64;
664 (t_residual) << bitshift_amt as i64
665 };
666
667 let t = max(
668 (t_prediction as i64 + t_residual) as AbsoluteT,
669 prev_event.t,
670 );
671 debug_assert!(t >= prev_event.t);
672 last_delta_t = (t - prev_event.t) as DeltaT;
673 pixel.push(EventCoordless { d, t });
677
678 idx += 1;
679 }
680 }
681 });
682 });
683 }
684 }
685}
686
687#[cfg(test)]
688mod compression_tests {
689 use crate::codec::compressed::fenwick::context_switching::FenwickModel;
690 use crate::codec::compressed::source_model::cabac_contexts::eof_context;
691 use crate::codec::compressed::source_model::event_structure::event_cube::EventCube;
692 use crate::codec::compressed::source_model::{ComponentCompression, HandleEvent};
693 use crate::{Coord, Event};
694 use arithmetic_coding_adder_dep::Encoder;
695 use bitstream_io::{BigEndian, BitReader, BitWriter};
696 use rand::prelude::StdRng;
697 use rand::{Rng, SeedableRng};
698 use std::cmp::min;
699 use std::error::Error;
700 use std::io::Cursor;
701
702 #[test]
703 fn compress_and_decompress_intra() -> Result<(), Box<dyn Error>> {
704 let mut cube = EventCube::new(0, 0, 1, 255, 255, 10);
705 let mut counter = 0;
706 for _ in 0..3 {
707 for y in 0..16 {
708 for x in 0..15 {
709 cube.ingest_event(Event {
710 coord: Coord { x, y, c: None },
711 t: 280 + counter,
712 d: 7,
713 });
714 counter += 1;
715 }
716 }
717 }
718
719 let bufwriter = Vec::new();
720 let mut stream = BitWriter::endian(bufwriter, BigEndian);
721
722 let mut source_model = FenwickModel::with_symbols(u16::MAX as usize, 1 << 30);
723 let contexts = crate::codec::compressed::source_model::cabac_contexts::Contexts::new(
724 &mut source_model,
725 255,
726 );
727
728 let mut encoder = Encoder::new(source_model);
729
730 cube.compress_intra(&mut encoder, &contexts, &mut stream, None)?;
731 eof_context(&contexts, &mut encoder, &mut stream);
732
733 let mut source_model = FenwickModel::with_symbols(u16::MAX as usize, 1 << 30);
734 let contexts = crate::codec::compressed::source_model::cabac_contexts::Contexts::new(
735 &mut source_model,
736 255,
737 );
738 let mut decoder = arithmetic_coding_adder_dep::Decoder::new(source_model);
739 let mut stream = BitReader::endian(Cursor::new(stream.into_writer()), BigEndian);
740
741 let mut cube2 = cube.clone();
742
743 cube2.decompress_intra(&mut decoder, &contexts, &mut stream, 255);
744
745 for c in 0..3 {
746 for y in 0..16 {
747 for x in 0..16 {
748 dbg!(c, y, x);
749 dbg!(
750 &cube.raw_event_lists[c][y][x],
751 &cube2.raw_event_lists[c][y][x]
752 );
753 if !cube.raw_event_lists[c][y][x].is_empty() {
754 assert!(!cube2.raw_event_lists[c][y][x].is_empty());
755 assert_eq!(
756 cube.raw_event_lists[c][y][x][0],
757 cube2.raw_event_lists[c][y][x][0]
758 );
759 } else {
760 assert!(cube2.raw_event_lists[c][y][x].is_empty());
761 }
762 }
763 }
764 }
765
766 Ok(())
767 }
768
769 #[test]
770 fn compress_and_decompress_inter() -> Result<(), Box<dyn Error>> {
771 let mut cube = EventCube::new(0, 0, 1, 255, 255, 2);
772 let mut counter = 0;
773 for _ in 0..3 {
774 for y in 0..16 {
775 for x in 0..15 {
776 cube.ingest_event(Event {
777 coord: Coord { x, y, c: None },
778 t: min(
779 280 + counter,
780 cube.start_t + (cube.num_intervals as u32 - 1) * cube.dt_ref,
781 ),
782 d: 7,
783 });
784 counter += 1;
785 }
786 }
787 }
788
789 let mut rng = StdRng::seed_from_u64(1234);
790
791 for y in 0..16 {
792 for x in 0..15 {
793 for _ in 0..rng.gen_range(0..3) {
794 cube.ingest_event(Event {
795 coord: Coord { x, y, c: None },
796 t: min(
797 280 + counter,
798 cube.start_t + (cube.num_intervals as u32 - 1) * cube.dt_ref,
799 ),
800 d: rng.gen_range(4..12),
801 });
802 counter += 1;
803 }
804 }
805 }
806
807 let bufwriter = Vec::new();
808 let mut stream = BitWriter::endian(bufwriter, BigEndian);
809
810 let mut source_model = FenwickModel::with_symbols(u16::MAX as usize, 1 << 30);
811 let contexts = crate::codec::compressed::source_model::cabac_contexts::Contexts::new(
812 &mut source_model,
813 255,
814 );
815
816 let mut encoder = Encoder::new(source_model);
817
818 cube.compress_intra(&mut encoder, &contexts, &mut stream, Some(0))?;
819 cube.compress_inter(&mut encoder, &contexts, &mut stream, Some(0))?;
820
821 eof_context(&contexts, &mut encoder, &mut stream);
822
823 let mut source_model = FenwickModel::with_symbols(u16::MAX as usize, 1 << 30);
824 let contexts = crate::codec::compressed::source_model::cabac_contexts::Contexts::new(
825 &mut source_model,
826 255,
827 );
828 let mut decoder = arithmetic_coding_adder_dep::Decoder::new(source_model);
829 let mut stream = BitReader::endian(Cursor::new(stream.into_writer()), BigEndian);
830
831 let mut cube2 = cube.clone();
832 cube2.decompress_intra(&mut decoder, &contexts, &mut stream, 255);
833 cube2.decompress_inter(&mut decoder, &contexts, &mut stream);
834
835 for c in 0..3 {
836 for y in 0..16 {
837 for x in 0..16 {
838 if !cube.raw_event_lists[c][y][x].is_empty() {
839 assert!(!cube2.raw_event_lists[c][y][x].is_empty());
840 assert_eq!(
841 cube.raw_event_lists[c][y][x][0],
842 cube2.raw_event_lists[c][y][x][0]
843 );
844 for i in 0..cube.raw_event_lists[c][y][x].len() {
845 assert_eq!(
846 cube.raw_event_lists[c][y][x][i],
847 cube2.raw_event_lists[c][y][x][i]
848 );
849 }
850 } else {
851 assert!(cube2.raw_event_lists[c][y][x].is_empty());
852 }
853 }
854 }
855 }
856
857 Ok(())
858 }
859
860 #[test]
861 fn compress_and_decompress_empty() -> Result<(), Box<dyn Error>> {
862 let mut cube = EventCube::new(0, 0, 1, 255, 255, 10);
863
864 let bufwriter = Vec::new();
865 let mut stream = BitWriter::endian(bufwriter, BigEndian);
866
867 let mut source_model = FenwickModel::with_symbols(u16::MAX as usize, 1 << 30);
868 let contexts = crate::codec::compressed::source_model::cabac_contexts::Contexts::new(
869 &mut source_model,
870 255,
871 );
872
873 let mut encoder = Encoder::new(source_model);
874
875 cube.compress_intra(&mut encoder, &contexts, &mut stream, Some(0))?;
876 cube.compress_inter(&mut encoder, &contexts, &mut stream, Some(0))?;
877
878 eof_context(&contexts, &mut encoder, &mut stream);
879
880 let mut source_model = FenwickModel::with_symbols(u16::MAX as usize, 1 << 30);
881 let contexts = crate::codec::compressed::source_model::cabac_contexts::Contexts::new(
882 &mut source_model,
883 255,
884 );
885 let mut decoder = arithmetic_coding_adder_dep::Decoder::new(source_model);
886 let mut stream = BitReader::endian(Cursor::new(stream.into_writer()), BigEndian);
887
888 let mut cube2 = cube.clone();
889 cube2.decompress_intra(&mut decoder, &contexts, &mut stream, 255);
890 cube2.decompress_inter(&mut decoder, &contexts, &mut stream);
891
892 for c in 0..3 {
893 for y in 0..16 {
894 for x in 0..16 {
895 if !cube.raw_event_lists[c][y][x].is_empty() {
896 assert!(!cube2.raw_event_lists[c][y][x].is_empty());
897 assert_eq!(
898 cube.raw_event_lists[c][y][x][0],
899 cube2.raw_event_lists[c][y][x][0]
900 );
901 assert_eq!(
902 cube.raw_event_lists[c][y][x],
903 cube2.raw_event_lists[c][y][x]
904 );
905 } else {
906 assert!(cube2.raw_event_lists[c][y][x].is_empty());
907 }
908 }
909 }
910 }
911
912 Ok(())
913 }
914
915 #[test]
916 fn compress_and_decompress_intra_huge_tresidual() -> Result<(), Box<dyn Error>> {
917 let num_intervals = 2;
918 let mut cube = EventCube::new(0, 0, 1, 255000, 255, num_intervals);
919
920 cube.ingest_event(Event {
921 coord: Coord {
922 x: 3,
923 y: 3,
924 c: None,
925 },
926 t: 255001,
927 d: 7,
928 });
929 cube.ingest_event(Event {
930 coord: Coord {
931 x: 4,
932 y: 3,
933 c: None,
934 },
935 t: 280,
936 d: 7,
937 });
938
939 let bufwriter = Vec::new();
940 let mut stream = BitWriter::endian(bufwriter, BigEndian);
941
942 let mut source_model = FenwickModel::with_symbols(u16::MAX as usize, 1 << 30);
943 let contexts = crate::codec::compressed::source_model::cabac_contexts::Contexts::new(
944 &mut source_model,
945 255,
946 );
947
948 let mut encoder = Encoder::new(source_model);
949
950 cube.compress_intra(&mut encoder, &contexts, &mut stream, Some(0))?;
951 cube.compress_inter(&mut encoder, &contexts, &mut stream, Some(0))?;
952
953 eof_context(&contexts, &mut encoder, &mut stream);
954
955 let mut source_model = FenwickModel::with_symbols(u16::MAX as usize, 1 << 30);
956 let contexts = crate::codec::compressed::source_model::cabac_contexts::Contexts::new(
957 &mut source_model,
958 255,
959 );
960 let mut decoder = arithmetic_coding_adder_dep::Decoder::new(source_model);
961 let mut stream = BitReader::endian(Cursor::new(stream.into_writer()), BigEndian);
962
963 let mut cube2 = cube.clone();
964 cube2.decompress_intra(&mut decoder, &contexts, &mut stream, 255000);
965 cube2.decompress_inter(&mut decoder, &contexts, &mut stream);
966
967 assert_eq!(
969 cube.raw_event_lists[0][3][3][0].t,
970 cube2.raw_event_lists[0][3][3][0].t
971 );
972 assert_eq!(
973 cube.raw_event_lists[0][3][4][0].t,
974 cube2.raw_event_lists[0][3][4][0].t
975 );
976
977 Ok(())
978 }
979
980 #[test]
981 fn compress_and_decompress_inter_huge_tresidual() -> Result<(), Box<dyn Error>> {
982 let num_intervals = 2;
983 let mut cube = EventCube::new(0, 0, 1, 255000, 255, num_intervals);
984
985 cube.ingest_event(Event {
986 coord: Coord {
987 x: 3,
988 y: 3,
989 c: None,
990 },
991 t: 255001,
992 d: 7,
993 });
994 cube.ingest_event(Event {
995 coord: Coord {
996 x: 4,
997 y: 3,
998 c: None,
999 },
1000 t: 280,
1001 d: 7,
1002 });
1003 cube.ingest_event(Event {
1004 coord: Coord {
1005 x: 4,
1006 y: 3,
1007 c: None,
1008 },
1009 t: 255001,
1010 d: 7,
1011 });
1012
1013 let bufwriter = Vec::new();
1014 let mut stream = BitWriter::endian(bufwriter, BigEndian);
1015
1016 let mut source_model = FenwickModel::with_symbols(u16::MAX as usize, 1 << 30);
1017 let contexts = crate::codec::compressed::source_model::cabac_contexts::Contexts::new(
1018 &mut source_model,
1019 255,
1020 );
1021
1022 let mut encoder = Encoder::new(source_model);
1023
1024 cube.compress_intra(&mut encoder, &contexts, &mut stream, Some(0))?;
1025 cube.compress_inter(&mut encoder, &contexts, &mut stream, Some(0))?;
1026
1027 eof_context(&contexts, &mut encoder, &mut stream);
1028
1029 let mut source_model = FenwickModel::with_symbols(u16::MAX as usize, 1 << 30);
1030 let contexts = crate::codec::compressed::source_model::cabac_contexts::Contexts::new(
1031 &mut source_model,
1032 255,
1033 );
1034 let mut decoder = arithmetic_coding_adder_dep::Decoder::new(source_model);
1035 let mut stream = BitReader::endian(Cursor::new(stream.into_writer()), BigEndian);
1036
1037 let mut cube2 = cube.clone();
1038 cube2.decompress_intra(&mut decoder, &contexts, &mut stream, 255000);
1039
1040 cube2.decompress_inter(&mut decoder, &contexts, &mut stream);
1041
1042 assert_eq!(
1044 cube.raw_event_lists[0][3][3][0].t,
1045 cube2.raw_event_lists[0][3][3][0].t
1046 );
1047 assert_eq!(
1048 cube.raw_event_lists[0][3][4][0].t,
1049 cube2.raw_event_lists[0][3][4][0].t
1050 );
1051 assert_eq!(
1052 cube.raw_event_lists[0][3][4][1].t,
1053 cube2.raw_event_lists[0][3][4][1].t
1054 );
1055
1056 Ok(())
1057 }
1058}