summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@gnome.org>2009-12-14 15:48:47 +0100
committerBenjamin Otte <otte@redhat.com>2010-04-07 10:38:42 +0200
commitdec875bad712cd0f39cce903ce8cd4939e0417f8 (patch)
tree8d28362a848d38167ec57c3f6576b69e1c1f2127
parentb60d75cbd4ae9ac60f88617cf290b70bcf514298 (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 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,