box_blur (GdkPixbuf * in, GdkPixbuf * output, guchar * intermediate, gint kw,
          gint kh, RsvgIRect boundarys, RsvgFilterPrimitiveOutput op)
{
    gint ch;
    gint x, y;
    gint rowstride, height, width;

    guchar *in_pixels;
    guchar *output_pixels;

    gint sum;


    height = gdk_pixbuf_get_height (in);
    width = gdk_pixbuf_get_width (in);

    in_pixels = gdk_pixbuf_get_pixels (in);
    output_pixels = gdk_pixbuf_get_pixels (output);

    rowstride = gdk_pixbuf_get_rowstride (in);

    if (kw > boundarys.x1 - boundarys.x0)
        kw = boundarys.x1 - boundarys.x0;

    if (kh > boundarys.y1 - boundarys.y0)
        kh = boundarys.y1 - boundarys.y0;


    if (kw >= 1) {
        for (ch = 0; ch < 4; ch++) {
            switch (ch) {
            case 0:
                if (!op.Rused)
                    continue;
            case 1:
                if (!op.Gused)
                    continue;
            case 2:
                if (!op.Bused)
                    continue;
            case 3:
                if (!op.Aused)
                    continue;
            }
            for (y = boundarys.y0; y < boundarys.y1; y++) {
                sum = 0;
                for (x = boundarys.x0; x < boundarys.x0 + kw; x++) {
                    sum += (intermediate[x % kw] = in_pixels[4 * x + y * rowstride + ch]);

                    if (x - kw / 2 >= 0 && x - kw / 2 < boundarys.x1)
                        output_pixels[4 * (x - kw / 2) + y * rowstride + ch] = sum / kw;
                }
                for (x = boundarys.x0 + kw; x < boundarys.x1; x++) {
                    sum -= intermediate[x % kw];
                    sum += (intermediate[x % kw] = in_pixels[4 * x + y * rowstride + ch]);
                    output_pixels[4 * (x - kw / 2) + y * rowstride + ch] = sum / kw;
                }
                for (x = boundarys.x1; x < boundarys.x1 + kw; x++) {
                    sum -= intermediate[x % kw];

                    if (x - kw / 2 >= 0 && x - kw / 2 < boundarys.x1)
                        output_pixels[4 * (x - kw / 2) + y * rowstride + ch] = sum / kw;
                }
            }
        }
        in_pixels = output_pixels;
    }

    if (kh >= 1) {
        for (ch = 0; ch < 4; ch++) {
            switch (ch) {
            case 0:
                if (!op.Rused)
                    continue;
            case 1:
                if (!op.Gused)
                    continue;
            case 2:
                if (!op.Bused)
                    continue;
            case 3:
                if (!op.Aused)
                    continue;
            }


            for (x = boundarys.x0; x < boundarys.x1; x++) {
                sum = 0;

                for (y = boundarys.y0; y < boundarys.y0 + kh; y++) {
                    sum += (intermediate[y % kh] = in_pixels[4 * x + y * rowstride + ch]);

                    if (y - kh / 2 >= 0 && y - kh / 2 < boundarys.y1)
                        output_pixels[4 * x + (y - kh / 2) * rowstride + ch] = sum / kh;
                }
                for (; y < boundarys.y1; y++) {
                    sum -= intermediate[y % kh];
                    sum += (intermediate[y % kh] = in_pixels[4 * x + y * rowstride + ch]);
                    output_pixels[4 * x + (y - kh / 2) * rowstride + ch] = sum / kh;
                }
                for (; y < boundarys.y1 + kh; y++) {
                    sum -= intermediate[y % kh];

                    if (y - kh / 2 >= 0 && y - kh / 2 < boundarys.y1)
                        output_pixels[4 * x + (y - kh / 2) * rowstride + ch] = sum / kh;
                }
            }
        }
    }
}
box_blur (GdkPixbuf * in, GdkPixbuf * output, guchar * intermediate, gint kw,
          gint kh, RsvgIRect boundarys, RsvgFilterPrimitiveOutput op)
{
    gint ch;
    gint x, y;
    gint rowstride, height, width;

    guchar *in_pixels;
    guchar *output_pixels;

    gint sum;


    height = gdk_pixbuf_get_height (in);
    width = gdk_pixbuf_get_width (in);

    in_pixels = gdk_pixbuf_get_pixels (in);
    output_pixels = gdk_pixbuf_get_pixels (output);

    rowstride = gdk_pixbuf_get_rowstride (in);

    if (kw > boundarys.x1 - boundarys.x0)
        kw = boundarys.x1 - boundarys.x0;

    if (kh > boundarys.y1 - boundarys.y0)
        kh = boundarys.y1 - boundarys.y0;


    if (kw >= 1) {
        for (ch = 0; ch < 4; ch++) {
            switch (ch) {
            case 0:
                if (!op.Rused)
                    continue;
            case 1:
                if (!op.Gused)
                    continue;
            case 2:
                if (!op.Bused)
                    continue;
            case 3:
                if (!op.Aused)
                    continue;
            }
            for (y = boundarys.y0; y < boundarys.y1; y++) {
                sum = 0;
                for (x = boundarys.x0; x < boundarys.x0 + kw; x++) {
                    sum += (intermediate[x % kw] = in_pixels[4 * x + y * rowstride + ch]);

                    if (x - kw / 2 >= 0 && x - kw / 2 < boundarys.x1)
                        output_pixels[4 * (x - kw / 2) + y * rowstride + ch] = sum / kw;
                }
                for (x = boundarys.x0 + kw; x < boundarys.x1; x++) {
                    sum -= intermediate[x % kw];
                    sum += (intermediate[x % kw] = in_pixels[4 * x + y * rowstride + ch]);
                    output_pixels[4 * (x - kw / 2) + y * rowstride + ch] = sum / kw;
                }
                for (x = boundarys.x1; x < boundarys.x1 + kw; x++) {
                    sum -= intermediate[x % kw];

                    if (x - kw / 2 >= 0 && x - kw / 2 < boundarys.x1)
                        output_pixels[4 * (x - kw / 2) + y * rowstride + ch] = sum / kw;
                }
            }
        }
        in_pixels = output_pixels;
    }

    if (kh >= 1) {
        for (ch = 0; ch < 4; ch++) {
            switch (ch) {
            case 0:
                if (!op.Rused)
                    continue;
            case 1:
                if (!op.Gused)
                    continue;
            case 2:
                if (!op.Bused)
                    continue;
            case 3:
                if (!op.Aused)
                    continue;
            }


            for (x = boundarys.x0; x < boundarys.x1; x++) {
                sum = 0;

                for (y = boundarys.y0; y < boundarys.y0 + kh; y++) {
                    sum += (intermediate[y % kh] = in_pixels[4 * x + y * rowstride + ch]);

                    if (y - kh / 2 >= 0 && y - kh / 2 < boundarys.y1)
                        output_pixels[4 * x + (y - kh / 2) * rowstride + ch] = sum / kh;
                }
                for (; y < boundarys.y1; y++) {
                    sum -= intermediate[y % kh];
                    sum += (intermediate[y % kh] = in_pixels[4 * x + y * rowstride + ch]);
                    output_pixels[4 * x + (y - kh / 2) * rowstride + ch] = sum / kh;
                }
                for (; y < boundarys.y1 + kh; y++) {
                    sum -= intermediate[y % kh];

                    if (y - kh / 2 >= 0 && y - kh / 2 < boundarys.y1)
                        output_pixels[4 * x + (y - kh / 2) * rowstride + ch] = sum / kh;
                }
            }
        }
    }
}