package com.android.gallery3d.ui;

import android.graphics.Bitmap;


public class BoxBlurFilter {
    private static final int RED_MASK = 0xff0000;
    private static final int RED_MASK_SHIFT = 16;
    private static final int GREEN_MASK = 0x00ff00;
    private static final int GREEN_MASK_SHIFT = 8;
    private static final int BLUE_MASK = 0x0000ff;
    private static final int RADIUS = 4;
    private static final int KERNEL_SIZE = RADIUS * 2 + 1;
    private static final int NUM_COLORS = 256;
    private static final int[] KERNEL_NORM = new int[KERNEL_SIZE * NUM_COLORS];

    public static final int MODE_REPEAT = 1;
    public static final int MODE_CLAMP = 2;

    static {
        int index = 0;
        // Build a lookup table from summed to normalized kernel values.
        // The formula: KERNAL_NORM[value] = value / KERNEL_SIZE
        for (int i = 0; i < NUM_COLORS; ++i) {
            for (int j = 0; j < KERNEL_SIZE; ++j) {
                KERNEL_NORM[index++] = i;
            }
        }
    }

    private BoxBlurFilter() {
    }

    private static int sample(int x, int width, int mode) {
        if (x >= 0 && x < width) return x;
        return mode == MODE_REPEAT
                ? x < 0 ? x + width : x - width
                : x < 0 ? 0 : width - 1;
    }

    public static void apply(
            Bitmap bitmap, int horizontalMode, int verticalMode) {

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        int data[] = new int[width * height];
        bitmap.getPixels(data, 0, width, 0, 0, width, height);
        int temp[] = new int[width * height];
        applyOneDimension(data, temp, width, height, horizontalMode);
        applyOneDimension(temp, data, height, width, verticalMode);
        bitmap.setPixels(data, 0, width, 0, 0, width, height);
    }

    private static void applyOneDimension(
            int[] in, int[] out, int width, int height, int mode) {
        for (int y = 0, read = 0; y < height; ++y, read += width) {
            // Evaluate the kernel for the first pixel in the row.
            int red = 0;
            int green = 0;
            int blue = 0;
            for (int i = -RADIUS; i <= RADIUS; ++i) {
                int argb = in[read + sample(i, width, mode)];
                red += (argb & RED_MASK) >> RED_MASK_SHIFT;
                green += (argb & GREEN_MASK) >> GREEN_MASK_SHIFT;
                blue += argb & BLUE_MASK;
            }
            for (int x = 0, write = y; x < width; ++x, write += height) {
                // Output the current pixel.
                out[write] = 0xFF000000
                        | (KERNEL_NORM[red] << RED_MASK_SHIFT)
                        | (KERNEL_NORM[green] << GREEN_MASK_SHIFT)
                        | KERNEL_NORM[blue];

                // Slide to the next pixel, adding the new rightmost pixel and
                // subtracting the former leftmost.
                int prev = in[read + sample(x - RADIUS, width, mode)];
                int next = in[read + sample(x + RADIUS + 1, width, mode)];
                red += ((next & RED_MASK) - (prev & RED_MASK)) >> RED_MASK_SHIFT;
                green += ((next & GREEN_MASK) - (prev & GREEN_MASK)) >> GREEN_MASK_SHIFT;
                blue += (next & BLUE_MASK) - (prev & BLUE_MASK);
            }
        }
    }
}
