In C++ version, made locals const where appropriate and used C++11 auto where type was already explicit via a static_cast.

pull/91/head
Neil Haran 5 years ago
parent 08ac806145
commit 9adf9f027a

@ -80,7 +80,7 @@ QrSegment QrSegment::makeNumeric(const char *digits) {
int accumCount = 0; int accumCount = 0;
int charCount = 0; int charCount = 0;
for (; *digits != '\0'; digits++, charCount++) { for (; *digits != '\0'; digits++, charCount++) {
char c = *digits; const char c = *digits;
if (c < '0' || c > '9') if (c < '0' || c > '9')
throw std::domain_error("String contains non-numeric characters"); throw std::domain_error("String contains non-numeric characters");
accumData = accumData * 10 + (c - '0'); accumData = accumData * 10 + (c - '0');
@ -177,7 +177,7 @@ QrSegment::QrSegment(Mode md, int numCh, std::vector<bool> &&dt) :
int QrSegment::getTotalBits(const vector<QrSegment> &segs, int version) { int QrSegment::getTotalBits(const vector<QrSegment> &segs, int version) {
int result = 0; int result = 0;
for (const QrSegment &seg : segs) { for (const QrSegment &seg : segs) {
int ccbits = seg.mode.numCharCountBits(version); const int ccbits = seg.mode.numCharCountBits(version);
if (seg.numChars >= (1L << ccbits)) if (seg.numChars >= (1L << ccbits))
return -1; // The segment's length doesn't fit the field's bit width return -1; // The segment's length doesn't fit the field's bit width
if (4 + ccbits > INT_MAX - result) if (4 + ccbits > INT_MAX - result)
@ -202,7 +202,7 @@ bool QrSegment::isAlphanumeric(const char *text) {
bool QrSegment::isNumeric(const char *text) { bool QrSegment::isNumeric(const char *text) {
for (; *text != '\0'; text++) { for (; *text != '\0'; text++) {
char c = *text; const char c = *text;
if (c < '0' || c > '9') if (c < '0' || c > '9')
return false; return false;
} }
@ -241,13 +241,13 @@ int QrCode::getFormatBits(Ecc ecl) {
QrCode QrCode::encodeText(const char *text, Ecc ecl) { QrCode QrCode::encodeText(const char *text, Ecc ecl) {
vector<QrSegment> segs = QrSegment::makeSegments(text); const vector<QrSegment> segs = QrSegment::makeSegments(text);
return encodeSegments(segs, ecl); return encodeSegments(segs, ecl);
} }
QrCode QrCode::encodeBinary(const vector<uint8_t> &data, Ecc ecl) { QrCode QrCode::encodeBinary(const vector<uint8_t> &data, Ecc ecl) {
vector<QrSegment> segs{QrSegment::makeBytes(data)}; const vector<QrSegment> segs{QrSegment::makeBytes(data)};
return encodeSegments(segs, ecl); return encodeSegments(segs, ecl);
} }
@ -260,7 +260,7 @@ QrCode QrCode::encodeSegments(const vector<QrSegment> &segs, Ecc ecl,
// Find the minimal version number to use // Find the minimal version number to use
int version, dataUsedBits; int version, dataUsedBits;
for (version = minVersion; ; version++) { for (version = minVersion; ; version++) {
int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available const int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available
dataUsedBits = QrSegment::getTotalBits(segs, version); dataUsedBits = QrSegment::getTotalBits(segs, version);
if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits) if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits)
break; // This version number is found to be suitable break; // This version number is found to be suitable
@ -295,7 +295,7 @@ QrCode QrCode::encodeSegments(const vector<QrSegment> &segs, Ecc ecl,
throw std::logic_error("Assertion error"); throw std::logic_error("Assertion error");
// Add terminator and pad up to a byte if applicable // Add terminator and pad up to a byte if applicable
size_t dataCapacityBits = static_cast<size_t>(getNumDataCodewords(version, ecl)) * 8; const auto dataCapacityBits = static_cast<size_t>(getNumDataCodewords(version, ecl)) * 8;
if (bb.size() > dataCapacityBits) if (bb.size() > dataCapacityBits)
throw std::logic_error("Assertion error"); throw std::logic_error("Assertion error");
bb.appendBits(0, std::min(4, static_cast<int>(dataCapacityBits - bb.size()))); bb.appendBits(0, std::min(4, static_cast<int>(dataCapacityBits - bb.size())));
@ -326,7 +326,7 @@ QrCode::QrCode(int ver, Ecc ecl, const vector<uint8_t> &dataCodewords, int msk)
if (msk < -1 || msk > 7) if (msk < -1 || msk > 7)
throw std::domain_error("Mask value out of range"); throw std::domain_error("Mask value out of range");
size = ver * 4 + 17; size = ver * 4 + 17;
size_t sz = static_cast<size_t>(size); const auto sz = static_cast<size_t>(size);
modules = vector<vector<bool> >(sz, vector<bool>(sz)); // Initially all white modules = vector<vector<bool> >(sz, vector<bool>(sz)); // Initially all white
isFunction = vector<vector<bool> >(sz, vector<bool>(sz)); isFunction = vector<vector<bool> >(sz, vector<bool>(sz));
@ -341,7 +341,7 @@ QrCode::QrCode(int ver, Ecc ecl, const vector<uint8_t> &dataCodewords, int msk)
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
applyMask(i); applyMask(i);
drawFormatBits(i); drawFormatBits(i);
long penalty = getPenaltyScore(); const long penalty = getPenaltyScore();
if (penalty < minPenalty) { if (penalty < minPenalty) {
msk = i; msk = i;
minPenalty = penalty; minPenalty = penalty;
@ -427,7 +427,7 @@ void QrCode::drawFunctionPatterns() {
// Draw numerous alignment patterns // Draw numerous alignment patterns
const vector<int> alignPatPos = getAlignmentPatternPositions(); const vector<int> alignPatPos = getAlignmentPatternPositions();
size_t numAlign = alignPatPos.size(); const size_t numAlign = alignPatPos.size();
for (size_t i = 0; i < numAlign; i++) { for (size_t i = 0; i < numAlign; i++) {
for (size_t j = 0; j < numAlign; j++) { for (size_t j = 0; j < numAlign; j++) {
// Don't draw on the three finder corners // Don't draw on the three finder corners
@ -444,11 +444,11 @@ void QrCode::drawFunctionPatterns() {
void QrCode::drawFormatBits(int msk) { void QrCode::drawFormatBits(int msk) {
// Calculate error correction code and pack bits // Calculate error correction code and pack bits
int data = getFormatBits(errorCorrectionLevel) << 3 | msk; // errCorrLvl is uint2, msk is uint3 const int data = getFormatBits(errorCorrectionLevel) << 3 | msk; // errCorrLvl is uint2, msk is uint3
int rem = data; int rem = data;
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
rem = (rem << 1) ^ ((rem >> 9) * 0x537); rem = (rem << 1) ^ ((rem >> 9) * 0x537);
int bits = (data << 10 | rem) ^ 0x5412; // uint15 const int bits = (data << 10 | rem) ^ 0x5412; // uint15
if (bits >> 15 != 0) if (bits >> 15 != 0)
throw std::logic_error("Assertion error"); throw std::logic_error("Assertion error");
@ -478,15 +478,15 @@ void QrCode::drawVersion() {
int rem = version; // version is uint6, in the range [7, 40] int rem = version; // version is uint6, in the range [7, 40]
for (int i = 0; i < 12; i++) for (int i = 0; i < 12; i++)
rem = (rem << 1) ^ ((rem >> 11) * 0x1F25); rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
long bits = static_cast<long>(version) << 12 | rem; // uint18 const auto bits = static_cast<long>(version) << 12 | rem; // uint18
if (bits >> 18 != 0) if (bits >> 18 != 0)
throw std::logic_error("Assertion error"); throw std::logic_error("Assertion error");
// Draw two copies // Draw two copies
for (int i = 0; i < 18; i++) { for (int i = 0; i < 18; i++) {
bool bit = getBit(bits, i); const bool bit = getBit(bits, i);
int a = size - 11 + i % 3; const int a = size - 11 + i % 3;
int b = i / 3; const int b = i / 3;
setFunctionModule(a, b, bit); setFunctionModule(a, b, bit);
setFunctionModule(b, a, bit); setFunctionModule(b, a, bit);
} }
@ -496,8 +496,8 @@ void QrCode::drawVersion() {
void QrCode::drawFinderPattern(int x, int y) { void QrCode::drawFinderPattern(int x, int y) {
for (int dy = -4; dy <= 4; dy++) { for (int dy = -4; dy <= 4; dy++) {
for (int dx = -4; dx <= 4; dx++) { for (int dx = -4; dx <= 4; dx++) {
int dist = std::max(std::abs(dx), std::abs(dy)); // Chebyshev/infinity norm const int dist = std::max(std::abs(dx), std::abs(dy)); // Chebyshev/infinity norm
int xx = x + dx, yy = y + dy; const int xx = x + dx, yy = y + dy;
if (0 <= xx && xx < size && 0 <= yy && yy < size) if (0 <= xx && xx < size && 0 <= yy && yy < size)
setFunctionModule(xx, yy, dist != 2 && dist != 4); setFunctionModule(xx, yy, dist != 2 && dist != 4);
} }
@ -514,8 +514,8 @@ void QrCode::drawAlignmentPattern(int x, int y) {
void QrCode::setFunctionModule(int x, int y, bool isBlack) { void QrCode::setFunctionModule(int x, int y, bool isBlack) {
size_t ux = static_cast<size_t>(x); const auto ux = static_cast<size_t>(x);
size_t uy = static_cast<size_t>(y); const auto uy = static_cast<size_t>(y);
modules .at(uy).at(ux) = isBlack; modules .at(uy).at(ux) = isBlack;
isFunction.at(uy).at(ux) = true; isFunction.at(uy).at(ux) = true;
} }
@ -531,11 +531,11 @@ vector<uint8_t> QrCode::addEccAndInterleave(const vector<uint8_t> &data) const {
throw std::invalid_argument("Invalid argument"); throw std::invalid_argument("Invalid argument");
// Calculate parameter numbers // Calculate parameter numbers
int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[static_cast<int>(errorCorrectionLevel)][version]; const int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[static_cast<int>(errorCorrectionLevel)][version];
int blockEccLen = ECC_CODEWORDS_PER_BLOCK [static_cast<int>(errorCorrectionLevel)][version]; const int blockEccLen = ECC_CODEWORDS_PER_BLOCK [static_cast<int>(errorCorrectionLevel)][version];
int rawCodewords = getNumRawDataModules(version) / 8; const int rawCodewords = getNumRawDataModules(version) / 8;
int numShortBlocks = numBlocks - rawCodewords % numBlocks; const int numShortBlocks = numBlocks - rawCodewords % numBlocks;
int shortBlockLen = rawCodewords / numBlocks; const int shortBlockLen = rawCodewords / numBlocks;
// Split data into blocks and append ECC to each block // Split data into blocks and append ECC to each block
vector<vector<uint8_t> > blocks; vector<vector<uint8_t> > blocks;
@ -576,9 +576,9 @@ void QrCode::drawCodewords(const vector<uint8_t> &data) {
right = 5; right = 5;
for (int vert = 0; vert < size; vert++) { // Vertical counter for (int vert = 0; vert < size; vert++) { // Vertical counter
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
size_t x = static_cast<size_t>(right - j); // Actual x coordinate const auto x = static_cast<size_t>(right - j); // Actual x coordinate
bool upward = ((right + 1) & 2) == 0; const bool upward = ((right + 1) & 2) == 0;
size_t y = static_cast<size_t>(upward ? size - 1 - vert : vert); // Actual y coordinate const auto y = static_cast<size_t>(upward ? size - 1 - vert : vert); // Actual y coordinate
if (!isFunction.at(y).at(x) && i < data.size() * 8) { if (!isFunction.at(y).at(x) && i < data.size() * 8) {
modules.at(y).at(x) = getBit(data.at(i >> 3), 7 - static_cast<int>(i & 7)); modules.at(y).at(x) = getBit(data.at(i >> 3), 7 - static_cast<int>(i & 7));
i++; i++;
@ -596,7 +596,7 @@ void QrCode::drawCodewords(const vector<uint8_t> &data) {
void QrCode::applyMask(int msk) { void QrCode::applyMask(int msk) {
if (msk < 0 || msk > 7) if (msk < 0 || msk > 7)
throw std::domain_error("Mask value out of range"); throw std::domain_error("Mask value out of range");
size_t sz = static_cast<size_t>(size); const auto sz = static_cast<size_t>(size);
for (size_t y = 0; y < sz; y++) { for (size_t y = 0; y < sz; y++) {
for (size_t x = 0; x < sz; x++) { for (size_t x = 0; x < sz; x++) {
bool invert; bool invert;
@ -668,7 +668,7 @@ long QrCode::getPenaltyScore() const {
// 2*2 blocks of modules having same color // 2*2 blocks of modules having same color
for (int y = 0; y < size - 1; y++) { for (int y = 0; y < size - 1; y++) {
for (int x = 0; x < size - 1; x++) { for (int x = 0; x < size - 1; x++) {
bool color = module(x, y); const bool color = module(x, y);
if ( color == module(x + 1, y) && if ( color == module(x + 1, y) &&
color == module(x, y + 1) && color == module(x, y + 1) &&
color == module(x + 1, y + 1)) color == module(x + 1, y + 1))
@ -684,9 +684,9 @@ long QrCode::getPenaltyScore() const {
black++; black++;
} }
} }
int total = size * size; // Note that size is odd, so black/total != 1/2 const int total = size * size; // Note that size is odd, so black/total != 1/2
// Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)% // 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; const auto k = static_cast<int>((std::abs(black * 20L - total * 10L) + total - 1) / total) - 1;
result += k * PENALTY_N4; result += k * PENALTY_N4;
return result; return result;
} }
@ -696,8 +696,8 @@ vector<int> QrCode::getAlignmentPatternPositions() const {
if (version == 1) if (version == 1)
return vector<int>(); return vector<int>();
else { else {
int numAlign = version / 7 + 2; const int numAlign = version / 7 + 2;
int step = (version == 32) ? 26 : const int step = (version == 32) ? 26 :
(version*4 + numAlign*2 + 1) / (numAlign*2 - 2) * 2; (version*4 + numAlign*2 + 1) / (numAlign*2 - 2) * 2;
vector<int> result; vector<int> result;
for (int i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step) for (int i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step)
@ -713,7 +713,7 @@ int QrCode::getNumRawDataModules(int ver) {
throw std::domain_error("Version number out of range"); throw std::domain_error("Version number out of range");
int result = (16 * ver + 128) * ver + 64; int result = (16 * ver + 128) * ver + 64;
if (ver >= 2) { if (ver >= 2) {
int numAlign = ver / 7 + 2; const int numAlign = ver / 7 + 2;
result -= (25 * numAlign - 10) * numAlign - 55; result -= (25 * numAlign - 10) * numAlign - 55;
if (ver >= 7) if (ver >= 7)
result -= 36; result -= 36;
@ -731,7 +731,7 @@ int QrCode::getNumDataCodewords(int ver, Ecc ecl) {
} }
vector<uint8_t> QrCode::reedSolomonComputeDivisor(int degree) { vector<uint8_t> QrCode::reedSolomonComputeDivisor(const int degree) {
if (degree < 1 || degree > 255) if (degree < 1 || degree > 255)
throw std::domain_error("Degree out of range"); throw std::domain_error("Degree out of range");
// Polynomial coefficients are stored from highest to lowest power, excluding the leading term which is always 1. // Polynomial coefficients are stored from highest to lowest power, excluding the leading term which is always 1.
@ -759,7 +759,7 @@ vector<uint8_t> QrCode::reedSolomonComputeDivisor(int degree) {
vector<uint8_t> QrCode::reedSolomonComputeRemainder(const vector<uint8_t> &data, const vector<uint8_t> &divisor) { vector<uint8_t> QrCode::reedSolomonComputeRemainder(const vector<uint8_t> &data, const vector<uint8_t> &divisor) {
vector<uint8_t> result(divisor.size()); vector<uint8_t> result(divisor.size());
for (uint8_t b : data) { // Polynomial division for (uint8_t b : data) { // Polynomial division
uint8_t factor = b ^ result.at(0); const uint8_t factor = b ^ result.at(0);
result.erase(result.begin()); result.erase(result.begin());
result.push_back(0); result.push_back(0);
for (size_t i = 0; i < result.size(); i++) for (size_t i = 0; i < result.size(); i++)
@ -783,10 +783,10 @@ uint8_t QrCode::reedSolomonMultiply(uint8_t x, uint8_t y) {
int QrCode::finderPenaltyCountPatterns(const std::array<int,7> &runHistory) const { int QrCode::finderPenaltyCountPatterns(const std::array<int,7> &runHistory) const {
int n = runHistory.at(1); const int n = runHistory.at(1);
if (n > size * 3) if (n > size * 3)
throw std::logic_error("Assertion error"); throw std::logic_error("Assertion error");
bool core = n > 0 && runHistory.at(2) == n && runHistory.at(3) == n * 3 && runHistory.at(4) == n && runHistory.at(5) == n; const bool core = n > 0 && runHistory.at(2) == n && runHistory.at(3) == n * 3 && runHistory.at(4) == n && runHistory.at(5) == n;
return (core && runHistory.at(0) >= n * 4 && runHistory.at(6) >= n ? 1 : 0) return (core && runHistory.at(0) >= n * 4 && runHistory.at(6) >= n ? 1 : 0)
+ (core && runHistory.at(6) >= n * 4 && runHistory.at(0) >= n ? 1 : 0); + (core && runHistory.at(6) >= n * 4 && runHistory.at(0) >= n ? 1 : 0);
} }

Loading…
Cancel
Save