summaryrefslogtreecommitdiffstats
path: root/src/display/cairo-utils.cpp
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2013-03-03 14:32:49 +0000
committertavmjong-free <tavmjong@free.fr>2013-03-03 14:32:49 +0000
commit2b80c70fe2db359933a311ae2f1e331c7e54af5f (patch)
tree6a6e2b39e29bee3d7b1849e52390e9994f34f8d4 /src/display/cairo-utils.cpp
parentODF output: write correct Inkscape version number to metadata (diff)
downloadinkscape-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/display/cairo-utils.cpp')
-rw-r--r--src/display/cairo-utils.cpp91
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;
}