| 1 | // Copyright (c) 2017-2020, 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 | #![allow (non_upper_case_globals)] |
| 11 | #![allow (non_camel_case_types)] |
| 12 | #![allow (dead_code)] |
| 13 | |
| 14 | use crate::context::*; |
| 15 | use crate::partition::BlockSize::*; |
| 16 | use crate::partition::*; |
| 17 | use crate::transform::*; |
| 18 | |
| 19 | static has_null: &[u8] = &[]; |
| 20 | |
| 21 | // Tables to store if the top-right reference pixels are available. The flags |
| 22 | // are represented with bits, packed into 8-bit integers. E.g., for the 32x32 |
| 23 | // blocks in a 128x128 superblock, the index of the "o" block is 10 (in raster |
| 24 | // order), so its flag is stored at the 3rd bit of the 2nd entry in the table, |
| 25 | // i.e. (table[10 / 8] >> (10 % 8)) & 1. |
| 26 | // . . . . |
| 27 | // . . . . |
| 28 | // . . o . |
| 29 | // . . . . |
| 30 | #[rustfmt::skip] |
| 31 | static has_tr_4x4: &[u8] = &[ |
| 32 | 255, 255, 255, 255, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
| 33 | 127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
| 34 | 255, 127, 255, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
| 35 | 127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
| 36 | 255, 255, 255, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
| 37 | 127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
| 38 | 255, 127, 255, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
| 39 | 127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85, |
| 40 | ]; |
| 41 | |
| 42 | static has_tr_4x8: &[u8] = &[ |
| 43 | 255, 255, 255, 255, 119, 119, 119, 119, 127, 127, 127, 127, 119, 119, 119, |
| 44 | 119, 255, 127, 255, 127, 119, 119, 119, 119, 127, 127, 127, 127, 119, 119, |
| 45 | 119, 119, 255, 255, 255, 127, 119, 119, 119, 119, 127, 127, 127, 127, 119, |
| 46 | 119, 119, 119, 255, 127, 255, 127, 119, 119, 119, 119, 127, 127, 127, 127, |
| 47 | 119, 119, 119, 119, |
| 48 | ]; |
| 49 | |
| 50 | #[rustfmt::skip] |
| 51 | static has_tr_8x4: &[u8] = &[ |
| 52 | 255, 255, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0, |
| 53 | 127, 127, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0, |
| 54 | 255, 127, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0, |
| 55 | 127, 127, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0, |
| 56 | ]; |
| 57 | |
| 58 | #[rustfmt::skip] |
| 59 | static has_tr_8x8: &[u8] = &[ |
| 60 | 255, 255, 85, 85, 119, 119, 85, 85, 127, 127, 85, 85, 119, 119, 85, 85, |
| 61 | 255, 127, 85, 85, 119, 119, 85, 85, 127, 127, 85, 85, 119, 119, 85, 85, |
| 62 | ]; |
| 63 | static has_tr_8x16: &[u8] = &[ |
| 64 | 255, 255, 119, 119, 127, 127, 119, 119, 255, 127, 119, 119, 127, 127, 119, |
| 65 | 119, |
| 66 | ]; |
| 67 | static has_tr_16x8: &[u8] = |
| 68 | &[255, 0, 85, 0, 119, 0, 85, 0, 127, 0, 85, 0, 119, 0, 85, 0]; |
| 69 | static has_tr_16x16: &[u8] = &[255, 85, 119, 85, 127, 85, 119, 85]; |
| 70 | static has_tr_16x32: &[u8] = &[255, 119, 127, 119]; |
| 71 | static has_tr_32x16: &[u8] = &[15, 5, 7, 5]; |
| 72 | static has_tr_32x32: &[u8] = &[95, 87]; |
| 73 | static has_tr_32x64: &[u8] = &[127]; |
| 74 | static has_tr_64x32: &[u8] = &[19]; |
| 75 | static has_tr_64x64: &[u8] = &[7]; |
| 76 | static has_tr_64x128: &[u8] = &[3]; |
| 77 | static has_tr_128x64: &[u8] = &[1]; |
| 78 | static has_tr_128x128: &[u8] = &[1]; |
| 79 | static has_tr_4x16: &[u8] = &[ |
| 80 | 255, 255, 255, 255, 127, 127, 127, 127, 255, 127, 255, 127, 127, 127, 127, |
| 81 | 127, 255, 255, 255, 127, 127, 127, 127, 127, 255, 127, 255, 127, 127, 127, |
| 82 | 127, 127, |
| 83 | ]; |
| 84 | static has_tr_16x4: &[u8] = &[ |
| 85 | 255, 0, 0, 0, 85, 0, 0, 0, 119, 0, 0, 0, 85, 0, 0, 0, 127, 0, 0, 0, 85, 0, |
| 86 | 0, 0, 119, 0, 0, 0, 85, 0, 0, 0, |
| 87 | ]; |
| 88 | static has_tr_8x32: &[u8] = &[255, 255, 127, 127, 255, 127, 127, 127]; |
| 89 | static has_tr_32x8: &[u8] = &[15, 0, 5, 0, 7, 0, 5, 0]; |
| 90 | static has_tr_16x64: &[u8] = &[255, 127]; |
| 91 | static has_tr_64x16: &[u8] = &[3, 1]; |
| 92 | |
| 93 | static has_tr_tables: &[&[u8]] = &[ |
| 94 | has_tr_4x4, // 4x4 |
| 95 | has_tr_4x8, // 4x8 |
| 96 | has_tr_8x4, // 8x4 |
| 97 | has_tr_8x8, // 8x8 |
| 98 | has_tr_8x16, // 8x16 |
| 99 | has_tr_16x8, // 16x8 |
| 100 | has_tr_16x16, // 16x16 |
| 101 | has_tr_16x32, // 16x32 |
| 102 | has_tr_32x16, // 32x16 |
| 103 | has_tr_32x32, // 32x32 |
| 104 | has_tr_32x64, // 32x64 |
| 105 | has_tr_64x32, // 64x32 |
| 106 | has_tr_64x64, // 64x64 |
| 107 | has_tr_64x128, // 64x128 |
| 108 | has_tr_128x64, // 128x64 |
| 109 | has_tr_128x128, // 128x128 |
| 110 | has_tr_4x16, // 4x16 |
| 111 | has_tr_16x4, // 16x4 |
| 112 | has_tr_8x32, // 8x32 |
| 113 | has_tr_32x8, // 32x8 |
| 114 | has_tr_16x64, // 16x64 |
| 115 | has_tr_64x16, // 64x16 |
| 116 | ]; |
| 117 | |
| 118 | #[rustfmt::skip] |
| 119 | static has_tr_vert_8x8: &[u8] = &[ |
| 120 | 255, 255, 0, 0, 119, 119, 0, 0, 127, 127, 0, 0, 119, 119, 0, 0, |
| 121 | 255, 127, 0, 0, 119, 119, 0, 0, 127, 127, 0, 0, 119, 119, 0, 0, |
| 122 | ]; |
| 123 | static has_tr_vert_16x16: &[u8] = &[255, 0, 119, 0, 127, 0, 119, 0]; |
| 124 | static has_tr_vert_32x32: &[u8] = &[15, 7]; |
| 125 | static has_tr_vert_64x64: &[u8] = &[3]; |
| 126 | |
| 127 | // The _vert_* tables are like the ordinary tables above, but describe the |
| 128 | // order we visit square blocks when doing a PARTITION_VERT_A or |
| 129 | // PARTITION_VERT_B. This is the same order as normal except for on the last |
| 130 | // split where we go vertically (TL, BL, TR, BR). We treat the rectangular block |
| 131 | // as a pair of squares, which means that these tables work correctly for both |
| 132 | // mixed vertical partition types. |
| 133 | // |
| 134 | // There are tables for each of the square sizes. Vertical rectangles (like |
| 135 | // BLOCK_16X32) use their respective "non-vert" table |
| 136 | static has_tr_vert_tables: &[&[u8]] = &[ |
| 137 | has_null, // 4X4 |
| 138 | has_tr_4x8, // 4X8 |
| 139 | has_null, // 8X4 |
| 140 | has_tr_vert_8x8, // 8X8 |
| 141 | has_tr_8x16, // 8X16 |
| 142 | has_null, // 16X8 |
| 143 | has_tr_vert_16x16, // 16X16 |
| 144 | has_tr_16x32, // 16X32 |
| 145 | has_null, // 32X16 |
| 146 | has_tr_vert_32x32, // 32X32 |
| 147 | has_tr_32x64, // 32X64 |
| 148 | has_null, // 64X32 |
| 149 | has_tr_vert_64x64, // 64X64 |
| 150 | has_tr_64x128, // 64x128 |
| 151 | has_null, // 128x64 |
| 152 | has_tr_128x128, // 128x128 |
| 153 | ]; |
| 154 | |
| 155 | // TODO: Enable the case for PARTITION_VERT_A/B once they can be encoded by rav1e. |
| 156 | pub fn get_has_tr_table( |
| 157 | /*partition: PartitionType, */ bsize: BlockSize, |
| 158 | ) -> &'static [u8] { |
| 159 | let ret: &[u8]; |
| 160 | // If this is a mixed vertical partition, look up bsize in orders_vert. |
| 161 | /*if partition == PartitionType::PARTITION_VERT_A || partition == PartitionType::PARTITION_VERT_B { |
| 162 | debug_assert!(bsize < BlockSize::BLOCK_SIZES); |
| 163 | ret = has_tr_vert_tables[bsize as usize]; |
| 164 | } else */ |
| 165 | { |
| 166 | ret = has_tr_tables[bsize as usize]; |
| 167 | } |
| 168 | |
| 169 | //debug_assert!(ret != ptr::has_null()); |
| 170 | |
| 171 | ret |
| 172 | } |
| 173 | |
| 174 | pub fn has_top_right( |
| 175 | bsize: BlockSize, partition_bo: TileBlockOffset, top_available: bool, |
| 176 | right_available: bool, tx_size: TxSize, row_off: usize, col_off: usize, |
| 177 | ss_x: usize, _ss_y: usize, |
| 178 | ) -> bool { |
| 179 | if !top_available || !right_available { |
| 180 | return false; |
| 181 | }; |
| 182 | |
| 183 | let bw_unit = bsize.width_mi(); |
| 184 | let plane_bw_unit = (bw_unit >> ss_x).max(1); |
| 185 | let top_right_count_unit = tx_size.width_mi(); |
| 186 | |
| 187 | let mi_col = partition_bo.0.x; |
| 188 | let mi_row = partition_bo.0.y; |
| 189 | |
| 190 | if row_off > 0 { |
| 191 | // Just need to check if enough pixels on the right. |
| 192 | // 128x128 SB is not supported yet by rav1e |
| 193 | if bsize.width() > BLOCK_64X64.width() { |
| 194 | // Special case: For 128x128 blocks, the transform unit whose |
| 195 | // top-right corner is at the center of the block does in fact have |
| 196 | // pixels available at its top-right corner. |
| 197 | if row_off == BLOCK_64X64.height_mi() >> _ss_y |
| 198 | && col_off + top_right_count_unit == BLOCK_64X64.width_mi() >> ss_x |
| 199 | { |
| 200 | return false; |
| 201 | } |
| 202 | let plane_bw_unit_64 = BLOCK_64X64.width_mi() >> ss_x; |
| 203 | let col_off_64 = col_off % plane_bw_unit_64; |
| 204 | return col_off_64 + top_right_count_unit < plane_bw_unit_64; |
| 205 | } |
| 206 | col_off + top_right_count_unit < plane_bw_unit |
| 207 | } else { |
| 208 | // All top-right pixels are in the block above, which is already available. |
| 209 | if col_off + top_right_count_unit < plane_bw_unit { |
| 210 | return true; |
| 211 | }; |
| 212 | |
| 213 | let bw_in_mi_log2 = bsize.width_log2() - MI_SIZE_LOG2; |
| 214 | let bh_in_mi_log2 = bsize.height_log2() - MI_SIZE_LOG2; |
| 215 | let sb_mi_size: usize = 16; // 64x64 |
| 216 | let blk_row_in_sb = (mi_row & (sb_mi_size - 1)) >> bh_in_mi_log2; |
| 217 | let blk_col_in_sb = (mi_col & (sb_mi_size - 1)) >> bw_in_mi_log2; |
| 218 | |
| 219 | // Top row of superblock: so top-right pixels are in the top and/or |
| 220 | // top-right superblocks, both of which are already available. |
| 221 | if blk_row_in_sb == 0 { |
| 222 | return true; |
| 223 | }; |
| 224 | |
| 225 | // Rightmost column of superblock (and not the top row): so top-right pixels |
| 226 | // fall in the right superblock, which is not available yet. |
| 227 | if ((blk_col_in_sb + 1) << bw_in_mi_log2) >= sb_mi_size { |
| 228 | return false; |
| 229 | }; |
| 230 | |
| 231 | // General case (neither top row nor rightmost column): check if the |
| 232 | // top-right block is coded before the current block. |
| 233 | let this_blk_index = |
| 234 | (blk_row_in_sb << (MAX_MIB_SIZE_LOG2 - bw_in_mi_log2)) + blk_col_in_sb; |
| 235 | let idx1 = this_blk_index / 8; |
| 236 | let idx2 = this_blk_index % 8; |
| 237 | let has_tr_table: &[u8] = get_has_tr_table(/*partition,*/ bsize); |
| 238 | |
| 239 | ((has_tr_table[idx1] >> idx2) & 1) != 0 |
| 240 | } |
| 241 | } |
| 242 | |
| 243 | // Similar to the has_tr_* tables, but store if the bottom-left reference |
| 244 | // pixels are available. |
| 245 | static has_bl_4x4: &[u8] = &[ |
| 246 | 84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0, 1, 1, 1, 84, 85, 85, 85, |
| 247 | 16, 17, 17, 17, 84, 85, 85, 85, 0, 0, 1, 0, 84, 85, 85, 85, 16, 17, 17, 17, |
| 248 | 84, 85, 85, 85, 0, 1, 1, 1, 84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, |
| 249 | 0, 0, 0, 0, 84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0, 1, 1, 1, 84, |
| 250 | 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0, 0, 1, 0, 84, 85, 85, 85, 16, |
| 251 | 17, 17, 17, 84, 85, 85, 85, 0, 1, 1, 1, 84, 85, 85, 85, 16, 17, 17, 17, 84, |
| 252 | 85, 85, 85, 0, 0, 0, 0, |
| 253 | ]; |
| 254 | static has_bl_4x8: &[u8] = &[ |
| 255 | 16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, 17, 0, 0, 1, 0, 16, 17, 17, 17, 0, |
| 256 | 1, 1, 1, 16, 17, 17, 17, 0, 0, 0, 0, 16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, |
| 257 | 17, 0, 0, 1, 0, 16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, 17, 0, 0, 0, 0, |
| 258 | ]; |
| 259 | static has_bl_8x4: &[u8] = &[ |
| 260 | 254, 255, 84, 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 1, 254, |
| 261 | 255, 84, 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 0, 254, 255, |
| 262 | 84, 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 1, 254, 255, 84, |
| 263 | 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 0, |
| 264 | ]; |
| 265 | static has_bl_8x8: &[u8] = &[ |
| 266 | 84, 85, 16, 17, 84, 85, 0, 1, 84, 85, 16, 17, 84, 85, 0, 0, 84, 85, 16, 17, |
| 267 | 84, 85, 0, 1, 84, 85, 16, 17, 84, 85, 0, 0, |
| 268 | ]; |
| 269 | static has_bl_8x16: &[u8] = |
| 270 | &[16, 17, 0, 1, 16, 17, 0, 0, 16, 17, 0, 1, 16, 17, 0, 0]; |
| 271 | static has_bl_16x8: &[u8] = |
| 272 | &[254, 84, 254, 16, 254, 84, 254, 0, 254, 84, 254, 16, 254, 84, 254, 0]; |
| 273 | static has_bl_16x16: &[u8] = &[84, 16, 84, 0, 84, 16, 84, 0]; |
| 274 | static has_bl_16x32: &[u8] = &[16, 0, 16, 0]; |
| 275 | static has_bl_32x16: &[u8] = &[78, 14, 78, 14]; |
| 276 | static has_bl_32x32: &[u8] = &[4, 4]; |
| 277 | static has_bl_32x64: &[u8] = &[0]; |
| 278 | static has_bl_64x32: &[u8] = &[34]; |
| 279 | static has_bl_64x64: &[u8] = &[0]; |
| 280 | static has_bl_64x128: &[u8] = &[0]; |
| 281 | static has_bl_128x64: &[u8] = &[0]; |
| 282 | static has_bl_128x128: &[u8] = &[0]; |
| 283 | static has_bl_4x16: &[u8] = &[ |
| 284 | 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, |
| 285 | 1, 1, 1, 0, 0, 0, 0, |
| 286 | ]; |
| 287 | static has_bl_16x4: &[u8] = &[ |
| 288 | 254, 254, 254, 84, 254, 254, 254, 16, 254, 254, 254, 84, 254, 254, 254, 0, |
| 289 | 254, 254, 254, 84, 254, 254, 254, 16, 254, 254, 254, 84, 254, 254, 254, 0, |
| 290 | ]; |
| 291 | static has_bl_8x32: &[u8] = &[0, 1, 0, 0, 0, 1, 0, 0]; |
| 292 | static has_bl_32x8: &[u8] = &[238, 78, 238, 14, 238, 78, 238, 14]; |
| 293 | static has_bl_16x64: &[u8] = &[0, 0]; |
| 294 | static has_bl_64x16: &[u8] = &[42, 42]; |
| 295 | |
| 296 | static has_bl_tables: &[&[u8]] = &[ |
| 297 | has_bl_4x4, // 4x4 |
| 298 | has_bl_4x8, // 4x8 |
| 299 | has_bl_8x4, // 8x4 |
| 300 | has_bl_8x8, // 8x8 |
| 301 | has_bl_8x16, // 8x16 |
| 302 | has_bl_16x8, // 16x8 |
| 303 | has_bl_16x16, // 16x16 |
| 304 | has_bl_16x32, // 16x32 |
| 305 | has_bl_32x16, // 32x16 |
| 306 | has_bl_32x32, // 32x32 |
| 307 | has_bl_32x64, // 32x64 |
| 308 | has_bl_64x32, // 64x32 |
| 309 | has_bl_64x64, // 64x64 |
| 310 | has_bl_64x128, // 64x128 |
| 311 | has_bl_128x64, // 128x64 |
| 312 | has_bl_128x128, // 128x128 |
| 313 | has_bl_4x16, // 4x16 |
| 314 | has_bl_16x4, // 16x4 |
| 315 | has_bl_8x32, // 8x32 |
| 316 | has_bl_32x8, // 32x8 |
| 317 | has_bl_16x64, // 16x64 |
| 318 | has_bl_64x16, // 64x16 |
| 319 | ]; |
| 320 | |
| 321 | #[rustfmt::skip] |
| 322 | static has_bl_vert_8x8: &[u8] = &[ |
| 323 | 254, 255, 16, 17, 254, 255, 0, 1, 254, 255, 16, 17, 254, 255, 0, 0, |
| 324 | 254, 255, 16, 17, 254, 255, 0, 1, 254, 255, 16, 17, 254, 255, 0, 0, |
| 325 | ]; |
| 326 | static has_bl_vert_16x16: &[u8] = &[254, 16, 254, 0, 254, 16, 254, 0]; |
| 327 | static has_bl_vert_32x32: &[u8] = &[14, 14]; |
| 328 | static has_bl_vert_64x64: &[u8] = &[2]; |
| 329 | |
| 330 | // The _vert_* tables are like the ordinary tables above, but describe the |
| 331 | // order we visit square blocks when doing a PARTITION_VERT_A or |
| 332 | // PARTITION_VERT_B. This is the same order as normal except for on the last |
| 333 | // split where we go vertically (TL, BL, TR, BR). We treat the rectangular block |
| 334 | // as a pair of squares, which means that these tables work correctly for both |
| 335 | // mixed vertical partition types. |
| 336 | // |
| 337 | // There are tables for each of the square sizes. Vertical rectangles (like |
| 338 | // BLOCK_16X32) use their respective "non-vert" table |
| 339 | static has_bl_vert_tables: &[&[u8]] = &[ |
| 340 | has_null, // 4x4 |
| 341 | has_bl_4x8, // 4x8 |
| 342 | has_null, // 8x4 |
| 343 | has_bl_vert_8x8, // 8x8 |
| 344 | has_bl_8x16, // 8x16 |
| 345 | has_null, // 16x8 |
| 346 | has_bl_vert_16x16, // 16x16 |
| 347 | has_bl_16x32, // 16x32 |
| 348 | has_null, // 32x16 |
| 349 | has_bl_vert_32x32, // 32x32 |
| 350 | has_bl_32x64, // 32x64 |
| 351 | has_null, // 64x32 |
| 352 | has_bl_vert_64x64, // 64x64 |
| 353 | has_bl_64x128, // 64x128 |
| 354 | has_null, // 128x64 |
| 355 | has_bl_128x128, // 128x128 |
| 356 | ]; |
| 357 | |
| 358 | pub fn get_has_bl_table( |
| 359 | /*partition: PartitionType, */ bsize: BlockSize, |
| 360 | ) -> &'static [u8] { |
| 361 | let ret: &[u8]; |
| 362 | // If this is a mixed vertical partition, look up bsize in orders_vert. |
| 363 | /*if (partition == PARTITION_VERT_A || partition == PARTITION_VERT_B) { |
| 364 | //assert(bsize < BLOCK_SIZES); |
| 365 | ret = has_bl_vert_tables[bsize as usize]; |
| 366 | } else*/ |
| 367 | { |
| 368 | ret = has_bl_tables[bsize as usize]; |
| 369 | } |
| 370 | //debug_assert!(ret != ptr::has_null()); |
| 371 | ret |
| 372 | } |
| 373 | |
| 374 | pub fn has_bottom_left( |
| 375 | bsize: BlockSize, partition_bo: TileBlockOffset, bottom_available: bool, |
| 376 | left_available: bool, tx_size: TxSize, row_off: usize, col_off: usize, |
| 377 | _ss_x: usize, ss_y: usize, |
| 378 | ) -> bool { |
| 379 | if !bottom_available || !left_available { |
| 380 | return false; |
| 381 | }; |
| 382 | |
| 383 | // Special case for 128x* blocks, when col_off is half the block width. |
| 384 | // This is needed because 128x* superblocks are divided into 64x* blocks in |
| 385 | // raster order |
| 386 | // 128x128 SB is not supported yet by rav1e |
| 387 | if bsize.width() > BLOCK_64X64.width() && col_off > 0 { |
| 388 | let plane_bw_unit_64 = BLOCK_64X64.width_mi() >> _ss_x; |
| 389 | let col_off_64 = col_off % plane_bw_unit_64; |
| 390 | if col_off_64 == 0 { |
| 391 | // We are at the left edge of top-right or bottom-right 64x* block. |
| 392 | let plane_bh_unit_64 = BLOCK_64X64.height_mi() >> ss_y; |
| 393 | let row_off_64 = row_off % plane_bh_unit_64; |
| 394 | let plane_bh_unit = (bsize.height_mi() >> ss_y).min(plane_bh_unit_64); |
| 395 | // Check if all bottom-left pixels are in the left 64x* block (which is |
| 396 | // already coded). |
| 397 | return row_off_64 + tx_size.height_mi() < plane_bh_unit; |
| 398 | } |
| 399 | } |
| 400 | |
| 401 | if col_off > 0 { |
| 402 | // Bottom-left pixels are in the bottom-left block, which is not available. |
| 403 | false |
| 404 | } else { |
| 405 | let bh_unit = bsize.height_mi(); |
| 406 | let plane_bh_unit = (bh_unit >> ss_y).max(1); |
| 407 | let bottom_left_count_unit = tx_size.height_mi(); |
| 408 | |
| 409 | let mi_col = partition_bo.0.x; |
| 410 | let mi_row = partition_bo.0.y; |
| 411 | |
| 412 | // All bottom-left pixels are in the left block, which is already available. |
| 413 | if row_off + bottom_left_count_unit < plane_bh_unit { |
| 414 | return true; |
| 415 | }; |
| 416 | |
| 417 | let bw_in_mi_log2 = bsize.width_log2() - MI_SIZE_LOG2; |
| 418 | let bh_in_mi_log2 = bsize.height_log2() - MI_SIZE_LOG2; |
| 419 | let sb_mi_size: usize = 16; // 64x64 |
| 420 | let blk_row_in_sb = (mi_row & (sb_mi_size - 1)) >> bh_in_mi_log2; |
| 421 | let blk_col_in_sb = (mi_col & (sb_mi_size - 1)) >> bw_in_mi_log2; |
| 422 | |
| 423 | // Leftmost column of superblock: so bottom-left pixels maybe in the left |
| 424 | // and/or bottom-left superblocks. But only the left superblock is |
| 425 | // available, so check if all required pixels fall in that superblock. |
| 426 | if blk_col_in_sb == 0 { |
| 427 | let blk_start_row_off = blk_row_in_sb << bh_in_mi_log2 >> ss_y; |
| 428 | let row_off_in_sb = blk_start_row_off + row_off; |
| 429 | let sb_height_unit = sb_mi_size >> ss_y; |
| 430 | return row_off_in_sb + bottom_left_count_unit < sb_height_unit; |
| 431 | //return row_off_in_sb + (bottom_left_count_unit << 1) < sb_height_unit; // Don't it need tx height? again? |
| 432 | } |
| 433 | |
| 434 | // Bottom row of superblock (and not the leftmost column): so bottom-left |
| 435 | // pixels fall in the bottom superblock, which is not available yet. |
| 436 | if ((blk_row_in_sb + 1) << bh_in_mi_log2) >= sb_mi_size { |
| 437 | return false; |
| 438 | }; |
| 439 | |
| 440 | // General case (neither leftmost column nor bottom row): check if the |
| 441 | // bottom-left block is coded before the current block. |
| 442 | let this_blk_index = |
| 443 | (blk_row_in_sb << (MAX_MIB_SIZE_LOG2 - bw_in_mi_log2)) + blk_col_in_sb; |
| 444 | let idx1 = this_blk_index / 8; |
| 445 | let idx2 = this_blk_index % 8; |
| 446 | let has_bl_table: &[u8] = get_has_bl_table(/*partition,*/ bsize); |
| 447 | |
| 448 | ((has_bl_table[idx1] >> idx2) & 1) != 0 |
| 449 | } |
| 450 | } |
| 451 | |