Moved {encodeText(), encodeBinary(), encodeSegments()} into class QrCode in Python and JavaScript implementations, for consistency with Java implementation.
This commit is contained in:
parent
de261ca62d
commit
f325bfe638
|
@ -42,7 +42,7 @@ function redrawQrCode() {
|
|||
var ecl = getInputErrorCorrectionLevel();
|
||||
var text = document.getElementById("text-input").value;
|
||||
var segs = qrcodegen.QrSegment.makeSegments(text);
|
||||
var qr = qrcodegen.encodeSegments(segs, ecl);
|
||||
var qr = qrcodegen.QrCode.encodeSegments(segs, ecl);
|
||||
|
||||
// Get scale and border
|
||||
var scale = parseInt(document.getElementById("scale-input").value, 10);
|
||||
|
|
|
@ -27,11 +27,11 @@
|
|||
|
||||
/*
|
||||
* Module "qrcodegen". Public members inside this namespace:
|
||||
* - Function encodeText(str text, QrCode.Ecc ecl) -> QrCode
|
||||
* - Function encodeBinary(list<int> data, QrCode.Ecc ecl) -> QrCode
|
||||
* - Function encodeSegments(list<QrSegment> segs, QrCode.Ecc ecl,
|
||||
* int minVersion=1, int maxVersion=40, mask=-1, boostEcl=true) -> QrCode
|
||||
* - Class QrCode:
|
||||
* - Function encodeText(str text, QrCode.Ecc ecl) -> QrCode
|
||||
* - Function encodeBinary(list<int> data, QrCode.Ecc ecl) -> QrCode
|
||||
* - Function encodeSegments(list<QrSegment> segs, QrCode.Ecc ecl,
|
||||
* int minVersion=1, int maxVersion=40, mask=-1, boostEcl=true) -> QrCode
|
||||
* - Constructor QrCode(QrCode qr, int mask)
|
||||
* - Constructor QrCode(list<int> bytes, int mask, int version, QrCode.Ecc ecl)
|
||||
* - Method getVersion() -> int
|
||||
|
@ -60,87 +60,6 @@
|
|||
*/
|
||||
var qrcodegen = new function() {
|
||||
|
||||
/*---- Public static factory functions for QrCode ----*/
|
||||
|
||||
/*
|
||||
* Returns a QR Code symbol representing the given Unicode text string at the given error correction level.
|
||||
* As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer Unicode
|
||||
* code points (not UTF-16 code units). The smallest possible QR Code version is automatically chosen for the output.
|
||||
*/
|
||||
this.encodeText = function(text, ecl) {
|
||||
var segs = this.QrSegment.makeSegments(text);
|
||||
return this.encodeSegments(segs, ecl);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Returns a QR Code symbol representing the given binary data string at the given error correction level.
|
||||
* This function always encodes using the binary segment mode, not any text mode. The maximum number of
|
||||
* bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
|
||||
*/
|
||||
this.encodeBinary = function(data, ecl) {
|
||||
var seg = this.QrSegment.makeBytes(data);
|
||||
return this.encodeSegments([seg], ecl);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Returns a QR Code symbol representing the specified data segments with the specified encoding parameters.
|
||||
* The smallest possible QR Code version within the specified range is automatically chosen for the output.
|
||||
* This function allows the user to create a custom sequence of segments that switches
|
||||
* 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.
|
||||
*/
|
||||
this.encodeSegments = function(segs, ecl, minVersion, maxVersion, mask, boostEcl) {
|
||||
if (minVersion == undefined) minVersion = 1;
|
||||
if (maxVersion == undefined) maxVersion = 40;
|
||||
if (mask == undefined) mask = -1;
|
||||
if (boostEcl == undefined) boostEcl = true;
|
||||
if (!(1 <= minVersion && minVersion <= maxVersion && maxVersion <= 40) || mask < -1 || mask > 7)
|
||||
throw "Invalid value";
|
||||
|
||||
// Find the minimal version number to use
|
||||
var version, dataUsedBits;
|
||||
for (version = minVersion; ; version++) {
|
||||
var dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8; // Number of data bits available
|
||||
dataUsedBits = this.QrSegment.getTotalBits(segs, version);
|
||||
if (dataUsedBits != null && dataUsedBits <= dataCapacityBits)
|
||||
break; // This version number is found to be suitable
|
||||
if (version >= maxVersion) // All versions in the range could not fit the given data
|
||||
throw "Data too long";
|
||||
}
|
||||
|
||||
// Increase the error correction level while the data still fits in the current version number
|
||||
[this.QrCode.Ecc.MEDIUM, this.QrCode.Ecc.QUARTILE, this.QrCode.Ecc.HIGH].forEach(function(newEcl) {
|
||||
if (boostEcl && dataUsedBits <= QrCode.getNumDataCodewords(version, newEcl) * 8)
|
||||
ecl = newEcl;
|
||||
});
|
||||
|
||||
// Create the data bit string by concatenating all segments
|
||||
var dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8;
|
||||
var bb = new BitBuffer();
|
||||
segs.forEach(function(seg) {
|
||||
bb.appendBits(seg.getMode().getModeBits(), 4);
|
||||
bb.appendBits(seg.getNumChars(), seg.getMode().numCharCountBits(version));
|
||||
bb.appendData(seg);
|
||||
});
|
||||
|
||||
// Add terminator and pad up to a byte if applicable
|
||||
bb.appendBits(0, Math.min(4, dataCapacityBits - bb.bitLength()));
|
||||
bb.appendBits(0, (8 - bb.bitLength() % 8) % 8);
|
||||
|
||||
// Pad with alternate bytes until data capacity is reached
|
||||
for (var padByte = 0xEC; bb.bitLength() < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
||||
bb.appendBits(padByte, 8);
|
||||
if (bb.bitLength() % 8 != 0)
|
||||
throw "Assertion error";
|
||||
|
||||
// Create the QR Code symbol
|
||||
return new this.QrCode(bb.getBytes(), mask, version, ecl);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*---- QR Code symbol class ----*/
|
||||
|
||||
/*
|
||||
|
@ -594,6 +513,85 @@ var qrcodegen = new function() {
|
|||
};
|
||||
|
||||
|
||||
/*---- Public static factory functions for QrCode ----*/
|
||||
|
||||
/*
|
||||
* Returns a QR Code symbol representing the given Unicode text string at the given error correction level.
|
||||
* As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer Unicode
|
||||
* code points (not UTF-16 code units). The smallest possible QR Code version is automatically chosen for the output.
|
||||
*/
|
||||
this.QrCode.encodeText = function(text, ecl) {
|
||||
var segs = qrcodegen.QrSegment.makeSegments(text);
|
||||
return this.encodeSegments(segs, ecl);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Returns a QR Code symbol representing the given binary data string at the given error correction level.
|
||||
* This function always encodes using the binary segment mode, not any text mode. The maximum number of
|
||||
* bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
|
||||
*/
|
||||
this.QrCode.encodeBinary = function(data, ecl) {
|
||||
var seg = qrcodegen.QrSegment.makeBytes(data);
|
||||
return this.encodeSegments([seg], ecl);
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns a QR Code symbol representing the specified data segments with the specified encoding parameters.
|
||||
* The smallest possible QR Code version within the specified range is automatically chosen for the output.
|
||||
* This function allows the user to create a custom sequence of segments that switches
|
||||
* 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.
|
||||
*/
|
||||
this.QrCode.encodeSegments = function(segs, ecl, minVersion, maxVersion, mask, boostEcl) {
|
||||
if (minVersion == undefined) minVersion = 1;
|
||||
if (maxVersion == undefined) maxVersion = 40;
|
||||
if (mask == undefined) mask = -1;
|
||||
if (boostEcl == undefined) boostEcl = true;
|
||||
if (!(1 <= minVersion && minVersion <= maxVersion && maxVersion <= 40) || mask < -1 || mask > 7)
|
||||
throw "Invalid value";
|
||||
|
||||
// Find the minimal version number to use
|
||||
var version, dataUsedBits;
|
||||
for (version = minVersion; ; version++) {
|
||||
var dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8; // Number of data bits available
|
||||
dataUsedBits = qrcodegen.QrSegment.getTotalBits(segs, version);
|
||||
if (dataUsedBits != null && dataUsedBits <= dataCapacityBits)
|
||||
break; // This version number is found to be suitable
|
||||
if (version >= maxVersion) // All versions in the range could not fit the given data
|
||||
throw "Data too long";
|
||||
}
|
||||
|
||||
// Increase the error correction level while the data still fits in the current version number
|
||||
[this.Ecc.MEDIUM, this.Ecc.QUARTILE, this.Ecc.HIGH].forEach(function(newEcl) {
|
||||
if (boostEcl && dataUsedBits <= QrCode.getNumDataCodewords(version, newEcl) * 8)
|
||||
ecl = newEcl;
|
||||
});
|
||||
|
||||
// Create the data bit string by concatenating all segments
|
||||
var dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8;
|
||||
var bb = new BitBuffer();
|
||||
segs.forEach(function(seg) {
|
||||
bb.appendBits(seg.getMode().getModeBits(), 4);
|
||||
bb.appendBits(seg.getNumChars(), seg.getMode().numCharCountBits(version));
|
||||
bb.appendData(seg);
|
||||
});
|
||||
|
||||
// Add terminator and pad up to a byte if applicable
|
||||
bb.appendBits(0, Math.min(4, dataCapacityBits - bb.bitLength()));
|
||||
bb.appendBits(0, (8 - bb.bitLength() % 8) % 8);
|
||||
|
||||
// Pad with alternate bytes until data capacity is reached
|
||||
for (var padByte = 0xEC; bb.bitLength() < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
||||
bb.appendBits(padByte, 8);
|
||||
if (bb.bitLength() % 8 != 0)
|
||||
throw "Assertion error";
|
||||
|
||||
// Create the QR Code symbol
|
||||
return new this(bb.getBytes(), mask, version, ecl);
|
||||
};
|
||||
|
||||
|
||||
/*---- Private static helper functions ----*/
|
||||
|
||||
var QrCode = {}; // Private object to assign properties to
|
||||
|
|
|
@ -39,7 +39,7 @@ def do_basic_demo():
|
|||
"""Creates a single QR Code, then prints it to the console."""
|
||||
text = u"Hello, world!" # User-supplied Unicode text
|
||||
errcorlvl = qrcodegen.QrCode.Ecc.LOW # Error correction level
|
||||
qr = qrcodegen.encode_text(text, errcorlvl)
|
||||
qr = qrcodegen.QrCode.encode_text(text, errcorlvl)
|
||||
print_qr(qr)
|
||||
|
||||
|
||||
|
@ -47,27 +47,27 @@ def do_variety_demo():
|
|||
"""Creates a variety of QR Codes that exercise different features of the library, and prints each one to the console."""
|
||||
|
||||
# Project Nayuki URL
|
||||
qr = qrcodegen.encode_text("https://www.nayuki.io/", qrcodegen.QrCode.Ecc.HIGH)
|
||||
qr = qrcodegen.QrCode.encode_text("https://www.nayuki.io/", qrcodegen.QrCode.Ecc.HIGH)
|
||||
qr = qrcodegen.QrCode(qrcode=qr, mask=3) # Change mask, forcing to mask #3
|
||||
print_qr(qr)
|
||||
|
||||
# Numeric mode encoding (3.33 bits per digit)
|
||||
qr = qrcodegen.encode_text("314159265358979323846264338327950288419716939937510", qrcodegen.QrCode.Ecc.MEDIUM)
|
||||
qr = qrcodegen.QrCode.encode_text("314159265358979323846264338327950288419716939937510", qrcodegen.QrCode.Ecc.MEDIUM)
|
||||
print_qr(qr)
|
||||
|
||||
# Alphanumeric mode encoding (5.5 bits per character)
|
||||
qr = qrcodegen.encode_text("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", qrcodegen.QrCode.Ecc.HIGH)
|
||||
qr = qrcodegen.QrCode.encode_text("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", qrcodegen.QrCode.Ecc.HIGH)
|
||||
print_qr(qr)
|
||||
|
||||
# Unicode text as UTF-8, and different masks
|
||||
qr = qrcodegen.encode_text(u"\u3053\u3093\u306B\u3061\u0077\u0061\u3001\u4E16\u754C\uFF01\u0020\u03B1\u03B2\u03B3\u03B4", qrcodegen.QrCode.Ecc.QUARTILE)
|
||||
qr = qrcodegen.QrCode.encode_text(u"\u3053\u3093\u306B\u3061\u0077\u0061\u3001\u4E16\u754C\uFF01\u0020\u03B1\u03B2\u03B3\u03B4", qrcodegen.QrCode.Ecc.QUARTILE)
|
||||
print_qr(qrcodegen.QrCode(qrcode=qr, mask=0))
|
||||
print_qr(qrcodegen.QrCode(qrcode=qr, mask=1))
|
||||
print_qr(qrcodegen.QrCode(qrcode=qr, mask=5))
|
||||
print_qr(qrcodegen.QrCode(qrcode=qr, mask=7))
|
||||
|
||||
# Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland)
|
||||
qr = qrcodegen.encode_text("Alice was beginning to get very tired of sitting by her sister on the bank, "
|
||||
qr = qrcodegen.QrCode.encode_text("Alice was beginning to get very tired of sitting by her sister on the bank, "
|
||||
"and of having nothing to do: once or twice she had peeped into the book her sister was reading, "
|
||||
"but it had no pictures or conversations in it, 'and what is the use of a book,' thought Alice "
|
||||
"'without pictures or conversations?' So she was considering in her own mind (as well as she could, "
|
||||
|
@ -83,27 +83,27 @@ def do_segment_demo():
|
|||
# Illustration "silver"
|
||||
silver0 = "THE SQUARE ROOT OF 2 IS 1."
|
||||
silver1 = "41421356237309504880168872420969807856967187537694807317667973799"
|
||||
qr = qrcodegen.encode_text(silver0 + silver1, qrcodegen.QrCode.Ecc.LOW)
|
||||
qr = qrcodegen.QrCode.encode_text(silver0 + silver1, qrcodegen.QrCode.Ecc.LOW)
|
||||
print_qr(qr)
|
||||
|
||||
segs = [
|
||||
qrcodegen.QrSegment.make_alphanumeric(silver0),
|
||||
qrcodegen.QrSegment.make_numeric(silver1)]
|
||||
qr = qrcodegen.encode_segments(segs, qrcodegen.QrCode.Ecc.LOW)
|
||||
qr = qrcodegen.QrCode.encode_segments(segs, qrcodegen.QrCode.Ecc.LOW)
|
||||
print_qr(qr)
|
||||
|
||||
# Illustration "golden"
|
||||
golden0 = u"Golden ratio \u03C6 = 1."
|
||||
golden1 = u"6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374"
|
||||
golden2 = u"......"
|
||||
qr = qrcodegen.encode_text(golden0 + golden1 + golden2, qrcodegen.QrCode.Ecc.LOW)
|
||||
qr = qrcodegen.QrCode.encode_text(golden0 + golden1 + golden2, qrcodegen.QrCode.Ecc.LOW)
|
||||
print_qr(qr)
|
||||
|
||||
segs = [
|
||||
qrcodegen.QrSegment.make_bytes(golden0.encode("UTF-8")),
|
||||
qrcodegen.QrSegment.make_numeric(golden1),
|
||||
qrcodegen.QrSegment.make_alphanumeric(golden2)]
|
||||
qr = qrcodegen.encode_segments(segs, qrcodegen.QrCode.Ecc.LOW)
|
||||
qr = qrcodegen.QrCode.encode_segments(segs, qrcodegen.QrCode.Ecc.LOW)
|
||||
print_qr(qr)
|
||||
|
||||
|
||||
|
|
|
@ -27,11 +27,11 @@ import itertools, re, sys
|
|||
|
||||
"""
|
||||
Public members inside this module "qrcodegen":
|
||||
- Function encode_text(str text, QrCode.Ecc ecl) -> QrCode
|
||||
- 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
|
||||
- Class QrCode:
|
||||
- Function encode_text(str text, QrCode.Ecc ecl) -> QrCode
|
||||
- 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
|
||||
- Constructor QrCode(QrCode qr, int mask)
|
||||
- Constructor QrCode(bytes bytes, int mask, int version, QrCode.Ecc ecl)
|
||||
- Method get_version() -> int
|
||||
|
@ -59,81 +59,81 @@ Public members inside this module "qrcodegen":
|
|||
"""
|
||||
|
||||
|
||||
# ---- Public static factory functions for QrCode ----
|
||||
|
||||
def encode_text(text, ecl):
|
||||
"""Returns a QR Code symbol representing the given Unicode text string at the given error correction level.
|
||||
As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer Unicode
|
||||
code points (not UTF-16 code units). The smallest possible QR Code version is automatically chosen for the output."""
|
||||
segs = QrSegment.make_segments(text)
|
||||
return encode_segments(segs, ecl)
|
||||
|
||||
|
||||
def encode_binary(data, ecl):
|
||||
"""Returns a QR Code symbol representing the given binary data string at the given error correction level.
|
||||
This function always encodes using the binary segment mode, not any text mode. The maximum number of
|
||||
bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output."""
|
||||
if not isinstance(data, bytes):
|
||||
raise TypeError("Binary array expected")
|
||||
return QrCode.encode_segments([QrSegment.make_bytes(data)], ecl)
|
||||
|
||||
|
||||
def encode_segments(segs, ecl, minversion=1, maxversion=40, mask=-1, boostecl=True):
|
||||
"""Returns a QR Code symbol representing the specified data segments with the specified encoding parameters.
|
||||
The smallest possible QR Code version within the specified range is automatically chosen for the output.
|
||||
This function allows the user to create a custom sequence of segments that switches
|
||||
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:
|
||||
raise ValueError("Invalid value")
|
||||
|
||||
# Find the minimal version number to use
|
||||
for version in range(minversion, maxversion + 1):
|
||||
datacapacitybits = QrCode._get_num_data_codewords(version, ecl) * 8 # Number of data bits available
|
||||
datausedbits = QrSegment.get_total_bits(segs, version)
|
||||
if datausedbits is not None and datausedbits <= datacapacitybits:
|
||||
break # This version number is found to be suitable
|
||||
if version >= maxversion: # All versions in the range could not fit the given data
|
||||
raise ValueError("Data too long")
|
||||
if datausedbits is None:
|
||||
raise AssertionError()
|
||||
|
||||
# Increase the error correction level while the data still fits in the current version number
|
||||
for newecl in (QrCode.Ecc.MEDIUM, QrCode.Ecc.QUARTILE, QrCode.Ecc.HIGH):
|
||||
if boostecl and datausedbits <= QrCode._get_num_data_codewords(version, newecl) * 8:
|
||||
ecl = newecl
|
||||
|
||||
# Create the data bit string by concatenating all segments
|
||||
datacapacitybits = QrCode._get_num_data_codewords(version, ecl) * 8
|
||||
bb = _BitBuffer()
|
||||
for seg in segs:
|
||||
bb.append_bits(seg.get_mode().get_mode_bits(), 4)
|
||||
bb.append_bits(seg.get_num_chars(), seg.get_mode().num_char_count_bits(version))
|
||||
bb.append_all(seg)
|
||||
|
||||
# Add terminator and pad up to a byte if applicable
|
||||
bb.append_bits(0, min(4, datacapacitybits - bb.bit_length()))
|
||||
bb.append_bits(0, -bb.bit_length() % 8)
|
||||
|
||||
# Pad with alternate bytes until data capacity is reached
|
||||
for padbyte in itertools.cycle((0xEC, 0x11)):
|
||||
if bb.bit_length() >= datacapacitybits:
|
||||
break
|
||||
bb.append_bits(padbyte, 8)
|
||||
assert bb.bit_length() % 8 == 0
|
||||
|
||||
# Create the QR Code symbol
|
||||
return QrCode(None, bb.get_bytes(), mask, version, ecl)
|
||||
|
||||
|
||||
|
||||
# ---- QR Code symbol class ----
|
||||
|
||||
class QrCode(object):
|
||||
"""Represents an immutable square grid of black or white cells for a QR Code symbol. This class covers the
|
||||
QR Code model 2 specification, supporting all versions (sizes) from 1 to 40, all 4 error correction levels."""
|
||||
|
||||
# ---- Public static factory functions ----
|
||||
|
||||
def encode_text(text, ecl):
|
||||
"""Returns a QR Code symbol representing the given Unicode text string at the given error correction level.
|
||||
As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer Unicode
|
||||
code points (not UTF-16 code units). The smallest possible QR Code version is automatically chosen for the output."""
|
||||
segs = QrSegment.make_segments(text)
|
||||
return QrCode.encode_segments(segs, ecl)
|
||||
|
||||
|
||||
def encode_binary(data, ecl):
|
||||
"""Returns a QR Code symbol representing the given binary data string at the given error correction level.
|
||||
This function always encodes using the binary segment mode, not any text mode. The maximum number of
|
||||
bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output."""
|
||||
if not isinstance(data, bytes):
|
||||
raise TypeError("Binary array expected")
|
||||
return QrCode.encode_segments([QrSegment.make_bytes(data)], ecl)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def encode_segments(segs, ecl, minversion=1, maxversion=40, mask=-1, boostecl=True):
|
||||
"""Returns a QR Code symbol representing the specified data segments with the specified encoding parameters.
|
||||
The smallest possible QR Code version within the specified range is automatically chosen for the output.
|
||||
This function allows the user to create a custom sequence of segments that switches
|
||||
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:
|
||||
raise ValueError("Invalid value")
|
||||
|
||||
# Find the minimal version number to use
|
||||
for version in range(minversion, maxversion + 1):
|
||||
datacapacitybits = QrCode._get_num_data_codewords(version, ecl) * 8 # Number of data bits available
|
||||
datausedbits = QrSegment.get_total_bits(segs, version)
|
||||
if datausedbits is not None and datausedbits <= datacapacitybits:
|
||||
break # This version number is found to be suitable
|
||||
if version >= maxversion: # All versions in the range could not fit the given data
|
||||
raise ValueError("Data too long")
|
||||
if datausedbits is None:
|
||||
raise AssertionError()
|
||||
|
||||
# Increase the error correction level while the data still fits in the current version number
|
||||
for newecl in (QrCode.Ecc.MEDIUM, QrCode.Ecc.QUARTILE, QrCode.Ecc.HIGH):
|
||||
if boostecl and datausedbits <= QrCode._get_num_data_codewords(version, newecl) * 8:
|
||||
ecl = newecl
|
||||
|
||||
# Create the data bit string by concatenating all segments
|
||||
datacapacitybits = QrCode._get_num_data_codewords(version, ecl) * 8
|
||||
bb = _BitBuffer()
|
||||
for seg in segs:
|
||||
bb.append_bits(seg.get_mode().get_mode_bits(), 4)
|
||||
bb.append_bits(seg.get_num_chars(), seg.get_mode().num_char_count_bits(version))
|
||||
bb.append_all(seg)
|
||||
|
||||
# Add terminator and pad up to a byte if applicable
|
||||
bb.append_bits(0, min(4, datacapacitybits - bb.bit_length()))
|
||||
bb.append_bits(0, -bb.bit_length() % 8)
|
||||
|
||||
# Pad with alternate bytes until data capacity is reached
|
||||
for padbyte in itertools.cycle((0xEC, 0x11)):
|
||||
if bb.bit_length() >= datacapacitybits:
|
||||
break
|
||||
bb.append_bits(padbyte, 8)
|
||||
assert bb.bit_length() % 8 == 0
|
||||
|
||||
# Create the QR Code symbol
|
||||
return QrCode(None, bb.get_bytes(), mask, version, ecl)
|
||||
|
||||
|
||||
# ---- Constructor ----
|
||||
|
||||
def __init__(self, qrcode=None, datacodewords=None, mask=None, version=None, errcorlvl=None):
|
||||
|
|
Loading…
Reference in New Issue