1 //! Decode QR-Codes 2 3 pub use self::decode::{decode, MetaData, Version}; 4 pub use crate::decode::bmp_grid::BmpDecode; 5 use std::error::Error; 6 use std::io::Write; 7 8 mod bmp_grid; 9 mod decode; 10 mod version_db; 11 12 /// A simple point in (some) space 13 #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] 14 pub struct Point { 15 /// x 16 pub x: i32, 17 /// y 18 pub y: i32, 19 } 20 21 /// Wrapper around any grid that can be interpreted as a QR code 22 #[derive(Debug, Clone)] 23 pub struct Grid<G> { 24 /// The backing binary square 25 pub grid: G, 26 /// The bounds of the square, in underlying coordinates. 27 /// 28 /// If this grid references for example an underlying image, these values will be set to 29 /// coordinates in that image. 30 pub bounds: [Point; 4], 31 } 32 33 impl<G> Grid<G> 34 where 35 G: BitGrid, 36 { 37 /// Create a new grid from a BitGrid. 38 /// 39 /// This just initialises the bounds to 0. new(grid: G) -> Self40 pub fn new(grid: G) -> Self { 41 Grid { 42 grid, 43 bounds: [ 44 Point { x: 0, y: 0 }, 45 Point { x: 0, y: 0 }, 46 Point { x: 0, y: 0 }, 47 Point { x: 0, y: 0 }, 48 ], 49 } 50 } 51 52 /// Try to decode the grid. 53 /// 54 /// If successful returns the decoded string as well as metadata about the code. decode(&self) -> DeQRResult<(MetaData, String)>55 pub fn decode(&self) -> DeQRResult<(MetaData, String)> { 56 let mut out = Vec::new(); 57 let meta = self.decode_to(&mut out)?; 58 let out = String::from_utf8(out)?; 59 Ok((meta, out)) 60 } 61 62 /// Try to decode the grid. 63 /// 64 /// Instead of returning a String, this methode writes the decoded result to the given writer 65 /// 66 /// **Warning**: This may lead to half decoded content to be written to the writer. decode_to<W>(&self, writer: W) -> DeQRResult<MetaData> where W: Write,67 pub fn decode_to<W>(&self, writer: W) -> DeQRResult<MetaData> 68 where 69 W: Write, 70 { 71 crate::decode::decode(&self.grid, writer) 72 } 73 } 74 75 /// A grid that contains exactly one QR code square. 76 /// 77 /// The common trait for everything that can be decoded as a QR code. Given a normal image, we first 78 /// need to find the QR grids in it. 79 /// 80 /// This trait can be implemented when some object is known to be exactly the bit-pattern 81 /// of a QR code. 82 pub trait BitGrid { 83 /// Return the size of the grid. 84 /// 85 /// Since QR codes are always squares, the grid is assumed to be size * size. size(&self) -> usize86 fn size(&self) -> usize; 87 88 /// Return the value of the bit at the given location. 89 /// 90 /// `true` means 'black', `false` means 'white' bit(&self, y: usize, x: usize) -> bool91 fn bit(&self, y: usize, x: usize) -> bool; 92 93 #[cfg(feature = "img")] write_grid_to(&self, p: &str)94 fn write_grid_to(&self, p: &str) { 95 let mut dyn_img = image::GrayImage::new(self.size() as u32, self.size() as u32); 96 for y in 0..self.size() { 97 for x in 0..self.size() { 98 let color = match self.bit(x, y) { 99 true => 0, 100 false => 255, 101 }; 102 dyn_img.get_pixel_mut(x as u32, y as u32).data[0] = color; 103 } 104 } 105 dyn_img.save(p).unwrap(); 106 } 107 } 108 109 /// A basic GridImage that can be generated from a given function. 110 /// 111 /// # Example 112 /// 113 /// ```rust 114 /// # fn main() -> Result<(), qr_code::decode::DeQRError> { 115 /// let grid = [ 116 /// [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, ], 117 /// [1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, ], 118 /// [1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, ], 119 /// [1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, ], 120 /// [1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, ], 121 /// [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, ], 122 /// [1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], 123 /// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], 124 /// [1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, ], 125 /// [1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, ], 126 /// [0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, ], 127 /// [1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, ], 128 /// [0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, ], 129 /// [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, ], 130 /// [1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, ], 131 /// [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ], 132 /// [1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, ], 133 /// [1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, ], 134 /// [1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, ], 135 /// [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, ], 136 /// [1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, ], 137 /// ]; 138 /// 139 /// let simple = qr_code::decode::SimpleGrid::from_func(21, |x, y| { 140 /// grid[y][x] == 1 141 /// }); 142 /// let grid = qr_code::decode::Grid::new(simple); 143 /// let (_meta, content) = grid.decode()?; 144 /// assert_eq!(content, "rqrr"); 145 /// # Ok(()) 146 /// # } 147 /// ``` 148 #[derive(Debug, Clone)] 149 pub struct SimpleGrid { 150 cell_bitmap: Vec<u8>, 151 size: usize, 152 } 153 154 impl SimpleGrid { 155 /// from_func from_func<F>(size: usize, fill_func: F) -> Self where F: Fn(usize, usize) -> bool,156 pub fn from_func<F>(size: usize, fill_func: F) -> Self 157 where 158 F: Fn(usize, usize) -> bool, 159 { 160 let mut cell_bitmap = vec![0; (size * size + 7) / 8]; 161 let mut c = 0; 162 for y in 0..size { 163 for x in 0..size { 164 if fill_func(x, y) { 165 cell_bitmap[c >> 3] |= 1 << (c & 7) as u8; 166 } 167 c += 1; 168 } 169 } 170 171 SimpleGrid { cell_bitmap, size } 172 } 173 } 174 175 impl BitGrid for SimpleGrid { size(&self) -> usize176 fn size(&self) -> usize { 177 self.size 178 } 179 bit(&self, y: usize, x: usize) -> bool180 fn bit(&self, y: usize, x: usize) -> bool { 181 let c = y * self.size + x; 182 self.cell_bitmap[c >> 3] & (1 << (c & 7) as u8) != 0 183 } 184 } 185 186 /// Possible errors that can happen during decoding 187 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 188 pub enum DeQRError { 189 /// Could not write the output to the output stream/string 190 IoError, 191 /// Expected more bits to decode 192 DataUnderflow, 193 /// Expected less bits to decode 194 DataOverflow, 195 /// Unknown data type in encoding 196 UnknownDataType, 197 /// Could not correct errors / code corrupt 198 DataEcc, 199 /// Could not read format information from both locations 200 FormatEcc, 201 /// Unsupported / non-existent version read 202 InvalidVersion, 203 /// Unsupported / non-existent grid size read 204 InvalidGridSize, 205 /// Output was not encoded in expected UTF8 206 EncodingError, 207 } 208 209 type DeQRResult<T> = Result<T, DeQRError>; 210 211 impl Error for DeQRError {} 212 213 impl From<::std::string::FromUtf8Error> for DeQRError { from(_: ::std::string::FromUtf8Error) -> Self214 fn from(_: ::std::string::FromUtf8Error) -> Self { 215 DeQRError::EncodingError 216 } 217 } 218 219 impl ::std::fmt::Display for DeQRError { fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result220 fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result { 221 let msg = match self { 222 DeQRError::IoError => "IoError(Could not write to output)", 223 DeQRError::DataUnderflow => "DataUnderflow(Expected more bits to decode)", 224 DeQRError::DataOverflow => "DataOverflow(Expected less bits to decode)", 225 DeQRError::UnknownDataType => "UnknownDataType(DataType not known or not implemented)", 226 DeQRError::DataEcc => "Ecc(Too many errors to correct)", 227 DeQRError::FormatEcc => "Ecc(Version information corrupt)", 228 DeQRError::InvalidVersion => "InvalidVersion(Invalid version or corrupt)", 229 DeQRError::InvalidGridSize => "InvalidGridSize(Invalid version or corrupt)", 230 DeQRError::EncodingError => "Encoding(Not UTF8)", 231 }; 232 write!(f, "{}", msg) 233 } 234 } 235 236 #[cfg(test)] 237 mod tests { 238 use super::*; 239 240 #[test] test_rqrr()241 fn test_rqrr() { 242 let grid = [ 243 [ 244 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 245 ], 246 [ 247 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 248 ], 249 [ 250 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 251 ], 252 [ 253 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 254 ], 255 [ 256 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 257 ], 258 [ 259 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 260 ], 261 [ 262 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 263 ], 264 [ 265 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 266 ], 267 [ 268 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 269 ], 270 [ 271 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 272 ], 273 [ 274 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 275 ], 276 [ 277 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 278 ], 279 [ 280 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 281 ], 282 [ 283 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 284 ], 285 [ 286 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 287 ], 288 [ 289 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 290 ], 291 [ 292 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 293 ], 294 [ 295 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 296 ], 297 [ 298 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 299 ], 300 [ 301 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 302 ], 303 [ 304 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 305 ], 306 ]; 307 308 let img = crate::decode::SimpleGrid::from_func(21, |x, y| grid[y][x] == 1); 309 310 let mut buf = vec![0; img.size() * img.size() / 8 + 1]; 311 for y in 0..img.size() { 312 for x in 0..img.size() { 313 let i = y * img.size() + x; 314 if img.bit(y, x) { 315 buf[i >> 3] |= 1 << ((i & 7) as u8); 316 } 317 } 318 } 319 320 let mut vec = Vec::new(); 321 crate::decode::decode(&img, &mut vec).unwrap(); 322 323 assert_eq!(b"rqrr".as_ref(), &vec[..]) 324 } 325 326 #[test] test_github()327 fn test_github() { 328 let grid = [ 329 [ 330 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 331 1, 332 ], 333 [ 334 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 335 1, 336 ], 337 [ 338 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 339 1, 340 ], 341 [ 342 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 343 1, 344 ], 345 [ 346 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 347 1, 348 ], 349 [ 350 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 351 1, 352 ], 353 [ 354 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 355 1, 356 ], 357 [ 358 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 359 0, 360 ], 361 [ 362 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 363 0, 364 ], 365 [ 366 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 367 1, 368 ], 369 [ 370 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 371 1, 372 ], 373 [ 374 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 375 0, 376 ], 377 [ 378 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 379 1, 380 ], 381 [ 382 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 383 1, 384 ], 385 [ 386 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 387 1, 388 ], 389 [ 390 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 391 0, 392 ], 393 [ 394 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 395 1, 396 ], 397 [ 398 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 399 1, 400 ], 401 [ 402 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 403 1, 404 ], 405 [ 406 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 407 0, 408 ], 409 [ 410 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 411 0, 412 ], 413 [ 414 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 415 1, 416 ], 417 [ 418 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 419 1, 420 ], 421 [ 422 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 423 0, 424 ], 425 [ 426 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 427 1, 428 ], 429 [ 430 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 431 1, 432 ], 433 [ 434 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 435 1, 436 ], 437 [ 438 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 439 0, 440 ], 441 [ 442 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 443 1, 444 ], 445 ]; 446 447 let img = crate::decode::SimpleGrid::from_func(29, |x, y| grid[y][x] == 1); 448 449 let mut buf = vec![0; img.size() * img.size() / 8 + 1]; 450 for y in 0..img.size() { 451 for x in 0..img.size() { 452 let i = y * img.size() + x; 453 if img.bit(y, x) { 454 buf[i >> 3] |= 1 << ((i & 7) as u8); 455 } 456 } 457 } 458 459 let mut vec = Vec::new(); 460 crate::decode::decode(&img, &mut vec).unwrap(); 461 462 assert_eq!(b"https://github.com/WanzenBug/rqrr".as_ref(), &vec[..]) 463 } 464 465 #[test] test_number()466 fn test_number() { 467 let grid = [ 468 [ 469 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 470 1, 471 ], 472 [ 473 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 474 1, 475 ], 476 [ 477 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 478 1, 479 ], 480 [ 481 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 482 1, 483 ], 484 [ 485 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 486 1, 487 ], 488 [ 489 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 490 1, 491 ], 492 [ 493 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 494 1, 495 ], 496 [ 497 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 498 0, 499 ], 500 [ 501 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 502 0, 503 ], 504 [ 505 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 506 1, 507 ], 508 [ 509 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 510 0, 511 ], 512 [ 513 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 514 1, 515 ], 516 [ 517 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 518 0, 519 ], 520 [ 521 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 522 1, 523 ], 524 [ 525 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 526 0, 527 ], 528 [ 529 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 530 1, 531 ], 532 [ 533 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 534 0, 535 ], 536 [ 537 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 538 1, 539 ], 540 [ 541 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 542 0, 543 ], 544 [ 545 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 546 0, 547 ], 548 [ 549 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 550 0, 551 ], 552 [ 553 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 554 1, 555 ], 556 [ 557 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 558 0, 559 ], 560 [ 561 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 562 1, 563 ], 564 [ 565 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 566 1, 567 ], 568 [ 569 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 570 0, 571 ], 572 [ 573 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 574 0, 575 ], 576 [ 577 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 578 0, 579 ], 580 [ 581 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 582 0, 583 ], 584 ]; 585 586 let img = crate::decode::SimpleGrid::from_func(29, |x, y| grid[y][x] == 1); 587 588 let mut buf = vec![0; img.size() * img.size() / 8 + 1]; 589 for y in 0..img.size() { 590 for x in 0..img.size() { 591 let i = y * img.size() + x; 592 if img.bit(y, x) { 593 buf[i >> 3] |= 1 << ((i & 7) as u8); 594 } 595 } 596 } 597 598 let mut vec = Vec::new(); 599 crate::decode::decode(&img, &mut vec).unwrap(); 600 601 assert_eq!(b"1234567891011121314151617181920".as_ref(), &vec[..]) 602 } 603 604 /* 605 #[test] 606 fn test_fuzz() { 607 use arbitrary::Arbitrary; 608 let data = include_bytes!("../../test_data/crash-0d7a321bf16ab956c7bdbf0167bcc4861a1c61f1"); 609 let mut unstructured = arbitrary::Unstructured::new(data); 610 let qr_code = qr_code::QrCode::arbitrary(&mut unstructured).unwrap(); 611 dbg!(&qr_code); 612 let bmp = qr_code.to_bmp().mul(3).add_white_border(12); 613 bmp.write(std::fs::File::create("cc.bmp").unwrap()).unwrap(); 614 let _ = bmp.decode().unwrap(); 615 } 616 */ 617 } 618