1cc1dc7a3Sopenharmony_ci// SPDX-License-Identifier: Apache-2.0 2cc1dc7a3Sopenharmony_ci// ---------------------------------------------------------------------------- 3cc1dc7a3Sopenharmony_ci// Copyright 2011-2024 Arm Limited 4cc1dc7a3Sopenharmony_ci// 5cc1dc7a3Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); you may not 6cc1dc7a3Sopenharmony_ci// use this file except in compliance with the License. You may obtain a copy 7cc1dc7a3Sopenharmony_ci// of the License at: 8cc1dc7a3Sopenharmony_ci// 9cc1dc7a3Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 10cc1dc7a3Sopenharmony_ci// 11cc1dc7a3Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 12cc1dc7a3Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13cc1dc7a3Sopenharmony_ci// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14cc1dc7a3Sopenharmony_ci// License for the specific language governing permissions and limitations 15cc1dc7a3Sopenharmony_ci// under the License. 16cc1dc7a3Sopenharmony_ci// ---------------------------------------------------------------------------- 17cc1dc7a3Sopenharmony_ci 18cc1dc7a3Sopenharmony_ci/** 19cc1dc7a3Sopenharmony_ci * @brief Functions and data declarations. 20cc1dc7a3Sopenharmony_ci */ 21cc1dc7a3Sopenharmony_ci 22cc1dc7a3Sopenharmony_ci#ifndef ASTCENC_INTERNAL_INCLUDED 23cc1dc7a3Sopenharmony_ci#define ASTCENC_INTERNAL_INCLUDED 24cc1dc7a3Sopenharmony_ci 25cc1dc7a3Sopenharmony_ci#include <algorithm> 26cc1dc7a3Sopenharmony_ci#include <cstddef> 27cc1dc7a3Sopenharmony_ci#include <cstdint> 28cc1dc7a3Sopenharmony_ci#if defined(ASTCENC_DIAGNOSTICS) 29cc1dc7a3Sopenharmony_ci #include <cstdio> 30cc1dc7a3Sopenharmony_ci#endif 31cc1dc7a3Sopenharmony_ci#include <cstdlib> 32cc1dc7a3Sopenharmony_ci#include <limits> 33cc1dc7a3Sopenharmony_ci 34cc1dc7a3Sopenharmony_ci#ifdef ASTC_CUSTOMIZED_ENABLE 35cc1dc7a3Sopenharmony_ci#include <unistd.h> 36cc1dc7a3Sopenharmony_ci#include <string> 37cc1dc7a3Sopenharmony_ci#if defined(_WIN32) && !defined(__CYGWIN__) 38cc1dc7a3Sopenharmony_ci#define NOMINMAX 39cc1dc7a3Sopenharmony_ci#include <windows.h> 40cc1dc7a3Sopenharmony_ci#include <io.h> 41cc1dc7a3Sopenharmony_ci#else 42cc1dc7a3Sopenharmony_ci#include <dlfcn.h> 43cc1dc7a3Sopenharmony_ci#endif 44cc1dc7a3Sopenharmony_ci#endif 45cc1dc7a3Sopenharmony_ci 46cc1dc7a3Sopenharmony_ci#include "astcenc.h" 47cc1dc7a3Sopenharmony_ci#include "astcenc_mathlib.h" 48cc1dc7a3Sopenharmony_ci#include "astcenc_vecmathlib.h" 49cc1dc7a3Sopenharmony_ci 50cc1dc7a3Sopenharmony_ci/** 51cc1dc7a3Sopenharmony_ci * @brief Make a promise to the compiler's optimizer. 52cc1dc7a3Sopenharmony_ci * 53cc1dc7a3Sopenharmony_ci * A promise is an expression that the optimizer is can assume is true for to help it generate 54cc1dc7a3Sopenharmony_ci * faster code. Common use cases for this are to promise that a for loop will iterate more than 55cc1dc7a3Sopenharmony_ci * once, or that the loop iteration count is a multiple of a vector length, which avoids pre-loop 56cc1dc7a3Sopenharmony_ci * checks and can avoid loop tails if loops are unrolled by the auto-vectorizer. 57cc1dc7a3Sopenharmony_ci */ 58cc1dc7a3Sopenharmony_ci#if defined(NDEBUG) 59cc1dc7a3Sopenharmony_ci #if !defined(__clang__) && defined(_MSC_VER) 60cc1dc7a3Sopenharmony_ci #define promise(cond) __assume(cond) 61cc1dc7a3Sopenharmony_ci #elif defined(__clang__) 62cc1dc7a3Sopenharmony_ci #if __has_builtin(__builtin_assume) 63cc1dc7a3Sopenharmony_ci #define promise(cond) __builtin_assume(cond) 64cc1dc7a3Sopenharmony_ci #elif __has_builtin(__builtin_unreachable) 65cc1dc7a3Sopenharmony_ci #define promise(cond) if (!(cond)) { __builtin_unreachable(); } 66cc1dc7a3Sopenharmony_ci #else 67cc1dc7a3Sopenharmony_ci #define promise(cond) 68cc1dc7a3Sopenharmony_ci #endif 69cc1dc7a3Sopenharmony_ci #else // Assume GCC 70cc1dc7a3Sopenharmony_ci #define promise(cond) if (!(cond)) { __builtin_unreachable(); } 71cc1dc7a3Sopenharmony_ci #endif 72cc1dc7a3Sopenharmony_ci#else 73cc1dc7a3Sopenharmony_ci #define promise(cond) assert(cond) 74cc1dc7a3Sopenharmony_ci#endif 75cc1dc7a3Sopenharmony_ci 76cc1dc7a3Sopenharmony_ci/* ============================================================================ 77cc1dc7a3Sopenharmony_ci Constants 78cc1dc7a3Sopenharmony_ci============================================================================ */ 79cc1dc7a3Sopenharmony_ci#if !defined(ASTCENC_BLOCK_MAX_TEXELS) 80cc1dc7a3Sopenharmony_ci #define ASTCENC_BLOCK_MAX_TEXELS 216 // A 3D 6x6x6 block 81cc1dc7a3Sopenharmony_ci#endif 82cc1dc7a3Sopenharmony_ci 83cc1dc7a3Sopenharmony_ci/** @brief The maximum number of texels a block can support (6x6x6 block). */ 84cc1dc7a3Sopenharmony_cistatic constexpr unsigned int BLOCK_MAX_TEXELS { ASTCENC_BLOCK_MAX_TEXELS }; 85cc1dc7a3Sopenharmony_ci 86cc1dc7a3Sopenharmony_ci/** @brief The maximum number of components a block can support. */ 87cc1dc7a3Sopenharmony_cistatic constexpr unsigned int BLOCK_MAX_COMPONENTS { 4 }; 88cc1dc7a3Sopenharmony_ci 89cc1dc7a3Sopenharmony_ci/** @brief The maximum number of partitions a block can support. */ 90cc1dc7a3Sopenharmony_cistatic constexpr unsigned int BLOCK_MAX_PARTITIONS { 4 }; 91cc1dc7a3Sopenharmony_ci 92cc1dc7a3Sopenharmony_ci/** @brief The number of partitionings, per partition count, suported by the ASTC format. */ 93cc1dc7a3Sopenharmony_cistatic constexpr unsigned int BLOCK_MAX_PARTITIONINGS { 1024 }; 94cc1dc7a3Sopenharmony_ci 95cc1dc7a3Sopenharmony_ci/** @brief The maximum number of texels used during partition selection for texel clustering. */ 96cc1dc7a3Sopenharmony_cistatic constexpr uint8_t BLOCK_MAX_KMEANS_TEXELS { 64 }; 97cc1dc7a3Sopenharmony_ci 98cc1dc7a3Sopenharmony_ci/** @brief The maximum number of weights a block can support. */ 99cc1dc7a3Sopenharmony_cistatic constexpr unsigned int BLOCK_MAX_WEIGHTS { 64 }; 100cc1dc7a3Sopenharmony_ci 101cc1dc7a3Sopenharmony_ci/** @brief The maximum number of weights a block can support per plane in 2 plane mode. */ 102cc1dc7a3Sopenharmony_cistatic constexpr unsigned int BLOCK_MAX_WEIGHTS_2PLANE { BLOCK_MAX_WEIGHTS / 2 }; 103cc1dc7a3Sopenharmony_ci 104cc1dc7a3Sopenharmony_ci/** @brief The minimum number of weight bits a candidate encoding must encode. */ 105cc1dc7a3Sopenharmony_cistatic constexpr unsigned int BLOCK_MIN_WEIGHT_BITS { 24 }; 106cc1dc7a3Sopenharmony_ci 107cc1dc7a3Sopenharmony_ci/** @brief The maximum number of weight bits a candidate encoding can encode. */ 108cc1dc7a3Sopenharmony_cistatic constexpr unsigned int BLOCK_MAX_WEIGHT_BITS { 96 }; 109cc1dc7a3Sopenharmony_ci 110cc1dc7a3Sopenharmony_ci/** @brief The index indicating a bad (unused) block mode in the remap array. */ 111cc1dc7a3Sopenharmony_cistatic constexpr uint16_t BLOCK_BAD_BLOCK_MODE { 0xFFFFu }; 112cc1dc7a3Sopenharmony_ci 113cc1dc7a3Sopenharmony_ci/** @brief The index indicating a bad (unused) partitioning in the remap array. */ 114cc1dc7a3Sopenharmony_cistatic constexpr uint16_t BLOCK_BAD_PARTITIONING { 0xFFFFu }; 115cc1dc7a3Sopenharmony_ci 116cc1dc7a3Sopenharmony_ci/** @brief The number of partition index bits supported by the ASTC format . */ 117cc1dc7a3Sopenharmony_cistatic constexpr unsigned int PARTITION_INDEX_BITS { 10 }; 118cc1dc7a3Sopenharmony_ci 119cc1dc7a3Sopenharmony_ci/** @brief The offset of the plane 2 weights in shared weight arrays. */ 120cc1dc7a3Sopenharmony_cistatic constexpr unsigned int WEIGHTS_PLANE2_OFFSET { BLOCK_MAX_WEIGHTS_2PLANE }; 121cc1dc7a3Sopenharmony_ci 122cc1dc7a3Sopenharmony_ci/** @brief The sum of quantized weights for one texel. */ 123cc1dc7a3Sopenharmony_cistatic constexpr float WEIGHTS_TEXEL_SUM { 16.0f }; 124cc1dc7a3Sopenharmony_ci 125cc1dc7a3Sopenharmony_ci/** @brief The number of block modes supported by the ASTC format. */ 126cc1dc7a3Sopenharmony_cistatic constexpr unsigned int WEIGHTS_MAX_BLOCK_MODES { 2048 }; 127cc1dc7a3Sopenharmony_ci 128cc1dc7a3Sopenharmony_ci/** @brief The number of weight grid decimation modes supported by the ASTC format. */ 129cc1dc7a3Sopenharmony_cistatic constexpr unsigned int WEIGHTS_MAX_DECIMATION_MODES { 87 }; 130cc1dc7a3Sopenharmony_ci 131cc1dc7a3Sopenharmony_ci/** @brief The high default error used to initialize error trackers. */ 132cc1dc7a3Sopenharmony_cistatic constexpr float ERROR_CALC_DEFAULT { 1e30f }; 133cc1dc7a3Sopenharmony_ci 134cc1dc7a3Sopenharmony_ci/** 135cc1dc7a3Sopenharmony_ci * @brief The minimum tuning setting threshold for the one partition fast path. 136cc1dc7a3Sopenharmony_ci */ 137cc1dc7a3Sopenharmony_cistatic constexpr float TUNE_MIN_SEARCH_MODE0 { 0.85f }; 138cc1dc7a3Sopenharmony_ci 139cc1dc7a3Sopenharmony_ci/** 140cc1dc7a3Sopenharmony_ci * @brief The maximum number of candidate encodings tested for each encoding mode. 141cc1dc7a3Sopenharmony_ci * 142cc1dc7a3Sopenharmony_ci * This can be dynamically reduced by the compression quality preset. 143cc1dc7a3Sopenharmony_ci */ 144cc1dc7a3Sopenharmony_cistatic constexpr unsigned int TUNE_MAX_TRIAL_CANDIDATES { 8 }; 145cc1dc7a3Sopenharmony_ci 146cc1dc7a3Sopenharmony_ci/** 147cc1dc7a3Sopenharmony_ci * @brief The maximum number of candidate partitionings tested for each encoding mode. 148cc1dc7a3Sopenharmony_ci * 149cc1dc7a3Sopenharmony_ci * This can be dynamically reduced by the compression quality preset. 150cc1dc7a3Sopenharmony_ci */ 151cc1dc7a3Sopenharmony_cistatic constexpr unsigned int TUNE_MAX_PARTITIONING_CANDIDATES { 8 }; 152cc1dc7a3Sopenharmony_ci 153cc1dc7a3Sopenharmony_ci/** 154cc1dc7a3Sopenharmony_ci * @brief The maximum quant level using full angular endpoint search method. 155cc1dc7a3Sopenharmony_ci * 156cc1dc7a3Sopenharmony_ci * The angular endpoint search is used to find the min/max weight that should 157cc1dc7a3Sopenharmony_ci * be used for a given quantization level. It is effective but expensive, so 158cc1dc7a3Sopenharmony_ci * we only use it where it has the most value - low quant levels with wide 159cc1dc7a3Sopenharmony_ci * spacing. It is used below TUNE_MAX_ANGULAR_QUANT (inclusive). Above this we 160cc1dc7a3Sopenharmony_ci * assume the min weight is 0.0f, and the max weight is 1.0f. 161cc1dc7a3Sopenharmony_ci * 162cc1dc7a3Sopenharmony_ci * Note the angular algorithm is vectorized, and using QUANT_12 exactly fills 163cc1dc7a3Sopenharmony_ci * one 8-wide vector. Decreasing by one doesn't buy much performance, and 164cc1dc7a3Sopenharmony_ci * increasing by one is disproportionately expensive. 165cc1dc7a3Sopenharmony_ci */ 166cc1dc7a3Sopenharmony_cistatic constexpr unsigned int TUNE_MAX_ANGULAR_QUANT { 7 }; /* QUANT_12 */ 167cc1dc7a3Sopenharmony_ci 168cc1dc7a3Sopenharmony_cistatic_assert((BLOCK_MAX_TEXELS % ASTCENC_SIMD_WIDTH) == 0, 169cc1dc7a3Sopenharmony_ci "BLOCK_MAX_TEXELS must be multiple of ASTCENC_SIMD_WIDTH"); 170cc1dc7a3Sopenharmony_ci 171cc1dc7a3Sopenharmony_cistatic_assert(BLOCK_MAX_TEXELS <= 216, 172cc1dc7a3Sopenharmony_ci "BLOCK_MAX_TEXELS must not be greater than 216"); 173cc1dc7a3Sopenharmony_ci 174cc1dc7a3Sopenharmony_cistatic_assert((BLOCK_MAX_WEIGHTS % ASTCENC_SIMD_WIDTH) == 0, 175cc1dc7a3Sopenharmony_ci "BLOCK_MAX_WEIGHTS must be multiple of ASTCENC_SIMD_WIDTH"); 176cc1dc7a3Sopenharmony_ci 177cc1dc7a3Sopenharmony_cistatic_assert((WEIGHTS_MAX_BLOCK_MODES % ASTCENC_SIMD_WIDTH) == 0, 178cc1dc7a3Sopenharmony_ci "WEIGHTS_MAX_BLOCK_MODES must be multiple of ASTCENC_SIMD_WIDTH"); 179cc1dc7a3Sopenharmony_ci 180cc1dc7a3Sopenharmony_ci 181cc1dc7a3Sopenharmony_ci/* ============================================================================ 182cc1dc7a3Sopenharmony_ci Commonly used data structures 183cc1dc7a3Sopenharmony_ci============================================================================ */ 184cc1dc7a3Sopenharmony_ci 185cc1dc7a3Sopenharmony_ci/** 186cc1dc7a3Sopenharmony_ci * @brief The ASTC endpoint formats. 187cc1dc7a3Sopenharmony_ci * 188cc1dc7a3Sopenharmony_ci * Note, the values here are used directly in the encoding in the format so do not rearrange. 189cc1dc7a3Sopenharmony_ci */ 190cc1dc7a3Sopenharmony_cienum endpoint_formats 191cc1dc7a3Sopenharmony_ci{ 192cc1dc7a3Sopenharmony_ci FMT_LUMINANCE = 0, 193cc1dc7a3Sopenharmony_ci FMT_LUMINANCE_DELTA = 1, 194cc1dc7a3Sopenharmony_ci FMT_HDR_LUMINANCE_LARGE_RANGE = 2, 195cc1dc7a3Sopenharmony_ci FMT_HDR_LUMINANCE_SMALL_RANGE = 3, 196cc1dc7a3Sopenharmony_ci FMT_LUMINANCE_ALPHA = 4, 197cc1dc7a3Sopenharmony_ci FMT_LUMINANCE_ALPHA_DELTA = 5, 198cc1dc7a3Sopenharmony_ci FMT_RGB_SCALE = 6, 199cc1dc7a3Sopenharmony_ci FMT_HDR_RGB_SCALE = 7, 200cc1dc7a3Sopenharmony_ci FMT_RGB = 8, 201cc1dc7a3Sopenharmony_ci FMT_RGB_DELTA = 9, 202cc1dc7a3Sopenharmony_ci FMT_RGB_SCALE_ALPHA = 10, 203cc1dc7a3Sopenharmony_ci FMT_HDR_RGB = 11, 204cc1dc7a3Sopenharmony_ci FMT_RGBA = 12, 205cc1dc7a3Sopenharmony_ci FMT_RGBA_DELTA = 13, 206cc1dc7a3Sopenharmony_ci FMT_HDR_RGB_LDR_ALPHA = 14, 207cc1dc7a3Sopenharmony_ci FMT_HDR_RGBA = 15 208cc1dc7a3Sopenharmony_ci}; 209cc1dc7a3Sopenharmony_ci 210cc1dc7a3Sopenharmony_ci/** 211cc1dc7a3Sopenharmony_ci * @brief The ASTC quantization methods. 212cc1dc7a3Sopenharmony_ci * 213cc1dc7a3Sopenharmony_ci * Note, the values here are used directly in the encoding in the format so do not rearrange. 214cc1dc7a3Sopenharmony_ci */ 215cc1dc7a3Sopenharmony_cienum quant_method 216cc1dc7a3Sopenharmony_ci{ 217cc1dc7a3Sopenharmony_ci QUANT_2 = 0, 218cc1dc7a3Sopenharmony_ci QUANT_3 = 1, 219cc1dc7a3Sopenharmony_ci QUANT_4 = 2, 220cc1dc7a3Sopenharmony_ci QUANT_5 = 3, 221cc1dc7a3Sopenharmony_ci QUANT_6 = 4, 222cc1dc7a3Sopenharmony_ci QUANT_8 = 5, 223cc1dc7a3Sopenharmony_ci QUANT_10 = 6, 224cc1dc7a3Sopenharmony_ci QUANT_12 = 7, 225cc1dc7a3Sopenharmony_ci QUANT_16 = 8, 226cc1dc7a3Sopenharmony_ci QUANT_20 = 9, 227cc1dc7a3Sopenharmony_ci QUANT_24 = 10, 228cc1dc7a3Sopenharmony_ci QUANT_32 = 11, 229cc1dc7a3Sopenharmony_ci QUANT_40 = 12, 230cc1dc7a3Sopenharmony_ci QUANT_48 = 13, 231cc1dc7a3Sopenharmony_ci QUANT_64 = 14, 232cc1dc7a3Sopenharmony_ci QUANT_80 = 15, 233cc1dc7a3Sopenharmony_ci QUANT_96 = 16, 234cc1dc7a3Sopenharmony_ci QUANT_128 = 17, 235cc1dc7a3Sopenharmony_ci QUANT_160 = 18, 236cc1dc7a3Sopenharmony_ci QUANT_192 = 19, 237cc1dc7a3Sopenharmony_ci QUANT_256 = 20 238cc1dc7a3Sopenharmony_ci}; 239cc1dc7a3Sopenharmony_ci 240cc1dc7a3Sopenharmony_ci/** 241cc1dc7a3Sopenharmony_ci * @brief The number of levels use by an ASTC quantization method. 242cc1dc7a3Sopenharmony_ci * 243cc1dc7a3Sopenharmony_ci * @param method The quantization method 244cc1dc7a3Sopenharmony_ci * 245cc1dc7a3Sopenharmony_ci * @return The number of levels used by @c method. 246cc1dc7a3Sopenharmony_ci */ 247cc1dc7a3Sopenharmony_cistatic inline unsigned int get_quant_level(quant_method method) 248cc1dc7a3Sopenharmony_ci{ 249cc1dc7a3Sopenharmony_ci switch (method) 250cc1dc7a3Sopenharmony_ci { 251cc1dc7a3Sopenharmony_ci case QUANT_2: return 2; 252cc1dc7a3Sopenharmony_ci case QUANT_3: return 3; 253cc1dc7a3Sopenharmony_ci case QUANT_4: return 4; 254cc1dc7a3Sopenharmony_ci case QUANT_5: return 5; 255cc1dc7a3Sopenharmony_ci case QUANT_6: return 6; 256cc1dc7a3Sopenharmony_ci case QUANT_8: return 8; 257cc1dc7a3Sopenharmony_ci case QUANT_10: return 10; 258cc1dc7a3Sopenharmony_ci case QUANT_12: return 12; 259cc1dc7a3Sopenharmony_ci case QUANT_16: return 16; 260cc1dc7a3Sopenharmony_ci case QUANT_20: return 20; 261cc1dc7a3Sopenharmony_ci case QUANT_24: return 24; 262cc1dc7a3Sopenharmony_ci case QUANT_32: return 32; 263cc1dc7a3Sopenharmony_ci case QUANT_40: return 40; 264cc1dc7a3Sopenharmony_ci case QUANT_48: return 48; 265cc1dc7a3Sopenharmony_ci case QUANT_64: return 64; 266cc1dc7a3Sopenharmony_ci case QUANT_80: return 80; 267cc1dc7a3Sopenharmony_ci case QUANT_96: return 96; 268cc1dc7a3Sopenharmony_ci case QUANT_128: return 128; 269cc1dc7a3Sopenharmony_ci case QUANT_160: return 160; 270cc1dc7a3Sopenharmony_ci case QUANT_192: return 192; 271cc1dc7a3Sopenharmony_ci case QUANT_256: return 256; 272cc1dc7a3Sopenharmony_ci } 273cc1dc7a3Sopenharmony_ci 274cc1dc7a3Sopenharmony_ci // Unreachable - the enum is fully described 275cc1dc7a3Sopenharmony_ci return 0; 276cc1dc7a3Sopenharmony_ci} 277cc1dc7a3Sopenharmony_ci 278cc1dc7a3Sopenharmony_ci/** 279cc1dc7a3Sopenharmony_ci * @brief Computed metrics about a partition in a block. 280cc1dc7a3Sopenharmony_ci */ 281cc1dc7a3Sopenharmony_cistruct partition_metrics 282cc1dc7a3Sopenharmony_ci{ 283cc1dc7a3Sopenharmony_ci /** @brief The error-weighted average color in the partition. */ 284cc1dc7a3Sopenharmony_ci vfloat4 avg; 285cc1dc7a3Sopenharmony_ci 286cc1dc7a3Sopenharmony_ci /** @brief The dominant error-weighted direction in the partition. */ 287cc1dc7a3Sopenharmony_ci vfloat4 dir; 288cc1dc7a3Sopenharmony_ci}; 289cc1dc7a3Sopenharmony_ci 290cc1dc7a3Sopenharmony_ci/** 291cc1dc7a3Sopenharmony_ci * @brief Computed lines for a a three component analysis. 292cc1dc7a3Sopenharmony_ci */ 293cc1dc7a3Sopenharmony_cistruct partition_lines3 294cc1dc7a3Sopenharmony_ci{ 295cc1dc7a3Sopenharmony_ci /** @brief Line for uncorrelated chroma. */ 296cc1dc7a3Sopenharmony_ci line3 uncor_line; 297cc1dc7a3Sopenharmony_ci 298cc1dc7a3Sopenharmony_ci /** @brief Line for correlated chroma, passing though the origin. */ 299cc1dc7a3Sopenharmony_ci line3 samec_line; 300cc1dc7a3Sopenharmony_ci 301cc1dc7a3Sopenharmony_ci /** @brief Post-processed line for uncorrelated chroma. */ 302cc1dc7a3Sopenharmony_ci processed_line3 uncor_pline; 303cc1dc7a3Sopenharmony_ci 304cc1dc7a3Sopenharmony_ci /** @brief Post-processed line for correlated chroma, passing though the origin. */ 305cc1dc7a3Sopenharmony_ci processed_line3 samec_pline; 306cc1dc7a3Sopenharmony_ci 307cc1dc7a3Sopenharmony_ci /** 308cc1dc7a3Sopenharmony_ci * @brief The length of the line for uncorrelated chroma. 309cc1dc7a3Sopenharmony_ci * 310cc1dc7a3Sopenharmony_ci * This is used for both the uncorrelated and same chroma lines - they are normally very similar 311cc1dc7a3Sopenharmony_ci * and only used for the relative ranking of partitionings against one another. 312cc1dc7a3Sopenharmony_ci */ 313cc1dc7a3Sopenharmony_ci float line_length; 314cc1dc7a3Sopenharmony_ci}; 315cc1dc7a3Sopenharmony_ci 316cc1dc7a3Sopenharmony_ci/** 317cc1dc7a3Sopenharmony_ci * @brief The partition information for a single partition. 318cc1dc7a3Sopenharmony_ci * 319cc1dc7a3Sopenharmony_ci * ASTC has a total of 1024 candidate partitions for each of 2/3/4 partition counts, although this 320cc1dc7a3Sopenharmony_ci * 1024 includes seeds that generate duplicates of other seeds and seeds that generate completely 321cc1dc7a3Sopenharmony_ci * empty partitions. These are both valid encodings, but astcenc will skip both during compression 322cc1dc7a3Sopenharmony_ci * as they are not useful. 323cc1dc7a3Sopenharmony_ci */ 324cc1dc7a3Sopenharmony_cistruct partition_info 325cc1dc7a3Sopenharmony_ci{ 326cc1dc7a3Sopenharmony_ci /** @brief The number of partitions in this partitioning. */ 327cc1dc7a3Sopenharmony_ci uint16_t partition_count; 328cc1dc7a3Sopenharmony_ci 329cc1dc7a3Sopenharmony_ci /** @brief The index (seed) of this partitioning. */ 330cc1dc7a3Sopenharmony_ci uint16_t partition_index; 331cc1dc7a3Sopenharmony_ci 332cc1dc7a3Sopenharmony_ci /** 333cc1dc7a3Sopenharmony_ci * @brief The number of texels in each partition. 334cc1dc7a3Sopenharmony_ci * 335cc1dc7a3Sopenharmony_ci * Note that some seeds result in zero texels assigned to a partition. These are valid, but are 336cc1dc7a3Sopenharmony_ci * skipped by this compressor as there is no point spending bits encoding an unused endpoints. 337cc1dc7a3Sopenharmony_ci */ 338cc1dc7a3Sopenharmony_ci uint8_t partition_texel_count[BLOCK_MAX_PARTITIONS]; 339cc1dc7a3Sopenharmony_ci 340cc1dc7a3Sopenharmony_ci /** @brief The partition of each texel in the block. */ 341cc1dc7a3Sopenharmony_ci uint8_t partition_of_texel[BLOCK_MAX_TEXELS]; 342cc1dc7a3Sopenharmony_ci 343cc1dc7a3Sopenharmony_ci /** @brief The list of texels in each partition. */ 344cc1dc7a3Sopenharmony_ci uint8_t texels_of_partition[BLOCK_MAX_PARTITIONS][BLOCK_MAX_TEXELS]; 345cc1dc7a3Sopenharmony_ci}; 346cc1dc7a3Sopenharmony_ci 347cc1dc7a3Sopenharmony_ci/** 348cc1dc7a3Sopenharmony_ci * @brief The weight grid information for a single decimation pattern. 349cc1dc7a3Sopenharmony_ci * 350cc1dc7a3Sopenharmony_ci * ASTC can store one weight per texel, but is also capable of storing lower resolution weight grids 351cc1dc7a3Sopenharmony_ci * that are interpolated during decompression to assign a with to a texel. Storing fewer weights 352cc1dc7a3Sopenharmony_ci * can free up a substantial amount of bits that we can then spend on more useful things, such as 353cc1dc7a3Sopenharmony_ci * more accurate endpoints and weights, or additional partitions. 354cc1dc7a3Sopenharmony_ci * 355cc1dc7a3Sopenharmony_ci * This data structure is used to store information about a single weight grid decimation pattern, 356cc1dc7a3Sopenharmony_ci * for a single block size. 357cc1dc7a3Sopenharmony_ci */ 358cc1dc7a3Sopenharmony_cistruct decimation_info 359cc1dc7a3Sopenharmony_ci{ 360cc1dc7a3Sopenharmony_ci /** @brief The total number of texels in the block. */ 361cc1dc7a3Sopenharmony_ci uint8_t texel_count; 362cc1dc7a3Sopenharmony_ci 363cc1dc7a3Sopenharmony_ci /** @brief The maximum number of stored weights that contribute to each texel, between 1 and 4. */ 364cc1dc7a3Sopenharmony_ci uint8_t max_texel_weight_count; 365cc1dc7a3Sopenharmony_ci 366cc1dc7a3Sopenharmony_ci /** @brief The total number of weights stored. */ 367cc1dc7a3Sopenharmony_ci uint8_t weight_count; 368cc1dc7a3Sopenharmony_ci 369cc1dc7a3Sopenharmony_ci /** @brief The number of stored weights in the X dimension. */ 370cc1dc7a3Sopenharmony_ci uint8_t weight_x; 371cc1dc7a3Sopenharmony_ci 372cc1dc7a3Sopenharmony_ci /** @brief The number of stored weights in the Y dimension. */ 373cc1dc7a3Sopenharmony_ci uint8_t weight_y; 374cc1dc7a3Sopenharmony_ci 375cc1dc7a3Sopenharmony_ci /** @brief The number of stored weights in the Z dimension. */ 376cc1dc7a3Sopenharmony_ci uint8_t weight_z; 377cc1dc7a3Sopenharmony_ci 378cc1dc7a3Sopenharmony_ci /** 379cc1dc7a3Sopenharmony_ci * @brief The number of weights that contribute to each texel. 380cc1dc7a3Sopenharmony_ci * Value is between 1 and 4. 381cc1dc7a3Sopenharmony_ci */ 382cc1dc7a3Sopenharmony_ci uint8_t texel_weight_count[BLOCK_MAX_TEXELS]; 383cc1dc7a3Sopenharmony_ci 384cc1dc7a3Sopenharmony_ci /** 385cc1dc7a3Sopenharmony_ci * @brief The weight index of the N weights that are interpolated for each texel. 386cc1dc7a3Sopenharmony_ci * Stored transposed to improve vectorization. 387cc1dc7a3Sopenharmony_ci */ 388cc1dc7a3Sopenharmony_ci uint8_t texel_weights_tr[4][BLOCK_MAX_TEXELS]; 389cc1dc7a3Sopenharmony_ci 390cc1dc7a3Sopenharmony_ci /** 391cc1dc7a3Sopenharmony_ci * @brief The bilinear contribution of the N weights that are interpolated for each texel. 392cc1dc7a3Sopenharmony_ci * Value is between 0 and 16, stored transposed to improve vectorization. 393cc1dc7a3Sopenharmony_ci */ 394cc1dc7a3Sopenharmony_ci uint8_t texel_weight_contribs_int_tr[4][BLOCK_MAX_TEXELS]; 395cc1dc7a3Sopenharmony_ci 396cc1dc7a3Sopenharmony_ci /** 397cc1dc7a3Sopenharmony_ci * @brief The bilinear contribution of the N weights that are interpolated for each texel. 398cc1dc7a3Sopenharmony_ci * Value is between 0 and 1, stored transposed to improve vectorization. 399cc1dc7a3Sopenharmony_ci */ 400cc1dc7a3Sopenharmony_ci ASTCENC_ALIGNAS float texel_weight_contribs_float_tr[4][BLOCK_MAX_TEXELS]; 401cc1dc7a3Sopenharmony_ci 402cc1dc7a3Sopenharmony_ci /** @brief The number of texels that each stored weight contributes to. */ 403cc1dc7a3Sopenharmony_ci uint8_t weight_texel_count[BLOCK_MAX_WEIGHTS]; 404cc1dc7a3Sopenharmony_ci 405cc1dc7a3Sopenharmony_ci /** 406cc1dc7a3Sopenharmony_ci * @brief The list of texels that use a specific weight index. 407cc1dc7a3Sopenharmony_ci * Stored transposed to improve vectorization. 408cc1dc7a3Sopenharmony_ci */ 409cc1dc7a3Sopenharmony_ci uint8_t weight_texels_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS]; 410cc1dc7a3Sopenharmony_ci 411cc1dc7a3Sopenharmony_ci /** 412cc1dc7a3Sopenharmony_ci * @brief The bilinear contribution to the N texels that use each weight. 413cc1dc7a3Sopenharmony_ci * Value is between 0 and 1, stored transposed to improve vectorization. 414cc1dc7a3Sopenharmony_ci */ 415cc1dc7a3Sopenharmony_ci ASTCENC_ALIGNAS float weights_texel_contribs_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS]; 416cc1dc7a3Sopenharmony_ci 417cc1dc7a3Sopenharmony_ci /** 418cc1dc7a3Sopenharmony_ci * @brief The bilinear contribution to the Nth texel that uses each weight. 419cc1dc7a3Sopenharmony_ci * Value is between 0 and 1, stored transposed to improve vectorization. 420cc1dc7a3Sopenharmony_ci */ 421cc1dc7a3Sopenharmony_ci float texel_contrib_for_weight[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS]; 422cc1dc7a3Sopenharmony_ci}; 423cc1dc7a3Sopenharmony_ci 424cc1dc7a3Sopenharmony_ci/** 425cc1dc7a3Sopenharmony_ci * @brief Metadata for single block mode for a specific block size. 426cc1dc7a3Sopenharmony_ci */ 427cc1dc7a3Sopenharmony_cistruct block_mode 428cc1dc7a3Sopenharmony_ci{ 429cc1dc7a3Sopenharmony_ci /** @brief The block mode index in the ASTC encoded form. */ 430cc1dc7a3Sopenharmony_ci uint16_t mode_index; 431cc1dc7a3Sopenharmony_ci 432cc1dc7a3Sopenharmony_ci /** @brief The decimation mode index in the compressor reindexed list. */ 433cc1dc7a3Sopenharmony_ci uint8_t decimation_mode; 434cc1dc7a3Sopenharmony_ci 435cc1dc7a3Sopenharmony_ci /** @brief The weight quantization used by this block mode. */ 436cc1dc7a3Sopenharmony_ci uint8_t quant_mode; 437cc1dc7a3Sopenharmony_ci 438cc1dc7a3Sopenharmony_ci /** @brief The weight quantization used by this block mode. */ 439cc1dc7a3Sopenharmony_ci uint8_t weight_bits; 440cc1dc7a3Sopenharmony_ci 441cc1dc7a3Sopenharmony_ci /** @brief Is a dual weight plane used by this block mode? */ 442cc1dc7a3Sopenharmony_ci uint8_t is_dual_plane : 1; 443cc1dc7a3Sopenharmony_ci 444cc1dc7a3Sopenharmony_ci /** 445cc1dc7a3Sopenharmony_ci * @brief Get the weight quantization used by this block mode. 446cc1dc7a3Sopenharmony_ci * 447cc1dc7a3Sopenharmony_ci * @return The quantization level. 448cc1dc7a3Sopenharmony_ci */ 449cc1dc7a3Sopenharmony_ci inline quant_method get_weight_quant_mode() const 450cc1dc7a3Sopenharmony_ci { 451cc1dc7a3Sopenharmony_ci return static_cast<quant_method>(this->quant_mode); 452cc1dc7a3Sopenharmony_ci } 453cc1dc7a3Sopenharmony_ci}; 454cc1dc7a3Sopenharmony_ci 455cc1dc7a3Sopenharmony_ci/** 456cc1dc7a3Sopenharmony_ci * @brief Metadata for single decimation mode for a specific block size. 457cc1dc7a3Sopenharmony_ci */ 458cc1dc7a3Sopenharmony_cistruct decimation_mode 459cc1dc7a3Sopenharmony_ci{ 460cc1dc7a3Sopenharmony_ci /** @brief The max weight precision for 1 plane, or -1 if not supported. */ 461cc1dc7a3Sopenharmony_ci int8_t maxprec_1plane; 462cc1dc7a3Sopenharmony_ci 463cc1dc7a3Sopenharmony_ci /** @brief The max weight precision for 2 planes, or -1 if not supported. */ 464cc1dc7a3Sopenharmony_ci int8_t maxprec_2planes; 465cc1dc7a3Sopenharmony_ci 466cc1dc7a3Sopenharmony_ci /** 467cc1dc7a3Sopenharmony_ci * @brief Bitvector indicating weight quant modes used by active 1 plane block modes. 468cc1dc7a3Sopenharmony_ci * 469cc1dc7a3Sopenharmony_ci * Bit 0 = QUANT_2, Bit 1 = QUANT_3, etc. 470cc1dc7a3Sopenharmony_ci */ 471cc1dc7a3Sopenharmony_ci uint16_t refprec_1plane; 472cc1dc7a3Sopenharmony_ci 473cc1dc7a3Sopenharmony_ci /** 474cc1dc7a3Sopenharmony_ci * @brief Bitvector indicating weight quant methods used by active 2 plane block modes. 475cc1dc7a3Sopenharmony_ci * 476cc1dc7a3Sopenharmony_ci * Bit 0 = QUANT_2, Bit 1 = QUANT_3, etc. 477cc1dc7a3Sopenharmony_ci */ 478cc1dc7a3Sopenharmony_ci uint16_t refprec_2planes; 479cc1dc7a3Sopenharmony_ci 480cc1dc7a3Sopenharmony_ci /** 481cc1dc7a3Sopenharmony_ci * @brief Set a 1 plane weight quant as active. 482cc1dc7a3Sopenharmony_ci * 483cc1dc7a3Sopenharmony_ci * @param weight_quant The quant method to set. 484cc1dc7a3Sopenharmony_ci */ 485cc1dc7a3Sopenharmony_ci void set_ref_1plane(quant_method weight_quant) 486cc1dc7a3Sopenharmony_ci { 487cc1dc7a3Sopenharmony_ci refprec_1plane |= (1 << weight_quant); 488cc1dc7a3Sopenharmony_ci } 489cc1dc7a3Sopenharmony_ci 490cc1dc7a3Sopenharmony_ci /** 491cc1dc7a3Sopenharmony_ci * @brief Test if this mode is active below a given 1 plane weight quant (inclusive). 492cc1dc7a3Sopenharmony_ci * 493cc1dc7a3Sopenharmony_ci * @param max_weight_quant The max quant method to test. 494cc1dc7a3Sopenharmony_ci */ 495cc1dc7a3Sopenharmony_ci bool is_ref_1plane(quant_method max_weight_quant) const 496cc1dc7a3Sopenharmony_ci { 497cc1dc7a3Sopenharmony_ci uint16_t mask = static_cast<uint16_t>((1 << (max_weight_quant + 1)) - 1); 498cc1dc7a3Sopenharmony_ci return (refprec_1plane & mask) != 0; 499cc1dc7a3Sopenharmony_ci } 500cc1dc7a3Sopenharmony_ci 501cc1dc7a3Sopenharmony_ci /** 502cc1dc7a3Sopenharmony_ci * @brief Set a 2 plane weight quant as active. 503cc1dc7a3Sopenharmony_ci * 504cc1dc7a3Sopenharmony_ci * @param weight_quant The quant method to set. 505cc1dc7a3Sopenharmony_ci */ 506cc1dc7a3Sopenharmony_ci void set_ref_2plane(quant_method weight_quant) 507cc1dc7a3Sopenharmony_ci { 508cc1dc7a3Sopenharmony_ci refprec_2planes |= static_cast<uint16_t>(1 << weight_quant); 509cc1dc7a3Sopenharmony_ci } 510cc1dc7a3Sopenharmony_ci 511cc1dc7a3Sopenharmony_ci /** 512cc1dc7a3Sopenharmony_ci * @brief Test if this mode is active below a given 2 plane weight quant (inclusive). 513cc1dc7a3Sopenharmony_ci * 514cc1dc7a3Sopenharmony_ci * @param max_weight_quant The max quant method to test. 515cc1dc7a3Sopenharmony_ci */ 516cc1dc7a3Sopenharmony_ci bool is_ref_2plane(quant_method max_weight_quant) const 517cc1dc7a3Sopenharmony_ci { 518cc1dc7a3Sopenharmony_ci uint16_t mask = static_cast<uint16_t>((1 << (max_weight_quant + 1)) - 1); 519cc1dc7a3Sopenharmony_ci return (refprec_2planes & mask) != 0; 520cc1dc7a3Sopenharmony_ci } 521cc1dc7a3Sopenharmony_ci}; 522cc1dc7a3Sopenharmony_ci 523cc1dc7a3Sopenharmony_ci/** 524cc1dc7a3Sopenharmony_ci * @brief Data tables for a single block size. 525cc1dc7a3Sopenharmony_ci * 526cc1dc7a3Sopenharmony_ci * The decimation tables store the information to apply weight grid dimension reductions. We only 527cc1dc7a3Sopenharmony_ci * store the decimation modes that are actually needed by the current context; many of the possible 528cc1dc7a3Sopenharmony_ci * modes will be unused (too many weights for the current block size or disabled by heuristics). The 529cc1dc7a3Sopenharmony_ci * actual number of weights stored is @c decimation_mode_count, and the @c decimation_modes and 530cc1dc7a3Sopenharmony_ci * @c decimation_tables arrays store the active modes contiguously at the start of the array. These 531cc1dc7a3Sopenharmony_ci * entries are not stored in any particular order. 532cc1dc7a3Sopenharmony_ci * 533cc1dc7a3Sopenharmony_ci * The block mode tables store the unpacked block mode settings. Block modes are stored in the 534cc1dc7a3Sopenharmony_ci * compressed block as an 11 bit field, but for any given block size and set of compressor 535cc1dc7a3Sopenharmony_ci * heuristics, only a subset of the block modes will be used. The actual number of block modes 536cc1dc7a3Sopenharmony_ci * stored is indicated in @c block_mode_count, and the @c block_modes array store the active modes 537cc1dc7a3Sopenharmony_ci * contiguously at the start of the array. These entries are stored in incrementing "packed" value 538cc1dc7a3Sopenharmony_ci * order, which doesn't mean much once unpacked. To allow decompressors to reference the packed data 539cc1dc7a3Sopenharmony_ci * efficiently the @c block_mode_packed_index array stores the mapping between physical ID and the 540cc1dc7a3Sopenharmony_ci * actual remapped array index. 541cc1dc7a3Sopenharmony_ci */ 542cc1dc7a3Sopenharmony_cistruct block_size_descriptor 543cc1dc7a3Sopenharmony_ci{ 544cc1dc7a3Sopenharmony_ci /** @brief The block X dimension, in texels. */ 545cc1dc7a3Sopenharmony_ci uint8_t xdim; 546cc1dc7a3Sopenharmony_ci 547cc1dc7a3Sopenharmony_ci /** @brief The block Y dimension, in texels. */ 548cc1dc7a3Sopenharmony_ci uint8_t ydim; 549cc1dc7a3Sopenharmony_ci 550cc1dc7a3Sopenharmony_ci /** @brief The block Z dimension, in texels. */ 551cc1dc7a3Sopenharmony_ci uint8_t zdim; 552cc1dc7a3Sopenharmony_ci 553cc1dc7a3Sopenharmony_ci /** @brief The block total texel count. */ 554cc1dc7a3Sopenharmony_ci uint8_t texel_count; 555cc1dc7a3Sopenharmony_ci 556cc1dc7a3Sopenharmony_ci /** 557cc1dc7a3Sopenharmony_ci * @brief The number of stored decimation modes which are "always" modes. 558cc1dc7a3Sopenharmony_ci * 559cc1dc7a3Sopenharmony_ci * Always modes are stored at the start of the decimation_modes list. 560cc1dc7a3Sopenharmony_ci */ 561cc1dc7a3Sopenharmony_ci unsigned int decimation_mode_count_always; 562cc1dc7a3Sopenharmony_ci 563cc1dc7a3Sopenharmony_ci /** @brief The number of stored decimation modes for selected encodings. */ 564cc1dc7a3Sopenharmony_ci unsigned int decimation_mode_count_selected; 565cc1dc7a3Sopenharmony_ci 566cc1dc7a3Sopenharmony_ci /** @brief The number of stored decimation modes for any encoding. */ 567cc1dc7a3Sopenharmony_ci unsigned int decimation_mode_count_all; 568cc1dc7a3Sopenharmony_ci 569cc1dc7a3Sopenharmony_ci /** 570cc1dc7a3Sopenharmony_ci * @brief The number of stored block modes which are "always" modes. 571cc1dc7a3Sopenharmony_ci * 572cc1dc7a3Sopenharmony_ci * Always modes are stored at the start of the block_modes list. 573cc1dc7a3Sopenharmony_ci */ 574cc1dc7a3Sopenharmony_ci unsigned int block_mode_count_1plane_always; 575cc1dc7a3Sopenharmony_ci 576cc1dc7a3Sopenharmony_ci /** @brief The number of stored block modes for active 1 plane encodings. */ 577cc1dc7a3Sopenharmony_ci unsigned int block_mode_count_1plane_selected; 578cc1dc7a3Sopenharmony_ci 579cc1dc7a3Sopenharmony_ci /** @brief The number of stored block modes for active 1 and 2 plane encodings. */ 580cc1dc7a3Sopenharmony_ci unsigned int block_mode_count_1plane_2plane_selected; 581cc1dc7a3Sopenharmony_ci 582cc1dc7a3Sopenharmony_ci /** @brief The number of stored block modes for any encoding. */ 583cc1dc7a3Sopenharmony_ci unsigned int block_mode_count_all; 584cc1dc7a3Sopenharmony_ci 585cc1dc7a3Sopenharmony_ci /** @brief The number of selected partitionings for 1/2/3/4 partitionings. */ 586cc1dc7a3Sopenharmony_ci unsigned int partitioning_count_selected[BLOCK_MAX_PARTITIONS]; 587cc1dc7a3Sopenharmony_ci 588cc1dc7a3Sopenharmony_ci /** @brief The number of partitionings for 1/2/3/4 partitionings. */ 589cc1dc7a3Sopenharmony_ci unsigned int partitioning_count_all[BLOCK_MAX_PARTITIONS]; 590cc1dc7a3Sopenharmony_ci 591cc1dc7a3Sopenharmony_ci /** @brief The active decimation modes, stored in low indices. */ 592cc1dc7a3Sopenharmony_ci decimation_mode decimation_modes[WEIGHTS_MAX_DECIMATION_MODES]; 593cc1dc7a3Sopenharmony_ci 594cc1dc7a3Sopenharmony_ci /** @brief The active decimation tables, stored in low indices. */ 595cc1dc7a3Sopenharmony_ci ASTCENC_ALIGNAS decimation_info decimation_tables[WEIGHTS_MAX_DECIMATION_MODES]; 596cc1dc7a3Sopenharmony_ci 597cc1dc7a3Sopenharmony_ci /** @brief The packed block mode array index, or @c BLOCK_BAD_BLOCK_MODE if not active. */ 598cc1dc7a3Sopenharmony_ci uint16_t block_mode_packed_index[WEIGHTS_MAX_BLOCK_MODES]; 599cc1dc7a3Sopenharmony_ci 600cc1dc7a3Sopenharmony_ci /** @brief The active block modes, stored in low indices. */ 601cc1dc7a3Sopenharmony_ci block_mode block_modes[WEIGHTS_MAX_BLOCK_MODES]; 602cc1dc7a3Sopenharmony_ci 603cc1dc7a3Sopenharmony_ci /** @brief The active partition tables, stored in low indices per-count. */ 604cc1dc7a3Sopenharmony_ci partition_info partitionings[(3 * BLOCK_MAX_PARTITIONINGS) + 1]; 605cc1dc7a3Sopenharmony_ci 606cc1dc7a3Sopenharmony_ci /** 607cc1dc7a3Sopenharmony_ci * @brief The packed partition table array index, or @c BLOCK_BAD_PARTITIONING if not active. 608cc1dc7a3Sopenharmony_ci * 609cc1dc7a3Sopenharmony_ci * Indexed by partition_count - 2, containing 2, 3 and 4 partitions. 610cc1dc7a3Sopenharmony_ci */ 611cc1dc7a3Sopenharmony_ci uint16_t partitioning_packed_index[3][BLOCK_MAX_PARTITIONINGS]; 612cc1dc7a3Sopenharmony_ci 613cc1dc7a3Sopenharmony_ci /** @brief The active texels for k-means partition selection. */ 614cc1dc7a3Sopenharmony_ci uint8_t kmeans_texels[BLOCK_MAX_KMEANS_TEXELS]; 615cc1dc7a3Sopenharmony_ci 616cc1dc7a3Sopenharmony_ci /** 617cc1dc7a3Sopenharmony_ci * @brief The canonical 2-partition coverage pattern used during block partition search. 618cc1dc7a3Sopenharmony_ci * 619cc1dc7a3Sopenharmony_ci * Indexed by remapped index, not physical index. 620cc1dc7a3Sopenharmony_ci */ 621cc1dc7a3Sopenharmony_ci uint64_t coverage_bitmaps_2[BLOCK_MAX_PARTITIONINGS][2]; 622cc1dc7a3Sopenharmony_ci 623cc1dc7a3Sopenharmony_ci /** 624cc1dc7a3Sopenharmony_ci * @brief The canonical 3-partition coverage pattern used during block partition search. 625cc1dc7a3Sopenharmony_ci * 626cc1dc7a3Sopenharmony_ci * Indexed by remapped index, not physical index. 627cc1dc7a3Sopenharmony_ci */ 628cc1dc7a3Sopenharmony_ci uint64_t coverage_bitmaps_3[BLOCK_MAX_PARTITIONINGS][3]; 629cc1dc7a3Sopenharmony_ci 630cc1dc7a3Sopenharmony_ci /** 631cc1dc7a3Sopenharmony_ci * @brief The canonical 4-partition coverage pattern used during block partition search. 632cc1dc7a3Sopenharmony_ci * 633cc1dc7a3Sopenharmony_ci * Indexed by remapped index, not physical index. 634cc1dc7a3Sopenharmony_ci */ 635cc1dc7a3Sopenharmony_ci uint64_t coverage_bitmaps_4[BLOCK_MAX_PARTITIONINGS][4]; 636cc1dc7a3Sopenharmony_ci 637cc1dc7a3Sopenharmony_ci /** 638cc1dc7a3Sopenharmony_ci * @brief Get the block mode structure for index @c block_mode. 639cc1dc7a3Sopenharmony_ci * 640cc1dc7a3Sopenharmony_ci * This function can only return block modes that are enabled by the current compressor config. 641cc1dc7a3Sopenharmony_ci * Decompression from an arbitrary source should not use this without first checking that the 642cc1dc7a3Sopenharmony_ci * packed block mode index is not @c BLOCK_BAD_BLOCK_MODE. 643cc1dc7a3Sopenharmony_ci * 644cc1dc7a3Sopenharmony_ci * @param block_mode The packed block mode index. 645cc1dc7a3Sopenharmony_ci * 646cc1dc7a3Sopenharmony_ci * @return The block mode structure. 647cc1dc7a3Sopenharmony_ci */ 648cc1dc7a3Sopenharmony_ci const block_mode& get_block_mode(unsigned int block_mode) const 649cc1dc7a3Sopenharmony_ci { 650cc1dc7a3Sopenharmony_ci unsigned int packed_index = this->block_mode_packed_index[block_mode]; 651cc1dc7a3Sopenharmony_ci assert(packed_index != BLOCK_BAD_BLOCK_MODE && packed_index < this->block_mode_count_all); 652cc1dc7a3Sopenharmony_ci return this->block_modes[packed_index]; 653cc1dc7a3Sopenharmony_ci } 654cc1dc7a3Sopenharmony_ci 655cc1dc7a3Sopenharmony_ci /** 656cc1dc7a3Sopenharmony_ci * @brief Get the decimation mode structure for index @c decimation_mode. 657cc1dc7a3Sopenharmony_ci * 658cc1dc7a3Sopenharmony_ci * This function can only return decimation modes that are enabled by the current compressor 659cc1dc7a3Sopenharmony_ci * config. The mode array is stored packed, but this is only ever indexed by the packed index 660cc1dc7a3Sopenharmony_ci * stored in the @c block_mode and never exists in an unpacked form. 661cc1dc7a3Sopenharmony_ci * 662cc1dc7a3Sopenharmony_ci * @param decimation_mode The packed decimation mode index. 663cc1dc7a3Sopenharmony_ci * 664cc1dc7a3Sopenharmony_ci * @return The decimation mode structure. 665cc1dc7a3Sopenharmony_ci */ 666cc1dc7a3Sopenharmony_ci const decimation_mode& get_decimation_mode(unsigned int decimation_mode) const 667cc1dc7a3Sopenharmony_ci { 668cc1dc7a3Sopenharmony_ci return this->decimation_modes[decimation_mode]; 669cc1dc7a3Sopenharmony_ci } 670cc1dc7a3Sopenharmony_ci 671cc1dc7a3Sopenharmony_ci /** 672cc1dc7a3Sopenharmony_ci * @brief Get the decimation info structure for index @c decimation_mode. 673cc1dc7a3Sopenharmony_ci * 674cc1dc7a3Sopenharmony_ci * This function can only return decimation modes that are enabled by the current compressor 675cc1dc7a3Sopenharmony_ci * config. The mode array is stored packed, but this is only ever indexed by the packed index 676cc1dc7a3Sopenharmony_ci * stored in the @c block_mode and never exists in an unpacked form. 677cc1dc7a3Sopenharmony_ci * 678cc1dc7a3Sopenharmony_ci * @param decimation_mode The packed decimation mode index. 679cc1dc7a3Sopenharmony_ci * 680cc1dc7a3Sopenharmony_ci * @return The decimation info structure. 681cc1dc7a3Sopenharmony_ci */ 682cc1dc7a3Sopenharmony_ci const decimation_info& get_decimation_info(unsigned int decimation_mode) const 683cc1dc7a3Sopenharmony_ci { 684cc1dc7a3Sopenharmony_ci return this->decimation_tables[decimation_mode]; 685cc1dc7a3Sopenharmony_ci } 686cc1dc7a3Sopenharmony_ci 687cc1dc7a3Sopenharmony_ci /** 688cc1dc7a3Sopenharmony_ci * @brief Get the partition info table for a given partition count. 689cc1dc7a3Sopenharmony_ci * 690cc1dc7a3Sopenharmony_ci * @param partition_count The number of partitions we want the table for. 691cc1dc7a3Sopenharmony_ci * 692cc1dc7a3Sopenharmony_ci * @return The pointer to the table of 1024 entries (for 2/3/4 parts) or 1 entry (for 1 part). 693cc1dc7a3Sopenharmony_ci */ 694cc1dc7a3Sopenharmony_ci const partition_info* get_partition_table(unsigned int partition_count) const 695cc1dc7a3Sopenharmony_ci { 696cc1dc7a3Sopenharmony_ci if (partition_count == 1) 697cc1dc7a3Sopenharmony_ci { 698cc1dc7a3Sopenharmony_ci partition_count = 5; 699cc1dc7a3Sopenharmony_ci } 700cc1dc7a3Sopenharmony_ci unsigned int index = (partition_count - 2) * BLOCK_MAX_PARTITIONINGS; 701cc1dc7a3Sopenharmony_ci return this->partitionings + index; 702cc1dc7a3Sopenharmony_ci } 703cc1dc7a3Sopenharmony_ci 704cc1dc7a3Sopenharmony_ci /** 705cc1dc7a3Sopenharmony_ci * @brief Get the partition info structure for a given partition count and seed. 706cc1dc7a3Sopenharmony_ci * 707cc1dc7a3Sopenharmony_ci * @param partition_count The number of partitions we want the info for. 708cc1dc7a3Sopenharmony_ci * @param index The partition seed (between 0 and 1023). 709cc1dc7a3Sopenharmony_ci * 710cc1dc7a3Sopenharmony_ci * @return The partition info structure. 711cc1dc7a3Sopenharmony_ci */ 712cc1dc7a3Sopenharmony_ci const partition_info& get_partition_info(unsigned int partition_count, unsigned int index) const 713cc1dc7a3Sopenharmony_ci { 714cc1dc7a3Sopenharmony_ci unsigned int packed_index = 0; 715cc1dc7a3Sopenharmony_ci if (partition_count >= 2) 716cc1dc7a3Sopenharmony_ci { 717cc1dc7a3Sopenharmony_ci packed_index = this->partitioning_packed_index[partition_count - 2][index]; 718cc1dc7a3Sopenharmony_ci } 719cc1dc7a3Sopenharmony_ci 720cc1dc7a3Sopenharmony_ci assert(packed_index != BLOCK_BAD_PARTITIONING && packed_index < this->partitioning_count_all[partition_count - 1]); 721cc1dc7a3Sopenharmony_ci auto& result = get_partition_table(partition_count)[packed_index]; 722cc1dc7a3Sopenharmony_ci assert(index == result.partition_index); 723cc1dc7a3Sopenharmony_ci return result; 724cc1dc7a3Sopenharmony_ci } 725cc1dc7a3Sopenharmony_ci 726cc1dc7a3Sopenharmony_ci /** 727cc1dc7a3Sopenharmony_ci * @brief Get the partition info structure for a given partition count and seed. 728cc1dc7a3Sopenharmony_ci * 729cc1dc7a3Sopenharmony_ci * @param partition_count The number of partitions we want the info for. 730cc1dc7a3Sopenharmony_ci * @param packed_index The raw array offset. 731cc1dc7a3Sopenharmony_ci * 732cc1dc7a3Sopenharmony_ci * @return The partition info structure. 733cc1dc7a3Sopenharmony_ci */ 734cc1dc7a3Sopenharmony_ci const partition_info& get_raw_partition_info(unsigned int partition_count, unsigned int packed_index) const 735cc1dc7a3Sopenharmony_ci { 736cc1dc7a3Sopenharmony_ci assert(packed_index != BLOCK_BAD_PARTITIONING && packed_index < this->partitioning_count_all[partition_count - 1]); 737cc1dc7a3Sopenharmony_ci auto& result = get_partition_table(partition_count)[packed_index]; 738cc1dc7a3Sopenharmony_ci return result; 739cc1dc7a3Sopenharmony_ci } 740cc1dc7a3Sopenharmony_ci}; 741cc1dc7a3Sopenharmony_ci 742cc1dc7a3Sopenharmony_ci/** 743cc1dc7a3Sopenharmony_ci * @brief The image data for a single block. 744cc1dc7a3Sopenharmony_ci * 745cc1dc7a3Sopenharmony_ci * The @c data_[rgba] fields store the image data in an encoded SoA float form designed for easy 746cc1dc7a3Sopenharmony_ci * vectorization. Input data is converted to float and stored as values between 0 and 65535. LDR 747cc1dc7a3Sopenharmony_ci * data is stored as direct UNORM data, HDR data is stored as LNS data. 748cc1dc7a3Sopenharmony_ci * 749cc1dc7a3Sopenharmony_ci * The @c rgb_lns and @c alpha_lns fields that assigned a per-texel use of HDR are only used during 750cc1dc7a3Sopenharmony_ci * decompression. The current compressor will always use HDR endpoint formats when in HDR mode. 751cc1dc7a3Sopenharmony_ci */ 752cc1dc7a3Sopenharmony_cistruct image_block 753cc1dc7a3Sopenharmony_ci{ 754cc1dc7a3Sopenharmony_ci /** @brief The input (compress) or output (decompress) data for the red color component. */ 755cc1dc7a3Sopenharmony_ci ASTCENC_ALIGNAS float data_r[BLOCK_MAX_TEXELS]; 756cc1dc7a3Sopenharmony_ci 757cc1dc7a3Sopenharmony_ci /** @brief The input (compress) or output (decompress) data for the green color component. */ 758cc1dc7a3Sopenharmony_ci ASTCENC_ALIGNAS float data_g[BLOCK_MAX_TEXELS]; 759cc1dc7a3Sopenharmony_ci 760cc1dc7a3Sopenharmony_ci /** @brief The input (compress) or output (decompress) data for the blue color component. */ 761cc1dc7a3Sopenharmony_ci ASTCENC_ALIGNAS float data_b[BLOCK_MAX_TEXELS]; 762cc1dc7a3Sopenharmony_ci 763cc1dc7a3Sopenharmony_ci /** @brief The input (compress) or output (decompress) data for the alpha color component. */ 764cc1dc7a3Sopenharmony_ci ASTCENC_ALIGNAS float data_a[BLOCK_MAX_TEXELS]; 765cc1dc7a3Sopenharmony_ci 766cc1dc7a3Sopenharmony_ci mutable partition_metrics pms[BLOCK_MAX_PARTITIONS]; 767cc1dc7a3Sopenharmony_ci 768cc1dc7a3Sopenharmony_ci /** @brief The number of texels in the block. */ 769cc1dc7a3Sopenharmony_ci uint8_t texel_count; 770cc1dc7a3Sopenharmony_ci 771cc1dc7a3Sopenharmony_ci /** @brief The original data for texel 0 for constant color block encoding. */ 772cc1dc7a3Sopenharmony_ci vfloat4 origin_texel; 773cc1dc7a3Sopenharmony_ci 774cc1dc7a3Sopenharmony_ci /** @brief The min component value of all texels in the block. */ 775cc1dc7a3Sopenharmony_ci vfloat4 data_min; 776cc1dc7a3Sopenharmony_ci 777cc1dc7a3Sopenharmony_ci /** @brief The mean component value of all texels in the block. */ 778cc1dc7a3Sopenharmony_ci vfloat4 data_mean; 779cc1dc7a3Sopenharmony_ci 780cc1dc7a3Sopenharmony_ci /** @brief The max component value of all texels in the block. */ 781cc1dc7a3Sopenharmony_ci vfloat4 data_max; 782cc1dc7a3Sopenharmony_ci 783cc1dc7a3Sopenharmony_ci /** @brief The relative error significance of the color channels. */ 784cc1dc7a3Sopenharmony_ci vfloat4 channel_weight; 785cc1dc7a3Sopenharmony_ci 786cc1dc7a3Sopenharmony_ci /** @brief Is this grayscale block where R == G == B for all texels? */ 787cc1dc7a3Sopenharmony_ci bool grayscale; 788cc1dc7a3Sopenharmony_ci 789cc1dc7a3Sopenharmony_ci /** @brief Is the eventual decode using decode_unorm8 rounding? */ 790cc1dc7a3Sopenharmony_ci bool decode_unorm8; 791cc1dc7a3Sopenharmony_ci 792cc1dc7a3Sopenharmony_ci /** @brief Set to 1 if a texel is using HDR RGB endpoints (decompression only). */ 793cc1dc7a3Sopenharmony_ci uint8_t rgb_lns[BLOCK_MAX_TEXELS]; 794cc1dc7a3Sopenharmony_ci 795cc1dc7a3Sopenharmony_ci /** @brief Set to 1 if a texel is using HDR alpha endpoints (decompression only). */ 796cc1dc7a3Sopenharmony_ci uint8_t alpha_lns[BLOCK_MAX_TEXELS]; 797cc1dc7a3Sopenharmony_ci 798cc1dc7a3Sopenharmony_ci /** @brief The X position of this block in the input or output image. */ 799cc1dc7a3Sopenharmony_ci unsigned int xpos; 800cc1dc7a3Sopenharmony_ci 801cc1dc7a3Sopenharmony_ci /** @brief The Y position of this block in the input or output image. */ 802cc1dc7a3Sopenharmony_ci unsigned int ypos; 803cc1dc7a3Sopenharmony_ci 804cc1dc7a3Sopenharmony_ci /** @brief The Z position of this block in the input or output image. */ 805cc1dc7a3Sopenharmony_ci unsigned int zpos; 806cc1dc7a3Sopenharmony_ci 807cc1dc7a3Sopenharmony_ci /** 808cc1dc7a3Sopenharmony_ci * @brief Get an RGBA texel value from the data. 809cc1dc7a3Sopenharmony_ci * 810cc1dc7a3Sopenharmony_ci * @param index The texel index. 811cc1dc7a3Sopenharmony_ci * 812cc1dc7a3Sopenharmony_ci * @return The texel in RGBA component ordering. 813cc1dc7a3Sopenharmony_ci */ 814cc1dc7a3Sopenharmony_ci inline vfloat4 texel(unsigned int index) const 815cc1dc7a3Sopenharmony_ci { 816cc1dc7a3Sopenharmony_ci return vfloat4(data_r[index], 817cc1dc7a3Sopenharmony_ci data_g[index], 818cc1dc7a3Sopenharmony_ci data_b[index], 819cc1dc7a3Sopenharmony_ci data_a[index]); 820cc1dc7a3Sopenharmony_ci } 821cc1dc7a3Sopenharmony_ci 822cc1dc7a3Sopenharmony_ci /** 823cc1dc7a3Sopenharmony_ci * @brief Get an RGB texel value from the data. 824cc1dc7a3Sopenharmony_ci * 825cc1dc7a3Sopenharmony_ci * @param index The texel index. 826cc1dc7a3Sopenharmony_ci * 827cc1dc7a3Sopenharmony_ci * @return The texel in RGB0 component ordering. 828cc1dc7a3Sopenharmony_ci */ 829cc1dc7a3Sopenharmony_ci inline vfloat4 texel3(unsigned int index) const 830cc1dc7a3Sopenharmony_ci { 831cc1dc7a3Sopenharmony_ci return vfloat3(data_r[index], 832cc1dc7a3Sopenharmony_ci data_g[index], 833cc1dc7a3Sopenharmony_ci data_b[index]); 834cc1dc7a3Sopenharmony_ci } 835cc1dc7a3Sopenharmony_ci 836cc1dc7a3Sopenharmony_ci /** 837cc1dc7a3Sopenharmony_ci * @brief Get the default alpha value for endpoints that don't store it. 838cc1dc7a3Sopenharmony_ci * 839cc1dc7a3Sopenharmony_ci * The default depends on whether the alpha endpoint is LDR or HDR. 840cc1dc7a3Sopenharmony_ci * 841cc1dc7a3Sopenharmony_ci * @return The alpha value in the scaled range used by the compressor. 842cc1dc7a3Sopenharmony_ci */ 843cc1dc7a3Sopenharmony_ci inline float get_default_alpha() const 844cc1dc7a3Sopenharmony_ci { 845cc1dc7a3Sopenharmony_ci return this->alpha_lns[0] ? static_cast<float>(0x7800) : static_cast<float>(0xFFFF); 846cc1dc7a3Sopenharmony_ci } 847cc1dc7a3Sopenharmony_ci 848cc1dc7a3Sopenharmony_ci /** 849cc1dc7a3Sopenharmony_ci * @brief Test if a single color channel is constant across the block. 850cc1dc7a3Sopenharmony_ci * 851cc1dc7a3Sopenharmony_ci * Constant color channels are easier to compress as interpolating between two identical colors 852cc1dc7a3Sopenharmony_ci * always returns the same value, irrespective of the weight used. They therefore can be ignored 853cc1dc7a3Sopenharmony_ci * for the purposes of weight selection and use of a second weight plane. 854cc1dc7a3Sopenharmony_ci * 855cc1dc7a3Sopenharmony_ci * @return @c true if the channel is constant across the block, @c false otherwise. 856cc1dc7a3Sopenharmony_ci */ 857cc1dc7a3Sopenharmony_ci inline bool is_constant_channel(int channel) const 858cc1dc7a3Sopenharmony_ci { 859cc1dc7a3Sopenharmony_ci vmask4 lane_mask = vint4::lane_id() == vint4(channel); 860cc1dc7a3Sopenharmony_ci vmask4 color_mask = this->data_min == this->data_max; 861cc1dc7a3Sopenharmony_ci return any(lane_mask & color_mask); 862cc1dc7a3Sopenharmony_ci } 863cc1dc7a3Sopenharmony_ci 864cc1dc7a3Sopenharmony_ci /** 865cc1dc7a3Sopenharmony_ci * @brief Test if this block is a luminance block with constant 1.0 alpha. 866cc1dc7a3Sopenharmony_ci * 867cc1dc7a3Sopenharmony_ci * @return @c true if the block is a luminance block , @c false otherwise. 868cc1dc7a3Sopenharmony_ci */ 869cc1dc7a3Sopenharmony_ci inline bool is_luminance() const 870cc1dc7a3Sopenharmony_ci { 871cc1dc7a3Sopenharmony_ci float default_alpha = this->get_default_alpha(); 872cc1dc7a3Sopenharmony_ci bool alpha1 = (this->data_min.lane<3>() == default_alpha) && 873cc1dc7a3Sopenharmony_ci (this->data_max.lane<3>() == default_alpha); 874cc1dc7a3Sopenharmony_ci return this->grayscale && alpha1; 875cc1dc7a3Sopenharmony_ci } 876cc1dc7a3Sopenharmony_ci 877cc1dc7a3Sopenharmony_ci /** 878cc1dc7a3Sopenharmony_ci * @brief Test if this block is a luminance block with variable alpha. 879cc1dc7a3Sopenharmony_ci * 880cc1dc7a3Sopenharmony_ci * @return @c true if the block is a luminance + alpha block , @c false otherwise. 881cc1dc7a3Sopenharmony_ci */ 882cc1dc7a3Sopenharmony_ci inline bool is_luminancealpha() const 883cc1dc7a3Sopenharmony_ci { 884cc1dc7a3Sopenharmony_ci float default_alpha = this->get_default_alpha(); 885cc1dc7a3Sopenharmony_ci bool alpha1 = (this->data_min.lane<3>() == default_alpha) && 886cc1dc7a3Sopenharmony_ci (this->data_max.lane<3>() == default_alpha); 887cc1dc7a3Sopenharmony_ci return this->grayscale && !alpha1; 888cc1dc7a3Sopenharmony_ci } 889cc1dc7a3Sopenharmony_ci}; 890cc1dc7a3Sopenharmony_ci 891cc1dc7a3Sopenharmony_ci/** 892cc1dc7a3Sopenharmony_ci * @brief Data structure storing the color endpoints for a block. 893cc1dc7a3Sopenharmony_ci */ 894cc1dc7a3Sopenharmony_cistruct endpoints 895cc1dc7a3Sopenharmony_ci{ 896cc1dc7a3Sopenharmony_ci /** @brief The number of partition endpoints stored. */ 897cc1dc7a3Sopenharmony_ci unsigned int partition_count; 898cc1dc7a3Sopenharmony_ci 899cc1dc7a3Sopenharmony_ci /** @brief The colors for endpoint 0. */ 900cc1dc7a3Sopenharmony_ci vfloat4 endpt0[BLOCK_MAX_PARTITIONS]; 901cc1dc7a3Sopenharmony_ci 902cc1dc7a3Sopenharmony_ci /** @brief The colors for endpoint 1. */ 903cc1dc7a3Sopenharmony_ci vfloat4 endpt1[BLOCK_MAX_PARTITIONS]; 904cc1dc7a3Sopenharmony_ci}; 905cc1dc7a3Sopenharmony_ci 906cc1dc7a3Sopenharmony_ci/** 907cc1dc7a3Sopenharmony_ci * @brief Data structure storing the color endpoints and weights. 908cc1dc7a3Sopenharmony_ci */ 909cc1dc7a3Sopenharmony_cistruct endpoints_and_weights 910cc1dc7a3Sopenharmony_ci{ 911cc1dc7a3Sopenharmony_ci /** @brief True if all active values in weight_error_scale are the same. */ 912cc1dc7a3Sopenharmony_ci bool is_constant_weight_error_scale; 913cc1dc7a3Sopenharmony_ci 914cc1dc7a3Sopenharmony_ci /** @brief The color endpoints. */ 915cc1dc7a3Sopenharmony_ci endpoints ep; 916cc1dc7a3Sopenharmony_ci 917cc1dc7a3Sopenharmony_ci /** @brief The ideal weight for each texel; may be undecimated or decimated. */ 918cc1dc7a3Sopenharmony_ci ASTCENC_ALIGNAS float weights[BLOCK_MAX_TEXELS]; 919cc1dc7a3Sopenharmony_ci 920cc1dc7a3Sopenharmony_ci /** @brief The ideal weight error scaling for each texel; may be undecimated or decimated. */ 921cc1dc7a3Sopenharmony_ci ASTCENC_ALIGNAS float weight_error_scale[BLOCK_MAX_TEXELS]; 922cc1dc7a3Sopenharmony_ci}; 923cc1dc7a3Sopenharmony_ci 924cc1dc7a3Sopenharmony_ci/** 925cc1dc7a3Sopenharmony_ci * @brief Utility storing estimated errors from choosing particular endpoint encodings. 926cc1dc7a3Sopenharmony_ci */ 927cc1dc7a3Sopenharmony_cistruct encoding_choice_errors 928cc1dc7a3Sopenharmony_ci{ 929cc1dc7a3Sopenharmony_ci /** @brief Error of using LDR RGB-scale instead of complete endpoints. */ 930cc1dc7a3Sopenharmony_ci float rgb_scale_error; 931cc1dc7a3Sopenharmony_ci 932cc1dc7a3Sopenharmony_ci /** @brief Error of using HDR RGB-scale instead of complete endpoints. */ 933cc1dc7a3Sopenharmony_ci float rgb_luma_error; 934cc1dc7a3Sopenharmony_ci 935cc1dc7a3Sopenharmony_ci /** @brief Error of using luminance instead of RGB. */ 936cc1dc7a3Sopenharmony_ci float luminance_error; 937cc1dc7a3Sopenharmony_ci 938cc1dc7a3Sopenharmony_ci /** @brief Error of discarding alpha and using a constant 1.0 alpha. */ 939cc1dc7a3Sopenharmony_ci float alpha_drop_error; 940cc1dc7a3Sopenharmony_ci 941cc1dc7a3Sopenharmony_ci /** @brief Can we use delta offset encoding? */ 942cc1dc7a3Sopenharmony_ci bool can_offset_encode; 943cc1dc7a3Sopenharmony_ci 944cc1dc7a3Sopenharmony_ci /** @brief Can we use blue contraction encoding? */ 945cc1dc7a3Sopenharmony_ci bool can_blue_contract; 946cc1dc7a3Sopenharmony_ci}; 947cc1dc7a3Sopenharmony_ci 948cc1dc7a3Sopenharmony_ci/** 949cc1dc7a3Sopenharmony_ci * @brief Preallocated working buffers, allocated per thread during context creation. 950cc1dc7a3Sopenharmony_ci */ 951cc1dc7a3Sopenharmony_cistruct ASTCENC_ALIGNAS compression_working_buffers 952cc1dc7a3Sopenharmony_ci{ 953cc1dc7a3Sopenharmony_ci /** @brief Ideal endpoints and weights for plane 1. */ 954cc1dc7a3Sopenharmony_ci endpoints_and_weights ei1; 955cc1dc7a3Sopenharmony_ci 956cc1dc7a3Sopenharmony_ci /** @brief Ideal endpoints and weights for plane 2. */ 957cc1dc7a3Sopenharmony_ci endpoints_and_weights ei2; 958cc1dc7a3Sopenharmony_ci 959cc1dc7a3Sopenharmony_ci /** 960cc1dc7a3Sopenharmony_ci * @brief Decimated ideal weight values in the ~0-1 range. 961cc1dc7a3Sopenharmony_ci * 962cc1dc7a3Sopenharmony_ci * Note that values can be slightly below zero or higher than one due to 963cc1dc7a3Sopenharmony_ci * endpoint extents being inside the ideal color representation. 964cc1dc7a3Sopenharmony_ci * 965cc1dc7a3Sopenharmony_ci * For two planes, second plane starts at @c WEIGHTS_PLANE2_OFFSET offsets. 966cc1dc7a3Sopenharmony_ci */ 967cc1dc7a3Sopenharmony_ci ASTCENC_ALIGNAS float dec_weights_ideal[WEIGHTS_MAX_DECIMATION_MODES * BLOCK_MAX_WEIGHTS]; 968cc1dc7a3Sopenharmony_ci 969cc1dc7a3Sopenharmony_ci /** 970cc1dc7a3Sopenharmony_ci * @brief Decimated quantized weight values in the unquantized 0-64 range. 971cc1dc7a3Sopenharmony_ci * 972cc1dc7a3Sopenharmony_ci * For two planes, second plane starts at @c WEIGHTS_PLANE2_OFFSET offsets. 973cc1dc7a3Sopenharmony_ci */ 974cc1dc7a3Sopenharmony_ci uint8_t dec_weights_uquant[WEIGHTS_MAX_BLOCK_MODES * BLOCK_MAX_WEIGHTS]; 975cc1dc7a3Sopenharmony_ci 976cc1dc7a3Sopenharmony_ci /** @brief Error of the best encoding combination for each block mode. */ 977cc1dc7a3Sopenharmony_ci ASTCENC_ALIGNAS float errors_of_best_combination[WEIGHTS_MAX_BLOCK_MODES]; 978cc1dc7a3Sopenharmony_ci 979cc1dc7a3Sopenharmony_ci /** @brief The best color quant for each block mode. */ 980cc1dc7a3Sopenharmony_ci uint8_t best_quant_levels[WEIGHTS_MAX_BLOCK_MODES]; 981cc1dc7a3Sopenharmony_ci 982cc1dc7a3Sopenharmony_ci /** @brief The best color quant for each block mode if modes are the same and we have spare bits. */ 983cc1dc7a3Sopenharmony_ci uint8_t best_quant_levels_mod[WEIGHTS_MAX_BLOCK_MODES]; 984cc1dc7a3Sopenharmony_ci 985cc1dc7a3Sopenharmony_ci /** @brief The best endpoint format for each partition. */ 986cc1dc7a3Sopenharmony_ci uint8_t best_ep_formats[WEIGHTS_MAX_BLOCK_MODES][BLOCK_MAX_PARTITIONS]; 987cc1dc7a3Sopenharmony_ci 988cc1dc7a3Sopenharmony_ci /** @brief The total bit storage needed for quantized weights for each block mode. */ 989cc1dc7a3Sopenharmony_ci int8_t qwt_bitcounts[WEIGHTS_MAX_BLOCK_MODES]; 990cc1dc7a3Sopenharmony_ci 991cc1dc7a3Sopenharmony_ci /** @brief The cumulative error for quantized weights for each block mode. */ 992cc1dc7a3Sopenharmony_ci float qwt_errors[WEIGHTS_MAX_BLOCK_MODES]; 993cc1dc7a3Sopenharmony_ci 994cc1dc7a3Sopenharmony_ci /** @brief The low weight value in plane 1 for each block mode. */ 995cc1dc7a3Sopenharmony_ci float weight_low_value1[WEIGHTS_MAX_BLOCK_MODES]; 996cc1dc7a3Sopenharmony_ci 997cc1dc7a3Sopenharmony_ci /** @brief The high weight value in plane 1 for each block mode. */ 998cc1dc7a3Sopenharmony_ci float weight_high_value1[WEIGHTS_MAX_BLOCK_MODES]; 999cc1dc7a3Sopenharmony_ci 1000cc1dc7a3Sopenharmony_ci /** @brief The low weight value in plane 1 for each quant level and decimation mode. */ 1001cc1dc7a3Sopenharmony_ci float weight_low_values1[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1]; 1002cc1dc7a3Sopenharmony_ci 1003cc1dc7a3Sopenharmony_ci /** @brief The high weight value in plane 1 for each quant level and decimation mode. */ 1004cc1dc7a3Sopenharmony_ci float weight_high_values1[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1]; 1005cc1dc7a3Sopenharmony_ci 1006cc1dc7a3Sopenharmony_ci /** @brief The low weight value in plane 2 for each block mode. */ 1007cc1dc7a3Sopenharmony_ci float weight_low_value2[WEIGHTS_MAX_BLOCK_MODES]; 1008cc1dc7a3Sopenharmony_ci 1009cc1dc7a3Sopenharmony_ci /** @brief The high weight value in plane 2 for each block mode. */ 1010cc1dc7a3Sopenharmony_ci float weight_high_value2[WEIGHTS_MAX_BLOCK_MODES]; 1011cc1dc7a3Sopenharmony_ci 1012cc1dc7a3Sopenharmony_ci /** @brief The low weight value in plane 2 for each quant level and decimation mode. */ 1013cc1dc7a3Sopenharmony_ci float weight_low_values2[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1]; 1014cc1dc7a3Sopenharmony_ci 1015cc1dc7a3Sopenharmony_ci /** @brief The high weight value in plane 2 for each quant level and decimation mode. */ 1016cc1dc7a3Sopenharmony_ci float weight_high_values2[WEIGHTS_MAX_DECIMATION_MODES][TUNE_MAX_ANGULAR_QUANT + 1]; 1017cc1dc7a3Sopenharmony_ci}; 1018cc1dc7a3Sopenharmony_ci 1019cc1dc7a3Sopenharmony_cistruct dt_init_working_buffers 1020cc1dc7a3Sopenharmony_ci{ 1021cc1dc7a3Sopenharmony_ci uint8_t weight_count_of_texel[BLOCK_MAX_TEXELS]; 1022cc1dc7a3Sopenharmony_ci uint8_t grid_weights_of_texel[BLOCK_MAX_TEXELS][4]; 1023cc1dc7a3Sopenharmony_ci uint8_t weights_of_texel[BLOCK_MAX_TEXELS][4]; 1024cc1dc7a3Sopenharmony_ci 1025cc1dc7a3Sopenharmony_ci uint8_t texel_count_of_weight[BLOCK_MAX_WEIGHTS]; 1026cc1dc7a3Sopenharmony_ci uint8_t texels_of_weight[BLOCK_MAX_WEIGHTS][BLOCK_MAX_TEXELS]; 1027cc1dc7a3Sopenharmony_ci uint8_t texel_weights_of_weight[BLOCK_MAX_WEIGHTS][BLOCK_MAX_TEXELS]; 1028cc1dc7a3Sopenharmony_ci}; 1029cc1dc7a3Sopenharmony_ci 1030cc1dc7a3Sopenharmony_ci/** 1031cc1dc7a3Sopenharmony_ci * @brief Weight quantization transfer table. 1032cc1dc7a3Sopenharmony_ci * 1033cc1dc7a3Sopenharmony_ci * ASTC can store texel weights at many quantization levels, so for performance we store essential 1034cc1dc7a3Sopenharmony_ci * information about each level as a precomputed data structure. Unquantized weights are integers 1035cc1dc7a3Sopenharmony_ci * or floats in the range [0, 64]. 1036cc1dc7a3Sopenharmony_ci * 1037cc1dc7a3Sopenharmony_ci * This structure provides a table, used to estimate the closest quantized weight for a given 1038cc1dc7a3Sopenharmony_ci * floating-point weight. For each quantized weight, the corresponding unquantized values. For each 1039cc1dc7a3Sopenharmony_ci * quantized weight, a previous-value and a next-value. 1040cc1dc7a3Sopenharmony_ci*/ 1041cc1dc7a3Sopenharmony_cistruct quant_and_transfer_table 1042cc1dc7a3Sopenharmony_ci{ 1043cc1dc7a3Sopenharmony_ci /** @brief The unscrambled unquantized value. */ 1044cc1dc7a3Sopenharmony_ci uint8_t quant_to_unquant[32]; 1045cc1dc7a3Sopenharmony_ci 1046cc1dc7a3Sopenharmony_ci /** @brief The scrambling order: scrambled_quant = map[unscrambled_quant]. */ 1047cc1dc7a3Sopenharmony_ci uint8_t scramble_map[32]; 1048cc1dc7a3Sopenharmony_ci 1049cc1dc7a3Sopenharmony_ci /** @brief The unscrambling order: unscrambled_unquant = map[scrambled_quant]. */ 1050cc1dc7a3Sopenharmony_ci uint8_t unscramble_and_unquant_map[32]; 1051cc1dc7a3Sopenharmony_ci 1052cc1dc7a3Sopenharmony_ci /** 1053cc1dc7a3Sopenharmony_ci * @brief A table of previous-and-next weights, indexed by the current unquantized value. 1054cc1dc7a3Sopenharmony_ci * * bits 7:0 = previous-index, unquantized 1055cc1dc7a3Sopenharmony_ci * * bits 15:8 = next-index, unquantized 1056cc1dc7a3Sopenharmony_ci */ 1057cc1dc7a3Sopenharmony_ci uint16_t prev_next_values[65]; 1058cc1dc7a3Sopenharmony_ci}; 1059cc1dc7a3Sopenharmony_ci 1060cc1dc7a3Sopenharmony_ci/** @brief The precomputed quant and transfer table. */ 1061cc1dc7a3Sopenharmony_ciextern const quant_and_transfer_table quant_and_xfer_tables[12]; 1062cc1dc7a3Sopenharmony_ci 1063cc1dc7a3Sopenharmony_ci/** @brief The block is an error block, and will return error color or NaN. */ 1064cc1dc7a3Sopenharmony_cistatic constexpr uint8_t SYM_BTYPE_ERROR { 0 }; 1065cc1dc7a3Sopenharmony_ci 1066cc1dc7a3Sopenharmony_ci/** @brief The block is a constant color block using FP16 colors. */ 1067cc1dc7a3Sopenharmony_cistatic constexpr uint8_t SYM_BTYPE_CONST_F16 { 1 }; 1068cc1dc7a3Sopenharmony_ci 1069cc1dc7a3Sopenharmony_ci/** @brief The block is a constant color block using UNORM16 colors. */ 1070cc1dc7a3Sopenharmony_cistatic constexpr uint8_t SYM_BTYPE_CONST_U16 { 2 }; 1071cc1dc7a3Sopenharmony_ci 1072cc1dc7a3Sopenharmony_ci/** @brief The block is a normal non-constant color block. */ 1073cc1dc7a3Sopenharmony_cistatic constexpr uint8_t SYM_BTYPE_NONCONST { 3 }; 1074cc1dc7a3Sopenharmony_ci 1075cc1dc7a3Sopenharmony_ci/** 1076cc1dc7a3Sopenharmony_ci * @brief A symbolic representation of a compressed block. 1077cc1dc7a3Sopenharmony_ci * 1078cc1dc7a3Sopenharmony_ci * The symbolic representation stores the unpacked content of a single 1079cc1dc7a3Sopenharmony_ci * physical compressed block, in a form which is much easier to access for 1080cc1dc7a3Sopenharmony_ci * the rest of the compressor code. 1081cc1dc7a3Sopenharmony_ci */ 1082cc1dc7a3Sopenharmony_cistruct symbolic_compressed_block 1083cc1dc7a3Sopenharmony_ci{ 1084cc1dc7a3Sopenharmony_ci /** @brief The block type, one of the @c SYM_BTYPE_* constants. */ 1085cc1dc7a3Sopenharmony_ci uint8_t block_type; 1086cc1dc7a3Sopenharmony_ci 1087cc1dc7a3Sopenharmony_ci /** @brief The number of partitions; valid for @c NONCONST blocks. */ 1088cc1dc7a3Sopenharmony_ci uint8_t partition_count; 1089cc1dc7a3Sopenharmony_ci 1090cc1dc7a3Sopenharmony_ci /** @brief Non-zero if the color formats matched; valid for @c NONCONST blocks. */ 1091cc1dc7a3Sopenharmony_ci uint8_t color_formats_matched; 1092cc1dc7a3Sopenharmony_ci 1093cc1dc7a3Sopenharmony_ci /** @brief The plane 2 color component, or -1 if single plane; valid for @c NONCONST blocks. */ 1094cc1dc7a3Sopenharmony_ci int8_t plane2_component; 1095cc1dc7a3Sopenharmony_ci 1096cc1dc7a3Sopenharmony_ci /** @brief The block mode; valid for @c NONCONST blocks. */ 1097cc1dc7a3Sopenharmony_ci uint16_t block_mode; 1098cc1dc7a3Sopenharmony_ci 1099cc1dc7a3Sopenharmony_ci /** @brief The partition index; valid for @c NONCONST blocks if 2 or more partitions. */ 1100cc1dc7a3Sopenharmony_ci uint16_t partition_index; 1101cc1dc7a3Sopenharmony_ci 1102cc1dc7a3Sopenharmony_ci /** @brief The endpoint color formats for each partition; valid for @c NONCONST blocks. */ 1103cc1dc7a3Sopenharmony_ci uint8_t color_formats[BLOCK_MAX_PARTITIONS]; 1104cc1dc7a3Sopenharmony_ci 1105cc1dc7a3Sopenharmony_ci /** @brief The endpoint color quant mode; valid for @c NONCONST blocks. */ 1106cc1dc7a3Sopenharmony_ci quant_method quant_mode; 1107cc1dc7a3Sopenharmony_ci 1108cc1dc7a3Sopenharmony_ci /** @brief The error of the current encoding; valid for @c NONCONST blocks. */ 1109cc1dc7a3Sopenharmony_ci float errorval; 1110cc1dc7a3Sopenharmony_ci 1111cc1dc7a3Sopenharmony_ci // We can't have both of these at the same time 1112cc1dc7a3Sopenharmony_ci union { 1113cc1dc7a3Sopenharmony_ci /** @brief The constant color; valid for @c CONST blocks. */ 1114cc1dc7a3Sopenharmony_ci int constant_color[BLOCK_MAX_COMPONENTS]; 1115cc1dc7a3Sopenharmony_ci 1116cc1dc7a3Sopenharmony_ci /** @brief The quantized endpoint color pairs; valid for @c NONCONST blocks. */ 1117cc1dc7a3Sopenharmony_ci uint8_t color_values[BLOCK_MAX_PARTITIONS][8]; 1118cc1dc7a3Sopenharmony_ci }; 1119cc1dc7a3Sopenharmony_ci 1120cc1dc7a3Sopenharmony_ci /** @brief The quantized and decimated weights. 1121cc1dc7a3Sopenharmony_ci * 1122cc1dc7a3Sopenharmony_ci * Weights are stored in the 0-64 unpacked range allowing them to be used 1123cc1dc7a3Sopenharmony_ci * directly in encoding passes without per-use unpacking. Packing happens 1124cc1dc7a3Sopenharmony_ci * when converting to/from the physical bitstream encoding. 1125cc1dc7a3Sopenharmony_ci * 1126cc1dc7a3Sopenharmony_ci * If dual plane, the second plane starts at @c weights[WEIGHTS_PLANE2_OFFSET]. 1127cc1dc7a3Sopenharmony_ci */ 1128cc1dc7a3Sopenharmony_ci uint8_t weights[BLOCK_MAX_WEIGHTS]; 1129cc1dc7a3Sopenharmony_ci 1130cc1dc7a3Sopenharmony_ci /** 1131cc1dc7a3Sopenharmony_ci * @brief Get the weight quantization used by this block mode. 1132cc1dc7a3Sopenharmony_ci * 1133cc1dc7a3Sopenharmony_ci * @return The quantization level. 1134cc1dc7a3Sopenharmony_ci */ 1135cc1dc7a3Sopenharmony_ci inline quant_method get_color_quant_mode() const 1136cc1dc7a3Sopenharmony_ci { 1137cc1dc7a3Sopenharmony_ci return this->quant_mode; 1138cc1dc7a3Sopenharmony_ci } 1139cc1dc7a3Sopenharmony_ci QualityProfile privateProfile; 1140cc1dc7a3Sopenharmony_ci}; 1141cc1dc7a3Sopenharmony_ci 1142cc1dc7a3Sopenharmony_ci/** 1143cc1dc7a3Sopenharmony_ci * @brief Parameter structure for @c compute_pixel_region_variance(). 1144cc1dc7a3Sopenharmony_ci * 1145cc1dc7a3Sopenharmony_ci * This function takes a structure to avoid spilling arguments to the stack on every function 1146cc1dc7a3Sopenharmony_ci * invocation, as there are a lot of parameters. 1147cc1dc7a3Sopenharmony_ci */ 1148cc1dc7a3Sopenharmony_cistruct pixel_region_args 1149cc1dc7a3Sopenharmony_ci{ 1150cc1dc7a3Sopenharmony_ci /** @brief The image to analyze. */ 1151cc1dc7a3Sopenharmony_ci const astcenc_image* img; 1152cc1dc7a3Sopenharmony_ci 1153cc1dc7a3Sopenharmony_ci /** @brief The component swizzle pattern. */ 1154cc1dc7a3Sopenharmony_ci astcenc_swizzle swz; 1155cc1dc7a3Sopenharmony_ci 1156cc1dc7a3Sopenharmony_ci /** @brief Should the algorithm bother with Z axis processing? */ 1157cc1dc7a3Sopenharmony_ci bool have_z; 1158cc1dc7a3Sopenharmony_ci 1159cc1dc7a3Sopenharmony_ci /** @brief The kernel radius for alpha processing. */ 1160cc1dc7a3Sopenharmony_ci unsigned int alpha_kernel_radius; 1161cc1dc7a3Sopenharmony_ci 1162cc1dc7a3Sopenharmony_ci /** @brief The X dimension of the working data to process. */ 1163cc1dc7a3Sopenharmony_ci unsigned int size_x; 1164cc1dc7a3Sopenharmony_ci 1165cc1dc7a3Sopenharmony_ci /** @brief The Y dimension of the working data to process. */ 1166cc1dc7a3Sopenharmony_ci unsigned int size_y; 1167cc1dc7a3Sopenharmony_ci 1168cc1dc7a3Sopenharmony_ci /** @brief The Z dimension of the working data to process. */ 1169cc1dc7a3Sopenharmony_ci unsigned int size_z; 1170cc1dc7a3Sopenharmony_ci 1171cc1dc7a3Sopenharmony_ci /** @brief The X position of first src and dst data in the data set. */ 1172cc1dc7a3Sopenharmony_ci unsigned int offset_x; 1173cc1dc7a3Sopenharmony_ci 1174cc1dc7a3Sopenharmony_ci /** @brief The Y position of first src and dst data in the data set. */ 1175cc1dc7a3Sopenharmony_ci unsigned int offset_y; 1176cc1dc7a3Sopenharmony_ci 1177cc1dc7a3Sopenharmony_ci /** @brief The Z position of first src and dst data in the data set. */ 1178cc1dc7a3Sopenharmony_ci unsigned int offset_z; 1179cc1dc7a3Sopenharmony_ci 1180cc1dc7a3Sopenharmony_ci /** @brief The working memory buffer. */ 1181cc1dc7a3Sopenharmony_ci vfloat4 *work_memory; 1182cc1dc7a3Sopenharmony_ci}; 1183cc1dc7a3Sopenharmony_ci 1184cc1dc7a3Sopenharmony_ci/** 1185cc1dc7a3Sopenharmony_ci * @brief Parameter structure for @c compute_averages_proc(). 1186cc1dc7a3Sopenharmony_ci */ 1187cc1dc7a3Sopenharmony_cistruct avg_args 1188cc1dc7a3Sopenharmony_ci{ 1189cc1dc7a3Sopenharmony_ci /** @brief The arguments for the nested variance computation. */ 1190cc1dc7a3Sopenharmony_ci pixel_region_args arg; 1191cc1dc7a3Sopenharmony_ci 1192cc1dc7a3Sopenharmony_ci /** @brief The image Stride dimensions. */ 1193cc1dc7a3Sopenharmony_ci unsigned int img_size_stride; 1194cc1dc7a3Sopenharmony_ci 1195cc1dc7a3Sopenharmony_ci /** @brief The image X dimensions. */ 1196cc1dc7a3Sopenharmony_ci unsigned int img_size_x; 1197cc1dc7a3Sopenharmony_ci 1198cc1dc7a3Sopenharmony_ci /** @brief The image Y dimensions. */ 1199cc1dc7a3Sopenharmony_ci unsigned int img_size_y; 1200cc1dc7a3Sopenharmony_ci 1201cc1dc7a3Sopenharmony_ci /** @brief The image Z dimensions. */ 1202cc1dc7a3Sopenharmony_ci unsigned int img_size_z; 1203cc1dc7a3Sopenharmony_ci 1204cc1dc7a3Sopenharmony_ci /** @brief The maximum working block dimensions in X and Y dimensions. */ 1205cc1dc7a3Sopenharmony_ci unsigned int blk_size_xy; 1206cc1dc7a3Sopenharmony_ci 1207cc1dc7a3Sopenharmony_ci /** @brief The maximum working block dimensions in Z dimensions. */ 1208cc1dc7a3Sopenharmony_ci unsigned int blk_size_z; 1209cc1dc7a3Sopenharmony_ci 1210cc1dc7a3Sopenharmony_ci /** @brief The working block memory size. */ 1211cc1dc7a3Sopenharmony_ci unsigned int work_memory_size; 1212cc1dc7a3Sopenharmony_ci}; 1213cc1dc7a3Sopenharmony_ci 1214cc1dc7a3Sopenharmony_ci#if defined(ASTCENC_DIAGNOSTICS) 1215cc1dc7a3Sopenharmony_ci/* See astcenc_diagnostic_trace header for details. */ 1216cc1dc7a3Sopenharmony_ciclass TraceLog; 1217cc1dc7a3Sopenharmony_ci#endif 1218cc1dc7a3Sopenharmony_ci 1219cc1dc7a3Sopenharmony_ci/** 1220cc1dc7a3Sopenharmony_ci * @brief The astcenc compression context. 1221cc1dc7a3Sopenharmony_ci */ 1222cc1dc7a3Sopenharmony_cistruct astcenc_contexti 1223cc1dc7a3Sopenharmony_ci{ 1224cc1dc7a3Sopenharmony_ci /** @brief The configuration this context was created with. */ 1225cc1dc7a3Sopenharmony_ci astcenc_config config; 1226cc1dc7a3Sopenharmony_ci 1227cc1dc7a3Sopenharmony_ci /** @brief The thread count supported by this context. */ 1228cc1dc7a3Sopenharmony_ci unsigned int thread_count; 1229cc1dc7a3Sopenharmony_ci 1230cc1dc7a3Sopenharmony_ci /** @brief The block size descriptor this context was created with. */ 1231cc1dc7a3Sopenharmony_ci block_size_descriptor* bsd; 1232cc1dc7a3Sopenharmony_ci 1233cc1dc7a3Sopenharmony_ci /* 1234cc1dc7a3Sopenharmony_ci * Fields below here are not needed in a decompress-only build, but some remain as they are 1235cc1dc7a3Sopenharmony_ci * small and it avoids littering the code with #ifdefs. The most significant contributors to 1236cc1dc7a3Sopenharmony_ci * large structure size are omitted. 1237cc1dc7a3Sopenharmony_ci */ 1238cc1dc7a3Sopenharmony_ci 1239cc1dc7a3Sopenharmony_ci /** @brief The input image alpha channel averages table, may be @c nullptr if not needed. */ 1240cc1dc7a3Sopenharmony_ci float* input_alpha_averages; 1241cc1dc7a3Sopenharmony_ci 1242cc1dc7a3Sopenharmony_ci /** @brief The scratch working buffers, one per thread (see @c thread_count). */ 1243cc1dc7a3Sopenharmony_ci compression_working_buffers* working_buffers; 1244cc1dc7a3Sopenharmony_ci 1245cc1dc7a3Sopenharmony_ci#if !defined(ASTCENC_DECOMPRESS_ONLY) 1246cc1dc7a3Sopenharmony_ci /** @brief The pixel region and variance worker arguments. */ 1247cc1dc7a3Sopenharmony_ci avg_args avg_preprocess_args; 1248cc1dc7a3Sopenharmony_ci#endif 1249cc1dc7a3Sopenharmony_ci 1250cc1dc7a3Sopenharmony_ci#if defined(ASTCENC_DIAGNOSTICS) 1251cc1dc7a3Sopenharmony_ci /** 1252cc1dc7a3Sopenharmony_ci * @brief The diagnostic trace logger. 1253cc1dc7a3Sopenharmony_ci * 1254cc1dc7a3Sopenharmony_ci * Note that this is a singleton, so can only be used in single threaded mode. It only exists 1255cc1dc7a3Sopenharmony_ci * here so we have a reference to close the file at the end of the capture. 1256cc1dc7a3Sopenharmony_ci */ 1257cc1dc7a3Sopenharmony_ci TraceLog* trace_log; 1258cc1dc7a3Sopenharmony_ci#endif 1259cc1dc7a3Sopenharmony_ci}; 1260cc1dc7a3Sopenharmony_ci 1261cc1dc7a3Sopenharmony_ci/* ============================================================================ 1262cc1dc7a3Sopenharmony_ci Functionality for managing block sizes and partition tables. 1263cc1dc7a3Sopenharmony_ci============================================================================ */ 1264cc1dc7a3Sopenharmony_ci 1265cc1dc7a3Sopenharmony_ci/** 1266cc1dc7a3Sopenharmony_ci * @brief Populate the block size descriptor for the target block size. 1267cc1dc7a3Sopenharmony_ci * 1268cc1dc7a3Sopenharmony_ci * This will also initialize the partition table metadata, which is stored as part of the BSD 1269cc1dc7a3Sopenharmony_ci * structure. 1270cc1dc7a3Sopenharmony_ci * 1271cc1dc7a3Sopenharmony_ci * @param x_texels The number of texels in the block X dimension. 1272cc1dc7a3Sopenharmony_ci * @param y_texels The number of texels in the block Y dimension. 1273cc1dc7a3Sopenharmony_ci * @param z_texels The number of texels in the block Z dimension. 1274cc1dc7a3Sopenharmony_ci * @param can_omit_modes Can we discard modes and partitionings that astcenc won't use? 1275cc1dc7a3Sopenharmony_ci * @param partition_count_cutoff The partition count cutoff to use, if we can omit partitionings. 1276cc1dc7a3Sopenharmony_ci * @param mode_cutoff The block mode percentile cutoff [0-1]. 1277cc1dc7a3Sopenharmony_ci * @param[out] bsd The descriptor to initialize. 1278cc1dc7a3Sopenharmony_ci */ 1279cc1dc7a3Sopenharmony_ci#ifdef ASTC_CUSTOMIZED_ENABLE 1280cc1dc7a3Sopenharmony_cibool init_block_size_descriptor( 1281cc1dc7a3Sopenharmony_ci#else 1282cc1dc7a3Sopenharmony_civoid init_block_size_descriptor( 1283cc1dc7a3Sopenharmony_ci#endif 1284cc1dc7a3Sopenharmony_ci QualityProfile privateProfile, 1285cc1dc7a3Sopenharmony_ci unsigned int x_texels, 1286cc1dc7a3Sopenharmony_ci unsigned int y_texels, 1287cc1dc7a3Sopenharmony_ci unsigned int z_texels, 1288cc1dc7a3Sopenharmony_ci bool can_omit_modes, 1289cc1dc7a3Sopenharmony_ci unsigned int partition_count_cutoff, 1290cc1dc7a3Sopenharmony_ci float mode_cutoff, 1291cc1dc7a3Sopenharmony_ci block_size_descriptor& bsd); 1292cc1dc7a3Sopenharmony_ci 1293cc1dc7a3Sopenharmony_ci/** 1294cc1dc7a3Sopenharmony_ci * @brief Populate the partition tables for the target block size. 1295cc1dc7a3Sopenharmony_ci * 1296cc1dc7a3Sopenharmony_ci * Note the @c bsd descriptor must be initialized by calling @c init_block_size_descriptor() before 1297cc1dc7a3Sopenharmony_ci * calling this function. 1298cc1dc7a3Sopenharmony_ci * 1299cc1dc7a3Sopenharmony_ci * @param[out] bsd The block size information structure to populate. 1300cc1dc7a3Sopenharmony_ci * @param can_omit_partitionings True if we can we drop partitionings that astcenc won't use. 1301cc1dc7a3Sopenharmony_ci * @param partition_count_cutoff The partition count cutoff to use, if we can omit partitionings. 1302cc1dc7a3Sopenharmony_ci */ 1303cc1dc7a3Sopenharmony_civoid init_partition_tables( 1304cc1dc7a3Sopenharmony_ci block_size_descriptor& bsd, 1305cc1dc7a3Sopenharmony_ci bool can_omit_partitionings, 1306cc1dc7a3Sopenharmony_ci unsigned int partition_count_cutoff); 1307cc1dc7a3Sopenharmony_ci 1308cc1dc7a3Sopenharmony_ci/** 1309cc1dc7a3Sopenharmony_ci * @brief Get the percentile table for 2D block modes. 1310cc1dc7a3Sopenharmony_ci * 1311cc1dc7a3Sopenharmony_ci * This is an empirically determined prioritization of which block modes to use in the search in 1312cc1dc7a3Sopenharmony_ci * terms of their centile (lower centiles = more useful). 1313cc1dc7a3Sopenharmony_ci * 1314cc1dc7a3Sopenharmony_ci * Returns a dynamically allocated array; caller must free with delete[]. 1315cc1dc7a3Sopenharmony_ci * 1316cc1dc7a3Sopenharmony_ci * @param xdim The block x size. 1317cc1dc7a3Sopenharmony_ci * @param ydim The block y size. 1318cc1dc7a3Sopenharmony_ci * 1319cc1dc7a3Sopenharmony_ci * @return The unpacked table. 1320cc1dc7a3Sopenharmony_ci */ 1321cc1dc7a3Sopenharmony_ciconst float* get_2d_percentile_table( 1322cc1dc7a3Sopenharmony_ci unsigned int xdim, 1323cc1dc7a3Sopenharmony_ci unsigned int ydim); 1324cc1dc7a3Sopenharmony_ci 1325cc1dc7a3Sopenharmony_ci/** 1326cc1dc7a3Sopenharmony_ci * @brief Query if a 2D block size is legal. 1327cc1dc7a3Sopenharmony_ci * 1328cc1dc7a3Sopenharmony_ci * @return True if legal, false otherwise. 1329cc1dc7a3Sopenharmony_ci */ 1330cc1dc7a3Sopenharmony_cibool is_legal_2d_block_size( 1331cc1dc7a3Sopenharmony_ci unsigned int xdim, 1332cc1dc7a3Sopenharmony_ci unsigned int ydim); 1333cc1dc7a3Sopenharmony_ci 1334cc1dc7a3Sopenharmony_ci/** 1335cc1dc7a3Sopenharmony_ci * @brief Query if a 3D block size is legal. 1336cc1dc7a3Sopenharmony_ci * 1337cc1dc7a3Sopenharmony_ci * @return True if legal, false otherwise. 1338cc1dc7a3Sopenharmony_ci */ 1339cc1dc7a3Sopenharmony_cibool is_legal_3d_block_size( 1340cc1dc7a3Sopenharmony_ci unsigned int xdim, 1341cc1dc7a3Sopenharmony_ci unsigned int ydim, 1342cc1dc7a3Sopenharmony_ci unsigned int zdim); 1343cc1dc7a3Sopenharmony_ci 1344cc1dc7a3Sopenharmony_ci/* ============================================================================ 1345cc1dc7a3Sopenharmony_ci Functionality for managing BISE quantization and unquantization. 1346cc1dc7a3Sopenharmony_ci============================================================================ */ 1347cc1dc7a3Sopenharmony_ci 1348cc1dc7a3Sopenharmony_ci/** 1349cc1dc7a3Sopenharmony_ci * @brief The precomputed table for quantizing color values. 1350cc1dc7a3Sopenharmony_ci * 1351cc1dc7a3Sopenharmony_ci * Converts unquant value in 0-255 range into quant value in 0-255 range. 1352cc1dc7a3Sopenharmony_ci * No BISE scrambling is applied at this stage. 1353cc1dc7a3Sopenharmony_ci * 1354cc1dc7a3Sopenharmony_ci * The BISE encoding results in ties where available quant<256> values are 1355cc1dc7a3Sopenharmony_ci * equidistant the available quant<BISE> values. This table stores two values 1356cc1dc7a3Sopenharmony_ci * for each input - one for use with a negative residual, and one for use with 1357cc1dc7a3Sopenharmony_ci * a positive residual. 1358cc1dc7a3Sopenharmony_ci * 1359cc1dc7a3Sopenharmony_ci * Indexed by [quant_mode - 4][data_value * 2 + residual]. 1360cc1dc7a3Sopenharmony_ci */ 1361cc1dc7a3Sopenharmony_ciextern const uint8_t color_unquant_to_uquant_tables[17][512]; 1362cc1dc7a3Sopenharmony_ci 1363cc1dc7a3Sopenharmony_ci/** 1364cc1dc7a3Sopenharmony_ci * @brief The precomputed table for packing quantized color values. 1365cc1dc7a3Sopenharmony_ci * 1366cc1dc7a3Sopenharmony_ci * Converts quant value in 0-255 range into packed quant value in 0-N range, 1367cc1dc7a3Sopenharmony_ci * with BISE scrambling applied. 1368cc1dc7a3Sopenharmony_ci * 1369cc1dc7a3Sopenharmony_ci * Indexed by [quant_mode - 4][data_value]. 1370cc1dc7a3Sopenharmony_ci */ 1371cc1dc7a3Sopenharmony_ciextern const uint8_t color_uquant_to_scrambled_pquant_tables[17][256]; 1372cc1dc7a3Sopenharmony_ci 1373cc1dc7a3Sopenharmony_ci/** 1374cc1dc7a3Sopenharmony_ci * @brief The precomputed table for unpacking color values. 1375cc1dc7a3Sopenharmony_ci * 1376cc1dc7a3Sopenharmony_ci * Converts quant value in 0-N range into unpacked value in 0-255 range, 1377cc1dc7a3Sopenharmony_ci * with BISE unscrambling applied. 1378cc1dc7a3Sopenharmony_ci * 1379cc1dc7a3Sopenharmony_ci * Indexed by [quant_mode - 4][data_value]. 1380cc1dc7a3Sopenharmony_ci */ 1381cc1dc7a3Sopenharmony_ciextern const uint8_t* color_scrambled_pquant_to_uquant_tables[17]; 1382cc1dc7a3Sopenharmony_ci 1383cc1dc7a3Sopenharmony_ci/** 1384cc1dc7a3Sopenharmony_ci * @brief The precomputed quant mode storage table. 1385cc1dc7a3Sopenharmony_ci * 1386cc1dc7a3Sopenharmony_ci * Indexing by [integer_count/2][bits] gives us the quantization level for a given integer count and 1387cc1dc7a3Sopenharmony_ci * number of compressed storage bits. Returns -1 for cases where the requested integer count cannot 1388cc1dc7a3Sopenharmony_ci * ever fit in the supplied storage size. 1389cc1dc7a3Sopenharmony_ci */ 1390cc1dc7a3Sopenharmony_ciextern const int8_t quant_mode_table[10][128]; 1391cc1dc7a3Sopenharmony_ci 1392cc1dc7a3Sopenharmony_ci/** 1393cc1dc7a3Sopenharmony_ci * @brief Encode a packed string using BISE. 1394cc1dc7a3Sopenharmony_ci * 1395cc1dc7a3Sopenharmony_ci * Note that BISE can return strings that are not a whole number of bytes in length, and ASTC can 1396cc1dc7a3Sopenharmony_ci * start storing strings in a block at arbitrary bit offsets in the encoded data. 1397cc1dc7a3Sopenharmony_ci * 1398cc1dc7a3Sopenharmony_ci * @param quant_level The BISE alphabet size. 1399cc1dc7a3Sopenharmony_ci * @param character_count The number of characters in the string. 1400cc1dc7a3Sopenharmony_ci * @param input_data The unpacked string, one byte per character. 1401cc1dc7a3Sopenharmony_ci * @param[in,out] output_data The output packed string. 1402cc1dc7a3Sopenharmony_ci * @param bit_offset The starting offset in the output storage. 1403cc1dc7a3Sopenharmony_ci */ 1404cc1dc7a3Sopenharmony_civoid encode_ise( 1405cc1dc7a3Sopenharmony_ci quant_method quant_level, 1406cc1dc7a3Sopenharmony_ci unsigned int character_count, 1407cc1dc7a3Sopenharmony_ci const uint8_t* input_data, 1408cc1dc7a3Sopenharmony_ci uint8_t* output_data, 1409cc1dc7a3Sopenharmony_ci unsigned int bit_offset); 1410cc1dc7a3Sopenharmony_ci 1411cc1dc7a3Sopenharmony_ci/** 1412cc1dc7a3Sopenharmony_ci * @brief Decode a packed string using BISE. 1413cc1dc7a3Sopenharmony_ci * 1414cc1dc7a3Sopenharmony_ci * Note that BISE input strings are not a whole number of bytes in length, and ASTC can start 1415cc1dc7a3Sopenharmony_ci * strings at arbitrary bit offsets in the encoded data. 1416cc1dc7a3Sopenharmony_ci * 1417cc1dc7a3Sopenharmony_ci * @param quant_level The BISE alphabet size. 1418cc1dc7a3Sopenharmony_ci * @param character_count The number of characters in the string. 1419cc1dc7a3Sopenharmony_ci * @param input_data The packed string. 1420cc1dc7a3Sopenharmony_ci * @param[in,out] output_data The output storage, one byte per character. 1421cc1dc7a3Sopenharmony_ci * @param bit_offset The starting offset in the output storage. 1422cc1dc7a3Sopenharmony_ci */ 1423cc1dc7a3Sopenharmony_civoid decode_ise( 1424cc1dc7a3Sopenharmony_ci quant_method quant_level, 1425cc1dc7a3Sopenharmony_ci unsigned int character_count, 1426cc1dc7a3Sopenharmony_ci const uint8_t* input_data, 1427cc1dc7a3Sopenharmony_ci uint8_t* output_data, 1428cc1dc7a3Sopenharmony_ci unsigned int bit_offset); 1429cc1dc7a3Sopenharmony_ci 1430cc1dc7a3Sopenharmony_ci/** 1431cc1dc7a3Sopenharmony_ci * @brief Return the number of bits needed to encode an ISE sequence. 1432cc1dc7a3Sopenharmony_ci * 1433cc1dc7a3Sopenharmony_ci * This implementation assumes that the @c quant level is untrusted, given it may come from random 1434cc1dc7a3Sopenharmony_ci * data being decompressed, so we return an arbitrary unencodable size if that is the case. 1435cc1dc7a3Sopenharmony_ci * 1436cc1dc7a3Sopenharmony_ci * @param character_count The number of items in the sequence. 1437cc1dc7a3Sopenharmony_ci * @param quant_level The desired quantization level. 1438cc1dc7a3Sopenharmony_ci * 1439cc1dc7a3Sopenharmony_ci * @return The number of bits needed to encode the BISE string. 1440cc1dc7a3Sopenharmony_ci */ 1441cc1dc7a3Sopenharmony_ciunsigned int get_ise_sequence_bitcount( 1442cc1dc7a3Sopenharmony_ci unsigned int character_count, 1443cc1dc7a3Sopenharmony_ci quant_method quant_level); 1444cc1dc7a3Sopenharmony_ci 1445cc1dc7a3Sopenharmony_ci/* ============================================================================ 1446cc1dc7a3Sopenharmony_ci Functionality for managing color partitioning. 1447cc1dc7a3Sopenharmony_ci============================================================================ */ 1448cc1dc7a3Sopenharmony_ci 1449cc1dc7a3Sopenharmony_ci/** 1450cc1dc7a3Sopenharmony_ci * @brief Compute averages and dominant directions for each partition in a 2 component texture. 1451cc1dc7a3Sopenharmony_ci * 1452cc1dc7a3Sopenharmony_ci * @param pi The partition info for the current trial. 1453cc1dc7a3Sopenharmony_ci * @param blk The image block color data to be compressed. 1454cc1dc7a3Sopenharmony_ci * @param component1 The first component included in the analysis. 1455cc1dc7a3Sopenharmony_ci * @param component2 The second component included in the analysis. 1456cc1dc7a3Sopenharmony_ci * @param[out] pm The output partition metrics. 1457cc1dc7a3Sopenharmony_ci * - Only pi.partition_count array entries actually get initialized. 1458cc1dc7a3Sopenharmony_ci * - Direction vectors @c pm.dir are not normalized. 1459cc1dc7a3Sopenharmony_ci */ 1460cc1dc7a3Sopenharmony_civoid compute_avgs_and_dirs_2_comp( 1461cc1dc7a3Sopenharmony_ci const partition_info& pi, 1462cc1dc7a3Sopenharmony_ci const image_block& blk, 1463cc1dc7a3Sopenharmony_ci unsigned int component1, 1464cc1dc7a3Sopenharmony_ci unsigned int component2, 1465cc1dc7a3Sopenharmony_ci partition_metrics pm[BLOCK_MAX_PARTITIONS]); 1466cc1dc7a3Sopenharmony_ci 1467cc1dc7a3Sopenharmony_ci/** 1468cc1dc7a3Sopenharmony_ci * @brief Compute averages and dominant directions for each partition in a 3 component texture. 1469cc1dc7a3Sopenharmony_ci * 1470cc1dc7a3Sopenharmony_ci * @param pi The partition info for the current trial. 1471cc1dc7a3Sopenharmony_ci * @param blk The image block color data to be compressed. 1472cc1dc7a3Sopenharmony_ci * @param omitted_component The component excluded from the analysis. 1473cc1dc7a3Sopenharmony_ci * @param[out] pm The output partition metrics. 1474cc1dc7a3Sopenharmony_ci * - Only pi.partition_count array entries actually get initialized. 1475cc1dc7a3Sopenharmony_ci * - Direction vectors @c pm.dir are not normalized. 1476cc1dc7a3Sopenharmony_ci */ 1477cc1dc7a3Sopenharmony_civoid compute_avgs_and_dirs_3_comp( 1478cc1dc7a3Sopenharmony_ci const partition_info& pi, 1479cc1dc7a3Sopenharmony_ci const image_block& blk, 1480cc1dc7a3Sopenharmony_ci unsigned int omitted_component, 1481cc1dc7a3Sopenharmony_ci partition_metrics pm[BLOCK_MAX_PARTITIONS]); 1482cc1dc7a3Sopenharmony_ci 1483cc1dc7a3Sopenharmony_ci/** 1484cc1dc7a3Sopenharmony_ci * @brief Compute averages and dominant directions for each partition in a 3 component texture. 1485cc1dc7a3Sopenharmony_ci * 1486cc1dc7a3Sopenharmony_ci * This is a specialization of @c compute_avgs_and_dirs_3_comp where the omitted component is 1487cc1dc7a3Sopenharmony_ci * always alpha, a common case during partition search. 1488cc1dc7a3Sopenharmony_ci * 1489cc1dc7a3Sopenharmony_ci * @param pi The partition info for the current trial. 1490cc1dc7a3Sopenharmony_ci * @param blk The image block color data to be compressed. 1491cc1dc7a3Sopenharmony_ci * @param[out] pm The output partition metrics. 1492cc1dc7a3Sopenharmony_ci * - Only pi.partition_count array entries actually get initialized. 1493cc1dc7a3Sopenharmony_ci * - Direction vectors @c pm.dir are not normalized. 1494cc1dc7a3Sopenharmony_ci */ 1495cc1dc7a3Sopenharmony_civoid compute_avgs_and_dirs_3_comp_rgb( 1496cc1dc7a3Sopenharmony_ci const partition_info& pi, 1497cc1dc7a3Sopenharmony_ci const image_block& blk, 1498cc1dc7a3Sopenharmony_ci partition_metrics pm[BLOCK_MAX_PARTITIONS]); 1499cc1dc7a3Sopenharmony_ci 1500cc1dc7a3Sopenharmony_ci/** 1501cc1dc7a3Sopenharmony_ci * @brief Compute averages and dominant directions for each partition in a 4 component texture. 1502cc1dc7a3Sopenharmony_ci * 1503cc1dc7a3Sopenharmony_ci * @param pi The partition info for the current trial. 1504cc1dc7a3Sopenharmony_ci * @param blk The image block color data to be compressed. 1505cc1dc7a3Sopenharmony_ci * @param[out] pm The output partition metrics. 1506cc1dc7a3Sopenharmony_ci * - Only pi.partition_count array entries actually get initialized. 1507cc1dc7a3Sopenharmony_ci * - Direction vectors @c pm.dir are not normalized. 1508cc1dc7a3Sopenharmony_ci */ 1509cc1dc7a3Sopenharmony_civoid compute_avgs_and_dirs_4_comp( 1510cc1dc7a3Sopenharmony_ci const partition_info& pi, 1511cc1dc7a3Sopenharmony_ci const image_block& blk, 1512cc1dc7a3Sopenharmony_ci partition_metrics pm[BLOCK_MAX_PARTITIONS]); 1513cc1dc7a3Sopenharmony_ci 1514cc1dc7a3Sopenharmony_ci/** 1515cc1dc7a3Sopenharmony_ci * @brief Compute the RGB error for uncorrelated and same chroma projections. 1516cc1dc7a3Sopenharmony_ci * 1517cc1dc7a3Sopenharmony_ci * The output of compute averages and dirs is post processed to define two lines, both of which go 1518cc1dc7a3Sopenharmony_ci * through the mean-color-value. One line has a direction defined by the dominant direction; this 1519cc1dc7a3Sopenharmony_ci * is used to assess the error from using an uncorrelated color representation. The other line goes 1520cc1dc7a3Sopenharmony_ci * through (0,0,0) and is used to assess the error from using an RGBS color representation. 1521cc1dc7a3Sopenharmony_ci * 1522cc1dc7a3Sopenharmony_ci * This function computes the squared error when using these two representations. 1523cc1dc7a3Sopenharmony_ci * 1524cc1dc7a3Sopenharmony_ci * @param pi The partition info for the current trial. 1525cc1dc7a3Sopenharmony_ci * @param blk The image block color data to be compressed. 1526cc1dc7a3Sopenharmony_ci * @param[in,out] plines Processed line inputs, and line length outputs. 1527cc1dc7a3Sopenharmony_ci * @param[out] uncor_error The cumulative error for using the uncorrelated line. 1528cc1dc7a3Sopenharmony_ci * @param[out] samec_error The cumulative error for using the same chroma line. 1529cc1dc7a3Sopenharmony_ci */ 1530cc1dc7a3Sopenharmony_civoid compute_error_squared_rgb( 1531cc1dc7a3Sopenharmony_ci const partition_info& pi, 1532cc1dc7a3Sopenharmony_ci const image_block& blk, 1533cc1dc7a3Sopenharmony_ci partition_lines3 plines[BLOCK_MAX_PARTITIONS], 1534cc1dc7a3Sopenharmony_ci float& uncor_error, 1535cc1dc7a3Sopenharmony_ci float& samec_error); 1536cc1dc7a3Sopenharmony_ci 1537cc1dc7a3Sopenharmony_ci/** 1538cc1dc7a3Sopenharmony_ci * @brief Compute the RGBA error for uncorrelated and same chroma projections. 1539cc1dc7a3Sopenharmony_ci * 1540cc1dc7a3Sopenharmony_ci * The output of compute averages and dirs is post processed to define two lines, both of which go 1541cc1dc7a3Sopenharmony_ci * through the mean-color-value. One line has a direction defined by the dominant direction; this 1542cc1dc7a3Sopenharmony_ci * is used to assess the error from using an uncorrelated color representation. The other line goes 1543cc1dc7a3Sopenharmony_ci * through (0,0,0,1) and is used to assess the error from using an RGBS color representation. 1544cc1dc7a3Sopenharmony_ci * 1545cc1dc7a3Sopenharmony_ci * This function computes the squared error when using these two representations. 1546cc1dc7a3Sopenharmony_ci * 1547cc1dc7a3Sopenharmony_ci * @param pi The partition info for the current trial. 1548cc1dc7a3Sopenharmony_ci * @param blk The image block color data to be compressed. 1549cc1dc7a3Sopenharmony_ci * @param uncor_plines Processed uncorrelated partition lines for each partition. 1550cc1dc7a3Sopenharmony_ci * @param samec_plines Processed same chroma partition lines for each partition. 1551cc1dc7a3Sopenharmony_ci * @param[out] line_lengths The length of each components deviation from the line. 1552cc1dc7a3Sopenharmony_ci * @param[out] uncor_error The cumulative error for using the uncorrelated line. 1553cc1dc7a3Sopenharmony_ci * @param[out] samec_error The cumulative error for using the same chroma line. 1554cc1dc7a3Sopenharmony_ci */ 1555cc1dc7a3Sopenharmony_civoid compute_error_squared_rgba( 1556cc1dc7a3Sopenharmony_ci const partition_info& pi, 1557cc1dc7a3Sopenharmony_ci const image_block& blk, 1558cc1dc7a3Sopenharmony_ci const processed_line4 uncor_plines[BLOCK_MAX_PARTITIONS], 1559cc1dc7a3Sopenharmony_ci const processed_line4 samec_plines[BLOCK_MAX_PARTITIONS], 1560cc1dc7a3Sopenharmony_ci float line_lengths[BLOCK_MAX_PARTITIONS], 1561cc1dc7a3Sopenharmony_ci float& uncor_error, 1562cc1dc7a3Sopenharmony_ci float& samec_error); 1563cc1dc7a3Sopenharmony_ci 1564cc1dc7a3Sopenharmony_ci/** 1565cc1dc7a3Sopenharmony_ci * @brief Find the best set of partitions to trial for a given block. 1566cc1dc7a3Sopenharmony_ci * 1567cc1dc7a3Sopenharmony_ci * On return the @c best_partitions list will contain the two best partition 1568cc1dc7a3Sopenharmony_ci * candidates; one assuming data has uncorrelated chroma and one assuming the 1569cc1dc7a3Sopenharmony_ci * data has correlated chroma. The best candidate is returned first in the list. 1570cc1dc7a3Sopenharmony_ci * 1571cc1dc7a3Sopenharmony_ci * @param bsd The block size information. 1572cc1dc7a3Sopenharmony_ci * @param blk The image block color data to compress. 1573cc1dc7a3Sopenharmony_ci * @param partition_count The number of partitions in the block. 1574cc1dc7a3Sopenharmony_ci * @param partition_search_limit The number of candidate partition encodings to trial. 1575cc1dc7a3Sopenharmony_ci * @param[out] best_partitions The best partition candidates. 1576cc1dc7a3Sopenharmony_ci * @param requested_candidates The number of requested partitionings. May return fewer if 1577cc1dc7a3Sopenharmony_ci * candidates are not available. 1578cc1dc7a3Sopenharmony_ci * 1579cc1dc7a3Sopenharmony_ci * @return The actual number of candidates returned. 1580cc1dc7a3Sopenharmony_ci */ 1581cc1dc7a3Sopenharmony_ciunsigned int find_best_partition_candidates( 1582cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 1583cc1dc7a3Sopenharmony_ci const image_block& blk, 1584cc1dc7a3Sopenharmony_ci unsigned int partition_count, 1585cc1dc7a3Sopenharmony_ci unsigned int partition_search_limit, 1586cc1dc7a3Sopenharmony_ci unsigned int best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES], 1587cc1dc7a3Sopenharmony_ci unsigned int requested_candidates); 1588cc1dc7a3Sopenharmony_ci 1589cc1dc7a3Sopenharmony_ci/* ============================================================================ 1590cc1dc7a3Sopenharmony_ci Functionality for managing images and image related data. 1591cc1dc7a3Sopenharmony_ci============================================================================ */ 1592cc1dc7a3Sopenharmony_ci 1593cc1dc7a3Sopenharmony_ci/** 1594cc1dc7a3Sopenharmony_ci * @brief Get a vector mask indicating lanes decompressing into a UNORM8 value. 1595cc1dc7a3Sopenharmony_ci * 1596cc1dc7a3Sopenharmony_ci * @param decode_mode The color profile for LDR_SRGB settings. 1597cc1dc7a3Sopenharmony_ci * @param blk The image block for output image bitness settings. 1598cc1dc7a3Sopenharmony_ci * 1599cc1dc7a3Sopenharmony_ci * @return The component mask vector. 1600cc1dc7a3Sopenharmony_ci */ 1601cc1dc7a3Sopenharmony_cistatic inline vmask4 get_u8_component_mask( 1602cc1dc7a3Sopenharmony_ci astcenc_profile decode_mode, 1603cc1dc7a3Sopenharmony_ci const image_block& blk 1604cc1dc7a3Sopenharmony_ci) { 1605cc1dc7a3Sopenharmony_ci vmask4 u8_mask(false); 1606cc1dc7a3Sopenharmony_ci // Decode mode writing to a unorm8 output value 1607cc1dc7a3Sopenharmony_ci if (blk.decode_unorm8) 1608cc1dc7a3Sopenharmony_ci { 1609cc1dc7a3Sopenharmony_ci u8_mask = vmask4(true); 1610cc1dc7a3Sopenharmony_ci } 1611cc1dc7a3Sopenharmony_ci // SRGB writing to a unorm8 RGB value 1612cc1dc7a3Sopenharmony_ci else if (decode_mode == ASTCENC_PRF_LDR_SRGB) 1613cc1dc7a3Sopenharmony_ci { 1614cc1dc7a3Sopenharmony_ci u8_mask = vmask4(true, true, true, false); 1615cc1dc7a3Sopenharmony_ci } 1616cc1dc7a3Sopenharmony_ci 1617cc1dc7a3Sopenharmony_ci return u8_mask; 1618cc1dc7a3Sopenharmony_ci} 1619cc1dc7a3Sopenharmony_ci 1620cc1dc7a3Sopenharmony_ci/** 1621cc1dc7a3Sopenharmony_ci * @brief Setup computation of regional averages in an image. 1622cc1dc7a3Sopenharmony_ci * 1623cc1dc7a3Sopenharmony_ci * This must be done by only a single thread per image, before any thread calls 1624cc1dc7a3Sopenharmony_ci * @c compute_averages(). 1625cc1dc7a3Sopenharmony_ci * 1626cc1dc7a3Sopenharmony_ci * Results are written back into @c img->input_alpha_averages. 1627cc1dc7a3Sopenharmony_ci * 1628cc1dc7a3Sopenharmony_ci * @param img The input image data, also holds output data. 1629cc1dc7a3Sopenharmony_ci * @param alpha_kernel_radius The kernel radius (in pixels) for alpha mods. 1630cc1dc7a3Sopenharmony_ci * @param swz Input data component swizzle. 1631cc1dc7a3Sopenharmony_ci * @param[out] ag The average variance arguments to init. 1632cc1dc7a3Sopenharmony_ci * 1633cc1dc7a3Sopenharmony_ci * @return The number of tasks in the processing stage. 1634cc1dc7a3Sopenharmony_ci */ 1635cc1dc7a3Sopenharmony_ciunsigned int init_compute_averages( 1636cc1dc7a3Sopenharmony_ci const astcenc_image& img, 1637cc1dc7a3Sopenharmony_ci unsigned int alpha_kernel_radius, 1638cc1dc7a3Sopenharmony_ci const astcenc_swizzle& swz, 1639cc1dc7a3Sopenharmony_ci avg_args& ag); 1640cc1dc7a3Sopenharmony_ci 1641cc1dc7a3Sopenharmony_ci/** 1642cc1dc7a3Sopenharmony_ci * @brief Compute averages for a pixel region. 1643cc1dc7a3Sopenharmony_ci * 1644cc1dc7a3Sopenharmony_ci * The routine computes both in a single pass, using a summed-area table to decouple the running 1645cc1dc7a3Sopenharmony_ci * time from the averaging/variance kernel size. 1646cc1dc7a3Sopenharmony_ci * 1647cc1dc7a3Sopenharmony_ci * @param[out] ctx The compressor context storing the output data. 1648cc1dc7a3Sopenharmony_ci * @param arg The input parameter structure. 1649cc1dc7a3Sopenharmony_ci */ 1650cc1dc7a3Sopenharmony_civoid compute_pixel_region_variance( 1651cc1dc7a3Sopenharmony_ci astcenc_contexti& ctx, 1652cc1dc7a3Sopenharmony_ci const pixel_region_args& arg); 1653cc1dc7a3Sopenharmony_ci/** 1654cc1dc7a3Sopenharmony_ci * @brief Load a single image block from the input image. 1655cc1dc7a3Sopenharmony_ci * 1656cc1dc7a3Sopenharmony_ci * @param decode_mode The compression color profile. 1657cc1dc7a3Sopenharmony_ci * @param img The input image data. 1658cc1dc7a3Sopenharmony_ci * @param[out] blk The image block to populate. 1659cc1dc7a3Sopenharmony_ci * @param bsd The block size information. 1660cc1dc7a3Sopenharmony_ci * @param xpos The block X coordinate in the input image. 1661cc1dc7a3Sopenharmony_ci * @param ypos The block Y coordinate in the input image. 1662cc1dc7a3Sopenharmony_ci * @param zpos The block Z coordinate in the input image. 1663cc1dc7a3Sopenharmony_ci * @param swz The swizzle to apply on load. 1664cc1dc7a3Sopenharmony_ci */ 1665cc1dc7a3Sopenharmony_civoid load_image_block( 1666cc1dc7a3Sopenharmony_ci astcenc_profile decode_mode, 1667cc1dc7a3Sopenharmony_ci const astcenc_image& img, 1668cc1dc7a3Sopenharmony_ci image_block& blk, 1669cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 1670cc1dc7a3Sopenharmony_ci unsigned int xpos, 1671cc1dc7a3Sopenharmony_ci unsigned int ypos, 1672cc1dc7a3Sopenharmony_ci unsigned int zpos, 1673cc1dc7a3Sopenharmony_ci const astcenc_swizzle& swz); 1674cc1dc7a3Sopenharmony_ci 1675cc1dc7a3Sopenharmony_ci/** 1676cc1dc7a3Sopenharmony_ci * @brief Load a single image block from the input image. 1677cc1dc7a3Sopenharmony_ci * 1678cc1dc7a3Sopenharmony_ci * This specialized variant can be used only if the block is 2D LDR U8 data, 1679cc1dc7a3Sopenharmony_ci * with no swizzle. 1680cc1dc7a3Sopenharmony_ci * 1681cc1dc7a3Sopenharmony_ci * @param decode_mode The compression color profile. 1682cc1dc7a3Sopenharmony_ci * @param img The input image data. 1683cc1dc7a3Sopenharmony_ci * @param[out] blk The image block to populate. 1684cc1dc7a3Sopenharmony_ci * @param bsd The block size information. 1685cc1dc7a3Sopenharmony_ci * @param xpos The block X coordinate in the input image. 1686cc1dc7a3Sopenharmony_ci * @param ypos The block Y coordinate in the input image. 1687cc1dc7a3Sopenharmony_ci * @param zpos The block Z coordinate in the input image. 1688cc1dc7a3Sopenharmony_ci * @param swz The swizzle to apply on load. 1689cc1dc7a3Sopenharmony_ci */ 1690cc1dc7a3Sopenharmony_civoid load_image_block_fast_ldr( 1691cc1dc7a3Sopenharmony_ci astcenc_profile decode_mode, 1692cc1dc7a3Sopenharmony_ci const astcenc_image& img, 1693cc1dc7a3Sopenharmony_ci image_block& blk, 1694cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 1695cc1dc7a3Sopenharmony_ci unsigned int xpos, 1696cc1dc7a3Sopenharmony_ci unsigned int ypos, 1697cc1dc7a3Sopenharmony_ci unsigned int zpos, 1698cc1dc7a3Sopenharmony_ci const astcenc_swizzle& swz); 1699cc1dc7a3Sopenharmony_ci 1700cc1dc7a3Sopenharmony_ci/** 1701cc1dc7a3Sopenharmony_ci * @brief Store a single image block to the output image. 1702cc1dc7a3Sopenharmony_ci * 1703cc1dc7a3Sopenharmony_ci * @param[out] img The output image data. 1704cc1dc7a3Sopenharmony_ci * @param blk The image block to export. 1705cc1dc7a3Sopenharmony_ci * @param bsd The block size information. 1706cc1dc7a3Sopenharmony_ci * @param xpos The block X coordinate in the input image. 1707cc1dc7a3Sopenharmony_ci * @param ypos The block Y coordinate in the input image. 1708cc1dc7a3Sopenharmony_ci * @param zpos The block Z coordinate in the input image. 1709cc1dc7a3Sopenharmony_ci * @param swz The swizzle to apply on store. 1710cc1dc7a3Sopenharmony_ci */ 1711cc1dc7a3Sopenharmony_civoid store_image_block( 1712cc1dc7a3Sopenharmony_ci astcenc_image& img, 1713cc1dc7a3Sopenharmony_ci const image_block& blk, 1714cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 1715cc1dc7a3Sopenharmony_ci unsigned int xpos, 1716cc1dc7a3Sopenharmony_ci unsigned int ypos, 1717cc1dc7a3Sopenharmony_ci unsigned int zpos, 1718cc1dc7a3Sopenharmony_ci const astcenc_swizzle& swz); 1719cc1dc7a3Sopenharmony_ci 1720cc1dc7a3Sopenharmony_ci/* ============================================================================ 1721cc1dc7a3Sopenharmony_ci Functionality for computing endpoint colors and weights for a block. 1722cc1dc7a3Sopenharmony_ci============================================================================ */ 1723cc1dc7a3Sopenharmony_ci 1724cc1dc7a3Sopenharmony_ci/** 1725cc1dc7a3Sopenharmony_ci * @brief Compute ideal endpoint colors and weights for 1 plane of weights. 1726cc1dc7a3Sopenharmony_ci * 1727cc1dc7a3Sopenharmony_ci * The ideal endpoints define a color line for the partition. For each texel the ideal weight 1728cc1dc7a3Sopenharmony_ci * defines an exact position on the partition color line. We can then use these to assess the error 1729cc1dc7a3Sopenharmony_ci * introduced by removing and quantizing the weight grid. 1730cc1dc7a3Sopenharmony_ci * 1731cc1dc7a3Sopenharmony_ci * @param blk The image block color data to compress. 1732cc1dc7a3Sopenharmony_ci * @param pi The partition info for the current trial. 1733cc1dc7a3Sopenharmony_ci * @param[out] ei The endpoint and weight values. 1734cc1dc7a3Sopenharmony_ci */ 1735cc1dc7a3Sopenharmony_civoid compute_ideal_colors_and_weights_1plane( 1736cc1dc7a3Sopenharmony_ci const image_block& blk, 1737cc1dc7a3Sopenharmony_ci const partition_info& pi, 1738cc1dc7a3Sopenharmony_ci endpoints_and_weights& ei); 1739cc1dc7a3Sopenharmony_ci 1740cc1dc7a3Sopenharmony_ci/** 1741cc1dc7a3Sopenharmony_ci * @brief Compute ideal endpoint colors and weights for 2 planes of weights. 1742cc1dc7a3Sopenharmony_ci * 1743cc1dc7a3Sopenharmony_ci * The ideal endpoints define a color line for the partition. For each texel the ideal weight 1744cc1dc7a3Sopenharmony_ci * defines an exact position on the partition color line. We can then use these to assess the error 1745cc1dc7a3Sopenharmony_ci * introduced by removing and quantizing the weight grid. 1746cc1dc7a3Sopenharmony_ci * 1747cc1dc7a3Sopenharmony_ci * @param bsd The block size information. 1748cc1dc7a3Sopenharmony_ci * @param blk The image block color data to compress. 1749cc1dc7a3Sopenharmony_ci * @param plane2_component The component assigned to plane 2. 1750cc1dc7a3Sopenharmony_ci * @param[out] ei1 The endpoint and weight values for plane 1. 1751cc1dc7a3Sopenharmony_ci * @param[out] ei2 The endpoint and weight values for plane 2. 1752cc1dc7a3Sopenharmony_ci */ 1753cc1dc7a3Sopenharmony_civoid compute_ideal_colors_and_weights_2planes( 1754cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 1755cc1dc7a3Sopenharmony_ci const image_block& blk, 1756cc1dc7a3Sopenharmony_ci unsigned int plane2_component, 1757cc1dc7a3Sopenharmony_ci endpoints_and_weights& ei1, 1758cc1dc7a3Sopenharmony_ci endpoints_and_weights& ei2); 1759cc1dc7a3Sopenharmony_ci 1760cc1dc7a3Sopenharmony_ci/** 1761cc1dc7a3Sopenharmony_ci * @brief Compute the optimal unquantized weights for a decimation table. 1762cc1dc7a3Sopenharmony_ci * 1763cc1dc7a3Sopenharmony_ci * After computing ideal weights for the case for a complete weight grid, we we want to compute the 1764cc1dc7a3Sopenharmony_ci * ideal weights for the case where weights exist only for some texels. We do this with a 1765cc1dc7a3Sopenharmony_ci * steepest-descent grid solver which works as follows: 1766cc1dc7a3Sopenharmony_ci * 1767cc1dc7a3Sopenharmony_ci * First, for each actual weight, perform a weighted averaging of the texels affected by the weight. 1768cc1dc7a3Sopenharmony_ci * Then, set step size to <some initial value> and attempt one step towards the original ideal 1769cc1dc7a3Sopenharmony_ci * weight if it helps to reduce error. 1770cc1dc7a3Sopenharmony_ci * 1771cc1dc7a3Sopenharmony_ci * @param ei The non-decimated endpoints and weights. 1772cc1dc7a3Sopenharmony_ci * @param di The selected weight decimation. 1773cc1dc7a3Sopenharmony_ci * @param[out] dec_weight_ideal_value The ideal values for the decimated weight set. 1774cc1dc7a3Sopenharmony_ci */ 1775cc1dc7a3Sopenharmony_civoid compute_ideal_weights_for_decimation( 1776cc1dc7a3Sopenharmony_ci const endpoints_and_weights& ei, 1777cc1dc7a3Sopenharmony_ci const decimation_info& di, 1778cc1dc7a3Sopenharmony_ci float* dec_weight_ideal_value); 1779cc1dc7a3Sopenharmony_ci 1780cc1dc7a3Sopenharmony_ci/** 1781cc1dc7a3Sopenharmony_ci * @brief Compute the optimal quantized weights for a decimation table. 1782cc1dc7a3Sopenharmony_ci * 1783cc1dc7a3Sopenharmony_ci * We test the two closest weight indices in the allowed quantization range and keep the weight that 1784cc1dc7a3Sopenharmony_ci * is the closest match. 1785cc1dc7a3Sopenharmony_ci * 1786cc1dc7a3Sopenharmony_ci * @param di The selected weight decimation. 1787cc1dc7a3Sopenharmony_ci * @param low_bound The lowest weight allowed. 1788cc1dc7a3Sopenharmony_ci * @param high_bound The highest weight allowed. 1789cc1dc7a3Sopenharmony_ci * @param dec_weight_ideal_value The ideal weight set. 1790cc1dc7a3Sopenharmony_ci * @param[out] dec_weight_quant_uvalue The output quantized weight as a float. 1791cc1dc7a3Sopenharmony_ci * @param[out] dec_weight_uquant The output quantized weight as encoded int. 1792cc1dc7a3Sopenharmony_ci * @param quant_level The desired weight quant level. 1793cc1dc7a3Sopenharmony_ci */ 1794cc1dc7a3Sopenharmony_civoid compute_quantized_weights_for_decimation( 1795cc1dc7a3Sopenharmony_ci const decimation_info& di, 1796cc1dc7a3Sopenharmony_ci float low_bound, 1797cc1dc7a3Sopenharmony_ci float high_bound, 1798cc1dc7a3Sopenharmony_ci const float* dec_weight_ideal_value, 1799cc1dc7a3Sopenharmony_ci float* dec_weight_quant_uvalue, 1800cc1dc7a3Sopenharmony_ci uint8_t* dec_weight_uquant, 1801cc1dc7a3Sopenharmony_ci quant_method quant_level); 1802cc1dc7a3Sopenharmony_ci 1803cc1dc7a3Sopenharmony_ci/** 1804cc1dc7a3Sopenharmony_ci * @brief Compute the error of a decimated weight set for 1 plane. 1805cc1dc7a3Sopenharmony_ci * 1806cc1dc7a3Sopenharmony_ci * After computing ideal weights for the case with one weight per texel, we want to compute the 1807cc1dc7a3Sopenharmony_ci * error for decimated weight grids where weights are stored at a lower resolution. This function 1808cc1dc7a3Sopenharmony_ci * computes the error of the reduced grid, compared to the full grid. 1809cc1dc7a3Sopenharmony_ci * 1810cc1dc7a3Sopenharmony_ci * @param eai The ideal weights for the full grid. 1811cc1dc7a3Sopenharmony_ci * @param di The selected weight decimation. 1812cc1dc7a3Sopenharmony_ci * @param dec_weight_quant_uvalue The quantized weights for the decimated grid. 1813cc1dc7a3Sopenharmony_ci * 1814cc1dc7a3Sopenharmony_ci * @return The accumulated error. 1815cc1dc7a3Sopenharmony_ci */ 1816cc1dc7a3Sopenharmony_cifloat compute_error_of_weight_set_1plane( 1817cc1dc7a3Sopenharmony_ci const endpoints_and_weights& eai, 1818cc1dc7a3Sopenharmony_ci const decimation_info& di, 1819cc1dc7a3Sopenharmony_ci const float* dec_weight_quant_uvalue); 1820cc1dc7a3Sopenharmony_ci 1821cc1dc7a3Sopenharmony_ci/** 1822cc1dc7a3Sopenharmony_ci * @brief Compute the error of a decimated weight set for 2 planes. 1823cc1dc7a3Sopenharmony_ci * 1824cc1dc7a3Sopenharmony_ci * After computing ideal weights for the case with one weight per texel, we want to compute the 1825cc1dc7a3Sopenharmony_ci * error for decimated weight grids where weights are stored at a lower resolution. This function 1826cc1dc7a3Sopenharmony_ci * computes the error of the reduced grid, compared to the full grid. 1827cc1dc7a3Sopenharmony_ci * 1828cc1dc7a3Sopenharmony_ci * @param eai1 The ideal weights for the full grid and plane 1. 1829cc1dc7a3Sopenharmony_ci * @param eai2 The ideal weights for the full grid and plane 2. 1830cc1dc7a3Sopenharmony_ci * @param di The selected weight decimation. 1831cc1dc7a3Sopenharmony_ci * @param dec_weight_quant_uvalue_plane1 The quantized weights for the decimated grid plane 1. 1832cc1dc7a3Sopenharmony_ci * @param dec_weight_quant_uvalue_plane2 The quantized weights for the decimated grid plane 2. 1833cc1dc7a3Sopenharmony_ci * 1834cc1dc7a3Sopenharmony_ci * @return The accumulated error. 1835cc1dc7a3Sopenharmony_ci */ 1836cc1dc7a3Sopenharmony_cifloat compute_error_of_weight_set_2planes( 1837cc1dc7a3Sopenharmony_ci const endpoints_and_weights& eai1, 1838cc1dc7a3Sopenharmony_ci const endpoints_and_weights& eai2, 1839cc1dc7a3Sopenharmony_ci const decimation_info& di, 1840cc1dc7a3Sopenharmony_ci const float* dec_weight_quant_uvalue_plane1, 1841cc1dc7a3Sopenharmony_ci const float* dec_weight_quant_uvalue_plane2); 1842cc1dc7a3Sopenharmony_ci 1843cc1dc7a3Sopenharmony_ci/** 1844cc1dc7a3Sopenharmony_ci * @brief Pack a single pair of color endpoints as effectively as possible. 1845cc1dc7a3Sopenharmony_ci * 1846cc1dc7a3Sopenharmony_ci * The user requests a base color endpoint mode in @c format, but the quantizer may choose a 1847cc1dc7a3Sopenharmony_ci * delta-based representation. It will report back the format variant it actually used. 1848cc1dc7a3Sopenharmony_ci * 1849cc1dc7a3Sopenharmony_ci * @param color0 The input unquantized color0 endpoint for absolute endpoint pairs. 1850cc1dc7a3Sopenharmony_ci * @param color1 The input unquantized color1 endpoint for absolute endpoint pairs. 1851cc1dc7a3Sopenharmony_ci * @param rgbs_color The input unquantized RGBS variant endpoint for same chroma endpoints. 1852cc1dc7a3Sopenharmony_ci * @param rgbo_color The input unquantized RGBS variant endpoint for HDR endpoints. 1853cc1dc7a3Sopenharmony_ci * @param format The desired base format. 1854cc1dc7a3Sopenharmony_ci * @param[out] output The output storage for the quantized colors/ 1855cc1dc7a3Sopenharmony_ci * @param quant_level The quantization level requested. 1856cc1dc7a3Sopenharmony_ci * 1857cc1dc7a3Sopenharmony_ci * @return The actual endpoint mode used. 1858cc1dc7a3Sopenharmony_ci */ 1859cc1dc7a3Sopenharmony_ciuint8_t pack_color_endpoints( 1860cc1dc7a3Sopenharmony_ci QualityProfile privateProfile, 1861cc1dc7a3Sopenharmony_ci vfloat4 color0, 1862cc1dc7a3Sopenharmony_ci vfloat4 color1, 1863cc1dc7a3Sopenharmony_ci vfloat4 rgbs_color, 1864cc1dc7a3Sopenharmony_ci vfloat4 rgbo_color, 1865cc1dc7a3Sopenharmony_ci int format, 1866cc1dc7a3Sopenharmony_ci uint8_t* output, 1867cc1dc7a3Sopenharmony_ci quant_method quant_level); 1868cc1dc7a3Sopenharmony_ci 1869cc1dc7a3Sopenharmony_ci/** 1870cc1dc7a3Sopenharmony_ci * @brief Unpack a single pair of encoded endpoints. 1871cc1dc7a3Sopenharmony_ci * 1872cc1dc7a3Sopenharmony_ci * Endpoints must be unscrambled and converted into the 0-255 range before calling this functions. 1873cc1dc7a3Sopenharmony_ci * 1874cc1dc7a3Sopenharmony_ci * @param decode_mode The decode mode (LDR, HDR, etc). 1875cc1dc7a3Sopenharmony_ci * @param format The color endpoint mode used. 1876cc1dc7a3Sopenharmony_ci * @param input The raw array of encoded input integers. The length of this array 1877cc1dc7a3Sopenharmony_ci * depends on @c format; it can be safely assumed to be large enough. 1878cc1dc7a3Sopenharmony_ci * @param[out] rgb_hdr Is the endpoint using HDR for the RGB channels? 1879cc1dc7a3Sopenharmony_ci * @param[out] alpha_hdr Is the endpoint using HDR for the A channel? 1880cc1dc7a3Sopenharmony_ci * @param[out] output0 The output color for endpoint 0. 1881cc1dc7a3Sopenharmony_ci * @param[out] output1 The output color for endpoint 1. 1882cc1dc7a3Sopenharmony_ci */ 1883cc1dc7a3Sopenharmony_civoid unpack_color_endpoints( 1884cc1dc7a3Sopenharmony_ci astcenc_profile decode_mode, 1885cc1dc7a3Sopenharmony_ci int format, 1886cc1dc7a3Sopenharmony_ci const uint8_t* input, 1887cc1dc7a3Sopenharmony_ci bool& rgb_hdr, 1888cc1dc7a3Sopenharmony_ci bool& alpha_hdr, 1889cc1dc7a3Sopenharmony_ci vint4& output0, 1890cc1dc7a3Sopenharmony_ci vint4& output1); 1891cc1dc7a3Sopenharmony_ci 1892cc1dc7a3Sopenharmony_ci/** 1893cc1dc7a3Sopenharmony_ci * @brief Unpack an LDR RGBA color that uses delta encoding. 1894cc1dc7a3Sopenharmony_ci * 1895cc1dc7a3Sopenharmony_ci * @param input0 The packed endpoint 0 color. 1896cc1dc7a3Sopenharmony_ci * @param input1 The packed endpoint 1 color deltas. 1897cc1dc7a3Sopenharmony_ci * @param[out] output0 The unpacked endpoint 0 color. 1898cc1dc7a3Sopenharmony_ci * @param[out] output1 The unpacked endpoint 1 color. 1899cc1dc7a3Sopenharmony_ci */ 1900cc1dc7a3Sopenharmony_civoid rgba_delta_unpack( 1901cc1dc7a3Sopenharmony_ci vint4 input0, 1902cc1dc7a3Sopenharmony_ci vint4 input1, 1903cc1dc7a3Sopenharmony_ci vint4& output0, 1904cc1dc7a3Sopenharmony_ci vint4& output1); 1905cc1dc7a3Sopenharmony_ci 1906cc1dc7a3Sopenharmony_ci/** 1907cc1dc7a3Sopenharmony_ci * @brief Unpack an LDR RGBA color that uses direct encoding. 1908cc1dc7a3Sopenharmony_ci * 1909cc1dc7a3Sopenharmony_ci * @param input0 The packed endpoint 0 color. 1910cc1dc7a3Sopenharmony_ci * @param input1 The packed endpoint 1 color. 1911cc1dc7a3Sopenharmony_ci * @param[out] output0 The unpacked endpoint 0 color. 1912cc1dc7a3Sopenharmony_ci * @param[out] output1 The unpacked endpoint 1 color. 1913cc1dc7a3Sopenharmony_ci */ 1914cc1dc7a3Sopenharmony_civoid rgba_unpack( 1915cc1dc7a3Sopenharmony_ci vint4 input0, 1916cc1dc7a3Sopenharmony_ci vint4 input1, 1917cc1dc7a3Sopenharmony_ci vint4& output0, 1918cc1dc7a3Sopenharmony_ci vint4& output1); 1919cc1dc7a3Sopenharmony_ci 1920cc1dc7a3Sopenharmony_ci/** 1921cc1dc7a3Sopenharmony_ci * @brief Unpack a set of quantized and decimated weights. 1922cc1dc7a3Sopenharmony_ci * 1923cc1dc7a3Sopenharmony_ci * TODO: Can we skip this for non-decimated weights now that the @c scb is 1924cc1dc7a3Sopenharmony_ci * already storing unquantized weights? 1925cc1dc7a3Sopenharmony_ci * 1926cc1dc7a3Sopenharmony_ci * @param bsd The block size information. 1927cc1dc7a3Sopenharmony_ci * @param scb The symbolic compressed encoding. 1928cc1dc7a3Sopenharmony_ci * @param di The weight grid decimation table. 1929cc1dc7a3Sopenharmony_ci * @param is_dual_plane @c true if this is a dual plane block, @c false otherwise. 1930cc1dc7a3Sopenharmony_ci * @param[out] weights_plane1 The output array for storing the plane 1 weights. 1931cc1dc7a3Sopenharmony_ci * @param[out] weights_plane2 The output array for storing the plane 2 weights. 1932cc1dc7a3Sopenharmony_ci */ 1933cc1dc7a3Sopenharmony_civoid unpack_weights( 1934cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 1935cc1dc7a3Sopenharmony_ci const symbolic_compressed_block& scb, 1936cc1dc7a3Sopenharmony_ci const decimation_info& di, 1937cc1dc7a3Sopenharmony_ci bool is_dual_plane, 1938cc1dc7a3Sopenharmony_ci int weights_plane1[BLOCK_MAX_TEXELS], 1939cc1dc7a3Sopenharmony_ci int weights_plane2[BLOCK_MAX_TEXELS]); 1940cc1dc7a3Sopenharmony_ci 1941cc1dc7a3Sopenharmony_ci/** 1942cc1dc7a3Sopenharmony_ci * @brief Identify, for each mode, which set of color endpoint produces the best result. 1943cc1dc7a3Sopenharmony_ci * 1944cc1dc7a3Sopenharmony_ci * Returns the best @c tune_candidate_limit best looking modes, along with the ideal color encoding 1945cc1dc7a3Sopenharmony_ci * combination for each. The modified quantization level can be used when all formats are the same, 1946cc1dc7a3Sopenharmony_ci * as this frees up two additional bits of storage. 1947cc1dc7a3Sopenharmony_ci * 1948cc1dc7a3Sopenharmony_ci * @param pi The partition info for the current trial. 1949cc1dc7a3Sopenharmony_ci * @param blk The image block color data to compress. 1950cc1dc7a3Sopenharmony_ci * @param ep The ideal endpoints. 1951cc1dc7a3Sopenharmony_ci * @param qwt_bitcounts Bit counts for different quantization methods. 1952cc1dc7a3Sopenharmony_ci * @param qwt_errors Errors for different quantization methods. 1953cc1dc7a3Sopenharmony_ci * @param tune_candidate_limit The max number of candidates to return, may be less. 1954cc1dc7a3Sopenharmony_ci * @param start_block_mode The first block mode to inspect. 1955cc1dc7a3Sopenharmony_ci * @param end_block_mode The last block mode to inspect. 1956cc1dc7a3Sopenharmony_ci * @param[out] partition_format_specifiers The best formats per partition. 1957cc1dc7a3Sopenharmony_ci * @param[out] block_mode The best packed block mode indexes. 1958cc1dc7a3Sopenharmony_ci * @param[out] quant_level The best color quant level. 1959cc1dc7a3Sopenharmony_ci * @param[out] quant_level_mod The best color quant level if endpoints are the same. 1960cc1dc7a3Sopenharmony_ci * @param[out] tmpbuf Preallocated scratch buffers for the compressor. 1961cc1dc7a3Sopenharmony_ci * 1962cc1dc7a3Sopenharmony_ci * @return The actual number of candidate matches returned. 1963cc1dc7a3Sopenharmony_ci */ 1964cc1dc7a3Sopenharmony_ciunsigned int compute_ideal_endpoint_formats( 1965cc1dc7a3Sopenharmony_ci QualityProfile privateProfile, 1966cc1dc7a3Sopenharmony_ci const partition_info& pi, 1967cc1dc7a3Sopenharmony_ci const image_block& blk, 1968cc1dc7a3Sopenharmony_ci const endpoints& ep, 1969cc1dc7a3Sopenharmony_ci const int8_t* qwt_bitcounts, 1970cc1dc7a3Sopenharmony_ci const float* qwt_errors, 1971cc1dc7a3Sopenharmony_ci unsigned int tune_candidate_limit, 1972cc1dc7a3Sopenharmony_ci unsigned int start_block_mode, 1973cc1dc7a3Sopenharmony_ci unsigned int end_block_mode, 1974cc1dc7a3Sopenharmony_ci uint8_t partition_format_specifiers[TUNE_MAX_TRIAL_CANDIDATES][BLOCK_MAX_PARTITIONS], 1975cc1dc7a3Sopenharmony_ci int block_mode[TUNE_MAX_TRIAL_CANDIDATES], 1976cc1dc7a3Sopenharmony_ci quant_method quant_level[TUNE_MAX_TRIAL_CANDIDATES], 1977cc1dc7a3Sopenharmony_ci quant_method quant_level_mod[TUNE_MAX_TRIAL_CANDIDATES], 1978cc1dc7a3Sopenharmony_ci compression_working_buffers& tmpbuf); 1979cc1dc7a3Sopenharmony_ci 1980cc1dc7a3Sopenharmony_ci/** 1981cc1dc7a3Sopenharmony_ci * @brief For a given 1 plane weight set recompute the endpoint colors. 1982cc1dc7a3Sopenharmony_ci * 1983cc1dc7a3Sopenharmony_ci * As we quantize and decimate weights the optimal endpoint colors may change slightly, so we must 1984cc1dc7a3Sopenharmony_ci * recompute the ideal colors for a specific weight set. 1985cc1dc7a3Sopenharmony_ci * 1986cc1dc7a3Sopenharmony_ci * @param blk The image block color data to compress. 1987cc1dc7a3Sopenharmony_ci * @param pi The partition info for the current trial. 1988cc1dc7a3Sopenharmony_ci * @param di The weight grid decimation table. 1989cc1dc7a3Sopenharmony_ci * @param dec_weights_uquant The quantized weight set. 1990cc1dc7a3Sopenharmony_ci * @param[in,out] ep The color endpoints (modifed in place). 1991cc1dc7a3Sopenharmony_ci * @param[out] rgbs_vectors The RGB+scale vectors for LDR blocks. 1992cc1dc7a3Sopenharmony_ci * @param[out] rgbo_vectors The RGB+offset vectors for HDR blocks. 1993cc1dc7a3Sopenharmony_ci */ 1994cc1dc7a3Sopenharmony_civoid recompute_ideal_colors_1plane( 1995cc1dc7a3Sopenharmony_ci const image_block& blk, 1996cc1dc7a3Sopenharmony_ci const partition_info& pi, 1997cc1dc7a3Sopenharmony_ci const decimation_info& di, 1998cc1dc7a3Sopenharmony_ci const uint8_t* dec_weights_uquant, 1999cc1dc7a3Sopenharmony_ci endpoints& ep, 2000cc1dc7a3Sopenharmony_ci vfloat4 rgbs_vectors[BLOCK_MAX_PARTITIONS], 2001cc1dc7a3Sopenharmony_ci vfloat4 rgbo_vectors[BLOCK_MAX_PARTITIONS]); 2002cc1dc7a3Sopenharmony_ci 2003cc1dc7a3Sopenharmony_ci/** 2004cc1dc7a3Sopenharmony_ci * @brief For a given 2 plane weight set recompute the endpoint colors. 2005cc1dc7a3Sopenharmony_ci * 2006cc1dc7a3Sopenharmony_ci * As we quantize and decimate weights the optimal endpoint colors may change slightly, so we must 2007cc1dc7a3Sopenharmony_ci * recompute the ideal colors for a specific weight set. 2008cc1dc7a3Sopenharmony_ci * 2009cc1dc7a3Sopenharmony_ci * @param blk The image block color data to compress. 2010cc1dc7a3Sopenharmony_ci * @param bsd The block_size descriptor. 2011cc1dc7a3Sopenharmony_ci * @param di The weight grid decimation table. 2012cc1dc7a3Sopenharmony_ci * @param dec_weights_uquant_plane1 The quantized weight set for plane 1. 2013cc1dc7a3Sopenharmony_ci * @param dec_weights_uquant_plane2 The quantized weight set for plane 2. 2014cc1dc7a3Sopenharmony_ci * @param[in,out] ep The color endpoints (modifed in place). 2015cc1dc7a3Sopenharmony_ci * @param[out] rgbs_vector The RGB+scale color for LDR blocks. 2016cc1dc7a3Sopenharmony_ci * @param[out] rgbo_vector The RGB+offset color for HDR blocks. 2017cc1dc7a3Sopenharmony_ci * @param plane2_component The component assigned to plane 2. 2018cc1dc7a3Sopenharmony_ci */ 2019cc1dc7a3Sopenharmony_civoid recompute_ideal_colors_2planes( 2020cc1dc7a3Sopenharmony_ci const image_block& blk, 2021cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 2022cc1dc7a3Sopenharmony_ci const decimation_info& di, 2023cc1dc7a3Sopenharmony_ci const uint8_t* dec_weights_uquant_plane1, 2024cc1dc7a3Sopenharmony_ci const uint8_t* dec_weights_uquant_plane2, 2025cc1dc7a3Sopenharmony_ci endpoints& ep, 2026cc1dc7a3Sopenharmony_ci vfloat4& rgbs_vector, 2027cc1dc7a3Sopenharmony_ci vfloat4& rgbo_vector, 2028cc1dc7a3Sopenharmony_ci int plane2_component); 2029cc1dc7a3Sopenharmony_ci 2030cc1dc7a3Sopenharmony_ci/** 2031cc1dc7a3Sopenharmony_ci * @brief Expand the angular tables needed for the alternative to PCA that we use. 2032cc1dc7a3Sopenharmony_ci */ 2033cc1dc7a3Sopenharmony_civoid prepare_angular_tables(); 2034cc1dc7a3Sopenharmony_ci 2035cc1dc7a3Sopenharmony_ci/** 2036cc1dc7a3Sopenharmony_ci * @brief Compute the angular endpoints for one plane for each block mode. 2037cc1dc7a3Sopenharmony_ci * 2038cc1dc7a3Sopenharmony_ci * @param only_always Only consider block modes that are always enabled. 2039cc1dc7a3Sopenharmony_ci * @param bsd The block size descriptor for the current trial. 2040cc1dc7a3Sopenharmony_ci * @param dec_weight_ideal_value The ideal decimated unquantized weight values. 2041cc1dc7a3Sopenharmony_ci * @param max_weight_quant The maximum block mode weight quantization allowed. 2042cc1dc7a3Sopenharmony_ci * @param[out] tmpbuf Preallocated scratch buffers for the compressor. 2043cc1dc7a3Sopenharmony_ci */ 2044cc1dc7a3Sopenharmony_civoid compute_angular_endpoints_1plane( 2045cc1dc7a3Sopenharmony_ci QualityProfile privateProfile, 2046cc1dc7a3Sopenharmony_ci bool only_always, 2047cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 2048cc1dc7a3Sopenharmony_ci const float* dec_weight_ideal_value, 2049cc1dc7a3Sopenharmony_ci unsigned int max_weight_quant, 2050cc1dc7a3Sopenharmony_ci compression_working_buffers& tmpbuf); 2051cc1dc7a3Sopenharmony_ci 2052cc1dc7a3Sopenharmony_ci/** 2053cc1dc7a3Sopenharmony_ci * @brief Compute the angular endpoints for two planes for each block mode. 2054cc1dc7a3Sopenharmony_ci * 2055cc1dc7a3Sopenharmony_ci * @param bsd The block size descriptor for the current trial. 2056cc1dc7a3Sopenharmony_ci * @param dec_weight_ideal_value The ideal decimated unquantized weight values. 2057cc1dc7a3Sopenharmony_ci * @param max_weight_quant The maximum block mode weight quantization allowed. 2058cc1dc7a3Sopenharmony_ci * @param[out] tmpbuf Preallocated scratch buffers for the compressor. 2059cc1dc7a3Sopenharmony_ci */ 2060cc1dc7a3Sopenharmony_civoid compute_angular_endpoints_2planes( 2061cc1dc7a3Sopenharmony_ci QualityProfile privateProfile, 2062cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 2063cc1dc7a3Sopenharmony_ci const float* dec_weight_ideal_value, 2064cc1dc7a3Sopenharmony_ci unsigned int max_weight_quant, 2065cc1dc7a3Sopenharmony_ci compression_working_buffers& tmpbuf); 2066cc1dc7a3Sopenharmony_ci 2067cc1dc7a3Sopenharmony_ci/* ============================================================================ 2068cc1dc7a3Sopenharmony_ci Functionality for high level compression and decompression access. 2069cc1dc7a3Sopenharmony_ci============================================================================ */ 2070cc1dc7a3Sopenharmony_ci 2071cc1dc7a3Sopenharmony_ci/** 2072cc1dc7a3Sopenharmony_ci * @brief Compress an image block into a physical block. 2073cc1dc7a3Sopenharmony_ci * 2074cc1dc7a3Sopenharmony_ci * @param ctx The compressor context and configuration. 2075cc1dc7a3Sopenharmony_ci * @param blk The image block color data to compress. 2076cc1dc7a3Sopenharmony_ci * @param[out] pcb The physical compressed block output. 2077cc1dc7a3Sopenharmony_ci * @param[out] tmpbuf Preallocated scratch buffers for the compressor. 2078cc1dc7a3Sopenharmony_ci */ 2079cc1dc7a3Sopenharmony_civoid compress_block( 2080cc1dc7a3Sopenharmony_ci const astcenc_contexti& ctx, 2081cc1dc7a3Sopenharmony_ci const image_block& blk, 2082cc1dc7a3Sopenharmony_ci uint8_t pcb[16], 2083cc1dc7a3Sopenharmony_ci#if QUALITY_CONTROL 2084cc1dc7a3Sopenharmony_ci compression_working_buffers& tmpbuf, 2085cc1dc7a3Sopenharmony_ci bool calQualityEnable, 2086cc1dc7a3Sopenharmony_ci int32_t *mseBlock[RGBA_COM] 2087cc1dc7a3Sopenharmony_ci#else 2088cc1dc7a3Sopenharmony_ci compression_working_buffers& tmpbuf 2089cc1dc7a3Sopenharmony_ci#endif 2090cc1dc7a3Sopenharmony_ci ); 2091cc1dc7a3Sopenharmony_ci 2092cc1dc7a3Sopenharmony_ci/** 2093cc1dc7a3Sopenharmony_ci * @brief Decompress a symbolic block in to an image block. 2094cc1dc7a3Sopenharmony_ci * 2095cc1dc7a3Sopenharmony_ci * @param decode_mode The decode mode (LDR, HDR, etc). 2096cc1dc7a3Sopenharmony_ci * @param bsd The block size information. 2097cc1dc7a3Sopenharmony_ci * @param xpos The X coordinate of the block in the overall image. 2098cc1dc7a3Sopenharmony_ci * @param ypos The Y coordinate of the block in the overall image. 2099cc1dc7a3Sopenharmony_ci * @param zpos The Z coordinate of the block in the overall image. 2100cc1dc7a3Sopenharmony_ci * @param[out] blk The decompressed image block color data. 2101cc1dc7a3Sopenharmony_ci */ 2102cc1dc7a3Sopenharmony_civoid decompress_symbolic_block( 2103cc1dc7a3Sopenharmony_ci astcenc_profile decode_mode, 2104cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 2105cc1dc7a3Sopenharmony_ci int xpos, 2106cc1dc7a3Sopenharmony_ci int ypos, 2107cc1dc7a3Sopenharmony_ci int zpos, 2108cc1dc7a3Sopenharmony_ci const symbolic_compressed_block& scb, 2109cc1dc7a3Sopenharmony_ci image_block& blk); 2110cc1dc7a3Sopenharmony_ci 2111cc1dc7a3Sopenharmony_ci/** 2112cc1dc7a3Sopenharmony_ci * @brief Compute the error between a symbolic block and the original input data. 2113cc1dc7a3Sopenharmony_ci * 2114cc1dc7a3Sopenharmony_ci * This function is specialized for 2 plane and 1 partition search. 2115cc1dc7a3Sopenharmony_ci * 2116cc1dc7a3Sopenharmony_ci * In RGBM mode this will reject blocks that attempt to encode a zero M value. 2117cc1dc7a3Sopenharmony_ci * 2118cc1dc7a3Sopenharmony_ci * @param config The compressor config. 2119cc1dc7a3Sopenharmony_ci * @param bsd The block size information. 2120cc1dc7a3Sopenharmony_ci * @param scb The symbolic compressed encoding. 2121cc1dc7a3Sopenharmony_ci * @param blk The original image block color data. 2122cc1dc7a3Sopenharmony_ci * 2123cc1dc7a3Sopenharmony_ci * @return Returns the computed error, or a negative value if the encoding 2124cc1dc7a3Sopenharmony_ci * should be rejected for any reason. 2125cc1dc7a3Sopenharmony_ci */ 2126cc1dc7a3Sopenharmony_cifloat compute_symbolic_block_difference_2plane( 2127cc1dc7a3Sopenharmony_ci const astcenc_config& config, 2128cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 2129cc1dc7a3Sopenharmony_ci const symbolic_compressed_block& scb, 2130cc1dc7a3Sopenharmony_ci const image_block& blk); 2131cc1dc7a3Sopenharmony_ci 2132cc1dc7a3Sopenharmony_ci/** 2133cc1dc7a3Sopenharmony_ci * @brief Compute the error between a symbolic block and the original input data. 2134cc1dc7a3Sopenharmony_ci * 2135cc1dc7a3Sopenharmony_ci * This function is specialized for 1 plane and N partition search. 2136cc1dc7a3Sopenharmony_ci * 2137cc1dc7a3Sopenharmony_ci * In RGBM mode this will reject blocks that attempt to encode a zero M value. 2138cc1dc7a3Sopenharmony_ci * 2139cc1dc7a3Sopenharmony_ci * @param config The compressor config. 2140cc1dc7a3Sopenharmony_ci * @param bsd The block size information. 2141cc1dc7a3Sopenharmony_ci * @param scb The symbolic compressed encoding. 2142cc1dc7a3Sopenharmony_ci * @param blk The original image block color data. 2143cc1dc7a3Sopenharmony_ci * 2144cc1dc7a3Sopenharmony_ci * @return Returns the computed error, or a negative value if the encoding 2145cc1dc7a3Sopenharmony_ci * should be rejected for any reason. 2146cc1dc7a3Sopenharmony_ci */ 2147cc1dc7a3Sopenharmony_cifloat compute_symbolic_block_difference_1plane( 2148cc1dc7a3Sopenharmony_ci const astcenc_config& config, 2149cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 2150cc1dc7a3Sopenharmony_ci const symbolic_compressed_block& scb, 2151cc1dc7a3Sopenharmony_ci const image_block& blk); 2152cc1dc7a3Sopenharmony_ci 2153cc1dc7a3Sopenharmony_ci/** 2154cc1dc7a3Sopenharmony_ci * @brief Compute the error between a symbolic block and the original input data. 2155cc1dc7a3Sopenharmony_ci * 2156cc1dc7a3Sopenharmony_ci * This function is specialized for 1 plane and 1 partition search. 2157cc1dc7a3Sopenharmony_ci * 2158cc1dc7a3Sopenharmony_ci * In RGBM mode this will reject blocks that attempt to encode a zero M value. 2159cc1dc7a3Sopenharmony_ci * 2160cc1dc7a3Sopenharmony_ci * @param config The compressor config. 2161cc1dc7a3Sopenharmony_ci * @param bsd The block size information. 2162cc1dc7a3Sopenharmony_ci * @param scb The symbolic compressed encoding. 2163cc1dc7a3Sopenharmony_ci * @param blk The original image block color data. 2164cc1dc7a3Sopenharmony_ci * 2165cc1dc7a3Sopenharmony_ci * @return Returns the computed error, or a negative value if the encoding 2166cc1dc7a3Sopenharmony_ci * should be rejected for any reason. 2167cc1dc7a3Sopenharmony_ci */ 2168cc1dc7a3Sopenharmony_cifloat compute_symbolic_block_difference_1plane_1partition( 2169cc1dc7a3Sopenharmony_ci const astcenc_config& config, 2170cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 2171cc1dc7a3Sopenharmony_ci const symbolic_compressed_block& scb, 2172cc1dc7a3Sopenharmony_ci const image_block& blk); 2173cc1dc7a3Sopenharmony_ci 2174cc1dc7a3Sopenharmony_ci/** 2175cc1dc7a3Sopenharmony_ci * @brief Convert a symbolic representation into a binary physical encoding. 2176cc1dc7a3Sopenharmony_ci * 2177cc1dc7a3Sopenharmony_ci * It is assumed that the symbolic encoding is valid and encodable, or 2178cc1dc7a3Sopenharmony_ci * previously flagged as an error block if an error color it to be encoded. 2179cc1dc7a3Sopenharmony_ci * 2180cc1dc7a3Sopenharmony_ci * @param bsd The block size information. 2181cc1dc7a3Sopenharmony_ci * @param scb The symbolic representation. 2182cc1dc7a3Sopenharmony_ci * @param[out] pcb The physical compressed block output. 2183cc1dc7a3Sopenharmony_ci */ 2184cc1dc7a3Sopenharmony_civoid symbolic_to_physical( 2185cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 2186cc1dc7a3Sopenharmony_ci const symbolic_compressed_block& scb, 2187cc1dc7a3Sopenharmony_ci uint8_t pcb[16]); 2188cc1dc7a3Sopenharmony_ci 2189cc1dc7a3Sopenharmony_ci/** 2190cc1dc7a3Sopenharmony_ci * @brief Convert a binary physical encoding into a symbolic representation. 2191cc1dc7a3Sopenharmony_ci * 2192cc1dc7a3Sopenharmony_ci * This function can cope with arbitrary input data; output blocks will be 2193cc1dc7a3Sopenharmony_ci * flagged as an error block if the encoding is invalid. 2194cc1dc7a3Sopenharmony_ci * 2195cc1dc7a3Sopenharmony_ci * @param bsd The block size information. 2196cc1dc7a3Sopenharmony_ci * @param pcb The physical compresesd block input. 2197cc1dc7a3Sopenharmony_ci * @param[out] scb The output symbolic representation. 2198cc1dc7a3Sopenharmony_ci */ 2199cc1dc7a3Sopenharmony_civoid physical_to_symbolic( 2200cc1dc7a3Sopenharmony_ci const block_size_descriptor& bsd, 2201cc1dc7a3Sopenharmony_ci const uint8_t pcb[16], 2202cc1dc7a3Sopenharmony_ci symbolic_compressed_block& scb); 2203cc1dc7a3Sopenharmony_ci 2204cc1dc7a3Sopenharmony_ci/* ============================================================================ 2205cc1dc7a3Sopenharmony_ciPlatform-specific functions. 2206cc1dc7a3Sopenharmony_ci============================================================================ */ 2207cc1dc7a3Sopenharmony_ci/** 2208cc1dc7a3Sopenharmony_ci * @brief Allocate an aligned memory buffer. 2209cc1dc7a3Sopenharmony_ci * 2210cc1dc7a3Sopenharmony_ci * Allocated memory must be freed by aligned_free. 2211cc1dc7a3Sopenharmony_ci * 2212cc1dc7a3Sopenharmony_ci * @param size The desired buffer size. 2213cc1dc7a3Sopenharmony_ci * @param align The desired buffer alignment; must be 2^N, may be increased 2214cc1dc7a3Sopenharmony_ci * by the implementation to a minimum allowable alignment. 2215cc1dc7a3Sopenharmony_ci * 2216cc1dc7a3Sopenharmony_ci * @return The memory buffer pointer or nullptr on allocation failure. 2217cc1dc7a3Sopenharmony_ci */ 2218cc1dc7a3Sopenharmony_citemplate<typename T> 2219cc1dc7a3Sopenharmony_ciT* aligned_malloc(size_t size, size_t align) 2220cc1dc7a3Sopenharmony_ci{ 2221cc1dc7a3Sopenharmony_ci void* ptr; 2222cc1dc7a3Sopenharmony_ci int error = 0; 2223cc1dc7a3Sopenharmony_ci 2224cc1dc7a3Sopenharmony_ci // Don't allow this to under-align a type 2225cc1dc7a3Sopenharmony_ci size_t min_align = astc::max(alignof(T), sizeof(void*)); 2226cc1dc7a3Sopenharmony_ci size_t real_align = astc::max(min_align, align); 2227cc1dc7a3Sopenharmony_ci 2228cc1dc7a3Sopenharmony_ci#if defined(_WIN32) 2229cc1dc7a3Sopenharmony_ci ptr = _aligned_malloc(size, real_align); 2230cc1dc7a3Sopenharmony_ci#else 2231cc1dc7a3Sopenharmony_ci error = posix_memalign(&ptr, real_align, size); 2232cc1dc7a3Sopenharmony_ci#endif 2233cc1dc7a3Sopenharmony_ci 2234cc1dc7a3Sopenharmony_ci if (error || (!ptr)) 2235cc1dc7a3Sopenharmony_ci { 2236cc1dc7a3Sopenharmony_ci return nullptr; 2237cc1dc7a3Sopenharmony_ci } 2238cc1dc7a3Sopenharmony_ci 2239cc1dc7a3Sopenharmony_ci return static_cast<T*>(ptr); 2240cc1dc7a3Sopenharmony_ci} 2241cc1dc7a3Sopenharmony_ci 2242cc1dc7a3Sopenharmony_ci/** 2243cc1dc7a3Sopenharmony_ci * @brief Free an aligned memory buffer. 2244cc1dc7a3Sopenharmony_ci * 2245cc1dc7a3Sopenharmony_ci * @param ptr The buffer to free. 2246cc1dc7a3Sopenharmony_ci */ 2247cc1dc7a3Sopenharmony_citemplate<typename T> 2248cc1dc7a3Sopenharmony_civoid aligned_free(T* ptr) 2249cc1dc7a3Sopenharmony_ci{ 2250cc1dc7a3Sopenharmony_ci#if defined(_WIN32) 2251cc1dc7a3Sopenharmony_ci _aligned_free(ptr); 2252cc1dc7a3Sopenharmony_ci#else 2253cc1dc7a3Sopenharmony_ci free(ptr); 2254cc1dc7a3Sopenharmony_ci#endif 2255cc1dc7a3Sopenharmony_ci} 2256cc1dc7a3Sopenharmony_ci 2257cc1dc7a3Sopenharmony_ci#ifdef ASTC_CUSTOMIZED_ENABLE 2258cc1dc7a3Sopenharmony_ci#ifdef BUILD_HMOS_SDK 2259cc1dc7a3Sopenharmony_ci#if defined(_WIN32) && !defined(__CYGWIN__) 2260cc1dc7a3Sopenharmony_ciconst LPCSTR g_astcCustomizedSo = "../../hms/toolchains/lib/libastcCustomizedEncode.dll"; 2261cc1dc7a3Sopenharmony_ci#elif defined(__APPLE__) 2262cc1dc7a3Sopenharmony_ciconst std::string g_astcCustomizedSo = "../../hms/toolchains/lib/libastcCustomizedEncode.dylib"; 2263cc1dc7a3Sopenharmony_ci#else 2264cc1dc7a3Sopenharmony_ciconst std::string g_astcCustomizedSo = "../../hms/toolchains/lib/libastcCustomizedEncode.so"; 2265cc1dc7a3Sopenharmony_ci#endif 2266cc1dc7a3Sopenharmony_ci#else 2267cc1dc7a3Sopenharmony_ciconst std::string g_astcCustomizedSo = "/system/lib64/module/hms/graphic/libastcCustomizedEncode.z.so"; 2268cc1dc7a3Sopenharmony_ci#endif 2269cc1dc7a3Sopenharmony_ciusing IsCustomizedBlockMode = bool (*)(const int); 2270cc1dc7a3Sopenharmony_ciusing CustomizedMaxPartitions = int (*)(); 2271cc1dc7a3Sopenharmony_ciusing CustomizedBlockMode = int (*)(); 2272cc1dc7a3Sopenharmony_ci 2273cc1dc7a3Sopenharmony_ciclass AstcCustomizedSoManager 2274cc1dc7a3Sopenharmony_ci{ 2275cc1dc7a3Sopenharmony_cipublic: 2276cc1dc7a3Sopenharmony_ci AstcCustomizedSoManager() 2277cc1dc7a3Sopenharmony_ci { 2278cc1dc7a3Sopenharmony_ci astcCustomizedSoOpened_ = false; 2279cc1dc7a3Sopenharmony_ci astcCustomizedSoHandle_ = nullptr; 2280cc1dc7a3Sopenharmony_ci isCustomizedBlockModeFunc_ = nullptr; 2281cc1dc7a3Sopenharmony_ci customizedMaxPartitionsFunc_ = nullptr; 2282cc1dc7a3Sopenharmony_ci customizedBlockModeFunc_ = nullptr; 2283cc1dc7a3Sopenharmony_ci } 2284cc1dc7a3Sopenharmony_ci ~AstcCustomizedSoManager() 2285cc1dc7a3Sopenharmony_ci { 2286cc1dc7a3Sopenharmony_ci if (!astcCustomizedSoOpened_ || astcCustomizedSoHandle_ == nullptr) 2287cc1dc7a3Sopenharmony_ci { 2288cc1dc7a3Sopenharmony_ci printf("astcenc customized so is not be opened when dlclose!\n"); 2289cc1dc7a3Sopenharmony_ci return; 2290cc1dc7a3Sopenharmony_ci } 2291cc1dc7a3Sopenharmony_ci#if defined(_WIN32) && !defined(__CYGWIN__) 2292cc1dc7a3Sopenharmony_ci if (!FreeLibrary(astcCustomizedSoHandle_)) 2293cc1dc7a3Sopenharmony_ci { 2294cc1dc7a3Sopenharmony_ci printf("astc dll FreeLibrary failed: %s\n", g_astcCustomizedSo); 2295cc1dc7a3Sopenharmony_ci } 2296cc1dc7a3Sopenharmony_ci#else 2297cc1dc7a3Sopenharmony_ci if (dlclose(astcCustomizedSoHandle_) != 0) 2298cc1dc7a3Sopenharmony_ci { 2299cc1dc7a3Sopenharmony_ci printf("astcenc so dlclose failed: %s\n", g_astcCustomizedSo.c_str()); 2300cc1dc7a3Sopenharmony_ci } 2301cc1dc7a3Sopenharmony_ci#endif 2302cc1dc7a3Sopenharmony_ci } 2303cc1dc7a3Sopenharmony_ci IsCustomizedBlockMode isCustomizedBlockModeFunc_; 2304cc1dc7a3Sopenharmony_ci CustomizedMaxPartitions customizedMaxPartitionsFunc_; 2305cc1dc7a3Sopenharmony_ci CustomizedBlockMode customizedBlockModeFunc_; 2306cc1dc7a3Sopenharmony_ci bool LoadSutCustomizedSo() 2307cc1dc7a3Sopenharmony_ci { 2308cc1dc7a3Sopenharmony_ci if (!astcCustomizedSoOpened_) 2309cc1dc7a3Sopenharmony_ci { 2310cc1dc7a3Sopenharmony_ci#if defined(_WIN32) && !defined(__CYGWIN__) 2311cc1dc7a3Sopenharmony_ci if ((_access(g_astcCustomizedSo, 0) == -1)) 2312cc1dc7a3Sopenharmony_ci { 2313cc1dc7a3Sopenharmony_ci printf("astc customized dll(%s) is not found!\n", g_astcCustomizedSo); 2314cc1dc7a3Sopenharmony_ci return false; 2315cc1dc7a3Sopenharmony_ci } 2316cc1dc7a3Sopenharmony_ci astcCustomizedSoHandle_ = LoadLibrary(g_astcCustomizedSo); 2317cc1dc7a3Sopenharmony_ci if (astcCustomizedSoHandle_ == nullptr) 2318cc1dc7a3Sopenharmony_ci { 2319cc1dc7a3Sopenharmony_ci printf("astc libAstcCustomizedEnc LoadLibrary failed!\n"); 2320cc1dc7a3Sopenharmony_ci return false; 2321cc1dc7a3Sopenharmony_ci } 2322cc1dc7a3Sopenharmony_ci isCustomizedBlockModeFunc_ = 2323cc1dc7a3Sopenharmony_ci reinterpret_cast<IsCustomizedBlockMode>(GetProcAddress(astcCustomizedSoHandle_, 2324cc1dc7a3Sopenharmony_ci "IsCustomizedBlockMode")); 2325cc1dc7a3Sopenharmony_ci if (isCustomizedBlockModeFunc_ == nullptr) 2326cc1dc7a3Sopenharmony_ci { 2327cc1dc7a3Sopenharmony_ci printf("astc isCustomizedBlockModeFunc_ GetProcAddress failed!\n"); 2328cc1dc7a3Sopenharmony_ci if (!FreeLibrary(astcCustomizedSoHandle_)) 2329cc1dc7a3Sopenharmony_ci { 2330cc1dc7a3Sopenharmony_ci printf("astc isCustomizedBlockModeFunc_ FreeLibrary failed!\n"); 2331cc1dc7a3Sopenharmony_ci } 2332cc1dc7a3Sopenharmony_ci return false; 2333cc1dc7a3Sopenharmony_ci } 2334cc1dc7a3Sopenharmony_ci customizedMaxPartitionsFunc_ = 2335cc1dc7a3Sopenharmony_ci reinterpret_cast<CustomizedMaxPartitions>(GetProcAddress(astcCustomizedSoHandle_, 2336cc1dc7a3Sopenharmony_ci "CustomizedMaxPartitions")); 2337cc1dc7a3Sopenharmony_ci if (customizedMaxPartitionsFunc_ == nullptr) 2338cc1dc7a3Sopenharmony_ci { 2339cc1dc7a3Sopenharmony_ci printf("astc customizedMaxPartitionsFunc_ GetProcAddress failed!\n"); 2340cc1dc7a3Sopenharmony_ci if (!FreeLibrary(astcCustomizedSoHandle_)) 2341cc1dc7a3Sopenharmony_ci { 2342cc1dc7a3Sopenharmony_ci printf("astc customizedMaxPartitionsFunc_ FreeLibrary failed!\n"); 2343cc1dc7a3Sopenharmony_ci } 2344cc1dc7a3Sopenharmony_ci return false; 2345cc1dc7a3Sopenharmony_ci } 2346cc1dc7a3Sopenharmony_ci customizedBlockModeFunc_ = 2347cc1dc7a3Sopenharmony_ci reinterpret_cast<CustomizedBlockMode>(GetProcAddress(astcCustomizedSoHandle_, 2348cc1dc7a3Sopenharmony_ci "CustomizedBlockMode")); 2349cc1dc7a3Sopenharmony_ci if (customizedBlockModeFunc_ == nullptr) 2350cc1dc7a3Sopenharmony_ci { 2351cc1dc7a3Sopenharmony_ci printf("astc customizedBlockModeFunc_ GetProcAddress failed!\n"); 2352cc1dc7a3Sopenharmony_ci if (!FreeLibrary(astcCustomizedSoHandle_)) 2353cc1dc7a3Sopenharmony_ci { 2354cc1dc7a3Sopenharmony_ci printf("astc customizedBlockModeFunc_ FreeLibrary failed!\n"); 2355cc1dc7a3Sopenharmony_ci } 2356cc1dc7a3Sopenharmony_ci return false; 2357cc1dc7a3Sopenharmony_ci } 2358cc1dc7a3Sopenharmony_ci printf("astcenc customized dll load success: %s!\n", g_astcCustomizedSo); 2359cc1dc7a3Sopenharmony_ci#else 2360cc1dc7a3Sopenharmony_ci if (access(g_astcCustomizedSo.c_str(), F_OK) == -1) 2361cc1dc7a3Sopenharmony_ci { 2362cc1dc7a3Sopenharmony_ci printf("astc customized so(%s) is not found!\n", g_astcCustomizedSo.c_str()); 2363cc1dc7a3Sopenharmony_ci return false; 2364cc1dc7a3Sopenharmony_ci } 2365cc1dc7a3Sopenharmony_ci astcCustomizedSoHandle_ = dlopen(g_astcCustomizedSo.c_str(), 1); 2366cc1dc7a3Sopenharmony_ci if (astcCustomizedSoHandle_ == nullptr) 2367cc1dc7a3Sopenharmony_ci { 2368cc1dc7a3Sopenharmony_ci printf("astc libAstcCustomizedEnc dlopen failed!\n"); 2369cc1dc7a3Sopenharmony_ci return false; 2370cc1dc7a3Sopenharmony_ci } 2371cc1dc7a3Sopenharmony_ci isCustomizedBlockModeFunc_ = 2372cc1dc7a3Sopenharmony_ci reinterpret_cast<IsCustomizedBlockMode>(dlsym(astcCustomizedSoHandle_, 2373cc1dc7a3Sopenharmony_ci "IsCustomizedBlockMode")); 2374cc1dc7a3Sopenharmony_ci if (isCustomizedBlockModeFunc_ == nullptr) 2375cc1dc7a3Sopenharmony_ci { 2376cc1dc7a3Sopenharmony_ci printf("astc isCustomizedBlockModeFunc_ dlsym failed!\n"); 2377cc1dc7a3Sopenharmony_ci dlclose(astcCustomizedSoHandle_); 2378cc1dc7a3Sopenharmony_ci astcCustomizedSoHandle_ = nullptr; 2379cc1dc7a3Sopenharmony_ci return false; 2380cc1dc7a3Sopenharmony_ci } 2381cc1dc7a3Sopenharmony_ci customizedMaxPartitionsFunc_ = 2382cc1dc7a3Sopenharmony_ci reinterpret_cast<CustomizedMaxPartitions>(dlsym(astcCustomizedSoHandle_, 2383cc1dc7a3Sopenharmony_ci "CustomizedMaxPartitions")); 2384cc1dc7a3Sopenharmony_ci if (customizedMaxPartitionsFunc_ == nullptr) 2385cc1dc7a3Sopenharmony_ci { 2386cc1dc7a3Sopenharmony_ci printf("astc customizedMaxPartitionsFunc_ dlsym failed!\n"); 2387cc1dc7a3Sopenharmony_ci dlclose(astcCustomizedSoHandle_); 2388cc1dc7a3Sopenharmony_ci astcCustomizedSoHandle_ = nullptr; 2389cc1dc7a3Sopenharmony_ci return false; 2390cc1dc7a3Sopenharmony_ci } 2391cc1dc7a3Sopenharmony_ci customizedBlockModeFunc_ = 2392cc1dc7a3Sopenharmony_ci reinterpret_cast<CustomizedBlockMode>(dlsym(astcCustomizedSoHandle_, 2393cc1dc7a3Sopenharmony_ci "CustomizedBlockMode")); 2394cc1dc7a3Sopenharmony_ci if (customizedBlockModeFunc_ == nullptr) 2395cc1dc7a3Sopenharmony_ci { 2396cc1dc7a3Sopenharmony_ci printf("astc customizedBlockModeFunc_ dlsym failed!\n"); 2397cc1dc7a3Sopenharmony_ci dlclose(astcCustomizedSoHandle_); 2398cc1dc7a3Sopenharmony_ci astcCustomizedSoHandle_ = nullptr; 2399cc1dc7a3Sopenharmony_ci return false; 2400cc1dc7a3Sopenharmony_ci } 2401cc1dc7a3Sopenharmony_ci printf("astcenc customized so dlopen success: %s\n", g_astcCustomizedSo.c_str()); 2402cc1dc7a3Sopenharmony_ci#endif 2403cc1dc7a3Sopenharmony_ci astcCustomizedSoOpened_ = true; 2404cc1dc7a3Sopenharmony_ci } 2405cc1dc7a3Sopenharmony_ci return true; 2406cc1dc7a3Sopenharmony_ci } 2407cc1dc7a3Sopenharmony_ciprivate: 2408cc1dc7a3Sopenharmony_ci bool astcCustomizedSoOpened_; 2409cc1dc7a3Sopenharmony_ci#if defined(_WIN32) && !defined(__CYGWIN__) 2410cc1dc7a3Sopenharmony_ci HINSTANCE astcCustomizedSoHandle_; 2411cc1dc7a3Sopenharmony_ci#else 2412cc1dc7a3Sopenharmony_ci void *astcCustomizedSoHandle_; 2413cc1dc7a3Sopenharmony_ci#endif 2414cc1dc7a3Sopenharmony_ci}; 2415cc1dc7a3Sopenharmony_ciextern AstcCustomizedSoManager g_astcCustomizedSoManager; 2416cc1dc7a3Sopenharmony_ci#endif 2417cc1dc7a3Sopenharmony_ci 2418cc1dc7a3Sopenharmony_ci#endif 2419