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 */ 182 struct astcenc_context; 183 184 /** 185 * @brief A codec API error code. 186 */ 187 enum 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 */ 221 enum 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. */ 233 static const float ASTCENC_PRE_FASTEST = 0.0f; 234 235 /** @brief The fast search preset. */ 236 static const float ASTCENC_PRE_FAST = 10.0f; 237 238 /** @brief The medium quality search preset. */ 239 static const float ASTCENC_PRE_MEDIUM = 60.0f; 240 241 /** @brief The thorough quality search preset. */ 242 static const float ASTCENC_PRE_THOROUGH = 98.0f; 243 244 /** @brief The thorough quality search preset. */ 245 static const float ASTCENC_PRE_VERYTHOROUGH = 99.0f; 246 247 /** @brief The exhaustive, highest quality, search preset. */ 248 static const float ASTCENC_PRE_EXHAUSTIVE = 100.0f; 249 250 /** 251 * @brief A codec component swizzle selector. 252 */ 253 enum 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 */ 274 struct 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 */ 289 enum 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 */ 307 static 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 */ 315 static 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 */ 324 static 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 */ 332 static 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 */ 340 static 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 */ 350 static 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 */ 373 static const unsigned int ASTCENC_FLG_MAP_RGBM = 1 << 6; 374 375 /** 376 * @brief The bit mask of all valid flags. 377 */ 378 static 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 */ 397 struct 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 #if defined(ASTCENC_DIAGNOSTICS) 559 /** 560 * @brief The path to save the diagnostic trace data to. 561 * 562 * This option is not part of the public API, and requires special builds 563 * of the library. 564 */ 565 const char* trace_file_path; 566 #endif 567 }; 568 569 /** 570 * @brief An uncompressed 2D or 3D image. 571 * 572 * 3D image are passed in as an array of 2D slices. Each slice has identical 573 * size and color format. 574 */ 575 struct astcenc_image 576 { 577 /** @brief The X dimension of the image, in texels. */ 578 unsigned int dim_x; 579 580 /** @brief The Y dimension of the image, in texels. */ 581 unsigned int dim_y; 582 583 /** @brief The Z dimension of the image, in texels. */ 584 unsigned int dim_z; 585 586 /** @brief The data type per component. */ 587 astcenc_type data_type; 588 589 /** @brief The array of 2D slices, of length @c dim_z. */ 590 void** data; 591 }; 592 593 /** 594 * @brief A block encoding metadata query result. 595 * 596 * If the block is an error block or a constant color block or an error block all fields other than 597 * the profile, block dimensions, and error/constant indicator will be zero. 598 */ 599 struct astcenc_block_info 600 { 601 /** @brief The block encoding color profile. */ 602 astcenc_profile profile; 603 604 /** @brief The number of texels in the X dimension. */ 605 unsigned int block_x; 606 607 /** @brief The number of texels in the Y dimension. */ 608 unsigned int block_y; 609 610 /** @brief The number of texel in the Z dimension. */ 611 unsigned int block_z; 612 613 /** @brief The number of texels in the block. */ 614 unsigned int texel_count; 615 616 /** @brief True if this block is an error block. */ 617 bool is_error_block; 618 619 /** @brief True if this block is a constant color block. */ 620 bool is_constant_block; 621 622 /** @brief True if this block is an HDR block. */ 623 bool is_hdr_block; 624 625 /** @brief True if this block uses two weight planes. */ 626 bool is_dual_plane_block; 627 628 /** @brief The number of partitions if not constant color. */ 629 unsigned int partition_count; 630 631 /** @brief The partition index if 2 - 4 partitions used. */ 632 unsigned int partition_index; 633 634 /** @brief The component index of the second plane if dual plane. */ 635 unsigned int dual_plane_component; 636 637 /** @brief The color endpoint encoding mode for each partition. */ 638 unsigned int color_endpoint_modes[4]; 639 640 /** @brief The number of color endpoint quantization levels. */ 641 unsigned int color_level_count; 642 643 /** @brief The number of weight quantization levels. */ 644 unsigned int weight_level_count; 645 646 /** @brief The number of weights in the X dimension. */ 647 unsigned int weight_x; 648 649 /** @brief The number of weights in the Y dimension. */ 650 unsigned int weight_y; 651 652 /** @brief The number of weights in the Z dimension. */ 653 unsigned int weight_z; 654 655 /** @brief The unpacked color endpoints for each partition. */ 656 float color_endpoints[4][2][4]; 657 658 /** @brief The per-texel interpolation weights for the block. */ 659 float weight_values_plane1[216]; 660 661 /** @brief The per-texel interpolation weights for the block. */ 662 float weight_values_plane2[216]; 663 664 /** @brief The per-texel partition assignments for the block. */ 665 uint8_t partition_assignment[216]; 666 }; 667 668 /** 669 * Populate a codec config based on default settings. 670 * 671 * Power users can edit the returned config struct to fine tune before allocating the context. 672 * 673 * @param profile Color profile. 674 * @param block_x ASTC block size X dimension. 675 * @param block_y ASTC block size Y dimension. 676 * @param block_z ASTC block size Z dimension. 677 * @param quality Search quality preset / effort level. Either an 678 * @c ASTCENC_PRE_* value, or a effort level between 0 679 * and 100. Performance is not linear between 0 and 100. 680 681 * @param flags A valid set of @c ASTCENC_FLG_* flag bits. 682 * @param[out] config Output config struct to populate. 683 * 684 * @return @c ASTCENC_SUCCESS on success, or an error if the inputs are invalid 685 * either individually, or in combination. 686 */ 687 ASTCENC_PUBLIC astcenc_error astcenc_config_init( 688 astcenc_profile profile, 689 unsigned int block_x, 690 unsigned int block_y, 691 unsigned int block_z, 692 float quality, 693 unsigned int flags, 694 astcenc_config* config); 695 696 /** 697 * @brief Allocate a new codec context based on a config. 698 * 699 * This function allocates all of the memory resources and threads needed by the codec. This can be 700 * slow, so it is recommended that contexts are reused to serially compress or decompress multiple 701 * images to amortize setup cost. 702 * 703 * Contexts can be allocated to support only decompression using the @c ASTCENC_FLG_DECOMPRESS_ONLY 704 * flag when creating the configuration. The compression functions will fail if invoked. For a 705 * decompress-only library build the @c ASTCENC_FLG_DECOMPRESS_ONLY flag must be set when creating 706 * any context. 707 * 708 * @param[in] config Codec config. 709 * @param thread_count Thread count to configure for. 710 * @param[out] context Location to store an opaque context pointer. 711 * 712 * @return @c ASTCENC_SUCCESS on success, or an error if context creation failed. 713 */ 714 ASTCENC_PUBLIC astcenc_error astcenc_context_alloc( 715 const astcenc_config* config, 716 unsigned int thread_count, 717 astcenc_context** context); 718 719 /** 720 * @brief Compress an image. 721 * 722 * A single context can only compress or decompress a single image at a time. 723 * 724 * For a context configured for multi-threading, any set of the N threads can call this function. 725 * Work will be dynamically scheduled across the threads available. Each thread must have a unique 726 * @c thread_index. 727 * 728 * @param context Codec context. 729 * @param[in,out] image An input image, in 2D slices. 730 * @param swizzle Compression data swizzle, applied before compression. 731 * @param[out] data_out Pointer to output data array. 732 * @param data_len Length of the output data array. 733 * @param thread_index Thread index [0..N-1] of calling thread. 734 * 735 * @return @c ASTCENC_SUCCESS on success, or an error if compression failed. 736 */ 737 ASTCENC_PUBLIC astcenc_error astcenc_compress_image( 738 astcenc_context* context, 739 astcenc_image* image, 740 const astcenc_swizzle* swizzle, 741 uint8_t* data_out, 742 size_t data_len, 743 unsigned int thread_index); 744 745 /** 746 * @brief Reset the codec state for a new compression. 747 * 748 * The caller is responsible for synchronizing threads in the worker thread pool. This function must 749 * only be called when all threads have exited the @c astcenc_compress_image() function for image N, 750 * but before any thread enters it for image N + 1. 751 * 752 * Calling this is not required (but won't hurt), if the context is created for single threaded use. 753 * 754 * @param context Codec context. 755 * 756 * @return @c ASTCENC_SUCCESS on success, or an error if reset failed. 757 */ 758 ASTCENC_PUBLIC astcenc_error astcenc_compress_reset( 759 astcenc_context* context); 760 761 /** 762 * @brief Decompress an image. 763 * 764 * @param context Codec context. 765 * @param[in] data Pointer to compressed data. 766 * @param data_len Length of the compressed data, in bytes. 767 * @param[in,out] image_out Output image. 768 * @param swizzle Decompression data swizzle, applied after decompression. 769 * @param thread_index Thread index [0..N-1] of calling thread. 770 * 771 * @return @c ASTCENC_SUCCESS on success, or an error if decompression failed. 772 */ 773 ASTCENC_PUBLIC astcenc_error astcenc_decompress_image( 774 astcenc_context* context, 775 const uint8_t* data, 776 size_t data_len, 777 astcenc_image* image_out, 778 const astcenc_swizzle* swizzle, 779 unsigned int thread_index); 780 781 /** 782 * @brief Reset the codec state for a new decompression. 783 * 784 * The caller is responsible for synchronizing threads in the worker thread pool. This function must 785 * only be called when all threads have exited the @c astcenc_decompress_image() function for image 786 * N, but before any thread enters it for image N + 1. 787 * 788 * Calling this is not required (but won't hurt), if the context is created for single threaded use. 789 * 790 * @param context Codec context. 791 * 792 * @return @c ASTCENC_SUCCESS on success, or an error if reset failed. 793 */ 794 ASTCENC_PUBLIC astcenc_error astcenc_decompress_reset( 795 astcenc_context* context); 796 797 /** 798 * Free the compressor context. 799 * 800 * @param context The codec context. 801 */ 802 ASTCENC_PUBLIC void astcenc_context_free( 803 astcenc_context* context); 804 805 /** 806 * @brief Provide a high level summary of a block's encoding. 807 * 808 * This feature is primarily useful for codec developers but may be useful for developers building 809 * advanced content packaging pipelines. 810 * 811 * @param context Codec context. 812 * @param data One block of compressed ASTC data. 813 * @param info The output info structure to populate. 814 * 815 * @return @c ASTCENC_SUCCESS if the block was decoded, or an error otherwise. Note that this 816 * function will return success even if the block itself was an error block encoding, as the 817 * decode was correctly handled. 818 */ 819 ASTCENC_PUBLIC astcenc_error astcenc_get_block_info( 820 astcenc_context* context, 821 const uint8_t data[16], 822 astcenc_block_info* info); 823 824 /** 825 * @brief Get a printable string for specific status code. 826 * 827 * @param status The status value. 828 * 829 * @return A human readable nul-terminated string. 830 */ 831 ASTCENC_PUBLIC const char* astcenc_get_error_string( 832 astcenc_error status); 833 834 #endif 835