├── .gitignore ├── Makefile ├── CMakeLists.txt ├── LICENSE ├── README.md ├── QR_Encode.h ├── main.c └── QR_Encode.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | qr_encode 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PROG = qr_encode 2 | OBJS = main.o QR_Encode.o 3 | CFLAGS = -std=c99 -D_XOPEN_SOURCE 4 | 5 | $(PROG): $(OBJS) 6 | $(CC) $(LDFLAGS) -o $@ $^ 7 | 8 | main.o: CFLAGS += -Wall -Wextra -pedantic -Werror 9 | 10 | clean: 11 | rm -f $(PROG) $(OBJS) 12 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | project(qr_image_embedded) 4 | add_library(${PROJECT_NAME} "QR_Encode.c" "QR_Encode.h") 5 | add_executable(qr_encode "main.c" ) 6 | target_link_libraries(qr_encode ${PROJECT_NAME}) 7 | if(MSVC) 8 | target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX) 9 | else(MSVC) 10 | target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -pedantic -Werror) 11 | endif(MSVC) 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Alexey Mednyy 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A QR Code encoding library 2 | 3 | This library encodes data in a QR Code. 4 | The output is a binary stream representing the QR Code. 5 | 6 | The main function is EncodeData() and is declared as follows: 7 | 8 | ```c++ 9 | /** 10 | * @brief EncodeData encodes data into QR code 11 | * @param level One of QR_LEVEL_{L,M,Q,H}. 12 | * @param version 0 for auto detect or required output version. 13 | * @param maskPattern Choose concrete mask pattern or use autodetect 14 | * @param data_in A pointer to the input data to encode. 15 | * @param in_size Size of data pointed to by data_in. If set to 0, the function will interpret source as a NUL terminated string. 16 | * @param output Pointer to storage of at MAX_BITDATA bytes in which to store produced data. 17 | * @return -1 on error or width of the produced QR code 18 | */ 19 | int EncodeData(QR_Level level, int version, QR_MaskPattern maskPattern, const char* data_in, size_t in_size, unsigned char* output); 20 | ``` 21 | ## Example use 22 | 23 | ```c++ 24 | uint8_t encoded[MAX_BITDATA]; 25 | int width = EncodeData(QR_LEVEL_L, 0, QR_MaskAuto, data, 0, encoded); 26 | int size = ((width*width)/8) + (((width*width)%8)?1:0); 27 | 28 | // Dump it out somewhere. 29 | write(fd, encoded, size); 30 | 31 | // Render it somehow. 32 | for (x = 0; x < width; x++) { 33 | for (y = 0; y < width; y++) { 34 | int byte = (x * width + y) / 8; 35 | int bit = (x * width + y) % 8; 36 | int value = encoded[byte] & (0x80 >> bit); 37 | set_pixel(x, y, value ? BLACK : WHITE); 38 | } 39 | } 40 | ``` 41 | ## in action 42 | [![asciicast](https://asciinema.org/a/Mn3hwE4AzSZks7a67ra8ofqlh.png)](https://asciinema.org/a/3Nd3kf8cRvLjgLEdMHitDMrP5) 43 | 44 | -------------------------------------------------------------------------------- /QR_Encode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QR_Encode.h 3 | * 4 | * Created on: Jan 18, 2012 5 | * Author: swex 6 | */ 7 | 8 | #ifndef _QR_ENCODE_H_ 9 | #define _QR_ENCODE_H_ 10 | #include //just for size_t 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif /* __cplusplus */ 14 | /* Error correction level */ 15 | typedef enum { 16 | QR_LEVEL_L = (0), 17 | QR_LEVEL_M = (1), 18 | QR_LEVEL_Q = (2), 19 | QR_LEVEL_H = (3) 20 | } QR_Level; 21 | 22 | /* Data Mode */ 23 | typedef enum { 24 | QR_MODE_NUMERAL = (0), 25 | QR_MODE_ALPHABET = (1), 26 | QR_MODE_8BIT = (2), 27 | QR_MODE_KANJI = (3), 28 | } QR_DataMode; 29 | 30 | /* Mask pattern */ 31 | typedef enum { 32 | QR_MaskAuto = -1, //calculate penalty and take the best mask (takes longer) 33 | QR_Mask1 = 0, //(row + column) mod 2 == 0 34 | QR_Mask2, // (row) mod 2 == 0 35 | QR_Mask3, // (column) mod 3 == 0 36 | QR_Mask4, // (row + column) mod 3 == 0 37 | QR_Mask5, // ( floor(row / 2) + floor(column / 3) ) mod 2 == 0 38 | QR_Mask6, // ((row * column) mod 2) + ((row * column) mod 3) == 0 39 | QR_Mask7, // ( ((row * column) mod 2) + ((row * column) mod 3) ) mod 2 == 0 40 | QR_Mask8, // ( ((row + column) mod 2) + ((row * column) mod 3) ) mod 2 == 0 41 | } QR_MaskPattern; 42 | 43 | /*Encoding errors*/ 44 | typedef enum { 45 | QR_E_EmptyInput = -1, 46 | QR_E_InvalidVersion = -2, 47 | QR_E_VersionNotFit = -3, 48 | } QR_EncodeError; 49 | 50 | /* Sizes */ 51 | #define MAX_ALLCODEWORD (3706) /* The maximum total number of code words */ 52 | #define MAX_DATACODEWORD (2956) /* Maximum data word code (version 40-L) */ 53 | #define MAX_CODEBLOCK (153) /* (Including RS code word) the maximum number \ 54 | of block data code word */ 55 | #define MAX_MODULESIZE (177) /* Maximum number of modules in a side */ 56 | #define MAX_BITDATA (3917) /* finfile data */ 57 | 58 | /** 59 | * @brief EncodeData encodes data into QR code 60 | * @param level One of QR_LEVEL_{L,M,Q,H}. 61 | * @param version 0 for auto detect or required output version. 62 | * @param maskPattern Choose concrete mask pattern or use autodetect 63 | * @param data_in A pointer to the input data to encode. 64 | * @param in_size Size of data pointed to by data_in. If set to 0, the function will interpret source as a NUL terminated string. 65 | * @param output Pointer to storage of at MAX_BITDATA bytes in which to store produced data. 66 | * @return <0 on error @see QR_EncodeError or width of the produced QR code 67 | */ 68 | int EncodeData(QR_Level level, int version, QR_MaskPattern maskPattern, const char* data_in, size_t in_size, unsigned char* output); 69 | /* See README.md for usage. */ 70 | #ifdef __cplusplus 71 | } 72 | #endif /* __cplusplus */ 73 | #endif /* _QR_ENCODE_H_ */ 74 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include "QR_Encode.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) /* 0664 */ 11 | 12 | #define WHITE "\x1b[47m\x1b[30m" 13 | #define BLACK "\x1b[40m\x1b[37m" 14 | #define RESET "\x1b[0m" 15 | 16 | static int margin = 4; 17 | 18 | /* Because getprogname(3) is not portable yet. */ 19 | const char* progname; 20 | 21 | static void usage(void); 22 | static void white(void); 23 | static void black(void); 24 | static void nl(void); 25 | static void top_bottom_margin(int width); 26 | static void left_right_margin(void); 27 | static void ansi_qr(const unsigned char* data, int width); 28 | 29 | static void usage(void) 30 | { 31 | fprintf(stderr, "%s [-l level] [-v version] [-p mask] [-o file] " 32 | "[-m margin] \n", 33 | progname); 34 | fprintf(stderr, "level, version and mask defaults to 3, 0 and auto respectively\n"); 35 | exit(2); 36 | } 37 | 38 | static void printError(int error) 39 | { 40 | switch (error) { 41 | case QR_E_EmptyInput: 42 | dprintf(STDOUT_FILENO, "empty input\n"); 43 | break; 44 | case QR_E_VersionNotFit: 45 | dprintf(STDOUT_FILENO, "Required version does not fit into output buffer\n"); 46 | break; 47 | case QR_E_InvalidVersion: 48 | dprintf(STDOUT_FILENO, "Input data can't fit in QR code\n"); 49 | break; 50 | default: 51 | dprintf(STDOUT_FILENO, "Unknown error\n"); 52 | break; 53 | } 54 | } 55 | 56 | int main(int argc, char* argv[]) 57 | { 58 | progname = argv[0]; 59 | QR_Level level = QR_LEVEL_H; 60 | int version = 0; 61 | QR_MaskPattern mask = QR_MaskAuto; 62 | char* fname = NULL; 63 | int fd = -1; 64 | int ch; 65 | 66 | while ((ch = getopt(argc, argv, "l:v:o:m:p:")) != -1) { 67 | switch (ch) { 68 | case 'l': 69 | level = atoi(optarg); 70 | break; 71 | case 'v': 72 | version = atoi(optarg); 73 | break; 74 | case 'o': 75 | fname = optarg; 76 | break; 77 | case 'm': 78 | margin = atoi(optarg); 79 | break; 80 | case 'p': 81 | mask = atoi(optarg); 82 | break; 83 | default: 84 | usage(); 85 | /* NOTREACHED */ 86 | } 87 | } 88 | 89 | argc -= optind; 90 | argv += optind; 91 | 92 | if (argc != 1) { 93 | usage(); 94 | /* NOTREACHED */ 95 | } 96 | errno = EINVAL; 97 | if (level < QR_LEVEL_L || level > QR_LEVEL_H) { 98 | err(1, "level"); 99 | } 100 | if (version < 0 || version > 40) { 101 | err(1, "version"); 102 | } 103 | if (mask < QR_MaskAuto || mask > QR_Mask8) { 104 | err(1, "mask"); 105 | } 106 | errno = 0; 107 | unsigned char encoded[MAX_BITDATA]; 108 | 109 | int width = EncodeData(level, version, mask, argv[0], 0, encoded); 110 | if (width <= 0) { 111 | printError(width); 112 | exit(EXIT_FAILURE); 113 | } 114 | int size = ((width * width) / 8) + (((width * width) % 8) ? 1 : 0); 115 | 116 | printf("QR Code width: %d\n", width); 117 | 118 | if (fname != NULL && *fname != '\0') { 119 | fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, MODE); 120 | if (fd == -1) { 121 | err(1, "open"); 122 | } 123 | 124 | printf("writing file (%d bytes)\n", size); 125 | if (write(fd, encoded, size) != size) { 126 | err(1, "write"); 127 | } 128 | 129 | close(fd); 130 | } 131 | 132 | ansi_qr(encoded, width); 133 | 134 | return 0; 135 | } 136 | 137 | enum { was_reset, 138 | was_white, 139 | was_black } static last_color 140 | = was_reset; 141 | 142 | static void white(void) 143 | { 144 | if (last_color != was_white) { 145 | printf(WHITE); 146 | last_color = was_white; 147 | } 148 | printf(" "); 149 | } 150 | 151 | static void black(void) 152 | { 153 | if (last_color != was_black) { 154 | printf(BLACK); 155 | last_color = was_black; 156 | } 157 | printf(" "); 158 | } 159 | 160 | static void nl(void) 161 | { 162 | if (last_color != was_reset) { 163 | printf(RESET); 164 | last_color = was_reset; 165 | } 166 | printf("\n"); 167 | } 168 | 169 | static void top_bottom_margin(int width) 170 | { 171 | int i, j; 172 | 173 | for (i = 0; i < margin; i++) { 174 | for (j = 0; j < width + (margin * 2); j++) { 175 | white(); 176 | } 177 | nl(); 178 | } 179 | } 180 | 181 | static void left_right_margin(void) 182 | { 183 | int i; 184 | 185 | for (i = 0; i < margin; i++) { 186 | white(); 187 | } 188 | } 189 | 190 | static void ansi_qr(const unsigned char* data, int width) 191 | { 192 | int i, j; 193 | 194 | top_bottom_margin(width); 195 | for (i = 0; i < width; i++) { 196 | left_right_margin(); 197 | for (j = 0; j < width; j++) { 198 | long byte = (i * width + j) / 8; 199 | long bit = (i * width + j) % 8; 200 | if (data[byte] & (0x80 >> bit)) { 201 | black(); 202 | } else { 203 | white(); 204 | } 205 | } 206 | left_right_margin(); 207 | nl(); 208 | } 209 | top_bottom_margin(width); 210 | } 211 | -------------------------------------------------------------------------------- /QR_Encode.c: -------------------------------------------------------------------------------- 1 | #include "QR_Encode.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #ifdef QR_ENCODE_CONFIG 8 | #include 9 | #else 10 | 11 | #ifndef QR_IMAGE_STORAGE_ATTRIBUTE_NOINIT 12 | #define QR_IMAGE_STORAGE_ATTRIBUTE_NOINIT 13 | #endif // #ifndef QR_IMAGE_STORAGE_ATTRIBUTE_NOINIT 14 | 15 | #ifndef QR_STORAGE_ATTRIBUTE_EXTERNAL_RAM 16 | #define QR_STORAGE_ATTRIBUTE_EXTERNAL_RAM 17 | #endif //#ifndef QR_STORAGE_ATTRIBUTE_EXTERNAL_RAM 18 | 19 | #ifndef QR_ENCODE_CUSTOM_OUTPUT 20 | typedef enum { 21 | QR_ColorWhite = 0, 22 | QR_ColorBlack = 1 23 | } QR_COLOR; 24 | 25 | static void putBitToPos(unsigned int pos, QR_COLOR bw, uint8_t* bits) 26 | { 27 | if (bw == QR_ColorWhite) { 28 | //assume all data zeroed before 29 | return; 30 | } 31 | static const uint8_t bitpos[8] = { 128, 64, 32, 16, 8, 4, 2, 1 }; 32 | bits[pos / 8] |= bitpos[pos % 8]; 33 | } 34 | 35 | static void doQrOutput(uint8_t m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE], int nSymbolSize, uint8_t* output) 36 | { 37 | memset(output, 0, MAX_BITDATA); 38 | for (int i = 0; i < nSymbolSize; i++) { 39 | for (int j = 0; j < nSymbolSize; j++) { 40 | if (m_byModuleData[i][j]) { 41 | putBitToPos((j * nSymbolSize) + i, QR_ColorBlack, output); 42 | } 43 | } 44 | } 45 | } 46 | #endif // ifndef QR_ENCODE_CUSTOM_OUTPUT 47 | 48 | #endif //QR_ENCODE_CONFIG 49 | 50 | typedef struct { 51 | int16_t ncRSBlock; //RS block number 52 | int16_t ncAllCodeWord; //The number of codewords in the block 53 | int16_t ncDataCodeWord; //The number of data code words (the number of code words - the number of RS code word) 54 | } RS_BLOCKINFO; 55 | 56 | /* Group version (model number) */ 57 | typedef enum { 58 | QR_VERSION_S = (0), /* 1 ~ 9 */ 59 | QR_VERSION_M = (1), /* 10 ~ 26 */ 60 | QR_VERSION_L = (2), /* 27 ~ 40 */ 61 | } QR_VersionModel; 62 | 63 | ///////////////////////////////////////////////////////////////////////////// 64 | //Version code-related information (model number) 65 | 66 | typedef struct { 67 | int16_t nVersionNo; 68 | int16_t ncAllCodeWord; 69 | 70 | // Error correction levels (0 = L, 1 = M, 2 = Q, 3 = H) 71 | int16_t ncDataCodeWord[4]; // data len 72 | 73 | int16_t ncAlignPoint; // position 74 | int16_t nAlignPoint[6]; // numberof 75 | 76 | RS_BLOCKINFO RS_BlockInfo1[4]; // EC pos 77 | RS_BLOCKINFO RS_BlockInfo2[4]; // EC pos 78 | 79 | } QR_VERSIONINFO; 80 | 81 | #ifndef ZeroMemory 82 | #define ZeroMemory(Destination, Length) memset((Destination), 0, (Length)) 83 | #endif //ifndef ZeroMemory 84 | 85 | typedef struct { 86 | QR_Level nLevel; 87 | int nVersion; 88 | QR_MaskPattern nMaskingNo; 89 | int ncDataCodeWordBit, ncAllCodeWord; 90 | int nEncodeVersion; 91 | int ncDataBlock; 92 | int nSymbolSize; 93 | } QR_ENCODING_CONTEXT; 94 | 95 | // clang-format off 96 | static const QR_VERSIONINFO QR_VersionInfo[] = {{0}, // (Ver.0) 97 | { 1, // Ver.1 98 | 26, {19, 16, 13, 9}, 99 | 0, {0, 0, 0, 0, 0, 0}, 100 | {{1, 26, 19}, 101 | {1, 26, 16}, 102 | {1, 26, 13}, 103 | {1, 26, 9}}, 104 | {{0, 0, 0}, 105 | {0, 0, 0}, 106 | {0, 0, 0}, 107 | {0, 0, 0}}}, 108 | { 2, // Ver.2 109 | 44, {34, 28, 22, 16}, 110 | 1, {18, 0, 0, 0, 0, 0}, 111 | {{1, 44, 34}, 112 | {1, 44, 28}, 113 | {1, 44, 22}, 114 | {1, 44, 16}}, 115 | {{0, 0, 0}, 116 | {0, 0, 0}, 117 | {0, 0, 0}, 118 | {0, 0, 0}}}, 119 | { 3, // Ver.3 120 | 70, {55, 44, 34, 26}, 121 | 1, {22, 0, 0, 0, 0, 0}, 122 | {{1, 70, 55}, 123 | {1, 70, 44}, 124 | {2, 35, 17}, 125 | {2, 35, 13}}, 126 | {{0, 0, 0}, 127 | {0, 0, 0}, 128 | {0, 0, 0}, 129 | {0, 0, 0}}}, 130 | { 4, // Ver.4 131 | 100, {80, 64, 48, 36}, 132 | 1, {26, 0, 0, 0, 0, 0}, 133 | {{1, 100, 80}, 134 | {2, 50, 32}, 135 | {2, 50, 24}, 136 | {4, 25, 9}}, 137 | {{0, 0, 0}, 138 | {0, 0, 0}, 139 | {0, 0, 0}, 140 | {0, 0, 0}}}, 141 | { 5, // Ver.5 142 | 134, {108, 86, 62, 46}, 143 | 1, {30, 0, 0, 0, 0, 0}, 144 | {{1, 134, 108}, 145 | {2, 67, 43}, 146 | {2, 33, 15}, 147 | {2, 33, 11}}, 148 | {{0, 0, 0}, 149 | {0, 0, 0}, 150 | {2, 34, 16}, 151 | {2, 34, 12}}}, 152 | { 6, // Ver.6 153 | 172, {136, 108, 76, 60}, 154 | 1, {34, 0, 0, 0, 0, 0}, 155 | {{2, 86, 68}, 156 | {4, 43, 27}, 157 | {4, 43, 19}, 158 | {4, 43, 15}}, 159 | {{0, 0, 0}, 160 | {0, 0, 0}, 161 | {0, 0, 0}, 162 | {0, 0, 0}}}, 163 | { 7, // Ver.7 164 | 196, {156, 124, 88, 66}, 165 | 2, {22, 38, 0, 0, 0, 0}, 166 | {{2, 98, 78}, 167 | {4, 49, 31}, 168 | {2, 32, 14}, 169 | {4, 39, 13}}, 170 | {{0, 0, 0}, 171 | {0, 0, 0}, 172 | {4, 33, 15}, 173 | {1, 40, 14}}}, 174 | { 8, // Ver.8 175 | 242, {194, 154, 110, 86}, 176 | 2, {24, 42, 0, 0, 0, 0}, 177 | {{2, 121, 97}, 178 | {2, 60, 38}, 179 | {4, 40, 18}, 180 | {4, 40, 14}}, 181 | {{0, 0, 0}, 182 | {2, 61, 39}, 183 | {2, 41, 19}, 184 | {2, 41, 15}}}, 185 | { 9, // Ver.9 186 | 292, {232, 182, 132, 100}, 187 | 2, {26, 46, 0, 0, 0, 0}, 188 | {{2, 146, 116}, 189 | {3, 58, 36}, 190 | {4, 36, 16}, 191 | {4, 36, 12}}, 192 | {{0, 0, 0}, 193 | {2, 59, 37}, 194 | {4, 37, 17}, 195 | {4, 37, 13}}}, 196 | {10, // Ver.10 197 | 346, {274, 216, 154, 122}, 198 | 2, {28, 50, 0, 0, 0, 0}, 199 | {{2, 86, 68}, 200 | {4, 69, 43}, 201 | {6, 43, 19}, 202 | {6, 43, 15}}, 203 | {{2, 87, 69}, 204 | {1, 70, 44}, 205 | {2, 44, 20}, 206 | {2, 44, 16}}}, 207 | {11, // Ver.11 208 | 404, {324, 254, 180, 140}, 209 | 2, {30, 54, 0, 0, 0, 0}, 210 | {{4, 101, 81}, 211 | {1, 80, 50}, 212 | {4, 50, 22}, 213 | {3, 36, 12}}, 214 | {{0, 0, 0}, 215 | {4, 81, 51}, 216 | {4, 51, 23}, 217 | {8, 37, 13}}}, 218 | {12, // Ver.12 219 | 466, {370, 290, 206, 158}, 220 | 2, {32, 58, 0, 0, 0, 0}, 221 | {{2, 116, 92}, 222 | {6, 58, 36}, 223 | {4, 46, 20}, 224 | {7, 42, 14}}, 225 | {{2, 117, 93}, 226 | {2, 59, 37}, 227 | {6, 47, 21}, 228 | {4, 43, 15}}}, 229 | {13, // Ver.13 230 | 532, {428, 334, 244, 180}, 231 | 2, {34, 62, 0, 0, 0, 0}, 232 | {{4, 133, 107}, 233 | {8, 59, 37}, 234 | {8, 44, 20}, 235 | {12, 33, 11}}, 236 | {{0, 0, 0}, 237 | {1, 60, 38}, 238 | {4, 45, 21}, 239 | {4, 34, 12}}}, 240 | {14, // Ver.14 241 | 581, {461, 365, 261, 197}, 242 | 3, {26, 46, 66, 0, 0, 0}, 243 | {{3, 145, 115}, 244 | {4, 64, 40}, 245 | {11, 36, 16}, 246 | {11, 36, 12}}, 247 | {{1, 146, 116}, 248 | {5, 65, 41}, 249 | {5, 37, 17}, 250 | {5, 37, 13}}}, 251 | {15, // Ver.15 252 | 655, {523, 415, 295, 223}, 253 | 3, {26, 48, 70, 0, 0, 0}, 254 | {{5, 109, 87}, 255 | {5, 65, 41}, 256 | {5, 54, 24}, 257 | {11, 36, 12}}, 258 | {{1, 110, 88}, 259 | {5, 66, 42}, 260 | {7, 55, 25}, 261 | {7, 37, 13}}}, 262 | {16, // Ver.16 263 | 733, {589, 453, 325, 253}, 264 | 3, {26, 50, 74, 0, 0, 0}, 265 | {{5, 122, 98}, 266 | {7, 73, 45}, 267 | {15, 43, 19}, 268 | {3, 45, 15}}, 269 | {{1, 123, 99}, 270 | {3, 74, 46}, 271 | {2, 44, 20}, 272 | {13, 46, 16}}}, 273 | {17, // Ver.17 274 | 815, {647, 507, 367, 283}, 275 | 3, {30, 54, 78, 0, 0, 0}, 276 | {{1, 135, 107}, 277 | {10, 74, 46}, 278 | {1, 50, 22}, 279 | {2, 42, 14}}, 280 | {{5, 136, 108}, 281 | {1, 75, 47}, 282 | {15, 51, 23}, 283 | {17, 43, 15}}}, 284 | {18, // Ver.18 285 | 901, {721, 563, 397, 313}, 286 | 3, {30, 56, 82, 0, 0, 0}, 287 | {{5, 150, 120}, 288 | {9, 69, 43}, 289 | {17, 50, 22}, 290 | {2, 42, 14}}, 291 | {{1, 151, 121}, 292 | {4, 70, 44}, 293 | {1, 51, 23}, 294 | {19, 43, 15}}}, 295 | {19, // Ver.19 296 | 991, {795, 627, 445, 341}, 297 | 3, {30, 58, 86, 0, 0, 0}, 298 | {{3, 141, 113}, 299 | {3, 70, 44}, 300 | {17, 47, 21}, 301 | {9, 39, 13}}, 302 | {{4, 142, 114}, 303 | {11, 71, 45}, 304 | {4, 48, 22}, 305 | {16, 40, 14}}}, 306 | {20, // Ver.20 307 | 1085, {861, 669, 485, 385}, 308 | 3, {34, 62, 90, 0, 0, 0}, 309 | {{3, 135, 107}, 310 | {3, 67, 41}, 311 | {15, 54, 24}, 312 | {15, 43, 15}}, 313 | {{5, 136, 108}, 314 | {13, 68, 42}, 315 | {5, 55, 25}, 316 | {10, 44, 16}}}, 317 | {21, // Ver.21 318 | 1156, {932, 714, 512, 406}, 319 | 4, {28, 50, 72, 94, 0, 0}, 320 | {{4, 144, 116}, 321 | {17, 68, 42}, 322 | {17, 50, 22}, 323 | {19, 46, 16}}, 324 | {{4, 145, 117}, 325 | {0, 0, 0}, 326 | {6, 51, 23}, 327 | {6, 47, 17}}}, 328 | {22, // Ver.22 329 | 1258, {1006, 782, 568, 442}, 330 | 4, {26, 50, 74, 98, 0, 0}, 331 | {{2, 139, 111}, 332 | {17, 74, 46}, 333 | {7, 54, 24}, 334 | {34, 37, 13}}, 335 | {{7, 140, 112}, 336 | {0, 0, 0}, 337 | {16, 55, 25}, 338 | {0, 0, 0}}}, 339 | {23, // Ver.23 340 | 1364, {1094, 860, 614, 464}, 341 | 4, {30, 54, 78, 102, 0, 0}, 342 | {{4, 151, 121}, 343 | {4, 75, 47}, 344 | {11, 54, 24}, 345 | {16, 45, 15}}, 346 | {{5, 152, 122}, 347 | {14, 76, 48}, 348 | {14, 55, 25}, 349 | {14, 46, 16}}}, 350 | {24, // Ver.24 351 | 1474, {1174, 914, 664, 514}, 352 | 4, {28, 54, 80, 106, 0, 0}, 353 | {{6, 147, 117}, 354 | {6, 73, 45}, 355 | {11, 54, 24}, 356 | {30, 46, 16}}, 357 | {{4, 148, 118}, 358 | {14, 74, 46}, 359 | {16, 55, 25}, 360 | {2, 47, 17}}}, 361 | {25, // Ver.25 362 | 1588, {1276, 1000, 718, 538}, 363 | 4, {32, 58, 84, 110, 0, 0}, 364 | {{8, 132, 106}, 365 | {8, 75, 47}, 366 | {7, 54, 24}, 367 | {22, 45, 15}}, 368 | {{4, 133, 107}, 369 | {13, 76, 48}, 370 | {22, 55, 25}, 371 | {13, 46, 16}}}, 372 | {26, // Ver.26 373 | 1706, {1370, 1062, 754, 596}, 374 | 4, {30, 58, 86, 114, 0, 0}, 375 | {{10, 142, 114}, 376 | {19, 74, 46}, 377 | {28, 50, 22}, 378 | {33, 46, 16}}, 379 | {{2, 143, 115}, 380 | {4, 75, 47}, 381 | {6, 51, 23}, 382 | {4, 47, 17}}}, 383 | {27, // Ver.27 384 | 1828, {1468, 1128, 808, 628}, 385 | 4, {34, 62, 90, 118, 0, 0}, 386 | {{8, 152, 122}, 387 | {22, 73, 45}, 388 | {8, 53, 23}, 389 | {12, 45, 15}}, 390 | {{4, 153, 123}, 391 | {3, 74, 46}, 392 | {26, 54, 24}, 393 | {28, 46, 16}}}, 394 | {28, // Ver.28 395 | 1921, {1531, 1193, 871, 661}, 396 | 5, {26, 50, 74, 98, 122, 0}, 397 | {{3, 147, 117}, 398 | {3, 73, 45}, 399 | {4, 54, 24}, 400 | {11, 45, 15}}, 401 | {{10, 148, 118}, 402 | {23, 74, 46}, 403 | {31, 55, 25}, 404 | {31, 46, 16}}}, 405 | {29, // Ver.29 406 | 2051, {1631, 1267, 911, 701}, 407 | 5, {30, 54, 78, 102, 126, 0}, 408 | {{7, 146, 116}, 409 | {21, 73, 45}, 410 | {1, 53, 23}, 411 | {19, 45, 15}}, 412 | {{7, 147, 117}, 413 | {7, 74, 46}, 414 | {37, 54, 24}, 415 | {26, 46, 16}}}, 416 | {30, // Ver.30 417 | 2185, {1735, 1373, 985, 745}, 418 | 5, {26, 52, 78, 104, 130, 0}, 419 | {{5, 145, 115}, 420 | {19, 75, 47}, 421 | {15, 54, 24}, 422 | {23, 45, 15}}, 423 | {{10, 146, 116}, 424 | {10, 76, 48}, 425 | {25, 55, 25}, 426 | {25, 46, 16}}}, 427 | {31, // Ver.31 428 | 2323, {1843, 1455, 1033, 793}, 429 | 5, {30, 56, 82, 108, 134, 0}, 430 | {{13, 145, 115}, 431 | {2, 74, 46}, 432 | {42, 54, 24}, 433 | {23, 45, 15}}, 434 | {{3, 146, 116}, 435 | {29, 75, 47}, 436 | {1, 55, 25}, 437 | {28, 46, 16}}}, 438 | {32, // Ver.32 439 | 2465, {1955, 1541, 1115, 845}, 440 | 5, {34, 60, 86, 112, 138, 0}, 441 | {{17, 145, 115}, 442 | {10, 74, 46}, 443 | {10, 54, 24}, 444 | {19, 45, 15}}, 445 | {{0, 0, 0}, 446 | {23, 75, 47}, 447 | {35, 55, 25}, 448 | {35, 46, 16}}}, 449 | {33, // Ver.33 450 | 2611, {2071, 1631, 1171, 901}, 451 | 5, {30, 58, 86, 114, 142, 0}, 452 | {{17, 145, 115}, 453 | {14, 74, 46}, 454 | {29, 54, 24}, 455 | {11, 45, 15}}, 456 | {{1, 146, 116}, 457 | {21, 75, 47}, 458 | {19, 55, 25}, 459 | {46, 46, 16}}}, 460 | {34, // Ver.34 461 | 2761, {2191, 1725, 1231, 961}, 462 | 5, {34, 62, 90, 118, 146, 0}, 463 | {{13, 145, 115}, 464 | {14, 74, 46}, 465 | {44, 54, 24}, 466 | {59, 46, 16}}, 467 | {{6, 146, 116}, 468 | {23, 75, 47}, 469 | {7, 55, 25}, 470 | {1, 47, 17}}}, 471 | {35, // Ver.35 472 | 2876, {2306, 1812, 1286, 986}, 473 | 6, {30, 54, 78, 102, 126, 150}, 474 | {{12, 151, 121}, 475 | {12, 75, 47}, 476 | {39, 54, 24}, 477 | {22, 45, 15}}, 478 | {{7, 152, 122}, 479 | {26, 76, 48}, 480 | {14, 55, 25}, 481 | {41, 46, 16}}}, 482 | {36, // Ver.36 483 | 3034, {2434, 1914, 1354, 1054}, 484 | 6, {24, 50, 76, 102, 128, 154}, 485 | {{6, 151, 121}, 486 | {6, 75, 47}, 487 | {46, 54, 24}, 488 | {2, 45, 15}}, 489 | {{14, 152, 122}, 490 | {34, 76, 48}, 491 | {10, 55, 25}, 492 | {64, 46, 16}}}, 493 | {37, // Ver.37 494 | 3196, {2566, 1992, 1426, 1096}, 495 | 6, {28, 54, 80, 106, 132, 158}, 496 | {{17, 152, 122}, 497 | {29, 74, 46}, 498 | {49, 54, 24}, 499 | {24, 45, 15}}, 500 | {{4, 153, 123}, 501 | {14, 75, 47}, 502 | {10, 55, 25}, 503 | {46, 46, 16}}}, 504 | {38, // Ver.38 505 | 3362, {2702, 2102, 1502, 1142}, 506 | 6, {32, 58, 84, 110, 136, 162}, 507 | {{4, 152, 122}, 508 | {13, 74, 46}, 509 | {48, 54, 24}, 510 | {42, 45, 15}}, 511 | {{18, 153, 123}, 512 | {32, 75, 47}, 513 | {14, 55, 25}, 514 | {32, 46, 16}}}, 515 | {39, // Ver.39 516 | 3532, {2812, 2216, 1582, 1222}, 517 | 6, {26, 54, 82, 110, 138, 166}, 518 | {{20, 147, 117}, 519 | {40, 75, 47}, 520 | {43, 54, 24}, 521 | {10, 45, 15}}, 522 | {{4, 148, 118}, 523 | {7, 76, 48}, 524 | {22, 55, 25}, 525 | {67, 46, 16}}}, 526 | {40, // Ver.40 527 | 3706, {2956, 2334, 1666, 1276}, 528 | 6, {30, 58, 86, 114, 142, 170}, 529 | {{19, 148, 118}, 530 | {18, 75, 47}, 531 | {34, 54, 24}, 532 | {20, 45, 15}}, 533 | {{6, 149, 119}, 534 | {31, 76, 48}, 535 | {34, 55, 25}, 536 | {61, 46, 16}}} 537 | }; 538 | 539 | //RS STUFF 540 | 541 | static const uint8_t byExpToInt[] = { 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 542 | 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 543 | 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 544 | 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 545 | 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 546 | 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 547 | 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, 548 | 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, 549 | 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, 550 | 168, 77, 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, 551 | 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 552 | 227, 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 553 | 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 554 | 81, 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, 555 | 18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, 556 | 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1}; 557 | 558 | 559 | static const uint8_t byIntToExp[] = { 0, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 560 | 4, 100, 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, 561 | 5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, 562 | 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, 77, 228, 114, 166, 563 | 6, 191, 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 564 | 54, 208, 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 565 | 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, 566 | 202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, 567 | 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24, 568 | 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, 569 | 55, 63, 209, 91, 149, 188, 207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 570 | 242, 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 571 | 31, 45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, 572 | 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, 573 | 203, 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, 574 | 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175}; 575 | 576 | 577 | 578 | static const uint8_t byRSExp7[] = {87, 229, 146, 149, 238, 102, 21}; 579 | static const uint8_t byRSExp10[] = {251, 67, 46, 61, 118, 70, 64, 94, 32, 45}; 580 | static const uint8_t byRSExp13[] = { 74, 152, 176, 100, 86, 100, 106, 104, 130, 218, 206, 140, 78}; 581 | static const uint8_t byRSExp15[] = { 8, 183, 61, 91, 202, 37, 51, 58, 58, 237, 140, 124, 5, 99, 105}; 582 | static const uint8_t byRSExp16[] = {120, 104, 107, 109, 102, 161, 76, 3, 91, 191, 147, 169, 182, 194, 225, 120}; 583 | static const uint8_t byRSExp17[] = { 43, 139, 206, 78, 43, 239, 123, 206, 214, 147, 24, 99, 150, 39, 243, 163, 136}; 584 | static const uint8_t byRSExp18[] = {215, 234, 158, 94, 184, 97, 118, 170, 79, 187, 152, 148, 252, 179, 5, 98, 96, 153}; 585 | static const uint8_t byRSExp20[] = { 17, 60, 79, 50, 61, 163, 26, 187, 202, 180, 221, 225, 83, 239, 156, 164, 212, 212, 188, 190}; 586 | static const uint8_t byRSExp22[] = {210, 171, 247, 242, 93, 230, 14, 109, 221, 53, 200, 74, 8, 172, 98, 80, 219, 134, 160, 105, 587 | 165, 231}; 588 | static const uint8_t byRSExp24[] = {229, 121, 135, 48, 211, 117, 251, 126, 159, 180, 169, 152, 192, 226, 228, 218, 111, 0, 117, 232, 589 | 87, 96, 227, 21}; 590 | static const uint8_t byRSExp26[] = {173, 125, 158, 2, 103, 182, 118, 17, 145, 201, 111, 28, 165, 53, 161, 21, 245, 142, 13, 102, 591 | 48, 227, 153, 145, 218, 70}; 592 | static const uint8_t byRSExp28[] = {168, 223, 200, 104, 224, 234, 108, 180, 110, 190, 195, 147, 205, 27, 232, 201, 21, 43, 245, 87, 593 | 42, 195, 212, 119, 242, 37, 9, 123}; 594 | static const uint8_t byRSExp30[] = { 41, 173, 145, 152, 216, 31, 179, 182, 50, 48, 110, 86, 239, 96, 222, 125, 42, 173, 226, 193, 595 | 224, 130, 156, 37, 251, 216, 238, 40, 192, 180}; 596 | static const uint8_t byRSExp32[] = { 10, 6, 106, 190, 249, 167, 4, 67, 209, 138, 138, 32, 242, 123, 89, 27, 120, 185, 80, 156, 597 | 38, 69, 171, 60, 28, 222, 80, 52, 254, 185, 220, 241}; 598 | static const uint8_t byRSExp34[] = {111, 77, 146, 94, 26, 21, 108, 19, 105, 94, 113, 193, 86, 140, 163, 125, 58, 158, 229, 239, 599 | 218, 103, 56, 70, 114, 61, 183, 129, 167, 13, 98, 62, 129, 51}; 600 | static const uint8_t byRSExp36[] = {200, 183, 98, 16, 172, 31, 246, 234, 60, 152, 115, 0, 167, 152, 113, 248, 238, 107, 18, 63, 601 | 218, 37, 87, 210, 105, 177, 120, 74, 121, 196, 117, 251, 113, 233, 30, 120}; 602 | static const uint8_t byRSExp38[] = {159, 34, 38, 228, 230, 59, 243, 95, 49, 218, 176, 164, 20, 65, 45, 111, 39, 81, 49, 118, 603 | 113, 222, 193, 250, 242, 168, 217, 41, 164, 247, 177, 30, 238, 18, 120, 153, 60, 193}; 604 | static const uint8_t byRSExp40[] = { 59, 116, 79, 161, 252, 98, 128, 205, 128, 161, 247, 57, 163, 56, 235, 106, 53, 26, 187, 174, 605 | 226, 104, 170, 7, 175, 35, 181, 114, 88, 41, 47, 163, 125, 134, 72, 20, 232, 53, 35, 15}; 606 | static const uint8_t byRSExp42[] = {250, 103, 221, 230, 25, 18, 137, 231, 0, 3, 58, 242, 221, 191, 110, 84, 230, 8, 188, 106, 607 | 96, 147, 15, 131, 139, 34, 101, 223, 39, 101, 213, 199, 237, 254, 201, 123, 171, 162, 194, 117, 608 | 50, 96}; 609 | static const uint8_t byRSExp44[] = {190, 7, 61, 121, 71, 246, 69, 55, 168, 188, 89, 243, 191, 25, 72, 123, 9, 145, 14, 247, 610 | 1, 238, 44, 78, 143, 62, 224, 126, 118, 114, 68, 163, 52, 194, 217, 147, 204, 169, 37, 130, 611 | 113, 102, 73, 181}; 612 | static const uint8_t byRSExp46[] = {112, 94, 88, 112, 253, 224, 202, 115, 187, 99, 89, 5, 54, 113, 129, 44, 58, 16, 135, 216, 613 | 169, 211, 36, 1, 4, 96, 60, 241, 73, 104, 234, 8, 249, 245, 119, 174, 52, 25, 157, 224, 614 | 43, 202, 223, 19, 82, 15}; 615 | static const uint8_t byRSExp48[] = {228, 25, 196, 130, 211, 146, 60, 24, 251, 90, 39, 102, 240, 61, 178, 63, 46, 123, 115, 18, 616 | 221, 111, 135, 160, 182, 205, 107, 206, 95, 150, 120, 184, 91, 21, 247, 156, 140, 238, 191, 11, 617 | 94, 227, 84, 50, 163, 39, 34, 108}; 618 | static const uint8_t byRSExp50[] = {232, 125, 157, 161, 164, 9, 118, 46, 209, 99, 203, 193, 35, 3, 209, 111, 195, 242, 203, 225, 619 | 46, 13, 32, 160, 126, 209, 130, 160, 242, 215, 242, 75, 77, 42, 189, 32, 113, 65, 124, 69, 620 | 228, 114, 235, 175, 124, 170, 215, 232, 133, 205}; 621 | static const uint8_t byRSExp52[] = {116, 50, 86, 186, 50, 220, 251, 89, 192, 46, 86, 127, 124, 19, 184, 233, 151, 215, 22, 14, 622 | 59, 145, 37, 242, 203, 134, 254, 89, 190, 94, 59, 65, 124, 113, 100, 233, 235, 121, 22, 76, 623 | 86, 97, 39, 242, 200, 220, 101, 33, 239, 254, 116, 51}; 624 | static const uint8_t byRSExp54[] = {183, 26, 201, 87, 210, 221, 113, 21, 46, 65, 45, 50, 238, 184, 249, 225, 102, 58, 209, 218, 625 | 109, 165, 26, 95, 184, 192, 52, 245, 35, 254, 238, 175, 172, 79, 123, 25, 122, 43, 120, 108, 626 | 215, 80, 128, 201, 235, 8, 153, 59, 101, 31, 198, 76, 31, 156}; 627 | static const uint8_t byRSExp56[] = {106, 120, 107, 157, 164, 216, 112, 116, 2, 91, 248, 163, 36, 201, 202, 229, 6, 144, 254, 155, 628 | 135, 208, 170, 209, 12, 139, 127, 142, 182, 249, 177, 174, 190, 28, 10, 85, 239, 184, 101, 124, 629 | 152, 206, 96, 23, 163, 61, 27, 196, 247, 151, 154, 202, 207, 20, 61, 10}; 630 | static const uint8_t byRSExp58[] = { 82, 116, 26, 247, 66, 27, 62, 107, 252, 182, 200, 185, 235, 55, 251, 242, 210, 144, 154, 237, 631 | 176, 141, 192, 248, 152, 249, 206, 85, 253, 142, 65, 165, 125, 23, 24, 30, 122, 240, 214, 6, 632 | 129, 218, 29, 145, 127, 134, 206, 245, 117, 29, 41, 63, 159, 142, 233, 125, 148, 123}; 633 | static const uint8_t byRSExp60[] = {107, 140, 26, 12, 9, 141, 243, 197, 226, 197, 219, 45, 211, 101, 219, 120, 28, 181, 127, 6, 634 | 100, 247, 2, 205, 198, 57, 115, 219, 101, 109, 160, 82, 37, 38, 238, 49, 160, 209, 121, 86, 635 | 11, 124, 30, 181, 84, 25, 194, 87, 65, 102, 190, 220, 70, 27, 209, 16, 89, 7, 33, 240}; 636 | static const uint8_t byRSExp62[] = { 65, 202, 113, 98, 71, 223, 248, 118, 214, 94, 0, 122, 37, 23, 2, 228, 58, 121, 7, 105, 637 | 135, 78, 243, 118, 70, 76, 223, 89, 72, 50, 70, 111, 194, 17, 212, 126, 181, 35, 221, 117, 638 | 235, 11, 229, 149, 147, 123, 213, 40, 115, 6, 200, 100, 26, 246, 182, 218, 127, 215, 36, 186, 639 | 110, 106}; 640 | static const uint8_t byRSExp64[] = { 45, 51, 175, 9, 7, 158, 159, 49, 68, 119, 92, 123, 177, 204, 187, 254, 200, 78, 141, 149, 641 | 119, 26, 127, 53, 160, 93, 199, 212, 29, 24, 145, 156, 208, 150, 218, 209, 4, 216, 91, 47, 642 | 184, 146, 47, 140, 195, 195, 125, 242, 238, 63, 99, 108, 140, 230, 242, 31, 204, 11, 178, 243, 643 | 217, 156, 213, 231}; 644 | static const uint8_t byRSExp66[] = { 5, 118, 222, 180, 136, 136, 162, 51, 46, 117, 13, 215, 81, 17, 139, 247, 197, 171, 95, 173, 645 | 65, 137, 178, 68, 111, 95, 101, 41, 72, 214, 169, 197, 95, 7, 44, 154, 77, 111, 236, 40, 646 | 121, 143, 63, 87, 80, 253, 240, 126, 217, 77, 34, 232, 106, 50, 168, 82, 76, 146, 67, 106, 647 | 171, 25, 132, 93, 45, 105}; 648 | static const uint8_t byRSExp68[] = {247, 159, 223, 33, 224, 93, 77, 70, 90, 160, 32, 254, 43, 150, 84, 101, 190, 205, 133, 52, 649 | 60, 202, 165, 220, 203, 151, 93, 84, 15, 84, 253, 173, 160, 89, 227, 52, 199, 97, 95, 231, 650 | 52, 177, 41, 125, 137, 241, 166, 225, 118, 2, 54, 32, 82, 215, 175, 198, 43, 238, 235, 27, 651 | 101, 184, 127, 3, 5, 8, 163, 238}; 652 | 653 | static const uint8_t* byRSExp[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, byRSExp7, NULL, NULL, 654 | byRSExp10, NULL, NULL, byRSExp13, NULL, byRSExp15, byRSExp16, byRSExp17, byRSExp18, NULL, 655 | byRSExp20, NULL, byRSExp22, NULL, byRSExp24, NULL, byRSExp26, NULL, byRSExp28, NULL, 656 | byRSExp30, NULL, byRSExp32, NULL, byRSExp34, NULL, byRSExp36, NULL, byRSExp38, NULL, 657 | byRSExp40, NULL, byRSExp42, NULL, byRSExp44, NULL, byRSExp46, NULL, byRSExp48, NULL, 658 | byRSExp50, NULL, byRSExp52, NULL, byRSExp54, NULL, byRSExp56, NULL, byRSExp58, NULL, 659 | byRSExp60, NULL, byRSExp62, NULL, byRSExp64, NULL, byRSExp66, NULL, byRSExp68}; 660 | 661 | 662 | static const int nIndicatorLenNumeral[] = {10, 12, 14}; 663 | static const int nIndicatorLenAlphabet[] = { 9, 11, 13}; 664 | static const int nIndicatorLen8Bit[] = { 8, 16, 16}; 665 | static const int nIndicatorLenKanji[] = { 8, 10, 12}; 666 | // clang-format on 667 | 668 | typedef enum { 669 | UTF8_ACCEPT = 0, 670 | UTF8_REJECT = 1, 671 | } UTF8_Validity; 672 | 673 | static uint32_t updatestate(uint32_t* state, uint32_t byte) 674 | { 675 | static const uint8_t utf8d[] = { 676 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 677 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 678 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1f 679 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 680 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 681 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3f 682 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 683 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 684 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5f 685 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 686 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 687 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7f 688 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 689 | 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 690 | 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9f 691 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 692 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 693 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // a0..bf 694 | 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 695 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 696 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // c0..df 697 | 0xa, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 698 | 0x3, 0x3, 0x4, 0x3, 0x3, // e0..ef 699 | 0xb, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 700 | 0x8, 0x8, 0x8, 0x8, 0x8 // f0..ff 701 | }; 702 | static const uint8_t utf8d_transition[] = { 703 | 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 704 | 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0 705 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 706 | 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 707 | 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2 708 | 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 709 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 710 | 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4 711 | 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 712 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 713 | 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6 714 | 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 715 | 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 716 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // s7..s8 717 | }; 718 | 719 | uint32_t type = utf8d[byte]; 720 | *state = utf8d_transition[16 * *state + type]; 721 | return *state; 722 | } 723 | // credit: Travis Downs 724 | int is_utf8(const char* c, size_t len) 725 | { 726 | size_t half = len / 2; 727 | while ((uint8_t)c[half] <= 0xBF && (uint8_t)c[half] > 0x80 && half > 0) { 728 | half--; 729 | } 730 | uint32_t s1 = 0, s2 = 0; 731 | for (size_t i = 0, j = half; i < half; i++, j++) { 732 | updatestate(&s1, (uint8_t)c[i]); 733 | updatestate(&s2, (uint8_t)c[j]); 734 | } 735 | for (size_t j = half * 2; j < len; j++) { 736 | updatestate(&s2, (uint8_t)c[j]); 737 | } 738 | return (s1 != UTF8_REJECT) && (s2 != UTF8_REJECT); 739 | } 740 | 741 | static int IsNumeralData(uint8_t c) 742 | { 743 | if (c >= '0' && c <= '9') { 744 | return 1; 745 | } 746 | return 0; 747 | } 748 | 749 | ///////////////////////////////////////////////////////////////////////////// 750 | // APPLICATIONS: Check the appropriate alphanumeric mode 751 | // Argument: research letter 752 | // Returns: = true if applicable 753 | 754 | static int IsAlphabetData(uint8_t c) 755 | { 756 | if (c >= '0' && c <= '9') { 757 | return 1; 758 | } 759 | 760 | if (c >= 'A' && c <= 'Z') { 761 | return 1; 762 | } 763 | 764 | if (c == ' ' || c == '$' || c == '%' || c == '*' || c == '+' || c == '-' || c == '.' || c == '/' || c == ':') { 765 | return 1; 766 | } 767 | 768 | return 0; 769 | } 770 | 771 | ///////////////////////////////////////////////////////////////////////////// 772 | // APPLICATIONS: Check the appropriate kanji mode 773 | // Arguments: The character study (16-bit characters) 774 | // Returns: = true if applicable 775 | // Remarks: S-JIS is excluded since the EBBFh 776 | 777 | inline static int IsKanjiData(uint8_t c1, uint8_t c2) 778 | { 779 | uint16_t val = c1 << 8 | c2; 780 | return !(val < 0x8140 || (val > 0x9ffc && val < 0xe040) || val > 0xebbf); 781 | } 782 | 783 | ///////////////////////////////////////////////////////////////////////////// 784 | // APPLICATIONS: Binary character alphanumeric mode 785 | // Number of arguments: the target character 786 | // Returns: binary value 787 | 788 | static uint8_t AlphabetToBinary(uint8_t c) 789 | { 790 | if (c >= '0' && c <= '9') { 791 | return (uint8_t)(c - '0'); 792 | } 793 | 794 | if (c >= 'A' && c <= 'Z') { 795 | return (uint8_t)(c - 'A' + 10); 796 | } 797 | 798 | if (c == ' ') { 799 | return 36; 800 | } 801 | 802 | if (c == '$') { 803 | return 37; 804 | } 805 | 806 | if (c == '%') { 807 | return 38; 808 | } 809 | 810 | if (c == '*') { 811 | return 39; 812 | } 813 | 814 | if (c == '+') { 815 | return 40; 816 | } 817 | 818 | if (c == '-') { 819 | return 41; 820 | } 821 | 822 | if (c == '.') { 823 | return 42; 824 | } 825 | 826 | if (c == '/') { 827 | return 43; 828 | } 829 | 830 | return 44; // c == ':' 831 | } 832 | 833 | ///////////////////////////////////////////////////////////////////////////// 834 | // APPLICATIONS: Binary Kanji character mode 835 | // Number of arguments: the target character 836 | // Returns: binary value 837 | static uint16_t KanjiToBinaly(uint16_t wc) 838 | { 839 | if (wc >= 0x8140 && wc <= 0x9ffc) { 840 | wc -= 0x8140; 841 | } else { // (wc >= 0xe040 && wc <= 0xebbf) 842 | wc -= 0xc140; 843 | } 844 | 845 | return (uint16_t)(((wc >> 8) * 0xc0) + (wc & 0x00ff)); 846 | } 847 | 848 | static int SetBitStream(int nIndex, uint16_t wData, int ncData, uint8_t m_byDataCodeWord[MAX_DATACODEWORD]) 849 | { 850 | int i; 851 | 852 | if (nIndex == -1 || nIndex + ncData > MAX_DATACODEWORD * 8) { 853 | return -1; 854 | } 855 | 856 | for (i = 0; i < ncData; ++i) { 857 | if (wData & (1 << (ncData - i - 1))) { 858 | m_byDataCodeWord[(nIndex + i) / 8] |= 1 << (7 - ((nIndex + i) % 8)); 859 | } 860 | } 861 | 862 | return nIndex + ncData; 863 | } 864 | 865 | static int GetBitLength(uint8_t nMode, int ncData, int nVerGroup) 866 | { 867 | int ncBits = 0; 868 | 869 | switch (nMode) { 870 | case QR_MODE_NUMERAL: 871 | ncBits = 4 + nIndicatorLenNumeral[nVerGroup] + (10 * (ncData / 3)); 872 | switch (ncData % 3) { 873 | case 1: 874 | ncBits += 4; 875 | break; 876 | case 2: 877 | ncBits += 7; 878 | break; 879 | default: // case 0: 880 | break; 881 | } 882 | 883 | break; 884 | 885 | case QR_MODE_ALPHABET: 886 | ncBits = 4 + nIndicatorLenAlphabet[nVerGroup] + (11 * (ncData / 2)) + (6 * (ncData % 2)); 887 | break; 888 | 889 | case QR_MODE_8BIT: 890 | ncBits = 4 + nIndicatorLen8Bit[nVerGroup] + (8 * ncData); 891 | break; 892 | 893 | default: // case QR_MODE_KANJI: 894 | ncBits = 4 + nIndicatorLenKanji[nVerGroup] + (13 * (ncData / 2)); 895 | break; 896 | } 897 | 898 | return ncBits; 899 | } 900 | 901 | static int EncodeSourceData(const char* input_data, int ncLength, int nVerGroup, int16_t m_nBlockLength[MAX_DATACODEWORD], uint8_t m_byBlockMode[MAX_DATACODEWORD], uint8_t m_byDataCodeWord[MAX_DATACODEWORD], QR_ENCODING_CONTEXT* ctx) 902 | { 903 | 904 | ZeroMemory(m_nBlockLength, MAX_DATACODEWORD * sizeof(m_nBlockLength[0])); 905 | 906 | int i, j; 907 | int validUTF8 = is_utf8(input_data, ncLength); 908 | // Investigate whether continuing characters (bytes) which mode is what 909 | for (ctx->ncDataBlock = i = 0; i < ncLength; ++i) { 910 | QR_DataMode byMode; 911 | 912 | if (!validUTF8 && ncLength % 2 == 0 && i % 2 == 0 && i < ncLength - 1 && IsKanjiData(input_data[i], input_data[i + 1])) { 913 | byMode = QR_MODE_KANJI; 914 | } else if (IsNumeralData(input_data[i])) { 915 | byMode = QR_MODE_NUMERAL; 916 | } else if (IsAlphabetData(input_data[i])) { 917 | byMode = QR_MODE_ALPHABET; 918 | } else { 919 | byMode = QR_MODE_8BIT; 920 | } 921 | 922 | if (i == 0) { 923 | m_byBlockMode[0] = byMode; 924 | } 925 | if (m_byBlockMode[ctx->ncDataBlock] != byMode) { 926 | m_byBlockMode[++ctx->ncDataBlock] = byMode; 927 | } 928 | 929 | ++m_nBlockLength[ctx->ncDataBlock]; 930 | 931 | if (byMode == QR_MODE_KANJI) { 932 | //Kanji characters rather than the number recorded in 933 | ++m_nBlockLength[ctx->ncDataBlock]; 934 | ++i; 935 | } 936 | } 937 | 938 | ++ctx->ncDataBlock; 939 | 940 | ///////////////////////////////////////////////////////////////////////// 941 | // Linked by a sequence of conditional block alphanumeric mode and numeric mode block adjacent 942 | 943 | int ncSrcBits, ncDstBits; //The bit length of the block mode if you have over the original bit length and a single alphanumeric 944 | int nBlock = 0; 945 | 946 | while (nBlock < ctx->ncDataBlock - 1) { 947 | int ncJoinFront, ncJoinBehind; //Bit length when combined with 8-bit byte block mode before and after 948 | int nJoinPosition = 0; // Block the binding of 8-bit byte mode: combined with the previous -1 = 0 = do not bind, bind behind a = 949 | 950 | // Sort of - "digit alphanumeric" - "or alphanumeric numbers" 951 | if ((m_byBlockMode[nBlock] == QR_MODE_NUMERAL && m_byBlockMode[nBlock + 1] == QR_MODE_ALPHABET) || (m_byBlockMode[nBlock] == QR_MODE_ALPHABET && m_byBlockMode[nBlock + 1] == QR_MODE_NUMERAL)) { 952 | 953 | // If you compare the bit length of alphanumeric characters and a single block mode over the original bit length 954 | ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) + GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup); 955 | 956 | ncDstBits = GetBitLength(QR_MODE_ALPHABET, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup); 957 | 958 | if (ncSrcBits > ncDstBits) { 959 | // If there is an 8-bit byte block mode back and forth, check whether they favor the binding of 960 | if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) { 961 | // There are 8-bit byte block mode before 962 | ncJoinFront = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1] + m_nBlockLength[nBlock], nVerGroup) + GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup); 963 | 964 | if (ncJoinFront > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock - 1], nVerGroup)) { 965 | ncJoinFront = 0; //8-bit byte and block mode does not bind 966 | } 967 | } else { 968 | ncJoinFront = 0; 969 | } 970 | 971 | if (nBlock < ctx->ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) { 972 | // There are 8-bit byte mode block behind 973 | ncJoinBehind = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 1] + m_nBlockLength[nBlock + 2], nVerGroup); 974 | 975 | if (ncJoinBehind > ncDstBits + GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock + 2], nVerGroup)) { 976 | ncJoinBehind = 0; //8-bit byte and block mode does not bind 977 | } 978 | } else { 979 | ncJoinBehind = 0; 980 | } 981 | 982 | if (ncJoinFront != 0 && ncJoinBehind != 0) { 983 | // If there is a 8-bit byte block mode has priority both before and after the way the data length is shorter 984 | nJoinPosition = (ncJoinFront < ncJoinBehind) ? -1 : 1; 985 | } else { 986 | nJoinPosition = (ncJoinFront != 0) ? -1 : ((ncJoinBehind != 0) ? 1 : 0); 987 | } 988 | 989 | if (nJoinPosition != 0) { 990 | // Block the binding of 8-bit byte mode 991 | if (nJoinPosition == -1) { 992 | m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock]; 993 | 994 | // The subsequent shift 995 | for (i = nBlock; i < ctx->ncDataBlock - 1; ++i) { 996 | m_byBlockMode[i] = m_byBlockMode[i + 1]; 997 | m_nBlockLength[i] = m_nBlockLength[i + 1]; 998 | } 999 | } else { 1000 | m_byBlockMode[nBlock + 1] = QR_MODE_8BIT; 1001 | m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2]; 1002 | 1003 | // The subsequent shift 1004 | for (i = nBlock + 2; i < ctx->ncDataBlock - 1; ++i) { 1005 | m_byBlockMode[i] = m_byBlockMode[i + 1]; 1006 | m_nBlockLength[i] = m_nBlockLength[i + 1]; 1007 | } 1008 | } 1009 | 1010 | --ctx->ncDataBlock; 1011 | } else { 1012 | // Block mode integrated into a single alphanumeric string of numbers and alphanumeric 1013 | 1014 | if (nBlock < ctx->ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_ALPHABET) { 1015 | // Binding mode of the block followed by alphanumeric block attempts to join 1016 | m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2]; 1017 | 1018 | // The subsequent shift 1019 | for (i = nBlock + 2; i < ctx->ncDataBlock - 1; ++i) { 1020 | m_byBlockMode[i] = m_byBlockMode[i + 1]; 1021 | m_nBlockLength[i] = m_nBlockLength[i + 1]; 1022 | } 1023 | 1024 | --ctx->ncDataBlock; 1025 | } 1026 | 1027 | m_byBlockMode[nBlock] = QR_MODE_ALPHABET; 1028 | m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1]; 1029 | 1030 | // The subsequent shift 1031 | for (i = nBlock + 1; i < ctx->ncDataBlock - 1; ++i) { 1032 | m_byBlockMode[i] = m_byBlockMode[i + 1]; 1033 | m_nBlockLength[i] = m_nBlockLength[i + 1]; 1034 | } 1035 | 1036 | --ctx->ncDataBlock; 1037 | 1038 | if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_ALPHABET) { 1039 | 1040 | // Combined mode of alphanumeric block before the block bound 1041 | m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock]; 1042 | 1043 | // The subsequent shift 1044 | for (i = nBlock; i < ctx->ncDataBlock - 1; ++i) { 1045 | m_byBlockMode[i] = m_byBlockMode[i + 1]; 1046 | m_nBlockLength[i] = m_nBlockLength[i + 1]; 1047 | } 1048 | 1049 | --ctx->ncDataBlock; 1050 | } 1051 | } 1052 | 1053 | continue; 1054 | //Re-examine the block of the current position 1055 | } 1056 | } 1057 | 1058 | ++nBlock; //Investigate the next block 1059 | } 1060 | 1061 | ///////////////////////////////////////////////////////////////////////// 1062 | // 8-bit byte block mode over the short block mode to continuous 1063 | 1064 | nBlock = 0; 1065 | 1066 | while (nBlock < ctx->ncDataBlock - 1) { 1067 | ncSrcBits = GetBitLength(m_byBlockMode[nBlock], m_nBlockLength[nBlock], nVerGroup) 1068 | + GetBitLength(m_byBlockMode[nBlock + 1], m_nBlockLength[nBlock + 1], nVerGroup); 1069 | 1070 | ncDstBits = GetBitLength(QR_MODE_8BIT, m_nBlockLength[nBlock] + m_nBlockLength[nBlock + 1], nVerGroup); 1071 | 1072 | // If there is a 8-bit byte block mode before, subtract the duplicate indicator minute 1073 | if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) { 1074 | ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]); 1075 | } 1076 | 1077 | // If there is a block behind the 8-bit byte mode, subtract the duplicate indicator minute 1078 | if (nBlock < ctx->ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) { 1079 | ncDstBits -= (4 + nIndicatorLen8Bit[nVerGroup]); 1080 | } 1081 | 1082 | if (ncSrcBits > ncDstBits) { 1083 | if (nBlock >= 1 && m_byBlockMode[nBlock - 1] == QR_MODE_8BIT) { 1084 | // 8-bit byte mode coupling block in front of the block to join 1085 | m_nBlockLength[nBlock - 1] += m_nBlockLength[nBlock]; 1086 | 1087 | // The subsequent shift 1088 | for (i = nBlock; i < ctx->ncDataBlock - 1; ++i) { 1089 | m_byBlockMode[i] = m_byBlockMode[i + 1]; 1090 | m_nBlockLength[i] = m_nBlockLength[i + 1]; 1091 | } 1092 | 1093 | --ctx->ncDataBlock; 1094 | --nBlock; 1095 | } 1096 | 1097 | if (nBlock < ctx->ncDataBlock - 2 && m_byBlockMode[nBlock + 2] == QR_MODE_8BIT) { 1098 | // 8-bit byte mode coupling block at the back of the block to join 1099 | m_nBlockLength[nBlock + 1] += m_nBlockLength[nBlock + 2]; 1100 | 1101 | // The subsequent shift 1102 | for (i = nBlock + 2; i < ctx->ncDataBlock - 1; ++i) { 1103 | m_byBlockMode[i] = m_byBlockMode[i + 1]; 1104 | m_nBlockLength[i] = m_nBlockLength[i + 1]; 1105 | } 1106 | 1107 | --ctx->ncDataBlock; 1108 | } 1109 | 1110 | m_byBlockMode[nBlock] = QR_MODE_8BIT; 1111 | m_nBlockLength[nBlock] += m_nBlockLength[nBlock + 1]; 1112 | 1113 | // The subsequent shift 1114 | for (i = nBlock + 1; i < ctx->ncDataBlock - 1; ++i) { 1115 | m_byBlockMode[i] = m_byBlockMode[i + 1]; 1116 | m_nBlockLength[i] = m_nBlockLength[i + 1]; 1117 | } 1118 | 1119 | --ctx->ncDataBlock; 1120 | 1121 | // Re-examination in front of the block bound 1122 | if (nBlock >= 1) { 1123 | --nBlock; 1124 | } 1125 | 1126 | continue; 1127 | } 1128 | 1129 | ++nBlock; //Investigate the next block 1130 | } 1131 | 1132 | ///////////////////////////////////////////////////////////////////////// 1133 | // Mosquito bit array 1134 | int ncComplete = 0; //Data pre-processing counter 1135 | 1136 | uint16_t wBinCode; 1137 | 1138 | ctx->ncDataCodeWordBit = 0; //Bit counter processing unit 1139 | 1140 | ZeroMemory(m_byDataCodeWord, MAX_DATACODEWORD); 1141 | 1142 | for (i = 0; i < ctx->ncDataBlock && ctx->ncDataCodeWordBit != -1; ++i) { 1143 | if (m_byBlockMode[i] == QR_MODE_NUMERAL) { 1144 | ///////////////////////////////////////////////////////////////// 1145 | // Numeric mode 1146 | // Indicator (0001b) 1147 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, 1, 4, m_byDataCodeWord); 1148 | 1149 | //Set number of characters 1150 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLenNumeral[nVerGroup], m_byDataCodeWord); 1151 | 1152 | // Save the bit string 1153 | for (j = 0; j < m_nBlockLength[i]; j += 3) { 1154 | if (j < m_nBlockLength[i] - 2) { 1155 | wBinCode = (uint16_t)(((input_data[ncComplete + j] - '0') * 100) + ((input_data[ncComplete + j + 1] - '0') * 10) + (input_data[ncComplete + j + 2] - '0')); 1156 | 1157 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, wBinCode, 10, m_byDataCodeWord); 1158 | } else if (j == m_nBlockLength[i] - 2) { 1159 | 1160 | // 2 bytes fraction 1161 | wBinCode = (uint16_t)(((input_data[ncComplete + j] - '0') * 10) + (input_data[ncComplete + j + 1] - '0')); 1162 | 1163 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, wBinCode, 7, m_byDataCodeWord); 1164 | } else if (j == m_nBlockLength[i] - 1) { 1165 | 1166 | // A fraction of bytes 1167 | wBinCode = (uint16_t)(input_data[ncComplete + j] - '0'); 1168 | 1169 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, wBinCode, 4, m_byDataCodeWord); 1170 | } 1171 | } 1172 | 1173 | ncComplete += m_nBlockLength[i]; 1174 | } 1175 | 1176 | else if (m_byBlockMode[i] == QR_MODE_ALPHABET) { 1177 | ///////////////////////////////////////////////////////////////// 1178 | // Alphanumeric mode 1179 | // Mode indicator (0010b) 1180 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, 2, 4, m_byDataCodeWord); 1181 | 1182 | // Set number of characters 1183 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLenAlphabet[nVerGroup], m_byDataCodeWord); 1184 | 1185 | // Save the bit string 1186 | for (j = 0; j < m_nBlockLength[i]; j += 2) { 1187 | if (j < m_nBlockLength[i] - 1) { 1188 | wBinCode = (uint16_t)((AlphabetToBinary(input_data[ncComplete + j]) * 45) + AlphabetToBinary(input_data[ncComplete + j + 1])); 1189 | 1190 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, wBinCode, 11, m_byDataCodeWord); 1191 | } else { 1192 | // A fraction of bytes 1193 | wBinCode = (uint16_t)AlphabetToBinary(input_data[ncComplete + j]); 1194 | 1195 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, wBinCode, 6, m_byDataCodeWord); 1196 | } 1197 | } 1198 | 1199 | ncComplete += m_nBlockLength[i]; 1200 | } 1201 | 1202 | else if (m_byBlockMode[i] == QR_MODE_8BIT) { 1203 | ///////////////////////////////////////////////////////////////// 1204 | // 8-bit byte mode 1205 | 1206 | // Mode indicator (0100b) 1207 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, 4, 4, m_byDataCodeWord); 1208 | 1209 | // Set number of characters 1210 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, (uint16_t)m_nBlockLength[i], nIndicatorLen8Bit[nVerGroup], m_byDataCodeWord); 1211 | 1212 | // Save the bit string 1213 | for (j = 0; j < m_nBlockLength[i]; ++j) { 1214 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, (uint16_t)input_data[ncComplete + j], 8, m_byDataCodeWord); 1215 | } 1216 | 1217 | ncComplete += m_nBlockLength[i]; 1218 | } else // m_byBlockMode[i] == QR_MODE_KANJI 1219 | { 1220 | ///////////////////////////////////////////////////////////////// 1221 | 1222 | // Kanji mode 1223 | 1224 | // Mode indicator (1000b) 1225 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, 8, 4, m_byDataCodeWord); 1226 | 1227 | // Set number of characters 1228 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, (uint16_t)(m_nBlockLength[i] / 2), nIndicatorLenKanji[nVerGroup], m_byDataCodeWord); 1229 | 1230 | // Save the bit string in character mode 1231 | for (j = 0; j < m_nBlockLength[i] / 2; ++j) { 1232 | uint16_t wBinCode = KanjiToBinaly((uint16_t)(((uint8_t)input_data[ncComplete + (j * 2)] << 8) + (uint8_t)input_data[ncComplete + (j * 2) + 1])); 1233 | ctx->ncDataCodeWordBit = SetBitStream(ctx->ncDataCodeWordBit, wBinCode, 13, m_byDataCodeWord); 1234 | } 1235 | 1236 | ncComplete += m_nBlockLength[i]; 1237 | } 1238 | } 1239 | 1240 | return (ctx->ncDataCodeWordBit != -1); 1241 | } 1242 | 1243 | ///////////////////////////////////////////////////////////////////////////// 1244 | // APPLICATIONS: To get the bit length 1245 | // Args: data mode type, data length, group version (model number) 1246 | // Returns: data bit length 1247 | // Remarks: data length of argument in Kanji mode is the number of bytes, not characters 1248 | 1249 | static int GetEncodeVersion(int nVersion, const char* lpsSource, int ncLength, int16_t m_nBlockLength[MAX_DATACODEWORD], uint8_t m_byBlockMode[MAX_DATACODEWORD], uint8_t m_byDataCodeWord[MAX_DATACODEWORD], QR_ENCODING_CONTEXT* ctx) 1250 | { 1251 | int nVerGroup = nVersion >= 27 ? QR_VERSION_L : (nVersion >= 10 ? QR_VERSION_M : QR_VERSION_S); 1252 | int i, j; 1253 | 1254 | for (i = nVerGroup; i <= QR_VERSION_L; ++i) { 1255 | if (EncodeSourceData(lpsSource, ncLength, i, m_nBlockLength, m_byBlockMode, m_byDataCodeWord, ctx)) { 1256 | if (i == QR_VERSION_S) { 1257 | for (j = 1; j <= 9; ++j) { 1258 | if ((ctx->ncDataCodeWordBit + 7) / 8 <= QR_VersionInfo[j].ncDataCodeWord[ctx->nLevel]) { 1259 | return j; 1260 | } 1261 | } 1262 | } else if (i == QR_VERSION_M) { 1263 | for (j = 10; j <= 26; ++j) { 1264 | if ((ctx->ncDataCodeWordBit + 7) / 8 <= QR_VersionInfo[j].ncDataCodeWord[ctx->nLevel]) { 1265 | return j; 1266 | } 1267 | } 1268 | } else if (i == QR_VERSION_L) { 1269 | for (j = 27; j <= 40; ++j) { 1270 | if ((ctx->ncDataCodeWordBit + 7) / 8 <= QR_VersionInfo[j].ncDataCodeWord[ctx->nLevel]) { 1271 | return j; 1272 | } 1273 | } 1274 | } 1275 | } 1276 | } 1277 | 1278 | return 0; 1279 | } 1280 | 1281 | static int min(int a, int b) 1282 | { 1283 | if (a <= b) { 1284 | return a; 1285 | } 1286 | return b; 1287 | } 1288 | 1289 | static void GetRSCodeWord(uint8_t* lpbyRSWork, int ncDataCodeWord, int ncRSCodeWord) 1290 | { 1291 | int i, j; 1292 | 1293 | for (i = 0; i < ncDataCodeWord; ++i) { 1294 | if (lpbyRSWork[0] != 0) { 1295 | uint8_t nExpFirst = byIntToExp[lpbyRSWork[0]]; //Multiplier coefficient is calculated from the first term 1296 | 1297 | for (j = 0; j < ncRSCodeWord; ++j) { 1298 | 1299 | //Add (% 255 ^ 255 = 1) the first term multiplier to multiplier sections 1300 | uint8_t nExpElement = (uint8_t)(((int)(byRSExp[ncRSCodeWord][j] + nExpFirst)) % 255); 1301 | 1302 | //Surplus calculated by the exclusive 1303 | lpbyRSWork[j] = (uint8_t)(lpbyRSWork[j + 1] ^ byExpToInt[nExpElement]); 1304 | } 1305 | 1306 | //Shift the remaining digits 1307 | for (j = ncRSCodeWord; j < ncDataCodeWord + ncRSCodeWord - 1; ++j) { 1308 | lpbyRSWork[j] = lpbyRSWork[j + 1]; 1309 | } 1310 | } else { 1311 | 1312 | //Shift the remaining digits 1313 | for (j = 0; j < ncDataCodeWord + ncRSCodeWord - 1; ++j) { 1314 | lpbyRSWork[j] = lpbyRSWork[j + 1]; 1315 | } 1316 | } 1317 | } 1318 | } 1319 | 1320 | static void SetFinderPattern(int x, int y, uint8_t m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE]) 1321 | { 1322 | static uint8_t byPattern[] = { 0x7f, // 1111111b 1323 | 0x41, // 1000001b 1324 | 0x5d, // 1011101b 1325 | 0x5d, // 1011101b 1326 | 0x5d, // 1011101b 1327 | 0x41, // 1000001b 1328 | 0x7f }; // 1111111b 1329 | int i, j; 1330 | 1331 | for (i = 0; i < 7; ++i) { 1332 | for (j = 0; j < 7; ++j) { 1333 | m_byModuleData[x + j][y + i] = (byPattern[i] & (1 << (6 - j))) ? '\x30' : '\x20'; 1334 | } 1335 | } 1336 | } 1337 | 1338 | static void SetVersionPattern(uint8_t m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE], QR_ENCODING_CONTEXT const* const ctx) 1339 | { 1340 | int i, j; 1341 | 1342 | if (ctx->nVersion <= 6) { 1343 | return; 1344 | } 1345 | 1346 | uint32_t nVerData = ctx->nVersion << 12; 1347 | 1348 | //Calculated bit remainder 1349 | 1350 | for (i = 0; i < 6; ++i) { 1351 | if (nVerData & (1 << (17 - i))) { 1352 | nVerData ^= (0x1f25 << (5 - i)); 1353 | } 1354 | } 1355 | 1356 | nVerData += ctx->nVersion << 12; 1357 | 1358 | for (i = 0; i < 6; ++i) { 1359 | for (j = 0; j < 3; ++j) { 1360 | m_byModuleData[ctx->nSymbolSize - 11 + j][i] = m_byModuleData[i][ctx->nSymbolSize - 11 + j] = (nVerData & (1 << (i * 3 + j))) ? '\x30' : '\x20'; 1361 | } 1362 | } 1363 | } 1364 | 1365 | static void SetAlignmentPattern(int x, int y, uint8_t m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE]) 1366 | { 1367 | static uint8_t byPattern[] = { 0x1f, // 11111b 1368 | 0x11, // 10001b 1369 | 0x15, // 10101b 1370 | 0x11, // 10001b 1371 | 0x1f }; // 11111b 1372 | int i, j; 1373 | 1374 | if (m_byModuleData[x][y] & 0x20) { 1375 | return; //Excluded due to overlap with the functional module 1376 | } 1377 | 1378 | x -= 2; 1379 | y -= 2; //Convert the coordinates to the upper left corner 1380 | 1381 | for (i = 0; i < 5; ++i) { 1382 | for (j = 0; j < 5; ++j) { 1383 | m_byModuleData[x + j][y + i] = (byPattern[i] & (1 << (4 - j))) ? '\x30' : '\x20'; 1384 | } 1385 | } 1386 | } 1387 | 1388 | static void SetFunctionModule(uint8_t m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE], QR_ENCODING_CONTEXT const* const ctx) 1389 | { 1390 | int i, j; 1391 | 1392 | //Position detection pattern 1393 | SetFinderPattern(0, 0, m_byModuleData); 1394 | SetFinderPattern(ctx->nSymbolSize - 7, 0, m_byModuleData); 1395 | SetFinderPattern(0, ctx->nSymbolSize - 7, m_byModuleData); 1396 | 1397 | //Separator pattern position detection 1398 | for (i = 0; i < 8; ++i) { 1399 | m_byModuleData[i][7] = m_byModuleData[7][i] = '\x20'; 1400 | m_byModuleData[ctx->nSymbolSize - 8][i] = m_byModuleData[ctx->nSymbolSize - 8 + i][7] = '\x20'; 1401 | m_byModuleData[i][ctx->nSymbolSize - 8] = m_byModuleData[7][ctx->nSymbolSize - 8 + i] = '\x20'; 1402 | } 1403 | 1404 | //Registration as part of a functional module position description format information 1405 | for (i = 0; i < 9; ++i) { 1406 | m_byModuleData[i][8] = m_byModuleData[8][i] = '\x20'; 1407 | } 1408 | 1409 | for (i = 0; i < 8; ++i) { 1410 | m_byModuleData[ctx->nSymbolSize - 8 + i][8] = m_byModuleData[8][ctx->nSymbolSize - 8 + i] = '\x20'; 1411 | } 1412 | 1413 | //Version information pattern 1414 | SetVersionPattern(m_byModuleData, ctx); 1415 | 1416 | //Pattern alignment 1417 | for (i = 0; i < QR_VersionInfo[ctx->nVersion].ncAlignPoint; ++i) { 1418 | SetAlignmentPattern(QR_VersionInfo[ctx->nVersion].nAlignPoint[i], 6, m_byModuleData); 1419 | SetAlignmentPattern(6, QR_VersionInfo[ctx->nVersion].nAlignPoint[i], m_byModuleData); 1420 | 1421 | for (j = 0; j < QR_VersionInfo[ctx->nVersion].ncAlignPoint; ++j) { 1422 | SetAlignmentPattern(QR_VersionInfo[ctx->nVersion].nAlignPoint[i], QR_VersionInfo[ctx->nVersion].nAlignPoint[j], m_byModuleData); 1423 | } 1424 | } 1425 | 1426 | //Timing pattern 1427 | for (i = 8; i <= ctx->nSymbolSize - 9; ++i) { 1428 | m_byModuleData[i][6] = (i % 2) == 0 ? '\x30' : '\x20'; 1429 | m_byModuleData[6][i] = (i % 2) == 0 ? '\x30' : '\x20'; 1430 | } 1431 | } 1432 | 1433 | static void SetCodeWordPattern(uint8_t m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE], const uint8_t m_byAllCodeWord[MAX_ALLCODEWORD], QR_ENCODING_CONTEXT const* const ctx) 1434 | { 1435 | int x = ctx->nSymbolSize; 1436 | int y = ctx->nSymbolSize - 1; 1437 | 1438 | int nCoef_x = 1; //placement orientation axis x 1439 | int nCoef_y = 1; //placement orientation axis y 1440 | 1441 | int i, j; 1442 | 1443 | for (i = 0; i < ctx->ncAllCodeWord; ++i) { 1444 | for (j = 0; j < 8; ++j) { 1445 | do { 1446 | x += nCoef_x; 1447 | nCoef_x *= -1; 1448 | 1449 | if (nCoef_x < 0) { 1450 | y += nCoef_y; 1451 | 1452 | if (y < 0 || y == ctx->nSymbolSize) { 1453 | y = (y < 0) ? 0 : ctx->nSymbolSize - 1; 1454 | nCoef_y *= -1; 1455 | 1456 | x -= 2; 1457 | 1458 | if (x == 6) { //Timing pattern 1459 | --x; 1460 | } 1461 | } 1462 | } 1463 | } while (m_byModuleData[x][y] & 0x20); //Exclude a functional module 1464 | 1465 | m_byModuleData[x][y] = (m_byAllCodeWord[i] & (1 << (7 - j))) ? '\x02' : '\x00'; 1466 | } 1467 | } 1468 | } 1469 | 1470 | static void SetMaskingPattern(int nPatternNo, uint8_t m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE], QR_ENCODING_CONTEXT const* const ctx) 1471 | { 1472 | int i, j; 1473 | 1474 | for (i = 0; i < ctx->nSymbolSize; ++i) { 1475 | for (j = 0; j < ctx->nSymbolSize; ++j) { 1476 | if (!(m_byModuleData[j][i] & 0x20)) //Exclude a functional module 1477 | { 1478 | int bMask; 1479 | 1480 | switch (nPatternNo) { 1481 | case 0: 1482 | bMask = ((i + j) % 2 == 0); 1483 | break; 1484 | 1485 | case 1: 1486 | bMask = (i % 2 == 0); 1487 | break; 1488 | 1489 | case 2: 1490 | bMask = (j % 3 == 0); 1491 | break; 1492 | 1493 | case 3: 1494 | bMask = ((i + j) % 3 == 0); 1495 | break; 1496 | 1497 | case 4: 1498 | bMask = (((i / 2) + (j / 3)) % 2 == 0); 1499 | break; 1500 | 1501 | case 5: 1502 | bMask = (((i * j) % 2) + ((i * j) % 3) == 0); 1503 | break; 1504 | 1505 | case 6: 1506 | bMask = ((((i * j) % 2) + ((i * j) % 3)) % 2 == 0); 1507 | break; 1508 | 1509 | default: // case 7: 1510 | bMask = ((((i * j) % 3) + ((i + j) % 2)) % 2 == 0); 1511 | break; 1512 | } 1513 | 1514 | m_byModuleData[j][i] = (uint8_t)((m_byModuleData[j][i] & 0xfe) | (((m_byModuleData[j][i] & 0x02) > 1) ^ bMask)); 1515 | } 1516 | } 1517 | } 1518 | } 1519 | 1520 | static void SetFormatInfoPattern(int nPatternNo, uint8_t m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE], QR_ENCODING_CONTEXT const* const ctx) 1521 | { 1522 | int nFormatInfo; 1523 | int i; 1524 | 1525 | switch (ctx->nLevel) { 1526 | case QR_LEVEL_M: 1527 | nFormatInfo = 0x00; // 00nnnb 1528 | break; 1529 | 1530 | case QR_LEVEL_L: 1531 | nFormatInfo = 0x08; // 01nnnb 1532 | break; 1533 | 1534 | case QR_LEVEL_Q: 1535 | nFormatInfo = 0x18; // 11nnnb 1536 | break; 1537 | 1538 | default: // case QR_LEVEL_H: 1539 | nFormatInfo = 0x10; // 10nnnb 1540 | break; 1541 | } 1542 | 1543 | nFormatInfo += nPatternNo; 1544 | 1545 | int nFormatData = nFormatInfo << 10; 1546 | 1547 | //Calculated bit remainder 1548 | 1549 | for (i = 0; i < 5; ++i) { 1550 | if (nFormatData & (1 << (14 - i))) { 1551 | nFormatData ^= (0x0537 << (4 - i)); // 10100110111b 1552 | } 1553 | } 1554 | 1555 | nFormatData += nFormatInfo << 10; 1556 | 1557 | //Masking 1558 | nFormatData ^= 0x5412; // 101010000010010b 1559 | 1560 | // Position detection patterns located around the upper left 1561 | for (i = 0; i <= 5; ++i) { 1562 | m_byModuleData[8][i] = (nFormatData & (1 << i)) ? '\x30' : '\x20'; 1563 | } 1564 | 1565 | m_byModuleData[8][7] = (nFormatData & (1 << 6)) ? '\x30' : '\x20'; 1566 | m_byModuleData[8][8] = (nFormatData & (1 << 7)) ? '\x30' : '\x20'; 1567 | m_byModuleData[7][8] = (nFormatData & (1 << 8)) ? '\x30' : '\x20'; 1568 | 1569 | for (i = 9; i <= 14; ++i) { 1570 | m_byModuleData[14 - i][8] = (nFormatData & (1 << i)) ? '\x30' : '\x20'; 1571 | } 1572 | 1573 | //Position detection patterns located under the upper right corner 1574 | for (i = 0; i <= 7; ++i) { 1575 | m_byModuleData[ctx->nSymbolSize - 1 - i][8] = (nFormatData & (1 << i)) ? '\x30' : '\x20'; 1576 | } 1577 | 1578 | //Right lower left position detection patterns located 1579 | m_byModuleData[8][ctx->nSymbolSize - 8] = '\x30'; //Module fixed dark 1580 | 1581 | for (i = 8; i <= 14; ++i) { 1582 | m_byModuleData[8][ctx->nSymbolSize - 15 + i] = (nFormatData & (1 << i)) ? '\x30' : '\x20'; 1583 | } 1584 | } 1585 | static int CountPenalty(uint8_t m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE], QR_ENCODING_CONTEXT const* const ctx) 1586 | { 1587 | int nPenalty = 0; 1588 | int i, j, k; 1589 | 1590 | //Column of the same color adjacent module 1591 | for (i = 0; i < ctx->nSymbolSize; ++i) { 1592 | for (j = 0; j < ctx->nSymbolSize - 4; ++j) { 1593 | int nCount = 1; 1594 | 1595 | for (k = j + 1; k < ctx->nSymbolSize; k++) { 1596 | if (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i][k] & 0x11) == 0)) { 1597 | ++nCount; 1598 | } else { 1599 | break; 1600 | } 1601 | } 1602 | 1603 | if (nCount >= 5) { 1604 | nPenalty += 3 + (nCount - 5); 1605 | } 1606 | 1607 | j = k - 1; 1608 | } 1609 | } 1610 | 1611 | //Adjacent module line of the same color 1612 | for (i = 0; i < ctx->nSymbolSize; ++i) { 1613 | for (j = 0; j < ctx->nSymbolSize - 4; ++j) { 1614 | int nCount = 1; 1615 | 1616 | for (k = j + 1; k < ctx->nSymbolSize; k++) { 1617 | if (((m_byModuleData[j][i] & 0x11) == 0) == ((m_byModuleData[k][i] & 0x11) == 0)) { 1618 | ++nCount; 1619 | } else { 1620 | break; 1621 | } 1622 | } 1623 | 1624 | if (nCount >= 5) { 1625 | nPenalty += 3 + (nCount - 5); 1626 | } 1627 | 1628 | j = k - 1; 1629 | } 1630 | } 1631 | 1632 | //Modules of the same color block (2 ~ 2) 1633 | for (i = 0; i < ctx->nSymbolSize - 1; ++i) { 1634 | for (j = 0; j < ctx->nSymbolSize - 1; ++j) { 1635 | if ((((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i + 1][j] & 0x11) == 0)) && (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i][j + 1] & 0x11) == 0)) && (((m_byModuleData[i][j] & 0x11) == 0) == ((m_byModuleData[i + 1][j + 1] & 0x11) == 0))) { 1636 | nPenalty += 3; 1637 | } 1638 | } 1639 | } 1640 | 1641 | //Pattern (dark dark: light: dark: light) ratio 1:1:3:1:1 in the same column 1642 | for (i = 0; i < ctx->nSymbolSize; ++i) { 1643 | for (j = 0; j < ctx->nSymbolSize - 6; ++j) { 1644 | if (((j == 0) || (!(m_byModuleData[i][j - 1] & 0x11))) && (m_byModuleData[i][j] & 0x11) && (!(m_byModuleData[i][j + 1] & 0x11)) && (m_byModuleData[i][j + 2] & 0x11) && (m_byModuleData[i][j + 3] & 0x11) && (m_byModuleData[i][j + 4] & 0x11) && (!(m_byModuleData[i][j + 5] & 0x11)) && (m_byModuleData[i][j + 6] & 0x11) && ((j == ctx->nSymbolSize - 7) || (!(m_byModuleData[i][j + 7] & 0x11)))) { 1645 | 1646 | //Clear pattern of four or more before or after 1647 | if (((j < 2 || !(m_byModuleData[i][j - 2] & 0x11)) && (j < 3 || !(m_byModuleData[i][j - 3] & 0x11)) && (j < 4 || !(m_byModuleData[i][j - 4] & 0x11))) || ((j >= ctx->nSymbolSize - 8 || !(m_byModuleData[i][j + 8] & 0x11)) && (j >= ctx->nSymbolSize - 9 || !(m_byModuleData[i][j + 9] & 0x11)) && (j >= ctx->nSymbolSize - 10 || !(m_byModuleData[i][j + 10] & 0x11)))) { 1648 | nPenalty += 40; 1649 | } 1650 | } 1651 | } 1652 | } 1653 | 1654 | //Pattern (dark dark: light: dark: light) in the same line ratio 1:1:3:1:1 1655 | for (i = 0; i < ctx->nSymbolSize; ++i) { 1656 | for (j = 0; j < ctx->nSymbolSize - 6; ++j) { 1657 | if (((j == 0) || (!(m_byModuleData[j - 1][i] & 0x11))) && (m_byModuleData[j][i] & 0x11) && (!(m_byModuleData[j + 1][i] & 0x11)) && (m_byModuleData[j + 2][i] & 0x11) && (m_byModuleData[j + 3][i] & 0x11) && (m_byModuleData[j + 4][i] & 0x11) && (!(m_byModuleData[j + 5][i] & 0x11)) && (m_byModuleData[j + 6][i] & 0x11) && ((j == ctx->nSymbolSize - 7) || (!(m_byModuleData[j + 7][i] & 0x11)))) { 1658 | 1659 | //Clear pattern of four or more before or after 1660 | if (((j < 2 || !(m_byModuleData[j - 2][i] & 0x11)) && (j < 3 || !(m_byModuleData[j - 3][i] & 0x11)) && (j < 4 || !(m_byModuleData[j - 4][i] & 0x11))) || ((j >= ctx->nSymbolSize - 8 || !(m_byModuleData[j + 8][i] & 0x11)) && (j >= ctx->nSymbolSize - 9 || !(m_byModuleData[j + 9][i] & 0x11)) && (j >= ctx->nSymbolSize - 10 || !(m_byModuleData[j + 10][i] & 0x11)))) { 1661 | nPenalty += 40; 1662 | } 1663 | } 1664 | } 1665 | } 1666 | 1667 | //The proportion of modules for the entire dark 1668 | int nCount = 0; 1669 | 1670 | for (i = 0; i < ctx->nSymbolSize; ++i) { 1671 | for (j = 0; j < ctx->nSymbolSize; ++j) { 1672 | if (!(m_byModuleData[i][j] & 0x11)) { 1673 | ++nCount; 1674 | } 1675 | } 1676 | } 1677 | 1678 | nPenalty += (abs(50 - ((nCount * 100) / (ctx->nSymbolSize * ctx->nSymbolSize))) / 5) * 10; 1679 | 1680 | return nPenalty; 1681 | } 1682 | 1683 | static void FormatModule(uint8_t m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE], uint8_t m_byAllCodeWord[MAX_ALLCODEWORD], QR_ENCODING_CONTEXT* ctx) 1684 | { 1685 | int i, j; 1686 | 1687 | ZeroMemory(m_byModuleData, MAX_MODULESIZE * MAX_MODULESIZE * sizeof(uint8_t)); 1688 | 1689 | //Function module placement 1690 | SetFunctionModule(m_byModuleData, ctx); 1691 | 1692 | //Data placement 1693 | SetCodeWordPattern(m_byModuleData, m_byAllCodeWord, ctx); 1694 | 1695 | if (ctx->nMaskingNo == QR_MaskAuto) { 1696 | 1697 | //Select the best pattern masking 1698 | ctx->nMaskingNo = 0; 1699 | 1700 | SetMaskingPattern(ctx->nMaskingNo, m_byModuleData, ctx); //Masking 1701 | SetFormatInfoPattern(ctx->nMaskingNo, m_byModuleData, ctx); //Placement pattern format information 1702 | 1703 | int nMinPenalty = CountPenalty(m_byModuleData, ctx); 1704 | 1705 | for (i = 1; i <= 7; ++i) { 1706 | SetMaskingPattern(i, m_byModuleData, ctx); //Masking 1707 | SetFormatInfoPattern(i, m_byModuleData, ctx); //Placement pattern format information 1708 | 1709 | int nPenalty = CountPenalty(m_byModuleData, ctx); 1710 | 1711 | if (nPenalty < nMinPenalty) { 1712 | nMinPenalty = nPenalty; 1713 | ctx->nMaskingNo = i; 1714 | } 1715 | } 1716 | } 1717 | 1718 | SetMaskingPattern(ctx->nMaskingNo, m_byModuleData, ctx); //Masking 1719 | SetFormatInfoPattern(ctx->nMaskingNo, m_byModuleData, ctx); //Placement pattern format information 1720 | 1721 | // The module pattern converted to a Boolean value 1722 | 1723 | for (i = 0; i < ctx->nSymbolSize; ++i) { 1724 | for (j = 0; j < ctx->nSymbolSize; ++j) { 1725 | m_byModuleData[i][j] = (uint8_t)((m_byModuleData[i][j] & 0x11) != 0); 1726 | } 1727 | } 1728 | } 1729 | 1730 | int EncodeData(QR_Level level, int version, QR_MaskPattern maskPattern, const char* data_in, size_t in_size, uint8_t* output) 1731 | { 1732 | int i, j; 1733 | QR_ENCODING_CONTEXT ctx; 1734 | QR_IMAGE_STORAGE_ATTRIBUTE_NOINIT uint8_t m_byModuleData[MAX_MODULESIZE][MAX_MODULESIZE] = { 0 }; // [x][y] 1735 | QR_STORAGE_ATTRIBUTE_EXTERNAL_RAM uint8_t m_byAllCodeWord[MAX_ALLCODEWORD] = { 0 }; 1736 | QR_STORAGE_ATTRIBUTE_EXTERNAL_RAM int16_t m_nBlockLength[MAX_DATACODEWORD] = { 0 }; 1737 | QR_STORAGE_ATTRIBUTE_EXTERNAL_RAM uint8_t m_byBlockMode[MAX_DATACODEWORD] = { 0 }; 1738 | QR_STORAGE_ATTRIBUTE_EXTERNAL_RAM uint8_t m_byDataCodeWord[MAX_DATACODEWORD] = { 0 }; 1739 | QR_STORAGE_ATTRIBUTE_EXTERNAL_RAM uint8_t m_byRSWork[MAX_CODEBLOCK] = { 0 }; 1740 | ctx.nLevel = level; 1741 | ctx.nMaskingNo = maskPattern; 1742 | 1743 | // If the data length is not specified, acquired by lstrlen 1744 | int ncLength = in_size > 0 ? in_size : strlen(data_in); 1745 | 1746 | if (ncLength == 0) { 1747 | return QR_E_EmptyInput; // No data 1748 | } 1749 | 1750 | // Check version (model number) 1751 | 1752 | ctx.nEncodeVersion = GetEncodeVersion(version, data_in, ncLength, m_nBlockLength, m_byBlockMode, m_byDataCodeWord, &ctx); 1753 | 1754 | if (ctx.nEncodeVersion == 0) { 1755 | return QR_E_InvalidVersion; 1756 | } 1757 | // Over-capacity 1758 | if (version == QR_VERSION_S) { 1759 | // Auto Part 1760 | ctx.nVersion = ctx.nEncodeVersion; 1761 | } else { 1762 | if (ctx.nEncodeVersion <= version) { 1763 | ctx.nVersion = version; 1764 | } else { 1765 | return QR_E_VersionNotFit; // Over-capacity 1766 | } 1767 | } 1768 | 1769 | // Terminator addition code "0000" 1770 | int ncDataCodeWord = QR_VersionInfo[ctx.nVersion].ncDataCodeWord[level]; 1771 | 1772 | int ncTerminater = min(4, (ncDataCodeWord * 8) - ctx.ncDataCodeWordBit); 1773 | 1774 | if (ncTerminater > 0) { 1775 | ctx.ncDataCodeWordBit = SetBitStream(ctx.ncDataCodeWordBit, 0, ncTerminater, m_byDataCodeWord); 1776 | } 1777 | 1778 | // Additional padding code "11101100, 00010001" 1779 | uint8_t byPaddingCode = 0xec; 1780 | 1781 | for (i = (ctx.ncDataCodeWordBit + 7) / 8; i < ncDataCodeWord; ++i) { 1782 | m_byDataCodeWord[i] = byPaddingCode; 1783 | 1784 | byPaddingCode = (uint8_t)(byPaddingCode == 0xec ? 0x11 : 0xec); 1785 | } 1786 | 1787 | // Calculated the total clear area code word 1788 | ctx.ncAllCodeWord = QR_VersionInfo[ctx.nVersion].ncAllCodeWord; 1789 | 1790 | ZeroMemory(m_byAllCodeWord, ctx.ncAllCodeWord); 1791 | 1792 | int nDataCwIndex = 0; // Position data processing code word 1793 | 1794 | // Division number data block 1795 | int ncBlock1 = QR_VersionInfo[ctx.nVersion].RS_BlockInfo1[level].ncRSBlock; 1796 | int ncBlock2 = QR_VersionInfo[ctx.nVersion].RS_BlockInfo2[level].ncRSBlock; 1797 | int ncBlockSum = ncBlock1 + ncBlock2; 1798 | int nBlockNo = 0; // Block number in the process 1799 | 1800 | // The number of data code words by block 1801 | int ncDataCw1 = QR_VersionInfo[ctx.nVersion].RS_BlockInfo1[level].ncDataCodeWord; 1802 | int ncDataCw2 = QR_VersionInfo[ctx.nVersion].RS_BlockInfo2[level].ncDataCodeWord; 1803 | 1804 | // Code word interleaving data placement 1805 | for (i = 0; i < ncBlock1; ++i) { 1806 | for (j = 0; j < ncDataCw1; ++j) { 1807 | m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++]; 1808 | } 1809 | 1810 | ++nBlockNo; 1811 | } 1812 | 1813 | for (i = 0; i < ncBlock2; ++i) { 1814 | for (j = 0; j < ncDataCw2; ++j) { 1815 | if (j < ncDataCw1) { 1816 | m_byAllCodeWord[(ncBlockSum * j) + nBlockNo] = m_byDataCodeWord[nDataCwIndex++]; 1817 | } else { 1818 | // 2 minute fraction block placement event 1819 | m_byAllCodeWord[(ncBlockSum * ncDataCw1) + i] = m_byDataCodeWord[nDataCwIndex++]; 1820 | } 1821 | } 1822 | 1823 | ++nBlockNo; 1824 | } 1825 | 1826 | // RS code words by block number (currently пїЅпїЅ The same number) 1827 | int ncRSCw1 = QR_VersionInfo[ctx.nVersion].RS_BlockInfo1[level].ncAllCodeWord - ncDataCw1; 1828 | int ncRSCw2 = QR_VersionInfo[ctx.nVersion].RS_BlockInfo2[level].ncAllCodeWord - ncDataCw2; 1829 | 1830 | // RS code word is calculated 1831 | nDataCwIndex = 0; 1832 | nBlockNo = 0; 1833 | 1834 | for (i = 0; i < ncBlock1; ++i) { 1835 | ZeroMemory(m_byRSWork, sizeof(m_byRSWork)); 1836 | memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw1); 1837 | GetRSCodeWord(m_byRSWork, ncDataCw1, ncRSCw1); 1838 | // RS code word placement 1839 | for (j = 0; j < ncRSCw1; ++j) { 1840 | m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j]; 1841 | } 1842 | nDataCwIndex += ncDataCw1; 1843 | ++nBlockNo; 1844 | } 1845 | 1846 | for (i = 0; i < ncBlock2; ++i) { 1847 | ZeroMemory(m_byRSWork, sizeof(m_byRSWork)); 1848 | memmove(m_byRSWork, m_byDataCodeWord + nDataCwIndex, ncDataCw2); 1849 | GetRSCodeWord(m_byRSWork, ncDataCw2, ncRSCw2); 1850 | // RS code word placement 1851 | for (j = 0; j < ncRSCw2; ++j) { 1852 | m_byAllCodeWord[ncDataCodeWord + (ncBlockSum * j) + nBlockNo] = m_byRSWork[j]; 1853 | } 1854 | nDataCwIndex += ncDataCw2; 1855 | ++nBlockNo; 1856 | } 1857 | 1858 | ctx.nSymbolSize = ctx.nVersion * 4 + 17; 1859 | 1860 | // Module placement 1861 | FormatModule(m_byModuleData, m_byAllCodeWord, &ctx); 1862 | doQrOutput(m_byModuleData, ctx.nSymbolSize, output); 1863 | 1864 | return ctx.nSymbolSize; 1865 | } 1866 | --------------------------------------------------------------------------------