rsvg_filter_primitive_image_render_ext (RsvgFilterPrimitive * self, RsvgFilterContext * ctx)
{
    RsvgIRect boundarys;
    RsvgFilterPrimitiveImage *upself;
    GdkPixbuf *img;
    int i;
    GdkPixbuf *intermediate;
    unsigned char *pixels;
    int channelmap[4];
    int length;

    upself = (RsvgFilterPrimitiveImage *) self;

    if (!upself->href)
        return NULL;

    boundarys = rsvg_filter_primitive_get_bounds (self, ctx);

    img = rsvg_pixbuf_new_from_href (upself->href->str,
                                     rsvg_handle_get_base_uri (upself->ctx), NULL);

    if (!img)
        return NULL;


    intermediate = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 1, 8, boundarys.x1 - boundarys.x0,
                                   boundarys.y1 - boundarys.y0);


    rsvg_art_affine_image (img, intermediate,
                           ctx->paffine,
                           (boundarys.x1 - boundarys.x0) / ctx->paffine[0],
                           (boundarys.y1 - boundarys.y0) / ctx->paffine[3]);

    if (!intermediate) {
        g_object_unref (img);
        return NULL;
    }


    g_object_unref (img);

    length = gdk_pixbuf_get_height (intermediate) * gdk_pixbuf_get_rowstride (intermediate);
    for (i = 0; i < 4; i++)
        channelmap[i] = ctx->channelmap[i];
    pixels = gdk_pixbuf_get_pixels (intermediate);
    for (i = 0; i < length; i += 4) {
        unsigned char alpha;
        unsigned char pixel[4];
        int ch;
        alpha = pixels[i + 3];

        pixel[channelmap[3]] = alpha;
        if (alpha)
            for (ch = 0; ch < 3; ch++)
                pixel[channelmap[ch]] = pixels[i + ch] * alpha / 255;
        else
            for (ch = 0; ch < 3; ch++)
                pixel[channelmap[ch]] = 0;
        for (ch = 0; ch < 4; ch++)
            pixels[i + ch] = pixel[ch];
    }

    return intermediate;

}
rsvg_filter_primitive_image_render_ext (RsvgFilterPrimitive * self, RsvgFilterContext * ctx)
{
    RsvgIRect boundarys;
    RsvgFilterPrimitiveImage *upself;
    GdkPixbuf *img;
    int i;
    GdkPixbuf *intermediate;
    unsigned char *pixels;
    int channelmap[4];
    int length;

    upself = (RsvgFilterPrimitiveImage *) self;

    if (!upself->href)
        return NULL;

    boundarys = rsvg_filter_primitive_get_bounds (self, ctx);

    img = rsvg_pixbuf_new_from_href (upself->href->str,
                                     rsvg_handle_get_base_uri (upself->ctx), NULL);

    if (!img)
        return NULL;


    intermediate = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 1, 8, boundarys.x1 - boundarys.x0,
                                   boundarys.y1 - boundarys.y0);


    rsvg_art_affine_image (img, intermediate,
                           ctx->paffine,
                           (boundarys.x1 - boundarys.x0) / ctx->paffine[0],
                           (boundarys.y1 - boundarys.y0) / ctx->paffine[3]);

    if (!intermediate) {
        g_object_unref (img);
        return NULL;
    }


    g_object_unref (img);

    length = gdk_pixbuf_get_height (intermediate) * gdk_pixbuf_get_rowstride (intermediate);
    for (i = 0; i < 4; i++)
        channelmap[i] = ctx->channelmap[i];
    pixels = gdk_pixbuf_get_pixels (intermediate);
    for (i = 0; i < length; i += 4) {
        unsigned char alpha;
        unsigned char pixel[4];
        int ch;
        alpha = pixels[i + 3];

        pixel[channelmap[3]] = alpha;
        if (alpha)
            for (ch = 0; ch < 3; ch++)
                pixel[channelmap[ch]] = pixels[i + ch] * alpha / 255;
        else
            for (ch = 0; ch < 3; ch++)
                pixel[channelmap[ch]] = 0;
        for (ch = 0; ch < 4; ch++)
            pixels[i + ch] = pixel[ch];
    }

    return intermediate;

}