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

This commit is contained in:
Project Nayuki 2017-08-17 21:29:15 +00:00
parent 5a47e04b52
commit 20a05141ec
3 changed files with 36 additions and 19 deletions

View File

@ -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);
}

View File

@ -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),

View File

@ -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);