Skip to content

Commit

Permalink
Avoid uninitialized data in coeff_contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
kornelski committed Oct 21, 2023
1 parent 77752bd commit 53fdcc1
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 15 deletions.
19 changes: 13 additions & 6 deletions src/context/block_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use std::mem::MaybeUninit;

use super::*;

use crate::predict::PredictionMode;
Expand Down Expand Up @@ -1918,10 +1920,11 @@ impl<'a> ContextWriter<'a> {
w: &mut W,
) {
// SAFETY: We write to the array below before reading from it.
let mut coeff_contexts: Aligned<[i8; MAX_CODED_TX_SQUARE]> =
let mut coeff_contexts: Aligned<[MaybeUninit<i8>; MAX_CODED_TX_SQUARE]> =
unsafe { Aligned::uninitialized() };

self.get_nz_map_contexts(
// get_nz_map_contexts sets coeff_contexts contiguously as a parallel array for scan, not in scan order
let coeff_contexts = self.get_nz_map_contexts(
levels,
scan,
eob,
Expand All @@ -1932,24 +1935,28 @@ impl<'a> ContextWriter<'a> {

let bhl = Self::get_txb_bhl(tx_size);

for (c, (&pos, &v)) in scan.iter().zip(coeffs.iter()).enumerate().rev() {
let scan_with_ctx =
scan.iter().copied().zip(coeff_contexts.iter().copied());
for (c, ((pos, coeff_ctx), v)) in
scan_with_ctx.zip(coeffs.iter().copied()).enumerate().rev()
{
let pos = pos as usize;
let coeff_ctx = coeff_contexts.data[pos];
let coeff_ctx = coeff_ctx as usize;
let level = v.abs();

if c == usize::from(eob) - 1 {
symbol_with_update!(
self,
w,
cmp::min(u32::cast_from(level), 3) - 1,
&self.fc.coeff_base_eob_cdf[txs_ctx][plane_type][coeff_ctx as usize]
&self.fc.coeff_base_eob_cdf[txs_ctx][plane_type][coeff_ctx]
);
} else {
symbol_with_update!(
self,
w,
cmp::min(u32::cast_from(level), 3),
&self.fc.coeff_base_cdf[txs_ctx][plane_type][coeff_ctx as usize]
&self.fc.coeff_base_cdf[txs_ctx][plane_type][coeff_ctx]
);
}

Expand Down
27 changes: 18 additions & 9 deletions src/context/transform_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use super::*;
use crate::predict::PredictionMode;
use crate::predict::PredictionMode::*;
use crate::transform::TxType::*;
use std::mem::MaybeUninit;

pub const MAX_TX_SIZE: usize = 64;

Expand Down Expand Up @@ -905,25 +906,33 @@ impl<'a> ContextWriter<'a> {
Self::get_nz_map_ctx_from_stats(stats, coeff_idx, bhl, tx_size, tx_class)
}

pub fn get_nz_map_contexts(
/// `coeff_contexts_no_scan` is not in the scan order.
/// Value for `pos = scan[i]` is at `coeff[i]`, not at `coeff[pos]`.
pub fn get_nz_map_contexts<'c>(
&self, levels: &mut [u8], scan: &[u16], eob: u16, tx_size: TxSize,
tx_class: TxClass, coeff_contexts: &mut [i8],
) {
tx_class: TxClass, coeff_contexts_no_scan: &'c mut [MaybeUninit<i8>],
) -> &'c mut [i8] {
let bhl = Self::get_txb_bhl(tx_size);
let area = av1_get_coded_tx_size(tx_size).area();
for i in 0..eob {
let pos = scan[i as usize];
coeff_contexts[pos as usize] = Self::get_nz_map_ctx(

let scan = &scan[..usize::from(eob)];
let coeffs = &mut coeff_contexts_no_scan[..usize::from(eob)];
for (i, (coeff, pos)) in
coeffs.iter_mut().zip(scan.iter().copied()).enumerate()
{
coeff.write(Self::get_nz_map_ctx(
levels,
pos as usize,
bhl,
area,
i as usize,
i == eob - 1,
i,
i == usize::from(eob) - 1,
tx_size,
tx_class,
) as i8;
) as i8);
}
// SAFETY: every element has been initialized
unsafe { slice_assume_init_mut(coeffs) }
}

pub fn get_br_ctx(
Expand Down

0 comments on commit 53fdcc1

Please sign in to comment.