31 EXTRACT_ARGB32(in, a, r, g, b);
37 ASSEMBLE_ARGB32(out, a, r, g, b);
46 EXTRACT_ARGB32(in, a, r, g, b);
50 ASSEMBLE_ARGB32(out, a, r, g, b);
55struct ComponentTransfer
57 ComponentTransfer(
guint32 color)
59 , _mask(0xff << _shift) {}
66struct ComponentTransferTable :
public ComponentTransfer
68 ComponentTransferTable(
guint32 color, std::vector<double>
const &values)
69 : ComponentTransfer(color)
72 for (
unsigned i = 0; i < values.size(); ++i) {
73 _v[i] = std::round(std::clamp(values[i], 0.0, 1.0) * 255);
83 guint32 component = (in & _mask) >> _shift;
84 if (_v.size() == 1 || component == 255) {
85 component = _v.back();
87 guint32 k = (_v.size() - 1) * component;
90 component = _v[k] * 255 + (_v[k + 1] - _v[k]) * dx;
91 component = (component + 127) / 255;
93 return (in & ~_mask) | (component << _shift);
97 std::vector<guint32> _v;
100struct ComponentTransferDiscrete :
public ComponentTransfer
102 ComponentTransferDiscrete(
guint32 color, std::vector<double>
const &values)
103 : ComponentTransfer(color)
106 for (
unsigned i = 0; i< values.size(); ++i) {
107 _v[i] = std::round(std::clamp(values[i], 0.0, 1.0) * 255);
113 guint32 component = (in & _mask) >> _shift;
114 guint32 k = _v.size() * component / 255;
115 if (k == _v.size()) --k;
117 return (in & ~_mask) | ((
guint32)component << _shift);
121 std::vector<guint32> _v;
124struct ComponentTransferLinear :
public ComponentTransfer
126 ComponentTransferLinear(
guint32 color,
double intercept,
double slope)
127 : ComponentTransfer(color)
128 , _intercept(round(intercept * 255 * 255))
129 , _slope(round(slope * 255)) {}
133 gint32 component = (in & _mask) >> _shift;
136 component =
pxclamp(_slope * component + _intercept, 0, 255 * 255);
137 component = (component + 127) / 255;
138 return (in & ~_mask) | (component << _shift);
146struct ComponentTransferGamma :
public ComponentTransfer
148 ComponentTransferGamma(
guint32 color,
double amplitude,
double exponent,
double offset)
149 : ComponentTransfer(color)
150 , _amplitude(amplitude)
151 , _exponent(exponent)
156 double component = (in & _mask) >> _shift;
158 component = _amplitude * std::pow(component, _exponent) + _offset;
160 return (in & ~_mask) | (cpx << _shift);
189 for (
unsigned i = 0; i < 4; ++i) {
191 if (i == 3) color = 3;
220 cairo_surface_destroy(out);
Cairo software blending templates.
G_GNUC_CONST gint32 pxclamp(gint32 v, gint32 low, gint32 high)
void ink_cairo_surface_filter(cairo_surface_t *in, cairo_surface_t *out, Filter &&filter)
cairo_surface_t * ink_cairo_surface_create_same_size(cairo_surface_t *s, cairo_content_t c)
void ink_cairo_surface_blit(cairo_surface_t *src, cairo_surface_t *dest)
void set_cairo_surface_ci(cairo_surface_t *surface, SPColorInterpolation ci)
Set the color_interpolation_value for a Cairo surface.
Cairo integration helpers.
G_GNUC_CONST guint32 premul_alpha(const guint32 color, const guint32 alpha)
G_GNUC_CONST guint32 unpremul_alpha(const guint32 color, const guint32 alpha)
3x3 matrix representing an affine transformation.
~FilterComponentTransfer() override
FilterComponentTransferType type[4]
void render_cairo(FilterSlot &slot) const override
double complexity(Geom::Affine const &ctm) const override
bool can_handle_affine(Geom::Affine const &) const override
Indicate whether the filter primitive can handle the given affine.
std::vector< double > tableValues[4]
FilterComponentTransfer()
SPColorInterpolation color_interpolation
cairo_surface_t * getcairo(int slot)
Returns the pixblock in specified slot.
void set(int slot, cairo_surface_t *s)
Sets or re-sets the pixblock associated with given slot.
struct _cairo_surface cairo_surface_t
@ COMPONENTTRANSFER_TYPE_GAMMA
@ COMPONENTTRANSFER_TYPE_TABLE
@ COMPONENTTRANSFER_TYPE_LINEAR
@ COMPONENTTRANSFER_TYPE_ERROR
@ COMPONENTTRANSFER_TYPE_DISCRETE
@ COMPONENTTRANSFER_TYPE_IDENTITY
Helper class to stream background task notifications as a series of messages.