• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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