MCPcopy Index your code
hub / github.com/SoftbearStudios/bitcode / pack_arithmetic

Function pack_arithmetic

src/pack.rs:391–433  ·  view source on GitHub ↗

Packs multiple bytes into one. All the bytes must be < `FACTOR`. Factors 2,4,16 are bit packing. Factors 3,6 are arithmetic coding.

(bytes: &[u8], out: &mut Vec<u8>)

Source from the content-addressed store, hash-verified

389/// Packs multiple bytes into one. All the bytes must be < `FACTOR`.
390/// Factors 2,4,16 are bit packing. Factors 3,6 are arithmetic coding.
391fn pack_arithmetic<const FACTOR: usize>(bytes: &[u8], out: &mut Vec<u8>) {
392 debug_assert!(bytes.iter().all(|&v| v < FACTOR as u8));
393 let divisor = factor_to_divisor::<FACTOR>();
394
395 let floor = bytes.len() / divisor;
396 let ceil = (bytes.len() + (divisor - 1)) / divisor;
397
398 out.reserve(ceil);
399 let packed = &mut out.spare_capacity_mut()[..ceil];
400
401 for i in 0..floor {
402 unsafe {
403 packed.get_unchecked_mut(i).write(if FACTOR == 2 && BMI2 {
404 #[cfg(not(all(target_arch = "x86_64", target_feature = "bmi2")))]
405 unreachable!();
406 #[cfg(all(target_arch = "x86_64", target_feature = "bmi2"))]
407 {
408 // Could use on any pow2 FACTOR, but only 2 is faster (target-cpu=native).
409 let chunk = (bytes.as_ptr() as *const u8 as *const [u8; 8]).add(i);
410 let chunk = u64::from_le_bytes(*chunk);
411 std::arch::x86_64::_pext_u64(chunk, 0x0101010101010101) as u8
412 }
413 } else {
414 let mut acc = 0;
415 for byte_index in 0..divisor {
416 let byte = *bytes.get_unchecked(i * divisor + byte_index);
417 acc += byte * (FACTOR as u8).pow(byte_index as u32);
418 }
419 acc
420 });
421 }
422 }
423 if floor < ceil {
424 let mut acc = 0;
425 for &v in bytes[floor * divisor..].iter().rev() {
426 acc *= FACTOR as u8;
427 acc += v;
428 }
429 packed[floor].write(acc);
430 }
431 // Safety: `ceil` elements after len were initialized by loops above.
432 unsafe { out.set_len(out.len() + ceil) };
433}
434
435/// Opposite of `pack_arithmetic`. `out` will be overwritten with the unpacked bytes.
436fn unpack_arithmetic<const FACTOR: usize>(

Callers

nothing calls this directly

Calls 4

as_ptrMethod · 0.80
lenMethod · 0.45
reserveMethod · 0.45
writeMethod · 0.45

Tested by

no test coverage detected