| 15 | namespace ZXing::DataMatrix { |
| 16 | |
| 17 | std::vector<DataBlock> GetDataBlocks(const ByteArray& rawCodewords, const Version& version, bool fix259) |
| 18 | { |
| 19 | // First count the total number of data blocks |
| 20 | // Now establish DataBlocks of the appropriate size and number of data codewords |
| 21 | auto& ecBlocks = version.ecBlocks; |
| 22 | const int numResultBlocks = ecBlocks.numBlocks(); |
| 23 | std::vector<DataBlock> result; |
| 24 | result.reserve(numResultBlocks); |
| 25 | for (auto& ecBlock : ecBlocks.blocks) |
| 26 | for (int i = 0; i < ecBlock.count; i++) |
| 27 | result.push_back({ecBlock.dataCodewords, ByteArray(ecBlocks.codewordsPerBlock + ecBlock.dataCodewords)}); |
| 28 | |
| 29 | // All blocks have the same amount of data, except that the last n |
| 30 | // (where n may be 0) have 1 less byte. Figure out where these start. |
| 31 | // TODO(bbrown): There is only one case where there is a difference for Data Matrix for size 144 |
| 32 | const int numCodewords = Size(result[0].codewords); |
| 33 | const int numDataCodewords = numCodewords - ecBlocks.codewordsPerBlock; |
| 34 | |
| 35 | // The last elements of result may be 1 element shorter for 144 matrix |
| 36 | // first fill out as many elements as all of them have minus 1 |
| 37 | int rawCodewordsOffset = 0; |
| 38 | for (int i = 0; i < numDataCodewords - 1; i++) |
| 39 | for (int j = 0; j < numResultBlocks; j++) |
| 40 | result[j].codewords[i] = rawCodewords[rawCodewordsOffset++]; |
| 41 | |
| 42 | // Fill out the last data block in the longer ones |
| 43 | const bool size144x144 = version.symbolHeight == 144; |
| 44 | const int numLongerBlocks = size144x144 ? 8 : numResultBlocks; |
| 45 | for (int j = 0; j < numLongerBlocks; j++) |
| 46 | result[j].codewords[numDataCodewords - 1] = rawCodewords[rawCodewordsOffset++]; |
| 47 | |
| 48 | // Now add in error correction blocks |
| 49 | for (int i = numDataCodewords; i < numCodewords; i++) { |
| 50 | for (int j = 0; j < numResultBlocks; j++) { |
| 51 | int jOffset = size144x144 && fix259 ? (j + 8) % numResultBlocks : j; |
| 52 | int iOffset = size144x144 && jOffset > 7 ? i - 1 : i; |
| 53 | result[jOffset].codewords[iOffset] = rawCodewords[rawCodewordsOffset++]; |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | if (rawCodewordsOffset != Size(rawCodewords)) |
| 58 | return {}; |
| 59 | |
| 60 | return result; |
| 61 | } |
| 62 | |
| 63 | } // namespace ZXing::DataMatrix |