From 20a05141ec530dec3a5e6392848d72aed05a652f Mon Sep 17 00:00:00 2001 From: Project Nayuki Date: Thu, 17 Aug 2017 21:29:15 +0000 Subject: [PATCH] Added C++ QrSegment constructor taking BitBuffer argument, updated existing code to use it. --- cpp/QrCodeGeneratorDemo.cpp | 19 ++++++++++++------- cpp/QrSegment.cpp | 32 ++++++++++++++++++++------------ cpp/QrSegment.hpp | 4 ++++ 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/cpp/QrCodeGeneratorDemo.cpp b/cpp/QrCodeGeneratorDemo.cpp index d730bb4..ed13d0b 100644 --- a/cpp/QrCodeGeneratorDemo.cpp +++ b/cpp/QrCodeGeneratorDemo.cpp @@ -29,6 +29,7 @@ #include #include #include +#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 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 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); } diff --git a/cpp/QrSegment.cpp b/cpp/QrSegment.cpp index f46f950..9fd42ff 100644 --- a/cpp/QrSegment.cpp +++ b/cpp/QrSegment.cpp @@ -24,7 +24,6 @@ #include #include #include -#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 &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::makeSegments(const char *text) { QrSegment QrSegment::makeEci(long assignVal) { - vector data; + BitBuffer bb; if (0 <= assignVal && assignVal < (1 << 7)) - data = {static_cast(assignVal)}; - else if ((1 << 7) <= assignVal && assignVal < (1 << 14)) - data = {static_cast(0x80 | (assignVal >> 8)), static_cast(assignVal)}; - else if ((1 << 14) <= assignVal && assignVal < 999999L) - data = {static_cast(0xC0 | (assignVal >> 16)), static_cast(assignVal >> 8), static_cast(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 &b, int bitLen) : mode(md), numChars(numCh), diff --git a/cpp/QrSegment.hpp b/cpp/QrSegment.hpp index 01e413a..ef99d55 100644 --- a/cpp/QrSegment.hpp +++ b/cpp/QrSegment.hpp @@ -25,6 +25,7 @@ #include #include +#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 &b, int bitLen);