Skip to content

Commit 6e6a705

Browse files
committed
Plugins (alphablend): Fix blending and associated crashes due to buffer overruns.
1 parent b40b4f7 commit 6e6a705

File tree

1 file changed

+30
-21
lines changed

1 file changed

+30
-21
lines changed

libvisual-plugins/plugins/morph/alphablend/morph_alphablend.c

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@
2424
#include "config.h"
2525
#include "gettext.h"
2626
#include <libvisual/libvisual.h>
27+
#include <stdlib.h>
2728

2829
VISUAL_PLUGIN_API_VERSION_VALIDATOR
2930

3031
static int lv_morph_alpha_init (VisPluginData *plugin);
3132
static void lv_morph_alpha_cleanup (VisPluginData *plugin);
3233
static void lv_morph_alpha_apply (VisPluginData *plugin, float progress, VisAudio *audio, VisVideo *dest, VisVideo *src1, VisVideo *src2);
3334

34-
static inline void alpha_blend_buffer (uint8_t *dest, uint8_t *src1, uint8_t *src2, int size, int depth, float alpha);
35+
typedef void (*BlendFunc) (uint8_t *, const uint8_t *, const uint8_t *, visual_size_t, uint8_t);
36+
37+
static BlendFunc get_blend_func (VisVideoDepth depth);
3538

3639
const VisPluginInfo *get_plugin_info (void)
3740
{
@@ -80,33 +83,39 @@ static void lv_morph_alpha_cleanup (VisPluginData *plugin)
8083

8184
static void lv_morph_alpha_apply (VisPluginData *plugin, float progress, VisAudio *audio, VisVideo *dest, VisVideo *src1, VisVideo *src2)
8285
{
83-
alpha_blend_buffer (visual_video_get_pixels (dest),
84-
visual_video_get_pixels (src1),
85-
visual_video_get_pixels (src2),
86-
visual_video_get_size (dest),
87-
visual_video_get_depth (dest),
88-
progress);
86+
int width = visual_video_get_width (dest);
87+
int height = visual_video_get_height (dest);
88+
int depth = visual_video_get_depth (dest);
89+
int pitch = visual_video_get_pitch (dest);
90+
91+
uint8_t *src1_row_ptr = visual_video_get_pixels (src1);
92+
uint8_t *src2_row_ptr = visual_video_get_pixels (src2);
93+
uint8_t *dest_row_ptr = visual_video_get_pixels (dest);
94+
95+
uint8_t alpha = progress * 255;
96+
BlendFunc blend_func = get_blend_func (depth);
97+
98+
for (int y = 0; y < height; y++) {
99+
blend_func (dest_row_ptr, src1_row_ptr, src2_row_ptr, width, alpha);
100+
src1_row_ptr += pitch;
101+
src2_row_ptr += pitch;
102+
dest_row_ptr += pitch;
103+
}
89104
}
90105

91-
static inline void alpha_blend_buffer (uint8_t *dest, uint8_t *src1, uint8_t *src2, int size, int depth, float progress)
106+
static BlendFunc get_blend_func (VisVideoDepth depth)
92107
{
93-
uint8_t a = progress * 255;
94-
95108
switch (depth) {
96109
case VISUAL_VIDEO_DEPTH_8BIT:
97-
visual_alpha_blend_8 (dest, src1, src2, size, a);
98-
break;
99-
110+
return visual_alpha_blend_8;
100111
case VISUAL_VIDEO_DEPTH_16BIT:
101-
visual_alpha_blend_16 (dest, src1, src2, size, a);
102-
break;
103-
112+
return visual_alpha_blend_16;
104113
case VISUAL_VIDEO_DEPTH_24BIT:
105-
visual_alpha_blend_24 (dest, src1, src2, size, a);
106-
break;
107-
114+
return visual_alpha_blend_24;
108115
case VISUAL_VIDEO_DEPTH_32BIT:
109-
visual_alpha_blend_32 (dest, src1, src2, size, a);
110-
break;
116+
return visual_alpha_blend_32;
117+
default:
118+
visual_log (VISUAL_LOG_CRITICAL, "Unsupported depth for blending (%d)", depth);
119+
abort ();
111120
}
112121
}

0 commit comments

Comments
 (0)