mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-13 14:34:33 +02:00
make HistogramAdd() a pointer in dsp
* merged the two HistogramAdd/AddEval() into a single call (with detection of special case when b==out) * added a SSE2 variant * harmonize the histogram type to 'uint32_t' instead of just 'int'. This has a lot of ripples on signatures. * 1-2% faster Change-Id: I10299ff300f36cdbca5a560df1ae4d4df149d306
This commit is contained in:
@ -332,14 +332,14 @@ const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX] = {
|
||||
#define APPROX_LOG_WITH_CORRECTION_MAX 65536
|
||||
#define APPROX_LOG_MAX 4096
|
||||
#define LOG_2_RECIPROCAL 1.44269504088896338700465094007086
|
||||
static float FastSLog2Slow(int v) {
|
||||
static float FastSLog2Slow(uint32_t v) {
|
||||
assert(v >= LOG_LOOKUP_IDX_MAX);
|
||||
if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
|
||||
int log_cnt = 0;
|
||||
int y = 1;
|
||||
uint32_t y = 1;
|
||||
int correction = 0;
|
||||
const float v_f = (float)v;
|
||||
const int orig_v = v;
|
||||
const uint32_t orig_v = v;
|
||||
do {
|
||||
++log_cnt;
|
||||
v = v >> 1;
|
||||
@ -358,12 +358,12 @@ static float FastSLog2Slow(int v) {
|
||||
}
|
||||
}
|
||||
|
||||
static float FastLog2Slow(int v) {
|
||||
static float FastLog2Slow(uint32_t v) {
|
||||
assert(v >= LOG_LOOKUP_IDX_MAX);
|
||||
if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
|
||||
int log_cnt = 0;
|
||||
int y = 1;
|
||||
const int orig_v = v;
|
||||
uint32_t y = 1;
|
||||
const uint32_t orig_v = v;
|
||||
double log_2;
|
||||
do {
|
||||
++log_cnt;
|
||||
@ -1437,6 +1437,7 @@ void VP8LConvertFromBGRA(const uint32_t* const in_data, int num_pixels,
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Bundles multiple (1, 2, 4 or 8) pixels into a single pixel.
|
||||
void VP8LBundleColorMap(const uint8_t* const row, int width,
|
||||
int xbits, uint32_t* const dst) {
|
||||
@ -1458,14 +1459,17 @@ void VP8LBundleColorMap(const uint8_t* const row, int width,
|
||||
}
|
||||
}
|
||||
|
||||
static double ExtraCost(const int* population, int length) {
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static double ExtraCost(const uint32_t* population, int length) {
|
||||
int i;
|
||||
double cost = 0.;
|
||||
for (i = 2; i < length - 2; ++i) cost += (i >> 1) * population[i + 2];
|
||||
return cost;
|
||||
}
|
||||
|
||||
static double ExtraCostCombined(const int* X, const int* Y, int length) {
|
||||
static double ExtraCostCombined(const uint32_t* X, const uint32_t* Y,
|
||||
int length) {
|
||||
int i;
|
||||
double cost = 0.;
|
||||
for (i = 2; i < length - 2; ++i) {
|
||||
@ -1476,7 +1480,7 @@ static double ExtraCostCombined(const int* X, const int* Y, int length) {
|
||||
}
|
||||
|
||||
// Returns the various RLE counts
|
||||
static VP8LStreaks HuffmanCostCount(const int* population, int length) {
|
||||
static VP8LStreaks HuffmanCostCount(const uint32_t* population, int length) {
|
||||
int i;
|
||||
int streak = 0;
|
||||
VP8LStreaks stats;
|
||||
@ -1496,8 +1500,8 @@ static VP8LStreaks HuffmanCostCount(const int* population, int length) {
|
||||
return stats;
|
||||
}
|
||||
|
||||
static VP8LStreaks HuffmanCostCombinedCount(const int* X, const int* Y,
|
||||
int length) {
|
||||
static VP8LStreaks HuffmanCostCombinedCount(const uint32_t* X,
|
||||
const uint32_t* Y, int length) {
|
||||
int i;
|
||||
int streak = 0;
|
||||
VP8LStreaks stats;
|
||||
@ -1524,6 +1528,41 @@ static VP8LStreaks HuffmanCostCombinedCount(const int* X, const int* Y,
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void HistogramAdd(const VP8LHistogram* const a,
|
||||
const VP8LHistogram* const b,
|
||||
VP8LHistogram* const out) {
|
||||
int i;
|
||||
const int literal_size = VP8LHistogramNumCodes(a->palette_code_bits_);
|
||||
assert(a->palette_code_bits_ == b->palette_code_bits_);
|
||||
if (b != out) {
|
||||
for (i = 0; i < literal_size; ++i) {
|
||||
out->literal_[i] = a->literal_[i] + b->literal_[i];
|
||||
}
|
||||
for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
|
||||
out->distance_[i] = a->distance_[i] + b->distance_[i];
|
||||
}
|
||||
for (i = 0; i < NUM_LITERAL_CODES; ++i) {
|
||||
out->red_[i] = a->red_[i] + b->red_[i];
|
||||
out->blue_[i] = a->blue_[i] + b->blue_[i];
|
||||
out->alpha_[i] = a->alpha_[i] + b->alpha_[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < literal_size; ++i) {
|
||||
out->literal_[i] += a->literal_[i];
|
||||
}
|
||||
for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
|
||||
out->distance_[i] += a->distance_[i];
|
||||
}
|
||||
for (i = 0; i < NUM_LITERAL_CODES; ++i) {
|
||||
out->red_[i] += a->red_[i];
|
||||
out->blue_[i] += a->blue_[i];
|
||||
out->alpha_[i] += a->alpha_[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
VP8LProcessBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed;
|
||||
VP8LProcessBlueAndRedFunc VP8LAddGreenToBlueAndRed;
|
||||
VP8LPredictorFunc VP8LPredictors[16];
|
||||
@ -1546,6 +1585,8 @@ VP8LCostCombinedFunc VP8LExtraCostCombined;
|
||||
VP8LCostCountFunc VP8LHuffmanCostCount;
|
||||
VP8LCostCombinedCountFunc VP8LHuffmanCostCombinedCount;
|
||||
|
||||
VP8LHistogramAddFunc VP8LHistogramAdd;
|
||||
|
||||
extern void VP8LDspInitSSE2(void);
|
||||
extern void VP8LDspInitNEON(void);
|
||||
extern void VP8LDspInitMIPS32(void);
|
||||
@ -1574,6 +1615,8 @@ void VP8LDspInit(void) {
|
||||
VP8LHuffmanCostCount = HuffmanCostCount;
|
||||
VP8LHuffmanCostCombinedCount = HuffmanCostCombinedCount;
|
||||
|
||||
VP8LHistogramAdd = HistogramAdd;
|
||||
|
||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||
if (VP8GetCPUInfo != NULL) {
|
||||
#if defined(WEBP_USE_SSE2)
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "../webp/types.h"
|
||||
#include "../webp/decode.h"
|
||||
|
||||
#include "../enc/histogram.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -123,24 +125,25 @@ static WEBP_INLINE uint32_t VP8LSubSampleSize(uint32_t size,
|
||||
#define LOG_LOOKUP_IDX_MAX 256
|
||||
extern const float kLog2Table[LOG_LOOKUP_IDX_MAX];
|
||||
extern const float kSLog2Table[LOG_LOOKUP_IDX_MAX];
|
||||
typedef float (*VP8LFastLog2SlowFunc)(int v);
|
||||
typedef float (*VP8LFastLog2SlowFunc)(uint32_t v);
|
||||
|
||||
extern VP8LFastLog2SlowFunc VP8LFastLog2Slow;
|
||||
extern VP8LFastLog2SlowFunc VP8LFastSLog2Slow;
|
||||
|
||||
static WEBP_INLINE float VP8LFastLog2(int v) {
|
||||
static WEBP_INLINE float VP8LFastLog2(uint32_t v) {
|
||||
return (v < LOG_LOOKUP_IDX_MAX) ? kLog2Table[v] : VP8LFastLog2Slow(v);
|
||||
}
|
||||
// Fast calculation of v * log2(v) for integer input.
|
||||
static WEBP_INLINE float VP8LFastSLog2(int v) {
|
||||
static WEBP_INLINE float VP8LFastSLog2(uint32_t v) {
|
||||
return (v < LOG_LOOKUP_IDX_MAX) ? kSLog2Table[v] : VP8LFastSLog2Slow(v);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Huffman-cost related functions.
|
||||
|
||||
typedef double (*VP8LCostFunc)(const int* population, int length);
|
||||
typedef double (*VP8LCostCombinedFunc)(const int* X, const int* Y, int length);
|
||||
typedef double (*VP8LCostFunc)(const uint32_t* population, int length);
|
||||
typedef double (*VP8LCostCombinedFunc)(const uint32_t* X, const uint32_t* Y,
|
||||
int length);
|
||||
|
||||
extern VP8LCostFunc VP8LExtraCost;
|
||||
extern VP8LCostCombinedFunc VP8LExtraCostCombined;
|
||||
@ -150,13 +153,19 @@ typedef struct { // small struct to hold counters
|
||||
int streaks[2][2]; // [zero/non-zero][streak<3 / streak>=3]
|
||||
} VP8LStreaks;
|
||||
|
||||
typedef VP8LStreaks (*VP8LCostCountFunc)(const int* population, int length);
|
||||
typedef VP8LStreaks (*VP8LCostCombinedCountFunc)(const int* X, const int* Y,
|
||||
int length);
|
||||
typedef VP8LStreaks (*VP8LCostCountFunc)(const uint32_t* population,
|
||||
int length);
|
||||
typedef VP8LStreaks (*VP8LCostCombinedCountFunc)(const uint32_t* X,
|
||||
const uint32_t* Y, int length);
|
||||
|
||||
extern VP8LCostCountFunc VP8LHuffmanCostCount;
|
||||
extern VP8LCostCombinedCountFunc VP8LHuffmanCostCombinedCount;
|
||||
|
||||
typedef void (*VP8LHistogramAddFunc)(const VP8LHistogram* const a,
|
||||
const VP8LHistogram* const b,
|
||||
VP8LHistogram* const out);
|
||||
extern VP8LHistogramAddFunc VP8LHistogramAdd;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// PrefixEncode()
|
||||
|
||||
|
@ -26,13 +26,13 @@
|
||||
#define APPROX_LOG_MAX 4096
|
||||
#define LOG_2_RECIPROCAL 1.44269504088896338700465094007086
|
||||
|
||||
static float FastSLog2Slow(int v) {
|
||||
static float FastSLog2Slow(uint32_t v) {
|
||||
assert(v >= LOG_LOOKUP_IDX_MAX);
|
||||
if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
|
||||
int log_cnt, y, correction;
|
||||
uint32_t log_cnt, y, correction;
|
||||
const int c24 = 24;
|
||||
const float v_f = (float)v;
|
||||
int temp;
|
||||
uint32_t temp;
|
||||
|
||||
// Xf = 256 = 2^8
|
||||
// log_cnt is index of leading one in upper 24 bits
|
||||
@ -62,13 +62,13 @@ static float FastSLog2Slow(int v) {
|
||||
}
|
||||
}
|
||||
|
||||
static float FastLog2Slow(int v) {
|
||||
static float FastLog2Slow(uint32_t v) {
|
||||
assert(v >= LOG_LOOKUP_IDX_MAX);
|
||||
if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
|
||||
int log_cnt, y;
|
||||
uint32_t log_cnt, y;
|
||||
const int c24 = 24;
|
||||
double log_2;
|
||||
int temp;
|
||||
uint32_t temp;
|
||||
|
||||
__asm__ volatile(
|
||||
"clz %[log_cnt], %[v] \n\t"
|
||||
@ -86,7 +86,7 @@ static float FastLog2Slow(int v) {
|
||||
// Since the division is still expensive, add this correction factor only
|
||||
// for large values of 'v'.
|
||||
|
||||
const int correction = (23 * (v & (y - 1))) >> 4;
|
||||
const uint32_t correction = (23 * (v & (y - 1))) >> 4;
|
||||
log_2 += (double)correction / v;
|
||||
}
|
||||
return (float)log_2;
|
||||
@ -98,8 +98,8 @@ static float FastLog2Slow(int v) {
|
||||
// C version of this function:
|
||||
// int i = 0;
|
||||
// int64_t cost = 0;
|
||||
// int* pop = (int*)&population[4];
|
||||
// const int* LoopEnd = (int*)&population[length];
|
||||
// const uint32_t* pop = &population[4];
|
||||
// const uint32_t* LoopEnd = &population[length];
|
||||
// while (pop != LoopEnd) {
|
||||
// ++i;
|
||||
// cost += i * *pop;
|
||||
@ -107,10 +107,10 @@ static float FastLog2Slow(int v) {
|
||||
// pop += 2;
|
||||
// }
|
||||
// return (double)cost;
|
||||
static double ExtraCost(const int* const population, int length) {
|
||||
static double ExtraCost(const uint32_t* const population, int length) {
|
||||
int i, temp0, temp1;
|
||||
const int* pop = &population[4];
|
||||
const int* const LoopEnd = &population[length];
|
||||
const uint32_t* pop = &population[4];
|
||||
const uint32_t* const LoopEnd = &population[length];
|
||||
|
||||
__asm__ volatile(
|
||||
"mult $zero, $zero \n\t"
|
||||
@ -139,12 +139,12 @@ static double ExtraCost(const int* const population, int length) {
|
||||
// C version of this function:
|
||||
// int i = 0;
|
||||
// int64_t cost = 0;
|
||||
// int* pX = (int*)&X[4];
|
||||
// int* pY = (int*)&Y[4];
|
||||
// const int* LoopEnd = (int*)&X[length];
|
||||
// const uint32_t* pX = &X[4];
|
||||
// const uint32_t* pY = &Y[4];
|
||||
// const uint32_t* LoopEnd = &X[length];
|
||||
// while (pX != LoopEnd) {
|
||||
// const int xy0 = *pX + *pY;
|
||||
// const int xy1 = *(pX + 1) + *(pY + 1);
|
||||
// const uint32_t xy0 = *pX + *pY;
|
||||
// const uint32_t xy1 = *(pX + 1) + *(pY + 1);
|
||||
// ++i;
|
||||
// cost += i * xy0;
|
||||
// cost += i * xy1;
|
||||
@ -152,12 +152,12 @@ static double ExtraCost(const int* const population, int length) {
|
||||
// pY += 2;
|
||||
// }
|
||||
// return (double)cost;
|
||||
static double ExtraCostCombined(const int* const X, const int* const Y,
|
||||
int length) {
|
||||
static double ExtraCostCombined(const uint32_t* const X,
|
||||
const uint32_t* const Y, int length) {
|
||||
int i, temp0, temp1, temp2, temp3;
|
||||
const int* pX = &X[4];
|
||||
const int* pY = &Y[4];
|
||||
const int* const LoopEnd = &X[length];
|
||||
const uint32_t* pX = &X[4];
|
||||
const uint32_t* pY = &Y[4];
|
||||
const uint32_t* const LoopEnd = &X[length];
|
||||
|
||||
__asm__ volatile(
|
||||
"mult $zero, $zero \n\t"
|
||||
@ -217,7 +217,7 @@ static double ExtraCostCombined(const int* const X, const int* const Y,
|
||||
);
|
||||
|
||||
// Returns the various RLE counts
|
||||
static VP8LStreaks HuffmanCostCount(const int* population, int length) {
|
||||
static VP8LStreaks HuffmanCostCount(const uint32_t* population, int length) {
|
||||
int i;
|
||||
int streak = 0;
|
||||
VP8LStreaks stats;
|
||||
@ -230,19 +230,19 @@ static VP8LStreaks HuffmanCostCount(const int* population, int length) {
|
||||
if (population[i] == population[i + 1]) {
|
||||
continue;
|
||||
}
|
||||
temp0 = population[i] != 0;
|
||||
temp0 = (population[i] != 0);
|
||||
HUFFMAN_COST_PASS
|
||||
streak = 0;
|
||||
}
|
||||
++streak;
|
||||
temp0 = population[i] != 0;
|
||||
temp0 = (population[i] != 0);
|
||||
HUFFMAN_COST_PASS
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
static VP8LStreaks HuffmanCostCombinedCount(const int* X, const int* Y,
|
||||
int length) {
|
||||
static VP8LStreaks HuffmanCostCombinedCount(const uint32_t* X,
|
||||
const uint32_t* Y, int length) {
|
||||
int i;
|
||||
int streak = 0;
|
||||
VP8LStreaks stats;
|
||||
@ -251,20 +251,20 @@ static VP8LStreaks HuffmanCostCombinedCount(const int* X, const int* Y,
|
||||
int temp0, temp1, temp2, temp3;
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
for (i = 0; i < length - 1; ++i) {
|
||||
const int xy = X[i] + Y[i];
|
||||
const int xy_next = X[i + 1] + Y[i + 1];
|
||||
const uint32_t xy = X[i] + Y[i];
|
||||
const uint32_t xy_next = X[i + 1] + Y[i + 1];
|
||||
++streak;
|
||||
if (xy == xy_next) {
|
||||
continue;
|
||||
}
|
||||
temp0 = xy != 0;
|
||||
temp0 = (xy != 0);
|
||||
HUFFMAN_COST_PASS
|
||||
streak = 0;
|
||||
}
|
||||
{
|
||||
const int xy = X[i] + Y[i];
|
||||
const uint32_t xy = X[i] + Y[i];
|
||||
++streak;
|
||||
temp0 = xy != 0;
|
||||
temp0 = (xy != 0);
|
||||
HUFFMAN_COST_PASS
|
||||
}
|
||||
|
||||
|
@ -383,6 +383,88 @@ static void ConvertBGRAToBGR(const uint32_t* src,
|
||||
VP8LConvertBGRAToBGR_C((const uint32_t*)in, num_pixels, dst);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#define LINE_SIZE 16 // 8 or 16
|
||||
static void AddVector(const uint32_t* a, const uint32_t* b, uint32_t* out,
|
||||
int size) {
|
||||
int i;
|
||||
assert(size % LINE_SIZE == 0);
|
||||
for (i = 0; i < size; i += LINE_SIZE) {
|
||||
const __m128i a0 = _mm_loadu_si128((__m128i*)&a[i + 0]);
|
||||
const __m128i a1 = _mm_loadu_si128((__m128i*)&a[i + 4]);
|
||||
#if (LINE_SIZE == 16)
|
||||
const __m128i a2 = _mm_loadu_si128((__m128i*)&a[i + 8]);
|
||||
const __m128i a3 = _mm_loadu_si128((__m128i*)&a[i + 12]);
|
||||
#endif
|
||||
const __m128i b0 = _mm_loadu_si128((__m128i*)&b[i + 0]);
|
||||
const __m128i b1 = _mm_loadu_si128((__m128i*)&b[i + 4]);
|
||||
#if (LINE_SIZE == 16)
|
||||
const __m128i b2 = _mm_loadu_si128((__m128i*)&b[i + 8]);
|
||||
const __m128i b3 = _mm_loadu_si128((__m128i*)&b[i + 12]);
|
||||
#endif
|
||||
_mm_storeu_si128((__m128i*)&out[i + 0], _mm_add_epi32(a0, b0));
|
||||
_mm_storeu_si128((__m128i*)&out[i + 4], _mm_add_epi32(a1, b1));
|
||||
#if (LINE_SIZE == 16)
|
||||
_mm_storeu_si128((__m128i*)&out[i + 8], _mm_add_epi32(a2, b2));
|
||||
_mm_storeu_si128((__m128i*)&out[i + 12], _mm_add_epi32(a3, b3));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void AddVectorEq(const uint32_t* a, uint32_t* out, int size) {
|
||||
int i;
|
||||
assert(size % LINE_SIZE == 0);
|
||||
for (i = 0; i < size; i += LINE_SIZE) {
|
||||
const __m128i a0 = _mm_loadu_si128((__m128i*)&a[i + 0]);
|
||||
const __m128i a1 = _mm_loadu_si128((__m128i*)&a[i + 4]);
|
||||
#if (LINE_SIZE == 16)
|
||||
const __m128i a2 = _mm_loadu_si128((__m128i*)&a[i + 8]);
|
||||
const __m128i a3 = _mm_loadu_si128((__m128i*)&a[i + 12]);
|
||||
#endif
|
||||
const __m128i b0 = _mm_loadu_si128((__m128i*)&out[i + 0]);
|
||||
const __m128i b1 = _mm_loadu_si128((__m128i*)&out[i + 4]);
|
||||
#if (LINE_SIZE == 16)
|
||||
const __m128i b2 = _mm_loadu_si128((__m128i*)&out[i + 8]);
|
||||
const __m128i b3 = _mm_loadu_si128((__m128i*)&out[i + 12]);
|
||||
#endif
|
||||
_mm_storeu_si128((__m128i*)&out[i + 0], _mm_add_epi32(a0, b0));
|
||||
_mm_storeu_si128((__m128i*)&out[i + 4], _mm_add_epi32(a1, b1));
|
||||
#if (LINE_SIZE == 16)
|
||||
_mm_storeu_si128((__m128i*)&out[i + 8], _mm_add_epi32(a2, b2));
|
||||
_mm_storeu_si128((__m128i*)&out[i + 12], _mm_add_epi32(a3, b3));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#undef LINE_SIZE
|
||||
|
||||
// Note we are adding uint32_t's as *signed* int32's (using _mm_add_epi32). But
|
||||
// that's ok since the histogram values are less than 1<<28 (max picture size).
|
||||
static void HistogramAdd(const VP8LHistogram* const a,
|
||||
const VP8LHistogram* const b,
|
||||
VP8LHistogram* const out) {
|
||||
int i;
|
||||
const int literal_size = VP8LHistogramNumCodes(a->palette_code_bits_);
|
||||
assert(a->palette_code_bits_ == b->palette_code_bits_);
|
||||
if (b != out) {
|
||||
AddVector(a->literal_, b->literal_, out->literal_, NUM_LITERAL_CODES);
|
||||
AddVector(a->red_, b->red_, out->red_, NUM_LITERAL_CODES);
|
||||
AddVector(a->blue_, b->blue_, out->blue_, NUM_LITERAL_CODES);
|
||||
AddVector(a->alpha_, b->alpha_, out->alpha_, NUM_LITERAL_CODES);
|
||||
} else {
|
||||
AddVectorEq(a->literal_, out->literal_, NUM_LITERAL_CODES);
|
||||
AddVectorEq(a->red_, out->red_, NUM_LITERAL_CODES);
|
||||
AddVectorEq(a->blue_, out->blue_, NUM_LITERAL_CODES);
|
||||
AddVectorEq(a->alpha_, out->alpha_, NUM_LITERAL_CODES);
|
||||
}
|
||||
for (i = NUM_LITERAL_CODES; i < literal_size; ++i) {
|
||||
out->literal_[i] = a->literal_[i] + b->literal_[i];
|
||||
}
|
||||
for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
|
||||
out->distance_[i] = a->distance_[i] + b->distance_[i];
|
||||
}
|
||||
}
|
||||
|
||||
#endif // WEBP_USE_SSE2
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -405,6 +487,8 @@ void VP8LDspInitSSE2(void) {
|
||||
VP8LConvertBGRAToRGBA4444 = ConvertBGRAToRGBA4444;
|
||||
VP8LConvertBGRAToRGB565 = ConvertBGRAToRGB565;
|
||||
VP8LConvertBGRAToBGR = ConvertBGRAToBGR;
|
||||
|
||||
VP8LHistogramAdd = HistogramAdd;
|
||||
#endif // WEBP_USE_SSE2
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user