mirror of
https://github.com/exoticorn/upkr.git
synced 2026-01-20 11:36:42 +01:00
add --eof-in-length option
This commit is contained in:
@@ -21,7 +21,7 @@ pub fn pack(
|
|||||||
if let Some(m) = match_finder.matches(pos).next() {
|
if let Some(m) = match_finder.matches(pos).next() {
|
||||||
let max_offset = 1 << (m.length * 3 - 1).min(31);
|
let max_offset = 1 << (m.length * 3 - 1).min(31);
|
||||||
let offset = pos - m.pos;
|
let offset = pos - m.pos;
|
||||||
if offset < max_offset {
|
if offset < max_offset && m.length >= config.min_length() {
|
||||||
lz::Op::Match {
|
lz::Op::Match {
|
||||||
offset: offset as u32,
|
offset: offset as u32,
|
||||||
len: m.length as u32,
|
len: m.length as u32,
|
||||||
@@ -40,7 +40,7 @@ pub fn pack(
|
|||||||
.zip(data[(pos - offset)..].iter())
|
.zip(data[(pos - offset)..].iter())
|
||||||
.take_while(|(a, b)| a == b)
|
.take_while(|(a, b)| a == b)
|
||||||
.count();
|
.count();
|
||||||
if length > 0 {
|
if length >= config.min_length() {
|
||||||
lz::Op::Match {
|
lz::Op::Match {
|
||||||
offset: offset as u32,
|
offset: offset as u32,
|
||||||
len: length as u32,
|
len: length as u32,
|
||||||
|
|||||||
12
src/lib.rs
12
src/lib.rs
@@ -22,6 +22,7 @@ pub struct Config {
|
|||||||
pub simplified_prob_update: bool,
|
pub simplified_prob_update: bool,
|
||||||
|
|
||||||
pub no_repeated_offsets: bool,
|
pub no_repeated_offsets: bool,
|
||||||
|
pub eof_in_length: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
@@ -39,6 +40,17 @@ impl Default for Config {
|
|||||||
simplified_prob_update: false,
|
simplified_prob_update: false,
|
||||||
|
|
||||||
no_repeated_offsets: false,
|
no_repeated_offsets: false,
|
||||||
|
eof_in_length: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn min_length(&self) -> usize {
|
||||||
|
if self.eof_in_length {
|
||||||
|
2
|
||||||
|
} else {
|
||||||
|
1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/lz.rs
17
src/lz.rs
@@ -40,11 +40,12 @@ impl Op {
|
|||||||
coder,
|
coder,
|
||||||
state,
|
state,
|
||||||
256 * state.parity_contexts + 1,
|
256 * state.parity_contexts + 1,
|
||||||
offset + 1,
|
offset + if config.eof_in_length { 0 } else { 1 },
|
||||||
config,
|
config,
|
||||||
);
|
);
|
||||||
state.last_offset = offset;
|
state.last_offset = offset;
|
||||||
}
|
}
|
||||||
|
assert!(!config.eof_in_length || len > 1);
|
||||||
encode_length(coder, state, 256 * state.parity_contexts + 65, len, config);
|
encode_length(coder, state, 256 * state.parity_contexts + 65, len, config);
|
||||||
state.prev_was_match = true;
|
state.prev_was_match = true;
|
||||||
state.pos += len as usize;
|
state.pos += len as usize;
|
||||||
@@ -60,16 +61,21 @@ pub fn encode_eof(coder: &mut dyn EntropyCoder, state: &mut CoderState, config:
|
|||||||
state.pos % state.parity_contexts * 256,
|
state.pos % state.parity_contexts * 256,
|
||||||
config.is_match_bit,
|
config.is_match_bit,
|
||||||
);
|
);
|
||||||
if !state.prev_was_match {
|
if !state.prev_was_match && !config.no_repeated_offsets {
|
||||||
encode_bit(
|
encode_bit(
|
||||||
coder,
|
coder,
|
||||||
state,
|
state,
|
||||||
256 * state.parity_contexts,
|
256 * state.parity_contexts,
|
||||||
config.new_offset_bit,
|
config.new_offset_bit ^ config.eof_in_length,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if !config.eof_in_length || config.no_repeated_offsets {
|
||||||
encode_length(coder, state, 256 * state.parity_contexts + 1, 1, config);
|
encode_length(coder, state, 256 * state.parity_contexts + 1, 1, config);
|
||||||
}
|
}
|
||||||
|
if config.eof_in_length {
|
||||||
|
encode_length(coder, state, 256 * state.parity_contexts + 65, 1, config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn encode_bit(
|
fn encode_bit(
|
||||||
coder: &mut dyn EntropyCoder,
|
coder: &mut dyn EntropyCoder,
|
||||||
@@ -183,7 +189,7 @@ pub fn unpack_internal(
|
|||||||
&mut contexts,
|
&mut contexts,
|
||||||
256 * config.parity_contexts + 1,
|
256 * config.parity_contexts + 1,
|
||||||
&config,
|
&config,
|
||||||
) - 1;
|
) - if config.eof_in_length { 0 } else { 1 };
|
||||||
if offset == 0 {
|
if offset == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -194,6 +200,9 @@ pub fn unpack_internal(
|
|||||||
256 * config.parity_contexts + 65,
|
256 * config.parity_contexts + 65,
|
||||||
&config,
|
&config,
|
||||||
);
|
);
|
||||||
|
if config.eof_in_length && length == 1 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if let Some(ref mut result) = result {
|
if let Some(ref mut result) = result {
|
||||||
for _ in 0..length {
|
for _ in 0..length {
|
||||||
result.push(result[result.len() - offset]);
|
result.push(result[result.len() - offset]);
|
||||||
|
|||||||
@@ -30,12 +30,14 @@ fn main() -> Result<()> {
|
|||||||
config.bitstream_is_big_endian = true;
|
config.bitstream_is_big_endian = true;
|
||||||
}
|
}
|
||||||
Long("no-repeated-offsets") => config.no_repeated_offsets = true,
|
Long("no-repeated-offsets") => config.no_repeated_offsets = true,
|
||||||
|
Long("eof-in-length") => config.eof_in_length = true,
|
||||||
|
|
||||||
Long("z80") => {
|
Long("z80") => {
|
||||||
config.use_bitstream = true;
|
config.use_bitstream = true;
|
||||||
config.bitstream_is_big_endian = true;
|
config.bitstream_is_big_endian = true;
|
||||||
config.invert_bit_encoding = true;
|
config.invert_bit_encoding = true;
|
||||||
config.simplified_prob_update = true;
|
config.simplified_prob_update = true;
|
||||||
|
level = 9;
|
||||||
}
|
}
|
||||||
Long("x86") => {
|
Long("x86") => {
|
||||||
config.use_bitstream = true;
|
config.use_bitstream = true;
|
||||||
|
|||||||
@@ -110,6 +110,9 @@ fn parse(
|
|||||||
max_arrivals: usize,
|
max_arrivals: usize,
|
||||||
config: &crate::Config,
|
config: &crate::Config,
|
||||||
) {
|
) {
|
||||||
|
if length < config.min_length() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
cost_counter.reset();
|
cost_counter.reset();
|
||||||
let mut state = arrival.state.clone();
|
let mut state = arrival.state.clone();
|
||||||
let op = lz::Op::Match {
|
let op = lz::Op::Match {
|
||||||
|
|||||||
Reference in New Issue
Block a user