diff --git a/Texconv/texconv.cpp b/Texconv/texconv.cpp index 0c83595..cec34fd 100644 --- a/Texconv/texconv.cpp +++ b/Texconv/texconv.cpp @@ -101,6 +101,7 @@ enum OPTIONS OPT_COLORKEY, OPT_TONEMAP, OPT_X2_BIAS, + OPT_INVERT_Y, OPT_FILELIST, OPT_ROTATE_COLOR, OPT_PAPER_WHITE_NITS, @@ -186,6 +187,7 @@ const SValue g_pOptions[] = { L"c", OPT_COLORKEY }, { L"tonemap", OPT_TONEMAP }, { L"x2bias", OPT_X2_BIAS }, + { L"inverty", OPT_INVERT_Y }, { L"flist", OPT_FILELIST }, { L"rotatecolor", OPT_ROTATE_COLOR }, { L"nits", OPT_PAPER_WHITE_NITS }, @@ -749,6 +751,7 @@ namespace wprintf(L" -nits 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" -inverty Invert Y (i.e. green) channel values\n"); wprintf(L" -flist use text file with a list of input files (one per line)\n"); wprintf(L"\n : "); @@ -2475,6 +2478,54 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) cimage.reset(); } + // --- Invert Y Channel -------------------------------------------------------- + if (dwOptions & (DWORD64(1) << OPT_INVERT_Y)) + { + std::unique_ptr timage(new (std::nothrow) ScratchImage); + if (!timage) + { + wprintf(L"\nERROR: Memory allocation failed\n"); + return 1; + } + + hr = TransformImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(), + [&](XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t width, size_t y) + { + static const XMVECTORU32 s_selecty = { { { XM_SELECT_0, XM_SELECT_1, XM_SELECT_0, XM_SELECT_0 } } }; + + UNREFERENCED_PARAMETER(y); + + for (size_t j = 0; j < width; ++j) + { + XMVECTOR value = inPixels[j]; + + XMVECTOR inverty = XMVectorSubtract(g_XMOne, value); + + outPixels[j] = XMVectorSelect(value, inverty, s_selecty); + } + }, *timage); + if (FAILED(hr)) + { + wprintf(L" FAILED [inverty] (%x)\n", hr); + return 1; + } + + auto& tinfo = timage->GetMetadata(); + tinfo; + + assert(info.width == tinfo.width); + assert(info.height == tinfo.height); + assert(info.depth == tinfo.depth); + assert(info.arraySize == tinfo.arraySize); + assert(info.mipLevels == tinfo.mipLevels); + assert(info.miscFlags == tinfo.miscFlags); + assert(info.format == tinfo.format); + assert(info.dimension == tinfo.dimension); + + image.swap(timage); + cimage.reset(); + } + // --- Generate mips ----------------------------------------------------------- DWORD dwFilter3D = dwFilter; if (!ispow2(info.width) || !ispow2(info.height) || !ispow2(info.depth))