nr-filter-blend.cpp revision 1eb1d82bb52720d1379a4ed8f78c0e700251956d
/*
* SVG feBlend renderer
*
* "This filter composites two objects together using commonly used
* imaging software blending modes. It performs a pixel-wise combination
* of two input images."
* http://www.w3.org/TR/SVG11/filters.html#feBlend
*
* Authors:
* Niko Kiirala <niko@kiirala.com>
*
* Copyright (C) 2007 authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include "display/nr-filter-blend.h"
#include "display/nr-filter-primitive.h"
#include "display/nr-filter-slot.h"
#include "display/nr-filter-types.h"
#include "libnr/nr-pixblock.h"
#include "libnr/nr-matrix.h"
#include "libnr/nr-pixops.h"
unsigned char zero_rgba[4] = {0, 0, 0, 0};
// in1 begins before in2 on y-axis
}
}
// in2 begins before in1 on y-axis
}
}
}
// in1 begins before in2 on x-axis
}
// in2 begins before in1 on x-axis
}
}
}
// in1 ends after in2 on x-axis
}
// in2 ends after in1 on x-axis
}
}
}
// in1 ends after in2 on y-axis
}
}
// in2 ends after in1 on y-axis
}
}
}
}
/*
* From http://www.w3.org/TR/SVG11/filters.html#feBlend
*
* For all feBlend modes, the result opacity is computed as follows:
* qr = 1 - (1-qa)*(1-qb)
*
* For the compositing formulas below, the following definitions apply:
* cr = Result color (RGB) - premultiplied
* qa = Opacity value at a given pixel for image A
* qb = Opacity value at a given pixel for image B
* ca = Color (RGB) at a given pixel for image A - premultiplied
* cb = Color (RGB) at a given pixel for image B - premultiplied
*/
/*
* These blending equations given in SVG standard are for color values
* in the range 0..1. As these values are stored as unsigned char values,
* they need some reworking. An unsigned char value can be thought as
* 0.8 fixed point representation of color value. This is how I've
* ended up with these equations here.
*/
// Set alpha / opacity. This line is same for all the blending modes,
// so let's save some copy-pasting.
// cr = (1 - qa) * cb + ca
inline void blend_normal(unsigned char *r, unsigned char const *a, unsigned char const *b) {
}
// cr = (1-qa)*cb + (1-qb)*ca + ca*cb
inline void blend_multiply(unsigned char *r, unsigned char const *a, unsigned char const *b) {
+ a[0] * b[0]);
+ a[1] * b[1]);
+ a[2] * b[2]);
}
// cr = cb + ca - ca * cb
inline void blend_screen(unsigned char *r, unsigned char const *a, unsigned char const *b) {
}
// cr = Min ((1 - qa) * cb + ca, (1 - qb) * ca + cb)
inline void blend_darken(unsigned char *r, unsigned char const *a, unsigned char const *b) {
}
// cr = Max ((1 - qa) * cb + ca, (1 - qb) * ca + cb)
inline void blend_lighten(unsigned char *r, unsigned char const *a, unsigned char const *b) {
}
namespace NR {
{}
return new FilterBlend();
}
{}
// Bail out if either one of source images is missing
return 1;
}
out = new NRPixBlock;
true);
// Blending modes are defined for premultiplied RGBA values,
// thus convert them to that format before blending
in1 = new NRPixBlock;
false);
}
in2 = new NRPixBlock;
false);
}
switch (_blend_mode) {
case BLEND_MULTIPLY:
break;
case BLEND_SCREEN:
break;
case BLEND_DARKEN:
break;
case BLEND_LIGHTEN:
break;
case BLEND_NORMAL:
default:
break;
}
if (in1 != original_in1) {
delete in1;
}
if (in2 != original_in2) {
delete in2;
}
return 0;
}
}
}
mode == BLEND_LIGHTEN)
{
_blend_mode = mode;
}
}
} /* namespace NR */
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :