2 * FormatInformation.cpp
5 * Created by Christian Brunschen on 18/05/2008.
6 * Copyright 2008 ZXing authors All rights reserved.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
21 #include "FormatInformation.h"
26 int FormatInformation::FORMAT_INFO_MASK_QR = 0x5412;
27 int FormatInformation::FORMAT_INFO_DECODE_LOOKUP[][2] = {
61 int FormatInformation::N_FORMAT_INFO_DECODE_LOOKUPS = 32;
63 int FormatInformation::BITS_SET_IN_HALF_BYTE[] = {
64 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
67 int FormatInformation::numBitsDiffering(unsigned int a, unsigned int b) {
69 return BITS_SET_IN_HALF_BYTE[a & 0x0F] +
70 BITS_SET_IN_HALF_BYTE[(a >> 4 & 0x0F)] +
71 BITS_SET_IN_HALF_BYTE[(a >> 8 & 0x0F)] +
72 BITS_SET_IN_HALF_BYTE[(a >> 12 & 0x0F)] +
73 BITS_SET_IN_HALF_BYTE[(a >> 16 & 0x0F)] +
74 BITS_SET_IN_HALF_BYTE[(a >> 20 & 0x0F)] +
75 BITS_SET_IN_HALF_BYTE[(a >> 24 & 0x0F)] +
76 BITS_SET_IN_HALF_BYTE[(a >> 28 & 0x0F)];
79 Ref<FormatInformation>
80 FormatInformation::decodeFormatInformation(int rawFormatInfo) {
81 Ref<FormatInformation> result(doDecodeFormatInformation(rawFormatInfo));
85 return doDecodeFormatInformation(rawFormatInfo ^ FORMAT_INFO_MASK_QR);
87 Ref<FormatInformation>
88 FormatInformation::doDecodeFormatInformation(int rawFormatInfo) {
90 int unmaskedFormatInfo = rawFormatInfo ^ FORMAT_INFO_MASK_QR;
91 // Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing
92 int bestDifference = numeric_limits<int>::max();
93 int bestFormatInfo = 0;
94 for (int i = 0; i < N_FORMAT_INFO_DECODE_LOOKUPS; i++) {
95 int* decodeInfo = FORMAT_INFO_DECODE_LOOKUP[i];
96 int targetInfo = decodeInfo[0];
97 if (targetInfo == unmaskedFormatInfo) {
98 // Found an exact match
99 Ref<FormatInformation> result(new FormatInformation(decodeInfo[1]));
102 int bitsDifference = numBitsDiffering(unmaskedFormatInfo, targetInfo);
103 if (bitsDifference < bestDifference) {
104 bestFormatInfo = decodeInfo[1];
105 bestDifference = bitsDifference;
108 if (bestDifference <= 3) {
109 Ref<FormatInformation> result(new FormatInformation(bestFormatInfo));
112 Ref<FormatInformation> result;
116 bool operator==(const FormatInformation &a,
117 const FormatInformation &b) {
118 return &(a.errorCorrectionLevel_) == &(b.errorCorrectionLevel_) &&
119 a.dataMask_ == b.dataMask_;
122 ostream& operator<<(ostream& out, const FormatInformation& fi) {
123 const FormatInformation *fip = &fi;
124 out << "FormatInformation @ " << (unsigned int)fip;