qrencode  4.1.1
About: libqrencode is a fast and compact library and command-line utility for encoding data in a QR Code symbol.
  Fossies Dox: qrencode-4.1.1.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

mmask.c
Go to the documentation of this file.
1/*
2 * qrencode - QR Code encoder
3 *
4 * Masking for Micro QR Code.
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#if HAVE_CONFIG_H
23# include "config.h"
24#endif
25#include <stdlib.h>
26#include <string.h>
27#include <limits.h>
28#include <errno.h>
29
30#include "qrencode.h"
31#include "mqrspec.h"
32#include "mmask.h"
33
34STATIC_IN_RELEASE void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level)
35{
36 unsigned int format;
37 unsigned char v;
38 int i;
39
40 format = MQRspec_getFormatInfo(mask, version, level);
41
42 for(i = 0; i < 8; i++) {
43 v = 0x84 | (format & 1);
44 frame[width * (i + 1) + 8] = v;
45 format = format >> 1;
46 }
47 for(i = 0; i < 7; i++) {
48 v = 0x84 | (format & 1);
49 frame[width * 8 + 7 - i] = v;
50 format = format >> 1;
51 }
52}
53
54#define MASKMAKER(__exp__) \
55 int x, y;\
56\
57 for(y = 0; y < width; y++) {\
58 for(x = 0; x < width; x++) {\
59 if(*s & 0x80) {\
60 *d = *s;\
61 } else {\
62 *d = *s ^ ((__exp__) == 0);\
63 }\
64 s++; d++;\
65 }\
66 }
67
68static void Mask_mask0(int width, const unsigned char *s, unsigned char *d)
69{
70 MASKMAKER(y&1)
71}
72
73static void Mask_mask1(int width, const unsigned char *s, unsigned char *d)
74{
75 MASKMAKER(((y/2)+(x/3))&1)
76}
77
78static void Mask_mask2(int width, const unsigned char *s, unsigned char *d)
79{
80 MASKMAKER((((x*y)&1)+(x*y)%3)&1)
81}
82
83static void Mask_mask3(int width, const unsigned char *s, unsigned char *d)
84{
85 MASKMAKER((((x+y)&1)+((x*y)%3))&1)
86}
87
88#define maskNum (4)
89typedef void MaskMaker(int, const unsigned char *, unsigned char *);
92};
93
94#ifdef WITH_TESTS
95unsigned char *MMask_makeMaskedFrame(int width, unsigned char *frame, int mask)
96{
97 unsigned char *masked;
98
99 masked = (unsigned char *)malloc((size_t)(width * width));
100 if(masked == NULL) return NULL;
101
102 maskMakers[mask](width, frame, masked);
103
104 return masked;
105}
106#endif
107
108unsigned char *MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level)
109{
110 unsigned char *masked;
111 int width;
112
113 if(mask < 0 || mask >= maskNum) {
114 errno = EINVAL;
115 return NULL;
116 }
117
118 width = MQRspec_getWidth(version);
119 masked = (unsigned char *)malloc((size_t)(width * width));
120 if(masked == NULL) return NULL;
121
122 maskMakers[mask](width, frame, masked);
123 MMask_writeFormatInformation(version, width, masked, mask, level);
124
125 return masked;
126}
127
128STATIC_IN_RELEASE int MMask_evaluateSymbol(int width, unsigned char *frame)
129{
130 int x, y;
131 unsigned char *p;
132 int sum1 = 0, sum2 = 0;
133
134 p = frame + width * (width - 1);
135 for(x = 1; x < width; x++) {
136 sum1 += (p[x] & 1);
137 }
138
139 p = frame + width * 2 - 1;
140 for(y = 1; y < width; y++) {
141 sum2 += (*p & 1);
142 p += width;
143 }
144
145 return (sum1 <= sum2)?(sum1 * 16 + sum2):(sum2 * 16 + sum1);
146}
147
148unsigned char *MMask_mask(int version, unsigned char *frame, QRecLevel level)
149{
150 int i;
151 unsigned char *mask, *bestMask;
152 int maxScore = 0;
153 int score;
154 int width;
155
156 width = MQRspec_getWidth(version);
157
158 mask = (unsigned char *)malloc((size_t)(width * width));
159 if(mask == NULL) return NULL;
160 bestMask = NULL;
161
162 for(i = 0; i < maskNum; i++) {
163 score = 0;
164 maskMakers[i](width, frame, mask);
166 score = MMask_evaluateSymbol(width, mask);
167 if(score > maxScore) {
168 maxScore = score;
169 free(bestMask);
170 bestMask = mask;
171 mask = (unsigned char *)malloc((size_t)(width * width));
172 if(mask == NULL) break;
173 }
174 }
175 free(mask);
176 return bestMask;
177}
static void Mask_mask3(int width, const unsigned char *s, unsigned char *d)
Definition: mmask.c:83
#define MASKMAKER(__exp__)
Definition: mmask.c:54
static void Mask_mask2(int width, const unsigned char *s, unsigned char *d)
Definition: mmask.c:78
void MaskMaker(int, const unsigned char *, unsigned char *)
Definition: mmask.c:89
unsigned char * MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level)
Definition: mmask.c:108
static void Mask_mask1(int width, const unsigned char *s, unsigned char *d)
Definition: mmask.c:73
STATIC_IN_RELEASE int MMask_evaluateSymbol(int width, unsigned char *frame)
Definition: mmask.c:128
static MaskMaker * maskMakers[(4)]
Definition: mmask.c:90
unsigned char * MMask_mask(int version, unsigned char *frame, QRecLevel level)
Definition: mmask.c:148
STATIC_IN_RELEASE void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level)
Definition: mmask.c:34
static void Mask_mask0(int width, const unsigned char *s, unsigned char *d)
Definition: mmask.c:68
#define maskNum
Definition: mmask.c:88
unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level)
Format information.
Definition: mqrspec.c:139
int MQRspec_getWidth(int version)
Return the width of the symbol for the version.
Definition: mqrspec.c:80
static QRecLevel level
Definition: qrenc.c:50
static int version
Definition: qrenc.c:40
QRecLevel
Level of error correction.
Definition: qrencode.h:124