mask.c 7.3 KB

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