Updated astc-encoder.

This commit is contained in:
Бранимир Караџић
2023-04-02 09:23:46 -07:00
parent 7afa241925
commit c3b3c6bf48
18 changed files with 830 additions and 1137 deletions

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2020-2022 Arm Limited
// Copyright 2020-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -43,6 +43,14 @@
* for faster processing. The caller is responsible for creating the worker threads, and
* synchronizing between images.
*
* Extended instruction set support
* ================================
*
* This library supports use of extended instruction sets, such as SSE4.1 and AVX2. These are
* enabled at compile time when building the library. There is no runtime checking in the core
* library that the instruction sets used are actually available. Checking compatibility is the
* responsibility of the calling code.
*
* Threading
* =========
*
@@ -191,8 +199,6 @@ enum astcenc_error {
ASTCENC_ERR_OUT_OF_MEM,
/** @brief The call failed due to the build using fast math. */
ASTCENC_ERR_BAD_CPU_FLOAT,
/** @brief The call failed due to the build using an unsupported ISA. */
ASTCENC_ERR_BAD_CPU_ISA,
/** @brief The call failed due to an out-of-spec parameter. */
ASTCENC_ERR_BAD_PARAM,
/** @brief The call failed due to an out-of-spec block size. */
@@ -306,14 +312,6 @@ enum astcenc_type
*/
static const unsigned int ASTCENC_FLG_MAP_NORMAL = 1 << 0;
/**
* @brief Enable mask map compression.
*
* Input data will be treated a multi-layer mask map, where is is desirable for the color components
* to be treated independently for the purposes of error analysis.
*/
static const unsigned int ASTCENC_FLG_MAP_MASK = 1 << 1;
/**
* @brief Enable alpha weighting.
*
@@ -376,7 +374,6 @@ static const unsigned int ASTCENC_FLG_MAP_RGBM = 1 << 6;
* @brief The bit mask of all valid flags.
*/
static const unsigned int ASTCENC_ALL_FLAGS =
ASTCENC_FLG_MAP_MASK |
ASTCENC_FLG_MAP_NORMAL |
ASTCENC_FLG_MAP_RGBM |
ASTCENC_FLG_USE_ALPHA_WEIGHT |
@@ -481,28 +478,28 @@ struct astcenc_config
/**
* @brief The number of trial candidates per mode search (-candidatelimit).
*
* Valid values are between 1 and TUNE_MAX_TRIAL_CANDIDATES (default 4).
* Valid values are between 1 and TUNE_MAX_TRIAL_CANDIDATES.
*/
unsigned int tune_candidate_limit;
/**
* @brief The number of trial partitionings per search (-2partitioncandidatelimit).
*
* Valid values are between 1 and TUNE_MAX_PARTITIIONING_CANDIDATES.
* Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES.
*/
unsigned int tune_2partitioning_candidate_limit;
/**
* @brief The number of trial partitionings per search (-3partitioncandidatelimit).
*
* Valid values are between 1 and TUNE_MAX_PARTITIIONING_CANDIDATES.
* Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES.
*/
unsigned int tune_3partitioning_candidate_limit;
/**
* @brief The number of trial partitionings per search (-4partitioncandidatelimit).
*
* Valid values are between 1 and TUNE_MAX_PARTITIIONING_CANDIDATES.
* Valid values are between 1 and TUNE_MAX_PARTITIONING_CANDIDATES.
*/
unsigned int tune_4partitioning_candidate_limit;
@@ -529,21 +526,21 @@ struct astcenc_config
*
* This option is further scaled for normal maps, so it skips less often.
*/
float tune_2_partition_early_out_limit_factor;
float tune_2partition_early_out_limit_factor;
/**
* @brief The threshold for skipping 4.1 trials (-3partitionlimitfactor).
*
* This option is further scaled for normal maps, so it skips less often.
*/
float tune_3_partition_early_out_limit_factor;
float tune_3partition_early_out_limit_factor;
/**
* @brief The threshold for skipping two weight planes (-2planelimitcorrelation).
*
* This option is ineffective for normal maps.
*/
float tune_2_plane_early_out_limit_correlation;
float tune_2plane_early_out_limit_correlation;
#if defined(ASTCENC_DIAGNOSTICS)
/**

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2022 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -725,8 +725,7 @@ void compute_error_squared_rgba(
const image_block& blk,
const processed_line4 uncor_plines[BLOCK_MAX_PARTITIONS],
const processed_line4 samec_plines[BLOCK_MAX_PARTITIONS],
float uncor_lengths[BLOCK_MAX_PARTITIONS],
float samec_lengths[BLOCK_MAX_PARTITIONS],
float line_lengths[BLOCK_MAX_PARTITIONS],
float& uncor_error,
float& samec_error
) {
@@ -740,12 +739,6 @@ void compute_error_squared_rgba(
{
const uint8_t *texel_indexes = pi.texels_of_partition[partition];
float uncor_loparam = 1e10f;
float uncor_hiparam = -1e10f;
float samec_loparam = 1e10f;
float samec_hiparam = -1e10f;
processed_line4 l_uncor = uncor_plines[partition];
processed_line4 l_samec = samec_plines[partition];
@@ -773,9 +766,6 @@ void compute_error_squared_rgba(
vfloat uncor_loparamv(1e10f);
vfloat uncor_hiparamv(-1e10f);
vfloat samec_loparamv(1e10f);
vfloat samec_hiparamv(-1e10f);
vfloat ew_r(blk.channel_weight.lane<0>());
vfloat ew_g(blk.channel_weight.lane<1>());
vfloat ew_b(blk.channel_weight.lane<2>());
@@ -825,9 +815,6 @@ void compute_error_squared_rgba(
+ (data_b * l_samec_bs2)
+ (data_a * l_samec_bs3);
samec_loparamv = min(samec_param, samec_loparamv);
samec_hiparamv = max(samec_param, samec_hiparamv);
vfloat samec_dist0 = samec_param * l_samec_bs0 - data_r;
vfloat samec_dist1 = samec_param * l_samec_bs1 - data_g;
vfloat samec_dist2 = samec_param * l_samec_bs2 - data_b;
@@ -843,18 +830,9 @@ void compute_error_squared_rgba(
lane_ids += vint(ASTCENC_SIMD_WIDTH);
}
uncor_loparam = hmin_s(uncor_loparamv);
uncor_hiparam = hmax_s(uncor_hiparamv);
samec_loparam = hmin_s(samec_loparamv);
samec_hiparam = hmax_s(samec_hiparamv);
float uncor_linelen = uncor_hiparam - uncor_loparam;
float samec_linelen = samec_hiparam - samec_loparam;
// Turn very small numbers and NaNs into a small number
uncor_lengths[partition] = astc::max(uncor_linelen, 1e-7f);
samec_lengths[partition] = astc::max(samec_linelen, 1e-7f);
float uncor_linelen = hmax_s(uncor_hiparamv) - hmin_s(uncor_loparamv);
line_lengths[partition] = astc::max(uncor_linelen, 1e-7f);
}
uncor_error = hadd_s(uncor_errorsumv);
@@ -882,19 +860,9 @@ void compute_error_squared_rgb(
unsigned int texel_count = pi.partition_texel_count[partition];
promise(texel_count > 0);
float uncor_loparam = 1e10f;
float uncor_hiparam = -1e10f;
float samec_loparam = 1e10f;
float samec_hiparam = -1e10f;
processed_line3 l_uncor = pl.uncor_pline;
processed_line3 l_samec = pl.samec_pline;
// This implementation is an example vectorization of this function.
// It works for - the codec is a 2-4% faster than not vectorizing - but
// the benefit is limited by the use of gathers and register pressure
// Vectorize some useful scalar inputs
vfloat l_uncor_bs0(l_uncor.bs.lane<0>());
vfloat l_uncor_bs1(l_uncor.bs.lane<1>());
@@ -913,9 +881,6 @@ void compute_error_squared_rgb(
vfloat uncor_loparamv(1e10f);
vfloat uncor_hiparamv(-1e10f);
vfloat samec_loparamv(1e10f);
vfloat samec_hiparamv(-1e10f);
vfloat ew_r(blk.channel_weight.lane<0>());
vfloat ew_g(blk.channel_weight.lane<1>());
vfloat ew_b(blk.channel_weight.lane<2>());
@@ -958,9 +923,6 @@ void compute_error_squared_rgb(
+ (data_g * l_samec_bs1)
+ (data_b * l_samec_bs2);
samec_loparamv = min(samec_param, samec_loparamv);
samec_hiparamv = max(samec_param, samec_hiparamv);
vfloat samec_dist0 = samec_param * l_samec_bs0 - data_r;
vfloat samec_dist1 = samec_param * l_samec_bs1 - data_g;
vfloat samec_dist2 = samec_param * l_samec_bs2 - data_b;
@@ -974,18 +936,9 @@ void compute_error_squared_rgb(
lane_ids += vint(ASTCENC_SIMD_WIDTH);
}
uncor_loparam = hmin_s(uncor_loparamv);
uncor_hiparam = hmax_s(uncor_hiparamv);
samec_loparam = hmin_s(samec_loparamv);
samec_hiparam = hmax_s(samec_hiparamv);
float uncor_linelen = uncor_hiparam - uncor_loparam;
float samec_linelen = samec_hiparam - samec_loparam;
// Turn very small numbers and NaNs into a small number
pl.uncor_line_len = astc::max(uncor_linelen, 1e-7f);
pl.samec_line_len = astc::max(samec_linelen, 1e-7f);
float uncor_linelen = hmax_s(uncor_hiparamv) - hmin_s(uncor_loparamv);
pl.line_length = astc::max(uncor_linelen, 1e-7f);
}
uncor_error = hadd_s(uncor_errorsumv);

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2022 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -330,17 +330,17 @@ static void init_decimation_info_2d(
for (unsigned int j = 0; j < wb.weight_count_of_texel[i]; j++)
{
di.texel_weights_int_4t[j][i] = wb.weights_of_texel[i][j];
di.texel_weights_float_4t[j][i] = static_cast<float>(wb.weights_of_texel[i][j]) * (1.0f / WEIGHTS_TEXEL_SUM);
di.texel_weights_4t[j][i] = wb.grid_weights_of_texel[i][j];
di.texel_weight_contribs_int_tr[j][i] = wb.weights_of_texel[i][j];
di.texel_weight_contribs_float_tr[j][i] = static_cast<float>(wb.weights_of_texel[i][j]) * (1.0f / WEIGHTS_TEXEL_SUM);
di.texel_weights_tr[j][i] = wb.grid_weights_of_texel[i][j];
}
// Init all 4 entries so we can rely on zeros for vectorization
for (unsigned int j = wb.weight_count_of_texel[i]; j < 4; j++)
{
di.texel_weights_int_4t[j][i] = 0;
di.texel_weights_float_4t[j][i] = 0.0f;
di.texel_weights_4t[j][i] = 0;
di.texel_weight_contribs_int_tr[j][i] = 0;
di.texel_weight_contribs_float_tr[j][i] = 0.0f;
di.texel_weights_tr[j][i] = 0;
}
}
@@ -356,43 +356,30 @@ static void init_decimation_info_2d(
uint8_t texel = wb.texels_of_weight[i][j];
// Create transposed versions of these for better vectorization
di.weight_texel[j][i] = texel;
di.weights_flt[j][i] = static_cast<float>(wb.texel_weights_of_weight[i][j]);
di.weight_texels_tr[j][i] = texel;
di.weights_texel_contribs_tr[j][i] = static_cast<float>(wb.texel_weights_of_weight[i][j]);
// perform a layer of array unrolling. An aspect of this unrolling is that
// one of the texel-weight indexes is an identity-mapped index; we will use this
// fact to reorder the indexes so that the first one is the identity index.
int swap_idx = -1;
// Store the per-texel contribution of this weight for each texel it contributes to
di.texel_contrib_for_weight[j][i] = 0.0f;
for (unsigned int k = 0; k < 4; k++)
{
uint8_t dttw = di.texel_weights_4t[k][texel];
float dttwf = di.texel_weights_float_4t[k][texel];
uint8_t dttw = di.texel_weights_tr[k][texel];
float dttwf = di.texel_weight_contribs_float_tr[k][texel];
if (dttw == i && dttwf != 0.0f)
{
swap_idx = k;
di.texel_contrib_for_weight[j][i] = di.texel_weight_contribs_float_tr[k][texel];
break;
}
di.texel_weights_texel[i][j][k] = dttw;
di.texel_weights_float_texel[i][j][k] = dttwf;
}
if (swap_idx != 0)
{
uint8_t vi = di.texel_weights_texel[i][j][0];
float vf = di.texel_weights_float_texel[i][j][0];
di.texel_weights_texel[i][j][0] = di.texel_weights_texel[i][j][swap_idx];
di.texel_weights_float_texel[i][j][0] = di.texel_weights_float_texel[i][j][swap_idx];
di.texel_weights_texel[i][j][swap_idx] = vi;
di.texel_weights_float_texel[i][j][swap_idx] = vf;
}
}
// Initialize array tail so we can over-fetch with SIMD later to avoid loop tails
// Match last texel in active lane in SIMD group, for better gathers
uint8_t last_texel = di.weight_texel[texel_count_wt - 1][i];
uint8_t last_texel = di.weight_texels_tr[texel_count_wt - 1][i];
for (unsigned int j = texel_count_wt; j < max_texel_count_of_weight; j++)
{
di.weight_texel[j][i] = last_texel;
di.weights_flt[j][i] = 0.0f;
di.weight_texels_tr[j][i] = last_texel;
di.weights_texel_contribs_tr[j][i] = 0.0f;
}
}
@@ -404,16 +391,16 @@ static void init_decimation_info_2d(
for (unsigned int j = 0; j < 4; j++)
{
di.texel_weights_float_4t[j][i] = 0;
di.texel_weights_4t[j][i] = 0;
di.texel_weights_int_4t[j][i] = 0;
di.texel_weight_contribs_float_tr[j][i] = 0;
di.texel_weights_tr[j][i] = 0;
di.texel_weight_contribs_int_tr[j][i] = 0;
}
}
// Initialize array tail so we can over-fetch with SIMD later to avoid loop tails
// Match last texel in active lane in SIMD group, for better gathers
unsigned int last_texel_count_wt = wb.texel_count_of_weight[weights_per_block - 1];
uint8_t last_texel = di.weight_texel[last_texel_count_wt - 1][weights_per_block - 1];
uint8_t last_texel = di.weight_texels_tr[last_texel_count_wt - 1][weights_per_block - 1];
unsigned int weights_per_block_simd = round_up_to_simd_multiple_vla(weights_per_block);
for (unsigned int i = weights_per_block; i < weights_per_block_simd; i++)
@@ -422,8 +409,8 @@ static void init_decimation_info_2d(
for (unsigned int j = 0; j < max_texel_count_of_weight; j++)
{
di.weight_texel[j][i] = last_texel;
di.weights_flt[j][i] = 0.0f;
di.weight_texels_tr[j][i] = last_texel;
di.weights_texel_contribs_tr[j][i] = 0.0f;
}
}
@@ -600,16 +587,16 @@ static void init_decimation_info_3d(
// Init all 4 entries so we can rely on zeros for vectorization
for (unsigned int j = 0; j < 4; j++)
{
di.texel_weights_int_4t[j][i] = 0;
di.texel_weights_float_4t[j][i] = 0.0f;
di.texel_weights_4t[j][i] = 0;
di.texel_weight_contribs_int_tr[j][i] = 0;
di.texel_weight_contribs_float_tr[j][i] = 0.0f;
di.texel_weights_tr[j][i] = 0;
}
for (unsigned int j = 0; j < wb.weight_count_of_texel[i]; j++)
{
di.texel_weights_int_4t[j][i] = wb.weights_of_texel[i][j];
di.texel_weights_float_4t[j][i] = static_cast<float>(wb.weights_of_texel[i][j]) * (1.0f / WEIGHTS_TEXEL_SUM);
di.texel_weights_4t[j][i] = wb.grid_weights_of_texel[i][j];
di.texel_weight_contribs_int_tr[j][i] = wb.weights_of_texel[i][j];
di.texel_weight_contribs_float_tr[j][i] = static_cast<float>(wb.weights_of_texel[i][j]) * (1.0f / WEIGHTS_TEXEL_SUM);
di.texel_weights_tr[j][i] = wb.grid_weights_of_texel[i][j];
}
}
@@ -625,43 +612,30 @@ static void init_decimation_info_3d(
unsigned int texel = wb.texels_of_weight[i][j];
// Create transposed versions of these for better vectorization
di.weight_texel[j][i] = static_cast<uint8_t>(texel);
di.weights_flt[j][i] = static_cast<float>(wb.texel_weights_of_weight[i][j]);
di.weight_texels_tr[j][i] = static_cast<uint8_t>(texel);
di.weights_texel_contribs_tr[j][i] = static_cast<float>(wb.texel_weights_of_weight[i][j]);
// perform a layer of array unrolling. An aspect of this unrolling is that
// one of the texel-weight indexes is an identity-mapped index; we will use this
// fact to reorder the indexes so that the first one is the identity index.
int swap_idx = -1;
// Store the per-texel contribution of this weight for each texel it contributes to
di.texel_contrib_for_weight[j][i] = 0.0f;
for (unsigned int k = 0; k < 4; k++)
{
uint8_t dttw = di.texel_weights_4t[k][texel];
float dttwf = di.texel_weights_float_4t[k][texel];
uint8_t dttw = di.texel_weights_tr[k][texel];
float dttwf = di.texel_weight_contribs_float_tr[k][texel];
if (dttw == i && dttwf != 0.0f)
{
swap_idx = k;
di.texel_contrib_for_weight[j][i] = di.texel_weight_contribs_float_tr[k][texel];
break;
}
di.texel_weights_texel[i][j][k] = dttw;
di.texel_weights_float_texel[i][j][k] = dttwf;
}
if (swap_idx != 0)
{
uint8_t vi = di.texel_weights_texel[i][j][0];
float vf = di.texel_weights_float_texel[i][j][0];
di.texel_weights_texel[i][j][0] = di.texel_weights_texel[i][j][swap_idx];
di.texel_weights_float_texel[i][j][0] = di.texel_weights_float_texel[i][j][swap_idx];
di.texel_weights_texel[i][j][swap_idx] = vi;
di.texel_weights_float_texel[i][j][swap_idx] = vf;
}
}
// Initialize array tail so we can over-fetch with SIMD later to avoid loop tails
// Match last texel in active lane in SIMD group, for better gathers
uint8_t last_texel = di.weight_texel[texel_count_wt - 1][i];
uint8_t last_texel = di.weight_texels_tr[texel_count_wt - 1][i];
for (unsigned int j = texel_count_wt; j < max_texel_count_of_weight; j++)
{
di.weight_texel[j][i] = last_texel;
di.weights_flt[j][i] = 0.0f;
di.weight_texels_tr[j][i] = last_texel;
di.weights_texel_contribs_tr[j][i] = 0.0f;
}
}
@@ -673,16 +647,16 @@ static void init_decimation_info_3d(
for (unsigned int j = 0; j < 4; j++)
{
di.texel_weights_float_4t[j][i] = 0;
di.texel_weights_4t[j][i] = 0;
di.texel_weights_int_4t[j][i] = 0;
di.texel_weight_contribs_float_tr[j][i] = 0;
di.texel_weights_tr[j][i] = 0;
di.texel_weight_contribs_int_tr[j][i] = 0;
}
}
// Initialize array tail so we can over-fetch with SIMD later to avoid loop tails
// Match last texel in active lane in SIMD group, for better gathers
int last_texel_count_wt = wb.texel_count_of_weight[weights_per_block - 1];
uint8_t last_texel = di.weight_texel[last_texel_count_wt - 1][weights_per_block - 1];
uint8_t last_texel = di.weight_texels_tr[last_texel_count_wt - 1][weights_per_block - 1];
unsigned int weights_per_block_simd = round_up_to_simd_multiple_vla(weights_per_block);
for (unsigned int i = weights_per_block; i < weights_per_block_simd; i++)
@@ -691,8 +665,8 @@ static void init_decimation_info_3d(
for (int j = 0; j < max_texel_count_of_weight; j++)
{
di.weight_texel[j][i] = last_texel;
di.weights_flt[j][i] = 0.0f;
di.weight_texels_tr[j][i] = last_texel;
di.weights_texel_contribs_tr[j][i] = 0.0f;
}
}
@@ -802,8 +776,8 @@ static void construct_dt_entry_2d(
assert(maxprec_1plane >= 0 || maxprec_2planes >= 0);
bsd.decimation_modes[index].maxprec_1plane = static_cast<int8_t>(maxprec_1plane);
bsd.decimation_modes[index].maxprec_2planes = static_cast<int8_t>(maxprec_2planes);
bsd.decimation_modes[index].refprec_1_plane = 0;
bsd.decimation_modes[index].refprec_2_planes = 0;
bsd.decimation_modes[index].refprec_1plane = 0;
bsd.decimation_modes[index].refprec_2planes = 0;
}
/**
@@ -960,11 +934,11 @@ static void construct_block_size_descriptor_2d(
if (is_dual_plane)
{
dm.set_ref_2_plane(bm.get_weight_quant_mode());
dm.set_ref_2plane(bm.get_weight_quant_mode());
}
else
{
dm.set_ref_1_plane(bm.get_weight_quant_mode());
dm.set_ref_1plane(bm.get_weight_quant_mode());
}
bsd.block_mode_packed_index[i] = static_cast<uint16_t>(packed_bm_idx);
@@ -995,8 +969,8 @@ static void construct_block_size_descriptor_2d(
{
bsd.decimation_modes[i].maxprec_1plane = -1;
bsd.decimation_modes[i].maxprec_2planes = -1;
bsd.decimation_modes[i].refprec_1_plane = 0;
bsd.decimation_modes[i].refprec_2_planes = 0;
bsd.decimation_modes[i].refprec_1plane = 0;
bsd.decimation_modes[i].refprec_2planes = 0;
}
// Determine the texels to use for kmeans clustering.
@@ -1081,8 +1055,8 @@ static void construct_block_size_descriptor_3d(
bsd.decimation_modes[decimation_mode_count].maxprec_1plane = static_cast<int8_t>(maxprec_1plane);
bsd.decimation_modes[decimation_mode_count].maxprec_2planes = static_cast<int8_t>(maxprec_2planes);
bsd.decimation_modes[decimation_mode_count].refprec_1_plane = maxprec_1plane == -1 ? 0 : 0xFFFF;
bsd.decimation_modes[decimation_mode_count].refprec_2_planes = maxprec_2planes == -1 ? 0 : 0xFFFF;
bsd.decimation_modes[decimation_mode_count].refprec_1plane = maxprec_1plane == -1 ? 0 : 0xFFFF;
bsd.decimation_modes[decimation_mode_count].refprec_2planes = maxprec_2planes == -1 ? 0 : 0xFFFF;
decimation_mode_count++;
}
}
@@ -1093,8 +1067,8 @@ static void construct_block_size_descriptor_3d(
{
bsd.decimation_modes[i].maxprec_1plane = -1;
bsd.decimation_modes[i].maxprec_2planes = -1;
bsd.decimation_modes[i].refprec_1_plane = 0;
bsd.decimation_modes[i].refprec_2_planes = 0;
bsd.decimation_modes[i].refprec_1plane = 0;
bsd.decimation_modes[i].refprec_2planes = 0;
}
bsd.decimation_mode_count_always = 0; // Skipped for 3D modes

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2021 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -44,17 +44,43 @@
* @brief Determine the quantized value given a quantization level.
*
* @param quant_level The quantization level to use.
* @param value The value to convert. This may be outside of the 0-255 range and will be
* clamped before the value is looked up.
* @param value The value to convert. This must be in the 0-255 range.
*
* @return The encoded quantized value. These are not necessarily in order; the compressor
* scrambles the values slightly to make hardware implementation easier.
* @return The unpacked quantized value, returned in 0-255 range.
*/
static inline uint8_t quant_color(
quant_method quant_level,
int value
) {
return color_unquant_to_uquant_tables[quant_level - QUANT_6][value];
int index = value * 2 + 1;
return color_unquant_to_uquant_tables[quant_level - QUANT_6][index];
}
/**
* @brief Determine the quantized value given a quantization level and residual.
*
* @param quant_level The quantization level to use.
* @param value The value to convert. This must be in the 0-255 range.
* @param valuef The original value before rounding, used to compute a residual.
*
* @return The unpacked quantized value, returned in 0-255 range.
*/
static inline uint8_t quant_color(
quant_method quant_level,
int value,
float valuef
) {
int index = value * 2;
// Compute the residual to determine if we should round down or up ties.
// Test should be residual >= 0, but empirical testing shows small bias helps.
float residual = valuef - static_cast<float>(value);
if (residual >= -0.1f)
{
index++;
}
return color_unquant_to_uquant_tables[quant_level - QUANT_6][index];
}
/**
@@ -86,16 +112,16 @@ static void quantize_rgb(
float b1 = astc::clamp255f(color1.lane<2>() * scale);
int ri0, gi0, bi0, ri1, gi1, bi1;
float rgb0_addon = 0.5f;
float rgb1_addon = 0.5f;
float rgb0_addon = 0.0f;
float rgb1_addon = 0.0f;
do
{
ri0 = quant_color(quant_level, astc::max(astc::flt2int_rd(r0 + rgb0_addon), 0));
gi0 = quant_color(quant_level, astc::max(astc::flt2int_rd(g0 + rgb0_addon), 0));
bi0 = quant_color(quant_level, astc::max(astc::flt2int_rd(b0 + rgb0_addon), 0));
ri1 = quant_color(quant_level, astc::min(astc::flt2int_rd(r1 + rgb1_addon), 255));
gi1 = quant_color(quant_level, astc::min(astc::flt2int_rd(g1 + rgb1_addon), 255));
bi1 = quant_color(quant_level, astc::min(astc::flt2int_rd(b1 + rgb1_addon), 255));
ri0 = quant_color(quant_level, astc::max(astc::flt2int_rtn(r0 + rgb0_addon), 0), r0 + rgb0_addon);
gi0 = quant_color(quant_level, astc::max(astc::flt2int_rtn(g0 + rgb0_addon), 0), g0 + rgb0_addon);
bi0 = quant_color(quant_level, astc::max(astc::flt2int_rtn(b0 + rgb0_addon), 0), b0 + rgb0_addon);
ri1 = quant_color(quant_level, astc::min(astc::flt2int_rtn(r1 + rgb1_addon), 255), r1 + rgb1_addon);
gi1 = quant_color(quant_level, astc::min(astc::flt2int_rtn(g1 + rgb1_addon), 255), g1 + rgb1_addon);
bi1 = quant_color(quant_level, astc::min(astc::flt2int_rtn(b1 + rgb1_addon), 255), b1 + rgb1_addon);
rgb0_addon -= 0.2f;
rgb1_addon += 0.2f;
@@ -133,8 +159,8 @@ static void quantize_rgba(
float a0 = astc::clamp255f(color0.lane<3>() * scale);
float a1 = astc::clamp255f(color1.lane<3>() * scale);
output[6] = quant_color(quant_level, astc::flt2int_rtn(a0));
output[7] = quant_color(quant_level, astc::flt2int_rtn(a1));
output[6] = quant_color(quant_level, astc::flt2int_rtn(a0), a0);
output[7] = quant_color(quant_level, astc::flt2int_rtn(a1), a1);
quantize_rgb(color0, color1, output, quant_level);
}
@@ -180,13 +206,13 @@ static bool try_quantize_rgb_blue_contract(
}
// Quantize the inverse-blue-contracted color
int ri0 = quant_color(quant_level, astc::flt2int_rtn(r0));
int gi0 = quant_color(quant_level, astc::flt2int_rtn(g0));
int bi0 = quant_color(quant_level, astc::flt2int_rtn(b0));
int ri0 = quant_color(quant_level, astc::flt2int_rtn(r0), r0);
int gi0 = quant_color(quant_level, astc::flt2int_rtn(g0), g0);
int bi0 = quant_color(quant_level, astc::flt2int_rtn(b0), b0);
int ri1 = quant_color(quant_level, astc::flt2int_rtn(r1));
int gi1 = quant_color(quant_level, astc::flt2int_rtn(g1));
int bi1 = quant_color(quant_level, astc::flt2int_rtn(b1));
int ri1 = quant_color(quant_level, astc::flt2int_rtn(r1), r1);
int gi1 = quant_color(quant_level, astc::flt2int_rtn(g1), g1);
int bi1 = quant_color(quant_level, astc::flt2int_rtn(b1), b1);
// If color #1 is not larger than color #0 then blue-contraction cannot be used. Note that
// blue-contraction and quantization change this order, which is why we must test afterwards.
@@ -217,7 +243,7 @@ static bool try_quantize_rgb_blue_contract(
*
* @return Returns @c false on failure, @c true on success.
*/
static int try_quantize_rgba_blue_contract(
static bool try_quantize_rgba_blue_contract(
vfloat4 color0,
vfloat4 color1,
uint8_t output[8],
@@ -228,8 +254,8 @@ static int try_quantize_rgba_blue_contract(
float a0 = astc::clamp255f(color0.lane<3>() * scale);
float a1 = astc::clamp255f(color1.lane<3>() * scale);
output[6] = quant_color(quant_level, astc::flt2int_rtn(a1));
output[7] = quant_color(quant_level, astc::flt2int_rtn(a0));
output[6] = quant_color(quant_level, astc::flt2int_rtn(a1), a1);
output[7] = quant_color(quant_level, astc::flt2int_rtn(a0), a0);
return try_quantize_rgb_blue_contract(color0, color1, output, quant_level);
}
@@ -728,9 +754,9 @@ static void quantize_rgbs(
float g = astc::clamp255f(color.lane<1>() * scale);
float b = astc::clamp255f(color.lane<2>() * scale);
int ri = quant_color(quant_level, astc::flt2int_rtn(r));
int gi = quant_color(quant_level, astc::flt2int_rtn(g));
int bi = quant_color(quant_level, astc::flt2int_rtn(b));
int ri = quant_color(quant_level, astc::flt2int_rtn(r), r);
int gi = quant_color(quant_level, astc::flt2int_rtn(g), g);
int bi = quant_color(quant_level, astc::flt2int_rtn(b), b);
float oldcolorsum = hadd_rgb_s(color) * scale;
float newcolorsum = static_cast<float>(ri + gi + bi);
@@ -764,8 +790,8 @@ static void quantize_rgbs_alpha(
float a0 = astc::clamp255f(color0.lane<3>() * scale);
float a1 = astc::clamp255f(color1.lane<3>() * scale);
output[4] = quant_color(quant_level, astc::flt2int_rtn(a0));
output[5] = quant_color(quant_level, astc::flt2int_rtn(a1));
output[4] = quant_color(quant_level, astc::flt2int_rtn(a0), a0);
output[5] = quant_color(quant_level, astc::flt2int_rtn(a1), a1);
quantize_rgbs(color, output, quant_level);
}
@@ -799,8 +825,8 @@ static void quantize_luminance(
lum1 = avg;
}
output[0] = quant_color(quant_level, astc::flt2int_rtn(lum0));
output[1] = quant_color(quant_level, astc::flt2int_rtn(lum1));
output[0] = quant_color(quant_level, astc::flt2int_rtn(lum0), lum0);
output[1] = quant_color(quant_level, astc::flt2int_rtn(lum1), lum1);
}
/**
@@ -828,48 +854,10 @@ static void quantize_luminance_alpha(
float a0 = astc::clamp255f(color0.lane<3>());
float a1 = astc::clamp255f(color1.lane<3>());
// If endpoints are close then pull apart slightly; this gives > 8 bit normal map precision.
if (quant_level > 18)
{
if (fabsf(lum0 - lum1) < 3.0f)
{
if (lum0 < lum1)
{
lum0 -= 0.5f;
lum1 += 0.5f;
}
else
{
lum0 += 0.5f;
lum1 -= 0.5f;
}
lum0 = astc::clamp255f(lum0);
lum1 = astc::clamp255f(lum1);
}
if (fabsf(a0 - a1) < 3.0f)
{
if (a0 < a1)
{
a0 -= 0.5f;
a1 += 0.5f;
}
else
{
a0 += 0.5f;
a1 -= 0.5f;
}
a0 = astc::clamp255f(a0);
a1 = astc::clamp255f(a1);
}
}
output[0] = quant_color(quant_level, astc::flt2int_rtn(lum0));
output[1] = quant_color(quant_level, astc::flt2int_rtn(lum1));
output[2] = quant_color(quant_level, astc::flt2int_rtn(a0));
output[3] = quant_color(quant_level, astc::flt2int_rtn(a1));
output[0] = quant_color(quant_level, astc::flt2int_rtn(lum0), lum0);
output[1] = quant_color(quant_level, astc::flt2int_rtn(lum1), lum1);
output[2] = quant_color(quant_level, astc::flt2int_rtn(a0), a0);
output[3] = quant_color(quant_level, astc::flt2int_rtn(a1), a1);
}
/**
@@ -1661,8 +1649,8 @@ static void quantize_hdr_rgb_ldr_alpha(
float a0 = astc::clamp255f(color0.lane<3>() * scale);
float a1 = astc::clamp255f(color1.lane<3>() * scale);
output[6] = quant_color(quant_level, astc::flt2int_rtn(a0));
output[7] = quant_color(quant_level, astc::flt2int_rtn(a1));
output[6] = quant_color(quant_level, astc::flt2int_rtn(a0), a0);
output[7] = quant_color(quant_level, astc::flt2int_rtn(a1), a1);
quantize_hdr_rgb(color0, color1, output, quant_level);
}

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2022 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -277,17 +277,14 @@ static bool realign_weights_decimated(
promise(texels_to_evaluate > 0);
for (unsigned int te_idx = 0; te_idx < texels_to_evaluate; te_idx++)
{
unsigned int texel = di.weight_texel[te_idx][we_idx];
unsigned int texel = di.weight_texels_tr[te_idx][we_idx];
const uint8_t *texel_weights = di.texel_weights_texel[we_idx][te_idx];
const float *texel_weights_float = di.texel_weights_float_texel[we_idx][te_idx];
float tw_base = di.texel_contrib_for_weight[te_idx][we_idx];
float tw_base = texel_weights_float[0];
float weight_base = (uqw_base * tw_base
+ uq_weightsf[texel_weights[1]] * texel_weights_float[1])
+ (uq_weightsf[texel_weights[2]] * texel_weights_float[2]
+ uq_weightsf[texel_weights[3]] * texel_weights_float[3]);
float weight_base = (uq_weightsf[di.texel_weights_tr[0][texel]] * di.texel_weight_contribs_float_tr[0][texel]
+ uq_weightsf[di.texel_weights_tr[1][texel]] * di.texel_weight_contribs_float_tr[1][texel])
+ (uq_weightsf[di.texel_weights_tr[2][texel]] * di.texel_weight_contribs_float_tr[2][texel]
+ uq_weightsf[di.texel_weights_tr[3][texel]] * di.texel_weight_contribs_float_tr[3][texel]);
// Ideally this is integer rounded, but IQ gain it isn't worth the overhead
// float weight = astc::flt_rd(weight_base + 0.5f);
@@ -394,7 +391,7 @@ static float compress_symbolic_block_for_partition_1plane(
for (unsigned int i = 0; i < max_decimation_modes; i++)
{
const auto& dm = bsd.get_decimation_mode(i);
if (!dm.is_ref_1_plane(static_cast<quant_method>(max_weight_quant)))
if (!dm.is_ref_1plane(static_cast<quant_method>(max_weight_quant)))
{
continue;
}
@@ -564,7 +561,7 @@ static float compress_symbolic_block_for_partition_1plane(
workscb.color_formats_matched = 0;
if (partition_count >= 2 && all_same)
{
uint8_t colorvals[BLOCK_MAX_PARTITIONS][12];
uint8_t colorvals[BLOCK_MAX_PARTITIONS][8];
uint8_t color_formats_mod[BLOCK_MAX_PARTITIONS] { 0 };
bool all_same_mod = true;
for (unsigned int j = 0; j < partition_count; j++)
@@ -622,12 +619,12 @@ static float compress_symbolic_block_for_partition_1plane(
trace_add_data("error_prerealign", errorval);
best_errorval_in_mode = astc::min(errorval, best_errorval_in_mode);
// Average refinement improvement is 3.5% per iteration (allow 5%), but the first
// iteration can help more so we give it a extra 10% leeway. Use this knowledge to
// Average refinement improvement is 3.5% per iteration (allow 4.5%), but the first
// iteration can help more so we give it a extra 8% leeway. Use this knowledge to
// drive a heuristic to skip blocks that are unlikely to catch up with the best
// block we have already.
unsigned int iters_remaining = config.tune_refinement_limit - l;
float threshold = (0.05f * static_cast<float>(iters_remaining)) + 1.1f;
float threshold = (0.045f * static_cast<float>(iters_remaining)) + 1.08f;
if (errorval > (threshold * best_errorval_in_scb))
{
break;
@@ -672,10 +669,10 @@ static float compress_symbolic_block_for_partition_1plane(
best_errorval_in_mode = astc::min(errorval, best_errorval_in_mode);
// Average refinement improvement is 3.5% per iteration, so skip blocks that are
// unlikely to catch up with the best block we have already. Assume a 5% per step to
// unlikely to catch up with the best block we have already. Assume a 4.5% per step to
// give benefit of the doubt ...
unsigned int iters_remaining = config.tune_refinement_limit - 1 - l;
float threshold = (0.05f * static_cast<float>(iters_remaining)) + 1.0f;
float threshold = (0.045f * static_cast<float>(iters_remaining)) + 1.0f;
if (errorval > (threshold * best_errorval_in_scb))
{
break;
@@ -746,7 +743,7 @@ static float compress_symbolic_block_for_partition_2planes(
for (unsigned int i = 0; i < bsd.decimation_mode_count_selected; i++)
{
const auto& dm = bsd.get_decimation_mode(i);
if (!dm.is_ref_2_plane(static_cast<quant_method>(max_weight_quant)))
if (!dm.is_ref_2plane(static_cast<quant_method>(max_weight_quant)))
{
continue;
}
@@ -956,12 +953,12 @@ static float compress_symbolic_block_for_partition_2planes(
trace_add_data("error_prerealign", errorval);
best_errorval_in_mode = astc::min(errorval, best_errorval_in_mode);
// Average refinement improvement is 3.5% per iteration (allow 5%), but the first
// iteration can help more so we give it a extra 10% leeway. Use this knowledge to
// Average refinement improvement is 3.5% per iteration (allow 4.5%), but the first
// iteration can help more so we give it a extra 8% leeway. Use this knowledge to
// drive a heuristic to skip blocks that are unlikely to catch up with the best
// block we have already.
unsigned int iters_remaining = config.tune_refinement_limit - l;
float threshold = (0.05f * static_cast<float>(iters_remaining)) + 1.1f;
float threshold = (0.045f * static_cast<float>(iters_remaining)) + 1.08f;
if (errorval > (threshold * best_errorval_in_scb))
{
break;
@@ -1007,10 +1004,10 @@ static float compress_symbolic_block_for_partition_2planes(
best_errorval_in_mode = astc::min(errorval, best_errorval_in_mode);
// Average refinement improvement is 3.5% per iteration, so skip blocks that are
// unlikely to catch up with the best block we have already. Assume a 5% per step to
// unlikely to catch up with the best block we have already. Assume a 4.5% per step to
// give benefit of the doubt ...
unsigned int iters_remaining = config.tune_refinement_limit - 1 - l;
float threshold = (0.05f * static_cast<float>(iters_remaining)) + 1.0f;
float threshold = (0.045f * static_cast<float>(iters_remaining)) + 1.0f;
if (errorval > (threshold * best_errorval_in_scb))
{
break;
@@ -1266,8 +1263,8 @@ void compress_block(
float exit_thresholds_for_pcount[BLOCK_MAX_PARTITIONS] {
0.0f,
ctx.config.tune_2_partition_early_out_limit_factor,
ctx.config.tune_3_partition_early_out_limit_factor,
ctx.config.tune_2partition_early_out_limit_factor,
ctx.config.tune_3partition_early_out_limit_factor,
0.0f
};
@@ -1321,7 +1318,7 @@ void compress_block(
lowest_correl = prepare_block_statistics(bsd.texel_count, blk);
#endif
block_skip_two_plane = lowest_correl > ctx.config.tune_2_plane_early_out_limit_correlation;
block_skip_two_plane = lowest_correl > ctx.config.tune_2plane_early_out_limit_correlation;
// Test the four possible 1-partition, 2-planes modes. Do this in reverse, as
// alpha is the most likely to be non-correlated if it is present in the data.
@@ -1334,7 +1331,7 @@ void compress_block(
if (block_skip_two_plane)
{
trace_add_data("skip", "tune_2_plane_early_out_limit_correlation");
trace_add_data("skip", "tune_2plane_early_out_limit_correlation");
continue;
}
@@ -1356,7 +1353,7 @@ void compress_block(
// If attempting two planes is much worse than the best one plane result
// then further two plane searches are unlikely to help so move on ...
if (errorval > (best_errorvals_for_pcount[0] * 2.0f))
if (errorval > (best_errorvals_for_pcount[0] * 1.85f))
{
break;
}
@@ -1371,7 +1368,7 @@ void compress_block(
// Find best blocks for 2, 3 and 4 partitions
for (int partition_count = 2; partition_count <= max_partitions; partition_count++)
{
unsigned int partition_indices[TUNE_MAX_PARTITIIONING_CANDIDATES];
unsigned int partition_indices[TUNE_MAX_PARTITIONING_CANDIDATES];
unsigned int requested_indices = requested_partition_indices[partition_count - 2];
@@ -1402,10 +1399,9 @@ void compress_block(
// If using N partitions doesn't improve much over using N-1 partitions then skip trying
// N+1. Error can dramatically improve if the data is correlated or non-correlated and
// aligns with a partitioning that suits that encoding, so for this inner loop check add
// a large error scale because the "other" trial could be a lot better. In total the
// error must be at least 2x worse than the best existing error to early-out.
// a large error scale because the "other" trial could be a lot better.
float best_error = best_errorvals_for_pcount[partition_count - 1];
float best_error_scale = exit_thresholds_for_pcount[partition_count - 1] * 2.0f;
float best_error_scale = exit_thresholds_for_pcount[partition_count - 1] * 1.85f;
if (best_error > (best_error_in_prev * best_error_scale))
{
trace_add_data("skip", "tune_partition_early_out_limit_factor");

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2022 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -121,8 +121,8 @@ void unpack_weights(
promise(max_weight_count > 0);
for (int j = 0; j < max_weight_count; j++)
{
vint texel_weights(di.texel_weights_4t[j] + i);
vint texel_weights_int(di.texel_weights_int_4t[j] + i);
vint texel_weights(di.texel_weights_tr[j] + i);
vint texel_weights_int(di.texel_weight_contribs_int_tr[j] + i);
summed_value += vtable_8bt_32bi(tab0p, tab1p, tab2p, tab3p, texel_weights) * texel_weights_int;
}
@@ -156,8 +156,8 @@ void unpack_weights(
promise(max_weight_count > 0);
for (int j = 0; j < max_weight_count; j++)
{
vint texel_weights(di.texel_weights_4t[j] + i);
vint texel_weights_int(di.texel_weights_int_4t[j] + i);
vint texel_weights(di.texel_weights_tr[j] + i);
vint texel_weights_int(di.texel_weight_contribs_int_tr[j] + i);
sum_plane1 += vtable_8bt_32bi(tab0_plane1p, tab1_plane1p, texel_weights) * texel_weights_int;
sum_plane2 += vtable_8bt_32bi(tab0_plane2p, tab1_plane2p, texel_weights) * texel_weights_int;

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2021-2022 Arm Limited
// Copyright 2021-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -24,6 +24,8 @@
#include <cassert>
#include <cstdarg>
#include <cstdio>
#include <cmath>
#include <limits>
#include <string>
#include "astcenc_diagnostic_trace.h"
@@ -203,6 +205,19 @@ void trace_add_data(
const char* key,
float value
) {
// Turn infinities into parseable values
if (std::isinf(value))
{
if (value > 0.0f)
{
value = std::numeric_limits<float>::max();
}
else
{
value = -std::numeric_limits<float>::max();
}
}
char buffer[256];
sprintf(buffer, "%.20g", (double)value);
TraceNode* node = g_TraceLog->get_current_leaf();

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2022 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -52,9 +52,9 @@ struct astcenc_preset_config
float tune_db_limit_a_base;
float tune_db_limit_b_base;
float tune_mse_overshoot;
float tune_2_partition_early_out_limit_factor;
float tune_3_partition_early_out_limit_factor;
float tune_2_plane_early_out_limit_correlation;
float tune_2partition_early_out_limit_factor;
float tune_3partition_early_out_limit_factor;
float tune_2plane_early_out_limit_correlation;
};
/**
@@ -157,48 +157,6 @@ static astcenc_error validate_cpu_float()
return ASTCENC_SUCCESS;
}
/**
* @brief Validate CPU ISA support meets the requirements of this build of the library.
*
* Each library build is statically compiled for a particular set of CPU ISA features, such as the
* SIMD support or other ISA extensions such as POPCNT. This function checks that the host CPU
* actually supports everything this build needs.
*
* @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure.
*/
static astcenc_error validate_cpu_isa()
{
#if ASTCENC_SSE >= 41
if (!cpu_supports_sse41())
{
return ASTCENC_ERR_BAD_CPU_ISA;
}
#endif
#if ASTCENC_POPCNT >= 1
if (!cpu_supports_popcnt())
{
return ASTCENC_ERR_BAD_CPU_ISA;
}
#endif
#if ASTCENC_F16C >= 1
if (!cpu_supports_f16c())
{
return ASTCENC_ERR_BAD_CPU_ISA;
}
#endif
#if ASTCENC_AVX >= 2
if (!cpu_supports_avx2())
{
return ASTCENC_ERR_BAD_CPU_ISA;
}
#endif
return ASTCENC_SUCCESS;
}
/**
* @brief Validate config profile.
*
@@ -273,8 +231,7 @@ static astcenc_error validate_flags(
}
// Flags field must only contain at most a single map type
exMask = ASTCENC_FLG_MAP_MASK
| ASTCENC_FLG_MAP_NORMAL
exMask = ASTCENC_FLG_MAP_NORMAL
| ASTCENC_FLG_MAP_RGBM;
if (popcount(flags & exMask) > 1)
{
@@ -435,14 +392,14 @@ static astcenc_error validate_config(
config.tune_block_mode_limit = astc::clamp(config.tune_block_mode_limit, 1u, 100u);
config.tune_refinement_limit = astc::max(config.tune_refinement_limit, 1u);
config.tune_candidate_limit = astc::clamp(config.tune_candidate_limit, 1u, TUNE_MAX_TRIAL_CANDIDATES);
config.tune_2partitioning_candidate_limit = astc::clamp(config.tune_2partitioning_candidate_limit, 1u, TUNE_MAX_PARTITIIONING_CANDIDATES);
config.tune_3partitioning_candidate_limit = astc::clamp(config.tune_3partitioning_candidate_limit, 1u, TUNE_MAX_PARTITIIONING_CANDIDATES);
config.tune_4partitioning_candidate_limit = astc::clamp(config.tune_4partitioning_candidate_limit, 1u, TUNE_MAX_PARTITIIONING_CANDIDATES);
config.tune_2partitioning_candidate_limit = astc::clamp(config.tune_2partitioning_candidate_limit, 1u, TUNE_MAX_PARTITIONING_CANDIDATES);
config.tune_3partitioning_candidate_limit = astc::clamp(config.tune_3partitioning_candidate_limit, 1u, TUNE_MAX_PARTITIONING_CANDIDATES);
config.tune_4partitioning_candidate_limit = astc::clamp(config.tune_4partitioning_candidate_limit, 1u, TUNE_MAX_PARTITIONING_CANDIDATES);
config.tune_db_limit = astc::max(config.tune_db_limit, 0.0f);
config.tune_mse_overshoot = astc::max(config.tune_mse_overshoot, 1.0f);
config.tune_2_partition_early_out_limit_factor = astc::max(config.tune_2_partition_early_out_limit_factor, 0.0f);
config.tune_3_partition_early_out_limit_factor = astc::max(config.tune_3_partition_early_out_limit_factor, 0.0f);
config.tune_2_plane_early_out_limit_correlation = astc::max(config.tune_2_plane_early_out_limit_correlation, 0.0f);
config.tune_2partition_early_out_limit_factor = astc::max(config.tune_2partition_early_out_limit_factor, 0.0f);
config.tune_3partition_early_out_limit_factor = astc::max(config.tune_3partition_early_out_limit_factor, 0.0f);
config.tune_2plane_early_out_limit_correlation = astc::max(config.tune_2plane_early_out_limit_correlation, 0.0f);
// Specifying a zero weight color component is not allowed; force to small value
float max_weight = astc::max(astc::max(config.cw_r_weight, config.cw_g_weight),
@@ -476,14 +433,6 @@ astcenc_error astcenc_config_init(
) {
astcenc_error status;
// Check basic library compatibility options here so they are checked early. Note, these checks
// are repeated in context_alloc for cases where callers use a manually defined config struct
status = validate_cpu_isa();
if (status != ASTCENC_SUCCESS)
{
return status;
}
status = validate_cpu_float();
if (status != ASTCENC_SUCCESS)
{
@@ -556,17 +505,17 @@ astcenc_error astcenc_config_init(
config.tune_block_mode_limit = (*preset_configs)[start].tune_block_mode_limit;
config.tune_refinement_limit = (*preset_configs)[start].tune_refinement_limit;
config.tune_candidate_limit = astc::min((*preset_configs)[start].tune_candidate_limit, TUNE_MAX_TRIAL_CANDIDATES);
config.tune_2partitioning_candidate_limit = astc::min((*preset_configs)[start].tune_2partitioning_candidate_limit, TUNE_MAX_PARTITIIONING_CANDIDATES);
config.tune_3partitioning_candidate_limit = astc::min((*preset_configs)[start].tune_3partitioning_candidate_limit, TUNE_MAX_PARTITIIONING_CANDIDATES);
config.tune_4partitioning_candidate_limit = astc::min((*preset_configs)[start].tune_4partitioning_candidate_limit, TUNE_MAX_PARTITIIONING_CANDIDATES);
config.tune_2partitioning_candidate_limit = astc::min((*preset_configs)[start].tune_2partitioning_candidate_limit, TUNE_MAX_PARTITIONING_CANDIDATES);
config.tune_3partitioning_candidate_limit = astc::min((*preset_configs)[start].tune_3partitioning_candidate_limit, TUNE_MAX_PARTITIONING_CANDIDATES);
config.tune_4partitioning_candidate_limit = astc::min((*preset_configs)[start].tune_4partitioning_candidate_limit, TUNE_MAX_PARTITIONING_CANDIDATES);
config.tune_db_limit = astc::max((*preset_configs)[start].tune_db_limit_a_base - 35 * ltexels,
(*preset_configs)[start].tune_db_limit_b_base - 19 * ltexels);
config.tune_mse_overshoot = (*preset_configs)[start].tune_mse_overshoot;
config.tune_2_partition_early_out_limit_factor = (*preset_configs)[start].tune_2_partition_early_out_limit_factor;
config.tune_3_partition_early_out_limit_factor =(*preset_configs)[start].tune_3_partition_early_out_limit_factor;
config.tune_2_plane_early_out_limit_correlation = (*preset_configs)[start].tune_2_plane_early_out_limit_correlation;
config.tune_2partition_early_out_limit_factor = (*preset_configs)[start].tune_2partition_early_out_limit_factor;
config.tune_3partition_early_out_limit_factor = (*preset_configs)[start].tune_3partition_early_out_limit_factor;
config.tune_2plane_early_out_limit_correlation = (*preset_configs)[start].tune_2plane_early_out_limit_correlation;
}
// Start and end node are not the same - so interpolate between them
else
@@ -606,9 +555,9 @@ astcenc_error astcenc_config_init(
config.tune_mse_overshoot = LERP(tune_mse_overshoot);
config.tune_2_partition_early_out_limit_factor = LERP(tune_2_partition_early_out_limit_factor);
config.tune_3_partition_early_out_limit_factor = LERP(tune_3_partition_early_out_limit_factor);
config.tune_2_plane_early_out_limit_correlation = LERP(tune_2_plane_early_out_limit_correlation);
config.tune_2partition_early_out_limit_factor = LERP(tune_2partition_early_out_limit_factor);
config.tune_3partition_early_out_limit_factor = LERP(tune_3partition_early_out_limit_factor);
config.tune_2plane_early_out_limit_correlation = LERP(tune_2plane_early_out_limit_correlation);
#undef LERP
#undef LERPI
#undef LERPUI
@@ -657,20 +606,14 @@ astcenc_error astcenc_config_init(
config.cw_g_weight = 0.0f;
config.cw_b_weight = 0.0f;
config.tune_2_partition_early_out_limit_factor *= 1.5f;
config.tune_3_partition_early_out_limit_factor *= 1.5f;
config.tune_2_plane_early_out_limit_correlation = 0.99f;
config.tune_2partition_early_out_limit_factor *= 1.5f;
config.tune_3partition_early_out_limit_factor *= 1.5f;
config.tune_2plane_early_out_limit_correlation = 0.99f;
// Normals are prone to blocking artifacts on smooth curves
// so force compressor to try harder here ...
config.tune_db_limit *= 1.03f;
}
else if (flags & ASTCENC_FLG_MAP_MASK)
{
// Masks are prone to blocking artifacts on mask edges
// so force compressor to try harder here ...
config.tune_db_limit *= 1.03f;
}
else if (flags & ASTCENC_FLG_MAP_RGBM)
{
config.rgbm_m_scale = 5.0f;
@@ -709,12 +652,6 @@ astcenc_error astcenc_context_alloc(
astcenc_error status;
const astcenc_config& config = *configp;
status = validate_cpu_isa();
if (status != ASTCENC_SUCCESS)
{
return status;
}
status = validate_cpu_float();
if (status != ASTCENC_SUCCESS)
{
@@ -1406,8 +1343,6 @@ const char* astcenc_get_error_string(
return "ASTCENC_ERR_OUT_OF_MEM";
case ASTCENC_ERR_BAD_CPU_FLOAT:
return "ASTCENC_ERR_BAD_CPU_FLOAT";
case ASTCENC_ERR_BAD_CPU_ISA:
return "ASTCENC_ERR_BAD_CPU_ISA";
case ASTCENC_ERR_BAD_PARAM:
return "ASTCENC_ERR_BAD_PARAM";
case ASTCENC_ERR_BAD_BLOCK_SIZE:

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2022 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -540,7 +540,7 @@ unsigned int find_best_partition_candidates(
const image_block& blk,
unsigned int partition_count,
unsigned int partition_search_limit,
unsigned int best_partitions[TUNE_MAX_PARTITIIONING_CANDIDATES],
unsigned int best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES],
unsigned int requested_candidates
) {
// Constant used to estimate quantization error for a given partitioning; the optimal value for
@@ -573,12 +573,12 @@ unsigned int find_best_partition_candidates(
bool uses_alpha = !blk.is_constant_channel(3);
// Partitioning errors assuming uncorrelated-chrominance endpoints
float uncor_best_errors[TUNE_MAX_PARTITIIONING_CANDIDATES];
unsigned int uncor_best_partitions[TUNE_MAX_PARTITIIONING_CANDIDATES];
float uncor_best_errors[TUNE_MAX_PARTITIONING_CANDIDATES];
unsigned int uncor_best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES];
// Partitioning errors assuming same-chrominance endpoints
float samec_best_errors[TUNE_MAX_PARTITIIONING_CANDIDATES];
unsigned int samec_best_partitions[TUNE_MAX_PARTITIIONING_CANDIDATES];
float samec_best_errors[TUNE_MAX_PARTITIONING_CANDIDATES];
unsigned int samec_best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES];
for (unsigned int i = 0; i < requested_candidates; i++)
{
@@ -604,8 +604,7 @@ unsigned int find_best_partition_candidates(
processed_line4 uncor_plines[BLOCK_MAX_PARTITIONS];
processed_line4 samec_plines[BLOCK_MAX_PARTITIONS];
float uncor_line_lens[BLOCK_MAX_PARTITIONS];
float samec_line_lens[BLOCK_MAX_PARTITIONS];
float line_lengths[BLOCK_MAX_PARTITIONS];
for (unsigned int j = 0; j < partition_count; j++)
{
@@ -631,8 +630,7 @@ unsigned int find_best_partition_candidates(
blk,
uncor_plines,
samec_plines,
uncor_line_lens,
samec_line_lens,
line_lengths,
uncor_error,
samec_error);
@@ -651,8 +649,8 @@ unsigned int find_best_partition_candidates(
float tpp = static_cast<float>(pi.partition_texel_count[j]);
vfloat4 error_weights(tpp * weight_imprecision_estim);
vfloat4 uncor_vector = uncor_lines[j].b * uncor_line_lens[j];
vfloat4 samec_vector = samec_lines[j].b * samec_line_lens[j];
vfloat4 uncor_vector = uncor_lines[j].b * line_lengths[j];
vfloat4 samec_vector = samec_lines[j].b * line_lengths[j];
uncor_error += dot_s(uncor_vector * uncor_vector, error_weights);
samec_error += dot_s(samec_vector * samec_vector, error_weights);
@@ -719,8 +717,8 @@ unsigned int find_best_partition_candidates(
float tpp = static_cast<float>(pi.partition_texel_count[j]);
vfloat4 error_weights(tpp * weight_imprecision_estim);
vfloat4 uncor_vector = pl.uncor_line.b * pl.uncor_line_len;
vfloat4 samec_vector = pl.samec_line.b * pl.samec_line_len;
vfloat4 uncor_vector = pl.uncor_line.b * pl.line_length;
vfloat4 samec_vector = pl.samec_line.b * pl.line_length;
uncor_error += dot3_s(uncor_vector * uncor_vector, error_weights);
samec_error += dot3_s(samec_vector * samec_vector, error_weights);
@@ -731,22 +729,12 @@ unsigned int find_best_partition_candidates(
}
}
bool best_is_uncor = uncor_best_partitions[0] > samec_best_partitions[0];
unsigned int interleave[2 * TUNE_MAX_PARTITIIONING_CANDIDATES];
unsigned int interleave[2 * TUNE_MAX_PARTITIONING_CANDIDATES];
for (unsigned int i = 0; i < requested_candidates; i++)
{
if (best_is_uncor)
{
interleave[2 * i] = bsd.get_raw_partition_info(partition_count, uncor_best_partitions[i]).partition_index;
interleave[2 * i + 1] = bsd.get_raw_partition_info(partition_count, samec_best_partitions[i]).partition_index;
}
else
{
interleave[2 * i] = bsd.get_raw_partition_info(partition_count, samec_best_partitions[i]).partition_index;
interleave[2 * i + 1] = bsd.get_raw_partition_info(partition_count, uncor_best_partitions[i]).partition_index;
}
}
uint64_t bitmasks[1024/64] { 0 };
unsigned int emitted = 0;

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2022 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -41,10 +41,10 @@ static vfloat bilinear_infill_vla(
unsigned int index
) {
// Load the bilinear filter texel weight indexes in the decimated grid
vint weight_idx0 = vint(di.texel_weights_4t[0] + index);
vint weight_idx1 = vint(di.texel_weights_4t[1] + index);
vint weight_idx2 = vint(di.texel_weights_4t[2] + index);
vint weight_idx3 = vint(di.texel_weights_4t[3] + index);
vint weight_idx0 = vint(di.texel_weights_tr[0] + index);
vint weight_idx1 = vint(di.texel_weights_tr[1] + index);
vint weight_idx2 = vint(di.texel_weights_tr[2] + index);
vint weight_idx3 = vint(di.texel_weights_tr[3] + index);
// Load the bilinear filter weights from the decimated grid
vfloat weight_val0 = gatherf(weights, weight_idx0);
@@ -53,10 +53,10 @@ static vfloat bilinear_infill_vla(
vfloat weight_val3 = gatherf(weights, weight_idx3);
// Load the weight contribution factors for each decimated weight
vfloat tex_weight_float0 = loada(di.texel_weights_float_4t[0] + index);
vfloat tex_weight_float1 = loada(di.texel_weights_float_4t[1] + index);
vfloat tex_weight_float2 = loada(di.texel_weights_float_4t[2] + index);
vfloat tex_weight_float3 = loada(di.texel_weights_float_4t[3] + index);
vfloat tex_weight_float0 = loada(di.texel_weight_contribs_float_tr[0] + index);
vfloat tex_weight_float1 = loada(di.texel_weight_contribs_float_tr[1] + index);
vfloat tex_weight_float2 = loada(di.texel_weight_contribs_float_tr[2] + index);
vfloat tex_weight_float3 = loada(di.texel_weight_contribs_float_tr[3] + index);
// Compute the bilinear interpolation to generate the per-texel weight
return (weight_val0 * tex_weight_float0 + weight_val1 * tex_weight_float1) +
@@ -81,16 +81,16 @@ static vfloat bilinear_infill_vla_2(
unsigned int index
) {
// Load the bilinear filter texel weight indexes in the decimated grid
vint weight_idx0 = vint(di.texel_weights_4t[0] + index);
vint weight_idx1 = vint(di.texel_weights_4t[1] + index);
vint weight_idx0 = vint(di.texel_weights_tr[0] + index);
vint weight_idx1 = vint(di.texel_weights_tr[1] + index);
// Load the bilinear filter weights from the decimated grid
vfloat weight_val0 = gatherf(weights, weight_idx0);
vfloat weight_val1 = gatherf(weights, weight_idx1);
// Load the weight contribution factors for each decimated weight
vfloat tex_weight_float0 = loada(di.texel_weights_float_4t[0] + index);
vfloat tex_weight_float1 = loada(di.texel_weights_float_4t[1] + index);
vfloat tex_weight_float0 = loada(di.texel_weight_contribs_float_tr[0] + index);
vfloat tex_weight_float1 = loada(di.texel_weight_contribs_float_tr[1] + index);
// Compute the bilinear interpolation to generate the per-texel weight
return (weight_val0 * tex_weight_float0 + weight_val1 * tex_weight_float1);
@@ -894,8 +894,8 @@ void compute_ideal_weights_for_decimation(
for (unsigned int j = 0; j < max_texel_count; j++)
{
vint texel(di.weight_texel[j] + i);
vfloat weight = loada(di.weights_flt[j] + i);
vint texel(di.weight_texels_tr[j] + i);
vfloat weight = loada(di.weights_texel_contribs_tr[j] + i);
if (!constant_wes)
{
@@ -952,8 +952,8 @@ void compute_ideal_weights_for_decimation(
for (unsigned int j = 0; j < max_texel_count; j++)
{
vint texel(di.weight_texel[j] + i);
vfloat contrib_weight = loada(di.weights_flt[j] + i);
vint texel(di.weight_texels_tr[j] + i);
vfloat contrib_weight = loada(di.weights_texel_contribs_tr[j] + i);
if (!constant_wes)
{

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2022 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -137,7 +137,7 @@ static constexpr unsigned int TUNE_MAX_TRIAL_CANDIDATES { 8 };
*
* This can be dynamically reduced by the compression quality preset.
*/
static constexpr unsigned int TUNE_MAX_PARTITIIONING_CANDIDATES { 32 };
static constexpr unsigned int TUNE_MAX_PARTITIONING_CANDIDATES { 32 };
/**
* @brief The maximum quant level using full angular endpoint search method.
@@ -154,10 +154,12 @@ static constexpr unsigned int TUNE_MAX_PARTITIIONING_CANDIDATES { 32 };
*/
static constexpr unsigned int TUNE_MAX_ANGULAR_QUANT { 7 }; /* QUANT_12 */
static_assert((BLOCK_MAX_TEXELS % ASTCENC_SIMD_WIDTH) == 0,
"BLOCK_MAX_TEXELS must be multiple of ASTCENC_SIMD_WIDTH");
static_assert(BLOCK_MAX_TEXELS <= 216,
"BLOCK_MAX_TEXELS must not be greater than 216");
static_assert((BLOCK_MAX_WEIGHTS % ASTCENC_SIMD_WIDTH) == 0,
"BLOCK_MAX_WEIGHTS must be multiple of ASTCENC_SIMD_WIDTH");
@@ -291,11 +293,13 @@ struct partition_lines3
/** @brief Post-processed line for correlated chroma, passing though the origin. */
processed_line3 samec_pline;
/** @brief The length of the line for uncorrelated chroma. */
float uncor_line_len;
/** @brief The length of the line for correlated chroma. */
float samec_line_len;
/**
* @brief The length of the line for uncorrelated chroma.
*
* This is used for both the uncorrelated and same chroma lines - they are normally very similar
* and only used for the relative ranking of partitionings against one another.
*/
float line_length;
};
/**
@@ -317,8 +321,8 @@ struct partition_info
/**
* @brief The number of texels in each partition.
*
* Note that some seeds result in zero texels assigned to a partition are valid, but are skipped
* by this compressor as there is no point spending bits encoding an unused color endpoint.
* Note that some seeds result in zero texels assigned to a partition. These are valid, but are
* skipped by this compressor as there is no point spending bits encoding an unused endpoints.
*/
uint8_t partition_texel_count[BLOCK_MAX_PARTITIONS];
@@ -360,38 +364,50 @@ struct decimation_info
/** @brief The number of stored weights in the Z dimension. */
uint8_t weight_z;
/** @brief The number of stored weights that contribute to each texel, between 1 and 4. */
/**
* @brief The number of weights that contribute to each texel.
* Value is between 1 and 4.
*/
uint8_t texel_weight_count[BLOCK_MAX_TEXELS];
/** @brief The weight index of the N weights that need to be interpolated for each texel. */
uint8_t texel_weights_4t[4][BLOCK_MAX_TEXELS];
/**
* @brief The weight index of the N weights that are interpolated for each texel.
* Stored transposed to improve vectorization.
*/
uint8_t texel_weights_tr[4][BLOCK_MAX_TEXELS];
/** @brief The bilinear interpolation weighting of the N input weights for each texel, between 0 and 16. */
uint8_t texel_weights_int_4t[4][BLOCK_MAX_TEXELS];
/**
* @brief The bilinear contribution of the N weights that are interpolated for each texel.
* Value is between 0 and 16, stored transposed to improve vectorization.
*/
uint8_t texel_weight_contribs_int_tr[4][BLOCK_MAX_TEXELS];
/** @brief The bilinear interpolation weighting of the N input weights for each texel, between 0 and 1. */
alignas(ASTCENC_VECALIGN) float texel_weights_float_4t[4][BLOCK_MAX_TEXELS];
/**
* @brief The bilinear contribution of the N weights that are interpolated for each texel.
* Value is between 0 and 1, stored transposed to improve vectorization.
*/
alignas(ASTCENC_VECALIGN) float texel_weight_contribs_float_tr[4][BLOCK_MAX_TEXELS];
/** @brief The number of texels that each stored weight contributes to. */
uint8_t weight_texel_count[BLOCK_MAX_WEIGHTS];
/** @brief The list of weights that contribute to each texel. */
uint8_t weight_texel[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS];
/** @brief The list of weight indices that contribute to each texel. */
alignas(ASTCENC_VECALIGN) float weights_flt[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS];
/**
* @brief The list of texels that use a specific weight index.
* Stored transposed to improve vectorization.
*/
uint8_t weight_texels_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS];
/**
* @brief Folded structure for faster access:
* texel_weights_texel[i][j][.] = texel_weights[.][weight_texel[i][j]]
* @brief The bilinear contribution to the N texels that use each weight.
* Value is between 0 and 1, stored transposed to improve vectorization.
*/
uint8_t texel_weights_texel[BLOCK_MAX_WEIGHTS][BLOCK_MAX_TEXELS][4];
alignas(ASTCENC_VECALIGN) float weights_texel_contribs_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS];
/**
* @brief Folded structure for faster access:
* texel_weights_float_texel[i][j][.] = texel_weights_float[.][weight_texel[i][j]]
* @brief The bilinear contribution to the Nth texel that uses each weight.
* Value is between 0 and 1, stored transposed to improve vectorization.
*/
float texel_weights_float_texel[BLOCK_MAX_WEIGHTS][BLOCK_MAX_TEXELS][4];
float texel_contrib_for_weight[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS];
};
/**
@@ -441,23 +457,23 @@ struct decimation_mode
*
* Bit 0 = QUANT_2, Bit 1 = QUANT_3, etc.
*/
uint16_t refprec_1_plane;
uint16_t refprec_1plane;
/**
* @brief Bitvector indicating weight quant methods used by active 2 plane block modes.
*
* Bit 0 = QUANT_2, Bit 1 = QUANT_3, etc.
*/
uint16_t refprec_2_planes;
uint16_t refprec_2planes;
/**
* @brief Set a 1 plane weight quant as active.
*
* @param weight_quant The quant method to set.
*/
void set_ref_1_plane(quant_method weight_quant)
void set_ref_1plane(quant_method weight_quant)
{
refprec_1_plane |= (1 << weight_quant);
refprec_1plane |= (1 << weight_quant);
}
/**
@@ -465,10 +481,10 @@ struct decimation_mode
*
* @param max_weight_quant The max quant method to test.
*/
bool is_ref_1_plane(quant_method max_weight_quant) const
bool is_ref_1plane(quant_method max_weight_quant) const
{
uint16_t mask = static_cast<uint16_t>((1 << (max_weight_quant + 1)) - 1);
return (refprec_1_plane & mask) != 0;
return (refprec_1plane & mask) != 0;
}
/**
@@ -476,9 +492,9 @@ struct decimation_mode
*
* @param weight_quant The quant method to set.
*/
void set_ref_2_plane(quant_method weight_quant)
void set_ref_2plane(quant_method weight_quant)
{
refprec_2_planes |= static_cast<uint16_t>(1 << weight_quant);
refprec_2planes |= static_cast<uint16_t>(1 << weight_quant);
}
/**
@@ -486,10 +502,10 @@ struct decimation_mode
*
* @param max_weight_quant The max quant method to test.
*/
bool is_ref_2_plane(quant_method max_weight_quant) const
bool is_ref_2plane(quant_method max_weight_quant) const
{
uint16_t mask = static_cast<uint16_t>((1 << (max_weight_quant + 1)) - 1);
return (refprec_2_planes & mask) != 0;
return (refprec_2planes & mask) != 0;
}
};
@@ -1322,9 +1338,14 @@ bool is_legal_3d_block_size(
* Converts unquant value in 0-255 range into quant value in 0-255 range.
* No BISE scrambling is applied at this stage.
*
* Indexed by [quant_mode - 4][data_value].
* The BISE encoding results in ties where available quant<256> values are
* equidistant the available quant<BISE> values. This table stores two values
* for each input - one for use with a negative residual, and one for use with
* a positive residual.
*
* Indexed by [quant_mode - 4][data_value * 2 + residual].
*/
extern const uint8_t color_unquant_to_uquant_tables[17][256];
extern const uint8_t color_unquant_to_uquant_tables[17][512];
/**
* @brief The precomputed table for packing quantized color values.
@@ -1514,8 +1535,7 @@ void compute_error_squared_rgb(
* @param blk The image block color data to be compressed.
* @param uncor_plines Processed uncorrelated partition lines for each partition.
* @param samec_plines Processed same chroma partition lines for each partition.
* @param[out] uncor_lengths The length of each components deviation from the line.
* @param[out] samec_lengths The length of each components deviation from the line.
* @param[out] line_lengths The length of each components deviation from the line.
* @param[out] uncor_error The cumulative error for using the uncorrelated line.
* @param[out] samec_error The cumulative error for using the same chroma line.
*/
@@ -1524,8 +1544,7 @@ void compute_error_squared_rgba(
const image_block& blk,
const processed_line4 uncor_plines[BLOCK_MAX_PARTITIONS],
const processed_line4 samec_plines[BLOCK_MAX_PARTITIONS],
float uncor_lengths[BLOCK_MAX_PARTITIONS],
float samec_lengths[BLOCK_MAX_PARTITIONS],
float line_lengths[BLOCK_MAX_PARTITIONS],
float& uncor_error,
float& samec_error);
@@ -1551,7 +1570,7 @@ unsigned int find_best_partition_candidates(
const image_block& blk,
unsigned int partition_count,
unsigned int partition_search_limit,
unsigned int best_partitions[TUNE_MAX_PARTITIIONING_CANDIDATES],
unsigned int best_partitions[TUNE_MAX_PARTITIONING_CANDIDATES],
unsigned int requested_candidates);
/* ============================================================================
@@ -2106,34 +2125,6 @@ void physical_to_symbolic(
/* ============================================================================
Platform-specific functions.
============================================================================ */
/**
* @brief Run-time detection if the host CPU supports the POPCNT extension.
*
* @return @c true if supported, @c false if not.
*/
bool cpu_supports_popcnt();
/**
* @brief Run-time detection if the host CPU supports F16C extension.
*
* @return @c true if supported, @c false if not.
*/
bool cpu_supports_f16c();
/**
* @brief Run-time detection if the host CPU supports SSE 4.1 extension.
*
* @return @c true if supported, @c false if not.
*/
bool cpu_supports_sse41();
/**
* @brief Run-time detection if the host CPU supports AVX 2 extension.
*
* @return @c true if supported, @c false if not.
*/
bool cpu_supports_avx2();
/**
* @brief Allocate an aligned memory buffer.
*

View File

@@ -48,8 +48,6 @@
#define ASTCENC_SSE 42
#elif defined(__SSE4_1__)
#define ASTCENC_SSE 41
#elif defined(__SSE3__)
#define ASTCENC_SSE 30
#elif defined(__SSE2__)
#define ASTCENC_SSE 20
#else

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2022 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -21,6 +21,9 @@
#include "astcenc_internal.h"
/** @brief The number of 64-bit words needed to represent a canonical partition bit pattern. */
#define BIT_PATTERN_WORDS (((ASTCENC_BLOCK_MAX_TEXELS * 2) + 63) / 64)
/**
* @brief Generate a canonical representation of a partition pattern.
*
@@ -35,15 +38,15 @@
static void generate_canonical_partitioning(
unsigned int texel_count,
const uint8_t* partition_of_texel,
uint64_t bit_pattern[7]
uint64_t bit_pattern[BIT_PATTERN_WORDS]
) {
// Clear the pattern
for (unsigned int i = 0; i < 7; i++)
for (unsigned int i = 0; i < BIT_PATTERN_WORDS; i++)
{
bit_pattern[i] = 0;
}
// Store a mapping to reorder the raw partitions so that the the partitions are ordered such
// Store a mapping to reorder the raw partitions so that the partitions are ordered such
// that the lowest texel index in partition N is smaller than the lowest texel index in
// partition N + 1.
int mapped_index[BLOCK_MAX_PARTITIONS];
@@ -76,13 +79,29 @@ static void generate_canonical_partitioning(
* @return @c true if the patterns are the same, @c false otherwise.
*/
static bool compare_canonical_partitionings(
const uint64_t part1[7],
const uint64_t part2[7]
const uint64_t part1[BIT_PATTERN_WORDS],
const uint64_t part2[BIT_PATTERN_WORDS]
) {
return (part1[0] == part2[0]) && (part1[1] == part2[1]) &&
(part1[2] == part2[2]) && (part1[3] == part2[3]) &&
(part1[4] == part2[4]) && (part1[5] == part2[5]) &&
(part1[6] == part2[6]);
return (part1[0] == part2[0])
#if BIT_PATTERN_WORDS > 1
&& (part1[1] == part2[1])
#endif
#if BIT_PATTERN_WORDS > 2
&& (part1[2] == part2[2])
#endif
#if BIT_PATTERN_WORDS > 3
&& (part1[3] == part2[3])
#endif
#if BIT_PATTERN_WORDS > 4
&& (part1[4] == part2[4])
#endif
#if BIT_PATTERN_WORDS > 5
&& (part1[5] == part2[5])
#endif
#if BIT_PATTERN_WORDS > 6
&& (part1[6] == part2[6])
#endif
;
}
/**
@@ -401,11 +420,11 @@ static void build_partition_table_for_one_partition_count(
continue;
}
generate_canonical_partitioning(bsd.texel_count, ptab[next_index].partition_of_texel, canonical_patterns + next_index * 7);
generate_canonical_partitioning(bsd.texel_count, ptab[next_index].partition_of_texel, canonical_patterns + next_index * BIT_PATTERN_WORDS);
bool keep_canonical = true;
for (unsigned int j = 0; j < next_index; j++)
{
bool match = compare_canonical_partitionings(canonical_patterns + 7 * next_index, canonical_patterns + 7 * j);
bool match = compare_canonical_partitionings(canonical_patterns + next_index * BIT_PATTERN_WORDS, canonical_patterns + j * BIT_PATTERN_WORDS);
if (match)
{
keep_canonical = false;
@@ -452,7 +471,8 @@ void init_partition_tables(
bsd.partitioning_count_selected[0] = 1;
bsd.partitioning_count_all[0] = 1;
uint64_t* canonical_patterns = new uint64_t[BLOCK_MAX_PARTITIONINGS * 7];
uint64_t* canonical_patterns = new uint64_t[BLOCK_MAX_PARTITIONINGS * BIT_PATTERN_WORDS];
build_partition_table_for_one_partition_count(bsd, can_omit_partitionings, partition_count_cutoff, 2, par_tab2, canonical_patterns);
build_partition_table_for_one_partition_count(bsd, can_omit_partitionings, partition_count_cutoff, 3, par_tab3, canonical_patterns);
build_partition_table_for_one_partition_count(bsd, can_omit_partitionings, partition_count_cutoff, 4, par_tab4, canonical_patterns);

View File

@@ -1,166 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2020-2022 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
// ----------------------------------------------------------------------------
/**
* @brief Platform-specific function implementations.
*
* This module contains functions for querying the host extended ISA support.
*/
// Include before the defines below to pick up any auto-setup based on compiler
// built-in config, if not being set explicitly by the build system
#include "astcenc_internal.h"
#if (ASTCENC_SSE > 0) || (ASTCENC_AVX > 0) || \
(ASTCENC_POPCNT > 0) || (ASTCENC_F16C > 0)
static bool g_init { false };
/** Does this CPU support SSE 4.1? Set to -1 if not yet initialized. */
static bool g_cpu_has_sse41 { false };
/** Does this CPU support AVX2? Set to -1 if not yet initialized. */
static bool g_cpu_has_avx2 { false };
/** Does this CPU support POPCNT? Set to -1 if not yet initialized. */
static bool g_cpu_has_popcnt { false };
/** Does this CPU support F16C? Set to -1 if not yet initialized. */
static bool g_cpu_has_f16c { false };
/* ============================================================================
Platform code for Visual Studio
============================================================================ */
#if !defined(__clang__) && defined(_MSC_VER)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <intrin.h>
/**
* @brief Detect platform CPU ISA support and update global trackers.
*/
static void detect_cpu_isa()
{
int data[4];
__cpuid(data, 0);
int num_id = data[0];
if (num_id >= 1)
{
__cpuidex(data, 1, 0);
// SSE41 = Bank 1, ECX, bit 19
g_cpu_has_sse41 = data[2] & (1 << 19) ? true : false;
// POPCNT = Bank 1, ECX, bit 23
g_cpu_has_popcnt = data[2] & (1 << 23) ? true : false;
// F16C = Bank 1, ECX, bit 29
g_cpu_has_f16c = data[2] & (1 << 29) ? true : false;
}
if (num_id >= 7)
{
__cpuidex(data, 7, 0);
// AVX2 = Bank 7, EBX, bit 5
g_cpu_has_avx2 = data[1] & (1 << 5) ? true : false;
}
// Ensure state bits are updated before init flag is updated
MemoryBarrier();
g_init = true;
}
/* ============================================================================
Platform code for GCC and Clang
============================================================================ */
#else
#include <cpuid.h>
/**
* @brief Detect platform CPU ISA support and update global trackers.
*/
static void detect_cpu_isa()
{
unsigned int data[4];
if (__get_cpuid_count(1, 0, &data[0], &data[1], &data[2], &data[3]))
{
// SSE41 = Bank 1, ECX, bit 19
g_cpu_has_sse41 = data[2] & (1 << 19) ? true : false;
// POPCNT = Bank 1, ECX, bit 23
g_cpu_has_popcnt = data[2] & (1 << 23) ? true : false;
// F16C = Bank 1, ECX, bit 29
g_cpu_has_f16c = data[2] & (1 << 29) ? true : false;
}
g_cpu_has_avx2 = 0;
if (__get_cpuid_count(7, 0, &data[0], &data[1], &data[2], &data[3]))
{
// AVX2 = Bank 7, EBX, bit 5
g_cpu_has_avx2 = data[1] & (1 << 5) ? true : false;
}
// Ensure state bits are updated before init flag is updated
__sync_synchronize();
g_init = true;
}
#endif
/* See header for documentation. */
bool cpu_supports_popcnt()
{
if (!g_init)
{
detect_cpu_isa();
}
return g_cpu_has_popcnt;
}
/* See header for documentation. */
bool cpu_supports_f16c()
{
if (!g_init)
{
detect_cpu_isa();
}
return g_cpu_has_f16c;
}
/* See header for documentation. */
bool cpu_supports_sse41()
{
if (!g_init)
{
detect_cpu_isa();
}
return g_cpu_has_sse41;
}
/* See header for documentation. */
bool cpu_supports_avx2()
{
if (!g_init)
{
detect_cpu_isa();
}
return g_cpu_has_avx2;
}
#endif

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2021 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -23,321 +23,320 @@
#if !defined(ASTCENC_DECOMPRESS_ONLY)
// Starts from QUANT_6
// Not scrambled
const uint8_t color_unquant_to_uquant_tables[17][256] {
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
204, 204, 204, 204, 204, 204, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
// Not scrambled, starts from QUANT_6
const uint8_t color_unquant_to_uquant_tables[17][512] {
{ // QUANT_6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 102, 102, 102, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 153, 153, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
},
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 109, 109, 109, 109,
109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
146, 146, 146, 146, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
182, 182, 182, 182, 182, 182, 182, 182, 182, 219, 219, 219, 219, 219, 219, 219,
219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219,
219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
{ // QUANT_8
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 109, 109, 109, 109, 109, 109, 109, 109, 109,
109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
146, 146, 146, 146, 146, 146, 146, 146, 146, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182,
182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219,
219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219,
219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
},
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 84, 84, 84, 84, 84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
84, 84, 84, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 171, 171, 171,
171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
171, 171, 171, 171, 171, 171, 171, 171, 171, 199, 199, 199, 199, 199, 199, 199,
199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
199, 199, 199, 199, 199, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
227, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
{ // QUANT_10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
84, 84, 84, 84, 84, 84, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 171, 171, 171, 171, 171, 171,
171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
227, 227, 227, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
},
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 69, 69, 69, 69, 69, 69,
69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
69, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
92, 92, 92, 92, 92, 92, 92, 92, 92, 116, 116, 116, 116, 116, 116, 116,
116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
139, 139, 139, 139, 139, 139, 139, 163, 163, 163, 163, 163, 163, 163, 163, 163,
163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 186,
186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
186, 186, 186, 186, 186, 186, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
{ // QUANT_12
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
69, 69, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 186, 186,
186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
232, 232, 232, 232, 232, 232, 232, 232, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
},
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 68, 68, 68, 68,
68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 85, 85, 85,
85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 102, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 119,
119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
136, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
170, 170, 170, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
187, 187, 187, 187, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
204, 204, 204, 204, 204, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221,
221, 221, 221, 221, 221, 221, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
238, 238, 238, 238, 238, 238, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255
{ // QUANT_16
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 68, 68, 68, 68, 68, 68, 68, 68,
68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 85, 85, 85, 85, 85, 85,
85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 102, 102, 102, 102,
102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 119, 119,
119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
136, 136, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
153, 153, 153, 153, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
170, 170, 170, 170, 170, 170, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
187, 187, 187, 187, 187, 187, 187, 187, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221,
221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
},
{
0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 67, 67, 67,
67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80, 94, 94, 94, 94, 94, 94, 94, 94,
94, 94, 94, 94, 94, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
107, 107, 107, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 148, 148, 148,
148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 161, 161, 161, 161, 161,
161, 161, 161, 161, 161, 161, 161, 161, 175, 175, 175, 175, 175, 175, 175, 175,
175, 175, 175, 175, 175, 175, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188,
188, 188, 188, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 228, 228,
228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 242, 242, 242, 242, 242,
242, 242, 242, 242, 242, 242, 242, 242, 242, 255, 255, 255, 255, 255, 255, 255
{ // QUANT_20
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 67, 67, 67, 67, 67, 67,
67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
107, 107, 107, 107, 107, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 148, 148, 148, 148, 148,
148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175,
175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188,
188, 188, 188, 188, 188, 188, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
201, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 228, 228, 228, 228,
228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 242, 242, 242, 242, 242, 242, 242, 242, 242,
242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
},
{
0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 33, 33, 33, 33,
33, 33, 33, 33, 33, 33, 33, 44, 44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 66, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99, 99, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 145, 145, 145, 145,
145, 145, 145, 145, 145, 145, 145, 156, 156, 156, 156, 156, 156, 156, 156, 156,
156, 156, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 178, 178, 178,
178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189,
189, 189, 189, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 211, 211,
211, 211, 211, 211, 211, 211, 211, 211, 211, 222, 222, 222, 222, 222, 222, 222,
222, 222, 222, 222, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 244,
244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 255, 255, 255, 255, 255, 255
{ // QUANT_24
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 33, 33, 33, 33, 33, 33, 33, 33,
33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 66, 66, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 110, 110, 110, 110, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 145, 145, 145, 145, 145, 145, 145, 145,
145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
156, 156, 156, 156, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 178, 178, 178, 178, 178, 178,
178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189,
189, 189, 189, 189, 189, 189, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 211, 211, 211, 211,
211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222,
222, 222, 222, 222, 222, 222, 222, 222, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 244, 244,
244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
},
{
0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16,
16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24, 33, 33, 33,
33, 33, 33, 33, 33, 33, 41, 41, 41, 41, 41, 41, 41, 41, 49, 49,
49, 49, 49, 49, 49, 49, 57, 57, 57, 57, 57, 57, 57, 57, 66, 66,
66, 66, 66, 66, 66, 66, 66, 74, 74, 74, 74, 74, 74, 74, 74, 82,
82, 82, 82, 82, 82, 82, 82, 90, 90, 90, 90, 90, 90, 90, 90, 99,
99, 99, 99, 99, 99, 99, 99, 99, 107, 107, 107, 107, 107, 107, 107, 107,
115, 115, 115, 115, 115, 115, 115, 115, 123, 123, 123, 123, 123, 123, 123, 123,
132, 132, 132, 132, 132, 132, 132, 132, 140, 140, 140, 140, 140, 140, 140, 140,
148, 148, 148, 148, 148, 148, 148, 148, 156, 156, 156, 156, 156, 156, 156, 156,
156, 165, 165, 165, 165, 165, 165, 165, 165, 173, 173, 173, 173, 173, 173, 173,
173, 181, 181, 181, 181, 181, 181, 181, 181, 189, 189, 189, 189, 189, 189, 189,
189, 189, 198, 198, 198, 198, 198, 198, 198, 198, 206, 206, 206, 206, 206, 206,
206, 206, 214, 214, 214, 214, 214, 214, 214, 214, 222, 222, 222, 222, 222, 222,
222, 222, 222, 231, 231, 231, 231, 231, 231, 231, 231, 239, 239, 239, 239, 239,
239, 239, 239, 247, 247, 247, 247, 247, 247, 247, 247, 255, 255, 255, 255, 255
{ // QUANT_32
0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 33, 33, 33, 33, 33, 33,
33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 49, 49, 49, 49, 49,
49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 82, 82, 82,
82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 115,
115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
140, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
156, 156, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
173, 173, 173, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189,
189, 189, 189, 189, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
206, 206, 206, 206, 206, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222,
222, 222, 222, 222, 222, 222, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 239, 239, 239, 239, 239, 239, 239, 239, 239,
239, 239, 239, 239, 239, 239, 239, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 255, 255, 255, 255, 255, 255, 255, 255, 255
},
{
0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 13,
13, 19, 19, 19, 19, 19, 19, 26, 26, 26, 26, 26, 26, 26, 32, 32,
32, 32, 32, 32, 39, 39, 39, 39, 39, 39, 39, 45, 45, 45, 45, 45,
45, 52, 52, 52, 52, 52, 52, 52, 58, 58, 58, 58, 58, 58, 65, 65,
65, 65, 65, 65, 65, 71, 71, 71, 71, 71, 71, 78, 78, 78, 78, 78,
78, 78, 84, 84, 84, 84, 84, 84, 91, 91, 91, 91, 91, 91, 91, 97,
97, 97, 97, 97, 97, 104, 104, 104, 104, 104, 104, 104, 110, 110, 110, 110,
110, 110, 117, 117, 117, 117, 117, 117, 117, 123, 123, 123, 123, 123, 123, 123,
132, 132, 132, 132, 132, 132, 132, 138, 138, 138, 138, 138, 138, 138, 145, 145,
145, 145, 145, 145, 151, 151, 151, 151, 151, 151, 151, 158, 158, 158, 158, 158,
158, 164, 164, 164, 164, 164, 164, 164, 171, 171, 171, 171, 171, 171, 177, 177,
177, 177, 177, 177, 177, 184, 184, 184, 184, 184, 184, 190, 190, 190, 190, 190,
190, 190, 197, 197, 197, 197, 197, 197, 203, 203, 203, 203, 203, 203, 203, 210,
210, 210, 210, 210, 210, 216, 216, 216, 216, 216, 216, 216, 223, 223, 223, 223,
223, 223, 229, 229, 229, 229, 229, 229, 229, 236, 236, 236, 236, 236, 236, 242,
242, 242, 242, 242, 242, 242, 249, 249, 249, 249, 249, 249, 255, 255, 255, 255
{ // QUANT_40
0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
78, 78, 78, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 97, 97, 97,
97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 110, 110, 110, 110, 110, 110, 110, 110, 110,
110, 110, 110, 110, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 145, 145, 145, 145,
145, 145, 145, 145, 145, 145, 145, 145, 145, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
158, 158, 158, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 177, 177, 177,
177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 190, 190, 190, 190, 190, 190, 190, 190, 190,
190, 190, 190, 190, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 210, 210,
210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 223, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 223, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 242,
242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 255, 255, 255, 255, 255, 255, 255
},
{
0, 0, 0, 5, 5, 5, 5, 5, 5, 11, 11, 11, 11, 11, 16, 16,
16, 16, 16, 21, 21, 21, 21, 21, 21, 27, 27, 27, 27, 27, 32, 32,
32, 32, 32, 32, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 48, 48,
48, 48, 48, 48, 54, 54, 54, 54, 54, 59, 59, 59, 59, 59, 59, 65,
65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 76, 76, 76, 76, 76, 81,
81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 92, 92, 92, 92, 92, 97,
97, 97, 97, 97, 97, 103, 103, 103, 103, 103, 108, 108, 108, 108, 108, 113,
113, 113, 113, 113, 113, 119, 119, 119, 119, 119, 124, 124, 124, 124, 124, 124,
131, 131, 131, 131, 131, 131, 136, 136, 136, 136, 136, 142, 142, 142, 142, 142,
142, 147, 147, 147, 147, 147, 152, 152, 152, 152, 152, 158, 158, 158, 158, 158,
158, 163, 163, 163, 163, 163, 169, 169, 169, 169, 169, 169, 174, 174, 174, 174,
174, 179, 179, 179, 179, 179, 185, 185, 185, 185, 185, 185, 190, 190, 190, 190,
190, 196, 196, 196, 196, 196, 196, 201, 201, 201, 201, 201, 207, 207, 207, 207,
207, 207, 212, 212, 212, 212, 212, 217, 217, 217, 217, 217, 223, 223, 223, 223,
223, 223, 228, 228, 228, 228, 228, 234, 234, 234, 234, 234, 234, 239, 239, 239,
239, 239, 244, 244, 244, 244, 244, 250, 250, 250, 250, 250, 250, 255, 255, 255
{ // QUANT_48
0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 48, 48, 48, 48,
48, 48, 48, 48, 48, 48, 48, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 97, 97,
97, 97, 97, 97, 97, 97, 97, 97, 97, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 113, 113,
113, 113, 113, 113, 113, 113, 113, 113, 113, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 142, 142, 142, 142, 142, 142, 142, 142, 142,
142, 142, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 158, 158, 158, 158, 158, 158, 158, 158, 158,
158, 158, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 174, 174, 174, 174, 174, 174, 174, 174,
174, 174, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 190, 190, 190, 190, 190, 190, 190, 190,
190, 190, 190, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 207, 207, 207, 207, 207, 207, 207,
207, 207, 207, 207, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 223, 223, 223, 223, 223, 223, 223,
223, 223, 223, 223, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 239, 239, 239, 239, 239, 239,
239, 239, 239, 239, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 255, 255, 255, 255, 255, 255
},
{
0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, 12, 12, 16,
16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 24, 28, 28, 28, 28, 32,
32, 32, 32, 36, 36, 36, 36, 40, 40, 40, 40, 44, 44, 44, 44, 48,
48, 48, 48, 52, 52, 52, 52, 56, 56, 56, 56, 60, 60, 60, 60, 65,
65, 65, 65, 65, 69, 69, 69, 69, 73, 73, 73, 73, 77, 77, 77, 77,
81, 81, 81, 81, 85, 85, 85, 85, 89, 89, 89, 89, 93, 93, 93, 93,
97, 97, 97, 97, 101, 101, 101, 101, 105, 105, 105, 105, 109, 109, 109, 109,
113, 113, 113, 113, 117, 117, 117, 117, 121, 121, 121, 121, 125, 125, 125, 125,
130, 130, 130, 130, 134, 134, 134, 134, 138, 138, 138, 138, 142, 142, 142, 142,
146, 146, 146, 146, 150, 150, 150, 150, 154, 154, 154, 154, 158, 158, 158, 158,
162, 162, 162, 162, 166, 166, 166, 166, 170, 170, 170, 170, 174, 174, 174, 174,
178, 178, 178, 178, 182, 182, 182, 182, 186, 186, 186, 186, 190, 190, 190, 190,
190, 195, 195, 195, 195, 199, 199, 199, 199, 203, 203, 203, 203, 207, 207, 207,
207, 211, 211, 211, 211, 215, 215, 215, 215, 219, 219, 219, 219, 223, 223, 223,
223, 227, 227, 227, 227, 231, 231, 231, 231, 235, 235, 235, 235, 239, 239, 239,
239, 243, 243, 243, 243, 247, 247, 247, 247, 251, 251, 251, 251, 255, 255, 255
{ // QUANT_64
0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16,
16, 16, 16, 16, 16, 20, 20, 20, 20, 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24, 28, 28, 28, 28, 28, 28, 28, 28, 32, 32, 32,
32, 32, 32, 32, 32, 36, 36, 36, 36, 36, 36, 36, 36, 40, 40, 40, 40, 40, 40, 40, 40, 44, 44, 44, 44, 44, 44, 44, 44, 48, 48, 48,
48, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 56, 56, 56, 56, 56, 56, 56, 56, 60, 60, 60, 60, 60, 60, 60, 60, 60, 65, 65,
65, 65, 65, 65, 65, 65, 65, 69, 69, 69, 69, 69, 69, 69, 69, 73, 73, 73, 73, 73, 73, 73, 73, 77, 77, 77, 77, 77, 77, 77, 77, 81,
81, 81, 81, 81, 81, 81, 81, 85, 85, 85, 85, 85, 85, 85, 85, 89, 89, 89, 89, 89, 89, 89, 89, 93, 93, 93, 93, 93, 93, 93, 93, 97,
97, 97, 97, 97, 97, 97, 97, 101, 101, 101, 101, 101, 101, 101, 101, 105, 105, 105, 105, 105, 105, 105, 105, 109, 109, 109, 109, 109, 109, 109, 109, 113,
113, 113, 113, 113, 113, 113, 113, 117, 117, 117, 117, 117, 117, 117, 117, 121, 121, 121, 121, 121, 121, 121, 121, 125, 125, 125, 125, 125, 125, 125, 125, 125,
130, 130, 130, 130, 130, 130, 130, 130, 130, 134, 134, 134, 134, 134, 134, 134, 134, 138, 138, 138, 138, 138, 138, 138, 138, 142, 142, 142, 142, 142, 142, 142,
142, 146, 146, 146, 146, 146, 146, 146, 146, 150, 150, 150, 150, 150, 150, 150, 150, 154, 154, 154, 154, 154, 154, 154, 154, 158, 158, 158, 158, 158, 158, 158,
158, 162, 162, 162, 162, 162, 162, 162, 162, 166, 166, 166, 166, 166, 166, 166, 166, 170, 170, 170, 170, 170, 170, 170, 170, 174, 174, 174, 174, 174, 174, 174,
174, 178, 178, 178, 178, 178, 178, 178, 178, 182, 182, 182, 182, 182, 182, 182, 182, 186, 186, 186, 186, 186, 186, 186, 186, 190, 190, 190, 190, 190, 190, 190,
190, 190, 195, 195, 195, 195, 195, 195, 195, 195, 195, 199, 199, 199, 199, 199, 199, 199, 199, 203, 203, 203, 203, 203, 203, 203, 203, 207, 207, 207, 207, 207,
207, 207, 207, 211, 211, 211, 211, 211, 211, 211, 211, 215, 215, 215, 215, 215, 215, 215, 215, 219, 219, 219, 219, 219, 219, 219, 219, 223, 223, 223, 223, 223,
223, 223, 223, 227, 227, 227, 227, 227, 227, 227, 227, 231, 231, 231, 231, 231, 231, 231, 231, 235, 235, 235, 235, 235, 235, 235, 235, 239, 239, 239, 239, 239,
239, 239, 239, 243, 243, 243, 243, 243, 243, 243, 243, 247, 247, 247, 247, 247, 247, 247, 247, 251, 251, 251, 251, 251, 251, 251, 251, 255, 255, 255, 255, 255
},
{
0, 0, 3, 3, 3, 6, 6, 6, 9, 9, 9, 9, 13, 13, 13, 16,
16, 16, 19, 19, 19, 22, 22, 22, 25, 25, 25, 25, 29, 29, 29, 32,
32, 32, 35, 35, 35, 38, 38, 38, 38, 42, 42, 42, 45, 45, 45, 48,
48, 48, 51, 51, 51, 54, 54, 54, 54, 58, 58, 58, 61, 61, 61, 64,
64, 64, 67, 67, 67, 67, 71, 71, 71, 74, 74, 74, 77, 77, 77, 80,
80, 80, 83, 83, 83, 83, 87, 87, 87, 90, 90, 90, 93, 93, 93, 96,
96, 96, 96, 100, 100, 100, 103, 103, 103, 106, 106, 106, 109, 109, 109, 112,
112, 112, 112, 116, 116, 116, 119, 119, 119, 122, 122, 122, 125, 125, 125, 125,
130, 130, 130, 130, 133, 133, 133, 136, 136, 136, 139, 139, 139, 143, 143, 143,
143, 146, 146, 146, 149, 149, 149, 152, 152, 152, 155, 155, 155, 159, 159, 159,
159, 162, 162, 162, 165, 165, 165, 168, 168, 168, 172, 172, 172, 172, 175, 175,
175, 178, 178, 178, 181, 181, 181, 184, 184, 184, 188, 188, 188, 188, 191, 191,
191, 194, 194, 194, 197, 197, 197, 201, 201, 201, 201, 204, 204, 204, 207, 207,
207, 210, 210, 210, 213, 213, 213, 217, 217, 217, 217, 220, 220, 220, 223, 223,
223, 226, 226, 226, 230, 230, 230, 230, 233, 233, 233, 236, 236, 236, 239, 239,
239, 242, 242, 242, 246, 246, 246, 246, 249, 249, 249, 252, 252, 252, 255, 255
{ // QUANT_80
0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 9, 9, 9, 9, 9, 9, 9, 13, 13, 13, 13, 13, 13, 13, 16, 16,
16, 16, 16, 16, 19, 19, 19, 19, 19, 19, 22, 22, 22, 22, 22, 22, 25, 25, 25, 25, 25, 25, 25, 29, 29, 29, 29, 29, 29, 29, 32, 32,
32, 32, 32, 32, 35, 35, 35, 35, 35, 35, 38, 38, 38, 38, 38, 38, 38, 42, 42, 42, 42, 42, 42, 42, 45, 45, 45, 45, 45, 45, 48, 48,
48, 48, 48, 48, 51, 51, 51, 51, 51, 51, 54, 54, 54, 54, 54, 54, 54, 58, 58, 58, 58, 58, 58, 58, 61, 61, 61, 61, 61, 61, 64, 64,
64, 64, 64, 64, 67, 67, 67, 67, 67, 67, 67, 71, 71, 71, 71, 71, 71, 71, 74, 74, 74, 74, 74, 74, 77, 77, 77, 77, 77, 77, 80, 80,
80, 80, 80, 80, 83, 83, 83, 83, 83, 83, 83, 87, 87, 87, 87, 87, 87, 87, 90, 90, 90, 90, 90, 90, 93, 93, 93, 93, 93, 93, 96, 96,
96, 96, 96, 96, 96, 100, 100, 100, 100, 100, 100, 100, 103, 103, 103, 103, 103, 103, 106, 106, 106, 106, 106, 106, 109, 109, 109, 109, 109, 109, 112, 112,
112, 112, 112, 112, 112, 116, 116, 116, 116, 116, 116, 116, 119, 119, 119, 119, 119, 119, 122, 122, 122, 122, 122, 122, 125, 125, 125, 125, 125, 125, 125, 125,
130, 130, 130, 130, 130, 130, 130, 130, 133, 133, 133, 133, 133, 133, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, 139, 139, 139, 143, 143, 143, 143, 143,
143, 143, 146, 146, 146, 146, 146, 146, 149, 149, 149, 149, 149, 149, 152, 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 159, 159, 159, 159, 159,
159, 159, 162, 162, 162, 162, 162, 162, 165, 165, 165, 165, 165, 165, 168, 168, 168, 168, 168, 168, 168, 172, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175,
175, 175, 178, 178, 178, 178, 178, 178, 181, 181, 181, 181, 181, 181, 184, 184, 184, 184, 184, 184, 184, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191,
191, 191, 194, 194, 194, 194, 194, 194, 197, 197, 197, 197, 197, 197, 197, 201, 201, 201, 201, 201, 201, 201, 204, 204, 204, 204, 204, 204, 207, 207, 207, 207,
207, 207, 210, 210, 210, 210, 210, 210, 213, 213, 213, 213, 213, 213, 213, 217, 217, 217, 217, 217, 217, 217, 220, 220, 220, 220, 220, 220, 223, 223, 223, 223,
223, 223, 226, 226, 226, 226, 226, 226, 226, 230, 230, 230, 230, 230, 230, 230, 233, 233, 233, 233, 233, 233, 236, 236, 236, 236, 236, 236, 239, 239, 239, 239,
239, 239, 242, 242, 242, 242, 242, 242, 242, 246, 246, 246, 246, 246, 246, 246, 249, 249, 249, 249, 249, 249, 252, 252, 252, 252, 252, 252, 255, 255, 255, 255
},
{
0, 0, 2, 2, 5, 5, 5, 8, 8, 8, 10, 10, 13, 13, 13, 16,
16, 16, 18, 18, 21, 21, 21, 24, 24, 24, 26, 26, 29, 29, 29, 32,
32, 32, 35, 35, 35, 37, 37, 40, 40, 40, 43, 43, 43, 45, 45, 48,
48, 48, 51, 51, 51, 53, 53, 56, 56, 56, 59, 59, 59, 61, 61, 64,
64, 64, 67, 67, 67, 70, 70, 70, 72, 72, 75, 75, 75, 78, 78, 78,
80, 80, 83, 83, 83, 86, 86, 86, 88, 88, 91, 91, 91, 94, 94, 94,
96, 96, 99, 99, 99, 102, 102, 102, 104, 104, 107, 107, 107, 110, 110, 110,
112, 112, 115, 115, 115, 118, 118, 118, 120, 120, 123, 123, 123, 126, 126, 126,
129, 129, 129, 132, 132, 132, 135, 135, 137, 137, 137, 140, 140, 140, 143, 143,
145, 145, 145, 148, 148, 148, 151, 151, 153, 153, 153, 156, 156, 156, 159, 159,
161, 161, 161, 164, 164, 164, 167, 167, 169, 169, 169, 172, 172, 172, 175, 175,
177, 177, 177, 180, 180, 180, 183, 183, 185, 185, 185, 188, 188, 188, 191, 191,
191, 194, 194, 196, 196, 196, 199, 199, 199, 202, 202, 204, 204, 204, 207, 207,
207, 210, 210, 212, 212, 212, 215, 215, 215, 218, 218, 220, 220, 220, 223, 223,
223, 226, 226, 226, 229, 229, 231, 231, 231, 234, 234, 234, 237, 237, 239, 239,
239, 242, 242, 242, 245, 245, 247, 247, 247, 250, 250, 250, 253, 253, 255, 255
{ // QUANT_96
0, 0, 0, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 16, 16,
16, 16, 16, 18, 18, 18, 18, 18, 21, 21, 21, 21, 21, 21, 24, 24, 24, 24, 24, 26, 26, 26, 26, 26, 29, 29, 29, 29, 29, 29, 32, 32,
32, 32, 32, 32, 35, 35, 35, 35, 35, 37, 37, 37, 37, 37, 40, 40, 40, 40, 40, 40, 43, 43, 43, 43, 43, 45, 45, 45, 45, 45, 48, 48,
48, 48, 48, 48, 51, 51, 51, 51, 51, 53, 53, 53, 53, 53, 56, 56, 56, 56, 56, 56, 59, 59, 59, 59, 59, 61, 61, 61, 61, 61, 64, 64,
64, 64, 64, 64, 67, 67, 67, 67, 67, 67, 70, 70, 70, 70, 70, 72, 72, 72, 72, 72, 75, 75, 75, 75, 75, 75, 78, 78, 78, 78, 78, 80,
80, 80, 80, 80, 83, 83, 83, 83, 83, 83, 86, 86, 86, 86, 86, 88, 88, 88, 88, 88, 91, 91, 91, 91, 91, 91, 94, 94, 94, 94, 94, 96,
96, 96, 96, 96, 99, 99, 99, 99, 99, 99, 102, 102, 102, 102, 102, 104, 104, 104, 104, 104, 107, 107, 107, 107, 107, 107, 110, 110, 110, 110, 110, 112,
112, 112, 112, 112, 115, 115, 115, 115, 115, 115, 118, 118, 118, 118, 118, 120, 120, 120, 120, 120, 123, 123, 123, 123, 123, 123, 126, 126, 126, 126, 126, 126,
129, 129, 129, 129, 129, 129, 132, 132, 132, 132, 132, 132, 135, 135, 135, 135, 135, 137, 137, 137, 137, 137, 140, 140, 140, 140, 140, 140, 143, 143, 143, 143,
143, 145, 145, 145, 145, 145, 148, 148, 148, 148, 148, 148, 151, 151, 151, 151, 151, 153, 153, 153, 153, 153, 156, 156, 156, 156, 156, 156, 159, 159, 159, 159,
159, 161, 161, 161, 161, 161, 164, 164, 164, 164, 164, 164, 167, 167, 167, 167, 167, 169, 169, 169, 169, 169, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175,
175, 177, 177, 177, 177, 177, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183, 183, 185, 185, 185, 185, 185, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191,
191, 191, 194, 194, 194, 194, 194, 196, 196, 196, 196, 196, 199, 199, 199, 199, 199, 199, 202, 202, 202, 202, 202, 204, 204, 204, 204, 204, 207, 207, 207, 207,
207, 207, 210, 210, 210, 210, 210, 212, 212, 212, 212, 212, 215, 215, 215, 215, 215, 215, 218, 218, 218, 218, 218, 220, 220, 220, 220, 220, 223, 223, 223, 223,
223, 223, 226, 226, 226, 226, 226, 226, 229, 229, 229, 229, 229, 231, 231, 231, 231, 231, 234, 234, 234, 234, 234, 234, 237, 237, 237, 237, 237, 239, 239, 239,
239, 239, 242, 242, 242, 242, 242, 242, 245, 245, 245, 245, 245, 247, 247, 247, 247, 247, 250, 250, 250, 250, 250, 250, 253, 253, 253, 253, 253, 255, 255, 255
},
{
0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14,
16, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 26, 28, 28, 30, 30,
32, 32, 34, 34, 36, 36, 38, 38, 40, 40, 42, 42, 44, 44, 46, 46,
48, 48, 50, 50, 52, 52, 54, 54, 56, 56, 58, 58, 60, 60, 62, 62,
64, 64, 66, 66, 68, 68, 70, 70, 72, 72, 74, 74, 76, 76, 78, 78,
80, 80, 82, 82, 84, 84, 86, 86, 88, 88, 90, 90, 92, 92, 94, 94,
96, 96, 98, 98, 100, 100, 102, 102, 104, 104, 106, 106, 108, 108, 110, 110,
112, 112, 114, 114, 116, 116, 118, 118, 120, 120, 122, 122, 124, 124, 126, 126,
129, 129, 131, 131, 133, 133, 135, 135, 137, 137, 139, 139, 141, 141, 143, 143,
145, 145, 147, 147, 149, 149, 151, 151, 153, 153, 155, 155, 157, 157, 159, 159,
161, 161, 163, 163, 165, 165, 167, 167, 169, 169, 171, 171, 173, 173, 175, 175,
177, 177, 179, 179, 181, 181, 183, 183, 185, 185, 187, 187, 189, 189, 191, 191,
193, 193, 195, 195, 197, 197, 199, 199, 201, 201, 203, 203, 205, 205, 207, 207,
209, 209, 211, 211, 213, 213, 215, 215, 217, 217, 219, 219, 221, 221, 223, 223,
225, 225, 227, 227, 229, 229, 231, 231, 233, 233, 235, 235, 237, 237, 239, 239,
241, 241, 243, 243, 245, 245, 247, 247, 249, 249, 251, 251, 253, 253, 255, 255
{ // QUANT_128
0, 0, 0, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, 8, 8, 8, 8, 10, 10, 10, 10, 12, 12, 12, 12, 14, 14, 14, 14, 16,
16, 16, 16, 18, 18, 18, 18, 20, 20, 20, 20, 22, 22, 22, 22, 24, 24, 24, 24, 26, 26, 26, 26, 28, 28, 28, 28, 30, 30, 30, 30, 32,
32, 32, 32, 34, 34, 34, 34, 36, 36, 36, 36, 38, 38, 38, 38, 40, 40, 40, 40, 42, 42, 42, 42, 44, 44, 44, 44, 46, 46, 46, 46, 48,
48, 48, 48, 50, 50, 50, 50, 52, 52, 52, 52, 54, 54, 54, 54, 56, 56, 56, 56, 58, 58, 58, 58, 60, 60, 60, 60, 62, 62, 62, 62, 64,
64, 64, 64, 66, 66, 66, 66, 68, 68, 68, 68, 70, 70, 70, 70, 72, 72, 72, 72, 74, 74, 74, 74, 76, 76, 76, 76, 78, 78, 78, 78, 80,
80, 80, 80, 82, 82, 82, 82, 84, 84, 84, 84, 86, 86, 86, 86, 88, 88, 88, 88, 90, 90, 90, 90, 92, 92, 92, 92, 94, 94, 94, 94, 96,
96, 96, 96, 98, 98, 98, 98, 100, 100, 100, 100, 102, 102, 102, 102, 104, 104, 104, 104, 106, 106, 106, 106, 108, 108, 108, 108, 110, 110, 110, 110, 112,
112, 112, 112, 114, 114, 114, 114, 116, 116, 116, 116, 118, 118, 118, 118, 120, 120, 120, 120, 122, 122, 122, 122, 124, 124, 124, 124, 126, 126, 126, 126, 126,
129, 129, 129, 129, 129, 131, 131, 131, 131, 133, 133, 133, 133, 135, 135, 135, 135, 137, 137, 137, 137, 139, 139, 139, 139, 141, 141, 141, 141, 143, 143, 143,
143, 145, 145, 145, 145, 147, 147, 147, 147, 149, 149, 149, 149, 151, 151, 151, 151, 153, 153, 153, 153, 155, 155, 155, 155, 157, 157, 157, 157, 159, 159, 159,
159, 161, 161, 161, 161, 163, 163, 163, 163, 165, 165, 165, 165, 167, 167, 167, 167, 169, 169, 169, 169, 171, 171, 171, 171, 173, 173, 173, 173, 175, 175, 175,
175, 177, 177, 177, 177, 179, 179, 179, 179, 181, 181, 181, 181, 183, 183, 183, 183, 185, 185, 185, 185, 187, 187, 187, 187, 189, 189, 189, 189, 191, 191, 191,
191, 193, 193, 193, 193, 195, 195, 195, 195, 197, 197, 197, 197, 199, 199, 199, 199, 201, 201, 201, 201, 203, 203, 203, 203, 205, 205, 205, 205, 207, 207, 207,
207, 209, 209, 209, 209, 211, 211, 211, 211, 213, 213, 213, 213, 215, 215, 215, 215, 217, 217, 217, 217, 219, 219, 219, 219, 221, 221, 221, 221, 223, 223, 223,
223, 225, 225, 225, 225, 227, 227, 227, 227, 229, 229, 229, 229, 231, 231, 231, 231, 233, 233, 233, 233, 235, 235, 235, 235, 237, 237, 237, 237, 239, 239, 239,
239, 241, 241, 241, 241, 243, 243, 243, 243, 245, 245, 245, 245, 247, 247, 247, 247, 249, 249, 249, 249, 251, 251, 251, 251, 253, 253, 253, 253, 255, 255, 255
},
{
0, 1, 1, 3, 4, 4, 6, 6, 8, 9, 9, 11, 12, 12, 14, 14,
16, 17, 17, 19, 20, 20, 22, 22, 24, 25, 25, 27, 28, 28, 30, 30,
32, 33, 33, 35, 36, 36, 38, 38, 40, 41, 41, 43, 44, 44, 46, 46,
48, 49, 49, 51, 52, 52, 54, 54, 56, 57, 57, 59, 60, 60, 62, 62,
64, 65, 65, 67, 68, 68, 70, 70, 72, 73, 73, 75, 76, 76, 78, 78,
80, 81, 81, 83, 84, 84, 86, 86, 88, 89, 89, 91, 92, 92, 94, 94,
96, 97, 97, 99, 100, 100, 102, 102, 104, 105, 105, 107, 108, 108, 110, 110,
112, 113, 113, 115, 116, 116, 118, 118, 120, 121, 121, 123, 124, 124, 126, 126,
129, 129, 131, 131, 132, 134, 134, 135, 137, 137, 139, 139, 140, 142, 142, 143,
145, 145, 147, 147, 148, 150, 150, 151, 153, 153, 155, 155, 156, 158, 158, 159,
161, 161, 163, 163, 164, 166, 166, 167, 169, 169, 171, 171, 172, 174, 174, 175,
177, 177, 179, 179, 180, 182, 182, 183, 185, 185, 187, 187, 188, 190, 190, 191,
193, 193, 195, 195, 196, 198, 198, 199, 201, 201, 203, 203, 204, 206, 206, 207,
209, 209, 211, 211, 212, 214, 214, 215, 217, 217, 219, 219, 220, 222, 222, 223,
225, 225, 227, 227, 228, 230, 230, 231, 233, 233, 235, 235, 236, 238, 238, 239,
241, 241, 243, 243, 244, 246, 246, 247, 249, 249, 251, 251, 252, 254, 254, 255
{ // QUANT_160
0, 0, 1, 1, 1, 3, 3, 3, 4, 4, 4, 6, 6, 6, 6, 8, 8, 8, 9, 9, 9, 11, 11, 11, 12, 12, 12, 14, 14, 14, 14, 16,
16, 16, 17, 17, 17, 19, 19, 19, 20, 20, 20, 22, 22, 22, 22, 24, 24, 24, 25, 25, 25, 27, 27, 27, 28, 28, 28, 30, 30, 30, 30, 32,
32, 32, 33, 33, 33, 35, 35, 35, 36, 36, 36, 38, 38, 38, 38, 40, 40, 40, 41, 41, 41, 43, 43, 43, 44, 44, 44, 46, 46, 46, 46, 48,
48, 48, 49, 49, 49, 51, 51, 51, 52, 52, 52, 54, 54, 54, 54, 56, 56, 56, 57, 57, 57, 59, 59, 59, 60, 60, 60, 62, 62, 62, 62, 64,
64, 64, 65, 65, 65, 67, 67, 67, 68, 68, 68, 70, 70, 70, 70, 72, 72, 72, 73, 73, 73, 75, 75, 75, 76, 76, 76, 78, 78, 78, 78, 80,
80, 80, 81, 81, 81, 83, 83, 83, 84, 84, 84, 86, 86, 86, 86, 88, 88, 88, 89, 89, 89, 91, 91, 91, 92, 92, 92, 94, 94, 94, 94, 96,
96, 96, 97, 97, 97, 99, 99, 99, 100, 100, 100, 102, 102, 102, 102, 104, 104, 104, 105, 105, 105, 107, 107, 107, 108, 108, 108, 110, 110, 110, 110, 112,
112, 112, 113, 113, 113, 115, 115, 115, 116, 116, 116, 118, 118, 118, 118, 120, 120, 120, 121, 121, 121, 123, 123, 123, 124, 124, 124, 126, 126, 126, 126, 126,
129, 129, 129, 129, 129, 131, 131, 131, 132, 132, 132, 134, 134, 134, 135, 135, 135, 137, 137, 137, 137, 139, 139, 139, 140, 140, 140, 142, 142, 142, 143, 143,
143, 145, 145, 145, 145, 147, 147, 147, 148, 148, 148, 150, 150, 150, 151, 151, 151, 153, 153, 153, 153, 155, 155, 155, 156, 156, 156, 158, 158, 158, 159, 159,
159, 161, 161, 161, 161, 163, 163, 163, 164, 164, 164, 166, 166, 166, 167, 167, 167, 169, 169, 169, 169, 171, 171, 171, 172, 172, 172, 174, 174, 174, 175, 175,
175, 177, 177, 177, 177, 179, 179, 179, 180, 180, 180, 182, 182, 182, 183, 183, 183, 185, 185, 185, 185, 187, 187, 187, 188, 188, 188, 190, 190, 190, 191, 191,
191, 193, 193, 193, 193, 195, 195, 195, 196, 196, 196, 198, 198, 198, 199, 199, 199, 201, 201, 201, 201, 203, 203, 203, 204, 204, 204, 206, 206, 206, 207, 207,
207, 209, 209, 209, 209, 211, 211, 211, 212, 212, 212, 214, 214, 214, 215, 215, 215, 217, 217, 217, 217, 219, 219, 219, 220, 220, 220, 222, 222, 222, 223, 223,
223, 225, 225, 225, 225, 227, 227, 227, 228, 228, 228, 230, 230, 230, 231, 231, 231, 233, 233, 233, 233, 235, 235, 235, 236, 236, 236, 238, 238, 238, 239, 239,
239, 241, 241, 241, 241, 243, 243, 243, 244, 244, 244, 246, 246, 246, 247, 247, 247, 249, 249, 249, 249, 251, 251, 251, 252, 252, 252, 254, 254, 254, 255, 255
},
{
0, 1, 2, 2, 4, 5, 6, 6, 8, 9, 10, 10, 12, 13, 14, 14,
16, 17, 18, 18, 20, 21, 22, 22, 24, 25, 26, 26, 28, 29, 30, 30,
32, 33, 34, 34, 36, 37, 38, 38, 40, 41, 42, 42, 44, 45, 46, 46,
48, 49, 50, 50, 52, 53, 54, 54, 56, 57, 58, 58, 60, 61, 62, 62,
64, 65, 66, 66, 68, 69, 70, 70, 72, 73, 74, 74, 76, 77, 78, 78,
80, 81, 82, 82, 84, 85, 86, 86, 88, 89, 90, 90, 92, 93, 94, 94,
96, 97, 98, 98, 100, 101, 102, 102, 104, 105, 106, 106, 108, 109, 110, 110,
112, 113, 114, 114, 116, 117, 118, 118, 120, 121, 122, 122, 124, 125, 126, 126,
129, 129, 130, 131, 133, 133, 134, 135, 137, 137, 138, 139, 141, 141, 142, 143,
145, 145, 146, 147, 149, 149, 150, 151, 153, 153, 154, 155, 157, 157, 158, 159,
161, 161, 162, 163, 165, 165, 166, 167, 169, 169, 170, 171, 173, 173, 174, 175,
177, 177, 178, 179, 181, 181, 182, 183, 185, 185, 186, 187, 189, 189, 190, 191,
193, 193, 194, 195, 197, 197, 198, 199, 201, 201, 202, 203, 205, 205, 206, 207,
209, 209, 210, 211, 213, 213, 214, 215, 217, 217, 218, 219, 221, 221, 222, 223,
225, 225, 226, 227, 229, 229, 230, 231, 233, 233, 234, 235, 237, 237, 238, 239,
241, 241, 242, 243, 245, 245, 246, 247, 249, 249, 250, 251, 253, 253, 254, 255
{ // QUANT_192
0, 0, 1, 1, 2, 2, 2, 4, 4, 4, 5, 5, 6, 6, 6, 8, 8, 8, 9, 9, 10, 10, 10, 12, 12, 12, 13, 13, 14, 14, 14, 16,
16, 16, 17, 17, 18, 18, 18, 20, 20, 20, 21, 21, 22, 22, 22, 24, 24, 24, 25, 25, 26, 26, 26, 28, 28, 28, 29, 29, 30, 30, 30, 32,
32, 32, 33, 33, 34, 34, 34, 36, 36, 36, 37, 37, 38, 38, 38, 40, 40, 40, 41, 41, 42, 42, 42, 44, 44, 44, 45, 45, 46, 46, 46, 48,
48, 48, 49, 49, 50, 50, 50, 52, 52, 52, 53, 53, 54, 54, 54, 56, 56, 56, 57, 57, 58, 58, 58, 60, 60, 60, 61, 61, 62, 62, 62, 64,
64, 64, 65, 65, 66, 66, 66, 68, 68, 68, 69, 69, 70, 70, 70, 72, 72, 72, 73, 73, 74, 74, 74, 76, 76, 76, 77, 77, 78, 78, 78, 80,
80, 80, 81, 81, 82, 82, 82, 84, 84, 84, 85, 85, 86, 86, 86, 88, 88, 88, 89, 89, 90, 90, 90, 92, 92, 92, 93, 93, 94, 94, 94, 96,
96, 96, 97, 97, 98, 98, 98, 100, 100, 100, 101, 101, 102, 102, 102, 104, 104, 104, 105, 105, 106, 106, 106, 108, 108, 108, 109, 109, 110, 110, 110, 112,
112, 112, 113, 113, 114, 114, 114, 116, 116, 116, 117, 117, 118, 118, 118, 120, 120, 120, 121, 121, 122, 122, 122, 124, 124, 124, 125, 125, 126, 126, 126, 126,
129, 129, 129, 129, 130, 130, 131, 131, 131, 133, 133, 133, 134, 134, 135, 135, 135, 137, 137, 137, 138, 138, 139, 139, 139, 141, 141, 141, 142, 142, 143, 143,
143, 145, 145, 145, 146, 146, 147, 147, 147, 149, 149, 149, 150, 150, 151, 151, 151, 153, 153, 153, 154, 154, 155, 155, 155, 157, 157, 157, 158, 158, 159, 159,
159, 161, 161, 161, 162, 162, 163, 163, 163, 165, 165, 165, 166, 166, 167, 167, 167, 169, 169, 169, 170, 170, 171, 171, 171, 173, 173, 173, 174, 174, 175, 175,
175, 177, 177, 177, 178, 178, 179, 179, 179, 181, 181, 181, 182, 182, 183, 183, 183, 185, 185, 185, 186, 186, 187, 187, 187, 189, 189, 189, 190, 190, 191, 191,
191, 193, 193, 193, 194, 194, 195, 195, 195, 197, 197, 197, 198, 198, 199, 199, 199, 201, 201, 201, 202, 202, 203, 203, 203, 205, 205, 205, 206, 206, 207, 207,
207, 209, 209, 209, 210, 210, 211, 211, 211, 213, 213, 213, 214, 214, 215, 215, 215, 217, 217, 217, 218, 218, 219, 219, 219, 221, 221, 221, 222, 222, 223, 223,
223, 225, 225, 225, 226, 226, 227, 227, 227, 229, 229, 229, 230, 230, 231, 231, 231, 233, 233, 233, 234, 234, 235, 235, 235, 237, 237, 237, 238, 238, 239, 239,
239, 241, 241, 241, 242, 242, 243, 243, 243, 245, 245, 245, 246, 246, 247, 247, 247, 249, 249, 249, 250, 250, 251, 251, 251, 253, 253, 253, 254, 254, 255, 255
},
{ // QUANT_256
0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15,
16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31,
32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47,
48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63,
64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79,
80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 88, 88, 89, 89, 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 95, 95,
96, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111,
112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 127, 127,
128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141, 142, 142, 143, 143,
144, 144, 145, 145, 146, 146, 147, 147, 148, 148, 149, 149, 150, 150, 151, 151, 152, 152, 153, 153, 154, 154, 155, 155, 156, 156, 157, 157, 158, 158, 159, 159,
160, 160, 161, 161, 162, 162, 163, 163, 164, 164, 165, 165, 166, 166, 167, 167, 168, 168, 169, 169, 170, 170, 171, 171, 172, 172, 173, 173, 174, 174, 175, 175,
176, 176, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183, 184, 184, 185, 185, 186, 186, 187, 187, 188, 188, 189, 189, 190, 190, 191, 191,
192, 192, 193, 193, 194, 194, 195, 195, 196, 196, 197, 197, 198, 198, 199, 199, 200, 200, 201, 201, 202, 202, 203, 203, 204, 204, 205, 205, 206, 206, 207, 207,
208, 208, 209, 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216, 216, 217, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223,
224, 224, 225, 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, 239,
240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255
},
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
}
};
// Starts from QUANT_6
// Scrambled
const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] {
{
{ // QUANT_6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -355,13 +354,13 @@ const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] {
3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
},
{
{ // QUANT_8
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
@@ -373,35 +372,35 @@ const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] {
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
},
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
{ // QUANT_10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6,
4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
},
{
{ // QUANT_12
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10,
6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7, 7, 7, 7,
11, 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
@@ -409,7 +408,7 @@ const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] {
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
},
{
{ // QUANT_16
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
@@ -427,25 +426,25 @@ const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] {
13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15
},
{
{ // QUANT_20
0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10, 10,
6, 6, 6, 6, 6, 6, 6, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 15, 15, 15,
14, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 11, 11, 11, 11, 11,
11, 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7, 7, 7,
11, 11, 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 5, 5,
17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1
},
{
{ // QUANT_24
0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10,
@@ -463,15 +462,15 @@ const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] {
3, 3, 3, 3, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1, 1
},
{
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6,
6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8,
8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10,
10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12,
12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
{ // QUANT_32
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8,
8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10,
10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12,
12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14,
14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15,
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17,
18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19,
19, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21,
@@ -481,51 +480,51 @@ const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] {
27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29,
29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31
},
{
0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16,
16, 24, 24, 24, 24, 24, 24, 32, 32, 32, 32, 32, 32, 32, 2, 2,
2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 18, 18, 18, 18, 18,
18, 26, 26, 26, 26, 26, 26, 26, 34, 34, 34, 34, 34, 34, 4, 4,
4, 4, 4, 4, 4, 12, 12, 12, 12, 12, 12, 20, 20, 20, 20, 20,
20, 20, 28, 28, 28, 28, 28, 28, 36, 36, 36, 36, 36, 36, 36, 6,
6, 6, 6, 6, 6, 14, 14, 14, 14, 14, 14, 14, 22, 22, 22, 22,
22, 22, 30, 30, 30, 30, 30, 30, 30, 38, 38, 38, 38, 38, 38, 38,
39, 39, 39, 39, 39, 39, 39, 31, 31, 31, 31, 31, 31, 31, 23, 23,
23, 23, 23, 23, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7,
7, 37, 37, 37, 37, 37, 37, 37, 29, 29, 29, 29, 29, 29, 21, 21,
21, 21, 21, 21, 21, 13, 13, 13, 13, 13, 13, 5, 5, 5, 5, 5,
5, 5, 35, 35, 35, 35, 35, 35, 27, 27, 27, 27, 27, 27, 27, 19,
19, 19, 19, 19, 19, 11, 11, 11, 11, 11, 11, 11, 3, 3, 3, 3,
3, 3, 33, 33, 33, 33, 33, 33, 33, 25, 25, 25, 25, 25, 25, 17,
17, 17, 17, 17, 17, 17, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1
{ // QUANT_40
0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16,
24, 24, 24, 24, 24, 24, 24, 32, 32, 32, 32, 32, 32, 32, 2, 2,
2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 18, 18, 18, 18, 18, 18,
18, 26, 26, 26, 26, 26, 26, 34, 34, 34, 34, 34, 34, 34, 4, 4,
4, 4, 4, 4, 12, 12, 12, 12, 12, 12, 12, 20, 20, 20, 20, 20,
20, 28, 28, 28, 28, 28, 28, 28, 36, 36, 36, 36, 36, 36, 36, 6,
6, 6, 6, 6, 6, 14, 14, 14, 14, 14, 14, 22, 22, 22, 22, 22,
22, 22, 30, 30, 30, 30, 30, 30, 38, 38, 38, 38, 38, 38, 38, 38,
39, 39, 39, 39, 39, 39, 39, 39, 31, 31, 31, 31, 31, 31, 23, 23,
23, 23, 23, 23, 23, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7,
7, 37, 37, 37, 37, 37, 37, 37, 29, 29, 29, 29, 29, 29, 29, 21,
21, 21, 21, 21, 21, 13, 13, 13, 13, 13, 13, 13, 5, 5, 5, 5,
5, 5, 35, 35, 35, 35, 35, 35, 35, 27, 27, 27, 27, 27, 27, 19,
19, 19, 19, 19, 19, 19, 11, 11, 11, 11, 11, 11, 3, 3, 3, 3,
3, 3, 33, 33, 33, 33, 33, 33, 33, 25, 25, 25, 25, 25, 25, 25,
17, 17, 17, 17, 17, 17, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1
},
{
0, 0, 0, 16, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32, 2, 2,
2, 2, 2, 18, 18, 18, 18, 18, 18, 34, 34, 34, 34, 34, 4, 4,
4, 4, 4, 4, 20, 20, 20, 20, 20, 36, 36, 36, 36, 36, 6, 6,
6, 6, 6, 6, 22, 22, 22, 22, 22, 38, 38, 38, 38, 38, 38, 8,
8, 8, 8, 8, 24, 24, 24, 24, 24, 24, 40, 40, 40, 40, 40, 10,
10, 10, 10, 10, 26, 26, 26, 26, 26, 26, 42, 42, 42, 42, 42, 12,
12, 12, 12, 12, 12, 28, 28, 28, 28, 28, 44, 44, 44, 44, 44, 14,
14, 14, 14, 14, 14, 30, 30, 30, 30, 30, 46, 46, 46, 46, 46, 46,
47, 47, 47, 47, 47, 47, 31, 31, 31, 31, 31, 15, 15, 15, 15, 15,
15, 45, 45, 45, 45, 45, 29, 29, 29, 29, 29, 13, 13, 13, 13, 13,
13, 43, 43, 43, 43, 43, 27, 27, 27, 27, 27, 27, 11, 11, 11, 11,
11, 41, 41, 41, 41, 41, 25, 25, 25, 25, 25, 25, 9, 9, 9, 9,
9, 39, 39, 39, 39, 39, 39, 23, 23, 23, 23, 23, 7, 7, 7, 7,
7, 7, 37, 37, 37, 37, 37, 21, 21, 21, 21, 21, 5, 5, 5, 5,
5, 5, 35, 35, 35, 35, 35, 19, 19, 19, 19, 19, 19, 3, 3, 3,
3, 3, 33, 33, 33, 33, 33, 17, 17, 17, 17, 17, 17, 1, 1, 1
{ // QUANT_48
0, 0, 0, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 2, 2,
2, 2, 2, 18, 18, 18, 18, 18, 34, 34, 34, 34, 34, 34, 4, 4,
4, 4, 4, 20, 20, 20, 20, 20, 20, 36, 36, 36, 36, 36, 6, 6,
6, 6, 6, 22, 22, 22, 22, 22, 22, 38, 38, 38, 38, 38, 38, 8,
8, 8, 8, 8, 24, 24, 24, 24, 24, 40, 40, 40, 40, 40, 40, 10,
10, 10, 10, 10, 26, 26, 26, 26, 26, 42, 42, 42, 42, 42, 42, 12,
12, 12, 12, 12, 28, 28, 28, 28, 28, 28, 44, 44, 44, 44, 44, 14,
14, 14, 14, 14, 30, 30, 30, 30, 30, 30, 46, 46, 46, 46, 46, 46,
47, 47, 47, 47, 47, 47, 31, 31, 31, 31, 31, 31, 15, 15, 15, 15,
15, 45, 45, 45, 45, 45, 29, 29, 29, 29, 29, 29, 13, 13, 13, 13,
13, 43, 43, 43, 43, 43, 43, 27, 27, 27, 27, 27, 11, 11, 11, 11,
11, 41, 41, 41, 41, 41, 41, 25, 25, 25, 25, 25, 9, 9, 9, 9,
9, 39, 39, 39, 39, 39, 39, 23, 23, 23, 23, 23, 23, 7, 7, 7,
7, 7, 37, 37, 37, 37, 37, 21, 21, 21, 21, 21, 21, 5, 5, 5,
5, 5, 35, 35, 35, 35, 35, 35, 19, 19, 19, 19, 19, 3, 3, 3,
3, 3, 33, 33, 33, 33, 33, 33, 17, 17, 17, 17, 17, 1, 1, 1
},
{
0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4,
4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8,
8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12,
12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16,
16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,
20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,
24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27,
28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31,
{ // QUANT_64
0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8,
8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12,
12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16,
16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20,
20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24,
24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 28,
28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 31,
32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35,
36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39,
40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43,
@@ -535,29 +534,29 @@ const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] {
55, 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59,
59, 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63
},
{
0, 0, 16, 16, 16, 32, 32, 32, 48, 48, 48, 48, 64, 64, 64, 2,
2, 2, 18, 18, 18, 34, 34, 34, 50, 50, 50, 50, 66, 66, 66, 4,
4, 4, 20, 20, 20, 36, 36, 36, 36, 52, 52, 52, 68, 68, 68, 6,
6, 6, 22, 22, 22, 38, 38, 38, 38, 54, 54, 54, 70, 70, 70, 8,
8, 8, 24, 24, 24, 24, 40, 40, 40, 56, 56, 56, 72, 72, 72, 10,
10, 10, 26, 26, 26, 26, 42, 42, 42, 58, 58, 58, 74, 74, 74, 12,
12, 12, 12, 28, 28, 28, 44, 44, 44, 60, 60, 60, 76, 76, 76, 14,
14, 14, 14, 30, 30, 30, 46, 46, 46, 62, 62, 62, 78, 78, 78, 78,
79, 79, 79, 79, 63, 63, 63, 47, 47, 47, 31, 31, 31, 15, 15, 15,
15, 77, 77, 77, 61, 61, 61, 45, 45, 45, 29, 29, 29, 13, 13, 13,
13, 75, 75, 75, 59, 59, 59, 43, 43, 43, 27, 27, 27, 27, 11, 11,
11, 73, 73, 73, 57, 57, 57, 41, 41, 41, 25, 25, 25, 25, 9, 9,
9, 71, 71, 71, 55, 55, 55, 39, 39, 39, 39, 23, 23, 23, 7, 7,
7, 69, 69, 69, 53, 53, 53, 37, 37, 37, 37, 21, 21, 21, 5, 5,
5, 67, 67, 67, 51, 51, 51, 51, 35, 35, 35, 19, 19, 19, 3, 3,
3, 65, 65, 65, 49, 49, 49, 49, 33, 33, 33, 17, 17, 17, 1, 1
{ // QUANT_80
0, 0, 16, 16, 16, 32, 32, 32, 48, 48, 48, 64, 64, 64, 64, 2,
2, 2, 18, 18, 18, 34, 34, 34, 50, 50, 50, 66, 66, 66, 66, 4,
4, 4, 20, 20, 20, 36, 36, 36, 52, 52, 52, 52, 68, 68, 68, 6,
6, 6, 22, 22, 22, 38, 38, 38, 54, 54, 54, 54, 70, 70, 70, 8,
8, 8, 24, 24, 24, 40, 40, 40, 40, 56, 56, 56, 72, 72, 72, 10,
10, 10, 26, 26, 26, 42, 42, 42, 42, 58, 58, 58, 74, 74, 74, 12,
12, 12, 28, 28, 28, 28, 44, 44, 44, 60, 60, 60, 76, 76, 76, 14,
14, 14, 30, 30, 30, 30, 46, 46, 46, 62, 62, 62, 78, 78, 78, 78,
79, 79, 79, 79, 63, 63, 63, 47, 47, 47, 31, 31, 31, 31, 15, 15,
15, 77, 77, 77, 61, 61, 61, 45, 45, 45, 29, 29, 29, 29, 13, 13,
13, 75, 75, 75, 59, 59, 59, 43, 43, 43, 43, 27, 27, 27, 11, 11,
11, 73, 73, 73, 57, 57, 57, 41, 41, 41, 41, 25, 25, 25, 9, 9,
9, 71, 71, 71, 55, 55, 55, 55, 39, 39, 39, 23, 23, 23, 7, 7,
7, 69, 69, 69, 53, 53, 53, 53, 37, 37, 37, 21, 21, 21, 5, 5,
5, 67, 67, 67, 67, 51, 51, 51, 35, 35, 35, 19, 19, 19, 3, 3,
3, 65, 65, 65, 65, 49, 49, 49, 33, 33, 33, 17, 17, 17, 1, 1
},
{
0, 0, 32, 32, 64, 64, 64, 2, 2, 2, 34, 34, 66, 66, 66, 4,
4, 4, 36, 36, 68, 68, 68, 6, 6, 6, 38, 38, 70, 70, 70, 8,
8, 8, 40, 40, 40, 72, 72, 10, 10, 10, 42, 42, 42, 74, 74, 12,
12, 12, 44, 44, 44, 76, 76, 14, 14, 14, 46, 46, 46, 78, 78, 16,
{ // QUANT_96
0, 32, 32, 32, 64, 64, 64, 2, 2, 34, 34, 34, 66, 66, 66, 4,
4, 36, 36, 36, 68, 68, 68, 6, 6, 38, 38, 38, 70, 70, 70, 8,
8, 8, 40, 40, 72, 72, 72, 10, 10, 10, 42, 42, 74, 74, 74, 12,
12, 12, 44, 44, 76, 76, 76, 14, 14, 14, 46, 46, 78, 78, 78, 16,
16, 16, 48, 48, 48, 80, 80, 80, 18, 18, 50, 50, 50, 82, 82, 82,
20, 20, 52, 52, 52, 84, 84, 84, 22, 22, 54, 54, 54, 86, 86, 86,
24, 24, 56, 56, 56, 88, 88, 88, 26, 26, 58, 58, 58, 90, 90, 90,
@@ -566,20 +565,20 @@ const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] {
91, 91, 91, 59, 59, 59, 27, 27, 89, 89, 89, 57, 57, 57, 25, 25,
87, 87, 87, 55, 55, 55, 23, 23, 85, 85, 85, 53, 53, 53, 21, 21,
83, 83, 83, 51, 51, 51, 19, 19, 81, 81, 81, 49, 49, 49, 17, 17,
17, 79, 79, 47, 47, 47, 15, 15, 15, 77, 77, 45, 45, 45, 13, 13,
13, 75, 75, 43, 43, 43, 11, 11, 11, 73, 73, 41, 41, 41, 9, 9,
9, 71, 71, 71, 39, 39, 7, 7, 7, 69, 69, 69, 37, 37, 5, 5,
5, 67, 67, 67, 35, 35, 3, 3, 3, 65, 65, 65, 33, 33, 1, 1
17, 79, 79, 79, 47, 47, 15, 15, 15, 77, 77, 77, 45, 45, 13, 13,
13, 75, 75, 75, 43, 43, 11, 11, 11, 73, 73, 73, 41, 41, 9, 9,
9, 71, 71, 71, 39, 39, 39, 7, 7, 69, 69, 69, 37, 37, 37, 5,
5, 67, 67, 67, 35, 35, 35, 3, 3, 65, 65, 65, 33, 33, 33, 1
},
{
0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15,
16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31,
32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39,
40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47,
48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55,
56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63,
{ // QUANT_128
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24,
24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32,
32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40,
40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48,
48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56,
56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 63,
64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71,
72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79,
80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87,
@@ -589,25 +588,25 @@ const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] {
112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119,
120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 127, 127
},
{
0, 32, 32, 64, 96, 96, 128, 128, 2, 34, 34, 66, 98, 98, 130, 130,
4, 36, 36, 68, 100, 100, 132, 132, 6, 38, 38, 70, 102, 102, 134, 134,
8, 40, 40, 72, 104, 104, 136, 136, 10, 42, 42, 74, 106, 106, 138, 138,
12, 44, 44, 76, 108, 108, 140, 140, 14, 46, 46, 78, 110, 110, 142, 142,
16, 48, 48, 80, 112, 112, 144, 144, 18, 50, 50, 82, 114, 114, 146, 146,
20, 52, 52, 84, 116, 116, 148, 148, 22, 54, 54, 86, 118, 118, 150, 150,
24, 56, 56, 88, 120, 120, 152, 152, 26, 58, 58, 90, 122, 122, 154, 154,
28, 60, 60, 92, 124, 124, 156, 156, 30, 62, 62, 94, 126, 126, 158, 158,
159, 159, 127, 127, 95, 63, 63, 31, 157, 157, 125, 125, 93, 61, 61, 29,
155, 155, 123, 123, 91, 59, 59, 27, 153, 153, 121, 121, 89, 57, 57, 25,
151, 151, 119, 119, 87, 55, 55, 23, 149, 149, 117, 117, 85, 53, 53, 21,
147, 147, 115, 115, 83, 51, 51, 19, 145, 145, 113, 113, 81, 49, 49, 17,
143, 143, 111, 111, 79, 47, 47, 15, 141, 141, 109, 109, 77, 45, 45, 13,
139, 139, 107, 107, 75, 43, 43, 11, 137, 137, 105, 105, 73, 41, 41, 9,
135, 135, 103, 103, 71, 39, 39, 7, 133, 133, 101, 101, 69, 37, 37, 5,
131, 131, 99, 99, 67, 35, 35, 3, 129, 129, 97, 97, 65, 33, 33, 1
{ // QUANT_160
0, 32, 64, 64, 96, 128, 128, 128, 2, 34, 66, 66, 98, 130, 130, 130,
4, 36, 68, 68, 100, 132, 132, 132, 6, 38, 70, 70, 102, 134, 134, 134,
8, 40, 72, 72, 104, 136, 136, 136, 10, 42, 74, 74, 106, 138, 138, 138,
12, 44, 76, 76, 108, 140, 140, 140, 14, 46, 78, 78, 110, 142, 142, 142,
16, 48, 80, 80, 112, 144, 144, 144, 18, 50, 82, 82, 114, 146, 146, 146,
20, 52, 84, 84, 116, 148, 148, 148, 22, 54, 86, 86, 118, 150, 150, 150,
24, 56, 88, 88, 120, 152, 152, 152, 26, 58, 90, 90, 122, 154, 154, 154,
28, 60, 92, 92, 124, 156, 156, 156, 30, 62, 94, 94, 126, 158, 158, 158,
159, 159, 159, 127, 95, 95, 63, 31, 157, 157, 157, 125, 93, 93, 61, 29,
155, 155, 155, 123, 91, 91, 59, 27, 153, 153, 153, 121, 89, 89, 57, 25,
151, 151, 151, 119, 87, 87, 55, 23, 149, 149, 149, 117, 85, 85, 53, 21,
147, 147, 147, 115, 83, 83, 51, 19, 145, 145, 145, 113, 81, 81, 49, 17,
143, 143, 143, 111, 79, 79, 47, 15, 141, 141, 141, 109, 77, 77, 45, 13,
139, 139, 139, 107, 75, 75, 43, 11, 137, 137, 137, 105, 73, 73, 41, 9,
135, 135, 135, 103, 71, 71, 39, 7, 133, 133, 133, 101, 69, 69, 37, 5,
131, 131, 131, 99, 67, 67, 35, 3, 129, 129, 129, 97, 65, 65, 33, 1
},
{
{ // QUANT_192
0, 64, 128, 128, 2, 66, 130, 130, 4, 68, 132, 132, 6, 70, 134, 134,
8, 72, 136, 136, 10, 74, 138, 138, 12, 76, 140, 140, 14, 78, 142, 142,
16, 80, 144, 144, 18, 82, 146, 146, 20, 84, 148, 148, 22, 86, 150, 150,
@@ -625,7 +624,7 @@ const uint8_t color_uquant_to_scrambled_pquant_tables[17][256] {
143, 143, 79, 15, 141, 141, 77, 13, 139, 139, 75, 11, 137, 137, 73, 9,
135, 135, 71, 7, 133, 133, 69, 5, 131, 131, 67, 3, 129, 129, 65, 1
},
{
{ // QUANT_256
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2021 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -23,6 +23,50 @@
#include <cassert>
/**
* @brief Reverse bits in a byte.
*
* @param p The value to reverse.
*
* @return The reversed result.
*/
static inline int bitrev8(int p)
{
p = ((p & 0x0F) << 4) | ((p >> 4) & 0x0F);
p = ((p & 0x33) << 2) | ((p >> 2) & 0x33);
p = ((p & 0x55) << 1) | ((p >> 1) & 0x55);
return p;
}
/**
* @brief Read up to 8 bits at an arbitrary bit offset.
*
* The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may
* span two separate bytes in memory.
*
* @param bitcount The number of bits to read.
* @param bitoffset The bit offset to read from, between 0 and 7.
* @param[in,out] ptr The data pointer to read from.
*
* @return The read value.
*/
static inline int read_bits(
int bitcount,
int bitoffset,
const uint8_t* ptr
) {
int mask = (1 << bitcount) - 1;
ptr += bitoffset >> 3;
bitoffset &= 7;
int value = ptr[0] | (ptr[1] << 8);
value >>= bitoffset;
value &= mask;
return value;
}
#if !defined(ASTCENC_DECOMPRESS_ONLY)
/**
* @brief Write up to 8 bits at an arbitrary bit offset.
*
@@ -54,47 +98,6 @@ static inline void write_bits(
ptr[1] |= value >> 8;
}
/**
* @brief Read up to 8 bits at an arbitrary bit offset.
*
* The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may
* span two separate bytes in memory.
*
* @param bitcount The number of bits to read.
* @param bitoffset The bit offset to read from, between 0 and 7.
* @param[in,out] ptr The data pointer to read from.
*
* @return The read value.
*/
static inline int read_bits(
int bitcount,
int bitoffset,
const uint8_t* ptr
) {
int mask = (1 << bitcount) - 1;
ptr += bitoffset >> 3;
bitoffset &= 7;
int value = ptr[0] | (ptr[1] << 8);
value >>= bitoffset;
value &= mask;
return value;
}
/**
* @brief Reverse bits in a byte.
*
* @param p The value to reverse.
*
* @return The reversed result.
*/
static inline int bitrev8(int p)
{
p = ((p & 0x0F) << 4) | ((p >> 4) & 0x0F);
p = ((p & 0x33) << 2) | ((p >> 2) & 0x33);
p = ((p & 0x55) << 1) | ((p >> 1) & 0x55);
return p;
}
/* See header for documentation. */
void symbolic_to_physical(
const block_size_descriptor& bsd,
@@ -282,6 +285,8 @@ void symbolic_to_physical(
scb.partition_count == 1 ? 17 : 19 + PARTITION_INDEX_BITS);
}
#endif
/* See header for documentation. */
void physical_to_symbolic(
const block_size_descriptor& bsd,

View File

@@ -1046,7 +1046,7 @@ ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4& t0p)
*/
ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint4& t0p, vint4& t1p)
{
#if ASTCENC_SSE >= 30
#if ASTCENC_SSE >= 41
t0p = t0;
t1p = t0 ^ t1;
#else
@@ -1062,7 +1062,7 @@ ASTCENC_SIMD_INLINE void vtable_prepare(
vint4 t0, vint4 t1, vint4 t2, vint4 t3,
vint4& t0p, vint4& t1p, vint4& t2p, vint4& t3p)
{
#if ASTCENC_SSE >= 30
#if ASTCENC_SSE >= 41
t0p = t0;
t1p = t0 ^ t1;
t2p = t1 ^ t2;
@@ -1080,7 +1080,7 @@ ASTCENC_SIMD_INLINE void vtable_prepare(
*/
ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx)
{
#if ASTCENC_SSE >= 30
#if ASTCENC_SSE >= 41
// Set index byte MSB to 1 for unused bytes so shuffle returns zero
__m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
@@ -1102,7 +1102,7 @@ ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx)
*/
ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx)
{
#if ASTCENC_SSE >= 30
#if ASTCENC_SSE >= 41
// Set index byte MSB to 1 for unused bytes so shuffle returns zero
__m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
@@ -1130,7 +1130,7 @@ ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx)
*/
ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 t2, vint4 t3, vint4 idx)
{
#if ASTCENC_SSE >= 30
#if ASTCENC_SSE >= 41
// Set index byte MSB to 1 for unused bytes so shuffle returns zero
__m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2011-2022 Arm Limited
// Copyright 2011-2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -353,7 +353,7 @@ void compute_angular_endpoints_1plane(
for (unsigned int i = 0; i < max_decimation_modes; i++)
{
const decimation_mode& dm = bsd.decimation_modes[i];
if (!dm.is_ref_1_plane(static_cast<quant_method>(max_weight_quant)))
if (!dm.is_ref_1plane(static_cast<quant_method>(max_weight_quant)))
{
continue;
}
@@ -422,7 +422,7 @@ void compute_angular_endpoints_2planes(
for (unsigned int i = 0; i < bsd.decimation_mode_count_selected; i++)
{
const decimation_mode& dm = bsd.decimation_modes[i];
if (!dm.is_ref_2_plane(static_cast<quant_method>(max_weight_quant)))
if (!dm.is_ref_2plane(static_cast<quant_method>(max_weight_quant)))
{
continue;
}