I have the next bilinear resizing algorithm, and even though I use fixed point is still quite slow for my requirements. In the past I tried to cache some values in tables but the improvement was of a few not noticeable milliseconds.
Is any other way I can improve the speed? As this is intended for ARM processors, I know I could write it with NEON instructions, but unfortunately I don't have the knowledge for such task.
void resize_bilinear(const unsigned int *input, unsigned int *output, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int targetWidth, const unsigned int targetHeight)
{
unsigned int widthCoefficient, heightCoefficient, x, y;
unsigned int pixel1, pixel2, pixel3, pixel4;
unsigned int hc1, hc2, wc1, wc2, offsetX, offsetY;
unsigned int r, g, b, a;
const unsigned int wStepFixed16b = ((sourceWidth - 1) << 16) / ((unsigned int)(targetWidth - 1));
const unsigned int hStepFixed16b = ((sourceHeight - 1) << 16) / ((unsigned int)(targetHeight - 1));
heightCoefficient = 0;
int offsetPixelY;
int offsetPixelY1;
int offsetX1;
for (y = 0; y < targetHeight; y++)
{
offsetY = (heightCoefficient >> 16);
hc2 = (heightCoefficient >> 9) & (unsigned char)127;
hc1 = 128 - hc2;
widthCoefficient = 0;
offsetPixelY = offsetY * sourceWidth;
offsetPixelY1 = (offsetY + 1) * sourceWidth;
for (x = 0; x < targetWidth; x++)
{
offsetX = (widthCoefficient >> 16);
wc2 = (widthCoefficient >> 9) & (unsigned char)127;
wc1 = 128 - wc2;
offsetX1 = offsetX + 1;
pixel1 = *(input + (offsetPixelY + offsetX));
pixel2 = *(input + (offsetPixelY1 + offsetX));
pixel3 = *(input + (offsetPixelY + offsetX1));
pixel4 = *(input + (offsetPixelY1 + offsetX1));
a = ((((pixel1 >> 24) & 0xff) * hc1 + ((pixel2 >> 24) & 0xff) * hc2) * wc1 +
(((pixel3 >> 24) & 0xff) * hc1 + ((pixel4 >> 24) & 0xff) * hc2) * wc2) >> 14;
r = ((((pixel1 >> 16) & 0xff) * hc1 + ((pixel2 >> 16) & 0xff) * hc2) * wc1 +
(((pixel3 >> 16) & 0xff) * hc1 + ((pixel4 >> 16) & 0xff) * hc2) * wc2) >> 14;
g = ((((pixel1 >> 8) & 0xff) * hc1 + ((pixel2 >> 8) & 0xff) * hc2) * wc1 +
(((pixel3 >> 8) & 0xff) * hc1 + ((pixel4 >> 8) & 0xff) * hc2) * wc2) >> 14;
b = ((((pixel1) & 0xff) * hc1 + ((pixel2) & 0xff) * hc2) * wc1 +
(((pixel3) & 0xff) * hc1 + ((pixel4) & 0xff) * hc2) * wc2) >> 14;
*output++ = (a << 24) | (r << 16) | (g << 8) | b;
widthCoefficient += wStepFixed16b;
}
heightCoefficient += hStepFixed16b;
}
}