| 683 | } |
| 684 | |
| 685 | static void performErrorCorrection(uint8_t version, uint8_t ecc, BitBucket *data) { |
| 686 | |
| 687 | // See: http://www.thonky.com/qr-code-tutorial/structure-final-message |
| 688 | |
| 689 | #if LOCK_VERSION == 0 |
| 690 | uint8_t numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecc][version - 1]; |
| 691 | uint16_t totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[ecc][version - 1]; |
| 692 | uint16_t moduleCount = NUM_RAW_DATA_MODULES[version - 1]; |
| 693 | #else |
| 694 | uint8_t numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecc]; |
| 695 | uint16_t totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[ecc]; |
| 696 | uint16_t moduleCount = NUM_RAW_DATA_MODULES; |
| 697 | #endif |
| 698 | |
| 699 | uint8_t blockEccLen = totalEcc / numBlocks; |
| 700 | uint8_t numShortBlocks = numBlocks - moduleCount / 8 % numBlocks; |
| 701 | uint8_t shortBlockLen = moduleCount / 8 / numBlocks; |
| 702 | |
| 703 | uint8_t shortDataBlockLen = shortBlockLen - blockEccLen; |
| 704 | |
| 705 | uint8_t result[data->capacityBytes]; |
| 706 | memset(result, 0, sizeof(result)); |
| 707 | |
| 708 | uint8_t coeff[blockEccLen]; |
| 709 | rs_init(blockEccLen, coeff); |
| 710 | |
| 711 | uint16_t offset = 0; |
| 712 | uint8_t *dataBytes = data->data; |
| 713 | |
| 714 | |
| 715 | // Interleave all short blocks |
| 716 | for (uint8_t i = 0; i < shortDataBlockLen; i++) { |
| 717 | uint16_t index = i; |
| 718 | uint8_t stride = shortDataBlockLen; |
| 719 | for (uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) { |
| 720 | result[offset++] = dataBytes[index]; |
| 721 | |
| 722 | #if LOCK_VERSION == 0 || LOCK_VERSION >= 5 |
| 723 | if (blockNum == numShortBlocks) { stride++; } |
| 724 | #endif |
| 725 | index += stride; |
| 726 | } |
| 727 | } |
| 728 | |
| 729 | // Version less than 5 only have short blocks |
| 730 | #if LOCK_VERSION == 0 || LOCK_VERSION >= 5 |
| 731 | { |
| 732 | // Interleave long blocks |
| 733 | uint16_t index = shortDataBlockLen * (numShortBlocks + 1); |
| 734 | uint8_t stride = shortDataBlockLen; |
| 735 | for (uint8_t blockNum = 0; blockNum < numBlocks - numShortBlocks; blockNum++) { |
| 736 | result[offset++] = dataBytes[index]; |
| 737 | |
| 738 | if (blockNum == 0) { stride++; } |
| 739 | index += stride; |
| 740 | } |
| 741 | } |
| 742 | #endif |
no test coverage detected