diff options
-rw-r--r-- | pixman/Makefile.am | 2 | ||||
-rw-r--r-- | pixman/pixman-bits-image.c | 43 | ||||
-rw-r--r-- | pixman/pixman-color-space-private.h | 50 | ||||
-rw-r--r-- | pixman/pixman-color-space.c | 185 | ||||
-rw-r--r-- | pixman/pixman-format.c | 95 | ||||
-rw-r--r-- | pixman/pixman-general.c | 39 | ||||
-rw-r--r-- | pixman/pixman-image.c | 29 | ||||
-rw-r--r-- | pixman/pixman-private.h | 23 | ||||
-rw-r--r-- | pixman/pixman.c | 57 | ||||
-rw-r--r-- | pixman/pixman.h | 9 |
10 files changed, 441 insertions, 91 deletions
diff --git a/pixman/Makefile.am b/pixman/Makefile.am index a52a9e6..0b3e40d 100644 --- a/pixman/Makefile.am +++ b/pixman/Makefile.am @@ -15,6 +15,8 @@ libpixman_1_la_SOURCES = \ pixman-private.h \ pixman-image.c \ pixman-implementation.c \ + pixman-color-space.c \ + pixman-color-space-private.h \ pixman-combine32.c \ pixman-combine32.h \ pixman-combine64.c \ diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c index f5b7b49..a2c1a51 100644 --- a/pixman/pixman-bits-image.c +++ b/pixman/pixman-bits-image.c @@ -32,7 +32,9 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> + #include "pixman-private.h" +#include "pixman-color-space-private.h" #include "pixman-combine32.h" /* Store functions */ @@ -972,7 +974,10 @@ pixman_image_create_bits (pixman_format_code_t format, rowstrides[0] = rowstride_bytes; } - image = pixman_image_create_planar (format, width, height, num_planes, planes, rowstrides); + image = pixman_image_create_planar (format, + _pixman_format_get_default_color_space (format), + width, height, + num_planes, planes, rowstrides); if (!image) { @@ -986,22 +991,37 @@ pixman_image_create_bits (pixman_format_code_t format, return image; } +static pixman_color_space_t +_pixman_color_space_optimize (pixman_format_code_t format, + pixman_color_space_t color_space) +{ + if (color_space == PIXMAN_COLOR_SPACE_ARGB_UNMULTIPLIED && + !PIXMAN_FORMAT_A (format)) + return PIXMAN_COLOR_SPACE_ARGB; + + return color_space; +} + PIXMAN_EXPORT pixman_image_t * -pixman_image_create_planar (pixman_format_code_t format, - int width, - int height, - unsigned int num_planes, - uint32_t ** bits, - int * rowstrides_bytes) +pixman_image_create_planar (pixman_format_code_t format, + pixman_color_space_t color_space, + int width, + int height, + unsigned int num_planes, + uint32_t ** bits, + int * rowstrides_bytes) { pixman_image_t *image; unsigned int plane; - return_val_if_fail (bits == NULL || rowstrides_bytes == NULL, NULL); + return_val_if_fail (bits != NULL && rowstrides_bytes != NULL, NULL); return_val_if_fail (num_planes == pixman_format_num_planes (format), NULL); - for (plane = 0; plane < num_planes; plane++) { - return_val_if_fail (bits[plane] == NULL, NULL); - return_val_if_fail ((rowstrides_bytes[plane] % sizeof (uint32_t)) == 0, NULL); + if (width && height) + { + for (plane = 0; plane < num_planes; plane++) { + return_val_if_fail (bits[plane] != NULL, NULL); + return_val_if_fail ((rowstrides_bytes[plane] % sizeof (uint32_t)) == 0, NULL); + } } image = _pixman_image_allocate (); @@ -1010,6 +1030,7 @@ pixman_image_create_planar (pixman_format_code_t format, image->type = BITS; image->bits.format = format; + image->bits.color_space = _pixman_color_space_optimize (format, color_space); image->bits.width = width; image->bits.height = height; image->bits.read_func = NULL; diff --git a/pixman/pixman-color-space-private.h b/pixman/pixman-color-space-private.h new file mode 100644 index 0000000..383bebd --- /dev/null +++ b/pixman/pixman-color-space-private.h @@ -0,0 +1,50 @@ +/* + * Copyright © 2010 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef PIXMAN_COLOR_SPACE_PRIVATE_H +#define PIXMAN_COLOR_SPACE_PRIVATE_H + +#include "pixman-private.h" + +void +_pixman_color_space_to_argb_32 (pixman_color_space_t color_space, + uint32_t * values, + int width); + +void +_pixman_color_space_from_argb_32 (pixman_color_space_t color_space, + uint32_t * values, + int width); + +void +_pixman_color_space_to_argb_64 (pixman_color_space_t color_space, + uint64_t * values, + int width); + +void +_pixman_color_space_from_argb_64 (pixman_color_space_t color_space, + uint64_t * values, + int width); + +#endif /* PIXMAN_COLOR_SPACE_PRIVATE_H */ diff --git a/pixman/pixman-color-space.c b/pixman/pixman-color-space.c new file mode 100644 index 0000000..1046978 --- /dev/null +++ b/pixman/pixman-color-space.c @@ -0,0 +1,185 @@ +/* + * Copyright © 2010 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Author: Benjamin Otte <otte@gnome.org> + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "pixman-color-space-private.h" + +#include "pixman-private.h" + +/* uint32_t versions */ + +static uint32_t +premultiply_32 (uint32_t value) +{ + uint32_t alpha = value >> 24; + return (value & 0xff000000) | + (((value & 0x00ff0000) * alpha / 255) & 0x00ff0000) | + (((value & 0x0000ff00) * alpha / 255) & 0x0000ff00) | + (((value & 0x000000ff) * alpha / 255) & 0x000000ff); +} + +static uint32_t +unpremultiply_32 (uint32_t value) +{ + uint32_t alpha = value >> 24; + + if (alpha == 0) + return 0; + + return (value & 0xff000000) | + ((((value & 0x00ff0000) * 255 + 127) / alpha) & 0x00ff0000) | + ((((value & 0x0000ff00) * 255 + 127) / alpha) & 0x0000ff00) | + ((((value & 0x000000ff) * 255 + 127) / alpha) & 0x000000ff); +} + +void +_pixman_color_space_to_argb_32 (pixman_color_space_t color_space, + uint32_t * values, + int width) +{ + int i; + + switch (color_space) + { + case PIXMAN_COLOR_SPACE_ARGB: + break; + case PIXMAN_COLOR_SPACE_ARGB_UNMULTIPLIED: + for (i = 0; i < width; i++) + values[i] = premultiply_32 (values[i]); + break; + case PIXMAN_COLOR_SPACE_YCBCR_HD: + case PIXMAN_COLOR_SPACE_YCBCR_SD: + case PIXMAN_COLOR_SPACE_YCBCR_JPEG: + /* XXX */ + break; + default: + break; + } +} + +void +_pixman_color_space_from_argb_32 (pixman_color_space_t color_space, + uint32_t * values, + int width) +{ + int i; + + switch (color_space) + { + case PIXMAN_COLOR_SPACE_ARGB: + break; + case PIXMAN_COLOR_SPACE_ARGB_UNMULTIPLIED: + for (i = 0; i < width; i++) + values[i] = unpremultiply_32 (values[i]); + break; + case PIXMAN_COLOR_SPACE_YCBCR_HD: + case PIXMAN_COLOR_SPACE_YCBCR_SD: + case PIXMAN_COLOR_SPACE_YCBCR_JPEG: + /* XXX */ + break; + default: + break; + } +} + +/* uint64_t versions */ + +static uint64_t +premultiply_64 (uint64_t value) +{ + uint32_t alpha = value >> 48; + return (value & 0xffff000000000000ULL) | + (((value & 0x0000ffff00000000ULL) * alpha / 65535) & 0x0000ffff00000000ULL) | + (((value & 0x00000000ffff0000ULL) * alpha / 65535) & 0x00000000ffff0000ULL) | + (((value & 0x000000000000ffffULL) * alpha / 65535) & 0x000000000000ffffULL); +} + +static uint32_t +unpremultiply_64 (uint64_t value) +{ + uint32_t alpha = value >> 48; + + if (alpha == 0) + return 0; + + return (value & 0xffff000000000000ULL) | + ((((value & 0x0000ffff00000000ULL) * 255 + 127) / alpha) & 0x0000ffff00000000ULL) | + ((((value & 0x00000000ffff0000ULL) * 255 + 127) / alpha) & 0x00000000ffff0000ULL) | + ((((value & 0x000000000000ffffULL) * 255 + 127) / alpha) & 0x000000000000ffffULL); +} + +void +_pixman_color_space_to_argb_64 (pixman_color_space_t color_space, + uint64_t * values, + int width) +{ + int i; + + switch (color_space) + { + case PIXMAN_COLOR_SPACE_ARGB: + break; + case PIXMAN_COLOR_SPACE_ARGB_UNMULTIPLIED: + for (i = 0; i < width; i++) + values[i] = premultiply_64 (values[i]); + break; + case PIXMAN_COLOR_SPACE_YCBCR_HD: + case PIXMAN_COLOR_SPACE_YCBCR_SD: + case PIXMAN_COLOR_SPACE_YCBCR_JPEG: + /* XXX */ + break; + default: + break; + } +} + +void +_pixman_color_space_from_argb_64 (pixman_color_space_t color_space, + uint64_t * values, + int width) +{ + int i; + + switch (color_space) + { + case PIXMAN_COLOR_SPACE_ARGB: + break; + case PIXMAN_COLOR_SPACE_ARGB_UNMULTIPLIED: + for (i = 0; i < width; i++) + values[i] = unpremultiply_64 (values[i]); + break; + case PIXMAN_COLOR_SPACE_YCBCR_HD: + case PIXMAN_COLOR_SPACE_YCBCR_SD: + case PIXMAN_COLOR_SPACE_YCBCR_JPEG: + /* XXX */ + break; + default: + break; + } +} diff --git a/pixman/pixman-format.c b/pixman/pixman-format.c index 6d091e8..46368e6 100644 --- a/pixman/pixman-format.c +++ b/pixman/pixman-format.c @@ -77,6 +77,7 @@ typedef struct { pixman_bool_t supported_source; pixman_bool_t supported_destination; unsigned int num_planes; + pixman_color_space_t default_color_space; uint32_t * (* alloc_bits) (pixman_format_code_t format, int width, int height, @@ -85,63 +86,63 @@ typedef struct { } format_info_t; static const format_info_t format_infos[] = { - { PIXMAN_a2b10g10r10, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_x2b10g10r10, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_a2r10g10b10, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_x2r10g10b10, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_a8r8g8b8, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_x8r8g8b8, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_a8b8g8r8, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_x8b8g8r8, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_b8g8r8a8, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_b8g8r8x8, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_r8g8b8, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_b8g8r8, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_r5g6b5, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_b5g6r5, TRUE, TRUE, 1, alloc_bits }, + { PIXMAN_a2b10g10r10, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_x2b10g10r10, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_a2r10g10b10, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_x2r10g10b10, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_a8r8g8b8, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_x8r8g8b8, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_a8b8g8r8, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_x8b8g8r8, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_b8g8r8a8, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_b8g8r8x8, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_r8g8b8, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_b8g8r8, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_r5g6b5, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_b5g6r5, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, /* 16 bpp formats */ - { PIXMAN_a1r5g5b5, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_x1r5g5b5, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_a1b5g5r5, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_x1b5g5r5, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_a4r4g4b4, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_x4r4g4b4, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_a4b4g4r4, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_x4b4g4r4, TRUE, TRUE, 1, alloc_bits }, + { PIXMAN_a1r5g5b5, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_x1r5g5b5, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_a1b5g5r5, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_x1b5g5r5, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_a4r4g4b4, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_x4r4g4b4, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_a4b4g4r4, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_x4b4g4r4, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, /* 8bpp formats */ - { PIXMAN_a8, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_r3g3b2, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_b2g3r3, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_a2r2g2b2, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_a2b2g2r2, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_c8, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_g8, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_x4a4, TRUE, TRUE, 1, alloc_bits }, + { PIXMAN_a8, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_r3g3b2, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_b2g3r3, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_a2r2g2b2, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_a2b2g2r2, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_c8, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_g8, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_x4a4, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, /* Collides with PIXMAN_c8 - { PIXMAN_x4c4, TRUE, TRUE, 1, alloc_bits }, + { PIXMAN_x4c4, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, */ /* Collides with PIXMAN_g8 - { PIXMAN_x4g4, TRUE, TRUE, 1, alloc_bits }, + { PIXMAN_x4g4, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, */ /* 4bpp formats */ - { PIXMAN_a4, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_r1g2b1, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_b1g2r1, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_a1r1g1b1, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_a1b1g1r1, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_c4, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_g4, TRUE, TRUE, 1, alloc_bits }, + { PIXMAN_a4, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_r1g2b1, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_b1g2r1, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_a1r1g1b1, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_a1b1g1r1, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_c4, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_g4, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, /* 1bpp formats */ - { PIXMAN_a1, TRUE, TRUE, 1, alloc_bits }, - { PIXMAN_g1, TRUE, TRUE, 1, alloc_bits }, + { PIXMAN_a1, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_g1, TRUE, TRUE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, /* YUV formats */ - { PIXMAN_yuy2, TRUE, FALSE, 1, alloc_bits }, - { PIXMAN_yv12, TRUE, FALSE, 1, alloc_bits }, + { PIXMAN_yuy2, TRUE, FALSE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, + { PIXMAN_yv12, TRUE, FALSE, 1, PIXMAN_COLOR_SPACE_ARGB, alloc_bits }, }; /* default values for "invalid" at the end */ static const format_info_t invalid_format = - { 0, FALSE, FALSE, 0, NULL }; + { 0, FALSE, FALSE, 0, PIXMAN_COLOR_SPACE_ARGB, NULL }; static const format_info_t * @@ -175,6 +176,12 @@ _pixman_format_alloc_bits (pixman_format_code_t format, return info->alloc_bits (format, width, height, bits, rowstrides); } +pixman_color_space_t +_pixman_format_get_default_color_space (pixman_format_code_t format) +{ + return _get_format_info (format)->default_color_space; +} + /** * pixman_format_supported_source: * @format: A pixman_format_code_t format diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c index bddf79a..1d18133 100644 --- a/pixman/pixman-general.c +++ b/pixman/pixman-general.c @@ -36,8 +36,8 @@ #include <stdlib.h> #include <string.h> #include "pixman-private.h" +#include "pixman-color-space-private.h" #include "pixman-combine32.h" -#include "pixman-private.h" #define SCANLINE_BUFFER_LENGTH 8192 @@ -106,29 +106,32 @@ general_composite_rect (pixman_implementation_t *imp, if (op == PIXMAN_OP_CLEAR) fetch_src = NULL; - else if (wide) - fetch_src = _pixman_image_get_scanline_64; + else if (src->common.type == BITS && + src->bits.color_space != PIXMAN_COLOR_SPACE_ARGB) + fetch_src = wide ? _pixman_image_get_scanline_64_argb : _pixman_image_get_scanline_32_argb; else - fetch_src = _pixman_image_get_scanline_32; + fetch_src = wide ? _pixman_image_get_scanline_64 : _pixman_image_get_scanline_32; if (!mask || op == PIXMAN_OP_CLEAR) fetch_mask = NULL; - else if (wide) - fetch_mask = _pixman_image_get_scanline_64; + else if (mask->common.type == BITS && + mask->bits.color_space != PIXMAN_COLOR_SPACE_ARGB) + fetch_mask = wide ? _pixman_image_get_scanline_64_argb : _pixman_image_get_scanline_32_argb; else - fetch_mask = _pixman_image_get_scanline_32; + fetch_mask = wide ? _pixman_image_get_scanline_64 : _pixman_image_get_scanline_32; if (op == PIXMAN_OP_CLEAR || op == PIXMAN_OP_SRC) fetch_dest = NULL; - else if (wide) - fetch_dest = _pixman_image_get_scanline_64; + else if (dest->common.type == BITS && + dest->bits.color_space != PIXMAN_COLOR_SPACE_ARGB) + fetch_dest = wide ? _pixman_image_get_scanline_64_argb : _pixman_image_get_scanline_32_argb; else - fetch_dest = _pixman_image_get_scanline_32; + fetch_dest = wide ? _pixman_image_get_scanline_64 : _pixman_image_get_scanline_32; if (wide) - store = _pixman_image_store_scanline_64; + store = _pixman_image_store_scanline_64; else - store = _pixman_image_store_scanline_32; + store = _pixman_image_store_scanline_32; /* Skip the store step and composite directly into the * destination if the output format of the compose func matches @@ -143,14 +146,15 @@ general_composite_rect (pixman_implementation_t *imp, (op == PIXMAN_OP_OVER || op == PIXMAN_OP_ADD || op == PIXMAN_OP_SRC || - op == PIXMAN_OP_CLEAR || + op == PIXMAN_OP_CLEAR || op == PIXMAN_OP_IN_REVERSE || op == PIXMAN_OP_OUT_REVERSE || op == PIXMAN_OP_DST))) { if (!wide && - !dest->common.alpha_map && - !dest->bits.write_func) + !dest->common.alpha_map && + !dest->bits.write_func && + dest->bits.color_space == PIXMAN_COLOR_SPACE_ARGB) { store = NULL; } @@ -247,6 +251,11 @@ general_composite_rect (pixman_implementation_t *imp, (void *)mask_buffer, width); + if (wide) + _pixman_color_space_from_argb_64 (dest->bits.color_space, (uint64_t *) dest_buffer, width); + else + _pixman_color_space_from_argb_32 (dest->bits.color_space, (uint32_t *) dest_buffer, width); + /* write back */ store (&(dest->bits), dest_x, dest_y + i, width, (void *)dest_buffer); diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c index 6b878c3..ca06acf 100644 --- a/pixman/pixman-image.c +++ b/pixman/pixman-image.c @@ -30,6 +30,7 @@ #include <assert.h> #include "pixman-private.h" +#include "pixman-color-space-private.h" #include "pixman-combine32.h" pixman_bool_t @@ -148,6 +149,20 @@ _pixman_image_get_scanline_32 (pixman_image_t *image, image->common.get_scanline_32 (image, x, y, width, buffer, mask, mask_bits); } +void +_pixman_image_get_scanline_32_argb (pixman_image_t *image, + int x, + int y, + int width, + uint32_t * buffer, + const uint32_t *mask, + uint32_t mask_bits) +{ + image->common.get_scanline_32 (image, x, y, width, buffer, mask, mask_bits); + + _pixman_color_space_to_argb_32 (image->bits.color_space, buffer, width); +} + /* Even thought the type of buffer is uint32_t *, the function actually expects * a uint64_t *buffer. */ @@ -163,6 +178,20 @@ _pixman_image_get_scanline_64 (pixman_image_t *image, image->common.get_scanline_64 (image, x, y, width, buffer, unused, unused2); } +void +_pixman_image_get_scanline_64_argb (pixman_image_t *image, + int x, + int y, + int width, + uint32_t * buffer, + const uint32_t *unused, + uint32_t unused2) +{ + image->common.get_scanline_64 (image, x, y, width, buffer, unused, unused2); + + _pixman_color_space_to_argb_64 (image->bits.color_space, (uint64_t *) buffer, width); +} + static void image_property_changed (pixman_image_t *image) { diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index d66c343..40ed9e3 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -203,6 +203,8 @@ struct bits_image pixman_read_memory_func_t read_func; pixman_write_memory_func_t write_func; + pixman_color_space_t color_space; + struct { uint32_t * bits; int rowstride; /* in number of uint32_t's */ @@ -251,6 +253,15 @@ _pixman_image_get_scanline_32 (pixman_image_t *image, const uint32_t *mask, uint32_t mask_bits); +void +_pixman_image_get_scanline_32_argb (pixman_image_t *image, + int x, + int y, + int width, + uint32_t * buffer, + const uint32_t *mask, + uint32_t mask_bits); + /* Even thought the type of buffer is uint32_t *, the function actually expects * a uint64_t *buffer. */ @@ -264,6 +275,15 @@ _pixman_image_get_scanline_64 (pixman_image_t *image, uint32_t unused2); void +_pixman_image_get_scanline_64_argb (pixman_image_t *image, + int x, + int y, + int width, + uint32_t * buffer, + const uint32_t *unused, + uint32_t unused2); + +void _pixman_image_store_scanline_32 (bits_image_t * image, int x, int y, @@ -280,6 +300,9 @@ _pixman_image_store_scanline_64 (bits_image_t * image, int width, const uint32_t *buffer); +pixman_color_space_t +_pixman_format_get_default_color_space (pixman_format_code_t format); + uint32_t * _pixman_format_alloc_bits (pixman_format_code_t format, int width, diff --git a/pixman/pixman.c b/pixman/pixman.c index 3c2cf60..e98e31d 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -588,6 +588,7 @@ do_composite (pixman_implementation_t *imp, const pixman_fast_path_t *info; cache_t *cache; int i; + pixman_bool_t is_argb; src_format = src->common.extended_format_code; src_flags = src->common.flags; @@ -653,29 +654,37 @@ do_composite (pixman_implementation_t *imp, if (op == PIXMAN_OP_DST) return; + /* check color spaces */ + is_argb = (dest->type != BITS || dest->bits.color_space == PIXMAN_COLOR_SPACE_ARGB) && + (!mask || mask->type != BITS || mask->bits.color_space == PIXMAN_COLOR_SPACE_ARGB) && + (src->type != BITS || src->bits.color_space == PIXMAN_COLOR_SPACE_ARGB); + /* Check cache for fast paths */ cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache); - for (i = 0; i < N_CACHED_FAST_PATHS; ++i) + if (is_argb) { - info = &(cache->cache[i]); - - /* Note that we check for equality here, not whether - * the cached fast path matches. This is to prevent - * us from selecting an overly general fast path - * when a more specific one would work. - */ - if (info->op == op && - info->src_format == src_format && - info->mask_format == mask_format && - info->dest_format == dest_format && - info->src_flags == src_flags && - info->mask_flags == mask_flags && - info->dest_flags == dest_flags && - info->func) - { - goto found; - } + for (i = 0; i < N_CACHED_FAST_PATHS; ++i) + { + info = &(cache->cache[i]); + + /* Note that we check for equality here, not whether + * the cached fast path matches. This is to prevent + * us from selecting an overly general fast path + * when a more specific one would work. + */ + if (info->op == op && + info->src_format == src_format && + info->mask_format == mask_format && + info->dest_format == dest_format && + info->src_flags == src_flags && + info->mask_flags == mask_flags && + info->dest_flags == dest_flags && + info->func) + { + goto found; + } + } } while (imp) @@ -685,6 +694,8 @@ do_composite (pixman_implementation_t *imp, while (info->op != PIXMAN_OP_NONE) { if ((info->op == op || info->op == PIXMAN_OP_any) && + /* color space */ + (is_argb || info->op == PIXMAN_OP_any) && /* Formats */ ((info->src_format == src_format) || (info->src_format == PIXMAN_any)) && @@ -877,10 +888,14 @@ color_to_uint32 (const pixman_color_t *color) static pixman_bool_t color_to_pixel (pixman_color_t * color, uint32_t * pixel, - pixman_format_code_t format) + pixman_format_code_t format, + pixman_color_space_t color_space) { uint32_t c = color_to_uint32 (color); + if (color_space != PIXMAN_COLOR_SPACE_ARGB) + return FALSE; + if (!(format == PIXMAN_a8r8g8b8 || format == PIXMAN_x8r8g8b8 || format == PIXMAN_a8b8g8r8 || @@ -998,7 +1013,7 @@ pixman_image_fill_boxes (pixman_op_t op, { uint32_t pixel; - if (color_to_pixel (color, &pixel, dest->bits.format)) + if (color_to_pixel (color, &pixel, dest->bits.format, dest->bits.color_space)) { pixman_region32_t fill_region; int n_rects, j; diff --git a/pixman/pixman.h b/pixman/pixman.h index 89ce899..f483163 100644 --- a/pixman/pixman.h +++ b/pixman/pixman.h @@ -709,6 +709,14 @@ typedef enum { PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0) } pixman_format_code_t; +typedef enum { + PIXMAN_COLOR_SPACE_ARGB, + PIXMAN_COLOR_SPACE_ARGB_UNMULTIPLIED, + PIXMAN_COLOR_SPACE_YCBCR_HD, + PIXMAN_COLOR_SPACE_YCBCR_SD, + PIXMAN_COLOR_SPACE_YCBCR_JPEG +} pixman_color_space_t; + /* Querying supported format values. */ pixman_bool_t pixman_format_supported_destination (pixman_format_code_t format); pixman_bool_t pixman_format_supported_source (pixman_format_code_t format); @@ -736,6 +744,7 @@ pixman_image_t *pixman_image_create_bits (pixman_format_code_t uint32_t *bits, int rowstride_bytes); pixman_image_t *pixman_image_create_planar (pixman_format_code_t format, + pixman_color_space_t color_space, int width, int height, unsigned int num_planes, |