diff --git a/src/image.cpp b/src/image.cpp index 91408eef4..df1f36a3e 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -836,9 +836,82 @@ namespace bgfx bool imageConvert(void* _dst, TextureFormat::Enum _dstFormat, const void* _src, TextureFormat::Enum _srcFormat, uint32_t _width, uint32_t _height) { const uint32_t srcBpp = s_imageBlockInfo[_srcFormat].bitsPerPixel; + + if (_dstFormat == _srcFormat) + { + bx::memCopy(_dst, _src, _width*_height*srcBpp/8); + return true; + } + return imageConvert(_dst, _dstFormat, _src, _srcFormat, _width, _height, _width*srcBpp/8); } + ImageContainer* imageConvert(bx::AllocatorI* _allocator, TextureFormat::Enum _dstFormat, const ImageContainer& _input) + { + ImageContainer* output = imageAlloc(_allocator + , _dstFormat + , _input.m_width + , _input.m_height + , _input.m_depth + , _input.m_numLayers + , _input.m_cubeMap + , 1 < _input.m_numMips + ); + + const uint8_t bpp = getBitsPerPixel(_dstFormat); + const uint16_t numSides = _input.m_numLayers * (_input.m_cubeMap ? 6 : 1); + + uint8_t* dst = (uint8_t*)output->m_data ; + for (uint16_t side = 0; side < numSides; ++side) + { + for (uint8_t lod = 0, num = _input.m_numMips; lod < num; ++lod) + { + ImageMip mip; + if (imageGetRawData(_input, side, lod, _input.m_data, _input.m_size, mip) ) + { + bool ok = imageConvert(dst + , _dstFormat + , mip.m_data + , mip.m_format + , mip.m_width + , mip.m_height + ); + BX_CHECK(ok, "Conversion from %s to %s failed!" + , getName(_input.m_format) + , getName(output->m_format) + ); + BX_UNUSED(ok); + + dst += mip.m_width*mip.m_height*bpp/8; + } + } + } + + return output; + } + + ImageContainer* imageParseBgfx(bx::AllocatorI* _allocator, const void* _src, uint32_t _size) + { + ImageContainer imageContainer; + if (!imageParse(imageContainer, _src, _size) ) + { + return NULL; + } + + ImageContainer* output = imageAlloc(_allocator + , imageContainer.m_format + , imageContainer.m_width + , imageContainer.m_height + , imageContainer.m_depth + , imageContainer.m_numLayers + , imageContainer.m_cubeMap + , 1 < imageContainer.m_numMips + , _src + ); + + return output; + } + uint8_t bitRangeConvert(uint32_t _in, uint32_t _from, uint32_t _to) { using namespace bx; @@ -1623,7 +1696,7 @@ namespace bgfx } } - ImageContainer* imageAlloc(bx::AllocatorI* _allocator, TextureFormat::Enum _format, uint16_t _width, uint16_t _height, uint16_t _depth, uint16_t _numLayers, bool _cubeMap, bool _hasMips) + ImageContainer* imageAlloc(bx::AllocatorI* _allocator, TextureFormat::Enum _format, uint16_t _width, uint16_t _height, uint16_t _depth, uint16_t _numLayers, bool _cubeMap, bool _hasMips, const void* _data) { const ImageBlockInfo& blockInfo = getBlockInfo(_format); const uint16_t blockWidth = blockInfo.blockWidth; @@ -1639,10 +1712,10 @@ namespace bgfx const uint8_t numMips = _hasMips ? imageGetNumMips(_format, _width, _height) : 1; uint32_t size = imageGetSize(NULL, _width, _height, _depth, _cubeMap, _hasMips, _numLayers, _format); - ImageContainer* imageContainer = (ImageContainer*)BX_ALLOC(_allocator, size + sizeof(ImageContainer) ); + ImageContainer* imageContainer = (ImageContainer*)BX_ALLOC(_allocator, (NULL != _data ? 0 : size) + sizeof(ImageContainer) ); imageContainer->m_allocator = _allocator; - imageContainer->m_data = imageContainer + 1; + imageContainer->m_data = NULL != _data ? const_cast(_data) : imageContainer + 1; imageContainer->m_format = _format; imageContainer->m_size = size; imageContainer->m_offset = 0; diff --git a/src/image.h b/src/image.h index 282e5264a..ef05a1f2b 100644 --- a/src/image.h +++ b/src/image.h @@ -138,13 +138,45 @@ namespace bgfx bool imageConvert(TextureFormat::Enum _dstFormat, TextureFormat::Enum _srcFormat); /// - void imageConvert(void* _dst, uint32_t _bpp, bx::PackFn _pack, const void* _src, bx::UnpackFn _unpack, uint32_t _size); + void imageConvert( + void* _dst + , uint32_t _bpp + , bx::PackFn _pack + , const void* _src + , bx::UnpackFn _unpack + , uint32_t _size + ); /// - void imageConvert(void* _dst, uint32_t _dstBpp, bx::PackFn _pack, const void* _src, uint32_t _srcBpp, bx::UnpackFn _unpack, uint32_t _width, uint32_t _height, uint32_t _srcPitch); + void imageConvert( + void* _dst + , uint32_t _dstBpp + , bx::PackFn _pack + , const void* _src + , uint32_t _srcBpp + , bx::UnpackFn _unpack + , uint32_t _width + , uint32_t _height + , uint32_t _srcPitch + ); /// - bool imageConvert(void* _dst, TextureFormat::Enum _dstFormat, const void* _src, TextureFormat::Enum _srcFormat, uint32_t _width, uint32_t _height); + bool imageConvert( + void* _dst + , TextureFormat::Enum _dstFormat + , const void* _src + , TextureFormat::Enum _srcFormat + , uint32_t _width + , uint32_t _height + ); + + /// + ImageContainer* imageConvert( + bx::AllocatorI* _allocator + , TextureFormat::Enum _dstFormat + , const void* _src + , uint32_t _size + ); /// ImageContainer* imageAlloc( @@ -156,19 +188,45 @@ namespace bgfx , uint16_t _numLayers , bool _cubeMap , bool _hasMips + , const void* _data = NULL ); /// void imageFree(ImageContainer* _imageContainer); /// - void imageWriteTga(bx::WriterI* _writer, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, bool _grayscale, bool _yflip, bx::Error* _err = NULL); + void imageWriteTga( + bx::WriterI* _writer + , uint32_t _width + , uint32_t _height + , uint32_t _pitch + , const void* _src + , bool _grayscale + , bool _yflip + , bx::Error* _err = NULL + ); /// - void imageWriteKtx(bx::WriterI* _writer, TextureFormat::Enum _format, bool _cubeMap, uint32_t _width, uint32_t _height, uint32_t _depth, uint8_t _numMips, const void* _src, bx::Error* _err = NULL); + void imageWriteKtx( + bx::WriterI* _writer + , TextureFormat::Enum _format + , bool _cubeMap + , uint32_t _width + , uint32_t _height + , uint32_t _depth + , uint8_t _numMips + , const void* _src + , bx::Error* _err = NULL + ); /// - void imageWriteKtx(bx::WriterI* _writer, ImageContainer& _imageContainer, const void* _data, uint32_t _size, bx::Error* _err = NULL); + void imageWriteKtx( + bx::WriterI* _writer + , ImageContainer& _imageContainer + , const void* _data + , uint32_t _size + , bx::Error* _err = NULL + ); /// bool imageParse(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader);