mask.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /*
  2. * qrencode - QR Code encoder
  3. *
  4. * Masking.
  5. * Copyright (C) 2006-2011 Kentaro Fukuchi <[email protected]>
  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. #if HAVE_CONFIG_H
  22. # include "config.h"
  23. #endif
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <limits.h>
  27. #include <errno.h>
  28. #include "qrencode.h"
  29. #include "qrspec.h"
  30. #include "mask.h"
  31. __STATIC int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level)
  32. {
  33. unsigned int format;
  34. unsigned char v;
  35. int i;
  36. int blacks = 0;
  37. format = QRspec_getFormatInfo(mask, level);
  38. for(i=0; i<8; i++) {
  39. if(format & 1) {
  40. blacks += 2;
  41. v = 0x85;
  42. } else {
  43. v = 0x84;
  44. }
  45. frame[width * 8 + width - 1 - i] = v;
  46. if(i < 6) {
  47. frame[width * i + 8] = v;
  48. } else {
  49. frame[width * (i + 1) + 8] = v;
  50. }
  51. format= format >> 1;
  52. }
  53. for(i=0; i<7; i++) {
  54. if(format & 1) {
  55. blacks += 2;
  56. v = 0x85;
  57. } else {
  58. v = 0x84;
  59. }
  60. frame[width * (width - 7 + i) + 8] = v;
  61. if(i == 0) {
  62. frame[width * 8 + 7] = v;
  63. } else {
  64. frame[width * 8 + 6 - i] = v;
  65. }
  66. format= format >> 1;
  67. }
  68. return blacks;
  69. }
  70. /**
  71. * Demerit coefficients.
  72. * See Section 8.8.2, pp.45, JIS X0510:2004.
  73. */
  74. #define N1 (3)
  75. #define N2 (3)
  76. #define N3 (40)
  77. #define N4 (10)
  78. #define MASKMAKER(__exp__) \
  79. int x, y;\
  80. int b = 0;\
  81. \
  82. for(y=0; y<width; y++) {\
  83. for(x=0; x<width; x++) {\
  84. if(*s & 0x80) {\
  85. *d = *s;\
  86. } else {\
  87. *d = *s ^ ((__exp__) == 0);\
  88. }\
  89. b += (int)(*d & 1);\
  90. s++; d++;\
  91. }\
  92. }\
  93. return b;
  94. static int Mask_mask0(int width, const unsigned char *s, unsigned char *d)
  95. {
  96. MASKMAKER((x+y)&1)
  97. }
  98. static int Mask_mask1(int width, const unsigned char *s, unsigned char *d)
  99. {
  100. MASKMAKER(y&1)
  101. }
  102. static int Mask_mask2(int width, const unsigned char *s, unsigned char *d)
  103. {
  104. MASKMAKER(x%3)
  105. }
  106. static int Mask_mask3(int width, const unsigned char *s, unsigned char *d)
  107. {
  108. MASKMAKER((x+y)%3)
  109. }
  110. static int Mask_mask4(int width, const unsigned char *s, unsigned char *d)
  111. {
  112. MASKMAKER(((y/2)+(x/3))&1)
  113. }
  114. static int Mask_mask5(int width, const unsigned char *s, unsigned char *d)
  115. {
  116. MASKMAKER(((x*y)&1)+(x*y)%3)
  117. }
  118. static int Mask_mask6(int width, const unsigned char *s, unsigned char *d)
  119. {
  120. MASKMAKER((((x*y)&1)+(x*y)%3)&1)
  121. }
  122. static int Mask_mask7(int width, const unsigned char *s, unsigned char *d)
  123. {
  124. MASKMAKER((((x*y)%3)+((x+y)&1))&1)
  125. }
  126. #define maskNum (8)
  127. typedef int MaskMaker(int, const unsigned char *, unsigned char *);
  128. static MaskMaker *maskMakers[maskNum] = {
  129. Mask_mask0, Mask_mask1, Mask_mask2, Mask_mask3,
  130. Mask_mask4, Mask_mask5, Mask_mask6, Mask_mask7
  131. };
  132. #ifdef WITH_TESTS
  133. unsigned char *Mask_makeMaskedFrame(int width, unsigned char *frame, int mask)
  134. {
  135. unsigned char *masked;
  136. masked = (unsigned char *)malloc(width * width);
  137. if(masked == NULL) return NULL;
  138. maskMakers[mask](width, frame, masked);
  139. return masked;
  140. }
  141. #endif
  142. unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level)
  143. {
  144. unsigned char *masked;
  145. if(mask < 0 || mask >= maskNum) {
  146. errno = EINVAL;
  147. return NULL;
  148. }
  149. masked = (unsigned char *)malloc(width * width);
  150. if(masked == NULL) return NULL;
  151. maskMakers[mask](width, frame, masked);
  152. Mask_writeFormatInformation(width, masked, mask, level);
  153. return masked;
  154. }
  155. //static int n1;
  156. //static int n2;
  157. //static int n3;
  158. //static int n4;
  159. __STATIC int Mask_calcN1N3(int length, int *runLength)
  160. {
  161. int i;
  162. int demerit = 0;
  163. int fact;
  164. for(i=0; i<length; i++) {
  165. if(runLength[i] >= 5) {
  166. demerit += N1 + (runLength[i] - 5);
  167. //n1 += N1 + (runLength[i] - 5);
  168. }
  169. if((i & 1)) {
  170. if(i >= 3 && i < length-2 && (runLength[i] % 3) == 0) {
  171. fact = runLength[i] / 3;
  172. if(runLength[i-2] == fact &&
  173. runLength[i-1] == fact &&
  174. runLength[i+1] == fact &&
  175. runLength[i+2] == fact) {
  176. if(i == 3 || runLength[i-3] >= 4 * fact) {
  177. demerit += N3;
  178. //n3 += N3;
  179. } else if(i+4 >= length || runLength[i+3] >= 4 * fact) {
  180. demerit += N3;
  181. //n3 += N3;
  182. }
  183. }
  184. }
  185. }
  186. }
  187. return demerit;
  188. }
  189. __STATIC int Mask_calcN2(int width, unsigned char *frame)
  190. {
  191. int x, y;
  192. unsigned char *p;
  193. unsigned char b22, w22;
  194. int demerit = 0;
  195. p = frame + width + 1;
  196. for(y=1; y<width; y++) {
  197. for(x=1; x<width; x++) {
  198. b22 = p[0] & p[-1] & p[-width] & p [-width-1];
  199. w22 = p[0] | p[-1] | p[-width] | p [-width-1];
  200. if((b22 | (w22 ^ 1))&1) {
  201. demerit += N2;
  202. }
  203. p++;
  204. }
  205. p++;
  206. }
  207. return demerit;
  208. }
  209. __STATIC int Mask_calcRunLengthH(int width, unsigned char *frame, int *runLength)
  210. {
  211. int head;
  212. int i;
  213. unsigned char prev;
  214. if(frame[0] & 1) {
  215. runLength[0] = -1;
  216. head = 1;
  217. } else {
  218. head = 0;
  219. }
  220. runLength[head] = 1;
  221. prev = frame[0];
  222. for(i=1; i<width; i++) {
  223. if((frame[i] ^ prev) & 1) {
  224. head++;
  225. runLength[head] = 1;
  226. prev = frame[i];
  227. } else {
  228. runLength[head]++;
  229. }
  230. }
  231. return head + 1;
  232. }
  233. __STATIC int Mask_calcRunLengthV(int width, unsigned char *frame, int *runLength)
  234. {
  235. int head;
  236. int i;
  237. unsigned char prev;
  238. if(frame[0] & 1) {
  239. runLength[0] = -1;
  240. head = 1;
  241. } else {
  242. head = 0;
  243. }
  244. runLength[head] = 1;
  245. prev = frame[0];
  246. for(i=1; i<width; i++) {
  247. if((frame[i * width] ^ prev) & 1) {
  248. head++;
  249. runLength[head] = 1;
  250. prev = frame[i * width];
  251. } else {
  252. runLength[head]++;
  253. }
  254. }
  255. return head + 1;
  256. }
  257. __STATIC int Mask_evaluateSymbol(int width, unsigned char *frame)
  258. {
  259. int x, y;
  260. int demerit = 0;
  261. int runLength[QRSPEC_WIDTH_MAX + 1];
  262. int length;
  263. demerit += Mask_calcN2(width, frame);
  264. for(y=0; y<width; y++) {
  265. length = Mask_calcRunLengthH(width, frame + y * width, runLength);
  266. demerit += Mask_calcN1N3(length, runLength);
  267. }
  268. for(x=0; x<width; x++) {
  269. length = Mask_calcRunLengthV(width, frame + x, runLength);
  270. demerit += Mask_calcN1N3(length, runLength);
  271. }
  272. return demerit;
  273. }
  274. unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level)
  275. {
  276. int i;
  277. unsigned char *mask, *bestMask;
  278. int minDemerit = INT_MAX;
  279. int blacks;
  280. int bratio;
  281. int demerit;
  282. int w2 = width * width;
  283. mask = (unsigned char *)malloc(w2);
  284. if(mask == NULL) return NULL;
  285. bestMask = (unsigned char *)malloc(w2);
  286. if(bestMask == NULL) {
  287. free(mask);
  288. return NULL;
  289. }
  290. for(i=0; i<maskNum; i++) {
  291. // n1 = n2 = n3 = n4 = 0;
  292. demerit = 0;
  293. blacks = maskMakers[i](width, frame, mask);
  294. blacks += Mask_writeFormatInformation(width, mask, i, level);
  295. bratio = (200 * blacks + w2) / w2 / 2; /* (int)(100*blacks/w2+0.5) */
  296. demerit = (abs(bratio - 50) / 5) * N4;
  297. // n4 = demerit;
  298. demerit += Mask_evaluateSymbol(width, mask);
  299. // printf("(%d,%d,%d,%d)=%d\n", n1, n2, n3 ,n4, demerit);
  300. if(demerit < minDemerit) {
  301. minDemerit = demerit;
  302. memcpy(bestMask, mask, w2);
  303. }
  304. }
  305. free(mask);
  306. return bestMask;
  307. }