diff --git a/libvisual-plugins/plugins/morph/alphablend/morph_alphablend.c b/libvisual-plugins/plugins/morph/alphablend/morph_alphablend.c index f32ff26a0..bc76bcb35 100644 --- a/libvisual-plugins/plugins/morph/alphablend/morph_alphablend.c +++ b/libvisual-plugins/plugins/morph/alphablend/morph_alphablend.c @@ -24,6 +24,7 @@ #include "config.h" #include "gettext.h" #include +#include VISUAL_PLUGIN_API_VERSION_VALIDATOR @@ -31,7 +32,9 @@ static int lv_morph_alpha_init (VisPluginData *plugin); static void lv_morph_alpha_cleanup (VisPluginData *plugin); static void lv_morph_alpha_apply (VisPluginData *plugin, float progress, VisAudio *audio, VisVideo *dest, VisVideo *src1, VisVideo *src2); -static inline void alpha_blend_buffer (uint8_t *dest, uint8_t *src1, uint8_t *src2, int size, int depth, float alpha); +typedef void (*BlendFunc) (uint8_t *, const uint8_t *, const uint8_t *, visual_size_t, uint8_t); + +static BlendFunc get_blend_func (VisVideoDepth depth); const VisPluginInfo *get_plugin_info (void) { @@ -80,33 +83,39 @@ static void lv_morph_alpha_cleanup (VisPluginData *plugin) static void lv_morph_alpha_apply (VisPluginData *plugin, float progress, VisAudio *audio, VisVideo *dest, VisVideo *src1, VisVideo *src2) { - alpha_blend_buffer (visual_video_get_pixels (dest), - visual_video_get_pixels (src1), - visual_video_get_pixels (src2), - visual_video_get_size (dest), - visual_video_get_depth (dest), - progress); + int width = visual_video_get_width (dest); + int height = visual_video_get_height (dest); + int depth = visual_video_get_depth (dest); + int pitch = visual_video_get_pitch (dest); + + uint8_t *src1_row_ptr = visual_video_get_pixels (src1); + uint8_t *src2_row_ptr = visual_video_get_pixels (src2); + uint8_t *dest_row_ptr = visual_video_get_pixels (dest); + + uint8_t alpha = progress * 255; + BlendFunc blend_func = get_blend_func (depth); + + for (int y = 0; y < height; y++) { + blend_func (dest_row_ptr, src1_row_ptr, src2_row_ptr, width, alpha); + src1_row_ptr += pitch; + src2_row_ptr += pitch; + dest_row_ptr += pitch; + } } -static inline void alpha_blend_buffer (uint8_t *dest, uint8_t *src1, uint8_t *src2, int size, int depth, float alpha) +static BlendFunc get_blend_func (VisVideoDepth depth) { - uint8_t a = alpha * (1/255.0); - switch (depth) { case VISUAL_VIDEO_DEPTH_8BIT: - visual_alpha_blend_8 (dest, src1, src2, size, a); - break; - + return visual_alpha_blend_8; case VISUAL_VIDEO_DEPTH_16BIT: - visual_alpha_blend_16 (dest, src1, src2, size, a); - break; - + return visual_alpha_blend_16; case VISUAL_VIDEO_DEPTH_24BIT: - visual_alpha_blend_24 (dest, src1, src2, size, a); - break; - + return visual_alpha_blend_24; case VISUAL_VIDEO_DEPTH_32BIT: - visual_alpha_blend_32 (dest, src1, src2, size, a); - break; + return visual_alpha_blend_32; + default: + visual_log (VISUAL_LOG_CRITICAL, "Unsupported depth for blending (%d)", depth); + abort (); } } diff --git a/libvisual/libvisual/lv_alpha_blend.c b/libvisual/libvisual/lv_alpha_blend.c index 8ec690ce2..ca79e3994 100644 --- a/libvisual/libvisual/lv_alpha_blend.c +++ b/libvisual/libvisual/lv_alpha_blend.c @@ -16,31 +16,30 @@ typedef struct { #pragma pack() -void visual_alpha_blend_8 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha) +void visual_alpha_blend_8 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t n, uint8_t alpha) { - simd_interpolate_8 (dest, src1, src2, alpha, (int) size); + simd_interpolate_8 (dest, src1, src2, alpha, (int) n); } -void visual_alpha_blend_16 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha) +void visual_alpha_blend_16 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t n, uint8_t alpha) { rgb16_t *destr = (rgb16_t *) dest; rgb16_t *src1r = (rgb16_t *) src1; rgb16_t *src2r = (rgb16_t *) src2; - visual_size_t i; - for (i = 0; i < size / 2; i++) { + for (visual_size_t i = 0; i < n; i++) { destr[i].r = (alpha * (src2r[i].r - src1r[i].r)) / 255 + src1r[i].r; destr[i].g = (alpha * (src2r[i].g - src1r[i].g)) / 255 + src1r[i].g; destr[i].b = (alpha * (src2r[i].b - src1r[i].b)) / 255 + src1r[i].b; } } -void visual_alpha_blend_24 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha) +void visual_alpha_blend_24 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t n, uint8_t alpha) { - simd_interpolate_8 (dest, src1, src2, alpha, (int) size * 3); + simd_interpolate_8 (dest, src1, src2, alpha, (int) n * 3); } -void visual_alpha_blend_32 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha) +void visual_alpha_blend_32 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t n, uint8_t alpha) { - simd_interpolate_8 (dest, src1, src2, alpha, (int) size * 4); + simd_interpolate_8 (dest, src1, src2, alpha, (int) n * 4); } diff --git a/libvisual/libvisual/lv_alpha_blend.h b/libvisual/libvisual/lv_alpha_blend.h index 636bf5b81..3ed2f292f 100644 --- a/libvisual/libvisual/lv_alpha_blend.h +++ b/libvisual/libvisual/lv_alpha_blend.h @@ -7,10 +7,10 @@ LV_BEGIN_DECLS -LV_API void visual_alpha_blend_8 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha); -LV_API void visual_alpha_blend_16 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha); -LV_API void visual_alpha_blend_24 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha); -LV_API void visual_alpha_blend_32 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha); +LV_API void visual_alpha_blend_8 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t n, uint8_t alpha); +LV_API void visual_alpha_blend_16 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t n, uint8_t alpha); +LV_API void visual_alpha_blend_24 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t n, uint8_t alpha); +LV_API void visual_alpha_blend_32 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t n, uint8_t alpha); LV_END_DECLS