From 886ba55a25db213719c96116f9eabb188b946571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Tue, 21 Nov 2017 17:39:36 -0800 Subject: [PATCH] texturec: Allow pass thru texture to change format. --- include/bimg/encode.h | 22 ++++++++++ src/image.cpp | 14 +++--- src/image_encode.cpp | 88 +++++++++++++++++++++++++++++++++++++ tools/texturec/texturec.cpp | 12 ++++- 4 files changed, 127 insertions(+), 9 deletions(-) diff --git a/include/bimg/encode.h b/include/bimg/encode.h index 9deda53..3c6d4c6 100644 --- a/include/bimg/encode.h +++ b/include/bimg/encode.h @@ -47,6 +47,28 @@ namespace bimg , bx::Error* _err = NULL ); + /// + void imageEncode( + bx::AllocatorI* _allocator + , void* _dst + , const void* _src + , TextureFormat::Enum _srcFormat + , uint32_t _width + , uint32_t _height + , uint32_t _depth + , TextureFormat::Enum _dstFormat + , Quality::Enum _quality + , bx::Error* _err + ); + + /// + ImageContainer* imageEncode( + bx::AllocatorI* _allocator + , TextureFormat::Enum _dstFormat + , Quality::Enum _quality + , const ImageContainer& _input + ); + /// void imageRgba32f11to01( void* _dst diff --git a/src/image.cpp b/src/image.cpp index 6ba9d0a..d76e824 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -786,7 +786,7 @@ namespace bimg { bx::packRgba4, bx::unpackRgba4 }, // RGBA4 { bx::packRgb5a1, bx::unpackRgb5a1 }, // RGB5A1 { bx::packRgb10A2, bx::unpackRgb10A2 }, // RGB10A2 - { bx::packRG11B10F, bx::unpackRG11B10F }, // RG11B10F + { bx::packRG11B10F, bx::unpackRG11B10F }, // RG11B10F { NULL, NULL }, // UnknownDepth { bx::packR16, bx::unpackR16 }, // D16 { bx::packR24, bx::unpackR24 }, // D24 @@ -3089,17 +3089,17 @@ namespace bimg } } - void imageDecodeToRgba32f(bx::AllocatorI* _allocator, void* _dst, const void* _src, uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _dstPitch, TextureFormat::Enum _format) + void imageDecodeToRgba32f(bx::AllocatorI* _allocator, void* _dst, const void* _src, uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _dstPitch, TextureFormat::Enum _srcFormat) { const uint8_t* src = (const uint8_t*)_src; uint8_t* dst = (uint8_t*)_dst; - const uint32_t srcBpp = s_imageBlockInfo[_format].bitsPerPixel; + const uint32_t srcBpp = s_imageBlockInfo[_srcFormat].bitsPerPixel; const uint32_t srcPitch = _width*srcBpp/8; for (uint32_t zz = 0; zz < _depth; ++zz, src += _height*srcPitch, dst += _height*_dstPitch) { - switch (_format) + switch (_srcFormat) { case TextureFormat::BC5: { @@ -3142,17 +3142,17 @@ namespace bimg break; default: - if (isCompressed(_format) ) + if (isCompressed(_srcFormat) ) { uint32_t size = imageGetSize(NULL, uint16_t(_width), uint16_t(_height), 0, false, false, 1, TextureFormat::RGBA8); void* temp = BX_ALLOC(_allocator, size); - imageDecodeToRgba8(temp, src, _width, _height, _width*4, _format); + imageDecodeToRgba8(temp, src, _width, _height, _width*4, _srcFormat); imageRgba8ToRgba32f(dst, _width, _height, _width*4, temp); BX_FREE(_allocator, temp); } else { - imageConvert(dst, TextureFormat::RGBA32F, src, _format, _width, _height, 1, srcPitch); + imageConvert(dst, TextureFormat::RGBA32F, src, _srcFormat, _width, _height, 1, srcPitch); } break; } diff --git a/src/image_encode.cpp b/src/image_encode.cpp index 4f80d66..433cc2b 100644 --- a/src/image_encode.cpp +++ b/src/image_encode.cpp @@ -196,6 +196,94 @@ namespace bimg } } + void imageEncode(bx::AllocatorI* _allocator, void* _dst, const void* _src, TextureFormat::Enum _srcFormat, uint32_t _width, uint32_t _height, uint32_t _depth, TextureFormat::Enum _dstFormat, Quality::Enum _quality, bx::Error* _err) + { + switch (_dstFormat) + { + case bimg::TextureFormat::BC1: + case bimg::TextureFormat::BC2: + case bimg::TextureFormat::BC3: + case bimg::TextureFormat::BC4: + case bimg::TextureFormat::BC5: + case bimg::TextureFormat::ETC1: + case bimg::TextureFormat::ETC2: + case bimg::TextureFormat::PTC14: + case bimg::TextureFormat::PTC14A: + { + uint8_t* temp = (uint8_t*)BX_ALLOC(_allocator, _width*_height*_depth*4); + imageDecodeToRgba8(temp, _src, _width, _height, _width*4, _srcFormat); + imageEncodeFromRgba8(_dst, temp, _width, _height, _depth, _dstFormat, _quality, _err); + BX_FREE(_allocator, temp); + } + break; + + case bimg::TextureFormat::BC6H: + case bimg::TextureFormat::BC7: + { + uint8_t* temp = (uint8_t*)BX_ALLOC(_allocator, _width*_height*_depth*16); + imageDecodeToRgba32f(_allocator, temp, _src, _width, _height, _depth, _width*16, _srcFormat); + imageEncodeFromRgba32f(_allocator, _dst, temp, _width, _height, _depth, _dstFormat, _quality, _err); + BX_FREE(_allocator, temp); + } + break; + + default: + BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!"); + break; + } + } + + ImageContainer* imageEncode(bx::AllocatorI* _allocator, TextureFormat::Enum _dstFormat, Quality::Enum _quality, const ImageContainer& _input) + { + ImageContainer* output = imageAlloc(_allocator + , _dstFormat + , uint16_t(_input.m_width) + , uint16_t(_input.m_height) + , uint16_t(_input.m_depth) + , _input.m_numLayers + , _input.m_cubeMap + , 1 < _input.m_numMips + ); + + const uint16_t numSides = _input.m_numLayers * (_input.m_cubeMap ? 6 : 1); + + bx::Error err; + + for (uint16_t side = 0; side < numSides && err.isOk(); ++side) + { + for (uint8_t lod = 0, num = _input.m_numMips; lod < num && err.isOk(); ++lod) + { + ImageMip mip; + if (imageGetRawData(_input, side, lod, _input.m_data, _input.m_size, mip) ) + { + ImageMip dstMip; + imageGetRawData(*output, side, lod, output->m_data, output->m_size, dstMip); + uint8_t* dstData = const_cast(dstMip.m_data); + + imageEncode(_allocator + , dstData + , mip.m_data + , mip.m_format + , mip.m_width + , mip.m_height + , mip.m_depth + , _dstFormat + , _quality + , &err + ); + } + } + } + + if (err.isOk() ) + { + return output; + } + + imageFree(output); + return NULL; + } + void imageRgba32f11to01(void* _dst, uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _pitch, const void* _src) { const uint8_t* src = (const uint8_t*)_src; diff --git a/tools/texturec/texturec.cpp b/tools/texturec/texturec.cpp index 3ac699c..d120391 100644 --- a/tools/texturec/texturec.cpp +++ b/tools/texturec/texturec.cpp @@ -148,7 +148,6 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData ; const bool passThru = true - && inputFormat == outputFormat && !needResize && (1 < input->m_numMips) == _options.mips && !_options.sdf @@ -183,7 +182,16 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData if (passThru) { - output = bimg::imageConvert(_allocator, outputFormat, *input); + if (inputFormat != outputFormat + && bimg::isCompressed(outputFormat) ) + { + output = bimg::imageEncode(_allocator, outputFormat, _options.quality, *input); + } + else + { + output = bimg::imageConvert(_allocator, outputFormat, *input); + } + bimg::imageFree(input); return output; }