TTKMusicPlayer  3.7.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
rsecc.c
Go to the documentation of this file.
1 /*
2  * qrencode - QR Code encoder
3  *
4  * Reed solomon error correction code encoder specialized for QR code.
5  * This code is rewritten by Kentaro Fukuchi, referring to the FEC library
6  * developed by Phil Karn (KA9Q).
7  *
8  * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
9  * Copyright (C) 2014-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24  */
25 
26 #include "config.h"
27 #include <stdlib.h>
28 #include <string.h>
29 #if HAVE_LIBPTHREAD
30 #include <pthread.h>
31 #endif
32 
33 #include "rsecc.h"
34 
35 #if HAVE_LIBPTHREAD
36 static pthread_mutex_t RSECC_mutex = PTHREAD_MUTEX_INITIALIZER;
37 #endif
38 
39 static int initialized = 0;
40 
41 #define SYMBOL_SIZE (8)
42 #define symbols ((1U << SYMBOL_SIZE) - 1)
43 static const unsigned int proot = 0x11d; /* stands for x^8+x^4+x^3+x^2+1 (see pp.37 of JIS X0510:2004) */
44 
45 /* min/max codeword length of ECC, calculated from the specification. */
46 #define min_length (2)
47 #define max_length (30)
48 #define max_generatorSize (max_length)
49 
50 static unsigned char alpha[symbols + 1];
51 static unsigned char aindex[symbols + 1];
52 static unsigned char generator[max_length - min_length + 1][max_generatorSize + 1];
53 static unsigned char generatorInitialized[max_length - min_length + 1];
54 
55 static void RSECC_initLookupTable(void)
56 {
57  unsigned int i, b;
58 
59  alpha[symbols] = 0;
60  aindex[0] = symbols;
61 
62  b = 1;
63  for(i = 0; i < symbols; i++) {
64  alpha[i] = b;
65  aindex[b] = i;
66  b <<= 1;
67  if(b & (symbols + 1)) {
68  b ^= proot;
69  }
70  b &= symbols;
71  }
72 }
73 
74 static void RSECC_init(void)
75 {
77  memset(generatorInitialized, 0, (max_length - min_length + 1));
78  initialized = 1;
79 }
80 
81 static void generator_init(size_t length)
82 {
83  size_t i, j;
84  int g[max_generatorSize + 1];
85 
86  g[0] = 1;
87  for(i = 0; i < length; i++) {
88  g[i + 1] = 1;
89  /* Because g[0] never be zero, skipped some conditional checks. */
90  for(j = i; j > 0; j--) {
91  g[j] = g[j - 1] ^ alpha[(aindex[g[j]] + i) % symbols];
92  }
93  g[0] = alpha[(aindex[g[0]] + i) % symbols];
94  }
95 
96  for(i = 0; i <= length; i++) {
97  generator[length - min_length][i] = aindex[g[i]];
98  }
99 
100  generatorInitialized[length - min_length] = 1;
101 }
102 
103 int RSECC_encode(size_t data_length, size_t ecc_length, const unsigned char *data, unsigned char *ecc)
104 {
105  size_t i, j;
106  unsigned char feedback;
107  unsigned char *gen;
108 
109 #if HAVE_LIBPTHREAD
110  pthread_mutex_lock(&RSECC_mutex);
111 #endif
112  if(!initialized) {
113  RSECC_init();
114  }
115 #if HAVE_LIBPTHREAD
116  pthread_mutex_unlock(&RSECC_mutex);
117 #endif
118 
119  if(ecc_length > max_length) return -1;
120 
121  memset(ecc, 0, ecc_length);
122 #if HAVE_LIBPTHREAD
123  pthread_mutex_lock(&RSECC_mutex);
124 #endif
125  if(!generatorInitialized[ecc_length - min_length]) generator_init(ecc_length);
126 #if HAVE_LIBPTHREAD
127  pthread_mutex_unlock(&RSECC_mutex);
128 #endif
129  gen = generator[ecc_length - min_length];
130 
131  for(i = 0; i < data_length; i++) {
132  feedback = aindex[data[i] ^ ecc[0]];
133  if(feedback != symbols) {
134  for(j = 1; j < ecc_length; j++) {
135  ecc[j] ^= alpha[(unsigned int)(feedback + gen[ecc_length - j]) % symbols];
136  }
137  }
138  memmove(&ecc[0], &ecc[1], ecc_length - 1);
139  if(feedback != symbols) {
140  ecc[ecc_length - 1] = alpha[(unsigned int)(feedback + gen[0]) % symbols];
141  } else {
142  ecc[ecc_length - 1] = 0;
143  }
144  }
145 
146  return 0;
147 }
#define symbols
Definition: rsecc.c:42
#define min_length
Definition: rsecc.c:46
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
#define max_length
Definition: rsecc.c:47
static void RSECC_init(void)
Definition: rsecc.c:74
static void RSECC_initLookupTable(void)
Definition: rsecc.c:55
static unsigned char generator[max_length-min_length+1][max_generatorSize+1]
Definition: rsecc.c:52
static const unsigned int proot
Definition: rsecc.c:43
static int initialized
Definition: rsecc.c:39
static unsigned char aindex[symbols+1]
Definition: rsecc.c:51
static unsigned char alpha[symbols+1]
Definition: rsecc.c:50
#define max_generatorSize
Definition: rsecc.c:48
int RSECC_encode(size_t data_length, size_t ecc_length, const unsigned char *data, unsigned char *ecc)
Definition: rsecc.c:103
static void generator_init(size_t length)
Definition: rsecc.c:81
static pthread_mutex_t RSECC_mutex
Definition: rsecc.c:36
static unsigned char generatorInitialized[max_length-min_length+1]
Definition: rsecc.c:53