My program uses graphics convolution, an algorithm that processes pixels to make them round, soft and blurred. This particular algorithm is well-known, but its slowing down the operation of the whole program.

Can you suggest any improvements of this algorithm? I tried following from here, especially "ultimate solution" all the way to the bottom of that page, hoping to reduce the number of for loops one within another, but it did not work.

import perceptron.DoubleBuffer.ImageRenderContext;
import util.ColorUtility;
import java.awt.image.DataBuffer;

public final class Convolution {

    DoubleBuffer buffer;
    int[] d;
    int s, h, e;
    int[] temp;


    /**
     * Constructs new Convolution using the convolution degree and DoubleBuffer as input parameters.
     *
     * @param std
     * @param b
     */
    public Convolution(int std, DoubleBuffer b) {
        s = 2 * std;
        h = s / 2;
        e = 256 / h;
        d = new int[s];
        buffer = b;
        for (int i = 0; i &lt; s; i++) {
            d[i] = (int) (256 * gaussian(i - s / 2, std));
        }
        temp = new int[b.buffer.W * b.buffer.H];
    }

    /**
     * Optimized power function. Poor quality?
     */
    public static double power(final double a, final double b) {
        final long tmp = (Double.doubleToLongBits(a) &gt;&gt; 32);
        final long tmp2 = (long) (b * (tmp - 1072632447) + 1072632447);
        return Double.longBitsToDouble(tmp2 &lt;&lt; 32);
    }

    /**
     * Optimized exponent function with little benefit.
     */
    public static double exponent(double val) {
        final long tmp = (long) (1512775 * val + (1072693248 - 60801));
        return Double.longBitsToDouble(tmp &lt;&lt; 32);
    }

    /**
     * Calculate the Gaussian for blurring.
     *
     * @param x
     * @param sigma
     * @return
     */
    static double gaussian(float x, float sigma) {
        return exponent(-.5 * (x * x) / (sigma * sigma)) / (sigma * 2.506628);
        //return exponent(-.5 * pow(x / sigma, 2)) / (sigma * sqrt(2 * PI));
        //return exp(-.5 * pow(x / sigma, 2)) / (sigma * sqrt(2 * PI)); // actual equation
    }

    /**
     * Process the loaded buffer (image).
     *
     * @param amount
     */
    public void operate(int amount) {

        ImageRenderContext source = buffer.output;
        DataBuffer sourcebuffer = buffer.output.data_buffer;
        DataBuffer destbuffer = buffer.buffer.data_buffer;


        if (buffer.convolution != 0) {

            int W = buffer.output.W;
            int H = buffer.output.H;
            int Hp = H - h;
            // Do X blur
            int i = 0;
            for (int y = 0; y &lt; H; y++) {
                for (int x = 0; x &lt; W; x++) {
                    int Y = 0, G = 0;
                    for (int k = 0; k &lt; s; k++) {
                        int c = source.get_color_for_convolution.getColor(x + k - h &lt;&lt; 8, y &lt;&lt; 8);
                        int w = d[k];
                        Y += w * (c &amp; 0xff00ff);
                        G += w * (c &amp; 0x00ff00);
                    }
                    temp[i++] = (0xff00ff00 &amp; Y | 0x00ff0000 &amp; G) &gt;&gt; 8;
                }
            }
            // Do Y blur
            i = 0;
            int notamount = 256 - amount;
            for (int y = 0; y &lt; h; y++) {
                for (int x = 0; x &lt; W; x++) {
                    int Y = 0, G = 0;
                    for (int k = 0; k &lt; s; k++) {
                        int y2 = (y - h + k + H) % H;
                        int c = temp[x + W * (y2)];
                        int w = d[k];
                        Y += w * (c &amp; 0xff00ff);
                        G += w * (c &amp; 0x00ff00);
                    }
                    int c1 = (0xff00ff00 &amp; Y | 0x00ff0000 &amp; G) &gt;&gt; 8;
                    int c2 = sourcebuffer.getElem(i) &lt;&lt; 1;
                    int r = ((c2 &gt;&gt; 16) &amp; 0x1fe) - ((c1 &gt;&gt; 16) &amp; 0xff);
                    int g = ((c2 &gt;&gt; 8) &amp; 0x1fe) - ((c1 &gt;&gt; 8) &amp; 0xff);
                    int b = ((c2) &amp; 0x1fe) - ((c1) &amp; 0xff);
                    r = r &lt; 0 ? 0 : r &gt; 0xff ? 0xff : r;
                    g = g &lt; 0 ? 0 : g &gt; 0xff ? 0xff : g;
                    b = b &lt; 0 ? 0 : b &gt; 0xff ? 0xff : b;
                    c2 = (r &lt;&lt; 16) | (g &lt;&lt; 8) | (b);
                    c2 = ColorUtility.average(c1, amount, c2, notamount);
                    destbuffer.setElem(i++, c2);
                }
            }
            for (int y = h; y &lt; Hp; y++) {
                for (int x = 0; x &lt; W; x++) {
                    int Y = 0, G = 0;
                    for (int k = 0; k &lt; s; k++) {
                        int c = temp[x + W * (y - h + k)];
                        int w = d[k];
                        Y += w * (c &amp; 0xff00ff);
                        G += w * (c &amp; 0x00ff00);
                    }
                    int c1 = (0xff00ff00 &amp; Y | 0x00ff0000 &amp; G) &gt;&gt; 8;
                    int c2 = sourcebuffer.getElem(i) &lt;&lt; 1;
                    int r = ((c2 &gt;&gt; 16) &amp; 0x1fe) - ((c1 &gt;&gt; 16) &amp; 0xff);
                    int g = ((c2 &gt;&gt; 8) &amp; 0x1fe) - ((c1 &gt;&gt; 8) &amp; 0xff);
                    int b = ((c2) &amp; 0x1fe) - ((c1) &amp; 0xff);
                    r = r &lt; 0 ? 0 : r &gt; 0xff ? 0xff : r;
                    g = g &lt; 0 ? 0 : g &gt; 0xff ? 0xff : g;
                    b = b &lt; 0 ? 0 : b &gt; 0xff ? 0xff : b;
                    c2 = (r &lt;&lt; 16) | (g &lt;&lt; 8) | (b);
                    c2 = ColorUtility.average(c1, amount, c2, notamount);
                    destbuffer.setElem(i++, c2);
                }
            }
            for (int y = Hp; y &lt; H; y++) {
                for (int x = 0; x &lt; W; x++) {
                    int Y = 0, G = 0;
                    for (int k = 0; k &lt; s; k++) {
                        int y2 = y - h + k;
                        if (y2 &lt; 0) {
                            y2 = 0;
                        else if (y2 &gt;= H) {
                            y2 = H - 1;
                        }
                        int c = temp[x + W * (y2)];
                        int w = d[k];
                        Y += w * (c &amp; 0xff00ff);
                        G += w * (c &amp; 0x00ff00);
                    }
                    int c1 = (0xff00ff00 &amp; Y | 0x00ff0000 &amp; G) &gt;&gt; 8;
                    int c2 = sourcebuffer.getElem(i) &lt;&lt; 1;
                    int r = ((c2 &gt;&gt; 16) &amp; 0x1fe) - ((c1 &gt;&gt; 16) &amp; 0xff);
                    int g = ((c2 &gt;&gt; 8) &amp; 0x1fe) - ((c1 &gt;&gt; 8) &amp; 0xff);
                    int b = ((c2) &amp; 0x1fe) - ((c1) &amp; 0xff);
                    r = r &lt; 0 ? 0 : r &gt; 0xff ? 0xff : r;
                    g = g &lt; 0 ? 0 : g &gt; 0xff ? 0xff : g;
                    b = b &lt; 0 ? 0 : b &gt; 0xff ? 0xff : b;
                    c2 = (r &lt;&lt; 16) | (g &lt;&lt; 8) | (b);
                    c2 = ColorUtility.average(c1, amount, c2, notamount);
                    destbuffer.setElem(i++, c2);
                }
            }

        } else {
            buffer.buffer.data_buffer = buffer.output.data_buffer;
        }
    }
}



Question: Can I use opencv 64 bit in visual studio 32 bit version in a 64 bit machine?
Answer: Yes, Visual Studio is always a 32 bit application (at least so far), but you can compile your code into application that can run in 64 bit mode, and even run and debug the application in 64 bit mode from Visual Studio.