| 386 | } |
| 387 | |
| 388 | static DecoderResult DoDecode(const BitMatrix& bits) |
| 389 | { |
| 390 | // Construct a parser and read version, error-correction level |
| 391 | const Version* version = VersionForDimensionsOf(bits); |
| 392 | if (version == nullptr) |
| 393 | return FormatError("Invalid matrix dimension"); |
| 394 | |
| 395 | // Read codewords |
| 396 | ByteArray codewords = CodewordsFromBitMatrix(bits, *version); |
| 397 | if (codewords.empty()) |
| 398 | return FormatError("Invalid number of code words"); |
| 399 | |
| 400 | bool fix259 = false; // see https://github.com/zxing-cpp/zxing-cpp/issues/259 |
| 401 | retry: |
| 402 | // Separate into data blocks |
| 403 | std::vector<DataBlock> dataBlocks = GetDataBlocks(codewords, *version, fix259); |
| 404 | if (dataBlocks.empty()) |
| 405 | return FormatError("Invalid number of data blocks"); |
| 406 | |
| 407 | // Count total number of data bytes |
| 408 | ByteArray resultBytes(TransformReduce(dataBlocks, 0, [](const auto& db) { return db.numDataCodewords; })); |
| 409 | |
| 410 | // Error-correct and copy data blocks together into a stream of bytes |
| 411 | const int dataBlocksCount = Size(dataBlocks); |
| 412 | for (int j = 0; j < dataBlocksCount; j++) { |
| 413 | auto& [numDataCodewords, codewords] = dataBlocks[j]; |
| 414 | if (!CorrectErrors(codewords, numDataCodewords)) { |
| 415 | if(version->versionNumber == 24 && !fix259) { |
| 416 | fix259 = true; |
| 417 | goto retry; |
| 418 | } |
| 419 | return ChecksumError(); |
| 420 | } |
| 421 | |
| 422 | for (int i = 0; i < numDataCodewords; i++) { |
| 423 | // De-interlace data blocks. |
| 424 | resultBytes[i * dataBlocksCount + j] = codewords[i]; |
| 425 | } |
| 426 | } |
| 427 | #ifdef PRINT_DEBUG |
| 428 | if (fix259) |
| 429 | printf("-> needed retry with fix259 for 144x144 symbol\n"); |
| 430 | #endif |
| 431 | |
| 432 | // Decode the contents of that stream of bytes |
| 433 | return DecodedBitStreamParser::Decode(std::move(resultBytes), version->isDMRE()) |
| 434 | .setVersionNumber(version->versionNumber); |
| 435 | } |
| 436 | |
| 437 | static BitMatrix FlippedL(const BitMatrix& bits) |
| 438 | { |
no test coverage detected