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

@ -24,7 +24,6 @@
#include <climits>
#include <cstddef>
#include <cstring>
#include "BitBuffer.hpp"
#include "QrSegment.hpp"
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) {
if (data.size() >= (unsigned int)INT_MAX / 8)
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
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
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) {
vector<uint8_t> data;
BitBuffer bb;
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
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 < 999999L) {
bb.appendBits(6, 3);
bb.appendBits(assignVal, 21);
} else
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) :
mode(md),
numChars(numCh),

@ -25,6 +25,7 @@
#include <cstdint>
#include <vector>
#include "BitBuffer.hpp"
namespace qrcodegen {
@ -148,6 +149,9 @@ class QrSegment final {
/*
* 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);

Loading…
Cancel
Save