diff --git a/DirectXTex/DirectXTex.h b/DirectXTex/DirectXTex.h index ad683f7..464a7fd 100644 --- a/DirectXTex/DirectXTex.h +++ b/DirectXTex/DirectXTex.h @@ -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 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 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 diff --git a/DirectXTex/DirectXTex.inl b/DirectXTex/DirectXTex.inl index 4b71eca..7ca3f4c 100644 --- a/DirectXTex/DirectXTex.inl +++ b/DirectXTex/DirectXTex.inl @@ -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); +} diff --git a/DirectXTex/DirectXTexTGA.cpp b/DirectXTex/DirectXTexTGA.cpp index 8d6d73a..25d523f 100644 --- a/DirectXTex/DirectXTexTGA.cpp +++ b/DirectXTex/DirectXTexTGA.cpp @@ -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(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(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(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(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(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(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(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(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;