Added TGA_FLAGS for TGA reader (#197)
This commit is contained in:
Родитель
9dbde8de5d
Коммит
80f38c3903
|
@ -192,6 +192,17 @@ namespace DirectX
|
|||
// Enables the loader to read large dimension .dds files (i.e. greater than known hardware requirements)
|
||||
};
|
||||
|
||||
enum TGA_FLAGS : unsigned long
|
||||
{
|
||||
TGA_FLAGS_NONE = 0x0,
|
||||
|
||||
TGA_FLAGS_BGR = 0x1,
|
||||
// 24bpp files are returned as BGRX; 32bpp files are returned as BGRA
|
||||
|
||||
TGA_FLAGS_ALLOW_ALL_ZERO_ALPHA = 0x2,
|
||||
// If the loaded image has an all zero alpha channel, normally we assume it should be opaque. This flag leaves it alone.
|
||||
};
|
||||
|
||||
enum WIC_FLAGS : unsigned long
|
||||
{
|
||||
WIC_FLAGS_NONE = 0x0,
|
||||
|
@ -254,9 +265,11 @@ namespace DirectX
|
|||
|
||||
HRESULT __cdecl GetMetadataFromTGAMemory(
|
||||
_In_reads_bytes_(size) const void* pSource, _In_ size_t size,
|
||||
_In_ TGA_FLAGS flags,
|
||||
_Out_ TexMetadata& metadata) noexcept;
|
||||
HRESULT __cdecl GetMetadataFromTGAFile(
|
||||
_In_z_ const wchar_t* szFile,
|
||||
_In_ TGA_FLAGS flags,
|
||||
_Out_ TexMetadata& metadata) noexcept;
|
||||
|
||||
HRESULT __cdecl GetMetadataFromWICMemory(
|
||||
|
@ -271,6 +284,14 @@ namespace DirectX
|
|||
_Out_ TexMetadata& metadata,
|
||||
_In_opt_ std::function<void __cdecl(IWICMetadataQueryReader*)> getMQR = nullptr);
|
||||
|
||||
// Compatability helpers
|
||||
HRESULT __cdecl GetMetadataFromTGAMemory(
|
||||
_In_reads_bytes_(size) const void* pSource, _In_ size_t size,
|
||||
_Out_ TexMetadata& metadata) noexcept;
|
||||
HRESULT __cdecl GetMetadataFromTGAFile(
|
||||
_In_z_ const wchar_t* szFile,
|
||||
_Out_ TexMetadata& metadata) noexcept;
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Bitmap image container
|
||||
struct Image
|
||||
|
@ -401,13 +422,19 @@ namespace DirectX
|
|||
// TGA operations
|
||||
HRESULT __cdecl LoadFromTGAMemory(
|
||||
_In_reads_bytes_(size) const void* pSource, _In_ size_t size,
|
||||
_In_ TGA_FLAGS flags,
|
||||
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image) noexcept;
|
||||
HRESULT __cdecl LoadFromTGAFile(
|
||||
_In_z_ const wchar_t* szFile,
|
||||
_In_ TGA_FLAGS flags,
|
||||
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image) noexcept;
|
||||
|
||||
HRESULT __cdecl SaveToTGAMemory(_In_ const Image& image, _Out_ Blob& blob, _In_opt_ const TexMetadata* metadata = nullptr) noexcept;
|
||||
HRESULT __cdecl SaveToTGAFile(_In_ const Image& image, _In_z_ const wchar_t* szFile, _In_opt_ const TexMetadata* metadata = nullptr) noexcept;
|
||||
HRESULT __cdecl SaveToTGAMemory(_In_ const Image& image,
|
||||
_In_ TGA_FLAGS flags,
|
||||
_Out_ Blob& blob, _In_opt_ const TexMetadata* metadata = nullptr) noexcept;
|
||||
HRESULT __cdecl SaveToTGAFile(_In_ const Image& image,
|
||||
_In_ TGA_FLAGS flags,
|
||||
_In_z_ const wchar_t* szFile, _In_opt_ const TexMetadata* metadata = nullptr) noexcept;
|
||||
|
||||
// WIC operations
|
||||
HRESULT __cdecl LoadFromWICMemory(
|
||||
|
@ -440,6 +467,17 @@ namespace DirectX
|
|||
_In_z_ const wchar_t* szFile, _In_opt_ const GUID* targetFormat = nullptr,
|
||||
_In_opt_ std::function<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr);
|
||||
|
||||
// Compatability helpers
|
||||
HRESULT __cdecl LoadFromTGAMemory(
|
||||
_In_reads_bytes_(size) const void* pSource, _In_ size_t size,
|
||||
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image) noexcept;
|
||||
HRESULT __cdecl LoadFromTGAFile(
|
||||
_In_z_ const wchar_t* szFile,
|
||||
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image) noexcept;
|
||||
|
||||
HRESULT __cdecl SaveToTGAMemory(_In_ const Image& image, _Out_ Blob& blob, _In_opt_ const TexMetadata* metadata = nullptr) noexcept;
|
||||
HRESULT __cdecl SaveToTGAFile(_In_ const Image& image, _In_z_ const wchar_t* szFile, _In_opt_ const TexMetadata* metadata = nullptr) noexcept;
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// Texture conversion, resizing, mipmap generation, and block compression
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
//=====================================================================================
|
||||
DEFINE_ENUM_FLAG_OPERATORS(CP_FLAGS);
|
||||
DEFINE_ENUM_FLAG_OPERATORS(DDS_FLAGS);
|
||||
DEFINE_ENUM_FLAG_OPERATORS(TGA_FLAGS);
|
||||
DEFINE_ENUM_FLAG_OPERATORS(WIC_FLAGS);
|
||||
DEFINE_ENUM_FLAG_OPERATORS(TEX_FR_FLAGS);
|
||||
DEFINE_ENUM_FLAG_OPERATORS(TEX_FILTER_FLAGS);
|
||||
|
@ -148,3 +149,43 @@ inline HRESULT __cdecl SaveToDDSFile(const Image& image, DDS_FLAGS flags, const
|
|||
|
||||
return SaveToDDSFile(&image, 1, mdata, flags, szFile);
|
||||
}
|
||||
|
||||
|
||||
//=====================================================================================
|
||||
// Compatability helpers
|
||||
//=====================================================================================
|
||||
_Use_decl_annotations_
|
||||
inline HRESULT __cdecl GetMetadataFromTGAMemory(const void* pSource, size_t size, TexMetadata& metadata) noexcept
|
||||
{
|
||||
return GetMetadataFromTGAMemory(pSource, size, TGA_FLAGS_NONE, metadata);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
inline HRESULT __cdecl GetMetadataFromTGAFile(const wchar_t* szFile, TexMetadata& metadata) noexcept
|
||||
{
|
||||
return GetMetadataFromTGAFile(szFile, TGA_FLAGS_NONE, metadata);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
inline HRESULT __cdecl LoadFromTGAMemory(const void* pSource, size_t size, TexMetadata* metadata, ScratchImage& image) noexcept
|
||||
{
|
||||
return LoadFromTGAMemory(pSource, size, TGA_FLAGS_NONE, metadata, image);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
inline HRESULT __cdecl LoadFromTGAFile(const wchar_t* szFile, TexMetadata* metadata, ScratchImage& image) noexcept
|
||||
{
|
||||
return LoadFromTGAFile(szFile, TGA_FLAGS_NONE, metadata, image);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
inline HRESULT __cdecl SaveToTGAMemory(const Image& image, Blob& blob, const TexMetadata* metadata) noexcept
|
||||
{
|
||||
return SaveToTGAMemory(image, TGA_FLAGS_NONE, blob, metadata);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
inline HRESULT __cdecl SaveToTGAFile(const Image& image, const wchar_t* szFile, const TexMetadata* metadata) noexcept
|
||||
{
|
||||
return SaveToTGAFile(image, TGA_FLAGS_NONE, szFile, metadata);
|
||||
}
|
||||
|
|
|
@ -134,6 +134,7 @@ namespace
|
|||
HRESULT DecodeTGAHeader(
|
||||
_In_reads_bytes_(size) const void* pSource,
|
||||
size_t size,
|
||||
TGA_FLAGS flags,
|
||||
_Out_ TexMetadata& metadata,
|
||||
size_t& offset,
|
||||
_Inout_opt_ uint32_t* convFlags) noexcept
|
||||
|
@ -177,16 +178,22 @@ namespace
|
|||
break;
|
||||
|
||||
case 24:
|
||||
metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
metadata.SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
|
||||
if (flags & TGA_FLAGS_BGR)
|
||||
{
|
||||
metadata.format = DXGI_FORMAT_B8G8R8X8_UNORM;
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
break;
|
||||
|
||||
case 32:
|
||||
metadata.format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
// We could use DXGI_FORMAT_B8G8R8A8_UNORM, but we prefer DXGI 1.0 formats
|
||||
metadata.format = (flags & TGA_FLAGS_BGR) ? DXGI_FORMAT_B8G8R8A8_UNORM : DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -275,6 +282,7 @@ namespace
|
|||
HRESULT UncompressPixels(
|
||||
_In_reads_bytes_(size) const void* pSource,
|
||||
size_t size,
|
||||
TGA_FLAGS flags,
|
||||
_In_ const Image* image,
|
||||
_In_ uint32_t convFlags) noexcept
|
||||
{
|
||||
|
@ -444,7 +452,7 @@ namespace
|
|||
}
|
||||
|
||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||
if (maxalpha == 0)
|
||||
if (maxalpha == 0 && !(flags & TGA_FLAGS_ALLOW_ALL_ZERO_ALPHA))
|
||||
{
|
||||
opaquealpha = true;
|
||||
hr = SetAlphaChannelToOpaque(image);
|
||||
|
@ -458,7 +466,7 @@ namespace
|
|||
}
|
||||
break;
|
||||
|
||||
//----------------------------------------------------------------------- 24/32-bit
|
||||
//------------------------------------------------------ 24/32-bit (with swizzling)
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
{
|
||||
uint32_t minalpha = 255;
|
||||
|
@ -589,7 +597,7 @@ namespace
|
|||
}
|
||||
|
||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||
if (maxalpha == 0)
|
||||
if (maxalpha == 0 && !(flags & TGA_FLAGS_ALLOW_ALL_ZERO_ALPHA))
|
||||
{
|
||||
opaquealpha = true;
|
||||
hr = SetAlphaChannelToOpaque(image);
|
||||
|
@ -603,6 +611,189 @@ namespace
|
|||
}
|
||||
break;
|
||||
|
||||
//-------------------------------------------------------------------- 32-bit (BGR)
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
||||
{
|
||||
assert((convFlags & CONV_FLAGS_EXPAND) == 0);
|
||||
|
||||
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);
|
||||
|
||||
auto dPtr = reinterpret_cast<uint32_t*>(image->pixels
|
||||
+ (image->rowPitch * ((convFlags & CONV_FLAGS_INVERTY) ? y : (image->height - y - 1))))
|
||||
+ offset;
|
||||
|
||||
for (size_t x = 0; x < image->width; )
|
||||
{
|
||||
if (sPtr >= endPtr)
|
||||
return E_FAIL;
|
||||
|
||||
if (*sPtr & 0x80)
|
||||
{
|
||||
// Repeat
|
||||
size_t j = size_t(*sPtr & 0x7F) + 1;
|
||||
++sPtr;
|
||||
|
||||
assert(offset * 4 < rowPitch);
|
||||
|
||||
if (sPtr + 3 >= endPtr)
|
||||
return E_FAIL;
|
||||
|
||||
uint32_t alpha = *(sPtr + 3);
|
||||
|
||||
auto t = *reinterpret_cast<const uint32_t*>(sPtr);
|
||||
|
||||
minalpha = std::min(minalpha, alpha);
|
||||
maxalpha = std::max(maxalpha, alpha);
|
||||
|
||||
sPtr += 4;
|
||||
|
||||
for (; j > 0; --j, ++x)
|
||||
{
|
||||
if (x >= image->width)
|
||||
return E_FAIL;
|
||||
|
||||
*dPtr = t;
|
||||
|
||||
if (convFlags & CONV_FLAGS_INVERTX)
|
||||
--dPtr;
|
||||
else
|
||||
++dPtr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Literal
|
||||
size_t j = size_t(*sPtr & 0x7F) + 1;
|
||||
++sPtr;
|
||||
|
||||
if (sPtr + (j * 4) > endPtr)
|
||||
return E_FAIL;
|
||||
|
||||
for (; j > 0; --j, ++x)
|
||||
{
|
||||
if (x >= image->width)
|
||||
return E_FAIL;
|
||||
|
||||
assert(offset * 4 < rowPitch);
|
||||
|
||||
if (sPtr + 3 >= endPtr)
|
||||
return E_FAIL;
|
||||
|
||||
uint32_t alpha = *(sPtr + 3);
|
||||
*dPtr = *reinterpret_cast<const uint32_t*>(sPtr);
|
||||
|
||||
minalpha = std::min(minalpha, alpha);
|
||||
maxalpha = std::max(maxalpha, alpha);
|
||||
|
||||
sPtr += 4;
|
||||
|
||||
if (convFlags & CONV_FLAGS_INVERTX)
|
||||
--dPtr;
|
||||
else
|
||||
++dPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||
if (maxalpha == 0 && !(flags & TGA_FLAGS_ALLOW_ALL_ZERO_ALPHA))
|
||||
{
|
||||
opaquealpha = true;
|
||||
hr = SetAlphaChannelToOpaque(image);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
else if (minalpha == 255)
|
||||
{
|
||||
opaquealpha = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//-------------------------------------------------------------------- 24-bit (BGR)
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM:
|
||||
{
|
||||
assert((convFlags & CONV_FLAGS_EXPAND) != 0);
|
||||
|
||||
for (size_t y = 0; y < image->height; ++y)
|
||||
{
|
||||
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
|
||||
|
||||
auto dPtr = reinterpret_cast<uint32_t*>(image->pixels
|
||||
+ (image->rowPitch * ((convFlags & CONV_FLAGS_INVERTY) ? y : (image->height - y - 1))))
|
||||
+ offset;
|
||||
|
||||
for (size_t x = 0; x < image->width; )
|
||||
{
|
||||
if (sPtr >= endPtr)
|
||||
return E_FAIL;
|
||||
|
||||
if (*sPtr & 0x80)
|
||||
{
|
||||
// Repeat
|
||||
size_t j = size_t(*sPtr & 0x7F) + 1;
|
||||
++sPtr;
|
||||
|
||||
assert(offset * 3 < rowPitch);
|
||||
|
||||
if (sPtr + 2 >= endPtr)
|
||||
return E_FAIL;
|
||||
|
||||
uint32_t t = uint32_t(*sPtr) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2) << 16);
|
||||
sPtr += 3;
|
||||
|
||||
for (; j > 0; --j, ++x)
|
||||
{
|
||||
if (x >= image->width)
|
||||
return E_FAIL;
|
||||
|
||||
*dPtr = t;
|
||||
|
||||
if (convFlags & CONV_FLAGS_INVERTX)
|
||||
--dPtr;
|
||||
else
|
||||
++dPtr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Literal
|
||||
size_t j = size_t(*sPtr & 0x7F) + 1;
|
||||
++sPtr;
|
||||
|
||||
if (sPtr + (j * 3) > endPtr)
|
||||
return E_FAIL;
|
||||
|
||||
for (; j > 0; --j, ++x)
|
||||
{
|
||||
if (x >= image->width)
|
||||
return E_FAIL;
|
||||
|
||||
assert(offset * 3 < rowPitch);
|
||||
|
||||
if (sPtr + 2 >= endPtr)
|
||||
return E_FAIL;
|
||||
|
||||
*dPtr = uint32_t(*sPtr) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2) << 16);
|
||||
sPtr += 3;
|
||||
|
||||
if (convFlags & CONV_FLAGS_INVERTX)
|
||||
--dPtr;
|
||||
else
|
||||
++dPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
default:
|
||||
return E_FAIL;
|
||||
|
@ -618,6 +809,7 @@ namespace
|
|||
HRESULT CopyPixels(
|
||||
_In_reads_bytes_(size) const void* pSource,
|
||||
size_t size,
|
||||
TGA_FLAGS flags,
|
||||
_In_ const Image* image,
|
||||
_In_ uint32_t convFlags) noexcept
|
||||
{
|
||||
|
@ -702,7 +894,7 @@ namespace
|
|||
}
|
||||
|
||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||
if (maxalpha == 0)
|
||||
if (maxalpha == 0 && !(flags & TGA_FLAGS_ALLOW_ALL_ZERO_ALPHA))
|
||||
{
|
||||
opaquealpha = true;
|
||||
hr = SetAlphaChannelToOpaque(image);
|
||||
|
@ -716,7 +908,7 @@ namespace
|
|||
}
|
||||
break;
|
||||
|
||||
//----------------------------------------------------------------------- 24/32-bit
|
||||
//------------------------------------------------------ 24/32-bit (with swizzling)
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
{
|
||||
uint32_t minalpha = 255;
|
||||
|
@ -770,7 +962,7 @@ namespace
|
|||
}
|
||||
|
||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||
if (maxalpha == 0)
|
||||
if (maxalpha == 0 && !(flags & TGA_FLAGS_ALLOW_ALL_ZERO_ALPHA))
|
||||
{
|
||||
opaquealpha = true;
|
||||
hr = SetAlphaChannelToOpaque(image);
|
||||
|
@ -784,6 +976,91 @@ namespace
|
|||
}
|
||||
break;
|
||||
|
||||
//-------------------------------------------------------------------- 32-bit (BGR)
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
||||
{
|
||||
assert((convFlags & CONV_FLAGS_EXPAND) == 0);
|
||||
|
||||
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);
|
||||
|
||||
auto dPtr = reinterpret_cast<uint32_t*>(image->pixels
|
||||
+ (image->rowPitch * ((convFlags & CONV_FLAGS_INVERTY) ? y : (image->height - y - 1))))
|
||||
+ offset;
|
||||
|
||||
for (size_t x = 0; x < image->width; ++x)
|
||||
{
|
||||
assert(offset * 4 < rowPitch);
|
||||
|
||||
if (sPtr + 3 >= endPtr)
|
||||
return E_FAIL;
|
||||
|
||||
uint32_t alpha = *(sPtr + 3);
|
||||
*dPtr = *reinterpret_cast<const uint32_t*>(sPtr);
|
||||
|
||||
minalpha = std::min(minalpha, alpha);
|
||||
maxalpha = std::max(maxalpha, alpha);
|
||||
|
||||
sPtr += 4;
|
||||
|
||||
if (convFlags & CONV_FLAGS_INVERTX)
|
||||
--dPtr;
|
||||
else
|
||||
++dPtr;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||
if (maxalpha == 0 && !(flags & TGA_FLAGS_ALLOW_ALL_ZERO_ALPHA))
|
||||
{
|
||||
opaquealpha = true;
|
||||
hr = SetAlphaChannelToOpaque(image);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
else if (minalpha == 255)
|
||||
{
|
||||
opaquealpha = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//-------------------------------------------------------------------- 24-bit (BGR)
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM:
|
||||
{
|
||||
assert((convFlags & CONV_FLAGS_EXPAND) != 0);
|
||||
|
||||
for (size_t y = 0; y < image->height; ++y)
|
||||
{
|
||||
size_t offset = ((convFlags & CONV_FLAGS_INVERTX) ? (image->width - 1) : 0);
|
||||
|
||||
auto dPtr = reinterpret_cast<uint32_t*>(image->pixels
|
||||
+ (image->rowPitch * ((convFlags & CONV_FLAGS_INVERTY) ? y : (image->height - y - 1))))
|
||||
+ offset;
|
||||
|
||||
for (size_t x = 0; x < image->width; ++x)
|
||||
{
|
||||
assert(offset * 3 < rowPitch);
|
||||
|
||||
if (sPtr + 2 >= endPtr)
|
||||
return E_FAIL;
|
||||
|
||||
*dPtr = uint32_t(*sPtr) | uint32_t(*(sPtr + 1) << 8) | uint32_t(*(sPtr + 2) << 16);
|
||||
sPtr += 3;
|
||||
|
||||
if (convFlags & CONV_FLAGS_INVERTX)
|
||||
--dPtr;
|
||||
else
|
||||
++dPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
default:
|
||||
return E_FAIL;
|
||||
|
@ -980,17 +1257,18 @@ _Use_decl_annotations_
|
|||
HRESULT DirectX::GetMetadataFromTGAMemory(
|
||||
const void* pSource,
|
||||
size_t size,
|
||||
TGA_FLAGS flags,
|
||||
TexMetadata& metadata) noexcept
|
||||
{
|
||||
if (!pSource || size == 0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
size_t offset;
|
||||
return DecodeTGAHeader(pSource, size, metadata, offset, nullptr);
|
||||
return DecodeTGAHeader(pSource, size, flags, metadata, offset, nullptr);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TexMetadata& metadata) noexcept
|
||||
HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TGA_FLAGS flags, TexMetadata& metadata) noexcept
|
||||
{
|
||||
if (!szFile)
|
||||
return E_INVALIDARG;
|
||||
|
@ -1034,7 +1312,7 @@ HRESULT DirectX::GetMetadataFromTGAFile(const wchar_t* szFile, TexMetadata& meta
|
|||
}
|
||||
|
||||
size_t offset;
|
||||
return DecodeTGAHeader(header, bytesRead, metadata, offset, nullptr);
|
||||
return DecodeTGAHeader(header, bytesRead, flags, metadata, offset, nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1045,6 +1323,7 @@ _Use_decl_annotations_
|
|||
HRESULT DirectX::LoadFromTGAMemory(
|
||||
const void* pSource,
|
||||
size_t size,
|
||||
TGA_FLAGS flags,
|
||||
TexMetadata* metadata,
|
||||
ScratchImage& image) noexcept
|
||||
{
|
||||
|
@ -1056,7 +1335,7 @@ HRESULT DirectX::LoadFromTGAMemory(
|
|||
size_t offset;
|
||||
uint32_t convFlags = 0;
|
||||
TexMetadata mdata;
|
||||
HRESULT hr = DecodeTGAHeader(pSource, size, mdata, offset, &convFlags);
|
||||
HRESULT hr = DecodeTGAHeader(pSource, size, flags, mdata, offset, &convFlags);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
|
@ -1075,11 +1354,11 @@ HRESULT DirectX::LoadFromTGAMemory(
|
|||
|
||||
if (convFlags & CONV_FLAGS_RLE)
|
||||
{
|
||||
hr = UncompressPixels(pPixels, remaining, image.GetImage(0, 0, 0), convFlags);
|
||||
hr = UncompressPixels(pPixels, remaining, flags, image.GetImage(0, 0, 0), convFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = CopyPixels(pPixels, remaining, image.GetImage(0, 0, 0), convFlags);
|
||||
hr = CopyPixels(pPixels, remaining, flags, image.GetImage(0, 0, 0), convFlags);
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
|
@ -1122,6 +1401,7 @@ HRESULT DirectX::LoadFromTGAMemory(
|
|||
_Use_decl_annotations_
|
||||
HRESULT DirectX::LoadFromTGAFile(
|
||||
const wchar_t* szFile,
|
||||
TGA_FLAGS flags,
|
||||
TexMetadata* metadata,
|
||||
ScratchImage& image) noexcept
|
||||
{
|
||||
|
@ -1171,7 +1451,7 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||
size_t offset;
|
||||
uint32_t convFlags = 0;
|
||||
TexMetadata mdata;
|
||||
HRESULT hr = DecodeTGAHeader(header, bytesRead, mdata, offset, &convFlags);
|
||||
HRESULT hr = DecodeTGAHeader(header, bytesRead, flags, mdata, offset, &convFlags);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
|
@ -1269,7 +1549,7 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||
}
|
||||
|
||||
uint32_t tflags = TEXP_SCANLINE_NONE;
|
||||
if (maxalpha == 0)
|
||||
if (maxalpha == 0 && !(flags & TGA_FLAGS_ALLOW_ALL_ZERO_ALPHA))
|
||||
{
|
||||
opaquealpha = true;
|
||||
tflags = TEXP_SCANLINE_SETALPHA;
|
||||
|
@ -1290,7 +1570,63 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||
}
|
||||
break;
|
||||
|
||||
// If we start using DXGI_FORMAT_B8G8R8X8_UNORM or DXGI_FORMAT_B8G8R8A8_UNORM we need to check for a fully 0 alpha channel
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
||||
{
|
||||
assert(image.GetImageCount() == 1);
|
||||
const Image* img = image.GetImage(0, 0, 0);
|
||||
if (!img)
|
||||
{
|
||||
image.Release();
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
// Scan for non-zero alpha channel
|
||||
uint32_t minalpha = 255;
|
||||
uint32_t maxalpha = 0;
|
||||
|
||||
const uint8_t *pPixels = img->pixels;
|
||||
if (!pPixels)
|
||||
{
|
||||
image.Release();
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
size_t rowPitch = img->rowPitch;
|
||||
|
||||
for (size_t h = 0; h < img->height; ++h)
|
||||
{
|
||||
auto sPtr = reinterpret_cast<const uint32_t*>(pPixels);
|
||||
|
||||
for (size_t x = 0; x < img->width; ++x)
|
||||
{
|
||||
uint32_t alpha = ((*sPtr & 0xFF000000) >> 24);
|
||||
|
||||
minalpha = std::min(minalpha, alpha);
|
||||
maxalpha = std::max(maxalpha, alpha);
|
||||
|
||||
++sPtr;
|
||||
}
|
||||
|
||||
pPixels += rowPitch;
|
||||
}
|
||||
|
||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||
if (maxalpha == 0 && !(flags & TGA_FLAGS_ALLOW_ALL_ZERO_ALPHA))
|
||||
{
|
||||
opaquealpha = true;
|
||||
hr = SetAlphaChannelToOpaque(img);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
image.Release();
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
else if (minalpha == 255)
|
||||
{
|
||||
opaquealpha = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_B5G5R5A1_UNORM:
|
||||
{
|
||||
|
@ -1333,7 +1669,7 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||
}
|
||||
|
||||
// If there are no non-zero alpha channel entries, we'll assume alpha is not used and force it to opaque
|
||||
if (maxalpha == 0)
|
||||
if (maxalpha == 0 && !(flags & TGA_FLAGS_ALLOW_ALL_ZERO_ALPHA))
|
||||
{
|
||||
opaquealpha = true;
|
||||
hr = SetAlphaChannelToOpaque(img);
|
||||
|
@ -1350,6 +1686,10 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||
}
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_B8G8R8X8_UNORM:
|
||||
// Should never be trying to direct-read 24bpp
|
||||
return E_FAIL;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1377,11 +1717,11 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||
|
||||
if (convFlags & CONV_FLAGS_RLE)
|
||||
{
|
||||
hr = UncompressPixels(temp.get(), remaining, image.GetImage(0, 0, 0), convFlags);
|
||||
hr = UncompressPixels(temp.get(), remaining, flags, image.GetImage(0, 0, 0), convFlags);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = CopyPixels(temp.get(), remaining, image.GetImage(0, 0, 0), convFlags);
|
||||
hr = CopyPixels(temp.get(), remaining, flags, image.GetImage(0, 0, 0), convFlags);
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
|
@ -1451,7 +1791,11 @@ HRESULT DirectX::LoadFromTGAFile(
|
|||
// Save a TGA file to memory
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::SaveToTGAMemory(const Image& image, Blob& blob, const TexMetadata* metadata) noexcept
|
||||
HRESULT DirectX::SaveToTGAMemory(
|
||||
const Image& image,
|
||||
TGA_FLAGS /*flags*/,
|
||||
Blob& blob,
|
||||
const TexMetadata* metadata) noexcept
|
||||
{
|
||||
if (!image.pixels)
|
||||
return E_POINTER;
|
||||
|
@ -1535,7 +1879,11 @@ HRESULT DirectX::SaveToTGAMemory(const Image& image, Blob& blob, const TexMetada
|
|||
// Save a TGA file to disk
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::SaveToTGAFile(const Image& image, const wchar_t* szFile, const TexMetadata* metadata) noexcept
|
||||
HRESULT DirectX::SaveToTGAFile(
|
||||
const Image& image,
|
||||
TGA_FLAGS /*flags*/,
|
||||
const wchar_t* szFile,
|
||||
const TexMetadata* metadata) noexcept
|
||||
{
|
||||
if (!szFile)
|
||||
return E_INVALIDARG;
|
||||
|
|
Загрузка…
Ссылка в новой задаче