b3e4991faeba9d490160bb88bf142fe3f28eeefdjucablues * feComponentTransfer filter primitive renderer
5ef6cb9428f2e6f5457e890a1c3b37f53730c07aFelipe C. da S. Sanches * Felipe Corrêa da Silva Sanches <juca@members.fsf.org>
5e5e1f6c598e7ee29846563874900ae3d0810149jaspervdg * Jasper van de Gronde <th.v.d.gronde@hccnet.nl>
b3e4991faeba9d490160bb88bf142fe3f28eeefdjucablues * Copyright (C) 2007 authors
b3e4991faeba9d490160bb88bf142fe3f28eeefdjucablues * Released under GNU GPL, read the file 'COPYING' for more information
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński#include "display/nr-filter-component-transfer.h"
b3e4991faeba9d490160bb88bf142fe3f28eeefdjucabluesFilterPrimitive * FilterComponentTransfer::create() {
b3e4991faeba9d490160bb88bf142fe3f28eeefdjucabluesFilterComponentTransfer::~FilterComponentTransfer()
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-freestruct ComponentTransferTable : public ComponentTransfer {
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński ComponentTransferTable(guint32 color, std::vector<double> const &values)
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński for (unsigned i = 0; i< values.size(); ++i) {
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński _v[i] = round(CLAMP(values[i], 0.0, 1.0) * 255);
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński guint32 component = (in & _mask) >> _shift;
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński component = _v[k]*255 + (_v[k+1] - _v[k])*dx;
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński return (in & ~_mask) | (component << _shift);
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-freestruct ComponentTransferDiscrete : public ComponentTransfer {
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński ComponentTransferDiscrete(guint32 color, std::vector<double> const &values)
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński for (unsigned i = 0; i< values.size(); ++i) {
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński _v[i] = round(CLAMP(values[i], 0.0, 1.0) * 255);
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński guint32 component = (in & _mask) >> _shift;
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-free return (in & ~_mask) | ((guint32)component << _shift);
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-freestruct ComponentTransferLinear : public ComponentTransfer {
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński ComponentTransferLinear(guint32 color, double intercept, double slope)
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński gint32 component = (in & _mask) >> _shift;
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński // TODO: this can probably be reduced to something simpler
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński component = pxclamp(_slope * component + _intercept, 0, 255*255);
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński return (in & ~_mask) | (component << _shift);
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-freestruct ComponentTransferGamma : public ComponentTransfer {
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński ComponentTransferGamma(guint32 color, double amplitude, double exponent, double offset)
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński double component = (in & _mask) >> _shift;
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński component = _amplitude * pow(component, _exponent) + _offset;
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-free guint32 cpx = pxclamp(component * 255.0, 0, 255);
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosińskivoid FilterComponentTransfer::render_cairo(FilterSlot &slot)
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński cairo_surface_t *input = slot.getcairo(_input);
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński cairo_surface_t *out = ink_cairo_surface_create_same_size(input, CAIRO_CONTENT_COLOR_ALPHA);
9f6f7e74a1ded383518676e0ecb2ccc5caa73d25tavmjong-free // We may need to transform input surface to correct color interpolation space. The input surface
9f6f7e74a1ded383518676e0ecb2ccc5caa73d25tavmjong-free // might be used as input to another primitive but it is likely that all the primitives in a given
9f6f7e74a1ded383518676e0ecb2ccc5caa73d25tavmjong-free // filter use the same color interpolation space so we don't copy the input before converting.
9f6f7e74a1ded383518676e0ecb2ccc5caa73d25tavmjong-free SPColorInterpolation ci_fp = SP_CSS_COLOR_INTERPOLATION_AUTO;
9f6f7e74a1ded383518676e0ecb2ccc5caa73d25tavmjong-free ci_fp = (SPColorInterpolation)_style->color_interpolation_filters.computed;
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński //cairo_surface_t *outtemp = ink_cairo_surface_create_identical(out);
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-free // We need to operate on unmultipled by alpha color values otherwise a change in alpha screws
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-free // up the premultiplied by alpha r, g, b values.
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-free ink_cairo_surface_filter(out, out, UnmultiplyAlpha());
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński // parameters: R = 0, G = 1, B = 2, A = 3
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński // Cairo: R = 2, G = 1, B = 0, A = 3
3c841a7cc2d4432ce4961ae20c6671ef4f7466c8tavmjong-free // If tableValues is empty, use identity.
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-free for (unsigned i = 0; i < 4; ++i) {
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-free ComponentTransferTable(color, tableValues[i]));
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-free ComponentTransferDiscrete(color, tableValues[i]));
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-free ComponentTransferLinear(color, intercept[i], slope[i]));
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-free ComponentTransferGamma(color, amplitude[i], exponent[i], offset[i]));
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński //ink_cairo_surface_blit(out, outtemp);
77793cdab9411c49c1659b7ba6802cc10d9a7e89tavmjong-free ink_cairo_surface_filter(out, out, MultiplyAlpha());
354e9a1515ed6d7957de6b135670bfb538468351Krzysztof Kosiński //cairo_surface_destroy(outtemp);
dff9bb0d25ad38c515c32e2c76a20e747c8eed10Krzysztof Kosińskibool FilterComponentTransfer::can_handle_affine(Geom::Affine const &)
1cf2607271f83cc4b20ccace552395d793055c90Krzysztof Kosińskidouble FilterComponentTransfer::complexity(Geom::Affine const &)
d9a7c806ee7f408ddb61ff4f233c9d96111ee2b5johanengelen} /* namespace Filters */
d9a7c806ee7f408ddb61ff4f233c9d96111ee2b5johanengelen} /* namespace Inkscape */
b3e4991faeba9d490160bb88bf142fe3f28eeefdjucablues Local Variables:
b3e4991faeba9d490160bb88bf142fe3f28eeefdjucablues c-file-style:"stroustrup"
b3e4991faeba9d490160bb88bf142fe3f28eeefdjucablues c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
b3e4991faeba9d490160bb88bf142fe3f28eeefdjucablues indent-tabs-mode:nil
b3e4991faeba9d490160bb88bf142fe3f28eeefdjucablues fill-column:99
a4030d5ca449e7e384bc699cd249ee704faaeab0Chris Morgan// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :