Skip to content

Commit 4f8c4ac

Browse files
authored
Merge pull request #383 from Libvisual/fix-alphablend-blending
Plugins (alphablend): Fix blending and associated crashes due to buffer overruns.
2 parents b521806 + aba8a84 commit 4f8c4ac

File tree

3 files changed

+42
-34
lines changed

3 files changed

+42
-34
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 alpha)
106+
static BlendFunc get_blend_func (VisVideoDepth depth)
92107
{
93-
uint8_t a = alpha * (1/255.0);
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
}

libvisual/libvisual/lv_alpha_blend.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,30 @@ typedef struct {
1616

1717
#pragma pack()
1818

19-
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)
19+
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)
2020
{
21-
simd_interpolate_8 (dest, src1, src2, alpha, (int) size);
21+
simd_interpolate_8 (dest, src1, src2, alpha, (int) n);
2222
}
2323

24-
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)
24+
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)
2525
{
2626
rgb16_t *destr = (rgb16_t *) dest;
2727
rgb16_t *src1r = (rgb16_t *) src1;
2828
rgb16_t *src2r = (rgb16_t *) src2;
29-
visual_size_t i;
3029

31-
for (i = 0; i < size / 2; i++) {
30+
for (visual_size_t i = 0; i < n; i++) {
3231
destr[i].r = (alpha * (src2r[i].r - src1r[i].r)) / 255 + src1r[i].r;
3332
destr[i].g = (alpha * (src2r[i].g - src1r[i].g)) / 255 + src1r[i].g;
3433
destr[i].b = (alpha * (src2r[i].b - src1r[i].b)) / 255 + src1r[i].b;
3534
}
3635
}
3736

38-
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)
37+
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)
3938
{
40-
simd_interpolate_8 (dest, src1, src2, alpha, (int) size * 3);
39+
simd_interpolate_8 (dest, src1, src2, alpha, (int) n * 3);
4140
}
4241

43-
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)
42+
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)
4443
{
45-
simd_interpolate_8 (dest, src1, src2, alpha, (int) size * 4);
44+
simd_interpolate_8 (dest, src1, src2, alpha, (int) n * 4);
4645
}

libvisual/libvisual/lv_alpha_blend.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77

88
LV_BEGIN_DECLS
99

10-
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);
11-
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);
12-
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);
13-
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);
10+
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);
11+
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);
12+
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);
13+
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);
1414

1515
LV_END_DECLS
1616

0 commit comments

Comments
 (0)