Coverage Report

Created: 2025-12-05 07:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rav1e-0.8.1/src/tiling/tile.rs
Line
Count
Source
1
// Copyright (c) 2019-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
use crate::context::*;
13
use crate::frame::*;
14
use crate::util::*;
15
16
/// Rectangle of a tile, in pixels
17
///
18
/// This is similar to Rect, but with unsigned (x, y) for convenience.
19
#[derive(Debug, Clone, Copy)]
20
pub struct TileRect {
21
  pub x: usize,
22
  pub y: usize,
23
  pub width: usize,
24
  pub height: usize,
25
}
26
27
impl TileRect {
28
  #[inline(always)]
29
0
  pub const fn decimated(&self, xdec: usize, ydec: usize) -> Self {
30
0
    Self {
31
0
      x: self.x >> xdec,
32
0
      y: self.y >> ydec,
33
0
      width: self.width >> xdec,
34
0
      height: self.height >> ydec,
35
0
    }
36
0
  }
37
38
  #[inline(always)]
39
0
  pub const fn to_frame_plane_offset(
40
0
    &self, tile_po: PlaneOffset,
41
0
  ) -> PlaneOffset {
42
0
    PlaneOffset {
43
0
      x: self.x as isize + tile_po.x,
44
0
      y: self.y as isize + tile_po.y,
45
0
    }
46
0
  }
47
48
  #[inline(always)]
49
0
  pub fn to_frame_block_offset(
50
0
    &self, tile_bo: TileBlockOffset, xdec: usize, ydec: usize,
51
0
  ) -> PlaneBlockOffset {
52
0
    debug_assert!(self.x % (MI_SIZE >> xdec) == 0);
53
0
    debug_assert!(self.y % (MI_SIZE >> ydec) == 0);
54
0
    let bx = self.x >> (MI_SIZE_LOG2 - xdec);
55
0
    let by = self.y >> (MI_SIZE_LOG2 - ydec);
56
0
    PlaneBlockOffset(BlockOffset { x: bx + tile_bo.0.x, y: by + tile_bo.0.y })
57
0
  }
58
59
  #[inline(always)]
60
0
  pub fn to_frame_super_block_offset(
61
0
    &self, tile_sbo: TileSuperBlockOffset, sb_size_log2: usize, xdec: usize,
62
0
    ydec: usize,
63
0
  ) -> PlaneSuperBlockOffset {
64
0
    debug_assert!(sb_size_log2 == 6 || sb_size_log2 == 7);
65
0
    debug_assert!(self.x % (1 << (sb_size_log2 - xdec)) == 0);
66
0
    debug_assert!(self.y % (1 << (sb_size_log2 - ydec)) == 0);
67
0
    let sbx = self.x >> (sb_size_log2 - xdec);
68
0
    let sby = self.y >> (sb_size_log2 - ydec);
69
0
    PlaneSuperBlockOffset(SuperBlockOffset {
70
0
      x: sbx + tile_sbo.0.x,
71
0
      y: sby + tile_sbo.0.y,
72
0
    })
73
0
  }
74
}
75
76
impl From<TileRect> for Rect {
77
  #[inline(always)]
78
0
  fn from(tile_rect: TileRect) -> Rect {
79
0
    Rect {
80
0
      x: tile_rect.x as isize,
81
0
      y: tile_rect.y as isize,
82
0
      width: tile_rect.width,
83
0
      height: tile_rect.height,
84
0
    }
85
0
  }
86
}
87
88
/// Tiled view of a frame
89
#[derive(Debug)]
90
pub struct Tile<'a, T: Pixel> {
91
  pub planes: [PlaneRegion<'a, T>; MAX_PLANES],
92
}
93
94
/// Mutable tiled view of a frame
95
#[derive(Debug)]
96
pub struct TileMut<'a, T: Pixel> {
97
  pub planes: [PlaneRegionMut<'a, T>; MAX_PLANES],
98
}
99
100
// common impl for Tile and TileMut
101
macro_rules! tile_common {
102
  // $name: Tile or TileMut
103
  // $pr_type: PlaneRegion or PlaneRegionMut
104
  // $iter: iter or iter_mut
105
  //opt_mut: nothing or mut
106
  ($name:ident, $pr_type:ident, $iter:ident $(,$opt_mut:tt)?) => {
107
    impl<'a, T: Pixel> $name<'a, T> {
108
109
      #[inline(always)]
110
0
      pub fn new(
111
0
        frame: &'a $($opt_mut)? Frame<T>,
112
0
        luma_rect: TileRect,
113
0
      ) -> Self {
114
0
        let mut planes_iter = frame.planes.$iter();
115
0
        Self {
116
0
          planes: [
117
0
            {
118
0
              let plane = planes_iter.next().unwrap();
119
0
              $pr_type::new(plane, luma_rect.into())
120
0
            },
121
0
            {
122
0
              let plane = planes_iter.next().unwrap();
123
0
              let rect = luma_rect.decimated(plane.cfg.xdec, plane.cfg.ydec);
124
0
              $pr_type::new(plane, rect.into())
125
0
            },
126
0
            {
127
0
              let plane = planes_iter.next().unwrap();
128
0
              let rect = luma_rect.decimated(plane.cfg.xdec, plane.cfg.ydec);
129
0
              $pr_type::new(plane, rect.into())
130
0
            },
131
0
          ],
132
0
        }
133
0
      }
Unexecuted instantiation: <rav1e::tiling::tile::Tile<u16>>::new
Unexecuted instantiation: <rav1e::tiling::tile::TileMut<u16>>::new
Unexecuted instantiation: <rav1e::tiling::tile::Tile<u8>>::new
Unexecuted instantiation: <rav1e::tiling::tile::TileMut<u8>>::new
134
135
      /// Return a view to a subregion of a Tile
136
      ///
137
      /// The subregion must be included in (i.e. must not exceed) this Tile.
138
      ///
139
      /// It is described by an `Area`, relative to the luma plane of
140
      /// this region.
141
      ///
142
      /// # Panics
143
      ///
144
      /// - If the requested dimensions are larger than the plane size
145
      #[inline(always)]
146
0
      pub fn subregion(&self, area: Area) -> Tile<'_, T> {
147
0
        let tile_rect = area.to_rect(
148
          0,
149
          0,
150
0
          self.planes[0].rect().width,
151
0
          self.planes[0].rect().height,
152
        );
153
        Tile {
154
          planes: {
155
0
            let sub_plane = |pli: usize| {
156
0
              let plane = &self.planes[pli];
157
0
              let &PlaneConfig { xdec, ydec, .. } = plane.plane_cfg;
158
0
              let rect = tile_rect.decimated(xdec, ydec);
159
0
              if !plane.is_null() {
160
0
                assert!(rect.x >= 0 && rect.x as usize <= plane.rect().width);
161
0
                assert!(rect.y >= 0 && rect.y as usize <= plane.rect().height);
162
0
                assert!(rect.x as usize + rect.width <=
163
0
                        plane.rect().x as usize + plane.rect().width);
164
0
                assert!(rect.y as usize + rect.height <=
165
0
                        plane.rect().y as usize + plane.rect().height);
166
0
              }
167
0
              plane.subregion(rect.to_area())
168
0
            };
Unexecuted instantiation: <rav1e::tiling::tile::Tile<u16>>::subregion::{closure#0}
Unexecuted instantiation: <rav1e::tiling::tile::TileMut<u16>>::subregion::{closure#0}
Unexecuted instantiation: <rav1e::tiling::tile::Tile<u8>>::subregion::{closure#0}
Unexecuted instantiation: <rav1e::tiling::tile::TileMut<u8>>::subregion::{closure#0}
169
0
            [sub_plane(0), sub_plane(1), sub_plane(2)]
170
          },
171
        }
172
0
      }
Unexecuted instantiation: <rav1e::tiling::tile::Tile<u16>>::subregion
Unexecuted instantiation: <rav1e::tiling::tile::TileMut<u16>>::subregion
Unexecuted instantiation: <rav1e::tiling::tile::Tile<u8>>::subregion
Unexecuted instantiation: <rav1e::tiling::tile::TileMut<u8>>::subregion
173
174
      // Return an equivalent Tile with origin homed to 0,0.  Data
175
      // pointer is not moved (0,0 points to the same pixel previously
176
      // pointed to by old x,y).
177
      #[inline(always)]
178
0
      pub fn home(&self) -> Self {
179
0
        Self {
180
0
          planes: [
181
0
            self.planes[0].home(),
182
0
            self.planes[1].home(),
183
0
            self.planes[2].home(),
184
0
          ],
185
0
        }
186
0
      }
Unexecuted instantiation: <rav1e::tiling::tile::Tile<u16>>::home
Unexecuted instantiation: <rav1e::tiling::tile::Tile<u8>>::home
Unexecuted instantiation: <rav1e::tiling::tile::TileMut<_>>::home
187
188
      // Return a copy of this tile's contents in a new backing frame.
189
      #[inline(always)]
190
0
      pub(crate) fn scratch_copy(&self) -> Frame<T> {
191
0
        Frame {
192
0
          planes: [
193
0
            self.planes[0].scratch_copy(),
194
0
            self.planes[1].scratch_copy(),
195
0
            self.planes[2].scratch_copy(),
196
0
          ],
197
0
        }
198
0
      }
Unexecuted instantiation: <rav1e::tiling::tile::Tile<u16>>::scratch_copy
Unexecuted instantiation: <rav1e::tiling::tile::Tile<u8>>::scratch_copy
Unexecuted instantiation: <rav1e::tiling::tile::TileMut<_>>::scratch_copy
199
    }
200
  }
201
}
202
203
tile_common!(Tile, PlaneRegion, iter);
204
tile_common!(TileMut, PlaneRegionMut, iter_mut, mut);
205
206
impl<T: Pixel> TileMut<'_, T> {
207
  #[inline(always)]
208
0
  pub fn as_const(&self) -> Tile<'_, T> {
209
0
    Tile {
210
0
      planes: [
211
0
        self.planes[0].as_const(),
212
0
        self.planes[1].as_const(),
213
0
        self.planes[2].as_const(),
214
0
      ],
215
0
    }
216
0
  }
Unexecuted instantiation: <rav1e::tiling::tile::TileMut<u16>>::as_const
Unexecuted instantiation: <rav1e::tiling::tile::TileMut<u8>>::as_const
217
}