From ea0b7daa5b940b1e1bfbd2aec0bb1b208ed3c462 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Tue, 2 Jun 2026 11:54:28 +0300 Subject: [PATCH 1/2] Offset: apply hoist optimizations --- src/libImaging/Offset.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/libImaging/Offset.c b/src/libImaging/Offset.c index 91ee91083cc..9ff428d77a7 100644 --- a/src/libImaging/Offset.c +++ b/src/libImaging/Offset.c @@ -16,6 +16,12 @@ #include "Imaging.h" +/** + * Copy `im` into a newly allocated image, + * wrapping every pixel by (xoffset, yoffset) modulo the image size. + * + * Contract: im is read-only. + */ Imaging ImagingOffset(Imaging im, int xoffset, int yoffset) { int x, y; @@ -45,19 +51,23 @@ ImagingOffset(Imaging im, int xoffset, int yoffset) { yoffset += im->ysize; } -#define OFFSET(image) \ - for (y = 0; y < im->ysize; y++) { \ - for (x = 0; x < im->xsize; x++) { \ - int yi = (y + yoffset) % im->ysize; \ - int xi = (x + xoffset) % im->xsize; \ - imOut->image[y][x] = im->image[yi][xi]; \ - } \ + // yi depends only on y, so compute it (and both row pointers) once per + // row instead of redoing the modulo and pointer chase for every x. +#define OFFSET(type, image) \ + for (y = 0; y < im->ysize; y++) { \ + int yi = (y + yoffset) % im->ysize; \ + type *restrict out = imOut->image[y]; \ + type *restrict in = im->image[yi]; \ + for (x = 0; x < im->xsize; x++) { \ + int xi = (x + xoffset) % im->xsize; \ + out[x] = in[xi]; \ + } \ } if (im->image8) { - OFFSET(image8) + OFFSET(UINT8, image8) } else { - OFFSET(image32) + OFFSET(INT32, image32) } return imOut; From 53568b10254ec8299c09232ec558b9f82453daae Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Sat, 4 Jul 2026 13:30:15 +0300 Subject: [PATCH 2/2] Update src/libImaging/Offset.c Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com> --- src/libImaging/Offset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libImaging/Offset.c b/src/libImaging/Offset.c index 9ff428d77a7..e3cc3cf0b7a 100644 --- a/src/libImaging/Offset.c +++ b/src/libImaging/Offset.c @@ -56,8 +56,8 @@ ImagingOffset(Imaging im, int xoffset, int yoffset) { #define OFFSET(type, image) \ for (y = 0; y < im->ysize; y++) { \ int yi = (y + yoffset) % im->ysize; \ - type *restrict out = imOut->image[y]; \ type *restrict in = im->image[yi]; \ + type *restrict out = imOut->image[y]; \ for (x = 0; x < im->xsize; x++) { \ int xi = (x + xoffset) % im->xsize; \ out[x] = in[xi]; \