Skip to main content

zenjxl_decoder/image/
rect.rs

1// Copyright (c) the JPEG XL Project Authors. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file.
5
6use super::DataTypeTag;
7
8#[derive(Clone, Copy, Debug)]
9pub struct Rect {
10    pub origin: (usize, usize),
11    // width, height
12    pub size: (usize, usize),
13}
14
15impl Rect {
16    pub fn check_within(&self, size: (usize, usize)) {
17        if self.origin.0.checked_add(self.size.0).unwrap() > size.0
18            || self.origin.1.checked_add(self.size.1).unwrap() > size.1
19        {
20            panic!(
21                "Rect out of bounds: {}x{}+{}+{} rect in {}x{} view",
22                self.size.0, self.size.1, self.origin.0, self.origin.1, size.0, size.1
23            );
24        }
25    }
26
27    #[inline]
28    pub fn to_byte_rect(&self, data_type: DataTypeTag) -> Rect {
29        self.to_byte_rect_sz(data_type.size())
30    }
31
32    #[inline]
33    pub fn to_byte_rect_sz(&self, sz: usize) -> Rect {
34        Rect {
35            origin: (self.origin.0 * sz, self.origin.1),
36            size: (self.size.0 * sz, self.size.1),
37        }
38    }
39
40    pub fn downsample(&self, downsample: (u8, u8)) -> Rect {
41        Rect {
42            origin: (self.origin.0 >> downsample.0, self.origin.1 >> downsample.1),
43            size: (self.size.0 >> downsample.0, self.size.1 >> downsample.1),
44        }
45    }
46
47    pub fn end(&self) -> (usize, usize) {
48        (self.origin.0 + self.size.0, self.origin.1 + self.size.1)
49    }
50
51    pub fn clip(&self, size: (usize, usize)) -> Rect {
52        let end = self.end();
53        Rect {
54            origin: self.origin,
55            size: (
56                end.0.min(size.0).saturating_sub(self.origin.0),
57                end.1.min(size.1).saturating_sub(self.origin.1),
58            ),
59        }
60    }
61}