summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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,