mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Issue 820 second format info was read incorrectly
Semantically, this is just C++ version of the changes from Java. I also did some minor renaming of variables to match the current Java source to aide in keeping the two trees in sync. git-svn-id: https://zxing.googlecode.com/svn/trunk@1754 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
9afb71c862
commit
d65d3e0d4b
|
@ -59,32 +59,42 @@ int FormatInformation::numBitsDiffering(unsigned int a, unsigned int b) {
|
|||
+ BITS_SET_IN_HALF_BYTE[(a >> 28 & 0x0F)];
|
||||
}
|
||||
|
||||
Ref<FormatInformation> FormatInformation::decodeFormatInformation(int rawFormatInfo) {
|
||||
Ref<FormatInformation> result(doDecodeFormatInformation(rawFormatInfo));
|
||||
Ref<FormatInformation> FormatInformation::decodeFormatInformation(int maskedFormatInfo1, int maskedFormatInfo2) {
|
||||
Ref<FormatInformation> result(doDecodeFormatInformation(maskedFormatInfo1, maskedFormatInfo2));
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
return doDecodeFormatInformation(rawFormatInfo ^ FORMAT_INFO_MASK_QR);
|
||||
// Should return null, but, some QR codes apparently
|
||||
// do not mask this info. Try again by actually masking the pattern
|
||||
// first
|
||||
return doDecodeFormatInformation(maskedFormatInfo1 ^ FORMAT_INFO_MASK_QR,
|
||||
maskedFormatInfo2 ^ FORMAT_INFO_MASK_QR);
|
||||
}
|
||||
Ref<FormatInformation> FormatInformation::doDecodeFormatInformation(int rawFormatInfo) {
|
||||
// Unmask:
|
||||
int unmaskedFormatInfo = rawFormatInfo ^ FORMAT_INFO_MASK_QR;
|
||||
Ref<FormatInformation> FormatInformation::doDecodeFormatInformation(int maskedFormatInfo1, int maskedFormatInfo2) {
|
||||
// Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing
|
||||
int bestDifference = numeric_limits<int>::max();
|
||||
int bestFormatInfo = 0;
|
||||
for (int i = 0; i < N_FORMAT_INFO_DECODE_LOOKUPS; i++) {
|
||||
int* decodeInfo = FORMAT_INFO_DECODE_LOOKUP[i];
|
||||
int targetInfo = decodeInfo[0];
|
||||
if (targetInfo == unmaskedFormatInfo) {
|
||||
if (targetInfo == maskedFormatInfo1 || targetInfo == maskedFormatInfo2) {
|
||||
// Found an exact match
|
||||
Ref<FormatInformation> result(new FormatInformation(decodeInfo[1]));
|
||||
return result;
|
||||
}
|
||||
int bitsDifference = numBitsDiffering(unmaskedFormatInfo, targetInfo);
|
||||
int bitsDifference = numBitsDiffering(maskedFormatInfo1, targetInfo);
|
||||
if (bitsDifference < bestDifference) {
|
||||
bestFormatInfo = decodeInfo[1];
|
||||
bestDifference = bitsDifference;
|
||||
}
|
||||
if (maskedFormatInfo1 != maskedFormatInfo2) {
|
||||
// also try the other option
|
||||
bitsDifference = numBitsDiffering(maskedFormatInfo2, targetInfo);
|
||||
if (bitsDifference < bestDifference) {
|
||||
bestFormatInfo = decodeInfo[1];
|
||||
bestDifference = bitsDifference;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bestDifference <= 3) {
|
||||
Ref<FormatInformation> result(new FormatInformation(bestFormatInfo));
|
||||
|
|
|
@ -41,8 +41,8 @@ private:
|
|||
|
||||
public:
|
||||
static int numBitsDiffering(unsigned int a, unsigned int b);
|
||||
static Ref<FormatInformation> decodeFormatInformation(int rawFormatInfo);
|
||||
static Ref<FormatInformation> doDecodeFormatInformation(int rawFormatInfo);
|
||||
static Ref<FormatInformation> decodeFormatInformation(int maskedFormatInfo1, int maskedFormatInfo2);
|
||||
static Ref<FormatInformation> doDecodeFormatInformation(int maskedFormatInfo1, int maskedFormatInfo2);
|
||||
ErrorCorrectionLevel &getErrorCorrectionLevel();
|
||||
unsigned char getDataMask();
|
||||
friend bool operator==(const FormatInformation &a, const FormatInformation &b);
|
||||
|
|
|
@ -43,36 +43,31 @@ Ref<FormatInformation> BitMatrixParser::readFormatInformation() {
|
|||
}
|
||||
|
||||
// Read top-left format info bits
|
||||
int formatInfoBits = 0;
|
||||
for (int x = 0; x < 6; x++) {
|
||||
formatInfoBits = copyBit(x, 8, formatInfoBits);
|
||||
int formatInfoBits1 = 0;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
formatInfoBits1 = copyBit(i, 8, formatInfoBits1);
|
||||
}
|
||||
// .. and skip a bit in the timing pattern ...
|
||||
formatInfoBits = copyBit(7, 8, formatInfoBits);
|
||||
formatInfoBits = copyBit(8, 8, formatInfoBits);
|
||||
formatInfoBits = copyBit(8, 7, formatInfoBits);
|
||||
formatInfoBits1 = copyBit(7, 8, formatInfoBits1);
|
||||
formatInfoBits1 = copyBit(8, 8, formatInfoBits1);
|
||||
formatInfoBits1 = copyBit(8, 7, formatInfoBits1);
|
||||
// .. and skip a bit in the timing pattern ...
|
||||
for (int y = 5; y >= 0; y--) {
|
||||
formatInfoBits = copyBit(8, y, formatInfoBits);
|
||||
for (int j = 5; j >= 0; j--) {
|
||||
formatInfoBits1 = copyBit(8, j, formatInfoBits1);
|
||||
}
|
||||
|
||||
parsedFormatInfo_ = FormatInformation::decodeFormatInformation(formatInfoBits);
|
||||
if (parsedFormatInfo_ != 0) {
|
||||
return parsedFormatInfo_;
|
||||
}
|
||||
|
||||
// Hmm, failed. Try the top-right/bottom-left pattern
|
||||
// Read the top-right/bottom-left pattern
|
||||
int dimension = bitMatrix_->getDimension();
|
||||
formatInfoBits = 0;
|
||||
int yMin = dimension - 8;
|
||||
for (int y = dimension - 1; y >= yMin; y--) {
|
||||
formatInfoBits = copyBit(8, y, formatInfoBits);
|
||||
int formatInfoBits2 = 0;
|
||||
int jMin = dimension - 7;
|
||||
for (int j = dimension - 1; j >= jMin; j--) {
|
||||
formatInfoBits2 = copyBit(8, j, formatInfoBits2);
|
||||
}
|
||||
for (int x = dimension - 7; x < dimension; x++) {
|
||||
formatInfoBits = copyBit(x, 8, formatInfoBits);
|
||||
for (int i = dimension - 8; i < dimension; i++) {
|
||||
formatInfoBits2 = copyBit(i, 8, formatInfoBits2);
|
||||
}
|
||||
|
||||
parsedFormatInfo_ = FormatInformation::decodeFormatInformation(formatInfoBits);
|
||||
parsedFormatInfo_ = FormatInformation::decodeFormatInformation(formatInfoBits1,formatInfoBits2);
|
||||
if (parsedFormatInfo_ != 0) {
|
||||
return parsedFormatInfo_;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue