Change some long method signatures to use where
. Adapt lifetime elision.
And removed a huge unused code segment.
This commit is contained in:
parent
84f1fed203
commit
eacaaab721
397
src/canvas.rs
397
src/canvas.rs
|
@ -140,7 +140,7 @@ impl Canvas {
|
|||
|
||||
/// Obtains a mutable module at the given coordinates. For convenience,
|
||||
/// negative coordinates will wrap around.
|
||||
pub fn get_mut<'a>(&'a mut self, x: i16, y: i16) -> &'a mut Module {
|
||||
pub fn get_mut(&mut self, x: i16, y: i16) -> &mut Module {
|
||||
let index = self.coords_to_index(x, y);
|
||||
self.modules.get_mut(index)
|
||||
}
|
||||
|
@ -959,7 +959,7 @@ impl DataModuleIter {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator<(i16, i16)> for DataModuleIter {
|
||||
impl Iterator<(i16, i16)> for DataModuleIter {
|
||||
fn next(&mut self) -> Option<(i16, i16)> {
|
||||
let adjusted_ref_col = if self.x <= self.timing_pattern_column {
|
||||
self.x + 1
|
||||
|
@ -1163,9 +1163,9 @@ mod data_iter_tests {
|
|||
//------------------------------------------------------------------------------
|
||||
//{{{ Data placement
|
||||
|
||||
fn draw_codewords<'a, I: Iterator<&'a mut Module>>(codewords: &[u8],
|
||||
is_half_codeword_at_end: bool,
|
||||
modules: &mut I) {
|
||||
fn draw_codewords<'a, I>(codewords: &[u8], is_half_codeword_at_end: bool, modules: &mut I)
|
||||
where I: Iterator<&'a mut Module>
|
||||
{
|
||||
let length = codewords.len();
|
||||
let last_word = if is_half_codeword_at_end { length-1 } else { length };
|
||||
for (i, b) in codewords.iter().enumerate() {
|
||||
|
@ -1737,390 +1737,3 @@ impl Canvas {
|
|||
//}}}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
|
||||
static ALL_PATTERNS: [MaskPattern, ..8] = [Pattern0, Pattern1, Pattern2, Pattern3, Pattern4, Pattern5, Pattern6, Pattern7];
|
||||
|
||||
|
||||
fn apply_mask(canvas: &mut Canvas, ec_level: ErrorCorrectionLevel, pattern: MaskPattern) {
|
||||
draw_format_info_patterns(canvas, ec_level, pattern);
|
||||
|
||||
let width = canvas.width();
|
||||
for y in range(0, width) {
|
||||
for x in range(0, width) {
|
||||
if should_mask(pattern, x, y) {
|
||||
let mut color = canvas.index_mut(&(x, y));
|
||||
*color = match *color {
|
||||
DataWhite => DataBlack,
|
||||
DataBlack => DataWhite,
|
||||
other => other,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_black(color: ModuleState) -> bool {
|
||||
match color {
|
||||
Black | DataBlack => true,
|
||||
Empty | White | DataWhite => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate_adjacent_penalty(canvas: &Canvas, is_horizontal: bool) -> uint {
|
||||
let mut score = 0u;
|
||||
let width = canvas.width();
|
||||
|
||||
let mut prev_is_black = false;
|
||||
let mut consec_length = 1u;
|
||||
for x in range(0, width) {
|
||||
for y in range(0, width) {
|
||||
let coords = if is_horizontal { (y, x) } else { (x, y) };
|
||||
let cur_is_black = is_black((*canvas)[coords]);
|
||||
if y != 0 && prev_is_black == cur_is_black {
|
||||
consec_length += 1;
|
||||
} else {
|
||||
if consec_length >= 5 {
|
||||
score += consec_length - 2;
|
||||
}
|
||||
consec_length = 1;
|
||||
}
|
||||
prev_is_black = cur_is_black;
|
||||
}
|
||||
}
|
||||
|
||||
if consec_length >= 5 {
|
||||
score += consec_length - 2;
|
||||
}
|
||||
|
||||
score
|
||||
}
|
||||
|
||||
fn evaluate_block_penalty(canvas: &Canvas) -> uint {
|
||||
let mut score = 0u;
|
||||
let width = canvas.width();
|
||||
|
||||
for x in range(0, width-1) {
|
||||
for y in range(0, width-1) {
|
||||
let color0 = is_black((*canvas)[(x, y)]);
|
||||
let color1 = is_black((*canvas)[(x+1, y)]);
|
||||
let color2 = is_black((*canvas)[(x, y+1)]);
|
||||
let color3 = is_black((*canvas)[(x+1, y+1)]);
|
||||
if color0 == color1 && color1 == color2 && color2 == color3 {
|
||||
score += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
score
|
||||
}
|
||||
|
||||
fn evaluate_finder_penalty(canvas: &Canvas, is_horizontal: bool) -> uint {
|
||||
use std::iter::order::eq;
|
||||
|
||||
let mut score = 0u;
|
||||
let width = canvas.width();
|
||||
|
||||
for x in range(0, width) {
|
||||
for y in range(0, width-6) {
|
||||
let colors = range(y, y+7)
|
||||
.map(|r| if is_horizontal { (r, x) } else { (x, r) })
|
||||
.map(|coords| is_black((*canvas)[coords]));
|
||||
if eq(colors, [true, false, true, true, true, false, true].iter().map(|&b| b)) {
|
||||
score += 40;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
score
|
||||
}
|
||||
|
||||
fn evaluate_proportion_penalty(canvas: &Canvas) -> uint {
|
||||
let black_modules = canvas.modules.iter().filter(|&&m| is_black(m)).count();
|
||||
let width = canvas.width;
|
||||
let total_modules = width * width;
|
||||
let ratio = black_modules * 200 / total_modules;
|
||||
if ratio >= 100 { ratio - 100 } else { 100 - ratio }
|
||||
}
|
||||
|
||||
fn apply_best_mask(canvas: &Canvas, ec_level: ErrorCorrectionLevel) -> Canvas {
|
||||
ALL_PATTERNS.iter().map(|&pattern| {
|
||||
let mut canvas_copy = canvas.clone();
|
||||
apply_mask(&mut canvas_copy, ec_level, pattern);
|
||||
canvas_copy
|
||||
}).min_by(|c| {
|
||||
use std::io::stdio::stdout;
|
||||
let s1 = evaluate_adjacent_penalty(c, true);
|
||||
let s2 = evaluate_adjacent_penalty(c, false);
|
||||
let s3 = evaluate_block_penalty(c);
|
||||
let s4 = evaluate_finder_penalty(c, true);
|
||||
let s5 = evaluate_finder_penalty(c, false);
|
||||
let s6 = evaluate_proportion_penalty(c);
|
||||
stdout().write_line(format!("{} + {} + {} + {} + {} + {}", s1, s2, s3, s4, s5, s6).as_slice());
|
||||
s1 + s2 + s3 + s4 + s5 + s6
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use collections::{bitv, Bitv};
|
||||
use canvas::{Canvas, Empty, Black, White, DataBlack, DataWhite,
|
||||
draw_finder_patterns, draw_alignment_patterns,
|
||||
draw_timing_patterns, draw_version_info_patterns,
|
||||
draw_format_info_patterns, Pattern4, Pattern0, apply_mask,
|
||||
draw_all_functional_patterns, evaluate_adjacent_penalty,
|
||||
evaluate_block_penalty, evaluate_finder_penalty,
|
||||
evaluate_proportion_penalty, apply_best_mask};
|
||||
use ec::{L, Q};
|
||||
|
||||
#[test]
|
||||
fn test_draw_format_info_patterns() {
|
||||
let mut c = Canvas::new(1);
|
||||
draw_format_info_patterns(&mut c, L, Pattern4);
|
||||
assert_eq!(c.to_debug_str().as_slice(), "\n\
|
||||
????????#????????????\n\
|
||||
????????#????????????\n\
|
||||
????????#????????????\n\
|
||||
????????#????????????\n\
|
||||
???????? ????????????\n\
|
||||
????????#????????????\n\
|
||||
?????????????????????\n\
|
||||
???????? ????????????\n\
|
||||
## ##? ???? # ####\n\
|
||||
?????????????????????\n\
|
||||
?????????????????????\n\
|
||||
?????????????????????\n\
|
||||
?????????????????????\n\
|
||||
?????????????????????\n\
|
||||
???????? ????????????\n\
|
||||
????????#????????????\n\
|
||||
????????#????????????\n\
|
||||
???????? ????????????\n\
|
||||
???????? ????????????\n\
|
||||
????????#????????????\n\
|
||||
????????#????????????");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_draw_all_functional_patterns() {
|
||||
let mut c = Canvas::new(2);
|
||||
draw_all_functional_patterns(&mut c);
|
||||
assert_eq!(c.to_debug_str().as_slice(), "\n\
|
||||
####### ???????? #######\n\
|
||||
# # ???????? # #\n\
|
||||
# ### # ???????? # ### #\n\
|
||||
# ### # ???????? # ### #\n\
|
||||
# ### # ???????? # ### #\n\
|
||||
# # ???????? # #\n\
|
||||
####### # # # # # #######\n\
|
||||
\x20 ???????? \n\
|
||||
\x20 # ???????? \n\
|
||||
?????? ??????????????????\n\
|
||||
??????#??????????????????\n\
|
||||
?????? ??????????????????\n\
|
||||
??????#??????????????????\n\
|
||||
?????? ??????????????????\n\
|
||||
??????#??????????????????\n\
|
||||
?????? ??????????????????\n\
|
||||
??????#?????????#####????\n\
|
||||
\x20 #???????# #????\n\
|
||||
####### ???????# # #????\n\
|
||||
# # ???????# #????\n\
|
||||
# ### # ???????#####????\n\
|
||||
# ### # ????????????????\n\
|
||||
# ### # ????????????????\n\
|
||||
# # ????????????????\n\
|
||||
####### ????????????????");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_modules_increase() {
|
||||
use canvas::DataModuleIter;
|
||||
|
||||
let res: Vec<uint> = DataModuleIter::new(17).collect();
|
||||
|
||||
assert_eq!(res, vec![
|
||||
0,17,1,18,2,19,3,20,4,21,5,22,6,23,7,24,8,25,9,26,10,27,11,28,12,29,
|
||||
13,30,14,31,15,32,16,33,50,67,49,66,48,65,47,64,46,63,45,62,44,61,
|
||||
43,60,42,59,41,58,40,57,39,56,38,55,37,54,36,53,35,52,34,51,68,85,
|
||||
69,86,70,87,71,88,72,89,73,90,74,91,75,92,76,93,77,94,78,95,79,96,
|
||||
80,97,81,98,82,99,83,100,84,101,118,135,117,134,116,133,115,132,114,
|
||||
131,113,130,112,129,111,128,110,127,109,126,108,125,107,124,106,123,
|
||||
105,122,104,121,103,120,102,119,136,153,137,154,138,155,139,156,140,
|
||||
157,141,158,142,159,143,160,144,161,145,162,146,163,147,164,148,165,
|
||||
149,166,150,167,151,168,152,169,203,220,202,219,201,218,200,217,199,
|
||||
216,198,215,197,214,196,213,195,212,194,211,193,210,192,209,191,208,
|
||||
190,207,189,206,188,205,187,204,221,238,222,239,223,240,224,241,225,
|
||||
242,226,243,227,244,228,245,229,246,230,247,231,248,232,249,233,250,
|
||||
234,251,235,252,236,253,237,254,271,288,270,287,269,286,268,285,267,
|
||||
284,266,283,265,282,264,281,263,280,262,279,261,278,260,277,259,276,
|
||||
258,275,257,274,256,273,255,272
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fill_in_modules() {
|
||||
let mut c = Canvas::new(2);
|
||||
draw_all_functional_patterns(&mut c);
|
||||
c.fill_data_bits([true, false, false].iter().cycle().map(|&b| b));
|
||||
assert_eq!(c.to_debug_str().as_slice(), "\n\
|
||||
####### ..*...*. #######\n\
|
||||
# # .*.*.*.* # #\n\
|
||||
# ### # *...*... # ### #\n\
|
||||
# ### # ..*...*. # ### #\n\
|
||||
# ### # .*.*.*.* # ### #\n\
|
||||
# # *...*... # #\n\
|
||||
####### # # # # # #######\n\
|
||||
\x20 ..*...*. \n\
|
||||
\x20 # .*.*.*.* \n\
|
||||
..*.*. .**...*...*..**..*\n\
|
||||
.*.*..#....*...*.........\n\
|
||||
*....* *..*.*.*.*.**..**.\n\
|
||||
..*.*.#.**...*...*..**..*\n\
|
||||
.*.*.. ....*...*.........\n\
|
||||
*....*#*..*.*.*.*.**..**.\n\
|
||||
..*.*. .**...*...*..**..*\n\
|
||||
.*.*..#....*...*#####....\n\
|
||||
\x20 #.*.*.*.# #.**.\n\
|
||||
####### *...*..# # #*..*\n\
|
||||
# # ..*...*# #....\n\
|
||||
# ### # .*.*.*.#####.**.\n\
|
||||
# ### # *...*..*....*..*\n\
|
||||
# ### # ..*......**.....\n\
|
||||
# # .*.*.**.*..*.**.\n\
|
||||
####### *...*..*....*..*");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_apply_mask() {
|
||||
let mut c = Canvas::new(1);
|
||||
draw_all_functional_patterns(&mut c);
|
||||
c.fill_data_bits(Bitv::new().iter());
|
||||
apply_mask(&mut c, L, Pattern0);
|
||||
|
||||
assert_eq!(c.to_debug_str().as_slice(), "\n\
|
||||
####### .*.* #######\n\
|
||||
# # *.*. # #\n\
|
||||
# ### # #.*.* # ### #\n\
|
||||
# ### # *.*. # ### #\n\
|
||||
# ### # .*.* # ### #\n\
|
||||
# # *.*. # #\n\
|
||||
####### # # # #######\n\
|
||||
\x20 #*.*. \n\
|
||||
### #####.*.*## # \n\
|
||||
.*.*.* *.*.*.*.*.*.*.\n\
|
||||
*.*.*.#.*.*.*.*.*.*.*\n\
|
||||
.*.*.* *.*.*.*.*.*.*.\n\
|
||||
*.*.*.#.*.*.*.*.*.*.*\n\
|
||||
\x20 #*.*.*.*.*.*.\n\
|
||||
####### #.*.*.*.*.*.*\n\
|
||||
# # #*.*.*.*.*.*.\n\
|
||||
# ### # #.*.*.*.*.*.*\n\
|
||||
# ### # *.*.*.*.*.*.\n\
|
||||
# ### # #.*.*.*.*.*.*\n\
|
||||
# # #*.*.*.*.*.*.\n\
|
||||
####### #.*.*.*.*.*.*");
|
||||
}
|
||||
|
||||
fn prepare_canvas_for_penalty_scoring() -> Canvas {
|
||||
let mut c = Canvas::new(1);
|
||||
let data = bitv::from_bytes(
|
||||
|
||||
|
||||
b"\x20\x5b\x0b\x78\xd1\x72\xdc\x4d\x43\x40\xec\x11\x00\xa8\x48\x16\x52\xd9\x36\x9c\x00\x2e\x0f\xb4\x7a\x10");
|
||||
draw_all_functional_patterns(&mut c);
|
||||
c.fill_data_bits(data.iter());
|
||||
apply_mask(&mut c, Q, Pattern0);
|
||||
c
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_penalty_canvas() {
|
||||
let c = prepare_canvas_for_penalty_scoring();
|
||||
assert_eq!(c.to_debug_str().as_slice(), "\n\
|
||||
####### #*... #######\n\
|
||||
# # #..*. # #\n\
|
||||
# ### # #..** # ### #\n\
|
||||
# ### # #.... # ### #\n\
|
||||
# ### # #.*.. # ### #\n\
|
||||
# # .*.. # #\n\
|
||||
####### # # # #######\n\
|
||||
\x20 #.... \n\
|
||||
\x20## # ## ...* # #####\n\
|
||||
.*.... .****....*...*\n\
|
||||
..**.*#*.**...*.**...\n\
|
||||
.**.** *..**.*.*.***.\n\
|
||||
*...*.#.*.***.***.*.*\n\
|
||||
\x20 #*.*..*...*.*\n\
|
||||
####### #.*....*.**..\n\
|
||||
# # *.**.**.*...\n\
|
||||
# ### # #.*...*******\n\
|
||||
# ### # *.*.*.*...*.\n\
|
||||
# ### # #...****.*..*\n\
|
||||
# # #.**.*...*.**\n\
|
||||
####### ...****....*");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_penalty_score_adjacent() {
|
||||
let c = prepare_canvas_for_penalty_scoring();
|
||||
assert_eq!(evaluate_adjacent_penalty(&c, true), 88);
|
||||
assert_eq!(evaluate_adjacent_penalty(&c, false), 92);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_penalty_score_block() {
|
||||
let c = prepare_canvas_for_penalty_scoring();
|
||||
assert_eq!(evaluate_block_penalty(&c), 90);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_penalty_score_finder() {
|
||||
let c = prepare_canvas_for_penalty_scoring();
|
||||
assert_eq!(evaluate_finder_penalty(&c, true), 480);
|
||||
assert_eq!(evaluate_finder_penalty(&c, false), 440);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_penalty_score_proportion() {
|
||||
let c = prepare_canvas_for_penalty_scoring();
|
||||
assert_eq!(evaluate_proportion_penalty(&c), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_best_mask() {
|
||||
let mut c = Canvas::new(1);
|
||||
let data = bitv::from_bytes(b"\x20\x5b\x0b\x78\xd1\x72\xdc\x4d\x43\x40\xec\x11\x00\xa8\x48\x16\x52\xd9\x36\x9c\x00\x2e\x0f\xb4\x7a\x10");
|
||||
draw_all_functional_patterns(&mut c);
|
||||
c.fill_data_bits(data.iter());
|
||||
|
||||
let c2 = apply_best_mask(&c, Q);
|
||||
|
||||
assert_eq!(c2.to_debug_str().as_slice(), "\n\
|
||||
####### #*... #######\n\
|
||||
# # #..*. # #\n\
|
||||
# ### # #..** # ### #\n\
|
||||
# ### # #.... # ### #\n\
|
||||
# ### # #.*.. # ### #\n\
|
||||
# # .*.. # #\n\
|
||||
####### # # # #######\n\
|
||||
\x20 #.... \n\
|
||||
\x20## # ## ...* # #####\n\
|
||||
.*.... .****....*...*\n\
|
||||
..**.*#*.**...*.**...\n\
|
||||
.**.** *..**.*.*.***.\n\
|
||||
*...*.#.*.***.***.*.*\n\
|
||||
\x20 #*.*..*...*.*\n\
|
||||
####### #.*....*.**..\n\
|
||||
# # *.**.**.*...\n\
|
||||
# ### # #.*...*******\n\
|
||||
# ### # *.*.*.*...*.\n\
|
||||
# ### # #...****.*..*\n\
|
||||
# # #.**.*...*.**\n\
|
||||
####### ...****....*");
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
@ -102,8 +102,9 @@ impl<'a, T: Copy> InterleaveSupport<T> for &'a [T] {
|
|||
///
|
||||
/// The longest slice must be at the last of `blocks`, and `blocks` must not be
|
||||
/// empty.
|
||||
fn interleave<'a, 'b, T: Copy,
|
||||
V: InterleaveSupport<T> + Collection>(blocks: &Vec<V>) -> Vec<T> {
|
||||
fn interleave<T: Copy, V>(blocks: &Vec<V>) -> Vec<T>
|
||||
where V: InterleaveSupport<T> + Collection
|
||||
{
|
||||
let last_block_len = blocks.last().unwrap().len();
|
||||
let mut res = Vec::with_capacity(last_block_len * blocks.len());
|
||||
for i in range(0, last_block_len) {
|
||||
|
|
|
@ -165,7 +165,7 @@ impl QrCode {
|
|||
}
|
||||
|
||||
impl Index<(uint, uint), bool> for QrCode {
|
||||
fn index<'a>(&'a self, &(x, y): &(uint, uint)) -> &'a bool {
|
||||
fn index(&self, &(x, y): &(uint, uint)) -> &bool {
|
||||
let index = y * self.width + x;
|
||||
self.content.index(&index)
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ impl<'a> Parser<'a> {
|
|||
/// Segment { mode: Numeric, begin: 3, end: 6 },
|
||||
/// Segment { mode: Byte, begin: 6, end: 10 }]);
|
||||
///
|
||||
pub fn new(data: &'a [u8]) -> Parser {
|
||||
pub fn new(data: &[u8]) -> Parser {
|
||||
Parser {
|
||||
ecs_iter: EcsIter { base: data.iter(), index: 0, ended: false },
|
||||
state: SInit,
|
||||
|
|
|
@ -95,9 +95,9 @@ impl Version {
|
|||
///
|
||||
/// If the entry compares equal to the default value of T, this method
|
||||
/// returns `Err(InvalidVersion)`.
|
||||
pub fn fetch<T: PartialEq + Default + Copy>(&self,
|
||||
ec_level: ErrorCorrectionLevel,
|
||||
table: &[[T, ..4]]) -> QrResult<T> {
|
||||
pub fn fetch<T>(&self, ec_level: ErrorCorrectionLevel, table: &[[T, ..4]]) -> QrResult<T>
|
||||
where T: PartialEq + Default + Copy
|
||||
{
|
||||
match *self {
|
||||
Version(v @ 1..40) => Ok(table[v as uint - 1][ec_level as uint]),
|
||||
MicroVersion(v @ 1..4) => {
|
||||
|
|
Loading…
Reference in a new issue