roxify 1.13.7 → 1.13.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -8
- package/dist/stub-progress.d.ts +4 -4
- package/dist/stub-progress.js +4 -4
- package/dist/utils/decoder.d.ts +46 -2
- package/dist/utils/decoder.js +248 -38
- package/dist/utils/ecc.js +0 -1
- package/dist/utils/encoder.d.ts +30 -1
- package/dist/utils/encoder.js +34 -18
- package/dist/utils/inspection.d.ts +1 -1
- package/dist/utils/inspection.js +2 -2
- package/dist/utils/robust-audio.js +0 -13
- package/dist/utils/robust-image.js +0 -26
- package/package.json +12 -29
- package/roxify_native-aarch64-apple-darwin.node +0 -0
- package/roxify_native-aarch64-pc-windows-msvc.node +0 -0
- package/roxify_native-aarch64-unknown-linux-gnu.node +0 -0
- package/roxify_native-i686-pc-windows-msvc.node +0 -0
- package/roxify_native-i686-unknown-linux-gnu.node +0 -0
- package/{dist/rox-macos-universal → roxify_native-universal-apple-darwin.node} +0 -0
- package/roxify_native-x86_64-apple-darwin.node +0 -0
- package/roxify_native-x86_64-pc-windows-msvc.node +0 -0
- package/roxify_native-x86_64-unknown-linux-gnu.node +0 -0
- package/scripts/postinstall.cjs +23 -2
- package/Cargo.toml +0 -91
- package/dist/roxify_native +0 -0
- package/dist/roxify_native-macos-arm64 +0 -0
- package/dist/roxify_native-macos-x64 +0 -0
- package/dist/roxify_native.exe +0 -0
- package/native/archive.rs +0 -220
- package/native/audio.rs +0 -151
- package/native/bench_hybrid.rs +0 -145
- package/native/bwt.rs +0 -56
- package/native/context_mixing.rs +0 -117
- package/native/core.rs +0 -378
- package/native/crypto.rs +0 -209
- package/native/encoder.rs +0 -405
- package/native/hybrid.rs +0 -297
- package/native/image_utils.rs +0 -82
- package/native/io_advice.rs +0 -43
- package/native/io_ntfs_optimized.rs +0 -99
- package/native/lib.rs +0 -480
- package/native/main.rs +0 -842
- package/native/mtf.rs +0 -106
- package/native/packer.rs +0 -604
- package/native/png_chunk_writer.rs +0 -146
- package/native/png_utils.rs +0 -554
- package/native/pool.rs +0 -101
- package/native/progress.rs +0 -142
- package/native/rans.rs +0 -149
- package/native/rans_byte.rs +0 -286
- package/native/reconstitution.rs +0 -623
- package/native/streaming.rs +0 -189
- package/native/streaming_decode.rs +0 -625
- package/native/streaming_encode.rs +0 -684
- package/native/test_small_bwt.rs +0 -31
- package/native/test_stages.rs +0 -70
package/native/pool.rs
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
use anyhow::Result;
|
|
2
|
-
use parking_lot::RwLock;
|
|
3
|
-
use std::sync::Arc;
|
|
4
|
-
|
|
5
|
-
pub struct ReusableBuffer {
|
|
6
|
-
data: Vec<u8>,
|
|
7
|
-
capacity: usize,
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
impl ReusableBuffer {
|
|
11
|
-
pub fn new(capacity: usize) -> Self {
|
|
12
|
-
ReusableBuffer {
|
|
13
|
-
data: vec![0u8; capacity],
|
|
14
|
-
capacity,
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
|
19
|
-
&mut self.data
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
pub fn as_slice(&self) -> &[u8] {
|
|
23
|
-
&self.data
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
pub fn resize(&mut self, new_size: usize) -> Result<()> {
|
|
27
|
-
if new_size > self.capacity {
|
|
28
|
-
return Err(anyhow::anyhow!("Buffer overflow: {} > {}", new_size, self.capacity));
|
|
29
|
-
}
|
|
30
|
-
self.data.truncate(new_size);
|
|
31
|
-
Ok(())
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
pub fn clear(&mut self) {
|
|
35
|
-
self.data.clear();
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
pub struct BufferPool {
|
|
40
|
-
buffers: Arc<RwLock<Vec<Arc<RwLock<ReusableBuffer>>>>>,
|
|
41
|
-
default_capacity: usize,
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
impl BufferPool {
|
|
45
|
-
pub fn new(pool_size: usize, capacity: usize) -> Self {
|
|
46
|
-
let mut buffers = Vec::with_capacity(pool_size);
|
|
47
|
-
for _ in 0..pool_size {
|
|
48
|
-
buffers.push(Arc::new(RwLock::new(ReusableBuffer::new(capacity))));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
BufferPool {
|
|
52
|
-
buffers: Arc::new(RwLock::new(buffers)),
|
|
53
|
-
default_capacity: capacity,
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
pub fn acquire(&self) -> Arc<RwLock<ReusableBuffer>> {
|
|
58
|
-
let mut pool = self.buffers.write();
|
|
59
|
-
if let Some(buf) = pool.pop() {
|
|
60
|
-
buf
|
|
61
|
-
} else {
|
|
62
|
-
Arc::new(RwLock::new(ReusableBuffer::new(self.default_capacity)))
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
pub fn release(&self, buf: Arc<RwLock<ReusableBuffer>>) {
|
|
67
|
-
buf.write().clear();
|
|
68
|
-
let mut pool = self.buffers.write();
|
|
69
|
-
if pool.len() < 16 {
|
|
70
|
-
pool.push(buf);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
pub struct ZeroCopyBuffer {
|
|
76
|
-
ptr: *const u8,
|
|
77
|
-
len: usize,
|
|
78
|
-
owned: bool,
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
impl ZeroCopyBuffer {
|
|
82
|
-
pub fn from_slice(data: &[u8]) -> Self {
|
|
83
|
-
ZeroCopyBuffer {
|
|
84
|
-
ptr: data.as_ptr(),
|
|
85
|
-
len: data.len(),
|
|
86
|
-
owned: false,
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
pub fn as_slice(&self) -> &[u8] {
|
|
91
|
-
unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
pub fn len(&self) -> usize {
|
|
95
|
-
self.len
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
pub fn is_empty(&self) -> bool {
|
|
99
|
-
self.len == 0
|
|
100
|
-
}
|
|
101
|
-
}
|
package/native/progress.rs
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
use parking_lot::Mutex;
|
|
2
|
-
use std::sync::Arc;
|
|
3
|
-
use std::time::Instant;
|
|
4
|
-
|
|
5
|
-
#[derive(Clone, Debug)]
|
|
6
|
-
pub struct ProgressSnapshot {
|
|
7
|
-
pub current: u64,
|
|
8
|
-
pub total: u64,
|
|
9
|
-
pub percentage: f64,
|
|
10
|
-
pub elapsed_ms: u64,
|
|
11
|
-
pub eta_ms: Option<u64>,
|
|
12
|
-
pub speed_bytes_per_sec: f64,
|
|
13
|
-
pub step: String,
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
struct ProgressInner {
|
|
17
|
-
total: u64,
|
|
18
|
-
current: u64,
|
|
19
|
-
step: String,
|
|
20
|
-
start: Instant,
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
pub struct ProgressBar {
|
|
24
|
-
inner: Arc<Mutex<ProgressInner>>,
|
|
25
|
-
callback: Arc<Mutex<Option<Box<dyn Fn(ProgressSnapshot) + Send>>>>,
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
impl ProgressBar {
|
|
29
|
-
pub fn new(total: u64) -> Self {
|
|
30
|
-
Self {
|
|
31
|
-
inner: Arc::new(Mutex::new(ProgressInner {
|
|
32
|
-
total,
|
|
33
|
-
current: 0,
|
|
34
|
-
step: String::new(),
|
|
35
|
-
start: Instant::now(),
|
|
36
|
-
})),
|
|
37
|
-
callback: Arc::new(Mutex::new(None)),
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
pub fn with_callback<F: Fn(ProgressSnapshot) + Send + 'static>(total: u64, cb: F) -> Self {
|
|
42
|
-
Self {
|
|
43
|
-
inner: Arc::new(Mutex::new(ProgressInner {
|
|
44
|
-
total,
|
|
45
|
-
current: 0,
|
|
46
|
-
step: String::new(),
|
|
47
|
-
start: Instant::now(),
|
|
48
|
-
})),
|
|
49
|
-
callback: Arc::new(Mutex::new(Some(Box::new(cb)))),
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
pub fn inc(&self, delta: u64) {
|
|
54
|
-
let snapshot = {
|
|
55
|
-
let mut inner = self.inner.lock();
|
|
56
|
-
inner.current += delta;
|
|
57
|
-
self.snapshot_inner(&inner)
|
|
58
|
-
};
|
|
59
|
-
self.emit(snapshot);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
pub fn set(&self, value: u64) {
|
|
63
|
-
let snapshot = {
|
|
64
|
-
let mut inner = self.inner.lock();
|
|
65
|
-
inner.current = value;
|
|
66
|
-
self.snapshot_inner(&inner)
|
|
67
|
-
};
|
|
68
|
-
self.emit(snapshot);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
pub fn set_step(&self, step: &str) {
|
|
72
|
-
let snapshot = {
|
|
73
|
-
let mut inner = self.inner.lock();
|
|
74
|
-
inner.step = step.to_string();
|
|
75
|
-
self.snapshot_inner(&inner)
|
|
76
|
-
};
|
|
77
|
-
self.emit(snapshot);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
pub fn snapshot(&self) -> ProgressSnapshot {
|
|
81
|
-
let inner = self.inner.lock();
|
|
82
|
-
self.snapshot_inner(&inner)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
fn snapshot_inner(&self, inner: &ProgressInner) -> ProgressSnapshot {
|
|
86
|
-
let elapsed = inner.start.elapsed();
|
|
87
|
-
let elapsed_ms = elapsed.as_millis() as u64;
|
|
88
|
-
let percentage = if inner.total > 0 {
|
|
89
|
-
(inner.current as f64 / inner.total as f64) * 100.0
|
|
90
|
-
} else {
|
|
91
|
-
0.0
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
let elapsed_secs = elapsed.as_secs_f64();
|
|
95
|
-
let speed = if elapsed_secs > 0.01 {
|
|
96
|
-
inner.current as f64 / elapsed_secs
|
|
97
|
-
} else {
|
|
98
|
-
0.0
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
let eta_ms = if speed > 0.0 && inner.current > 0 && inner.current < inner.total {
|
|
102
|
-
let remaining = inner.total - inner.current;
|
|
103
|
-
Some((remaining as f64 / speed * 1000.0) as u64)
|
|
104
|
-
} else {
|
|
105
|
-
None
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
ProgressSnapshot {
|
|
109
|
-
current: inner.current,
|
|
110
|
-
total: inner.total,
|
|
111
|
-
percentage,
|
|
112
|
-
elapsed_ms,
|
|
113
|
-
eta_ms,
|
|
114
|
-
speed_bytes_per_sec: speed,
|
|
115
|
-
step: inner.step.clone(),
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
fn emit(&self, snapshot: ProgressSnapshot) {
|
|
120
|
-
if let Some(ref cb) = *self.callback.lock() {
|
|
121
|
-
cb(snapshot);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
pub fn finish(&self) {
|
|
126
|
-
let snapshot = {
|
|
127
|
-
let mut inner = self.inner.lock();
|
|
128
|
-
inner.current = inner.total;
|
|
129
|
-
self.snapshot_inner(&inner)
|
|
130
|
-
};
|
|
131
|
-
self.emit(snapshot);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
pub fn get_progress(&self) -> (u64, u64) {
|
|
135
|
-
let inner = self.inner.lock();
|
|
136
|
-
(inner.current, inner.total)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
pub fn set_message(&self, msg: String) {
|
|
140
|
-
self.set_step(&msg);
|
|
141
|
-
}
|
|
142
|
-
}
|
package/native/rans.rs
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
use anyhow::Result;
|
|
2
|
-
|
|
3
|
-
const RANS_L: u32 = 1 << 31;
|
|
4
|
-
const RANS_M: u32 = 1 << 16;
|
|
5
|
-
|
|
6
|
-
#[derive(Clone, Debug)]
|
|
7
|
-
pub struct Symbol {
|
|
8
|
-
pub start: u32,
|
|
9
|
-
pub freq: u32,
|
|
10
|
-
pub scale_bits: u32,
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
pub struct RansEncoder {
|
|
14
|
-
state: u32,
|
|
15
|
-
output: Vec<u8>,
|
|
16
|
-
symbols: Vec<Symbol>,
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
impl RansEncoder {
|
|
20
|
-
pub fn new(symbols: Vec<Symbol>) -> Self {
|
|
21
|
-
RansEncoder {
|
|
22
|
-
state: RANS_L,
|
|
23
|
-
output: Vec::new(),
|
|
24
|
-
symbols,
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
pub fn encode(&mut self, symbol_idx: usize) -> Result<()> {
|
|
29
|
-
if symbol_idx >= self.symbols.len() {
|
|
30
|
-
return Err(anyhow::anyhow!("Symbol index out of bounds"));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
let sym = &self.symbols[symbol_idx];
|
|
34
|
-
|
|
35
|
-
while self.state >= (sym.freq << 16) {
|
|
36
|
-
self.output.push((self.state & 0xFF) as u8);
|
|
37
|
-
self.state >>= 8;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
let x = ((self.state / sym.freq) << sym.scale_bits) + sym.start;
|
|
41
|
-
let y = self.state % sym.freq;
|
|
42
|
-
self.state = x + y;
|
|
43
|
-
|
|
44
|
-
Ok(())
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
pub fn finish(mut self) -> Vec<u8> {
|
|
48
|
-
while self.state > 0 {
|
|
49
|
-
self.output.push((self.state & 0xFF) as u8);
|
|
50
|
-
self.state >>= 8;
|
|
51
|
-
}
|
|
52
|
-
self.output.reverse();
|
|
53
|
-
self.output
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
pub struct RansDecoder {
|
|
58
|
-
state: u32,
|
|
59
|
-
data: Vec<u8>,
|
|
60
|
-
pos: usize,
|
|
61
|
-
symbols: Vec<Symbol>,
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
impl RansDecoder {
|
|
65
|
-
pub fn new(data: Vec<u8>, symbols: Vec<Symbol>) -> Self {
|
|
66
|
-
let mut decoder = RansDecoder {
|
|
67
|
-
state: RANS_L,
|
|
68
|
-
data,
|
|
69
|
-
pos: 0,
|
|
70
|
-
symbols,
|
|
71
|
-
};
|
|
72
|
-
decoder.refill();
|
|
73
|
-
decoder
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
fn refill(&mut self) {
|
|
77
|
-
while self.state < RANS_L && self.pos < self.data.len() {
|
|
78
|
-
self.state = (self.state << 8) | (self.data[self.pos] as u32);
|
|
79
|
-
self.pos += 1;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
pub fn decode(&mut self) -> Result<usize> {
|
|
84
|
-
let x = self.state & 0xFFFF;
|
|
85
|
-
|
|
86
|
-
let mut sym_idx = 0;
|
|
87
|
-
for (i, sym) in self.symbols.iter().enumerate() {
|
|
88
|
-
if x >= sym.start && x < sym.start + sym.freq {
|
|
89
|
-
sym_idx = i;
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
let sym = &self.symbols[sym_idx];
|
|
95
|
-
let q = self.state / sym.freq;
|
|
96
|
-
let r = self.state % sym.freq;
|
|
97
|
-
|
|
98
|
-
self.state = (q << sym.scale_bits) + (r + sym.start);
|
|
99
|
-
self.refill();
|
|
100
|
-
|
|
101
|
-
Ok(sym_idx)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
pub fn is_finished(&self) -> bool {
|
|
105
|
-
self.state == RANS_L && self.pos >= self.data.len()
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
pub fn build_symbols_from_frequencies(freqs: &[u32]) -> Vec<Symbol> {
|
|
110
|
-
let total: u32 = freqs.iter().sum();
|
|
111
|
-
if total == 0 {
|
|
112
|
-
return Vec::new();
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
let scale_bits = 16 - (total.leading_zeros() - 16);
|
|
116
|
-
let mut symbols = Vec::new();
|
|
117
|
-
let mut start = 0u32;
|
|
118
|
-
|
|
119
|
-
for freq in freqs {
|
|
120
|
-
if *freq > 0 {
|
|
121
|
-
let scaled = ((*freq as u64) << scale_bits) / (total as u64);
|
|
122
|
-
symbols.push(Symbol {
|
|
123
|
-
start,
|
|
124
|
-
freq: *freq,
|
|
125
|
-
scale_bits,
|
|
126
|
-
});
|
|
127
|
-
start += scaled as u32;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
symbols
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
pub fn estimate_entropy(freqs: &[u32]) -> f64 {
|
|
135
|
-
let total: u32 = freqs.iter().sum();
|
|
136
|
-
if total == 0 {
|
|
137
|
-
return 0.0;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
let total_f = total as f64;
|
|
141
|
-
freqs
|
|
142
|
-
.iter()
|
|
143
|
-
.filter(|&&f| f > 0)
|
|
144
|
-
.map(|&f| {
|
|
145
|
-
let p = (f as f64) / total_f;
|
|
146
|
-
-p * p.log2()
|
|
147
|
-
})
|
|
148
|
-
.sum()
|
|
149
|
-
}
|
package/native/rans_byte.rs
DELETED
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
use anyhow::Result;
|
|
2
|
-
|
|
3
|
-
const PROB_BITS: u32 = 12;
|
|
4
|
-
const PROB_SCALE: u32 = 1 << PROB_BITS;
|
|
5
|
-
const RANS_BYTE_L: u32 = 1 << 23;
|
|
6
|
-
|
|
7
|
-
#[derive(Clone, Debug)]
|
|
8
|
-
pub struct SymbolStats {
|
|
9
|
-
pub freqs: [u32; 256],
|
|
10
|
-
pub cum_freqs: [u32; 257],
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
impl SymbolStats {
|
|
14
|
-
pub fn from_data(data: &[u8]) -> Self {
|
|
15
|
-
let mut raw = [0u32; 256];
|
|
16
|
-
for &b in data {
|
|
17
|
-
raw[b as usize] += 1;
|
|
18
|
-
}
|
|
19
|
-
Self::normalize(raw)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
fn normalize(raw: [u32; 256]) -> Self {
|
|
23
|
-
let total: u64 = raw.iter().map(|&f| f as u64).sum();
|
|
24
|
-
if total == 0 {
|
|
25
|
-
let mut freqs = [0u32; 256];
|
|
26
|
-
freqs[0] = PROB_SCALE;
|
|
27
|
-
let mut cum = [0u32; 257];
|
|
28
|
-
cum[1] = PROB_SCALE;
|
|
29
|
-
for i in 2..257 { cum[i] = PROB_SCALE; }
|
|
30
|
-
return SymbolStats { freqs, cum_freqs: cum };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
let mut freqs = [0u32; 256];
|
|
34
|
-
let mut assigned = 0u32;
|
|
35
|
-
let mut max_idx = 0usize;
|
|
36
|
-
let mut max_raw = 0u32;
|
|
37
|
-
|
|
38
|
-
for i in 0..256 {
|
|
39
|
-
if raw[i] > 0 {
|
|
40
|
-
freqs[i] = ((raw[i] as u64 * PROB_SCALE as u64) / total).max(1) as u32;
|
|
41
|
-
assigned += freqs[i];
|
|
42
|
-
if raw[i] > max_raw {
|
|
43
|
-
max_raw = raw[i];
|
|
44
|
-
max_idx = i;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if assigned > PROB_SCALE {
|
|
50
|
-
let excess = assigned - PROB_SCALE;
|
|
51
|
-
freqs[max_idx] = freqs[max_idx].saturating_sub(excess);
|
|
52
|
-
if freqs[max_idx] == 0 { freqs[max_idx] = 1; }
|
|
53
|
-
} else if assigned < PROB_SCALE {
|
|
54
|
-
freqs[max_idx] += PROB_SCALE - assigned;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
let mut cum_freqs = [0u32; 257];
|
|
58
|
-
for i in 0..256 {
|
|
59
|
-
cum_freqs[i + 1] = cum_freqs[i] + freqs[i];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
SymbolStats { freqs, cum_freqs }
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
pub fn serialize(&self) -> Vec<u8> {
|
|
66
|
-
let mut out = Vec::with_capacity(512);
|
|
67
|
-
let mut entries: Vec<(u8, u16)> = Vec::new();
|
|
68
|
-
for i in 0..256 {
|
|
69
|
-
if self.freqs[i] > 0 {
|
|
70
|
-
entries.push((i as u8, self.freqs[i] as u16));
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
out.extend_from_slice(&(entries.len() as u16).to_le_bytes());
|
|
74
|
-
for (sym, freq) in &entries {
|
|
75
|
-
out.push(*sym);
|
|
76
|
-
out.extend_from_slice(&freq.to_le_bytes());
|
|
77
|
-
}
|
|
78
|
-
out
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
pub fn deserialize(data: &[u8]) -> Result<(Self, usize)> {
|
|
82
|
-
if data.len() < 2 {
|
|
83
|
-
return Err(anyhow::anyhow!("Stats too short"));
|
|
84
|
-
}
|
|
85
|
-
let count = u16::from_le_bytes([data[0], data[1]]) as usize;
|
|
86
|
-
let needed = 2 + count * 3;
|
|
87
|
-
if data.len() < needed {
|
|
88
|
-
return Err(anyhow::anyhow!("Truncated stats"));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
let mut freqs = [0u32; 256];
|
|
92
|
-
let mut pos = 2;
|
|
93
|
-
for _ in 0..count {
|
|
94
|
-
let sym = data[pos] as usize;
|
|
95
|
-
let freq = u16::from_le_bytes([data[pos + 1], data[pos + 2]]) as u32;
|
|
96
|
-
freqs[sym] = freq;
|
|
97
|
-
pos += 3;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
let mut cum_freqs = [0u32; 257];
|
|
101
|
-
for i in 0..256 {
|
|
102
|
-
cum_freqs[i + 1] = cum_freqs[i] + freqs[i];
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
Ok((SymbolStats { freqs, cum_freqs }, needed))
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
#[inline(always)]
|
|
110
|
-
fn rans_enc_put(state: &mut u32, buf: &mut Vec<u8>, start: u32, freq: u32) {
|
|
111
|
-
let x_max = ((RANS_BYTE_L >> PROB_BITS) << 8) * freq;
|
|
112
|
-
let mut x = *state;
|
|
113
|
-
while x >= x_max {
|
|
114
|
-
buf.push((x & 0xFF) as u8);
|
|
115
|
-
x >>= 8;
|
|
116
|
-
}
|
|
117
|
-
*state = ((x / freq) << PROB_BITS) + (x % freq) + start;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
#[inline(always)]
|
|
121
|
-
fn rans_dec_renorm(state: &mut u32, data: &[u8], pos: &mut usize) {
|
|
122
|
-
while *state < RANS_BYTE_L && *pos < data.len() {
|
|
123
|
-
*state = (*state << 8) | (data[*pos] as u32);
|
|
124
|
-
*pos += 1;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
fn write_state(out: &mut Vec<u8>, state: u32) {
|
|
129
|
-
out.push((state >> 24) as u8);
|
|
130
|
-
out.push(((state >> 16) & 0xFF) as u8);
|
|
131
|
-
out.push(((state >> 8) & 0xFF) as u8);
|
|
132
|
-
out.push((state & 0xFF) as u8);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
fn read_state(data: &[u8], pos: &mut usize) -> u32 {
|
|
136
|
-
let s = (data[*pos] as u32) << 24
|
|
137
|
-
| (data[*pos + 1] as u32) << 16
|
|
138
|
-
| (data[*pos + 2] as u32) << 8
|
|
139
|
-
| (data[*pos + 3] as u32);
|
|
140
|
-
*pos += 4;
|
|
141
|
-
s
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
pub fn rans_encode_block(data: &[u8], stats: &SymbolStats) -> Vec<u8> {
|
|
145
|
-
if data.is_empty() {
|
|
146
|
-
return Vec::new();
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if data.len() < 8 {
|
|
150
|
-
return rans_encode_single(data, stats);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
let mut s0: u32 = RANS_BYTE_L;
|
|
154
|
-
let mut s1: u32 = RANS_BYTE_L;
|
|
155
|
-
let mut rev_bytes: Vec<u8> = Vec::with_capacity(data.len() + 32);
|
|
156
|
-
|
|
157
|
-
let len = data.len();
|
|
158
|
-
let even_start = if len % 2 == 0 { len } else { len - 1 };
|
|
159
|
-
|
|
160
|
-
if len % 2 != 0 {
|
|
161
|
-
let sym = data[len - 1] as usize;
|
|
162
|
-
rans_enc_put(&mut s1, &mut rev_bytes, stats.cum_freqs[sym], stats.freqs[sym]);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
let mut i = even_start;
|
|
166
|
-
while i >= 2 {
|
|
167
|
-
i -= 2;
|
|
168
|
-
let sym1 = data[i + 1] as usize;
|
|
169
|
-
rans_enc_put(&mut s1, &mut rev_bytes, stats.cum_freqs[sym1], stats.freqs[sym1]);
|
|
170
|
-
let sym0 = data[i] as usize;
|
|
171
|
-
rans_enc_put(&mut s0, &mut rev_bytes, stats.cum_freqs[sym0], stats.freqs[sym0]);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
let mut output = Vec::with_capacity(9 + rev_bytes.len());
|
|
175
|
-
output.push(1);
|
|
176
|
-
write_state(&mut output, s0);
|
|
177
|
-
write_state(&mut output, s1);
|
|
178
|
-
|
|
179
|
-
for &b in rev_bytes.iter().rev() {
|
|
180
|
-
output.push(b);
|
|
181
|
-
}
|
|
182
|
-
output
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
fn rans_encode_single(data: &[u8], stats: &SymbolStats) -> Vec<u8> {
|
|
186
|
-
let mut state: u32 = RANS_BYTE_L;
|
|
187
|
-
let mut rev_bytes: Vec<u8> = Vec::with_capacity(data.len() + 16);
|
|
188
|
-
|
|
189
|
-
for &byte in data.iter().rev() {
|
|
190
|
-
let s = byte as usize;
|
|
191
|
-
rans_enc_put(&mut state, &mut rev_bytes, stats.cum_freqs[s], stats.freqs[s]);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
let mut output = Vec::with_capacity(5 + rev_bytes.len());
|
|
195
|
-
output.push(0);
|
|
196
|
-
write_state(&mut output, state);
|
|
197
|
-
|
|
198
|
-
for &b in rev_bytes.iter().rev() {
|
|
199
|
-
output.push(b);
|
|
200
|
-
}
|
|
201
|
-
output
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
pub fn rans_decode_block(encoded: &[u8], stats: &SymbolStats, output_len: usize) -> Result<Vec<u8>> {
|
|
205
|
-
if encoded.is_empty() {
|
|
206
|
-
return Err(anyhow::anyhow!("Data too short"));
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
let mut cum2sym = [0u8; PROB_SCALE as usize];
|
|
210
|
-
for s in 0..256usize {
|
|
211
|
-
let start = stats.cum_freqs[s] as usize;
|
|
212
|
-
let end = stats.cum_freqs[s + 1] as usize;
|
|
213
|
-
if end > start {
|
|
214
|
-
cum2sym[start..end].fill(s as u8);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
let mode = encoded[0];
|
|
219
|
-
let mut pos = 1usize;
|
|
220
|
-
|
|
221
|
-
if mode == 1 && output_len >= 8 {
|
|
222
|
-
return rans_decode_interleaved(encoded, &cum2sym, stats, output_len, &mut pos);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if pos + 4 > encoded.len() {
|
|
226
|
-
return Err(anyhow::anyhow!("Data too short"));
|
|
227
|
-
}
|
|
228
|
-
let mut state = read_state(encoded, &mut pos);
|
|
229
|
-
let mut output = Vec::with_capacity(output_len);
|
|
230
|
-
|
|
231
|
-
for _ in 0..output_len {
|
|
232
|
-
let slot = state & (PROB_SCALE - 1);
|
|
233
|
-
let sym = cum2sym[slot as usize];
|
|
234
|
-
output.push(sym);
|
|
235
|
-
|
|
236
|
-
let freq = stats.freqs[sym as usize];
|
|
237
|
-
let start = stats.cum_freqs[sym as usize];
|
|
238
|
-
state = freq * (state >> PROB_BITS) + slot - start;
|
|
239
|
-
|
|
240
|
-
rans_dec_renorm(&mut state, encoded, &mut pos);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
Ok(output)
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
fn rans_decode_interleaved(
|
|
247
|
-
encoded: &[u8],
|
|
248
|
-
cum2sym: &[u8; PROB_SCALE as usize],
|
|
249
|
-
stats: &SymbolStats,
|
|
250
|
-
output_len: usize,
|
|
251
|
-
pos: &mut usize,
|
|
252
|
-
) -> Result<Vec<u8>> {
|
|
253
|
-
if *pos + 8 > encoded.len() {
|
|
254
|
-
return Err(anyhow::anyhow!("Data too short for interleaved"));
|
|
255
|
-
}
|
|
256
|
-
let mut s0 = read_state(encoded, pos);
|
|
257
|
-
let mut s1 = read_state(encoded, pos);
|
|
258
|
-
let mut output = Vec::with_capacity(output_len);
|
|
259
|
-
|
|
260
|
-
let pairs = output_len / 2;
|
|
261
|
-
for _ in 0..pairs {
|
|
262
|
-
let slot0 = s0 & (PROB_SCALE - 1);
|
|
263
|
-
let sym0 = cum2sym[slot0 as usize];
|
|
264
|
-
output.push(sym0);
|
|
265
|
-
let freq0 = stats.freqs[sym0 as usize];
|
|
266
|
-
let start0 = stats.cum_freqs[sym0 as usize];
|
|
267
|
-
s0 = freq0 * (s0 >> PROB_BITS) + slot0 - start0;
|
|
268
|
-
rans_dec_renorm(&mut s0, encoded, pos);
|
|
269
|
-
|
|
270
|
-
let slot1 = s1 & (PROB_SCALE - 1);
|
|
271
|
-
let sym1 = cum2sym[slot1 as usize];
|
|
272
|
-
output.push(sym1);
|
|
273
|
-
let freq1 = stats.freqs[sym1 as usize];
|
|
274
|
-
let start1 = stats.cum_freqs[sym1 as usize];
|
|
275
|
-
s1 = freq1 * (s1 >> PROB_BITS) + slot1 - start1;
|
|
276
|
-
rans_dec_renorm(&mut s1, encoded, pos);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if output_len % 2 != 0 {
|
|
280
|
-
let slot = s1 & (PROB_SCALE - 1);
|
|
281
|
-
let sym = cum2sym[slot as usize];
|
|
282
|
-
output.push(sym);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
Ok(output)
|
|
286
|
-
}
|