5 releases
Uses old Rust 2015
0.1.4 | Sep 21, 2017 |
---|---|
0.1.3 | Jul 13, 2016 |
0.1.2 | Jun 20, 2016 |
0.1.1 | Jun 13, 2016 |
0.1.0 | Jun 11, 2016 |
#681 in Compression
Used in 2 crates
(via mayda_codec)
32KB
697 lines
Compiler plugins to generate basic encoding and decoding functions. The
functions generated by the encode!
and decode!
syntax extensions follow
the convention encode_T_a_b
. The functions generated by the
encode_simd!
and decode_simd!
syntax extensions follow the convention
encode_simd_T_a
. The functions generated by the encode_util!
syntax
extention follow the conventions encode_delta_T
and encode_zz_shift_T
.
T
is one of the unsigned integer types, a
is the number of bits per
integer, and b
is the number of integers encoded.
encode!
and decode!
take as arguments the unsigned integer type width
in bits and a step for the number of integers (a divisor of 32). Functions
are generated for numbers of bits in the interval 0...max_bits
, and for
numbers of integers in multiples of the step up to 32. encode_simd!
and
decode_simd!
take as arguments the unsigned integer type width in bits
and a path to the relevant simd module. Functions are generated for numbers
of bits in the interval 0...max_bits
, and for exactly 128 integers.
encode_util!
takes as arguments the unsigned integer type width in bits
and a path to the relevant simd module. Functions are generated for the
type width and for an arbitrary number of integers.
Pointers to the functions generated by encode!
and decode!
are
available in ENCODE_T
and DECODE_T
, respectively, with the pointer for
encode_T_a_b
at ENCODE_T[a][b / c - 1]
where c
is the step.
Pointers to the functions generated by encode_simd!
and decode_simd!
are availabe in ENCODE_SIMD_T
and DECODE_SIMD_T
, respectively, with the
pointer for encode_simd_T_a
at ENCODE_SIMD_T[a]
. The functions
generated by encode_util!
are public. All arrays are public and constant.
Safety
The functions generated by this crate use wildly unsafe pointer operations.
You must verify that enough memory is already allocated after the pointers
that the offsets are valid. They are not intended to be used outside the
mayda
crate.
Examples
The syntax extensions defined in this crate can be invoked as
encode!(u32, 32, 8);
decode!(u32, 32, 8);
This is replaced by 128 functions that encode u32 integers and 128 functions that decode u32 integers. For example, the functions that encode and decode the 24 least significant bits of 8 u32 integers are
unsafe fn encode_u32_24_8(mut i_ptr: *const u32, mut s_ptr: *mut u32) {
let mut out = *i_ptr as u32;
i_ptr = i_ptr.offset(1);
out |= (*i_ptr as u32) << 24usize;
*s_ptr = out;
s_ptr = s_ptr.offset(1);
out = (*i_ptr >> 8usize) as u32;
i_ptr = i_ptr.offset(1);
out |= (*i_ptr as u32) << 16usize;
*s_ptr = out;
s_ptr = s_ptr.offset(1);
out = (*i_ptr >> 16usize) as u32;
i_ptr = i_ptr.offset(1);
out |= (*i_ptr as u32) << 8usize;
i_ptr = i_ptr.offset(1);
*s_ptr = out;
s_ptr = s_ptr.offset(1);
out = *i_ptr as u32;
i_ptr = i_ptr.offset(1);
out |= (*i_ptr as u32) << 24usize;
*s_ptr = out;
s_ptr = s_ptr.offset(1);
out = (*i_ptr >> 8usize) as u32;
i_ptr = i_ptr.offset(1);
out |= (*i_ptr as u32) << 16usize;
*s_ptr = out;
s_ptr = s_ptr.offset(1);
out = (*i_ptr >> 16usize) as u32;
i_ptr = i_ptr.offset(1);
out |= (*i_ptr as u32) << 8usize;
*s_ptr = out;
}
unsafe fn decode_u32_24_8(mut s_ptr: *const u32, mut o_ptr: *mut u32) {
let mask: u32 = !0 >> 8usize;
let mut out;
out = *s_ptr as u32;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
out = (*s_ptr >> 24usize) as u32;
s_ptr = s_ptr.offset(1);
out |= (*s_ptr as u32) << 8usize;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
out = (*s_ptr >> 16usize) as u32;
s_ptr = s_ptr.offset(1);
out |= (*s_ptr as u32) << 16usize;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
out = (*s_ptr >> 8usize) as u32;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
s_ptr = s_ptr.offset(1);
out = *s_ptr as u32;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
out = (*s_ptr >> 24usize) as u32;
s_ptr = s_ptr.offset(1);
out |= (*s_ptr as u32) << 8usize;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
out = (*s_ptr >> 16usize) as u32;
s_ptr = s_ptr.offset(1);
out |= (*s_ptr as u32) << 16usize;
*o_ptr = out & mask;
o_ptr = o_ptr.offset(1);
out = (*s_ptr >> 8usize) as u32;
*o_ptr = out & mask;
}