diff --git a/libbz2-rs-sys/src/bzlib.rs b/libbz2-rs-sys/src/bzlib.rs index d5949a9fa..4bd94278e 100644 --- a/libbz2-rs-sys/src/bzlib.rs +++ b/libbz2-rs-sys/src/bzlib.rs @@ -551,13 +551,13 @@ pub(crate) struct DState { pub inUse16: [bool; 16], pub seqToUnseq: [u8; 256], pub mtfa: [u8; 4096], - pub mtfbase: [i32; 16], + pub mtfbase: [u16; 16], pub selector: [u8; 18002], pub selectorMtf: [u8; 18002], pub len: [[u8; 258]; 6], pub limit: [[i32; 258]; 6], pub base: [[i32; 258]; 6], - pub perm: [[i32; 258]; 6], + pub perm: [[u16; 258]; 6], pub minLens: [u8; 6], pub save: SaveArea, } @@ -571,12 +571,12 @@ pub(crate) struct SaveArea { pub alphaSize: u16, pub EOB: u16, pub groupNo: i32, - pub groupPos: u8, - pub nextSym: i32, pub nblock: u32, pub es: i32, pub zvec: i32, + pub nextSym: u16, pub nSelectors: u16, + pub groupPos: u8, pub zn: u8, pub nGroups: u8, pub curr: u8, diff --git a/libbz2-rs-sys/src/decompress.rs b/libbz2-rs-sys/src/decompress.rs index 074d331d1..b0c8159e1 100644 --- a/libbz2-rs-sys/src/decompress.rs +++ b/libbz2-rs-sys/src/decompress.rs @@ -12,8 +12,8 @@ use crate::{debug_log, huffman}; /*-- Constants for the fast MTF decoder. --*/ -const MTFA_SIZE: i32 = 4096; -const MTFL_SIZE: i32 = 16; +const MTFA_SIZE: u16 = 4096; +const MTFL_SIZE: usize = 16; #[derive(Debug, Clone, Copy)] #[allow(non_camel_case_types)] @@ -785,7 +785,7 @@ pub(crate) fn decompress( Some(&nextSym) => nextSym, None => error!(BZ_DATA_ERROR), }; - if nextSym == BZ_RUNA as i32 || nextSym == BZ_RUNB as i32 { + if nextSym == BZ_RUNA || nextSym == BZ_RUNB { current_block = Block46; } else { es += 1; @@ -842,90 +842,26 @@ pub(crate) fn decompress( _ => {} } if current_block == Block40 { - if nextSym == EOB as i32 { + if nextSym == EOB { current_block = Block41; + } else if nextSym == BZ_RUNA || nextSym == BZ_RUNB { + es = -1; + logN = 0; + current_block = Block46; + } else if nblock >= 100000 * nblockMAX100k as u32 { + error!(BZ_DATA_ERROR); } else { - if nextSym == 0 || nextSym == 1 { - es = -1; - logN = 0; - } else if nblock >= 100000 * nblockMAX100k as u32 { - error!(BZ_DATA_ERROR); - } else { - let mut ii_0: i32; - let mut jj_0: i32; - let mut kk_0: i32; - let mut pp: i32; - let mut lno: i32; - let off: i32; - let mut nn: u32; - nn = (nextSym - 1) as u32; - if nn < 16 { - pp = s.mtfbase[0_usize]; - uc = s.mtfa[(pp as c_uint).wrapping_add(nn) as usize]; - while nn > 3 { - let z: i32 = (pp as c_uint).wrapping_add(nn) as i32; - s.mtfa[z as usize] = s.mtfa[(z - 1) as usize]; - s.mtfa[(z - 1) as usize] = s.mtfa[(z - 2) as usize]; - s.mtfa[(z - 2) as usize] = s.mtfa[(z - 3) as usize]; - s.mtfa[(z - 3) as usize] = s.mtfa[(z - 4) as usize]; - nn = (nn).wrapping_sub(4); - } - while nn > 0 { - s.mtfa[(pp as c_uint).wrapping_add(nn) as usize] = s.mtfa - [(pp as c_uint).wrapping_add(nn).wrapping_sub(1) as usize]; - nn = nn.wrapping_sub(1); - } - s.mtfa[pp as usize] = uc; - } else { - lno = nn.wrapping_div(16) as i32; - off = nn.wrapping_rem(16) as i32; - pp = s.mtfbase[lno as usize] + off; - uc = s.mtfa[pp as usize]; - while pp > s.mtfbase[lno as usize] { - s.mtfa[pp as usize] = s.mtfa[(pp - 1) as usize]; - pp -= 1; - } - s.mtfbase[lno as usize] += 1; - while lno > 0 { - s.mtfbase[lno as usize] -= 1; - s.mtfa[s.mtfbase[lno as usize] as usize] = - s.mtfa[(s.mtfbase[(lno - 1) as usize] + 16 - 1) as usize]; - lno -= 1; - } - s.mtfbase[0_usize] -= 1; - s.mtfa[s.mtfbase[0_usize] as usize] = uc; - if s.mtfbase[0_usize] == 0 { - kk_0 = 4096 - 1; - ii_0 = 256 / 16 - 1; - while ii_0 >= 0 { - jj_0 = 16 - 1; - while jj_0 >= 0 { - s.mtfa[kk_0 as usize] = - s.mtfa[(s.mtfbase[ii_0 as usize] + jj_0) as usize]; - kk_0 -= 1; - jj_0 -= 1; - } - s.mtfbase[ii_0 as usize] = kk_0 + 1; - ii_0 -= 1; - } - } - } - s.unzftab[s.seqToUnseq[uc as usize] as usize] += 1; - match s.smallDecompress { - DecompressMode::Small => { - ll16[nblock as usize] = s.seqToUnseq[uc as usize] as u16 - } - DecompressMode::Fast => { - tt[nblock as usize] = s.seqToUnseq[uc as usize] as u32 - } - } - nblock += 1; - update_group_pos!(s); - zn = gMinlen; - current_block = BZ_X_MTF_5; - continue; + let uc = usize::from(initialize_mtfa(&mut s.mtfa, &mut s.mtfbase, nextSym)); + s.unzftab[usize::from(s.seqToUnseq[uc])] += 1; + match s.smallDecompress { + DecompressMode::Small => ll16[nblock as usize] = s.seqToUnseq[uc] as u16, + DecompressMode::Fast => tt[nblock as usize] = s.seqToUnseq[uc] as u32, } - current_block = Block46; + nblock += 1; + update_group_pos!(s); + zn = gMinlen; + current_block = BZ_X_MTF_5; + continue; } match current_block { Block46 => {} @@ -1116,7 +1052,7 @@ pub(crate) fn decompress( if logN >= LOG_2MB { error!(BZ_DATA_ERROR); } else { - let mul = match nextSym as u16 { + let mul = match nextSym { BZ_RUNA => 1, BZ_RUNB => 2, _ => 0, @@ -1254,6 +1190,7 @@ pub(crate) fn decompress( /*--- Create the Huffman decoding tables ---*/ for t in 0..nGroups as usize { + // NOTE: s.nInUse <= 256, alphaSize <= 258 let len = &s.len[t][..alphaSize as usize]; let mut minLen = 32u8; @@ -1281,14 +1218,13 @@ pub(crate) fn decompress( s.unzftab.fill(0); /*-- MTF init --*/ - let mut kk: i32; - kk = MTFA_SIZE - 1; + let mut kk: u16 = MTFA_SIZE - 1; for ii in (0..256 / MTFL_SIZE).rev() { for jj in (0..MTFL_SIZE).rev() { - s.mtfa[kk as usize] = (ii * MTFL_SIZE + jj) as u8; + s.mtfa[usize::from(kk)] = (ii * MTFL_SIZE + jj) as u8; kk -= 1; } - s.mtfbase[ii as usize] = kk + 1; + s.mtfbase[ii] = kk + 1; } /*-- end MTF init --*/ @@ -1332,3 +1268,47 @@ pub(crate) fn decompress( ret_val } + +fn initialize_mtfa(mtfa: &mut [u8; 4096], mtfbase: &mut [u16; 16], nextSym: u16) -> u8 { + let nn = usize::from(nextSym - 1); + + if nn < MTFL_SIZE { + // avoid general case expense + let pp = usize::from(mtfbase[0]); + let uc = mtfa[pp + nn]; + mtfa[pp..][..=nn].rotate_right(1); + + uc + } else { + // general case + let mut lno = nn.wrapping_div(MTFL_SIZE); + let off = nn.wrapping_rem(MTFL_SIZE); + let base = usize::from(mtfbase[lno]); + let uc = mtfa[base + off]; + + // shift this range one to the right + mtfa.copy_within(base..base + off, base + 1); + + mtfbase[lno] += 1; + while lno > 0 { + mtfbase[lno] -= 1; + mtfa[usize::from(mtfbase[lno])] = mtfa[usize::from(mtfbase[lno - 1] + 16 - 1)]; + lno -= 1; + } + mtfbase[0] -= 1; + mtfa[usize::from(mtfbase[0])] = uc; + + if mtfbase[0] == 0 { + let mut kk = MTFA_SIZE - 1; + for ii in (0..256 / MTFL_SIZE).rev() { + for jj in (0..MTFL_SIZE).rev() { + mtfa[usize::from(kk)] = mtfa[usize::from(mtfbase[ii]) + jj]; + kk -= 1; + } + mtfbase[ii] = kk + 1; + } + } + + uc + } +} diff --git a/libbz2-rs-sys/src/huffman.rs b/libbz2-rs-sys/src/huffman.rs index 7bfa1d57a..2319f354c 100644 --- a/libbz2-rs-sys/src/huffman.rs +++ b/libbz2-rs-sys/src/huffman.rs @@ -176,18 +176,20 @@ pub(crate) fn assign_codes( #[inline(always)] pub(crate) fn create_decode_tables( - limit: &mut [i32], - base: &mut [i32], - perm: &mut [i32], + limit: &mut [i32; 258], + base: &mut [i32; 258], + perm: &mut [u16; 258], length: &[u8], minLen: u8, maxLen: u8, ) { - let mut pp: i32 = 0; + assert!(length.len() <= 258); + + let mut pp = 0; for i in minLen..=maxLen { for (j, e) in length.iter().enumerate() { if *e == i { - perm[pp as usize] = j as i32; + perm[pp] = j as u16; pp += 1; } } @@ -196,7 +198,7 @@ pub(crate) fn create_decode_tables( base[0..BZ_MAX_CODE_LEN].fill(0); for l in length { - base[*l as usize + 1] += 1; + base[usize::from(*l) + 1] += 1; } for i in 1..BZ_MAX_CODE_LEN { @@ -206,13 +208,13 @@ pub(crate) fn create_decode_tables( limit[0..BZ_MAX_CODE_LEN].fill(0); let mut vec = 0; - for i in minLen..=maxLen { - vec += base[i as usize + 1] - base[i as usize]; - limit[i as usize] = vec - 1; + for i in usize::from(minLen)..=usize::from(maxLen) { + vec += base[i + 1] - base[i]; + limit[i] = vec - 1; vec <<= 1; } - for i in minLen + 1..=maxLen { - base[i as usize] = ((limit[i as usize - 1] + 1) << 1) - base[i as usize]; + for i in usize::from(minLen)..usize::from(maxLen) { + base[i + 1] = (2 * (limit[i] + 1)) - base[i + 1]; } }