1 // SPDX-License-Identifier: Apache-2.0
2 // ----------------------------------------------------------------------------
3 // Copyright 2011-2022 Arm Limited
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
6 // use this file except in compliance with the License. You may obtain a copy
7 // of the License at:
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 // License for the specific language governing permissions and limitations
15 // under the License.
16 // ----------------------------------------------------------------------------
17
18 /**
19 * @brief Functions for printing build info and help messages.
20 */
21
22 #include "astcenccli_internal.h"
23 #include "astcenccli_version.h"
24
25 /** @brief The version header. */
26 static const char *astcenc_copyright_string =
27 R"(astcenc v%s, %u-bit %s%s%s
28 Copyright 2011-%s Arm Limited, all rights reserved
29 )";
30
31 /** @brief The short-form help text. */
32 static const char *astcenc_short_help =
33 R"(
34 Basic usage:
35
36 To compress an image use:
37 astcenc {-cl|-cs|-ch|-cH} <in> <out> <blockdim> <quality> [options]
38
39 e.g. using LDR profile, 8x6 blocks, and the thorough quality preset:
40 astcenc -cl kodim01.png kodim01.astc 8x6 -thorough
41
42 To decompress an image use:
43 astcenc {-dl|-ds|-dh|-dH} <in> <out>
44
45 e.g. using LDR profile:
46 astcenc -dl kodim01.astc kodim01.png
47
48 To perform a compression test, writing back the decompressed output, use:
49 astcenc {-tl|-ts|-th|-tH} <in> <out> <blockdim> <quality> [options]
50
51 e.g. using LDR profile, 8x6 blocks, and the thorough quality preset:
52 astcenc -tl kodim01.png kodim01-test.png 8x6 -thorough
53
54 The -*l options are used to configure the codec to support only the linear
55 LDR profile, preventing use of the HDR encoding features.
56
57 The -*s options are used to configure the codec to support only
58 the sRGB LDR profile, preventing use of the HDR encoding features. Input
59 texture data must be encoded in the sRGB colorspace for this option to
60 provide correct output results.
61
62 The -*h/-*H options are used to configure the codec to support the HDR ASTC
63 color profile. Textures compressed with this profile may fail to decompress
64 correctly on GPU hardware without HDR profile support. The -*h options
65 configure the compressor for HDR RGB components and an LDR alpha component.
66 The -*H options configure the compressor for HDR across all 4 components.
67
68 For full help documentation run 'astcenc -help'.
69 )";
70
71 /** @brief The long-form help text. */
72 static const char *astcenc_long_help = R"(
73 NAME
74 astcenc - compress or decompress images using the ASTC format
75
76 SYNOPSIS
77 astcenc {-h|-help}
78 astcenc {-v|-version}
79 astcenc {-cl|-cs|-ch|-cH} <in> <out> <blocksize> <quality> [options]
80 astcenc {-dl|-ds|-dh|-dH} <in> <out> <blocksize> <quality> [options]
81 astcenc {-tl|-ts|-th|-tH} <in> <out> <blocksize> <quality> [options]
82
83 DESCRIPTION
84 astcenc compresses image files into the Adaptive Scalable Texture
85 Compression (ASTC) image format, a lossy compression format design
86 for use in real-time graphics applications. It is a fully featured
87 compressor implementation, supporting all of the compression
88 profiles and block sizes specified by the ASTC format:
89
90 All color profiles (LDR linear, LDR sRGB, and HDR)
91 All 2D block sizes (4x4 though to 12x12)
92 All 3D block sizes (3x3x3 through to 6x6x6)
93
94 The compressor provides a flexible quality level, allowing users to
95 trade off compressed image quality against compression performance.
96 For ease of use, a number of quality presets are also provided. For
97 advanced users the compressor provides many additional control
98 options for fine tuning quality.
99
100 astcenc can also be used to decompress ASTC compressed images, and
101 perform compression image quality analysis.
102
103 COMPRESSION
104 To compress an image using the ASTC format you must specify the
105 color profile, the input file name, the output file name, the target
106 block size, and the quality preset.
107
108 The color profile is specified using the -cl (LDR linear), -cs (LDR
109 sRGB), -ch (HDR RGB, LDR A), or -cH (HDR RGBA) encoder options. Note
110 that not all GPUs implementing ASTC support the HDR profile.
111
112 The input file path must match a valid file format for compression,
113 and the output file format must be a valid output for compression.
114 See the FILE FORMATS section for the list of supported formats.
115
116 The block size must be a valid ASTC block size. Every block
117 compresses into 128 bits of compressed output, so the block size
118 determines the compressed data bitrate.
119
120 Supported 2D block sizes are:
121
122 4x4: 8.00 bpp 10x5: 2.56 bpp
123 5x4: 6.40 bpp 10x6: 2.13 bpp
124 5x5: 5.12 bpp 8x8: 2.00 bpp
125 6x5: 4.27 bpp 10x8: 1.60 bpp
126 6x6: 3.56 bpp 10x10: 1.28 bpp
127 8x5: 3.20 bpp 12x10: 1.07 bpp
128 8x6: 2.67 bpp 12x12: 0.89 bpp
129
130 Supported 3D block sizes are:
131
132 3x3x3: 4.74 bpp 5x5x4: 1.28 bpp
133 4x3x3: 3.56 bpp 5x5x5: 1.02 bpp
134 4x4x3: 2.67 bpp 6x5x5: 0.85 bpp
135 4x4x4: 2.00 bpp 6x6x5: 0.71 bpp
136 5x4x4: 1.60 bpp 6x6x6: 0.59 bpp
137
138 The quality level configures the quality-performance tradeoff for
139 the compressor; more complete searches of the search space improve
140 image quality at the expense of compression time. The quality level
141 can be set to any value between 0 (fastest) and 100 (thorough), or
142 to a fixed quality preset:
143
144 -fastest (equivalent to quality = 0)
145 -fast (equivalent to quality = 10)
146 -medium (equivalent to quality = 60)
147 -thorough (equivalent to quality = 98)
148 -exhaustive (equivalent to quality = 100)
149
150 For compression of production content we recommend using a quality
151 level equivalent to -medium or higher.
152
153 Using quality levels higher than -thorough will significantly
154 increase compression time, but typically only gives minor quality
155 improvements.
156
157 There are a number of additional compressor options which are useful
158 to consider for common usage, based on the type of image data being
159 compressed.
160
161 -mask
162 The input texture is a mask texture with unrelated data stored
163 in the various color components, so enable error heuristics that
164 aim to improve quality by minimizing the effect of error
165 cross-talk across the color components.
166
167 -normal
168 The input texture is a three component linear LDR normal map
169 storing unit length normals as (R=X, G=Y, B=Z). The output will
170 be a two component X+Y normal map stored as (RGB=X, A=Y). The Z
171 component can be recovered programmatically in shader code by
172 using the equation:
173
174 nml.xy = texture(...).ga; // Load in [0,1]
175 nml.xy = nml.xy * 2.0 - 1.0; // Unpack to [-1,1]
176 nml.z = sqrt(1 - dot(nml.xy, nml.xy)); // Compute Z
177
178 -rgbm <max>
179 The input texture is an RGBM encoded texture, storing values HDR
180 values between 0 and <max> in an LDR container format with a
181 shared multiplier. Shaders reconstruct the HDR value as:
182
183 vec3 hdr_value = tex.rgb * tex.a * max;
184
185 The compression behavior of the ASTC format for RGBM data
186 requires that the user's RGBM encoding preprocess keeps values
187 of M above a lower threshold to avoid them quantizing to zero
188 during compression. We recommend trying 16/255 or 32/255.
189
190 -perceptual
191 The codec should optimize perceptual error, instead of direct
192 RMS error. This aims to improves perceived image quality, but
193 typically lowers the measured PSNR score. Perceptual methods are
194 currently only available for normal maps and RGB color data.
195
196 -array <size>
197 Loads an array of <size> 2D image slices to use as a 3D image.
198 The input filename given is used is decorated with the postfix
199 "_<slice>" to find the file to load. For example, an input named
200 "input.png" would load as input_0.png, input_1.png, etc.
201
202 -pp-normalize
203 Run a preprocess over the image that forces normal vectors to
204 be unit length. Preprocessing applies before any codec encoding
205 swizzle, so normal data must be in the RGB components in the
206 source image.
207
208 -pp-premultiply
209 Run a preprocess over the image that scales RGB components in
210 the image by the alpha value. Preprocessing applies before any
211 codec encoding swizzle, so color data must be in the RGB
212 components in the source image.)"
213 // This split in the literals is needed for Visual Studio; the compiler
214 // will concatenate these two strings together ...
215 R"(
216
217 COMPRESSION TIPS & TRICKS
218 ASTC is a block-based format that can be prone to block artifacts.
219 If block artifacts are a problem when compressing a given texture,
220 increasing the compressor quality preset can help to alleviate the
221 problem.
222
223 If a texture exhibits severe block artifacts in only some of the
224 color components, which is a common problem for mask textures, then
225 using the -cw option to raise the weighting of the affected color
226 component(s) may help. For example, if the green color component is
227 particularly badly encoded then try '-cw 1 6 1 1'.
228
229 ADVANCED COMPRESSION
230 Error weighting options
231 -----------------------
232
233 These options provide low-level control of the codec error metric
234 computation, used to determine what good compression looks like.
235
236 -a <radius>
237 For textures with alpha component, scale per-texel weights by
238 the alpha value. The alpha value chosen for scaling of any
239 particular texel is taken as an average across a neighborhood of
240 the texel defined by the <radius> argument. Setting <radius> to
241 0 causes only the texel's own alpha to be used.
242
243 ASTC blocks that are entirely zero weighted, after the radius is
244 taken into account, are replaced by constant color blocks. This
245 is an RDO-like technique to improve compression ratio in any
246 application packaging compression that is applied.
247
248 -cw <red> <green> <blue> <alpha>
249 Assign an additional weight scaling to each color component,
250 allowing the components to be treated differently in terms of
251 error significance. Set values above 1 to increase a component's
252 significance, and values below 1 to decrease it. Set to 0 to
253 exclude a component from error computation.
254
255 -mpsnr <low> <high>
256 Set the low and high f-stop values for the mPSNR error metric.
257 The mPSNR error metric only applies to HDR textures.
258
259 Performance-quality tradeoff options
260 ------------------------------------
261
262 These options provide low-level control of the codec heuristics that
263 drive the performance-quality trade off. The presets vary by block
264 bitrate; the recommended starting point for a 4x4 block is very
265 different to a 8x8 block. The presets documented here are for the
266 high bitrate mode (fewer than 25 texels).
267
268 -partitioncountlimit <number>
269 Test up to and including <number> partitions for each block.
270 Higher numbers give better quality, as more complex blocks can
271 be encoded, but will increase search time. Preset defaults are:
272
273 -fastest : 2
274 -fast : 3
275 -medium : 4
276 -thorough : 4
277 -exhaustive : 4
278
279 -partitionindexlimit <number>
280 Test <number> block partition indices for each partition count.
281 Higher numbers give better quality, however large values give
282 diminishing returns especially for smaller block sizes. Preset
283 defaults are:
284
285 -fastest : 8
286 -fast : 12
287 -medium : 26
288 -thorough : 76
289 -exhaustive : 1024
290
291 -blockmodelimit <number>
292 Test block modes below <number> usage centile in an empirically
293 determined distribution of block mode frequency. This option is
294 ineffective for 3D textures. Preset defaults are:
295
296 -fastest : 40
297 -fast : 55
298 -medium : 76
299 -thorough : 93
300 -exhaustive : 100
301
302 -refinementlimit <value>
303 Iterate only <value> refinement iterations on colors and
304 weights. Minimum value is 1. Preset defaults are:
305
306 -fastest : 2
307 -fast : 3
308 -medium : 3
309 -thorough : 4
310 -exhaustive : 4
311
312 -candidatelimit <value>
313 Trial only <value> candidate encodings for each block mode:
314
315 -fastest : 2
316 -fast : 3
317 -medium : 3
318 -thorough : 4
319 -exhaustive : 4
320
321 -dblimit <number>
322 Stop compression work on a block as soon as the PSNR of the
323 block, measured in dB, exceeds <number>. This option is
324 ineffective for HDR textures. Preset defaults, where N is the
325 number of texels in a block, are:
326
327 -fastest : MAX(63-19*log10(N), 85-35*log10(N))
328 -fast : MAX(63-19*log10(N), 85-35*log10(N))
329 -medium : MAX(70-19*log10(N), 95-35*log10(N))
330 -thorough : MAX(77-19*log10(N), 105-35*log10(N))
331 -exhaustive : 999
332
333 -2partitionlimitfactor <factor>
334 Stop compression work on a block after only testing blocks with
335 up to two partitions and one plane of weights, unless the two
336 partition error term is lower than the error term from encoding
337 with one partition by more than the specified factor. Preset
338 defaults are:
339
340 -fastest : 1.0
341 -fast : 1.0
342 -medium : 1.2
343 -thorough : 2.5
344 -exhaustive : 10.0
345
346 -3partitionlimitfactor <factor>
347 Stop compression work on a block after only testing blocks with
348 up to three partitions and one plane of weights, unless the three
349 partition error term is lower than the error term from encoding
350 with two partitions by more than the specified factor. Preset
351 defaults are:
352
353 -fastest : 1.00
354 -fast : 1.10
355 -medium : 1.25
356 -thorough : 1.25
357 -exhaustive : 10.00
358
359 -2planelimitcorrelation <factor>
360 Stop compression after testing only one plane of weights, unless
361 the minimum color correlation factor between any pair of color
362 components is below this factor. This option is ineffective for
363 normal maps. Preset defaults are:
364
365 -fastest : 0.50
366 -fast : 0.65
367 -medium : 0.85
368 -thorough : 0.95
369 -exhaustive : 0.99
370
371 -lowweightmodelimit <weight count>
372 Use a simpler weight search for weight counts less than or
373 equal to this threshold. Preset defaults are bitrate dependent:
374
375 -fastest : 25
376 -fast : 20
377 -medium : 16
378 -thorough : 12
379 -exhaustive : 0
380
381 Other options
382 -------------
383
384 -esw <swizzle>
385 Swizzle the color components before compression. The swizzle is
386 specified using a 4-character string, which defines the output
387 format ordering. The characters may be taken from the set
388 [rgba01], selecting either input color components or a literal
389 zero or one. For example to swap the RG components, and replace
390 alpha with 1, the swizzle 'grb1' should be used.
391
392 The input swizzle takes place before any compression, and all
393 error weighting applied using the -cw option is applied to the
394 post-swizzle component ordering.
395
396 By default all 4 post-swizzle components are included in the
397 error metrics during compression. When using -esw to map two
398 component data to the L+A endpoint (e.g. -esw rrrg) the
399 luminance data stored in the RGB components will be weighted 3
400 times more strongly than the alpha component. This can be
401 corrected using the -cw option to zero the weights of unused
402 components; e.g. using -cw 1 0 0 1.
403
404 -dsw <swizzle>
405 Swizzle the color components after decompression. The swizzle is
406 specified using the same method as the -esw option, with support
407 for an additional "z" character. This is used to specify that
408 the compressed data stores an X+Y normal map, and that the Z
409 output component should be reconstructed from the two components
410 stored in the data. For the typical ASTC normal encoding, which
411 uses an 'rrrg' compression swizzle, you should specify an 'raz1'
412 swizzle for decompression.
413
414 -yflip
415 Flip the image in the vertical axis prior to compression and
416 after decompression. Note that using this option in a test mode
417 (-t*) will have no effect as the image will be flipped twice.
418
419 -j <threads>
420 Explicitly specify the number of threads to use in the codec. If
421 not specified, the codec will use one thread per CPU detected in
422 the system.
423
424 -silent
425 Suppresses all non-essential diagnostic output from the codec.
426 Error messages will always be printed, as will mandatory outputs
427 for the selected operation mode. For example, the test mode will
428 always output image quality metrics and compression time but
429 will suppress all other output.)"
430 // This split in the literals is needed for Visual Studio; the compiler
431 // will concatenate these two strings together ...
432 R"(
433
434 DECOMPRESSION
435 To decompress an image stored in the ASTC format you must specify
436 the color profile, the input file name, and the output file name.
437
438 The color profile is specified using the -dl (LDR linear), -ds (LDR
439 sRGB), -dh (HDR RGB, LDR A), or -dH (HDR RGBA) decoder options.
440
441 The input file path must match a valid file format for
442 decompression, and the output file format must be a valid output for
443 a decompressed image. Note that not all output formats that the
444 compression path can produce are supported for decompression. See
445 the FILE FORMATS section for the list of supported formats.
446
447 The -dsw option documented in ADVANCED COMPRESSION option
448 documentation is also relevant to decompression.
449
450 TEST
451 To perform a compression test which round-trips a single image
452 through compression and decompression and stores the decompressed
453 result back to file, you must specify same settings as COMPRESSION
454 other than swapping the color profile to select test mode. Note that
455 the compressed intermediate data is discarded in this mode.
456
457 The color profile is specified using the -tl (LDR linear), -ts (LDR
458 sRGB), -th (HDR RGB, LDR A), or -tH (HDR RGBA) encoder options.
459
460 This operation mode will print error metrics suitable for either LDR
461 and HDR images, allowing some assessment of the compression image
462 quality.
463
464 COMPRESSION FILE FORMATS
465 The following formats are supported as compression inputs:
466
467 LDR Formats:
468 BMP (*.bmp)
469 PNG (*.png)
470 Targa (*.tga)
471 JPEG (*.jpg)
472
473 HDR Formats:
474 OpenEXR (*.exr)
475 Radiance HDR (*.hdr)
476
477 Container Formats:
478 Khronos Texture KTX (*.ktx)
479 DirectDraw Surface DDS (*.dds)
480
481 For the KTX and DDS formats only a subset of the features of the
482 formats are supported:
483
484 Texture topology must be 2D, 2D-array, 3D, or cube-map. Note
485 that 2D-array textures are treated as 3D block input.
486
487 Texel format must be R, RG, RGB, BGR, RGBA, BGRA, L, or LA.
488
489 Only the first mipmap in the file will be read.
490
491 The following formats are supported as compression outputs:
492
493 ASTC (*.astc)
494 Khronos Texture KTX (*.ktx)
495
496
497 DECOMPRESSION FILE FORMATS
498 The following formats are supported as decompression inputs:
499
500 ASTC (*.astc)
501 Khronos Texture KTX (*.ktx)
502
503 The following formats are supported as decompression outputs:
504
505 LDR Formats:
506 BMP (*.bmp)
507 PNG (*.png)
508 Targa (*.tga)
509
510 HDR Formats:
511 OpenEXR (*.exr)
512 Radiance HDR (*.hdr)
513
514 Container Formats:
515 Khronos Texture KTX (*.ktx)
516 DirectDraw Surface DDS (*.dds)
517
518 QUICK REFERENCE
519
520 To compress an image use:
521 astcenc {-cl|-cs|-ch|-cH} <in> <out> <blockdim> <quality> [options]
522
523 To decompress an image use:
524 astcenc {-dl|-ds|-dh|-dH} <in> <out>
525
526 To perform a quality test use:
527 astcenc {-tl|-ts|-th|-tH} <in> <out> <blockdim> <quality> [options]
528
529 Mode -*l = linear LDR, -*s = sRGB LDR, -*h = HDR RGB/LDR A, -*H = HDR.
530 Quality = -fastest/-fast/-medium/-thorough/-exhaustive/a float [0-100].
531 )";
532
533 /* See header for documentation. */
astcenc_print_header()534 void astcenc_print_header()
535 {
536 #if (ASTCENC_AVX == 2)
537 const char* simdtype = "avx2";
538 #elif (ASTCENC_SSE == 41)
539 const char* simdtype = "sse4.1";
540 #elif (ASTCENC_SSE == 20)
541 const char* simdtype = "sse2";
542 #elif (ASTCENC_NEON == 1)
543 const char* simdtype = "neon";
544 #else
545 const char* simdtype = "none";
546 #endif
547
548 #if (ASTCENC_POPCNT == 1)
549 const char* pcnttype = "+popcnt";
550 #else
551 const char* pcnttype = "";
552 #endif
553
554 #if (ASTCENC_F16C == 1)
555 const char* f16ctype = "+f16c";
556 #else
557 const char* f16ctype = "";
558 #endif
559
560 unsigned int bits = static_cast<unsigned int>(sizeof(void*) * 8);
561 printf(astcenc_copyright_string,
562 VERSION_STRING, bits, simdtype, pcnttype, f16ctype, YEAR_STRING);
563 }
564
565 /* See header for documentation. */
astcenc_print_shorthelp()566 void astcenc_print_shorthelp()
567 {
568 astcenc_print_header();
569 printf("%s", astcenc_short_help);
570 }
571
572 /* See header for documentation. */
astcenc_print_longhelp()573 void astcenc_print_longhelp()
574 {
575 astcenc_print_header();
576 printf("%s", astcenc_long_help);
577 }
578