| 798 | uint64_t high64; |
| 799 | |
| 800 | void decode(uint8_t *dst, size_t dstX, size_t dstY, size_t dstWidth, size_t dstHeight, size_t dstPitch, size_t dstBpp, bool isSigned) const { |
| 801 | uint8_t mode = 0; |
| 802 | Data data(low64, high64); |
| 803 | assert(dstBpp == sizeof(Color)); |
| 804 | |
| 805 | if ((data.low64 & 0x2) == 0) { |
| 806 | mode = data.consumeBits(1, 0); |
| 807 | } else { |
| 808 | mode = data.consumeBits(4, 0); |
| 809 | } |
| 810 | |
| 811 | int blockIndex = modeToIndex(mode); |
| 812 | // Handle illegal or reserved mode |
| 813 | if (blockIndex == -1) { |
| 814 | for (int y = 0; y < 4 && y + dstY < dstHeight; y++) { |
| 815 | for (int x = 0; x < 4 && x + dstX < dstWidth; x++) { |
| 816 | auto out = reinterpret_cast<Color *>(dst + sizeof(Color) * x + dstPitch * y); |
| 817 | out->rgba = {0, 0, 0}; |
| 818 | } |
| 819 | } |
| 820 | return; |
| 821 | } |
| 822 | const BlockDesc *blockDesc = blockDescs[blockIndex]; |
| 823 | |
| 824 | RGBf e[4]; |
| 825 | e[0].isSigned = e[1].isSigned = e[2].isSigned = e[3].isSigned = isSigned; |
| 826 | |
| 827 | int partition = 0; |
| 828 | ModeDesc modeDesc; |
| 829 | for (int index = 0; blockDesc[index].type != End; index++) { |
| 830 | const BlockDesc desc = blockDesc[index]; |
| 831 | |
| 832 | switch (desc.type) { |
| 833 | case Mode: |
| 834 | modeDesc = desc.modeDesc; |
| 835 | assert(modeDesc.number == mode); |
| 836 | |
| 837 | e[0].size[0] = e[0].size[1] = e[0].size[2] = modeDesc.endpointBits; |
| 838 | for (int i = 0; i < RGBfChannels; i++) { |
| 839 | if (modeDesc.hasDelta) { |
| 840 | e[1].size[i] = e[2].size[i] = e[3].size[i] = modeDesc.deltaBits.channel[i]; |
| 841 | } else { |
| 842 | e[1].size[i] = e[2].size[i] = e[3].size[i] = modeDesc.endpointBits; |
| 843 | } |
| 844 | } |
| 845 | break; |
| 846 | case Partition: |
| 847 | partition |= data.consumeBits(desc.MSB, desc.LSB); |
| 848 | break; |
| 849 | case EP0: |
| 850 | case EP1: |
| 851 | case EP2: |
| 852 | case EP3: |
| 853 | e[desc.type].channel[desc.channel] |= data.consumeBits(desc.MSB, desc.LSB); |
| 854 | break; |
| 855 | default: |
| 856 | assert(false); |
| 857 | return; |
no test coverage detected