Add ATC & ASTC support

- Add ATC formats for Android etc.
- Add enums for "useful" ASTC formats, using https://developer.nvidia.com/astc-texture-compression-for-game-assets as a guide

- Support decoding ATC/ATCE/ATCI
- Generalise block code to handle non-power-of-two
- Add DDS support for ETC/old (non-DX10) PTC/ATC/ASTC
- Add KTX support for ATC/ASTC
This commit is contained in:
Andrew Willmott
2018-06-09 22:29:00 +01:00
parent 771f12733b
commit f1666e2bf2
2 changed files with 359 additions and 147 deletions

View File

@@ -65,6 +65,15 @@ namespace bimg
PTC14A, //!< PVRTC1 RGBA 4BPP
PTC22, //!< PVRTC2 RGBA 2BPP
PTC24, //!< PVRTC2 RGBA 4BPP
ATC, //!< ATC RGB 4BPP
ATCE, //!< ATCE RGBA 8 BPP explicit alpha
ATCI, //!< ATCI RGBA 8 BPP interpolated alpha
ASTC4x4, //!< ASTC 4x4 8.0 BPP
ASTC5x5, //!< ASTC 5x5 5.12 BPP
ASTC6x6, //!< ASTC 6x6 3.56 BPP
ASTC8x5, //!< ASTC 8x5 3.20 BPP
ASTC8x6, //!< ASTC 8x6 2.67 BPP
ASTC10x5, //!< ASTC 10x5 2.56 BPP
Unknown, // Compressed formats above.

View File

@@ -11,92 +11,101 @@ namespace bimg
static const ImageBlockInfo s_imageBlockInfo[] =
{
// +-------------------------------------------- bits per pixel
// | +----------------------------------------- block width
// | | +-------------------------------------- block height
// | | | +---------------------------------- block size
// | | | | +------------------------------- min blocks x
// | | | | | +---------------------------- min blocks y
// | | | | | | +------------------------ depth bits
// | | | | | | | +--------------------- stencil bits
// | | | | | | | | +---+---+---+----- r, g, b, a bits
// | | | | | | | | r g b a +-- encoding type
// | | | | | | | | | | | | |
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // BC1
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // BC2
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // BC3
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // BC4
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // BC5
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Float) }, // BC6H
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // BC7
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ETC1
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ETC2
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ETC2A
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ETC2A1
{ 2, 8, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC12
{ 4, 4, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC14
{ 2, 8, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC12A
{ 4, 4, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC14A
{ 2, 8, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC22
{ 4, 4, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC24
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Count) }, // Unknown
{ 1, 8, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // R1
{ 8, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 8, uint8_t(bx::EncodingType::Unorm) }, // A8
{ 8, 1, 1, 1, 1, 1, 0, 0, 8, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // R8
{ 8, 1, 1, 1, 1, 1, 0, 0, 8, 0, 0, 0, uint8_t(bx::EncodingType::Int ) }, // R8I
{ 8, 1, 1, 1, 1, 1, 0, 0, 8, 0, 0, 0, uint8_t(bx::EncodingType::Uint ) }, // R8U
{ 8, 1, 1, 1, 1, 1, 0, 0, 8, 0, 0, 0, uint8_t(bx::EncodingType::Snorm) }, // R8S
{ 16, 1, 1, 2, 1, 1, 0, 0, 16, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // R16
{ 16, 1, 1, 2, 1, 1, 0, 0, 16, 0, 0, 0, uint8_t(bx::EncodingType::Int ) }, // R16I
{ 16, 1, 1, 2, 1, 1, 0, 0, 16, 0, 0, 0, uint8_t(bx::EncodingType::Uint ) }, // R16U
{ 16, 1, 1, 2, 1, 1, 0, 0, 16, 0, 0, 0, uint8_t(bx::EncodingType::Float) }, // R16F
{ 16, 1, 1, 2, 1, 1, 0, 0, 16, 0, 0, 0, uint8_t(bx::EncodingType::Snorm) }, // R16S
{ 32, 1, 1, 4, 1, 1, 0, 0, 32, 0, 0, 0, uint8_t(bx::EncodingType::Int ) }, // R32I
{ 32, 1, 1, 4, 1, 1, 0, 0, 32, 0, 0, 0, uint8_t(bx::EncodingType::Uint ) }, // R32U
{ 32, 1, 1, 4, 1, 1, 0, 0, 32, 0, 0, 0, uint8_t(bx::EncodingType::Float) }, // R32F
{ 16, 1, 1, 2, 1, 1, 0, 0, 8, 8, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // RG8
{ 16, 1, 1, 2, 1, 1, 0, 0, 8, 8, 0, 0, uint8_t(bx::EncodingType::Int ) }, // RG8I
{ 16, 1, 1, 2, 1, 1, 0, 0, 8, 8, 0, 0, uint8_t(bx::EncodingType::Uint ) }, // RG8U
{ 16, 1, 1, 2, 1, 1, 0, 0, 8, 8, 0, 0, uint8_t(bx::EncodingType::Snorm) }, // RG8S
{ 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // RG16
{ 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, uint8_t(bx::EncodingType::Int ) }, // RG16I
{ 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, uint8_t(bx::EncodingType::Uint ) }, // RG16U
{ 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, uint8_t(bx::EncodingType::Float) }, // RG16F
{ 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, uint8_t(bx::EncodingType::Snorm) }, // RG16S
{ 64, 1, 1, 8, 1, 1, 0, 0, 32, 32, 0, 0, uint8_t(bx::EncodingType::Int ) }, // RG32I
{ 64, 1, 1, 8, 1, 1, 0, 0, 32, 32, 0, 0, uint8_t(bx::EncodingType::Uint ) }, // RG32U
{ 64, 1, 1, 8, 1, 1, 0, 0, 32, 32, 0, 0, uint8_t(bx::EncodingType::Float) }, // RG32F
{ 24, 1, 1, 3, 1, 1, 0, 0, 8, 8, 8, 0, uint8_t(bx::EncodingType::Unorm) }, // RGB8
{ 24, 1, 1, 3, 1, 1, 0, 0, 8, 8, 8, 0, uint8_t(bx::EncodingType::Int ) }, // RGB8I
{ 24, 1, 1, 3, 1, 1, 0, 0, 8, 8, 8, 0, uint8_t(bx::EncodingType::Uint ) }, // RGB8U
{ 24, 1, 1, 3, 1, 1, 0, 0, 8, 8, 8, 0, uint8_t(bx::EncodingType::Snorm) }, // RGB8S
{ 32, 1, 1, 4, 1, 1, 0, 0, 9, 9, 9, 5, uint8_t(bx::EncodingType::Float) }, // RGB9E5F
{ 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, uint8_t(bx::EncodingType::Unorm) }, // BGRA8
{ 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, uint8_t(bx::EncodingType::Unorm) }, // RGBA8
{ 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, uint8_t(bx::EncodingType::Int ) }, // RGBA8I
{ 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, uint8_t(bx::EncodingType::Uint ) }, // RGBA8U
{ 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, uint8_t(bx::EncodingType::Snorm) }, // RGBA8S
{ 64, 1, 1, 8, 1, 1, 0, 0, 16, 16, 16, 16, uint8_t(bx::EncodingType::Unorm) }, // RGBA16
{ 64, 1, 1, 8, 1, 1, 0, 0, 16, 16, 16, 16, uint8_t(bx::EncodingType::Int ) }, // RGBA16I
{ 64, 1, 1, 8, 1, 1, 0, 0, 16, 16, 16, 16, uint8_t(bx::EncodingType::Uint ) }, // RGBA16U
{ 64, 1, 1, 8, 1, 1, 0, 0, 16, 16, 16, 16, uint8_t(bx::EncodingType::Float) }, // RGBA16F
{ 64, 1, 1, 8, 1, 1, 0, 0, 16, 16, 16, 16, uint8_t(bx::EncodingType::Snorm) }, // RGBA16S
{ 128, 1, 1, 16, 1, 1, 0, 0, 32, 32, 32, 32, uint8_t(bx::EncodingType::Int ) }, // RGBA32I
{ 128, 1, 1, 16, 1, 1, 0, 0, 32, 32, 32, 32, uint8_t(bx::EncodingType::Uint ) }, // RGBA32U
{ 128, 1, 1, 16, 1, 1, 0, 0, 32, 32, 32, 32, uint8_t(bx::EncodingType::Float) }, // RGBA32F
{ 16, 1, 1, 2, 1, 1, 0, 0, 5, 6, 5, 0, uint8_t(bx::EncodingType::Unorm) }, // R5G6B5
{ 16, 1, 1, 2, 1, 1, 0, 0, 4, 4, 4, 4, uint8_t(bx::EncodingType::Unorm) }, // RGBA4
{ 16, 1, 1, 2, 1, 1, 0, 0, 5, 5, 5, 1, uint8_t(bx::EncodingType::Unorm) }, // RGB5A1
{ 32, 1, 1, 4, 1, 1, 0, 0, 10, 10, 10, 2, uint8_t(bx::EncodingType::Unorm) }, // RGB10A2
{ 32, 1, 1, 4, 1, 1, 0, 0, 11, 11, 10, 0, uint8_t(bx::EncodingType::Unorm) }, // RG11B10F
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Count) }, // UnknownDepth
{ 16, 1, 1, 2, 1, 1, 16, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // D16
{ 24, 1, 1, 3, 1, 1, 24, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // D24
{ 32, 1, 1, 4, 1, 1, 24, 8, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // D24S8
{ 32, 1, 1, 4, 1, 1, 32, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // D32
{ 16, 1, 1, 2, 1, 1, 16, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Float) }, // D16F
{ 24, 1, 1, 3, 1, 1, 24, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Float) }, // D24F
{ 32, 1, 1, 4, 1, 1, 32, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Float) }, // D32F
{ 8, 1, 1, 1, 1, 1, 0, 8, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // D0S8
// | +----------------------------------------- block width
// | | +-------------------------------------- block height
// | | | +---------------------------------- block size
// | | | | +------------------------------- min blocks x
// | | | | | +---------------------------- min blocks y
// | | | | | | +------------------------ depth bits
// | | | | | | | +--------------------- stencil bits
// | | | | | | | | +---+---+---+----- r, g, b, a bits
// | | | | | | | | r g b a +-- encoding type
// | | | | | | | | | | | | |
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // BC1
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // BC2
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // BC3
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // BC4
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // BC5
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Float) }, // BC6H
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // BC7
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ETC1
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ETC2
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ETC2A
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ETC2A1
{ 2, 8, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC12
{ 4, 4, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC14
{ 2, 8, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC12A
{ 4, 4, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC14A
{ 2, 8, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC22
{ 4, 4, 4, 8, 2, 2, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // PTC24
{ 4, 4, 4, 8, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ATC
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ATCE
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ATCI
{ 8, 4, 4, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC4x4
{ 6, 5, 5, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC5x5
{ 4, 6, 6, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC6x6
{ 4, 8, 5, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC8x5
{ 3, 8, 6, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC8x6
{ 3, 10, 5, 16, 1, 1, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // ASTC10x5
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Count) }, // Unknown
{ 1, 8, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // R1
{ 8, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 8, uint8_t(bx::EncodingType::Unorm) }, // A8
{ 8, 1, 1, 1, 1, 1, 0, 0, 8, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // R8
{ 8, 1, 1, 1, 1, 1, 0, 0, 8, 0, 0, 0, uint8_t(bx::EncodingType::Int ) }, // R8I
{ 8, 1, 1, 1, 1, 1, 0, 0, 8, 0, 0, 0, uint8_t(bx::EncodingType::Uint ) }, // R8U
{ 8, 1, 1, 1, 1, 1, 0, 0, 8, 0, 0, 0, uint8_t(bx::EncodingType::Snorm) }, // R8S
{ 16, 1, 1, 2, 1, 1, 0, 0, 16, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // R16
{ 16, 1, 1, 2, 1, 1, 0, 0, 16, 0, 0, 0, uint8_t(bx::EncodingType::Int ) }, // R16I
{ 16, 1, 1, 2, 1, 1, 0, 0, 16, 0, 0, 0, uint8_t(bx::EncodingType::Uint ) }, // R16U
{ 16, 1, 1, 2, 1, 1, 0, 0, 16, 0, 0, 0, uint8_t(bx::EncodingType::Float) }, // R16F
{ 16, 1, 1, 2, 1, 1, 0, 0, 16, 0, 0, 0, uint8_t(bx::EncodingType::Snorm) }, // R16S
{ 32, 1, 1, 4, 1, 1, 0, 0, 32, 0, 0, 0, uint8_t(bx::EncodingType::Int ) }, // R32I
{ 32, 1, 1, 4, 1, 1, 0, 0, 32, 0, 0, 0, uint8_t(bx::EncodingType::Uint ) }, // R32U
{ 32, 1, 1, 4, 1, 1, 0, 0, 32, 0, 0, 0, uint8_t(bx::EncodingType::Float) }, // R32F
{ 16, 1, 1, 2, 1, 1, 0, 0, 8, 8, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // RG8
{ 16, 1, 1, 2, 1, 1, 0, 0, 8, 8, 0, 0, uint8_t(bx::EncodingType::Int ) }, // RG8I
{ 16, 1, 1, 2, 1, 1, 0, 0, 8, 8, 0, 0, uint8_t(bx::EncodingType::Uint ) }, // RG8U
{ 16, 1, 1, 2, 1, 1, 0, 0, 8, 8, 0, 0, uint8_t(bx::EncodingType::Snorm) }, // RG8S
{ 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // RG16
{ 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, uint8_t(bx::EncodingType::Int ) }, // RG16I
{ 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, uint8_t(bx::EncodingType::Uint ) }, // RG16U
{ 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, uint8_t(bx::EncodingType::Float) }, // RG16F
{ 32, 1, 1, 4, 1, 1, 0, 0, 16, 16, 0, 0, uint8_t(bx::EncodingType::Snorm) }, // RG16S
{ 64, 1, 1, 8, 1, 1, 0, 0, 32, 32, 0, 0, uint8_t(bx::EncodingType::Int ) }, // RG32I
{ 64, 1, 1, 8, 1, 1, 0, 0, 32, 32, 0, 0, uint8_t(bx::EncodingType::Uint ) }, // RG32U
{ 64, 1, 1, 8, 1, 1, 0, 0, 32, 32, 0, 0, uint8_t(bx::EncodingType::Float) }, // RG32F
{ 24, 1, 1, 3, 1, 1, 0, 0, 8, 8, 8, 0, uint8_t(bx::EncodingType::Unorm) }, // RGB8
{ 24, 1, 1, 3, 1, 1, 0, 0, 8, 8, 8, 0, uint8_t(bx::EncodingType::Int ) }, // RGB8I
{ 24, 1, 1, 3, 1, 1, 0, 0, 8, 8, 8, 0, uint8_t(bx::EncodingType::Uint ) }, // RGB8U
{ 24, 1, 1, 3, 1, 1, 0, 0, 8, 8, 8, 0, uint8_t(bx::EncodingType::Snorm) }, // RGB8S
{ 32, 1, 1, 4, 1, 1, 0, 0, 9, 9, 9, 5, uint8_t(bx::EncodingType::Float) }, // RGB9E5F
{ 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, uint8_t(bx::EncodingType::Unorm) }, // BGRA8
{ 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, uint8_t(bx::EncodingType::Unorm) }, // RGBA8
{ 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, uint8_t(bx::EncodingType::Int ) }, // RGBA8I
{ 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, uint8_t(bx::EncodingType::Uint ) }, // RGBA8U
{ 32, 1, 1, 4, 1, 1, 0, 0, 8, 8, 8, 8, uint8_t(bx::EncodingType::Snorm) }, // RGBA8S
{ 64, 1, 1, 8, 1, 1, 0, 0, 16, 16, 16, 16, uint8_t(bx::EncodingType::Unorm) }, // RGBA16
{ 64, 1, 1, 8, 1, 1, 0, 0, 16, 16, 16, 16, uint8_t(bx::EncodingType::Int ) }, // RGBA16I
{ 64, 1, 1, 8, 1, 1, 0, 0, 16, 16, 16, 16, uint8_t(bx::EncodingType::Uint ) }, // RGBA16U
{ 64, 1, 1, 8, 1, 1, 0, 0, 16, 16, 16, 16, uint8_t(bx::EncodingType::Float) }, // RGBA16F
{ 64, 1, 1, 8, 1, 1, 0, 0, 16, 16, 16, 16, uint8_t(bx::EncodingType::Snorm) }, // RGBA16S
{ 128, 1, 1, 16, 1, 1, 0, 0, 32, 32, 32, 32, uint8_t(bx::EncodingType::Int ) }, // RGBA32I
{ 128, 1, 1, 16, 1, 1, 0, 0, 32, 32, 32, 32, uint8_t(bx::EncodingType::Uint ) }, // RGBA32U
{ 128, 1, 1, 16, 1, 1, 0, 0, 32, 32, 32, 32, uint8_t(bx::EncodingType::Float) }, // RGBA32F
{ 16, 1, 1, 2, 1, 1, 0, 0, 5, 6, 5, 0, uint8_t(bx::EncodingType::Unorm) }, // R5G6B5
{ 16, 1, 1, 2, 1, 1, 0, 0, 4, 4, 4, 4, uint8_t(bx::EncodingType::Unorm) }, // RGBA4
{ 16, 1, 1, 2, 1, 1, 0, 0, 5, 5, 5, 1, uint8_t(bx::EncodingType::Unorm) }, // RGB5A1
{ 32, 1, 1, 4, 1, 1, 0, 0, 10, 10, 10, 2, uint8_t(bx::EncodingType::Unorm) }, // RGB10A2
{ 32, 1, 1, 4, 1, 1, 0, 0, 11, 11, 10, 0, uint8_t(bx::EncodingType::Unorm) }, // RG11B10F
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Count) }, // UnknownDepth
{ 16, 1, 1, 2, 1, 1, 16, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // D16
{ 24, 1, 1, 3, 1, 1, 24, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // D24
{ 32, 1, 1, 4, 1, 1, 24, 8, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // D24S8
{ 32, 1, 1, 4, 1, 1, 32, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // D32
{ 16, 1, 1, 2, 1, 1, 16, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Float) }, // D16F
{ 24, 1, 1, 3, 1, 1, 24, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Float) }, // D24F
{ 32, 1, 1, 4, 1, 1, 32, 0, 0, 0, 0, 0, uint8_t(bx::EncodingType::Float) }, // D32F
{ 8, 1, 1, 1, 1, 1, 0, 8, 0, 0, 0, 0, uint8_t(bx::EncodingType::Unorm) }, // D0S8
};
BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_imageBlockInfo) );
@@ -119,6 +128,15 @@ namespace bimg
"PTC14A", // PTC14A
"PTC22", // PTC22
"PTC24", // PTC24
"ATC", // ATC
"ATCE", // ATCE
"ATCI", // ATCI
"ASTC4x4", // ASTC4x4
"ASTC5x5", // ASTC5x5
"ASTC6x6", // ASTC6x6
"ASTC8x5", // ASTC8x5
"ASTC8x6", // ASTC8x6
"ASTC10x5", // ASTC10x5
"<unknown>", // Unknown
"R1", // R1
"A8", // A8
@@ -271,14 +289,12 @@ namespace bimg
{
const ImageBlockInfo& blockInfo = getBlockInfo(_format);
const uint8_t bpp = blockInfo.bitsPerPixel;
const uint16_t blockSize = blockInfo.blockSize;
const uint16_t blockWidth = blockInfo.blockWidth;
const uint16_t blockHeight = blockInfo.blockHeight;
const uint16_t minBlockX = blockInfo.minBlockX;
const uint16_t minBlockY = blockInfo.minBlockY;
_width = bx::uint16_max(blockWidth * minBlockX, ( (_width + blockWidth - 1) / blockWidth)*blockWidth);
_height = bx::uint16_max(blockHeight * minBlockY, ( (_height + blockHeight - 1) / blockHeight)*blockHeight);
_depth = bx::uint16_max(1, _depth);
const uint8_t numMips = calcNumMips(_hasMips, _width, _height, _depth);
const uint32_t sides = _cubeMap ? 6 : 1;
@@ -287,18 +303,22 @@ namespace bimg
uint32_t depth = _depth;
uint32_t size = 0;
for (uint32_t lod = 0; lod < numMips; ++lod)
{
width = bx::uint32_max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth);
height = bx::uint32_max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight);
depth = bx::uint32_max(1, depth);
if (_format != TextureFormat::Unknown)
{
for (uint32_t lod = 0; lod < numMips; ++lod)
{
depth = bx::uint32_max(1, depth);
size += uint32_t(uint64_t(width*height*depth)*bpp/8 * sides);
uint16_t blocksX = bx::uint32_max(minBlockX, ((width + blockWidth - 1) / blockWidth ));
uint16_t blocksY = bx::uint32_max(minBlockY, ((height + blockHeight - 1) / blockHeight));
width >>= 1;
height >>= 1;
depth >>= 1;
}
size += blocksX * blocksY * blockSize * depth * sides;
width >>= 1;
height >>= 1;
depth >>= 1;
}
}
size *= _numLayers;
@@ -318,7 +338,7 @@ namespace bimg
return size;
}
void imageSolid(void* _dst, uint32_t _width, uint32_t _height, uint32_t _solid)
void imageSolid(void* _dst, uint32_t _width, uint32_t _height, uint32_t _solid)
{
uint32_t* dst = (uint32_t*)_dst;
for (uint32_t ii = 0, num = _width*_height; ii < num; ++ii)
@@ -852,6 +872,15 @@ namespace bimg
{ NULL, NULL }, // PTC14A
{ NULL, NULL }, // PTC22
{ NULL, NULL }, // PTC24
{ NULL, NULL }, // ATC
{ NULL, NULL }, // ATCE
{ NULL, NULL }, // ATCI
{ NULL, NULL }, // ASTC4x4
{ NULL, NULL }, // ASTC5x5
{ NULL, NULL }, // ASTC6x6
{ NULL, NULL }, // ASTC8x5
{ NULL, NULL }, // ASTC8x6
{ NULL, NULL }, // ASTC10x5
{ NULL, NULL }, // Unknown
{ NULL, NULL }, // R1
{ bx::packR8, bx::unpackR8 }, // A8
@@ -1240,6 +1269,60 @@ namespace bimg
}
}
void decodeBlockATC(uint8_t _dst[16*4], const uint8_t _src[8])
{
uint8_t colors[4*4]; // You can see from comparison with decodeBlockDXT just how little sense the ATI patent-avoiding(?) modification makes
uint32_t c0 = _src[0] | (_src[1] << 8);
uint32_t c1 = _src[2] | (_src[3] << 8);
if ((c0 & 0x8000) == 0)
{
colors[0] = bitRangeConvert( (c0>> 0)&0x1f, 5, 8);
colors[1] = bitRangeConvert( (c0>> 5)&0x1f, 5, 8);
colors[2] = bitRangeConvert( (c0>>10)&0x1f, 5, 8);
colors[12] = bitRangeConvert( (c1>> 0)&0x1f, 5, 8);
colors[13] = bitRangeConvert( (c1>> 5)&0x3f, 6, 8);
colors[14] = bitRangeConvert( (c1>>11)&0x1f, 5, 8);
colors[ 4] = (2 * colors[0] + colors[12]) / 3;
colors[ 5] = (2 * colors[1] + colors[13]) / 3;
colors[ 6] = (2 * colors[2] + colors[14]) / 3;
colors[ 8] = (colors[0] + 2 * colors[12]) / 3;
colors[ 9] = (colors[1] + 2 * colors[13]) / 3;
colors[10] = (colors[2] + 2 * colors[14]) / 3;
}
else
{
colors[ 0] = 0;
colors[ 1] = 0;
colors[ 2] = 0;
colors[ 8] = bitRangeConvert( (c0>> 0)&0x1f, 5, 8);
colors[ 9] = bitRangeConvert( (c0>> 5)&0x1f, 5, 8);
colors[10] = bitRangeConvert( (c0>>10)&0x1f, 5, 8);
colors[12] = bitRangeConvert( (c1>> 0)&0x1f, 5, 8);
colors[13] = bitRangeConvert( (c1>> 5)&0x3f, 6, 8);
colors[14] = bitRangeConvert( (c1>>11)&0x1f, 5, 8);
colors[ 4] = colors[ 8] - colors[12] / 4;
colors[ 5] = colors[ 9] - colors[13] / 4;
colors[ 6] = colors[10] - colors[14] / 4;
}
for (uint32_t ii = 0, next = 8*4; ii < 16*4; ii += 4, next += 2)
{
int idx = ( (_src[next>>3] >> (next & 7) ) & 3) * 4;
_dst[ii+0] = colors[idx+0];
_dst[ii+1] = colors[idx+1];
_dst[ii+2] = colors[idx+2];
_dst[ii+3] = colors[idx+3];
}
}
static const int32_t s_etc1Mod[8][4] =
{
{ 2, 8, -2, -8},
@@ -1940,6 +2023,21 @@ namespace bimg
#define DDS_BC5U BX_MAKEFOURCC('B', 'C', '5', 'U')
#define DDS_DX10 BX_MAKEFOURCC('D', 'X', '1', '0')
#define DDS_ETC1 BX_MAKEFOURCC('E', 'T', 'C', '1')
#define DDS_ETC2 BX_MAKEFOURCC('E', 'T', 'C', '2')
#define DDS_ET2A BX_MAKEFOURCC('E', 'T', '2', 'A')
#define DDS_PTC2 BX_MAKEFOURCC('P', 'T', 'C', '2')
#define DDS_PTC4 BX_MAKEFOURCC('P', 'T', 'C', '4')
#define DDS_ATC BX_MAKEFOURCC('A', 'T', 'C', ' ')
#define DDS_ATCE BX_MAKEFOURCC('A', 'T', 'C', 'E')
#define DDS_ATCI BX_MAKEFOURCC('A', 'T', 'C', 'I')
#define DDS_ASTC4x4 BX_MAKEFOURCC('A', 'S', '4', '4')
#define DDS_ASTC5x5 BX_MAKEFOURCC('A', 'S', '5', '5')
#define DDS_ASTC6x6 BX_MAKEFOURCC('A', 'S', '6', '6')
#define DDS_ASTC8x5 BX_MAKEFOURCC('A', 'S', '8', '5')
#define DDS_ASTC8x6 BX_MAKEFOURCC('A', 'S', '8', '6')
#define DDS_ASTC10x5 BX_MAKEFOURCC('A', 'S', ':', '5')
#define DDS_R8G8B8 20
#define DDS_A8R8G8B8 21
#define DDS_R5G6B5 23
@@ -2047,36 +2145,52 @@ namespace bimg
static const TranslateDdsFormat s_translateDdsFourccFormat[] =
{
{ DDS_DXT1, TextureFormat::BC1, false },
{ DDS_DXT2, TextureFormat::BC2, false },
{ DDS_DXT3, TextureFormat::BC2, false },
{ DDS_DXT4, TextureFormat::BC3, false },
{ DDS_DXT5, TextureFormat::BC3, false },
{ DDS_ATI1, TextureFormat::BC4, false },
{ DDS_BC4U, TextureFormat::BC4, false },
{ DDS_ATI2, TextureFormat::BC5, false },
{ DDS_BC5U, TextureFormat::BC5, false },
{ DDS_A16B16G16R16, TextureFormat::RGBA16, false },
{ DDS_A16B16G16R16F, TextureFormat::RGBA16F, false },
{ DDPF_RGB|DDPF_ALPHAPIXELS, TextureFormat::BGRA8, false },
{ DDPF_INDEXED, TextureFormat::R8, false },
{ DDPF_LUMINANCE, TextureFormat::R8, false },
{ DDPF_ALPHA, TextureFormat::R8, false },
{ DDS_R16F, TextureFormat::R16F, false },
{ DDS_R32F, TextureFormat::R32F, false },
{ DDS_A8L8, TextureFormat::RG8, false },
{ DDS_G16R16, TextureFormat::RG16, false },
{ DDS_G16R16F, TextureFormat::RG16F, false },
{ DDS_G32R32F, TextureFormat::RG32F, false },
{ DDS_R8G8B8, TextureFormat::RGB8, false },
{ DDS_A8R8G8B8, TextureFormat::BGRA8, false },
{ DDS_A16B16G16R16, TextureFormat::RGBA16, false },
{ DDS_A16B16G16R16F, TextureFormat::RGBA16F, false },
{ DDS_A32B32G32R32F, TextureFormat::RGBA32F, false },
{ DDS_R5G6B5, TextureFormat::R5G6B5, false },
{ DDS_A4R4G4B4, TextureFormat::RGBA4, false },
{ DDS_A1R5G5B5, TextureFormat::RGB5A1, false },
{ DDS_A2B10G10R10, TextureFormat::RGB10A2, false },
{ DDS_DXT1, TextureFormat::BC1, false },
{ DDS_DXT2, TextureFormat::BC2, false },
{ DDS_DXT3, TextureFormat::BC2, false },
{ DDS_DXT4, TextureFormat::BC3, false },
{ DDS_DXT5, TextureFormat::BC3, false },
{ DDS_ATI1, TextureFormat::BC4, false },
{ DDS_BC4U, TextureFormat::BC4, false },
{ DDS_ATI2, TextureFormat::BC5, false },
{ DDS_BC5U, TextureFormat::BC5, false },
{ DDS_ETC1, TextureFormat::ETC1, false },
{ DDS_ETC2, TextureFormat::ETC2, false },
{ DDS_ET2A, TextureFormat::ETC2A, false },
{ DDS_PTC2, TextureFormat::PTC12A, false },
{ DDS_PTC4, TextureFormat::PTC14A, false },
{ DDS_ATC , TextureFormat::ATC, false },
{ DDS_ATCE, TextureFormat::ATCE, false },
{ DDS_ATCI, TextureFormat::ATCI, false },
{ DDS_ASTC4x4, TextureFormat::ASTC4x4, false },
{ DDS_ASTC5x5, TextureFormat::ASTC5x5, false },
{ DDS_ASTC6x6, TextureFormat::ASTC6x6, false },
{ DDS_ASTC8x5, TextureFormat::ASTC8x5, false },
{ DDS_ASTC8x6, TextureFormat::ASTC8x6, false },
{ DDS_ASTC10x5, TextureFormat::ASTC10x5, false },
{ DDS_A16B16G16R16, TextureFormat::RGBA16, false },
{ DDS_A16B16G16R16F, TextureFormat::RGBA16F, false },
{ DDPF_RGB|DDPF_ALPHAPIXELS, TextureFormat::BGRA8, false },
{ DDPF_INDEXED, TextureFormat::R8, false },
{ DDPF_LUMINANCE, TextureFormat::R8, false },
{ DDPF_ALPHA, TextureFormat::R8, false },
{ DDS_R16F, TextureFormat::R16F, false },
{ DDS_R32F, TextureFormat::R32F, false },
{ DDS_A8L8, TextureFormat::RG8, false },
{ DDS_G16R16, TextureFormat::RG16, false },
{ DDS_G16R16F, TextureFormat::RG16F, false },
{ DDS_G32R32F, TextureFormat::RG32F, false },
{ DDS_R8G8B8, TextureFormat::RGB8, false },
{ DDS_A8R8G8B8, TextureFormat::BGRA8, false },
{ DDS_A16B16G16R16, TextureFormat::RGBA16, false },
{ DDS_A16B16G16R16F, TextureFormat::RGBA16F, false },
{ DDS_A32B32G32R32F, TextureFormat::RGBA32F, false },
{ DDS_R5G6B5, TextureFormat::R5G6B5, false },
{ DDS_A4R4G4B4, TextureFormat::RGBA4, false },
{ DDS_A1R5G5B5, TextureFormat::RGB5A1, false },
{ DDS_A2B10G10R10, TextureFormat::RGB10A2, false },
};
static const TranslateDdsFormat s_translateDxgiFormat[] =
@@ -2379,6 +2493,21 @@ namespace bimg
#define KTX_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55
#define KTX_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56
#define KTX_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57
#define KTX_ATC_RGB_AMD 0x8C92
#define KTX_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93
#define KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
#define KTX_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
#define KTX_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
#define KTX_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
#define KTX_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
#define KTX_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
#define KTX_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
#define KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
#define KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
#define KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
#define KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
#define KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
#define KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
#define KTX_A8 0x803C
#define KTX_R8 0x8229
@@ -2488,6 +2617,15 @@ namespace bimg
{ KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, KTX_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT, KTX_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, KTX_ZERO, }, // PTC14A
{ KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, KTX_ZERO, KTX_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, KTX_ZERO, }, // PTC22
{ KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, KTX_ZERO, KTX_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, KTX_ZERO, }, // PTC24
{ KTX_ATC_RGB_AMD, KTX_ZERO, KTX_ATC_RGB_AMD, KTX_ZERO, }, // ATC
{ KTX_ATC_RGBA_EXPLICIT_ALPHA_AMD, KTX_ZERO, KTX_ATC_RGBA_EXPLICIT_ALPHA_AMD, KTX_ZERO, }, // ATCE
{ KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD, KTX_ZERO, KTX_ATC_RGBA_INTERPOLATED_ALPHA_AMD, KTX_ZERO, }, // ATCI
{ KTX_COMPRESSED_RGBA_ASTC_4x4_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, KTX_COMPRESSED_RGBA_ASTC_4x4_KHR, KTX_ZERO, }, // ASTC4x4
{ KTX_COMPRESSED_RGBA_ASTC_5x5_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, KTX_COMPRESSED_RGBA_ASTC_5x5_KHR, KTX_ZERO, }, // ASTC5x5
{ KTX_COMPRESSED_RGBA_ASTC_6x6_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, KTX_COMPRESSED_RGBA_ASTC_6x6_KHR, KTX_ZERO, }, // ASTC6x6
{ KTX_COMPRESSED_RGBA_ASTC_8x5_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, KTX_COMPRESSED_RGBA_ASTC_8x5_KHR, KTX_ZERO, }, // ASTC8x5
{ KTX_COMPRESSED_RGBA_ASTC_8x6_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, KTX_COMPRESSED_RGBA_ASTC_8x6_KHR, KTX_ZERO, }, // ASTC8x6
{ KTX_COMPRESSED_RGBA_ASTC_10x5_KHR, KTX_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, KTX_COMPRESSED_RGBA_ASTC_10x5_KHR, KTX_ZERO, }, // ASTC10x5
{ KTX_ZERO, KTX_ZERO, KTX_ZERO, KTX_ZERO, }, // Unknown
{ KTX_ZERO, KTX_ZERO, KTX_ZERO, KTX_ZERO, }, // R1
{ KTX_ALPHA, KTX_ZERO, KTX_ALPHA, KTX_UNSIGNED_BYTE, }, // A8
@@ -3114,6 +3252,71 @@ namespace bimg
imageCheckerboard(_dst, _width, _height, 16, UINT32_C(0xff000000), UINT32_C(0xffffffff) );
break;
case TextureFormat::ATC:
for (uint32_t yy = 0; yy < height; ++yy)
{
for (uint32_t xx = 0; xx < width; ++xx)
{
decodeBlockATC(temp, src);
src += 8;
uint8_t* block = &dst[(yy*_dstPitch+xx*4)*4];
bx::memCopy(&block[0*_dstPitch], &temp[ 0], 16);
bx::memCopy(&block[1*_dstPitch], &temp[16], 16);
bx::memCopy(&block[2*_dstPitch], &temp[32], 16);
bx::memCopy(&block[3*_dstPitch], &temp[48], 16);
}
}
break;
case TextureFormat::ATCE:
for (uint32_t yy = 0; yy < height; ++yy)
{
for (uint32_t xx = 0; xx < width; ++xx)
{
decodeBlockDxt23A(temp+3, src);
src += 8;
decodeBlockATC(temp, src);
src += 8;
uint8_t* block = &dst[(yy*_dstPitch+xx*4)*4];
bx::memCopy(&block[0*_dstPitch], &temp[ 0], 16);
bx::memCopy(&block[1*_dstPitch], &temp[16], 16);
bx::memCopy(&block[2*_dstPitch], &temp[32], 16);
bx::memCopy(&block[3*_dstPitch], &temp[48], 16);
}
}
break;
case TextureFormat::ATCI:
for (uint32_t yy = 0; yy < height; ++yy)
{
for (uint32_t xx = 0; xx < width; ++xx)
{
decodeBlockDxt45A(temp+3, src);
src += 8;
decodeBlockATC(temp, src);
src += 8;
uint8_t* block = &dst[(yy*_dstPitch+xx*4)*4];
bx::memCopy(&block[0*_dstPitch], &temp[ 0], 16);
bx::memCopy(&block[1*_dstPitch], &temp[16], 16);
bx::memCopy(&block[2*_dstPitch], &temp[32], 16);
bx::memCopy(&block[3*_dstPitch], &temp[48], 16);
}
}
break;
case TextureFormat::ASTC4x4:
case TextureFormat::ASTC5x5:
case TextureFormat::ASTC6x6:
case TextureFormat::ASTC8x5:
case TextureFormat::ASTC8x6:
case TextureFormat::ASTC10x5:
BX_WARN(false, "ASTC decoder is not implemented.");
imageCheckerboard(_dst, _width, _height, 16, UINT32_C(0xff000000), UINT32_C(0xffffff00) );
break;
case TextureFormat::RGBA8:
{
const uint32_t srcPitch = _width * 4;
@@ -3343,29 +3546,28 @@ namespace bimg
for (uint8_t lod = 0, num = _imageContainer.m_numMips; lod < num; ++lod)
{
width = bx::uint32_max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth);
height = bx::uint32_max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight);
uint32_t sourceSize = bx::toHostEndian(*(const uint32_t*)&data[offset], _imageContainer.m_ktxLE);
offset += sizeof(uint32_t);
depth = bx::uint32_max(1, depth);
const uint32_t mipSize = width*height*depth*bpp/8;
uint32_t blocksX = bx::uint32_max(minBlockX, ((width + blockWidth - 1) / blockWidth ));
uint32_t blocksY = bx::uint32_max(minBlockY, ((height + blockHeight - 1) / blockHeight));
const uint32_t size = mipSize*numSides;
uint32_t imageSize = bx::toHostEndian(*(const uint32_t*)&data[offset], _imageContainer.m_ktxLE);
BX_CHECK(size == imageSize, "KTX: Image size mismatch %d (expected %d).", size, imageSize);
BX_UNUSED(size, imageSize);
uint32_t destSize = blocksX * blocksY * blockSize * depth;
offset += sizeof(uint32_t);
BX_CHECK(sourceSize == destSize, "KTX: Image size mismatch %d (expected %d).", sourceSize, destSize);
for (uint16_t side = 0; side < numSides; ++side)
{
if (side == _side
&& lod == _lod)
{
_mip.m_width = width;
_mip.m_height = height;
_mip.m_width = blocksX * blockWidth;
_mip.m_height = blocksY * blockHeight;
_mip.m_depth = depth;
_mip.m_blockSize = blockSize;
_mip.m_size = mipSize;
_mip.m_size = destSize;
_mip.m_data = &data[offset];
_mip.m_bpp = bpp;
_mip.m_format = format;
@@ -3373,7 +3575,7 @@ namespace bimg
return true;
}
offset += mipSize;
offset += sourceSize;
BX_CHECK(offset <= _size, "Reading past size of data buffer! (offset %d, size %d)", offset, _size);
BX_UNUSED(_size);
@@ -3394,17 +3596,18 @@ namespace bimg
for (uint8_t lod = 0, num = _imageContainer.m_numMips; lod < num; ++lod)
{
width = bx::uint32_max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth);
height = bx::uint32_max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight);
depth = bx::uint32_max(1, depth);
uint32_t size = width*height*depth*bpp/8;
uint32_t blocksX = bx::uint32_max(minBlockX, ((width + blockWidth - 1) / blockWidth ));
uint32_t blocksY = bx::uint32_max(minBlockY, ((height + blockHeight - 1) / blockHeight));
uint32_t size = blocksX * blocksY * blockSize * depth;
if (side == _side
&& lod == _lod)
{
_mip.m_width = width;
_mip.m_height = height;
_mip.m_width = blocksX * blockWidth;
_mip.m_height = blocksY * blockHeight;
_mip.m_depth = depth;
_mip.m_blockSize = blockSize;
_mip.m_size = size;