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