This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch release/7.1
in repository ffmpeg.

commit bb88e295394e5db584063bde790bfbdba04d54ec
Author:     Niklas Haas <[email protected]>
AuthorDate: Wed Jul 30 13:36:21 2025 +0200
Commit:     Michael Niedermayer <[email protected]>
CommitDate: Fri Jun 19 15:58:40 2026 +0200

    swscale/alphablend: don't overread alpha plane on subsampled odd size
    
    This function overreads the input plane for odd dimensions, because the
    chroma plane is always rounded up, which means (xy << subsample) + 1 exceeds
    the actual alpha plane size.
    
    To verify:
      valgrind ffmpeg -pix_fmt yuva420p -f lavfi -i color -vf \
      "scale=1x1,format=yuva420p,scale=alphablend=uniform_color,format=yuv420p \
      -vframes 1 -f null -
    
    Fixes: https://trac.ffmpeg.org/ticket/11692
    (cherry picked from commit b7946098b19af4f06661213d591a5ed9cd3d26ff)
    Signed-off-by: Michael Niedermayer <[email protected]>
---
 libswscale/alphablend.c | 32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/libswscale/alphablend.c b/libswscale/alphablend.c
index b5967c889b..13e25961b9 100644
--- a/libswscale/alphablend.c
+++ b/libswscale/alphablend.c
@@ -25,6 +25,8 @@ int ff_sws_alphablendaway(SwsContext *c, const uint8_t *src[],
                           uint8_t *dst[], int dstStride[])
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
+    const int lum_w = c->srcW;
+    const int lum_h = c->srcH;
     int nb_components = desc->nb_components;
     int plane, x, ysrc;
     int plane_count = isGray(c->srcFormat) ? 1 : 3;
@@ -52,7 +54,8 @@ int ff_sws_alphablendaway(SwsContext *c, const uint8_t *src[],
             int y_subsample = plane ? desc->log2_chroma_h: 0;
             for (ysrc = 0; ysrc < AV_CEIL_RSHIFT(srcSliceH, y_subsample); 
ysrc++) {
                 int y = ysrc + (srcSliceY >> y_subsample);
-                if (x_subsample || y_subsample) {
+                int subsample_row = y_subsample && (y << y_subsample) + 1 < 
lum_h;
+                if (x_subsample || subsample_row) {
                     int alpha;
                     unsigned u;
                     if (sixteen_bits) {
@@ -62,21 +65,23 @@ int ff_sws_alphablendaway(SwsContext *c, const uint8_t 
*src[],
                               uint16_t *d = (      uint16_t *)(dst[plane      
] +  dstStride[plane      ] * y);
                         if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {
                             for (x = 0; x < w; x++) {
-                                if (y_subsample) {
-                                    alpha = (a[2*x]              + a[2*x + 1] 
+ 2 +
-                                             a[2*x + alpha_step] + a[2*x + 
alpha_step + 1]) >> 2;
+                                const int xnext = FFMIN(2*x + 1, lum_w - 1);
+                                if (subsample_row) {
+                                    alpha = (a[2*x]              + a[xnext] + 
2 +
+                                             a[2*x + alpha_step] + a[xnext + 
alpha_step]) >> 2;
                                 } else
-                                    alpha = (a[2*x] + a[2*x + 1]) >> 1;
+                                    alpha = (a[2*x] + a[xnext]) >> 1;
                                 u = s[x]*alpha + 
target_table[((x^y)>>5)&1][plane]*(max-alpha) + off;
                                 d[x] = av_clip((u + (u >> shift)) >> shift, 0, 
max);
                             }
                         } else {
                             for (x = 0; x < w; x++) {
-                                if (y_subsample) {
-                                    alpha = (av_bswap16(a[2*x])              + 
av_bswap16(a[2*x + 1]) + 2 +
-                                             av_bswap16(a[2*x + alpha_step]) + 
av_bswap16(a[2*x + alpha_step + 1])) >> 2;
+                                const int xnext = FFMIN(2*x + 1, lum_w - 1);
+                                if (subsample_row) {
+                                    alpha = (av_bswap16(a[2*x])              + 
av_bswap16(a[xnext]) + 2 +
+                                             av_bswap16(a[2*x + alpha_step]) + 
av_bswap16(a[xnext + alpha_step])) >> 2;
                                 } else
-                                    alpha = (av_bswap16(a[2*x]) + 
av_bswap16(a[2*x + 1])) >> 1;
+                                    alpha = (av_bswap16(a[2*x]) + 
av_bswap16(a[xnext])) >> 1;
                                 u = av_bswap16(s[x])*alpha + 
target_table[((x^y)>>5)&1][plane]*(max-alpha) + off;
                                 d[x] = av_clip((u + (u >> shift)) >> shift, 0, 
max);
                             }
@@ -87,11 +92,12 @@ int ff_sws_alphablendaway(SwsContext *c, const uint8_t 
*src[],
                         const uint8_t *a = src[plane_count] + 
(srcStride[plane_count] * ysrc << y_subsample);
                               uint8_t *d = dst[plane      ] + dstStride[plane] 
* y;
                         for (x = 0; x < w; x++) {
-                            if (y_subsample) {
-                                alpha = (a[2*x]              + a[2*x + 1] + 2 +
-                                         a[2*x + alpha_step] + a[2*x + 
alpha_step + 1]) >> 2;
+                            const int xnext = FFMIN(2*x + 1, lum_w - 1);
+                            if (subsample_row) {
+                                alpha = (a[2*x]              + a[xnext] + 2 +
+                                         a[2*x + alpha_step] + a[xnext + 
alpha_step]) >> 2;
                             } else
-                                alpha = (a[2*x] + a[2*x + 1]) >> 1;
+                                alpha = (a[2*x] + a[xnext]) >> 1;
                             u = s[x]*alpha + 
target_table[((x^y)>>5)&1][plane]*(255-alpha) + 128;
                             d[x] = (257*u) >> 16;
                         }

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to