From 46ff0402239b82c0012c6dea768a6ad6c95578f7 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:32:40 +0200 Subject: [PATCH 01/33] `fn HIST_count_simple`: pointer argument to reference --- lib/compress/hist.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress/hist.rs b/lib/compress/hist.rs index e1204bd2..96790af9 100644 --- a/lib/compress/hist.rs +++ b/lib/compress/hist.rs @@ -31,7 +31,7 @@ pub unsafe fn HIST_add( pub unsafe fn HIST_count_simple( count: *mut core::ffi::c_uint, - maxSymbolValuePtr: *mut core::ffi::c_uint, + maxSymbolValuePtr: &mut core::ffi::c_uint, src: *const core::ffi::c_void, srcSize: size_t, ) -> core::ffi::c_uint { @@ -188,7 +188,7 @@ pub unsafe fn HIST_countFast_wksp( workSpaceSize: size_t, ) -> size_t { if sourceSize < HIST_FAST_THRESHOLD as size_t { - return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize) as size_t; + return HIST_count_simple(count, &mut *maxSymbolValuePtr, source, sourceSize) as size_t; } if workSpace as size_t & 3 != 0 { // must be aligned on 4-bytes boundaries From 30c52a7861ffc8852092ad62003b9963631378e5 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:35:51 +0200 Subject: [PATCH 02/33] `fn HIST_count_parallel_wksp`: pointer argument to reference --- lib/compress/hist.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/compress/hist.rs b/lib/compress/hist.rs index 96790af9..e31b387a 100644 --- a/lib/compress/hist.rs +++ b/lib/compress/hist.rs @@ -83,7 +83,7 @@ pub unsafe fn HIST_count_simple( /// histogram's alphabet is larger than *maxSymbolValuePtr) unsafe fn HIST_count_parallel_wksp( count: *mut core::ffi::c_uint, - maxSymbolValuePtr: *mut core::ffi::c_uint, + maxSymbolValuePtr: &mut core::ffi::c_uint, source: *const core::ffi::c_void, sourceSize: size_t, check: HIST_checkInput_e, @@ -199,7 +199,7 @@ pub unsafe fn HIST_countFast_wksp( } HIST_count_parallel_wksp( count, - maxSymbolValuePtr, + &mut *maxSymbolValuePtr, source, sourceSize, trustInput, @@ -227,7 +227,7 @@ pub unsafe fn HIST_count_wksp( if *maxSymbolValuePtr < 255 { return HIST_count_parallel_wksp( count, - maxSymbolValuePtr, + &mut *maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue, From 3cb1988db79d847d18e3c7e86c7b2a6930126994 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:36:17 +0200 Subject: [PATCH 03/33] `fn HIST_countFast_wksp`: pointer argument to reference --- lib/compress/hist.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/compress/hist.rs b/lib/compress/hist.rs index e31b387a..b1142be3 100644 --- a/lib/compress/hist.rs +++ b/lib/compress/hist.rs @@ -181,14 +181,14 @@ unsafe fn HIST_count_parallel_wksp( /// `workSpaceSize` must be >= HIST_WKSP_SIZE pub unsafe fn HIST_countFast_wksp( count: *mut core::ffi::c_uint, - maxSymbolValuePtr: *mut core::ffi::c_uint, + maxSymbolValuePtr: &mut core::ffi::c_uint, source: *const core::ffi::c_void, sourceSize: size_t, workSpace: *mut core::ffi::c_void, workSpaceSize: size_t, ) -> size_t { if sourceSize < HIST_FAST_THRESHOLD as size_t { - return HIST_count_simple(count, &mut *maxSymbolValuePtr, source, sourceSize) as size_t; + return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize) as size_t; } if workSpace as size_t & 3 != 0 { // must be aligned on 4-bytes boundaries @@ -199,7 +199,7 @@ pub unsafe fn HIST_countFast_wksp( } HIST_count_parallel_wksp( count, - &mut *maxSymbolValuePtr, + maxSymbolValuePtr, source, sourceSize, trustInput, @@ -237,7 +237,7 @@ pub unsafe fn HIST_count_wksp( *maxSymbolValuePtr = 255; HIST_countFast_wksp( count, - maxSymbolValuePtr, + &mut *maxSymbolValuePtr, source, sourceSize, workSpace, @@ -255,7 +255,7 @@ pub unsafe fn HIST_countFast( let mut tmpCounters: [core::ffi::c_uint; HIST_WKSP_SIZE_U32] = [0; HIST_WKSP_SIZE_U32]; HIST_countFast_wksp( count, - maxSymbolValuePtr, + &mut *maxSymbolValuePtr, source, sourceSize, tmpCounters.as_mut_ptr() as *mut core::ffi::c_void, From 5e0540bbd2c0d52c576196a4bfe5626817fc7f1f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:36:39 +0200 Subject: [PATCH 04/33] `fn HIST_count_wksp`: pointer argument to reference --- lib/compress/hist.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/compress/hist.rs b/lib/compress/hist.rs index b1142be3..8d6447a4 100644 --- a/lib/compress/hist.rs +++ b/lib/compress/hist.rs @@ -211,7 +211,7 @@ pub unsafe fn HIST_countFast_wksp( /// `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned pub unsafe fn HIST_count_wksp( count: *mut core::ffi::c_uint, - maxSymbolValuePtr: *mut core::ffi::c_uint, + maxSymbolValuePtr: &mut core::ffi::c_uint, source: *const core::ffi::c_void, sourceSize: size_t, workSpace: *mut core::ffi::c_void, @@ -227,7 +227,7 @@ pub unsafe fn HIST_count_wksp( if *maxSymbolValuePtr < 255 { return HIST_count_parallel_wksp( count, - &mut *maxSymbolValuePtr, + maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue, @@ -237,7 +237,7 @@ pub unsafe fn HIST_count_wksp( *maxSymbolValuePtr = 255; HIST_countFast_wksp( count, - &mut *maxSymbolValuePtr, + maxSymbolValuePtr, source, sourceSize, workSpace, @@ -272,7 +272,7 @@ pub unsafe fn HIST_count( let mut tmpCounters: [core::ffi::c_uint; HIST_WKSP_SIZE_U32] = [0; HIST_WKSP_SIZE_U32]; HIST_count_wksp( count, - maxSymbolValuePtr, + &mut *maxSymbolValuePtr, src, srcSize, tmpCounters.as_mut_ptr() as *mut core::ffi::c_void, From 78cacf949725928038c27576ea3bbe6c61673537 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:36:50 +0200 Subject: [PATCH 05/33] `fn HIST_countFast`: pointer argument to reference --- lib/compress/hist.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress/hist.rs b/lib/compress/hist.rs index 8d6447a4..6c3d097a 100644 --- a/lib/compress/hist.rs +++ b/lib/compress/hist.rs @@ -248,14 +248,14 @@ pub unsafe fn HIST_count_wksp( /// fast variant (unsafe : won't check if src contains values beyond count[] limit) pub unsafe fn HIST_countFast( count: *mut core::ffi::c_uint, - maxSymbolValuePtr: *mut core::ffi::c_uint, + maxSymbolValuePtr: &mut core::ffi::c_uint, source: *const core::ffi::c_void, sourceSize: size_t, ) -> size_t { let mut tmpCounters: [core::ffi::c_uint; HIST_WKSP_SIZE_U32] = [0; HIST_WKSP_SIZE_U32]; HIST_countFast_wksp( count, - &mut *maxSymbolValuePtr, + maxSymbolValuePtr, source, sourceSize, tmpCounters.as_mut_ptr() as *mut core::ffi::c_void, From 71fd7efd310f3b5cf0a14310e68117cbcb75ca01 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:36:59 +0200 Subject: [PATCH 06/33] `fn HIST_count`: pointer argument to reference --- lib/compress/hist.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress/hist.rs b/lib/compress/hist.rs index 6c3d097a..025ac81b 100644 --- a/lib/compress/hist.rs +++ b/lib/compress/hist.rs @@ -265,14 +265,14 @@ pub unsafe fn HIST_countFast( pub unsafe fn HIST_count( count: *mut core::ffi::c_uint, - maxSymbolValuePtr: *mut core::ffi::c_uint, + maxSymbolValuePtr: &mut core::ffi::c_uint, src: *const core::ffi::c_void, srcSize: size_t, ) -> size_t { let mut tmpCounters: [core::ffi::c_uint; HIST_WKSP_SIZE_U32] = [0; HIST_WKSP_SIZE_U32]; HIST_count_wksp( count, - &mut *maxSymbolValuePtr, + maxSymbolValuePtr, src, srcSize, tmpCounters.as_mut_ptr() as *mut core::ffi::c_void, From ebb41c9b1c396348ae91144507dd11e3fa4d6f40 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:40:00 +0200 Subject: [PATCH 07/33] `fn FSE_initCState`: pointer argument to reference --- lib/common/fse.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/common/fse.rs b/lib/common/fse.rs index a3cb408f..7995fd46 100644 --- a/lib/common/fse.rs +++ b/lib/common/fse.rs @@ -70,20 +70,20 @@ pub(crate) struct FSE_symbolCompressionTransform { } #[inline] -pub(crate) unsafe fn FSE_initCState(statePtr: *mut FSE_CState_t, ct: *const FSE_CTable) { +pub(crate) unsafe fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: *const FSE_CTable) { let ptr = ct as *const core::ffi::c_void; let u16ptr = ptr as *const u16; let tableLog = MEM_read16(ptr) as u32; - (*statePtr).value = (1) << tableLog; - (*statePtr).stateTable = u16ptr.add(2) as *const core::ffi::c_void; - (*statePtr).symbolTT = ct.add(1).offset( + statePtr.value = (1) << tableLog; + statePtr.stateTable = u16ptr.add(2) as *const core::ffi::c_void; + statePtr.symbolTT = ct.add(1).offset( (if tableLog != 0 { (1) << tableLog.wrapping_sub(1) } else { 1 }) as isize, ) as *const core::ffi::c_void; - (*statePtr).stateLog = tableLog; + statePtr.stateLog = tableLog; } #[inline] @@ -92,7 +92,7 @@ pub(crate) unsafe fn FSE_initCState2( ct: *const FSE_CTable, symbol: u32, ) { - FSE_initCState(statePtr, ct); + FSE_initCState(&mut *statePtr, ct); let symbolTT = *((*statePtr).symbolTT as *const FSE_symbolCompressionTransform).offset(symbol as isize); let stateTable = (*statePtr).stateTable as *const u16; From 42a2b2e1bf2499c2471c401d83f2116b04b5d54f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:40:16 +0200 Subject: [PATCH 08/33] `fn FSE_initCState2`: pointer argument to reference --- lib/common/fse.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/common/fse.rs b/lib/common/fse.rs index 7995fd46..e2f3c4c2 100644 --- a/lib/common/fse.rs +++ b/lib/common/fse.rs @@ -88,18 +88,18 @@ pub(crate) unsafe fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: *const FSE_ #[inline] pub(crate) unsafe fn FSE_initCState2( - statePtr: *mut FSE_CState_t, + statePtr: &mut FSE_CState_t, ct: *const FSE_CTable, symbol: u32, ) { - FSE_initCState(&mut *statePtr, ct); + FSE_initCState(statePtr, ct); let symbolTT = - *((*statePtr).symbolTT as *const FSE_symbolCompressionTransform).offset(symbol as isize); - let stateTable = (*statePtr).stateTable as *const u16; + *(statePtr.symbolTT as *const FSE_symbolCompressionTransform).offset(symbol as isize); + let stateTable = statePtr.stateTable as *const u16; let nbBitsOut = (symbolTT.deltaNbBits).wrapping_add(((1) << 15) as u32) >> 16; - (*statePtr).value = (nbBitsOut << 16).wrapping_sub(symbolTT.deltaNbBits) as ptrdiff_t; - (*statePtr).value = *stateTable - .offset(((*statePtr).value >> nbBitsOut) + symbolTT.deltaFindState as ptrdiff_t) + statePtr.value = (nbBitsOut << 16).wrapping_sub(symbolTT.deltaNbBits) as ptrdiff_t; + statePtr.value = *stateTable + .offset((statePtr.value >> nbBitsOut) + symbolTT.deltaFindState as ptrdiff_t) as ptrdiff_t; } From 95e587c3f85a3ceff84524a7e5889eed5070212f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:41:17 +0200 Subject: [PATCH 09/33] `fn FSE_encodeSymbol`: pointer argument to reference --- lib/common/fse.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/common/fse.rs b/lib/common/fse.rs index e2f3c4c2..d1fcc8d3 100644 --- a/lib/common/fse.rs +++ b/lib/common/fse.rs @@ -106,16 +106,16 @@ pub(crate) unsafe fn FSE_initCState2( #[inline] pub(crate) unsafe fn FSE_encodeSymbol( bitC: &mut BIT_CStream_t, - statePtr: *mut FSE_CState_t, + statePtr: &mut FSE_CState_t, symbol: core::ffi::c_uint, ) { let symbolTT = - *((*statePtr).symbolTT as *const FSE_symbolCompressionTransform).offset(symbol as isize); - let stateTable = (*statePtr).stateTable as *const u16; - let nbBitsOut = (((*statePtr).value + symbolTT.deltaNbBits as ptrdiff_t) >> 16) as u32; - BIT_addBits(bitC, (*statePtr).value as BitContainerType, nbBitsOut); - (*statePtr).value = *stateTable - .offset(((*statePtr).value >> nbBitsOut) + symbolTT.deltaFindState as ptrdiff_t) + *(statePtr.symbolTT as *const FSE_symbolCompressionTransform).offset(symbol as isize); + let stateTable = statePtr.stateTable as *const u16; + let nbBitsOut = ((statePtr.value + symbolTT.deltaNbBits as ptrdiff_t) >> 16) as u32; + BIT_addBits(bitC, statePtr.value as BitContainerType, nbBitsOut); + statePtr.value = *stateTable + .offset((statePtr.value >> nbBitsOut) + symbolTT.deltaFindState as ptrdiff_t) as ptrdiff_t; } From 9295db76cb598d57f1f527fb46aa7de8a3815407 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:41:40 +0200 Subject: [PATCH 10/33] `fn FSE_flushCState`: pointer argument to reference --- lib/common/fse.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/common/fse.rs b/lib/common/fse.rs index d1fcc8d3..1e2b1343 100644 --- a/lib/common/fse.rs +++ b/lib/common/fse.rs @@ -120,12 +120,8 @@ pub(crate) unsafe fn FSE_encodeSymbol( } #[inline] -pub(crate) unsafe fn FSE_flushCState(bitC: &mut BIT_CStream_t, statePtr: *const FSE_CState_t) { - BIT_addBits( - bitC, - (*statePtr).value as BitContainerType, - (*statePtr).stateLog, - ); +pub(crate) unsafe fn FSE_flushCState(bitC: &mut BIT_CStream_t, statePtr: &FSE_CState_t) { + BIT_addBits(bitC, statePtr.value as BitContainerType, statePtr.stateLog); BIT_flushBits(bitC); } From 3a42cb4999759263fb9871acc1caf8a1347ec850 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:42:55 +0200 Subject: [PATCH 11/33] lib/compress/fse_compress: use the shared `FSE_initCState2` and `FSE_flushCState` --- lib/compress/fse_compress.rs | 49 ++++++------------------------------ 1 file changed, 7 insertions(+), 42 deletions(-) diff --git a/lib/compress/fse_compress.rs b/lib/compress/fse_compress.rs index e9c96623..637c2bac 100644 --- a/lib/compress/fse_compress.rs +++ b/lib/compress/fse_compress.rs @@ -1,52 +1,17 @@ -use libc::{ptrdiff_t, size_t}; +use libc::size_t; use crate::lib::common::bits::ZSTD_highbit32; use crate::lib::common::bitstream::{ - BIT_CStream_t, BIT_addBits, BIT_closeCStream, BIT_flushBits, BIT_flushBitsFast, - BIT_initCStream, BitContainerType, + BIT_CStream_t, BIT_closeCStream, BIT_flushBits, BIT_flushBitsFast, BIT_initCStream, + BitContainerType, }; use crate::lib::common::error_private::{ERR_isError, Error}; use crate::lib::common::fse::{ - FSE_CState_t, FSE_CTable, FSE_encodeSymbol, FSE_symbolCompressionTransform, - FSE_DEFAULT_TABLELOG, FSE_MAX_TABLELOG, FSE_MIN_TABLELOG, FSE_NCOUNTBOUND, + FSE_CState_t, FSE_CTable, FSE_encodeSymbol, FSE_flushCState, FSE_initCState2, + FSE_symbolCompressionTransform, FSE_DEFAULT_TABLELOG, FSE_MAX_TABLELOG, FSE_MIN_TABLELOG, + FSE_NCOUNTBOUND, }; -use crate::lib::common::mem::{MEM_read16, MEM_write64}; - -#[inline] -unsafe fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: *const FSE_CTable) { - let ptr = ct as *const core::ffi::c_void; - let u16ptr = ptr as *const u16; - let tableLog = MEM_read16(ptr) as u32; - statePtr.value = 1 << tableLog; - statePtr.stateTable = u16ptr.add(2) as *const core::ffi::c_void; - statePtr.symbolTT = ct.add(1).offset( - (if tableLog != 0 { - 1 << tableLog.wrapping_sub(1) - } else { - 1 - }) as isize, - ) as *const core::ffi::c_void; - statePtr.stateLog = tableLog; -} - -#[inline] -unsafe fn FSE_initCState2(statePtr: &mut FSE_CState_t, ct: *const FSE_CTable, symbol: u32) { - FSE_initCState(statePtr, ct); - let symbolTT = - *(statePtr.symbolTT as *const FSE_symbolCompressionTransform).offset(symbol as isize); - let stateTable = statePtr.stateTable as *const u16; - let nbBitsOut = (symbolTT.deltaNbBits).wrapping_add((1 << 15) as u32) >> 16; - statePtr.value = (nbBitsOut << 16).wrapping_sub(symbolTT.deltaNbBits) as ptrdiff_t; - statePtr.value = *stateTable - .offset((statePtr.value >> nbBitsOut) + symbolTT.deltaFindState as ptrdiff_t) - as ptrdiff_t; -} - -#[inline] -unsafe fn FSE_flushCState(bitC: &mut BIT_CStream_t, statePtr: &FSE_CState_t) { - BIT_addBits(bitC, statePtr.value as BitContainerType, statePtr.stateLog); - BIT_flushBits(bitC); -} +use crate::lib::common::mem::MEM_write64; /// Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). /// wkspSize should be sized to handle worst case situation, which is `1< Date: Mon, 10 Aug 2026 10:48:26 +0200 Subject: [PATCH 12/33] `fn ZSTD_estimateBlockSize_symbolType`: pass `fseCTable` as a slice --- lib/compress/zstd_compress.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/compress/zstd_compress.rs b/lib/compress/zstd_compress.rs index 9756e827..143fbb5e 100644 --- a/lib/compress/zstd_compress.rs +++ b/lib/compress/zstd_compress.rs @@ -6310,7 +6310,7 @@ unsafe fn ZSTD_estimateBlockSize_symbolType( codeTable: *const u8, nbSeq: size_t, maxCode: core::ffi::c_uint, - fseCTable: *const FSE_CTable, + fseCTable: &[FSE_CTable], additionalBits: *const u8, defaultNorm: *const core::ffi::c_short, defaultNormLog: u32, @@ -6342,7 +6342,7 @@ unsafe fn ZSTD_estimateBlockSize_symbolType( } else if type_0 == set_rle { cSymbolTypeSizeEstimateInBits = 0; } else if type_0 == set_compressed || type_0 == set_repeat { - cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max); + cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable.as_ptr(), countWksp, max); } if ERR_isError(cSymbolTypeSizeEstimateInBits) { return nbSeq * 10; @@ -6385,7 +6385,7 @@ unsafe fn ZSTD_estimateBlockSize_sequences( ofCodeTable, nbSeq, MaxOff, - (fseTables.offcodeCTable).as_ptr(), + &fseTables.offcodeCTable, core::ptr::null(), OF_defaultNorm.as_ptr(), OF_defaultNormLog, @@ -6398,7 +6398,7 @@ unsafe fn ZSTD_estimateBlockSize_sequences( llCodeTable, nbSeq, MaxLL, - (fseTables.litlengthCTable).as_ptr(), + &fseTables.litlengthCTable, LL_bits.as_ptr(), LL_defaultNorm.as_ptr(), LL_defaultNormLog, @@ -6411,7 +6411,7 @@ unsafe fn ZSTD_estimateBlockSize_sequences( mlCodeTable, nbSeq, MaxML, - (fseTables.matchlengthCTable).as_ptr(), + &fseTables.matchlengthCTable, ML_bits.as_ptr(), ML_defaultNorm.as_ptr(), ML_defaultNormLog, From d2375f430a8d0f78ee31f010c78e84834fab83e9 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:48:48 +0200 Subject: [PATCH 13/33] `fn ZSTD_estimateSubBlockSize_symbolType`: pass `fseCTable` as a slice --- lib/compress/zstd_compress_superblock.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/compress/zstd_compress_superblock.rs b/lib/compress/zstd_compress_superblock.rs index 0629f378..a31bd38f 100644 --- a/lib/compress/zstd_compress_superblock.rs +++ b/lib/compress/zstd_compress_superblock.rs @@ -711,7 +711,7 @@ unsafe fn ZSTD_estimateSubBlockSize_symbolType( codeTable: *const u8, maxCode: core::ffi::c_uint, nbSeq: size_t, - fseCTable: *const FSE_CTable, + fseCTable: &[FSE_CTable], additionalBits: *const u8, defaultNorm: *const core::ffi::c_short, defaultNormLog: u32, @@ -744,7 +744,7 @@ unsafe fn ZSTD_estimateSubBlockSize_symbolType( } else if type_0 == set_rle { cSymbolTypeSizeEstimateInBits = 0; } else if type_0 == set_compressed || type_0 == set_repeat { - cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max); + cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable.as_ptr(), countWksp, max); } if ERR_isError(cSymbolTypeSizeEstimateInBits) { return nbSeq * 10; @@ -784,7 +784,7 @@ unsafe fn ZSTD_estimateSubBlockSize_sequences( ofCodeTable, MaxOff, nbSeq, - (fseTables.offcodeCTable).as_ptr(), + &fseTables.offcodeCTable, core::ptr::null(), OF_defaultNorm.as_ptr(), OF_defaultNormLog, @@ -797,7 +797,7 @@ unsafe fn ZSTD_estimateSubBlockSize_sequences( llCodeTable, MaxLL, nbSeq, - (fseTables.litlengthCTable).as_ptr(), + &fseTables.litlengthCTable, LL_bits.as_ptr(), LL_defaultNorm.as_ptr(), LL_defaultNormLog, @@ -810,7 +810,7 @@ unsafe fn ZSTD_estimateSubBlockSize_sequences( mlCodeTable, MaxML, nbSeq, - (fseTables.matchlengthCTable).as_ptr(), + &fseTables.matchlengthCTable, ML_bits.as_ptr(), ML_defaultNorm.as_ptr(), ML_defaultNormLog, From 3319fe9514f342cf7bbf0a70f659cb56631c6d70 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:49:26 +0200 Subject: [PATCH 14/33] `fn ZSTD_selectEncodingType`: pass `prevCTable` as a slice --- lib/compress/zstd_compress.rs | 6 +++--- lib/compress/zstd_compress_sequences.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/compress/zstd_compress.rs b/lib/compress/zstd_compress.rs index 143fbb5e..038546d8 100644 --- a/lib/compress/zstd_compress.rs +++ b/lib/compress/zstd_compress.rs @@ -4908,7 +4908,7 @@ unsafe fn ZSTD_buildSequencesStatistics( mostFrequent, nbSeq, LLFSELog, - (prevEntropy.litlengthCTable).as_ptr(), + &prevEntropy.litlengthCTable, LL_defaultNorm.as_ptr(), LL_defaultNormLog, ZSTD_defaultAllowed, @@ -4965,7 +4965,7 @@ unsafe fn ZSTD_buildSequencesStatistics( mostFrequent_0, nbSeq, OffFSELog, - (prevEntropy.offcodeCTable).as_ptr(), + &prevEntropy.offcodeCTable, OF_defaultNorm.as_ptr(), OF_defaultNormLog, defaultPolicy, @@ -5016,7 +5016,7 @@ unsafe fn ZSTD_buildSequencesStatistics( mostFrequent_1, nbSeq, MLFSELog, - (prevEntropy.matchlengthCTable).as_ptr(), + &prevEntropy.matchlengthCTable, ML_defaultNorm.as_ptr(), ML_defaultNormLog, ZSTD_defaultAllowed, diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index 23e5ee33..4a410f4e 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -187,7 +187,7 @@ pub unsafe fn ZSTD_selectEncodingType( mostFrequent: size_t, nbSeq: size_t, FSELog: core::ffi::c_uint, - prevCTable: *const FSE_CTable, + prevCTable: &[FSE_CTable], defaultNorm: *const core::ffi::c_short, defaultNormLog: u32, isDefaultAllowed: ZSTD_DefaultPolicy_e, @@ -232,7 +232,7 @@ pub unsafe fn ZSTD_selectEncodingType( Error::GENERIC.to_error_code() }; let repeatCost = if *repeatMode != FSE_repeat_none { - ZSTD_fseBitCost(prevCTable, count, max) + ZSTD_fseBitCost(prevCTable.as_ptr(), count, max) } else { Error::GENERIC.to_error_code() }; From 191f2fcfe8a8c6670c41572f53144c88499169b2 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:50:00 +0200 Subject: [PATCH 15/33] `fn ZSTD_fseBitCost`: pass `ctable` as a slice --- lib/compress/zstd_compress.rs | 2 +- lib/compress/zstd_compress_sequences.rs | 8 ++++---- lib/compress/zstd_compress_superblock.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstd_compress.rs b/lib/compress/zstd_compress.rs index 038546d8..29749be7 100644 --- a/lib/compress/zstd_compress.rs +++ b/lib/compress/zstd_compress.rs @@ -6342,7 +6342,7 @@ unsafe fn ZSTD_estimateBlockSize_symbolType( } else if type_0 == set_rle { cSymbolTypeSizeEstimateInBits = 0; } else if type_0 == set_compressed || type_0 == set_repeat { - cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable.as_ptr(), countWksp, max); + cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max); } if ERR_isError(cSymbolTypeSizeEstimateInBits) { return nbSeq * 10; diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index 4a410f4e..79b5d239 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -124,7 +124,7 @@ unsafe fn ZSTD_entropyCost( /// Returns the cost in bits of encoding the distribution in count using ctable. /// Returns an error if ctable cannot represent all the symbols in count. pub unsafe fn ZSTD_fseBitCost( - ctable: *const FSE_CTable, + ctable: &[FSE_CTable], count: *const core::ffi::c_uint, max: core::ffi::c_uint, ) -> size_t { @@ -136,8 +136,8 @@ pub unsafe fn ZSTD_fseBitCost( symbolTT: core::ptr::null::(), stateLog: 0, }; - FSE_initCState(&mut cstate, ctable); - if ZSTD_getFSEMaxSymbolValue(ctable) < max { + FSE_initCState(&mut cstate, ctable.as_ptr()); + if ZSTD_getFSEMaxSymbolValue(ctable.as_ptr()) < max { return Error::GENERIC.to_error_code(); } for s in 0..max + 1 { @@ -232,7 +232,7 @@ pub unsafe fn ZSTD_selectEncodingType( Error::GENERIC.to_error_code() }; let repeatCost = if *repeatMode != FSE_repeat_none { - ZSTD_fseBitCost(prevCTable.as_ptr(), count, max) + ZSTD_fseBitCost(prevCTable, count, max) } else { Error::GENERIC.to_error_code() }; diff --git a/lib/compress/zstd_compress_superblock.rs b/lib/compress/zstd_compress_superblock.rs index a31bd38f..8bbb9063 100644 --- a/lib/compress/zstd_compress_superblock.rs +++ b/lib/compress/zstd_compress_superblock.rs @@ -744,7 +744,7 @@ unsafe fn ZSTD_estimateSubBlockSize_symbolType( } else if type_0 == set_rle { cSymbolTypeSizeEstimateInBits = 0; } else if type_0 == set_compressed || type_0 == set_repeat { - cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable.as_ptr(), countWksp, max); + cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max); } if ERR_isError(cSymbolTypeSizeEstimateInBits) { return nbSeq * 10; From f8aef705e50de6013bf05239026458d7f9348947 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:50:01 +0200 Subject: [PATCH 16/33] `fn ZSTD_getFSEMaxSymbolValue`: pass `ctable` as a slice --- lib/compress/zstd_compress_sequences.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index 79b5d239..36d5bbbd 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -52,9 +52,8 @@ static kInverseProbabilityLog256: [core::ffi::c_uint; 256] = [ 37, 36, 34, 33, 31, 30, 28, 26, 25, 23, 22, 20, 19, 17, 16, 14, 13, 11, 10, 8, 7, 5, 4, 2, 1, ]; -unsafe fn ZSTD_getFSEMaxSymbolValue(ctable: *const FSE_CTable) -> core::ffi::c_uint { - let ptr = ctable as *const core::ffi::c_void; - let u16ptr = ptr as *const u16; +unsafe fn ZSTD_getFSEMaxSymbolValue(ctable: &[FSE_CTable]) -> core::ffi::c_uint { + let u16ptr = ctable.as_ptr() as *const u16; MEM_read16(u16ptr.add(1) as *const core::ffi::c_void) as u32 } @@ -137,7 +136,7 @@ pub unsafe fn ZSTD_fseBitCost( stateLog: 0, }; FSE_initCState(&mut cstate, ctable.as_ptr()); - if ZSTD_getFSEMaxSymbolValue(ctable.as_ptr()) < max { + if ZSTD_getFSEMaxSymbolValue(ctable) < max { return Error::GENERIC.to_error_code(); } for s in 0..max + 1 { From 8b0e974383403182e4e0c27dc0d2a7a45aaf32ca Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:51:13 +0200 Subject: [PATCH 17/33] `fn ZSTD_encodeSequences`: pass the CTables as slices --- lib/compress/zstd_compress.rs | 9 +++------ lib/compress/zstd_compress_sequences.rs | 18 +++++++++--------- lib/compress/zstd_compress_superblock.rs | 6 +++--- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/lib/compress/zstd_compress.rs b/lib/compress/zstd_compress.rs index 29749be7..51678ecb 100644 --- a/lib/compress/zstd_compress.rs +++ b/lib/compress/zstd_compress.rs @@ -5078,9 +5078,6 @@ unsafe fn ZSTD_entropyCompressSeqStore_internal( ) -> size_t { let strategy = cctxParams.cParams.strategy; let count = entropyWorkspace as *mut core::ffi::c_uint; - let CTable_LitLength = (&raw const (nextEntropy.fse.litlengthCTable)).cast::(); - let CTable_OffsetBits = (&raw const (nextEntropy.fse.offcodeCTable)).cast::(); - let CTable_MatchLength = (&raw const (nextEntropy.fse.matchlengthCTable)).cast::(); let sequences: *const SeqDef = (*seqStorePtr).sequencesStart; let nbSeq = ((*seqStorePtr).sequences).offset_from((*seqStorePtr).sequencesStart) as size_t; let ofCodeTable: *const u8 = (*seqStorePtr).ofCode; @@ -5178,11 +5175,11 @@ unsafe fn ZSTD_entropyCompressSeqStore_internal( let bitstreamSize = ZSTD_encodeSequences( op as *mut core::ffi::c_void, oend.offset_from_unsigned(op), - CTable_MatchLength, + &nextEntropy.fse.matchlengthCTable, mlCodeTable, - CTable_OffsetBits, + &nextEntropy.fse.offcodeCTable, ofCodeTable, - CTable_LitLength, + &nextEntropy.fse.litlengthCTable, llCodeTable, sequences, nbSeq, diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index 36d5bbbd..84e00781 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -607,11 +607,11 @@ unsafe fn ZSTD_encodeSequences_bmi2( pub unsafe fn ZSTD_encodeSequences( dst: *mut core::ffi::c_void, dstCapacity: size_t, - CTable_MatchLength: *const FSE_CTable, + CTable_MatchLength: &[FSE_CTable], mlCodeTable: *const u8, - CTable_OffsetBits: *const FSE_CTable, + CTable_OffsetBits: &[FSE_CTable], ofCodeTable: *const u8, - CTable_LitLength: *const FSE_CTable, + CTable_LitLength: &[FSE_CTable], llCodeTable: *const u8, sequences: *const SeqDef, nbSeq: size_t, @@ -622,11 +622,11 @@ pub unsafe fn ZSTD_encodeSequences( return ZSTD_encodeSequences_bmi2( dst, dstCapacity, - CTable_MatchLength, + CTable_MatchLength.as_ptr(), mlCodeTable, - CTable_OffsetBits, + CTable_OffsetBits.as_ptr(), ofCodeTable, - CTable_LitLength, + CTable_LitLength.as_ptr(), llCodeTable, sequences, nbSeq, @@ -636,11 +636,11 @@ pub unsafe fn ZSTD_encodeSequences( ZSTD_encodeSequences_default( dst, dstCapacity, - CTable_MatchLength, + CTable_MatchLength.as_ptr(), mlCodeTable, - CTable_OffsetBits, + CTable_OffsetBits.as_ptr(), ofCodeTable, - CTable_LitLength, + CTable_LitLength.as_ptr(), llCodeTable, sequences, nbSeq, diff --git a/lib/compress/zstd_compress_superblock.rs b/lib/compress/zstd_compress_superblock.rs index 8bbb9063..7ff3db11 100644 --- a/lib/compress/zstd_compress_superblock.rs +++ b/lib/compress/zstd_compress_superblock.rs @@ -539,11 +539,11 @@ unsafe fn ZSTD_compressSubBlock_sequences( let bitstreamSize = ZSTD_encodeSequences( op as *mut core::ffi::c_void, oend.offset_from_unsigned(op), - (fseTables.matchlengthCTable).as_ptr(), + &fseTables.matchlengthCTable, mlCode, - (fseTables.offcodeCTable).as_ptr(), + &fseTables.offcodeCTable, ofCode, - (fseTables.litlengthCTable).as_ptr(), + &fseTables.litlengthCTable, llCode, sequences, nbSeq, From b12a3e13a52dfbfa000be64af8c17aa37ad74f61 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:51:45 +0200 Subject: [PATCH 18/33] `fn ZSTD_encodeSequences_default` and `_bmi2`: pass the CTables as slices --- lib/compress/zstd_compress_sequences.rs | 36 ++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index 84e00781..d0ab0099 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -551,11 +551,11 @@ unsafe fn ZSTD_encodeSequences_body( unsafe fn ZSTD_encodeSequences_default( dst: *mut core::ffi::c_void, dstCapacity: size_t, - CTable_MatchLength: *const FSE_CTable, + CTable_MatchLength: &[FSE_CTable], mlCodeTable: *const u8, - CTable_OffsetBits: *const FSE_CTable, + CTable_OffsetBits: &[FSE_CTable], ofCodeTable: *const u8, - CTable_LitLength: *const FSE_CTable, + CTable_LitLength: &[FSE_CTable], llCodeTable: *const u8, sequences: *const SeqDef, nbSeq: size_t, @@ -564,11 +564,11 @@ unsafe fn ZSTD_encodeSequences_default( ZSTD_encodeSequences_body( dst, dstCapacity, - CTable_MatchLength, + CTable_MatchLength.as_ptr(), mlCodeTable, - CTable_OffsetBits, + CTable_OffsetBits.as_ptr(), ofCodeTable, - CTable_LitLength, + CTable_LitLength.as_ptr(), llCodeTable, sequences, nbSeq, @@ -579,11 +579,11 @@ unsafe fn ZSTD_encodeSequences_default( unsafe fn ZSTD_encodeSequences_bmi2( dst: *mut core::ffi::c_void, dstCapacity: size_t, - CTable_MatchLength: *const FSE_CTable, + CTable_MatchLength: &[FSE_CTable], mlCodeTable: *const u8, - CTable_OffsetBits: *const FSE_CTable, + CTable_OffsetBits: &[FSE_CTable], ofCodeTable: *const u8, - CTable_LitLength: *const FSE_CTable, + CTable_LitLength: &[FSE_CTable], llCodeTable: *const u8, sequences: *const SeqDef, nbSeq: size_t, @@ -592,11 +592,11 @@ unsafe fn ZSTD_encodeSequences_bmi2( ZSTD_encodeSequences_body( dst, dstCapacity, - CTable_MatchLength, + CTable_MatchLength.as_ptr(), mlCodeTable, - CTable_OffsetBits, + CTable_OffsetBits.as_ptr(), ofCodeTable, - CTable_LitLength, + CTable_LitLength.as_ptr(), llCodeTable, sequences, nbSeq, @@ -622,11 +622,11 @@ pub unsafe fn ZSTD_encodeSequences( return ZSTD_encodeSequences_bmi2( dst, dstCapacity, - CTable_MatchLength.as_ptr(), + CTable_MatchLength, mlCodeTable, - CTable_OffsetBits.as_ptr(), + CTable_OffsetBits, ofCodeTable, - CTable_LitLength.as_ptr(), + CTable_LitLength, llCodeTable, sequences, nbSeq, @@ -636,11 +636,11 @@ pub unsafe fn ZSTD_encodeSequences( ZSTD_encodeSequences_default( dst, dstCapacity, - CTable_MatchLength.as_ptr(), + CTable_MatchLength, mlCodeTable, - CTable_OffsetBits.as_ptr(), + CTable_OffsetBits, ofCodeTable, - CTable_LitLength.as_ptr(), + CTable_LitLength, llCodeTable, sequences, nbSeq, From 505ee9788f7b6d3f0f9d14b72cfbc3b791e8103d Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:51:55 +0200 Subject: [PATCH 19/33] `fn ZSTD_encodeSequences_body`: pass the CTables as slices --- lib/compress/zstd_compress_sequences.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index d0ab0099..c25e42aa 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -361,11 +361,11 @@ pub unsafe fn ZSTD_buildCTable( unsafe fn ZSTD_encodeSequences_body( dst: *mut core::ffi::c_void, dstCapacity: size_t, - CTable_MatchLength: *const FSE_CTable, + CTable_MatchLength: &[FSE_CTable], mlCodeTable: *const u8, - CTable_OffsetBits: *const FSE_CTable, + CTable_OffsetBits: &[FSE_CTable], ofCodeTable: *const u8, - CTable_LitLength: *const FSE_CTable, + CTable_LitLength: &[FSE_CTable], llCodeTable: *const u8, sequences: *const SeqDef, nbSeq: size_t, @@ -404,17 +404,17 @@ unsafe fn ZSTD_encodeSequences_body( // first symbols FSE_initCState2( &mut stateMatchLength, - CTable_MatchLength, + CTable_MatchLength.as_ptr(), *mlCodeTable.add(nbSeq.wrapping_sub(1)) as u32, ); FSE_initCState2( &mut stateOffsetBits, - CTable_OffsetBits, + CTable_OffsetBits.as_ptr(), *ofCodeTable.add(nbSeq.wrapping_sub(1)) as u32, ); FSE_initCState2( &mut stateLitLength, - CTable_LitLength, + CTable_LitLength.as_ptr(), *llCodeTable.add(nbSeq.wrapping_sub(1)) as u32, ); BIT_addBits( @@ -564,11 +564,11 @@ unsafe fn ZSTD_encodeSequences_default( ZSTD_encodeSequences_body( dst, dstCapacity, - CTable_MatchLength.as_ptr(), + CTable_MatchLength, mlCodeTable, - CTable_OffsetBits.as_ptr(), + CTable_OffsetBits, ofCodeTable, - CTable_LitLength.as_ptr(), + CTable_LitLength, llCodeTable, sequences, nbSeq, @@ -592,11 +592,11 @@ unsafe fn ZSTD_encodeSequences_bmi2( ZSTD_encodeSequences_body( dst, dstCapacity, - CTable_MatchLength.as_ptr(), + CTable_MatchLength, mlCodeTable, - CTable_OffsetBits.as_ptr(), + CTable_OffsetBits, ofCodeTable, - CTable_LitLength.as_ptr(), + CTable_LitLength, llCodeTable, sequences, nbSeq, From 08e54fa09fd37e94a8eeca1d1f32a8f3e12b8de1 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:52:12 +0200 Subject: [PATCH 20/33] `fn FSE_compress_usingCTable`: pass `ct` as a slice --- lib/compress/fse_compress.rs | 4 ++-- lib/compress/huf_compress.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/compress/fse_compress.rs b/lib/compress/fse_compress.rs index 637c2bac..42b08408 100644 --- a/lib/compress/fse_compress.rs +++ b/lib/compress/fse_compress.rs @@ -738,7 +738,7 @@ pub(crate) unsafe fn FSE_compress_usingCTable( dstSize: size_t, src: *const core::ffi::c_void, srcSize: size_t, - ct: *const FSE_CTable, + ct: &[FSE_CTable], ) -> size_t { let fast = dstSize >= srcSize @@ -746,5 +746,5 @@ pub(crate) unsafe fn FSE_compress_usingCTable( .wrapping_add(4) .wrapping_add(size_of::()); - FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, fast) + FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct.as_ptr(), fast) } diff --git a/lib/compress/huf_compress.rs b/lib/compress/huf_compress.rs index f95daef1..35562b1c 100644 --- a/lib/compress/huf_compress.rs +++ b/lib/compress/huf_compress.rs @@ -172,7 +172,7 @@ unsafe fn HUF_compressWeights( oend.offset_from_unsigned(op), weightTable.as_ptr().cast::(), wtSize, - ((*wksp).CTable).as_mut_ptr(), + &(*wksp).CTable, ); if ERR_isError(cSize) { return cSize; From 2c063ad7447c56654289a6ad57076cb0fda7f11f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:52:37 +0200 Subject: [PATCH 21/33] `fn FSE_compress_usingCTable_generic`: pass `ct` as a slice --- lib/compress/fse_compress.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/compress/fse_compress.rs b/lib/compress/fse_compress.rs index 42b08408..4ee5aebd 100644 --- a/lib/compress/fse_compress.rs +++ b/lib/compress/fse_compress.rs @@ -620,7 +620,7 @@ unsafe fn FSE_compress_usingCTable_generic( dstSize: size_t, src: *const core::ffi::c_void, mut srcSize: size_t, - ct: *const FSE_CTable, + ct: &[FSE_CTable], fast: bool, ) -> size_t { let istart = src as *const u8; @@ -658,9 +658,9 @@ unsafe fn FSE_compress_usingCTable_generic( if srcSize & 1 != 0 { ip = ip.sub(1); - FSE_initCState2(&mut CState1, ct, *ip as u32); + FSE_initCState2(&mut CState1, ct.as_ptr(), *ip as u32); ip = ip.sub(1); - FSE_initCState2(&mut CState2, ct, *ip as u32); + FSE_initCState2(&mut CState2, ct.as_ptr(), *ip as u32); ip = ip.sub(1); FSE_encodeSymbol(&mut bitC, &mut CState1, *ip as core::ffi::c_uint); if fast { @@ -670,9 +670,9 @@ unsafe fn FSE_compress_usingCTable_generic( } } else { ip = ip.sub(1); - FSE_initCState2(&mut CState2, ct, *ip as u32); + FSE_initCState2(&mut CState2, ct.as_ptr(), *ip as u32); ip = ip.sub(1); - FSE_initCState2(&mut CState1, ct, *ip as u32); + FSE_initCState2(&mut CState1, ct.as_ptr(), *ip as u32); } // join to mod 4 @@ -746,5 +746,5 @@ pub(crate) unsafe fn FSE_compress_usingCTable( .wrapping_add(4) .wrapping_add(size_of::()); - FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct.as_ptr(), fast) + FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, fast) } From 7213b2e1cf9582538dcc6395bda5cb8cd1c8819b Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:53:03 +0200 Subject: [PATCH 22/33] `fn FSE_initCState2`: pass `ct` as a slice --- lib/common/fse.rs | 8 ++------ lib/compress/fse_compress.rs | 8 ++++---- lib/compress/zstd_compress_sequences.rs | 6 +++--- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/lib/common/fse.rs b/lib/common/fse.rs index 1e2b1343..743782a0 100644 --- a/lib/common/fse.rs +++ b/lib/common/fse.rs @@ -87,12 +87,8 @@ pub(crate) unsafe fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: *const FSE_ } #[inline] -pub(crate) unsafe fn FSE_initCState2( - statePtr: &mut FSE_CState_t, - ct: *const FSE_CTable, - symbol: u32, -) { - FSE_initCState(statePtr, ct); +pub(crate) unsafe fn FSE_initCState2(statePtr: &mut FSE_CState_t, ct: &[FSE_CTable], symbol: u32) { + FSE_initCState(statePtr, ct.as_ptr()); let symbolTT = *(statePtr.symbolTT as *const FSE_symbolCompressionTransform).offset(symbol as isize); let stateTable = statePtr.stateTable as *const u16; diff --git a/lib/compress/fse_compress.rs b/lib/compress/fse_compress.rs index 4ee5aebd..12a44b8f 100644 --- a/lib/compress/fse_compress.rs +++ b/lib/compress/fse_compress.rs @@ -658,9 +658,9 @@ unsafe fn FSE_compress_usingCTable_generic( if srcSize & 1 != 0 { ip = ip.sub(1); - FSE_initCState2(&mut CState1, ct.as_ptr(), *ip as u32); + FSE_initCState2(&mut CState1, ct, *ip as u32); ip = ip.sub(1); - FSE_initCState2(&mut CState2, ct.as_ptr(), *ip as u32); + FSE_initCState2(&mut CState2, ct, *ip as u32); ip = ip.sub(1); FSE_encodeSymbol(&mut bitC, &mut CState1, *ip as core::ffi::c_uint); if fast { @@ -670,9 +670,9 @@ unsafe fn FSE_compress_usingCTable_generic( } } else { ip = ip.sub(1); - FSE_initCState2(&mut CState2, ct.as_ptr(), *ip as u32); + FSE_initCState2(&mut CState2, ct, *ip as u32); ip = ip.sub(1); - FSE_initCState2(&mut CState1, ct.as_ptr(), *ip as u32); + FSE_initCState2(&mut CState1, ct, *ip as u32); } // join to mod 4 diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index c25e42aa..a54e1398 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -404,17 +404,17 @@ unsafe fn ZSTD_encodeSequences_body( // first symbols FSE_initCState2( &mut stateMatchLength, - CTable_MatchLength.as_ptr(), + CTable_MatchLength, *mlCodeTable.add(nbSeq.wrapping_sub(1)) as u32, ); FSE_initCState2( &mut stateOffsetBits, - CTable_OffsetBits.as_ptr(), + CTable_OffsetBits, *ofCodeTable.add(nbSeq.wrapping_sub(1)) as u32, ); FSE_initCState2( &mut stateLitLength, - CTable_LitLength.as_ptr(), + CTable_LitLength, *llCodeTable.add(nbSeq.wrapping_sub(1)) as u32, ); BIT_addBits( From 55c778a70c3774adbf816fdf50b845ebd8cf0214 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:54:04 +0200 Subject: [PATCH 23/33] `fn FSE_initCState`: pass `ct` as a slice --- lib/common/fse.rs | 8 ++++---- lib/compress/zstd_compress_sequences.rs | 2 +- lib/compress/zstd_opt.rs | 12 +++--------- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/lib/common/fse.rs b/lib/common/fse.rs index 743782a0..25179f43 100644 --- a/lib/common/fse.rs +++ b/lib/common/fse.rs @@ -70,13 +70,13 @@ pub(crate) struct FSE_symbolCompressionTransform { } #[inline] -pub(crate) unsafe fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: *const FSE_CTable) { - let ptr = ct as *const core::ffi::c_void; +pub(crate) unsafe fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: &[FSE_CTable]) { + let ptr = ct.as_ptr() as *const core::ffi::c_void; let u16ptr = ptr as *const u16; let tableLog = MEM_read16(ptr) as u32; statePtr.value = (1) << tableLog; statePtr.stateTable = u16ptr.add(2) as *const core::ffi::c_void; - statePtr.symbolTT = ct.add(1).offset( + statePtr.symbolTT = ct.as_ptr().add(1).offset( (if tableLog != 0 { (1) << tableLog.wrapping_sub(1) } else { @@ -88,7 +88,7 @@ pub(crate) unsafe fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: *const FSE_ #[inline] pub(crate) unsafe fn FSE_initCState2(statePtr: &mut FSE_CState_t, ct: &[FSE_CTable], symbol: u32) { - FSE_initCState(statePtr, ct.as_ptr()); + FSE_initCState(statePtr, ct); let symbolTT = *(statePtr.symbolTT as *const FSE_symbolCompressionTransform).offset(symbol as isize); let stateTable = statePtr.stateTable as *const u16; diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index a54e1398..5b5f4259 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -135,7 +135,7 @@ pub unsafe fn ZSTD_fseBitCost( symbolTT: core::ptr::null::(), stateLog: 0, }; - FSE_initCState(&mut cstate, ctable.as_ptr()); + FSE_initCState(&mut cstate, ctable); if ZSTD_getFSEMaxSymbolValue(ctable) < max { return Error::GENERIC.to_error_code(); } diff --git a/lib/compress/zstd_opt.rs b/lib/compress/zstd_opt.rs index e3611671..a482b1cc 100644 --- a/lib/compress/zstd_opt.rs +++ b/lib/compress/zstd_opt.rs @@ -275,10 +275,7 @@ unsafe fn ZSTD_rescaleFreqs( symbolTT: core::ptr::null::(), stateLog: 0, }; - FSE_initCState( - &mut llstate, - ((*(*optPtr).symbolCosts).fse.litlengthCTable).as_ptr(), - ); + FSE_initCState(&mut llstate, &(*(*optPtr).symbolCosts).fse.litlengthCTable); (*optPtr).litLengthSum = 0; for ll in 0..MaxLL + 1 { let scaleLog_0 = 10u32; // scale to 1K @@ -301,7 +298,7 @@ unsafe fn ZSTD_rescaleFreqs( }; FSE_initCState( &mut mlstate, - ((*(*optPtr).symbolCosts).fse.matchlengthCTable).as_ptr(), + &(*(*optPtr).symbolCosts).fse.matchlengthCTable, ); (*optPtr).matchLengthSum = 0; for ml in 0..MaxML + 1 { @@ -323,10 +320,7 @@ unsafe fn ZSTD_rescaleFreqs( symbolTT: core::ptr::null::(), stateLog: 0, }; - FSE_initCState( - &mut ofstate, - ((*(*optPtr).symbolCosts).fse.offcodeCTable).as_ptr(), - ); + FSE_initCState(&mut ofstate, &(*(*optPtr).symbolCosts).fse.offcodeCTable); (*optPtr).offCodeSum = 0; for of in 0..MaxOff + 1 { let scaleLog_2 = 10u32; From 853fa820fb87a39f0031e830194dbb8232a7a76c Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:57:30 +0200 Subject: [PATCH 24/33] `fn FSE_initCState` is now safe --- lib/common/fse.rs | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/common/fse.rs b/lib/common/fse.rs index 25179f43..7a3bf26d 100644 --- a/lib/common/fse.rs +++ b/lib/common/fse.rs @@ -1,7 +1,6 @@ use libc::ptrdiff_t; use crate::lib::common::bitstream::{BIT_CStream_t, BIT_addBits, BIT_flushBits, BitContainerType}; -use crate::lib::common::mem::MEM_read16; pub(crate) type FSE_CTable = core::ffi::c_uint; @@ -70,19 +69,19 @@ pub(crate) struct FSE_symbolCompressionTransform { } #[inline] -pub(crate) unsafe fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: &[FSE_CTable]) { - let ptr = ct.as_ptr() as *const core::ffi::c_void; - let u16ptr = ptr as *const u16; - let tableLog = MEM_read16(ptr) as u32; - statePtr.value = (1) << tableLog; - statePtr.stateTable = u16ptr.add(2) as *const core::ffi::c_void; - statePtr.symbolTT = ct.as_ptr().add(1).offset( - (if tableLog != 0 { - (1) << tableLog.wrapping_sub(1) - } else { - 1 - }) as isize, - ) as *const core::ffi::c_void; +pub(crate) fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: &[FSE_CTable]) { + // the table header occupies the first two bytes of `ct` + let [b0, b1, ..] = ct[0].to_ne_bytes(); + let tableLog = u16::from_ne_bytes([b0, b1]) as u32; + + // the state table follows the header, and the symbol transformation table + // follows the state table (which holds `1 << tableLog` u16 values) + let stateTable = &ct[1..]; + let symbolTT = &ct[1 + if tableLog != 0 { 1 << (tableLog - 1) } else { 1 }..]; + + statePtr.value = 1 << tableLog; + statePtr.stateTable = stateTable.as_ptr().cast::(); + statePtr.symbolTT = symbolTT.as_ptr().cast::(); statePtr.stateLog = tableLog; } From 893aa8aad6a9d0afa7cec85712a6028bb83259c8 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:57:59 +0200 Subject: [PATCH 25/33] `fn ZSTD_buildCTable`: pass `prevCTable` as a slice --- lib/compress/zstd_compress.rs | 6 +++--- lib/compress/zstd_compress_sequences.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/compress/zstd_compress.rs b/lib/compress/zstd_compress.rs index 51678ecb..11218613 100644 --- a/lib/compress/zstd_compress.rs +++ b/lib/compress/zstd_compress.rs @@ -4927,7 +4927,7 @@ unsafe fn ZSTD_buildSequencesStatistics( LL_defaultNorm.as_ptr(), LL_defaultNormLog, MaxLL, - (prevEntropy.litlengthCTable).as_ptr(), + &prevEntropy.litlengthCTable, size_of::<[FSE_CTable; 329]>(), entropyWorkspace, entropyWkspSize, @@ -4984,7 +4984,7 @@ unsafe fn ZSTD_buildSequencesStatistics( OF_defaultNorm.as_ptr(), OF_defaultNormLog, DefaultMaxOff, - (prevEntropy.offcodeCTable).as_ptr(), + &prevEntropy.offcodeCTable, size_of::<[FSE_CTable; 193]>(), entropyWorkspace, entropyWkspSize, @@ -5035,7 +5035,7 @@ unsafe fn ZSTD_buildSequencesStatistics( ML_defaultNorm.as_ptr(), ML_defaultNormLog, MaxML, - (prevEntropy.matchlengthCTable).as_ptr(), + &prevEntropy.matchlengthCTable, size_of::<[FSE_CTable; 363]>(), entropyWorkspace, entropyWkspSize, diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index 5b5f4259..2fd3aa04 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -268,7 +268,7 @@ pub unsafe fn ZSTD_buildCTable( defaultNorm: *const i16, defaultNormLog: u32, defaultMax: u32, - prevCTable: *const FSE_CTable, + prevCTable: &[FSE_CTable], prevCTableSize: size_t, entropyWorkspace: *mut core::ffi::c_void, entropyWorkspaceSize: size_t, @@ -290,7 +290,7 @@ pub unsafe fn ZSTD_buildCTable( } 3 => { core::ptr::copy_nonoverlapping( - prevCTable.cast::(), + prevCTable.as_ptr().cast::(), nextCTable.cast::(), prevCTableSize, ); From fd5fd799bedbfd0723acc781b8a11cf849ab008b Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 10:58:38 +0200 Subject: [PATCH 26/33] `fn ZSTD_buildCTable`: drop the redundant `prevCTableSize` argument --- lib/compress/zstd_compress.rs | 3 --- lib/compress/zstd_compress_sequences.rs | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/compress/zstd_compress.rs b/lib/compress/zstd_compress.rs index 11218613..9f21558d 100644 --- a/lib/compress/zstd_compress.rs +++ b/lib/compress/zstd_compress.rs @@ -4928,7 +4928,6 @@ unsafe fn ZSTD_buildSequencesStatistics( LL_defaultNormLog, MaxLL, &prevEntropy.litlengthCTable, - size_of::<[FSE_CTable; 329]>(), entropyWorkspace, entropyWkspSize, ); @@ -4985,7 +4984,6 @@ unsafe fn ZSTD_buildSequencesStatistics( OF_defaultNormLog, DefaultMaxOff, &prevEntropy.offcodeCTable, - size_of::<[FSE_CTable; 193]>(), entropyWorkspace, entropyWkspSize, ); @@ -5036,7 +5034,6 @@ unsafe fn ZSTD_buildSequencesStatistics( ML_defaultNormLog, MaxML, &prevEntropy.matchlengthCTable, - size_of::<[FSE_CTable; 363]>(), entropyWorkspace, entropyWkspSize, ); diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index 2fd3aa04..0734dd29 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -269,7 +269,6 @@ pub unsafe fn ZSTD_buildCTable( defaultNormLog: u32, defaultMax: u32, prevCTable: &[FSE_CTable], - prevCTableSize: size_t, entropyWorkspace: *mut core::ffi::c_void, entropyWorkspaceSize: size_t, ) -> size_t { @@ -292,7 +291,7 @@ pub unsafe fn ZSTD_buildCTable( core::ptr::copy_nonoverlapping( prevCTable.as_ptr().cast::(), nextCTable.cast::(), - prevCTableSize, + size_of_val(prevCTable), ); 0 } From 9a99521272b769e0293e32dbbd478b566982267a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 11:04:35 +0200 Subject: [PATCH 27/33] lib/common/fse: add a `FSE_readU16` helper --- lib/common/fse.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/common/fse.rs b/lib/common/fse.rs index 7a3bf26d..0572c6f5 100644 --- a/lib/common/fse.rs +++ b/lib/common/fse.rs @@ -68,11 +68,21 @@ pub(crate) struct FSE_symbolCompressionTransform { pub(crate) deltaNbBits: u32, } +/// Read the `index`th `u16` of a `u32`-typed table. +#[inline] +fn FSE_readU16(ct: &[FSE_CTable], index: usize) -> u16 { + let bytes = ct[index / 2].to_ne_bytes(); + if index.is_multiple_of(2) { + u16::from_ne_bytes([bytes[0], bytes[1]]) + } else { + u16::from_ne_bytes([bytes[2], bytes[3]]) + } +} + #[inline] pub(crate) fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: &[FSE_CTable]) { // the table header occupies the first two bytes of `ct` - let [b0, b1, ..] = ct[0].to_ne_bytes(); - let tableLog = u16::from_ne_bytes([b0, b1]) as u32; + let tableLog = FSE_readU16(ct, 0) as u32; // the state table follows the header, and the symbol transformation table // follows the state table (which holds `1 << tableLog` u16 values) From a873f0029e4cd74bbd9793c508347a50e53ac861 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 11:07:16 +0200 Subject: [PATCH 28/33] `fn FSE_initCState2` is now safe --- lib/common/fse.rs | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/lib/common/fse.rs b/lib/common/fse.rs index 0572c6f5..9d5d4136 100644 --- a/lib/common/fse.rs +++ b/lib/common/fse.rs @@ -84,10 +84,9 @@ pub(crate) fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: &[FSE_CTable]) { // the table header occupies the first two bytes of `ct` let tableLog = FSE_readU16(ct, 0) as u32; - // the state table follows the header, and the symbol transformation table - // follows the state table (which holds `1 << tableLog` u16 values) + // the state table follows the header let stateTable = &ct[1..]; - let symbolTT = &ct[1 + if tableLog != 0 { 1 << (tableLog - 1) } else { 1 }..]; + let symbolTT = &ct[FSE_symbolTTIndex(tableLog)..]; statePtr.value = 1 << tableLog; statePtr.stateTable = stateTable.as_ptr().cast::(); @@ -96,16 +95,35 @@ pub(crate) fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: &[FSE_CTable]) { } #[inline] -pub(crate) unsafe fn FSE_initCState2(statePtr: &mut FSE_CState_t, ct: &[FSE_CTable], symbol: u32) { +fn FSE_symbolTTIndex(tableLog: u32) -> usize { + 1 + if tableLog != 0 { 1 << (tableLog - 1) } else { 1 } +} + +/// Read the transform of `symbol` out of the symbol transformation table of `ct`. +#[inline] +fn FSE_readSymbolTT( + ct: &[FSE_CTable], + tableLog: u32, + symbol: u32, +) -> FSE_symbolCompressionTransform { + let index = FSE_symbolTTIndex(tableLog) + 2 * symbol as usize; + + FSE_symbolCompressionTransform { + deltaFindState: ct[index] as core::ffi::c_int, + deltaNbBits: ct[index + 1], + } +} + +#[inline] +pub(crate) fn FSE_initCState2(statePtr: &mut FSE_CState_t, ct: &[FSE_CTable], symbol: u32) { FSE_initCState(statePtr, ct); - let symbolTT = - *(statePtr.symbolTT as *const FSE_symbolCompressionTransform).offset(symbol as isize); - let stateTable = statePtr.stateTable as *const u16; - let nbBitsOut = (symbolTT.deltaNbBits).wrapping_add(((1) << 15) as u32) >> 16; - statePtr.value = (nbBitsOut << 16).wrapping_sub(symbolTT.deltaNbBits) as ptrdiff_t; - statePtr.value = *stateTable - .offset((statePtr.value >> nbBitsOut) + symbolTT.deltaFindState as ptrdiff_t) - as ptrdiff_t; + let symbolTT = FSE_readSymbolTT(ct, statePtr.stateLog, symbol); + let nbBitsOut = (symbolTT.deltaNbBits).wrapping_add((1) << 15) >> 16; + let value = (nbBitsOut << 16).wrapping_sub(symbolTT.deltaNbBits) as ptrdiff_t; + + // the state table starts at the third `u16` of `ct` + let index = 2 + (value >> nbBitsOut) + symbolTT.deltaFindState as ptrdiff_t; + statePtr.value = FSE_readU16(ct, index as usize) as ptrdiff_t; } #[inline] From 06c6137b12582c1d4d276573c66d733a97fafca8 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 11:08:24 +0200 Subject: [PATCH 29/33] `fn ZSTD_buildCTable`: pass `nextCTable` as a mutable slice --- lib/compress/zstd_compress.rs | 9 +++------ lib/compress/zstd_compress_sequences.rs | 10 +++++----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/lib/compress/zstd_compress.rs b/lib/compress/zstd_compress.rs index 9f21558d..b949e697 100644 --- a/lib/compress/zstd_compress.rs +++ b/lib/compress/zstd_compress.rs @@ -4871,9 +4871,6 @@ unsafe fn ZSTD_buildSequencesStatistics( let ostart = dst; let oend = dstEnd; let mut op = ostart; - let CTable_LitLength = (nextEntropy.litlengthCTable).as_mut_ptr(); - let CTable_OffsetBits = (nextEntropy.offcodeCTable).as_mut_ptr(); - let CTable_MatchLength = (nextEntropy.matchlengthCTable).as_mut_ptr(); let ofCodeTable: *const u8 = (*seqStorePtr).ofCode; let llCodeTable: *const u8 = (*seqStorePtr).llCode; let mlCodeTable: *const u8 = (*seqStorePtr).mlCode; @@ -4917,7 +4914,7 @@ unsafe fn ZSTD_buildSequencesStatistics( let countSize = ZSTD_buildCTable( op as *mut core::ffi::c_void, oend.offset_from_unsigned(op), - CTable_LitLength, + &mut nextEntropy.litlengthCTable, LLFSELog, stats.LLtype as SymbolEncodingType_e, countWorkspace, @@ -4973,7 +4970,7 @@ unsafe fn ZSTD_buildSequencesStatistics( let countSize_0 = ZSTD_buildCTable( op as *mut core::ffi::c_void, oend.offset_from_unsigned(op), - CTable_OffsetBits, + &mut nextEntropy.offcodeCTable, OffFSELog, stats.Offtype as SymbolEncodingType_e, countWorkspace, @@ -5023,7 +5020,7 @@ unsafe fn ZSTD_buildSequencesStatistics( let countSize_1 = ZSTD_buildCTable( op as *mut core::ffi::c_void, oend.offset_from_unsigned(op), - CTable_MatchLength, + &mut nextEntropy.matchlengthCTable, MLFSELog, stats.MLtype as SymbolEncodingType_e, countWorkspace, diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index 0734dd29..8f26a8b1 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -258,7 +258,7 @@ pub unsafe fn ZSTD_selectEncodingType( pub unsafe fn ZSTD_buildCTable( dst: *mut core::ffi::c_void, dstCapacity: size_t, - nextCTable: *mut FSE_CTable, + nextCTable: &mut [FSE_CTable], FSELog: u32, type_0: SymbolEncodingType_e, count: *mut core::ffi::c_uint, @@ -277,7 +277,7 @@ pub unsafe fn ZSTD_buildCTable( match type_0 as core::ffi::c_uint { 1 => { - let err_code = FSE_buildCTable_rle(nextCTable, max as u8); + let err_code = FSE_buildCTable_rle(nextCTable.as_mut_ptr(), max as u8); if ERR_isError(err_code) { return err_code; } @@ -290,14 +290,14 @@ pub unsafe fn ZSTD_buildCTable( 3 => { core::ptr::copy_nonoverlapping( prevCTable.as_ptr().cast::(), - nextCTable.cast::(), + nextCTable.as_mut_ptr().cast::(), size_of_val(prevCTable), ); 0 } 0 => { let err_code_0 = FSE_buildCTable_wksp( - nextCTable, + nextCTable.as_mut_ptr(), defaultNorm, defaultMax, defaultNormLog, @@ -341,7 +341,7 @@ pub unsafe fn ZSTD_buildCTable( return err_code_2; } let err_code_3 = FSE_buildCTable_wksp( - nextCTable, + nextCTable.as_mut_ptr(), ((*wksp).norm).as_mut_ptr(), max, tableLog, From d719066b25370b4eb9113f8c67184696d21158fc Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 11:08:39 +0200 Subject: [PATCH 30/33] `fn FSE_buildCTable_rle`: pass `ct` as a mutable slice --- lib/compress/fse_compress.rs | 4 ++-- lib/compress/zstd_compress_sequences.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/compress/fse_compress.rs b/lib/compress/fse_compress.rs index 12a44b8f..9a0b4aec 100644 --- a/lib/compress/fse_compress.rs +++ b/lib/compress/fse_compress.rs @@ -594,8 +594,8 @@ pub(crate) unsafe fn FSE_normalizeCount( } /// Fake FSE_CTable, for rle input (always same symbol). -pub(crate) unsafe fn FSE_buildCTable_rle(ct: *mut FSE_CTable, symbolValue: u8) -> size_t { - let ptr = ct as *mut core::ffi::c_void; +pub(crate) unsafe fn FSE_buildCTable_rle(ct: &mut [FSE_CTable], symbolValue: u8) -> size_t { + let ptr = ct.as_mut_ptr() as *mut core::ffi::c_void; let tableU16 = (ptr as *mut u16).add(2); let FSCTptr = (ptr as *mut u32).add(2) as *mut core::ffi::c_void; let symbolTT = FSCTptr as *mut FSE_symbolCompressionTransform; diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index 8f26a8b1..072b6107 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -277,7 +277,7 @@ pub unsafe fn ZSTD_buildCTable( match type_0 as core::ffi::c_uint { 1 => { - let err_code = FSE_buildCTable_rle(nextCTable.as_mut_ptr(), max as u8); + let err_code = FSE_buildCTable_rle(nextCTable, max as u8); if ERR_isError(err_code) { return err_code; } From fc5d00b197826ed42a9e6b05cbd2a7b96917c9f9 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 11:10:35 +0200 Subject: [PATCH 31/33] `fn FSE_buildCTable_rle` is now safe --- lib/common/fse.rs | 20 +++++++++++++++++--- lib/compress/fse_compress.rs | 26 ++++++++++---------------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/lib/common/fse.rs b/lib/common/fse.rs index 9d5d4136..a57059d5 100644 --- a/lib/common/fse.rs +++ b/lib/common/fse.rs @@ -68,7 +68,16 @@ pub(crate) struct FSE_symbolCompressionTransform { pub(crate) deltaNbBits: u32, } -/// Read the `index`th `u16` of a `u32`-typed table. +/// Pack two consecutive `u16` values into one `u32`. +#[inline] +pub(crate) fn FSE_writeU16Pair(first: u16, second: u16) -> FSE_CTable { + let [a, b] = first.to_ne_bytes(); + let [c, d] = second.to_ne_bytes(); + + u32::from_ne_bytes([a, b, c, d]) +} + +/// Read the `index`th `u16` of a `&[u32]`. #[inline] fn FSE_readU16(ct: &[FSE_CTable], index: usize) -> u16 { let bytes = ct[index / 2].to_ne_bytes(); @@ -95,8 +104,13 @@ pub(crate) fn FSE_initCState(statePtr: &mut FSE_CState_t, ct: &[FSE_CTable]) { } #[inline] -fn FSE_symbolTTIndex(tableLog: u32) -> usize { - 1 + if tableLog != 0 { 1 << (tableLog - 1) } else { 1 } +pub(crate) const fn FSE_symbolTTIndex(tableLog: u32) -> usize { + let skip_header = 1; + + match tableLog { + 0 => skip_header + 1, + _ => skip_header + (1 << (tableLog - 1)), + } } /// Read the transform of `symbol` out of the symbol transformation table of `ct`. diff --git a/lib/compress/fse_compress.rs b/lib/compress/fse_compress.rs index 9a0b4aec..24d7a14d 100644 --- a/lib/compress/fse_compress.rs +++ b/lib/compress/fse_compress.rs @@ -8,8 +8,8 @@ use crate::lib::common::bitstream::{ use crate::lib::common::error_private::{ERR_isError, Error}; use crate::lib::common::fse::{ FSE_CState_t, FSE_CTable, FSE_encodeSymbol, FSE_flushCState, FSE_initCState2, - FSE_symbolCompressionTransform, FSE_DEFAULT_TABLELOG, FSE_MAX_TABLELOG, FSE_MIN_TABLELOG, - FSE_NCOUNTBOUND, + FSE_symbolCompressionTransform, FSE_symbolTTIndex, FSE_writeU16Pair, FSE_DEFAULT_TABLELOG, + FSE_MAX_TABLELOG, FSE_MIN_TABLELOG, FSE_NCOUNTBOUND, }; use crate::lib::common::mem::MEM_write64; @@ -594,23 +594,17 @@ pub(crate) unsafe fn FSE_normalizeCount( } /// Fake FSE_CTable, for rle input (always same symbol). -pub(crate) unsafe fn FSE_buildCTable_rle(ct: &mut [FSE_CTable], symbolValue: u8) -> size_t { - let ptr = ct.as_mut_ptr() as *mut core::ffi::c_void; - let tableU16 = (ptr as *mut u16).add(2); - let FSCTptr = (ptr as *mut u32).add(2) as *mut core::ffi::c_void; - let symbolTT = FSCTptr as *mut FSE_symbolCompressionTransform; - - // header - *tableU16.sub(2) = 0; - *tableU16.sub(1) = symbolValue as u16; +pub(crate) fn FSE_buildCTable_rle(ct: &mut [FSE_CTable], symbolValue: u8) -> size_t { + // header: a tableLog of zero, and `symbolValue` as the maximum symbol value + ct[0] = FSE_writeU16Pair(0, symbolValue as u16); - // Build table - *tableU16 = 0; - *tableU16.add(1) = 0; // just in case + // the (two-entry) state table, zeroed just in case + ct[1] = FSE_writeU16Pair(0, 0); // Build Symbol Transformation Table - (*symbolTT.offset(symbolValue as isize)).deltaNbBits = 0; - (*symbolTT.offset(symbolValue as isize)).deltaFindState = 0; + let index = FSE_symbolTTIndex(0) + 2 * symbolValue as usize; + ct[index] = 0; // deltaFindState + ct[index + 1] = 0; // deltaNbBits 0 } From f347a1d415e2ed7ae476df3678ed2ba549aa34ba Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 12:09:55 +0200 Subject: [PATCH 32/33] `fn ZSTD_getFSEMaxSymbolValue`: make safe --- lib/compress/zstd_compress_sequences.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index 072b6107..b15b49d1 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -52,10 +52,9 @@ static kInverseProbabilityLog256: [core::ffi::c_uint; 256] = [ 37, 36, 34, 33, 31, 30, 28, 26, 25, 23, 22, 20, 19, 17, 16, 14, 13, 11, 10, 8, 7, 5, 4, 2, 1, ]; -unsafe fn ZSTD_getFSEMaxSymbolValue(ctable: &[FSE_CTable]) -> core::ffi::c_uint { - let u16ptr = ctable.as_ptr() as *const u16; - - MEM_read16(u16ptr.add(1) as *const core::ffi::c_void) as u32 +fn ZSTD_getFSEMaxSymbolValue(ctable: &[FSE_CTable]) -> core::ffi::c_uint { + let [_, _, a, b] = ctable[0].to_ne_bytes(); + u32::from(u16::from_ne_bytes([a, b])) } /// Returns true if we should use ncount=-1 else we should From dfd32d7e2d6d55ef3c03291bd893e11aa91237ba Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 10 Aug 2026 12:55:58 +0200 Subject: [PATCH 33/33] clippy --- lib/compress/zstd_compress_sequences.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_compress_sequences.rs b/lib/compress/zstd_compress_sequences.rs index b15b49d1..eb52ab39 100644 --- a/lib/compress/zstd_compress_sequences.rs +++ b/lib/compress/zstd_compress_sequences.rs @@ -8,7 +8,7 @@ use crate::lib::common::fse::{ FSE_CState_t, FSE_CTable, FSE_bitCost, FSE_encodeSymbol, FSE_flushCState, FSE_initCState, FSE_initCState2, FSE_repeat, FSE_repeat_check, FSE_repeat_none, FSE_repeat_valid, }; -use crate::lib::common::mem::{MEM_32bits, MEM_read16}; +use crate::lib::common::mem::MEM_32bits; use crate::lib::common::zstd_internal::{LLFSELog, LL_bits, MLFSELog, ML_bits, OffFSELog}; use crate::lib::compress::fse_compress::{ FSE_buildCTable_rle, FSE_buildCTable_wksp, FSE_normalizeCount, FSE_optimalTableLog,