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.
22 #include "BitMatrixParser.h"
23 #include "ErrorCorrectionLevel.h"
25 #include "DataBlock.h"
26 #include "DecodedBitStreamParser.h"
27 #include "../../ReaderException.h"
28 #include "../../common/reedsolomon/ReedSolomonException.h"
33 using namespace common;
34 using namespace reedsolomon;
37 void Decoder::correctErrors(ArrayRef<unsigned char> codewordBytes,
38 int numDataCodewords) {
39 int numCodewords = codewordBytes->size();
40 ArrayRef<int> codewordInts(numCodewords);
41 for (int i = 0; i < numCodewords; i++) {
42 codewordInts[i] = codewordBytes[i] & 0xff;
44 int numECCodewords = numCodewords - numDataCodewords;
46 rsDecoder_.decode(codewordInts, numECCodewords);
48 catch (ReedSolomonException *ex) {
49 ReaderException *rex = new ReaderException(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);
62 Version *version = parser.readVersion();
63 ErrorCorrectionLevel &ecLevel =
64 parser.readFormatInformation()->getErrorCorrectionLevel();
67 ArrayRef<unsigned char> codewords(parser.readCodewords());
68 // Separate into data blocks
69 ArrayRef<Ref<DataBlock> > dataBlocks (DataBlock::getDataBlocks(codewords, version, ecLevel));
71 // Count total number of data bytes
73 for (size_t i = 0; i < dataBlocks->size(); i++) {
74 totalBytes += dataBlocks[i]->getNumDataCodewords();
76 ArrayRef<unsigned char> resultBytes(totalBytes);
79 // Error-correct and copy data blocks together into a stream of bytes
80 for (size_t j = 0; j < dataBlocks->size(); j++) {
81 Ref<DataBlock> dataBlock (dataBlocks[j]);
82 ArrayRef<unsigned char> codewordBytes = dataBlock->getCodewords();
83 int numDataCodewords = dataBlock->getNumDataCodewords();
84 correctErrors(codewordBytes, numDataCodewords);
85 for (int i = 0; i < numDataCodewords; i++) {
86 resultBytes[resultOffset++] = codewordBytes[i];
90 // Decode the contents of that stream of bytes
91 Ref<String> text(new String(DecodedBitStreamParser::decode(resultBytes, version)));
93 Ref<DecoderResult> result(new DecoderResult(resultBytes, text));