From 5de76c05a3929004caacb1eb55b9a48fad99001c Mon Sep 17 00:00:00 2001 From: NPatch Date: Sat, 16 May 2020 18:08:21 +0300 Subject: [PATCH] LodePNG and EXR parsers now set ImageContainer.m_hasAlpha. hasAlpha field added in bimg::TextureInfo and bimg::imageGetSize. --- include/bimg/bimg.h | 2 ++ src/image.cpp | 3 +- src/image_decode.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/include/bimg/bimg.h b/include/bimg/bimg.h index 7fe8a75..ef3a744 100644 --- a/include/bimg/bimg.h +++ b/include/bimg/bimg.h @@ -174,6 +174,7 @@ namespace bimg uint8_t numMips; //!< Number of MIP maps. uint8_t bitsPerPixel; //!< Format bits per pixel. bool cubeMap; //!< Texture is cubemap. + bool hasAlpha; //!< Texture utilizes alpha channel. }; struct ImageContainer @@ -273,6 +274,7 @@ namespace bimg , bool _hasMips , uint16_t _numLayers , TextureFormat::Enum _format + , bool _hasAlpha = false ); /// diff --git a/src/image.cpp b/src/image.cpp index f9f0b89..b39cf00 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -294,7 +294,7 @@ namespace bimg return numMips; } - uint32_t imageGetSize(TextureInfo* _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, bool _hasMips, uint16_t _numLayers, TextureFormat::Enum _format) + uint32_t imageGetSize(TextureInfo* _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, bool _hasMips, uint16_t _numLayers, TextureFormat::Enum _format, bool _hasAlpha) { const ImageBlockInfo& blockInfo = getBlockInfo(_format); const uint8_t bpp = blockInfo.bitsPerPixel; @@ -341,6 +341,7 @@ namespace bimg _info->cubeMap = _cubeMap; _info->storageSize = size; _info->bitsPerPixel = bpp; + _info->hasAlpha = _hasAlpha; } return size; diff --git a/src/image_decode.cpp b/src/image_decode.cpp index 3e4ebe6..75ab35d 100644 --- a/src/image_decode.cpp +++ b/src/image_decode.cpp @@ -303,6 +303,75 @@ namespace bimg bx::memCopy( (uint8_t*)output->m_data + ii*4, state.info_raw.palette + data[ii]*4, 4); } } + + switch (state.info_raw.colortype) //Check for alpha values + { + case LCT_GREY: + case LCT_RGB: + break; + + case LCT_GREY_ALPHA: + if (8 == state.info_raw.bitdepth) + { + for (uint32_t ii = 0, num = width * height; ii < num; ++ii) + { + const uint8_t* rgba = (uint8_t*)data + ii * 2; + bool has_alpha = rgba[1] < UINT8_MAX; + if (has_alpha) + { + output->m_hasAlpha = has_alpha; + break; + } + } + } + else if(16 == state.info_raw.bitdepth) + { + for (uint32_t ii = 0, num = width * height; ii < num; ++ii) + { + const uint16_t* rgba = (uint16_t*)data + ii * 2; + bool has_alpha = rgba[1] < UINT16_MAX; + if (has_alpha) + { + output->m_hasAlpha = has_alpha; + break; + } + } + } + break; + + case LCT_RGBA: + if (8 == state.info_raw.bitdepth) + { + for (uint32_t ii = 0, num = width * height; ii < num; ++ii) + { + const uint8_t* dst = (uint8_t*)output->m_data + ii * 4; + bool has_alpha = dst[3] < UINT8_MAX; + if (has_alpha) + { + output->m_hasAlpha = has_alpha; + break; + } + } + } + else if (16 == state.info_raw.bitdepth) + { + for (uint32_t ii = 0, num = width * height; ii < num; ++ii) + { + const uint16_t* dst = (uint16_t*)output->m_data + ii * 4; + bool has_alpha = dst[3] < UINT16_MAX; + if (has_alpha) + { + output->m_hasAlpha = has_alpha; + break; + } + } + } + break; + + case LCT_PALETTE: + output->m_hasAlpha = lodepng_has_palette_alpha(&state.info_raw); + break; + } } else { @@ -331,6 +400,8 @@ namespace bimg uint32_t width = 0; uint32_t height = 0; + bool hasAlpha = false; + uint8_t* data = NULL; const char* err = NULL; EXRHeader exrHeader; @@ -431,6 +502,8 @@ namespace bimg }; bx::memCopy(&data[ii * bytesPerPixel], rgba, bytesPerPixel); + hasAlpha |= (hasAlpha || rgba[3] < 1.0f); + srcR += stepR; srcG += stepG; srcB += stepB; @@ -457,6 +530,8 @@ namespace bimg }; bx::memCopy(&data[ii * bytesPerPixel], rgba, bytesPerPixel); + hasAlpha |= (hasAlpha || rgba[3] < UINT16_MAX); + srcR += stepR; srcG += stepG; srcB += stepB; @@ -512,8 +587,10 @@ namespace bimg , data ); BX_FREE(_allocator, data); + output->m_hasAlpha = hasAlpha; } + return output; }