|
|
@@ -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;
|
|
|
};
|
|
|
@@ -88,14 +92,42 @@ void imageRgba32fNormalize(void* _dst, uint32_t _width, uint32_t _height, uint32
|
|
|
{
|
|
|
float xyz[3];
|
|
|
|
|
|
- xyz[0] = rgba[0];
|
|
|
- xyz[1] = rgba[1];
|
|
|
- xyz[2] = rgba[2];
|
|
|
+ xyz[0] = rgba[0];
|
|
|
+ xyz[1] = rgba[1];
|
|
|
+ xyz[2] = rgba[2];
|
|
|
bx::vec3Norm( (float*)dst, xyz);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+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)
|