texturec: Added premultiplied alpha option.

This commit is contained in:
Branimir Karadžić
2018-04-12 16:38:24 -07:00
parent 1b71e2d86d
commit 6bd4ba8fdd

View File

@@ -39,6 +39,7 @@ struct Options
, normalMap(false)
, equirect(false)
, iqa(false)
, pma(false)
, sdf(false)
, alphaTest(false)
{
@@ -53,6 +54,7 @@ struct Options
"\t mips: %s\n"
"\tnormalMap: %s\n"
"\t iqa: %s\n"
"\t pma: %s\n"
"\t sdf: %s\n"
, maxSize
, edge
@@ -60,6 +62,7 @@ struct Options
, mips ? "true" : "false"
, normalMap ? "true" : "false"
, iqa ? "true" : "false"
, pma ? "true" : "false"
, sdf ? "true" : "false"
);
}
@@ -72,6 +75,7 @@ struct Options
bool normalMap;
bool equirect;
bool iqa;
bool pma;
bool sdf;
bool alphaTest;
};
@@ -96,6 +100,34 @@ void imageRgba32fNormalize(void* _dst, uint32_t _width, uint32_t _height, uint32
}
}
void imagePremultiplyAlpha(void* _inOut, uint32_t _width, uint32_t _height, uint32_t _depth, bimg::TextureFormat::Enum _format)
{
uint8_t* inOut = (uint8_t*)_inOut;
uint32_t bpp = bimg::getBitsPerPixel(_format);
uint32_t pitch = _width*bpp/8;
bimg::PackFn pack = bimg::getPack(_format);
bimg::UnpackFn unpack = bimg::getUnpack(_format);
for (uint32_t zz = 0; zz < _depth; ++zz)
{
for (uint32_t yy = 0; yy < _height; ++yy)
{
for (uint32_t xx = 0; xx < _width; ++xx)
{
const uint32_t offset = yy*pitch + xx*bpp/8;
float rgba[4];
unpack(rgba, &inOut[offset]);
rgba[0] *= rgba[3];
rgba[1] *= rgba[3];
rgba[2] *= rgba[3];
pack(&inOut[offset], rgba);
}
}
}
}
bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData, uint32_t _inputSize, const Options& _options, bx::Error* _err)
{
BX_ERROR_SCOPE(_err);
@@ -173,6 +205,7 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
&& !_options.normalMap
&& !_options.equirect
&& !_options.iqa
&& !_options.pma
;
if (needResize)
@@ -257,6 +290,7 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
void* temp = NULL;
// Normal map.
if (_options.normalMap)
{
uint32_t size = bimg::imageGetSize(
@@ -360,6 +394,7 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
BX_FREE(_allocator, rgbaDst);
}
// HDR
else if ( (!bimg::isCompressed(input->m_format) && 8 != inputBlockInfo.rBits)
|| outputFormat == bimg::TextureFormat::BC6H
|| outputFormat == bimg::TextureFormat::BC7
@@ -389,6 +424,17 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
, mip.m_format
);
if (_options.pma)
{
imagePremultiplyAlpha(
rgba32f
, dstMip.m_width
, dstMip.m_height
, dstMip.m_depth
, bimg::TextureFormat::RGBA32F
);
}
bimg::imageEncodeFromRgba32f(_allocator
, dstData
, rgba32f
@@ -421,6 +467,17 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
, rgba32f
);
if (_options.pma)
{
imagePremultiplyAlpha(
rgba32f
, dstMip.m_width
, dstMip.m_height
, dstMip.m_depth
, bimg::TextureFormat::RGBA32F
);
}
bimg::imageGetRawData(*output, side, lod, output->m_data, output->m_size, dstMip);
dstData = const_cast<uint8_t*>(dstMip.m_data);
@@ -447,6 +504,7 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
BX_FREE(_allocator, rgbaDst);
}
// SDF
else if (_options.sdf)
{
uint32_t size = bimg::imageGetSize(
@@ -484,6 +542,7 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
, rgba
);
}
// RGBA8
else
{
uint32_t size = bimg::imageGetSize(
@@ -526,8 +585,20 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
bx::memCopy(ref, rgba, size);
}
if (_options.pma)
{
imagePremultiplyAlpha(
rgba
, dstMip.m_width
, dstMip.m_height
, dstMip.m_depth
, bimg::TextureFormat::RGBA8
);
}
bimg::imageGetRawData(*output, side, 0, output->m_data, output->m_size, dstMip);
dstData = const_cast<uint8_t*>(dstMip.m_data);
bimg::imageEncodeFromRgba8(dstData
, rgba
, dstMip.m_width
@@ -561,6 +632,17 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
);
}
if (_options.pma)
{
imagePremultiplyAlpha(
rgba
, dstMip.m_width
, dstMip.m_height
, dstMip.m_depth
, bimg::TextureFormat::RGBA8
);
}
bimg::imageGetRawData(*output, side, lod, output->m_data, output->m_size, dstMip);
dstData = const_cast<uint8_t*>(dstMip.m_data);
@@ -667,6 +749,7 @@ void help(const char* _error = NULL, bool _showHelp = true)
" --sdf <edge> Compute SDF texture.\n"
" --ref <alpha> Alpha reference value.\n"
" --iqa Image Quality Assessment\n"
" --pma Premultiply alpha into RGB channel.\n"
" --max <max size> Maximum width/height (image will be scaled down and\n"
" aspect ratio will be preserved.\n"
" --as <extension> Save as.\n"
@@ -765,6 +848,7 @@ int main(int _argc, const char* _argv[])
options.normalMap = cmdLine.hasArg('n', "normalmap");
options.equirect = cmdLine.hasArg("equirect");
options.iqa = cmdLine.hasArg("iqa");
options.pma = cmdLine.hasArg("pma");
const char* maxSize = cmdLine.findOption("max");
if (NULL != maxSize)