Skip to content

Commit 6c4cec3

Browse files
akxradarhere
authored andcommitted
Offset: apply hoist optimizations
Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com>
1 parent c8c74c8 commit 6c4cec3

1 file changed

Lines changed: 19 additions & 9 deletions

File tree

src/libImaging/Offset.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616

1717
#include "Imaging.h"
1818

19+
/**
20+
* Copy `im` into a newly allocated image,
21+
* wrapping every pixel by (xoffset, yoffset) modulo the image size.
22+
*
23+
* Contract: im is read-only.
24+
*/
1925
Imaging
2026
ImagingOffset(Imaging im, int xoffset, int yoffset) {
2127
int x, y;
@@ -48,19 +54,23 @@ ImagingOffset(Imaging im, int xoffset, int yoffset) {
4854
yoffset += im->ysize;
4955
}
5056

51-
#define OFFSET(image) \
52-
for (y = 0; y < im->ysize; y++) { \
53-
for (x = 0; x < im->xsize; x++) { \
54-
int yi = (y + yoffset) % im->ysize; \
55-
int xi = (x + xoffset) % im->xsize; \
56-
imOut->image[y][x] = im->image[yi][xi]; \
57-
} \
57+
// yi depends only on y, so compute it (and both row pointers) once per
58+
// row instead of redoing the modulo and pointer chase for every x.
59+
#define OFFSET(type, image) \
60+
for (y = 0; y < im->ysize; y++) { \
61+
int yi = (y + yoffset) % im->ysize; \
62+
type *restrict in = im->image[yi]; \
63+
type *restrict out = imOut->image[y]; \
64+
for (x = 0; x < im->xsize; x++) { \
65+
int xi = (x + xoffset) % im->xsize; \
66+
out[x] = in[xi]; \
67+
} \
5868
}
5969

6070
if (im->image8) {
61-
OFFSET(image8)
71+
OFFSET(UINT8, image8)
6272
} else {
63-
OFFSET(image32)
73+
OFFSET(INT32, image32)
6474
}
6575

6676
return imOut;

0 commit comments

Comments
 (0)