diff --git a/include/bimg/bimg.h b/include/bimg/bimg.h index 8f62b74..b35f7ef 100644 --- a/include/bimg/bimg.h +++ b/include/bimg/bimg.h @@ -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. diff --git a/src/image.cpp b/src/image.cpp index 3afcba4..12164e1 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -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 "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 @@ -2238,6 +2267,62 @@ namespace bimg } } + // BC6H, BC7 + // + 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 }, @@ -2938,6 +3023,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 @@ -3045,36 +3145,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[] = @@ -3377,6 +3493,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 @@ -3486,6 +3617,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 @@ -4146,6 +4286,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; @@ -4400,29 +4605,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; @@ -4430,7 +4634,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); @@ -4451,17 +4655,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;