| 1672 | // |
| 1673 | |
| 1674 | static int rleCompress(int inLength, const char in[], signed char out[]) { |
| 1675 | const char *inEnd = in + inLength; |
| 1676 | const char *runStart = in; |
| 1677 | const char *runEnd = in + 1; |
| 1678 | signed char *outWrite = out; |
| 1679 | |
| 1680 | while (runStart < inEnd) { |
| 1681 | while (runEnd < inEnd && *runStart == *runEnd && |
| 1682 | runEnd - runStart - 1 < MAX_RUN_LENGTH) { |
| 1683 | ++runEnd; |
| 1684 | } |
| 1685 | |
| 1686 | if (runEnd - runStart >= MIN_RUN_LENGTH) { |
| 1687 | // |
| 1688 | // Compressible run |
| 1689 | // |
| 1690 | |
| 1691 | *outWrite++ = static_cast<char>(runEnd - runStart) - 1; |
| 1692 | *outWrite++ = *(reinterpret_cast<const signed char *>(runStart)); |
| 1693 | runStart = runEnd; |
| 1694 | } else { |
| 1695 | // |
| 1696 | // Uncompressable run |
| 1697 | // |
| 1698 | |
| 1699 | while (runEnd < inEnd && |
| 1700 | ((runEnd + 1 >= inEnd || *runEnd != *(runEnd + 1)) || |
| 1701 | (runEnd + 2 >= inEnd || *(runEnd + 1) != *(runEnd + 2))) && |
| 1702 | runEnd - runStart < MAX_RUN_LENGTH) { |
| 1703 | ++runEnd; |
| 1704 | } |
| 1705 | |
| 1706 | *outWrite++ = static_cast<char>(runStart - runEnd); |
| 1707 | |
| 1708 | while (runStart < runEnd) { |
| 1709 | *outWrite++ = *(reinterpret_cast<const signed char *>(runStart++)); |
| 1710 | } |
| 1711 | } |
| 1712 | |
| 1713 | ++runEnd; |
| 1714 | } |
| 1715 | |
| 1716 | return static_cast<int>(outWrite - out); |
| 1717 | } |
| 1718 | |
| 1719 | // |
| 1720 | // Uncompress an array of bytes compressed with rleCompress(). |