mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-19 20:08:28 +01:00
dsp/filters*: use WEBP_RESTRICT qualifier
Better stack/register usage in SSE2/NEON code and improved vectorization of the C code with ndk r27/gcc-13/clang-16. This only affects non-vector pointers; any vector pointers are left as a follow up. Change-Id: I32b53dd38bfc7e2231d875409e7dfda7c513cfb6
This commit is contained in:
parent
b1cb37e659
commit
04d4b4f387
@ -497,8 +497,9 @@ typedef enum { // Filter types.
|
|||||||
WEBP_FILTER_FAST
|
WEBP_FILTER_FAST
|
||||||
} WEBP_FILTER_TYPE;
|
} WEBP_FILTER_TYPE;
|
||||||
|
|
||||||
typedef void (*WebPFilterFunc)(const uint8_t* in, int width, int height,
|
typedef void (*WebPFilterFunc)(const uint8_t* WEBP_RESTRICT in,
|
||||||
int stride, uint8_t* out);
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT out);
|
||||||
// In-place un-filtering.
|
// In-place un-filtering.
|
||||||
// Warning! 'prev_line' pointer can be equal to 'cur_line' or 'preds'.
|
// Warning! 'prev_line' pointer can be equal to 'cur_line' or 'preds'.
|
||||||
typedef void (*WebPUnfilterFunc)(const uint8_t* prev_line, const uint8_t* preds,
|
typedef void (*WebPUnfilterFunc)(const uint8_t* prev_line, const uint8_t* preds,
|
||||||
|
@ -23,14 +23,16 @@
|
|||||||
do { \
|
do { \
|
||||||
assert((in) != NULL); \
|
assert((in) != NULL); \
|
||||||
assert((out) != NULL); \
|
assert((out) != NULL); \
|
||||||
|
assert((in) != (out)); \
|
||||||
assert(width > 0); \
|
assert(width > 0); \
|
||||||
assert(height > 0); \
|
assert(height > 0); \
|
||||||
assert(stride >= width); \
|
assert(stride >= width); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
#if !WEBP_NEON_OMIT_C_CODE
|
||||||
static WEBP_INLINE void PredictLine_C(const uint8_t* src, const uint8_t* pred,
|
static WEBP_INLINE void PredictLine_C(const uint8_t* WEBP_RESTRICT src,
|
||||||
uint8_t* dst, int length) {
|
const uint8_t* WEBP_RESTRICT pred,
|
||||||
|
uint8_t* WEBP_RESTRICT dst, int length) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < length; ++i) dst[i] = (uint8_t)(src[i] - pred[i]);
|
for (i = 0; i < length; ++i) dst[i] = (uint8_t)(src[i] - pred[i]);
|
||||||
}
|
}
|
||||||
@ -38,9 +40,9 @@ static WEBP_INLINE void PredictLine_C(const uint8_t* src, const uint8_t* pred,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Horizontal filter.
|
// Horizontal filter.
|
||||||
|
|
||||||
static WEBP_INLINE void DoHorizontalFilter_C(const uint8_t* in,
|
static WEBP_INLINE void DoHorizontalFilter_C(const uint8_t* WEBP_RESTRICT in,
|
||||||
int width, int height, int stride,
|
int width, int height, int stride,
|
||||||
uint8_t* out) {
|
uint8_t* WEBP_RESTRICT out) {
|
||||||
const uint8_t* preds = in;
|
const uint8_t* preds = in;
|
||||||
int row;
|
int row;
|
||||||
DCHECK(in, out);
|
DCHECK(in, out);
|
||||||
@ -66,9 +68,9 @@ static WEBP_INLINE void DoHorizontalFilter_C(const uint8_t* in,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Vertical filter.
|
// Vertical filter.
|
||||||
|
|
||||||
static WEBP_INLINE void DoVerticalFilter_C(const uint8_t* in,
|
static WEBP_INLINE void DoVerticalFilter_C(const uint8_t* WEBP_RESTRICT in,
|
||||||
int width, int height, int stride,
|
int width, int height, int stride,
|
||||||
uint8_t* out) {
|
uint8_t* WEBP_RESTRICT out) {
|
||||||
const uint8_t* preds = in;
|
const uint8_t* preds = in;
|
||||||
int row;
|
int row;
|
||||||
DCHECK(in, out);
|
DCHECK(in, out);
|
||||||
@ -99,9 +101,9 @@ static WEBP_INLINE int GradientPredictor_C(uint8_t a, uint8_t b, uint8_t c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
#if !WEBP_NEON_OMIT_C_CODE
|
||||||
static WEBP_INLINE void DoGradientFilter_C(const uint8_t* in,
|
static WEBP_INLINE void DoGradientFilter_C(const uint8_t* WEBP_RESTRICT in,
|
||||||
int width, int height, int stride,
|
int width, int height, int stride,
|
||||||
uint8_t* out) {
|
uint8_t* WEBP_RESTRICT out) {
|
||||||
const uint8_t* preds = in;
|
const uint8_t* preds = in;
|
||||||
int row;
|
int row;
|
||||||
DCHECK(in, out);
|
DCHECK(in, out);
|
||||||
@ -136,18 +138,21 @@ static WEBP_INLINE void DoGradientFilter_C(const uint8_t* in,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
#if !WEBP_NEON_OMIT_C_CODE
|
||||||
static void HorizontalFilter_C(const uint8_t* data, int width, int height,
|
static void HorizontalFilter_C(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
DoHorizontalFilter_C(data, width, height, stride, filtered_data);
|
DoHorizontalFilter_C(data, width, height, stride, filtered_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void VerticalFilter_C(const uint8_t* data, int width, int height,
|
static void VerticalFilter_C(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
DoVerticalFilter_C(data, width, height, stride, filtered_data);
|
DoVerticalFilter_C(data, width, height, stride, filtered_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GradientFilter_C(const uint8_t* data, int width, int height,
|
static void GradientFilter_C(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
DoGradientFilter_C(data, width, height, stride, filtered_data);
|
DoGradientFilter_C(data, width, height, stride, filtered_data);
|
||||||
}
|
}
|
||||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||||
|
@ -26,8 +26,9 @@
|
|||||||
|
|
||||||
#define DCHECK(in, out) \
|
#define DCHECK(in, out) \
|
||||||
do { \
|
do { \
|
||||||
assert(in != NULL); \
|
assert((in) != NULL); \
|
||||||
assert(out != NULL); \
|
assert((out) != NULL); \
|
||||||
|
assert((in) != (out)); \
|
||||||
assert(width > 0); \
|
assert(width > 0); \
|
||||||
assert(height > 0); \
|
assert(height > 0); \
|
||||||
assert(stride >= width); \
|
assert(stride >= width); \
|
||||||
@ -101,7 +102,8 @@
|
|||||||
); \
|
); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static WEBP_INLINE void PredictLine_MIPSdspR2(const uint8_t* src, uint8_t* dst,
|
static WEBP_INLINE void PredictLine_MIPSdspR2(const uint8_t* WEBP_RESTRICT src,
|
||||||
|
uint8_t* WEBP_RESTRICT dst,
|
||||||
int length) {
|
int length) {
|
||||||
DO_PREDICT_LINE(src, dst, length, 0);
|
DO_PREDICT_LINE(src, dst, length, 0);
|
||||||
}
|
}
|
||||||
@ -191,9 +193,9 @@ static WEBP_INLINE void PredictLine_MIPSdspR2(const uint8_t* src, uint8_t* dst,
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static WEBP_INLINE void DoHorizontalFilter_MIPSdspR2(const uint8_t* in,
|
static WEBP_INLINE void DoHorizontalFilter_MIPSdspR2(
|
||||||
int width, int height,
|
const uint8_t* WEBP_RESTRICT in, int width, int height, int stride,
|
||||||
int stride, uint8_t* out) {
|
uint8_t* WEBP_RESTRICT out) {
|
||||||
const uint8_t* preds = in;
|
const uint8_t* preds = in;
|
||||||
int row;
|
int row;
|
||||||
DCHECK(in, out);
|
DCHECK(in, out);
|
||||||
@ -210,9 +212,9 @@ static WEBP_INLINE void DoHorizontalFilter_MIPSdspR2(const uint8_t* in,
|
|||||||
}
|
}
|
||||||
#undef FILTER_LINE_BY_LINE
|
#undef FILTER_LINE_BY_LINE
|
||||||
|
|
||||||
static void HorizontalFilter_MIPSdspR2(const uint8_t* data,
|
static void HorizontalFilter_MIPSdspR2(const uint8_t* WEBP_RESTRICT data,
|
||||||
int width, int height,
|
int width, int height, int stride,
|
||||||
int stride, uint8_t* filtered_data) {
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
DoHorizontalFilter_MIPSdspR2(data, width, height, stride, filtered_data);
|
DoHorizontalFilter_MIPSdspR2(data, width, height, stride, filtered_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,9 +230,9 @@ static void HorizontalFilter_MIPSdspR2(const uint8_t* data,
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static WEBP_INLINE void DoVerticalFilter_MIPSdspR2(const uint8_t* in,
|
static WEBP_INLINE void DoVerticalFilter_MIPSdspR2(
|
||||||
int width, int height,
|
const uint8_t* WEBP_RESTRICT in, int width, int height, int stride,
|
||||||
int stride, uint8_t* out) {
|
uint8_t* WEBP_RESTRICT out) {
|
||||||
const uint8_t* preds = in;
|
const uint8_t* preds = in;
|
||||||
int row;
|
int row;
|
||||||
DCHECK(in, out);
|
DCHECK(in, out);
|
||||||
@ -247,8 +249,9 @@ static WEBP_INLINE void DoVerticalFilter_MIPSdspR2(const uint8_t* in,
|
|||||||
}
|
}
|
||||||
#undef FILTER_LINE_BY_LINE
|
#undef FILTER_LINE_BY_LINE
|
||||||
|
|
||||||
static void VerticalFilter_MIPSdspR2(const uint8_t* data, int width, int height,
|
static void VerticalFilter_MIPSdspR2(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
DoVerticalFilter_MIPSdspR2(data, width, height, stride, filtered_data);
|
DoVerticalFilter_MIPSdspR2(data, width, height, stride, filtered_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,9 +287,9 @@ static int GradientPredictor_MIPSdspR2(uint8_t a, uint8_t b, uint8_t c) {
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static void DoGradientFilter_MIPSdspR2(const uint8_t* in,
|
static void DoGradientFilter_MIPSdspR2(const uint8_t* WEBP_RESTRICT in,
|
||||||
int width, int height, int stride,
|
int width, int height, int stride,
|
||||||
uint8_t* out) {
|
uint8_t* WEBP_RESTRICT out) {
|
||||||
const uint8_t* preds = in;
|
const uint8_t* preds = in;
|
||||||
int row;
|
int row;
|
||||||
DCHECK(in, out);
|
DCHECK(in, out);
|
||||||
@ -303,8 +306,9 @@ static void DoGradientFilter_MIPSdspR2(const uint8_t* in,
|
|||||||
}
|
}
|
||||||
#undef FILTER_LINE_BY_LINE
|
#undef FILTER_LINE_BY_LINE
|
||||||
|
|
||||||
static void GradientFilter_MIPSdspR2(const uint8_t* data, int width, int height,
|
static void GradientFilter_MIPSdspR2(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
DoGradientFilter_MIPSdspR2(data, width, height, stride, filtered_data);
|
DoGradientFilter_MIPSdspR2(data, width, height, stride, filtered_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
static WEBP_INLINE void PredictLineInverse0(const uint8_t* src,
|
static WEBP_INLINE void PredictLineInverse0(const uint8_t* src,
|
||||||
const uint8_t* pred,
|
const uint8_t* pred,
|
||||||
uint8_t* dst, int length) {
|
uint8_t* WEBP_RESTRICT dst,
|
||||||
|
int length) {
|
||||||
v16u8 src0, pred0, dst0;
|
v16u8 src0, pred0, dst0;
|
||||||
assert(length >= 0);
|
assert(length >= 0);
|
||||||
while (length >= 32) {
|
while (length >= 32) {
|
||||||
@ -58,8 +59,9 @@ static WEBP_INLINE void PredictLineInverse0(const uint8_t* src,
|
|||||||
|
|
||||||
#define DCHECK(in, out) \
|
#define DCHECK(in, out) \
|
||||||
do { \
|
do { \
|
||||||
assert(in != NULL); \
|
assert((in) != NULL); \
|
||||||
assert(out != NULL); \
|
assert((out) != NULL); \
|
||||||
|
assert((in) != (out)); \
|
||||||
assert(width > 0); \
|
assert(width > 0); \
|
||||||
assert(height > 0); \
|
assert(height > 0); \
|
||||||
assert(stride >= width); \
|
assert(stride >= width); \
|
||||||
@ -68,8 +70,9 @@ static WEBP_INLINE void PredictLineInverse0(const uint8_t* src,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Horrizontal filter
|
// Horrizontal filter
|
||||||
|
|
||||||
static void HorizontalFilter_MSA(const uint8_t* data, int width, int height,
|
static void HorizontalFilter_MSA(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
const uint8_t* preds = data;
|
const uint8_t* preds = data;
|
||||||
const uint8_t* in = data;
|
const uint8_t* in = data;
|
||||||
uint8_t* out = filtered_data;
|
uint8_t* out = filtered_data;
|
||||||
@ -99,8 +102,8 @@ static void HorizontalFilter_MSA(const uint8_t* data, int width, int height,
|
|||||||
|
|
||||||
static WEBP_INLINE void PredictLineGradient(const uint8_t* pinput,
|
static WEBP_INLINE void PredictLineGradient(const uint8_t* pinput,
|
||||||
const uint8_t* ppred,
|
const uint8_t* ppred,
|
||||||
uint8_t* poutput, int stride,
|
uint8_t* WEBP_RESTRICT poutput,
|
||||||
int size) {
|
int stride, int size) {
|
||||||
int w;
|
int w;
|
||||||
const v16i8 zero = { 0 };
|
const v16i8 zero = { 0 };
|
||||||
while (size >= 16) {
|
while (size >= 16) {
|
||||||
@ -131,8 +134,9 @@ static WEBP_INLINE void PredictLineGradient(const uint8_t* pinput,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void GradientFilter_MSA(const uint8_t* data, int width, int height,
|
static void GradientFilter_MSA(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
const uint8_t* in = data;
|
const uint8_t* in = data;
|
||||||
const uint8_t* preds = data;
|
const uint8_t* preds = data;
|
||||||
uint8_t* out = filtered_data;
|
uint8_t* out = filtered_data;
|
||||||
@ -159,8 +163,9 @@ static void GradientFilter_MSA(const uint8_t* data, int width, int height,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Vertical filter
|
// Vertical filter
|
||||||
|
|
||||||
static void VerticalFilter_MSA(const uint8_t* data, int width, int height,
|
static void VerticalFilter_MSA(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
const uint8_t* in = data;
|
const uint8_t* in = data;
|
||||||
const uint8_t* preds = data;
|
const uint8_t* preds = data;
|
||||||
uint8_t* out = filtered_data;
|
uint8_t* out = filtered_data;
|
||||||
|
@ -23,8 +23,9 @@
|
|||||||
|
|
||||||
#define DCHECK(in, out) \
|
#define DCHECK(in, out) \
|
||||||
do { \
|
do { \
|
||||||
assert(in != NULL); \
|
assert((in) != NULL); \
|
||||||
assert(out != NULL); \
|
assert((out) != NULL); \
|
||||||
|
assert((in) != (out)); \
|
||||||
assert(width > 0); \
|
assert(width > 0); \
|
||||||
assert(height > 0); \
|
assert(height > 0); \
|
||||||
assert(stride >= width); \
|
assert(stride >= width); \
|
||||||
@ -44,7 +45,7 @@
|
|||||||
#define ROTATE_RIGHT_N(A, N) vext_u8((A), (A), (8 - (N)) % 8)
|
#define ROTATE_RIGHT_N(A, N) vext_u8((A), (A), (8 - (N)) % 8)
|
||||||
|
|
||||||
static void PredictLine_NEON(const uint8_t* src, const uint8_t* pred,
|
static void PredictLine_NEON(const uint8_t* src, const uint8_t* pred,
|
||||||
uint8_t* dst, int length) {
|
uint8_t* WEBP_RESTRICT dst, int length) {
|
||||||
int i;
|
int i;
|
||||||
assert(length >= 0);
|
assert(length >= 0);
|
||||||
for (i = 0; i + 16 <= length; i += 16) {
|
for (i = 0; i + 16 <= length; i += 16) {
|
||||||
@ -57,16 +58,17 @@ static void PredictLine_NEON(const uint8_t* src, const uint8_t* pred,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Special case for left-based prediction (when preds==dst-1 or preds==src-1).
|
// Special case for left-based prediction (when preds==dst-1 or preds==src-1).
|
||||||
static void PredictLineLeft_NEON(const uint8_t* src, uint8_t* dst, int length) {
|
static void PredictLineLeft_NEON(const uint8_t* WEBP_RESTRICT src,
|
||||||
|
uint8_t* WEBP_RESTRICT dst, int length) {
|
||||||
PredictLine_NEON(src, src - 1, dst, length);
|
PredictLine_NEON(src, src - 1, dst, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Horizontal filter.
|
// Horizontal filter.
|
||||||
|
|
||||||
static WEBP_INLINE void DoHorizontalFilter_NEON(const uint8_t* in,
|
static WEBP_INLINE void DoHorizontalFilter_NEON(
|
||||||
int width, int height,
|
const uint8_t* WEBP_RESTRICT in, int width, int height, int stride,
|
||||||
int stride, uint8_t* out) {
|
uint8_t* WEBP_RESTRICT out) {
|
||||||
int row;
|
int row;
|
||||||
DCHECK(in, out);
|
DCHECK(in, out);
|
||||||
|
|
||||||
@ -86,17 +88,18 @@ static WEBP_INLINE void DoHorizontalFilter_NEON(const uint8_t* in,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HorizontalFilter_NEON(const uint8_t* data, int width, int height,
|
static void HorizontalFilter_NEON(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
DoHorizontalFilter_NEON(data, width, height, stride, filtered_data);
|
DoHorizontalFilter_NEON(data, width, height, stride, filtered_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Vertical filter.
|
// Vertical filter.
|
||||||
|
|
||||||
static WEBP_INLINE void DoVerticalFilter_NEON(const uint8_t* in,
|
static WEBP_INLINE void DoVerticalFilter_NEON(const uint8_t* WEBP_RESTRICT in,
|
||||||
int width, int height, int stride,
|
int width, int height, int stride,
|
||||||
uint8_t* out) {
|
uint8_t* WEBP_RESTRICT out) {
|
||||||
int row;
|
int row;
|
||||||
DCHECK(in, out);
|
DCHECK(in, out);
|
||||||
|
|
||||||
@ -115,8 +118,9 @@ static WEBP_INLINE void DoVerticalFilter_NEON(const uint8_t* in,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void VerticalFilter_NEON(const uint8_t* data, int width, int height,
|
static void VerticalFilter_NEON(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
DoVerticalFilter_NEON(data, width, height, stride, filtered_data);
|
DoVerticalFilter_NEON(data, width, height, stride, filtered_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +134,8 @@ static WEBP_INLINE int GradientPredictor_C(uint8_t a, uint8_t b, uint8_t c) {
|
|||||||
|
|
||||||
static void GradientPredictDirect_NEON(const uint8_t* const row,
|
static void GradientPredictDirect_NEON(const uint8_t* const row,
|
||||||
const uint8_t* const top,
|
const uint8_t* const top,
|
||||||
uint8_t* const out, int length) {
|
uint8_t* WEBP_RESTRICT const out,
|
||||||
|
int length) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i + 8 <= length; i += 8) {
|
for (i = 0; i + 8 <= length; i += 8) {
|
||||||
const uint8x8_t A = vld1_u8(&row[i - 1]);
|
const uint8x8_t A = vld1_u8(&row[i - 1]);
|
||||||
@ -146,9 +151,9 @@ static void GradientPredictDirect_NEON(const uint8_t* const row,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static WEBP_INLINE void DoGradientFilter_NEON(const uint8_t* in,
|
static WEBP_INLINE void DoGradientFilter_NEON(const uint8_t* WEBP_RESTRICT in,
|
||||||
int width, int height, int stride,
|
int width, int height, int stride,
|
||||||
uint8_t* out) {
|
uint8_t* WEBP_RESTRICT out) {
|
||||||
int row;
|
int row;
|
||||||
DCHECK(in, out);
|
DCHECK(in, out);
|
||||||
|
|
||||||
@ -167,8 +172,9 @@ static WEBP_INLINE void DoGradientFilter_NEON(const uint8_t* in,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GradientFilter_NEON(const uint8_t* data, int width, int height,
|
static void GradientFilter_NEON(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
DoGradientFilter_NEON(data, width, height, stride, filtered_data);
|
DoGradientFilter_NEON(data, width, height, stride, filtered_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,13 +27,15 @@
|
|||||||
do { \
|
do { \
|
||||||
assert((in) != NULL); \
|
assert((in) != NULL); \
|
||||||
assert((out) != NULL); \
|
assert((out) != NULL); \
|
||||||
|
assert((in) != (out)); \
|
||||||
assert(width > 0); \
|
assert(width > 0); \
|
||||||
assert(height > 0); \
|
assert(height > 0); \
|
||||||
assert(stride >= width); \
|
assert(stride >= width); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static void PredictLineTop_SSE2(const uint8_t* src, const uint8_t* pred,
|
static void PredictLineTop_SSE2(const uint8_t* WEBP_RESTRICT src,
|
||||||
uint8_t* dst, int length) {
|
const uint8_t* WEBP_RESTRICT pred,
|
||||||
|
uint8_t* WEBP_RESTRICT dst, int length) {
|
||||||
int i;
|
int i;
|
||||||
const int max_pos = length & ~31;
|
const int max_pos = length & ~31;
|
||||||
assert(length >= 0);
|
assert(length >= 0);
|
||||||
@ -51,7 +53,8 @@ static void PredictLineTop_SSE2(const uint8_t* src, const uint8_t* pred,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Special case for left-based prediction (when preds==dst-1 or preds==src-1).
|
// Special case for left-based prediction (when preds==dst-1 or preds==src-1).
|
||||||
static void PredictLineLeft_SSE2(const uint8_t* src, uint8_t* dst, int length) {
|
static void PredictLineLeft_SSE2(const uint8_t* WEBP_RESTRICT src,
|
||||||
|
uint8_t* WEBP_RESTRICT dst, int length) {
|
||||||
int i;
|
int i;
|
||||||
const int max_pos = length & ~31;
|
const int max_pos = length & ~31;
|
||||||
assert(length >= 0);
|
assert(length >= 0);
|
||||||
@ -71,9 +74,9 @@ static void PredictLineLeft_SSE2(const uint8_t* src, uint8_t* dst, int length) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Horizontal filter.
|
// Horizontal filter.
|
||||||
|
|
||||||
static WEBP_INLINE void DoHorizontalFilter_SSE2(const uint8_t* in,
|
static WEBP_INLINE void DoHorizontalFilter_SSE2(
|
||||||
int width, int height,
|
const uint8_t* WEBP_RESTRICT in, int width, int height, int stride,
|
||||||
int stride, uint8_t* out) {
|
uint8_t* WEBP_RESTRICT out) {
|
||||||
int row;
|
int row;
|
||||||
DCHECK(in, out);
|
DCHECK(in, out);
|
||||||
|
|
||||||
@ -96,9 +99,9 @@ static WEBP_INLINE void DoHorizontalFilter_SSE2(const uint8_t* in,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Vertical filter.
|
// Vertical filter.
|
||||||
|
|
||||||
static WEBP_INLINE void DoVerticalFilter_SSE2(const uint8_t* in,
|
static WEBP_INLINE void DoVerticalFilter_SSE2(const uint8_t* WEBP_RESTRICT in,
|
||||||
int width, int height, int stride,
|
int width, int height, int stride,
|
||||||
uint8_t* out) {
|
uint8_t* WEBP_RESTRICT out) {
|
||||||
int row;
|
int row;
|
||||||
DCHECK(in, out);
|
DCHECK(in, out);
|
||||||
|
|
||||||
@ -127,7 +130,8 @@ static WEBP_INLINE int GradientPredictor_SSE2(uint8_t a, uint8_t b, uint8_t c) {
|
|||||||
|
|
||||||
static void GradientPredictDirect_SSE2(const uint8_t* const row,
|
static void GradientPredictDirect_SSE2(const uint8_t* const row,
|
||||||
const uint8_t* const top,
|
const uint8_t* const top,
|
||||||
uint8_t* const out, int length) {
|
uint8_t* WEBP_RESTRICT const out,
|
||||||
|
int length) {
|
||||||
const int max_pos = length & ~7;
|
const int max_pos = length & ~7;
|
||||||
int i;
|
int i;
|
||||||
const __m128i zero = _mm_setzero_si128();
|
const __m128i zero = _mm_setzero_si128();
|
||||||
@ -151,9 +155,9 @@ static void GradientPredictDirect_SSE2(const uint8_t* const row,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static WEBP_INLINE void DoGradientFilter_SSE2(const uint8_t* in,
|
static WEBP_INLINE void DoGradientFilter_SSE2(const uint8_t* WEBP_RESTRICT in,
|
||||||
int width, int height, int stride,
|
int width, int height, int stride,
|
||||||
uint8_t* out) {
|
uint8_t* WEBP_RESTRICT out) {
|
||||||
int row;
|
int row;
|
||||||
DCHECK(in, out);
|
DCHECK(in, out);
|
||||||
|
|
||||||
@ -176,18 +180,21 @@ static WEBP_INLINE void DoGradientFilter_SSE2(const uint8_t* in,
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static void HorizontalFilter_SSE2(const uint8_t* data, int width, int height,
|
static void HorizontalFilter_SSE2(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
DoHorizontalFilter_SSE2(data, width, height, stride, filtered_data);
|
DoHorizontalFilter_SSE2(data, width, height, stride, filtered_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void VerticalFilter_SSE2(const uint8_t* data, int width, int height,
|
static void VerticalFilter_SSE2(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
DoVerticalFilter_SSE2(data, width, height, stride, filtered_data);
|
DoVerticalFilter_SSE2(data, width, height, stride, filtered_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GradientFilter_SSE2(const uint8_t* data, int width, int height,
|
static void GradientFilter_SSE2(const uint8_t* WEBP_RESTRICT data,
|
||||||
int stride, uint8_t* filtered_data) {
|
int width, int height, int stride,
|
||||||
|
uint8_t* WEBP_RESTRICT filtered_data) {
|
||||||
DoGradientFilter_SSE2(data, width, height, stride, filtered_data);
|
DoGradientFilter_SSE2(data, width, height, stride, filtered_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user