Skip to content

Commit 060374d

Browse files
committed
cram/codecs/rans_4x8/encode/order_1: Handle RLE within context
1 parent b9e2a2f commit 060374d

File tree

1 file changed

+27
-16
lines changed

1 file changed

+27
-16
lines changed

noodles-cram/src/codecs/rans_4x8/encode/order_1.rs

+27-16
Original file line numberDiff line numberDiff line change
@@ -92,35 +92,46 @@ fn write_frequencies<W>(writer: &mut W, frequencies: &Frequencies) -> io::Result
9292
where
9393
W: Write,
9494
{
95-
use super::order_0;
95+
let mut statuses = [false; ALPHABET_SIZE];
9696

97-
let sums: Vec<u16> = frequencies
98-
.iter()
99-
.map(|frequencies| frequencies.iter().sum())
100-
.collect();
97+
for (s, f) in statuses.iter_mut().zip(frequencies) {
98+
*s = !f.iter().any(|&g| g > 0);
99+
}
101100

102-
let mut rle = 0;
101+
let mut iter = frequencies.iter().zip(&statuses).enumerate();
102+
let mut prev_sym = 0;
103103

104-
for (sym, (f, &sum)) in frequencies.iter().zip(sums.iter()).enumerate() {
105-
if sum == 0 {
104+
while let Some((sym, (f, &is_empty))) = iter.next() {
105+
if is_empty {
106106
continue;
107107
}
108108

109-
if rle > 0 {
110-
rle -= 1;
111-
} else {
112-
writer.write_u8(sym as u8)?;
109+
// SAFETY: `sym <= ALPHABET_SIZE`.
110+
writer.write_u8(sym as u8)?;
111+
112+
if sym > 0 && sym - 1 == prev_sym {
113+
let i = sym + 1;
114+
let len = statuses[i..].iter().position(|s| *s).unwrap_or(0);
115+
116+
// SAFETY: `len < ALPHABET_SIZE`.
117+
writer.write_u8(len as u8)?;
118+
119+
order_0::write_frequencies(writer, f)?;
113120

114-
if sym > 0 && sums[sym - 1] > 0 {
115-
rle = sums[sym + 1..].iter().position(|&s| s == 0).unwrap_or(0);
116-
writer.write_u8(rle as u8)?;
121+
for (sym, (g, _)) in iter.by_ref().take(len) {
122+
order_0::write_frequencies(writer, g)?;
123+
prev_sym = sym;
117124
}
125+
126+
continue;
118127
}
119128

120129
order_0::write_frequencies(writer, f)?;
130+
131+
prev_sym = sym;
121132
}
122133

123-
writer.write_u8(0x00)?;
134+
writer.write_u8(NUL)?;
124135

125136
Ok(())
126137
}

0 commit comments

Comments
 (0)