From 5a5626edb27ebe230792654a3cc5c6dddde9defc Mon Sep 17 00:00:00 2001 From: Project Nayuki Date: Mon, 23 Oct 2017 04:42:53 +0000 Subject: [PATCH] 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. --- cpp/QrCode.cpp | 12 ++++----- cpp/QrCode.hpp | 7 ++++++ cpp/QrCodeGeneratorDemo.cpp | 12 ++++----- java/io/nayuki/qrcodegen/QrCode.java | 19 +++++++++----- .../nayuki/qrcodegen/QrCodeGeneratorDemo.java | 12 ++++----- .../qrcodegen/QrCodeGeneratorWorker.java | 2 +- javascript/qrcodegen-demo.js | 4 +-- javascript/qrcodegen.js | 25 +++++++++++++------ python/qrcodegen.py | 19 +++++++++----- rust/examples/qrcodegen-demo.rs | 14 ++++++----- rust/examples/qrcodegen-worker.rs | 4 ++- rust/src/lib.rs | 22 ++++++++++------ 12 files changed, 96 insertions(+), 56 deletions(-) diff --git a/cpp/QrCode.cpp b/cpp/QrCode.cpp index ef73d54..2f6e842 100644 --- a/cpp/QrCode.cpp +++ b/cpp/QrCode.cpp @@ -73,7 +73,7 @@ QrCode QrCode::encodeBinary(const vector &data, Ecc ecl) { QrCode QrCode::encodeSegments(const vector &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 &segs, Ecc ecl, QrCode::QrCode(int ver, Ecc ecl, const vector &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(size)), // Entirely white grid isFunction(size, vector(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 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(); @@ -520,7 +520,7 @@ vector 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] diff --git a/cpp/QrCode.hpp b/cpp/QrCode.hpp index 688e70a..fc5e89b 100644 --- a/cpp/QrCode.hpp +++ b/cpp/QrCode.hpp @@ -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 diff --git a/cpp/QrCodeGeneratorDemo.cpp b/cpp/QrCodeGeneratorDemo.cpp index 1107c4d..5c78b51 100644 --- a/cpp/QrCodeGeneratorDemo.cpp +++ b/cpp/QrCodeGeneratorDemo.cpp @@ -164,8 +164,8 @@ static void doSegmentDemo() { static void doMaskDemo() { // Project Nayuki URL std::vector 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 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 } diff --git a/java/io/nayuki/qrcodegen/QrCode.java b/java/io/nayuki/qrcodegen/QrCode.java index 7495d44..68d35ca 100644 --- a/java/io/nayuki/qrcodegen/QrCode.java +++ b/java/io/nayuki/qrcodegen/QrCode.java @@ -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 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 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] diff --git a/java/io/nayuki/qrcodegen/QrCodeGeneratorDemo.java b/java/io/nayuki/qrcodegen/QrCodeGeneratorDemo.java index 8e144a1..b05c2b2 100644 --- a/java/io/nayuki/qrcodegen/QrCodeGeneratorDemo.java +++ b/java/io/nayuki/qrcodegen/QrCodeGeneratorDemo.java @@ -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"); } diff --git a/java/io/nayuki/qrcodegen/QrCodeGeneratorWorker.java b/java/io/nayuki/qrcodegen/QrCodeGeneratorWorker.java index 30a105d..b23f8e1 100644 --- a/java/io/nayuki/qrcodegen/QrCodeGeneratorWorker.java +++ b/java/io/nayuki/qrcodegen/QrCodeGeneratorWorker.java @@ -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 diff --git a/javascript/qrcodegen-demo.js b/javascript/qrcodegen-demo.js index ddf6a6e..e75e689 100644 --- a/javascript/qrcodegen-demo.js +++ b/javascript/qrcodegen-demo.js @@ -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) diff --git a/javascript/qrcodegen.js b/javascript/qrcodegen.js index e2fc53e..19ae3a8 100644 --- a/javascript/qrcodegen.js +++ b/javascript/qrcodegen.js @@ -31,6 +31,7 @@ * - Function encodeBinary(list data, QrCode.Ecc ecl) -> QrCode * - Function encodeSegments(list segs, QrCode.Ecc ecl, * int minVersion=1, int maxVersion=40, mask=-1, boostEcl=true) -> QrCode + * - Constants int MIN_VERSION, MAX_VERSION * - Constructor QrCode(list 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++) { diff --git a/python/qrcodegen.py b/python/qrcodegen.py index 1d90bdc..9a5b32c 100644 --- a/python/qrcodegen.py +++ b/python/qrcodegen.py @@ -31,6 +31,7 @@ This module "qrcodegen", public members: - Function encode_binary(bytes data, QrCode.Ecc ecl) -> QrCode - Function encode_segments(list 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: diff --git a/rust/examples/qrcodegen-demo.rs b/rust/examples/qrcodegen-demo.rs index 477d61e..83501e8 100644 --- a/rust/examples/qrcodegen-demo.rs +++ b/rust/examples/qrcodegen-demo.rs @@ -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); } diff --git a/rust/examples/qrcodegen-worker.rs b/rust/examples/qrcodegen-worker.rs index 3ba8575..d79948a 100644 --- a/rust/examples/qrcodegen-worker.rs +++ b/rust/examples/qrcodegen-worker.rs @@ -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); diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 3b1c9c9..e9758d9 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -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::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, boostecl: bool) -> Option { - 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) -> 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 { - 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 { - 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);