diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2013-03-03 14:32:49 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2013-03-03 14:32:49 +0000 |
| commit | 2b80c70fe2db359933a311ae2f1e331c7e54af5f (patch) | |
| tree | 6a6e2b39e29bee3d7b1849e52390e9994f34f8d4 /src | |
| parent | ODF output: write correct Inkscape version number to metadata (diff) | |
| download | inkscape-2b80c70fe2db359933a311ae2f1e331c7e54af5f.tar.gz inkscape-2b80c70fe2db359933a311ae2f1e331c7e54af5f.zip | |
Use ink_cairo_surface_filter when converting surfaces between linearRGB and sRGB.
Huge speed advantage when using multiple threads.
(bzr r12170)
Diffstat (limited to 'src')
| -rw-r--r-- | src/display/cairo-utils.cpp | 91 |
1 files changed, 64 insertions, 27 deletions
diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 8eeee0277..a55b05fe3 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -26,6 +26,7 @@ #include "color.h" #include "style.h" #include "helper/geom-curves.h" +#include "display/cairo-templates.h" namespace { @@ -633,6 +634,22 @@ static guint32 linear_to_srgb( const guint32 c, const guint32 a ) { return premul_alpha( c2, a ); } +struct SurfaceSrgbToLinear { + + guint32 operator()(guint32 in) { + EXTRACT_ARGB32(in, a,r,g,b) ; // Unneeded semi-colon for indenting + if( a != 0 ) { + r = srgb_to_linear( r, a ); + g = srgb_to_linear( g, a ); + b = srgb_to_linear( b, a ); + } + ASSEMBLE_ARGB32(out, a,r,g,b); + return out; + } +private: + /* None */ +}; + int ink_cairo_surface_srgb_to_linear(cairo_surface_t *surface) { cairo_surface_flush(surface); @@ -641,23 +658,41 @@ int ink_cairo_surface_srgb_to_linear(cairo_surface_t *surface) int stride = cairo_image_surface_get_stride(surface); unsigned char *data = cairo_image_surface_get_data(surface); + ink_cairo_surface_filter( surface, surface, SurfaceSrgbToLinear() ); + /* TODO convert this to OpenMP somehow */ - for (int y = 0; y < height; ++y, data += stride) { - for (int x = 0; x < width; ++x) { - guint32 px = *reinterpret_cast<guint32*>(data + 4*x); - EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting - if( a != 0 ) { - r = srgb_to_linear( r, a ); - g = srgb_to_linear( g, a ); - b = srgb_to_linear( b, a ); - } - ASSEMBLE_ARGB32(px2, a,r,g,b); - *reinterpret_cast<guint32*>(data + 4*x) = px2; - } - } + // for (int y = 0; y < height; ++y, data += stride) { + // for (int x = 0; x < width; ++x) { + // guint32 px = *reinterpret_cast<guint32*>(data + 4*x); + // EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting + // if( a != 0 ) { + // r = srgb_to_linear( r, a ); + // g = srgb_to_linear( g, a ); + // b = srgb_to_linear( b, a ); + // } + // ASSEMBLE_ARGB32(px2, a,r,g,b); + // *reinterpret_cast<guint32*>(data + 4*x) = px2; + // } + // } return width * height; } +struct SurfaceLinearToSrgb { + + guint32 operator()(guint32 in) { + EXTRACT_ARGB32(in, a,r,g,b) ; // Unneeded semi-colon for indenting + if( a != 0 ) { + r = linear_to_srgb( r, a ); + g = linear_to_srgb( g, a ); + b = linear_to_srgb( b, a ); + } + ASSEMBLE_ARGB32(out, a,r,g,b); + return out; + } +private: + /* None */ +}; + int ink_cairo_surface_linear_to_srgb(cairo_surface_t *surface) { cairo_surface_flush(surface); @@ -666,20 +701,22 @@ int ink_cairo_surface_linear_to_srgb(cairo_surface_t *surface) int stride = cairo_image_surface_get_stride(surface); unsigned char *data = cairo_image_surface_get_data(surface); - /* TODO convert this to OpenMP somehow */ - for (int y = 0; y < height; ++y, data += stride) { - for (int x = 0; x < width; ++x) { - guint32 px = *reinterpret_cast<guint32*>(data + 4*x); - EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting - if( a != 0 ) { - r = linear_to_srgb( r, a ); - g = linear_to_srgb( g, a ); - b = linear_to_srgb( b, a ); - } - ASSEMBLE_ARGB32(px2, a,r,g,b); - *reinterpret_cast<guint32*>(data + 4*x) = px2; - } - } + ink_cairo_surface_filter( surface, surface, SurfaceLinearToSrgb() ); + + // /* TODO convert this to OpenMP somehow */ + // for (int y = 0; y < height; ++y, data += stride) { + // for (int x = 0; x < width; ++x) { + // guint32 px = *reinterpret_cast<guint32*>(data + 4*x); + // EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting + // if( a != 0 ) { + // r = linear_to_srgb( r, a ); + // g = linear_to_srgb( g, a ); + // b = linear_to_srgb( b, a ); + // } + // ASSEMBLE_ARGB32(px2, a,r,g,b); + // *reinterpret_cast<guint32*>(data + 4*x) = px2; + // } + // } return width * height; } |
