Skip to content

Commit ea0b7da

Browse files
committed
Offset: apply hoist optimizations
1 parent 31dba2d commit ea0b7da

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;
@@ -45,19 +51,23 @@ ImagingOffset(Imaging im, int xoffset, int yoffset) {
4551
yoffset += im->ysize;
4652
}
4753

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

5767
if (im->image8) {
58-
OFFSET(image8)
68+
OFFSET(UINT8, image8)
5969
} else {
60-
OFFSET(image32)
70+
OFFSET(INT32, image32)
6171
}
6272

6373
return imOut;

0 commit comments

Comments
 (0)