mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 22:28:22 +01:00
Merge "Fix FindClosestDiscretized in near lossless:"
This commit is contained in:
commit
f08e66245a
@ -14,6 +14,7 @@
|
|||||||
// Author: Jyrki Alakuijala (jyrki@google.com)
|
// Author: Jyrki Alakuijala (jyrki@google.com)
|
||||||
// Converted to C by Aleksander Kramarz (akramarz@google.com)
|
// Converted to C by Aleksander Kramarz (akramarz@google.com)
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "../dsp/lossless.h"
|
#include "../dsp/lossless.h"
|
||||||
@ -23,42 +24,14 @@
|
|||||||
#define MIN_DIM_FOR_NEAR_LOSSLESS 64
|
#define MIN_DIM_FOR_NEAR_LOSSLESS 64
|
||||||
#define MAX_LIMIT_BITS 5
|
#define MAX_LIMIT_BITS 5
|
||||||
|
|
||||||
// Computes quantized pixel value and distance from original value.
|
// Quantizes the value up or down to a multiple of 1<<bits (or to 255),
|
||||||
static void GetValAndDistance(int a, int initial, int bits,
|
// choosing the closer one, resolving ties using bankers' rounding.
|
||||||
int* const val, int* const distance) {
|
|
||||||
const int mask = ~((1 << bits) - 1);
|
|
||||||
*val = (initial & mask) | (initial >> (8 - bits));
|
|
||||||
*distance = 2 * abs(a - *val);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clamps the value to range [0, 255].
|
|
||||||
static int Clamp8b(int val) {
|
|
||||||
const int min_val = 0;
|
|
||||||
const int max_val = 0xff;
|
|
||||||
return (val < min_val) ? min_val : (val > max_val) ? max_val : val;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quantizes values {a, a+(1<<bits), a-(1<<bits)} and returns the nearest one.
|
|
||||||
static int FindClosestDiscretized(int a, int bits) {
|
static int FindClosestDiscretized(int a, int bits) {
|
||||||
int best_val = a, i;
|
const int mask = (1 << bits) - 1;
|
||||||
int min_distance = 256;
|
const int biased = a + (mask >> 1) + ((a >> bits) & 1);
|
||||||
|
assert(bits > 0);
|
||||||
for (i = -1; i <= 1; ++i) {
|
if (biased > 0xff) return 0xff;
|
||||||
int candidate, distance;
|
return biased & ~mask;
|
||||||
const int val = Clamp8b(a + i * (1 << bits));
|
|
||||||
GetValAndDistance(a, val, bits, &candidate, &distance);
|
|
||||||
if (i != 0) {
|
|
||||||
++distance;
|
|
||||||
}
|
|
||||||
// Smallest distance but favor i == 0 over i == -1 and i == 1
|
|
||||||
// since that keeps the overall intensity more constant in the
|
|
||||||
// images.
|
|
||||||
if (distance < min_distance) {
|
|
||||||
min_distance = distance;
|
|
||||||
best_val = candidate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return best_val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Applies FindClosestDiscretized to all channels of pixel.
|
// Applies FindClosestDiscretized to all channels of pixel.
|
||||||
|
Loading…
Reference in New Issue
Block a user