qrencode  4.1.1
About: libqrencode is a fast and compact library and command-line utility for encoding data in a QR Code symbol.
  Fossies Dox: qrencode-4.1.1.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

qrspec.c
Go to the documentation of this file.
1/*
2 * qrencode - QR Code encoder
3 *
4 * QR Code specification in convenient format.
5 * Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
6 *
7 * The following data / specifications are taken from
8 * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
9 * or
10 * "Automatic identification and data capture techniques --
11 * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
12 *
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or any later version.
17 *
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 */
27
28#if HAVE_CONFIG_H
29# include "config.h"
30#endif
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <errno.h>
35
36#include "qrspec.h"
37#include "qrinput.h"
38
39/******************************************************************************
40 * Version and capacity
41 *****************************************************************************/
42
43typedef struct {
44 int width; //< Edge length of the symbol
45 int words; //< Data capacity (bytes)
46 int remainder; //< Remainder bit (bits)
47 int ec[4]; //< Number of ECC code (bytes)
49
50/**
51 * Table of the capacity of symbols
52 * See Table 1 (pp.13) and Table 12-16 (pp.30-36), JIS X0510:2004.
53 */
55 { 0, 0, 0, { 0, 0, 0, 0}},
56 { 21, 26, 0, { 7, 10, 13, 17}}, // 1
57 { 25, 44, 7, { 10, 16, 22, 28}},
58 { 29, 70, 7, { 15, 26, 36, 44}},
59 { 33, 100, 7, { 20, 36, 52, 64}},
60 { 37, 134, 7, { 26, 48, 72, 88}}, // 5
61 { 41, 172, 7, { 36, 64, 96, 112}},
62 { 45, 196, 0, { 40, 72, 108, 130}},
63 { 49, 242, 0, { 48, 88, 132, 156}},
64 { 53, 292, 0, { 60, 110, 160, 192}},
65 { 57, 346, 0, { 72, 130, 192, 224}}, //10
66 { 61, 404, 0, { 80, 150, 224, 264}},
67 { 65, 466, 0, { 96, 176, 260, 308}},
68 { 69, 532, 0, { 104, 198, 288, 352}},
69 { 73, 581, 3, { 120, 216, 320, 384}},
70 { 77, 655, 3, { 132, 240, 360, 432}}, //15
71 { 81, 733, 3, { 144, 280, 408, 480}},
72 { 85, 815, 3, { 168, 308, 448, 532}},
73 { 89, 901, 3, { 180, 338, 504, 588}},
74 { 93, 991, 3, { 196, 364, 546, 650}},
75 { 97, 1085, 3, { 224, 416, 600, 700}}, //20
76 {101, 1156, 4, { 224, 442, 644, 750}},
77 {105, 1258, 4, { 252, 476, 690, 816}},
78 {109, 1364, 4, { 270, 504, 750, 900}},
79 {113, 1474, 4, { 300, 560, 810, 960}},
80 {117, 1588, 4, { 312, 588, 870, 1050}}, //25
81 {121, 1706, 4, { 336, 644, 952, 1110}},
82 {125, 1828, 4, { 360, 700, 1020, 1200}},
83 {129, 1921, 3, { 390, 728, 1050, 1260}},
84 {133, 2051, 3, { 420, 784, 1140, 1350}},
85 {137, 2185, 3, { 450, 812, 1200, 1440}}, //30
86 {141, 2323, 3, { 480, 868, 1290, 1530}},
87 {145, 2465, 3, { 510, 924, 1350, 1620}},
88 {149, 2611, 3, { 540, 980, 1440, 1710}},
89 {153, 2761, 3, { 570, 1036, 1530, 1800}},
90 {157, 2876, 0, { 570, 1064, 1590, 1890}}, //35
91 {161, 3034, 0, { 600, 1120, 1680, 1980}},
92 {165, 3196, 0, { 630, 1204, 1770, 2100}},
93 {169, 3362, 0, { 660, 1260, 1860, 2220}},
94 {173, 3532, 0, { 720, 1316, 1950, 2310}},
95 {177, 3706, 0, { 750, 1372, 2040, 2430}} //40
96};
97
99{
101}
102
104{
106}
107
109{
110 int i;
111 int words;
112
113 for(i = 1; i <= QRSPEC_VERSION_MAX; i++) {
114 words = qrspecCapacity[i].words - qrspecCapacity[i].ec[level];
115 if(words >= size) return i;
116 }
117
118 return QRSPEC_VERSION_MAX;
119}
120
122{
124}
125
127{
129}
130
131/******************************************************************************
132 * Length indicator
133 *****************************************************************************/
134
135static const int lengthTableBits[4][3] = {
136 {10, 12, 14},
137 { 9, 11, 13},
138 { 8, 16, 16},
139 { 8, 10, 12}
140};
141
143{
144 int l;
145
146 if(!QRinput_isSplittableMode(mode)) return 0;
147 if(version <= 9) {
148 l = 0;
149 } else if(version <= 26) {
150 l = 1;
151 } else {
152 l = 2;
153 }
154
155 return lengthTableBits[mode][l];
156}
157
159{
160 int l;
161 int bits;
162 int words;
163
164 if(!QRinput_isSplittableMode(mode)) return 0;
165 if(version <= 9) {
166 l = 0;
167 } else if(version <= 26) {
168 l = 1;
169 } else {
170 l = 2;
171 }
172
173 bits = lengthTableBits[mode][l];
174 words = (1 << bits) - 1;
175 if(mode == QR_MODE_KANJI) {
176 words *= 2; // the number of bytes is required
177 }
178
179 return words;
180}
181
182/******************************************************************************
183 * Error correction code
184 *****************************************************************************/
185
186/**
187 * Table of the error correction code (Reed-Solomon block)
188 * See Table 12-16 (pp.30-36), JIS X0510:2004.
189 */
190static const int eccTable[QRSPEC_VERSION_MAX+1][4][2] = {
191 {{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}},
192 {{ 1, 0}, { 1, 0}, { 1, 0}, { 1, 0}}, // 1
193 {{ 1, 0}, { 1, 0}, { 1, 0}, { 1, 0}},
194 {{ 1, 0}, { 1, 0}, { 2, 0}, { 2, 0}},
195 {{ 1, 0}, { 2, 0}, { 2, 0}, { 4, 0}},
196 {{ 1, 0}, { 2, 0}, { 2, 2}, { 2, 2}}, // 5
197 {{ 2, 0}, { 4, 0}, { 4, 0}, { 4, 0}},
198 {{ 2, 0}, { 4, 0}, { 2, 4}, { 4, 1}},
199 {{ 2, 0}, { 2, 2}, { 4, 2}, { 4, 2}},
200 {{ 2, 0}, { 3, 2}, { 4, 4}, { 4, 4}},
201 {{ 2, 2}, { 4, 1}, { 6, 2}, { 6, 2}}, //10
202 {{ 4, 0}, { 1, 4}, { 4, 4}, { 3, 8}},
203 {{ 2, 2}, { 6, 2}, { 4, 6}, { 7, 4}},
204 {{ 4, 0}, { 8, 1}, { 8, 4}, {12, 4}},
205 {{ 3, 1}, { 4, 5}, {11, 5}, {11, 5}},
206 {{ 5, 1}, { 5, 5}, { 5, 7}, {11, 7}}, //15
207 {{ 5, 1}, { 7, 3}, {15, 2}, { 3, 13}},
208 {{ 1, 5}, {10, 1}, { 1, 15}, { 2, 17}},
209 {{ 5, 1}, { 9, 4}, {17, 1}, { 2, 19}},
210 {{ 3, 4}, { 3, 11}, {17, 4}, { 9, 16}},
211 {{ 3, 5}, { 3, 13}, {15, 5}, {15, 10}}, //20
212 {{ 4, 4}, {17, 0}, {17, 6}, {19, 6}},
213 {{ 2, 7}, {17, 0}, { 7, 16}, {34, 0}},
214 {{ 4, 5}, { 4, 14}, {11, 14}, {16, 14}},
215 {{ 6, 4}, { 6, 14}, {11, 16}, {30, 2}},
216 {{ 8, 4}, { 8, 13}, { 7, 22}, {22, 13}}, //25
217 {{10, 2}, {19, 4}, {28, 6}, {33, 4}},
218 {{ 8, 4}, {22, 3}, { 8, 26}, {12, 28}},
219 {{ 3, 10}, { 3, 23}, { 4, 31}, {11, 31}},
220 {{ 7, 7}, {21, 7}, { 1, 37}, {19, 26}},
221 {{ 5, 10}, {19, 10}, {15, 25}, {23, 25}}, //30
222 {{13, 3}, { 2, 29}, {42, 1}, {23, 28}},
223 {{17, 0}, {10, 23}, {10, 35}, {19, 35}},
224 {{17, 1}, {14, 21}, {29, 19}, {11, 46}},
225 {{13, 6}, {14, 23}, {44, 7}, {59, 1}},
226 {{12, 7}, {12, 26}, {39, 14}, {22, 41}}, //35
227 {{ 6, 14}, { 6, 34}, {46, 10}, { 2, 64}},
228 {{17, 4}, {29, 14}, {49, 10}, {24, 46}},
229 {{ 4, 18}, {13, 32}, {48, 14}, {42, 32}},
230 {{20, 4}, {40, 7}, {43, 22}, {10, 67}},
231 {{19, 6}, {18, 31}, {34, 34}, {20, 61}},//40
232};
233
235{
236 int b1, b2;
237 int data, ecc;
238
239 b1 = eccTable[version][level][0];
240 b2 = eccTable[version][level][1];
243
244 if(b2 == 0) {
245 spec[0] = b1;
246 spec[1] = data / b1;
247 spec[2] = ecc / b1;
248 spec[3] = spec[4] = 0;
249 } else {
250 spec[0] = b1;
251 spec[1] = data / (b1 + b2);
252 spec[2] = ecc / (b1 + b2);
253 spec[3] = b2;
254 spec[4] = spec[1] + 1;
255 }
256}
257
258/******************************************************************************
259 * Alignment pattern
260 *****************************************************************************/
261
262/**
263 * Positions of alignment patterns.
264 * This array includes only the second and the third position of the alignment
265 * patterns. Rest of them can be calculated from the distance between them.
266 *
267 * See Table 1 in Appendix E (pp.71) of JIS X0510:2004.
268 */
269static const int alignmentPattern[QRSPEC_VERSION_MAX+1][2] = {
270 { 0, 0},
271 { 0, 0}, {18, 0}, {22, 0}, {26, 0}, {30, 0}, // 1- 5
272 {34, 0}, {22, 38}, {24, 42}, {26, 46}, {28, 50}, // 6-10
273 {30, 54}, {32, 58}, {34, 62}, {26, 46}, {26, 48}, //11-15
274 {26, 50}, {30, 54}, {30, 56}, {30, 58}, {34, 62}, //16-20
275 {28, 50}, {26, 50}, {30, 54}, {28, 54}, {32, 58}, //21-25
276 {30, 58}, {34, 62}, {26, 50}, {30, 54}, {26, 52}, //26-30
277 {30, 56}, {34, 60}, {30, 58}, {34, 62}, {30, 54}, //31-35
278 {24, 50}, {28, 54}, {32, 58}, {26, 54}, {30, 58}, //35-40
279};
280
281/**
282 * Put an alignment marker.
283 * @param frame
284 * @param width
285 * @param ox,oy center coordinate of the pattern
286 */
287static void QRspec_putAlignmentMarker(unsigned char *frame, int width, int ox, int oy)
288{
289 static const unsigned char finder[] = {
290 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
291 0xa1, 0xa0, 0xa0, 0xa0, 0xa1,
292 0xa1, 0xa0, 0xa1, 0xa0, 0xa1,
293 0xa1, 0xa0, 0xa0, 0xa0, 0xa1,
294 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
295 };
296 int x, y;
297 const unsigned char *s;
298
299 frame += (oy - 2) * width + ox - 2;
300 s = finder;
301 for(y = 0; y < 5; y++) {
302 for(x = 0; x < 5; x++) {
303 frame[x] = s[x];
304 }
305 frame += width;
306 s += 5;
307 }
308}
309
310static void QRspec_putAlignmentPattern(int version, unsigned char *frame, int width)
311{
312 int d, w, x, y, cx, cy;
313
314 if(version < 2) return;
315
317 if(d < 0) {
318 w = 2;
319 } else {
320 w = (width - alignmentPattern[version][0]) / d + 2;
321 }
322
323 if(w * w - 3 == 1) {
326 QRspec_putAlignmentMarker(frame, width, x, y);
327 return;
328 }
329
330 cx = alignmentPattern[version][0];
331 for(x = 1; x < w - 1; x++) {
332 QRspec_putAlignmentMarker(frame, width, 6, cx);
333 QRspec_putAlignmentMarker(frame, width, cx, 6);
334 cx += d;
335 }
336
337 cy = alignmentPattern[version][0];
338 for(y = 0; y < w-1; y++) {
339 cx = alignmentPattern[version][0];
340 for(x = 0; x < w-1; x++) {
341 QRspec_putAlignmentMarker(frame, width, cx, cy);
342 cx += d;
343 }
344 cy += d;
345 }
346}
347
348/******************************************************************************
349 * Version information pattern
350 *****************************************************************************/
351
352/**
353 * Version information pattern (BCH coded).
354 * See Table 1 in Appendix D (pp.68) of JIS X0510:2004.
355 */
356static const unsigned int versionPattern[QRSPEC_VERSION_MAX - 6] = {
357 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
358 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
359 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
360 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
361 0x27541, 0x28c69
362};
363
365{
366 if(version < 7 || version > QRSPEC_VERSION_MAX) return 0;
367
368 return versionPattern[version - 7];
369}
370
371/******************************************************************************
372 * Format information
373 *****************************************************************************/
374
375/* See calcFormatInfo in tests/test_qrspec.c */
376static const unsigned int formatInfo[4][8] = {
377 {0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976},
378 {0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0},
379 {0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed},
380 {0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b}
381};
382
383unsigned int QRspec_getFormatInfo(int mask, QRecLevel level)
384{
385 if(mask < 0 || mask > 7) return 0;
386
387 return formatInfo[level][mask];
388}
389
390/******************************************************************************
391 * Frame
392 *****************************************************************************/
393
394/**
395 * Put a finder pattern.
396 * @param frame
397 * @param width
398 * @param ox,oy upper-left coordinate of the pattern
399 */
400static void putFinderPattern(unsigned char *frame, int width, int ox, int oy)
401{
402 static const unsigned char finder[] = {
403 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
404 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
405 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
406 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
407 0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
408 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
409 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
410 };
411 int x, y;
412 const unsigned char *s;
413
414 frame += oy * width + ox;
415 s = finder;
416 for(y = 0; y < 7; y++) {
417 for(x = 0; x < 7; x++) {
418 frame[x] = s[x];
419 }
420 frame += width;
421 s += 7;
422 }
423}
424
425
426static unsigned char *QRspec_createFrame(int version)
427{
428 unsigned char *frame, *p, *q;
429 int width;
430 int x, y;
431 unsigned int verinfo, v;
432
434 frame = (unsigned char *)malloc((size_t)(width * width));
435 if(frame == NULL) return NULL;
436
437 memset(frame, 0, (size_t)(width * width));
438 /* Finder pattern */
439 putFinderPattern(frame, width, 0, 0);
440 putFinderPattern(frame, width, width - 7, 0);
441 putFinderPattern(frame, width, 0, width - 7);
442 /* Separator */
443 p = frame;
444 q = frame + width * (width - 7);
445 for(y = 0; y < 7; y++) {
446 p[7] = 0xc0;
447 p[width - 8] = 0xc0;
448 q[7] = 0xc0;
449 p += width;
450 q += width;
451 }
452 memset(frame + width * 7, 0xc0, 8);
453 memset(frame + width * 8 - 8, 0xc0, 8);
454 memset(frame + width * (width - 8), 0xc0, 8);
455 /* Mask format information area */
456 memset(frame + width * 8, 0x84, 9);
457 memset(frame + width * 9 - 8, 0x84, 8);
458 p = frame + 8;
459 for(y = 0; y < 8; y++) {
460 *p = 0x84;
461 p += width;
462 }
463 p = frame + width * (width - 7) + 8;
464 for(y = 0; y < 7; y++) {
465 *p = 0x84;
466 p += width;
467 }
468 /* Timing pattern */
469 p = frame + width * 6 + 8;
470 q = frame + width * 8 + 6;
471 for(x = 1; x < width-15; x++) {
472 *p = 0x90 | (x & 1);
473 *q = 0x90 | (x & 1);
474 p++;
475 q += width;
476 }
477 /* Alignment pattern */
478 QRspec_putAlignmentPattern(version, frame, width);
479
480 /* Version information */
481 if(version >= 7) {
483
484 p = frame + width * (width - 11);
485 v = verinfo;
486 for(x = 0; x < 6; x++) {
487 for(y = 0; y < 3; y++) {
488 p[width * y + x] = 0x88 | (v & 1);
489 v = v >> 1;
490 }
491 }
492
493 p = frame + width - 11;
494 v = verinfo;
495 for(y = 0; y < 6; y++) {
496 for(x = 0; x < 3; x++) {
497 p[x] = 0x88 | (v & 1);
498 v = v >> 1;
499 }
500 p += width;
501 }
502 }
503 /* and a little bit... */
504 frame[width * (width - 8) + 8] = 0x81;
505
506 return frame;
507}
508
509unsigned char *QRspec_newFrame(int version)
510{
511 if(version < 1 || version > QRSPEC_VERSION_MAX) return NULL;
512
514}
static int size
Definition: qrenc.c:41
static QRecLevel level
Definition: qrenc.c:50
static int version
Definition: qrenc.c:40
QRecLevel
Level of error correction.
Definition: qrencode.h:124
QRencodeMode
Encoding mode.
Definition: qrencode.h:109
@ QR_MODE_KANJI
Kanji (shift-jis) mode.
Definition: qrencode.h:114
#define QRSPEC_VERSION_MAX
Maximum version (size) of QR-code symbol.
Definition: qrencode.h:134
int QRinput_isSplittableMode(QRencodeMode mode)
Utilities.
Definition: qrinput.c:39
static unsigned char * QRspec_createFrame(int version)
Definition: qrspec.c:426
static void QRspec_putAlignmentMarker(unsigned char *frame, int width, int ox, int oy)
Put an alignment marker.
Definition: qrspec.c:287
static const int eccTable[40+1][4][2]
Error correction code.
Definition: qrspec.c:190
int QRspec_getRemainder(int version)
Return the numer of remainder bits.
Definition: qrspec.c:126
unsigned char * QRspec_newFrame(int version)
Frame.
Definition: qrspec.c:509
int QRspec_getMinimumVersion(int size, QRecLevel level)
Return a version number that satisfies the input code length.
Definition: qrspec.c:108
static const int alignmentPattern[40+1][2]
Alignment pattern.
Definition: qrspec.c:269
int QRspec_getWidth(int version)
Return the width of the symbol for the version.
Definition: qrspec.c:121
static const QRspec_Capacity qrspecCapacity[40+1]
Table of the capacity of symbols See Table 1 (pp.13) and Table 12-16 (pp.30-36), JIS X0510:2004.
Definition: qrspec.c:54
unsigned int QRspec_getVersionPattern(int version)
Version information pattern.
Definition: qrspec.c:364
static void QRspec_putAlignmentPattern(int version, unsigned char *frame, int width)
Definition: qrspec.c:310
int QRspec_getECCLength(int version, QRecLevel level)
Return maximum error correction code length (bytes) for the version.
Definition: qrspec.c:103
static void putFinderPattern(unsigned char *frame, int width, int ox, int oy)
Frame.
Definition: qrspec.c:400
int QRspec_maximumWords(QRencodeMode mode, int version)
Return the maximum length for the mode and version.
Definition: qrspec.c:158
static const unsigned int formatInfo[4][8]
Format information.
Definition: qrspec.c:376
static const int lengthTableBits[4][3]
Length indicator.
Definition: qrspec.c:135
unsigned int QRspec_getFormatInfo(int mask, QRecLevel level)
Format information.
Definition: qrspec.c:383
static const unsigned int versionPattern[40 - 6]
Version information pattern.
Definition: qrspec.c:356
int QRspec_lengthIndicator(QRencodeMode mode, int version)
Length indicator.
Definition: qrspec.c:142
void QRspec_getEccSpec(int version, QRecLevel level, int spec[5])
Error correction code.
Definition: qrspec.c:234
int QRspec_getDataLength(int version, QRecLevel level)
Return maximum data code length (bytes) for the version.
Definition: qrspec.c:98
Version and capacity.
Definition: qrspec.c:43
int ec[4]
Definition: qrspec.c:47
int remainder
Definition: qrspec.c:46