mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-13 14:34:33 +02:00
new segmentation algorithm
fixes the 'blocky sky problem' (saturation problem: when luma was flat, chroma noise was taking over, resulting in random segment id assigned. When just using a common uniform segment was better). + side clean-up and readibility/experimentability MACRO'ization + added '-map 7' option Change-Id: I35982a9e43c0fecbfdd7b05e4813e8ba8c121d71
This commit is contained in:
@ -49,8 +49,6 @@ extern VP8CPUInfo VP8GetCPUInfo;
|
||||
//------------------------------------------------------------------------------
|
||||
// Encoding
|
||||
|
||||
int VP8GetAlpha(const int histo[]);
|
||||
|
||||
// Transforms
|
||||
// VP8Idct: Does one of two inverse transforms. If do_two is set, the transforms
|
||||
// will be done for (ref, in, dst) and (ref + 4, in + 16, dst + 4).
|
||||
@ -85,10 +83,11 @@ typedef int (*VP8QuantizeBlock)(int16_t in[16], int16_t out[16],
|
||||
int n, const struct VP8Matrix* const mtx);
|
||||
extern VP8QuantizeBlock VP8EncQuantizeBlock;
|
||||
|
||||
// Compute susceptibility based on DCT-coeff histograms:
|
||||
// the higher, the "easier" the macroblock is to compress.
|
||||
typedef int (*VP8CHisto)(const uint8_t* ref, const uint8_t* pred,
|
||||
int start_block, int end_block);
|
||||
// Collect histogram for susceptibility calculation and accumulate in histo[].
|
||||
struct VP8Histogram;
|
||||
typedef void (*VP8CHisto)(const uint8_t* ref, const uint8_t* pred,
|
||||
int start_block, int end_block,
|
||||
struct VP8Histogram* const histo);
|
||||
extern const int VP8DspScan[16 + 4 + 4];
|
||||
extern VP8CHisto VP8CollectHistogram;
|
||||
|
||||
|
@ -17,31 +17,18 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static WEBP_INLINE uint8_t clip_8b(int v) {
|
||||
return (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255;
|
||||
}
|
||||
|
||||
static WEBP_INLINE int clip_max(int v, int max) {
|
||||
return (v > max) ? max : v;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Compute susceptibility based on DCT-coeff histograms:
|
||||
// the higher, the "easier" the macroblock is to compress.
|
||||
|
||||
static int ClipAlpha(int alpha) {
|
||||
return alpha < 0 ? 0 : alpha > 255 ? 255 : alpha;
|
||||
}
|
||||
|
||||
int VP8GetAlpha(const int histo[MAX_COEFF_THRESH + 1]) {
|
||||
int num = 0, den = 0, val = 0;
|
||||
int k;
|
||||
int alpha;
|
||||
// note: changing this loop to avoid the numerous "k + 1" slows things down.
|
||||
for (k = 0; k < MAX_COEFF_THRESH; ++k) {
|
||||
if (histo[k + 1]) {
|
||||
val += histo[k + 1];
|
||||
num += val * (k + 1);
|
||||
den += (k + 1) * (k + 1);
|
||||
}
|
||||
}
|
||||
// we scale the value to a usable [0..255] range
|
||||
alpha = den ? 10 * num / den - 5 : 0;
|
||||
return ClipAlpha(alpha);
|
||||
}
|
||||
|
||||
const int VP8DspScan[16 + 4 + 4] = {
|
||||
// Luma
|
||||
0 + 0 * BPS, 4 + 0 * BPS, 8 + 0 * BPS, 12 + 0 * BPS,
|
||||
@ -53,27 +40,23 @@ const int VP8DspScan[16 + 4 + 4] = {
|
||||
8 + 0 * BPS, 12 + 0 * BPS, 8 + 4 * BPS, 12 + 4 * BPS // V
|
||||
};
|
||||
|
||||
static int CollectHistogram(const uint8_t* ref, const uint8_t* pred,
|
||||
int start_block, int end_block) {
|
||||
int histo[MAX_COEFF_THRESH + 1] = { 0 };
|
||||
int16_t out[16];
|
||||
int j, k;
|
||||
static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
|
||||
int start_block, int end_block,
|
||||
VP8Histogram* const histo) {
|
||||
int j;
|
||||
for (j = start_block; j < end_block; ++j) {
|
||||
int k;
|
||||
int16_t out[16];
|
||||
|
||||
VP8FTransform(ref + VP8DspScan[j], pred + VP8DspScan[j], out);
|
||||
|
||||
// Convert coefficients to bin (within out[]).
|
||||
// Convert coefficients to bin.
|
||||
for (k = 0; k < 16; ++k) {
|
||||
const int v = abs(out[k]) >> 2;
|
||||
out[k] = (v > MAX_COEFF_THRESH) ? MAX_COEFF_THRESH : v;
|
||||
}
|
||||
|
||||
// Use bin to update histogram.
|
||||
for (k = 0; k < 16; ++k) {
|
||||
histo[out[k]]++;
|
||||
const int v = abs(out[k]) >> 3; // TODO(skal): add rounding?
|
||||
const int clipped_value = clip_max(v, MAX_COEFF_THRESH);
|
||||
histo->distribution[clipped_value]++;
|
||||
}
|
||||
}
|
||||
|
||||
return VP8GetAlpha(histo);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -89,15 +72,12 @@ static void InitTables(void) {
|
||||
if (!tables_ok) {
|
||||
int i;
|
||||
for (i = -255; i <= 255 + 255; ++i) {
|
||||
clip1[255 + i] = (i < 0) ? 0 : (i > 255) ? 255 : i;
|
||||
clip1[255 + i] = clip_8b(i);
|
||||
}
|
||||
tables_ok = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static WEBP_INLINE uint8_t clip_8b(int v) {
|
||||
return (!(v & ~0xff)) ? v : v < 0 ? 0 : 255;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Transforms (Paragraph 14.4)
|
||||
|
@ -25,13 +25,15 @@ extern "C" {
|
||||
// Compute susceptibility based on DCT-coeff histograms:
|
||||
// the higher, the "easier" the macroblock is to compress.
|
||||
|
||||
static int CollectHistogramSSE2(const uint8_t* ref, const uint8_t* pred,
|
||||
int start_block, int end_block) {
|
||||
int histo[MAX_COEFF_THRESH + 1] = { 0 };
|
||||
int16_t out[16];
|
||||
int j, k;
|
||||
static void CollectHistogramSSE2(const uint8_t* ref, const uint8_t* pred,
|
||||
int start_block, int end_block,
|
||||
VP8Histogram* const histo) {
|
||||
const __m128i max_coeff_thresh = _mm_set1_epi16(MAX_COEFF_THRESH);
|
||||
int j;
|
||||
for (j = start_block; j < end_block; ++j) {
|
||||
int16_t out[16];
|
||||
int k;
|
||||
|
||||
VP8FTransform(ref + VP8DspScan[j], pred + VP8DspScan[j], out);
|
||||
|
||||
// Convert coefficients to bin (within out[]).
|
||||
@ -47,9 +49,9 @@ static int CollectHistogramSSE2(const uint8_t* ref, const uint8_t* pred,
|
||||
const __m128i xor1 = _mm_xor_si128(out1, sign1);
|
||||
const __m128i abs0 = _mm_sub_epi16(xor0, sign0);
|
||||
const __m128i abs1 = _mm_sub_epi16(xor1, sign1);
|
||||
// v = abs(out) >> 2
|
||||
const __m128i v0 = _mm_srai_epi16(abs0, 2);
|
||||
const __m128i v1 = _mm_srai_epi16(abs1, 2);
|
||||
// v = abs(out) >> 3
|
||||
const __m128i v0 = _mm_srai_epi16(abs0, 3);
|
||||
const __m128i v1 = _mm_srai_epi16(abs1, 3);
|
||||
// bin = min(v, MAX_COEFF_THRESH)
|
||||
const __m128i bin0 = _mm_min_epi16(v0, max_coeff_thresh);
|
||||
const __m128i bin1 = _mm_min_epi16(v1, max_coeff_thresh);
|
||||
@ -58,13 +60,11 @@ static int CollectHistogramSSE2(const uint8_t* ref, const uint8_t* pred,
|
||||
_mm_storeu_si128((__m128i*)&out[8], bin1);
|
||||
}
|
||||
|
||||
// Use bin to update histogram.
|
||||
// Convert coefficients to bin.
|
||||
for (k = 0; k < 16; ++k) {
|
||||
histo[out[k]]++;
|
||||
histo->distribution[out[k]]++;
|
||||
}
|
||||
}
|
||||
|
||||
return VP8GetAlpha(histo);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user