Added support for making Extended Channel Interpretation (ECI) segments - in Java, C++, JavaScript, and Python language versions.
This commit is contained in:
parent
0482a1ec5b
commit
a610a3d8df
|
@ -53,6 +53,7 @@ const QrSegment::Mode QrSegment::Mode::NUMERIC (0x1, 10, 12, 14);
|
||||||
const QrSegment::Mode QrSegment::Mode::ALPHANUMERIC(0x2, 9, 11, 13);
|
const QrSegment::Mode QrSegment::Mode::ALPHANUMERIC(0x2, 9, 11, 13);
|
||||||
const QrSegment::Mode QrSegment::Mode::BYTE (0x4, 8, 16, 16);
|
const QrSegment::Mode QrSegment::Mode::BYTE (0x4, 8, 16, 16);
|
||||||
const QrSegment::Mode QrSegment::Mode::KANJI (0x8, 8, 10, 12);
|
const QrSegment::Mode QrSegment::Mode::KANJI (0x8, 8, 10, 12);
|
||||||
|
const QrSegment::Mode QrSegment::Mode::ECI (0x7, 0, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,6 +128,20 @@ vector<QrSegment> QrSegment::makeSegments(const char *text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QrSegment QrSegment::makeEci(long assignVal) {
|
||||||
|
vector<uint8_t> data;
|
||||||
|
if (0 <= assignVal && assignVal < (1 << 7))
|
||||||
|
data = {static_cast<uint8_t>(assignVal)};
|
||||||
|
else if ((1 << 7) <= assignVal && assignVal < (1 << 14))
|
||||||
|
data = {static_cast<uint8_t>(0x80 | (assignVal >> 8)), static_cast<uint8_t>(assignVal)};
|
||||||
|
else if ((1 << 14) <= assignVal && assignVal < 999999L)
|
||||||
|
data = {static_cast<uint8_t>(0xC0 | (assignVal >> 16)), static_cast<uint8_t>(assignVal >> 8), static_cast<uint8_t>(assignVal)};
|
||||||
|
else
|
||||||
|
throw "ECI assignment value out of range";
|
||||||
|
return QrSegment(Mode::ECI, 0, data, data.size() * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QrSegment::QrSegment(const Mode &md, int numCh, const vector<uint8_t> &b, int bitLen) :
|
QrSegment::QrSegment(const Mode &md, int numCh, const vector<uint8_t> &b, int bitLen) :
|
||||||
mode(md),
|
mode(md),
|
||||||
numChars(numCh),
|
numChars(numCh),
|
||||||
|
|
|
@ -52,6 +52,7 @@ class QrSegment final {
|
||||||
public: static const Mode ALPHANUMERIC;
|
public: static const Mode ALPHANUMERIC;
|
||||||
public: static const Mode BYTE;
|
public: static const Mode BYTE;
|
||||||
public: static const Mode KANJI;
|
public: static const Mode KANJI;
|
||||||
|
public: static const Mode ECI;
|
||||||
|
|
||||||
|
|
||||||
/*-- Fields --*/
|
/*-- Fields --*/
|
||||||
|
@ -106,6 +107,12 @@ class QrSegment final {
|
||||||
public: static std::vector<QrSegment> makeSegments(const char *text);
|
public: static std::vector<QrSegment> makeSegments(const char *text);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a segment representing an Extended Channel Interpretation (ECI) designator with the given assignment value.
|
||||||
|
*/
|
||||||
|
public: static QrSegment makeEci(long assignVal);
|
||||||
|
|
||||||
|
|
||||||
/*---- Public static helper functions ----*/
|
/*---- Public static helper functions ----*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -128,6 +128,26 @@ public final class QrSegment {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a segment representing an Extended Channel Interpretation (ECI) designator with the specified assignment value.
|
||||||
|
* @param assignVal the ECI assignment number (see the AIM ECI specification)
|
||||||
|
* @return a segment containing the data
|
||||||
|
* @throws IllegalArgumentException if the value is outside the range [0, 10<sup>6</sup>)
|
||||||
|
*/
|
||||||
|
public static QrSegment makeEci(int assignVal) {
|
||||||
|
byte[] data;
|
||||||
|
if (0 <= assignVal && assignVal < (1 << 7))
|
||||||
|
data = new byte[]{(byte)assignVal};
|
||||||
|
else if ((1 << 7) <= assignVal && assignVal < (1 << 14))
|
||||||
|
data = new byte[]{(byte)(0x80 | (assignVal >>> 8)), (byte)assignVal};
|
||||||
|
else if ((1 << 14) <= assignVal && assignVal < 999999)
|
||||||
|
data = new byte[]{(byte)(0xC0 | (assignVal >>> 16)), (byte)(assignVal >>> 8), (byte)assignVal};
|
||||||
|
else
|
||||||
|
throw new IllegalArgumentException("ECI assignment value out of range");
|
||||||
|
return new QrSegment(Mode.ECI, 0, data, data.length * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---- Instance fields ----*/
|
/*---- Instance fields ----*/
|
||||||
|
|
||||||
|
@ -228,7 +248,8 @@ public final class QrSegment {
|
||||||
NUMERIC (0x1, 10, 12, 14),
|
NUMERIC (0x1, 10, 12, 14),
|
||||||
ALPHANUMERIC(0x2, 9, 11, 13),
|
ALPHANUMERIC(0x2, 9, 11, 13),
|
||||||
BYTE (0x4, 8, 16, 16),
|
BYTE (0x4, 8, 16, 16),
|
||||||
KANJI (0x8, 8, 10, 12);
|
KANJI (0x8, 8, 10, 12),
|
||||||
|
ECI (0x7, 0, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
/*-- Fields --*/
|
/*-- Fields --*/
|
||||||
|
|
|
@ -46,13 +46,14 @@
|
||||||
* - Function makeNumeric(str data) -> QrSegment
|
* - Function makeNumeric(str data) -> QrSegment
|
||||||
* - Function makeAlphanumeric(str data) -> QrSegment
|
* - Function makeAlphanumeric(str data) -> QrSegment
|
||||||
* - Function makeSegments(str text) -> list<QrSegment>
|
* - Function makeSegments(str text) -> list<QrSegment>
|
||||||
|
* - Function makeEci(int assignVal) -> QrSegment
|
||||||
* - Constructor QrSegment(QrSegment.Mode mode, int numChars, list<int> bitData)
|
* - Constructor QrSegment(QrSegment.Mode mode, int numChars, list<int> bitData)
|
||||||
* - Field QrSegment.Mode mode
|
* - Field QrSegment.Mode mode
|
||||||
* - Field int numChars
|
* - Field int numChars
|
||||||
* - Method getBits() -> list<int>
|
* - Method getBits() -> list<int>
|
||||||
* - Constants RegExp NUMERIC_REGEX, ALPHANUMERIC_REGEX
|
* - Constants RegExp NUMERIC_REGEX, ALPHANUMERIC_REGEX
|
||||||
* - Enum Mode:
|
* - Enum Mode:
|
||||||
* - Constants NUMERIC, ALPHANUMERIC, BYTE, KANJI
|
* - Constants NUMERIC, ALPHANUMERIC, BYTE, KANJI, ECI
|
||||||
*/
|
*/
|
||||||
var qrcodegen = new function() {
|
var qrcodegen = new function() {
|
||||||
|
|
||||||
|
@ -815,6 +816,25 @@ var qrcodegen = new function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a segment representing an Extended Channel Interpretation (ECI) designator with the given assignment value.
|
||||||
|
*/
|
||||||
|
this.QrSegment.makeEci = function(assignVal) {
|
||||||
|
var bb = new BitBuffer();
|
||||||
|
if (0 <= assignVal && assignVal < (1 << 7))
|
||||||
|
bb.appendBits(assignVal, 8);
|
||||||
|
else if ((1 << 7) <= assignVal && assignVal < (1 << 14)) {
|
||||||
|
bb.appendBits(2, 2);
|
||||||
|
bb.appendBits(assignVal, 14);
|
||||||
|
} else if ((1 << 14) <= assignVal && assignVal < 999999) {
|
||||||
|
bb.appendBits(6, 3);
|
||||||
|
bb.appendBits(assignVal, 21);
|
||||||
|
} else
|
||||||
|
throw "ECI assignment value out of range";
|
||||||
|
return new this(this.Mode.ECI, 0, bb.getBits());
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Package-private helper function.
|
// Package-private helper function.
|
||||||
this.QrSegment.getTotalBits = function(segs, version) {
|
this.QrSegment.getTotalBits = function(segs, version) {
|
||||||
if (version < 1 || version > 40)
|
if (version < 1 || version > 40)
|
||||||
|
@ -856,6 +876,7 @@ var qrcodegen = new function() {
|
||||||
ALPHANUMERIC: new Mode(0x2, [ 9, 11, 13]),
|
ALPHANUMERIC: new Mode(0x2, [ 9, 11, 13]),
|
||||||
BYTE : new Mode(0x4, [ 8, 16, 16]),
|
BYTE : new Mode(0x4, [ 8, 16, 16]),
|
||||||
KANJI : new Mode(0x8, [ 8, 10, 12]),
|
KANJI : new Mode(0x8, [ 8, 10, 12]),
|
||||||
|
ECI : new Mode(0x7, [ 0, 0, 0]),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,13 +47,14 @@ This module "qrcodegen", public members:
|
||||||
- Function make_numeric(str digits) -> QrSegment
|
- Function make_numeric(str digits) -> QrSegment
|
||||||
- Function make_alphanumeric(str text) -> QrSegment
|
- Function make_alphanumeric(str text) -> QrSegment
|
||||||
- Function make_segments(str text) -> list<QrSegment>
|
- Function make_segments(str text) -> list<QrSegment>
|
||||||
|
- Function make_eci(int assignval) -> QrSegment
|
||||||
- Constructor QrSegment(QrSegment.Mode mode, int numch, list<int> bitdata)
|
- Constructor QrSegment(QrSegment.Mode mode, int numch, list<int> bitdata)
|
||||||
- Method get_mode() -> QrSegment.Mode
|
- Method get_mode() -> QrSegment.Mode
|
||||||
- Method get_num_chars() -> int
|
- Method get_num_chars() -> int
|
||||||
- Method get_bits() -> list<int>
|
- Method get_bits() -> list<int>
|
||||||
- Constants regex NUMERIC_REGEX, ALPHANUMERIC_REGEX
|
- Constants regex NUMERIC_REGEX, ALPHANUMERIC_REGEX
|
||||||
- Enum Mode:
|
- Enum Mode:
|
||||||
- Constants NUMERIC, ALPHANUMERIC, BYTE, KANJI
|
- Constants NUMERIC, ALPHANUMERIC, BYTE, KANJI, ECI
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -669,6 +670,24 @@ class QrSegment(object):
|
||||||
return [QrSegment.make_bytes(text.encode("UTF-8"))]
|
return [QrSegment.make_bytes(text.encode("UTF-8"))]
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def make_eci(assignval):
|
||||||
|
"""Returns a segment representing an Extended Channel Interpretation
|
||||||
|
(ECI) designator with the given assignment value."""
|
||||||
|
bb = _BitBuffer()
|
||||||
|
if 0 <= assignval < (1 << 7):
|
||||||
|
bb.append_bits(assignval, 8)
|
||||||
|
elif (1 << 7) <= assignval < (1 << 14):
|
||||||
|
bb.append_bits(2, 2)
|
||||||
|
bb.append_bits(assignval, 14)
|
||||||
|
elif (1 << 14) <= assignval < 999999:
|
||||||
|
bb.append_bits(6, 3)
|
||||||
|
bb.append_bits(assignval, 21)
|
||||||
|
else:
|
||||||
|
raise ValueError("ECI assignment value out of range")
|
||||||
|
return QrSegment(QrSegment.Mode.ECI, 0, bb.get_bits())
|
||||||
|
|
||||||
|
|
||||||
# ---- Constructor ----
|
# ---- Constructor ----
|
||||||
|
|
||||||
def __init__(self, mode, numch, bitdata):
|
def __init__(self, mode, numch, bitdata):
|
||||||
|
@ -746,6 +765,7 @@ class QrSegment(object):
|
||||||
Mode.ALPHANUMERIC = Mode(0x2, ( 9, 11, 13))
|
Mode.ALPHANUMERIC = Mode(0x2, ( 9, 11, 13))
|
||||||
Mode.BYTE = Mode(0x4, ( 8, 16, 16))
|
Mode.BYTE = Mode(0x4, ( 8, 16, 16))
|
||||||
Mode.KANJI = Mode(0x8, ( 8, 10, 12))
|
Mode.KANJI = Mode(0x8, ( 8, 10, 12))
|
||||||
|
Mode.ECI = Mode(0x7, ( 0, 0, 0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue