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.
get_has_tr_table( bsize: BlockSize, ) -> &'static [u8]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 
has_top_right( bsize: BlockSize, partition_bo: TileBlockOffset, top_available: bool, right_available: bool, tx_size: TxSize, row_off: usize, col_off: usize, ss_x: usize, _ss_y: usize, ) -> bool174 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 
get_has_bl_table( bsize: BlockSize, ) -> &'static [u8]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 
has_bottom_left( bsize: BlockSize, partition_bo: TileBlockOffset, bottom_available: bool, left_available: bool, tx_size: TxSize, row_off: usize, col_off: usize, _ss_x: usize, ss_y: usize, ) -> bool374 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