| 1 | // Copyright (c) 2017-2021, The rav1e contributors. All rights reserved |
| 2 | // |
| 3 | // This source code is subject to the terms of the BSD 2 Clause License and |
| 4 | // the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 5 | // was not distributed with this source code in the LICENSE file, you can |
| 6 | // obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 7 | // Media Patent License 1.0 was not distributed with this source code in the |
| 8 | // PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
| 9 | |
| 10 | pub const fn cdf<const VARS: usize, const CDF_LEN: usize>( |
| 11 | vars: [u16; VARS], |
| 12 | ) -> [u16; CDF_LEN] { |
| 13 | // Ensure that at least one zero is kept at the end |
| 14 | assert!(CDF_LEN > VARS); |
| 15 | |
| 16 | let mut out: [u16; CDF_LEN] = [0; CDF_LEN]; |
| 17 | let mut i: usize = 0; |
| 18 | while i < vars.len() { |
| 19 | assert!(vars[i] <= 32768); |
| 20 | out[i] = 32768 - vars[i]; |
| 21 | i += 1; |
| 22 | } |
| 23 | |
| 24 | out |
| 25 | } |
| 26 | |
| 27 | pub const fn cdf_2d< |
| 28 | const VARS: usize, |
| 29 | const CDF_LEN: usize, |
| 30 | const N_2D: usize, |
| 31 | >( |
| 32 | vars: [[u16; VARS]; N_2D], |
| 33 | ) -> [[u16; CDF_LEN]; N_2D] { |
| 34 | let mut out: [[u16; CDF_LEN]; N_2D] = [[0u16; CDF_LEN]; N_2D]; |
| 35 | let mut c: usize = 0; |
| 36 | while c < vars.len() { |
| 37 | out[c] = cdf(vars[c]); |
| 38 | c += 1; |
| 39 | } |
| 40 | |
| 41 | out |
| 42 | } |
| 43 | |
| 44 | pub const fn cdf_3d< |
| 45 | const VARS: usize, |
| 46 | const CDF_LEN: usize, |
| 47 | const N_2D: usize, |
| 48 | const N_3D: usize, |
| 49 | >( |
| 50 | vars: [[[u16; VARS]; N_2D]; N_3D], |
| 51 | ) -> [[[u16; CDF_LEN]; N_2D]; N_3D] { |
| 52 | let mut out: [[[u16; CDF_LEN]; N_2D]; N_3D] = [[[0u16; CDF_LEN]; N_2D]; N_3D]; |
| 53 | let mut c: usize = 0; |
| 54 | while c < vars.len() { |
| 55 | out[c] = cdf_2d(vars[c]); |
| 56 | c += 1; |
| 57 | } |
| 58 | |
| 59 | out |
| 60 | } |
| 61 | |
| 62 | pub const fn cdf_4d< |
| 63 | const VARS: usize, |
| 64 | const CDF_LEN: usize, |
| 65 | const N_2D: usize, |
| 66 | const N_3D: usize, |
| 67 | const N_4D: usize, |
| 68 | >( |
| 69 | vars: [[[[u16; VARS]; N_2D]; N_3D]; N_4D], |
| 70 | ) -> [[[[u16; CDF_LEN]; N_2D]; N_3D]; N_4D] { |
| 71 | let mut out: [[[[u16; CDF_LEN]; N_2D]; N_3D]; N_4D] = [[[[0u16; CDF_LEN]; N_2D]; N_3D]; N_4D]; |
| 72 | let mut c: usize = 0; |
| 73 | while c < vars.len() { |
| 74 | out[c] = cdf_3d(vars[c]); |
| 75 | c += 1; |
| 76 | } |
| 77 | |
| 78 | out |
| 79 | } |
| 80 | |
| 81 | pub const fn cdf_5d< |
| 82 | const VARS: usize, |
| 83 | const CDF_LEN: usize, |
| 84 | const N_2D: usize, |
| 85 | const N_3D: usize, |
| 86 | const N_4D: usize, |
| 87 | const N_5D: usize, |
| 88 | >( |
| 89 | vars: [[[[[u16; VARS]; N_2D]; N_3D]; N_4D]; N_5D], |
| 90 | ) -> [[[[[u16; CDF_LEN]; N_2D]; N_3D]; N_4D]; N_5D] { |
| 91 | let mut out: [[[[[u16; CDF_LEN]; N_2D]; N_3D]; N_4D]; N_5D] = [[[[[0u16; CDF_LEN]; N_2D]; N_3D]; N_4D]; N_5D]; |
| 92 | let mut c: usize = 0; |
| 93 | while c < vars.len() { |
| 94 | out[c] = cdf_4d(vars[c]); |
| 95 | c += 1; |
| 96 | } |
| 97 | |
| 98 | out |
| 99 | } |
| 100 | |
| 101 | #[cfg (test)] |
| 102 | mod test { |
| 103 | use super::*; |
| 104 | |
| 105 | #[test ] |
| 106 | fn cdf_len_ok() { |
| 107 | let _: [u16; 5] = cdf([]); |
| 108 | let _: [u16; 5] = cdf([1]); |
| 109 | let _: [u16; 5] = cdf([1, 2, 3, 4]); |
| 110 | } |
| 111 | |
| 112 | #[test ] |
| 113 | #[should_panic ] |
| 114 | fn cdf_len_panics() { |
| 115 | let _: [u16; 5] = cdf([1, 2, 3, 4, 5]); |
| 116 | } |
| 117 | |
| 118 | #[test ] |
| 119 | #[should_panic ] |
| 120 | fn cdf_val_panics() { |
| 121 | let _: [u16; 5] = cdf([40000]); |
| 122 | } |
| 123 | |
| 124 | #[test ] |
| 125 | fn cdf_vals_ok() { |
| 126 | let cdf: [u16; 5] = cdf([2000, 10000, 32768, 0]); |
| 127 | assert_eq!(cdf, [30768, 22768, 0, 32768, 0]); |
| 128 | } |
| 129 | |
| 130 | #[test ] |
| 131 | fn cdf_5d_ok() { |
| 132 | let cdf: [[[[[u16; 4]; 2]; 1]; 1]; 1] = |
| 133 | cdf_5d([[[[[1000, 2000], [3000, 4000]]]]]); |
| 134 | assert_eq!(cdf, [[[[[31768, 30768, 0, 0], [29768, 28768, 0, 0],]]]]) |
| 135 | } |
| 136 | } |
| 137 | |