EstervQrCode 1.1.1
Library for qr code manipulation
qrcode_gen.hpp
1 /*
2  * QR Code generator library (C++)
3  *
4  * Copyright (c) Project Nayuki. (MIT License)
5  * https://www.nayuki.io/page/qr-code-generator-library
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  * - The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  * - The Software is provided "as is", without warranty of any kind, express or
16  * implied, including but not limited to the warranties of merchantability,
17  * fitness for a particular purpose and noninfringement. In no event shall the
18  * authors or copyright holders be liable for any claim, damages or other
19  * liability, whether in an action of contract, tort or otherwise, arising from,
20  * out of or in connection with the Software or the use or other dealings in the
21  * Software.
22  */
23 
24 #pragma once
25 
26 #include <array>
27 #include <cstdint>
28 #include <stdexcept>
29 #include <string>
30 #include <vector>
31 #include <climits>
32 #include <sstream>
33 
35 
36  /*
37  * A segment of character/binary/control data in a QR Code symbol.
38  * Instances of this class are immutable.
39  * The mid-level way to create a segment is to take the payload data
40  * and call a static factory function such as QrSegment::makeNumeric().
41  * The low-level way to create a segment is to custom-make the bit buffer
42  * and call the QrSegment() constructor with appropriate values.
43  * This segment class imposes no length restrictions, but QR Codes have restrictions.
44  * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
45  * Any segment longer than this is meaningless for the purpose of generating QR Codes.
46  */
47 
48  class QrSegment final {
49 
50  /*---- Public helper enumeration ----*/
51 
52  /*
53  * Describes how a segment's data bits are interpreted. Immutable.
54  */
55  public: class Mode final {
56 
57  /*-- Constants --*/
58 
59  public: static const Mode NUMERIC;
60  public: static const Mode ALPHANUMERIC;
61  public: static const Mode BYTE;
62  public: static const Mode KANJI;
63  public: static const Mode ECI;
64 
65 
66  /*-- Fields --*/
67 
68  // The mode indicator bits, which is a uint4 value (range 0 to 15).
69  private: int modeBits;
70 
71  // Number of character count bits for three different version ranges.
72  private: int numBitsCharCount[3];
73 
74 
75  /*-- Constructor --*/
76 
77  private: Mode(int mode, int cc0, int cc1, int cc2);
78 
79 
80  /*-- Methods --*/
81 
82  /*
83  * (Package-private) Returns the mode indicator bits, which is an unsigned 4-bit value (range 0 to 15).
84  */
85  public: int getModeBits() const;
86 
87  /*
88  * (Package-private) Returns the bit width of the character count field for a segment in
89  * this mode in a QR Code at the given version number. The result is in the range [0, 16].
90  */
91  public: int numCharCountBits(int ver) const;
92 
93  };
94 
95 
96 
97  /*---- Static factory functions (mid level) ----*/
98 
99  /*
100  * Returns a segment representing the given binary data encoded in
101  * byte mode. All input byte vectors are acceptable. Any text string
102  * can be converted to UTF-8 bytes and encoded as a byte mode segment.
103  */
104  public: static QrSegment makeBytes(const std::vector<std::uint8_t> &data);
105 
106 
107  /*
108  * Returns a segment representing the given string of decimal digits encoded in numeric mode.
109  */
110  public: static QrSegment makeNumeric(const char *digits);
111 
112 
113  /*
114  * Returns a segment representing the given text string encoded in alphanumeric mode.
115  * The characters allowed are: 0 to 9, A to Z (uppercase only), space,
116  * dollar, percent, asterisk, plus, hyphen, period, slash, colon.
117  */
118  public: static QrSegment makeAlphanumeric(const char *text);
119 
120 
121  /*
122  * Returns a list of zero or more segments to represent the given text string. The result
123  * may use various segment modes and switch modes to optimize the length of the bit stream.
124  */
125  public: static std::vector<QrSegment> makeSegments(const char *text);
126 
127 
128  /*
129  * Returns a segment representing an Extended Channel Interpretation
130  * (ECI) designator with the given assignment value.
131  */
132  public: static QrSegment makeEci(long assignVal);
133 
134 
135  /*---- Public static helper functions ----*/
136 
137  /*
138  * Tests whether the given string can be encoded as a segment in numeric mode.
139  * A string is encodable iff each character is in the range 0 to 9.
140  */
141  public: static bool isNumeric(const char *text);
142 
143 
144  /*
145  * Tests whether the given string can be encoded as a segment in alphanumeric mode.
146  * A string is encodable iff each character is in the following set: 0 to 9, A to Z
147  * (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.
148  */
149  public: static bool isAlphanumeric(const char *text);
150 
151 
152 
153  /*---- Instance fields ----*/
154 
155  /* The mode indicator of this segment. Accessed through getMode(). */
156  private: const Mode *mode;
157 
158  /* The length of this segment's unencoded data. Measured in characters for
159  * numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode.
160  * Always zero or positive. Not the same as the data's bit length.
161  * Accessed through getNumChars(). */
162  private: int numChars;
163 
164  /* The data bits of this segment. Accessed through getData(). */
165  private: std::vector<bool> data;
166 
167 
168  /*---- Constructors (low level) ----*/
169 
170  /*
171  * Creates a new QR Code segment with the given attributes and data.
172  * The character count (numCh) must agree with the mode and the bit buffer length,
173  * but the constraint isn't checked. The given bit buffer is copied and stored.
174  */
175  public: QrSegment(const Mode &md, int numCh, const std::vector<bool> &dt);
176 
177 
178  /*
179  * Creates a new QR Code segment with the given parameters and data.
180  * The character count (numCh) must agree with the mode and the bit buffer length,
181  * but the constraint isn't checked. The given bit buffer is moved and stored.
182  */
183  public: QrSegment(const Mode &md, int numCh, std::vector<bool> &&dt);
184 
185 
186  /*---- Methods ----*/
187 
188  /*
189  * Returns the mode field of this segment.
190  */
191  public: const Mode &getMode() const;
192 
193 
194  /*
195  * Returns the character count field of this segment.
196  */
197  public: int getNumChars() const;
198 
199 
200  /*
201  * Returns the data bits of this segment.
202  */
203  public: const std::vector<bool> &getData() const;
204 
205 
206  // (Package-private) Calculates the number of bits needed to encode the given segments at
207  // the given version. Returns a non-negative number if successful. Otherwise returns -1 if a
208  // segment has too many characters to fit its length field, or the total bits exceeds INT_MAX.
209  public: static int getTotalBits(const std::vector<QrSegment> &segs, int version);
210 
211 
212  /*---- Private constant ----*/
213 
214  /* The set of all legal characters in alphanumeric mode, where
215  * each character value maps to the index in the string. */
216  private: static const char *ALPHANUMERIC_CHARSET;
217 
218  };
219 
220 
221 
222  /*
223  * A QR Code symbol, which is a type of two-dimension barcode.
224  * Invented by Denso Wave and described in the ISO/IEC 18004 standard.
225  * Instances of this class represent an immutable square grid of dark and light cells.
226  * The class provides static factory functions to create a QR Code from text or binary data.
227  * The class covers the QR Code Model 2 specification, supporting all versions (sizes)
228  * from 1 to 40, all 4 error correction levels, and 4 character encoding modes.
229  *
230  * Ways to create a QR Code object:
231  * - High level: Take the payload data and call QrCode::encodeText() or QrCode::encodeBinary().
232  * - Mid level: Custom-make the list of segments and call QrCode::encodeSegments().
233  * - Low level: Custom-make the array of data codeword bytes (including
234  * segment headers and final padding, excluding error correction codewords),
235  * supply the appropriate version number, and call the QrCode() constructor.
236  * (Note that all ways require supplying the desired error correction level.)
237  */
238  class QrCode final {
239 
240  /*---- Public helper enumeration ----*/
241 
242  /*
243  * The error correction level in a QR Code symbol.
244  */
245  public: enum class Ecc {
246  LOW = 0 , // The QR Code can tolerate about 7% erroneous codewords
247  MEDIUM , // The QR Code can tolerate about 15% erroneous codewords
248  QUARTILE, // The QR Code can tolerate about 25% erroneous codewords
249  HIGH , // The QR Code can tolerate about 30% erroneous codewords
250  };
251 
252 
253  // Returns a value in the range 0 to 3 (unsigned 2-bit integer).
254  private: static int getFormatBits(Ecc ecl);
255 
256 
257 
258  /*---- Static factory functions (high level) ----*/
259 
260  /*
261  * Returns a QR Code representing the given Unicode text string at the given error correction level.
262  * As a conservative upper bound, this function is guaranteed to succeed for strings that have 2953 or fewer
263  * UTF-8 code units (not Unicode code points) if the low error correction level is used. The smallest possible
264  * QR Code version is automatically chosen for the output. The ECC level of the result may be higher than
265  * the ecl argument if it can be done without increasing the version.
266  */
267  public: static QrCode encodeText(const char *text, Ecc ecl);
268 
269 
270  /*
271  * Returns a QR Code representing the given binary data at the given error correction level.
272  * This function always encodes using the binary segment mode, not any text mode. The maximum number of
273  * bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
274  * The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
275  */
276  public: static QrCode encodeBinary(const std::vector<std::uint8_t> &data, Ecc ecl);
277 
278 
279  /*---- Static factory functions (mid level) ----*/
280 
281  /*
282  * Returns a QR Code representing the given segments with the given encoding parameters.
283  * The smallest possible QR Code version within the given range is automatically
284  * chosen for the output. Iff boostEcl is true, then the ECC level of the result
285  * may be higher than the ecl argument if it can be done without increasing the
286  * version. The mask number is either between 0 to 7 (inclusive) to force that
287  * mask, or -1 to automatically choose an appropriate mask (which may be slow).
288  * This function allows the user to create a custom sequence of segments that switches
289  * between modes (such as alphanumeric and byte) to encode text in less space.
290  * This is a mid-level API; the high-level API is encodeText() and encodeBinary().
291  */
292  public: static QrCode encodeSegments(const std::vector<QrSegment> &segs, Ecc ecl,
293  int minVersion=1, int maxVersion=40, int mask=-1, bool boostEcl=true); // All optional parameters
294 
295 
296 
297  /*---- Instance fields ----*/
298 
299  // Immutable scalar parameters:
300 
301  /* The version number of this QR Code, which is between 1 and 40 (inclusive).
302  * This determines the size of this barcode. */
303  private: int version;
304 
305  /* The width and height of this QR Code, measured in modules, between
306  * 21 and 177 (inclusive). This is equal to version * 4 + 17. */
307  private: int size;
308 
309  /* The error correction level used in this QR Code. */
310  private: Ecc errorCorrectionLevel;
311 
312  /* The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive).
313  * Even if a QR Code is created with automatic masking requested (mask = -1),
314  * the resulting object still has a mask value between 0 and 7. */
315  private: int mask;
316 
317  // Private grids of modules/pixels, with dimensions of size*size:
318 
319  // The modules of this QR Code (false = light, true = dark).
320  // Immutable after constructor finishes. Accessed through getModule().
321  private: std::vector<std::vector<bool> > modules;
322 
323  // Indicates function modules that are not subjected to masking. Discarded when constructor finishes.
324  private: std::vector<std::vector<bool> > isFunction;
325 
326 
327 
328  /*---- Constructor (low level) ----*/
329 
330  /*
331  * Creates a new QR Code with the given version number,
332  * error correction level, data codeword bytes, and mask number.
333  * This is a low-level API that most users should not use directly.
334  * A mid-level API is the encodeSegments() function.
335  */
336  public: QrCode(int ver, Ecc ecl, const std::vector<std::uint8_t> &dataCodewords, int msk);
337 
338 
339 
340  /*---- Public instance methods ----*/
341 
342  /*
343  * Returns this QR Code's version, in the range [1, 40].
344  */
345  public: int getVersion() const;
346 
347 
348  /*
349  * Returns this QR Code's size, in the range [21, 177].
350  */
351  public: int getSize() const;
352 
353 
354  /*
355  * Returns this QR Code's error correction level.
356  */
357  public: Ecc getErrorCorrectionLevel() const;
358 
359 
360  /*
361  * Returns this QR Code's mask, in the range [0, 7].
362  */
363  public: int getMask() const;
364 
365 
366  /*
367  * Returns the color of the module (pixel) at the given coordinates, which is false
368  * for light or true for dark. The top left corner has the coordinates (x=0, y=0).
369  * If the given coordinates are out of bounds, then false (light) is returned.
370  */
371  public: bool getModule(int x, int y) const;
372 
373 
374 
375  /*---- Private helper methods for constructor: Drawing function modules ----*/
376 
377  // Reads this object's version field, and draws and marks all function modules.
378  private: void drawFunctionPatterns();
379 
380 
381  // Draws two copies of the format bits (with its own error correction code)
382  // based on the given mask and this object's error correction level field.
383  private: void drawFormatBits(int msk);
384 
385 
386  // Draws two copies of the version bits (with its own error correction code),
387  // based on this object's version field, iff 7 <= version <= 40.
388  private: void drawVersion();
389 
390 
391  // Draws a 9*9 finder pattern including the border separator,
392  // with the center module at (x, y). Modules can be out of bounds.
393  private: void drawFinderPattern(int x, int y);
394 
395 
396  // Draws a 5*5 alignment pattern, with the center module
397  // at (x, y). All modules must be in bounds.
398  private: void drawAlignmentPattern(int x, int y);
399 
400 
401  // Sets the color of a module and marks it as a function module.
402  // Only used by the constructor. Coordinates must be in bounds.
403  private: void setFunctionModule(int x, int y, bool isDark);
404 
405 
406  // Returns the color of the module at the given coordinates, which must be in range.
407  private: bool module(int x, int y) const;
408 
409 
410  /*---- Private helper methods for constructor: Codewords and masking ----*/
411 
412  // Returns a new byte string representing the given data with the appropriate error correction
413  // codewords appended to it, based on this object's version and error correction level.
414  private: std::vector<std::uint8_t> addEccAndInterleave(const std::vector<std::uint8_t> &data) const;
415 
416 
417  // Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
418  // data area of this QR Code. Function modules need to be marked off before this is called.
419  private: void drawCodewords(const std::vector<std::uint8_t> &data);
420 
421 
422  // XORs the codeword modules in this QR Code with the given mask pattern.
423  // The function modules must be marked and the codeword bits must be drawn
424  // before masking. Due to the arithmetic of XOR, calling applyMask() with
425  // the same mask value a second time will undo the mask. A final well-formed
426  // QR Code needs exactly one (not zero, two, etc.) mask applied.
427  private: void applyMask(int msk);
428 
429 
430  // Calculates and returns the penalty score based on state of this QR Code's current modules.
431  // This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
432  private: long getPenaltyScore() const;
433 
434 
435 
436  /*---- Private helper functions ----*/
437 
438  // Returns an ascending list of positions of alignment patterns for this version number.
439  // Each position is in the range [0,177), and are used on both the x and y axes.
440  // This could be implemented as lookup table of 40 variable-length lists of unsigned bytes.
441  private: std::vector<int> getAlignmentPatternPositions() const;
442 
443 
444  // Returns the number of data bits that can be stored in a QR Code of the given version number, after
445  // all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
446  // The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
447  private: static int getNumRawDataModules(int ver);
448 
449 
450  // Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
451  // QR Code of the given version number and error correction level, with remainder bits discarded.
452  // This stateless pure function could be implemented as a (40*4)-cell lookup table.
453  private: static int getNumDataCodewords(int ver, Ecc ecl);
454 
455 
456  // Returns a Reed-Solomon ECC generator polynomial for the given degree. This could be
457  // implemented as a lookup table over all possible parameter values, instead of as an algorithm.
458  private: static std::vector<std::uint8_t> reedSolomonComputeDivisor(int degree);
459 
460 
461  // Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials.
462  private: static std::vector<std::uint8_t> reedSolomonComputeRemainder(const std::vector<std::uint8_t> &data, const std::vector<std::uint8_t> &divisor);
463 
464 
465  // Returns the product of the two given field elements modulo GF(2^8/0x11D).
466  // All inputs are valid. This could be implemented as a 256*256 lookup table.
467  private: static std::uint8_t reedSolomonMultiply(std::uint8_t x, std::uint8_t y);
468 
469 
470  // Can only be called immediately after a light run is added, and
471  // returns either 0, 1, or 2. A helper function for getPenaltyScore().
472  private: int finderPenaltyCountPatterns(const std::array<int,7> &runHistory) const;
473 
474 
475  // Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore().
476  private: int finderPenaltyTerminateAndCount(bool currentRunColor, int currentRunLength, std::array<int,7> &runHistory) const;
477 
478 
479  // Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore().
480  private: void finderPenaltyAddHistory(int currentRunLength, std::array<int,7> &runHistory) const;
481 
482 
483  // Returns true iff the i'th bit of x is set to 1.
484  private: static bool getBit(long x, int i);
485 
486 
487  /*---- Constants and tables ----*/
488 
489  // The minimum version number supported in the QR Code Model 2 standard.
490  public: static constexpr int MIN_VERSION = 1;
491 
492  // The maximum version number supported in the QR Code Model 2 standard.
493  public: static constexpr int MAX_VERSION = 40;
494 
495 
496  // For use in getPenaltyScore(), when evaluating which mask is best.
497  private: static const int PENALTY_N1;
498  private: static const int PENALTY_N2;
499  private: static const int PENALTY_N3;
500  private: static const int PENALTY_N4;
501 
502 
503  private: static const std::int8_t ECC_CODEWORDS_PER_BLOCK[4][41];
504  private: static const std::int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41];
505 
506  };
507 
508 
509 
510  /*---- Public exception class ----*/
511 
512  /*
513  * Thrown when the supplied data does not fit any QR Code version. Ways to handle this exception include:
514  * - Decrease the error correction level if it was greater than Ecc::LOW.
515  * - If the encodeSegments() function was called with a maxVersion argument, then increase
516  * it if it was less than QrCode::MAX_VERSION. (This advice does not apply to the other
517  * factory functions because they search all versions up to QrCode::MAX_VERSION.)
518  * - Split the text data into better or optimal segments in order to reduce the number of bits required.
519  * - Change the text or binary data to be shorter.
520  * - Change the text to fit the character set of a particular segment mode (e.g. alphanumeric).
521  * - Propagate the error upward to the caller/user.
522  */
524 
525  public: explicit data_too_long(const std::string &msg);
526 
527  };
528 
529 
530 
531  /*
532  * An appendable sequence of bits (0s and 1s). Mainly used by QrSegment.
533  */
534  class BitBuffer final : public std::vector<bool> {
535 
536  /*---- Constructor ----*/
537 
538  // Creates an empty bit buffer (length 0).
539  public: BitBuffer();
540 
541 
542 
543  /*---- Method ----*/
544 
545  // Appends the given number of low-order bits of the given value
546  // to this buffer. Requires 0 <= len <= 31 and val < 2^len.
547  public: void appendBits(std::uint32_t val, int len);
548 
549  };
550  /*---- utils functions ----*/
551 
552  /*
553  * @param the qr code object, the border, and the fill color.
554  * @return the svg string of the qr.
555  *
556  */
557  std::string toSvgString(const QrCode &qr, std::string fill);
558 
559 
560 }
Definition: qrcode_gen.hpp:534
void appendBits(std::uint32_t val, int len)
Definition: qrcode_gen.cpp:824
BitBuffer()
Definition: qrcode_gen.cpp:820
Definition: qrcode_gen.hpp:238
static constexpr int MIN_VERSION
Definition: qrcode_gen.hpp:490
int getSize() const
Definition: qrcode_gen.cpp:368
static QrCode encodeBinary(const std::vector< std::uint8_t > &data, Ecc ecl)
Definition: qrcode_gen.cpp:254
int getMask() const
Definition: qrcode_gen.cpp:378
Ecc
Definition: qrcode_gen.hpp:245
Ecc getErrorCorrectionLevel() const
Definition: qrcode_gen.cpp:373
static QrCode encodeText(const char *text, Ecc ecl)
Definition: qrcode_gen.cpp:247
static QrCode encodeSegments(const std::vector< QrSegment > &segs, Ecc ecl, int minVersion=1, int maxVersion=40, int mask=-1, bool boostEcl=true)
Definition: qrcode_gen.cpp:260
bool getModule(int x, int y) const
Definition: qrcode_gen.cpp:383
static constexpr int MAX_VERSION
Definition: qrcode_gen.hpp:493
int getVersion() const
Definition: qrcode_gen.cpp:363
QrCode(int ver, Ecc ecl, const std::vector< std::uint8_t > &dataCodewords, int msk)
Definition: qrcode_gen.cpp:321
Definition: qrcode_gen.hpp:55
static const Mode ALPHANUMERIC
Definition: qrcode_gen.hpp:60
int getModeBits() const
Definition: qrcode_gen.cpp:52
static const Mode BYTE
Definition: qrcode_gen.hpp:61
int numCharCountBits(int ver) const
Definition: qrcode_gen.cpp:57
static const Mode NUMERIC
Definition: qrcode_gen.hpp:59
static const Mode ECI
Definition: qrcode_gen.hpp:63
static const Mode KANJI
Definition: qrcode_gen.hpp:62
Definition: qrcode_gen.hpp:48
static QrSegment makeEci(long assignVal)
Definition: qrcode_gen.cpp:143
static QrSegment makeAlphanumeric(const char *text)
Definition: qrcode_gen.cpp:102
int getNumChars() const
Definition: qrcode_gen.cpp:220
static std::vector< QrSegment > makeSegments(const char *text)
Definition: qrcode_gen.cpp:125
static QrSegment makeBytes(const std::vector< std::uint8_t > &data)
Definition: qrcode_gen.cpp:69
const Mode & getMode() const
Definition: qrcode_gen.cpp:215
QrSegment(const Mode &md, int numCh, const std::vector< bool > &dt)
Definition: qrcode_gen.cpp:161
const std::vector< bool > & getData() const
Definition: qrcode_gen.cpp:225
static bool isAlphanumeric(const char *text)
Definition: qrcode_gen.cpp:206
static int getTotalBits(const std::vector< QrSegment > &segs, int version)
Definition: qrcode_gen.cpp:179
static QrSegment makeNumeric(const char *digits)
Definition: qrcode_gen.cpp:79
static bool isNumeric(const char *text)
Definition: qrcode_gen.cpp:196
Definition: qrcode_gen.hpp:523
data_too_long(const std::string &msg)
Definition: qrcode_gen.cpp:813
void * data
Definition: core_c.h:427
const CvArr CvArr * x
Definition: core_c.h:1195
const CvArr * y
Definition: core_c.h:1187
const char * text
Definition: imgproc_c.h:1143
Definition: qrcode_gen.hpp:34
std::string toSvgString(const QrCode &qr, std::string fill)
Definition: utils.cpp:4