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