vf_boxblur: Templatize blur{8,16}

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Timothy Gu 2015-11-01 10:20:58 -08:00
parent c03044c86a
commit dee7440531
1 changed files with 44 additions and 66 deletions

View File

@ -204,10 +204,7 @@ static int config_input(AVFilterLink *inlink)
return 0; return 0;
} }
static inline void blur8(uint8_t *dst, int dst_step, const uint8_t *src, int src_step, /* Naive boxblur would sum source pixels from x-radius .. x+radius
int len, int radius)
{
/* Naive boxblur would sum source pixels from x-radius .. x+radius
* for destination pixel x. That would be O(radius*width). * for destination pixel x. That would be O(radius*width).
* If you now look at what source pixels represent 2 consecutive * If you now look at what source pixels represent 2 consecutive
* output pixels, then you see they are almost identical and only * output pixels, then you see they are almost identical and only
@ -221,58 +218,39 @@ static inline void blur8(uint8_t *dst, int dst_step, const uint8_t *src, int src
* and subtracting 1 input pixel. * and subtracting 1 input pixel.
* The following code adopts this faster variant. * The following code adopts this faster variant.
*/ */
const int length = radius*2 + 1; #define BLUR(type, depth) \
const int inv = ((1<<16) + length/2)/length; static inline void blur ## depth(type *dst, int dst_step, const type *src, \
int x, sum = src[radius*src_step]; int src_step, int len, int radius) \
{ \
for (x = 0; x < radius; x++) const int length = radius*2 + 1; \
sum += src[x*src_step]<<1; const int inv = ((1<<16) + length/2)/length; \
int x, sum = src[radius*src_step]; \
sum = sum*inv + (1<<15); \
for (x = 0; x < radius; x++) \
for (x = 0; x <= radius; x++) { sum += src[x*src_step]<<1; \
sum += (src[(radius+x)*src_step] - src[(radius-x)*src_step])*inv; \
dst[x*dst_step] = sum>>16; sum = sum*inv + (1<<15); \
} \
for (x = 0; x <= radius; x++) { \
for (; x < len-radius; x++) { sum += (src[(radius+x)*src_step] - src[(radius-x)*src_step])*inv; \
sum += (src[(radius+x)*src_step] - src[(x-radius-1)*src_step])*inv; dst[x*dst_step] = sum>>16; \
dst[x*dst_step] = sum >>16; } \
} \
for (; x < len-radius; x++) { \
for (; x < len; x++) { sum += (src[(radius+x)*src_step] - src[(x-radius-1)*src_step])*inv; \
sum += (src[(2*len-radius-x-1)*src_step] - src[(x-radius-1)*src_step])*inv; dst[x*dst_step] = sum >>16; \
dst[x*dst_step] = sum>>16; } \
} \
for (; x < len; x++) { \
sum += (src[(2*len-radius-x-1)*src_step] - src[(x-radius-1)*src_step])*inv; \
dst[x*dst_step] = sum>>16; \
} \
} }
static inline void blur16(uint16_t *dst, int dst_step, const uint16_t *src, int src_step, BLUR(uint8_t, 8)
int len, int radius) BLUR(uint16_t, 16)
{
const int length = radius*2 + 1;
const int inv = ((1<<16) + length/2)/length;
int x, sum = src[radius*src_step];
for (x = 0; x < radius; x++) #undef BLUR
sum += src[x*src_step]<<1;
sum = sum*inv + (1<<15);
for (x = 0; x <= radius; x++) {
sum += (src[(radius+x)*src_step] - src[(radius-x)*src_step])*inv;
dst[x*dst_step] = sum>>16;
}
for (; x < len-radius; x++) {
sum += (src[(radius+x)*src_step] - src[(x-radius-1)*src_step])*inv;
dst[x*dst_step] = sum >>16;
}
for (; x < len; x++) {
sum += (src[(2*len-radius-x-1)*src_step] - src[(x-radius-1)*src_step])*inv;
dst[x*dst_step] = sum>>16;
}
}
static inline void blur(uint8_t *dst, int dst_step, const uint8_t *src, int src_step, static inline void blur(uint8_t *dst, int dst_step, const uint8_t *src, int src_step,
int len, int radius, int pixsize) int len, int radius, int pixsize)