HRESULT DumpBCImage()

in Texdiag/texdiag.cpp [1665:3200]


    HRESULT DumpBCImage(const Image& image, int pixelx, int pixely)
    {
        size_t sbpp;
        switch (image.format)
        {
        case DXGI_FORMAT_BC1_UNORM:
        case DXGI_FORMAT_BC1_UNORM_SRGB:
        case DXGI_FORMAT_BC4_UNORM:
        case DXGI_FORMAT_BC4_SNORM:
            sbpp = 8;
            break;

        case DXGI_FORMAT_BC2_UNORM:
        case DXGI_FORMAT_BC2_UNORM_SRGB:
        case DXGI_FORMAT_BC3_UNORM:
        case DXGI_FORMAT_BC3_UNORM_SRGB:
        case DXGI_FORMAT_BC5_UNORM:
        case DXGI_FORMAT_BC5_SNORM:
        case DXGI_FORMAT_BC6H_UF16:
        case DXGI_FORMAT_BC6H_SF16:
        case DXGI_FORMAT_BC7_UNORM:
        case DXGI_FORMAT_BC7_UNORM_SRGB:
            sbpp = 16;
            break;

        default:
            return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
        }

        const uint8_t *pSrc = image.pixels;
        const size_t rowPitch = image.rowPitch;

        size_t nblock = 0;
        for (size_t h = 0; h < image.height; h += 4, pSrc += rowPitch)
        {
            if (pixely >= 0)
            {
                if ((pixely < int(h)) || (pixely >= int(h + 4)))
                    continue;
            }

            const uint8_t *sptr = pSrc;

            size_t w = 0;
            for (size_t count = 0; count < rowPitch; count += sbpp, w += 4, ++nblock, sptr += sbpp)
            {
                if (pixelx >= 0)
                {
                    if ((pixelx < int(w)) || (pixelx >= int(w + 4)))
                        continue;
                }

                wprintf(L"   Block %zu (pixel: %zu x %zu)\n", nblock, w, h);
                switch (image.format)
                {
                case DXGI_FORMAT_BC1_UNORM:
                case DXGI_FORMAT_BC1_UNORM_SRGB:
                {
                    auto block = reinterpret_cast<const BC1Block*>(sptr);

                    if (block->rgb[0] <= block->rgb[1])
                    {
                        // Transparent block
                        wprintf(L"\tTransparent - E0: ");
                    }
                    else
                    {
                        // Opaque block
                        wprintf(L"\t     Opaque - E0: ");
                    }

                    Print565(block->rgb[0]);
                    wprintf(L"\n\t              E1: ");
                    Print565(block->rgb[1]);
                    wprintf(L"\n\t           Index: ");
                    PrintIndex2bpp(block->bitmap);
                    wprintf(L"\n");
                }
                break;

                case DXGI_FORMAT_BC2_UNORM:
                case DXGI_FORMAT_BC2_UNORM_SRGB:
                {
                    auto block = reinterpret_cast<const BC2Block*>(sptr);

                    wprintf(L"\tColor - E0: ");
                    Print565(block->bc1.rgb[0]);
                    wprintf(L"\n\t        E1: ");
                    Print565(block->bc1.rgb[1]);
                    wprintf(L"\n\t     Index: ");
                    PrintIndex2bpp(block->bc1.bitmap);
                    wprintf(L"\n");

                    wprintf(L"\tAlpha - ");

                    size_t j = 0;
                    uint32_t bitmap = block->bitmap[0];
                    for (; j < (NUM_PIXELS_PER_BLOCK / 2); ++j, bitmap >>= 4)
                    {
                        wprintf(L"%X%ls", bitmap & 0xF, ((j % 4) == 3) ? L" | " : L" ");
                    }

                    bitmap = block->bitmap[1];
                    for (; j < NUM_PIXELS_PER_BLOCK; ++j, bitmap >>= 4)
                    {
                        wprintf(L"%X%ls", bitmap & 0xF, ((j < (NUM_PIXELS_PER_BLOCK - 1)) && ((j % 4) == 3)) ? L" | " : L" ");
                    }

                    wprintf(L"\n");
                }
                break;

                case DXGI_FORMAT_BC3_UNORM:
                case DXGI_FORMAT_BC3_UNORM_SRGB:
                {
                    auto block = reinterpret_cast<const BC3Block*>(sptr);

                    wprintf(L"\tColor - E0: ");
                    Print565(block->bc1.rgb[0]);
                    wprintf(L"\n\t        E1: ");
                    Print565(block->bc1.rgb[1]);
                    wprintf(L"\n\t     Index: ");
                    PrintIndex2bpp(block->bc1.bitmap);
                    wprintf(L"\n");

                    wprintf(L"\tAlpha - E0: %0.3f  E1: %0.3f (%u)\n\t     Index: ",
                        (float(block->alpha[0]) / 255.f),
                        (float(block->alpha[1]) / 255.f), (block->alpha[0] > block->alpha[1]) ? 8u : 6u);

                    PrintIndex3bpp(block->bitmap);

                    wprintf(L"\n");
                }
                break;

                case DXGI_FORMAT_BC4_UNORM:
                {
                    auto block = reinterpret_cast<const BC4UBlock*>(sptr);

                    wprintf(L"\t   E0: %0.3f  E1: %0.3f (%u)\n\tIndex: ",
                        (float(block->red_0) / 255.f),
                        (float(block->red_1) / 255.f), (block->red_0 > block->red_1) ? 8u : 6u);

                    PrintIndex3bpp(block->indices);

                    wprintf(L"\n");
                }
                break;

                case DXGI_FORMAT_BC4_SNORM:
                {
                    auto block = reinterpret_cast<const BC4SBlock*>(sptr);

                    wprintf(L"\t   E0: %0.3f  E1: %0.3f (%u)\n\tIndex: ",
                        (float(block->red_0) / 127.f),
                        (float(block->red_1) / 127.f), (block->red_0 > block->red_1) ? 8u : 6u);

                    PrintIndex3bpp(block->indices);

                    wprintf(L"\n");
                }
                break;

                case DXGI_FORMAT_BC5_UNORM:
                {
                    auto block = reinterpret_cast<const BC5UBlock*>(sptr);

                    wprintf(L"\tU -   E0: %0.3f  E1: %0.3f (%u)\n\t   Index: ",
                        (float(block->u.red_0) / 255.f),
                        (float(block->u.red_1) / 255.f), (block->u.red_0 > block->u.red_1) ? 8u : 6u);

                    PrintIndex3bpp(block->u.indices);

                    wprintf(L"\n");

                    wprintf(L"\tV -   E0: %0.3f  E1: %0.3f (%u)\n\t   Index: ",
                        (float(block->v.red_0) / 255.f),
                        (float(block->v.red_1) / 255.f), (block->v.red_0 > block->v.red_1) ? 8u : 6u);

                    PrintIndex3bpp(block->v.indices);

                    wprintf(L"\n");
                }
                break;

                case DXGI_FORMAT_BC5_SNORM:
                {
                    auto block = reinterpret_cast<const BC5SBlock*>(sptr);

                    wprintf(L"\tU -   E0: %0.3f  E1: %0.3f (%u)\n\t   Index: ",
                        (float(block->u.red_0) / 127.f),
                        (float(block->u.red_1) / 127.f), (block->u.red_0 > block->u.red_1) ? 8u : 6u);

                    PrintIndex3bpp(block->u.indices);

                    wprintf(L"\n");

                    wprintf(L"\tV -   E0: %0.3f  E1: %0.3f (%u)\n\t   Index: ",
                        (float(block->v.red_0) / 127.f),
                        (float(block->v.red_1) / 127.f), (block->v.red_0 > block->v.red_1) ? 8u : 6u);

                    PrintIndex3bpp(block->v.indices);

                    wprintf(L"\n");
                }
                break;

                case DXGI_FORMAT_BC6H_UF16:
                case DXGI_FORMAT_BC6H_SF16:
                    // http://msdn.microsoft.com/en-us/library/windows/desktop/hh308952.aspx#decoding_the_bc6h_format

                    switch (*sptr & 0x03)
                    {
                    case 0x00:
                        // Mode 1 (2 bits, 00)
                    {
                        struct bc6h_mode1
                        {
                            uint64_t mode : 2; // { M, 0}, { M, 1}
                            uint64_t gy4 : 1;  // {GY, 4}
                            uint64_t by4 : 1;  // {BY, 4}
                            uint64_t bz4 : 1;  // {BZ, 4}
                            uint64_t rw : 10;  // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
                            uint64_t gw : 10;  // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
                            uint64_t bw : 10;  // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
                            uint64_t rx : 5;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}
                            uint64_t gz4 : 1;  // {GZ, 4}
                            uint64_t gy : 4;   // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
                            uint64_t gx : 5;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}
                            uint64_t bz0 : 1;  // {BZ, 0},
                            uint64_t gz : 4;   // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
                            uint64_t bx : 5;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}
                            uint64_t bz1 : 1;  // {BZ, 1}
                            uint64_t by : 3;   // {BY, 0}, {BY, 1}, {BY, 2}
                            uint64_t by3 : 1;  // {BY, 3}
                            uint64_t ry : 5;   // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}
                            uint64_t bz2 : 1;  // {BZ, 2}
                            uint64_t rz : 5;   // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}
                            uint64_t bz3 : 1;  // {BZ, 3}
                            uint64_t d : 5;    // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
                            uint64_t indices : 46;
                        };
                        static_assert(sizeof(bc6h_mode1) == 16, "Block size must be 16 bytes");

                        bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                        auto m = reinterpret_cast<const bc6h_mode1*>(sptr);

                        XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
                        XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
                        XMINT3 e1_A(int(m->ry),
                            int(m->gy | (m->gy4 << 4)),
                            int(m->by | (m->by3 << 3) | (m->by4 << 4)));
                        XMINT3 e1_B(int(m->rz),
                            int(m->gz | (m->gz4 << 4)),
                            int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4)));

                        if (bSigned)
                        {
                            e0_A.x = SIGN_EXTEND(e0_A.x, 10);
                            e0_A.y = SIGN_EXTEND(e0_A.y, 10);
                            e0_A.z = SIGN_EXTEND(e0_A.z, 10);

                            e0_B.x = SIGN_EXTEND(e0_B.x, 5);
                            e0_B.y = SIGN_EXTEND(e0_B.y, 5);
                            e0_B.z = SIGN_EXTEND(e0_B.z, 5);

                            e1_A.x = SIGN_EXTEND(e1_A.x, 5);
                            e1_A.y = SIGN_EXTEND(e1_A.y, 5);
                            e1_A.z = SIGN_EXTEND(e1_A.z, 5);

                            e1_B.x = SIGN_EXTEND(e1_B.x, 5);
                            e1_B.y = SIGN_EXTEND(e1_B.y, 5);
                            e1_B.z = SIGN_EXTEND(e1_B.z, 5);
                        }

                        wprintf(L"\tMode 1 - [10 5 5 5] shape %llu\n", m->d);
                        wprintf(L"\t         E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                        wprintf(L"\t         E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                        wprintf(L"\t         E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
                        wprintf(L"\t         E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
                        wprintf(L"\t         Index: ");
                        PrintIndex3bpp(m->indices, 1, m->d);
                        wprintf(L"\n");
                    }
                    break;

                    case 0x01:
                        // Mode 2 (2 bits, 01)
                    {
                        struct bc6h_mode2
                        {
                            uint64_t mode : 2; // { M, 0}, { M, 1}
                            uint64_t gy5 : 1;  // {GY, 5}
                            uint64_t gz45 : 2; // {GZ, 4}, {GZ, 5}
                            uint64_t rw : 7;   // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}
                            uint64_t bz : 2;   // {BZ, 0}, {BZ, 1}
                            uint64_t by4 : 1;  // {BY, 4},
                            uint64_t gw : 7;   // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}
                            uint64_t by5 : 1;  // {BY, 5}
                            uint64_t bz2 : 1;  // {BZ, 2}
                            uint64_t gy4 : 1;  // {GY, 4}
                            uint64_t bw : 7;   // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}
                            uint64_t bz3 : 1;  // {BZ, 3}
                            uint64_t bz5 : 1;  // {BZ, 5}
                            uint64_t bz4 : 1;  // {BZ, 4}
                            uint64_t rx : 6;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}
                            uint64_t gy : 4;   // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
                            uint64_t gx : 6;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}
                            uint64_t gz : 4;   // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
                            uint64_t bx : 5;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}
                            uint64_t by : 4;   // {BY, 0}, {BY, 1}, {BY, 2}, {BY, 3}
                            uint64_t ry : 6;   // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {RY, 5}
                            uint64_t rz : 6;   // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {RZ, 5},
                            uint64_t d : 5;    // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
                            uint64_t indices : 46;

                        };
                        static_assert(sizeof(bc6h_mode2) == 16, "Block size must be 16 bytes");

                        bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                        auto m = reinterpret_cast<const bc6h_mode2*>(sptr);

                        XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
                        XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
                        XMINT3 e1_A(int(m->ry),
                            int(m->gy | (m->gy4 << 4) | (m->gy5 << 5)),
                            int(m->by | (m->by4 << 4) | (m->by5 << 5)));
                        XMINT3 e1_B(int(m->rz),
                            int(m->gz | (m->gz45 << 4)),
                            int(m->bz | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4) | (m->bz5 << 5)));

                        if (bSigned)
                        {
                            e0_A.x = SIGN_EXTEND(e0_A.x, 7);
                            e0_A.y = SIGN_EXTEND(e0_A.y, 7);
                            e0_A.z = SIGN_EXTEND(e0_A.z, 7);

                            e0_B.x = SIGN_EXTEND(e0_B.x, 6);
                            e0_B.y = SIGN_EXTEND(e0_B.y, 6);
                            e0_B.z = SIGN_EXTEND(e0_B.z, 6);

                            e1_A.x = SIGN_EXTEND(e1_A.x, 6);
                            e1_A.y = SIGN_EXTEND(e1_A.y, 6);
                            e1_A.z = SIGN_EXTEND(e1_A.z, 6);

                            e1_B.x = SIGN_EXTEND(e1_B.x, 6);
                            e1_B.y = SIGN_EXTEND(e1_B.y, 6);
                            e1_B.z = SIGN_EXTEND(e1_B.z, 6);
                        }

                        wprintf(L"\tMode 2 - [7 6 6 6] shape %llu\n", m->d);
                        wprintf(L"\t         E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                        wprintf(L"\t         E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                        wprintf(L"\t         E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
                        wprintf(L"\t         E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
                        wprintf(L"\t         Index: ");
                        PrintIndex3bpp(m->indices, 1, m->d);
                        wprintf(L"\n");
                    }
                    break;

                    default:
                        switch (*sptr & 0x1F)
                        {
                        case 0x02:
                            // Mode 3 (5 bits, 00010)
                        {
                            struct bc6h_mode3
                            {
                                uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
                                uint64_t rw : 10;  // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
                                uint64_t gw : 10;  // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
                                uint64_t bw : 10;  // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
                                uint64_t rx : 5;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}
                                uint64_t rw10 : 1; // {RW,10}
                                uint64_t gy : 4;   // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
                                uint64_t gx : 4;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}
                                uint64_t gw10 : 1; // {GW,10}
                                uint64_t bz0 : 1;  // {BZ, 0}
                                uint64_t gz : 4;   // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
                                uint64_t bx : 4;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}
                                uint64_t bw10 : 1; // {BW,10}
                                uint64_t bz1 : 1;  // {BZ, 1}
                                uint64_t by : 3;   // {BY, 0}, {BY, 1}, {BY, 2}
                                uint64_t by3 : 1;  // {BY, 3}
                                uint64_t ry : 5;   // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}
                                uint64_t bz2 : 1;  // {BZ, 2}
                                uint64_t rz : 5;   // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}
                                uint64_t bz3 : 1;  // {BZ, 3}
                                uint64_t d : 5;    // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
                                uint64_t indices : 46;

                            };
                            static_assert(sizeof(bc6h_mode3) == 16, "Block size must be 16 bytes");

                            bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                            auto m = reinterpret_cast<const bc6h_mode3*>(sptr);

                            XMINT3 e0_A(int(m->rw | (m->rw10 << 10)),
                                int(m->gw | (m->gw10 << 10)),
                                int(m->bw | (m->bw10 << 10)));
                            XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
                            XMINT3 e1_A(int(m->ry), int(m->gy),
                                int(m->by | (m->by3 << 3)));
                            XMINT3 e1_B(int(m->rz),
                                int(m->gz),
                                int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3)));

                            if (bSigned)
                            {
                                e0_A.x = SIGN_EXTEND(e0_A.x, 11);
                                e0_A.y = SIGN_EXTEND(e0_A.y, 11);
                                e0_A.z = SIGN_EXTEND(e0_A.z, 11);

                                e0_B.x = SIGN_EXTEND(e0_B.x, 5);
                                e0_B.y = SIGN_EXTEND(e0_B.y, 4);
                                e0_B.z = SIGN_EXTEND(e0_B.z, 4);

                                e1_A.x = SIGN_EXTEND(e1_A.x, 5);
                                e1_A.y = SIGN_EXTEND(e1_A.y, 4);
                                e1_A.z = SIGN_EXTEND(e1_A.z, 4);

                                e1_B.x = SIGN_EXTEND(e1_B.x, 5);
                                e1_B.y = SIGN_EXTEND(e1_B.y, 4);
                                e1_B.z = SIGN_EXTEND(e1_B.z, 4);
                            }

                            wprintf(L"\tMode 3 - [11 5 4 4] shape %llu\n", m->d);
                            wprintf(L"\t         E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                            wprintf(L"\t         E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                            wprintf(L"\t         E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
                            wprintf(L"\t         E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
                            wprintf(L"\t         Index: ");
                            PrintIndex3bpp(m->indices, 1, m->d);
                            wprintf(L"\n");
                        }
                        break;

                        case 0x06:
                            // Mode 4 (5 bits, 00110)
                        {
                            struct bc6h_mode4
                            {
                                uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
                                uint64_t rw : 10;  // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
                                uint64_t gw : 10;  // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
                                uint64_t bw : 10;  // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
                                uint64_t rx : 4;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}
                                uint64_t rw10 : 1; // {RW,10}
                                uint64_t gz4 : 1;  // {GZ, 4}
                                uint64_t gy : 4;   // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
                                uint64_t gx : 5;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}
                                uint64_t gw10 : 1; // {GW,10}
                                uint64_t gz : 4;   // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
                                uint64_t bx : 4;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}
                                uint64_t bw10 : 1; // {BW,10}
                                uint64_t bz1 : 1;  // {BZ, 1}
                                uint64_t by : 3;   // {BY, 0}, {BY, 1}, {BY, 2}
                                uint64_t by3 : 1;  // {BY, 3}
                                uint64_t ry : 4;   // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}
                                uint64_t bz0 : 1;  // {BZ, 0}
                                uint64_t bz2 : 1;  // {BZ, 2}
                                uint64_t rz : 4;   // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}
                                uint64_t gy4 : 1;  // {GY, 4}
                                uint64_t bz3 : 1;  // {BZ, 3}
                                uint64_t d : 5;    // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
                                uint64_t indices : 46;

                            };
                            static_assert(sizeof(bc6h_mode4) == 16, "Block size must be 16 bytes");

                            bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                            auto m = reinterpret_cast<const bc6h_mode4*>(sptr);

                            XMINT3 e0_A(int(m->rw | (m->rw10 << 10)),
                                int(m->gw | (m->gw10 << 10)),
                                int(m->bw | (m->bw10 << 10)));
                            XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
                            XMINT3 e1_A(int(m->ry),
                                int(m->gy | (m->gy4 << 4)),
                                int(m->by | (m->by3 << 3)));
                            XMINT3 e1_B(int(m->rz),
                                int(m->gz | (m->gz4 << 4)),
                                int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3)));

                            if (bSigned)
                            {
                                e0_A.x = SIGN_EXTEND(e0_A.x, 11);
                                e0_A.y = SIGN_EXTEND(e0_A.y, 11);
                                e0_A.z = SIGN_EXTEND(e0_A.z, 11);

                                e0_B.x = SIGN_EXTEND(e0_B.x, 4);
                                e0_B.y = SIGN_EXTEND(e0_B.y, 5);
                                e0_B.z = SIGN_EXTEND(e0_B.z, 4);

                                e1_A.x = SIGN_EXTEND(e1_A.x, 4);
                                e1_A.y = SIGN_EXTEND(e1_A.y, 5);
                                e1_A.z = SIGN_EXTEND(e1_A.z, 4);

                                e1_B.x = SIGN_EXTEND(e1_B.x, 4);
                                e1_B.y = SIGN_EXTEND(e1_B.y, 5);
                                e1_B.z = SIGN_EXTEND(e1_B.z, 4);
                            }

                            wprintf(L"\tMode 4 - [11 4 5 4] shape %llu\n", m->d);
                            wprintf(L"\t         E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                            wprintf(L"\t         E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                            wprintf(L"\t         E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
                            wprintf(L"\t         E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
                            wprintf(L"\t         Index: ");
                            PrintIndex3bpp(m->indices, 1, m->d);
                            wprintf(L"\n");
                        }
                        break;

                        case 0x0A:
                            // Mode 5 (5 bits, 01010)
                        {
                            struct bc6h_mode5
                            {
                                uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
                                uint64_t rw : 10;  // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
                                uint64_t gw : 10;  // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
                                uint64_t bw : 10;  // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
                                uint64_t rx : 4;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}
                                uint64_t rw10 : 1; // {RW,10}
                                uint64_t by4 : 1;  // {BY, 4}
                                uint64_t gy : 4;   // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
                                uint64_t gx : 4;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}
                                uint64_t gw10 : 1; // {GW,10}
                                uint64_t bz0 : 1;  // {BZ, 0}
                                uint64_t gz : 4;   // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
                                uint64_t bx : 5;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}
                                uint64_t bw10 : 1; // {BW,10}
                                uint64_t by : 3;   // {BY, 0}, {BY, 1}, {BY, 2}
                                uint64_t by3 : 1;  // {BY, 3}
                                uint64_t ry : 4;   // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}
                                uint64_t bz12 : 2; // {BZ, 1}, {BZ, 2}
                                uint64_t rz : 5;   // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {BZ, 4}
                                uint64_t bz3 : 1;  // {BZ, 3}
                                uint64_t d : 5;    // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
                                uint64_t indices : 46;
                            };
                            static_assert(sizeof(bc6h_mode5) == 16, "Block size must be 16 bytes");

                            bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                            auto m = reinterpret_cast<const bc6h_mode5*>(sptr);

                            XMINT3 e0_A(int(m->rw | (m->rw10 << 10)),
                                int(m->gw | (m->gw10 << 10)),
                                int(m->bw | (m->bw10 << 10)));
                            XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
                            XMINT3 e1_A(int(m->ry), int(m->gy),
                                int(m->by | (m->by3 << 3) | (m->by4 << 4)));
                            XMINT3 e1_B(int(m->rz), int(m->gz),
                                int(m->bz0 | (m->bz12 << 1) | (m->bz3 << 3)));

                            if (bSigned)
                            {
                                e0_A.x = SIGN_EXTEND(e0_A.x, 11);
                                e0_A.y = SIGN_EXTEND(e0_A.y, 11);
                                e0_A.z = SIGN_EXTEND(e0_A.z, 11);

                                e0_B.x = SIGN_EXTEND(e0_B.x, 4);
                                e0_B.y = SIGN_EXTEND(e0_B.y, 4);
                                e0_B.z = SIGN_EXTEND(e0_B.z, 5);

                                e1_A.x = SIGN_EXTEND(e1_A.x, 4);
                                e1_A.y = SIGN_EXTEND(e1_A.y, 4);
                                e1_A.z = SIGN_EXTEND(e1_A.z, 5);

                                e1_B.x = SIGN_EXTEND(e1_B.x, 4);
                                e1_B.y = SIGN_EXTEND(e1_B.y, 4);
                                e1_B.z = SIGN_EXTEND(e1_B.z, 5);
                            }

                            wprintf(L"\tMode 5 - [11 4 4 5] shape %llu\n", m->d);
                            wprintf(L"\t         E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                            wprintf(L"\t         E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                            wprintf(L"\t         E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
                            wprintf(L"\t         E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
                            wprintf(L"\t         Index: ");
                            PrintIndex3bpp(m->indices, 1, m->d);
                            wprintf(L"\n");
                        }
                        break;

                        case 0x0E:
                            // Mode 6 (5 bits, 01110)
                        {
                            struct bc6h_mode6
                            {
                                uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
                                uint64_t rw : 9;   // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}
                                uint64_t by4 : 1;  // {BY, 4}
                                uint64_t gw : 9;   // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}
                                uint64_t gy4 : 1;  // {GY, 4}
                                uint64_t bw : 9;   // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}
                                uint64_t bz4 : 1;  // {BZ, 4}
                                uint64_t rx : 5;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}
                                uint64_t gz4 : 1;  // {GZ, 4}
                                uint64_t gy : 4;   // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
                                uint64_t gx : 5;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}
                                uint64_t bz0 : 1;  // {BZ, 0}
                                uint64_t gz : 4;   // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
                                uint64_t bx : 5;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}
                                uint64_t bz1 : 1;  // {BZ, 1}
                                uint64_t by : 3;   // {BY, 0}, {BY, 1}, {BY, 2}
                                uint64_t by3 : 1;  // {BY, 3}
                                uint64_t ry : 5;   // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4},
                                uint64_t bz2 : 1;  // {BZ, 2}
                                uint64_t rz : 5;   // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {BZ, 4}
                                uint64_t bz3 : 1;  // {BZ, 3}
                                uint64_t d : 5;    // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
                                uint64_t indices : 46;
                            };
                            static_assert(sizeof(bc6h_mode6) == 16, "Block size must be 16 bytes");

                            bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                            auto m = reinterpret_cast<const bc6h_mode6*>(sptr);

                            XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
                            XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
                            XMINT3 e1_A(int(m->ry),
                                int(m->gy | (m->gy4 << 4)),
                                int(m->by | (m->by3 << 3) | (m->by4 << 4)));
                            XMINT3 e1_B(int(m->rz),
                                int(m->gz | (m->gz4 << 4)),
                                int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4)));

                            if (bSigned)
                            {
                                e0_A.x = SIGN_EXTEND(e0_A.x, 9);
                                e0_A.y = SIGN_EXTEND(e0_A.y, 9);
                                e0_A.z = SIGN_EXTEND(e0_A.z, 9);

                                e0_B.x = SIGN_EXTEND(e0_B.x, 5);
                                e0_B.y = SIGN_EXTEND(e0_B.y, 5);
                                e0_B.z = SIGN_EXTEND(e0_B.z, 5);

                                e1_A.x = SIGN_EXTEND(e1_A.x, 5);
                                e1_A.y = SIGN_EXTEND(e1_A.y, 5);
                                e1_A.z = SIGN_EXTEND(e1_A.z, 5);

                                e1_B.x = SIGN_EXTEND(e1_B.x, 5);
                                e1_B.y = SIGN_EXTEND(e1_B.y, 5);
                                e1_B.z = SIGN_EXTEND(e1_B.z, 5);
                            }

                            wprintf(L"\tMode 6 - [9 5 5 5] shape %llu\n", m->d);
                            wprintf(L"\t         E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                            wprintf(L"\t         E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                            wprintf(L"\t         E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
                            wprintf(L"\t         E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
                            wprintf(L"\t         Index: ");
                            PrintIndex3bpp(m->indices, 1, m->d);
                            wprintf(L"\n");
                        }
                        break;

                        case 0x12:
                            // Mode 7 (5 bits, 10010)
                        {
                            struct bc6h_mode7
                            {
                                uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
                                uint64_t rw : 8;   // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}
                                uint64_t gz4 : 1;  // {GZ, 4}
                                uint64_t by4 : 1;  // {BY, 4}
                                uint64_t gw : 8;   // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}
                                uint64_t bz2 : 1;  // {BZ, 2}
                                uint64_t gy4 : 1;  // {GY, 4}
                                uint64_t bw : 8;   // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}
                                uint64_t bz3 : 1;  // {BZ, 3}
                                uint64_t bz4 : 1;  // {BZ, 4}
                                uint64_t rx : 6;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}
                                uint64_t gy : 4;   // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
                                uint64_t gx : 5;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}
                                uint64_t bz0 : 1;  // {BZ, 0}
                                uint64_t gz : 4;   // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
                                uint64_t bx : 5;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}
                                uint64_t bz1 : 1;  // {BZ, 1}
                                uint64_t by : 3;   // {BY, 0}, {BY, 1}, {BY, 2}
                                uint64_t by3 : 1;  // {BY, 3}
                                uint64_t ry : 6;   // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {RY, 5}
                                uint64_t rz : 6;   // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {RZ, 5}
                                uint64_t d : 5;    // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
                                uint64_t indices : 46;
                            };
                            static_assert(sizeof(bc6h_mode7) == 16, "Block size must be 16 bytes");

                            bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                            auto m = reinterpret_cast<const bc6h_mode7*>(sptr);

                            XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
                            XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
                            XMINT3 e1_A(int(m->ry),
                                int(m->gy | (m->gy4 << 4)),
                                int(m->by | (m->by3 << 3) | (m->by4 << 4)));
                            XMINT3 e1_B(int(m->rz),
                                int(m->gz | (m->gz4 << 4)),
                                int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4)));

                            if (bSigned)
                            {
                                e0_A.x = SIGN_EXTEND(e0_A.x, 8);
                                e0_A.y = SIGN_EXTEND(e0_A.y, 8);
                                e0_A.z = SIGN_EXTEND(e0_A.z, 8);

                                e0_B.x = SIGN_EXTEND(e0_B.x, 6);
                                e0_B.y = SIGN_EXTEND(e0_B.y, 5);
                                e0_B.z = SIGN_EXTEND(e0_B.z, 5);

                                e1_A.x = SIGN_EXTEND(e1_A.x, 6);
                                e1_A.y = SIGN_EXTEND(e1_A.y, 5);
                                e1_A.z = SIGN_EXTEND(e1_A.z, 5);

                                e1_B.x = SIGN_EXTEND(e1_B.x, 6);
                                e1_B.y = SIGN_EXTEND(e1_B.y, 5);
                                e1_B.z = SIGN_EXTEND(e1_B.z, 5);
                            }

                            wprintf(L"\tMode 7 - [8 6 5 5] shape %llu\n", m->d);
                            wprintf(L"\t         E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                            wprintf(L"\t         E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                            wprintf(L"\t         E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
                            wprintf(L"\t         E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
                            wprintf(L"\t         Index: ");
                            PrintIndex3bpp(m->indices, 1, m->d);
                            wprintf(L"\n");
                        }
                        break;

                        case 0x16:
                            // Mode 8 (5 bits, 10110)
                        {
                            struct bc6h_mode8
                            {
                                uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
                                uint64_t rw : 8;   // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}
                                uint64_t bz0 : 1;  // {BZ, 0}
                                uint64_t by4 : 1;  // {BY, 4}
                                uint64_t gw : 8;   // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}
                                uint64_t gy5 : 1;  // {GY, 5}
                                uint64_t gy4 : 1;  // {GY, 4}
                                uint64_t bw : 8;   // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}
                                uint64_t gz5 : 1;  // {GZ, 5}
                                uint64_t bz4 : 1;  // {BZ, 4}
                                uint64_t rx : 5;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}
                                uint64_t gz4 : 1;  // {GZ, 4}
                                uint64_t gy : 4;   // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
                                uint64_t gx : 6;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}
                                uint64_t gz : 4;   // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
                                uint64_t bx : 5;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}
                                uint64_t bz1 : 1;  // {BZ, 1}
                                uint64_t by : 3;   // {BY, 0}, {BY, 1}, {BY, 2}
                                uint64_t by3 : 1;  // {BY, 3}
                                uint64_t ry : 5;   // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}
                                uint64_t bz2 : 1;  // {BZ, 2}
                                uint64_t rz : 5;   // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}
                                uint64_t bz3 : 1;  // {BZ, 3}
                                uint64_t d : 5;    // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
                                uint64_t indices : 46;
                            };
                            static_assert(sizeof(bc6h_mode8) == 16, "Block size must be 16 bytes");

                            bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                            auto m = reinterpret_cast<const bc6h_mode8*>(sptr);

                            XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
                            XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
                            XMINT3 e1_A(int(m->ry),
                                int(m->gy | (m->gy4 << 4) | (m->gy5 << 5)),
                                int(m->by | (m->by3 << 3) | (m->by4 << 4)));
                            XMINT3 e1_B(int(m->rz),
                                int(m->gz | (m->gz4 << 4) | (m->gz5 << 5)),
                                int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4)));

                            if (bSigned)
                            {
                                e0_A.x = SIGN_EXTEND(e0_A.x, 8);
                                e0_A.y = SIGN_EXTEND(e0_A.y, 8);
                                e0_A.z = SIGN_EXTEND(e0_A.z, 8);

                                e0_B.x = SIGN_EXTEND(e0_B.x, 5);
                                e0_B.y = SIGN_EXTEND(e0_B.y, 6);
                                e0_B.z = SIGN_EXTEND(e0_B.z, 5);

                                e1_A.x = SIGN_EXTEND(e1_A.x, 5);
                                e1_A.y = SIGN_EXTEND(e1_A.y, 6);
                                e1_A.z = SIGN_EXTEND(e1_A.z, 5);

                                e1_B.x = SIGN_EXTEND(e1_B.x, 5);
                                e1_B.y = SIGN_EXTEND(e1_B.y, 6);
                                e1_B.z = SIGN_EXTEND(e1_B.z, 5);
                            }

                            wprintf(L"\tMode 8 - [8 5 6 5] shape %llu\n", m->d);
                            wprintf(L"\t         E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                            wprintf(L"\t         E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                            wprintf(L"\t         E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
                            wprintf(L"\t         E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
                            wprintf(L"\t         Index: ");
                            PrintIndex3bpp(m->indices, 1, m->d);
                            wprintf(L"\n");
                        }
                        break;

                        case 0x1A:
                            // Mode 9 (5 bits, 11010)
                        {
                            struct bc6h_mode9
                            {
                                uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
                                uint64_t rw : 8;   // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}
                                uint64_t bz1 : 1;  // {BZ, 1}
                                uint64_t by4 : 1;  // {BY, 4}
                                uint64_t gw : 8;   // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}
                                uint64_t by5 : 1;  // {BY, 5}
                                uint64_t gy4 : 1;  // {GY, 4}
                                uint64_t bw : 8;   // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}
                                uint64_t bz5 : 1;  // {BZ, 5}
                                uint64_t bz4 : 1;  // {BZ, 4}
                                uint64_t rx : 5;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}
                                uint64_t gz4 : 1;  // {GZ, 4}
                                uint64_t gy : 4;   // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
                                uint64_t gx : 5;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}
                                uint64_t bz0 : 1;  // {BZ, 0}
                                uint64_t gz : 4;   // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
                                uint64_t bx : 6;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}
                                uint64_t by : 3;   // {BY, 0}, {BY, 1}, {BY, 2}
                                uint64_t by3 : 1;  // {BY, 3}
                                uint64_t ry : 5;   // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}
                                uint64_t bz2 : 1;  // {BZ, 2}
                                uint64_t rz : 5;   // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}
                                uint64_t bz3 : 1;  // {BZ, 3}
                                uint64_t d : 5;    // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
                                uint64_t indices : 46;
                            };
                            static_assert(sizeof(bc6h_mode9) == 16, "Block size must be 16 bytes");

                            bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                            auto m = reinterpret_cast<const bc6h_mode9*>(sptr);

                            XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
                            XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
                            XMINT3 e1_A(int(m->ry),
                                int(m->gy | (m->gy4 << 4)),
                                int(m->by | (m->by3 << 3) | (m->by4 << 4) | (m->by5 << 5)));
                            XMINT3 e1_B(int(m->rz),
                                int(m->gz | (m->gz4 << 4)),
                                int(m->bz0 | (m->bz1 << 1) | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4) | (m->bz5 << 5)));

                            if (bSigned)
                            {
                                e0_A.x = SIGN_EXTEND(e0_A.x, 8);
                                e0_A.y = SIGN_EXTEND(e0_A.y, 8);
                                e0_A.z = SIGN_EXTEND(e0_A.z, 8);

                                e0_B.x = SIGN_EXTEND(e0_B.x, 5);
                                e0_B.y = SIGN_EXTEND(e0_B.y, 5);
                                e0_B.z = SIGN_EXTEND(e0_B.z, 6);

                                e1_A.x = SIGN_EXTEND(e1_A.x, 5);
                                e1_A.y = SIGN_EXTEND(e1_A.y, 5);
                                e1_A.z = SIGN_EXTEND(e1_A.z, 6);

                                e1_B.x = SIGN_EXTEND(e1_B.x, 5);
                                e1_B.y = SIGN_EXTEND(e1_B.y, 5);
                                e1_B.z = SIGN_EXTEND(e1_B.z, 6);
                            }

                            wprintf(L"\tMode 9 - [8 5 5 6] shape %llu\n", m->d);
                            wprintf(L"\t         E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                            wprintf(L"\t         E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                            wprintf(L"\t         E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
                            wprintf(L"\t         E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
                            wprintf(L"\t         Index: ");
                            PrintIndex3bpp(m->indices, 1, m->d);
                            wprintf(L"\n");
                        }
                        break;

                        case 0x1E:
                            // Mode 10 (5 bits, 11110)
                        {
                            struct bc6h_mode10
                            {
                                uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
                                uint64_t rw : 6;   // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}
                                uint64_t gz4 : 1;  // {GZ, 4}
                                uint64_t bz : 2;  // {BZ, 0}, {BZ, 1}
                                uint64_t by4 : 1;  // {BY, 4}
                                uint64_t gw : 6;   // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}
                                uint64_t gy5 : 1;  // {GY, 5}
                                uint64_t by5 : 1;  // {BY, 5}
                                uint64_t bz2 : 1;  // {BZ, 2}
                                uint64_t gy4 : 1;  // {GY, 4}
                                uint64_t bw : 6;   // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {GZ, 5}
                                uint64_t bz3 : 1;  // {BZ, 3}
                                uint64_t bz5 : 1;  // {BZ, 5}
                                uint64_t bz4 : 1;  // {BZ, 4}
                                uint64_t rx : 6;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}
                                uint64_t gy : 4;   // {GY, 0}, {GY, 1}, {GY, 2}, {GY, 3}
                                uint64_t gx : 6;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}
                                uint64_t gz : 4;   // {GZ, 0}, {GZ, 1}, {GZ, 2}, {GZ, 3}
                                uint64_t bx : 6;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}
                                uint64_t by : 3;   // {BY, 0}, {BY, 1}, {BY, 2}
                                uint64_t by3 : 1;  // {BY, 3}
                                uint64_t ry : 6;   // {RY, 0}, {RY, 1}, {RY, 2}, {RY, 3}, {RY, 4}, {RY, 5}
                                uint64_t rz : 6;   // {RZ, 0}, {RZ, 1}, {RZ, 2}, {RZ, 3}, {RZ, 4}, {RZ, 5}
                                uint64_t d : 5;    // { D, 0}, { D, 1}, { D, 2}, { D, 3}, { D, 4}
                                uint64_t indices : 46;
                            };
                            static_assert(sizeof(bc6h_mode10) == 16, "Block size must be 16 bytes");

                            bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                            auto m = reinterpret_cast<const bc6h_mode10*>(sptr);

                            XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
                            XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));
                            XMINT3 e1_A(int(m->ry),
                                int(m->gy | (m->gy4 << 4) | (m->gy5 << 5)),
                                int(m->by | (m->by3 << 3) | (m->by4 << 4) | (m->by5 << 5)));
                            XMINT3 e1_B(int(m->rz),
                                int(m->gz | (m->gz4 << 4)),
                                int(m->bz | (m->bz2 << 2) | (m->bz3 << 3) | (m->bz4 << 4) | (m->bz5 << 5)));

                            if (bSigned)
                            {
                                e0_A.x = SIGN_EXTEND(e0_A.x, 6);
                                e0_A.y = SIGN_EXTEND(e0_A.y, 6);
                                e0_A.z = SIGN_EXTEND(e0_A.z, 6);

                                e0_B.x = SIGN_EXTEND(e0_B.x, 6);
                                e0_B.y = SIGN_EXTEND(e0_B.y, 6);
                                e0_B.z = SIGN_EXTEND(e0_B.z, 6);

                                e1_A.x = SIGN_EXTEND(e1_A.x, 6);
                                e1_A.y = SIGN_EXTEND(e1_A.y, 6);
                                e1_A.z = SIGN_EXTEND(e1_A.z, 6);

                                e1_B.x = SIGN_EXTEND(e1_B.x, 6);
                                e1_B.y = SIGN_EXTEND(e1_B.y, 6);
                                e1_B.z = SIGN_EXTEND(e1_B.z, 6);
                            }

                            wprintf(L"\tMode 10 - [6 6 6 6] shape %llu\n", m->d);
                            wprintf(L"\t         E0(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                            wprintf(L"\t         E0(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                            wprintf(L"\t         E1(A): (%04X, %04X, %04X)\n", e1_A.x & 0xFFFF, e1_A.y & 0xFFFF, e1_A.z & 0xFFFF);
                            wprintf(L"\t         E1(B): (%04X, %04X, %04X)\n", e1_B.x & 0xFFFF, e1_B.y & 0xFFFF, e1_B.z & 0xFFFF);
                            wprintf(L"\t         Index: ");
                            PrintIndex3bpp(m->indices, 1, m->d);
                            wprintf(L"\n");
                        }
                        break;

                        case 0x03:
                            // Mode 11 (5 bits, 00011)
                        {
                            struct bc6h_mode11
                            {
                                uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
                                uint64_t rw : 10;  // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
                                uint64_t gw : 10;  // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
                                uint64_t bw : 10;  // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
                                uint64_t rx : 10;  // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}, {RX, 6}, {RX, 7}, {RX, 8}, {RX, 9}
                                uint64_t gx : 10;  // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}, {GX, 6}, {GX, 7}, {GX, 8}, {GX, 9}
                                uint64_t bx : 9;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}, {BX, 6}, {BX, 7}, {BX, 8}
                                uint64_t bx9 : 1;  // {BX, 9}
                                uint64_t indices : 63;
                            };
                            static_assert(sizeof(bc6h_mode11) == 16, "Block size must be 16 bytes");

                            bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                            auto m = reinterpret_cast<const bc6h_mode11*>(sptr);

                            XMINT3 e0_A(int(m->rw), int(m->gw), int(m->bw));
                            XMINT3 e0_B(int(m->rx), int(m->gx),
                                int(m->bx | (m->bx9 << 9)));

                            if (bSigned)
                            {
                                e0_A.x = SIGN_EXTEND(e0_A.x, 10);
                                e0_A.y = SIGN_EXTEND(e0_A.y, 10);
                                e0_A.z = SIGN_EXTEND(e0_A.z, 10);

                                e0_B.x = SIGN_EXTEND(e0_B.x, 10);
                                e0_B.y = SIGN_EXTEND(e0_B.y, 10);
                                e0_B.z = SIGN_EXTEND(e0_B.z, 10);
                            }

                            wprintf(L"\tMode 11 - [10 10]\n");
                            wprintf(L"\t         E(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                            wprintf(L"\t         E(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                            wprintf(L"\t         Index: ");
                            PrintIndex4bpp(m->indices, 0, 0);
                            wprintf(L"\n");
                        }
                        break;

                        case 0x07:
                            // Mode 12 (5 bits, 00111)
                        {
                            struct bc6h_mode12
                            {
                                uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
                                uint64_t rw : 10;  // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
                                uint64_t gw : 10;  // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
                                uint64_t bw : 10;  // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
                                uint64_t rx : 9;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}, {RX, 6}, {RX, 7}, {RX, 8}
                                uint64_t rw10 : 1; // {RW,10}
                                uint64_t gx : 9;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}, {GX, 6}, {GX, 7}, {GX, 8}
                                uint64_t gw10 : 1; // {GW,10}
                                uint64_t bx : 9;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}, {BX, 6}, {BX, 7}, {BX, 8}
                                uint64_t bw10 : 1; // {BW,10}
                                uint64_t indices : 63;
                            };
                            static_assert(sizeof(bc6h_mode12) == 16, "Block size must be 16 bytes");

                            bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                            auto m = reinterpret_cast<const bc6h_mode12*>(sptr);

                            XMINT3 e0_A(int(m->rw | (m->rw10 << 10)),
                                int(m->gw | (m->gw10 << 10)),
                                int(m->bw | (m->bw10 << 10)));
                            XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));

                            if (bSigned)
                            {
                                e0_A.x = SIGN_EXTEND(e0_A.x, 11);
                                e0_A.y = SIGN_EXTEND(e0_A.y, 11);
                                e0_A.z = SIGN_EXTEND(e0_A.z, 11);

                                e0_B.x = SIGN_EXTEND(e0_B.x, 9);
                                e0_B.y = SIGN_EXTEND(e0_B.y, 9);
                                e0_B.z = SIGN_EXTEND(e0_B.z, 9);
                            }

                            wprintf(L"\tMode 12 - [11 9]\n");
                            wprintf(L"\t         E(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                            wprintf(L"\t         E(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                            wprintf(L"\t         Index: ");
                            PrintIndex4bpp(m->indices, 0, 0);
                            wprintf(L"\n");
                        }
                        break;

                        case 0x0B:
                            // Mode 13 (5 bits, 01011)
                        {
                            struct bc6h_mode13
                            {
                                uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
                                uint64_t rw : 10;  // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
                                uint64_t gw : 10;  // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
                                uint64_t bw : 10;  // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
                                uint64_t rx : 8;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}, {RX, 4}, {RX, 5}, {RX, 6}, {RX, 7}
                                uint64_t rw11 : 1; // {RW,11}
                                uint64_t rw10 : 1; // {RW,10}
                                uint64_t gx : 8;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}, {GX, 4}, {GX, 5}, {GX, 6}, {GX, 7}
                                uint64_t gw11 : 1; // {GW,11}
                                uint64_t gw10 : 1; // {GW,10}
                                uint64_t bx : 8;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}, {BX, 4}, {BX, 5}, {BX, 6}, {BX, 7}
                                uint64_t bw11 : 1; // {BW,11}
                                uint64_t bw10 : 1; // {BW,10}
                                uint64_t indices : 63;
                            };
                            static_assert(sizeof(bc6h_mode13) == 16, "Block size must be 16 bytes");

                            bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                            auto m = reinterpret_cast<const bc6h_mode13*>(sptr);

                            XMINT3 e0_A(int(m->rw | (m->rw10 << 10) | (m->rw11 << 11)),
                                int(m->gw | (m->gw10 << 10) | (m->gw11 << 11)),
                                int(m->bw | (m->bw10 << 10) | (m->bw11 << 11)));
                            XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));

                            if (bSigned)
                            {
                                e0_A.x = SIGN_EXTEND(e0_A.x, 12);
                                e0_A.y = SIGN_EXTEND(e0_A.y, 12);
                                e0_A.z = SIGN_EXTEND(e0_A.z, 12);

                                e0_B.x = SIGN_EXTEND(e0_B.x, 8);
                                e0_B.y = SIGN_EXTEND(e0_B.y, 8);
                                e0_B.z = SIGN_EXTEND(e0_B.z, 8);
                            }

                            wprintf(L"\tMode 13 - [12 8]\n");
                            wprintf(L"\t         E(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                            wprintf(L"\t         E(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                            wprintf(L"\t         Index: ");
                            PrintIndex4bpp(m->indices, 0, 0);
                            wprintf(L"\n");
                        }
                        break;

                        case 0x0F:
                            // Mode 14 (5 bits, 01111)
                        {
                            struct bc6h_mode14
                            {
                                uint64_t mode : 5; // { M, 0}, { M, 1}, { M, 2}, { M, 3}, { M, 4}
                                uint64_t rw : 10;  // {RW, 0}, {RW, 1}, {RW, 2}, {RW, 3}, {RW, 4}, {RW, 5}, {RW, 6}, {RW, 7}, {RW, 8}, {RW, 9}
                                uint64_t gw : 10;  // {GW, 0}, {GW, 1}, {GW, 2}, {GW, 3}, {GW, 4}, {GW, 5}, {GW, 6}, {GW, 7}, {GW, 8}, {GW, 9}
                                uint64_t bw : 10;  // {BW, 0}, {BW, 1}, {BW, 2}, {BW, 3}, {BW, 4}, {BW, 5}, {BW, 6}, {BW, 7}, {BW, 8}, {BW, 9}
                                uint64_t rx : 4;   // {RX, 0}, {RX, 1}, {RX, 2}, {RX, 3}
                                uint64_t rw15 : 1; // {RW,15}
                                uint64_t rw14 : 1; // {RW,14}
                                uint64_t rw13 : 1; // {RW,13}
                                uint64_t rw12 : 1; // {RW,12}
                                uint64_t rw11 : 1; // {RW,11}
                                uint64_t rw10 : 1; // {RW,10}
                                uint64_t gx : 4;   // {GX, 0}, {GX, 1}, {GX, 2}, {GX, 3}
                                uint64_t gw15 : 1; // {GW,15}
                                uint64_t gw14 : 1; // {GW,14}
                                uint64_t gw13 : 1; // {GW,13}
                                uint64_t gw12 : 1; // {GW,12}
                                uint64_t gw11 : 1; // {GW,11}
                                uint64_t gw10 : 1; // {GW,10}
                                uint64_t bx : 4;   // {BX, 0}, {BX, 1}, {BX, 2}, {BX, 3}
                                uint64_t bw15 : 1; // {BW,15}
                                uint64_t bw14 : 1; // {BW,14}
                                uint64_t bw13 : 1; // {BW,13}
                                uint64_t bw12 : 1; // {BW,12}
                                uint64_t bw11 : 1; // {BW,11}
                                uint64_t bw10 : 1; // {BW,10}
                                uint64_t indices : 63;
                            };
                            static_assert(sizeof(bc6h_mode14) == 16, "Block size must be 16 bytes");

                            bool bSigned = (image.format == DXGI_FORMAT_BC6H_SF16) ? true : false;

                            auto m = reinterpret_cast<const bc6h_mode14*>(sptr);

                            XMINT3 e0_A(int(m->rw | (m->rw10 << 10) | (m->rw11 << 11) | (m->rw12 << 12) | (m->rw13 << 13) | (m->rw14 << 14) | (m->rw15 << 15)),
                                int(m->gw | (m->gw10 << 10) | (m->gw11 << 11) | (m->gw12 << 12) | (m->gw13 << 13) | (m->gw14 << 14) | (m->gw15 << 15)),
                                int(m->bw | (m->bw10 << 10) | (m->bw11 << 11) | (m->bw12 << 12) | (m->bw13 << 13) | (m->bw14 << 14) | (m->bw15 << 15)));
                            XMINT3 e0_B(int(m->rx), int(m->gx), int(m->bx));

                            if (bSigned)
                            {
                                e0_A.x = SIGN_EXTEND(e0_A.x, 16);
                                e0_A.y = SIGN_EXTEND(e0_A.y, 16);
                                e0_A.z = SIGN_EXTEND(e0_A.z, 16);

                                e0_B.x = SIGN_EXTEND(e0_B.x, 4);
                                e0_B.y = SIGN_EXTEND(e0_B.y, 4);
                                e0_B.z = SIGN_EXTEND(e0_B.z, 4);
                            }

                            wprintf(L"\tMode 14 - [16 4]\n");
                            wprintf(L"\t         E(A): (%04X, %04X, %04X)\n", e0_A.x & 0xFFFF, e0_A.y & 0xFFFF, e0_A.z & 0xFFFF);
                            wprintf(L"\t         E(B): (%04X, %04X, %04X)\n", e0_B.x & 0xFFFF, e0_B.y & 0xFFFF, e0_B.z & 0xFFFF);
                            wprintf(L"\t         Index: ");
                            PrintIndex4bpp(m->indices, 0, 0);
                            wprintf(L"\n");
                        }
                        break;

                        case 0x13: // Reserved mode (5 bits, 10011)
                            wprintf(L"\tERROR - Reserved mode 10011\n");
                            break;

                        case 0x17: // Reserved mode (5 bits, 10111)
                            wprintf(L"\tERROR - Reserved mode 10011\n");
                            break;

                        case 0x1B: // Reserved mode (5 bits, 11011)
                            wprintf(L"\tERROR - Reserved mode 11011\n");
                            break;

                        case 0x1F: // Reserved mode (5 bits, 11111)
                            wprintf(L"\tERROR - Reserved mode 11111\n");
                            break;

                        default:
                            break;
                        }
                        break;
                    }
                    break;

                case DXGI_FORMAT_BC7_UNORM:
                case DXGI_FORMAT_BC7_UNORM_SRGB:
                    // http://msdn.microsoft.com/en-us/library/windows/desktop/hh308954.aspx

                    if (*sptr & 0x01)
                    {
                        // Mode 0 (1)
                        struct bc7_mode0
                        {
                            uint64_t mode : 1;
                            uint64_t part : 4;
                            uint64_t r0 : 4;
                            uint64_t r1 : 4;
                            uint64_t r2 : 4;
                            uint64_t r3 : 4;
                            uint64_t r4 : 4;
                            uint64_t r5 : 4;
                            uint64_t g0 : 4;
                            uint64_t g1 : 4;
                            uint64_t g2 : 4;
                            uint64_t g3 : 4;
                            uint64_t g4 : 4;
                            uint64_t g5 : 4;
                            uint64_t b0 : 4;
                            uint64_t b1 : 4;
                            uint64_t b2 : 3;
                            uint64_t b2n : 1;
                            uint64_t b3 : 4;
                            uint64_t b4 : 4;
                            uint64_t b5 : 4;
                            uint64_t P0 : 1;
                            uint64_t P1 : 1;
                            uint64_t P2 : 1;
                            uint64_t P3 : 1;
                            uint64_t P4 : 1;
                            uint64_t P5 : 1;
                            uint64_t index : 45;
                        };
                        static_assert(sizeof(bc7_mode0) == 16, "Block size must be 16 bytes");

                        auto m = reinterpret_cast<const bc7_mode0*>(sptr);

                        wprintf(L"\tMode 0 - [4 4 4] partition %llu\n", m->part);
                        wprintf(L"\t         E0:(%0.3f, %0.3f, %0.3f)\n", float((m->r0 << 1) | m->P0) / 31.f, float((m->g0 << 1) | m->P0) / 31.f, float((m->b0 << 1) | m->P0) / 31.f);
                        wprintf(L"\t         E1:(%0.3f, %0.3f, %0.3f)\n", float((m->r1 << 1) | m->P1) / 31.f, float((m->g1 << 1) | m->P1) / 31.f, float((m->b1 << 1) | m->P1) / 31.f);
                        wprintf(L"\t         E2:(%0.3f, %0.3f, %0.3f)\n", float((m->r2 << 1) | m->P2) / 31.f, float((m->g2 << 1) | m->P2) / 31.f, float(((m->b2 | (m->b2n << 3)) << 1) | m->P2) / 31.f);
                        wprintf(L"\t         E3:(%0.3f, %0.3f, %0.3f)\n", float((m->r3 << 1) | m->P3) / 31.f, float((m->g3 << 1) | m->P3) / 31.f, float((m->b3 << 1) | m->P3) / 31.f);
                        wprintf(L"\t         E4:(%0.3f, %0.3f, %0.3f)\n", float((m->r4 << 1) | m->P4) / 31.f, float((m->g4 << 1) | m->P4) / 31.f, float((m->b4 << 1) | m->P4) / 31.f);
                        wprintf(L"\t         E5:(%0.3f, %0.3f, %0.3f)\n", float((m->r5 << 1) | m->P5) / 31.f, float((m->g5 << 1) | m->P5) / 31.f, float((m->b5 << 1) | m->P5) / 31.f);
                        wprintf(L"\t      Index: ");
                        PrintIndex2bpp(m->index, 2, m->part);
                        wprintf(L"\n");
                    }
                    else if (*sptr & 0x02)
                    {
                        // Mode 1 (01)
                        struct bc7_mode1
                        {
                            uint64_t mode : 2;
                            uint64_t part : 6;
                            uint64_t r0 : 6;
                            uint64_t r1 : 6;
                            uint64_t r2 : 6;
                            uint64_t r3 : 6;
                            uint64_t g0 : 6;
                            uint64_t g1 : 6;
                            uint64_t g2 : 6;
                            uint64_t g3 : 6;
                            uint64_t b0 : 6;
                            uint64_t b1 : 2;
                            uint64_t b1n : 4;
                            uint64_t b2 : 6;
                            uint64_t b3 : 6;
                            uint64_t P0 : 1;
                            uint64_t P1 : 1;
                            uint64_t index : 46;
                        };
                        static_assert(sizeof(bc7_mode1) == 16, "Block size must be 16 bytes");

                        auto m = reinterpret_cast<const bc7_mode1*>(sptr);

                        wprintf(L"\tMode 1 - [6 6 6] partition %llu\n", m->part);
                        wprintf(L"\t         E0:(%0.3f, %0.3f, %0.3f)\n", float((m->r0 << 1) | m->P0) / 127.f, float((m->g0 << 1) | m->P0) / 127.f, float((m->b0 << 1) | m->P0) / 127.f);
                        wprintf(L"\t         E1:(%0.3f, %0.3f, %0.3f)\n", float((m->r1 << 1) | m->P0) / 127.f, float((m->g1 << 1) | m->P0) / 127.f, float(((m->b1 | (m->b1n << 2)) << 1) | m->P0) / 127.f);
                        wprintf(L"\t         E2:(%0.3f, %0.3f, %0.3f)\n", float((m->r2 << 1) | m->P1) / 127.f, float((m->g2 << 1) | m->P1) / 127.f, float((m->b2 << 1) | m->P1) / 127.f);
                        wprintf(L"\t         E3:(%0.3f, %0.3f, %0.3f)\n", float((m->r3 << 1) | m->P1) / 127.f, float((m->g3 << 1) | m->P1) / 127.f, float((m->b3 << 1) | m->P1) / 127.f);
                        wprintf(L"\t      Index: ");
                        PrintIndex3bpp(m->index, 1, m->part);
                        wprintf(L"\n");
                    }
                    else if (*sptr & 0x04)
                    {
                        // Mode 2 (001)
                        struct bc7_mode2
                        {
                            uint64_t mode : 3;
                            uint64_t part : 6;
                            uint64_t r0 : 5;
                            uint64_t r1 : 5;
                            uint64_t r2 : 5;
                            uint64_t r3 : 5;
                            uint64_t r4 : 5;
                            uint64_t r5 : 5;
                            uint64_t g0 : 5;
                            uint64_t g1 : 5;
                            uint64_t g2 : 5;
                            uint64_t g3 : 5;
                            uint64_t g4 : 5;
                            uint64_t g5 : 5;
                            uint64_t b0 : 5;
                            uint64_t b1 : 5;
                            uint64_t b2 : 5;
                            uint64_t b3 : 5;
                            uint64_t b4 : 5;
                            uint64_t b5 : 5;
                            uint64_t index : 29;
                        };
                        static_assert(sizeof(bc7_mode2) == 16, "Block size must be 16 bytes");

                        auto m = reinterpret_cast<const bc7_mode2*>(sptr);

                        wprintf(L"\tMode 2 - [5 5 5] partition %llu\n", m->part);
                        wprintf(L"\t         E0:(%0.3f, %0.3f, %0.3f)\n", float(m->r0) / 31.f, float(m->g0) / 31.f, float(m->b0) / 31.f);
                        wprintf(L"\t         E1:(%0.3f, %0.3f, %0.3f)\n", float(m->r1) / 31.f, float(m->g1) / 31.f, float(m->b1) / 31.f);
                        wprintf(L"\t         E2:(%0.3f, %0.3f, %0.3f)\n", float(m->r2) / 31.f, float(m->g2) / 31.f, float(m->b2) / 31.f);
                        wprintf(L"\t         E3:(%0.3f, %0.3f, %0.3f)\n", float(m->r3) / 31.f, float(m->g3) / 31.f, float(m->b3) / 31.f);
                        wprintf(L"\t         E4:(%0.3f, %0.3f, %0.3f)\n", float(m->r4) / 31.f, float(m->g4) / 31.f, float(m->b4) / 31.f);
                        wprintf(L"\t         E5:(%0.3f, %0.3f, %0.3f)\n", float(m->r5) / 31.f, float(m->g5) / 31.f, float(m->b5) / 31.f);
                        wprintf(L"\t      Index: ");
                        PrintIndex2bpp(m->index, 2, m->part);
                        wprintf(L"\n");
                    }
                    else if (*sptr & 0x08)
                    {
                        // Mode 3 (0001)
                        struct bc7_mode3
                        {
                            uint64_t mode : 4;
                            uint64_t part : 6;
                            uint64_t r0 : 7;
                            uint64_t r1 : 7;
                            uint64_t r2 : 7;
                            uint64_t r3 : 7;
                            uint64_t g0 : 7;
                            uint64_t g1 : 7;
                            uint64_t g2 : 7;
                            uint64_t g3 : 5;
                            uint64_t g3n : 2;
                            uint64_t b0 : 7;
                            uint64_t b1 : 7;
                            uint64_t b2 : 7;
                            uint64_t b3 : 7;
                            uint64_t P0 : 1;
                            uint64_t P1 : 1;
                            uint64_t P2 : 1;
                            uint64_t P3 : 1;
                            uint64_t index : 30;
                        };
                        static_assert(sizeof(bc7_mode3) == 16, "Block size must be 16 bytes");

                        auto m = reinterpret_cast<const bc7_mode3*>(sptr);

                        wprintf(L"\tMode 3 - [7 7 7] partition %llu\n", m->part);
                        wprintf(L"\t         E0:(%0.3f, %0.3f, %0.3f)\n", float((m->r0 << 1) | m->P0) / 255.f, float((m->g0 << 1) | m->P0) / 255.f, float((m->b0 << 1) | m->P0) / 255.f);
                        wprintf(L"\t         E1:(%0.3f, %0.3f, %0.3f)\n", float((m->r1 << 1) | m->P1) / 255.f, float((m->g1 << 1) | m->P1) / 255.f, float((m->b1 << 1) | m->P1) / 255.f);
                        wprintf(L"\t         E2:(%0.3f, %0.3f, %0.3f)\n", float((m->r2 << 1) | m->P2) / 255.f, float((m->g2 << 1) | m->P2) / 255.f, float((m->b2 << 1) | m->P2) / 255.f);
                        wprintf(L"\t         E3:(%0.3f, %0.3f, %0.3f)\n", float((m->r3 << 1) | m->P3) / 255.f, float(((m->g3 | (m->g3n << 5)) << 1) | m->P3) / 255.f, float((m->b3 << 1) | m->P3) / 255.f);
                        wprintf(L"\t      Index: ");
                        PrintIndex2bpp(m->index, 1, m->part);
                        wprintf(L"\n");
                    }
                    else if (*sptr & 0x10)
                    {
                        // Mode 4 (00001)
                        struct bc7_mode4
                        {
                            uint64_t mode : 5;
                            uint64_t rot : 2;
                            uint64_t idx : 1;
                            uint64_t r0 : 5;
                            uint64_t r1 : 5;
                            uint64_t g0 : 5;
                            uint64_t g1 : 5;
                            uint64_t b0 : 5;
                            uint64_t b1 : 5;
                            uint64_t a0 : 6;
                            uint64_t a1 : 6;
                            uint64_t color_index : 14;
                            uint64_t color_indexn : 17;
                            uint64_t alpha_index : 47;
                        };
                        static_assert(sizeof(bc7_mode4) == 16, "Block size must be 16 bytes");

                        auto m = reinterpret_cast<const bc7_mode4*>(sptr);

                        wprintf(L"\tMode 4 - [5 5 5 A6] indx mode %ls, rot-bits %llu%ls\n", m->idx ? L"3-bit" : L"2-bit", m->rot, GetRotBits(m->rot));
                        wprintf(L"\t         C0:(%0.3f, %0.3f, %0.3f)\n", float(m->r0) / 31.f, float(m->g0) / 31.f, float(m->b0) / 31.f);
                        wprintf(L"\t         C1:(%0.3f, %0.3f, %0.3f)\n", float(m->r1) / 31.f, float(m->g1) / 31.f, float(m->b1) / 31.f);
                        wprintf(L"\t         A0:(%0.3f)\n", float(m->a0) / 63.f);
                        wprintf(L"\t         A1:(%0.3f)\n", float(m->a1) / 63.f);
                        wprintf(L"\t    Colors: ");

                        uint64_t color_index = uint64_t(m->color_index) | uint64_t(m->color_indexn << 14);
                        if (m->idx)
                            PrintIndex3bpp(color_index, 0, 0);
                        else
                            PrintIndex2bpp(color_index, 0, 0);
                        wprintf(L"\n");
                        wprintf(L"\t     Alpha: ");
                        PrintIndex3bpp(m->alpha_index, 0, 0);
                        wprintf(L"\n");
                    }
                    else if (*sptr & 0x20)
                    {
                        // Mode 5 (000001)
                        struct bc7_mode5
                        {
                            uint64_t mode : 6;
                            uint64_t rot : 2;
                            uint64_t r0 : 7;
                            uint64_t r1 : 7;
                            uint64_t g0 : 7;
                            uint64_t g1 : 7;
                            uint64_t b0 : 7;
                            uint64_t b1 : 7;
                            uint64_t a0 : 8;
                            uint64_t a1 : 6;
                            uint64_t a1n : 2;
                            uint64_t color_index : 31;
                            uint64_t alpha_index : 31;
                        };
                        static_assert(sizeof(bc7_mode5) == 16, "Block size must be 16 bytes");

                        auto m = reinterpret_cast<const bc7_mode5*>(sptr);

                        wprintf(L"\tMode 5 - [7 7 7 A8] rot-bits %llu%ls\n", m->rot, GetRotBits(m->rot));
                        wprintf(L"\t         C0:(%0.3f, %0.3f, %0.3f)\n", float(m->r0) / 127.f, float(m->g0) / 127.f, float(m->b0) / 127.f);
                        wprintf(L"\t         C1:(%0.3f, %0.3f, %0.3f)\n", float(m->r1) / 127.f, float(m->g1) / 127.f, float(m->b1) / 127.f);
                        wprintf(L"\t         A0:(%0.3f)\n", float(m->a0) / 255.f);
                        wprintf(L"\t         A1:(%0.3f)\n", float(m->a1 | (m->a1n << 6)) / 255.f);
                        wprintf(L"\t    Colors: ");
                        PrintIndex2bpp(m->color_index, 0, 0);
                        wprintf(L"\n");
                        wprintf(L"\t     Alpha: ");
                        PrintIndex2bpp(m->alpha_index, 0, 0);
                        wprintf(L"\n");
                    }
                    else if (*sptr & 0x40)
                    {
                        // Mode 6 (0000001)
                        struct bc7_mode6
                        {
                            uint64_t mode : 7;
                            uint64_t r0 : 7;
                            uint64_t r1 : 7;
                            uint64_t g0 : 7;
                            uint64_t g1 : 7;
                            uint64_t b0 : 7;
                            uint64_t b1 : 7;
                            uint64_t a0 : 7;
                            uint64_t a1 : 7;
                            uint64_t P0 : 1;
                            uint64_t P1 : 1;
                            uint64_t index : 63;

                        };
                        static_assert(sizeof(bc7_mode6) == 16, "Block size must be 16 bytes");

                        auto m = reinterpret_cast<const bc7_mode6*>(sptr);

                        wprintf(L"\tMode 6 - [7 7 7 A7]\n");
                        wprintf(L"\t         C0:(%0.3f, %0.3f, %0.3f)\n", float((m->r0 << 1) | m->P0) / 255.f, float((m->g0 << 1) | m->P0) / 255.f, float((m->b0 << 1) | m->P0) / 255.f);
                        wprintf(L"\t         C1:(%0.3f, %0.3f, %0.3f)\n", float((m->r1 << 1) | m->P1) / 255.f, float((m->g1 << 1) | m->P1) / 255.f, float((m->b1 << 1) | m->P1) / 255.f);
                        wprintf(L"\t         A0:(%0.3f)\n", float((m->a0 << 1) | m->P0) / 255.f);
                        wprintf(L"\t         A1:(%0.3f)\n", float((m->a1 << 1) | m->P1) / 255.f);
                        wprintf(L"\t      Index: ");
                        PrintIndex4bpp(m->index, 0, 0);
                        wprintf(L"\n");
                    }
                    else if (*sptr & 0x80)
                    {
                        // Mode 7 (00000001)
                        struct bc7_mode7
                        {
                            uint64_t mode : 8;
                            uint64_t part : 6;
                            uint64_t r0 : 5;
                            uint64_t r1 : 5;
                            uint64_t r2 : 5;
                            uint64_t r3 : 5;
                            uint64_t g0 : 5;
                            uint64_t g1 : 5;
                            uint64_t g2 : 5;
                            uint64_t g3 : 5;
                            uint64_t b0 : 5;
                            uint64_t b1 : 5;
                            uint64_t b2 : 5;
                            uint64_t b3 : 5;
                            uint64_t a0 : 5;
                            uint64_t a1 : 5;
                            uint64_t a2 : 5;
                            uint64_t a3 : 5;
                            uint64_t P0 : 1;
                            uint64_t P1 : 1;
                            uint64_t P2 : 1;
                            uint64_t P3 : 1;
                            uint64_t index : 30;

                        };
                        static_assert(sizeof(bc7_mode7) == 16, "Block size must be 16 bytes");

                        auto m = reinterpret_cast<const bc7_mode7*>(sptr);

                        wprintf(L"\tMode 7 - [5 5 5 A5] partition %llu\n", m->part);
                        wprintf(L"\t         C0:(%0.3f, %0.3f, %0.3f)\n", float((m->r0 << 1) | m->P0) / 63.f, float((m->g0 << 1) | m->P0) / 63.f, float((m->b0 << 1) | m->P0) / 63.f);
                        wprintf(L"\t         C1:(%0.3f, %0.3f, %0.3f)\n", float((m->r1 << 1) | m->P1) / 63.f, float((m->g1 << 1) | m->P1) / 63.f, float((m->b1 << 1) | m->P1) / 63.f);
                        wprintf(L"\t         C2:(%0.3f, %0.3f, %0.3f)\n", float((m->r2 << 1) | m->P2) / 63.f, float((m->g2 << 1) | m->P2) / 63.f, float((m->b2 << 1) | m->P2) / 63.f);
                        wprintf(L"\t         C3:(%0.3f, %0.3f, %0.3f)\n", float((m->r3 << 1) | m->P3) / 63.f, float((m->g3 << 1) | m->P3) / 63.f, float((m->b3 << 1) | m->P3) / 63.f);
                        wprintf(L"\t         A0:(%0.3f)\n", float((m->a0 << 1) | m->P0) / 63.f);
                        wprintf(L"\t         A1:(%0.3f)\n", float((m->a1 << 1) | m->P1) / 63.f);
                        wprintf(L"\t         A2:(%0.3f)\n", float((m->a2 << 1) | m->P2) / 63.f);
                        wprintf(L"\t         A3:(%0.3f)\n", float((m->a3 << 1) | m->P3) / 63.f);
                        wprintf(L"\t      Index: ");
                        PrintIndex4bpp(m->index, 1, m->part);
                        wprintf(L"\n");
                    }
                    else
                    {
                        // Reserved mode 8 (00000000)
                        wprintf(L"\tERROR - Reserved mode 8\n");
                    }
                    break;
                }
            }
        }

        return S_OK;
    }