QRBitMatrixParser.cpp Example File
appdemos/qtws/QZXing/zxing/zxing/qrcode/decoder/QRBitMatrixParser.cpp
#include <zxing/qrcode/decoder/BitMatrixParser.h>
#include <zxing/qrcode/decoder/DataMask.h>
namespace zxing {
namespace qrcode {
int BitMatrixParser::copyBit(size_t x, size_t y, int versionBits) {
return bitMatrix_->get(x, y) ? (versionBits << 1) | 0x1 : versionBits << 1;
}
BitMatrixParser::BitMatrixParser(Ref<BitMatrix> bitMatrix) :
bitMatrix_(bitMatrix), parsedVersion_(0), parsedFormatInfo_() {
size_t dimension = bitMatrix->getHeight();
if ((dimension < 21) || (dimension & 0x03) != 1) {
throw ReaderException("Dimension must be 1 mod 4 and >= 21");
}
}
Ref<FormatInformation> BitMatrixParser::readFormatInformation() {
if (parsedFormatInfo_ != 0) {
return parsedFormatInfo_;
}
int formatInfoBits1 = 0;
for (int i = 0; i < 6; i++) {
formatInfoBits1 = copyBit(i, 8, formatInfoBits1);
}
formatInfoBits1 = copyBit(7, 8, formatInfoBits1);
formatInfoBits1 = copyBit(8, 8, formatInfoBits1);
formatInfoBits1 = copyBit(8, 7, formatInfoBits1);
for (int j = 5; j >= 0; j--) {
formatInfoBits1 = copyBit(8, j, formatInfoBits1);
}
int dimension = bitMatrix_->getHeight();
int formatInfoBits2 = 0;
int jMin = dimension - 7;
for (int j = dimension - 1; j >= jMin; j--) {
formatInfoBits2 = copyBit(8, j, formatInfoBits2);
}
for (int i = dimension - 8; i < dimension; i++) {
formatInfoBits2 = copyBit(i, 8, formatInfoBits2);
}
parsedFormatInfo_ = FormatInformation::decodeFormatInformation(formatInfoBits1,formatInfoBits2);
if (parsedFormatInfo_ != 0) {
return parsedFormatInfo_;
}
throw ReaderException("Could not decode format information");
}
Version *BitMatrixParser::readVersion() {
if (parsedVersion_ != 0) {
return parsedVersion_;
}
int dimension = bitMatrix_->getHeight();
int provisionalVersion = (dimension - 17) >> 2;
if (provisionalVersion <= 6) {
return Version::getVersionForNumber(provisionalVersion);
}
int versionBits = 0;
for (int y = 5; y >= 0; y--) {
int xMin = dimension - 11;
for (int x = dimension - 9; x >= xMin; x--) {
versionBits = copyBit(x, y, versionBits);
}
}
parsedVersion_ = Version::decodeVersionInformation(versionBits);
if (parsedVersion_ != 0 && parsedVersion_->getDimensionForVersion() == dimension) {
return parsedVersion_;
}
versionBits = 0;
for (int x = 5; x >= 0; x--) {
int yMin = dimension - 11;
for (int y = dimension - 9; y >= yMin; y--) {
versionBits = copyBit(x, y, versionBits);
}
}
parsedVersion_ = Version::decodeVersionInformation(versionBits);
if (parsedVersion_ != 0 && parsedVersion_->getDimensionForVersion() == dimension) {
return parsedVersion_;
}
throw ReaderException("Could not decode version");
}
ArrayRef<byte> BitMatrixParser::readCodewords() {
Ref<FormatInformation> formatInfo = readFormatInformation();
Version *version = readVersion();
DataMask &dataMask = DataMask::forReference((int)formatInfo->getDataMask());
int dimension = bitMatrix_->getHeight();
dataMask.unmaskBitMatrix(*bitMatrix_, dimension);
Ref<BitMatrix> functionPattern = version->buildFunctionPattern();
bool readingUp = true;
ArrayRef<byte> result(version->getTotalCodewords());
int resultOffset = 0;
int currentByte = 0;
int bitsRead = 0;
for (int x = dimension - 1; x > 0; x -= 2) {
if (x == 6) {
x--;
}
for (int counter = 0; counter < dimension; counter++) {
int y = readingUp ? dimension - 1 - counter : counter;
for (int col = 0; col < 2; col++) {
if (!functionPattern->get(x - col, y)) {
bitsRead++;
currentByte <<= 1;
if (bitMatrix_->get(x - col, y)) {
currentByte |= 1;
}
if (bitsRead == 8) {
result[resultOffset++] = (byte)currentByte;
bitsRead = 0;
currentByte = 0;
}
}
}
}
readingUp = !readingUp;
}
if (resultOffset != version->getTotalCodewords()) {
throw ReaderException("Did not read all codewords");
}
return result;
}
void BitMatrixParser::remask() {
if (parsedFormatInfo_ == 0) {
return;
}
DataMask &dataMask = DataMask::forReference((int)parsedFormatInfo_->getDataMask());
int dimension = bitMatrix_->getHeight();
dataMask.unmaskBitMatrix(*bitMatrix_, dimension);
}
void BitMatrixParser::setMirror(boolean mirror) {
parsedVersion_ = 0;
parsedFormatInfo_ = 0;
mirror_ = mirror;
}
void BitMatrixParser::mirror() {
for (int x = 0; x < bitMatrix_->getWidth(); x++) {
for (int y = x + 1; y < bitMatrix_->getHeight(); y++) {
if (bitMatrix_->get(x, y) != bitMatrix_->get(y, x)) {
bitMatrix_->flip(y, x);
bitMatrix_->flip(x, y);
}
}
}
}
}
}