encodeBlocks takes the completed (terminated & padded) encoded data, splits the data into blocks (as specified by the QR Code version), applies error correction to each block, then interleaves the blocks together. The QR Code's final data sequence is returned.
()
| 443 | // |
| 444 | // The QR Code's final data sequence is returned. |
| 445 | func (q *QRCode) encodeBlocks() *bitset.Bitset { |
| 446 | // Split into blocks. |
| 447 | type dataBlock struct { |
| 448 | data *bitset.Bitset |
| 449 | ecStartOffset int |
| 450 | } |
| 451 | |
| 452 | block := make([]dataBlock, q.version.numBlocks()) |
| 453 | |
| 454 | start := 0 |
| 455 | end := 0 |
| 456 | blockID := 0 |
| 457 | |
| 458 | for _, b := range q.version.block { |
| 459 | for j := 0; j < b.numBlocks; j++ { |
| 460 | start = end |
| 461 | end = start + b.numDataCodewords*8 |
| 462 | |
| 463 | // Apply error correction to each block. |
| 464 | numErrorCodewords := b.numCodewords - b.numDataCodewords |
| 465 | block[blockID].data = reedsolomon.Encode(q.data.Substr(start, end), numErrorCodewords) |
| 466 | block[blockID].ecStartOffset = end - start |
| 467 | |
| 468 | blockID++ |
| 469 | } |
| 470 | } |
| 471 | |
| 472 | // Interleave the blocks. |
| 473 | |
| 474 | result := bitset.New() |
| 475 | |
| 476 | // Combine data blocks. |
| 477 | working := true |
| 478 | for i := 0; working; i += 8 { |
| 479 | working = false |
| 480 | |
| 481 | for j, b := range block { |
| 482 | if i >= block[j].ecStartOffset { |
| 483 | continue |
| 484 | } |
| 485 | |
| 486 | result.Append(b.data.Substr(i, i+8)) |
| 487 | |
| 488 | working = true |
| 489 | } |
| 490 | } |
| 491 | |
| 492 | // Combine error correction blocks. |
| 493 | working = true |
| 494 | for i := 0; working; i += 8 { |
| 495 | working = false |
| 496 | |
| 497 | for j, b := range block { |
| 498 | offset := i + block[j].ecStartOffset |
| 499 | if offset >= block[j].data.Len() { |
| 500 | continue |
| 501 | } |
| 502 |