Skip to main content

rxing/qrcode/encoder/
byte_matrix.rs

1/*
2 * Copyright 2008 ZXing authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use std::fmt;
18
19use crate::{Exceptions, common::BitMatrix};
20
21/**
22 * JAVAPORT: The original code was a 2D array of ints, but since it only ever gets assigned
23 * -1, 0, and 1, I'm going to use less memory and go with bytes.
24 *
25 * @author dswitkin@google.com (Daniel Switkin)
26 */
27#[derive(Debug, PartialEq, Eq, Clone)]
28pub struct ByteMatrix {
29    bytes: Vec<Vec<u8>>,
30    width: u32,
31    height: u32,
32}
33
34impl ByteMatrix {
35    pub fn new(width: u32, height: u32) -> Self {
36        Self {
37            bytes: vec![vec![0u8; width as usize]; height as usize],
38            width,
39            height,
40        }
41    }
42
43    pub fn getHeight(&self) -> u32 {
44        self.height
45    }
46
47    pub fn getWidth(&self) -> u32 {
48        self.width
49    }
50
51    pub fn get(&self, x: u32, y: u32) -> u8 {
52        self.bytes[y as usize][x as usize]
53    }
54
55    /**
56     * @return an internal representation as bytes, in row-major order. array[y][x] represents point (x,y)
57     */
58    pub fn getArray(&self) -> &Vec<Vec<u8>> {
59        &self.bytes
60    }
61
62    pub fn set(&mut self, x: u32, y: u32, value: u8) {
63        self.bytes[y as usize][x as usize] = value;
64    }
65
66    pub fn set_bool(&mut self, x: u32, y: u32, value: bool) {
67        self.bytes[y as usize][x as usize] = u8::from(value); //if value { 1 } else { 0 };
68    }
69
70    pub fn clear(&mut self, value: u8) {
71        for row in self.bytes.iter_mut() {
72            row.fill(value);
73        }
74    }
75}
76
77impl fmt::Display for ByteMatrix {
78    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79        let mut result = String::with_capacity(2 * self.width as usize * self.height as usize + 2);
80        for y in 0..self.height as usize {
81            let bytesY = &self.bytes[y];
82            for byte in bytesY.iter().take(self.width as usize) {
83                match *byte {
84                    0 => result.push_str(" 0"),
85                    1 => result.push_str(" 1"),
86                    _ => result.push_str("  "),
87                };
88            }
89            result.push('\n');
90        }
91        write!(f, "{result}")
92    }
93}
94
95impl TryFrom<ByteMatrix> for BitMatrix {
96    type Error = Exceptions;
97
98    fn try_from(value: ByteMatrix) -> Result<Self, Self::Error> {
99        let mut bit_matrix = BitMatrix::new(value.getWidth(), value.getHeight())?;
100        for y in 0..value.getHeight() {
101            for x in 0..value.getWidth() {
102                if value.get(x, y) > 0 {
103                    bit_matrix.set(x, y);
104                }
105            }
106        }
107        Ok(bit_matrix)
108    }
109}