1 | // Copyright (c) 2017-2022, 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 | use super::*; |
11 | |
12 | pub const MAX_SB_SIZE_LOG2: usize = 7; |
13 | const SB_SIZE_LOG2: usize = 6; |
14 | pub const SB_SIZE: usize = 1 << SB_SIZE_LOG2; |
15 | const SB_SQUARE: usize = SB_SIZE * SB_SIZE; |
16 | |
17 | pub const MI_SIZE_LOG2: usize = 2; |
18 | pub const MI_SIZE: usize = 1 << MI_SIZE_LOG2; |
19 | pub const MAX_MIB_SIZE_LOG2: usize = MAX_SB_SIZE_LOG2 - MI_SIZE_LOG2; |
20 | pub const MIB_SIZE_LOG2: usize = SB_SIZE_LOG2 - MI_SIZE_LOG2; |
21 | pub const MIB_SIZE: usize = 1 << MIB_SIZE_LOG2; |
22 | pub const MIB_MASK: usize = MIB_SIZE - 1; |
23 | |
24 | pub const SUPERBLOCK_TO_PLANE_SHIFT: usize = SB_SIZE_LOG2; |
25 | pub const SUPERBLOCK_TO_BLOCK_SHIFT: usize = MIB_SIZE_LOG2; |
26 | pub const BLOCK_TO_PLANE_SHIFT: usize = MI_SIZE_LOG2; |
27 | pub const IMPORTANCE_BLOCK_TO_BLOCK_SHIFT: usize = 1; |
28 | pub const LOCAL_BLOCK_MASK: usize = (1 << SUPERBLOCK_TO_BLOCK_SHIFT) - 1; |
29 | |
30 | pub const MAX_SB_IN_IMP_B: usize = 1 |
31 | << (MAX_SB_SIZE_LOG2 |
32 | - IMPORTANCE_BLOCK_TO_BLOCK_SHIFT |
33 | - BLOCK_TO_PLANE_SHIFT); |
34 | |
35 | /// Absolute offset in superblocks, where a superblock is defined |
36 | /// to be an `N*N` square where `N == (1 << SUPERBLOCK_TO_PLANE_SHIFT)`. |
37 | #[derive (Clone, Copy, Debug, PartialEq, Eq)] |
38 | pub struct SuperBlockOffset { |
39 | pub x: usize, |
40 | pub y: usize, |
41 | } |
42 | |
43 | /// Absolute offset in superblocks inside a plane, where a superblock is defined |
44 | /// to be an `N*N` square where `N == (1 << SUPERBLOCK_TO_PLANE_SHIFT)`. |
45 | #[derive (Clone, Copy, Debug, PartialEq, Eq)] |
46 | pub struct PlaneSuperBlockOffset(pub SuperBlockOffset); |
47 | |
48 | /// Absolute offset in superblocks inside a tile, where a superblock is defined |
49 | /// to be an `N*N` square where `N == (1 << SUPERBLOCK_TO_PLANE_SHIFT)`. |
50 | #[derive (Clone, Copy, Debug, PartialEq, Eq)] |
51 | pub struct TileSuperBlockOffset(pub SuperBlockOffset); |
52 | |
53 | impl SuperBlockOffset { |
54 | /// Offset of a block inside the current superblock. |
55 | #[inline ] |
56 | const fn block_offset(self, block_x: usize, block_y: usize) -> BlockOffset { |
57 | BlockOffset { |
58 | x: (self.x << SUPERBLOCK_TO_BLOCK_SHIFT) + block_x, |
59 | y: (self.y << SUPERBLOCK_TO_BLOCK_SHIFT) + block_y, |
60 | } |
61 | } |
62 | |
63 | /// Offset of the top-left pixel of this block. |
64 | #[inline ] |
65 | const fn plane_offset(self, plane: &PlaneConfig) -> PlaneOffset { |
66 | PlaneOffset { |
67 | x: (self.x as isize) << (SUPERBLOCK_TO_PLANE_SHIFT - plane.xdec), |
68 | y: (self.y as isize) << (SUPERBLOCK_TO_PLANE_SHIFT - plane.ydec), |
69 | } |
70 | } |
71 | } |
72 | |
73 | impl Add for SuperBlockOffset { |
74 | type Output = Self; |
75 | #[inline ] |
76 | fn add(self, rhs: Self) -> Self::Output { |
77 | Self { x: self.x + rhs.x, y: self.y + rhs.y } |
78 | } |
79 | } |
80 | |
81 | impl PlaneSuperBlockOffset { |
82 | /// Offset of a block inside the current superblock. |
83 | #[inline ] |
84 | pub const fn block_offset( |
85 | self, block_x: usize, block_y: usize, |
86 | ) -> PlaneBlockOffset { |
87 | PlaneBlockOffset(self.0.block_offset(block_x, block_y)) |
88 | } |
89 | |
90 | /// Offset of the top-left pixel of this block. |
91 | #[inline ] |
92 | pub const fn plane_offset(self, plane: &PlaneConfig) -> PlaneOffset { |
93 | self.0.plane_offset(plane) |
94 | } |
95 | } |
96 | |
97 | impl Add for PlaneSuperBlockOffset { |
98 | type Output = Self; |
99 | #[inline ] |
100 | fn add(self, rhs: Self) -> Self::Output { |
101 | PlaneSuperBlockOffset(self.0 + rhs.0) |
102 | } |
103 | } |
104 | |
105 | impl TileSuperBlockOffset { |
106 | /// Offset of a block inside the current superblock. |
107 | #[inline ] |
108 | pub const fn block_offset( |
109 | self, block_x: usize, block_y: usize, |
110 | ) -> TileBlockOffset { |
111 | TileBlockOffset(self.0.block_offset(block_x, block_y)) |
112 | } |
113 | |
114 | /// Offset of the top-left pixel of this block. |
115 | #[inline ] |
116 | pub const fn plane_offset(self, plane: &PlaneConfig) -> PlaneOffset { |
117 | self.0.plane_offset(plane) |
118 | } |
119 | } |
120 | |
121 | impl Add for TileSuperBlockOffset { |
122 | type Output = Self; |
123 | #[inline ] |
124 | fn add(self, rhs: Self) -> Self::Output { |
125 | TileSuperBlockOffset(self.0 + rhs.0) |
126 | } |
127 | } |
128 | |