rsvg_filter_primitive_turbulence_render (RsvgFilterPrimitive * self, RsvgFilterContext * ctx)
{
    RsvgFilterPrimitiveTurbulence *upself;
    gint x, y, tileWidth, tileHeight, rowstride, width, height;
    RsvgIRect boundarys;
    guchar *output_pixels;
    GdkPixbuf *output;
    gdouble affine[6];
    GdkPixbuf *in;

    in = rsvg_filter_get_in (self->in, ctx);
    height = gdk_pixbuf_get_height (in);
    width = gdk_pixbuf_get_width (in);
    rowstride = gdk_pixbuf_get_rowstride (in);

    upself = (RsvgFilterPrimitiveTurbulence *) self;
    boundarys = rsvg_filter_primitive_get_bounds (self, ctx);

    tileWidth = (boundarys.x1 - boundarys.x0);
    tileHeight = (boundarys.y1 - boundarys.y0);

    output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
    output_pixels = gdk_pixbuf_get_pixels (output);

    _rsvg_affine_invert (affine, ctx->paffine);

    for (y = 0; y < tileHeight; y++) {
        for (x = 0; x < tileWidth; x++) {
            gint i;
            double point[2];
            guchar *pixel;
            point[0] = affine[0] * (x + boundarys.x0) + affine[2] * (y + boundarys.y0) + affine[4];
            point[1] = affine[1] * (x + boundarys.x0) + affine[3] * (y + boundarys.y0) + affine[5];

            pixel = output_pixels + 4 * (x + boundarys.x0) + (y + boundarys.y0) * rowstride;

            for (i = 0; i < 4; i++) {
                double cr;

                cr = feTurbulence_turbulence (upself, i, point, (double) x, (double) y,
                                              (double) tileWidth, (double) tileHeight);

                if (upself->bFractalSum)
                    cr = ((cr * 255.) + 255.) / 2.;
                else
                    cr = (cr * 255.);

                cr = CLAMP (cr, 0., 255.);

                pixel[ctx->channelmap[i]] = (guchar) cr;
            }
            for (i = 0; i < 3; i++)
                pixel[ctx->channelmap[i]] =
                    pixel[ctx->channelmap[i]] * pixel[ctx->channelmap[3]] / 255;

        }
    }

    rsvg_filter_store_result (self->result, output, ctx);

    g_object_unref (in);
    g_object_unref (output);
}
rsvg_filter_primitive_turbulence_render (RsvgFilterPrimitive * self, RsvgFilterContext * ctx)
{
    RsvgFilterPrimitiveTurbulence *upself;
    gint x, y, tileWidth, tileHeight, rowstride, width, height;
    RsvgIRect boundarys;
    guchar *output_pixels;
    GdkPixbuf *output;
    gdouble affine[6];
    GdkPixbuf *in;

    in = rsvg_filter_get_in (self->in, ctx);
    height = gdk_pixbuf_get_height (in);
    width = gdk_pixbuf_get_width (in);
    rowstride = gdk_pixbuf_get_rowstride (in);

    upself = (RsvgFilterPrimitiveTurbulence *) self;
    boundarys = rsvg_filter_primitive_get_bounds (self, ctx);

    tileWidth = (boundarys.x1 - boundarys.x0);
    tileHeight = (boundarys.y1 - boundarys.y0);

    output = _rsvg_pixbuf_new_cleared (GDK_COLORSPACE_RGB, 1, 8, width, height);
    output_pixels = gdk_pixbuf_get_pixels (output);

    _rsvg_affine_invert (affine, ctx->paffine);

    for (y = 0; y < tileHeight; y++) {
        for (x = 0; x < tileWidth; x++) {
            gint i;
            double point[2];
            guchar *pixel;
            point[0] = affine[0] * (x + boundarys.x0) + affine[2] * (y + boundarys.y0) + affine[4];
            point[1] = affine[1] * (x + boundarys.x0) + affine[3] * (y + boundarys.y0) + affine[5];

            pixel = output_pixels + 4 * (x + boundarys.x0) + (y + boundarys.y0) * rowstride;

            for (i = 0; i < 4; i++) {
                double cr;

                cr = feTurbulence_turbulence (upself, i, point, (double) x, (double) y,
                                              (double) tileWidth, (double) tileHeight);

                if (upself->bFractalSum)
                    cr = ((cr * 255.) + 255.) / 2.;
                else
                    cr = (cr * 255.);

                cr = CLAMP (cr, 0., 255.);

                pixel[ctx->channelmap[i]] = (guchar) cr;
            }
            for (i = 0; i < 3; i++)
                pixel[ctx->channelmap[i]] =
                    pixel[ctx->channelmap[i]] * pixel[ctx->channelmap[3]] / 255;

        }
    }

    rsvg_filter_store_result (self->result, output, ctx);

    g_object_unref (in);
    g_object_unref (output);
}