astcenc.h 31 KB

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