Browse Source

Merge branch 'atc_and_astc_support' into master

Andrew Willmott 7 năm trước cách đây
mục cha
commit
1e49b8a6c8
2 tập tin đã thay đổi với 361 bổ sung147 xóa
  1. 9 0
      include/bimg/bimg.h
  2. 352 147
      src/image.cpp

+ 9 - 0
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.
 

+ 352 - 147
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>",  // 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;