This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 800c3a71e9e23dee9fd9b56f7ab565df85395113 Author: Niklas Haas <[email protected]> AuthorDate: Fri Mar 6 22:41:24 2026 +0100 Commit: Niklas Haas <[email protected]> CommitDate: Wed Mar 18 09:09:44 2026 +0000 swscale/ops_dispatch: properly handle negative strides The `memcpy_in` condition is reversed for negative strides, which require a memcpy() on the *first* line, not the last line. Additionally, the check just completely didn't work for negative linesizes, due to comparing against a negative stride. Signed-off-by: Niklas Haas <[email protected]> --- libswscale/ops_dispatch.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/libswscale/ops_dispatch.c b/libswscale/ops_dispatch.c index 713b34b86b..fb176dba15 100644 --- a/libswscale/ops_dispatch.c +++ b/libswscale/ops_dispatch.c @@ -40,7 +40,8 @@ typedef struct SwsOpPass { int pixel_bits_out; int idx_in[4]; int idx_out[4]; - bool memcpy_in; + bool memcpy_first; + bool memcpy_last; bool memcpy_out; } SwsOpPass; @@ -141,7 +142,8 @@ static int op_pass_setup(const SwsFrame *out, const SwsFrame *in, p->tail_off_out = safe_width * p->pixel_bits_out >> 3; p->tail_size_in = tail_size * p->pixel_bits_in >> 3; p->tail_size_out = tail_size * p->pixel_bits_out >> 3; - p->memcpy_in = false; + p->memcpy_first = false; + p->memcpy_last = false; p->memcpy_out = false; for (int i = 0; i < p->planes_in; i++) { @@ -152,7 +154,12 @@ static int op_pass_setup(const SwsFrame *out, const SwsFrame *in, const int plane_w = (aligned_w + sub_x) >> sub_x; const int plane_pad = (comp->over_read + sub_x) >> sub_x; const int plane_size = plane_w * p->pixel_bits_in >> 3; - p->memcpy_in |= plane_size + plane_pad > in->linesize[idx]; + const int total_size = plane_size + plane_pad; + if (in->linesize[idx] >= 0) { + p->memcpy_last |= total_size > in->linesize[idx]; + } else { + p->memcpy_first |= total_size > -in->linesize[idx]; + } exec->in[i] = in->data[idx]; exec->in_stride[i] = in->linesize[idx]; exec->in_sub_y[i] = sub_y; @@ -167,7 +174,7 @@ static int op_pass_setup(const SwsFrame *out, const SwsFrame *in, const int plane_w = (aligned_w + sub_x) >> sub_x; const int plane_pad = (comp->over_write + sub_x) >> sub_x; const int plane_size = plane_w * p->pixel_bits_out >> 3; - p->memcpy_out |= plane_size + plane_pad > out->linesize[idx]; + p->memcpy_out |= plane_size + plane_pad > FFABS(out->linesize[idx]); exec->out[i] = out->data[idx]; exec->out_stride[i] = out->linesize[idx]; exec->out_sub_y[i] = sub_y; @@ -268,7 +275,9 @@ static void op_pass_run(const SwsFrame *out, const SwsFrame *in, const int y, * * 1. We can overread the input, unless this is the last line of an * unpadded buffer. All defined operations can handle arbitrary pixel - * input, so overread of arbitrary data is fine. + * input, so overread of arbitrary data is fine. For flipped images, + * this condition is actually *inverted* to where the first line is + * the one at the end of the buffer. * * 2. We can overwrite the output, as long as we don't write more than the * amount of pixels that fit into one linesize. So we always need to @@ -280,8 +289,8 @@ static void op_pass_run(const SwsFrame *out, const SwsFrame *in, const int y, * need to worry about this for the end of a slice. */ - const int last_slice = y + h == pass->height; - const bool memcpy_in = last_slice && p->memcpy_in; + const bool memcpy_in = p->memcpy_last && y + h == pass->height || + p->memcpy_first && y == 0; const bool memcpy_out = p->memcpy_out; const int num_blocks = p->num_blocks; const int blocks_main = num_blocks - memcpy_out; _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
