Skip to content
86 changes: 35 additions & 51 deletions lib/common/bitstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,79 +187,63 @@ const fn get_middle_bits(

impl<'a> BIT_DStream_t<'a> {
pub(crate) fn new(srcBuffer: &'a [u8]) -> Result<Self, Error> {
let mut bitD = Self {
bitContainer: 0,
bitsConsumed: 0,
ptr: core::ptr::null::<core::ffi::c_char>(),
start: core::ptr::null::<core::ffi::c_char>(),
limitPtr: core::ptr::null::<core::ffi::c_char>(),
_marker: PhantomData,
};

if srcBuffer.is_empty() {
return Err(Error::srcSize_wrong);
}

const USIZE_BYTES: usize = size_of::<BitContainerType>();

if let Some(chunk) = srcBuffer.last_chunk() {
bitD.start = srcBuffer.as_ptr() as *const core::ffi::c_char;
bitD.limitPtr = bitD.start.wrapping_add(USIZE_BYTES);

bitD.ptr = (srcBuffer.as_ptr() as *const core::ffi::c_char)
.wrapping_add(srcBuffer.len())
.wrapping_sub(USIZE_BYTES);
bitD.bitContainer = usize::from_le_bytes(*chunk);

match srcBuffer.last().and_then(|v| v.checked_ilog2()) {
None => {
/* endMark not present */
return Err(Error::GENERIC);
}
Some(v) => {
bitD.bitsConsumed = 8 - v;
}
}
} else {
bitD.start = srcBuffer.as_ptr() as *const core::ffi::c_char;
bitD.limitPtr = bitD.start.wrapping_add(USIZE_BYTES);
bitD.ptr = bitD.start;
let start = srcBuffer.as_ptr() as *const core::ffi::c_char;
let limitPtr = start.wrapping_add(USIZE_BYTES);

bitD.bitContainer = usize::from(srcBuffer[0]);
// None when endMark not present
let bitsConsumed = srcBuffer
.last()
.and_then(|v| v.checked_ilog2())
.map(|v| 8 - v);

if let Some(chunk) = srcBuffer.last_chunk() {
Ok(Self {
bitContainer: usize::from_le_bytes(*chunk),
bitsConsumed: bitsConsumed.ok_or(Error::GENERIC)?,
ptr: start
.wrapping_add(srcBuffer.len())
.wrapping_sub(USIZE_BYTES),
start,
limitPtr,
_marker: PhantomData,
})
} else {
let mut bitContainer = usize::from(srcBuffer[0]);
if srcBuffer.len() >= 7 {
bitD.bitContainer += usize::from(srcBuffer[6]) << (USIZE_BYTES * 8 - 16);
bitContainer += usize::from(srcBuffer[6]) << (USIZE_BYTES * 8 - 16);
}
if srcBuffer.len() >= 6 {
bitD.bitContainer += usize::from(srcBuffer[5]) << (USIZE_BYTES * 8 - 24);
bitContainer += usize::from(srcBuffer[5]) << (USIZE_BYTES * 8 - 24);
}
if srcBuffer.len() >= 5 {
bitD.bitContainer += usize::from(srcBuffer[4]) << (USIZE_BYTES * 8 - 32);
bitContainer += usize::from(srcBuffer[4]) << (USIZE_BYTES * 8 - 32);
}
if srcBuffer.len() >= 4 {
bitD.bitContainer += usize::from(srcBuffer[3]) << 24;
bitContainer += usize::from(srcBuffer[3]) << 24;
}
if srcBuffer.len() >= 3 {
bitD.bitContainer += usize::from(srcBuffer[2]) << 16;
bitContainer += usize::from(srcBuffer[2]) << 16;
}
if srcBuffer.len() >= 2 {
bitD.bitContainer += usize::from(srcBuffer[1]) << 8;
bitContainer += usize::from(srcBuffer[1]) << 8;
}

match srcBuffer.last().and_then(|v| v.checked_ilog2()) {
None => {
/* endMark not present */
return Err(Error::corruption_detected);
}
Some(v) => {
bitD.bitsConsumed = 8 - v;
}
}

bitD.bitsConsumed += ((USIZE_BYTES - srcBuffer.len()) * 8) as u32;
Ok(Self {
bitContainer,
bitsConsumed: bitsConsumed.ok_or(Error::corruption_detected)?
+ ((USIZE_BYTES - srcBuffer.len()) * 8) as u32,
ptr: start,
start,
limitPtr,
_marker: PhantomData,
})
}

Ok(bitD)
}

/// Provides the next n bits from local register.
Expand Down
59 changes: 21 additions & 38 deletions lib/compress/huf_compress.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use core::ffi::{c_int, c_uint, c_void};
use core::ptr;

use libc::size_t;

Expand Down Expand Up @@ -1020,28 +1019,23 @@ pub struct HUF_CStream_t {
pub endPtr: *mut u8,
}

/// Initializes the bitstream.
///
/// # Returns
///
/// 0 or an error code.
unsafe fn HUF_initCStream(
bitC: &mut HUF_CStream_t,
startPtr: *mut c_void,
dstCapacity: size_t,
) -> size_t {
ptr::write_bytes(
ptr::from_mut(bitC).cast::<u8>(),
0,
size_of::<HUF_CStream_t>(),
);
bitC.startPtr = startPtr as *mut u8;
bitC.ptr = bitC.startPtr;
bitC.endPtr = (bitC.startPtr).add(dstCapacity).sub(size_of::<size_t>());
if dstCapacity <= size_of::<size_t>() {
return Error::dstSize_tooSmall.to_error_code();
impl HUF_CStream_t {
pub unsafe fn new(startPtr: *mut c_void, dstCapacity: size_t) -> Result<Self, Error> {
if dstCapacity <= size_of::<size_t>() {
return Err(Error::dstSize_tooSmall);
}

let startPtr = startPtr as *mut u8;
let endPtr = startPtr.add(dstCapacity).sub(size_of::<size_t>());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be safe with wrapping_{add ,sub}


Ok(HUF_CStream_t {
bitContainer: [0; 2],
bitPos: [0; 2],
startPtr,
ptr: startPtr,
endPtr,
})
}
0
}

/// Adds the symbol stored in HUF_CElt elt to the bitstream.
Expand Down Expand Up @@ -1270,27 +1264,16 @@ unsafe fn HUF_compress1X_usingCTable_internal_body(
let tableLog = CTable.header.tableLog as u32;
let ct = &CTable.elements;
let ip = src as *const u8;
let ostart = dst as *mut u8;
let oend = ostart.add(dstSize);
let mut bitC = HUF_CStream_t {
bitContainer: [0; 2],
bitPos: [0; 2],
startPtr: core::ptr::null_mut::<u8>(),
ptr: core::ptr::null_mut::<u8>(),
endPtr: core::ptr::null_mut::<u8>(),
};

/* init */
if dstSize < 8 {
return 0; /* not enough space to compress */
}
{
let op = ostart;
let initErr = HUF_initCStream(&mut bitC, op as *mut c_void, oend.offset_from_unsigned(op));
if ERR_isError(initErr) {
return 0;
}
}

let mut bitC = match HUF_CStream_t::new(dst, dstSize) {
Ok(bitC) => bitC,
Err(_) => return 0,
};
Comment on lines +1273 to +1276

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shorter as let-else


if dstSize < HUF_tightCompressBound(srcSize, tableLog as size_t) || tableLog > 11 {
HUF_compress1X_usingCTable_internal_body_loop(
Expand Down
Loading
Loading