1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/// 비트 단위 I/O — MQC, T1, T2에서 사용
///
/// JPEG 2000의 bit-stuffing 규칙:
/// 0xFF 바이트 뒤에는 최상위 비트를 0으로 강제 (stuff bit)
use crate::error::{Jp2Error, Result};
// ── BioWriter ──
/// 비트 단위 출력 스트림
pub struct BioWriter {
buf: Vec<u8>,
/// 현재 바이트 누적 값
acc: u32,
/// 현재 바이트에서 남은 비트 수
bits: u32,
/// 직전 바이트가 0xFF인지 (bit-stuffing용)
last_was_ff: bool,
}
impl BioWriter {
pub fn new() -> Self {
Self {
buf: Vec::new(),
acc: 0,
bits: 8,
last_was_ff: false,
}
}
/// 단일 비트 쓰기
#[inline]
pub fn putbit(&mut self, bit: u32) {
if self.bits == 0 {
self.byteout();
}
self.bits -= 1;
self.acc |= (bit & 1) << self.bits;
}
/// n비트 쓰기 (MSB first)
pub fn write(&mut self, value: u32, nbits: u32) {
for i in (0..nbits).rev() {
self.putbit((value >> i) & 1);
}
}
/// 바이트 경계까지 0으로 패딩 후 플러시
pub fn flush(&mut self) -> Result<()> {
// 남은 비트를 0으로 채워 바이트를 완성
if self.bits < 8 {
self.byteout();
}
Ok(())
}
/// 처리된 바이트 수
pub fn numbytes(&self) -> usize {
self.buf.len()
}
/// 결과 바이트열 참조
pub fn as_slice(&self) -> &[u8] {
&self.buf
}
/// 결과 바이트열 소비
pub fn into_vec(self) -> Vec<u8> {
self.buf
}
/// 현재 누적 바이트를 버퍼에 출력
fn byteout(&mut self) {
let byte = self.acc as u8;
self.buf.push(byte);
self.last_was_ff = byte == 0xFF;
self.acc = 0;
// 0xFF 뒤에는 7비트만 사용 (stuff bit)
self.bits = if self.last_was_ff { 7 } else { 8 };
}
}
impl Default for BioWriter {
fn default() -> Self {
Self::new()
}
}
// ── BioReader ──
/// 비트 단위 입력 스트림
pub struct BioReader<'a> {
data: &'a [u8],
pos: usize,
/// 현재 바이트 값
acc: u32,
/// 남은 비트 수
bits: u32,
/// 직전 바이트가 0xFF인지
last_was_ff: bool,
}
impl<'a> BioReader<'a> {
pub fn new(data: &'a [u8]) -> Self {
Self {
data,
pos: 0,
acc: 0,
bits: 0,
last_was_ff: false,
}
}
/// 단일 비트 읽기
#[inline]
pub fn getbit(&mut self) -> Result<u32> {
if self.bits == 0 {
self.bytein()?;
}
self.bits -= 1;
Ok((self.acc >> self.bits) & 1)
}
/// n비트 읽기 (MSB first)
pub fn read(&mut self, nbits: u32) -> Result<u32> {
let mut value = 0u32;
for _ in 0..nbits {
value = (value << 1) | self.getbit()?;
}
Ok(value)
}
/// 바이트 경계로 정렬 (남은 비트 버림)
pub fn inalign(&mut self) -> Result<()> {
self.bits = 0;
self.last_was_ff = false;
Ok(())
}
/// 처리된 바이트 수
pub fn numbytes(&self) -> usize {
self.pos
}
/// 다음 바이트를 읽어오기
fn bytein(&mut self) -> Result<()> {
if self.pos >= self.data.len() {
return Err(Jp2Error::OutOfBounds {
offset: self.pos,
len: 1,
});
}
self.acc = self.data[self.pos] as u32;
self.pos += 1;
// 직전이 0xFF였으면 7비트만 사용
self.bits = if self.last_was_ff { 7 } else { 8 };
self.last_was_ff = self.acc == 0xFF;
Ok(())
}
}