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.
This commit is contained in:
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…
Reference in New Issue