@@ -115,10 +115,12 @@ namespace
115
115
OPT_DIFF_COLOR,
116
116
OPT_THRESHOLD,
117
117
OPT_FILELIST,
118
- OPT_MAX
118
+ OPT_FLAGS_MAX,
119
+ OPT_VERSION,
120
+ OPT_HELP,
119
121
};
120
122
121
- static_assert (OPT_MAX <= 32 , " dwOptions is a unsigned int bitfield" );
123
+ static_assert (OPT_FLAGS_MAX <= 32 , " dwOptions is a unsigned int bitfield" );
122
124
123
125
// ////////////////////////////////////////////////////////////////////////////
124
126
// ////////////////////////////////////////////////////////////////////////////
@@ -141,9 +143,6 @@ namespace
141
143
{ L" f" , OPT_FORMAT },
142
144
{ L" if" , OPT_FILTER },
143
145
{ L" dword" , OPT_DDS_DWORD_ALIGN },
144
- { L" badtails" , OPT_DDS_BAD_DXTN_TAILS },
145
- { L" permissive" , OPT_DDS_PERMISSIVE },
146
- { L" ignoremips" , OPT_DDS_IGNORE_MIPS },
147
146
{ L" nologo" , OPT_NOLOGO },
148
147
{ L" o" , OPT_OUTPUTFILE },
149
148
{ L" l" , OPT_TOLOWER },
@@ -152,14 +151,44 @@ namespace
152
151
{ L" tu" , OPT_TYPELESS_UNORM },
153
152
{ L" tf" , OPT_TYPELESS_FLOAT },
154
153
{ L" xlum" , OPT_EXPAND_LUMINANCE },
155
- { L" targetx" , OPT_TARGET_PIXELX },
156
- { L" targety" , OPT_TARGET_PIXELY },
157
154
{ L" c" , OPT_DIFF_COLOR },
158
155
{ L" t" , OPT_THRESHOLD },
159
156
{ L" flist" , OPT_FILELIST },
157
+
158
+ // Deprecated options (recommend using new -- alternatives)
159
+ { L" badtails" , OPT_DDS_BAD_DXTN_TAILS },
160
+ { L" permissive" , OPT_DDS_PERMISSIVE },
161
+ { L" ignoremips" , OPT_DDS_IGNORE_MIPS },
162
+ { L" targetx" , OPT_TARGET_PIXELX },
163
+ { L" targety" , OPT_TARGET_PIXELY },
164
+
160
165
{ nullptr , 0 }
161
166
};
162
167
168
+ const SValue<uint32_t > g_pOptionsLong[] =
169
+ {
170
+ { L" bad-tails" , OPT_DDS_BAD_DXTN_TAILS },
171
+ { L" dword-alignment" , OPT_DDS_DWORD_ALIGN },
172
+ { L" expand-luminance" , OPT_EXPAND_LUMINANCE },
173
+ { L" file-list" , OPT_FILELIST },
174
+ { L" file-type" , OPT_FILETYPE },
175
+ { L" format" , OPT_FORMAT },
176
+ { L" help" , OPT_HELP },
177
+ { L" ignore-mips" , OPT_DDS_IGNORE_MIPS },
178
+ { L" image-filter" , OPT_FILTER },
179
+ { L" overwrite" , OPT_OVERWRITE },
180
+ { L" permissive" , OPT_DDS_PERMISSIVE },
181
+ { L" target-x" , OPT_TARGET_PIXELX },
182
+ { L" target-y" , OPT_TARGET_PIXELY },
183
+ { L" to-lowercase" , OPT_TOLOWER },
184
+ { L" typeless-unorm" , OPT_TYPELESS_UNORM },
185
+ { L" typeless-float" , OPT_TYPELESS_FLOAT },
186
+ { L" version" , OPT_VERSION },
187
+ { L" diff-color" , OPT_DIFF_COLOR },
188
+ { L" threshold" , OPT_THRESHOLD },
189
+ { nullptr , 0 }
190
+ };
191
+
163
192
#define DEFFMT (fmt ) { L## #fmt, DXGI_FORMAT_ ## fmt }
164
193
165
194
const SValue<DXGI_FORMAT> g_pFormats[] =
@@ -423,44 +452,51 @@ namespace
423
452
{
424
453
PrintLogo (false , g_ToolName, g_Description);
425
454
426
- static const wchar_t * const s_usage =
455
+ static const wchar_t * const s_usage =
427
456
L" Usage: texdiag <command> <options> [--] <files>\n "
428
- L" \n "
457
+ L" \n COMMANDS \ n"
429
458
L" info Output image metadata\n "
430
459
L" analyze Analyze and summarize image information\n "
431
460
L" compare Compare two images with MSE error metric\n "
432
461
L" diff Generate difference image from two images\n "
433
462
L" dumpbc Dump out compressed blocks (DDS BC only)\n "
434
463
L" dumpdds Dump out all the images in a complex DDS\n "
435
- L" \n "
464
+ L" \n OPTIONS \ n"
436
465
L" -r wildcard filename search is recursive\n "
437
- L" -if <filter> image filtering\n "
466
+ L" -flist <filename>, --file-list <filename>\n "
467
+ L" use text file with a list of input files (one per line)\n "
468
+ L" \n "
469
+ L" -if <filter>, --image-filter <filter> image filtering\n "
438
470
L" \n "
439
- L" (DDS input only)\n "
440
- L" -t{u|f} TYPELESS format is treated as UNORM or FLOAT\n "
441
- L" -dword Use DWORD instead of BYTE alignment\n "
442
- L" -badtails Fix for older DXTn with bad mipchain tails\n "
443
- L" -permissive Allow some DX9 variants with unusual header values\n "
444
- L" -ignoremips Reads just the top-level mip which reads some invalid files\n "
445
- L" -xlum expand legacy L8, L16, and A8P8 formats\n "
471
+ L" (DDS input only)\n "
472
+ L" -tu, --typeless-unorm TYPELESS format is treated as UNORM\n "
473
+ L" -tf, --typeless-float TYPELESS format is treated as FLOAT\n "
474
+ L" -dword, --dword-alignment Use DWORD instead of BYTE alignment\n "
475
+ L" --bad-tails Fix for older DXTn with bad mipchain tails\n "
476
+ L" --permissive Allow some DX9 variants with unusual header values\n "
477
+ L" --ignore-mips Reads just the top-level mip which reads some invalid files\n "
478
+ L" -xlum, --expand-luminance Expand legacy L8, L16, and A8P8 formats\n "
446
479
L" \n "
447
- L" (diff only)\n "
448
- L" -f <format> format\n "
449
- L" -o <path/filename> output filename for diff; output path for dumpdds\n "
450
- L" -l force output filename to lower case\n "
451
- L" -y overwrite existing output file (if any)\n "
452
- L" -c <hex-RGB> highlight difference color (defaults to off)\n "
453
- L" -t <threshold> highlight threshold (defaults to 0.25)\n "
480
+ L" (diff only)\n "
481
+ L" -f <format>, --format <format> pixel format for output\n "
482
+ L" -o <filename> output filename for diff\n "
483
+ L" -l, --to-lowercase force output filename to lower case\n "
484
+ L" -y, --overwrite overwrite existing output file (if any)\n "
485
+ L" -c <hex-RGB>, --diff-color <hex-RGB>\n "
486
+ L" highlight difference color (defaults to off)\n "
487
+ L" -t <threshold>, --threshold <threshold>\n "
488
+ L" highlight threshold (defaults to 0.25)\n "
454
489
L" \n "
455
490
L" (dumpbc only)\n "
456
- L" -targetx <num> dump pixels at location x (defaults to all)\n "
457
- L" -targety <num> dump pixels at location y (defaults to all)\n "
491
+ L" --target-x <num> dump pixels at location x (defaults to all)\n "
492
+ L" --target-y <num> dump pixels at location y (defaults to all)\n "
458
493
L" \n "
459
494
L" (dumpdds only)\n "
460
- L" -ft <filetype> output file type\n "
495
+ L" -o <path> output path for dumpdds\n "
496
+ L" -ft <filetype>, --file-type <filetype>\n "
497
+ " output file type\n "
461
498
L" \n "
462
499
L" -nologo suppress copyright message\n "
463
- L" -flist <filename> use text file with a list of input files (one per line)\n "
464
500
L" \n "
465
501
L" '-- ' is needed if any input filepath starts with the '-' or '/' character\n " ;
466
502
@@ -3062,50 +3098,76 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
3062
3098
std::list<SConversion> conversion;
3063
3099
bool allowOpts = true ;
3064
3100
3065
- for (int iArg = 2 ; iArg < argc; iArg++ )
3101
+ for (int iArg = 2 ; iArg < argc; ++iArg )
3066
3102
{
3067
3103
PWSTR pArg = argv[iArg];
3068
3104
3069
- if (allowOpts
3070
- && (' -' == pArg[0 ]) && (' -' == pArg[1 ]))
3105
+ if (allowOpts && ((' -' == pArg[0 ]) || (' /' == pArg[0 ])))
3071
3106
{
3072
- if (pArg[2 ] == 0 )
3073
- {
3074
- // "-- " is the POSIX standard for "end of options" marking to escape the '-' and '/' characters at the start of filepaths.
3075
- allowOpts = false ;
3076
- }
3077
- else if (!_wcsicmp (pArg, L" --version" ))
3078
- {
3079
- PrintLogo (true , g_ToolName, g_Description);
3080
- return 0 ;
3081
- }
3082
- else if (!_wcsicmp (pArg, L" --help" ))
3107
+ uint64_t dwOption = 0 ;
3108
+ PWSTR pValue = nullptr ;
3109
+
3110
+ if ((' -' == pArg[0 ]) && (' -' == pArg[1 ]))
3083
3111
{
3084
- PrintUsage ();
3085
- return 0 ;
3112
+ if (pArg[2 ] == 0 )
3113
+ {
3114
+ // "-- " is the POSIX standard for "end of options" marking to escape the '-' and '/' characters at the start of filepaths.
3115
+ allowOpts = false ;
3116
+ continue ;
3117
+ }
3118
+ else
3119
+ {
3120
+ pArg += 2 ;
3121
+
3122
+ for (pValue = pArg; *pValue && (' :' != *pValue) && (' =' != *pValue); ++pValue);
3123
+
3124
+ if (*pValue)
3125
+ *pValue++ = 0 ;
3126
+
3127
+ dwOption = LookupByName (pArg, g_pOptionsLong);
3128
+
3129
+ if (dwOption == OPT_VERSION)
3130
+ {
3131
+ PrintLogo (true , g_ToolName, g_Description);
3132
+ return 0 ;
3133
+ }
3134
+ else if (dwOption == OPT_HELP)
3135
+ {
3136
+ PrintUsage ();
3137
+ return 0 ;
3138
+ }
3139
+ }
3086
3140
}
3087
3141
else
3088
3142
{
3089
- wprintf (L" Unknown option: %ls\n " , pArg);
3090
- return 1 ;
3091
- }
3092
- }
3093
- else if (allowOpts
3094
- && ((' -' == pArg[0 ]) || (' /' == pArg[0 ])))
3095
- {
3096
- pArg++;
3097
- PWSTR pValue;
3143
+ pArg++;
3098
3144
3099
- for (pValue = pArg; *pValue && (' :' != *pValue); pValue++ );
3145
+ for (pValue = pArg; *pValue && (' :' != *pValue) && ( ' = ' != * pValue); ++pValue );
3100
3146
3101
- if (*pValue)
3102
- *pValue++ = 0 ;
3147
+ if (*pValue)
3148
+ *pValue++ = 0 ;
3103
3149
3104
- const uint32_t dwOption = LookupByName (pArg, g_pOptions);
3150
+ dwOption = LookupByName (pArg, g_pOptions);
3151
+
3152
+ if (!dwOption)
3153
+ {
3154
+ if (LookupByName (pArg, g_pOptionsLong))
3155
+ {
3156
+ wprintf (L" ERROR: did you mean `--%ls` (with two dashes)?\n " , pArg);
3157
+ return 1 ;
3158
+ }
3159
+ }
3160
+ }
3161
+
3162
+ if (!dwOption)
3163
+ {
3164
+ wprintf (L" ERROR: Unknown option: `%ls`\n\n Use %ls --help\n " , pArg, g_ToolName);
3165
+ return 1 ;
3166
+ }
3105
3167
3106
- if (!dwOption || ( dwOptions & (1 << dwOption) ))
3168
+ if (dwOptions & (1 << dwOption))
3107
3169
{
3108
- PrintUsage ( );
3170
+ wprintf ( L" ERROR: Duplicate option: `%ls` \n\n " , pArg );
3109
3171
return 1 ;
3110
3172
}
3111
3173
0 commit comments