summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@gnome.org>2009-12-14 15:48:47 +0100
committerSøren Sandmann Pedersen <ssp@redhat.com>2010-07-07 10:10:03 -0400
commit62dd909d6576ce018d6ac832b80cd168a3b8d3b4 (patch)
tree02ece08d478fd4b27835d01426c214ba08073d3b
parente8246983e5c48b915dc576943df55da3bd6cd9de (diff)
Add pixman_color_space_t
This differentiates pixel data from just having a format code to having a pixel layout - pixman_format_code_t - and color space - pixman_color_space_t. No new formats were added, only the option to create unmultiplied ARGB images exists now. In the future the general code path will look like this: Each colorspace provides a "canonical" format. pixman-access.c will provide accessors to read/write data from/to the image representation to the canonical format. Additional functions that convert between different color spaces will be added. These will be called from the generic store/fetch paths, so the accessors do not need to care about the color space. As a first step, compositing will still be done in ARGB, so the general path will look like this: src => fetch => convert \ > combine => convert => store => dest dest => fetch => convert / Benefits of this approach for adding more formats: - Minimal changes required to current code. With a simple check of the color space, all optimizations can continue working with a minimal performance impact. Even in the general case optimized store/fetch functions can be used. - Ease of optimization for common paths Common cases can be optimized easily. For example, Pixel-aligned rectangular fills with PIXMAN_OP_SRC and the same color space can be done with: src => fetch => store => dest and not a lot of code is required to do this. - Extensibility More color spaces can easily be added later, possibly even making use of the same accessors for data storage, i.e. linear RGB, more color matrices for YCbCr or even CMYK.
-rw-r--r--pixman/Makefile.am2
-rw-r--r--pixman/pixman-bits-image.c43
-rw-r--r--pixman/pixman-color-space-private.h50
-rw-r--r--pixman/pixman-color-space.c185
-rw-r--r--pixman/pixman-format.c95
-rw-r--r--pixman/pixman-general.c39
-rw-r--r--pixman/pixman-image.c29
-rw-r--r--pixman/pixman-private.h23
-rw-r--r--pixman/pixman.c57
-rw-r--r--pixman/pixman.h9
10 files changed, 441 insertions, 91 deletions
diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index a52a9e6e..0b3e40db 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 b41a5274..47ee87d8 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 */
@@ -967,7 +969,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)
{
@@ -981,22 +986,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 ();
@@ -1005,6 +1025,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 00000000..383bebd7
--- /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 00000000..10469784
--- /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 6d091e8e..46368e6b 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 fc742c03..975b4640 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;
}
@@ -246,6 +250,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 61354126..1a032c9c 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
@@ -145,6 +146,20 @@ _pixman_image_get_scanline_32 (pixman_image_t *image,
image->common.get_scanline_32 (image, x, y, width, buffer, mask);
}
+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.
*/
@@ -159,6 +174,20 @@ _pixman_image_get_scanline_64 (pixman_image_t *image,
image->common.get_scanline_64 (image, x, y, width, buffer, unused);
}
+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 4c4af54a..b8d5a62a 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -202,6 +202,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 */
@@ -248,6 +250,15 @@ _pixman_image_get_scanline_32 (pixman_image_t *image,
uint32_t * buffer,
const uint32_t *mask);
+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.
*/
@@ -260,6 +271,15 @@ _pixman_image_get_scanline_64 (pixman_image_t *image,
const uint32_t *unused);
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,
@@ -276,6 +296,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 3c2cf60e..e98e31d7 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 84f3e15e..95042ba4 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -721,6 +721,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);
@@ -748,6 +756,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,