2 * qrencode - QR Code encoder
5 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
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.
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.
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
30 __STATIC int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level)
37 format = QRspec_getFormatInfo(mask, level);
46 frame[width * 8 + width - 1 - i] = v;
48 frame[width * i + 8] = v;
50 frame[width * (i + 1) + 8] = v;
61 frame[width * (width - 7 + i) + 8] = v;
63 frame[width * 8 + 7] = v;
65 frame[width * 8 + 6 - i] = v;
74 * Demerit coefficients.
75 * See Section 8.8.2, pp.45, JIS X0510:2004.
82 #define MASKMAKER(__exp__) \
86 for(y=0; y<width; y++) {\
87 for(x=0; x<width; x++) {\
91 *d = *s ^ ((__exp__) == 0);\
99 static int Mask_mask0(int width, const unsigned char *s, unsigned char *d)
104 static int Mask_mask1(int width, const unsigned char *s, unsigned char *d)
109 static int Mask_mask2(int width, const unsigned char *s, unsigned char *d)
114 static int Mask_mask3(int width, const unsigned char *s, unsigned char *d)
119 static int Mask_mask4(int width, const unsigned char *s, unsigned char *d)
121 MASKMAKER(((y/2)+(x/3))&1)
124 static int Mask_mask5(int width, const unsigned char *s, unsigned char *d)
126 MASKMAKER(((x*y)&1)+(x*y)%3)
129 static int Mask_mask6(int width, const unsigned char *s, unsigned char *d)
131 MASKMAKER((((x*y)&1)+(x*y)%3)&1)
134 static int Mask_mask7(int width, const unsigned char *s, unsigned char *d)
136 MASKMAKER((((x*y)%3)+((x+y)&1))&1)
139 typedef int MaskMaker(int, const unsigned char *, unsigned char *);
140 static MaskMaker *maskMakers[] = {
141 Mask_mask0, Mask_mask1, Mask_mask2, Mask_mask3,
142 Mask_mask4, Mask_mask5, Mask_mask6, Mask_mask7
145 unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level)
147 unsigned char *masked;
149 masked = (unsigned char *)malloc(width * width);
150 if(masked == NULL) return NULL;
152 maskMakers[mask](width, frame, masked);
153 Mask_writeFormatInformation(width, masked, mask, level);
158 static int runLength[QRSPEC_WIDTH_MAX + 1];
165 static int Mask_calcN1N3(int length, int *runLength)
171 for(i=0; i<length; i++) {
172 if(runLength[i] >= 5) {
173 demerit += N1 + (runLength[i] - 5);
174 //n1 += N1 + (runLength[i] - 5);
177 if(i >= 3 && i < length-2 && (runLength[i] % 3) == 0) {
178 fact = runLength[i] / 3;
179 if(runLength[i-2] == fact &&
180 runLength[i-1] == fact &&
181 runLength[i+1] == fact &&
182 runLength[i+2] == fact) {
183 if(runLength[i-3] < 0 || runLength[i-3] >= 4 * fact) {
186 } else if(i+3 >= length || runLength[i+3] >= 4 * fact) {
198 __STATIC int Mask_evaluateSymbol(int width, unsigned char *frame)
202 unsigned char b22, w22;
207 for(y=0; y<width; y++) {
210 for(x=0; x<width; x++) {
212 b22 = p[0] & p[-1] & p[-width] & p [-width-1];
213 w22 = p[0] | p[-1] | p[-width] | p [-width-1];
214 if((b22 | (w22 ^ 1))&1) {
218 if(x == 0 && (p[0] & 1)) {
223 if((p[0] ^ p[-1]) & 1) {
232 demerit += Mask_calcN1N3(head+1, runLength);
235 for(x=0; x<width; x++) {
239 for(y=0; y<width; y++) {
240 if(y == 0 && (p[0] & 1)) {
245 if((p[0] ^ p[-width]) & 1) {
254 demerit += Mask_calcN1N3(head+1, runLength);
260 unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level)
263 unsigned char *mask, *bestMask;
264 int minDemerit = INT_MAX;
269 mask = (unsigned char *)malloc(width * width);
270 if(mask == NULL) return NULL;
274 // n1 = n2 = n3 = n4 = 0;
276 blacks = maskMakers[i](width, frame, mask);
277 blacks += Mask_writeFormatInformation(width, mask, i, level);
278 blacks = 100 * blacks / (width * width);
279 demerit = (abs(blacks - 50) / 5) * N4;
281 demerit += Mask_evaluateSymbol(width, mask);
282 // printf("(%d,%d,%d,%d)=%d\n", n1, n2, n3 ,n4, demerit);
283 if(demerit < minDemerit) {
284 minDemerit = demerit;
286 if(bestMask != NULL) {
289 bestMask = (unsigned char *)malloc(width * width);
290 if(bestMask == NULL) break;
291 memcpy(bestMask, mask, width * width);