Somewhat simplified black/white balance penalty calculation in all language versions.

This commit is contained in:
Project Nayuki 2018-08-26 03:20:12 +00:00
parent 7d7a9b4820
commit 5073db4487
7 changed files with 28 additions and 26 deletions

View File

@ -619,10 +619,11 @@ static long getPenaltyScore(const uint8_t qrcode[]) {
black++;
}
}
// Note that size is odd, so black/total != 1/2
int total = qrsize * qrsize;
// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
for (int k = 0; black*20L < (9L-k)*total || black*20L > (11L+k)*total; k++)
result += PENALTY_N4;
// Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)%
int k = (int)((labs(black * 20L - total * 10L) + total - 1) / total) - 1;
result += k * PENALTY_N4;
return result;
}

View File

@ -485,10 +485,11 @@ long QrCode::getPenaltyScore() const {
black++;
}
}
// Note that size is odd, so black/total != 1/2
int total = size * size;
// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
for (int k = 0; black*20L < (9L-k)*total || black*20L > (11L+k)*total; k++)
result += PENALTY_N4;
// Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)%
int k = static_cast<int>((std::abs(black * 20L - total * 10L) + total - 1) / total) - 1;
result += k * PENALTY_N4;
return result;
}

View File

@ -632,10 +632,11 @@ public final class QrCode {
black++;
}
}
// Note that size is odd, so black/total != 1/2
int total = size * size;
// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
for (int k = 0; black*20 < (9-k)*total || black*20 > (11+k)*total; k++)
result += PENALTY_N4;
// Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)%
int k = (Math.abs(black * 20 - total * 10) + total - 1) / total - 1;
result += k * PENALTY_N4;
return result;
}

View File

@ -480,10 +480,11 @@ var qrcodegen = new function() {
black++;
});
});
// Note that size is odd, so black/total != 1/2
var total = size * size;
// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
for (var k = 0; black*20 < (9-k)*total || black*20 > (11+k)*total; k++)
result += QrCode.PENALTY_N4;
// Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)%
var k = Math.ceil(Math.abs(black * 20 - total * 10) / total) - 1;
result += k * QrCode.PENALTY_N4;
return result;
}

View File

@ -476,12 +476,11 @@ class QrCode(object):
# Balance of black and white modules
black = sum((1 if cell else 0) for row in modules for cell in row)
# Note that size is odd, so black/total != 1/2
total = size**2
# Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
for k in itertools.count():
if (9-k)*total <= black*20 <= (11+k)*total:
break
result += QrCode._PENALTY_N4
# Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)%
k = (abs(black * 20 - total * 10) + total - 1) // total - 1
result += k * QrCode._PENALTY_N4
return result

View File

@ -609,13 +609,11 @@ impl QrCode {
for color in &self.modules {
black += *color as i32;
}
// Note that size is odd, so black/total != 1/2
let total: i32 = size * size;
// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
let mut k: i32 = 0;
while black*20 < (9-k)*total || black*20 > (11+k)*total {
result += PENALTY_N4;
k += 1;
}
// Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)%
let k: i32 = ((black * 20 - total * 10).abs() + total - 1) / total - 1;
result += k * PENALTY_N4;
result
}

View File

@ -548,10 +548,11 @@ namespace qrcodegen {
black++;
});
});
// Note that size is odd, so black/total != 1/2
let total: int = this.size * this.size;
// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
for (let k = 0; black*20 < (9-k)*total || black*20 > (11+k)*total; k++)
result += QrCode.PENALTY_N4;
// Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)%
let k: int = Math.ceil(Math.abs(black * 20 - total * 10) / total) - 1;
result += k * QrCode.PENALTY_N4;
return result;
}