1use oximedia_core::{OxiError, OxiResult};
4
5#[derive(Debug, Clone)]
36pub struct BitReader<'a> {
37 data: &'a [u8],
39 byte_pos: usize,
41 bit_pos: u8,
43}
44
45#[allow(clippy::elidable_lifetime_names)]
46impl<'a> BitReader<'a> {
47 #[must_use]
59 pub const fn new(data: &'a [u8]) -> Self {
60 Self {
61 data,
62 byte_pos: 0,
63 bit_pos: 0,
64 }
65 }
66
67 pub fn read_bit(&mut self) -> OxiResult<u8> {
88 if self.byte_pos >= self.data.len() {
89 return Err(OxiError::UnexpectedEof);
90 }
91
92 let bit = (self.data[self.byte_pos] >> (7 - self.bit_pos)) & 1;
94 self.bit_pos += 1;
95
96 if self.bit_pos == 8 {
97 self.bit_pos = 0;
98 self.byte_pos += 1;
99 }
100
101 Ok(bit)
102 }
103
104 pub fn read_bits(&mut self, n: u8) -> OxiResult<u64> {
129 if n > 64 {
130 return Err(OxiError::InvalidData(
131 "Cannot read more than 64 bits at once".to_string(),
132 ));
133 }
134
135 if n == 0 {
136 return Ok(0);
137 }
138
139 if self.bit_pos == 0 && n % 8 == 0 {
144 let num_bytes = usize::from(n / 8);
145 if self.byte_pos + num_bytes <= self.data.len() {
146 let slice = &self.data[self.byte_pos..self.byte_pos + num_bytes];
147 let value = match num_bytes {
148 1 => u64::from(slice[0]),
149 2 => {
150 let arr: [u8; 2] = [slice[0], slice[1]];
151 u64::from(u16::from_be_bytes(arr))
152 }
153 4 => {
154 let arr: [u8; 4] = [slice[0], slice[1], slice[2], slice[3]];
155 u64::from(u32::from_be_bytes(arr))
156 }
157 8 => {
158 let arr: [u8; 8] = [
159 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6],
160 slice[7],
161 ];
162 u64::from_be_bytes(arr)
163 }
164 _ => {
167 let mut v = 0u64;
168 for &byte in slice {
169 v = (v << 8) | u64::from(byte);
170 }
171 v
172 }
173 };
174 self.byte_pos += num_bytes;
175 return Ok(value);
176 }
177 }
178
179 let mut value = 0u64;
181 for _ in 0..n {
182 value = (value << 1) | u64::from(self.read_bit()?);
183 }
184
185 Ok(value)
186 }
187
188 #[allow(clippy::cast_possible_truncation)]
207 pub fn read_u8(&mut self) -> OxiResult<u8> {
208 Ok(self.read_bits(8)? as u8)
209 }
210
211 #[allow(clippy::cast_possible_truncation)]
229 pub fn read_u16(&mut self) -> OxiResult<u16> {
230 Ok(self.read_bits(16)? as u16)
231 }
232
233 #[allow(clippy::cast_possible_truncation)]
251 pub fn read_u32(&mut self) -> OxiResult<u32> {
252 Ok(self.read_bits(32)? as u32)
253 }
254
255 pub fn read_u64(&mut self) -> OxiResult<u64> {
273 self.read_bits(64)
274 }
275
276 pub fn read_flag(&mut self) -> OxiResult<bool> {
297 Ok(self.read_bit()? != 0)
298 }
299
300 pub fn skip_bits(&mut self, n: usize) {
316 for _ in 0..n {
317 if self.read_bit().is_err() {
318 break;
319 }
320 }
321 }
322
323 pub fn byte_align(&mut self) {
342 if self.bit_pos != 0 {
343 self.bit_pos = 0;
344 self.byte_pos += 1;
345 }
346 }
347
348 #[must_use]
364 pub fn has_more_data(&self) -> bool {
365 self.byte_pos < self.data.len()
366 }
367
368 #[must_use]
386 pub fn remaining_bytes(&self) -> usize {
387 if self.byte_pos >= self.data.len() {
388 0
389 } else {
390 self.data.len() - self.byte_pos - usize::from(self.bit_pos > 0)
391 }
392 }
393
394 #[must_use]
412 pub fn bits_read(&self) -> usize {
413 self.byte_pos * 8 + self.bit_pos as usize
414 }
415
416 #[must_use]
432 pub fn remaining_bits(&self) -> usize {
433 if self.byte_pos >= self.data.len() {
434 0
435 } else {
436 (self.data.len() - self.byte_pos) * 8 - self.bit_pos as usize
437 }
438 }
439
440 pub fn peek_bit(&self) -> OxiResult<u8> {
461 if self.byte_pos >= self.data.len() {
462 return Err(OxiError::UnexpectedEof);
463 }
464
465 Ok((self.data[self.byte_pos] >> (7 - self.bit_pos)) & 1)
466 }
467
468 #[must_use]
470 pub const fn data(&self) -> &'a [u8] {
471 self.data
472 }
473
474 #[must_use]
476 pub const fn byte_position(&self) -> usize {
477 self.byte_pos
478 }
479
480 #[must_use]
482 pub const fn bit_position(&self) -> u8 {
483 self.bit_pos
484 }
485}
486
487#[cfg(test)]
488mod tests {
489 use super::*;
490
491 #[test]
492 fn test_new() {
493 let data = [0xFF, 0x00];
494 let reader = BitReader::new(&data);
495 assert_eq!(reader.byte_position(), 0);
496 assert_eq!(reader.bit_position(), 0);
497 assert!(reader.has_more_data());
498 }
499
500 #[test]
501 fn test_read_bit() {
502 let data = [0b10110100];
503 let mut reader = BitReader::new(&data);
504
505 assert_eq!(reader.read_bit().expect("read_bit should succeed"), 1);
506 assert_eq!(reader.read_bit().expect("read_bit should succeed"), 0);
507 assert_eq!(reader.read_bit().expect("read_bit should succeed"), 1);
508 assert_eq!(reader.read_bit().expect("read_bit should succeed"), 1);
509 assert_eq!(reader.read_bit().expect("read_bit should succeed"), 0);
510 assert_eq!(reader.read_bit().expect("read_bit should succeed"), 1);
511 assert_eq!(reader.read_bit().expect("read_bit should succeed"), 0);
512 assert_eq!(reader.read_bit().expect("read_bit should succeed"), 0);
513 }
514
515 #[test]
516 fn test_read_bits() {
517 let data = [0b10110100, 0b11001010];
518 let mut reader = BitReader::new(&data);
519
520 assert_eq!(
521 reader.read_bits(4).expect("read_bits should succeed"),
522 0b1011
523 );
524 assert_eq!(
525 reader.read_bits(4).expect("read_bits should succeed"),
526 0b0100
527 );
528 assert_eq!(
529 reader.read_bits(8).expect("read_bits should succeed"),
530 0b11001010
531 );
532 }
533
534 #[test]
535 fn test_read_bits_across_bytes() {
536 let data = [0b10110100, 0b11001010];
537 let mut reader = BitReader::new(&data);
538
539 assert_eq!(
540 reader.read_bits(12).expect("read_bits should succeed"),
541 0b101101001100
542 );
543 assert_eq!(
544 reader.read_bits(4).expect("read_bits should succeed"),
545 0b1010
546 );
547 }
548
549 #[test]
550 fn test_read_bits_zero() {
551 let data = [0xFF];
552 let mut reader = BitReader::new(&data);
553 assert_eq!(reader.read_bits(0).expect("read_bits should succeed"), 0);
554 assert_eq!(reader.bits_read(), 0);
555 }
556
557 #[test]
558 fn test_read_bits_too_many() {
559 let data = [0xFF];
560 let mut reader = BitReader::new(&data);
561 let result = reader.read_bits(65);
562 assert!(result.is_err());
563 }
564
565 #[test]
566 fn test_read_u8() {
567 let data = [0x12, 0x34];
568 let mut reader = BitReader::new(&data);
569 assert_eq!(reader.read_u8().expect("read_u8 should succeed"), 0x12);
570 assert_eq!(reader.read_u8().expect("read_u8 should succeed"), 0x34);
571 }
572
573 #[test]
574 fn test_read_u16() {
575 let data = [0x12, 0x34];
576 let mut reader = BitReader::new(&data);
577 assert_eq!(reader.read_u16().expect("read_u16 should succeed"), 0x1234);
578 }
579
580 #[test]
581 fn test_read_u32() {
582 let data = [0x12, 0x34, 0x56, 0x78];
583 let mut reader = BitReader::new(&data);
584 assert_eq!(
585 reader.read_u32().expect("read_u32 should succeed"),
586 0x1234_5678
587 );
588 }
589
590 #[test]
591 fn test_read_u64() {
592 let data = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];
593 let mut reader = BitReader::new(&data);
594 assert_eq!(
595 reader.read_u64().expect("read_u64 should succeed"),
596 0x1234_5678_9ABC_DEF0
597 );
598 }
599
600 #[test]
601 fn test_read_flag() {
602 let data = [0b10100000];
603 let mut reader = BitReader::new(&data);
604 assert!(reader.read_flag().expect("read_flag should succeed"));
605 assert!(!reader.read_flag().expect("read_flag should succeed"));
606 assert!(reader.read_flag().expect("read_flag should succeed"));
607 }
608
609 #[test]
610 fn test_skip_bits() {
611 let data = [0xFF, 0x12];
612 let mut reader = BitReader::new(&data);
613 reader.skip_bits(8);
614 assert_eq!(reader.read_u8().expect("read_u8 should succeed"), 0x12);
615 }
616
617 #[test]
618 fn test_byte_align() {
619 let data = [0xFF, 0x12];
620 let mut reader = BitReader::new(&data);
621 reader.read_bits(3).expect("read_bits should succeed");
622 reader.byte_align();
623 assert_eq!(reader.bits_read(), 8);
624 assert_eq!(reader.read_u8().expect("read_u8 should succeed"), 0x12);
625 }
626
627 #[test]
628 fn test_byte_align_already_aligned() {
629 let data = [0xFF, 0x12];
630 let mut reader = BitReader::new(&data);
631 reader.byte_align();
632 assert_eq!(reader.bits_read(), 0);
633 }
634
635 #[test]
636 fn test_has_more_data() {
637 let data = [0xFF];
638 let mut reader = BitReader::new(&data);
639 assert!(reader.has_more_data());
640 reader.read_bits(8).expect("read_bits should succeed");
641 assert!(!reader.has_more_data());
642 }
643
644 #[test]
645 fn test_remaining_bytes() {
646 let data = [0xFF, 0x00, 0xFF];
647 let mut reader = BitReader::new(&data);
648 assert_eq!(reader.remaining_bytes(), 3);
649 reader.read_bits(4).expect("read_bits should succeed");
650 assert_eq!(reader.remaining_bytes(), 2);
651 reader.read_bits(4).expect("read_bits should succeed");
652 assert_eq!(reader.remaining_bytes(), 2);
653 }
654
655 #[test]
656 fn test_bits_read() {
657 let data = [0xFF, 0x00];
658 let mut reader = BitReader::new(&data);
659 assert_eq!(reader.bits_read(), 0);
660 reader.read_bits(5).expect("read_bits should succeed");
661 assert_eq!(reader.bits_read(), 5);
662 reader.read_bits(3).expect("read_bits should succeed");
663 assert_eq!(reader.bits_read(), 8);
664 }
665
666 #[test]
667 fn test_remaining_bits() {
668 let data = [0xFF, 0x00];
669 let mut reader = BitReader::new(&data);
670 assert_eq!(reader.remaining_bits(), 16);
671 reader.read_bits(5).expect("read_bits should succeed");
672 assert_eq!(reader.remaining_bits(), 11);
673 }
674
675 #[test]
676 fn test_peek_bit() {
677 let data = [0b10000000];
678 let mut reader = BitReader::new(&data);
679 assert_eq!(reader.peek_bit().expect("peek_bit should succeed"), 1);
680 assert_eq!(reader.peek_bit().expect("peek_bit should succeed"), 1);
681 assert_eq!(reader.bits_read(), 0);
682 reader.read_bit().expect("read_bit should succeed");
683 assert_eq!(reader.peek_bit().expect("peek_bit should succeed"), 0);
684 }
685
686 #[test]
687 fn test_eof() {
688 let data = [0xFF];
689 let mut reader = BitReader::new(&data);
690 reader.read_bits(8).expect("read_bits should succeed");
691 assert!(reader.read_bit().is_err());
692 assert!(reader.read_bits(1).is_err());
693 assert!(reader.peek_bit().is_err());
694 }
695
696 #[test]
697 fn test_empty_data() {
698 let data: [u8; 0] = [];
699 let reader = BitReader::new(&data);
700 assert!(!reader.has_more_data());
701 assert_eq!(reader.remaining_bytes(), 0);
702 assert_eq!(reader.remaining_bits(), 0);
703 }
704
705 #[test]
708 fn test_read_64_bits_max() {
709 let data = [0xFF; 8];
710 let mut reader = BitReader::new(&data);
711 let value = reader.read_bits(64).expect("read_bits should succeed");
712 assert_eq!(value, u64::MAX);
713 }
714
715 #[test]
716 fn test_read_across_multiple_bytes() {
717 let data = [0b10101010, 0b11001100, 0b11110000];
719 let mut reader = BitReader::new(&data);
720
721 assert_eq!(
722 reader.read_bits(4).expect("read_bits should succeed"),
723 0b1010
724 );
725 assert_eq!(
726 reader.read_bits(8).expect("read_bits should succeed"),
727 0b1010_1100
728 );
729 assert_eq!(
730 reader.read_bits(12).expect("read_bits should succeed"),
731 0b1100_1111_0000
732 );
733 }
734
735 #[test]
736 fn test_mixed_read_operations() {
737 let data = [0b11010010, 0b10110100];
738 let mut reader = BitReader::new(&data);
739
740 assert!(reader.read_flag().expect("read_flag should succeed")); assert!(reader.read_flag().expect("read_flag should succeed")); assert!(!reader.read_flag().expect("read_flag should succeed")); assert_eq!(
744 reader.read_bits(5).expect("read_bits should succeed"),
745 0b10010
746 ); assert_eq!(
748 reader.read_u8().expect("read_u8 should succeed"),
749 0b10110100
750 );
751 }
752
753 #[test]
754 fn test_byte_align_at_boundary() {
755 let data = [0xFF, 0x12, 0x34];
756 let mut reader = BitReader::new(&data);
757
758 reader.byte_align(); assert_eq!(reader.bits_read(), 0);
760
761 reader.read_bits(8).expect("read_bits should succeed");
762 reader.byte_align(); assert_eq!(reader.bits_read(), 8);
764 }
765
766 #[test]
767 fn test_skip_bits_partial_byte() {
768 let data = [0xFF, 0x12];
769 let mut reader = BitReader::new(&data);
770
771 reader.skip_bits(3);
772 assert_eq!(
773 reader.read_bits(5).expect("read_bits should succeed"),
774 0b11111
775 );
776 assert_eq!(reader.read_u8().expect("read_u8 should succeed"), 0x12);
777 }
778
779 #[test]
780 fn test_skip_bits_beyond_end() {
781 let data = [0xFF];
782 let mut reader = BitReader::new(&data);
783
784 reader.skip_bits(100); assert!(!reader.has_more_data());
786 }
787
788 #[test]
789 fn test_remaining_methods_consistency() {
790 let data = [0xFF, 0x00, 0xFF, 0x00];
791 let mut reader = BitReader::new(&data);
792
793 assert_eq!(reader.remaining_bits(), 32);
794 assert_eq!(reader.remaining_bytes(), 4);
795
796 reader.read_bits(5).expect("read_bits should succeed");
797 assert_eq!(reader.remaining_bits(), 27);
798 assert_eq!(reader.remaining_bytes(), 3);
799
800 reader.read_bits(11).expect("read_bits should succeed"); assert_eq!(reader.remaining_bits(), 16);
802 assert_eq!(reader.remaining_bytes(), 2);
803 }
804
805 #[test]
806 fn test_peek_doesnt_consume() {
807 let data = [0b10110100];
808 let mut reader = BitReader::new(&data);
809
810 for _ in 0..10 {
811 assert_eq!(reader.peek_bit().expect("peek_bit should succeed"), 1);
812 }
813 assert_eq!(reader.bits_read(), 0);
814
815 reader.read_bit().expect("read_bit should succeed");
816 for _ in 0..10 {
817 assert_eq!(reader.peek_bit().expect("peek_bit should succeed"), 0);
818 }
819 assert_eq!(reader.bits_read(), 1);
820 }
821
822 #[test]
823 fn test_read_all_integer_types() {
824 let data = [
826 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, ];
831 let mut reader = BitReader::new(&data);
832
833 assert_eq!(reader.read_u8().expect("read_u8 should succeed"), 0x12);
834 assert_eq!(reader.read_u16().expect("read_u16 should succeed"), 0x3456);
835 assert_eq!(
836 reader.read_u32().expect("read_u32 should succeed"),
837 0x789A_BCDE
838 );
839 assert_eq!(
840 reader.read_u64().expect("read_u64 should succeed"),
841 0xF011_2233_4455_6677
842 );
843 assert!(!reader.has_more_data());
844 }
845
846 #[test]
847 fn test_unaligned_integer_reads() {
848 let data = [0xFF, 0x12, 0x34, 0x56, 0x78];
849 let mut reader = BitReader::new(&data);
850
851 reader.read_bits(4).expect("read_bits should succeed"); assert_eq!(reader.read_bits(8).expect("read_bits should succeed"), 0xF1);
855 assert_eq!(
856 reader.read_bits(16).expect("read_bits should succeed"),
857 0x2345
858 );
859 assert_eq!(reader.read_bits(8).expect("read_bits should succeed"), 0x67);
860 }
861
862 #[test]
863 fn test_position_tracking() {
864 let data = [0xFF, 0x00, 0xFF];
865 let mut reader = BitReader::new(&data);
866
867 assert_eq!(reader.byte_position(), 0);
868 assert_eq!(reader.bit_position(), 0);
869
870 reader.read_bits(10).expect("read_bits should succeed");
871 assert_eq!(reader.byte_position(), 1);
872 assert_eq!(reader.bit_position(), 2);
873
874 reader.byte_align();
875 assert_eq!(reader.byte_position(), 2);
876 assert_eq!(reader.bit_position(), 0);
877 }
878
879 #[test]
880 fn test_data_accessor() {
881 let data = [0xFF, 0x00, 0xFF];
882 let reader = BitReader::new(&data);
883
884 assert_eq!(reader.data(), &data);
885 assert_eq!(reader.data().len(), 3);
886 }
887
888 #[test]
889 fn test_single_bit_pattern() {
890 let data = [0b10101010];
892 let mut reader = BitReader::new(&data);
893
894 for i in 0..8 {
895 let expected = if i % 2 == 0 { 1 } else { 0 };
896 assert_eq!(
897 reader.read_bit().expect("read_bit should succeed"),
898 expected
899 );
900 }
901 }
902
903 #[test]
904 fn test_eof_on_exact_boundary() {
905 let data = [0xFF];
906 let mut reader = BitReader::new(&data);
907
908 reader.read_bits(8).expect("read_bits should succeed");
909 assert!(!reader.has_more_data());
910 assert_eq!(reader.remaining_bits(), 0);
911
912 let result = reader.read_bit();
913 assert!(result.is_err());
914 }
915
916 #[test]
921 fn test_batch_read_u16_aligned() {
922 let data = [0xAB_u8, 0xCD];
923 let mut r_fast = BitReader::new(&data);
925 let fast = r_fast.read_u16().expect("read_u16 should succeed");
926
927 let mut r_slow = BitReader::new(&data);
929 let slow = r_slow.read_bits(16).expect("read_bits(16) should succeed") as u16;
930
931 assert_eq!(fast, slow);
932 assert_eq!(fast, 0xABCD);
933 }
934
935 #[test]
936 fn test_batch_read_u32_aligned() {
937 let data = [0x12_u8, 0x34, 0x56, 0x78];
938 let mut r_fast = BitReader::new(&data);
939 let fast = r_fast.read_u32().expect("read_u32 should succeed");
940
941 let mut r_slow = BitReader::new(&data);
942 let slow = r_slow.read_bits(32).expect("read_bits(32) should succeed") as u32;
943
944 assert_eq!(fast, slow);
945 assert_eq!(fast, 0x1234_5678);
946 }
947
948 #[test]
949 fn test_batch_read_u64_aligned() {
950 let data = [0x01_u8, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
951 let mut r_fast = BitReader::new(&data);
952 let fast = r_fast.read_u64().expect("read_u64 should succeed");
953
954 let mut r_slow = BitReader::new(&data);
955 let slow = r_slow.read_bits(64).expect("read_bits(64) should succeed");
956
957 assert_eq!(fast, slow);
958 assert_eq!(fast, 0x0102_0304_0506_0708);
959 }
960
961 #[test]
962 fn test_batch_read_unaligned_fallback() {
963 let data = [0b1010_1010_u8, 0b1100_1100];
967
968 let mut r_ref = BitReader::new(&data);
970 r_ref.read_bit().expect("skip first bit");
971 let expected = r_ref.read_bits(8).expect("read_bits(8) reference");
972
973 let mut r_test = BitReader::new(&data);
975 r_test.read_bit().expect("skip first bit");
976 let actual = r_test.read_bits(8).expect("read_bits(8) fast-path");
977
978 assert_eq!(actual, expected);
979 }
980
981 #[test]
990 fn test_issue_15_avc_sps_constraint_byte_alignment() {
991 let sps_bytes = [0x64u8, 0x00, 0x1f];
993 let mut reader = BitReader::new(&sps_bytes);
994
995 let profile_idc = reader.read_bits(8).expect("profile_idc read failed");
996 assert_eq!(profile_idc, 100, "High Profile profile_idc should be 100");
997
998 let constraint = reader.read_bits(8).expect("constraint byte read failed");
999 assert_eq!(constraint, 0x00, "all constraint flags clear in fixture");
1000
1001 let level_idc = reader.read_bits(8).expect("level_idc read failed");
1002 assert_eq!(level_idc, 31, "Level 3.1 level_idc should be 31");
1003 }
1004}