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 | */ |
190 | struct astcenc_context; |
191 | |
192 | /** |
193 | * @brief A codec API error code. |
194 | */ |
195 | enum 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 | */ |
227 | enum 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. */ |
239 | static const float ASTCENC_PRE_FASTEST = 0.0f; |
240 | |
241 | /** @brief The fast search preset. */ |
242 | static const float ASTCENC_PRE_FAST = 10.0f; |
243 | |
244 | /** @brief The medium quality search preset. */ |
245 | static const float ASTCENC_PRE_MEDIUM = 60.0f; |
246 | |
247 | /** @brief The thorough quality search preset. */ |
248 | static const float ASTCENC_PRE_THOROUGH = 98.0f; |
249 | |
250 | /** @brief The thorough quality search preset. */ |
251 | static const float ASTCENC_PRE_VERYTHOROUGH = 99.0f; |
252 | |
253 | /** @brief The exhaustive, highest quality, search preset. */ |
254 | static const float ASTCENC_PRE_EXHAUSTIVE = 100.0f; |
255 | |
256 | /** |
257 | * @brief A codec component swizzle selector. |
258 | */ |
259 | enum 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 | */ |
280 | struct 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 | */ |
295 | enum 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 | */ |
313 | static 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 | */ |
322 | static 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 | */ |
330 | static 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 | */ |
338 | static 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 | */ |
348 | static 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 | */ |
371 | static const unsigned int ASTCENC_FLG_MAP_RGBM = 1 << 6; |
372 | |
373 | /** |
374 | * @brief The bit mask of all valid flags. |
375 | */ |
376 | static 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 | */ |
394 | struct 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 | */ |
562 | struct 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 | */ |
586 | struct 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 | */ |
674 | ASTCENC_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 | */ |
701 | ASTCENC_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 | */ |
724 | ASTCENC_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 | */ |
745 | ASTCENC_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 | */ |
760 | ASTCENC_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 | */ |
781 | ASTCENC_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 | */ |
789 | ASTCENC_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 | */ |
806 | ASTCENC_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 | */ |
818 | ASTCENC_PUBLIC const char* astcenc_get_error_string( |
819 | astcenc_error status); |
820 | |
821 | #endif |
822 | |