mirror of
https://github.com/bkaradzic/bimg.git
synced 2026-02-17 20:52:38 +01:00
Updated astc-encoder.
This commit is contained in:
@@ -1006,7 +1006,7 @@ static void construct_block_size_descriptor_2d(
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocate block modes and decimation tables for a single £D block size.
|
||||
* @brief Allocate block modes and decimation tables for a single 3D block size.
|
||||
*
|
||||
* TODO: This function doesn't include all of the heuristics that we use for 2D block sizes such as
|
||||
* the percentile mode cutoffs. If 3D becomes more widely used we should look at this.
|
||||
|
||||
@@ -40,24 +40,6 @@
|
||||
|
||||
#include "astcenc_internal.h"
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* @return The encoded quantized value. These are not necessarily in order; the compressor
|
||||
* scrambles the values slightly to make hardware implementation easier.
|
||||
*/
|
||||
static inline int quant_color_clamp(
|
||||
quant_method quant_level,
|
||||
int value
|
||||
) {
|
||||
value = astc::clamp(value, 0, 255);
|
||||
return color_quant_tables[quant_level - QUANT_6][value];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine the quantized value given a quantization level.
|
||||
*
|
||||
@@ -72,23 +54,7 @@ static inline uint8_t quant_color(
|
||||
quant_method quant_level,
|
||||
int value
|
||||
) {
|
||||
return color_quant_tables[quant_level - QUANT_6][value];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine the unquantized value given a quantization level.
|
||||
*
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param value The value to convert.
|
||||
*
|
||||
* @return The encoded quantized value. These are not necessarily in order; the compressor
|
||||
* scrambles the values slightly to make hardware implementation easier.
|
||||
*/
|
||||
static inline uint8_t unquant_color(
|
||||
quant_method quant_level,
|
||||
int value
|
||||
) {
|
||||
return color_unquant_tables[quant_level - QUANT_6][value];
|
||||
return color_unquant_to_uquant_tables[quant_level - QUANT_6][value];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,28 +86,20 @@ static void quantize_rgb(
|
||||
float b1 = astc::clamp255f(color1.lane<2>() * scale);
|
||||
|
||||
int ri0, gi0, bi0, ri1, gi1, bi1;
|
||||
int ri0b, gi0b, bi0b, ri1b, gi1b, bi1b;
|
||||
float rgb0_addon = 0.5f;
|
||||
float rgb1_addon = 0.5f;
|
||||
do
|
||||
{
|
||||
ri0 = quant_color_clamp(quant_level, astc::flt2int_rd(r0 + rgb0_addon));
|
||||
gi0 = quant_color_clamp(quant_level, astc::flt2int_rd(g0 + rgb0_addon));
|
||||
bi0 = quant_color_clamp(quant_level, astc::flt2int_rd(b0 + rgb0_addon));
|
||||
ri1 = quant_color_clamp(quant_level, astc::flt2int_rd(r1 + rgb1_addon));
|
||||
gi1 = quant_color_clamp(quant_level, astc::flt2int_rd(g1 + rgb1_addon));
|
||||
bi1 = quant_color_clamp(quant_level, astc::flt2int_rd(b1 + rgb1_addon));
|
||||
|
||||
ri0b = unquant_color(quant_level, ri0);
|
||||
gi0b = unquant_color(quant_level, gi0);
|
||||
bi0b = unquant_color(quant_level, bi0);
|
||||
ri1b = unquant_color(quant_level, ri1);
|
||||
gi1b = unquant_color(quant_level, gi1);
|
||||
bi1b = unquant_color(quant_level, bi1);
|
||||
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));
|
||||
|
||||
rgb0_addon -= 0.2f;
|
||||
rgb1_addon += 0.2f;
|
||||
} while (ri0b + gi0b + bi0b > ri1b + gi1b + bi1b);
|
||||
} while (ri0 + gi0 + bi0 > ri1 + gi1 + bi1);
|
||||
|
||||
output[0] = static_cast<uint8_t>(ri0);
|
||||
output[1] = static_cast<uint8_t>(ri1);
|
||||
@@ -230,18 +188,9 @@ static bool try_quantize_rgb_blue_contract(
|
||||
int gi1 = quant_color(quant_level, astc::flt2int_rtn(g1));
|
||||
int bi1 = quant_color(quant_level, astc::flt2int_rtn(b1));
|
||||
|
||||
// Then unquantize again
|
||||
int ru0 = unquant_color(quant_level, ri0);
|
||||
int gu0 = unquant_color(quant_level, gi0);
|
||||
int bu0 = unquant_color(quant_level, bi0);
|
||||
|
||||
int ru1 = unquant_color(quant_level, ri1);
|
||||
int gu1 = unquant_color(quant_level, gi1);
|
||||
int bu1 = unquant_color(quant_level, bi1);
|
||||
|
||||
// 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 aftwards.
|
||||
if (ru1 + gu1 + bu1 <= ru0 + gu0 + bu0)
|
||||
// blue-contraction and quantization change this order, which is why we must test afterwards.
|
||||
if (ri1 + gi1 + bi1 <= ri0 + gi0 + bi0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -334,13 +283,9 @@ static bool try_quantize_rgb_delta(
|
||||
int g0be = quant_color(quant_level, g0b);
|
||||
int b0be = quant_color(quant_level, b0b);
|
||||
|
||||
int r0bu = unquant_color(quant_level, r0be);
|
||||
int g0bu = unquant_color(quant_level, g0be);
|
||||
int b0bu = unquant_color(quant_level, b0be);
|
||||
|
||||
r0b = r0bu | (r0a & 0x100);
|
||||
g0b = g0bu | (g0a & 0x100);
|
||||
b0b = b0bu | (b0a & 0x100);
|
||||
r0b = r0be | (r0a & 0x100);
|
||||
g0b = g0be | (g0a & 0x100);
|
||||
b0b = b0be | (b0a & 0x100);
|
||||
|
||||
// Get hold of the second value
|
||||
int r1d = astc::flt2int_rtn(r1);
|
||||
@@ -377,18 +322,14 @@ static bool try_quantize_rgb_delta(
|
||||
int g1de = quant_color(quant_level, g1d);
|
||||
int b1de = quant_color(quant_level, b1d);
|
||||
|
||||
int r1du = unquant_color(quant_level, r1de);
|
||||
int g1du = unquant_color(quant_level, g1de);
|
||||
int b1du = unquant_color(quant_level, b1de);
|
||||
|
||||
if (((r1d ^ r1du) | (g1d ^ g1du) | (b1d ^ b1du)) & 0xC0)
|
||||
if (((r1d ^ r1de) | (g1d ^ g1de) | (b1d ^ b1de)) & 0xC0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the sum of offsets triggers blue-contraction then encoding fails
|
||||
vint4 ep0(r0bu, g0bu, b0bu, 0);
|
||||
vint4 ep1(r1du, g1du, b1du, 0);
|
||||
vint4 ep0(r0be, g0be, b0be, 0);
|
||||
vint4 ep1(r1de, g1de, b1de, 0);
|
||||
bit_transfer_signed(ep1, ep0);
|
||||
if (hadd_rgb_s(ep1) < 0)
|
||||
{
|
||||
@@ -459,13 +400,9 @@ static bool try_quantize_rgb_delta_blue_contract(
|
||||
int g0be = quant_color(quant_level, g0b);
|
||||
int b0be = quant_color(quant_level, b0b);
|
||||
|
||||
int r0bu = unquant_color(quant_level, r0be);
|
||||
int g0bu = unquant_color(quant_level, g0be);
|
||||
int b0bu = unquant_color(quant_level, b0be);
|
||||
|
||||
r0b = r0bu | (r0a & 0x100);
|
||||
g0b = g0bu | (g0a & 0x100);
|
||||
b0b = b0bu | (b0a & 0x100);
|
||||
r0b = r0be | (r0a & 0x100);
|
||||
g0b = g0be | (g0a & 0x100);
|
||||
b0b = b0be | (b0a & 0x100);
|
||||
|
||||
// Get hold of the second value
|
||||
int r1d = astc::flt2int_rtn(r1);
|
||||
@@ -503,18 +440,14 @@ static bool try_quantize_rgb_delta_blue_contract(
|
||||
int g1de = quant_color(quant_level, g1d);
|
||||
int b1de = quant_color(quant_level, b1d);
|
||||
|
||||
int r1du = unquant_color(quant_level, r1de);
|
||||
int g1du = unquant_color(quant_level, g1de);
|
||||
int b1du = unquant_color(quant_level, b1de);
|
||||
|
||||
if (((r1d ^ r1du) | (g1d ^ g1du) | (b1d ^ b1du)) & 0xC0)
|
||||
if (((r1d ^ r1de) | (g1d ^ g1de) | (b1d ^ b1de)) & 0xC0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the sum of offsets does not trigger blue-contraction then encoding fails
|
||||
vint4 ep0(r0bu, g0bu, b0bu, 0);
|
||||
vint4 ep1(r1du, g1du, b1du, 0);
|
||||
vint4 ep0(r0be, g0be, b0be, 0);
|
||||
vint4 ep1(r1de, g1de, b1de, 0);
|
||||
bit_transfer_signed(ep1, ep0);
|
||||
if (hadd_rgb_s(ep1) >= 0)
|
||||
{
|
||||
@@ -569,7 +502,7 @@ static bool try_quantize_alpha_delta(
|
||||
a0a <<= 1;
|
||||
int a0b = a0a & 0xFF;
|
||||
int a0be = quant_color(quant_level, a0b);
|
||||
a0b = unquant_color(quant_level, a0be);
|
||||
a0b = a0be;
|
||||
a0b |= a0a & 0x100;
|
||||
int a1d = astc::flt2int_rtn(a1);
|
||||
a1d <<= 1;
|
||||
@@ -584,7 +517,7 @@ static bool try_quantize_alpha_delta(
|
||||
a1d |= (a0b & 0x100) >> 1;
|
||||
|
||||
int a1de = quant_color(quant_level, a1d);
|
||||
int a1du = unquant_color(quant_level, a1de);
|
||||
int a1du = a1de;
|
||||
if ((a1d ^ a1du) & 0xC0)
|
||||
{
|
||||
return false;
|
||||
@@ -647,8 +580,8 @@ static bool try_quantize_luminance_alpha_delta(
|
||||
int a0b = a0a & 0xFF;
|
||||
int l0be = quant_color(quant_level, l0b);
|
||||
int a0be = quant_color(quant_level, a0b);
|
||||
l0b = unquant_color(quant_level, l0be);
|
||||
a0b = unquant_color(quant_level, a0be);
|
||||
l0b = l0be;
|
||||
a0b = a0be;
|
||||
l0b |= l0a & 0x100;
|
||||
a0b |= a0a & 0x100;
|
||||
|
||||
@@ -676,8 +609,8 @@ static bool try_quantize_luminance_alpha_delta(
|
||||
|
||||
int l1de = quant_color(quant_level, l1d);
|
||||
int a1de = quant_color(quant_level, a1d);
|
||||
int l1du = unquant_color(quant_level, l1de);
|
||||
int a1du = unquant_color(quant_level, a1de);
|
||||
int l1du = l1de;
|
||||
int a1du = a1de;
|
||||
|
||||
if ((l1d ^ l1du) & 0xC0)
|
||||
{
|
||||
@@ -799,12 +732,8 @@ static void quantize_rgbs(
|
||||
int gi = quant_color(quant_level, astc::flt2int_rtn(g));
|
||||
int bi = quant_color(quant_level, astc::flt2int_rtn(b));
|
||||
|
||||
int ru = unquant_color(quant_level, ri);
|
||||
int gu = unquant_color(quant_level, gi);
|
||||
int bu = unquant_color(quant_level, bi);
|
||||
|
||||
float oldcolorsum = hadd_rgb_s(color) * scale;
|
||||
float newcolorsum = static_cast<float>(ru + gu + bu);
|
||||
float newcolorsum = static_cast<float>(ri + gi + bi);
|
||||
|
||||
float scalea = astc::clamp1f(color.lane<3>() * (oldcolorsum + 1e-10f) / (newcolorsum + 1e-10f));
|
||||
int scale_idx = astc::flt2int_rtn(scalea * 256.0f);
|
||||
@@ -949,33 +878,29 @@ static void quantize_luminance_alpha(
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param value The input unquantized value.
|
||||
* @param[out] quant_value The quantized value.
|
||||
* @param[out] unquant_value The unquantized value after quantization.
|
||||
*/
|
||||
static inline void quantize_and_unquantize_retain_top_two_bits(
|
||||
quant_method quant_level,
|
||||
uint8_t value,
|
||||
uint8_t& quant_value,
|
||||
uint8_t& unquant_value
|
||||
uint8_t& quant_value
|
||||
) {
|
||||
int perform_loop;
|
||||
uint8_t quantval;
|
||||
uint8_t uquantval;
|
||||
|
||||
do
|
||||
{
|
||||
quantval = quant_color(quant_level, value);
|
||||
uquantval = unquant_color(quant_level, quantval);
|
||||
|
||||
// Perform looping if the top two bits were modified by quant/unquant
|
||||
perform_loop = (value & 0xC0) != (uquantval & 0xC0);
|
||||
perform_loop = (value & 0xC0) != (quantval & 0xC0);
|
||||
|
||||
if ((uquantval & 0xC0) > (value & 0xC0))
|
||||
if ((quantval & 0xC0) > (value & 0xC0))
|
||||
{
|
||||
// Quant/unquant rounded UP so that the top two bits changed;
|
||||
// decrement the input in hopes that this will avoid rounding up.
|
||||
value--;
|
||||
}
|
||||
else if ((uquantval & 0xC0) < (value & 0xC0))
|
||||
else if ((quantval & 0xC0) < (value & 0xC0))
|
||||
{
|
||||
// Quant/unquant rounded DOWN so that the top two bits changed;
|
||||
// decrement the input in hopes that this will avoid rounding down.
|
||||
@@ -984,7 +909,6 @@ static inline void quantize_and_unquantize_retain_top_two_bits(
|
||||
} while (perform_loop);
|
||||
|
||||
quant_value = quantval;
|
||||
unquant_value = uquantval;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -992,34 +916,29 @@ static inline void quantize_and_unquantize_retain_top_two_bits(
|
||||
*
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param value The input unquantized value.
|
||||
* @param[out] quant_value The quantized value.
|
||||
* @param[out] unquant_value The unquantized value after quantization.
|
||||
* @param[out] quant_value The quantized value in 0-255 range.
|
||||
*/
|
||||
static inline void quantize_and_unquantize_retain_top_four_bits(
|
||||
quant_method quant_level,
|
||||
uint8_t value,
|
||||
uint8_t& quant_value,
|
||||
uint8_t& unquant_value
|
||||
uint8_t& quant_value
|
||||
) {
|
||||
uint8_t perform_loop;
|
||||
uint8_t quantval;
|
||||
uint8_t uquantval;
|
||||
|
||||
do
|
||||
{
|
||||
quantval = quant_color(quant_level, value);
|
||||
uquantval = unquant_color(quant_level, quantval);
|
||||
|
||||
// Perform looping if the top four bits were modified by quant/unquant
|
||||
perform_loop = (value & 0xF0) != (uquantval & 0xF0);
|
||||
perform_loop = (value & 0xF0) != (quantval & 0xF0);
|
||||
|
||||
if ((uquantval & 0xF0) > (value & 0xF0))
|
||||
if ((quantval & 0xF0) > (value & 0xF0))
|
||||
{
|
||||
// Quant/unquant rounded UP so that the top four bits changed;
|
||||
// decrement the input value in hopes that this will avoid rounding up.
|
||||
value--;
|
||||
}
|
||||
else if ((uquantval & 0xF0) < (value & 0xF0))
|
||||
else if ((quantval & 0xF0) < (value & 0xF0))
|
||||
{
|
||||
// Quant/unquant rounded DOWN so that the top four bits changed;
|
||||
// decrement the input value in hopes that this will avoid rounding down.
|
||||
@@ -1028,7 +947,6 @@ static inline void quantize_and_unquantize_retain_top_four_bits(
|
||||
} while (perform_loop);
|
||||
|
||||
quant_value = quantval;
|
||||
unquant_value = uquantval;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1139,11 +1057,10 @@ static void quantize_hdr_rgbo(
|
||||
r_lowbits |= (mode_enc & 3) << 6;
|
||||
|
||||
uint8_t r_quantval;
|
||||
uint8_t r_uquantval;
|
||||
quantize_and_unquantize_retain_top_two_bits(
|
||||
quant_level, static_cast<uint8_t>(r_lowbits), r_quantval, r_uquantval);
|
||||
quant_level, static_cast<uint8_t>(r_lowbits), r_quantval);
|
||||
|
||||
r_intval = (r_intval & ~0x3f) | (r_uquantval & 0x3f);
|
||||
r_intval = (r_intval & ~0x3f) | (r_quantval & 0x3f);
|
||||
float r_fval = static_cast<float>(r_intval) * mode_rscale;
|
||||
|
||||
// Recompute G and B, then quantize and unquantize them
|
||||
@@ -1239,16 +1156,14 @@ static void quantize_hdr_rgbo(
|
||||
|
||||
uint8_t g_quantval;
|
||||
uint8_t b_quantval;
|
||||
uint8_t g_uquantval;
|
||||
uint8_t b_uquantval;
|
||||
|
||||
quantize_and_unquantize_retain_top_four_bits(
|
||||
quant_level, static_cast<uint8_t>(g_lowbits), g_quantval, g_uquantval);
|
||||
quant_level, static_cast<uint8_t>(g_lowbits), g_quantval);
|
||||
quantize_and_unquantize_retain_top_four_bits(
|
||||
quant_level, static_cast<uint8_t>(b_lowbits), b_quantval, b_uquantval);
|
||||
quant_level, static_cast<uint8_t>(b_lowbits), b_quantval);
|
||||
|
||||
g_intval = (g_intval & ~0x1f) | (g_uquantval & 0x1f);
|
||||
b_intval = (b_intval & ~0x1f) | (b_uquantval & 0x1f);
|
||||
g_intval = (g_intval & ~0x1f) | (g_quantval & 0x1f);
|
||||
b_intval = (b_intval & ~0x1f) | (b_quantval & 0x1f);
|
||||
|
||||
g_fval = static_cast<float>(g_intval) * mode_rscale;
|
||||
b_fval = static_cast<float>(b_intval) * mode_rscale;
|
||||
@@ -1312,10 +1227,9 @@ static void quantize_hdr_rgbo(
|
||||
s_lowbits |= bit4 << 7;
|
||||
|
||||
uint8_t s_quantval;
|
||||
uint8_t s_uquantval;
|
||||
|
||||
quantize_and_unquantize_retain_top_four_bits(
|
||||
quant_level, static_cast<uint8_t>(s_lowbits), s_quantval, s_uquantval);
|
||||
quant_level, static_cast<uint8_t>(s_lowbits), s_quantval);
|
||||
|
||||
output[0] = r_quantval;
|
||||
output[1] = g_quantval;
|
||||
@@ -1355,9 +1269,8 @@ static void quantize_hdr_rgbo(
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
{
|
||||
uint8_t dummy;
|
||||
quantize_and_unquantize_retain_top_four_bits(
|
||||
quant_level, static_cast<uint8_t>(encvals[i]), output[i], dummy);
|
||||
quant_level, static_cast<uint8_t>(encvals[i]), output[i]);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -1497,7 +1410,7 @@ static void quantize_hdr_rgb(
|
||||
int a_lowbits = a_intval & 0xFF;
|
||||
|
||||
int a_quantval = quant_color(quant_level, a_lowbits);
|
||||
int a_uquantval = unquant_color(quant_level, a_quantval);
|
||||
int a_uquantval = a_quantval;
|
||||
a_intval = (a_intval & ~0xFF) | a_uquantval;
|
||||
float a_fval = static_cast<float>(a_intval) * mode_rscale;
|
||||
|
||||
@@ -1518,12 +1431,11 @@ static void quantize_hdr_rgb(
|
||||
c_lowbits |= (a_intval & 0x100) >> 2;
|
||||
|
||||
uint8_t c_quantval;
|
||||
uint8_t c_uquantval;
|
||||
|
||||
quantize_and_unquantize_retain_top_two_bits(
|
||||
quant_level, static_cast<uint8_t>(c_lowbits), c_quantval, c_uquantval);
|
||||
quant_level, static_cast<uint8_t>(c_lowbits), c_quantval);
|
||||
|
||||
c_intval = (c_intval & ~0x3F) | (c_uquantval & 0x3F);
|
||||
c_intval = (c_intval & ~0x3F) | (c_quantval & 0x3F);
|
||||
c_fval = static_cast<float>(c_intval) * mode_rscale;
|
||||
|
||||
// Recompute B0 and B1, then quantize and unquantize them
|
||||
@@ -1587,16 +1499,14 @@ static void quantize_hdr_rgb(
|
||||
|
||||
uint8_t b0_quantval;
|
||||
uint8_t b1_quantval;
|
||||
uint8_t b0_uquantval;
|
||||
uint8_t b1_uquantval;
|
||||
|
||||
quantize_and_unquantize_retain_top_two_bits(
|
||||
quant_level, static_cast<uint8_t>(b0_lowbits), b0_quantval, b0_uquantval);
|
||||
quant_level, static_cast<uint8_t>(b0_lowbits), b0_quantval);
|
||||
quantize_and_unquantize_retain_top_two_bits(
|
||||
quant_level, static_cast<uint8_t>(b1_lowbits), b1_quantval, b1_uquantval);
|
||||
quant_level, static_cast<uint8_t>(b1_lowbits), b1_quantval);
|
||||
|
||||
b0_intval = (b0_intval & ~0x3f) | (b0_uquantval & 0x3f);
|
||||
b1_intval = (b1_intval & ~0x3f) | (b1_uquantval & 0x3f);
|
||||
b0_intval = (b0_intval & ~0x3f) | (b0_quantval & 0x3f);
|
||||
b1_intval = (b1_intval & ~0x3f) | (b1_quantval & 0x3f);
|
||||
b0_fval = static_cast<float>(b0_intval) * mode_rscale;
|
||||
b1_fval = static_cast<float>(b1_intval) * mode_rscale;
|
||||
|
||||
@@ -1684,13 +1594,11 @@ static void quantize_hdr_rgb(
|
||||
|
||||
uint8_t d0_quantval;
|
||||
uint8_t d1_quantval;
|
||||
uint8_t d0_uquantval;
|
||||
uint8_t d1_uquantval;
|
||||
|
||||
quantize_and_unquantize_retain_top_four_bits(
|
||||
quant_level, static_cast<uint8_t>(d0_lowbits), d0_quantval, d0_uquantval);
|
||||
quant_level, static_cast<uint8_t>(d0_lowbits), d0_quantval);
|
||||
quantize_and_unquantize_retain_top_four_bits(
|
||||
quant_level, static_cast<uint8_t>(d1_lowbits), d1_quantval, d1_uquantval);
|
||||
quant_level, static_cast<uint8_t>(d1_lowbits), d1_quantval);
|
||||
|
||||
output[0] = static_cast<uint8_t>(a_quantval);
|
||||
output[1] = c_quantval;
|
||||
@@ -1726,10 +1634,9 @@ static void quantize_hdr_rgb(
|
||||
|
||||
for (int i = 4; i < 6; i++)
|
||||
{
|
||||
uint8_t dummy;
|
||||
int idx = astc::flt2int_rtn(vals[i] * 1.0f / 512.0f) + 128;
|
||||
quantize_and_unquantize_retain_top_two_bits(
|
||||
quant_level, static_cast<uint8_t>(idx), output[i], dummy);
|
||||
quant_level, static_cast<uint8_t>(idx), output[i]);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -1881,7 +1788,7 @@ static bool try_quantize_hdr_luminance_small_range(
|
||||
|
||||
v0 = lowval & 0x7F;
|
||||
v0e = quant_color(quant_level, v0);
|
||||
v0d = unquant_color(quant_level, v0e);
|
||||
v0d = v0e;
|
||||
|
||||
if (v0d < 0x80)
|
||||
{
|
||||
@@ -1891,7 +1798,7 @@ static bool try_quantize_hdr_luminance_small_range(
|
||||
{
|
||||
v1 = ((lowval >> 3) & 0xF0) | diffval;
|
||||
v1e = quant_color(quant_level, v1);
|
||||
v1d = unquant_color(quant_level, v1e);
|
||||
v1d = v1e;
|
||||
if ((v1d & 0xF0) == (v1 & 0xF0))
|
||||
{
|
||||
output[0] = static_cast<uint8_t>(v0e);
|
||||
@@ -1910,7 +1817,7 @@ static bool try_quantize_hdr_luminance_small_range(
|
||||
|
||||
v0 = (lowval & 0x7F) | 0x80;
|
||||
v0e = quant_color(quant_level, v0);
|
||||
v0d = unquant_color(quant_level, v0e);
|
||||
v0d = v0e;
|
||||
if ((v0d & 0x80) == 0)
|
||||
{
|
||||
return false;
|
||||
@@ -1925,7 +1832,7 @@ static bool try_quantize_hdr_luminance_small_range(
|
||||
|
||||
v1 = ((lowval >> 2) & 0xE0) | diffval;
|
||||
v1e = quant_color(quant_level, v1);
|
||||
v1d = unquant_color(quant_level, v1e);
|
||||
v1d = v1e;
|
||||
if ((v1d & 0xE0) != (v1 & 0xE0))
|
||||
{
|
||||
return false;
|
||||
@@ -1969,7 +1876,7 @@ static void quantize_hdr_alpha(
|
||||
|
||||
v6 = (val0 & 0x7F) | ((i & 1) << 7);
|
||||
v6e = quant_color(quant_level, v6);
|
||||
v6d = unquant_color(quant_level, v6e);
|
||||
v6d = v6e;
|
||||
|
||||
if ((v6 ^ v6d) & 0x80)
|
||||
{
|
||||
@@ -1988,7 +1895,7 @@ static void quantize_hdr_alpha(
|
||||
|
||||
v7 = ((i & 2) << 6) | ((val0 >> 7) << (6 - i)) | (diffval & mask);
|
||||
v7e = quant_color(quant_level, v7);
|
||||
v7d = unquant_color(quant_level, v7e);
|
||||
v7d = v7e;
|
||||
|
||||
static const int testbits[3] { 0xE0, 0xF0, 0xF8 };
|
||||
|
||||
|
||||
@@ -23,43 +23,6 @@
|
||||
|
||||
#include "astcenc_internal.h"
|
||||
|
||||
/**
|
||||
* @brief Unquantize a color.
|
||||
*
|
||||
* This function uses a lookup table as the quantization is encoded to make
|
||||
* hardware implementations easier, and is not a simple lerp.
|
||||
*
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param inputq The input quantized color.
|
||||
*
|
||||
* @return The unquantized color.
|
||||
*/
|
||||
static ASTCENC_SIMD_INLINE vint4 unquant_color(
|
||||
quant_method quant_level,
|
||||
vint4 inputq
|
||||
) {
|
||||
const uint8_t* unq = color_unquant_tables[quant_level - QUANT_6];
|
||||
return vint4(unq[inputq.lane<0>()], unq[inputq.lane<1>()],
|
||||
unq[inputq.lane<2>()], unq[inputq.lane<3>()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* @return The encoded quantized value. These are not necessarily in order; the compressor
|
||||
* scrambles the values slightly to make hardware implementation easier.
|
||||
*/
|
||||
static inline uint8_t unquant_color(
|
||||
quant_method quant_level,
|
||||
int value
|
||||
) {
|
||||
return color_unquant_tables[quant_level - QUANT_6][value];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Un-blue-contract a color.
|
||||
*
|
||||
@@ -80,23 +43,17 @@ static ASTCENC_SIMD_INLINE vint4 uncontract_color(
|
||||
/**
|
||||
* @brief Unpack an LDR RGBA color that uses delta encoding.
|
||||
*
|
||||
* @param input0q The raw quantized endpoint 0 color.
|
||||
* @param input1q The raw quantized endpoint 1 color deltas.
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input0 The packed endpoint 0 color.
|
||||
* @param input1 The packed endpoint 1 color deltas.
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void rgba_delta_unpack(
|
||||
vint4 input0q,
|
||||
vint4 input1q,
|
||||
quant_method quant_level,
|
||||
vint4 input0,
|
||||
vint4 input1,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
// Unquantize color endpoints
|
||||
vint4 input0 = unquant_color(quant_level, input0q);
|
||||
vint4 input1 = unquant_color(quant_level, input1q);
|
||||
|
||||
// Apply bit transfer
|
||||
bit_transfer_signed(input1, input0);
|
||||
|
||||
@@ -119,20 +76,18 @@ static void rgba_delta_unpack(
|
||||
*
|
||||
* Output alpha set to 255.
|
||||
*
|
||||
* @param input0q The raw quantized endpoint 0 color.
|
||||
* @param input1q The raw quantized endpoint 1 color deltas.
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input0 The packed endpoint 0 color.
|
||||
* @param input1 The packed endpoint 1 color deltas.
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void rgb_delta_unpack(
|
||||
vint4 input0q,
|
||||
vint4 input1q,
|
||||
quant_method quant_level,
|
||||
vint4 input0,
|
||||
vint4 input1,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
rgba_delta_unpack(input0q, input1q, quant_level, output0, output1);
|
||||
rgba_delta_unpack(input0, input1, output0, output1);
|
||||
output0.set_lane<3>(255);
|
||||
output1.set_lane<3>(255);
|
||||
}
|
||||
@@ -140,23 +95,17 @@ static void rgb_delta_unpack(
|
||||
/**
|
||||
* @brief Unpack an LDR RGBA color that uses direct encoding.
|
||||
*
|
||||
* @param input0q The raw quantized endpoint 0 color.
|
||||
* @param input1q The raw quantized endpoint 1 color.
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input0 The packed endpoint 0 color.
|
||||
* @param input1 The packed endpoint 1 color.
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void rgba_unpack(
|
||||
vint4 input0q,
|
||||
vint4 input1q,
|
||||
quant_method quant_level,
|
||||
vint4 input0,
|
||||
vint4 input1,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
// Unquantize color endpoints
|
||||
vint4 input0 = unquant_color(quant_level, input0q);
|
||||
vint4 input1 = unquant_color(quant_level, input1q);
|
||||
|
||||
// Apply blue-uncontraction if needed
|
||||
if (hadd_rgb_s(input0) > hadd_rgb_s(input1))
|
||||
{
|
||||
@@ -174,20 +123,18 @@ static void rgba_unpack(
|
||||
*
|
||||
* Output alpha set to 255.
|
||||
*
|
||||
* @param input0q The raw quantized endpoint 0 color.
|
||||
* @param input1q The raw quantized endpoint 1 color.
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input0 The packed endpoint 0 color.
|
||||
* @param input1 The packed endpoint 1 color.
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void rgb_unpack(
|
||||
vint4 input0q,
|
||||
vint4 input1q,
|
||||
quant_method quant_level,
|
||||
vint4 input0,
|
||||
vint4 input1,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
rgba_unpack(input0q, input1q, quant_level, output0, output1);
|
||||
rgba_unpack(input0, input1, output0, output1);
|
||||
output0.set_lane<3>(255);
|
||||
output1.set_lane<3>(255);
|
||||
}
|
||||
@@ -197,31 +144,24 @@ static void rgb_unpack(
|
||||
*
|
||||
* Note only the RGB channels use the scaled encoding, alpha uses direct.
|
||||
*
|
||||
* @param input0q The raw quantized endpoint 0 color.
|
||||
* @param alpha1q The raw quantized endpoint 1 alpha value.
|
||||
* @param scaleq The raw quantized scale.
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input0 The packed endpoint 0 color.
|
||||
* @param alpha1 The packed endpoint 1 alpha value.
|
||||
* @param scale The packed quantized scale.
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void rgb_scale_alpha_unpack(
|
||||
vint4 input0q,
|
||||
uint8_t alpha1q,
|
||||
uint8_t scaleq,
|
||||
quant_method quant_level,
|
||||
vint4 input0,
|
||||
uint8_t alpha1,
|
||||
uint8_t scale,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
// Unquantize color endpoints
|
||||
vint4 input = unquant_color(quant_level, input0q);
|
||||
uint8_t alpha1 = unquant_color(quant_level, alpha1q);
|
||||
uint8_t scale = unquant_color(quant_level, scaleq);
|
||||
|
||||
output1 = input;
|
||||
output1 = input0;
|
||||
output1.set_lane<3>(alpha1);
|
||||
|
||||
output0 = asr<8>(input * scale);
|
||||
output0.set_lane<3>(input.lane<3>());
|
||||
output0 = asr<8>(input0 * scale);
|
||||
output0.set_lane<3>(input0.lane<3>());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -229,26 +169,21 @@ static void rgb_scale_alpha_unpack(
|
||||
*
|
||||
* Output alpha is 255.
|
||||
*
|
||||
* @param input0q The raw quantized endpoint 0 color.
|
||||
* @param scaleq The raw quantized scale.
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input0 The packed endpoint 0 color.
|
||||
* @param scale The packed scale.
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void rgb_scale_unpack(
|
||||
vint4 input0q,
|
||||
int scaleq,
|
||||
quant_method quant_level,
|
||||
vint4 input0,
|
||||
int scale,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
vint4 input = unquant_color(quant_level, input0q);
|
||||
int scale = unquant_color(quant_level, scaleq);
|
||||
|
||||
output1 = input;
|
||||
output1 = input0;
|
||||
output1.set_lane<3>(255);
|
||||
|
||||
output0 = asr<8>(input * scale);
|
||||
output0 = asr<8>(input0 * scale);
|
||||
output0.set_lane<3>(255);
|
||||
}
|
||||
|
||||
@@ -257,19 +192,17 @@ static void rgb_scale_unpack(
|
||||
*
|
||||
* Output alpha is 255.
|
||||
*
|
||||
* @param input The raw quantized endpoints.
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input The packed endpoints.
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void luminance_unpack(
|
||||
const uint8_t input[2],
|
||||
quant_method quant_level,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
int lum0 = unquant_color(quant_level, input[0]);
|
||||
int lum1 = unquant_color(quant_level, input[1]);
|
||||
int lum0 = input[0];
|
||||
int lum1 = input[1];
|
||||
output0 = vint4(lum0, lum0, lum0, 255);
|
||||
output1 = vint4(lum1, lum1, lum1, 255);
|
||||
}
|
||||
@@ -279,19 +212,17 @@ static void luminance_unpack(
|
||||
*
|
||||
* Output alpha is 255.
|
||||
*
|
||||
* @param input The raw quantized endpoints (L0, L1).
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input The packed endpoints (L0, L1).
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void luminance_delta_unpack(
|
||||
const uint8_t input[2],
|
||||
quant_method quant_level,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
int v0 = unquant_color(quant_level, input[0]);
|
||||
int v1 = unquant_color(quant_level, input[1]);
|
||||
int v0 = input[0];
|
||||
int v1 = input[1];
|
||||
int l0 = (v0 >> 2) | (v1 & 0xC0);
|
||||
int l1 = l0 + (v1 & 0x3F);
|
||||
|
||||
@@ -304,21 +235,19 @@ static void luminance_delta_unpack(
|
||||
/**
|
||||
* @brief Unpack an LDR LA color that uses direct encoding.
|
||||
*
|
||||
* @param input The raw quantized endpoints (L0, L1, A0, A1).
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input The packed endpoints (L0, L1, A0, A1).
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void luminance_alpha_unpack(
|
||||
const uint8_t input[4],
|
||||
quant_method quant_level,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
int lum0 = unquant_color(quant_level, input[0]);
|
||||
int lum1 = unquant_color(quant_level, input[1]);
|
||||
int alpha0 = unquant_color(quant_level, input[2]);
|
||||
int alpha1 = unquant_color(quant_level, input[3]);
|
||||
int lum0 = input[0];
|
||||
int lum1 = input[1];
|
||||
int alpha0 = input[2];
|
||||
int alpha1 = input[3];
|
||||
output0 = vint4(lum0, lum0, lum0, alpha0);
|
||||
output1 = vint4(lum1, lum1, lum1, alpha1);
|
||||
}
|
||||
@@ -326,30 +255,34 @@ static void luminance_alpha_unpack(
|
||||
/**
|
||||
* @brief Unpack an LDR LA color that uses delta encoding.
|
||||
*
|
||||
* @param input The raw quantized endpoints (L0, L1, A0, A1).
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input The packed endpoints (L0, L1, A0, A1).
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void luminance_alpha_delta_unpack(
|
||||
const uint8_t input[4],
|
||||
quant_method quant_level,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
int lum0 = unquant_color(quant_level, input[0]);
|
||||
int lum1 = unquant_color(quant_level, input[1]);
|
||||
int alpha0 = unquant_color(quant_level, input[2]);
|
||||
int alpha1 = unquant_color(quant_level, input[3]);
|
||||
int lum0 = input[0];
|
||||
int lum1 = input[1];
|
||||
int alpha0 = input[2];
|
||||
int alpha1 = input[3];
|
||||
|
||||
lum0 |= (lum1 & 0x80) << 1;
|
||||
alpha0 |= (alpha1 & 0x80) << 1;
|
||||
lum1 &= 0x7F;
|
||||
alpha1 &= 0x7F;
|
||||
|
||||
if (lum1 & 0x40)
|
||||
{
|
||||
lum1 -= 0x80;
|
||||
}
|
||||
|
||||
if (alpha1 & 0x40)
|
||||
{
|
||||
alpha1 -= 0x80;
|
||||
}
|
||||
|
||||
lum0 >>= 1;
|
||||
lum1 >>= 1;
|
||||
@@ -368,21 +301,19 @@ static void luminance_alpha_delta_unpack(
|
||||
/**
|
||||
* @brief Unpack an HDR RGB + offset encoding.
|
||||
*
|
||||
* @param input The raw quantized endpoints (packed and modal).
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input The packed endpoints (packed and modal).
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void hdr_rgbo_unpack(
|
||||
const uint8_t input[4],
|
||||
quant_method quant_level,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
int v0 = unquant_color(quant_level, input[0]);
|
||||
int v1 = unquant_color(quant_level, input[1]);
|
||||
int v2 = unquant_color(quant_level, input[2]);
|
||||
int v3 = unquant_color(quant_level, input[3]);
|
||||
int v0 = input[0];
|
||||
int v1 = input[1];
|
||||
int v2 = input[2];
|
||||
int v3 = input[3];
|
||||
|
||||
int modeval = ((v0 & 0xC0) >> 6) | (((v1 & 0x80) >> 7) << 2) | (((v2 & 0x80) >> 7) << 3);
|
||||
|
||||
@@ -520,24 +451,22 @@ static void hdr_rgbo_unpack(
|
||||
/**
|
||||
* @brief Unpack an HDR RGB direct encoding.
|
||||
*
|
||||
* @param input The raw quantized endpoints (packed and modal).
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input The packed endpoints (packed and modal).
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void hdr_rgb_unpack(
|
||||
const uint8_t input[6],
|
||||
quant_method quant_level,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
|
||||
int v0 = unquant_color(quant_level, input[0]);
|
||||
int v1 = unquant_color(quant_level, input[1]);
|
||||
int v2 = unquant_color(quant_level, input[2]);
|
||||
int v3 = unquant_color(quant_level, input[3]);
|
||||
int v4 = unquant_color(quant_level, input[4]);
|
||||
int v5 = unquant_color(quant_level, input[5]);
|
||||
int v0 = input[0];
|
||||
int v1 = input[1];
|
||||
int v2 = input[2];
|
||||
int v3 = input[3];
|
||||
int v4 = input[4];
|
||||
int v5 = input[5];
|
||||
|
||||
// extract all the fixed-placement bitfields
|
||||
int modeval = ((v1 & 0x80) >> 7) | (((v2 & 0x80) >> 7) << 1) | (((v3 & 0x80) >> 7) << 2);
|
||||
@@ -688,21 +617,19 @@ static void hdr_rgb_unpack(
|
||||
/**
|
||||
* @brief Unpack an HDR RGB + LDR A direct encoding.
|
||||
*
|
||||
* @param input The raw quantized endpoints (packed and modal).
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input The packed endpoints (packed and modal).
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void hdr_rgb_ldr_alpha_unpack(
|
||||
const uint8_t input[8],
|
||||
quant_method quant_level,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
hdr_rgb_unpack(input, quant_level, output0, output1);
|
||||
hdr_rgb_unpack(input, output0, output1);
|
||||
|
||||
int v6 = unquant_color(quant_level, input[6]);
|
||||
int v7 = unquant_color(quant_level, input[7]);
|
||||
int v6 = input[6];
|
||||
int v7 = input[7];
|
||||
output0.set_lane<3>(v6);
|
||||
output1.set_lane<3>(v7);
|
||||
}
|
||||
@@ -710,19 +637,17 @@ static void hdr_rgb_ldr_alpha_unpack(
|
||||
/**
|
||||
* @brief Unpack an HDR L (small range) direct encoding.
|
||||
*
|
||||
* @param input The raw quantized endpoints (packed and modal).
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input The packed endpoints (packed and modal).
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void hdr_luminance_small_range_unpack(
|
||||
const uint8_t input[2],
|
||||
quant_method quant_level,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
int v0 = unquant_color(quant_level, input[0]);
|
||||
int v1 = unquant_color(quant_level, input[1]);
|
||||
int v0 = input[0];
|
||||
int v1 = input[1];
|
||||
|
||||
int y0, y1;
|
||||
if (v0 & 0x80)
|
||||
@@ -738,7 +663,9 @@ static void hdr_luminance_small_range_unpack(
|
||||
|
||||
y1 += y0;
|
||||
if (y1 > 0xFFF)
|
||||
{
|
||||
y1 = 0xFFF;
|
||||
}
|
||||
|
||||
output0 = vint4(y0 << 4, y0 << 4, y0 << 4, 0x7800);
|
||||
output1 = vint4(y1 << 4, y1 << 4, y1 << 4, 0x7800);
|
||||
@@ -747,19 +674,17 @@ static void hdr_luminance_small_range_unpack(
|
||||
/**
|
||||
* @brief Unpack an HDR L (large range) direct encoding.
|
||||
*
|
||||
* @param input The raw quantized endpoints (packed and modal).
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input The packed endpoints (packed and modal).
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void hdr_luminance_large_range_unpack(
|
||||
const uint8_t input[2],
|
||||
quant_method quant_level,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
int v0 = unquant_color(quant_level, input[0]);
|
||||
int v1 = unquant_color(quant_level, input[1]);
|
||||
int v0 = input[0];
|
||||
int v1 = input[1];
|
||||
|
||||
int y0, y1;
|
||||
if (v1 >= v0)
|
||||
@@ -780,20 +705,18 @@ static void hdr_luminance_large_range_unpack(
|
||||
/**
|
||||
* @brief Unpack an HDR A direct encoding.
|
||||
*
|
||||
* @param input The raw quantized endpoints (packed and modal).
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input The packed endpoints (packed and modal).
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void hdr_alpha_unpack(
|
||||
const uint8_t input[2],
|
||||
quant_method quant_level,
|
||||
int& output0,
|
||||
int& output1
|
||||
) {
|
||||
|
||||
int v6 = unquant_color(quant_level, input[0]);
|
||||
int v7 = unquant_color(quant_level, input[1]);
|
||||
int v6 = input[0];
|
||||
int v7 = input[1];
|
||||
|
||||
int selector = ((v6 >> 7) & 1) | ((v7 >> 6) & 2);
|
||||
v6 &= 0x7F;
|
||||
@@ -814,9 +737,13 @@ static void hdr_alpha_unpack(
|
||||
v7 += v6;
|
||||
|
||||
if (v7 < 0)
|
||||
{
|
||||
v7 = 0;
|
||||
}
|
||||
else if (v7 > 0xFFF)
|
||||
{
|
||||
v7 = 0xFFF;
|
||||
}
|
||||
|
||||
output0 = v6;
|
||||
output1 = v7;
|
||||
@@ -829,21 +756,19 @@ static void hdr_alpha_unpack(
|
||||
/**
|
||||
* @brief Unpack an HDR RGBA direct encoding.
|
||||
*
|
||||
* @param input The raw quantized endpoints (packed and modal).
|
||||
* @param quant_level The quantization level to use.
|
||||
* @param[out] output0 The unpacked and unquantized endpoint 0 color.
|
||||
* @param[out] output1 The unpacked and unquantized endpoint 1 color.
|
||||
* @param input The packed endpoints (packed and modal).
|
||||
* @param[out] output0 The unpacked endpoint 0 color.
|
||||
* @param[out] output1 The unpacked endpoint 1 color.
|
||||
*/
|
||||
static void hdr_rgb_hdr_alpha_unpack(
|
||||
const uint8_t input[8],
|
||||
quant_method quant_level,
|
||||
vint4& output0,
|
||||
vint4& output1
|
||||
) {
|
||||
hdr_rgb_unpack(input, quant_level, output0, output1);
|
||||
hdr_rgb_unpack(input, output0, output1);
|
||||
|
||||
int alpha0, alpha1;
|
||||
hdr_alpha_unpack(input + 6, quant_level, alpha0, alpha1);
|
||||
hdr_alpha_unpack(input + 6, alpha0, alpha1);
|
||||
|
||||
output0.set_lane<3>(alpha0);
|
||||
output1.set_lane<3>(alpha1);
|
||||
@@ -853,7 +778,6 @@ static void hdr_rgb_hdr_alpha_unpack(
|
||||
void unpack_color_endpoints(
|
||||
astcenc_profile decode_mode,
|
||||
int format,
|
||||
quant_method quant_level,
|
||||
const uint8_t* input,
|
||||
bool& rgb_hdr,
|
||||
bool& alpha_hdr,
|
||||
@@ -869,38 +793,38 @@ void unpack_color_endpoints(
|
||||
switch (format)
|
||||
{
|
||||
case FMT_LUMINANCE:
|
||||
luminance_unpack(input, quant_level, output0, output1);
|
||||
luminance_unpack(input, output0, output1);
|
||||
break;
|
||||
|
||||
case FMT_LUMINANCE_DELTA:
|
||||
luminance_delta_unpack(input, quant_level, output0, output1);
|
||||
luminance_delta_unpack(input, output0, output1);
|
||||
break;
|
||||
|
||||
case FMT_HDR_LUMINANCE_SMALL_RANGE:
|
||||
rgb_hdr = true;
|
||||
alpha_hdr_default = true;
|
||||
hdr_luminance_small_range_unpack(input, quant_level, output0, output1);
|
||||
hdr_luminance_small_range_unpack(input, output0, output1);
|
||||
break;
|
||||
|
||||
case FMT_HDR_LUMINANCE_LARGE_RANGE:
|
||||
rgb_hdr = true;
|
||||
alpha_hdr_default = true;
|
||||
hdr_luminance_large_range_unpack(input, quant_level, output0, output1);
|
||||
hdr_luminance_large_range_unpack(input, output0, output1);
|
||||
break;
|
||||
|
||||
case FMT_LUMINANCE_ALPHA:
|
||||
luminance_alpha_unpack(input, quant_level, output0, output1);
|
||||
luminance_alpha_unpack(input, output0, output1);
|
||||
break;
|
||||
|
||||
case FMT_LUMINANCE_ALPHA_DELTA:
|
||||
luminance_alpha_delta_unpack(input, quant_level, output0, output1);
|
||||
luminance_alpha_delta_unpack(input, output0, output1);
|
||||
break;
|
||||
|
||||
case FMT_RGB_SCALE:
|
||||
{
|
||||
vint4 input0q(input[0], input[1], input[2], 0);
|
||||
uint8_t scale = input[3];
|
||||
rgb_scale_unpack(input0q, scale, quant_level, output0, output1);
|
||||
rgb_scale_unpack(input0q, scale, output0, output1);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -909,21 +833,21 @@ void unpack_color_endpoints(
|
||||
vint4 input0q(input[0], input[1], input[2], input[4]);
|
||||
uint8_t alpha1q = input[5];
|
||||
uint8_t scaleq = input[3];
|
||||
rgb_scale_alpha_unpack(input0q, alpha1q, scaleq, quant_level, output0, output1);
|
||||
rgb_scale_alpha_unpack(input0q, alpha1q, scaleq, output0, output1);
|
||||
}
|
||||
break;
|
||||
|
||||
case FMT_HDR_RGB_SCALE:
|
||||
rgb_hdr = true;
|
||||
alpha_hdr_default = true;
|
||||
hdr_rgbo_unpack(input, quant_level,output0, output1);
|
||||
hdr_rgbo_unpack(input, output0, output1);
|
||||
break;
|
||||
|
||||
case FMT_RGB:
|
||||
{
|
||||
vint4 input0q(input[0], input[2], input[4], 0);
|
||||
vint4 input1q(input[1], input[3], input[5], 0);
|
||||
rgb_unpack(input0q, input1q, quant_level, output0, output1);
|
||||
rgb_unpack(input0q, input1q, output0, output1);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -931,21 +855,21 @@ void unpack_color_endpoints(
|
||||
{
|
||||
vint4 input0q(input[0], input[2], input[4], 0);
|
||||
vint4 input1q(input[1], input[3], input[5], 0);
|
||||
rgb_delta_unpack(input0q, input1q, quant_level, output0, output1);
|
||||
rgb_delta_unpack(input0q, input1q, output0, output1);
|
||||
}
|
||||
break;
|
||||
|
||||
case FMT_HDR_RGB:
|
||||
rgb_hdr = true;
|
||||
alpha_hdr_default = true;
|
||||
hdr_rgb_unpack(input, quant_level, output0, output1);
|
||||
hdr_rgb_unpack(input, output0, output1);
|
||||
break;
|
||||
|
||||
case FMT_RGBA:
|
||||
{
|
||||
vint4 input0q(input[0], input[2], input[4], input[6]);
|
||||
vint4 input1q(input[1], input[3], input[5], input[7]);
|
||||
rgba_unpack(input0q, input1q, quant_level, output0, output1);
|
||||
rgba_unpack(input0q, input1q, output0, output1);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -953,19 +877,19 @@ void unpack_color_endpoints(
|
||||
{
|
||||
vint4 input0q(input[0], input[2], input[4], input[6]);
|
||||
vint4 input1q(input[1], input[3], input[5], input[7]);
|
||||
rgba_delta_unpack(input0q, input1q, quant_level, output0, output1);
|
||||
rgba_delta_unpack(input0q, input1q, output0, output1);
|
||||
}
|
||||
break;
|
||||
|
||||
case FMT_HDR_RGB_LDR_ALPHA:
|
||||
rgb_hdr = true;
|
||||
hdr_rgb_ldr_alpha_unpack(input, quant_level, output0, output1);
|
||||
hdr_rgb_ldr_alpha_unpack(input, output0, output1);
|
||||
break;
|
||||
|
||||
case FMT_HDR_RGBA:
|
||||
rgb_hdr = true;
|
||||
alpha_hdr = true;
|
||||
hdr_rgb_hdr_alpha_unpack(input, quant_level, output0, output1);
|
||||
hdr_rgb_hdr_alpha_unpack(input, output0, output1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,6 @@ static bool realign_weights_undecimated(
|
||||
{
|
||||
unpack_color_endpoints(decode_mode,
|
||||
scb.color_formats[pa_idx],
|
||||
scb.get_color_quant_mode(),
|
||||
scb.color_values[pa_idx],
|
||||
rgb_hdr, alpha_hdr,
|
||||
endpnt0[pa_idx],
|
||||
@@ -225,7 +224,6 @@ static bool realign_weights_decimated(
|
||||
{
|
||||
unpack_color_endpoints(decode_mode,
|
||||
scb.color_formats[pa_idx],
|
||||
scb.get_color_quant_mode(),
|
||||
scb.color_values[pa_idx],
|
||||
rgb_hdr, alpha_hdr,
|
||||
endpnt0[pa_idx],
|
||||
|
||||
@@ -299,7 +299,6 @@ void decompress_symbolic_block(
|
||||
|
||||
unpack_color_endpoints(decode_mode,
|
||||
scb.color_formats[i],
|
||||
scb.get_color_quant_mode(),
|
||||
scb.color_values[i],
|
||||
rgb_lns, a_lns,
|
||||
ep0, ep1);
|
||||
@@ -362,7 +361,6 @@ float compute_symbolic_block_difference_2plane(
|
||||
|
||||
unpack_color_endpoints(config.profile,
|
||||
scb.color_formats[0],
|
||||
scb.get_color_quant_mode(),
|
||||
scb.color_values[0],
|
||||
rgb_lns, a_lns,
|
||||
ep0, ep1);
|
||||
@@ -457,7 +455,6 @@ float compute_symbolic_block_difference_1plane(
|
||||
|
||||
unpack_color_endpoints(config.profile,
|
||||
scb.color_formats[i],
|
||||
scb.get_color_quant_mode(),
|
||||
scb.color_values[i],
|
||||
rgb_lns, a_lns,
|
||||
ep0, ep1);
|
||||
@@ -546,7 +543,6 @@ float compute_symbolic_block_difference_1plane_1partition(
|
||||
|
||||
unpack_color_endpoints(config.profile,
|
||||
scb.color_formats[0],
|
||||
scb.get_color_quant_mode(),
|
||||
scb.color_values[0],
|
||||
rgb_lns, a_lns,
|
||||
ep0, ep1);
|
||||
|
||||
@@ -1357,7 +1357,6 @@ astcenc_error astcenc_get_block_info(
|
||||
|
||||
unpack_color_endpoints(ctx->config.profile,
|
||||
scb.color_formats[i],
|
||||
scb.get_color_quant_mode(),
|
||||
scb.color_values[i],
|
||||
rgb_hdr, a_hdr,
|
||||
endpnt[0], endpnt[1]);
|
||||
|
||||
@@ -536,7 +536,7 @@ unsigned int find_best_partition_candidates(
|
||||
const image_block& blk,
|
||||
unsigned int partition_count,
|
||||
unsigned int partition_search_limit,
|
||||
unsigned int best_partitions[BLOCK_MAX_PARTITIONINGS],
|
||||
unsigned int best_partitions[TUNE_MAX_PARTITIIONING_CANDIDATES],
|
||||
unsigned int requested_candidates
|
||||
) {
|
||||
// Constant used to estimate quantization error for a given partitioning; the optimal value for
|
||||
|
||||
@@ -691,7 +691,6 @@ float compute_error_of_weight_set_1plane(
|
||||
const float* dec_weight_quant_uvalue
|
||||
) {
|
||||
vfloatacc error_summav = vfloatacc::zero();
|
||||
float error_summa = 0.0f;
|
||||
unsigned int texel_count = di.texel_count;
|
||||
|
||||
// Process SIMD-width chunks, safe to over-fetch - the extra space is zero initialized
|
||||
@@ -745,7 +744,7 @@ float compute_error_of_weight_set_1plane(
|
||||
}
|
||||
|
||||
// Resolve the final scalar accumulator sum
|
||||
return error_summa = hadd_s(error_summav);
|
||||
return hadd_s(error_summav);
|
||||
}
|
||||
|
||||
/* See header for documentation. */
|
||||
|
||||
32
3rdparty/astc-encoder/source/astcenc_internal.h
vendored
32
3rdparty/astc-encoder/source/astcenc_internal.h
vendored
@@ -1322,20 +1322,32 @@ bool is_legal_3d_block_size(
|
||||
/**
|
||||
* @brief The precomputed table for quantizing color values.
|
||||
*
|
||||
* Returned value is in the ASTC BISE scrambled order.
|
||||
* 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].
|
||||
*/
|
||||
extern const uint8_t color_quant_tables[17][256];
|
||||
extern const uint8_t color_unquant_to_uquant_tables[17][256];
|
||||
|
||||
/**
|
||||
* @brief The precomputed table for unquantizing color values.
|
||||
* @brief The precomputed table for packing quantized color values.
|
||||
*
|
||||
* Returned value is in the ASTC BISE scrambled order.
|
||||
* Converts quant value in 0-255 range into packed quant value in 0-N range,
|
||||
* with BISE scrambling applied.
|
||||
*
|
||||
* Indexed by [quant_mode - 4][data_value].
|
||||
*/
|
||||
extern const uint8_t color_unquant_tables[17][256];
|
||||
extern const uint8_t color_uquant_to_scrambled_pquant_tables[17][256];
|
||||
|
||||
/**
|
||||
* @brief The precomputed table for unpacking color values.
|
||||
*
|
||||
* Converts quant value in 0-N range into unpacked value in 0-255 range,
|
||||
* with BISE unscrambling applied.
|
||||
*
|
||||
* Indexed by [quant_mode - 4][data_value].
|
||||
*/
|
||||
extern const uint8_t* color_scrambled_pquant_to_uquant_tables[17];
|
||||
|
||||
/**
|
||||
* @brief The precomputed quant mode storage table.
|
||||
@@ -1532,8 +1544,8 @@ void compute_error_squared_rgba(
|
||||
* @param partition_count The number of partitions in the block.
|
||||
* @param partition_search_limit The number of candidate partition encodings to trial.
|
||||
* @param[out] best_partitions The best partition candidates.
|
||||
* @param requested_candidates The number of requsted partitionings. May return fewer if
|
||||
* candidates are not avaiable.
|
||||
* @param requested_candidates The number of requested partitionings. May return fewer if
|
||||
* candidates are not available.
|
||||
*
|
||||
* @return The actual number of candidates returned.
|
||||
*/
|
||||
@@ -1798,11 +1810,12 @@ uint8_t pack_color_endpoints(
|
||||
quant_method quant_level);
|
||||
|
||||
/**
|
||||
* @brief Unpack a single pair of encoded and quantized color endpoints.
|
||||
* @brief Unpack a single pair of encoded endpoints.
|
||||
*
|
||||
* Endpoints must be unscrambled and converted into the 0-255 range before calling this functions.
|
||||
*
|
||||
* @param decode_mode The decode mode (LDR, HDR).
|
||||
* @param format The color endpoint mode used.
|
||||
* @param quant_level The quantization level used.
|
||||
* @param input The raw array of encoded input integers. The length of this array
|
||||
* depends on @c format; it can be safely assumed to be large enough.
|
||||
* @param[out] rgb_hdr Is the endpoint using HDR for the RGB channels?
|
||||
@@ -1813,7 +1826,6 @@ uint8_t pack_color_endpoints(
|
||||
void unpack_color_endpoints(
|
||||
astcenc_profile decode_mode,
|
||||
int format,
|
||||
quant_method quant_level,
|
||||
const uint8_t* input,
|
||||
bool& rgb_hdr,
|
||||
bool& alpha_hdr,
|
||||
|
||||
1093
3rdparty/astc-encoder/source/astcenc_quantization.cpp
vendored
1093
3rdparty/astc-encoder/source/astcenc_quantization.cpp
vendored
File diff suppressed because it is too large
Load Diff
@@ -265,13 +265,15 @@ void symbolic_to_physical(
|
||||
// Encode the color components
|
||||
uint8_t values_to_encode[32];
|
||||
int valuecount_to_encode = 0;
|
||||
|
||||
const uint8_t* pack_table = color_uquant_to_scrambled_pquant_tables[scb.quant_mode - QUANT_6];
|
||||
for (unsigned int i = 0; i < scb.partition_count; i++)
|
||||
{
|
||||
int vals = 2 * (scb.color_formats[i] >> 2) + 2;
|
||||
assert(vals <= 8);
|
||||
for (int j = 0; j < vals; j++)
|
||||
{
|
||||
values_to_encode[j + valuecount_to_encode] = scb.color_values[i][j];
|
||||
values_to_encode[j + valuecount_to_encode] = pack_table[scb.color_values[i][j]];
|
||||
}
|
||||
valuecount_to_encode += vals;
|
||||
}
|
||||
@@ -503,17 +505,19 @@ void physical_to_symbolic(
|
||||
|
||||
// Unpack the integer color values and assign to endpoints
|
||||
scb.quant_mode = static_cast<quant_method>(color_quant_level);
|
||||
|
||||
uint8_t values_to_decode[32];
|
||||
decode_ise(static_cast<quant_method>(color_quant_level), color_integer_count, pcb.data,
|
||||
values_to_decode, (partition_count == 1 ? 17 : 19 + PARTITION_INDEX_BITS));
|
||||
|
||||
int valuecount_to_decode = 0;
|
||||
const uint8_t* unpack_table = color_scrambled_pquant_to_uquant_tables[scb.quant_mode - QUANT_6];
|
||||
for (int i = 0; i < partition_count; i++)
|
||||
{
|
||||
int vals = 2 * (color_formats[i] >> 2) + 2;
|
||||
for (int j = 0; j < vals; j++)
|
||||
{
|
||||
scb.color_values[i][j] = values_to_decode[j + valuecount_to_decode];
|
||||
scb.color_values[i][j] = unpack_table[values_to_decode[j + valuecount_to_decode]];
|
||||
}
|
||||
valuecount_to_decode += vals;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user