1 // SPDX-License-Identifier: Apache-2.0 2 // ---------------------------------------------------------------------------- 3 // Copyright 2020-2024 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 #if defined(__aarch64__) 173 #define ASTCENC_NEON 1 174 #else 175 #define ASTCENC_NEON 0 176 #endif 177 178 enum QualityProfile { 179 HIGH_QUALITY_PROFILE = 0, // default profile 180 HIGH_SPEED_PROFILE, 181 CUSTOMIZED_PROFILE, 182 HIGH_SPEED_PROFILE_HIGHBITS 183 }; 184 185 static const int HIGH_SPEED_PROFILE_BLOCK_MODE = 67; // keep openSource type, example 186 static const int BYTE_MASK = 0xFF; 187 188 #define QUALITY_CONTROL (1) 189 #if QUALITY_CONTROL 190 enum ComponentRGBA { 191 R_COM = 0, 192 G_COM, 193 B_COM, 194 A_COM, 195 RGBA_COM 196 }; 197 #endif 198 199 #if defined(ASTCENC_DYNAMIC_LIBRARY) 200 #if defined(_MSC_VER) 201 #define ASTCENC_PUBLIC extern "C" __declspec(dllexport) 202 #else 203 #define ASTCENC_PUBLIC extern "C" __attribute__ ((visibility ("default"))) 204 #endif 205 #else 206 #define ASTCENC_PUBLIC 207 #endif 208 209 /* ============================================================================ 210 Data declarations 211 ============================================================================ */ 212 213 /** 214 * @brief An opaque structure; see astcenc_internal.h for definition. 215 */ 216 struct astcenc_context; 217 218 /** 219 * @brief A codec API error code. 220 */ 221 enum astcenc_error { 222 /** @brief The call was successful. */ 223 ASTCENC_SUCCESS = 0, 224 /** @brief The call failed due to low memory, or undersized I/O buffers. */ 225 ASTCENC_ERR_OUT_OF_MEM, 226 /** @brief The call failed due to the build using fast math. */ 227 ASTCENC_ERR_BAD_CPU_FLOAT, 228 /** @brief The call failed due to an out-of-spec parameter. */ 229 ASTCENC_ERR_BAD_PARAM, 230 /** @brief The call failed due to an out-of-spec block size. */ 231 ASTCENC_ERR_BAD_BLOCK_SIZE, 232 /** @brief The call failed due to an out-of-spec color profile. */ 233 ASTCENC_ERR_BAD_PROFILE, 234 /** @brief The call failed due to an out-of-spec quality value. */ 235 ASTCENC_ERR_BAD_QUALITY, 236 /** @brief The call failed due to an out-of-spec component swizzle. */ 237 ASTCENC_ERR_BAD_SWIZZLE, 238 /** @brief The call failed due to an out-of-spec flag set. */ 239 ASTCENC_ERR_BAD_FLAGS, 240 /** @brief The call failed due to the context not supporting the operation. */ 241 ASTCENC_ERR_BAD_CONTEXT, 242 /** @brief The call failed due to unimplemented functionality. */ 243 ASTCENC_ERR_NOT_IMPLEMENTED, 244 /** @brief The call failed due to an out-of-spec decode mode flag set. */ 245 ASTCENC_ERR_BAD_DECODE_MODE, 246 #if defined(ASTCENC_DIAGNOSTICS) 247 /** @brief The call failed due to an issue with diagnostic tracing. */ 248 ASTCENC_ERR_DTRACE_FAILURE, 249 #endif 250 #if QUALITY_CONTROL 251 ASTCENC_ERR_BAD_QUALITY_CHECK, 252 #endif 253 #ifdef ASTC_CUSTOMIZED_ENABLE 254 ASTCENC_ERR_DLOPEN_FAILED 255 #endif 256 }; 257 258 /** 259 * @brief A codec color profile. 260 */ 261 enum astcenc_profile { 262 /** @brief The LDR sRGB color profile. */ 263 ASTCENC_PRF_LDR_SRGB = 0, 264 /** @brief The LDR linear color profile. */ 265 ASTCENC_PRF_LDR, 266 /** @brief The HDR RGB with LDR alpha color profile. */ 267 ASTCENC_PRF_HDR_RGB_LDR_A, 268 /** @brief The HDR RGBA color profile. */ 269 ASTCENC_PRF_HDR 270 }; 271 272 /** @brief The fastest, lowest quality, search preset. */ 273 static const float ASTCENC_PRE_FASTEST = 0.0f; 274 275 /** @brief The fast search preset. */ 276 static const float ASTCENC_PRE_FAST = 10.0f; 277 278 /** @brief The medium quality search preset. */ 279 static const float ASTCENC_PRE_MEDIUM = 60.0f; 280 281 /** @brief The thorough quality search preset. */ 282 static const float ASTCENC_PRE_THOROUGH = 98.0f; 283 284 /** @brief The thorough quality search preset. */ 285 static const float ASTCENC_PRE_VERYTHOROUGH = 99.0f; 286 287 /** @brief The exhaustive, highest quality, search preset. */ 288 static const float ASTCENC_PRE_EXHAUSTIVE = 100.0f; 289 290 /** 291 * @brief A codec component swizzle selector. 292 */ 293 enum astcenc_swz 294 { 295 /** @brief Select the red component. */ 296 ASTCENC_SWZ_R = 0, 297 /** @brief Select the green component. */ 298 ASTCENC_SWZ_G = 1, 299 /** @brief Select the blue component. */ 300 ASTCENC_SWZ_B = 2, 301 /** @brief Select the alpha component. */ 302 ASTCENC_SWZ_A = 3, 303 /** @brief Use a constant zero component. */ 304 ASTCENC_SWZ_0 = 4, 305 /** @brief Use a constant one component. */ 306 ASTCENC_SWZ_1 = 5, 307 /** @brief Use a reconstructed normal vector Z component. */ 308 ASTCENC_SWZ_Z = 6 309 }; 310 311 /** 312 * @brief A texel component swizzle. 313 */ 314 struct astcenc_swizzle 315 { 316 /** @brief The red component selector. */ 317 astcenc_swz r; 318 /** @brief The green component selector. */ 319 astcenc_swz g; 320 /** @brief The blue component selector. */ 321 astcenc_swz b; 322 /** @brief The alpha component selector. */ 323 astcenc_swz a; 324 }; 325 326 /** 327 * @brief A texel component data format. 328 */ 329 enum astcenc_type 330 { 331 /** @brief Unorm 8-bit data per component. */ 332 ASTCENC_TYPE_U8 = 0, 333 /** @brief 16-bit float per component. */ 334 ASTCENC_TYPE_F16 = 1, 335 /** @brief 32-bit float per component. */ 336 ASTCENC_TYPE_F32 = 2, 337 /** @brief 32-bit RGBA 1010102 data. */ 338 ASTCENC_TYPE_RGBA1010102 = 3 339 }; 340 341 /** 342 * @brief Function pointer type for compression progress reporting callback. 343 */ 344 extern "C" typedef void (*astcenc_progress_callback)(float); 345 346 /** 347 * @brief Enable normal map compression. 348 * 349 * Input data will be treated a two component normal map, storing X and Y, and the codec will 350 * optimize for angular error rather than simple linear PSNR. In this mode the input swizzle should 351 * be e.g. rrrg (the default ordering for ASTC normals on the command line) or gggr (the ordering 352 * used by BC5n). 353 */ 354 static const unsigned int ASTCENC_FLG_MAP_NORMAL = 1 << 0; 355 356 /** 357 * @brief Enable compression heuristics that assume use of decode_unorm8 decode mode. 358 * 359 * The decode_unorm8 decode mode rounds differently to the decode_fp16 decode mode, so enabling this 360 * flag during compression will allow the compressor to use the correct rounding when selecting 361 * encodings. This will improve the compressed image quality if your application is using the 362 * decode_unorm8 decode mode, but will reduce image quality if using decode_fp16. 363 * 364 * Note that LDR_SRGB images will always use decode_unorm8 for the RGB channels, irrespective of 365 * this setting. 366 */ 367 static const unsigned int ASTCENC_FLG_USE_DECODE_UNORM8 = 1 << 1; 368 369 /** 370 * @brief Enable alpha weighting. 371 * 372 * The input alpha value is used for transparency, so errors in the RGB components are weighted by 373 * the transparency level. This allows the codec to more accurately encode the alpha value in areas 374 * where the color value is less significant. 375 */ 376 static const unsigned int ASTCENC_FLG_USE_ALPHA_WEIGHT = 1 << 2; 377 378 /** 379 * @brief Enable perceptual error metrics. 380 * 381 * This mode enables perceptual compression mode, which will optimize for perceptual error rather 382 * than best PSNR. Only some input modes support perceptual error metrics. 383 */ 384 static const unsigned int ASTCENC_FLG_USE_PERCEPTUAL = 1 << 3; 385 386 /** 387 * @brief Create a decompression-only context. 388 * 389 * This mode disables support for compression. This enables context allocation to skip some 390 * transient buffer allocation, resulting in lower memory usage. 391 */ 392 static const unsigned int ASTCENC_FLG_DECOMPRESS_ONLY = 1 << 4; 393 394 /** 395 * @brief Create a self-decompression context. 396 * 397 * This mode configures the compressor so that it is only guaranteed to be able to decompress images 398 * that were actually created using the current context. This is the common case for compression use 399 * cases, and setting this flag enables additional optimizations, but does mean that the context 400 * cannot reliably decompress arbitrary ASTC images. 401 */ 402 static const unsigned int ASTCENC_FLG_SELF_DECOMPRESS_ONLY = 1 << 5; 403 404 /** 405 * @brief Enable RGBM map compression. 406 * 407 * Input data will be treated as HDR data that has been stored in an LDR RGBM-encoded wrapper 408 * format. Data must be preprocessed by the user to be in LDR RGBM format before calling the 409 * compression function, this flag is only used to control the use of RGBM-specific heuristics and 410 * error metrics. 411 * 412 * IMPORTANT: The ASTC format is prone to bad failure modes with unconstrained RGBM data; very small 413 * M values can round to zero due to quantization and result in black or white pixels. It is highly 414 * recommended that the minimum value of M used in the encoding is kept above a lower threshold (try 415 * 16 or 32). Applying this threshold reduces the number of very dark colors that can be 416 * represented, but is still higher precision than 8-bit LDR. 417 * 418 * When this flag is set the value of @c rgbm_m_scale in the context must be set to the RGBM scale 419 * factor used during reconstruction. This defaults to 5 when in RGBM mode. 420 * 421 * It is recommended that the value of @c cw_a_weight is set to twice the value of the multiplier 422 * scale, ensuring that the M value is accurately encoded. This defaults to 10 when in RGBM mode, 423 * matching the default scale factor. 424 */ 425 static const unsigned int ASTCENC_FLG_MAP_RGBM = 1 << 6; 426 427 /** 428 * @brief The bit mask of all valid flags. 429 */ 430 static const unsigned int ASTCENC_ALL_FLAGS = 431 ASTCENC_FLG_MAP_NORMAL | 432 ASTCENC_FLG_MAP_RGBM | 433 ASTCENC_FLG_USE_ALPHA_WEIGHT | 434 ASTCENC_FLG_USE_PERCEPTUAL | 435 ASTCENC_FLG_USE_DECODE_UNORM8 | 436 ASTCENC_FLG_DECOMPRESS_ONLY | 437 ASTCENC_FLG_SELF_DECOMPRESS_ONLY; 438 439 /** 440 * @brief The config structure. 441 * 442 * This structure will initially be populated by a call to astcenc_config_init, but power users may 443 * modify it before calling astcenc_context_alloc. See astcenccli_toplevel_help.cpp for full user 444 * documentation of the power-user settings. 445 * 446 * Note for any settings which are associated with a specific color component, the value in the 447 * config applies to the component that exists after any compression data swizzle is applied. 448 */ 449 struct astcenc_config 450 { 451 /** @brief The color profile. */ 452 astcenc_profile profile; 453 454 /** @brief The set of set flags. */ 455 unsigned int flags; 456 457 /** @brief The ASTC block size X dimension. */ 458 unsigned int block_x; 459 460 /** @brief The ASTC block size Y dimension. */ 461 unsigned int block_y; 462 463 /** @brief The ASTC block size Z dimension. */ 464 unsigned int block_z; 465 466 /** @brief The red component weight scale for error weighting (-cw). */ 467 float cw_r_weight; 468 469 /** @brief The green component weight scale for error weighting (-cw). */ 470 float cw_g_weight; 471 472 /** @brief The blue component weight scale for error weighting (-cw). */ 473 float cw_b_weight; 474 475 /** @brief The alpha component weight scale for error weighting (-cw). */ 476 float cw_a_weight; 477 478 /** 479 * @brief The radius for any alpha-weight scaling (-a). 480 * 481 * It is recommended that this is set to 1 when using FLG_USE_ALPHA_WEIGHT on a texture that 482 * will be sampled using linear texture filtering to minimize color bleed out of transparent 483 * texels that are adjacent to non-transparent texels. 484 */ 485 unsigned int a_scale_radius; 486 487 /** @brief The RGBM scale factor for the shared multiplier (-rgbm). */ 488 float rgbm_m_scale; 489 490 /** 491 * @brief The maximum number of partitions searched (-partitioncountlimit). 492 * 493 * Valid values are between 1 and 4. 494 */ 495 unsigned int tune_partition_count_limit; 496 497 /** 498 * @brief The maximum number of partitions searched (-2partitionindexlimit). 499 * 500 * Valid values are between 1 and 1024. 501 */ 502 unsigned int tune_2partition_index_limit; 503 504 /** 505 * @brief The maximum number of partitions searched (-3partitionindexlimit). 506 * 507 * Valid values are between 1 and 1024. 508 */ 509 unsigned int tune_3partition_index_limit; 510 511 /** 512 * @brief The maximum number of partitions searched (-4partitionindexlimit). 513 * 514 * Valid values are between 1 and 1024. 515 */ 516 unsigned int tune_4partition_index_limit; 517 518 /** 519 * @brief The maximum centile for block modes searched (-blockmodelimit). 520 * 521 * Valid values are between 1 and 100. 522 */ 523 unsigned int tune_block_mode_limit; 524 525 /** 526 * @brief The maximum iterative refinements applied (-refinementlimit). 527 * 528 * Valid values are between 1 and N; there is no technical upper limit 529 * but little benefit is expected after N=4. 530 */ 531 unsigned int tune_refinement_limit; 532 533 /** 534 * @brief The number of trial candidates per mode search (-candidatelimit). 535 * 536 * Valid values are between 1 and TUNE_MAX_TRIAL_CANDIDATES. 537 */ 538 unsigned int tune_candidate_limit; 539 540 /** 541 * @brief The number of trial partitionings per search (-2partitioncandidatelimit). 542 * 543 * Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES. 544 */ 545 unsigned int tune_2partitioning_candidate_limit; 546 547 /** 548 * @brief The number of trial partitionings per search (-3partitioncandidatelimit). 549 * 550 * Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES. 551 */ 552 unsigned int tune_3partitioning_candidate_limit; 553 554 /** 555 * @brief The number of trial partitionings per search (-4partitioncandidatelimit). 556 * 557 * Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES. 558 */ 559 unsigned int tune_4partitioning_candidate_limit; 560 561 /** 562 * @brief The dB threshold for stopping block search (-dblimit). 563 * 564 * This option is ineffective for HDR textures. 565 */ 566 float tune_db_limit; 567 568 /** 569 * @brief The amount of MSE overshoot needed to early-out trials. 570 * 571 * The first early-out is for 1 partition, 1 plane trials, where we try a minimal encode using 572 * the high probability block modes. This can short-cut compression for simple blocks. 573 * 574 * The second early-out is for refinement trials, where we can exit refinement once quality is 575 * reached. 576 */ 577 float tune_mse_overshoot; 578 579 /** 580 * @brief The threshold for skipping 3.1/4.1 trials (-2partitionlimitfactor). 581 * 582 * This option is further scaled for normal maps, so it skips less often. 583 */ 584 float tune_2partition_early_out_limit_factor; 585 586 /** 587 * @brief The threshold for skipping 4.1 trials (-3partitionlimitfactor). 588 * 589 * This option is further scaled for normal maps, so it skips less often. 590 */ 591 float tune_3partition_early_out_limit_factor; 592 593 /** 594 * @brief The threshold for skipping two weight planes (-2planelimitcorrelation). 595 * 596 * This option is ineffective for normal maps. 597 */ 598 float tune_2plane_early_out_limit_correlation; 599 600 /** 601 * @brief The config enable for the mode0 fast-path search. 602 * 603 * If this is set to TUNE_MIN_TEXELS_MODE0 or higher then the early-out fast mode0 604 * search is enabled. This option is ineffective for 3D block sizes. 605 */ 606 float tune_search_mode0_enable; 607 608 /** 609 * @brief The progress callback, can be @c nullptr. 610 * 611 * If this is specified the codec will peridocially report progress for 612 * compression as a percentage between 0 and 100. The callback is called from one 613 * of the compressor threads, so doing significant work in the callback will 614 * reduce compression performance. 615 */ 616 astcenc_progress_callback progress_callback; 617 618 #if defined(ASTCENC_DIAGNOSTICS) 619 /** 620 * @brief The path to save the diagnostic trace data to. 621 * 622 * This option is not part of the public API, and requires special builds 623 * of the library. 624 */ 625 const char* trace_file_path; 626 #endif 627 QualityProfile privateProfile; 628 }; 629 630 /** 631 * @brief An uncompressed 2D or 3D image. 632 * 633 * 3D image are passed in as an array of 2D slices. Each slice has identical 634 * size and color format. 635 */ 636 struct astcenc_image 637 { 638 /** @brief The stride dimension of the image, in texels. */ 639 unsigned int dim_stride; 640 641 /** @brief The X dimension of the image, in texels. */ 642 unsigned int dim_x; 643 644 /** @brief The Y dimension of the image, in texels. */ 645 unsigned int dim_y; 646 647 /** @brief The Z dimension of the image, in texels. */ 648 unsigned int dim_z; 649 650 /** @brief The data type per component. */ 651 astcenc_type data_type; 652 653 /** @brief The array of 2D slices, of length @c dim_z. */ 654 void** data; 655 }; 656 657 /** 658 * @brief A block encoding metadata query result. 659 * 660 * If the block is an error block or a constant color block or an error block all fields other than 661 * the profile, block dimensions, and error/constant indicator will be zero. 662 */ 663 struct astcenc_block_info 664 { 665 /** @brief The block encoding color profile. */ 666 astcenc_profile profile; 667 668 /** @brief The number of texels in the X dimension. */ 669 unsigned int block_x; 670 671 /** @brief The number of texels in the Y dimension. */ 672 unsigned int block_y; 673 674 /** @brief The number of texel in the Z dimension. */ 675 unsigned int block_z; 676 677 /** @brief The number of texels in the block. */ 678 unsigned int texel_count; 679 680 /** @brief True if this block is an error block. */ 681 bool is_error_block; 682 683 /** @brief True if this block is a constant color block. */ 684 bool is_constant_block; 685 686 /** @brief True if this block is an HDR block. */ 687 bool is_hdr_block; 688 689 /** @brief True if this block uses two weight planes. */ 690 bool is_dual_plane_block; 691 692 /** @brief The number of partitions if not constant color. */ 693 unsigned int partition_count; 694 695 /** @brief The partition index if 2 - 4 partitions used. */ 696 unsigned int partition_index; 697 698 /** @brief The component index of the second plane if dual plane. */ 699 unsigned int dual_plane_component; 700 701 /** @brief The color endpoint encoding mode for each partition. */ 702 unsigned int color_endpoint_modes[4]; 703 704 /** @brief The number of color endpoint quantization levels. */ 705 unsigned int color_level_count; 706 707 /** @brief The number of weight quantization levels. */ 708 unsigned int weight_level_count; 709 710 /** @brief The number of weights in the X dimension. */ 711 unsigned int weight_x; 712 713 /** @brief The number of weights in the Y dimension. */ 714 unsigned int weight_y; 715 716 /** @brief The number of weights in the Z dimension. */ 717 unsigned int weight_z; 718 719 /** @brief The unpacked color endpoints for each partition. */ 720 float color_endpoints[4][2][4]; 721 722 /** @brief The per-texel interpolation weights for the block. */ 723 float weight_values_plane1[216]; 724 725 /** @brief The per-texel interpolation weights for the block. */ 726 float weight_values_plane2[216]; 727 728 /** @brief The per-texel partition assignments for the block. */ 729 uint8_t partition_assignment[216]; 730 }; 731 732 /** 733 * Populate a codec config based on default settings. 734 * 735 * Power users can edit the returned config struct to fine tune before allocating the context. 736 * 737 * @param profile Color profile. 738 * @param block_x ASTC block size X dimension. 739 * @param block_y ASTC block size Y dimension. 740 * @param block_z ASTC block size Z dimension. 741 * @param quality Search quality preset / effort level. Either an 742 * @c ASTCENC_PRE_* value, or a effort level between 0 743 * and 100. Performance is not linear between 0 and 100. 744 745 * @param flags A valid set of @c ASTCENC_FLG_* flag bits. 746 * @param[out] config Output config struct to populate. 747 * 748 * @return @c ASTCENC_SUCCESS on success, or an error if the inputs are invalid 749 * either individually, or in combination. 750 */ 751 ASTCENC_PUBLIC astcenc_error astcenc_config_init( 752 astcenc_profile profile, 753 unsigned int block_x, 754 unsigned int block_y, 755 unsigned int block_z, 756 float quality, 757 unsigned int flags, 758 astcenc_config* config); 759 760 /** 761 * @brief Allocate a new codec context based on a config. 762 * 763 * This function allocates all of the memory resources and threads needed by the codec. This can be 764 * slow, so it is recommended that contexts are reused to serially compress or decompress multiple 765 * images to amortize setup cost. 766 * 767 * Contexts can be allocated to support only decompression using the @c ASTCENC_FLG_DECOMPRESS_ONLY 768 * flag when creating the configuration. The compression functions will fail if invoked. For a 769 * decompress-only library build the @c ASTCENC_FLG_DECOMPRESS_ONLY flag must be set when creating 770 * any context. 771 * 772 * @param[in] config Codec config. 773 * @param thread_count Thread count to configure for. 774 * @param[out] context Location to store an opaque context pointer. 775 * 776 * @return @c ASTCENC_SUCCESS on success, or an error if context creation failed. 777 */ 778 ASTCENC_PUBLIC astcenc_error astcenc_context_alloc( 779 const astcenc_config* config, 780 unsigned int thread_count, 781 astcenc_context** context); 782 783 /** 784 * @brief Compress an image. 785 * 786 * A single context can only compress or decompress a single image at a time. 787 * 788 * For a context configured for multi-threading, any set of the N threads can call this function. 789 * Work will be dynamically scheduled across the threads available. Each thread must have a unique 790 * @c thread_index. 791 * 792 * @param context Codec context. 793 * @param[in,out] image An input image, in 2D slices. 794 * @param swizzle Compression data swizzle, applied before compression. 795 * @param[out] data_out Pointer to output data array. 796 * @param data_len Length of the output data array. 797 * @param thread_index Thread index [0..N-1] of calling thread. 798 * 799 * @return @c ASTCENC_SUCCESS on success, or an error if compression failed. 800 */ 801 ASTCENC_PUBLIC astcenc_error astcenc_compress_image( 802 astcenc_context* context, 803 astcenc_image* image, 804 const astcenc_swizzle* swizzle, 805 uint8_t* data_out, 806 size_t data_len, 807 #if QUALITY_CONTROL 808 bool calQualityEnable, 809 int32_t *mse[RGBA_COM], 810 #endif 811 unsigned int thread_index); 812 813 /** 814 * @brief Reset the codec state for a new compression. 815 * 816 * The caller is responsible for synchronizing threads in the worker thread pool. This function must 817 * only be called when all threads have exited the @c astcenc_compress_image() function for image N, 818 * but before any thread enters it for image N + 1. 819 * 820 * Calling this is not required (but won't hurt), if the context is created for single threaded use. 821 * 822 * @param context Codec context. 823 * 824 * @return @c ASTCENC_SUCCESS on success, or an error if reset failed. 825 */ 826 ASTCENC_PUBLIC astcenc_error astcenc_compress_reset( 827 astcenc_context* context); 828 829 /** 830 * @brief Decompress an image. 831 * 832 * @param context Codec context. 833 * @param[in] data Pointer to compressed data. 834 * @param data_len Length of the compressed data, in bytes. 835 * @param[in,out] image_out Output image. 836 * @param swizzle Decompression data swizzle, applied after decompression. 837 * @param thread_index Thread index [0..N-1] of calling thread. 838 * 839 * @return @c ASTCENC_SUCCESS on success, or an error if decompression failed. 840 */ 841 ASTCENC_PUBLIC astcenc_error astcenc_decompress_image( 842 astcenc_context* context, 843 const uint8_t* data, 844 size_t data_len, 845 astcenc_image* image_out, 846 const astcenc_swizzle* swizzle, 847 unsigned int thread_index); 848 849 /** 850 * @brief Reset the codec state for a new decompression. 851 * 852 * The caller is responsible for synchronizing threads in the worker thread pool. This function must 853 * only be called when all threads have exited the @c astcenc_decompress_image() function for image 854 * N, but before any thread enters it for image N + 1. 855 * 856 * Calling this is not required (but won't hurt), if the context is created for single threaded use. 857 * 858 * @param context Codec context. 859 * 860 * @return @c ASTCENC_SUCCESS on success, or an error if reset failed. 861 */ 862 ASTCENC_PUBLIC astcenc_error astcenc_decompress_reset( 863 astcenc_context* context); 864 865 /** 866 * Free the compressor context. 867 * 868 * @param context The codec context. 869 */ 870 ASTCENC_PUBLIC void astcenc_context_free( 871 astcenc_context* context); 872 873 /** 874 * @brief Provide a high level summary of a block's encoding. 875 * 876 * This feature is primarily useful for codec developers but may be useful for developers building 877 * advanced content packaging pipelines. 878 * 879 * @param context Codec context. 880 * @param data One block of compressed ASTC data. 881 * @param info The output info structure to populate. 882 * 883 * @return @c ASTCENC_SUCCESS if the block was decoded, or an error otherwise. Note that this 884 * function will return success even if the block itself was an error block encoding, as the 885 * decode was correctly handled. 886 */ 887 ASTCENC_PUBLIC astcenc_error astcenc_get_block_info( 888 astcenc_context* context, 889 const uint8_t data[16], 890 astcenc_block_info* info); 891 892 /** 893 * @brief Get a printable string for specific status code. 894 * 895 * @param status The status value. 896 * 897 * @return A human readable nul-terminated string. 898 */ 899 ASTCENC_PUBLIC const char* astcenc_get_error_string( 900 astcenc_error status); 901 902 #endif 903