Added C++ QrSegment constructor taking BitBuffer argument, updated existing code to use it.

pull/16/head
Project Nayuki 7 years ago
parent 5a47e04b52
commit 20a05141ec

@ -29,6 +29,7 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
#include "BitBuffer.hpp"
#include "QrCode.hpp" #include "QrCode.hpp"
using std::uint8_t; using std::uint8_t;
@ -139,15 +140,19 @@ static void doSegmentDemo() {
const QrCode qr4 = QrCode::encodeText(madoka, QrCode::Ecc::LOW); const QrCode qr4 = QrCode::encodeText(madoka, QrCode::Ecc::LOW);
printQr(qr4); printQr(qr4);
const std::vector<uint8_t> packedKanjiData{ // Kanji mode encoding (13 bits per character) const std::vector<int> packedKanjiData{ // Kanji mode encoding (13 bits per character)
0x01, 0xAC, 0x00, 0x9F, 0x80, 0xAE, 0xD5, 0x6B, 0x85, 0x70, 0x0035, 0x1002, 0x0FC0, 0x0AED, 0x0AD7,
0x28, 0xE1, 0x29, 0x02, 0xC8, 0x6F, 0x43, 0x1A, 0x18, 0xA0, 0x015C, 0x0147, 0x0129, 0x0059, 0x01BD,
0x1B, 0x05, 0x04, 0x28, 0x80, 0x01, 0x00, 0x00, 0x92, 0x44, 0x018D, 0x018A, 0x0036, 0x0141, 0x0144,
0x80, 0x24, 0x90, 0x00, 0x04, 0x10, 0x20, 0xA1, 0x13, 0x08, 0x0001, 0x0000, 0x0249, 0x0240, 0x0249,
0xA8, 0x00, 0x04, 0x10, 0x1F, 0xF0, 0x04, 0x00, 0x0000, 0x0104, 0x0105, 0x0113, 0x0115,
0x0000, 0x0208, 0x01FF, 0x0008,
}; };
qrcodegen::BitBuffer bb;
for (int c : packedKanjiData)
bb.appendBits(c, 13);
segs.clear(); segs.clear();
segs.push_back(QrSegment(QrSegment::Mode::KANJI, 29, packedKanjiData, 377)); segs.push_back(QrSegment(QrSegment::Mode::KANJI, packedKanjiData.size(), bb));
const QrCode qr5 = QrCode::encodeSegments(segs, QrCode::Ecc::LOW); const QrCode qr5 = QrCode::encodeSegments(segs, QrCode::Ecc::LOW);
printQr(qr5); printQr(qr5);
} }

@ -24,7 +24,6 @@
#include <climits> #include <climits>
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
#include "BitBuffer.hpp"
#include "QrSegment.hpp" #include "QrSegment.hpp"
using std::uint8_t; using std::uint8_t;
@ -60,7 +59,10 @@ const QrSegment::Mode QrSegment::Mode::ECI (0x7, 0, 0, 0);
QrSegment QrSegment::makeBytes(const vector<uint8_t> &data) { QrSegment QrSegment::makeBytes(const vector<uint8_t> &data) {
if (data.size() >= (unsigned int)INT_MAX / 8) if (data.size() >= (unsigned int)INT_MAX / 8)
throw "Buffer too long"; throw "Buffer too long";
return QrSegment(Mode::BYTE, (int)data.size(), data, (int)data.size() * 8); BitBuffer bb;
for (uint8_t b : data)
bb.appendBits(b, 8);
return QrSegment(Mode::BYTE, (int)data.size(), bb);
} }
@ -83,7 +85,7 @@ QrSegment QrSegment::makeNumeric(const char *digits) {
} }
if (accumCount > 0) // 1 or 2 digits remaining if (accumCount > 0) // 1 or 2 digits remaining
bb.appendBits(accumData, accumCount * 3 + 1); bb.appendBits(accumData, accumCount * 3 + 1);
return QrSegment(Mode::NUMERIC, charCount, bb.getBytes(), bb.size()); return QrSegment(Mode::NUMERIC, charCount, bb);
} }
@ -106,7 +108,7 @@ QrSegment QrSegment::makeAlphanumeric(const char *text) {
} }
if (accumCount > 0) // 1 character remaining if (accumCount > 0) // 1 character remaining
bb.appendBits(accumData, 6); bb.appendBits(accumData, 6);
return QrSegment(Mode::ALPHANUMERIC, charCount, bb.getBytes(), bb.size()); return QrSegment(Mode::ALPHANUMERIC, charCount, bb);
} }
@ -129,19 +131,25 @@ vector<QrSegment> QrSegment::makeSegments(const char *text) {
QrSegment QrSegment::makeEci(long assignVal) { QrSegment QrSegment::makeEci(long assignVal) {
vector<uint8_t> data; BitBuffer bb;
if (0 <= assignVal && assignVal < (1 << 7)) if (0 <= assignVal && assignVal < (1 << 7))
data = {static_cast<uint8_t>(assignVal)}; bb.appendBits(assignVal, 8);
else if ((1 << 7) <= assignVal && assignVal < (1 << 14)) else if ((1 << 7) <= assignVal && assignVal < (1 << 14)) {
data = {static_cast<uint8_t>(0x80 | (assignVal >> 8)), static_cast<uint8_t>(assignVal)}; bb.appendBits(2, 2);
else if ((1 << 14) <= assignVal && assignVal < 999999L) bb.appendBits(assignVal, 14);
data = {static_cast<uint8_t>(0xC0 | (assignVal >> 16)), static_cast<uint8_t>(assignVal >> 8), static_cast<uint8_t>(assignVal)}; } else if ((1 << 14) <= assignVal && assignVal < 999999L) {
else bb.appendBits(6, 3);
bb.appendBits(assignVal, 21);
} else
throw "ECI assignment value out of range"; throw "ECI assignment value out of range";
return QrSegment(Mode::ECI, 0, data, data.size() * 8); return QrSegment(Mode::ECI, 0, bb);
} }
QrSegment::QrSegment(const Mode &md, int numCh, const BitBuffer &data)
: QrSegment(md, numCh, data.getBytes(), data.size()) {}
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),

@ -25,6 +25,7 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
#include "BitBuffer.hpp"
namespace qrcodegen { namespace qrcodegen {
@ -148,6 +149,9 @@ class QrSegment final {
/* /*
* Creates a new QR Code data segment with the given parameters and data. * Creates a new QR Code data segment with the given parameters and data.
*/ */
public: QrSegment(const Mode &md, int numCh, const BitBuffer &data);
public: QrSegment(const Mode &md, int numCh, const std::vector<std::uint8_t> &b, int bitLen); public: QrSegment(const Mode &md, int numCh, const std::vector<std::uint8_t> &b, int bitLen);

Loading…
Cancel
Save