From 60d8bd454cf3bdc2fa48aff6c5803a44c4bf6932 Mon Sep 17 00:00:00 2001 From: Xi Ma Chen Date: Thu, 23 Apr 2026 13:54:13 -0700 Subject: [PATCH] Fix mip calculation for compressed formats. (#94) --- src/image.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/image.cpp b/src/image.cpp index 92632c7..df4276c 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -334,8 +334,8 @@ namespace bimg const uint16_t minBlockY = blockInfo.minBlockY; const uint8_t blockSize = blockInfo.blockSize; - _width = bx::max(blockWidth * minBlockX, ( (_width + blockWidth - 1) / blockWidth)*blockWidth); - _height = bx::max(blockHeight * minBlockY, ( (_height + blockHeight - 1) / blockHeight)*blockHeight); + _width = bx::max(1, _width); + _height = bx::max(1, _height); _depth = bx::max(1, _depth); const uint8_t numMips = calcNumMips(_hasMips, _width, _height, _depth); const uint32_t sides = _cubeMap ? 6 : 1; @@ -347,11 +347,11 @@ namespace bimg for (uint32_t lod = 0; lod < numMips; ++lod) { - width = bx::max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth); - height = bx::max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight); + uint32_t mipMidth = bx::max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth); + uint32_t mipHeight = bx::max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight); depth = bx::max(1, depth); - size += uint32_t(uint64_t(width/blockWidth * height/blockHeight * depth)*blockSize * sides); + size += uint32_t(uint64_t(mipMidth/blockWidth * mipHeight/blockHeight * depth)*blockSize * sides); width >>= 1; height >>= 1; @@ -5324,11 +5324,11 @@ namespace bimg for (uint8_t lod = 0, num = _imageContainer.m_numMips; lod < num; ++lod) { - width = bx::max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth); - height = bx::max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight); + uint32_t mipWidth = bx::max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth); + uint32_t mipHeight = bx::max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight); depth = bx::max(1, depth); - const uint32_t mipSize = width/blockWidth * height/blockHeight * depth * blockSize; + const uint32_t mipSize = mipWidth/blockWidth * mipHeight/blockHeight * depth * blockSize; if (_imageContainer.m_ktx) { @@ -5347,8 +5347,8 @@ namespace bimg if (side == _side && lod == _lod) { - _mip.m_width = width; - _mip.m_height = height; + _mip.m_width = mipWidth; + _mip.m_height = mipHeight; _mip.m_depth = depth; _mip.m_blockSize = blockSize; _mip.m_size = mipSize; @@ -5381,17 +5381,17 @@ namespace bimg { BX_ASSERT(offset <= _size, "Reading past size of data buffer! (offset %d, size %d)", offset, _size); - width = bx::max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth); - height = bx::max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight); + uint32_t mipWidth = bx::max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth); + uint32_t mipHeight = bx::max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight); depth = bx::max(1, depth); - uint32_t mipSize = width/blockWidth * height/blockHeight * depth * blockSize; + uint32_t mipSize = mipWidth/blockWidth * mipHeight/blockHeight * depth * blockSize; if (side == _side && lod == _lod) { - _mip.m_width = width; - _mip.m_height = height; + _mip.m_width = mipWidth; + _mip.m_height = mipHeight; _mip.m_depth = depth; _mip.m_blockSize = blockSize; _mip.m_size = mipSize; @@ -6005,11 +6005,11 @@ namespace bimg for (uint8_t lod = 0; lod < _numMips && _err->isOk(); ++lod) { - width = bx::max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth); - height = bx::max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight); + uint32_t mipWidth = bx::max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth); + uint32_t mipHeight = bx::max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight); depth = bx::max(1, depth); - const uint32_t mipSize = width/blockWidth * height/blockHeight * depth * blockSize; + const uint32_t mipSize = mipWidth/blockWidth * mipHeight/blockHeight * depth * blockSize; const uint32_t size = numSides == 6 && numLayers == 1 ? mipSize : mipSize * numSides * numLayers; total += bx::write(_writer, size, _err);