diff options
-rw-r--r-- | pixman/pixman-color-space.c | 117 | ||||
-rw-r--r-- | pixman/pixman-general.c | 8 | ||||
-rw-r--r-- | pixman/pixman.h | 8 |
3 files changed, 110 insertions, 23 deletions
diff --git a/pixman/pixman-color-space.c b/pixman/pixman-color-space.c index 7cefd14..9bbf9b9 100644 --- a/pixman/pixman-color-space.c +++ b/pixman/pixman-color-space.c @@ -25,6 +25,24 @@ const pixman_color_space_t _pixman_color_space_device_cmyk = { 4 }; +PIXMAN_EXPORT pixman_color_space_t * +pixman_color_space_create_gray () +{ + return (pixman_color_space_t *) &_pixman_color_space_device_gray; +} + +PIXMAN_EXPORT pixman_color_space_t * +pixman_color_space_create_rgb () +{ + return (pixman_color_space_t *) &_pixman_color_space_device_rgb; +} + +PIXMAN_EXPORT pixman_color_space_t * +pixman_color_space_create_cmyk () +{ + return (pixman_color_space_t *) &_pixman_color_space_device_cmyk; +} + static void _pixman_color_space_init (pixman_color_space_t *color_space, void *profile_data, @@ -33,6 +51,7 @@ _pixman_color_space_init (pixman_color_space_t *color_space, color_space->ref_count = 0; color_space->profile_data = profile_data; color_space->profile_len = profile_len; + color_space->n_components = 3; /* TODO */ } PIXMAN_EXPORT pixman_color_space_t * @@ -142,9 +161,10 @@ _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->src = source; + transform->dest = dest; + + if (source->common.color_space == dest->common.color_space) { transform->transform = NULL; transform->in = NULL; @@ -152,13 +172,13 @@ _pixman_color_space_create_transform (pixman_image_t *source, return; } - if (source->common.color_space->profile_data) + if (source->common.color_space && 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) + if (dest->common.color_space && dest->common.color_space->profile_data) transform->out = cmsOpenProfileFromMem (dest->common.color_space->profile_data, dest->common.color_space->profile_len); else @@ -189,12 +209,14 @@ _pixman_color_space_apply_transform (pixman_component_t *source, pixman_color_transform_t *transform) { double *tmps, *tmpd; - int i; + int i, n_comp; + + n_comp = 1 + pixman_color_space_get_num_components (transform->src->common.color_space); if (!transform->transform) { if (source != dest) - memcpy (dest, source, width * 4 * sizeof (pixman_component_t)); + memcpy (dest, source, width * n_comp * sizeof (pixman_component_t)); return; } @@ -202,26 +224,83 @@ _pixman_color_space_apply_transform (pixman_component_t *source, tmpd = malloc (width * 3 * sizeof (double)); /* TODO: n-components */ - for (i = 0; i < width; i++) + if (transform->src->common.color_space == NULL) + { + assert (n_comp == 1); + memset (tmps, 0, width * 3 * sizeof (double)); + } + else if (transform->src->common.color_space == &_pixman_color_space_device_gray) { - if (source[4*i]) + assert (n_comp == 2); + + for (i = 0; i < width; i++) + { + if (source[2*i]) + { + double inv = 1./source[2*i]; + tmps[3*i+0] = tmps[3*i+1] = tmps[3*i+2] = inv * source[2*i+1]; + } else { + tmps[3*i+0] = tmps[3*i+1] = tmps[3*i+2] = 0; + } + } + } + else if (transform->src->common.color_space == &_pixman_color_space_device_cmyk) + { + assert (n_comp == 5); + + for (i = 0; i < width; i++) + { + if (source[5*i]) + { + double inv = 1./source[5*i]; + double r,g,b, c, m, y, k; + + c = source[5*i+1]; + m = source[5*i+2]; + y = source[5*i+3]; + k = source[5*i+4]; + + r = MAX (0, 1 - c - k); + g = MAX (0, 1 - m - k); + b = MAX (0, 1 - y - k); + tmps[3*i+0] = inv * r; + tmps[3*i+1] = inv * g; + tmps[3*i+2] = inv * b; + } else { + tmps[3*i+0] = tmps[3*i+1] = tmps[3*i+2] = 0; + } + } + } + else + { + assert (n_comp == 4); + + for (i = 0; i < width; 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; + 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); + + for (i = 0; i < width; i++) + tmps[i] = source[n_comp * i]; + /* 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]; + dest[4*i+0] = tmps[i]; + dest[4*i+1] = tmps[i] * tmpd[3*i+0]; + dest[4*i+2] = tmps[i] * tmpd[3*i+1]; + dest[4*i+3] = tmps[i] * tmpd[3*i+2]; } free (tmpd); diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index a61c738..01af27e 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -78,17 +78,17 @@ general_composite_rect (pixman_implementation_t *imp, (dest->common.flags & FAST_PATH_NARROW_FORMAT); Bpp = narrow ? 4 : 8; - if (width * 4 > SCANLINE_BUFFER_LENGTH) + if (width * 5 > SCANLINE_BUFFER_LENGTH) { - scanline_buffer = pixman_malloc_abc (width, 3, 4 * sizeof(pixman_component_t)); + scanline_buffer = pixman_malloc_abc (width, 5*3, sizeof(pixman_component_t)); if (!scanline_buffer) return; } src_buffer = scanline_buffer; - mask_buffer = src_buffer + width * Bpp; - dest_buffer = mask_buffer + width * Bpp; + mask_buffer = src_buffer + width * 5; + dest_buffer = mask_buffer + width * 5; src_class = _pixman_image_classify (src, src_x, src_y, diff --git a/pixman/pixman.h b/pixman/pixman.h index 4654d0e..b4f3f40 100644 --- a/pixman/pixman.h +++ b/pixman/pixman.h @@ -989,6 +989,14 @@ void pixman_rasterize_trapezoid (pixman_image_t *image, int x_off, int y_off); +pixman_color_space_t * +pixman_color_space_create_gray (void); + +pixman_color_space_t * +pixman_color_space_create_rgb (void); + +pixman_color_space_t * +pixman_color_space_create_cmyk (void); pixman_color_space_t * pixman_color_space_create_icc (const void *profile, unsigned long profile_len); |