TTKMusicPlayer  3.7.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
mask.c
Go to the documentation of this file.
1 /*
2  * qrencode - QR Code encoder
3  *
4  * Masking.
5  * Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "config.h"
23 #include <stdlib.h>
24 #include <string.h>
25 #include <limits.h>
26 #include <errno.h>
27 
28 #include "qrencode.h"
29 #include "qrspec.h"
30 #include "mask.h"
31 
32 STATIC_IN_RELEASE int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level)
33 {
34  unsigned int format;
35  unsigned char v;
36  int i;
37  int blacks = 0;
38 
39  format = QRspec_getFormatInfo(mask, level);
40 
41  for(i = 0; i < 8; i++) {
42  if(format & 1) {
43  blacks += 2;
44  v = 0x85;
45  } else {
46  v = 0x84;
47  }
48  frame[width * 8 + width - 1 - i] = v;
49  if(i < 6) {
50  frame[width * i + 8] = v;
51  } else {
52  frame[width * (i + 1) + 8] = v;
53  }
54  format= format >> 1;
55  }
56  for(i = 0; i < 7; i++) {
57  if(format & 1) {
58  blacks += 2;
59  v = 0x85;
60  } else {
61  v = 0x84;
62  }
63  frame[width * (width - 7 + i) + 8] = v;
64  if(i == 0) {
65  frame[width * 8 + 7] = v;
66  } else {
67  frame[width * 8 + 6 - i] = v;
68  }
69  format= format >> 1;
70  }
71 
72  return blacks;
73 }
74 
79 #define N1 (3)
80 #define N2 (3)
81 #define N3 (40)
82 #define N4 (10)
83 
84 #define MASKMAKER(__exp__) \
85  int x, y;\
86  int b = 0;\
87 \
88  for(y = 0; y < width; y++) {\
89  for(x = 0; x < width; x++) {\
90  if(*s & 0x80) {\
91  *d = *s;\
92  } else {\
93  *d = *s ^ ((__exp__) == 0);\
94  }\
95  b += (int)(*d & 1);\
96  s++; d++;\
97  }\
98  }\
99  return b;
100 
101 static int Mask_mask0(int width, const unsigned char *s, unsigned char *d)
102 {
103  MASKMAKER((x+y)&1)
104 }
105 
106 static int Mask_mask1(int width, const unsigned char *s, unsigned char *d)
107 {
108  MASKMAKER(y&1)
109 }
110 
111 static int Mask_mask2(int width, const unsigned char *s, unsigned char *d)
112 {
113  MASKMAKER(x%3)
114 }
115 
116 static int Mask_mask3(int width, const unsigned char *s, unsigned char *d)
117 {
118  MASKMAKER((x+y)%3)
119 }
120 
121 static int Mask_mask4(int width, const unsigned char *s, unsigned char *d)
122 {
123  MASKMAKER(((y/2)+(x/3))&1)
124 }
125 
126 static int Mask_mask5(int width, const unsigned char *s, unsigned char *d)
127 {
128  MASKMAKER(((x*y)&1)+(x*y)%3)
129 }
130 
131 static int Mask_mask6(int width, const unsigned char *s, unsigned char *d)
132 {
133  MASKMAKER((((x*y)&1)+(x*y)%3)&1)
134 }
135 
136 static int Mask_mask7(int width, const unsigned char *s, unsigned char *d)
137 {
138  MASKMAKER((((x*y)%3)+((x+y)&1))&1)
139 }
140 
141 #define maskNum (8)
142 typedef int MaskMaker(int, const unsigned char *, unsigned char *);
146 };
147 
148 #ifdef WITH_TESTS
149 unsigned char *Mask_makeMaskedFrame(int width, unsigned char *frame, int mask)
150 {
151  unsigned char *masked;
152 
153  masked = (unsigned char *)malloc((size_t)(width * width));
154  if(masked == NULL) return NULL;
155 
156  maskMakers[mask](width, frame, masked);
157 
158  return masked;
159 }
160 #endif
161 
162 unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level)
163 {
164  unsigned char *masked;
165 
166  if(mask < 0 || mask >= maskNum) {
167  errno = EINVAL;
168  return NULL;
169  }
170 
171  masked = (unsigned char *)malloc((size_t)(width * width));
172  if(masked == NULL) return NULL;
173 
174  maskMakers[mask](width, frame, masked);
175  Mask_writeFormatInformation(width, masked, mask, level);
176 
177  return masked;
178 }
179 
180 
181 //static int n1;
182 //static int n2;
183 //static int n3;
184 //static int n4;
185 
186 STATIC_IN_RELEASE int Mask_calcN1N3(int length, int *runLength)
187 {
188  int i;
189  int demerit = 0;
190  int fact;
191 
192  for(i = 0; i < length; i++) {
193  if(runLength[i] >= 5) {
194  demerit += N1 + (runLength[i] - 5);
195  //n1 += N1 + (runLength[i] - 5);
196  }
197  if((i & 1)) {
198  if(i >= 3 && i < length-2 && (runLength[i] % 3) == 0) {
199  fact = runLength[i] / 3;
200  if(runLength[i-2] == fact &&
201  runLength[i-1] == fact &&
202  runLength[i+1] == fact &&
203  runLength[i+2] == fact) {
204  if(i == 3 || runLength[i-3] >= 4 * fact) {
205  demerit += N3;
206  //n3 += N3;
207  } else if(i+4 >= length || runLength[i+3] >= 4 * fact) {
208  demerit += N3;
209  //n3 += N3;
210  }
211  }
212  }
213  }
214  }
215 
216  return demerit;
217 }
218 
219 STATIC_IN_RELEASE int Mask_calcN2(int width, unsigned char *frame)
220 {
221  int x, y;
222  unsigned char *p;
223  unsigned char b22, w22;
224  int demerit = 0;
225 
226  p = frame + width + 1;
227  for(y = 1; y < width; y++) {
228  for(x = 1; x < width; x++) {
229  b22 = p[0] & p[-1] & p[-width] & p [-width-1];
230  w22 = p[0] | p[-1] | p[-width] | p [-width-1];
231  if((b22 | (w22 ^ 1))&1) {
232  demerit += N2;
233  }
234  p++;
235  }
236  p++;
237  }
238 
239  return demerit;
240 }
241 
242 STATIC_IN_RELEASE int Mask_calcRunLengthH(int width, unsigned char *frame, int *runLength)
243 {
244  int head;
245  int i;
246  unsigned char prev;
247 
248  if(frame[0] & 1) {
249  runLength[0] = -1;
250  head = 1;
251  } else {
252  head = 0;
253  }
254  runLength[head] = 1;
255  prev = frame[0];
256 
257  for(i = 1; i < width; i++) {
258  if((frame[i] ^ prev) & 1) {
259  head++;
260  runLength[head] = 1;
261  prev = frame[i];
262  } else {
263  runLength[head]++;
264  }
265  }
266 
267  return head + 1;
268 }
269 
270 STATIC_IN_RELEASE int Mask_calcRunLengthV(int width, unsigned char *frame, int *runLength)
271 {
272  int head;
273  int i;
274  unsigned char prev;
275 
276  if(frame[0] & 1) {
277  runLength[0] = -1;
278  head = 1;
279  } else {
280  head = 0;
281  }
282  runLength[head] = 1;
283  prev = frame[0];
284 
285  for(i = 1; i < width; i++) {
286  if((frame[i * width] ^ prev) & 1) {
287  head++;
288  runLength[head] = 1;
289  prev = frame[i * width];
290  } else {
291  runLength[head]++;
292  }
293  }
294 
295  return head + 1;
296 }
297 
298 STATIC_IN_RELEASE int Mask_evaluateSymbol(int width, unsigned char *frame)
299 {
300  int x, y;
301  int demerit = 0;
302  int runLength[QRSPEC_WIDTH_MAX + 1];
303  int length;
304 
305  demerit += Mask_calcN2(width, frame);
306 
307  for(y = 0; y < width; y++) {
308  length = Mask_calcRunLengthH(width, frame + y * width, runLength);
309  demerit += Mask_calcN1N3(length, runLength);
310  }
311 
312  for(x = 0; x < width; x++) {
313  length = Mask_calcRunLengthV(width, frame + x, runLength);
314  demerit += Mask_calcN1N3(length, runLength);
315  }
316 
317  return demerit;
318 }
319 
320 unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level)
321 {
322  int i;
323  unsigned char *mask, *bestMask;
324  int minDemerit = INT_MAX;
325  int blacks;
326  int bratio;
327  int demerit;
328  int w2 = width * width;
329 
330  mask = (unsigned char *)malloc((size_t)w2);
331  if(mask == NULL) return NULL;
332  bestMask = (unsigned char *)malloc((size_t)w2);
333  if(bestMask == NULL) {
334  free(mask);
335  return NULL;
336  }
337 
338  for(i = 0; i < maskNum; i++) {
339 // n1 = n2 = n3 = n4 = 0;
340  demerit = 0;
341  blacks = maskMakers[i](width, frame, mask);
342  blacks += Mask_writeFormatInformation(width, mask, i, level);
343  bratio = (200 * blacks + w2) / w2 / 2; /* (int)(100*blacks/w2+0.5) */
344  demerit = (abs(bratio - 50) / 5) * N4;
345 // n4 = demerit;
346  demerit += Mask_evaluateSymbol(width, mask);
347 // printf("(%d,%d,%d,%d)=%d\n", n1, n2, n3 ,n4, demerit);
348  if(demerit < minDemerit) {
349  minDemerit = demerit;
350  memcpy(bestMask, mask, (size_t)w2);
351  }
352  }
353  free(mask);
354  return bestMask;
355 }
static int Mask_mask3(int width, const unsigned char *s, unsigned char *d)
Definition: mask.c:116
#define N4
Definition: mask.c:82
static int Mask_mask2(int width, const unsigned char *s, unsigned char *d)
Definition: mask.c:111
static int Mask_mask1(int width, const unsigned char *s, unsigned char *d)
Definition: mask.c:106
#define STATIC_IN_RELEASE
Definition: config.h:95
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 int Mask_mask6(int width, const unsigned char *s, unsigned char *d)
Definition: mask.c:131
static int Mask_mask5(int width, const unsigned char *s, unsigned char *d)
Definition: mask.c:126
static int Mask_mask0(int width, const unsigned char *s, unsigned char *d)
Definition: mask.c:101
static MaskMaker * maskMakers[maskNum]
Definition: mask.c:143
#define MASKMAKER(__exp__)
Definition: mask.c:84
#define maskNum
Definition: mask.c:141
int MaskMaker(int, const unsigned char *, unsigned char *)
Definition: mask.c:142
#define N3
Definition: mask.c:81
unsigned char * Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level)
Definition: mask.c:162
unsigned char * Mask_mask(int width, unsigned char *frame, QRecLevel level)
Definition: mask.c:320
static int Mask_mask4(int width, const unsigned char *s, unsigned char *d)
Definition: mask.c:121
STATIC_IN_RELEASE int Mask_calcN2(int width, unsigned char *frame)
Definition: mask.c:219
STATIC_IN_RELEASE int Mask_calcRunLengthV(int width, unsigned char *frame, int *runLength)
Definition: mask.c:270
#define N1
Demerit coefficients.
Definition: mask.c:79
static int Mask_mask7(int width, const unsigned char *s, unsigned char *d)
Definition: mask.c:136
#define N2
Definition: mask.c:80
#define QRSPEC_WIDTH_MAX
Maximum width of a symbol.
Definition: qrspec.h:34
void free(voidpf ptr)
STATIC_IN_RELEASE int Mask_calcN1N3(int length, int *runLength)
Definition: mask.c:186
voidp malloc(uInt size)
STATIC_IN_RELEASE int Mask_calcRunLengthH(int width, unsigned char *frame, int *runLength)
Definition: mask.c:242
STATIC_IN_RELEASE int Mask_evaluateSymbol(int width, unsigned char *frame)
Definition: mask.c:298
STATIC_IN_RELEASE int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level)
Definition: mask.c:32