diff options
author | Andrea Canciani <ranma42@gmail.com> | 2011-02-18 00:10:58 +0100 |
---|---|---|
committer | Andrea Canciani <ranma42@gmail.com> | 2011-02-18 00:13:55 +0100 |
commit | 6261821e813bc106300cd079117c8a7777863a28 (patch) | |
tree | c57bc3511bef24facf8112d90290202e22b1efb0 | |
parent | 3b14619abd6ef16d8ed24952c623bba251682ad2 (diff) |
cs: hook into lcms
-rw-r--r-- | pixman/Makefile.am | 4 | ||||
-rw-r--r-- | pixman/pixman-color-space.c | 91 | ||||
-rw-r--r-- | pixman/pixman-general.c | 11 | ||||
-rw-r--r-- | pixman/pixman-private.h | 22 |
4 files changed, 126 insertions, 2 deletions
diff --git a/pixman/Makefile.am b/pixman/Makefile.am index 969e293..3508ca2 100644 --- a/pixman/Makefile.am +++ b/pixman/Makefile.am @@ -1,6 +1,6 @@ lib_LTLIBRARIES = libpixman-1.la -libpixman_1_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -no-undefined @PTHREAD_LDFLAGS@ -libpixman_1_la_LIBADD = @PTHREAD_LIBS@ @DEP_LIBS@ -lm +libpixman_1_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -no-undefined @PTHREAD_LDFLAGS@ -L/tmp/box_168a7e16-5de6-11df-b5e5-7c6d628b9511/pkgs/lcms-1.19/lib +libpixman_1_la_LIBADD = @PTHREAD_LIBS@ @DEP_LIBS@ -lm -llcms libpixman_1_la_SOURCES = \ pixman.h \ pixman-accessor.h \ diff --git a/pixman/pixman-color-space.c b/pixman/pixman-color-space.c index 5cbd453..7cefd14 100644 --- a/pixman/pixman-color-space.c +++ b/pixman/pixman-color-space.c @@ -136,3 +136,94 @@ _pixman_color_space_from_pixman_format (pixman_format_code_t pixman_format) return NULL; } } + +void +_pixman_color_space_create_transform (pixman_image_t *source, + pixman_image_t *dest, + pixman_color_transform_t *transform) +{ + if (source->common.color_space == NULL || + dest->common.color_space == NULL || + source->common.color_space == dest->common.color_space) + { + transform->transform = NULL; + transform->in = NULL; + transform->out = NULL; + return; + } + + if (source->common.color_space->profile_data) + transform->in = cmsOpenProfileFromMem (source->common.color_space->profile_data, + source->common.color_space->profile_len); + else + transform->in = cmsCreate_sRGBProfile(); + + if (dest->common.color_space->profile_data) + transform->out = cmsOpenProfileFromMem (dest->common.color_space->profile_data, + dest->common.color_space->profile_len); + else + transform->out = cmsCreate_sRGBProfile(); + + transform->transform = cmsCreateTransform(transform->in, TYPE_RGB_DBL, + transform->out, TYPE_RGB_DBL, + //INTENT_RELATIVE_COLORIMETRIC, 0); + INTENT_PERCEPTUAL, 0); +} + + +void +_pixman_color_space_destroy_transform (pixman_color_transform_t *transform) +{ + if (!transform->transform) + return; + + cmsDeleteTransform (transform->transform); + cmsCloseProfile (transform->in); + cmsCloseProfile (transform->out); +} + +void +_pixman_color_space_apply_transform (pixman_component_t *source, + pixman_component_t *dest, + int width, + pixman_color_transform_t *transform) +{ + double *tmps, *tmpd; + int i; + + if (!transform->transform) + { + if (source != dest) + memcpy (dest, source, width * 4 * sizeof (pixman_component_t)); + return; + } + + tmps = malloc (width * 3 * sizeof (double)); + tmpd = malloc (width * 3 * sizeof (double)); + + /* TODO: n-components */ + for (i = 0; i < width; i++) + { + if (source[4*i]) + { + double inv = 1./source[4*i]; + tmps[3*i+0] = inv * source[4*i+1]; + tmps[3*i+1] = inv * source[4*i+2]; + tmps[3*i+2] = inv * source[4*i+3]; + } else { + tmps[3*i+0] = tmps[3*i+1] = tmps[3*i+2] = 0; + } + } + cmsDoTransform (transform->transform, tmps, tmpd, width); + /* TODO: n-components */ + for (i = 0; i < width; i++) + { + dest[4*i+0] = source[4 * i]; + dest[4*i+1] = source[4 * i] * tmpd[3*i+0]; + dest[4*i+2] = source[4 * i] * tmpd[3*i+1]; + dest[4*i+3] = source[4 * i] * tmpd[3*i+2]; + } + + free (tmpd); + free (tmps); +} diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index d29d040..a61c738 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -42,6 +42,7 @@ #define SCANLINE_BUFFER_LENGTH 8192 + static void general_composite_rect (pixman_implementation_t *imp, pixman_op_t op, @@ -60,6 +61,7 @@ general_composite_rect (pixman_implementation_t *imp, pixman_component_t stack_scanline_buffer[SCANLINE_BUFFER_LENGTH * 3]; pixman_component_t *scanline_buffer = stack_scanline_buffer; pixman_component_t *src_buffer, *mask_buffer, *dest_buffer; + pixman_color_transform_t transform; fetch_scanline_new_t fetch_src = NULL, fetch_mask = NULL, fetch_dest = NULL; pixman_combine_func_t compose; store_scanline_new_t store; @@ -133,6 +135,8 @@ general_composite_rect (pixman_implementation_t *imp, if (!fetch_mask) mask_buffer = NULL; + _pixman_color_space_create_transform (src, dest, &transform); + for (i = 0; i < height; ++i) { /* fill first half of scanline with source */ @@ -160,6 +164,11 @@ general_composite_rect (pixman_implementation_t *imp, fetch_src (src, src_x, src_y + i, width, (void *)src_buffer, (void *)mask_buffer); } + + _pixman_color_space_apply_transform ((void*)src_buffer, + (void*)src_buffer, + width, + &transform); } else if (fetch_mask) { @@ -199,6 +208,8 @@ general_composite_rect (pixman_implementation_t *imp, } } + _pixman_color_space_destroy_transform (&transform); + if (scanline_buffer != stack_scanline_buffer) free (scanline_buffer); } diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index c527c70..c296b6d 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -15,6 +15,7 @@ #include <stdio.h> #include <string.h> #include <float.h> +#include <lcms.h> #include "pixman-compiler.h" #include "simpleops/atomic/simpleops-atomic.h" @@ -31,6 +32,12 @@ struct pixman_color_space { /* mime data? */ }; +typedef struct pixman_color_transform { + pixman_image_t *src, *dest; + cmsHPROFILE in, out; + cmsHTRANSFORM transform; +} pixman_color_transform_t; + extern const pixman_color_space_t _pixman_color_space_device_gray; extern const pixman_color_space_t _pixman_color_space_device_rgb; extern const pixman_color_space_t _pixman_color_space_device_cmyk; @@ -451,6 +458,21 @@ void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp); void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp); void _pixman_setup_combiner_functions_float (pixman_implementation_t *imp); + +void +_pixman_color_space_create_transform (pixman_image_t *source, + pixman_image_t *dest, + pixman_color_transform_t *transform); + +void +_pixman_color_space_destroy_transform (pixman_color_transform_t *transform); + +void +_pixman_color_space_apply_transform (pixman_component_t *source, + pixman_component_t *dest, + int width, + pixman_color_transform_t *transform); + typedef struct { pixman_op_t op; |