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