1// SPDX-License-Identifier: Apache-2.0
2// ----------------------------------------------------------------------------
3// Copyright 2020-2023 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 The core astcenc codec library interface.
20 *
21 * This interface is the entry point to the core astcenc codec. It aims to be easy to use for
22 * non-experts, but also to allow experts to have fine control over the compressor heuristics if
23 * needed. The core codec only handles compression and decompression, transferring all inputs and
24 * outputs via memory buffers. To catch obvious input/output buffer sizing issues, which can cause
25 * security and stability problems, all transfer buffers are explicitly sized.
26 *
27 * While the aim is that we keep this interface mostly stable, it should be viewed as a mutable
28 * interface tied to a specific source version. We are not trying to maintain backwards
29 * compatibility across codec versions.
30 *
31 * The API state management is based around an explicit context object, which is the context for all
32 * allocated memory resources needed to compress and decompress a single image. A context can be
33 * used to sequentially compress multiple images using the same configuration, allowing setup
34 * overheads to be amortized over multiple images, which is particularly important when images are
35 * small.
36 *
37 * Multi-threading can be used two ways.
38 *
39 * * An application wishing to process multiple images in parallel can allocate multiple
40 * contexts and assign each context to a thread.
41 * * An application wishing to process a single image in using multiple threads can configure
42 * contexts for multi-threaded use, and invoke astcenc_compress/decompress() once per thread
43 * for faster processing. The caller is responsible for creating the worker threads, and
44 * synchronizing between images.
45 *
46 * Extended instruction set support
47 * ================================
48 *
49 * This library supports use of extended instruction sets, such as SSE4.1 and AVX2. These are
50 * enabled at compile time when building the library. There is no runtime checking in the core
51 * library that the instruction sets used are actually available. Checking compatibility is the
52 * responsibility of the calling code.
53 *
54 * Threading
55 * =========
56 *
57 * In pseudo-code, the usage for manual user threading looks like this:
58 *
59 * // Configure the compressor run
60 * astcenc_config my_config;
61 * astcenc_config_init(..., &my_config);
62 *
63 * // Power users can tweak <my_config> settings here ...
64 *
65 * // Allocate working state given config and thread_count
66 * astcenc_context* my_context;
67 * astcenc_context_alloc(&my_config, thread_count, &my_context);
68 *
69 * // Compress each image using these config settings
70 * foreach image:
71 * // For each thread in the thread pool
72 * for i in range(0, thread_count):
73 * astcenc_compress_image(my_context, &my_input, my_output, i);
74 *
75 * astcenc_compress_reset(my_context);
76 *
77 * // Clean up
78 * astcenc_context_free(my_context);
79 *
80 * Images
81 * ======
82 *
83 * The codec supports compressing single images, which can be either 2D images or volumetric 3D
84 * images. Calling code is responsible for any handling of aggregate types, such as mipmap chains,
85 * texture arrays, or sliced 3D textures.
86 *
87 * Images are passed in as an astcenc_image structure. Inputs can be either 8-bit unorm, 16-bit
88 * half-float, or 32-bit float, as indicated by the data_type field.
89 *
90 * Images can be any dimension; there is no requirement to be a multiple of the ASTC block size.
91 *
92 * Data is always passed in as 4 color components, and accessed as an array of 2D image slices. Data
93 * within an image slice is always tightly packed without padding. Addressing looks like this:
94 *
95 * data[z_coord][y_coord * x_dim * 4 + x_coord * 4 ] // Red
96 * data[z_coord][y_coord * x_dim * 4 + x_coord * 4 + 1] // Green
97 * data[z_coord][y_coord * x_dim * 4 + x_coord * 4 + 2] // Blue
98 * data[z_coord][y_coord * x_dim * 4 + x_coord * 4 + 3] // Alpha
99 *
100 * Common compressor usage
101 * =======================
102 *
103 * One of the most important things for coding image quality is to align the input data component
104 * count with the ASTC color endpoint mode. This avoids wasting bits encoding components you don't
105 * actually need in the endpoint colors.
106 *
107 * | Input data | Encoding swizzle | Sampling swizzle |
108 * | ------------ | ---------------- | ---------------- |
109 * | 1 component | RRR1 | .[rgb] |
110 * | 2 components | RRRG | .[rgb]a |
111 * | 3 components | RGB1 | .rgb |
112 * | 4 components | RGBA | .rgba |
113 *
114 * The 1 and 2 component modes recommend sampling from "g" to recover the luminance value as this
115 * provide best compatibility with other texture formats where the green component may be stored at
116 * higher precision than the others, such as RGB565. For ASTC any of the RGB components can be used;
117 * the luminance endpoint component will be returned for all three.
118 *
119 * When using the normal map compression mode ASTC will store normals as a two component X+Y map.
120 * Input images must contain unit-length normalized and should be passed in using a two component
121 * swizzle. The astcenc command line tool defaults to an RRRG swizzle, but some developers prefer
122 * to use GGGR for compatability with BC5n which will work just as well. The Z component can be
123 * recovered programmatically in shader code, using knowledge that the vector is unit length and
124 * that Z must be positive for a tangent-space normal map.
125 *
126 * Decompress-only usage
127 * =====================
128 *
129 * For some use cases it is useful to have a cut-down context and/or library which supports
130 * decompression but not compression.
131 *
132 * A context can be made decompress-only using the ASTCENC_FLG_DECOMPRESS_ONLY flag when the context
133 * is allocated. These contexts have lower dynamic memory footprint than a full context.
134 *
135 * The entire library can be made decompress-only by building the files with the define
136 * ASTCENC_DECOMPRESS_ONLY set. In this build the context will be smaller, and the library will
137 * exclude the functionality which is only needed for compression. This reduces the binary size by
138 * ~180KB. For these builds contexts must be created with the ASTCENC_FLG_DECOMPRESS_ONLY flag.
139 *
140 * Note that context structures returned by a library built as decompress-only are incompatible with
141 * a library built with compression included, and visa versa, as they have different sizes and
142 * memory layout.
143 *
144 * Self-decompress-only usage
145 * ==========================
146 *
147 * ASTC is a complex format with a large search space. The parts of this search space that are
148 * searched is determined by heuristics that are, in part, tied to the quality level used when
149 * creating the context.
150 *
151 * A normal context is capable of decompressing any ASTC texture, including those generated by other
152 * compressors with unknown heuristics. This is the most flexible implementation, but forces the
153 * data tables used by the codec to include entries that are not needed during compression. This
154 * can slow down context creation by a significant amount, especially for the faster compression
155 * modes where few data table entries are actually used. To optimize this use case the context can
156 * be created with the ASTCENC_FLG_SELF_DECOMPRESS_ONLY flag. This tells the compressor that it will
157 * only be asked to decompress images that it compressed itself, allowing the data tables to
158 * exclude entries that are not needed by the current compression configuration. This reduces the
159 * size of the context data tables in memory and improves context creation performance. Note that,
160 * as of the 3.6 release, this flag no longer affects compression performance.
161 *
162 * Using this flag while attempting to decompress an valid image which was created by another
163 * compressor, or even another astcenc compressor version or configuration, may result in blocks
164 * returning as solid magenta or NaN value error blocks.
165 */
166
167#ifndef ASTCENC_INCLUDED
168#define ASTCENC_INCLUDED
169
170#include <cstddef>
171#include <cstdint>
172
173#if defined(ASTCENC_DYNAMIC_LIBRARY)
174 #if defined(_MSC_VER)
175 #define ASTCENC_PUBLIC extern "C" __declspec(dllexport)
176 #else
177 #define ASTCENC_PUBLIC extern "C" __attribute__ ((visibility ("default")))
178 #endif
179#else
180 #define ASTCENC_PUBLIC
181#endif
182
183/* ============================================================================
184 Data declarations
185============================================================================ */
186
187/**
188 * @brief An opaque structure; see astcenc_internal.h for definition.
189 */
190struct astcenc_context;
191
192/**
193 * @brief A codec API error code.
194 */
195enum astcenc_error {
196 /** @brief The call was successful. */
197 ASTCENC_SUCCESS = 0,
198 /** @brief The call failed due to low memory, or undersized I/O buffers. */
199 ASTCENC_ERR_OUT_OF_MEM,
200 /** @brief The call failed due to the build using fast math. */
201 ASTCENC_ERR_BAD_CPU_FLOAT,
202 /** @brief The call failed due to an out-of-spec parameter. */
203 ASTCENC_ERR_BAD_PARAM,
204 /** @brief The call failed due to an out-of-spec block size. */
205 ASTCENC_ERR_BAD_BLOCK_SIZE,
206 /** @brief The call failed due to an out-of-spec color profile. */
207 ASTCENC_ERR_BAD_PROFILE,
208 /** @brief The call failed due to an out-of-spec quality value. */
209 ASTCENC_ERR_BAD_QUALITY,
210 /** @brief The call failed due to an out-of-spec component swizzle. */
211 ASTCENC_ERR_BAD_SWIZZLE,
212 /** @brief The call failed due to an out-of-spec flag set. */
213 ASTCENC_ERR_BAD_FLAGS,
214 /** @brief The call failed due to the context not supporting the operation. */
215 ASTCENC_ERR_BAD_CONTEXT,
216 /** @brief The call failed due to unimplemented functionality. */
217 ASTCENC_ERR_NOT_IMPLEMENTED,
218#if defined(ASTCENC_DIAGNOSTICS)
219 /** @brief The call failed due to an issue with diagnostic tracing. */
220 ASTCENC_ERR_DTRACE_FAILURE,
221#endif
222};
223
224/**
225 * @brief A codec color profile.
226 */
227enum astcenc_profile {
228 /** @brief The LDR sRGB color profile. */
229 ASTCENC_PRF_LDR_SRGB = 0,
230 /** @brief The LDR linear color profile. */
231 ASTCENC_PRF_LDR,
232 /** @brief The HDR RGB with LDR alpha color profile. */
233 ASTCENC_PRF_HDR_RGB_LDR_A,
234 /** @brief The HDR RGBA color profile. */
235 ASTCENC_PRF_HDR
236};
237
238/** @brief The fastest, lowest quality, search preset. */
239static const float ASTCENC_PRE_FASTEST = 0.0f;
240
241/** @brief The fast search preset. */
242static const float ASTCENC_PRE_FAST = 10.0f;
243
244/** @brief The medium quality search preset. */
245static const float ASTCENC_PRE_MEDIUM = 60.0f;
246
247/** @brief The thorough quality search preset. */
248static const float ASTCENC_PRE_THOROUGH = 98.0f;
249
250/** @brief The thorough quality search preset. */
251static const float ASTCENC_PRE_VERYTHOROUGH = 99.0f;
252
253/** @brief The exhaustive, highest quality, search preset. */
254static const float ASTCENC_PRE_EXHAUSTIVE = 100.0f;
255
256/**
257 * @brief A codec component swizzle selector.
258 */
259enum astcenc_swz
260{
261 /** @brief Select the red component. */
262 ASTCENC_SWZ_R = 0,
263 /** @brief Select the green component. */
264 ASTCENC_SWZ_G = 1,
265 /** @brief Select the blue component. */
266 ASTCENC_SWZ_B = 2,
267 /** @brief Select the alpha component. */
268 ASTCENC_SWZ_A = 3,
269 /** @brief Use a constant zero component. */
270 ASTCENC_SWZ_0 = 4,
271 /** @brief Use a constant one component. */
272 ASTCENC_SWZ_1 = 5,
273 /** @brief Use a reconstructed normal vector Z component. */
274 ASTCENC_SWZ_Z = 6
275};
276
277/**
278 * @brief A texel component swizzle.
279 */
280struct astcenc_swizzle
281{
282 /** @brief The red component selector. */
283 astcenc_swz r;
284 /** @brief The green component selector. */
285 astcenc_swz g;
286 /** @brief The blue component selector. */
287 astcenc_swz b;
288 /** @brief The alpha component selector. */
289 astcenc_swz a;
290};
291
292/**
293 * @brief A texel component data format.
294 */
295enum astcenc_type
296{
297 /** @brief Unorm 8-bit data per component. */
298 ASTCENC_TYPE_U8 = 0,
299 /** @brief 16-bit float per component. */
300 ASTCENC_TYPE_F16 = 1,
301 /** @brief 32-bit float per component. */
302 ASTCENC_TYPE_F32 = 2
303};
304
305/**
306 * @brief Enable normal map compression.
307 *
308 * Input data will be treated a two component normal map, storing X and Y, and the codec will
309 * optimize for angular error rather than simple linear PSNR. In this mode the input swizzle should
310 * be e.g. rrrg (the default ordering for ASTC normals on the command line) or gggr (the ordering
311 * used by BC5n).
312 */
313static const unsigned int ASTCENC_FLG_MAP_NORMAL = 1 << 0;
314
315/**
316 * @brief Enable alpha weighting.
317 *
318 * The input alpha value is used for transparency, so errors in the RGB components are weighted by
319 * the transparency level. This allows the codec to more accurately encode the alpha value in areas
320 * where the color value is less significant.
321 */
322static const unsigned int ASTCENC_FLG_USE_ALPHA_WEIGHT = 1 << 2;
323
324/**
325 * @brief Enable perceptual error metrics.
326 *
327 * This mode enables perceptual compression mode, which will optimize for perceptual error rather
328 * than best PSNR. Only some input modes support perceptual error metrics.
329 */
330static const unsigned int ASTCENC_FLG_USE_PERCEPTUAL = 1 << 3;
331
332/**
333 * @brief Create a decompression-only context.
334 *
335 * This mode disables support for compression. This enables context allocation to skip some
336 * transient buffer allocation, resulting in lower memory usage.
337 */
338static const unsigned int ASTCENC_FLG_DECOMPRESS_ONLY = 1 << 4;
339
340/**
341 * @brief Create a self-decompression context.
342 *
343 * This mode configures the compressor so that it is only guaranteed to be able to decompress images
344 * that were actually created using the current context. This is the common case for compression use
345 * cases, and setting this flag enables additional optimizations, but does mean that the context
346 * cannot reliably decompress arbitrary ASTC images.
347 */
348static const unsigned int ASTCENC_FLG_SELF_DECOMPRESS_ONLY = 1 << 5;
349
350/**
351 * @brief Enable RGBM map compression.
352 *
353 * Input data will be treated as HDR data that has been stored in an LDR RGBM-encoded wrapper
354 * format. Data must be preprocessed by the user to be in LDR RGBM format before calling the
355 * compression function, this flag is only used to control the use of RGBM-specific heuristics and
356 * error metrics.
357 *
358 * IMPORTANT: The ASTC format is prone to bad failure modes with unconstrained RGBM data; very small
359 * M values can round to zero due to quantization and result in black or white pixels. It is highly
360 * recommended that the minimum value of M used in the encoding is kept above a lower threshold (try
361 * 16 or 32). Applying this threshold reduces the number of very dark colors that can be
362 * represented, but is still higher precision than 8-bit LDR.
363 *
364 * When this flag is set the value of @c rgbm_m_scale in the context must be set to the RGBM scale
365 * factor used during reconstruction. This defaults to 5 when in RGBM mode.
366 *
367 * It is recommended that the value of @c cw_a_weight is set to twice the value of the multiplier
368 * scale, ensuring that the M value is accurately encoded. This defaults to 10 when in RGBM mode,
369 * matching the default scale factor.
370 */
371static const unsigned int ASTCENC_FLG_MAP_RGBM = 1 << 6;
372
373/**
374 * @brief The bit mask of all valid flags.
375 */
376static const unsigned int ASTCENC_ALL_FLAGS =
377 ASTCENC_FLG_MAP_NORMAL |
378 ASTCENC_FLG_MAP_RGBM |
379 ASTCENC_FLG_USE_ALPHA_WEIGHT |
380 ASTCENC_FLG_USE_PERCEPTUAL |
381 ASTCENC_FLG_DECOMPRESS_ONLY |
382 ASTCENC_FLG_SELF_DECOMPRESS_ONLY;
383
384/**
385 * @brief The config structure.
386 *
387 * This structure will initially be populated by a call to astcenc_config_init, but power users may
388 * modify it before calling astcenc_context_alloc. See astcenccli_toplevel_help.cpp for full user
389 * documentation of the power-user settings.
390 *
391 * Note for any settings which are associated with a specific color component, the value in the
392 * config applies to the component that exists after any compression data swizzle is applied.
393 */
394struct astcenc_config
395{
396 /** @brief The color profile. */
397 astcenc_profile profile;
398
399 /** @brief The set of set flags. */
400 unsigned int flags;
401
402 /** @brief The ASTC block size X dimension. */
403 unsigned int block_x;
404
405 /** @brief The ASTC block size Y dimension. */
406 unsigned int block_y;
407
408 /** @brief The ASTC block size Z dimension. */
409 unsigned int block_z;
410
411 /** @brief The red component weight scale for error weighting (-cw). */
412 float cw_r_weight;
413
414 /** @brief The green component weight scale for error weighting (-cw). */
415 float cw_g_weight;
416
417 /** @brief The blue component weight scale for error weighting (-cw). */
418 float cw_b_weight;
419
420 /** @brief The alpha component weight scale for error weighting (-cw). */
421 float cw_a_weight;
422
423 /**
424 * @brief The radius for any alpha-weight scaling (-a).
425 *
426 * It is recommended that this is set to 1 when using FLG_USE_ALPHA_WEIGHT on a texture that
427 * will be sampled using linear texture filtering to minimize color bleed out of transparent
428 * texels that are adjacent to non-transparent texels.
429 */
430 unsigned int a_scale_radius;
431
432 /** @brief The RGBM scale factor for the shared multiplier (-rgbm). */
433 float rgbm_m_scale;
434
435 /**
436 * @brief The maximum number of partitions searched (-partitioncountlimit).
437 *
438 * Valid values are between 1 and 4.
439 */
440 unsigned int tune_partition_count_limit;
441
442 /**
443 * @brief The maximum number of partitions searched (-2partitionindexlimit).
444 *
445 * Valid values are between 1 and 1024.
446 */
447 unsigned int tune_2partition_index_limit;
448
449 /**
450 * @brief The maximum number of partitions searched (-3partitionindexlimit).
451 *
452 * Valid values are between 1 and 1024.
453 */
454 unsigned int tune_3partition_index_limit;
455
456 /**
457 * @brief The maximum number of partitions searched (-4partitionindexlimit).
458 *
459 * Valid values are between 1 and 1024.
460 */
461 unsigned int tune_4partition_index_limit;
462
463 /**
464 * @brief The maximum centile for block modes searched (-blockmodelimit).
465 *
466 * Valid values are between 1 and 100.
467 */
468 unsigned int tune_block_mode_limit;
469
470 /**
471 * @brief The maximum iterative refinements applied (-refinementlimit).
472 *
473 * Valid values are between 1 and N; there is no technical upper limit
474 * but little benefit is expected after N=4.
475 */
476 unsigned int tune_refinement_limit;
477
478 /**
479 * @brief The number of trial candidates per mode search (-candidatelimit).
480 *
481 * Valid values are between 1 and TUNE_MAX_TRIAL_CANDIDATES.
482 */
483 unsigned int tune_candidate_limit;
484
485 /**
486 * @brief The number of trial partitionings per search (-2partitioncandidatelimit).
487 *
488 * Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES.
489 */
490 unsigned int tune_2partitioning_candidate_limit;
491
492 /**
493 * @brief The number of trial partitionings per search (-3partitioncandidatelimit).
494 *
495 * Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES.
496 */
497 unsigned int tune_3partitioning_candidate_limit;
498
499 /**
500 * @brief The number of trial partitionings per search (-4partitioncandidatelimit).
501 *
502 * Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES.
503 */
504 unsigned int tune_4partitioning_candidate_limit;
505
506 /**
507 * @brief The dB threshold for stopping block search (-dblimit).
508 *
509 * This option is ineffective for HDR textures.
510 */
511 float tune_db_limit;
512
513 /**
514 * @brief The amount of MSE overshoot needed to early-out trials.
515 *
516 * The first early-out is for 1 partition, 1 plane trials, where we try a minimal encode using
517 * the high probability block modes. This can short-cut compression for simple blocks.
518 *
519 * The second early-out is for refinement trials, where we can exit refinement once quality is
520 * reached.
521 */
522 float tune_mse_overshoot;
523
524 /**
525 * @brief The threshold for skipping 3.1/4.1 trials (-2partitionlimitfactor).
526 *
527 * This option is further scaled for normal maps, so it skips less often.
528 */
529 float tune_2partition_early_out_limit_factor;
530
531 /**
532 * @brief The threshold for skipping 4.1 trials (-3partitionlimitfactor).
533 *
534 * This option is further scaled for normal maps, so it skips less often.
535 */
536 float tune_3partition_early_out_limit_factor;
537
538 /**
539 * @brief The threshold for skipping two weight planes (-2planelimitcorrelation).
540 *
541 * This option is ineffective for normal maps.
542 */
543 float tune_2plane_early_out_limit_correlation;
544
545#if defined(ASTCENC_DIAGNOSTICS)
546 /**
547 * @brief The path to save the diagnostic trace data to.
548 *
549 * This option is not part of the public API, and requires special builds
550 * of the library.
551 */
552 const char* trace_file_path;
553#endif
554};
555
556/**
557 * @brief An uncompressed 2D or 3D image.
558 *
559 * 3D image are passed in as an array of 2D slices. Each slice has identical
560 * size and color format.
561 */
562struct astcenc_image
563{
564 /** @brief The X dimension of the image, in texels. */
565 unsigned int dim_x;
566
567 /** @brief The Y dimension of the image, in texels. */
568 unsigned int dim_y;
569
570 /** @brief The Z dimension of the image, in texels. */
571 unsigned int dim_z;
572
573 /** @brief The data type per component. */
574 astcenc_type data_type;
575
576 /** @brief The array of 2D slices, of length @c dim_z. */
577 void** data;
578};
579
580/**
581 * @brief A block encoding metadata query result.
582 *
583 * If the block is an error block or a constant color block or an error block all fields other than
584 * the profile, block dimensions, and error/constant indicator will be zero.
585 */
586struct astcenc_block_info
587{
588 /** @brief The block encoding color profile. */
589 astcenc_profile profile;
590
591 /** @brief The number of texels in the X dimension. */
592 unsigned int block_x;
593
594 /** @brief The number of texels in the Y dimension. */
595 unsigned int block_y;
596
597 /** @brief The number of texel in the Z dimension. */
598 unsigned int block_z;
599
600 /** @brief The number of texels in the block. */
601 unsigned int texel_count;
602
603 /** @brief True if this block is an error block. */
604 bool is_error_block;
605
606 /** @brief True if this block is a constant color block. */
607 bool is_constant_block;
608
609 /** @brief True if this block is an HDR block. */
610 bool is_hdr_block;
611
612 /** @brief True if this block uses two weight planes. */
613 bool is_dual_plane_block;
614
615 /** @brief The number of partitions if not constant color. */
616 unsigned int partition_count;
617
618 /** @brief The partition index if 2 - 4 partitions used. */
619 unsigned int partition_index;
620
621 /** @brief The component index of the second plane if dual plane. */
622 unsigned int dual_plane_component;
623
624 /** @brief The color endpoint encoding mode for each partition. */
625 unsigned int color_endpoint_modes[4];
626
627 /** @brief The number of color endpoint quantization levels. */
628 unsigned int color_level_count;
629
630 /** @brief The number of weight quantization levels. */
631 unsigned int weight_level_count;
632
633 /** @brief The number of weights in the X dimension. */
634 unsigned int weight_x;
635
636 /** @brief The number of weights in the Y dimension. */
637 unsigned int weight_y;
638
639 /** @brief The number of weights in the Z dimension. */
640 unsigned int weight_z;
641
642 /** @brief The unpacked color endpoints for each partition. */
643 float color_endpoints[4][2][4];
644
645 /** @brief The per-texel interpolation weights for the block. */
646 float weight_values_plane1[216];
647
648 /** @brief The per-texel interpolation weights for the block. */
649 float weight_values_plane2[216];
650
651 /** @brief The per-texel partition assignments for the block. */
652 uint8_t partition_assignment[216];
653};
654
655/**
656 * Populate a codec config based on default settings.
657 *
658 * Power users can edit the returned config struct to fine tune before allocating the context.
659 *
660 * @param profile Color profile.
661 * @param block_x ASTC block size X dimension.
662 * @param block_y ASTC block size Y dimension.
663 * @param block_z ASTC block size Z dimension.
664 * @param quality Search quality preset / effort level. Either an
665 * @c ASTCENC_PRE_* value, or a effort level between 0
666 * and 100. Performance is not linear between 0 and 100.
667
668 * @param flags A valid set of @c ASTCENC_FLG_* flag bits.
669 * @param[out] config Output config struct to populate.
670 *
671 * @return @c ASTCENC_SUCCESS on success, or an error if the inputs are invalid
672 * either individually, or in combination.
673 */
674ASTCENC_PUBLIC astcenc_error astcenc_config_init(
675 astcenc_profile profile,
676 unsigned int block_x,
677 unsigned int block_y,
678 unsigned int block_z,
679 float quality,
680 unsigned int flags,
681 astcenc_config* config);
682
683/**
684 * @brief Allocate a new codec context based on a config.
685 *
686 * This function allocates all of the memory resources and threads needed by the codec. This can be
687 * slow, so it is recommended that contexts are reused to serially compress or decompress multiple
688 * images to amortize setup cost.
689 *
690 * Contexts can be allocated to support only decompression using the @c ASTCENC_FLG_DECOMPRESS_ONLY
691 * flag when creating the configuration. The compression functions will fail if invoked. For a
692 * decompress-only library build the @c ASTCENC_FLG_DECOMPRESS_ONLY flag must be set when creating
693 * any context.
694 *
695 * @param[in] config Codec config.
696 * @param thread_count Thread count to configure for.
697 * @param[out] context Location to store an opaque context pointer.
698 *
699 * @return @c ASTCENC_SUCCESS on success, or an error if context creation failed.
700 */
701ASTCENC_PUBLIC astcenc_error astcenc_context_alloc(
702 const astcenc_config* config,
703 unsigned int thread_count,
704 astcenc_context** context);
705
706/**
707 * @brief Compress an image.
708 *
709 * A single context can only compress or decompress a single image at a time.
710 *
711 * For a context configured for multi-threading, any set of the N threads can call this function.
712 * Work will be dynamically scheduled across the threads available. Each thread must have a unique
713 * @c thread_index.
714 *
715 * @param context Codec context.
716 * @param[in,out] image An input image, in 2D slices.
717 * @param swizzle Compression data swizzle, applied before compression.
718 * @param[out] data_out Pointer to output data array.
719 * @param data_len Length of the output data array.
720 * @param thread_index Thread index [0..N-1] of calling thread.
721 *
722 * @return @c ASTCENC_SUCCESS on success, or an error if compression failed.
723 */
724ASTCENC_PUBLIC astcenc_error astcenc_compress_image(
725 astcenc_context* context,
726 astcenc_image* image,
727 const astcenc_swizzle* swizzle,
728 uint8_t* data_out,
729 size_t data_len,
730 unsigned int thread_index);
731
732/**
733 * @brief Reset the codec state for a new compression.
734 *
735 * The caller is responsible for synchronizing threads in the worker thread pool. This function must
736 * only be called when all threads have exited the @c astcenc_compress_image() function for image N,
737 * but before any thread enters it for image N + 1.
738 *
739 * Calling this is not required (but won't hurt), if the context is created for single threaded use.
740 *
741 * @param context Codec context.
742 *
743 * @return @c ASTCENC_SUCCESS on success, or an error if reset failed.
744 */
745ASTCENC_PUBLIC astcenc_error astcenc_compress_reset(
746 astcenc_context* context);
747
748/**
749 * @brief Decompress an image.
750 *
751 * @param context Codec context.
752 * @param[in] data Pointer to compressed data.
753 * @param data_len Length of the compressed data, in bytes.
754 * @param[in,out] image_out Output image.
755 * @param swizzle Decompression data swizzle, applied after decompression.
756 * @param thread_index Thread index [0..N-1] of calling thread.
757 *
758 * @return @c ASTCENC_SUCCESS on success, or an error if decompression failed.
759 */
760ASTCENC_PUBLIC astcenc_error astcenc_decompress_image(
761 astcenc_context* context,
762 const uint8_t* data,
763 size_t data_len,
764 astcenc_image* image_out,
765 const astcenc_swizzle* swizzle,
766 unsigned int thread_index);
767
768/**
769 * @brief Reset the codec state for a new decompression.
770 *
771 * The caller is responsible for synchronizing threads in the worker thread pool. This function must
772 * only be called when all threads have exited the @c astcenc_decompress_image() function for image
773 * N, but before any thread enters it for image N + 1.
774 *
775 * Calling this is not required (but won't hurt), if the context is created for single threaded use.
776 *
777 * @param context Codec context.
778 *
779 * @return @c ASTCENC_SUCCESS on success, or an error if reset failed.
780 */
781ASTCENC_PUBLIC astcenc_error astcenc_decompress_reset(
782 astcenc_context* context);
783
784/**
785 * Free the compressor context.
786 *
787 * @param context The codec context.
788 */
789ASTCENC_PUBLIC void astcenc_context_free(
790 astcenc_context* context);
791
792/**
793 * @brief Provide a high level summary of a block's encoding.
794 *
795 * This feature is primarily useful for codec developers but may be useful for developers building
796 * advanced content packaging pipelines.
797 *
798 * @param context Codec context.
799 * @param data One block of compressed ASTC data.
800 * @param info The output info structure to populate.
801 *
802 * @return @c ASTCENC_SUCCESS if the block was decoded, or an error otherwise. Note that this
803 * function will return success even if the block itself was an error block encoding, as the
804 * decode was correctly handled.
805 */
806ASTCENC_PUBLIC astcenc_error astcenc_get_block_info(
807 astcenc_context* context,
808 const uint8_t data[16],
809 astcenc_block_info* info);
810
811/**
812 * @brief Get a printable string for specific status code.
813 *
814 * @param status The status value.
815 *
816 * @return A human readable nul-terminated string.
817 */
818ASTCENC_PUBLIC const char* astcenc_get_error_string(
819 astcenc_error status);
820
821#endif
822