Skip to content
Snippets Groups Projects
Commit f4215ddd authored by Evgeny Lavrik's avatar Evgeny Lavrik
Browse files

Added nayuki/QR-Code-generator at revision 9728f19

Added FairDbQr library
Added A4 Qr generation macro
parent 0f32a56a
No related branches found
No related tags found
No related merge requests found
......@@ -330,3 +330,5 @@ endif()
if (Boost_FOUND)
add_subdirectory(dbExamples)
endif()
add_subdirectory(dbUtils/Qr)
/*
* QR Code generator library (C++)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
#include "BitBuffer.hpp"
namespace qrcodegen {
BitBuffer::BitBuffer()
: std::vector<bool>() {}
std::vector<std::uint8_t> BitBuffer::getBytes() const {
std::vector<std::uint8_t> result(size() / 8 + (size() % 8 == 0 ? 0 : 1));
for (std::size_t i = 0; i < size(); i++)
result[i >> 3] |= (*this)[i] ? 1 << (7 - (i & 7)) : 0;
return result;
}
void BitBuffer::appendBits(std::uint32_t val, int len) {
if (len < 0 || len > 31 || val >> len != 0)
throw "Value out of range";
for (int i = len - 1; i >= 0; i--) // Append bit by bit
this->push_back(((val >> i) & 1) != 0);
}
}
/*
* QR Code generator library (C++)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
#pragma once
#include <cstdint>
#include <vector>
namespace qrcodegen {
/*
* An appendable sequence of bits (0's and 1's).
*/
class BitBuffer final : public std::vector<bool> {
/*---- Constructor ----*/
// Creates an empty bit buffer (length 0).
public: BitBuffer();
/*---- Methods ----*/
// Packs this buffer's bits into bytes in big endian,
// padding with '0' bit values, and returns the new vector.
public: std::vector<std::uint8_t> getBytes() const;
// Appends the given number of low bits of the given value
// to this sequence. Requires 0 <= val < 2^len.
public: void appendBits(std::uint32_t val, int len);
};
}
This diff is collapsed.
/*
* QR Code generator library (C++)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include "QrSegment.hpp"
namespace qrcodegen {
/*
* Represents an immutable square grid of black and white cells for a QR Code symbol, and
* provides static functions to create a QR Code from user-supplied textual or binary data.
* This class covers the QR Code model 2 specification, supporting all versions (sizes)
* from 1 to 40, all 4 error correction levels, and only 3 character encoding modes.
*/
class QrCode final {
/*---- Public helper enumeration ----*/
/*
* Represents the error correction level used in a QR Code symbol.
*/
public: enum class Ecc {
// Constants declared in ascending order of error protection.
LOW = 0, MEDIUM = 1, QUARTILE = 2, HIGH = 3
};
// Returns a value in the range 0 to 3 (unsigned 2-bit integer).
private: static int getFormatBits(Ecc ecl);
/*---- Public static factory functions ----*/
/*
* Returns a QR Code symbol representing the specified Unicode text string at the specified error correction level.
* As a conservative upper bound, this function is guaranteed to succeed for strings that have 2953 or fewer
* UTF-8 code units (not Unicode code points) if the low error correction level is used. The smallest possible
* QR Code version is automatically chosen for the output. The ECC level of the result may be higher than
* the ecl argument if it can be done without increasing the version.
*/
public: static QrCode encodeText(const char *text, Ecc ecl);
/*
* Returns a QR Code symbol representing the given binary data string at the given error correction level.
* This function always encodes using the binary segment mode, not any text mode. The maximum number of
* bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
* The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
*/
public: static QrCode encodeBinary(const std::vector<std::uint8_t> &data, Ecc ecl);
/*
* Returns a QR Code symbol representing the given data segments with the given encoding parameters.
* The smallest possible QR Code version within the given range is automatically chosen for the output.
* This function allows the user to create a custom sequence of segments that switches
* between modes (such as alphanumeric and binary) to encode text more efficiently.
* This function is considered to be lower level than simply encoding text or binary data.
*/
public: static QrCode encodeSegments(const std::vector<QrSegment> &segs, Ecc ecl,
int minVersion=1, int maxVersion=40, int mask=-1, bool boostEcl=true); // All optional parameters
/*---- Public constants ----*/
public: static constexpr int MIN_VERSION = 1;
public: static constexpr int MAX_VERSION = 40;
/*---- Instance fields ----*/
// Immutable scalar parameters
/* This QR Code symbol's version number, which is always between 1 and 40 (inclusive). */
private: int version;
/* The width and height of this QR Code symbol, measured in modules.
* Always equal to version &times; 4 + 17, in the range 21 to 177. */
private: int size;
/* The error correction level used in this QR Code symbol. */
private: Ecc errorCorrectionLevel;
/* The mask pattern used in this QR Code symbol, in the range 0 to 7 (i.e. unsigned 3-bit integer).
* Note that even if a constructor was called with automatic masking requested
* (mask = -1), the resulting object will still have a mask value between 0 and 7. */
private: int mask;
// Private grids of modules/pixels (conceptually immutable)
private: std::vector<std::vector<bool> > modules; // The modules of this QR Code symbol (false = white, true = black)
private: std::vector<std::vector<bool> > isFunction; // Indicates function modules that are not subjected to masking
/*---- Constructors ----*/
/*
* Creates a new QR Code symbol with the given version number, error correction level, binary data array,
* and mask number. This is a cumbersome low-level constructor that should not be invoked directly by the user.
* To go one level up, see the encodeSegments() function.
*/
public: QrCode(int ver, Ecc ecl, const std::vector<std::uint8_t> &dataCodewords, int mask);
/*---- Public instance methods ----*/
public: int getVersion() const;
public: int getSize() const;
public: Ecc getErrorCorrectionLevel() const;
public: int getMask() const;
/*
* Returns the color of the module (pixel) at the given coordinates, which is either
* false for white or true for black. The top left corner has the coordinates (x=0, y=0).
* If the given coordinates are out of bounds, then false (white) is returned.
*/
public: bool getModule(int x, int y) const;
/*
* Based on the given number of border modules to add as padding, this returns a
* string whose contents represents an SVG XML file that depicts this QR Code symbol.
* Note that Unix newlines (\n) are always used, regardless of the platform.
*/
public: std::string toSvgString(int border) const;
/*---- Private helper methods for constructor: Drawing function modules ----*/
private: void drawFunctionPatterns();
// Draws two copies of the format bits (with its own error correction code)
// based on the given mask and this object's error correction level field.
private: void drawFormatBits(int mask);
// Draws two copies of the version bits (with its own error correction code),
// based on this object's version field (which only has an effect for 7 <= version <= 40).
private: void drawVersion();
// Draws a 9*9 finder pattern including the border separator, with the center module at (x, y).
private: void drawFinderPattern(int x, int y);
// Draws a 5*5 alignment pattern, with the center module at (x, y).
private: void drawAlignmentPattern(int x, int y);
// Sets the color of a module and marks it as a function module.
// Only used by the constructor. Coordinates must be in range.
private: void setFunctionModule(int x, int y, bool isBlack);
// Returns the color of the module at the given coordinates, which must be in range.
private: bool module(int x, int y) const;
/*---- Private helper methods for constructor: Codewords and masking ----*/
// Returns a new byte string representing the given data with the appropriate error correction
// codewords appended to it, based on this object's version and error correction level.
private: std::vector<std::uint8_t> appendErrorCorrection(const std::vector<std::uint8_t> &data) const;
// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
// data area of this QR Code symbol. Function modules need to be marked off before this is called.
private: void drawCodewords(const std::vector<std::uint8_t> &data);
// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical
// properties, calling applyMask(m) twice with the same value is equivalent to no change at all.
// This means it is possible to apply a mask, undo it, and try another mask. Note that a final
// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.).
private: void applyMask(int mask);
// A messy helper function for the constructors. This QR Code must be in an unmasked state when this
// method is called. The given argument is the requested mask, which is -1 for auto or 0 to 7 for fixed.
// This method applies and returns the actual mask chosen, from 0 to 7.
private: int handleConstructorMasking(int mask);
// Calculates and returns the penalty score based on state of this QR Code's current modules.
// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
private: long getPenaltyScore() const;
/*---- Private static helper functions ----*/
// Returns a set of positions of the alignment patterns in ascending order. These positions are
// used on both the x and y axes. Each value in the resulting array is in the range [0, 177).
// This stateless pure function could be implemented as table of 40 variable-length lists of unsigned bytes.
private: static std::vector<int> getAlignmentPatternPositions(int ver);
// Returns the number of data bits that can be stored in a QR Code of the given version number, after
// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
private: static int getNumRawDataModules(int ver);
// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
// QR Code of the given version number and error correction level, with remainder bits discarded.
// This stateless pure function could be implemented as a (40*4)-cell lookup table.
private: static int getNumDataCodewords(int ver, Ecc ecl);
/*---- Private tables of constants ----*/
// For use in getPenaltyScore(), when evaluating which mask is best.
private: static const int PENALTY_N1;
private: static const int PENALTY_N2;
private: static const int PENALTY_N3;
private: static const int PENALTY_N4;
private: static const std::int8_t ECC_CODEWORDS_PER_BLOCK[4][41];
private: static const std::int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41];
/*---- Private helper class ----*/
/*
* Computes the Reed-Solomon error correction codewords for a sequence of data codewords
* at a given degree. Objects are immutable, and the state only depends on the degree.
* This class exists because each data block in a QR Code shares the same the divisor polynomial.
*/
private: class ReedSolomonGenerator final {
/*-- Immutable field --*/
// Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which
// is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}.
private: std::vector<std::uint8_t> coefficients;
/*-- Constructor --*/
/*
* Creates a Reed-Solomon ECC generator for the given degree. This could be implemented
* as a lookup table over all possible parameter values, instead of as an algorithm.
*/
public: explicit ReedSolomonGenerator(int degree);
/*-- Method --*/
/*
* Computes and returns the Reed-Solomon error correction codewords for the given
* sequence of data codewords. The returned object is always a new byte array.
* This method does not alter this object's state (because it is immutable).
*/
public: std::vector<std::uint8_t> getRemainder(const std::vector<std::uint8_t> &data) const;
/*-- Static function --*/
// Returns the product of the two given field elements modulo GF(2^8/0x11D).
// All inputs are valid. This could be implemented as a 256*256 lookup table.
private: static std::uint8_t multiply(std::uint8_t x, std::uint8_t y);
};
};
}
/*
* QR Code generator library (C++)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
#include <climits>
#include <cstring>
#include <utility>
#include "QrSegment.hpp"
using std::uint8_t;
using std::vector;
namespace qrcodegen {
QrSegment::Mode::Mode(int mode, int cc0, int cc1, int cc2) :
modeBits(mode) {
numBitsCharCount[0] = cc0;
numBitsCharCount[1] = cc1;
numBitsCharCount[2] = cc2;
}
int QrSegment::Mode::getModeBits() const {
return modeBits;
}
int QrSegment::Mode::numCharCountBits(int ver) const {
if ( 1 <= ver && ver <= 9) return numBitsCharCount[0];
else if (10 <= ver && ver <= 26) return numBitsCharCount[1];
else if (27 <= ver && ver <= 40) return numBitsCharCount[2];
else throw "Version number out of range";
}
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::BYTE (0x4, 8, 16, 16);
const QrSegment::Mode QrSegment::Mode::KANJI (0x8, 8, 10, 12);
const QrSegment::Mode QrSegment::Mode::ECI (0x7, 0, 0, 0);
QrSegment QrSegment::makeBytes(const vector<uint8_t> &data) {
if (data.size() > INT_MAX)
throw "Data too long";
BitBuffer bb;
for (uint8_t b : data)
bb.appendBits(b, 8);
return QrSegment(Mode::BYTE, static_cast<int>(data.size()), std::move(bb));
}
QrSegment QrSegment::makeNumeric(const char *digits) {
BitBuffer bb;
int accumData = 0;
int accumCount = 0;
int charCount = 0;
for (; *digits != '\0'; digits++, charCount++) {
char c = *digits;
if (c < '0' || c > '9')
throw "String contains non-numeric characters";
accumData = accumData * 10 + (c - '0');
accumCount++;
if (accumCount == 3) {
bb.appendBits(accumData, 10);
accumData = 0;
accumCount = 0;
}
}
if (accumCount > 0) // 1 or 2 digits remaining
bb.appendBits(accumData, accumCount * 3 + 1);
return QrSegment(Mode::NUMERIC, charCount, std::move(bb));
}
QrSegment QrSegment::makeAlphanumeric(const char *text) {
BitBuffer bb;
int accumData = 0;
int accumCount = 0;
int charCount = 0;
for (; *text != '\0'; text++, charCount++) {
const char *temp = std::strchr(ALPHANUMERIC_CHARSET, *text);
if (temp == nullptr)
throw "String contains unencodable characters in alphanumeric mode";
accumData = accumData * 45 + (temp - ALPHANUMERIC_CHARSET);
accumCount++;
if (accumCount == 2) {
bb.appendBits(accumData, 11);
accumData = 0;
accumCount = 0;
}
}
if (accumCount > 0) // 1 character remaining
bb.appendBits(accumData, 6);
return QrSegment(Mode::ALPHANUMERIC, charCount, std::move(bb));
}
vector<QrSegment> QrSegment::makeSegments(const char *text) {
// Select the most efficient segment encoding automatically
vector<QrSegment> result;
if (*text == '\0'); // Leave result empty
else if (isNumeric(text))
result.push_back(makeNumeric(text));
else if (isAlphanumeric(text))
result.push_back(makeAlphanumeric(text));
else {
vector<uint8_t> bytes;
for (; *text != '\0'; text++)
bytes.push_back(static_cast<uint8_t>(*text));
result.push_back(makeBytes(bytes));
}
return result;
}
QrSegment QrSegment::makeEci(long assignVal) {
BitBuffer bb;
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 < 1000000L) {
bb.appendBits(6, 3);
bb.appendBits(assignVal, 21);
} else
throw "ECI assignment value out of range";
return QrSegment(Mode::ECI, 0, std::move(bb));
}
QrSegment::QrSegment(Mode md, int numCh, const std::vector<bool> &dt) :
mode(md),
numChars(numCh),
data(dt) {
if (numCh < 0)
throw "Invalid value";
}
QrSegment::QrSegment(Mode md, int numCh, std::vector<bool> &&dt) :
mode(md),
numChars(numCh),
data(std::move(dt)) {
if (numCh < 0)
throw "Invalid value";
}
int QrSegment::getTotalBits(const vector<QrSegment> &segs, int version) {
if (version < 1 || version > 40)
throw "Version number out of range";
int result = 0;
for (const QrSegment &seg : segs) {
int ccbits = seg.mode.numCharCountBits(version);
// Fail if segment length value doesn't fit in the length field's bit-width
if (seg.numChars >= (1L << ccbits))
return -1;
if (4 + ccbits > INT_MAX - result)
return -1;
result += 4 + ccbits;
if (seg.data.size() > static_cast<unsigned int>(INT_MAX - result))
return -1;
result += static_cast<int>(seg.data.size());
}
return result;
}
bool QrSegment::isAlphanumeric(const char *text) {
for (; *text != '\0'; text++) {
if (std::strchr(ALPHANUMERIC_CHARSET, *text) == nullptr)
return false;
}
return true;
}
bool QrSegment::isNumeric(const char *text) {
for (; *text != '\0'; text++) {
char c = *text;
if (c < '0' || c > '9')
return false;
}
return true;
}
QrSegment::Mode QrSegment::getMode() const {
return mode;
}
int QrSegment::getNumChars() const {
return numChars;
}
const std::vector<bool> &QrSegment::getData() const {
return data;
}
const char *QrSegment::ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
}
/*
* QR Code generator library (C++)
*
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* - The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* - The Software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. In no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the Software or the use or other dealings in the
* Software.
*/
#pragma once
#include <cstdint>
#include <vector>
#include "BitBuffer.hpp"
namespace qrcodegen {
/*
* Represents a character string to be encoded in a QR Code symbol. Each segment has
* a mode, and a sequence of characters that is already encoded as a sequence of bits.
* Instances of this class are immutable.
* This segment class imposes no length restrictions, but QR Codes have restrictions.
* Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
* Any segment longer than this is meaningless for the purpose of generating QR Codes.
*/
class QrSegment final {
/*---- Public helper enumeration ----*/
/*
* The mode field of a segment. Immutable. Provides methods to retrieve closely related values.
*/
public: class Mode final {
/*-- Constants --*/
public: static const Mode NUMERIC;
public: static const Mode ALPHANUMERIC;
public: static const Mode BYTE;
public: static const Mode KANJI;
public: static const Mode ECI;
/*-- Fields --*/
private: int modeBits;
private: int numBitsCharCount[3];
/*-- Constructor --*/
private: Mode(int mode, int cc0, int cc1, int cc2);
/*-- Methods --*/
/*
* (Package-private) Returns the mode indicator bits, which is an unsigned 4-bit value (range 0 to 15).
*/
public: int getModeBits() const;
/*
* (Package-private) Returns the bit width of the segment character count field for this mode object at the given version number.
*/
public: int numCharCountBits(int ver) const;
};
/*---- Public static factory functions ----*/
/*
* Returns a segment representing the given binary data encoded in byte mode.
*/
public: static QrSegment makeBytes(const std::vector<std::uint8_t> &data);
/*
* Returns a segment representing the given string of decimal digits encoded in numeric mode.
*/
public: static QrSegment makeNumeric(const char *digits);
/*
* Returns a segment representing the given text string encoded in alphanumeric mode.
* The characters allowed are: 0 to 9, A to Z (uppercase only), space,
* dollar, percent, asterisk, plus, hyphen, period, slash, colon.
*/
public: static QrSegment makeAlphanumeric(const char *text);
/*
* Returns a list of zero or more segments to represent the given text string.
* The result may use various segment modes and switch modes to optimize the length of the bit stream.
*/
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 ----*/
/*
* Tests whether the given string can be encoded as a segment in alphanumeric mode.
*/
public: static bool isAlphanumeric(const char *text);
/*
* Tests whether the given string can be encoded as a segment in numeric mode.
*/
public: static bool isNumeric(const char *text);
/*---- Instance fields ----*/
/* The mode indicator for this segment. */
private: Mode mode;
/* The length of this segment's unencoded data, measured in characters. Always zero or positive. */
private: int numChars;
/* The data bits of this segment. */
private: std::vector<bool> data;
/*---- Constructors ----*/
/*
* Creates a new QR Code data segment with the given parameters and data.
*/
public: QrSegment(Mode md, int numCh, const std::vector<bool> &dt);
/*
* Creates a new QR Code data segment with the given parameters and data.
*/
public: QrSegment(Mode md, int numCh, std::vector<bool> &&dt);
/*---- Methods ----*/
public: Mode getMode() const;
public: int getNumChars() const;
public: const std::vector<bool> &getData() const;
// Package-private helper function.
public: static int getTotalBits(const std::vector<QrSegment> &segs, int version);
/*---- Private constant ----*/
/* The set of all legal characters in alphanumeric mode, where each character value maps to the index in the string. */
private: static const char *ALPHANUMERIC_CHARSET;
};
}
QR Code generator library
=========================
Introduction
------------
This project aims to be the best, clearest QR Code generator library in multiple languages. The primary goals are flexible options and absolute correctness. Secondary goals are compact implementation size and good documentation comments.
Home page with live JavaScript demo, extensive descriptions, and competitor comparisons: [https://www.nayuki.io/page/qr-code-generator-library](https://www.nayuki.io/page/qr-code-generator-library)
Features
--------
Core features:
* Available in 6 programming languages, all with nearly equal functionality: Java, JavaScript, Python, C++, C, Rust
* Significantly shorter code but more documentation comments compared to competing libraries
* Supports encoding all 40 versions (sizes) and all 4 error correction levels, as per the QR Code Model 2 standard
* Output formats: Raw modules/pixels of the QR symbol (all languages), SVG XML string (all languages except C), `BufferedImage` raster bitmap (Java only), HTML5 canvas (JavaScript only)
* Encodes numeric and special-alphanumeric text in less space than general text
* Open source code under the permissive MIT License
Manual parameters:
* User can specify minimum and maximum version numbers allowed, then library will automatically choose smallest version in the range that fits the data
* User can specify mask pattern manually, otherwise library will automatically evaluate all 8 masks and select the optimal one
* User can specify absolute error correction level, or allow the library to boost it if it doesn't increase the version number
* User can create a list of data segments manually and add ECI segments (all languages except C)
Optional advanced features (Java only):
* Encodes Japanese Unicode text in kanji mode to save a lot of space compared to UTF-8 bytes
* Computes optimal segment mode switching for text with mixed numeric/alphanumeric/general parts
Examples
--------
Java language:
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import io.nayuki.qrcodegen.*;
// Simple operation
QrCode qr0 = QrCode.encodeText("Hello, world!", QrCode.Ecc.MEDIUM);
BufferedImage img = qr0.toImage(4, 10);
ImageIO.write(img, "png", new File("qr-code.png"));
// Manual operation
List<QrSegment> segs = QrSegment.makeSegments("3141592653589793238462643383");
QrCode qr1 = QrCode.encodeSegments(segs, QrCode.Ecc.HIGH, 5, 5, 2, false);
for (int y = 0; y < qr1.size; y++) {
for (int x = 0; x < qr1.size; x++) {
(... paint qr1.getModule(x, y) ...)
}
}
JavaScript language:
// Name abbreviated for the sake of these examples here
var QRC = qrcodegen.QrCode;
// Simple operation
var qr0 = QRC.encodeText("Hello, world!", QRC.Ecc.MEDIUM);
var svg = qr0.toSvgString(4);
// Manual operation
var segs = qrcodegen.QrSegment.makeSegments("3141592653589793238462643383");
var qr1 = QRC.encodeSegments(segs, QRC.Ecc.HIGH, 5, 5, 2, false);
for (var y = 0; y < qr1.size; y++) {
for (var x = 0; x < qr1.size; x++) {
(... paint qr1.getModule(x, y) ...)
}
}
Python language:
from qrcodegen import *
# Simple operation
qr0 = QrCode.encode_text("Hello, world!", QrCode.Ecc.MEDIUM)
svg = qr0.to_svg_str(4)
# Manual operation
segs = QrSegment.make_segments("3141592653589793238462643383")
qr1 = QrCode.encode_segments(segs, QrCode.Ecc.HIGH, 5, 5, 2, False)
for y in range(qr1.get_size()):
for x in range(qr1.get_size()):
(... paint qr1.get_module(x, y) ...)
C++ language:
#include <string>
#include <vector>
#include "QrCode.hpp"
using namespace qrcodegen;
// Simple operation
QrCode qr0 = QrCode::encodeText("Hello, world!", QrCode::Ecc::MEDIUM);
std::string svg = qr0.toSvgString(4);
// Manual operation
std::vector<QrSegment> segs =
QrSegment::makeSegments("3141592653589793238462643383");
QrCode qr1 = QrCode::encodeSegments(
segs, QrCode::Ecc::HIGH, 5, 5, 2, false);
for (int y = 0; y < qr1.getSize(); y++) {
for (int x = 0; x < qr1.getSize(); x++) {
(... paint qr1.getModule(x, y) ...)
}
}
C language:
#include <stdbool.h>
#include <stdint.h>
#include "qrcodegen.h"
// Text data
uint8_t qr0[qrcodegen_BUFFER_LEN_MAX];
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
bool ok = qrcodegen_encodeText("Hello, world!",
tempBuffer, qr0, qrcodegen_Ecc_MEDIUM,
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX,
qrcodegen_Mask_AUTO, true);
if (!ok)
return;
int size = qrcodegen_getSize(qr0);
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
(... paint qrcodegen_getModule(qr0, x, y) ...)
}
}
// Binary data
uint8_t dataAndTemp[qrcodegen_BUFFER_LEN_FOR_VERSION(7)]
= {0xE3, 0x81, 0x82};
uint8_t qr1[qrcodegen_BUFFER_LEN_FOR_VERSION(7)];
ok = qrcodegen_encodeBinary(dataAndTemp, 3, qr1,
qrcodegen_Ecc_HIGH, 2, 7, qrcodegen_Mask_4, false);
Rust language:
extern crate qrcodegen;
use qrcodegen::QrCode;
use qrcodegen::QrCodeEcc;
use qrcodegen::QrSegment;
// Simple operation
let qr0 = QrCode::encode_text("Hello, world!",
QrCodeEcc::Medium).unwrap();
let svg = qr0.to_svg_string(4);
// Manual operation
let chrs: Vec<char> = "3141592653589793238462643383".chars().collect();
let segs = QrSegment::make_segments(&chrs);
let qr1 = QrCode::encode_segments_advanced(
&segs, QrCodeEcc::High, 5, 5, Some(2), false).unwrap();
for y in 0 .. qr1.size() {
for x in 0 .. qr1.size() {
(... paint qr1.get_module(x, y) ...)
}
}
More information about QR Code technology and this library's design can be found on the project home page.
License
-------
Copyright © 2017 Project Nayuki. (MIT License)
[https://www.nayuki.io/page/qr-code-generator-library](https://www.nayuki.io/page/qr-code-generator-library)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
* The Software is provided "as is", without warranty of any kind, express or
implied, including but not limited to the warranties of merchantability,
fitness for a particular purpose and noninfringement. In no event shall the
authors or copyright holders be liable for any claim, damages or other
liability, whether in an action of contract, tort or otherwise, arising from,
out of or in connection with the Software or the use or other dealings in the
Software.
9728f19
\ No newline at end of file
################################################################################
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# #
# This software is distributed under the terms of the #
# GNU Lesser General Public Licence version 3 (LGPL) version 3, #
# copied verbatim in the file "LICENSE" #
################################################################################
# Create a library called "FairDbQr"
Message("-- Compiling FairDbQr")
set(INCLUDE_DIRECTORIES
${CMAKE_SOURCE_DIR}/dbUtils/Qr
)
include_directories(${INCLUDE_DIRECTORIES})
set(LINK_DIRECTORIES
)
link_directories(${LINK_DIRECTORIES})
set(NO_DICT_SRCS
${CMAKE_SOURCE_DIR}/db3rdParty/qr/BitBuffer.cpp
${CMAKE_SOURCE_DIR}/db3rdParty/qr/QrCode.cpp
${CMAKE_SOURCE_DIR}/db3rdParty/qr/QrSegment.cpp
)
set(SRCS
FairDbQr.cxx
)
set(NO_DICT_HEADERS
${CMAKE_SOURCE_DIR}/db3rdParty/qr/BitBuffer.hpp
${CMAKE_SOURCE_DIR}/db3rdParty/qr/QrCode.hpp
${CMAKE_SOURCE_DIR}/db3rdParty/qr/QrSegment.hpp
)
set(HEADERS
FairDbQr.h
)
install(FILES "${CMAKE_SOURCE_DIR}/db3rdParty/qr/BitBuffer.hpp" DESTINATION include/qr)
install(FILES "${CMAKE_SOURCE_DIR}/db3rdParty/qr/QrCode.hpp" DESTINATION include/qr)
install(FILES "${CMAKE_SOURCE_DIR}/db3rdParty/qr/QrSegment.hpp" DESTINATION include/qr)
set(LINKDEF FairDbQrLinkDef.h)
set(LIBRARY_NAME FairDbQr)
set(DEPENDENCIES
FairDB Core Hist
)
GENERATE_LIBRARY()
#include "FairDbQr.h"
using qrcodegen::QrCode;
using qrcodegen::QrSegment;
TH2C* FairDbQr::EncodeString(std::string string)
{
const char *text = string.c_str();
const QrCode::Ecc errCorLvl = QrCode::Ecc::LOW;
const QrCode qr = QrCode::encodeText(text, errCorLvl);
Int_t size = qr.getSize();
TH2C *hist = new TH2C("QR Code", text, size, 0, size, size, 0, size);
for (Int_t x = 0; x < size; x++) {
for (Int_t y = 0; y < size; y++) {
if (qr.getModule(x, y)) {
hist->Fill(x,y);
}
}
}
hist->SetStats(0);
hist->SetMinimum(0);
hist->SetMaximum(1);
return hist;
}
#ifndef FAIRDBQR_H
#define FAIRDBQR_H
#include "Rtypes.h"
#include "TObject.h"
#include "TH2D.h"
#include "qr/BitBuffer.hpp"
#include "qr/QrCode.hpp"
#include "qr/QrSegment.hpp"
class FairDbQr: public TObject
{
public:
static TH2C* EncodeString(std::string string);
ClassDef(FairDbQr, 0);
};
#endif // FAIRDBQR_H
/********************************************************************************
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence version 3 (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class FairDbQr;
#endif
ID0
ID1
ID2
ID3
ID4
ID5
ID6
ID7
ID8
ID9
ID10
ID11
ID12
ID13
ID14
ID15
ID16
ID17
ID18
ID19
ID20
ID21
ID22
ID23
ID24
ID25
ID26
ID27
ID28
ID29
ID30
ID31
ID32
ID33
ID34
ID35
ID36
ID37
ID38
ID39
ID40
ID41
ID42
ID43
ID44
ID45
ID46
ID47
ID48
ID49
ID50
ID51
ID52
ID53
ID54
ID55
ID56
ID57
ID58
ID59
ID60
ID61
ID62
ID63
\ No newline at end of file
// Loads text strings from file QrInput.txt in current directory and
// creates an A4 paper sized canvas filled with QR codes
void QrPage()
{
Int_t n = 0;
const Int_t max = 1000;
std::vector< std::string > ids;
std::string line;
const char *file = "QrInput.txt";
ifstream data("QrInput.txt");
if (!data.good())
{
std::cout << "File does not exist, not plotting anything" << std::endl;
return;
}
while(!data.eof())
{
std::getline(data, line);
ids.emplace_back(std::string(line));
}
gStyle->SetPalette(0);
gStyle->SetOptStat(0);
gStyle->SetOptTitle(0);
gStyle->SetPadLeftMargin(0.0);
gStyle->SetPadRightMargin(0.00);
gStyle->SetPadTopMargin(0.25);
gStyle->SetPadBottomMargin(0.00);
TCanvas *qrCanvas = new TCanvas("qrCanvas", "qrCanvas", 210*2, 297*2);
qrCanvas->SetWindowSize(210*2, 297*2);
qrCanvas->DivideSquare(64);
for (Int_t i = 0; i < ids.size(); i++)
{
qrCanvas->cd(i+1);
TH2C *hcol1 = FairDbQr::EncodeString(ids[i]);
hcol1->SetName(TString::Format("QR%d", i).Data());
hcol1->Draw("COL A");
TPaveText *pt = new TPaveText(0.0,1.0,1.0,0.85, "NDC");
pt->AddText(ids[i].c_str());
pt->SetFillColor(kWhite);
pt->SetBorderSize(0);
pt->Draw();
}
qrCanvas->SaveAs("QrPage.pdf");
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment