Skip to content

Commit f600687

Browse files
committed
Speed up hline32 and hline32rgba by unswitch + vectorization hint
1 parent 1999938 commit f600687

1 file changed

Lines changed: 35 additions & 13 deletions

File tree

src/libImaging/Draw.c

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -165,18 +165,28 @@ hline32(Imaging im, int x0, int y0, int x1, int ink, Imaging mask) {
165165
x1 = im->xsize - 1;
166166
}
167167
p = im->image32[y0];
168-
while (x0 <= x1) {
169-
if (mask == NULL || mask->image8[y0][x0]) {
168+
if (mask == NULL) {
169+
for (; x0 <= x1; x0++) {
170170
p[x0] = ink;
171171
}
172-
x0++;
172+
} else {
173+
UINT8 *mask_row = mask->image8[y0];
174+
for (; x0 <= x1; x0++) {
175+
if (mask_row[x0]) {
176+
p[x0] = ink;
177+
}
178+
}
173179
}
174180
}
175181
}
176182

177183
static inline void
178184
hline32rgba(Imaging im, int x0, int y0, int x1, int ink, Imaging mask) {
179185
unsigned int tmp;
186+
UINT8 r = ((UINT8 *)&ink)[0];
187+
UINT8 g = ((UINT8 *)&ink)[1];
188+
UINT8 b = ((UINT8 *)&ink)[2];
189+
UINT8 a = ((UINT8 *)&ink)[3];
180190

181191
if (y0 >= 0 && y0 < im->ysize) {
182192
if (x0 < 0) {
@@ -189,17 +199,29 @@ hline32rgba(Imaging im, int x0, int y0, int x1, int ink, Imaging mask) {
189199
} else if (x1 >= im->xsize) {
190200
x1 = im->xsize - 1;
191201
}
192-
if (x0 <= x1) {
193-
UINT8 *out = (UINT8 *)im->image[y0] + x0 * 4;
194-
UINT8 *in = (UINT8 *)&ink;
195-
while (x0 <= x1) {
196-
if (mask == NULL || mask->image8[y0][x0]) {
197-
out[0] = BLEND(in[3], out[0], in[0], tmp);
198-
out[1] = BLEND(in[3], out[1], in[1], tmp);
199-
out[2] = BLEND(in[3], out[2], in[2], tmp);
202+
if (x0 > x1) {
203+
return;
204+
}
205+
206+
UINT8 *restrict out = (UINT8 *)im->image[y0] + x0 * 4;
207+
if (mask == NULL) {
208+
for (; x0 <= x1; x0++, out += 4) {
209+
out[0] = BLEND(a, out[0], r, tmp);
210+
out[1] = BLEND(a, out[1], g, tmp);
211+
out[2] = BLEND(a, out[2], b, tmp);
212+
// No-op, but allows the compiler to vectorize the loop:
213+
out[3] = BLEND(a, out[3], out[3], tmp);
214+
}
215+
} else {
216+
UINT8 *mask_row = mask->image8[y0];
217+
for (; x0 <= x1; x0++, out += 4) {
218+
if (mask_row[x0]) {
219+
out[0] = BLEND(a, out[0], r, tmp);
220+
out[1] = BLEND(a, out[1], g, tmp);
221+
out[2] = BLEND(a, out[2], b, tmp);
222+
// Not touching out[3] here, since the mask check prevents
223+
// vectorization anyway.
200224
}
201-
x0++;
202-
out += 4;
203225
}
204226
}
205227
}

0 commit comments

Comments
 (0)