Update TGA codec for TGA 2.0 (#151)
This commit is contained in:
parent
002baf8072
commit
351ff17936
@ -382,8 +382,8 @@ namespace DirectX
|
||||
_In_z_ const wchar_t* szFile,
|
||||
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image);
|
||||
|
||||
HRESULT __cdecl SaveToTGAMemory(_In_ const Image& image, _Out_ Blob& blob);
|
||||
HRESULT __cdecl SaveToTGAFile(_In_ const Image& image, _In_z_ const wchar_t* szFile);
|
||||
HRESULT __cdecl SaveToTGAMemory(_In_ const Image& image, _Out_ Blob& blob, _In_opt_ const TexMetadata* metadata = nullptr);
|
||||
HRESULT __cdecl SaveToTGAFile(_In_ const Image& image, _In_z_ const wchar_t* szFile, _In_opt_ const TexMetadata* metadata = nullptr);
|
||||
|
||||
// WIC operations
|
||||
HRESULT __cdecl LoadFromWICMemory(
|
||||
|
@ -110,6 +110,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <search.h>
|
||||
|
||||
|
@ -23,6 +23,9 @@ using namespace DirectX;
|
||||
|
||||
namespace
|
||||
{
|
||||
const char g_Signature[] = "TRUEVISION-XFILE.";
|
||||
// This is the official footer signature for the TGA 2.0 file format.
|
||||
|
||||
enum TGAImageType
|
||||
{
|
||||
TGA_NO_IMAGE = 0,
|
||||
@ -42,6 +45,15 @@ namespace
|
||||
TGA_FLAGS_INTERLEAVED_4WAY = 0x80, // Deprecated
|
||||
};
|
||||
|
||||
enum TGAAttributesType : uint8_t
|
||||
{
|
||||
TGA_ATTRIBUTE_NONE = 0, // 0: no alpha data included
|
||||
TGA_ATTRIBUTE_IGNORED = 1, // 1: undefined data, can be ignored
|
||||
TGA_ATTRIBUTE_UNDEFINED = 2, // 2: uedefined data, should be retained
|
||||
TGA_ATTRIBUTE_ALPHA = 3, // 3: useful alpha channel data
|
||||
TGA_ATTRIBUTE_PREMULTIPLIED = 4, // 4: pre-multiplied alpha
|
||||
};
|
||||
|
||||
#pragma pack(push,1)
|
||||
struct TGA_HEADER
|
||||
{
|
||||
@ -892,6 +904,82 @@ namespace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// TGA 2.0 Extension helpers
|
||||
//-------------------------------------------------------------------------------------
|
||||
void SetExtension(TGA_EXTENSION *ext, const TexMetadata& metadata)
|
||||
{
|
||||
memset(ext, 0, sizeof(TGA_EXTENSION));
|
||||
|
||||
ext->wSize = sizeof(TGA_EXTENSION);
|
||||
|
||||
memcpy(ext->szSoftwareId, "DirectXTex", sizeof("DirectXTex"));
|
||||
ext->wVersionNumber = DIRECTX_TEX_VERSION;
|
||||
ext->bVersionLetter = ' ';
|
||||
|
||||
if (IsSRGB(metadata.format))
|
||||
{
|
||||
ext->wGammaNumerator = 22;
|
||||
ext->wGammaDenominator = 10;
|
||||
}
|
||||
|
||||
switch (metadata.GetAlphaMode())
|
||||
{
|
||||
case TEX_ALPHA_MODE_UNKNOWN:
|
||||
ext->bAttributesType = HasAlpha(metadata.format) ? TGA_ATTRIBUTE_UNDEFINED : TGA_ATTRIBUTE_NONE;
|
||||
break;
|
||||
|
||||
case TEX_ALPHA_MODE_STRAIGHT:
|
||||
ext->bAttributesType = TGA_ATTRIBUTE_ALPHA;
|
||||
break;
|
||||
|
||||
case TEX_ALPHA_MODE_PREMULTIPLIED:
|
||||
ext->bAttributesType = TGA_ATTRIBUTE_PREMULTIPLIED;
|
||||
break;
|
||||
|
||||
case TEX_ALPHA_MODE_OPAQUE:
|
||||
ext->bAttributesType = TGA_ATTRIBUTE_IGNORED;
|
||||
break;
|
||||
|
||||
case TEX_ALPHA_MODE_CUSTOM:
|
||||
ext->bAttributesType = TGA_ATTRIBUTE_UNDEFINED;
|
||||
break;
|
||||
}
|
||||
|
||||
// Set file time stamp
|
||||
{
|
||||
time_t now = {};
|
||||
time(&now);
|
||||
|
||||
tm info;
|
||||
if (!gmtime_s(&info, &now))
|
||||
{
|
||||
ext->wStampMonth = static_cast<uint16_t>(info.tm_mon + 1);
|
||||
ext->wStampDay = static_cast<uint16_t>(info.tm_mday);
|
||||
ext->wStampYear = static_cast<uint16_t>(info.tm_year + 1900);
|
||||
ext->wStampHour = static_cast<uint16_t>(info.tm_hour);
|
||||
ext->wStampMinute = static_cast<uint16_t>(info.tm_min);
|
||||
ext->wStampSecond = static_cast<uint16_t>(info.tm_sec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEX_ALPHA_MODE GetAlphaModeFromExtension(const TGA_EXTENSION *ext)
|
||||
{
|
||||
if (ext && ext->wSize == sizeof(TGA_EXTENSION))
|
||||
{
|
||||
switch (ext->bAttributesType)
|
||||
{
|
||||
case TGA_ATTRIBUTE_IGNORED: return TEX_ALPHA_MODE_OPAQUE;
|
||||
case TGA_ATTRIBUTE_UNDEFINED: return TEX_ALPHA_MODE_CUSTOM;
|
||||
case TGA_ATTRIBUTE_ALPHA: return TEX_ALPHA_MODE_STRAIGHT;
|
||||
case TGA_ATTRIBUTE_PREMULTIPLIED: return TEX_ALPHA_MODE_PREMULTIPLIED;
|
||||
}
|
||||
}
|
||||
|
||||
return TEX_ALPHA_MODE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1021,6 +1109,21 @@ HRESULT DirectX::LoadFromTGAMemory(
|
||||
{
|
||||
metadata->SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
|
||||
}
|
||||
else if (size >= sizeof(TGA_FOOTER))
|
||||
{
|
||||
// Handle optional TGA 2.0 footer
|
||||
auto footer = reinterpret_cast<const TGA_FOOTER*>(static_cast<const uint8_t*>(pSource) + size - sizeof(TGA_FOOTER));
|
||||
|
||||
if (memcmp(footer->Signature, g_Signature, sizeof(g_Signature)) == 0)
|
||||
{
|
||||
if (footer->dwExtensionOffset != 0
|
||||
&& ((footer->dwExtensionOffset + sizeof(TGA_EXTENSION)) <= size))
|
||||
{
|
||||
auto ext = reinterpret_cast<const TGA_EXTENSION*>(static_cast<const uint8_t*>(pSource) + footer->dwExtensionOffset);
|
||||
metadata->SetAlphaMode(GetAlphaModeFromExtension(ext));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
@ -1312,6 +1415,46 @@ HRESULT DirectX::LoadFromTGAFile(
|
||||
{
|
||||
metadata->SetAlphaMode(TEX_ALPHA_MODE_OPAQUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle optional TGA 2.0 footer
|
||||
TGA_FOOTER footer = {};
|
||||
|
||||
if (SetFilePointer(hFile.get(), -static_cast<int>(sizeof(TGA_FOOTER)), 0, FILE_END) == INVALID_SET_FILE_POINTER)
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
if (!ReadFile(hFile.get(), &footer, sizeof(TGA_FOOTER), &bytesRead, nullptr))
|
||||
{
|
||||
image.Release();
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
if (bytesRead != sizeof(TGA_FOOTER))
|
||||
{
|
||||
image.Release();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (memcmp(footer.Signature, g_Signature, sizeof(g_Signature)) == 0)
|
||||
{
|
||||
if (footer.dwExtensionOffset != 0
|
||||
&& ((footer.dwExtensionOffset + sizeof(TGA_EXTENSION)) <= fileInfo.EndOfFile.LowPart))
|
||||
{
|
||||
LARGE_INTEGER filePos = { { static_cast<DWORD>(footer.dwExtensionOffset), 0 } };
|
||||
if (SetFilePointerEx(hFile.get(), filePos, nullptr, FILE_BEGIN))
|
||||
{
|
||||
TGA_EXTENSION ext = {};
|
||||
if (ReadFile(hFile.get(), &ext, sizeof(TGA_EXTENSION), &bytesRead, nullptr)
|
||||
&& bytesRead == sizeof(TGA_EXTENSION))
|
||||
{
|
||||
metadata->SetAlphaMode(GetAlphaModeFromExtension(&ext));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
@ -1322,7 +1465,7 @@ HRESULT DirectX::LoadFromTGAFile(
|
||||
// Save a TGA file to memory
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::SaveToTGAMemory(const Image& image, Blob& blob)
|
||||
HRESULT DirectX::SaveToTGAMemory(const Image& image, Blob& blob, const TexMetadata* metadata)
|
||||
{
|
||||
if (!image.pixels)
|
||||
return E_POINTER;
|
||||
@ -1349,13 +1492,18 @@ HRESULT DirectX::SaveToTGAMemory(const Image& image, Blob& blob)
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = blob.Initialize(sizeof(TGA_HEADER) + slicePitch);
|
||||
hr = blob.Initialize(sizeof(TGA_HEADER)
|
||||
+ slicePitch
|
||||
+ (metadata ? sizeof(TGA_EXTENSION) : 0)
|
||||
+ sizeof(TGA_FOOTER));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// Copy header
|
||||
auto dPtr = static_cast<uint8_t*>(blob.GetBufferPointer());
|
||||
assert(dPtr != nullptr);
|
||||
auto destPtr = static_cast<uint8_t*>(blob.GetBufferPointer());
|
||||
assert(destPtr != nullptr);
|
||||
|
||||
uint8_t* dPtr = destPtr;
|
||||
memcpy_s(dPtr, blob.GetBufferSize(), &tga_header, sizeof(TGA_HEADER));
|
||||
dPtr += sizeof(TGA_HEADER);
|
||||
|
||||
@ -1382,6 +1530,24 @@ HRESULT DirectX::SaveToTGAMemory(const Image& image, Blob& blob)
|
||||
pPixels += image.rowPitch;
|
||||
}
|
||||
|
||||
uint32_t extOffset = 0;
|
||||
if (metadata)
|
||||
{
|
||||
// metadata is only used for writing the TGA 2.0 extension header
|
||||
|
||||
auto ext = reinterpret_cast<TGA_EXTENSION*>(dPtr);
|
||||
SetExtension(ext, *metadata);
|
||||
|
||||
extOffset = static_cast<uint32_t>(dPtr - destPtr);
|
||||
dPtr += sizeof(TGA_EXTENSION);
|
||||
}
|
||||
|
||||
// Copy TGA 2.0 footer
|
||||
auto footer = reinterpret_cast<TGA_FOOTER*>(dPtr);
|
||||
footer->dwDeveloperOffset = 0;
|
||||
footer->dwExtensionOffset = extOffset;
|
||||
memcpy(footer->Signature, g_Signature, sizeof(g_Signature));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -1390,7 +1556,7 @@ HRESULT DirectX::SaveToTGAMemory(const Image& image, Blob& blob)
|
||||
// Save a TGA file to disk
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::SaveToTGAFile(const Image& image, const wchar_t* szFile)
|
||||
HRESULT DirectX::SaveToTGAFile(const Image& image, const wchar_t* szFile, const TexMetadata* metadata)
|
||||
{
|
||||
if (!szFile)
|
||||
return E_INVALIDARG;
|
||||
@ -1513,6 +1679,41 @@ HRESULT DirectX::SaveToTGAFile(const Image& image, const wchar_t* szFile)
|
||||
if (bytesWritten != rowPitch)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
uint32_t extOffset = 0;
|
||||
if (metadata)
|
||||
{
|
||||
// metadata is only used for writing the TGA 2.0 extension header
|
||||
TGA_EXTENSION ext = {};
|
||||
SetExtension(&ext, *metadata);
|
||||
|
||||
extOffset = SetFilePointer(hFile.get(), 0, nullptr, FILE_CURRENT);
|
||||
if (extOffset == INVALID_SET_FILE_POINTER)
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
if (!WriteFile(hFile.get(), &ext, sizeof(TGA_EXTENSION), &bytesWritten, nullptr))
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
if (bytesWritten != sizeof(TGA_EXTENSION))
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Write TGA 2.0 footer
|
||||
TGA_FOOTER footer = {};
|
||||
footer.dwExtensionOffset = extOffset;
|
||||
memcpy(footer.Signature, g_Signature, sizeof(g_Signature));
|
||||
|
||||
if (!WriteFile(hFile.get(), &footer, sizeof(footer), &bytesWritten, nullptr))
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
if (bytesWritten != sizeof(footer))
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
delonfail.clear();
|
||||
|
@ -54,6 +54,7 @@ using Microsoft::WRL::ComPtr;
|
||||
enum OPTIONS
|
||||
{
|
||||
OPT_RECURSIVE = 1,
|
||||
OPT_FILELIST,
|
||||
OPT_WIDTH,
|
||||
OPT_HEIGHT,
|
||||
OPT_MIPLEVELS,
|
||||
@ -72,6 +73,10 @@ enum OPTIONS
|
||||
OPT_DDS_DWORD_ALIGN,
|
||||
OPT_DDS_BAD_DXTN_TAILS,
|
||||
OPT_USE_DX10,
|
||||
OPT_TGA20,
|
||||
OPT_WIC_QUALITY,
|
||||
OPT_WIC_LOSSLESS,
|
||||
OPT_WIC_MULTIFRAME,
|
||||
OPT_NOLOGO,
|
||||
OPT_TIMING,
|
||||
OPT_SEPALPHA,
|
||||
@ -95,15 +100,11 @@ enum OPTIONS
|
||||
OPT_COMPRESS_MAX,
|
||||
OPT_COMPRESS_QUICK,
|
||||
OPT_COMPRESS_DITHER,
|
||||
OPT_WIC_QUALITY,
|
||||
OPT_WIC_LOSSLESS,
|
||||
OPT_WIC_MULTIFRAME,
|
||||
OPT_COLORKEY,
|
||||
OPT_TONEMAP,
|
||||
OPT_X2_BIAS,
|
||||
OPT_PRESERVE_ALPHA_COVERAGE,
|
||||
OPT_INVERT_Y,
|
||||
OPT_FILELIST,
|
||||
OPT_ROTATE_COLOR,
|
||||
OPT_PAPER_WHITE_NITS,
|
||||
OPT_MAX
|
||||
@ -140,6 +141,7 @@ struct SValue
|
||||
const SValue g_pOptions[] =
|
||||
{
|
||||
{ L"r", OPT_RECURSIVE },
|
||||
{ L"flist", OPT_FILELIST },
|
||||
{ L"w", OPT_WIDTH },
|
||||
{ L"h", OPT_HEIGHT },
|
||||
{ L"m", OPT_MIPLEVELS },
|
||||
@ -158,9 +160,14 @@ const SValue g_pOptions[] =
|
||||
{ L"dword", OPT_DDS_DWORD_ALIGN },
|
||||
{ L"badtails", OPT_DDS_BAD_DXTN_TAILS },
|
||||
{ L"dx10", OPT_USE_DX10 },
|
||||
{ L"tga20", OPT_TGA20 },
|
||||
{ L"wicq", OPT_WIC_QUALITY },
|
||||
{ L"wiclossless", OPT_WIC_LOSSLESS },
|
||||
{ L"wicmulti", OPT_WIC_MULTIFRAME },
|
||||
{ L"nologo", OPT_NOLOGO },
|
||||
{ L"timing", OPT_TIMING },
|
||||
{ L"sepalpha", OPT_SEPALPHA },
|
||||
{ L"keepcoverage", OPT_PRESERVE_ALPHA_COVERAGE },
|
||||
{ L"nowic", OPT_NO_WIC },
|
||||
{ L"tu", OPT_TYPELESS_UNORM },
|
||||
{ L"tf", OPT_TYPELESS_FLOAT },
|
||||
@ -181,15 +188,10 @@ const SValue g_pOptions[] =
|
||||
{ L"bcmax", OPT_COMPRESS_MAX },
|
||||
{ L"bcquick", OPT_COMPRESS_QUICK },
|
||||
{ L"bcdither", OPT_COMPRESS_DITHER },
|
||||
{ L"wicq", OPT_WIC_QUALITY },
|
||||
{ L"wiclossless", OPT_WIC_LOSSLESS },
|
||||
{ L"wicmulti", OPT_WIC_MULTIFRAME },
|
||||
{ L"c", OPT_COLORKEY },
|
||||
{ L"tonemap", OPT_TONEMAP },
|
||||
{ L"x2bias", OPT_X2_BIAS },
|
||||
{ L"keepcoverage", OPT_PRESERVE_ALPHA_COVERAGE },
|
||||
{ L"inverty", OPT_INVERT_Y },
|
||||
{ L"flist", OPT_FILELIST },
|
||||
{ L"rotatecolor", OPT_ROTATE_COLOR },
|
||||
{ L"nits", OPT_PAPER_WHITE_NITS },
|
||||
{ nullptr, 0 }
|
||||
@ -702,32 +704,34 @@ namespace
|
||||
|
||||
wprintf(L"Usage: texconv <options> <files>\n\n");
|
||||
wprintf(L" -r wildcard filename search is recursive\n");
|
||||
wprintf(L" -w <n> width\n");
|
||||
wprintf(L" -flist <filename> use text file with a list of input files (one per line)\n");
|
||||
wprintf(L"\n -w <n> width\n");
|
||||
wprintf(L" -h <n> height\n");
|
||||
wprintf(L" -m <n> miplevels\n");
|
||||
wprintf(L" -f <format> format\n");
|
||||
wprintf(L" -if <filter> image filtering\n");
|
||||
wprintf(L"\n -if <filter> image filtering\n");
|
||||
wprintf(L" -srgb{i|o} sRGB {input, output}\n");
|
||||
wprintf(L" -px <string> name prefix\n");
|
||||
wprintf(L"\n -px <string> name prefix\n");
|
||||
wprintf(L" -sx <string> name suffix\n");
|
||||
wprintf(L" -o <directory> output directory\n");
|
||||
wprintf(L" -y overwrite existing output file (if any)\n");
|
||||
wprintf(L" -ft <filetype> output file type\n");
|
||||
wprintf(L" -hflip horizonal flip of source image\n");
|
||||
wprintf(L"\n -hflip horizonal flip of source image\n");
|
||||
wprintf(L" -vflip vertical flip of source image\n");
|
||||
wprintf(L" -sepalpha resize/generate mips alpha channel separately\n");
|
||||
wprintf(L"\n -sepalpha resize/generate mips alpha channel separately\n");
|
||||
wprintf(L" from color channels\n");
|
||||
wprintf(L" -nowic Force non-WIC filtering\n");
|
||||
wprintf(L" -keepcoverage <ref> Preserve alpha coverage in mips for alpha test ref\n");
|
||||
wprintf(L"\n -nowic Force non-WIC filtering\n");
|
||||
wprintf(L" -wrap, -mirror texture addressing mode (wrap, mirror, or clamp)\n");
|
||||
wprintf(L" -pmalpha convert final texture to use premultiplied alpha\n");
|
||||
wprintf(L" -alpha convert premultiplied alpha to straight alpha\n");
|
||||
wprintf(L"\n -fl <feature-level> Set maximum feature level target (defaults to 11.0)\n");
|
||||
wprintf(L" -pow2 resize to fit a power-of-2, respecting aspect ratio\n");
|
||||
wprintf(
|
||||
L" -nmap <options> converts height-map to normal-map\n"
|
||||
L"\n -nmap <options> converts height-map to normal-map\n"
|
||||
L" options must be one or more of\n"
|
||||
L" r, g, b, a, l, m, u, v, i, o\n");
|
||||
wprintf(L" -nmapamp <weight> normal map amplitude (defaults to 1.0)\n");
|
||||
wprintf(L" -fl <feature-level> Set maximum feature level target (defaults to 11.0)\n");
|
||||
wprintf(L"\n (DDS input only)\n");
|
||||
wprintf(L" -t{u|f} TYPELESS format is treated as UNORM or FLOAT\n");
|
||||
wprintf(L" -dword Use DWORD instead of BYTE alignment\n");
|
||||
@ -735,6 +739,12 @@ namespace
|
||||
wprintf(L" -xlum expand legacy L8, L16, and A8P8 formats\n");
|
||||
wprintf(L"\n (DDS output only)\n");
|
||||
wprintf(L" -dx10 Force use of 'DX10' extended header\n");
|
||||
wprintf(L"\n (TGA output only)\n");
|
||||
wprintf(L" -tga20 Write file including TGA 2.0 extension area\n");
|
||||
wprintf(L"\n (BMP, PNG, JPG, TIF, WDP output only)\n");
|
||||
wprintf(L" -wicq <quality> When writing images with WIC use quality (0.0 to 1.0)\n");
|
||||
wprintf(L" -wiclossless When writing images with WIC use lossless mode\n");
|
||||
wprintf(L" -wicmulti When writing images with WIC encode multiframe images\n");
|
||||
wprintf(L"\n -nologo suppress copyright message\n");
|
||||
wprintf(L" -timing Display elapsed processing time\n\n");
|
||||
#ifdef _OPENMP
|
||||
@ -746,20 +756,15 @@ namespace
|
||||
wprintf(L" -bcdither Use dithering for BC1-3\n");
|
||||
wprintf(L" -bcmax Use exhaustive compression (BC7 only)\n");
|
||||
wprintf(L" -bcquick Use quick compression (BC7 only)\n");
|
||||
wprintf(L" -wicq <quality> When writing images with WIC use quality (0.0 to 1.0)\n");
|
||||
wprintf(L" -wiclossless When writing images with WIC use lossless mode\n");
|
||||
wprintf(L" -wicmulti When writing images with WIC encode multiframe images\n");
|
||||
wprintf(
|
||||
L" -aw <weight> BC7 GPU compressor weighting for alpha error metric\n"
|
||||
L" (defaults to 1.0)\n");
|
||||
wprintf(L" -c <hex-RGB> colorkey (a.k.a. chromakey) transparency\n");
|
||||
wprintf(L"\n -c <hex-RGB> colorkey (a.k.a. chromakey) transparency\n");
|
||||
wprintf(L" -rotatecolor <rot> rotates color primaries and/or applies a curve\n");
|
||||
wprintf(L" -nits <value> paper-white value in nits to use for HDR10 (def: 200.0)\n");
|
||||
wprintf(L" -tonemap Apply a tonemap operator based on maximum luminance\n");
|
||||
wprintf(L" -x2bias Enable *2 - 1 conversion cases for unorm/pos-only-float\n");
|
||||
wprintf(L" -keepcoverage <ref> Preserve alpha coverage in generated mips for alpha test ref\n");
|
||||
wprintf(L" -inverty Invert Y (i.e. green) channel values\n");
|
||||
wprintf(L" -flist <filename> use text file with a list of input files (one per line)\n");
|
||||
|
||||
wprintf(L"\n <format>: ");
|
||||
PrintList(13, g_pFormats);
|
||||
@ -2990,7 +2995,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
break;
|
||||
|
||||
case CODEC_TGA:
|
||||
hr = SaveToTGAFile(img[0], pConv->szDest);
|
||||
hr = SaveToTGAFile(img[0], pConv->szDest, (dwOptions & (DWORD64(1) << OPT_TGA20)) ? &info : nullptr);
|
||||
break;
|
||||
|
||||
case CODEC_HDR:
|
||||
|
Loading…
Reference in New Issue
Block a user