5 * Created by Christian Brunschen on 20/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 <zxing/qrcode/decoder/Decoder.h>
22 #include <zxing/qrcode/decoder/BitMatrixParser.h>
23 #include <zxing/qrcode/ErrorCorrectionLevel.h>
24 #include <zxing/qrcode/Version.h>
25 #include <zxing/qrcode/decoder/DataBlock.h>
26 #include <zxing/qrcode/decoder/DecodedBitStreamParser.h>
27 #include <zxing/ReaderException.h>
28 #include <zxing/common/reedsolomon/ReedSolomonException.h>
36 rsDecoder_(GF256::QR_CODE_FIELD) {
39 void Decoder::correctErrors(ArrayRef<unsigned char> codewordBytes, int numDataCodewords) {
40 int numCodewords = codewordBytes->size();
41 ArrayRef<int> codewordInts(numCodewords);
42 for (int i = 0; i < numCodewords; i++) {
43 codewordInts[i] = codewordBytes[i] & 0xff;
45 int numECCodewords = numCodewords - numDataCodewords;
48 rsDecoder_.decode(codewordInts, numECCodewords);
49 } catch (ReedSolomonException ex) {
50 ReaderException rex(ex.what());
54 for (int i = 0; i < numDataCodewords; i++) {
55 codewordBytes[i] = (unsigned char)codewordInts[i];
59 Ref<DecoderResult> Decoder::decode(Ref<BitMatrix> bits) {
60 // Construct a parser and read version, error-correction level
61 BitMatrixParser parser(bits);
63 Version *version = parser.readVersion();
64 ErrorCorrectionLevel &ecLevel = parser.readFormatInformation()->getErrorCorrectionLevel();
68 ArrayRef<unsigned char> codewords(parser.readCodewords());
71 // Separate into data blocks
72 std::vector<Ref<DataBlock> > dataBlocks(DataBlock::getDataBlocks(codewords, version, ecLevel));
75 // Count total number of data bytes
77 for (size_t i = 0; i < dataBlocks.size(); i++) {
78 totalBytes += dataBlocks[i]->getNumDataCodewords();
80 ArrayRef<unsigned char> resultBytes(totalBytes);
84 // Error-correct and copy data blocks together into a stream of bytes
85 for (size_t j = 0; j < dataBlocks.size(); j++) {
86 Ref<DataBlock> dataBlock(dataBlocks[j]);
87 ArrayRef<unsigned char> codewordBytes = dataBlock->getCodewords();
88 int numDataCodewords = dataBlock->getNumDataCodewords();
89 correctErrors(codewordBytes, numDataCodewords);
90 for (int i = 0; i < numDataCodewords; i++) {
91 resultBytes[resultOffset++] = codewordBytes[i];
95 // Decode the contents of that stream of bytes
96 Ref<String> text(new String(DecodedBitStreamParser::decode(resultBytes, version)));
98 Ref<DecoderResult> result(new DecoderResult(resultBytes, text));