Added integer constants for QR Code min/max version numbers, made use of new constants in library and example applications, in all language versions except C.

pull/20/head
Project Nayuki 7 years ago
parent 6f5eccf2fc
commit 5a5626edb2

@ -73,7 +73,7 @@ QrCode QrCode::encodeBinary(const vector<uint8_t> &data, Ecc ecl) {
QrCode QrCode::encodeSegments(const vector<QrSegment> &segs, Ecc ecl,
int minVersion, int maxVersion, int mask, bool boostEcl) {
if (!(1 <= minVersion && minVersion <= maxVersion && maxVersion <= 40) || mask < -1 || mask > 7)
if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
throw "Invalid value";
// Find the minimal version number to use
@ -122,13 +122,13 @@ QrCode QrCode::encodeSegments(const vector<QrSegment> &segs, Ecc ecl,
QrCode::QrCode(int ver, Ecc ecl, const vector<uint8_t> &dataCodewords, int mask) :
// Initialize fields
version(ver),
size(1 <= ver && ver <= 40 ? ver * 4 + 17 : -1), // Avoid signed overflow undefined behavior
size(MIN_VERSION <= ver && ver <= MAX_VERSION ? ver * 4 + 17 : -1), // Avoid signed overflow undefined behavior
errorCorrectionLevel(ecl),
modules(size, vector<bool>(size)), // Entirely white grid
isFunction(size, vector<bool>(size)) {
// Check arguments
if (ver < 1 || ver > 40 || mask < -1 || mask > 7)
if (ver < MIN_VERSION || ver > MAX_VERSION || mask < -1 || mask > 7)
throw "Value out of range";
// Draw function patterns, draw all codewords, do masking
@ -497,7 +497,7 @@ long QrCode::getPenaltyScore() const {
vector<int> QrCode::getAlignmentPatternPositions(int ver) {
if (ver < 1 || ver > 40)
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw "Version number out of range";
else if (ver == 1)
return vector<int>();
@ -520,7 +520,7 @@ vector<int> QrCode::getAlignmentPatternPositions(int ver) {
int QrCode::getNumRawDataModules(int ver) {
if (ver < 1 || ver > 40)
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw "Version number out of range";
int result = (16 * ver + 128) * ver + 64;
if (ver >= 2) {
@ -534,7 +534,7 @@ int QrCode::getNumRawDataModules(int ver) {
int QrCode::getNumDataCodewords(int ver, Ecc ecl) {
if (ver < 1 || ver > 40)
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw "Version number out of range";
return getNumRawDataModules(ver) / 8
- ECC_CODEWORDS_PER_BLOCK[ecl.getOrdinal()][ver]

@ -97,6 +97,13 @@ class QrCode final {
/*---- Public constants ----*/
public: static constexpr int MIN_VERSION = 1;
public: static constexpr int MAX_VERSION = 40;
/*---- Instance fields ----*/
// Immutable scalar parameters

@ -164,8 +164,8 @@ static void doSegmentDemo() {
static void doMaskDemo() {
// Project Nayuki URL
std::vector<QrSegment> segs0 = QrSegment::makeSegments("https://www.nayuki.io/");
printQr(QrCode::encodeSegments(segs0, QrCode::Ecc::HIGH, 1, 40, -1, true)); // Automatic mask
printQr(QrCode::encodeSegments(segs0, QrCode::Ecc::HIGH, 1, 40, 3, true)); // Force mask 3
printQr(QrCode::encodeSegments(segs0, QrCode::Ecc::HIGH, QrCode::MIN_VERSION, QrCode::MAX_VERSION, -1, true)); // Automatic mask
printQr(QrCode::encodeSegments(segs0, QrCode::Ecc::HIGH, QrCode::MIN_VERSION, QrCode::MAX_VERSION, 3, true)); // Force mask 3
// Chinese text as UTF-8
std::vector<QrSegment> segs1 = QrSegment::makeSegments(
@ -176,10 +176,10 @@ static void doMaskDemo() {
"\xE3\x80\x81\xE5\x85\xAC\xE9\x96\x8B\xE7\xB7\xA8\xE8\xBC\xAF\xE4\xB8\x94\xE5\xA4"
"\x9A\xE8\xAA\x9E\xE8\xA8\x80\xE7\x9A\x84\xE7\xB6\xB2\xE8\xB7\xAF\xE7\x99\xBE\xE7"
"\xA7\x91\xE5\x85\xA8\xE6\x9B\xB8\xE5\x8D\x94\xE4\xBD\x9C\xE8\xA8\x88\xE7\x95\xAB");
printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, 1, 40, 0, true)); // Force mask 0
printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, 1, 40, 1, true)); // Force mask 1
printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, 1, 40, 5, true)); // Force mask 5
printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, 1, 40, 7, true)); // Force mask 7
printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, QrCode::MIN_VERSION, QrCode::MAX_VERSION, 0, true)); // Force mask 0
printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, QrCode::MIN_VERSION, QrCode::MAX_VERSION, 1, true)); // Force mask 1
printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, QrCode::MIN_VERSION, QrCode::MAX_VERSION, 5, true)); // Force mask 5
printQr(QrCode::encodeSegments(segs1, QrCode::Ecc::MEDIUM, QrCode::MIN_VERSION, QrCode::MAX_VERSION, 7, true)); // Force mask 7
}

@ -91,7 +91,7 @@ public final class QrCode {
* @throws IllegalArgumentException if the data is too long to fit in the largest version QR Code at the ECL
*/
public static QrCode encodeSegments(List<QrSegment> segs, Ecc ecl) {
return encodeSegments(segs, ecl, 1, 40, -1, true);
return encodeSegments(segs, ecl, MIN_VERSION, MAX_VERSION, -1, true);
}
@ -115,7 +115,7 @@ public final class QrCode {
public static QrCode encodeSegments(List<QrSegment> segs, Ecc ecl, int minVersion, int maxVersion, int mask, boolean boostEcl) {
Objects.requireNonNull(segs);
Objects.requireNonNull(ecl);
if (!(1 <= minVersion && minVersion <= maxVersion && maxVersion <= 40) || mask < -1 || mask > 7)
if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
throw new IllegalArgumentException("Invalid value");
// Find the minimal version number to use
@ -162,6 +162,13 @@ public final class QrCode {
/*---- Public constants ----*/
public static final int MIN_VERSION = 1;
public static final int MAX_VERSION = 40;
/*---- Instance fields ----*/
// Public immutable scalar parameters
@ -203,7 +210,7 @@ public final class QrCode {
public QrCode(int ver, Ecc ecl, byte[] dataCodewords, int mask) {
// Check arguments
Objects.requireNonNull(ecl);
if (ver < 1 || ver > 40 || mask < -1 || mask > 7)
if (ver < MIN_VERSION || ver > MAX_VERSION || mask < -1 || mask > 7)
throw new IllegalArgumentException("Value out of range");
Objects.requireNonNull(dataCodewords);
@ -630,7 +637,7 @@ public final class QrCode {
// used on both the x and y axes. Each value in the resulting array is in the range [0, 177).
// This stateless pure function could be implemented as table of 40 variable-length lists of unsigned bytes.
private static int[] getAlignmentPatternPositions(int ver) {
if (ver < 1 || ver > 40)
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw new IllegalArgumentException("Version number out of range");
else if (ver == 1)
return new int[]{};
@ -656,7 +663,7 @@ public final class QrCode {
// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
private static int getNumRawDataModules(int ver) {
if (ver < 1 || ver > 40)
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw new IllegalArgumentException("Version number out of range");
int size = ver * 4 + 17;
@ -681,7 +688,7 @@ public final class QrCode {
// QR Code of the given version number and error correction level, with remainder bits discarded.
// This stateless pure function could be implemented as a (40*4)-cell lookup table.
static int getNumDataCodewords(int ver, Ecc ecl) {
if (ver < 1 || ver > 40)
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw new IllegalArgumentException("Version number out of range");
return getNumRawDataModules(ver) / 8
- ECC_CODEWORDS_PER_BLOCK[ecl.ordinal()][ver]

@ -161,20 +161,20 @@ public final class QrCodeGeneratorDemo {
// Project Nayuki URL
segs = QrSegment.makeSegments("https://www.nayuki.io/");
qr = QrCode.encodeSegments(segs, QrCode.Ecc.HIGH, 1, 40, -1, true); // Automatic mask
qr = QrCode.encodeSegments(segs, QrCode.Ecc.HIGH, QrCode.MIN_VERSION, QrCode.MAX_VERSION, -1, true); // Automatic mask
writePng(qr.toImage(8, 6), "project-nayuki-automask-QR.png");
qr = QrCode.encodeSegments(segs, QrCode.Ecc.HIGH, 1, 40, 3, true); // Force mask 3
qr = QrCode.encodeSegments(segs, QrCode.Ecc.HIGH, QrCode.MIN_VERSION, QrCode.MAX_VERSION, 3, true); // Force mask 3
writePng(qr.toImage(8, 6), "project-nayuki-mask3-QR.png");
// Chinese text as UTF-8
segs = QrSegment.makeSegments("維基百科Wikipedia聆聽i/ˌwɪkᵻˈpiːdi.ə/)是一個自由內容、公開編輯且多語言的網路百科全書協作計畫");
qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, 1, 40, 0, true); // Force mask 0
qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, QrCode.MIN_VERSION, QrCode.MAX_VERSION, 0, true); // Force mask 0
writePng(qr.toImage(10, 3), "unicode-mask0-QR.png");
qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, 1, 40, 1, true); // Force mask 1
qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, QrCode.MIN_VERSION, QrCode.MAX_VERSION, 1, true); // Force mask 1
writePng(qr.toImage(10, 3), "unicode-mask1-QR.png");
qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, 1, 40, 5, true); // Force mask 5
qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, QrCode.MIN_VERSION, QrCode.MAX_VERSION, 5, true); // Force mask 5
writePng(qr.toImage(10, 3), "unicode-mask5-QR.png");
qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, 1, 40, 7, true); // Force mask 7
qr = QrCode.encodeSegments(segs, QrCode.Ecc.MEDIUM, QrCode.MIN_VERSION, QrCode.MAX_VERSION, 7, true); // Force mask 7
writePng(qr.toImage(10, 3), "unicode-mask7-QR.png");
}

@ -67,7 +67,7 @@ public final class QrCodeGeneratorWorker {
int mask = input.nextInt();
int boostEcl = input.nextInt();
if (!(0 <= errCorLvl && errCorLvl <= 3) || !(-1 <= mask && mask <= 7) || (boostEcl >>> 1) != 0
|| !(1 <= minVersion && minVersion <= maxVersion && maxVersion <= 40))
|| !(QrCode.MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= QrCode.MAX_VERSION))
throw new RuntimeException();
// Make segments for encoding

@ -139,8 +139,8 @@ function handleVersionMinMax(which) {
var maxElem = document.getElementById("version-max-input");
var minVal = parseInt(minElem.value, 10);
var maxVal = parseInt(maxElem.value, 10);
minVal = Math.max(Math.min(minVal, 40), 1);
maxVal = Math.max(Math.min(maxVal, 40), 1);
minVal = Math.max(Math.min(minVal, qrcodegen.QrCode.MAX_VERSION), qrcodegen.QrCode.MIN_VERSION);
maxVal = Math.max(Math.min(maxVal, qrcodegen.QrCode.MAX_VERSION), qrcodegen.QrCode.MIN_VERSION);
if (which == "min" && minVal > maxVal)
maxVal = minVal;
else if (which == "max" && maxVal < minVal)

@ -31,6 +31,7 @@
* - Function encodeBinary(list<byte> data, QrCode.Ecc ecl) -> QrCode
* - Function encodeSegments(list<QrSegment> segs, QrCode.Ecc ecl,
* int minVersion=1, int maxVersion=40, mask=-1, boostEcl=true) -> QrCode
* - Constants int MIN_VERSION, MAX_VERSION
* - Constructor QrCode(list<int> datacodewords, int mask, int version, QrCode.Ecc ecl)
* - Fields int version, size, mask
* - Field QrCode.Ecc errorCorrectionLevel
@ -74,7 +75,7 @@ var qrcodegen = new function() {
// Check arguments and handle simple scalar fields
if (mask < -1 || mask > 7)
throw "Mask value out of range";
if (version < 1 || version > 40)
if (version < MIN_VERSION || version > MAX_VERSION)
throw "Version value out of range";
var size = version * 4 + 17;
@ -536,11 +537,11 @@ var qrcodegen = new function() {
* This function is considered to be lower level than simply encoding text or binary data.
*/
this.QrCode.encodeSegments = function(segs, ecl, minVersion, maxVersion, mask, boostEcl) {
if (minVersion == undefined) minVersion = 1;
if (maxVersion == undefined) maxVersion = 40;
if (minVersion == undefined) minVersion = MIN_VERSION;
if (maxVersion == undefined) maxVersion = MAX_VERSION;
if (mask == undefined) mask = -1;
if (boostEcl == undefined) boostEcl = true;
if (!(1 <= minVersion && minVersion <= maxVersion && maxVersion <= 40) || mask < -1 || mask > 7)
if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
throw "Invalid value";
// Find the minimal version number to use
@ -586,6 +587,14 @@ var qrcodegen = new function() {
};
/*---- Public constants for QrCode ----*/
var MIN_VERSION = 1;
var MAX_VERSION = 40;
Object.defineProperty(this.QrCode, "MIN_VERSION", {value:MIN_VERSION});
Object.defineProperty(this.QrCode, "MAX_VERSION", {value:MAX_VERSION});
/*---- Private static helper functions QrCode ----*/
var QrCode = {}; // Private object to assign properties to. Not the same object as 'this.QrCode'.
@ -595,7 +604,7 @@ var qrcodegen = new function() {
// used on both the x and y axes. Each value in the resulting sequence is in the range [0, 177).
// This stateless pure function could be implemented as table of 40 variable-length lists of integers.
QrCode.getAlignmentPatternPositions = function(ver) {
if (ver < 1 || ver > 40)
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw "Version number out of range";
else if (ver == 1)
return [];
@ -620,7 +629,7 @@ var qrcodegen = new function() {
// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
QrCode.getNumRawDataModules = function(ver) {
if (ver < 1 || ver > 40)
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw "Version number out of range";
var result = (16 * ver + 128) * ver + 64;
if (ver >= 2) {
@ -637,7 +646,7 @@ var qrcodegen = new function() {
// QR Code of the given version number and error correction level, with remainder bits discarded.
// This stateless pure function could be implemented as a (40*4)-cell lookup table.
QrCode.getNumDataCodewords = function(ver, ecl) {
if (ver < 1 || ver > 40)
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw "Version number out of range";
return Math.floor(QrCode.getNumRawDataModules(ver) / 8) -
QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] *
@ -816,7 +825,7 @@ var qrcodegen = new function() {
// Package-private helper function.
this.QrSegment.getTotalBits = function(segs, version) {
if (version < 1 || version > 40)
if (version < MIN_VERSION || version > MAX_VERSION)
throw "Version number out of range";
var result = 0;
for (var i = 0; i < segs.length; i++) {

@ -31,6 +31,7 @@ This module "qrcodegen", public members:
- Function encode_binary(bytes data, QrCode.Ecc ecl) -> QrCode
- Function encode_segments(list<QrSegment> segs, QrCode.Ecc ecl,
int minversion=1, int maxversion=40, mask=-1, boostecl=true) -> QrCode
- Constants int MIN_VERSION, MAX_VERSION
- Constructor QrCode(bytes datacodewords, int mask, int version, QrCode.Ecc ecl)
- Method get_version() -> int
- Method get_size() -> int
@ -95,7 +96,7 @@ class QrCode(object):
between modes (such as alphanumeric and binary) to encode text more efficiently.
This function is considered to be lower level than simply encoding text or binary data."""
if not (1 <= minversion <= maxversion <= 40) or not (-1 <= mask <= 7):
if not (QrCode.MIN_VERSION <= minversion <= maxversion <= QrCode.MAX_VERSION) or not (-1 <= mask <= 7):
raise ValueError("Invalid value")
# Find the minimal version number to use
@ -137,6 +138,12 @@ class QrCode(object):
return QrCode(bb.get_bytes(), mask, version, ecl)
# ---- Public constants ----
MIN_VERSION = 1
MAX_VERSION = 40
# ---- Constructor ----
def __init__(self, datacodewords, mask, version, errcorlvl):
@ -147,7 +154,7 @@ class QrCode(object):
# Check arguments and handle simple scalar fields
if not (-1 <= mask <= 7):
raise ValueError("Mask value out of range")
if not (1 <= version <= 40):
if not (QrCode.MIN_VERSION <= version <= QrCode.MAX_VERSION):
raise ValueError("Version value out of range")
if not isinstance(errcorlvl, QrCode.Ecc):
raise TypeError("QrCode.Ecc expected")
@ -480,7 +487,7 @@ class QrCode(object):
"""Returns a sequence of positions of the alignment patterns in ascending order. These positions are
used on both the x and y axes. Each value in the resulting sequence is in the range [0, 177).
This stateless pure function could be implemented as table of 40 variable-length lists of integers."""
if not (1 <= ver <= 40):
if not (QrCode.MIN_VERSION <= ver <= QrCode.MAX_VERSION):
raise ValueError("Version number out of range")
elif ver == 1:
return []
@ -504,7 +511,7 @@ class QrCode(object):
"""Returns the number of data bits that can be stored in a QR Code of the given version number, after
all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table."""
if not (1 <= ver <= 40):
if not (QrCode.MIN_VERSION <= ver <= QrCode.MAX_VERSION):
raise ValueError("Version number out of range")
result = (16 * ver + 128) * ver + 64
if ver >= 2:
@ -520,7 +527,7 @@ class QrCode(object):
"""Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
QR Code of the given version number and error correction level, with remainder bits discarded.
This stateless pure function could be implemented as a (40*4)-cell lookup table."""
if not (1 <= ver <= 40):
if not (QrCode.MIN_VERSION <= ver <= QrCode.MAX_VERSION):
raise ValueError("Version number out of range")
return QrCode._get_num_raw_data_modules(ver) // 8 \
- QrCode._ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] \
@ -698,7 +705,7 @@ class QrSegment(object):
# Package-private helper function.
@staticmethod
def get_total_bits(segs, version):
if not (1 <= version <= 40):
if not (QrCode.MIN_VERSION <= version <= QrCode.MAX_VERSION):
raise ValueError("Version number out of range")
result = 0
for seg in segs:

@ -28,6 +28,8 @@ extern crate qrcodegen;
use qrcodegen::QrCode;
use qrcodegen::QrCodeEcc;
use qrcodegen::QrSegment;
use qrcodegen::QrCode_MAX_VERSION;
use qrcodegen::QrCode_MIN_VERSION;
// The main application program.
@ -140,20 +142,20 @@ fn do_segment_demo() {
fn do_mask_demo() {
// Project Nayuki URL
let segs = QrSegment::make_segments(&to_chars("https://www.nayuki.io/"));
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::High, 1, 40, None, true).unwrap(); // Automatic mask
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::High, QrCode_MIN_VERSION, QrCode_MAX_VERSION, None, true).unwrap(); // Automatic mask
print_qr(&qr);
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::High, 1, 40, Some(3), true).unwrap(); // Force mask 3
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::High, QrCode_MIN_VERSION, QrCode_MAX_VERSION, Some(3), true).unwrap(); // Force mask 3
print_qr(&qr);
// Chinese text as UTF-8
let segs = QrSegment::make_segments(&to_chars("維基百科Wikipedia聆聽i/ˌwɪkᵻˈpiːdi.ə/)是一個自由內容、公開編輯且多語言的網路百科全書協作計畫"));
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, 1, 40, Some(0), true).unwrap(); // Force mask 0
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, QrCode_MIN_VERSION, QrCode_MAX_VERSION, Some(0), true).unwrap(); // Force mask 0
print_qr(&qr);
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, 1, 40, Some(1), true).unwrap(); // Force mask 1
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, QrCode_MIN_VERSION, QrCode_MAX_VERSION, Some(1), true).unwrap(); // Force mask 1
print_qr(&qr);
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, 1, 40, Some(5), true).unwrap(); // Force mask 5
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, QrCode_MIN_VERSION, QrCode_MAX_VERSION, Some(5), true).unwrap(); // Force mask 5
print_qr(&qr);
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, 1, 40, Some(7), true).unwrap(); // Force mask 7
let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, QrCode_MIN_VERSION, QrCode_MAX_VERSION, Some(7), true).unwrap(); // Force mask 7
print_qr(&qr);
}

@ -57,7 +57,9 @@ fn main() {
let mask = read_int();
let boostecl = read_int();
assert!(0 <= errcorlvl && errcorlvl <= 3);
assert!(1 <= minversion && minversion <= maxversion && maxversion <= 40);
assert!((qrcodegen::QrCode_MIN_VERSION as i16) <= minversion
&& minversion <= maxversion
&& maxversion <= (qrcodegen::QrCode_MAX_VERSION as i16));
assert!(-1 <= mask && mask <= 7);
assert!(boostecl >> 1 == 0);

@ -89,7 +89,7 @@ impl QrCode {
// This function is considered to be lower level than simply encoding text or binary data.
// Returns a wrapped QrCode if successful, or None if the data is too long to fit in any version at the given ECC level.
pub fn encode_segments(segs: &[QrSegment], ecl: QrCodeEcc) -> Option<QrCode> {
QrCode::encode_segments_advanced(segs, ecl, 1, 40, None, true)
QrCode::encode_segments_advanced(segs, ecl, QrCode_MIN_VERSION, QrCode_MAX_VERSION, None, true)
}
@ -102,7 +102,7 @@ impl QrCode {
// in any version in the given range at the given ECC level.
pub fn encode_segments_advanced(segs: &[QrSegment], mut ecl: QrCodeEcc,
minversion: u8, maxversion: u8, mask: Option<u8>, boostecl: bool) -> Option<QrCode> {
assert!(1 <= minversion && minversion <= maxversion && maxversion <= 40, "Invalid value");
assert!(QrCode_MIN_VERSION <= minversion && minversion <= maxversion && maxversion <= QrCode_MAX_VERSION, "Invalid value");
assert!(mask == None || mask.unwrap() <= 7, "Invalid value");
// Find the minimal version number to use
@ -170,7 +170,7 @@ impl QrCode {
// should not be invoked directly by the user. To go one level up, see the encode_segments() function.
pub fn encode_codewords(ver: u8, ecl: QrCodeEcc, datacodewords: &[u8], mask: Option<u8>) -> QrCode {
// Check arguments
assert!(1 <= ver && ver <= 40, "Value out of range");
assert!(QrCode_MIN_VERSION <= ver && ver <= QrCode_MAX_VERSION, "Value out of range");
assert!(mask == None || mask.unwrap() <= 7, "Value out of range");
// Initialize fields
@ -622,7 +622,7 @@ impl QrCode {
// used on both the x and y axes. Each value in the resulting list is in the range [0, 177).
// This stateless pure function could be implemented as table of 40 variable-length lists of unsigned bytes.
fn get_alignment_pattern_positions(ver: u8) -> Vec<i32> {
assert!(1 <= ver && ver <= 40, "Version number out of range");
assert!(QrCode_MIN_VERSION <= ver && ver <= QrCode_MAX_VERSION, "Version number out of range");
if ver == 1 {
vec![]
} else {
@ -648,7 +648,7 @@ impl QrCode {
// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
fn get_num_raw_data_modules(ver: u8) -> usize {
assert!(1 <= ver && ver <= 40, "Version number out of range");
assert!(QrCode_MIN_VERSION <= ver && ver <= QrCode_MAX_VERSION, "Version number out of range");
let mut result: usize = (16 * (ver as usize) + 128) * (ver as usize) + 64;
if ver >= 2 {
let numalign: usize = (ver as usize) / 7 + 2;
@ -665,7 +665,7 @@ impl QrCode {
// QR Code of the given version number and error correction level, with remainder bits discarded.
// This stateless pure function could be implemented as a (40*4)-cell lookup table.
fn get_num_data_codewords(ver: u8, ecl: QrCodeEcc) -> usize {
assert!(1 <= ver && ver <= 40, "Version number out of range");
assert!(QrCode_MIN_VERSION <= ver && ver <= QrCode_MAX_VERSION, "Version number out of range");
QrCode::get_num_raw_data_modules(ver) / 8
- QrCode::table_get(&ECC_CODEWORDS_PER_BLOCK, ver, ecl)
* QrCode::table_get(&NUM_ERROR_CORRECTION_BLOCKS, ver, ecl)
@ -674,13 +674,19 @@ impl QrCode {
// Returns an entry from the given table based on the given values.
fn table_get(table: &'static [[i8; 41]; 4], ver: u8, ecl: QrCodeEcc) -> usize {
assert!(1 <= ver && ver <= 40, "Version number out of range");
assert!(QrCode_MIN_VERSION <= ver && ver <= QrCode_MAX_VERSION, "Version number out of range");
table[ecl.ordinal()][ver as usize] as usize
}
}
/*---- Public constants ----*/
pub const QrCode_MIN_VERSION: u8 = 1;
pub const QrCode_MAX_VERSION: u8 = 40;
/*---- Private tables of constants ----*/
// For use in get_penalty_score(), when evaluating which mask is best.
@ -978,7 +984,7 @@ impl QrSegment {
// Package-private helper function.
fn get_total_bits(segs: &[QrSegment], version: u8) -> Option<usize> {
assert!(1 <= version && version <= 40, "Version number out of range");
assert!(QrCode_MIN_VERSION <= version && version <= QrCode_MAX_VERSION, "Version number out of range");
let mut result: usize = 0;
for seg in segs {
let ccbits = seg.mode.num_char_count_bits(version);

Loading…
Cancel
Save