MaskUtil.cpp Example File
appdemos/qtws/QZXing/zxing/zxing/qrcode/encoder/MaskUtil.cpp
#include "MaskUtil.h"
#include <zxing/common/IllegalArgumentException.h>
#include <stdlib.h>
namespace zxing {
namespace qrcode {
const int MaskUtil::N1 = 3;
const int MaskUtil::N2 = 3;
const int MaskUtil::N3 = 40;
const int MaskUtil::N4 = 10;
int MaskUtil::applyMaskPenaltyRule1(const ByteMatrix& matrix)
{
return applyMaskPenaltyRule1Internal(matrix, true) + applyMaskPenaltyRule1Internal(matrix, false);
}
int MaskUtil::applyMaskPenaltyRule2(const ByteMatrix& matrix)
{
int penalty = 0;
const std::vector<std::vector<byte> >& array = matrix.getArray();
int width = matrix.getWidth();
int height = matrix.getHeight();
for (int y = 0; y < height - 1; y++) {
const std::vector<byte>& arrayY = array[y];
for (int x = 0; x < width - 1; x++) {
int value = arrayY[x];
if (value == arrayY[x + 1] && value == array[y + 1][x] && value == array[y + 1][x + 1]) {
penalty++;
}
}
}
return N2 * penalty;
}
int MaskUtil::applyMaskPenaltyRule3(const ByteMatrix& matrix)
{
int numPenalties = 0;
const std::vector<std::vector<byte> >& array = matrix.getArray();
int width = matrix.getWidth();
int height = matrix.getHeight();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
const std::vector<byte>& arrayY = array[y];
if (x + 6 < width &&
arrayY[x] == 1 &&
arrayY[x + 1] == 0 &&
arrayY[x + 2] == 1 &&
arrayY[x + 3] == 1 &&
arrayY[x + 4] == 1 &&
arrayY[x + 5] == 0 &&
arrayY[x + 6] == 1 &&
(isWhiteHorizontal(arrayY, x - 4, x) || isWhiteHorizontal(arrayY, x + 7, x + 11))) {
numPenalties++;
}
if (y + 6 < height &&
array[y][x] == 1 &&
array[y + 1][x] == 0 &&
array[y + 2][x] == 1 &&
array[y + 3][x] == 1 &&
array[y + 4][x] == 1 &&
array[y + 5][x] == 0 &&
array[y + 6][x] == 1 &&
(isWhiteVertical(array, x, y - 4, y) || isWhiteVertical(array, x, y + 7, y + 11))) {
numPenalties++;
}
}
}
return numPenalties * N3;
}
bool MaskUtil::isWhiteHorizontal(const std::vector<byte>& rowArray, int from, int to)
{
from = std::max(from, 0);
to = std::min(to, (int)rowArray.size());
for (int i = from; i < to; i++) {
if (rowArray[i] == 1) {
return false;
}
}
return true;
}
bool MaskUtil::isWhiteVertical(const std::vector<std::vector<byte> > &array, int col, int from, int to)
{
from = std::max(from, 0);
to = std::min(to, (int)array.size());
for (int i = from; i < to; i++) {
if (array[i][col] == 1) {
return false;
}
}
return true;
}
int MaskUtil::applyMaskPenaltyRule4(const ByteMatrix& matrix)
{
int numDarkCells = 0;
const std::vector<std::vector<byte> >& array = matrix.getArray();
int width = matrix.getWidth();
int height = matrix.getHeight();
for (int y = 0; y < height; y++) {
const std::vector<byte>& arrayY = array[y];
for (size_t x = 0; x < width; x++) {
if (arrayY[x] == 1) {
numDarkCells++;
}
}
}
int numTotalCells = matrix.getHeight() * matrix.getWidth();
int fivePercentVariances = abs(numDarkCells * 2 - numTotalCells) * 10 / numTotalCells;
return fivePercentVariances * N4;
}
bool MaskUtil::getDataMaskBit(int maskPattern, int x, int y)
{
int intermediate;
int temp;
switch (maskPattern) {
case 0:
intermediate = (y + x) & 0x1;
break;
case 1:
intermediate = y & 0x1;
break;
case 2:
intermediate = x % 3;
break;
case 3:
intermediate = (y + x) % 3;
break;
case 4:
intermediate = ((y / 2) + (x / 3)) & 0x1;
break;
case 5:
temp = y * x;
intermediate = (temp & 0x1) + (temp % 3);
break;
case 6:
temp = y * x;
intermediate = ((temp & 0x1) + (temp % 3)) & 0x1;
break;
case 7:
temp = y * x;
intermediate = ((temp % 3) + ((y + x) & 0x1)) & 0x1;
break;
default:
throw IllegalArgumentException("Invalid mask pattern: " + maskPattern);
}
return intermediate == 0;
}
int MaskUtil::applyMaskPenaltyRule1Internal(const ByteMatrix& matrix, bool isHorizontal)
{
int penalty = 0;
int iLimit = isHorizontal ? matrix.getHeight() : matrix.getWidth();
int jLimit = isHorizontal ? matrix.getWidth() : matrix.getHeight();
const std::vector<std::vector<byte> >& array = matrix.getArray();
for (size_t i = 0; i < iLimit; i++) {
int numSameBitCells = 0;
int prevBit = -1;
for (int j = 0; j < jLimit; j++) {
int bit = isHorizontal ? array[i][j] : array[j][i];
if (bit == prevBit) {
numSameBitCells++;
} else {
if (numSameBitCells >= 5) {
penalty += N1 + (numSameBitCells - 5);
}
numSameBitCells = 1;
prevBit = bit;
}
}
if (numSameBitCells >= 5) {
penalty += N1 + (numSameBitCells - 5);
}
}
return penalty;
}
}
}