Calculates and returns the penalty score based on state of the given QR Code's current modules. This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
| 552 | // Calculates and returns the penalty score based on state of the given QR Code's current modules. |
| 553 | // This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score. |
| 554 | static long getPenaltyScore(const uint8_t qrcode[]) { |
| 555 | int qrsize = qrcodegen_getSize(qrcode); |
| 556 | long result = 0; |
| 557 | |
| 558 | // Adjacent modules in row having same color |
| 559 | for (int y = 0; y < qrsize; y++) { |
| 560 | bool colorX = false; |
| 561 | for (int x = 0, runX = -1; x < qrsize; x++) { |
| 562 | if (x == 0 || getModule(qrcode, x, y) != colorX) { |
| 563 | colorX = getModule(qrcode, x, y); |
| 564 | runX = 1; |
| 565 | } else { |
| 566 | runX++; |
| 567 | if (runX == 5) |
| 568 | result += PENALTY_N1; |
| 569 | else if (runX > 5) |
| 570 | result++; |
| 571 | } |
| 572 | } |
| 573 | } |
| 574 | // Adjacent modules in column having same color |
| 575 | for (int x = 0; x < qrsize; x++) { |
| 576 | bool colorY = false; |
| 577 | for (int y = 0, runY = -1; y < qrsize; y++) { |
| 578 | if (y == 0 || getModule(qrcode, x, y) != colorY) { |
| 579 | colorY = getModule(qrcode, x, y); |
| 580 | runY = 1; |
| 581 | } else { |
| 582 | runY++; |
| 583 | if (runY == 5) |
| 584 | result += PENALTY_N1; |
| 585 | else if (runY > 5) |
| 586 | result++; |
| 587 | } |
| 588 | } |
| 589 | } |
| 590 | |
| 591 | // 2*2 blocks of modules having same color |
| 592 | for (int y = 0; y < qrsize - 1; y++) { |
| 593 | for (int x = 0; x < qrsize - 1; x++) { |
| 594 | bool color = getModule(qrcode, x, y); |
| 595 | if ( color == getModule(qrcode, x + 1, y) && |
| 596 | color == getModule(qrcode, x, y + 1) && |
| 597 | color == getModule(qrcode, x + 1, y + 1)) |
| 598 | result += PENALTY_N2; |
| 599 | } |
| 600 | } |
| 601 | |
| 602 | // Finder-like pattern in rows |
| 603 | for (int y = 0; y < qrsize; y++) { |
| 604 | for (int x = 0, bits = 0; x < qrsize; x++) { |
| 605 | bits = ((bits << 1) & 0x7FF) | (getModule(qrcode, x, y) ? 1 : 0); |
| 606 | if (x >= 10 && (bits == 0x05D || bits == 0x5D0)) // Needs 11 bits accumulated |
| 607 | result += PENALTY_N3; |
| 608 | } |
| 609 | } |
| 610 | // Finder-like pattern in columns |
| 611 | for (int x = 0; x < qrsize; x++) { |
no test coverage detected