Tweaked code and comment in QrCode.encodeSegments() in all language versions.
This commit is contained in:
parent
c9553ead71
commit
c86dacacb7
|
@ -914,7 +914,6 @@ bool qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], siz
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concatenate all segments to create the data bit string
|
// Concatenate all segments to create the data bit string
|
||||||
int dataCapacityBits = getNumDataCodewords(version, ecl) * 8;
|
|
||||||
memset(qrcode, 0, qrcodegen_BUFFER_LEN_FOR_VERSION(version) * sizeof(qrcode[0]));
|
memset(qrcode, 0, qrcodegen_BUFFER_LEN_FOR_VERSION(version) * sizeof(qrcode[0]));
|
||||||
int bitLen = 0;
|
int bitLen = 0;
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
@ -935,16 +934,18 @@ bool qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], siz
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add terminator and pad up to a byte if applicable
|
// Add terminator and pad up to a byte if applicable
|
||||||
|
int dataCapacityBits = getNumDataCodewords(version, ecl) * 8;
|
||||||
|
assert(bitLen <= dataCapacityBits);
|
||||||
int terminatorBits = dataCapacityBits - bitLen;
|
int terminatorBits = dataCapacityBits - bitLen;
|
||||||
if (terminatorBits > 4)
|
if (terminatorBits > 4)
|
||||||
terminatorBits = 4;
|
terminatorBits = 4;
|
||||||
appendBitsToBuffer(0, terminatorBits, qrcode, &bitLen);
|
appendBitsToBuffer(0, terminatorBits, qrcode, &bitLen);
|
||||||
appendBitsToBuffer(0, (8 - bitLen % 8) % 8, qrcode, &bitLen);
|
appendBitsToBuffer(0, (8 - bitLen % 8) % 8, qrcode, &bitLen);
|
||||||
|
assert(bitLen % 8 == 0);
|
||||||
|
|
||||||
// Pad with alternate bytes until data capacity is reached
|
// Pad with alternating bytes until data capacity is reached
|
||||||
for (uint8_t padByte = 0xEC; bitLen < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
for (uint8_t padByte = 0xEC; bitLen < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
||||||
appendBitsToBuffer(padByte, 8, qrcode, &bitLen);
|
appendBitsToBuffer(padByte, 8, qrcode, &bitLen);
|
||||||
assert(bitLen % 8 == 0);
|
|
||||||
|
|
||||||
// Draw function and data codeword modules
|
// Draw function and data codeword modules
|
||||||
addEccAndInterleave(qrcode, version, ecl, tempBuffer);
|
addEccAndInterleave(qrcode, version, ecl, tempBuffer);
|
||||||
|
|
|
@ -87,7 +87,6 @@ QrCode QrCode::encodeSegments(const vector<QrSegment> &segs, Ecc ecl,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concatenate all segments to create the data bit string
|
// Concatenate all segments to create the data bit string
|
||||||
size_t dataCapacityBits = getNumDataCodewords(version, ecl) * 8;
|
|
||||||
BitBuffer bb;
|
BitBuffer bb;
|
||||||
for (const QrSegment &seg : segs) {
|
for (const QrSegment &seg : segs) {
|
||||||
bb.appendBits(seg.getMode().getModeBits(), 4);
|
bb.appendBits(seg.getMode().getModeBits(), 4);
|
||||||
|
@ -96,15 +95,18 @@ QrCode QrCode::encodeSegments(const vector<QrSegment> &segs, Ecc ecl,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add terminator and pad up to a byte if applicable
|
// Add terminator and pad up to a byte if applicable
|
||||||
|
size_t dataCapacityBits = getNumDataCodewords(version, ecl) * 8;
|
||||||
|
if (bb.size() > dataCapacityBits)
|
||||||
|
throw std::logic_error("Assertion error");
|
||||||
bb.appendBits(0, std::min<size_t>(4, dataCapacityBits - bb.size()));
|
bb.appendBits(0, std::min<size_t>(4, dataCapacityBits - bb.size()));
|
||||||
bb.appendBits(0, (8 - bb.size() % 8) % 8);
|
bb.appendBits(0, (8 - bb.size() % 8) % 8);
|
||||||
|
|
||||||
// Pad with alternate bytes until data capacity is reached
|
|
||||||
for (uint8_t padByte = 0xEC; bb.size() < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
|
||||||
bb.appendBits(padByte, 8);
|
|
||||||
if (bb.size() % 8 != 0)
|
if (bb.size() % 8 != 0)
|
||||||
throw std::logic_error("Assertion error");
|
throw std::logic_error("Assertion error");
|
||||||
|
|
||||||
|
// Pad with alternating bytes until data capacity is reached
|
||||||
|
for (uint8_t padByte = 0xEC; bb.size() < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
||||||
|
bb.appendBits(padByte, 8);
|
||||||
|
|
||||||
// Create the QR Code symbol
|
// Create the QR Code symbol
|
||||||
return QrCode(version, ecl, bb.getBytes(), mask);
|
return QrCode(version, ecl, bb.getBytes(), mask);
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,6 @@ public final class QrCode {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concatenate all segments to create the data bit string
|
// Concatenate all segments to create the data bit string
|
||||||
int dataCapacityBits = getNumDataCodewords(version, ecl) * 8;
|
|
||||||
BitBuffer bb = new BitBuffer();
|
BitBuffer bb = new BitBuffer();
|
||||||
for (QrSegment seg : segs) {
|
for (QrSegment seg : segs) {
|
||||||
bb.appendBits(seg.mode.modeBits, 4);
|
bb.appendBits(seg.mode.modeBits, 4);
|
||||||
|
@ -150,13 +149,15 @@ public final class QrCode {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add terminator and pad up to a byte if applicable
|
// Add terminator and pad up to a byte if applicable
|
||||||
|
int dataCapacityBits = getNumDataCodewords(version, ecl) * 8;
|
||||||
|
assert bb.bitLength() <= dataCapacityBits;
|
||||||
bb.appendBits(0, Math.min(4, dataCapacityBits - bb.bitLength()));
|
bb.appendBits(0, Math.min(4, dataCapacityBits - bb.bitLength()));
|
||||||
bb.appendBits(0, (8 - bb.bitLength() % 8) % 8);
|
bb.appendBits(0, (8 - bb.bitLength() % 8) % 8);
|
||||||
|
assert bb.bitLength() % 8 == 0;
|
||||||
|
|
||||||
// Pad with alternate bytes until data capacity is reached
|
// Pad with alternating bytes until data capacity is reached
|
||||||
for (int padByte = 0xEC; bb.bitLength() < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
for (int padByte = 0xEC; bb.bitLength() < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
||||||
bb.appendBits(padByte, 8);
|
bb.appendBits(padByte, 8);
|
||||||
assert bb.bitLength() % 8 == 0;
|
|
||||||
|
|
||||||
// Create the QR Code symbol
|
// Create the QR Code symbol
|
||||||
return new QrCode(version, ecl, bb.getBytes(), mask);
|
return new QrCode(version, ecl, bb.getBytes(), mask);
|
||||||
|
|
|
@ -554,7 +554,6 @@ var qrcodegen = new function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Concatenate all segments to create the data bit string
|
// Concatenate all segments to create the data bit string
|
||||||
var dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8;
|
|
||||||
var bb = new BitBuffer();
|
var bb = new BitBuffer();
|
||||||
segs.forEach(function(seg) {
|
segs.forEach(function(seg) {
|
||||||
bb.appendBits(seg.mode.modeBits, 4);
|
bb.appendBits(seg.mode.modeBits, 4);
|
||||||
|
@ -565,15 +564,18 @@ var qrcodegen = new function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add terminator and pad up to a byte if applicable
|
// Add terminator and pad up to a byte if applicable
|
||||||
|
var dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8;
|
||||||
|
if (bb.length > dataCapacityBits)
|
||||||
|
throw "Assertion error";
|
||||||
bb.appendBits(0, Math.min(4, dataCapacityBits - bb.length));
|
bb.appendBits(0, Math.min(4, dataCapacityBits - bb.length));
|
||||||
bb.appendBits(0, (8 - bb.length % 8) % 8);
|
bb.appendBits(0, (8 - bb.length % 8) % 8);
|
||||||
|
|
||||||
// Pad with alternate bytes until data capacity is reached
|
|
||||||
for (var padByte = 0xEC; bb.length < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
|
||||||
bb.appendBits(padByte, 8);
|
|
||||||
if (bb.length % 8 != 0)
|
if (bb.length % 8 != 0)
|
||||||
throw "Assertion error";
|
throw "Assertion error";
|
||||||
|
|
||||||
|
// Pad with alternating bytes until data capacity is reached
|
||||||
|
for (var padByte = 0xEC; bb.length < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
||||||
|
bb.appendBits(padByte, 8);
|
||||||
|
|
||||||
// Create the QR Code symbol
|
// Create the QR Code symbol
|
||||||
return new this(bb.getBytes(), mask, version, ecl);
|
return new this(bb.getBytes(), mask, version, ecl);
|
||||||
};
|
};
|
||||||
|
|
|
@ -116,7 +116,6 @@ class QrCode(object):
|
||||||
ecl = newecl
|
ecl = newecl
|
||||||
|
|
||||||
# Concatenate all segments to create the data bit string
|
# Concatenate all segments to create the data bit string
|
||||||
datacapacitybits = QrCode._get_num_data_codewords(version, ecl) * 8
|
|
||||||
bb = _BitBuffer()
|
bb = _BitBuffer()
|
||||||
for seg in segs:
|
for seg in segs:
|
||||||
bb.append_bits(seg.get_mode().get_mode_bits(), 4)
|
bb.append_bits(seg.get_mode().get_mode_bits(), 4)
|
||||||
|
@ -124,15 +123,17 @@ class QrCode(object):
|
||||||
bb.extend(seg._bitdata)
|
bb.extend(seg._bitdata)
|
||||||
|
|
||||||
# Add terminator and pad up to a byte if applicable
|
# Add terminator and pad up to a byte if applicable
|
||||||
|
datacapacitybits = QrCode._get_num_data_codewords(version, ecl) * 8
|
||||||
|
assert len(bb) <= datacapacitybits
|
||||||
bb.append_bits(0, min(4, datacapacitybits - len(bb)))
|
bb.append_bits(0, min(4, datacapacitybits - len(bb)))
|
||||||
bb.append_bits(0, -len(bb) % 8) # Note: Python's modulo on negative numbers behaves better than C family languages
|
bb.append_bits(0, -len(bb) % 8) # Note: Python's modulo on negative numbers behaves better than C family languages
|
||||||
|
assert len(bb) % 8 == 0
|
||||||
|
|
||||||
# Pad with alternate bytes until data capacity is reached
|
# Pad with alternating bytes until data capacity is reached
|
||||||
for padbyte in itertools.cycle((0xEC, 0x11)):
|
for padbyte in itertools.cycle((0xEC, 0x11)):
|
||||||
if len(bb) >= datacapacitybits:
|
if len(bb) >= datacapacitybits:
|
||||||
break
|
break
|
||||||
bb.append_bits(padbyte, 8)
|
bb.append_bits(padbyte, 8)
|
||||||
assert len(bb) % 8 == 0
|
|
||||||
|
|
||||||
# Create the QR Code symbol
|
# Create the QR Code symbol
|
||||||
return QrCode(bb.get_bytes(), mask, version, ecl)
|
return QrCode(bb.get_bytes(), mask, version, ecl)
|
||||||
|
|
|
@ -130,7 +130,6 @@ impl QrCode {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concatenate all segments to create the data bit string
|
// Concatenate all segments to create the data bit string
|
||||||
let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8;
|
|
||||||
let mut bb = BitBuffer(Vec::new());
|
let mut bb = BitBuffer(Vec::new());
|
||||||
for seg in segs {
|
for seg in segs {
|
||||||
bb.append_bits(seg.mode.mode_bits(), 4);
|
bb.append_bits(seg.mode.mode_bits(), 4);
|
||||||
|
@ -139,19 +138,21 @@ impl QrCode {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add terminator and pad up to a byte if applicable
|
// Add terminator and pad up to a byte if applicable
|
||||||
|
let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8;
|
||||||
|
assert!(bb.0.len() <= datacapacitybits);
|
||||||
let numzerobits = std::cmp::min(4, datacapacitybits - bb.0.len());
|
let numzerobits = std::cmp::min(4, datacapacitybits - bb.0.len());
|
||||||
bb.append_bits(0, numzerobits as u8);
|
bb.append_bits(0, numzerobits as u8);
|
||||||
let numzerobits = bb.0.len().wrapping_neg() & 7;
|
let numzerobits = bb.0.len().wrapping_neg() & 7;
|
||||||
bb.append_bits(0, numzerobits as u8);
|
bb.append_bits(0, numzerobits as u8);
|
||||||
|
assert_eq!(bb.0.len() % 8, 0, "Assertion error");
|
||||||
|
|
||||||
// Pad with alternate bytes until data capacity is reached
|
// Pad with alternating bytes until data capacity is reached
|
||||||
for padbyte in [0xEC, 0x11].iter().cycle() {
|
for padbyte in [0xEC, 0x11].iter().cycle() {
|
||||||
if bb.0.len() >= datacapacitybits {
|
if bb.0.len() >= datacapacitybits {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bb.append_bits(*padbyte, 8);
|
bb.append_bits(*padbyte, 8);
|
||||||
}
|
}
|
||||||
assert_eq!(bb.0.len() % 8, 0, "Assertion error");
|
|
||||||
|
|
||||||
let mut bytes = vec![0u8; bb.0.len() / 8];
|
let mut bytes = vec![0u8; bb.0.len() / 8];
|
||||||
for (i, bit) in bb.0.iter().enumerate() {
|
for (i, bit) in bb.0.iter().enumerate() {
|
||||||
|
|
|
@ -101,7 +101,6 @@ namespace qrcodegen {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Concatenate all segments to create the data bit string
|
// Concatenate all segments to create the data bit string
|
||||||
let dataCapacityBits: int = QrCode.getNumDataCodewords(version, ecl) * 8;
|
|
||||||
let bb = new BitBuffer();
|
let bb = new BitBuffer();
|
||||||
segs.forEach((seg: QrSegment) => {
|
segs.forEach((seg: QrSegment) => {
|
||||||
bb.appendBits(seg.mode.modeBits, 4);
|
bb.appendBits(seg.mode.modeBits, 4);
|
||||||
|
@ -111,15 +110,18 @@ namespace qrcodegen {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add terminator and pad up to a byte if applicable
|
// Add terminator and pad up to a byte if applicable
|
||||||
|
let dataCapacityBits: int = QrCode.getNumDataCodewords(version, ecl) * 8;
|
||||||
|
if (bb.length > dataCapacityBits)
|
||||||
|
throw "Assertion error";
|
||||||
bb.appendBits(0, Math.min(4, dataCapacityBits - bb.length));
|
bb.appendBits(0, Math.min(4, dataCapacityBits - bb.length));
|
||||||
bb.appendBits(0, (8 - bb.length % 8) % 8);
|
bb.appendBits(0, (8 - bb.length % 8) % 8);
|
||||||
|
|
||||||
// Pad with alternate bytes until data capacity is reached
|
|
||||||
for (let padByte = 0xEC; bb.length < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
|
||||||
bb.appendBits(padByte, 8);
|
|
||||||
if (bb.length % 8 != 0)
|
if (bb.length % 8 != 0)
|
||||||
throw "Assertion error";
|
throw "Assertion error";
|
||||||
|
|
||||||
|
// Pad with alternating bytes until data capacity is reached
|
||||||
|
for (let padByte = 0xEC; bb.length < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
||||||
|
bb.appendBits(padByte, 8);
|
||||||
|
|
||||||
// Create the QR Code symbol
|
// Create the QR Code symbol
|
||||||
return new QrCode(bb.getBytes(), mask, version, ecl);
|
return new QrCode(bb.getBytes(), mask, version, ecl);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue