Skip to content

Commit e2022ed

Browse files
committed
Split I16 ImageFilter loops so they are optimized by compiler
1 parent e2bc056 commit e2022ed

1 file changed

Lines changed: 75 additions & 66 deletions

File tree

src/libImaging/Filter.c

Lines changed: 75 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -154,17 +154,16 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float *kernel, float offset) {
154154
}
155155
out[x] = in0[x];
156156
}
157-
} else {
157+
} else if (im->type == IMAGING_TYPE_SPECIAL) {
158+
// Check for I;16 mode once, not per pixel
158159
int bigendian = 0;
159-
if (im->type == IMAGING_TYPE_SPECIAL) {
160-
if (
161-
im->mode == IMAGING_MODE_I_16B
160+
if (
161+
im->mode == IMAGING_MODE_I_16B
162162
#ifdef WORDS_BIGENDIAN
163-
|| im->mode == IMAGING_MODE_I_16N
163+
|| im->mode == IMAGING_MODE_I_16N
164164
#endif
165-
) {
166-
bigendian = 1;
167-
}
165+
) {
166+
bigendian = 1;
168167
}
169168
for (y = 1; y < ysize - 1; y++) {
170169
UINT8 *restrict in_1 = (UINT8 *)im->image[y - 1];
@@ -173,31 +172,35 @@ ImagingFilter3x3(Imaging imOut, Imaging im, const float *kernel, float offset) {
173172
UINT8 *restrict out = (UINT8 *)imOut->image[y];
174173

175174
out[0] = in0[0];
176-
if (im->type == IMAGING_TYPE_SPECIAL) {
177-
out[1] = in0[1];
178-
}
175+
out[1] = in0[1];
179176
for (x = 1; x < xsize - 1; x++) {
180177
float ss = offset;
181-
if (im->type == IMAGING_TYPE_SPECIAL) {
182-
ss += kernel_i16(3, in1, x, &kernel[0], bigendian);
183-
ss += kernel_i16(3, in0, x, &kernel[3], bigendian);
184-
ss += kernel_i16(3, in_1, x, &kernel[6], bigendian);
185-
int ss_int = ROUND_UP(ss);
186-
out[x * 2 + (bigendian ? 1 : 0)] = clip8(ss_int % 256);
187-
out[x * 2 + (bigendian ? 0 : 1)] = clip8(ss_int >> 8);
188-
} else {
189-
ss += KERNEL1x3(in1, x, &kernel[0], 1);
190-
ss += KERNEL1x3(in0, x, &kernel[3], 1);
191-
ss += KERNEL1x3(in_1, x, &kernel[6], 1);
192-
out[x] = clip8(ss);
193-
}
178+
ss += kernel_i16(3, in1, x, &kernel[0], bigendian);
179+
ss += kernel_i16(3, in0, x, &kernel[3], bigendian);
180+
ss += kernel_i16(3, in_1, x, &kernel[6], bigendian);
181+
int ss_int = ROUND_UP(ss);
182+
out[x * 2 + (bigendian ? 1 : 0)] = clip8(ss_int % 256);
183+
out[x * 2 + (bigendian ? 0 : 1)] = clip8(ss_int >> 8);
194184
}
195-
if (im->type == IMAGING_TYPE_SPECIAL) {
196-
out[x * 2] = in0[x * 2];
197-
out[x * 2 + 1] = in0[x * 2 + 1];
198-
} else {
199-
out[x] = in0[x];
185+
out[x * 2] = in0[x * 2];
186+
out[x * 2 + 1] = in0[x * 2 + 1];
187+
}
188+
} else {
189+
for (y = 1; y < ysize - 1; y++) {
190+
UINT8 *restrict in_1 = (UINT8 *)im->image[y - 1];
191+
UINT8 *restrict in0 = (UINT8 *)im->image[y];
192+
UINT8 *restrict in1 = (UINT8 *)im->image[y + 1];
193+
UINT8 *restrict out = (UINT8 *)imOut->image[y];
194+
195+
out[0] = in0[0];
196+
for (x = 1; x < xsize - 1; x++) {
197+
float ss = offset;
198+
ss += KERNEL1x3(in1, x, &kernel[0], 1);
199+
ss += KERNEL1x3(in0, x, &kernel[3], 1);
200+
ss += KERNEL1x3(in_1, x, &kernel[6], 1);
201+
out[x] = clip8(ss);
200202
}
203+
out[x] = in0[x];
201204
}
202205
}
203206
} else {
@@ -314,17 +317,16 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float *kernel, float offset) {
314317
out[x + 0] = in0[x + 0];
315318
out[x + 1] = in0[x + 1];
316319
}
317-
} else {
320+
} else if (im->type == IMAGING_TYPE_SPECIAL) {
321+
// Check for I;16 mode once, not per pixel
318322
int bigendian = 0;
319-
if (im->type == IMAGING_TYPE_SPECIAL) {
320-
if (
321-
im->mode == IMAGING_MODE_I_16B
323+
if (
324+
im->mode == IMAGING_MODE_I_16B
322325
#ifdef WORDS_BIGENDIAN
323-
|| im->mode == IMAGING_MODE_I_16N
326+
|| im->mode == IMAGING_MODE_I_16N
324327
#endif
325-
) {
326-
bigendian = 1;
327-
}
328+
) {
329+
bigendian = 1;
328330
}
329331
for (y = 2; y < ysize - 2; y++) {
330332
UINT8 *restrict in_2 = (UINT8 *)im->image[y - 2];
@@ -336,39 +338,46 @@ ImagingFilter5x5(Imaging imOut, Imaging im, const float *kernel, float offset) {
336338

337339
out[0] = in0[0];
338340
out[1] = in0[1];
339-
if (im->type == IMAGING_TYPE_SPECIAL) {
340-
out[2] = in0[2];
341-
out[3] = in0[3];
342-
}
341+
out[2] = in0[2];
342+
out[3] = in0[3];
343343
for (x = 2; x < xsize - 2; x++) {
344344
float ss = offset;
345-
if (im->type == IMAGING_TYPE_SPECIAL) {
346-
ss += kernel_i16(5, in2, x, &kernel[0], bigendian);
347-
ss += kernel_i16(5, in1, x, &kernel[5], bigendian);
348-
ss += kernel_i16(5, in0, x, &kernel[10], bigendian);
349-
ss += kernel_i16(5, in_1, x, &kernel[15], bigendian);
350-
ss += kernel_i16(5, in_2, x, &kernel[20], bigendian);
351-
int ss_int = ROUND_UP(ss);
352-
out[x * 2 + (bigendian ? 1 : 0)] = clip8(ss_int % 256);
353-
out[x * 2 + (bigendian ? 0 : 1)] = clip8(ss_int >> 8);
354-
} else {
355-
ss += KERNEL1x5(in2, x, &kernel[0], 1);
356-
ss += KERNEL1x5(in1, x, &kernel[5], 1);
357-
ss += KERNEL1x5(in0, x, &kernel[10], 1);
358-
ss += KERNEL1x5(in_1, x, &kernel[15], 1);
359-
ss += KERNEL1x5(in_2, x, &kernel[20], 1);
360-
out[x] = clip8(ss);
361-
}
345+
ss += kernel_i16(5, in2, x, &kernel[0], bigendian);
346+
ss += kernel_i16(5, in1, x, &kernel[5], bigendian);
347+
ss += kernel_i16(5, in0, x, &kernel[10], bigendian);
348+
ss += kernel_i16(5, in_1, x, &kernel[15], bigendian);
349+
ss += kernel_i16(5, in_2, x, &kernel[20], bigendian);
350+
int ss_int = ROUND_UP(ss);
351+
out[x * 2 + (bigendian ? 1 : 0)] = clip8(ss_int % 256);
352+
out[x * 2 + (bigendian ? 0 : 1)] = clip8(ss_int >> 8);
362353
}
363-
if (im->type == IMAGING_TYPE_SPECIAL) {
364-
out[x * 2 + 0] = in0[x * 2 + 0];
365-
out[x * 2 + 1] = in0[x * 2 + 1];
366-
out[x * 2 + 2] = in0[x * 2 + 2];
367-
out[x * 2 + 3] = in0[x * 2 + 3];
368-
} else {
369-
out[x + 0] = in0[x + 0];
370-
out[x + 1] = in0[x + 1];
354+
out[x * 2 + 0] = in0[x * 2 + 0];
355+
out[x * 2 + 1] = in0[x * 2 + 1];
356+
out[x * 2 + 2] = in0[x * 2 + 2];
357+
out[x * 2 + 3] = in0[x * 2 + 3];
358+
}
359+
} else {
360+
for (y = 2; y < ysize - 2; y++) {
361+
UINT8 *restrict in_2 = (UINT8 *)im->image[y - 2];
362+
UINT8 *restrict in_1 = (UINT8 *)im->image[y - 1];
363+
UINT8 *restrict in0 = (UINT8 *)im->image[y];
364+
UINT8 *restrict in1 = (UINT8 *)im->image[y + 1];
365+
UINT8 *restrict in2 = (UINT8 *)im->image[y + 2];
366+
UINT8 *restrict out = (UINT8 *)imOut->image[y];
367+
368+
out[0] = in0[0];
369+
out[1] = in0[1];
370+
for (x = 2; x < xsize - 2; x++) {
371+
float ss = offset;
372+
ss += KERNEL1x5(in2, x, &kernel[0], 1);
373+
ss += KERNEL1x5(in1, x, &kernel[5], 1);
374+
ss += KERNEL1x5(in0, x, &kernel[10], 1);
375+
ss += KERNEL1x5(in_1, x, &kernel[15], 1);
376+
ss += KERNEL1x5(in_2, x, &kernel[20], 1);
377+
out[x] = clip8(ss);
371378
}
379+
out[x + 0] = in0[x + 0];
380+
out[x + 1] = in0[x + 1];
372381
}
373382
}
374383
} else {

0 commit comments

Comments
 (0)