Return TEX_ALPHA_MODE_OPAQUE metadata if the reader knows it returned opaque alpha (#150)

This commit is contained in:
Chuck Walbourn 2019-10-03 14:58:14 -07:00 committed by GitHub
parent aacd3919e8
commit 7bda0c3a57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 178 additions and 93 deletions

View File

@ -427,9 +427,6 @@ namespace
if (metadata.format == DXGI_FORMAT_UNKNOWN)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
if (convFlags & CONV_FLAGS_PMALPHA)
metadata.miscFlags2 |= TEX_ALPHA_MODE_PREMULTIPLIED;
// Special flag for handling LUMINANCE legacy formats
if (flags & DDS_FLAGS_EXPAND_LUMINANCE)
{
@ -515,6 +512,16 @@ namespace
}
}
// Implicit alpha mode
if (convFlags & CONV_FLAGS_NOALPHA)
{
metadata.SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
}
else if (convFlags & CONV_FLAGS_PMALPHA)
{
metadata.SetAlphaMode(TEX_ALPHA_MODE_PREMULTIPLIED);
}
return S_OK;
}
}

View File

@ -282,6 +282,7 @@ namespace
metadata.depth = metadata.arraySize = metadata.mipLevels = 1;
metadata.format = DXGI_FORMAT_R32G32B32A32_FLOAT;
metadata.dimension = TEX_DIMENSION_TEXTURE2D;
metadata.SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
return S_OK;
}

View File

@ -159,6 +159,7 @@ namespace
case 24:
metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM;
metadata.SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
if (convFlags)
*convFlags |= CONV_FLAGS_EXPAND;
// We could use DXGI_FORMAT_B8G8R8X8_UNORM, but we prefer DXGI 1.0 formats
@ -280,6 +281,8 @@ namespace
auto sPtr = static_cast<const uint8_t*>(pSource);
const uint8_t* endPtr = sPtr + size;
bool opaquealpha = false;
switch (image->format)
{
//--------------------------------------------------------------------------- 8-bit
@ -349,7 +352,9 @@ namespace
//-------------------------------------------------------------------------- 16-bit
case DXGI_FORMAT_B5G5R5A1_UNORM:
{
bool nonzeroa = false;
uint32_t minalpha = 255;
uint32_t maxalpha = 0;
for (size_t y = 0; y < image->height; ++y)
{
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
@ -374,8 +379,11 @@ namespace
return E_FAIL;
auto t = static_cast<uint16_t>(uint32_t(*sPtr) | uint32_t(*(sPtr + 1u) << 8));
if (t & 0x8000)
nonzeroa = true;
uint32_t alpha = (t & 0x8000) ? 255 : 0;
minalpha = std::min(minalpha, alpha);
maxalpha = std::max(maxalpha, alpha);
sPtr += 2;
for (; j > 0; --j, ++x)
@ -406,8 +414,11 @@ namespace
return E_FAIL;
auto t = static_cast<uint16_t>(uint32_t(*sPtr) | uint32_t(*(sPtr + 1u) << 8));
if (t & 0x8000)
nonzeroa = true;
uint32_t alpha = (t & 0x8000) ? 255 : 0;
minalpha = std::min(minalpha, alpha);
maxalpha = std::max(maxalpha, alpha);
sPtr += 2;
*dPtr = t;
@ -421,19 +432,26 @@ namespace
}
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
if (!nonzeroa)
if (maxalpha == 0)
{
opaquealpha = true;
HRESULT hr = SetAlphaChannelToOpaque(image);
if (FAILED(hr))
return hr;
}
else if (minalpha == 255)
{
opaquealpha = true;
}
}
break;
//----------------------------------------------------------------------- 24/32-bit
case DXGI_FORMAT_R8G8B8A8_UNORM:
{
bool nonzeroa = false;
uint32_t minalpha = 255;
uint32_t maxalpha = 0;
for (size_t y = 0; y < image->height; ++y)
{
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
@ -465,7 +483,7 @@ namespace
t = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | 0xFF000000;
sPtr += 3;
nonzeroa = true;
minalpha = maxalpha = 255;
}
else
{
@ -475,10 +493,11 @@ namespace
return E_FAIL;
// BGRA -> RGBA
t = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | uint32_t(*(sPtr + 3) << 24);
uint32_t alpha = *(sPtr + 3);
t = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | uint32_t(alpha << 24);
if (*(sPtr + 3) > 0)
nonzeroa = true;
minalpha = std::min(minalpha, alpha);
maxalpha = std::max(maxalpha, alpha);
sPtr += 4;
}
@ -529,7 +548,7 @@ namespace
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | 0xFF000000;
sPtr += 3;
nonzeroa = true;
minalpha = maxalpha = 255;
}
else
{
@ -539,10 +558,11 @@ namespace
return E_FAIL;
// BGRA -> RGBA
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | uint32_t(*(sPtr + 3) << 24);
uint32_t alpha = *(sPtr + 3);
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | uint32_t(alpha << 24);
if (*(sPtr + 3) > 0)
nonzeroa = true;
minalpha = std::min(minalpha, alpha);
maxalpha = std::max(maxalpha, alpha);
sPtr += 4;
}
@ -557,12 +577,17 @@ namespace
}
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
if (!nonzeroa)
if (maxalpha == 0)
{
opaquealpha = true;
HRESULT hr = SetAlphaChannelToOpaque(image);
if (FAILED(hr))
return hr;
}
else if (minalpha == 255)
{
opaquealpha = true;
}
}
break;
@ -571,7 +596,7 @@ namespace
return E_FAIL;
}
return S_OK;
return opaquealpha ? S_FALSE : S_OK;
}
@ -606,6 +631,8 @@ namespace
auto sPtr = static_cast<const uint8_t*>(pSource);
const uint8_t* endPtr = sPtr + size;
bool opaquealpha = false;
switch (image->format)
{
//--------------------------------------------------------------------------- 8-bit
@ -637,7 +664,9 @@ namespace
//-------------------------------------------------------------------------- 16-bit
case DXGI_FORMAT_B5G5R5A1_UNORM:
{
bool nonzeroa = false;
uint32_t minalpha = 255;
uint32_t maxalpha = 0;
for (size_t y = 0; y < image->height; ++y)
{
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
@ -656,8 +685,9 @@ namespace
sPtr += 2;
*dPtr = t;
if (t & 0x8000)
nonzeroa = true;
uint32_t alpha = (t & 0x8000) ? 255 : 0;
minalpha = std::min(minalpha, alpha);
maxalpha = std::max(maxalpha, alpha);
if (convFlags & CONV_FLAGS_INVERTX)
--dPtr;
@ -667,19 +697,26 @@ namespace
}
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
if (!nonzeroa)
if (maxalpha == 0)
{
opaquealpha = true;
HRESULT hr = SetAlphaChannelToOpaque(image);
if (FAILED(hr))
return hr;
}
else if (minalpha == 255)
{
opaquealpha = true;
}
}
break;
//----------------------------------------------------------------------- 24/32-bit
case DXGI_FORMAT_R8G8B8A8_UNORM:
{
bool nonzeroa = false;
uint32_t minalpha = 255;
uint32_t maxalpha = 0;
for (size_t y = 0; y < image->height; ++y)
{
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
@ -701,7 +738,7 @@ namespace
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | 0xFF000000;
sPtr += 3;
nonzeroa = true;
minalpha = maxalpha = 255;
}
else
{
@ -711,10 +748,11 @@ namespace
return E_FAIL;
// BGRA -> RGBA
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | uint32_t(*(sPtr + 3) << 24);
uint32_t alpha = *(sPtr + 3);
*dPtr = uint32_t(*sPtr << 16) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2)) | uint32_t(alpha << 24);
if (*(sPtr + 3) > 0)
nonzeroa = true;
minalpha = std::min(minalpha, alpha);
maxalpha = std::max(maxalpha, alpha);
sPtr += 4;
}
@ -727,12 +765,17 @@ namespace
}
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
if (!nonzeroa)
if (maxalpha == 0)
{
opaquealpha = true;
HRESULT hr = SetAlphaChannelToOpaque(image);
if (FAILED(hr))
return hr;
}
else if (minalpha == 255)
{
opaquealpha = true;
}
}
break;
@ -741,7 +784,7 @@ namespace
return E_FAIL;
}
return S_OK;
return opaquealpha ? S_FALSE : S_OK;
}
@ -965,7 +1008,13 @@ HRESULT DirectX::LoadFromTGAMemory(
}
if (metadata)
{
memcpy(metadata, &mdata, sizeof(TexMetadata));
if (hr == S_FALSE)
{
metadata->SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
}
}
return S_OK;
}
@ -1051,6 +1100,8 @@ HRESULT DirectX::LoadFromTGAFile(
assert(image.GetPixels());
bool opaquealpha = false;
if (!(convFlags & (CONV_FLAGS_RLE | CONV_FLAGS_EXPAND | CONV_FLAGS_INVERTX)) && (convFlags & CONV_FLAGS_INVERTY))
{
// This case we can read directly into the image buffer in place
@ -1101,7 +1152,8 @@ HRESULT DirectX::LoadFromTGAFile(
size_t rowPitch = img->rowPitch;
// Scan for non-zero alpha channel
bool nonzeroa = false;
uint32_t minalpha = 255;
uint32_t maxalpha = 0;
for (size_t h = 0; h < img->height; ++h)
{
@ -1109,22 +1161,27 @@ HRESULT DirectX::LoadFromTGAFile(
for (size_t x = 0; x < img->width; ++x)
{
if ((*sPtr) & 0xff000000)
{
nonzeroa = true;
break;
}
uint32_t alpha = ((*sPtr & 0xFF000000) >> 24);
minalpha = std::min(minalpha, alpha);
maxalpha = std::max(maxalpha, alpha);
++sPtr;
}
if (nonzeroa)
break;
pPixels += rowPitch;
}
DWORD tflags = (!nonzeroa) ? TEXP_SCANLINE_SETALPHA : TEXP_SCANLINE_NONE;
DWORD tflags = TEXP_SCANLINE_NONE;
if (maxalpha == 0)
{
opaquealpha = true;
tflags = TEXP_SCANLINE_SETALPHA;
}
else if (minalpha == 255)
{
opaquealpha = true;
}
// Swizzle scanlines
pPixels = img->pixels;
@ -1150,7 +1207,8 @@ HRESULT DirectX::LoadFromTGAFile(
}
// Scan for non-zero alpha channel
bool nonzeroa = false;
uint32_t minalpha = 255;
uint32_t maxalpha = 0;
const uint8_t *pPixels = img->pixels;
if (!pPixels)
@ -1167,24 +1225,21 @@ HRESULT DirectX::LoadFromTGAFile(
for (size_t x = 0; x < img->width; ++x)
{
if (*sPtr & 0x8000)
{
nonzeroa = true;
break;
}
uint32_t alpha = (*sPtr & 0x8000) ? 255 : 0;
minalpha = std::min(minalpha, alpha);
maxalpha = std::max(maxalpha, alpha);
++sPtr;
}
if (nonzeroa)
break;
pPixels += rowPitch;
}
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
if (!nonzeroa)
if (maxalpha == 0)
{
opaquealpha = true;
hr = SetAlphaChannelToOpaque(img);
if (FAILED(hr))
{
@ -1192,6 +1247,10 @@ HRESULT DirectX::LoadFromTGAFile(
return hr;
}
}
else if (minalpha == 255)
{
opaquealpha = true;
}
}
break;
@ -1234,10 +1293,19 @@ HRESULT DirectX::LoadFromTGAFile(
image.Release();
return hr;
}
if (hr == S_FALSE)
opaquealpha = true;
}
if (metadata)
{
memcpy(metadata, &mdata, sizeof(TexMetadata));
if (opaquealpha)
{
metadata->SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
}
}
return S_OK;
}

View File

@ -79,8 +79,9 @@ namespace
struct WICConvert
{
GUID source;
GUID target;
GUID source;
GUID target;
TEX_ALPHA_MODE alphaMode;
};
const WICConvert g_WICConvert[] =
@ -88,54 +89,54 @@ namespace
// Directly support the formats listed in XnaTexUtil::g_WICFormats, so no conversion required
// Note target GUID in this conversion table must be one of those directly supported formats.
{ GUID_WICPixelFormat1bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat2bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat1bppIndexed, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat2bppIndexed, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat2bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM
{ GUID_WICPixelFormat4bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM
{ GUID_WICPixelFormat2bppGray, GUID_WICPixelFormat8bppGray, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8_UNORM
{ GUID_WICPixelFormat4bppGray, GUID_WICPixelFormat8bppGray, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8_UNORM
{ GUID_WICPixelFormat16bppGrayFixedPoint, GUID_WICPixelFormat16bppGrayHalf }, // DXGI_FORMAT_R16_FLOAT
{ GUID_WICPixelFormat32bppGrayFixedPoint, GUID_WICPixelFormat32bppGrayFloat }, // DXGI_FORMAT_R32_FLOAT
{ GUID_WICPixelFormat16bppGrayFixedPoint, GUID_WICPixelFormat16bppGrayHalf, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16_FLOAT
{ GUID_WICPixelFormat32bppGrayFixedPoint, GUID_WICPixelFormat32bppGrayFloat, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R32_FLOAT
{ GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat16bppBGRA5551 }, // DXGI_FORMAT_B5G5R5A1_UNORM
{ GUID_WICPixelFormat32bppBGR101010, GUID_WICPixelFormat32bppRGBA1010102 }, // DXGI_FORMAT_R10G10B10A2_UNORM
{ GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat16bppBGRA5551, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_B5G5R5A1_UNORM
{ GUID_WICPixelFormat32bppBGR101010, GUID_WICPixelFormat32bppRGBA1010102, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R10G10B10A2_UNORM
{ GUID_WICPixelFormat24bppBGR, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat24bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat32bppPBGRA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat32bppPRGBA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat24bppBGR, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat24bppRGB, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat32bppPBGRA, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat32bppPRGBA, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat48bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat48bppBGR, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat64bppBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat64bppPRGBA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat64bppPBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat48bppRGB, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat48bppBGR, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat64bppBGRA, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat64bppPRGBA, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat64bppPBGRA, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat48bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat48bppBGRFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat64bppRGBAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat64bppBGRAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat64bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat64bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat48bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat48bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat48bppBGRFixedPoint, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat64bppRGBAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat64bppBGRAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat64bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat64bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat48bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat128bppPRGBAFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat128bppRGBFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat128bppRGBAFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat32bppRGBE, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat128bppPRGBAFloat, GUID_WICPixelFormat128bppRGBAFloat, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat128bppRGBFloat, GUID_WICPixelFormat128bppRGBAFloat, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat128bppRGBAFixedPoint, GUID_WICPixelFormat128bppRGBAFloat, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat32bppRGBE, GUID_WICPixelFormat128bppRGBAFloat, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R32G32B32A32_FLOAT
{ GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_UNORM
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
{ GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat64bppPRGBAHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT
{ GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R8G8B8A8_UNORM
{ GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat64bppRGBA, TEX_ALPHA_MODE_OPAQUE }, // DXGI_FORMAT_R16G16B16A16_UNORM
{ GUID_WICPixelFormat64bppPRGBAHalf, GUID_WICPixelFormat64bppRGBAHalf, TEX_ALPHA_MODE_UNKNOWN }, // DXGI_FORMAT_R16G16B16A16_FLOAT
#endif
// We don't support n-channel formats
@ -148,11 +149,14 @@ namespace
_In_ const WICPixelFormatGUID& pixelFormat,
DWORD flags,
bool iswic2,
_Out_opt_ WICPixelFormatGUID* pConvert)
_Out_opt_ WICPixelFormatGUID* pConvert,
_Out_ TEX_ALPHA_MODE* alphaMode)
{
if (pConvert)
memset(pConvert, 0, sizeof(WICPixelFormatGUID));
*alphaMode = TEX_ALPHA_MODE_UNKNOWN;
DXGI_FORMAT format = _WICToDXGI(pixelFormat);
if (format == DXGI_FORMAT_UNKNOWN)
@ -174,6 +178,7 @@ namespace
if (pConvert)
memcpy_s(pConvert, sizeof(WICPixelFormatGUID), &GUID_WICPixelFormat128bppRGBAFloat, sizeof(GUID));
format = DXGI_FORMAT_R32G32B32A32_FLOAT;
*alphaMode = TEX_ALPHA_MODE_OPAQUE;
}
}
else
@ -187,6 +192,7 @@ namespace
format = _WICToDXGI(g_WICConvert[i].target);
assert(format != DXGI_FORMAT_UNKNOWN);
*alphaMode = g_WICConvert[i].alphaMode;
break;
}
}
@ -288,10 +294,13 @@ namespace
if (FAILED(hr))
return hr;
metadata.format = DetermineFormat(pixelFormat, flags, iswic2, pConvert);
TEX_ALPHA_MODE alphaMode;
metadata.format = DetermineFormat(pixelFormat, flags, iswic2, pConvert, &alphaMode);
if (metadata.format == DXGI_FORMAT_UNKNOWN)
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
metadata.SetAlphaMode(alphaMode);
if (!(flags & WIC_FLAGS_IGNORE_SRGB))
{
GUID containerFormat;