From 2819e6203baeb731599ba7ade526bb02f08d047b Mon Sep 17 00:00:00 2001 From: Pete Harris Date: Tue, 19 Apr 2022 21:43:22 +0100 Subject: [PATCH] Reduce ROM size (#323) A number of ROM tables store entries that are never used in practice. color_quant/unquant_tables store QUANT_2/3/4/5, which are illegal encodings. Truncate and bias. quant_mode_table stores values for more than 20 color integers, which are illegal encodings. Truncate. --- Source/astcenc_color_quantize.cpp | 251 ++++++++++++++++------------ Source/astcenc_color_unquantize.cpp | 85 ++++++---- Source/astcenc_internal.h | 14 +- Source/astcenc_quantization.cpp | 166 +----------------- 4 files changed, 211 insertions(+), 305 deletions(-) diff --git a/Source/astcenc_color_quantize.cpp b/Source/astcenc_color_quantize.cpp index f067c4d..b39a3e8 100644 --- a/Source/astcenc_color_quantize.cpp +++ b/Source/astcenc_color_quantize.cpp @@ -50,12 +50,45 @@ * @return The encoded quantized value. These are not necessarily in the order; the compressor * scrambles the values slightly to make hardware implementation easier. */ -static inline int quant_color( +static inline int quant_color_clamp( quant_method quant_level, int value ) { value = astc::clamp(value, 0, 255); - return color_quant_tables[quant_level][value]; + return color_quant_tables[quant_level - QUANT_6][value]; +} + +/** + * @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 the order; the compressor + * scrambles the values slightly to make hardware implementation easier. + */ +static inline int 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 the order; the compressor + * scrambles the values slightly to make hardware implementation easier. + */ +static inline int unquant_color( + quant_method quant_level, + int value +) { + return color_unquant_tables[quant_level - QUANT_6][value]; } /** @@ -93,19 +126,19 @@ static void quantize_rgb( int iters = 0; do { - ri0 = quant_color(quant_level, astc::flt2int_rd(r0 + rgb0_addon)); - gi0 = quant_color(quant_level, astc::flt2int_rd(g0 + rgb0_addon)); - bi0 = quant_color(quant_level, astc::flt2int_rd(b0 + rgb0_addon)); - ri1 = quant_color(quant_level, astc::flt2int_rd(r1 + rgb1_addon)); - gi1 = quant_color(quant_level, astc::flt2int_rd(g1 + rgb1_addon)); - bi1 = quant_color(quant_level, astc::flt2int_rd(b1 + rgb1_addon)); + 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 = color_unquant_tables[quant_level][ri0]; - gi0b = color_unquant_tables[quant_level][gi0]; - bi0b = color_unquant_tables[quant_level][bi0]; - ri1b = color_unquant_tables[quant_level][ri1]; - gi1b = color_unquant_tables[quant_level][gi1]; - bi1b = color_unquant_tables[quant_level][bi1]; + 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); rgb0_addon -= 0.2f; rgb1_addon += 0.2f; @@ -144,8 +177,8 @@ static void quantize_rgba( float a0 = astc::clamp255f(color0.lane<3>() * scale); float a1 = astc::clamp255f(color1.lane<3>() * scale); - output[6] = color_quant_tables[quant_level][astc::flt2int_rtn(a0)]; - output[7] = color_quant_tables[quant_level][astc::flt2int_rtn(a1)]; + output[6] = quant_color(quant_level, astc::flt2int_rtn(a0)); + output[7] = quant_color(quant_level, astc::flt2int_rtn(a1)); quantize_rgb(color0, color1, output, quant_level); } @@ -191,22 +224,22 @@ static bool try_quantize_rgb_blue_contract( } // Quantize the inverse-blue-contracted color - int ri0 = color_quant_tables[quant_level][astc::flt2int_rtn(r0)]; - int gi0 = color_quant_tables[quant_level][astc::flt2int_rtn(g0)]; - int bi0 = color_quant_tables[quant_level][astc::flt2int_rtn(b0)]; + 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 ri1 = color_quant_tables[quant_level][astc::flt2int_rtn(r1)]; - int gi1 = color_quant_tables[quant_level][astc::flt2int_rtn(g1)]; - int bi1 = color_quant_tables[quant_level][astc::flt2int_rtn(b1)]; + 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)); // Then unquantize again - int ru0 = color_unquant_tables[quant_level][ri0]; - int gu0 = color_unquant_tables[quant_level][gi0]; - int bu0 = color_unquant_tables[quant_level][bi0]; + int ru0 = unquant_color(quant_level, ri0); + int gu0 = unquant_color(quant_level, gi0); + int bu0 = unquant_color(quant_level, bi0); - int ru1 = color_unquant_tables[quant_level][ri1]; - int gu1 = color_unquant_tables[quant_level][gi1]; - int bu1 = color_unquant_tables[quant_level][bi1]; + 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. @@ -248,8 +281,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] = color_quant_tables[quant_level][astc::flt2int_rtn(a1)]; - output[7] = color_quant_tables[quant_level][astc::flt2int_rtn(a0)]; + output[6] = quant_color(quant_level, astc::flt2int_rtn(a1)); + output[7] = quant_color(quant_level, astc::flt2int_rtn(a0)); return try_quantize_rgb_blue_contract(color0, color1, output, quant_level); } @@ -299,13 +332,14 @@ static bool try_quantize_rgb_delta( int b0b = b0a & 0xFF; // Quantize then unquantize in order to get a value that we take differences against - int r0be = color_quant_tables[quant_level][r0b]; - int g0be = color_quant_tables[quant_level][g0b]; - int b0be = color_quant_tables[quant_level][b0b]; + int r0be = quant_color(quant_level, r0b); + int g0be = quant_color(quant_level, g0b); + int b0be = quant_color(quant_level, b0b); + + r0b = unquant_color(quant_level, r0be); + g0b = unquant_color(quant_level, g0be); + b0b = unquant_color(quant_level, b0be); - r0b = color_unquant_tables[quant_level][r0be]; - g0b = color_unquant_tables[quant_level][g0be]; - b0b = color_unquant_tables[quant_level][b0be]; r0b |= r0a & 0x100; g0b |= g0a & 0x100; b0b |= b0a & 0x100; @@ -341,13 +375,13 @@ static bool try_quantize_rgb_delta( // Then quantize and unquantize; if this causes either top two bits to flip, then encoding fails // since we have then corrupted either the top bit of the base or the sign bit of the offset - int r1de = color_quant_tables[quant_level][r1d]; - int g1de = color_quant_tables[quant_level][g1d]; - int b1de = color_quant_tables[quant_level][b1d]; + int r1de = quant_color(quant_level, r1d); + int g1de = quant_color(quant_level, g1d); + int b1de = quant_color(quant_level, b1d); - int r1du = color_unquant_tables[quant_level][r1de]; - int g1du = color_unquant_tables[quant_level][g1de]; - int b1du = color_unquant_tables[quant_level][b1de]; + 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) { @@ -441,13 +475,14 @@ static bool try_quantize_rgb_delta_blue_contract( int b0b = b0a & 0xFF; // Quantize, then unquantize in order to get a value that we take differences against. - int r0be = color_quant_tables[quant_level][r0b]; - int g0be = color_quant_tables[quant_level][g0b]; - int b0be = color_quant_tables[quant_level][b0b]; + int r0be = quant_color(quant_level, r0b); + int g0be = quant_color(quant_level, g0b); + int b0be = quant_color(quant_level, b0b); + + r0b = unquant_color(quant_level, r0be); + g0b = unquant_color(quant_level, g0be); + b0b = unquant_color(quant_level, b0be); - r0b = color_unquant_tables[quant_level][r0be]; - g0b = color_unquant_tables[quant_level][g0be]; - b0b = color_unquant_tables[quant_level][b0be]; r0b |= r0a & 0x100; g0b |= g0a & 0x100; b0b |= b0a & 0x100; @@ -484,13 +519,13 @@ static bool try_quantize_rgb_delta_blue_contract( // Then quantize and unquantize; if this causes any of the top two bits to flip, // then encoding fails, since we have then corrupted either the top bit of the base // or the sign bit of the offset. - int r1de = color_quant_tables[quant_level][r1d]; - int g1de = color_quant_tables[quant_level][g1d]; - int b1de = color_quant_tables[quant_level][b1d]; + int r1de = quant_color(quant_level, r1d); + int g1de = quant_color(quant_level, g1d); + int b1de = quant_color(quant_level, b1d); - int r1du = color_unquant_tables[quant_level][r1de]; - int g1du = color_unquant_tables[quant_level][g1de]; - int b1du = color_unquant_tables[quant_level][b1de]; + 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) { @@ -573,8 +608,8 @@ static bool try_quantize_alpha_delta( int a0a = astc::flt2int_rtn(a0); a0a <<= 1; int a0b = a0a & 0xFF; - int a0be = color_quant_tables[quant_level][a0b]; - a0b = color_unquant_tables[quant_level][a0be]; + int a0be = quant_color(quant_level, a0b); + a0b = unquant_color(quant_level, a0be); a0b |= a0a & 0x100; int a1d = astc::flt2int_rtn(a1); a1d <<= 1; @@ -588,8 +623,8 @@ static bool try_quantize_alpha_delta( a1d &= 0x7F; a1d |= (a0b & 0x100) >> 1; - int a1de = color_quant_tables[quant_level][a1d]; - int a1du = color_unquant_tables[quant_level][a1de]; + int a1de = quant_color(quant_level, a1d); + int a1du = unquant_color(quant_level, a1de); if ((a1d ^ a1du) & 0xC0) { return false; @@ -650,10 +685,10 @@ static bool try_quantize_luminance_alpha_delta( int l0b = l0a & 0xFF; int a0b = a0a & 0xFF; - int l0be = color_quant_tables[quant_level][l0b]; - int a0be = color_quant_tables[quant_level][a0b]; - l0b = color_unquant_tables[quant_level][l0be]; - a0b = color_unquant_tables[quant_level][a0be]; + 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 |= l0a & 0x100; a0b |= a0a & 0x100; @@ -679,10 +714,10 @@ static bool try_quantize_luminance_alpha_delta( l1d |= (l0b & 0x100) >> 1; a1d |= (a0b & 0x100) >> 1; - int l1de = color_quant_tables[quant_level][l1d]; - int a1de = color_quant_tables[quant_level][a1d]; - int l1du = color_unquant_tables[quant_level][l1de]; - int a1du = color_unquant_tables[quant_level][a1de]; + 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); if ((l1d ^ l1du) & 0xC0) { @@ -800,13 +835,13 @@ static void quantize_rgbs( float g = astc::clamp255f(color.lane<1>() * scale); float b = astc::clamp255f(color.lane<2>() * scale); - int ri = color_quant_tables[quant_level][astc::flt2int_rtn(r)]; - int gi = color_quant_tables[quant_level][astc::flt2int_rtn(g)]; - int bi = color_quant_tables[quant_level][astc::flt2int_rtn(b)]; + 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 ru = color_unquant_tables[quant_level][ri]; - int gu = color_unquant_tables[quant_level][gi]; - int bu = color_unquant_tables[quant_level][bi]; + 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 = (float)(ru + gu + bu); @@ -818,7 +853,7 @@ static void quantize_rgbs( output[0] = static_cast(ri); output[1] = static_cast(gi); output[2] = static_cast(bi); - output[3] = color_quant_tables[quant_level][scale_idx]; + output[3] = quant_color(quant_level, scale_idx); } /** @@ -840,8 +875,8 @@ static void quantize_rgbs_alpha( float a0 = astc::clamp255f(color0.lane<3>() * scale); float a1 = astc::clamp255f(color1.lane<3>() * scale); - output[4] = color_quant_tables[quant_level][astc::flt2int_rtn(a0)]; - output[5] = color_quant_tables[quant_level][astc::flt2int_rtn(a1)]; + output[4] = quant_color(quant_level, astc::flt2int_rtn(a0)); + output[5] = quant_color(quant_level, astc::flt2int_rtn(a1)); quantize_rgbs(color, output, quant_level); } @@ -875,8 +910,8 @@ static void quantize_luminance( lum1 = avg; } - output[0] = color_quant_tables[quant_level][astc::flt2int_rtn(lum0)]; - output[1] = color_quant_tables[quant_level][astc::flt2int_rtn(lum1)]; + output[0] = quant_color(quant_level, astc::flt2int_rtn(lum0)); + output[1] = quant_color(quant_level, astc::flt2int_rtn(lum1)); } /** @@ -942,10 +977,10 @@ static void quantize_luminance_alpha( } } - output[0] = color_quant_tables[quant_level][astc::flt2int_rtn(lum0)]; - output[1] = color_quant_tables[quant_level][astc::flt2int_rtn(lum1)]; - output[2] = color_quant_tables[quant_level][astc::flt2int_rtn(a0)]; - output[3] = color_quant_tables[quant_level][astc::flt2int_rtn(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)); } /** @@ -968,8 +1003,8 @@ static inline void quantize_and_unquantize_retain_top_two_bits( do { - quantval = color_quant_tables[quant_level][value]; - uquantval = color_unquant_tables[quant_level][quantval]; + 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); @@ -1012,8 +1047,8 @@ static inline void quantize_and_unquantize_retain_top_four_bits( do { - quantval = color_quant_tables[quant_level][value]; - uquantval = color_unquant_tables[quant_level][quantval]; + 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); @@ -1501,8 +1536,8 @@ static void quantize_hdr_rgb( int a_intval = astc::flt2int_rtn(a_base * mode_scale); int a_lowbits = a_intval & 0xFF; - int a_quantval = color_quant_tables[quant_level][a_lowbits]; - int a_uquantval = color_unquant_tables[quant_level][a_quantval]; + int a_quantval = quant_color(quant_level, a_lowbits); + int a_uquantval = unquant_color(quant_level, a_quantval); a_intval = (a_intval & ~0xFF) | a_uquantval; float a_fval = static_cast(a_intval) * mode_rscale; @@ -1726,7 +1761,7 @@ static void quantize_hdr_rgb( for (int i = 0; i < 4; i++) { int idx = astc::flt2int_rtn(vals[i] * 1.0f / 256.0f); - output[i] = color_quant_tables[quant_level][idx]; + output[i] = quant_color(quant_level, idx); } for (int i = 4; i < 6; i++) @@ -1759,8 +1794,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] = color_quant_tables[quant_level][astc::flt2int_rtn(a0)]; - output[7] = color_quant_tables[quant_level][astc::flt2int_rtn(a1)]; + output[6] = quant_color(quant_level, astc::flt2int_rtn(a0)); + output[7] = quant_color(quant_level, astc::flt2int_rtn(a1)); quantize_hdr_rgb(color0, color1, output, quant_level); } @@ -1832,9 +1867,9 @@ static void quantize_hdr_luminance_large_range( v1 = lower_v1; } - // OK; encode. - output[0] = color_quant_tables[quant_level][v0]; - output[1] = color_quant_tables[quant_level][v1]; + // OK; encode + output[0] = quant_color(quant_level, v0); + output[1] = quant_color(quant_level, v1); } /** @@ -1885,8 +1920,8 @@ static bool try_quantize_hdr_luminance_small_range( highval = astc::clamp(highval, 0, 2047); v0 = lowval & 0x7F; - v0e = color_quant_tables[quant_level][v0]; - v0d = color_unquant_tables[quant_level][v0e]; + v0e = quant_color(quant_level, v0); + v0d = unquant_color(quant_level, v0e); if (v0d < 0x80) { @@ -1895,8 +1930,8 @@ static bool try_quantize_hdr_luminance_small_range( if (diffval >= 0 && diffval <= 15) { v1 = ((lowval >> 3) & 0xF0) | diffval; - v1e = color_quant_tables[quant_level][v1]; - v1d = color_unquant_tables[quant_level][v1e]; + v1e = quant_color(quant_level, v1); + v1d = unquant_color(quant_level, v1e); if ((v1d & 0xF0) == (v1 & 0xF0)) { output[0] = static_cast(v0e); @@ -1914,8 +1949,8 @@ static bool try_quantize_hdr_luminance_small_range( highval = astc::clamp(highval, 0, 1023); v0 = (lowval & 0x7F) | 0x80; - v0e = color_quant_tables[quant_level][v0]; - v0d = color_unquant_tables[quant_level][v0e]; + v0e = quant_color(quant_level, v0); + v0d = unquant_color(quant_level, v0e); if ((v0d & 0x80) == 0) { return false; @@ -1929,8 +1964,8 @@ static bool try_quantize_hdr_luminance_small_range( } v1 = ((lowval >> 2) & 0xE0) | diffval; - v1e = color_quant_tables[quant_level][v1]; - v1d = color_unquant_tables[quant_level][v1e]; + v1e = quant_color(quant_level, v1); + v1d = unquant_color(quant_level, v1e); if ((v1d & 0xE0) != (v1 & 0xE0)) { return false; @@ -1973,8 +2008,8 @@ static void quantize_hdr_alpha( val1 = (ialpha1 + (128 >> i)) >> (8 - i); v6 = (val0 & 0x7F) | ((i & 1) << 7); - v6e = color_quant_tables[quant_level][v6]; - v6d = color_unquant_tables[quant_level][v6e]; + v6e = quant_color(quant_level, v6); + v6d = unquant_color(quant_level, v6e); if ((v6 ^ v6d) & 0x80) { @@ -1992,8 +2027,8 @@ static void quantize_hdr_alpha( } v7 = ((i & 2) << 6) | ((val0 >> 7) << (6 - i)) | (diffval & mask); - v7e = color_quant_tables[quant_level][v7]; - v7d = color_unquant_tables[quant_level][v7e]; + v7e = quant_color(quant_level, v7); + v7d = unquant_color(quant_level, v7e); static const int testbits[3] { 0xE0, 0xF0, 0xF8 }; @@ -2013,8 +2048,8 @@ static void quantize_hdr_alpha( v6 = val0 | 0x80; v7 = val1 | 0x80; - output[0] = color_quant_tables[quant_level][v6]; - output[1] = color_quant_tables[quant_level][v7]; + output[0] = quant_color(quant_level, v6); + output[1] = quant_color(quant_level, v7); return; } @@ -2047,7 +2082,7 @@ uint8_t pack_color_endpoints( uint8_t* output, quant_method quant_level ) { - assert(quant_level < 21); + assert(QUANT_6 <= quant_level && quant_level <= QUANT_256); // We do not support negative colors color0 = max(color0, 0.0f); diff --git a/Source/astcenc_color_unquantize.cpp b/Source/astcenc_color_unquantize.cpp index a1c2eeb..bb02d81 100644 --- a/Source/astcenc_color_unquantize.cpp +++ b/Source/astcenc_color_unquantize.cpp @@ -38,11 +38,28 @@ static ASTCENC_SIMD_INLINE vint4 unquant_color( quant_method quant_level, vint4 inputq ) { - const uint8_t* unq = color_unquant_tables[quant_level]; + 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 the order; the compressor + * scrambles the values slightly to make hardware implementation easier. + */ +static inline int unquant_color( + quant_method quant_level, + int value +) { + return color_unquant_tables[quant_level - QUANT_6][value]; +} + /** * @brief Un-blue-contract a color. * @@ -204,8 +221,8 @@ static void rgb_scale_alpha_unpack( ) { // Unquantize color endpoints vint4 input = unquant_color(quant_level, input0q); - uint8_t alpha1 = color_unquant_tables[quant_level][alpha1q]; - uint8_t scale = color_unquant_tables[quant_level][scaleq]; + uint8_t alpha1 = unquant_color(quant_level, alpha1q); + uint8_t scale = unquant_color(quant_level, scaleq); output1 = input; output1.set_lane<3>(alpha1); @@ -233,7 +250,7 @@ static void rgb_scale_unpack( vint4& output1 ) { vint4 input = unquant_color(quant_level, input0q); - int scale = color_unquant_tables[quant_level][scaleq]; + int scale = unquant_color(quant_level, scaleq); output1 = input; output1.set_lane<3>(255); @@ -258,8 +275,8 @@ static void luminance_unpack( vint4& output0, vint4& output1 ) { - int lum0 = color_unquant_tables[quant_level][input[0]]; - int lum1 = color_unquant_tables[quant_level][input[1]]; + int lum0 = unquant_color(quant_level, input[0]); + int lum1 = unquant_color(quant_level, input[1]); output0 = vint4(lum0, lum0, lum0, 255); output1 = vint4(lum1, lum1, lum1, 255); } @@ -280,8 +297,8 @@ static void luminance_delta_unpack( vint4& output0, vint4& output1 ) { - int v0 = color_unquant_tables[quant_level][input[0]]; - int v1 = color_unquant_tables[quant_level][input[1]]; + int v0 = unquant_color(quant_level, input[0]); + int v1 = unquant_color(quant_level, input[1]); int l0 = (v0 >> 2) | (v1 & 0xC0); int l1 = l0 + (v1 & 0x3F); @@ -305,10 +322,10 @@ static void luminance_alpha_unpack( vint4& output0, vint4& output1 ) { - int lum0 = color_unquant_tables[quant_level][input[0]]; - int lum1 = color_unquant_tables[quant_level][input[1]]; - int alpha0 = color_unquant_tables[quant_level][input[2]]; - int alpha1 = color_unquant_tables[quant_level][input[3]]; + 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]); output0 = vint4(lum0, lum0, lum0, alpha0); output1 = vint4(lum1, lum1, lum1, alpha1); } @@ -327,10 +344,10 @@ static void luminance_alpha_delta_unpack( vint4& output0, vint4& output1 ) { - int lum0 = color_unquant_tables[quant_level][input[0]]; - int lum1 = color_unquant_tables[quant_level][input[1]]; - int alpha0 = color_unquant_tables[quant_level][input[2]]; - int alpha1 = color_unquant_tables[quant_level][input[3]]; + 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]); lum0 |= (lum1 & 0x80) << 1; alpha0 |= (alpha1 & 0x80) << 1; @@ -369,10 +386,10 @@ static void hdr_rgbo_unpack( vint4& output0, vint4& output1 ) { - int v0 = color_unquant_tables[quant_level][input[0]]; - int v1 = color_unquant_tables[quant_level][input[1]]; - int v2 = color_unquant_tables[quant_level][input[2]]; - int v3 = color_unquant_tables[quant_level][input[3]]; + 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 modeval = ((v0 & 0xC0) >> 6) | (((v1 & 0x80) >> 7) << 2) | (((v2 & 0x80) >> 7) << 3); @@ -522,12 +539,12 @@ static void hdr_rgb_unpack( vint4& output1 ) { - int v0 = color_unquant_tables[quant_level][input[0]]; - int v1 = color_unquant_tables[quant_level][input[1]]; - int v2 = color_unquant_tables[quant_level][input[2]]; - int v3 = color_unquant_tables[quant_level][input[3]]; - int v4 = color_unquant_tables[quant_level][input[4]]; - int v5 = color_unquant_tables[quant_level][input[5]]; + 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]); // extract all the fixed-placement bitfields int modeval = ((v1 & 0x80) >> 7) | (((v2 & 0x80) >> 7) << 1) | (((v3 & 0x80) >> 7) << 2); @@ -691,8 +708,8 @@ static void hdr_rgb_ldr_alpha_unpack( ) { hdr_rgb_unpack(input, quant_level, output0, output1); - int v6 = color_unquant_tables[quant_level][input[6]]; - int v7 = color_unquant_tables[quant_level][input[7]]; + int v6 = unquant_color(quant_level, input[6]); + int v7 = unquant_color(quant_level, input[7]); output0.set_lane<3>(v6); output1.set_lane<3>(v7); } @@ -711,8 +728,8 @@ static void hdr_luminance_small_range_unpack( vint4& output0, vint4& output1 ) { - int v0 = color_unquant_tables[quant_level][input[0]]; - int v1 = color_unquant_tables[quant_level][input[1]]; + int v0 = unquant_color(quant_level, input[0]); + int v1 = unquant_color(quant_level, input[1]); int y0, y1; if (v0 & 0x80) @@ -748,8 +765,8 @@ static void hdr_luminance_large_range_unpack( vint4& output0, vint4& output1 ) { - int v0 = color_unquant_tables[quant_level][input[0]]; - int v1 = color_unquant_tables[quant_level][input[1]]; + int v0 = unquant_color(quant_level, input[0]); + int v1 = unquant_color(quant_level, input[1]); int y0, y1; if (v1 >= v0) @@ -782,8 +799,8 @@ static void hdr_alpha_unpack( int& output1 ) { - int v6 = color_unquant_tables[quant_level][input[0]]; - int v7 = color_unquant_tables[quant_level][input[1]]; + int v6 = unquant_color(quant_level, input[0]); + int v7 = unquant_color(quant_level, input[1]); int selector = ((v6 >> 7) & 1) | ((v7 >> 6) & 2); v6 &= 0x7F; diff --git a/Source/astcenc_internal.h b/Source/astcenc_internal.h index 17c00a8..e7e5c60 100644 --- a/Source/astcenc_internal.h +++ b/Source/astcenc_internal.h @@ -1511,16 +1511,20 @@ bool is_legal_3d_block_size( /** * @brief The precomputed table for quantizing color values. * - * Indexed by [quant_mode][data_value]. + * Returned value is in the ASTC BISE scrambled order. + * + * Indexed by [quant_mode - 4][data_value]. */ -extern const uint8_t color_quant_tables[21][256]; +extern const uint8_t color_quant_tables[17][256]; /** * @brief The precomputed table for unquantizing color values. * - * Indexed by [quant_mode][data_value]. + * Returned value is in the ASTC BISE scrambled order. + * + * Indexed by [quant_mode - 4][data_value]. */ -extern const uint8_t color_unquant_tables[21][256]; +extern const uint8_t color_unquant_tables[17][256]; /** * @brief The precomputed quant mode storage table. @@ -1529,7 +1533,7 @@ extern const uint8_t color_unquant_tables[21][256]; * number of compressed storage bits. Returns -1 for cases where the requested integer count cannot * ever fit in the supplied storage size. */ -extern const int8_t quant_mode_table[17][128]; +extern const int8_t quant_mode_table[10][128]; /** * @brief Encode a packed string using BISE. diff --git a/Source/astcenc_quantization.cpp b/Source/astcenc_quantization.cpp index 2d48abf..233a933 100644 --- a/Source/astcenc_quantization.cpp +++ b/Source/astcenc_quantization.cpp @@ -23,79 +23,9 @@ #if !defined(ASTCENC_DECOMPRESS_ONLY) -const uint8_t color_quant_tables[21][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, 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, 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, - 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, 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, 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, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 - }, - { - 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, 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, 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, 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, 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, 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, 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 - }, - { - 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, 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, - 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, 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, 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, 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, 3, 3, 3, 3, 3, 3 - }, - { - 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, 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, 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, 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, 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, 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, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 - }, +// Starts from QUANT_6 +// Scrambled +const uint8_t color_quant_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, 2, 2, 2, 2, 2, 2, @@ -406,19 +336,9 @@ const uint8_t color_quant_tables[21][256] { #endif -const uint8_t color_unquant_tables[21][256] { - { - 0, 255 - }, - { - 0, 128, 255 - }, - { - 0, 85, 170, 255 - }, - { - 0, 64, 128, 192, 255 - }, +// Starts from QUANT_6 +// Scrambled +const uint8_t color_unquant_tables[17][256] { { 0, 255, 51, 204, 102, 153 }, @@ -535,7 +455,7 @@ const uint8_t color_unquant_tables[21][256] { // The quant_mode_table[integercount/2][bits] gives us the quantization level for a given integer // count and number of bits that the integer may fit into. -const int8_t quant_mode_table[17][128] { +const int8_t quant_mode_table[10][128] { { -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, @@ -635,75 +555,5 @@ const int8_t quant_mode_table[17][128] { 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 17, 17 - }, - { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, - 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, - 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, - 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 15 - }, - { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 4, 4, 4, 4, 4, 4, - 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, - 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, 13, 13, 13, 13 - }, - { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11 - }, - { - -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, 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, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, - 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10 - }, - { - -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, 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, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, - 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9 - }, - { - -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, 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, 2, 2, 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, 4, 4, 4, 5, 5, 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, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8 - }, - { - -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, - 0, 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, - 2, 2, 2, 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, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - }, + } };