Skip to content

Commit ecead22

Browse files
author
Andreas Molzer
authored
Merge pull request #121 from Shnatsel/fewer-bounds-checks
Eliminate bounds checks in `read_coefficients()` (for zero performance gain?)
2 parents 5d8654d + d205a0c commit ecead22

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

src/vp8.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,16 +1647,21 @@ impl<R: Read> Vp8Decoder<R> {
16471647

16481648
fn read_coefficients(
16491649
&mut self,
1650-
block: &mut [i32],
1650+
block: &mut [i32; 16],
16511651
p: usize,
16521652
plane: usize,
16531653
complexity: usize,
16541654
dcq: i16,
16551655
acq: i16,
16561656
) -> Result<bool, DecodingError> {
1657+
// perform bounds checks once up front,
1658+
// so that the compiler doesn't have to insert them in the hot loop below
1659+
assert!(complexity <= 2);
1660+
16571661
let first = if plane == 0 { 1usize } else { 0usize };
16581662
let probs = &self.token_probs[plane];
16591663
let tree = &DCT_TOKEN_TREE;
1664+
let reader = &mut self.partitions[p];
16601665

16611666
let mut complexity = complexity;
16621667
let mut has_coefficients = false;
@@ -1666,9 +1671,9 @@ impl<R: Read> Vp8Decoder<R> {
16661671
let table = &probs[COEFF_BANDS[i] as usize][complexity];
16671672

16681673
let token = if !skip {
1669-
self.partitions[p].read_with_tree(tree, table, 0)?
1674+
reader.read_with_tree(tree, table, 0)?
16701675
} else {
1671-
self.partitions[p].read_with_tree(tree, table, 2)?
1676+
reader.read_with_tree(tree, table, 2)?
16721677
};
16731678

16741679
let mut abs_value = i32::from(match token {
@@ -1684,14 +1689,15 @@ impl<R: Read> Vp8Decoder<R> {
16841689
literal @ DCT_1..=DCT_4 => i16::from(literal),
16851690

16861691
category @ DCT_CAT1..=DCT_CAT6 => {
1687-
let t = PROB_DCT_CAT[(category - DCT_CAT1) as usize];
1692+
let probs = PROB_DCT_CAT[(category - DCT_CAT1) as usize];
16881693

16891694
let mut extra = 0i16;
1690-
let mut j = 0;
16911695

1692-
while t[j] > 0 {
1693-
extra = extra + extra + self.partitions[p].read_bool(t[j])? as i16;
1694-
j += 1;
1696+
for t in probs.iter().copied() {
1697+
if t == 0 {
1698+
break;
1699+
}
1700+
extra = extra + extra + reader.read_bool(t)? as i16;
16951701
}
16961702

16971703
i16::from(DCT_CAT_BASE[(category - DCT_CAT1) as usize]) + extra
@@ -1710,7 +1716,7 @@ impl<R: Read> Vp8Decoder<R> {
17101716
2
17111717
};
17121718

1713-
if self.partitions[p].read_bool(128)? {
1719+
if reader.read_bool(128)? {
17141720
abs_value = -abs_value;
17151721
}
17161722

@@ -1756,7 +1762,8 @@ impl<R: Read> Vp8Decoder<R> {
17561762
let mut left = self.left.complexity[y + 1];
17571763
for x in 0usize..4 {
17581764
let i = x + y * 4;
1759-
let block = &mut blocks[i * 16..i * 16 + 16];
1765+
let block = &mut blocks[i * 16..][..16];
1766+
let block: &mut [i32; 16] = block.try_into().unwrap();
17601767

17611768
let complexity = self.top[mbx].complexity[x + 1] + left;
17621769
let dcq = self.segment[sindex].ydc;
@@ -1783,7 +1790,8 @@ impl<R: Read> Vp8Decoder<R> {
17831790

17841791
for x in 0usize..2 {
17851792
let i = x + y * 2 + if j == 5 { 16 } else { 20 };
1786-
let block = &mut blocks[i * 16..i * 16 + 16];
1793+
let block = &mut blocks[i * 16..][..16];
1794+
let block: &mut [i32; 16] = block.try_into().unwrap();
17871795

17881796
let complexity = self.top[mbx].complexity[x + j] + left;
17891797
let dcq = self.segment[sindex].uvdc;

0 commit comments

Comments
 (0)