aboutsummaryrefslogtreecommitdiff
path: root/pixman
diff options
context:
space:
mode:
Diffstat (limited to 'pixman')
-rw-r--r--pixman/pixman/pixman-access.c6075
-rw-r--r--pixman/pixman/pixman.c2428
-rw-r--r--pixman/pixman/pixman.h1976
-rw-r--r--pixman/test/blitters-test.c839
-rw-r--r--pixman/test/composite.c17
-rw-r--r--pixman/test/fetch-test.c10
-rw-r--r--pixman/test/stress-test.c2
7 files changed, 5740 insertions, 5607 deletions
diff --git a/pixman/pixman/pixman-access.c b/pixman/pixman/pixman-access.c
index 8dc770081..32c4d8b2c 100644
--- a/pixman/pixman/pixman-access.c
+++ b/pixman/pixman/pixman-access.c
@@ -1,2989 +1,3086 @@
-/*
- *
- * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
- * 2005 Lars Knoll & Zack Rusin, Trolltech
- * 2008 Aaron Plattner, NVIDIA Corporation
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "pixman-private.h"
-#include "pixman-accessor.h"
-
-#define CONVERT_RGB24_TO_Y15(s) \
- (((((s) >> 16) & 0xff) * 153 + \
- (((s) >> 8) & 0xff) * 301 + \
- (((s) ) & 0xff) * 58) >> 2)
-
-#define CONVERT_RGB24_TO_RGB15(s) \
- ((((s) >> 3) & 0x001f) | \
- (((s) >> 6) & 0x03e0) | \
- (((s) >> 9) & 0x7c00))
-
-#define RGB15_TO_ENTRY(mif,rgb15) \
- ((mif)->ent[rgb15])
-
-#define RGB24_TO_ENTRY(mif,rgb24) \
- RGB15_TO_ENTRY (mif,CONVERT_RGB24_TO_RGB15 (rgb24))
-
-#define RGB24_TO_ENTRY_Y(mif,rgb24) \
- ((mif)->ent[CONVERT_RGB24_TO_Y15 (rgb24)])
-
-/*
- * YV12 setup and access macros
- */
-
-#define YV12_SETUP(image) \
- bits_image_t *__bits_image = (bits_image_t *)image; \
- uint32_t *bits = __bits_image->bits; \
- int stride = __bits_image->rowstride; \
- int offset0 = stride < 0 ? \
- ((-stride) >> 1) * ((__bits_image->height - 1) >> 1) - stride : \
- stride * __bits_image->height; \
- int offset1 = stride < 0 ? \
- offset0 + ((-stride) >> 1) * ((__bits_image->height) >> 1) : \
- offset0 + (offset0 >> 2)
-
-/* Note no trailing semicolon on the above macro; if it's there, then
- * the typical usage of YV12_SETUP(image); will have an extra trailing ;
- * that some compilers will interpret as a statement -- and then any further
- * variable declarations will cause an error.
- */
-
-#define YV12_Y(line) \
- ((uint8_t *) ((bits) + (stride) * (line)))
-
-#define YV12_U(line) \
- ((uint8_t *) ((bits) + offset1 + \
- ((stride) >> 1) * ((line) >> 1)))
-
-#define YV12_V(line) \
- ((uint8_t *) ((bits) + offset0 + \
- ((stride) >> 1) * ((line) >> 1)))
-
-/********************************** Fetch ************************************/
-
-static void
-fetch_scanline_a8r8g8b8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
-
- MEMCPY_WRAPPED (image,
- buffer, (const uint32_t *)bits + x,
- width * sizeof(uint32_t));
-}
-
-static void
-fetch_scanline_x8r8g8b8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint32_t *pixel = (const uint32_t *)bits + x;
- const uint32_t *end = pixel + width;
-
- while (pixel < end)
- *buffer++ = READ (image, pixel++) | 0xff000000;
-}
-
-static void
-fetch_scanline_a8b8g8r8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint32_t *pixel = (uint32_t *)bits + x;
- const uint32_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
-
- *buffer++ = (p & 0xff00ff00) |
- ((p >> 16) & 0xff) |
- ((p & 0xff) << 16);
- }
-}
-
-static void
-fetch_scanline_x8b8g8r8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint32_t *pixel = (uint32_t *)bits + x;
- const uint32_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
-
- *buffer++ = 0xff000000 |
- (p & 0x0000ff00) |
- ((p >> 16) & 0xff) |
- ((p & 0xff) << 16);
- }
-}
-
-static void
-fetch_scanline_b8g8r8a8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint32_t *pixel = (uint32_t *)bits + x;
- const uint32_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
-
- *buffer++ = (((p & 0xff000000) >> 24) |
- ((p & 0x00ff0000) >> 8) |
- ((p & 0x0000ff00) << 8) |
- ((p & 0x000000ff) << 24));
- }
-}
-
-static void
-fetch_scanline_b8g8r8x8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint32_t *pixel = (uint32_t *)bits + x;
- const uint32_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
-
- *buffer++ = (0xff000000 |
- ((p & 0xff000000) >> 24) |
- ((p & 0x00ff0000) >> 8) |
- ((p & 0x0000ff00) << 8));
- }
-}
-
-static void
-fetch_scanline_x14r6g6b6 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint32_t *pixel = (const uint32_t *)bits + x;
- const uint32_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t r, g, b;
-
- r = ((p & 0x3f000) << 6) | ((p & 0x30000));
- g = ((p & 0x00fc0) << 4) | ((p & 0x00c00) >> 2);
- b = ((p & 0x0003f) << 2) | ((p & 0x00030) >> 4);
-
- *buffer++ = 0xff000000 | r | g | b;
- }
-}
-
-/* Expects a uint64_t buffer */
-static void
-fetch_scanline_a2r10g10b10 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * b,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint32_t *pixel = bits + x;
- const uint32_t *end = pixel + width;
- uint64_t *buffer = (uint64_t *)b;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint64_t a = p >> 30;
- uint64_t r = (p >> 20) & 0x3ff;
- uint64_t g = (p >> 10) & 0x3ff;
- uint64_t b = p & 0x3ff;
-
- r = r << 6 | r >> 4;
- g = g << 6 | g >> 4;
- b = b << 6 | b >> 4;
-
- a <<= 14;
- a |= a >> 2;
- a |= a >> 4;
- a |= a >> 8;
-
- *buffer++ = a << 48 | r << 32 | g << 16 | b;
- }
-}
-
-/* Expects a uint64_t buffer */
-static void
-fetch_scanline_x2r10g10b10 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * b,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint32_t *pixel = (uint32_t *)bits + x;
- const uint32_t *end = pixel + width;
- uint64_t *buffer = (uint64_t *)b;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint64_t r = (p >> 20) & 0x3ff;
- uint64_t g = (p >> 10) & 0x3ff;
- uint64_t b = p & 0x3ff;
-
- r = r << 6 | r >> 4;
- g = g << 6 | g >> 4;
- b = b << 6 | b >> 4;
-
- *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
- }
-}
-
-/* Expects a uint64_t buffer */
-static void
-fetch_scanline_a2b10g10r10 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * b,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint32_t *pixel = bits + x;
- const uint32_t *end = pixel + width;
- uint64_t *buffer = (uint64_t *)b;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint64_t a = p >> 30;
- uint64_t b = (p >> 20) & 0x3ff;
- uint64_t g = (p >> 10) & 0x3ff;
- uint64_t r = p & 0x3ff;
-
- r = r << 6 | r >> 4;
- g = g << 6 | g >> 4;
- b = b << 6 | b >> 4;
-
- a <<= 14;
- a |= a >> 2;
- a |= a >> 4;
- a |= a >> 8;
-
- *buffer++ = a << 48 | r << 32 | g << 16 | b;
- }
-}
-
-/* Expects a uint64_t buffer */
-static void
-fetch_scanline_x2b10g10r10 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * b,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint32_t *pixel = (uint32_t *)bits + x;
- const uint32_t *end = pixel + width;
- uint64_t *buffer = (uint64_t *)b;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint64_t b = (p >> 20) & 0x3ff;
- uint64_t g = (p >> 10) & 0x3ff;
- uint64_t r = p & 0x3ff;
-
- r = r << 6 | r >> 4;
- g = g << 6 | g >> 4;
- b = b << 6 | b >> 4;
-
- *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
- }
-}
-
-static void
-fetch_scanline_r8g8b8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint8_t *pixel = (const uint8_t *)bits + 3 * x;
- const uint8_t *end = pixel + 3 * width;
-
- while (pixel < end)
- {
- uint32_t b = 0xff000000;
-
-#ifdef WORDS_BIGENDIAN
- b |= (READ (image, pixel++) << 16);
- b |= (READ (image, pixel++) << 8);
- b |= (READ (image, pixel++));
-#else
- b |= (READ (image, pixel++));
- b |= (READ (image, pixel++) << 8);
- b |= (READ (image, pixel++) << 16);
-#endif
-
- *buffer++ = b;
- }
-}
-
-static void
-fetch_scanline_b8g8r8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint8_t *pixel = (const uint8_t *)bits + 3 * x;
- const uint8_t *end = pixel + 3 * width;
-
- while (pixel < end)
- {
- uint32_t b = 0xff000000;
-#ifdef WORDS_BIGENDIAN
- b |= (READ (image, pixel++));
- b |= (READ (image, pixel++) << 8);
- b |= (READ (image, pixel++) << 16);
-#else
- b |= (READ (image, pixel++) << 16);
- b |= (READ (image, pixel++) << 8);
- b |= (READ (image, pixel++));
-#endif
- *buffer++ = b;
- }
-}
-
-static void
-fetch_scanline_r5g6b5 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint16_t *pixel = (const uint16_t *)bits + x;
- const uint16_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t r = (((p) << 3) & 0xf8) |
- (((p) << 5) & 0xfc00) |
- (((p) << 8) & 0xf80000);
-
- r |= (r >> 5) & 0x70007;
- r |= (r >> 6) & 0x300;
-
- *buffer++ = 0xff000000 | r;
- }
-}
-
-static void
-fetch_scanline_b5g6r5 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint16_t *pixel = (const uint16_t *)bits + x;
- const uint16_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t r, g, b;
-
- b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
- g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
- r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
-
- *buffer++ = 0xff000000 | r | g | b;
- }
-}
-
-static void
-fetch_scanline_a1r5g5b5 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint16_t *pixel = (const uint16_t *)bits + x;
- const uint16_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t r, g, b, a;
-
- a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
- r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
- g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
- b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
-
- *buffer++ = a | r | g | b;
- }
-}
-
-static void
-fetch_scanline_x1r5g5b5 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint16_t *pixel = (const uint16_t *)bits + x;
- const uint16_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t r, g, b;
-
- r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
- g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
- b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
-
- *buffer++ = 0xff000000 | r | g | b;
- }
-}
-
-static void
-fetch_scanline_a1b5g5r5 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint16_t *pixel = (const uint16_t *)bits + x;
- const uint16_t *end = pixel + width;
- uint32_t r, g, b, a;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
-
- a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
- b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
- g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
- r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
-
- *buffer++ = a | r | g | b;
- }
-}
-
-static void
-fetch_scanline_x1b5g5r5 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint16_t *pixel = (const uint16_t *)bits + x;
- const uint16_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t r, g, b;
-
- b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
- g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
- r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
-
- *buffer++ = 0xff000000 | r | g | b;
- }
-}
-
-static void
-fetch_scanline_a4r4g4b4 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint16_t *pixel = (const uint16_t *)bits + x;
- const uint16_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t r, g, b, a;
-
- a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
- r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
- g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
- b = ((p & 0x000f) | ((p & 0x000f) << 4));
-
- *buffer++ = a | r | g | b;
- }
-}
-
-static void
-fetch_scanline_x4r4g4b4 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint16_t *pixel = (const uint16_t *)bits + x;
- const uint16_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t r, g, b;
-
- r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
- g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
- b = ((p & 0x000f) | ((p & 0x000f) << 4));
-
- *buffer++ = 0xff000000 | r | g | b;
- }
-}
-
-static void
-fetch_scanline_a4b4g4r4 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint16_t *pixel = (const uint16_t *)bits + x;
- const uint16_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t r, g, b, a;
-
- a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
- b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
- g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
- r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
-
- *buffer++ = a | r | g | b;
- }
-}
-
-static void
-fetch_scanline_x4b4g4r4 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint16_t *pixel = (const uint16_t *)bits + x;
- const uint16_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t r, g, b;
-
- b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
- g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
- r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
-
- *buffer++ = 0xff000000 | r | g | b;
- }
-}
-
-static void
-fetch_scanline_a8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint8_t *pixel = (const uint8_t *)bits + x;
- const uint8_t *end = pixel + width;
-
- while (pixel < end)
- *buffer++ = READ (image, pixel++) << 24;
-}
-
-static void
-fetch_scanline_r3g3b2 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint8_t *pixel = (const uint8_t *)bits + x;
- const uint8_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t r, g, b;
-
- r = ((p & 0xe0) | ((p & 0xe0) >> 3) | ((p & 0xc0) >> 6)) << 16;
- g = ((p & 0x1c) | ((p & 0x18) >> 3) | ((p & 0x1c) << 3)) << 8;
- b = (((p & 0x03) ) |
- ((p & 0x03) << 2) |
- ((p & 0x03) << 4) |
- ((p & 0x03) << 6));
-
- *buffer++ = 0xff000000 | r | g | b;
- }
-}
-
-static void
-fetch_scanline_b2g3r3 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint8_t *pixel = (const uint8_t *)bits + x;
- const uint8_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t r, g, b;
-
- b = p & 0xc0;
- b |= b >> 2;
- b |= b >> 4;
- b &= 0xff;
-
- g = (p & 0x38) << 10;
- g |= g >> 3;
- g |= g >> 6;
- g &= 0xff00;
-
- r = (p & 0x7) << 21;
- r |= r >> 3;
- r |= r >> 6;
- r &= 0xff0000;
-
- *buffer++ = 0xff000000 | r | g | b;
- }
-}
-
-static void
-fetch_scanline_a2r2g2b2 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint8_t *pixel = (const uint8_t *)bits + x;
- const uint8_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t a, r, g, b;
-
- a = ((p & 0xc0) * 0x55) << 18;
- r = ((p & 0x30) * 0x55) << 12;
- g = ((p & 0x0c) * 0x55) << 6;
- b = ((p & 0x03) * 0x55);
-
- *buffer++ = a | r | g | b;
- }
-}
-
-static void
-fetch_scanline_a2b2g2r2 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint8_t *pixel = (const uint8_t *)bits + x;
- const uint8_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
- uint32_t a, r, g, b;
-
- a = ((p & 0xc0) * 0x55) << 18;
- b = ((p & 0x30) * 0x55) >> 4;
- g = ((p & 0x0c) * 0x55) << 6;
- r = ((p & 0x03) * 0x55) << 16;
-
- *buffer++ = a | r | g | b;
- }
-}
-
-static void
-fetch_scanline_c8 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const pixman_indexed_t * indexed = image->bits.indexed;
- const uint8_t *pixel = (const uint8_t *)bits + x;
- const uint8_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint32_t p = READ (image, pixel++);
-
- *buffer++ = indexed->rgba[p];
- }
-}
-
-static void
-fetch_scanline_x4a4 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const uint8_t *pixel = (const uint8_t *)bits + x;
- const uint8_t *end = pixel + width;
-
- while (pixel < end)
- {
- uint8_t p = READ (image, pixel++) & 0xf;
-
- *buffer++ = (p | (p << 4)) << 24;
- }
-}
-
-#define FETCH_8(img,l,o) (READ (img, (((uint8_t *)(l)) + ((o) >> 3))))
-#ifdef WORDS_BIGENDIAN
-#define FETCH_4(img,l,o) \
- (((4 * (o)) & 4) ? (FETCH_8 (img,l, 4 * (o)) & 0xf) : (FETCH_8 (img,l,(4 * (o))) >> 4))
-#else
-#define FETCH_4(img,l,o) \
- (((4 * (o)) & 4) ? (FETCH_8 (img, l, 4 * (o)) >> 4) : (FETCH_8 (img, l, (4 * (o))) & 0xf))
-#endif
-
-static void
-fetch_scanline_a4 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t p = FETCH_4 (image, bits, i + x);
-
- p |= p << 4;
-
- *buffer++ = p << 24;
- }
-}
-
-static void
-fetch_scanline_r1g2b1 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t p = FETCH_4 (image, bits, i + x);
- uint32_t r, g, b;
-
- r = ((p & 0x8) * 0xff) << 13;
- g = ((p & 0x6) * 0x55) << 7;
- b = ((p & 0x1) * 0xff);
-
- *buffer++ = 0xff000000 | r | g | b;
- }
-}
-
-static void
-fetch_scanline_b1g2r1 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t p = FETCH_4 (image, bits, i + x);
- uint32_t r, g, b;
-
- b = ((p & 0x8) * 0xff) >> 3;
- g = ((p & 0x6) * 0x55) << 7;
- r = ((p & 0x1) * 0xff) << 16;
-
- *buffer++ = 0xff000000 | r | g | b;
- }
-}
-
-static void
-fetch_scanline_a1r1g1b1 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- uint32_t a, r, g, b;
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t p = FETCH_4 (image, bits, i + x);
-
- a = ((p & 0x8) * 0xff) << 21;
- r = ((p & 0x4) * 0xff) << 14;
- g = ((p & 0x2) * 0xff) << 7;
- b = ((p & 0x1) * 0xff);
-
- *buffer++ = a | r | g | b;
- }
-}
-
-static void
-fetch_scanline_a1b1g1r1 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t p = FETCH_4 (image, bits, i + x);
- uint32_t a, r, g, b;
-
- a = ((p & 0x8) * 0xff) << 21;
- b = ((p & 0x4) * 0xff) >> 2;
- g = ((p & 0x2) * 0xff) << 7;
- r = ((p & 0x1) * 0xff) << 16;
-
- *buffer++ = a | r | g | b;
- }
-}
-
-static void
-fetch_scanline_c4 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const pixman_indexed_t * indexed = image->bits.indexed;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t p = FETCH_4 (image, bits, i + x);
-
- *buffer++ = indexed->rgba[p];
- }
-}
-
-static void
-fetch_scanline_a1 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t p = READ (image, bits + ((i + x) >> 5));
- uint32_t a;
-
-#ifdef WORDS_BIGENDIAN
- a = p >> (0x1f - ((i + x) & 0x1f));
-#else
- a = p >> ((i + x) & 0x1f);
-#endif
- a = a & 1;
- a |= a << 1;
- a |= a << 2;
- a |= a << 4;
-
- *buffer++ = a << 24;
- }
-}
-
-static void
-fetch_scanline_g1 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
- const pixman_indexed_t * indexed = image->bits.indexed;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t p = READ (image, bits + ((i + x) >> 5));
- uint32_t a;
-
-#ifdef WORDS_BIGENDIAN
- a = p >> (0x1f - ((i + x) & 0x1f));
-#else
- a = p >> ((i + x) & 0x1f);
-#endif
- a = a & 1;
-
- *buffer++ = indexed->rgba[a];
- }
-}
-
-static void
-fetch_scanline_yuy2 (pixman_image_t *image,
- int x,
- int line,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- const uint32_t *bits = image->bits.bits + image->bits.rowstride * line;
- int i;
-
- for (i = 0; i < width; i++)
- {
- int16_t y, u, v;
- int32_t r, g, b;
-
- y = ((uint8_t *) bits)[(x + i) << 1] - 16;
- u = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] - 128;
- v = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] - 128;
-
- /* R = 1.164(Y - 16) + 1.596(V - 128) */
- r = 0x012b27 * y + 0x019a2e * v;
- /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
- g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
- /* B = 1.164(Y - 16) + 2.018(U - 128) */
- b = 0x012b27 * y + 0x0206a2 * u;
-
- *buffer++ = 0xff000000 |
- (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
- (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
- (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
- }
-}
-
-static void
-fetch_scanline_yv12 (pixman_image_t *image,
- int x,
- int line,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- YV12_SETUP (image);
- uint8_t *y_line = YV12_Y (line);
- uint8_t *u_line = YV12_U (line);
- uint8_t *v_line = YV12_V (line);
- int i;
-
- for (i = 0; i < width; i++)
- {
- int16_t y, u, v;
- int32_t r, g, b;
-
- y = y_line[x + i] - 16;
- u = u_line[(x + i) >> 1] - 128;
- v = v_line[(x + i) >> 1] - 128;
-
- /* R = 1.164(Y - 16) + 1.596(V - 128) */
- r = 0x012b27 * y + 0x019a2e * v;
- /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
- g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
- /* B = 1.164(Y - 16) + 2.018(U - 128) */
- b = 0x012b27 * y + 0x0206a2 * u;
-
- *buffer++ = 0xff000000 |
- (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
- (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
- (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
- }
-}
-
-/**************************** Pixel wise fetching *****************************/
-
-/* Despite the type, expects a uint64_t buffer */
-static uint64_t
-fetch_pixel_a2r10g10b10 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t p = READ (image, bits + offset);
- uint64_t a = p >> 30;
- uint64_t r = (p >> 20) & 0x3ff;
- uint64_t g = (p >> 10) & 0x3ff;
- uint64_t b = p & 0x3ff;
-
- r = r << 6 | r >> 4;
- g = g << 6 | g >> 4;
- b = b << 6 | b >> 4;
-
- a <<= 14;
- a |= a >> 2;
- a |= a >> 4;
- a |= a >> 8;
-
- return a << 48 | r << 32 | g << 16 | b;
-}
-
-/* Despite the type, this function expects a uint64_t buffer */
-static uint64_t
-fetch_pixel_x2r10g10b10 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t p = READ (image, bits + offset);
- uint64_t r = (p >> 20) & 0x3ff;
- uint64_t g = (p >> 10) & 0x3ff;
- uint64_t b = p & 0x3ff;
-
- r = r << 6 | r >> 4;
- g = g << 6 | g >> 4;
- b = b << 6 | b >> 4;
-
- return 0xffffULL << 48 | r << 32 | g << 16 | b;
-}
-
-/* Despite the type, expects a uint64_t buffer */
-static uint64_t
-fetch_pixel_a2b10g10r10 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t p = READ (image, bits + offset);
- uint64_t a = p >> 30;
- uint64_t b = (p >> 20) & 0x3ff;
- uint64_t g = (p >> 10) & 0x3ff;
- uint64_t r = p & 0x3ff;
-
- r = r << 6 | r >> 4;
- g = g << 6 | g >> 4;
- b = b << 6 | b >> 4;
-
- a <<= 14;
- a |= a >> 2;
- a |= a >> 4;
- a |= a >> 8;
-
- return a << 48 | r << 32 | g << 16 | b;
-}
-
-/* Despite the type, this function expects a uint64_t buffer */
-static uint64_t
-fetch_pixel_x2b10g10r10 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t p = READ (image, bits + offset);
- uint64_t b = (p >> 20) & 0x3ff;
- uint64_t g = (p >> 10) & 0x3ff;
- uint64_t r = p & 0x3ff;
-
- r = r << 6 | r >> 4;
- g = g << 6 | g >> 4;
- b = b << 6 | b >> 4;
-
- return 0xffffULL << 48 | r << 32 | g << 16 | b;
-}
-
-static uint32_t
-fetch_pixel_a8r8g8b8 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- return READ (image, (uint32_t *)bits + offset);
-}
-
-static uint32_t
-fetch_pixel_x8r8g8b8 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
-
- return READ (image, (uint32_t *)bits + offset) | 0xff000000;
-}
-
-static uint32_t
-fetch_pixel_a8b8g8r8 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint32_t *)bits + offset);
-
- return ((pixel & 0xff000000) |
- ((pixel >> 16) & 0xff) |
- (pixel & 0x0000ff00) |
- ((pixel & 0xff) << 16));
-}
-
-static uint32_t
-fetch_pixel_x8b8g8r8 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint32_t *)bits + offset);
-
- return ((0xff000000) |
- ((pixel >> 16) & 0xff) |
- (pixel & 0x0000ff00) |
- ((pixel & 0xff) << 16));
-}
-
-static uint32_t
-fetch_pixel_b8g8r8a8 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint32_t *)bits + offset);
-
- return ((pixel & 0xff000000) >> 24 |
- (pixel & 0x00ff0000) >> 8 |
- (pixel & 0x0000ff00) << 8 |
- (pixel & 0x000000ff) << 24);
-}
-
-static uint32_t
-fetch_pixel_b8g8r8x8 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint32_t *)bits + offset);
-
- return ((0xff000000) |
- (pixel & 0xff000000) >> 24 |
- (pixel & 0x00ff0000) >> 8 |
- (pixel & 0x0000ff00) << 8);
-}
-
-static uint32_t
-fetch_pixel_x14r6g6b6 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint32_t *) bits + offset);
- uint32_t r, g, b;
-
- r = ((pixel & 0x3f000) << 6) | ((pixel & 0x30000));
- g = ((pixel & 0x00fc0) << 4) | ((pixel & 0x00c00) >> 2);
- b = ((pixel & 0x0003f) << 2) | ((pixel & 0x00030) >> 4);
-
- return 0xff000000 | r | g | b;
-}
-
-static uint32_t
-fetch_pixel_r8g8b8 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint8_t *pixel = ((uint8_t *) bits) + (offset * 3);
-
-#ifdef WORDS_BIGENDIAN
- return (0xff000000 |
- (READ (image, pixel + 0) << 16) |
- (READ (image, pixel + 1) << 8) |
- (READ (image, pixel + 2)));
-#else
- return (0xff000000 |
- (READ (image, pixel + 2) << 16) |
- (READ (image, pixel + 1) << 8) |
- (READ (image, pixel + 0)));
-#endif
-}
-
-static uint32_t
-fetch_pixel_b8g8r8 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint8_t *pixel = ((uint8_t *) bits) + (offset * 3);
-#ifdef WORDS_BIGENDIAN
- return (0xff000000 |
- (READ (image, pixel + 2) << 16) |
- (READ (image, pixel + 1) << 8) |
- (READ (image, pixel + 0)));
-#else
- return (0xff000000 |
- (READ (image, pixel + 0) << 16) |
- (READ (image, pixel + 1) << 8) |
- (READ (image, pixel + 2)));
-#endif
-}
-
-static uint32_t
-fetch_pixel_r5g6b5 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint16_t *) bits + offset);
- uint32_t r, g, b;
-
- r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
- g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
- b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
-
- return (0xff000000 | r | g | b);
-}
-
-static uint32_t
-fetch_pixel_b5g6r5 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t r, g, b;
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint16_t *) bits + offset);
-
- b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
- g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
- r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
-
- return (0xff000000 | r | g | b);
-}
-
-static uint32_t
-fetch_pixel_a1r5g5b5 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint16_t *) bits + offset);
- uint32_t a, r, g, b;
-
- a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
- r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
- g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
- b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
-
- return (a | r | g | b);
-}
-
-static uint32_t
-fetch_pixel_x1r5g5b5 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint16_t *) bits + offset);
- uint32_t r, g, b;
-
- r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
- g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
- b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
-
- return (0xff000000 | r | g | b);
-}
-
-static uint32_t
-fetch_pixel_a1b5g5r5 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint16_t *) bits + offset);
- uint32_t a, r, g, b;
-
- a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
- b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
- g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
- r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
-
- return (a | r | g | b);
-}
-
-static uint32_t
-fetch_pixel_x1b5g5r5 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint16_t *) bits + offset);
- uint32_t r, g, b;
-
- b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
- g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
- r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
-
- return (0xff000000 | r | g | b);
-}
-
-static uint32_t
-fetch_pixel_a4r4g4b4 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint16_t *) bits + offset);
- uint32_t a, r, g, b;
-
- a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
- r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
- g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
- b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
-
- return (a | r | g | b);
-}
-
-static uint32_t
-fetch_pixel_x4r4g4b4 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint16_t *) bits + offset);
- uint32_t r, g, b;
-
- r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
- g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
- b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
-
- return (0xff000000 | r | g | b);
-}
-
-static uint32_t
-fetch_pixel_a4b4g4r4 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint16_t *) bits + offset);
- uint32_t a, r, g, b;
-
- a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
- b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
- g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
- r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
-
- return (a | r | g | b);
-}
-
-static uint32_t
-fetch_pixel_x4b4g4r4 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint16_t *) bits + offset);
- uint32_t r, g, b;
-
- b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
- g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
- r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
-
- return (0xff000000 | r | g | b);
-}
-
-static uint32_t
-fetch_pixel_a8 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint8_t *) bits + offset);
-
- return pixel << 24;
-}
-
-static uint32_t
-fetch_pixel_r3g3b2 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint8_t *) bits + offset);
- uint32_t r, g, b;
-
- r = ((pixel & 0xe0) |
- ((pixel & 0xe0) >> 3) |
- ((pixel & 0xc0) >> 6)) << 16;
-
- g = ((pixel & 0x1c) |
- ((pixel & 0x18) >> 3) |
- ((pixel & 0x1c) << 3)) << 8;
-
- b = (((pixel & 0x03) ) |
- ((pixel & 0x03) << 2) |
- ((pixel & 0x03) << 4) |
- ((pixel & 0x03) << 6));
-
- return (0xff000000 | r | g | b);
-}
-
-static uint32_t
-fetch_pixel_b2g3r3 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t p = READ (image, (uint8_t *) bits + offset);
- uint32_t r, g, b;
-
- b = p & 0xc0;
- b |= b >> 2;
- b |= b >> 4;
- b &= 0xff;
-
- g = (p & 0x38) << 10;
- g |= g >> 3;
- g |= g >> 6;
- g &= 0xff00;
-
- r = (p & 0x7) << 21;
- r |= r >> 3;
- r |= r >> 6;
- r &= 0xff0000;
-
- return 0xff000000 | r | g | b;
-}
-
-static uint32_t
-fetch_pixel_a2r2g2b2 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint8_t *) bits + offset);
- uint32_t a, r, g, b;
-
- a = ((pixel & 0xc0) * 0x55) << 18;
- r = ((pixel & 0x30) * 0x55) << 12;
- g = ((pixel & 0x0c) * 0x55) << 6;
- b = ((pixel & 0x03) * 0x55);
-
- return a | r | g | b;
-}
-
-static uint32_t
-fetch_pixel_a2b2g2r2 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint8_t *) bits + offset);
- uint32_t a, r, g, b;
-
- a = ((pixel & 0xc0) * 0x55) << 18;
- b = ((pixel & 0x30) * 0x55) >> 4;
- g = ((pixel & 0x0c) * 0x55) << 6;
- r = ((pixel & 0x03) * 0x55) << 16;
-
- return a | r | g | b;
-}
-
-static uint32_t
-fetch_pixel_c8 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint8_t *) bits + offset);
- const pixman_indexed_t * indexed = image->indexed;
-
- return indexed->rgba[pixel];
-}
-
-static uint32_t
-fetch_pixel_x4a4 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, (uint8_t *) bits + offset);
-
- return ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
-}
-
-static uint32_t
-fetch_pixel_a4 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = FETCH_4 (image, bits, offset);
-
- pixel |= pixel << 4;
- return pixel << 24;
-}
-
-static uint32_t
-fetch_pixel_r1g2b1 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = FETCH_4 (image, bits, offset);
- uint32_t r, g, b;
-
- r = ((pixel & 0x8) * 0xff) << 13;
- g = ((pixel & 0x6) * 0x55) << 7;
- b = ((pixel & 0x1) * 0xff);
-
- return 0xff000000 | r | g | b;
-}
-
-static uint32_t
-fetch_pixel_b1g2r1 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = FETCH_4 (image, bits, offset);
- uint32_t r, g, b;
-
- b = ((pixel & 0x8) * 0xff) >> 3;
- g = ((pixel & 0x6) * 0x55) << 7;
- r = ((pixel & 0x1) * 0xff) << 16;
-
- return 0xff000000 | r | g | b;
-}
-
-static uint32_t
-fetch_pixel_a1r1g1b1 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = FETCH_4 (image, bits, offset);
- uint32_t a, r, g, b;
-
- a = ((pixel & 0x8) * 0xff) << 21;
- r = ((pixel & 0x4) * 0xff) << 14;
- g = ((pixel & 0x2) * 0xff) << 7;
- b = ((pixel & 0x1) * 0xff);
-
- return a | r | g | b;
-}
-
-static uint32_t
-fetch_pixel_a1b1g1r1 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = FETCH_4 (image, bits, offset);
- uint32_t a, r, g, b;
-
- a = ((pixel & 0x8) * 0xff) << 21;
- b = ((pixel & 0x4) * 0xff) >> 2;
- g = ((pixel & 0x2) * 0xff) << 7;
- r = ((pixel & 0x1) * 0xff) << 16;
-
- return a | r | g | b;
-}
-
-static uint32_t
-fetch_pixel_c4 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = FETCH_4 (image, bits, offset);
- const pixman_indexed_t * indexed = image->indexed;
-
- return indexed->rgba[pixel];
-}
-
-static uint32_t
-fetch_pixel_a1 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, bits + (offset >> 5));
- uint32_t a;
-
-#ifdef WORDS_BIGENDIAN
- a = pixel >> (0x1f - (offset & 0x1f));
-#else
- a = pixel >> (offset & 0x1f);
-#endif
- a = a & 1;
- a |= a << 1;
- a |= a << 2;
- a |= a << 4;
-
- return a << 24;
-}
-
-static uint32_t
-fetch_pixel_g1 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t *bits = image->bits + line * image->rowstride;
- uint32_t pixel = READ (image, bits + (offset >> 5));
- const pixman_indexed_t * indexed = image->indexed;
- uint32_t a;
-
-#ifdef WORDS_BIGENDIAN
- a = pixel >> (0x1f - (offset & 0x1f));
-#else
- a = pixel >> (offset & 0x1f);
-#endif
- a = a & 1;
-
- return indexed->rgba[a];
-}
-
-static uint32_t
-fetch_pixel_yuy2 (bits_image_t *image,
- int offset,
- int line)
-{
- const uint32_t *bits = image->bits + image->rowstride * line;
-
- int16_t y, u, v;
- int32_t r, g, b;
-
- y = ((uint8_t *) bits)[offset << 1] - 16;
- u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128;
- v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128;
-
- /* R = 1.164(Y - 16) + 1.596(V - 128) */
- r = 0x012b27 * y + 0x019a2e * v;
-
- /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
- g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
-
- /* B = 1.164(Y - 16) + 2.018(U - 128) */
- b = 0x012b27 * y + 0x0206a2 * u;
-
- return 0xff000000 |
- (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
- (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
- (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
-}
-
-static uint32_t
-fetch_pixel_yv12 (bits_image_t *image,
- int offset,
- int line)
-{
- YV12_SETUP (image);
- int16_t y = YV12_Y (line)[offset] - 16;
- int16_t u = YV12_U (line)[offset >> 1] - 128;
- int16_t v = YV12_V (line)[offset >> 1] - 128;
- int32_t r, g, b;
-
- /* R = 1.164(Y - 16) + 1.596(V - 128) */
- r = 0x012b27 * y + 0x019a2e * v;
-
- /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
- g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
-
- /* B = 1.164(Y - 16) + 2.018(U - 128) */
- b = 0x012b27 * y + 0x0206a2 * u;
-
- return 0xff000000 |
- (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
- (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
- (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
-}
-
-/*********************************** Store ************************************/
-
-#define SPLIT_A(v) \
- uint32_t a = ((v) >> 24), \
- r = ((v) >> 16) & 0xff, \
- g = ((v) >> 8) & 0xff, \
- b = (v) & 0xff
-
-#define SPLIT(v) \
- uint32_t r = ((v) >> 16) & 0xff, \
- g = ((v) >> 8) & 0xff, \
- b = (v) & 0xff
-
-static void
-store_scanline_a2r10g10b10 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *v)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint32_t *pixel = bits + x;
- uint64_t *values = (uint64_t *)v;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- WRITE (image, pixel++,
- ((values[i] >> 32) & 0xc0000000) |
- ((values[i] >> 18) & 0x3ff00000) |
- ((values[i] >> 12) & 0xffc00) |
- ((values[i] >> 6) & 0x3ff));
- }
-}
-
-static void
-store_scanline_x2r10g10b10 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *v)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint64_t *values = (uint64_t *)v;
- uint32_t *pixel = bits + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- WRITE (image, pixel++,
- ((values[i] >> 18) & 0x3ff00000) |
- ((values[i] >> 12) & 0xffc00) |
- ((values[i] >> 6) & 0x3ff));
- }
-}
-
-static void
-store_scanline_a2b10g10r10 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *v)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint32_t *pixel = bits + x;
- uint64_t *values = (uint64_t *)v;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- WRITE (image, pixel++,
- ((values[i] >> 32) & 0xc0000000) |
- ((values[i] >> 38) & 0x3ff) |
- ((values[i] >> 12) & 0xffc00) |
- ((values[i] << 14) & 0x3ff00000));
- }
-}
-
-static void
-store_scanline_x2b10g10r10 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *v)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint64_t *values = (uint64_t *)v;
- uint32_t *pixel = bits + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- WRITE (image, pixel++,
- ((values[i] >> 38) & 0x3ff) |
- ((values[i] >> 12) & 0xffc00) |
- ((values[i] << 14) & 0x3ff00000));
- }
-}
-
-static void
-store_scanline_a8r8g8b8 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
-
- MEMCPY_WRAPPED (image, ((uint32_t *)bits) + x, values,
- width * sizeof(uint32_t));
-}
-
-static void
-store_scanline_x8r8g8b8 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint32_t *pixel = (uint32_t *)bits + x;
- int i;
-
- for (i = 0; i < width; ++i)
- WRITE (image, pixel++, values[i] & 0xffffff);
-}
-
-static void
-store_scanline_a8b8g8r8 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint32_t *pixel = (uint32_t *)bits + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- WRITE (image, pixel++,
- (values[i] & 0xff00ff00) |
- ((values[i] >> 16) & 0xff) |
- ((values[i] & 0xff) << 16));
- }
-}
-
-static void
-store_scanline_x8b8g8r8 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint32_t *pixel = (uint32_t *)bits + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- WRITE (image, pixel++,
- (values[i] & 0x0000ff00) |
- ((values[i] >> 16) & 0xff) |
- ((values[i] & 0xff) << 16));
- }
-}
-
-static void
-store_scanline_b8g8r8a8 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint32_t *pixel = (uint32_t *)bits + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- WRITE (image, pixel++,
- ((values[i] >> 24) & 0x000000ff) |
- ((values[i] >> 8) & 0x0000ff00) |
- ((values[i] << 8) & 0x00ff0000) |
- ((values[i] << 24) & 0xff000000));
- }
-}
-
-static void
-store_scanline_b8g8r8x8 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint32_t *pixel = (uint32_t *)bits + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- WRITE (image, pixel++,
- ((values[i] >> 8) & 0x0000ff00) |
- ((values[i] << 8) & 0x00ff0000) |
- ((values[i] << 24) & 0xff000000));
- }
-}
-
-static void
-store_scanline_x14r6g6b6 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint32_t *pixel = ((uint32_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t s = values[i];
- uint32_t r, g, b;
-
- r = (s & 0xfc0000) >> 6;
- g = (s & 0x00fc00) >> 4;
- b = (s & 0x0000fc) >> 2;
-
- WRITE (image, pixel++, r | g | b);
- }
-}
-
-static void
-store_scanline_r8g8b8 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint8_t *pixel = ((uint8_t *) bits) + 3 * x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t val = values[i];
-
-#ifdef WORDS_BIGENDIAN
- WRITE (image, pixel++, (val & 0x00ff0000) >> 16);
- WRITE (image, pixel++, (val & 0x0000ff00) >> 8);
- WRITE (image, pixel++, (val & 0x000000ff) >> 0);
-#else
- WRITE (image, pixel++, (val & 0x000000ff) >> 0);
- WRITE (image, pixel++, (val & 0x0000ff00) >> 8);
- WRITE (image, pixel++, (val & 0x00ff0000) >> 16);
-#endif
- }
-}
-
-static void
-store_scanline_b8g8r8 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint8_t *pixel = ((uint8_t *) bits) + 3 * x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t val = values[i];
-
-#ifdef WORDS_BIGENDIAN
- WRITE (image, pixel++, (val & 0x000000ff) >> 0);
- WRITE (image, pixel++, (val & 0x0000ff00) >> 8);
- WRITE (image, pixel++, (val & 0x00ff0000) >> 16);
-#else
- WRITE (image, pixel++, (val & 0x00ff0000) >> 16);
- WRITE (image, pixel++, (val & 0x0000ff00) >> 8);
- WRITE (image, pixel++, (val & 0x000000ff) >> 0);
-#endif
- }
-}
-
-static void
-store_scanline_r5g6b5 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint16_t *pixel = ((uint16_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t s = values[i];
-
- WRITE (image, pixel++,
- ((s >> 3) & 0x001f) |
- ((s >> 5) & 0x07e0) |
- ((s >> 8) & 0xf800));
- }
-}
-
-static void
-store_scanline_b5g6r5 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint16_t *pixel = ((uint16_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT (values[i]);
-
- WRITE (image, pixel++,
- ((b << 8) & 0xf800) |
- ((g << 3) & 0x07e0) |
- ((r >> 3) ));
- }
-}
-
-static void
-store_scanline_a1r5g5b5 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint16_t *pixel = ((uint16_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT_A (values[i]);
-
- WRITE (image, pixel++,
- ((a << 8) & 0x8000) |
- ((r << 7) & 0x7c00) |
- ((g << 2) & 0x03e0) |
- ((b >> 3) ));
- }
-}
-
-static void
-store_scanline_x1r5g5b5 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint16_t *pixel = ((uint16_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT (values[i]);
-
- WRITE (image, pixel++,
- ((r << 7) & 0x7c00) |
- ((g << 2) & 0x03e0) |
- ((b >> 3) ));
- }
-}
-
-static void
-store_scanline_a1b5g5r5 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint16_t *pixel = ((uint16_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT_A (values[i]);
-
- WRITE (image, pixel++,
- ((a << 8) & 0x8000) |
- ((b << 7) & 0x7c00) |
- ((g << 2) & 0x03e0) |
- ((r >> 3) ));
- }
-}
-
-static void
-store_scanline_x1b5g5r5 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint16_t *pixel = ((uint16_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT (values[i]);
-
- WRITE (image, pixel++, ((b << 7) & 0x7c00) |
- ((g << 2) & 0x03e0) |
- ((r >> 3) ));
- }
-}
-
-static void
-store_scanline_a4r4g4b4 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint16_t *pixel = ((uint16_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT_A (values[i]);
-
- WRITE (image, pixel++,
- ((a << 8) & 0xf000) |
- ((r << 4) & 0x0f00) |
- ((g ) & 0x00f0) |
- ((b >> 4) ));
- }
-}
-
-static void
-store_scanline_x4r4g4b4 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint16_t *pixel = ((uint16_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT (values[i]);
-
- WRITE (image, pixel++,
- ((r << 4) & 0x0f00) |
- ((g ) & 0x00f0) |
- ((b >> 4) ));
- }
-}
-
-static void
-store_scanline_a4b4g4r4 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint16_t *pixel = ((uint16_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT_A (values[i]);
- WRITE (image, pixel++, ((a << 8) & 0xf000) |
- ((b << 4) & 0x0f00) |
- ((g ) & 0x00f0) |
- ((r >> 4) ));
- }
-}
-
-static void
-store_scanline_x4b4g4r4 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint16_t *pixel = ((uint16_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT (values[i]);
-
- WRITE (image, pixel++,
- ((b << 4) & 0x0f00) |
- ((g ) & 0x00f0) |
- ((r >> 4) ));
- }
-}
-
-static void
-store_scanline_a8 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint8_t *pixel = ((uint8_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- WRITE (image, pixel++, values[i] >> 24);
- }
-}
-
-static void
-store_scanline_r3g3b2 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint8_t *pixel = ((uint8_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT (values[i]);
-
- WRITE (image, pixel++,
- ((r ) & 0xe0) |
- ((g >> 3) & 0x1c) |
- ((b >> 6) ));
- }
-}
-
-static void
-store_scanline_b2g3r3 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint8_t *pixel = ((uint8_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT (values[i]);
-
- WRITE (image, pixel++,
- ((b ) & 0xc0) |
- ((g >> 2) & 0x38) |
- ((r >> 5) ));
- }
-}
-
-static void
-store_scanline_a2r2g2b2 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint8_t *pixel = ((uint8_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT_A (values[i]);
-
- WRITE (image, pixel++,
- ((a ) & 0xc0) |
- ((r >> 2) & 0x30) |
- ((g >> 4) & 0x0c) |
- ((b >> 6) ));
- }
-}
-
-static void
-store_scanline_a2b2g2r2 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint8_t *pixel = ((uint8_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- SPLIT_A (values[i]);
-
- WRITE (image, pixel++,
- ((a ) & 0xc0) |
- ((b >> 2) & 0x30) |
- ((g >> 4) & 0x0c) |
- ((r >> 6) ));
- }
-}
-
-static void
-store_scanline_c8 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint8_t *pixel = ((uint8_t *) bits) + x;
- const pixman_indexed_t *indexed = image->indexed;
- int i;
-
- for (i = 0; i < width; ++i)
- WRITE (image, pixel++, RGB24_TO_ENTRY (indexed,values[i]));
-}
-
-static void
-store_scanline_g8 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint8_t *pixel = ((uint8_t *) bits) + x;
- const pixman_indexed_t *indexed = image->indexed;
- int i;
-
- for (i = 0; i < width; ++i)
- WRITE (image, pixel++, RGB24_TO_ENTRY_Y (indexed,values[i]));
-}
-
-static void
-store_scanline_x4a4 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- uint8_t *pixel = ((uint8_t *) bits) + x;
- int i;
-
- for (i = 0; i < width; ++i)
- WRITE (image, pixel++, values[i] >> 28);
-}
-
-#define STORE_8(img,l,o,v) (WRITE (img, (uint8_t *)(l) + ((o) >> 3), (v)))
-#ifdef WORDS_BIGENDIAN
-
-#define STORE_4(img,l,o,v) \
- do \
- { \
- int bo = 4 * (o); \
- int v4 = (v) & 0x0f; \
- \
- STORE_8 (img, l, bo, ( \
- bo & 4 ? \
- (FETCH_8 (img, l, bo) & 0xf0) | (v4) : \
- (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4))); \
- } while (0)
-#else
-
-#define STORE_4(img,l,o,v) \
- do \
- { \
- int bo = 4 * (o); \
- int v4 = (v) & 0x0f; \
- \
- STORE_8 (img, l, bo, ( \
- bo & 4 ? \
- (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4) : \
- (FETCH_8 (img, l, bo) & 0xf0) | (v4))); \
- } while (0)
-#endif
-
-static void
-store_scanline_a4 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- int i;
-
- for (i = 0; i < width; ++i)
- STORE_4 (image, bits, i + x, values[i] >> 28);
-}
-
-static void
-store_scanline_r1g2b1 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t pixel;
-
- SPLIT (values[i]);
- pixel = (((r >> 4) & 0x8) |
- ((g >> 5) & 0x6) |
- ((b >> 7) ));
- STORE_4 (image, bits, i + x, pixel);
- }
-}
-
-static void
-store_scanline_b1g2r1 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t pixel;
-
- SPLIT (values[i]);
- pixel = (((b >> 4) & 0x8) |
- ((g >> 5) & 0x6) |
- ((r >> 7) ));
- STORE_4 (image, bits, i + x, pixel);
- }
-}
-
-static void
-store_scanline_a1r1g1b1 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t pixel;
-
- SPLIT_A (values[i]);
- pixel = (((a >> 4) & 0x8) |
- ((r >> 5) & 0x4) |
- ((g >> 6) & 0x2) |
- ((b >> 7) ));
-
- STORE_4 (image, bits, i + x, pixel);
- }
-}
-
-static void
-store_scanline_a1b1g1r1 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t pixel;
-
- SPLIT_A (values[i]);
- pixel = (((a >> 4) & 0x8) |
- ((b >> 5) & 0x4) |
- ((g >> 6) & 0x2) |
- ((r >> 7) ));
-
- STORE_4 (image, bits, i + x, pixel);
- }
-}
-
-static void
-store_scanline_c4 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- const pixman_indexed_t *indexed = image->indexed;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t pixel;
-
- pixel = RGB24_TO_ENTRY (indexed, values[i]);
- STORE_4 (image, bits, i + x, pixel);
- }
-}
-
-static void
-store_scanline_g4 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- const pixman_indexed_t *indexed = image->indexed;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t pixel;
-
- pixel = RGB24_TO_ENTRY_Y (indexed, values[i]);
- STORE_4 (image, bits, i + x, pixel);
- }
-}
-
-static void
-store_scanline_a1 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t *pixel = ((uint32_t *) bits) + ((i + x) >> 5);
- uint32_t mask, v;
-
-#ifdef WORDS_BIGENDIAN
- mask = 1 << (0x1f - ((i + x) & 0x1f));
-#else
- mask = 1 << ((i + x) & 0x1f);
-#endif
- v = values[i] & 0x80000000 ? mask : 0;
-
- WRITE (image, pixel, (READ (image, pixel) & ~mask) | v);
- }
-}
-
-static void
-store_scanline_g1 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *bits = image->bits + image->rowstride * y;
- const pixman_indexed_t *indexed = image->indexed;
- int i;
-
- for (i = 0; i < width; ++i)
- {
- uint32_t *pixel = ((uint32_t *) bits) + ((i + x) >> 5);
- uint32_t mask, v;
-
-#ifdef WORDS_BIGENDIAN
- mask = 1 << (0x1f - ((i + x) & 0x1f));
-#else
- mask = 1 << ((i + x) & 0x1f);
-#endif
- v = RGB24_TO_ENTRY_Y (indexed, values[i]) & 0x1 ? mask : 0;
-
- WRITE (image, pixel, (READ (image, pixel) & ~mask) | v);
- }
-}
-
-/*
- * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit
- * store proc. Despite the type, this function expects a uint64_t buffer.
- */
-static void
-store_scanline_generic_64 (bits_image_t * image,
- int x,
- int y,
- int width,
- const uint32_t *values)
-{
- uint32_t *argb8_pixels;
-
- assert (image->common.type == BITS);
-
- argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t));
- if (!argb8_pixels)
- return;
-
- /* Contract the scanline. We could do this in place if values weren't
- * const.
- */
- pixman_contract (argb8_pixels, (uint64_t *)values, width);
-
- image->store_scanline_32 (image, x, y, width, argb8_pixels);
-
- free (argb8_pixels);
-}
-
-/* Despite the type, this function expects both buffer
- * and mask to be uint64_t
- */
-static void
-fetch_scanline_generic_64 (pixman_image_t *image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t *mask)
-{
- pixman_format_code_t format;
-
- /* Fetch the pixels into the first half of buffer and then expand them in
- * place.
- */
- image->bits.fetch_scanline_32 (image, x, y, width, buffer, NULL);
-
- format = image->bits.format;
- if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR ||
- PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
- {
- /* Indexed formats are mapped to a8r8g8b8 with full
- * precision, so when expanding we shouldn't correct
- * for the width of the channels
- */
-
- format = PIXMAN_a8r8g8b8;
- }
-
- pixman_expand ((uint64_t *)buffer, buffer, format, width);
-}
-
-/* Despite the type, this function expects a uint64_t *buffer */
-static uint64_t
-fetch_pixel_generic_64 (bits_image_t *image,
- int offset,
- int line)
-{
- uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line);
- uint64_t result;
- pixman_format_code_t format;
-
- format = image->format;
- if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR ||
- PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
- {
- /* Indexed formats are mapped to a8r8g8b8 with full
- * precision, so when expanding we shouldn't correct
- * for the width of the channels
- */
-
- format = PIXMAN_a8r8g8b8;
- }
-
- pixman_expand ((uint64_t *)&result, &pixel32, format, 1);
-
- return result;
-}
-
-/*
- * XXX: The transformed fetch path only works at 32-bpp so far. When all
- * paths have wide versions, this can be removed.
- *
- * WARNING: This function loses precision!
- */
-static uint32_t
-fetch_pixel_generic_lossy_32 (bits_image_t *image,
- int offset,
- int line)
-{
- uint64_t pixel64 = image->fetch_pixel_64 (image, offset, line);
- uint32_t result;
-
- pixman_contract (&result, &pixel64, 1);
-
- return result;
-}
-
-typedef struct
-{
- pixman_format_code_t format;
- fetch_scanline_t fetch_scanline_32;
- fetch_scanline_t fetch_scanline_64;
- fetch_pixel_32_t fetch_pixel_32;
- fetch_pixel_64_t fetch_pixel_64;
- store_scanline_t store_scanline_32;
- store_scanline_t store_scanline_64;
-} format_info_t;
-
-#define FORMAT_INFO(format) \
- { \
- PIXMAN_ ## format, \
- fetch_scanline_ ## format, \
- fetch_scanline_generic_64, \
- fetch_pixel_ ## format, fetch_pixel_generic_64, \
- store_scanline_ ## format, store_scanline_generic_64 \
- }
-
-static const format_info_t accessors[] =
-{
-/* 32 bpp formats */
- FORMAT_INFO (a8r8g8b8),
- FORMAT_INFO (x8r8g8b8),
- FORMAT_INFO (a8b8g8r8),
- FORMAT_INFO (x8b8g8r8),
- FORMAT_INFO (b8g8r8a8),
- FORMAT_INFO (b8g8r8x8),
- FORMAT_INFO (x14r6g6b6),
-
-/* 24bpp formats */
- FORMAT_INFO (r8g8b8),
- FORMAT_INFO (b8g8r8),
-
-/* 16bpp formats */
- FORMAT_INFO (r5g6b5),
- FORMAT_INFO (b5g6r5),
-
- FORMAT_INFO (a1r5g5b5),
- FORMAT_INFO (x1r5g5b5),
- FORMAT_INFO (a1b5g5r5),
- FORMAT_INFO (x1b5g5r5),
- FORMAT_INFO (a4r4g4b4),
- FORMAT_INFO (x4r4g4b4),
- FORMAT_INFO (a4b4g4r4),
- FORMAT_INFO (x4b4g4r4),
-
-/* 8bpp formats */
- FORMAT_INFO (a8),
- FORMAT_INFO (r3g3b2),
- FORMAT_INFO (b2g3r3),
- FORMAT_INFO (a2r2g2b2),
- FORMAT_INFO (a2b2g2r2),
-
- FORMAT_INFO (c8),
-
-#define fetch_scanline_g8 fetch_scanline_c8
-#define fetch_pixel_g8 fetch_pixel_c8
- FORMAT_INFO (g8),
-
-#define fetch_scanline_x4c4 fetch_scanline_c8
-#define fetch_pixel_x4c4 fetch_pixel_c8
-#define store_scanline_x4c4 store_scanline_c8
- FORMAT_INFO (x4c4),
-
-#define fetch_scanline_x4g4 fetch_scanline_c8
-#define fetch_pixel_x4g4 fetch_pixel_c8
-#define store_scanline_x4g4 store_scanline_g8
- FORMAT_INFO (x4g4),
-
- FORMAT_INFO (x4a4),
-
-/* 4bpp formats */
- FORMAT_INFO (a4),
- FORMAT_INFO (r1g2b1),
- FORMAT_INFO (b1g2r1),
- FORMAT_INFO (a1r1g1b1),
- FORMAT_INFO (a1b1g1r1),
-
- FORMAT_INFO (c4),
-
-#define fetch_scanline_g4 fetch_scanline_c4
-#define fetch_pixel_g4 fetch_pixel_c4
- FORMAT_INFO (g4),
-
-/* 1bpp formats */
- FORMAT_INFO (a1),
- FORMAT_INFO (g1),
-
-/* Wide formats */
-
- { PIXMAN_a2r10g10b10,
- NULL, fetch_scanline_a2r10g10b10,
- fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10,
- NULL, store_scanline_a2r10g10b10 },
-
- { PIXMAN_x2r10g10b10,
- NULL, fetch_scanline_x2r10g10b10,
- fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10,
- NULL, store_scanline_x2r10g10b10 },
-
- { PIXMAN_a2b10g10r10,
- NULL, fetch_scanline_a2b10g10r10,
- fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10,
- NULL, store_scanline_a2b10g10r10 },
-
- { PIXMAN_x2b10g10r10,
- NULL, fetch_scanline_x2b10g10r10,
- fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10,
- NULL, store_scanline_x2b10g10r10 },
-
-/* YUV formats */
- { PIXMAN_yuy2,
- fetch_scanline_yuy2, fetch_scanline_generic_64,
- fetch_pixel_yuy2, fetch_pixel_generic_64,
- NULL, NULL },
-
- { PIXMAN_yv12,
- fetch_scanline_yv12, fetch_scanline_generic_64,
- fetch_pixel_yv12, fetch_pixel_generic_64,
- NULL, NULL },
-
- { PIXMAN_null },
-};
-
-static void
-setup_accessors (bits_image_t *image)
-{
- const format_info_t *info = accessors;
-
- while (info->format != PIXMAN_null)
- {
- if (info->format == image->format)
- {
- image->fetch_scanline_32 = info->fetch_scanline_32;
- image->fetch_scanline_64 = info->fetch_scanline_64;
- image->fetch_pixel_32 = info->fetch_pixel_32;
- image->fetch_pixel_64 = info->fetch_pixel_64;
- image->store_scanline_32 = info->store_scanline_32;
- image->store_scanline_64 = info->store_scanline_64;
-
- return;
- }
-
- info++;
- }
-}
-
-#ifndef PIXMAN_FB_ACCESSORS
-void
-_pixman_bits_image_setup_accessors_accessors (bits_image_t *image);
-
-void
-_pixman_bits_image_setup_accessors (bits_image_t *image)
-{
- if (image->read_func || image->write_func)
- _pixman_bits_image_setup_accessors_accessors (image);
- else
- setup_accessors (image);
-}
-
-#else
-
-void
-_pixman_bits_image_setup_accessors_accessors (bits_image_t *image)
-{
- setup_accessors (image);
-}
-
-#endif
+/*
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ * 2005 Lars Knoll & Zack Rusin, Trolltech
+ * 2008 Aaron Plattner, NVIDIA Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "pixman-private.h"
+#include "pixman-accessor.h"
+
+#define CONVERT_RGB24_TO_Y15(s) \
+ (((((s) >> 16) & 0xff) * 153 + \
+ (((s) >> 8) & 0xff) * 301 + \
+ (((s) ) & 0xff) * 58) >> 2)
+
+#define CONVERT_RGB24_TO_RGB15(s) \
+ ((((s) >> 3) & 0x001f) | \
+ (((s) >> 6) & 0x03e0) | \
+ (((s) >> 9) & 0x7c00))
+
+#define RGB15_TO_ENTRY(mif,rgb15) \
+ ((mif)->ent[rgb15])
+
+#define RGB24_TO_ENTRY(mif,rgb24) \
+ RGB15_TO_ENTRY (mif,CONVERT_RGB24_TO_RGB15 (rgb24))
+
+#define RGB24_TO_ENTRY_Y(mif,rgb24) \
+ ((mif)->ent[CONVERT_RGB24_TO_Y15 (rgb24)])
+
+/*
+ * YV12 setup and access macros
+ */
+
+#define YV12_SETUP(image) \
+ bits_image_t *__bits_image = (bits_image_t *)image; \
+ uint32_t *bits = __bits_image->bits; \
+ int stride = __bits_image->rowstride; \
+ int offset0 = stride < 0 ? \
+ ((-stride) >> 1) * ((__bits_image->height - 1) >> 1) - stride : \
+ stride * __bits_image->height; \
+ int offset1 = stride < 0 ? \
+ offset0 + ((-stride) >> 1) * ((__bits_image->height) >> 1) : \
+ offset0 + (offset0 >> 2)
+
+/* Note no trailing semicolon on the above macro; if it's there, then
+ * the typical usage of YV12_SETUP(image); will have an extra trailing ;
+ * that some compilers will interpret as a statement -- and then any further
+ * variable declarations will cause an error.
+ */
+
+#define YV12_Y(line) \
+ ((uint8_t *) ((bits) + (stride) * (line)))
+
+#define YV12_U(line) \
+ ((uint8_t *) ((bits) + offset1 + \
+ ((stride) >> 1) * ((line) >> 1)))
+
+#define YV12_V(line) \
+ ((uint8_t *) ((bits) + offset0 + \
+ ((stride) >> 1) * ((line) >> 1)))
+
+/********************************** Fetch ************************************/
+
+static void
+fetch_scanline_a8r8g8b8 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+
+ MEMCPY_WRAPPED (image,
+ buffer, (const uint32_t *)bits + x,
+ width * sizeof(uint32_t));
+}
+
+static void
+fetch_scanline_x8r8g8b8 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint32_t *pixel = (const uint32_t *)bits + x;
+ const uint32_t *end = pixel + width;
+
+ while (pixel < end)
+ *buffer++ = READ (image, pixel++) | 0xff000000;
+}
+
+static void
+fetch_scanline_a8b8g8r8 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint32_t *pixel = (uint32_t *)bits + x;
+ const uint32_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+
+ *buffer++ = (p & 0xff00ff00) |
+ ((p >> 16) & 0xff) |
+ ((p & 0xff) << 16);
+ }
+}
+
+static void
+fetch_scanline_x8b8g8r8 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint32_t *pixel = (uint32_t *)bits + x;
+ const uint32_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+
+ *buffer++ = 0xff000000 |
+ (p & 0x0000ff00) |
+ ((p >> 16) & 0xff) |
+ ((p & 0xff) << 16);
+ }
+}
+
+static void
+fetch_scanline_b8g8r8a8 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint32_t *pixel = (uint32_t *)bits + x;
+ const uint32_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+
+ *buffer++ = (((p & 0xff000000) >> 24) |
+ ((p & 0x00ff0000) >> 8) |
+ ((p & 0x0000ff00) << 8) |
+ ((p & 0x000000ff) << 24));
+ }
+}
+
+static void
+fetch_scanline_b8g8r8x8 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint32_t *pixel = (uint32_t *)bits + x;
+ const uint32_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+
+ *buffer++ = (0xff000000 |
+ ((p & 0xff000000) >> 24) |
+ ((p & 0x00ff0000) >> 8) |
+ ((p & 0x0000ff00) << 8));
+ }
+}
+
+static void
+fetch_scanline_r8g8b8a8 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint32_t *pixel = (uint32_t *)bits + x;
+ const uint32_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+
+ *buffer++ = (((p & 0x000000ff) << 24) | (p >> 8));
+ }
+}
+
+static void
+fetch_scanline_r8g8b8x8 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint32_t *pixel = (uint32_t *)bits + x;
+ const uint32_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+
+ *buffer++ = (0xff000000 | (p >> 8));
+ }
+}
+
+static void
+fetch_scanline_x14r6g6b6 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint32_t *pixel = (const uint32_t *)bits + x;
+ const uint32_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t r, g, b;
+
+ r = ((p & 0x3f000) << 6) | ((p & 0x30000));
+ g = ((p & 0x00fc0) << 4) | ((p & 0x00c00) >> 2);
+ b = ((p & 0x0003f) << 2) | ((p & 0x00030) >> 4);
+
+ *buffer++ = 0xff000000 | r | g | b;
+ }
+}
+
+/* Expects a uint64_t buffer */
+static void
+fetch_scanline_a2r10g10b10 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * b,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint32_t *pixel = bits + x;
+ const uint32_t *end = pixel + width;
+ uint64_t *buffer = (uint64_t *)b;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint64_t a = p >> 30;
+ uint64_t r = (p >> 20) & 0x3ff;
+ uint64_t g = (p >> 10) & 0x3ff;
+ uint64_t b = p & 0x3ff;
+
+ r = r << 6 | r >> 4;
+ g = g << 6 | g >> 4;
+ b = b << 6 | b >> 4;
+
+ a <<= 14;
+ a |= a >> 2;
+ a |= a >> 4;
+ a |= a >> 8;
+
+ *buffer++ = a << 48 | r << 32 | g << 16 | b;
+ }
+}
+
+/* Expects a uint64_t buffer */
+static void
+fetch_scanline_x2r10g10b10 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * b,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint32_t *pixel = (uint32_t *)bits + x;
+ const uint32_t *end = pixel + width;
+ uint64_t *buffer = (uint64_t *)b;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint64_t r = (p >> 20) & 0x3ff;
+ uint64_t g = (p >> 10) & 0x3ff;
+ uint64_t b = p & 0x3ff;
+
+ r = r << 6 | r >> 4;
+ g = g << 6 | g >> 4;
+ b = b << 6 | b >> 4;
+
+ *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
+ }
+}
+
+/* Expects a uint64_t buffer */
+static void
+fetch_scanline_a2b10g10r10 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * b,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint32_t *pixel = bits + x;
+ const uint32_t *end = pixel + width;
+ uint64_t *buffer = (uint64_t *)b;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint64_t a = p >> 30;
+ uint64_t b = (p >> 20) & 0x3ff;
+ uint64_t g = (p >> 10) & 0x3ff;
+ uint64_t r = p & 0x3ff;
+
+ r = r << 6 | r >> 4;
+ g = g << 6 | g >> 4;
+ b = b << 6 | b >> 4;
+
+ a <<= 14;
+ a |= a >> 2;
+ a |= a >> 4;
+ a |= a >> 8;
+
+ *buffer++ = a << 48 | r << 32 | g << 16 | b;
+ }
+}
+
+/* Expects a uint64_t buffer */
+static void
+fetch_scanline_x2b10g10r10 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * b,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint32_t *pixel = (uint32_t *)bits + x;
+ const uint32_t *end = pixel + width;
+ uint64_t *buffer = (uint64_t *)b;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint64_t b = (p >> 20) & 0x3ff;
+ uint64_t g = (p >> 10) & 0x3ff;
+ uint64_t r = p & 0x3ff;
+
+ r = r << 6 | r >> 4;
+ g = g << 6 | g >> 4;
+ b = b << 6 | b >> 4;
+
+ *buffer++ = 0xffffULL << 48 | r << 32 | g << 16 | b;
+ }
+}
+
+static void
+fetch_scanline_r8g8b8 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint8_t *pixel = (const uint8_t *)bits + 3 * x;
+ const uint8_t *end = pixel + 3 * width;
+
+ while (pixel < end)
+ {
+ uint32_t b = 0xff000000;
+
+#ifdef WORDS_BIGENDIAN
+ b |= (READ (image, pixel++) << 16);
+ b |= (READ (image, pixel++) << 8);
+ b |= (READ (image, pixel++));
+#else
+ b |= (READ (image, pixel++));
+ b |= (READ (image, pixel++) << 8);
+ b |= (READ (image, pixel++) << 16);
+#endif
+
+ *buffer++ = b;
+ }
+}
+
+static void
+fetch_scanline_b8g8r8 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint8_t *pixel = (const uint8_t *)bits + 3 * x;
+ const uint8_t *end = pixel + 3 * width;
+
+ while (pixel < end)
+ {
+ uint32_t b = 0xff000000;
+#ifdef WORDS_BIGENDIAN
+ b |= (READ (image, pixel++));
+ b |= (READ (image, pixel++) << 8);
+ b |= (READ (image, pixel++) << 16);
+#else
+ b |= (READ (image, pixel++) << 16);
+ b |= (READ (image, pixel++) << 8);
+ b |= (READ (image, pixel++));
+#endif
+ *buffer++ = b;
+ }
+}
+
+static void
+fetch_scanline_r5g6b5 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint16_t *pixel = (const uint16_t *)bits + x;
+ const uint16_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t r = (((p) << 3) & 0xf8) |
+ (((p) << 5) & 0xfc00) |
+ (((p) << 8) & 0xf80000);
+
+ r |= (r >> 5) & 0x70007;
+ r |= (r >> 6) & 0x300;
+
+ *buffer++ = 0xff000000 | r;
+ }
+}
+
+static void
+fetch_scanline_b5g6r5 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint16_t *pixel = (const uint16_t *)bits + x;
+ const uint16_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t r, g, b;
+
+ b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
+ g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
+ r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
+
+ *buffer++ = 0xff000000 | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_a1r5g5b5 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint16_t *pixel = (const uint16_t *)bits + x;
+ const uint16_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t r, g, b, a;
+
+ a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
+ r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
+ g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
+ b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
+
+ *buffer++ = a | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_x1r5g5b5 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint16_t *pixel = (const uint16_t *)bits + x;
+ const uint16_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t r, g, b;
+
+ r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
+ g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
+ b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
+
+ *buffer++ = 0xff000000 | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_a1b5g5r5 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint16_t *pixel = (const uint16_t *)bits + x;
+ const uint16_t *end = pixel + width;
+ uint32_t r, g, b, a;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+
+ a = (uint32_t) ((uint8_t) (0 - ((p & 0x8000) >> 15))) << 24;
+ b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
+ g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
+ r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
+
+ *buffer++ = a | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_x1b5g5r5 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint16_t *pixel = (const uint16_t *)bits + x;
+ const uint16_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t r, g, b;
+
+ b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
+ g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
+ r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
+
+ *buffer++ = 0xff000000 | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_a4r4g4b4 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint16_t *pixel = (const uint16_t *)bits + x;
+ const uint16_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t r, g, b, a;
+
+ a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
+ r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
+ g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
+ b = ((p & 0x000f) | ((p & 0x000f) << 4));
+
+ *buffer++ = a | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_x4r4g4b4 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint16_t *pixel = (const uint16_t *)bits + x;
+ const uint16_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t r, g, b;
+
+ r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
+ g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
+ b = ((p & 0x000f) | ((p & 0x000f) << 4));
+
+ *buffer++ = 0xff000000 | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_a4b4g4r4 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint16_t *pixel = (const uint16_t *)bits + x;
+ const uint16_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t r, g, b, a;
+
+ a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
+ b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
+ g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
+ r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
+
+ *buffer++ = a | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_x4b4g4r4 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint16_t *pixel = (const uint16_t *)bits + x;
+ const uint16_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t r, g, b;
+
+ b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) >> 4;
+ g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
+ r = ((p & 0x000f) | ((p & 0x000f) << 4)) << 16;
+
+ *buffer++ = 0xff000000 | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_a8 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint8_t *pixel = (const uint8_t *)bits + x;
+ const uint8_t *end = pixel + width;
+
+ while (pixel < end)
+ *buffer++ = READ (image, pixel++) << 24;
+}
+
+static void
+fetch_scanline_r3g3b2 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint8_t *pixel = (const uint8_t *)bits + x;
+ const uint8_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t r, g, b;
+
+ r = ((p & 0xe0) | ((p & 0xe0) >> 3) | ((p & 0xc0) >> 6)) << 16;
+ g = ((p & 0x1c) | ((p & 0x18) >> 3) | ((p & 0x1c) << 3)) << 8;
+ b = (((p & 0x03) ) |
+ ((p & 0x03) << 2) |
+ ((p & 0x03) << 4) |
+ ((p & 0x03) << 6));
+
+ *buffer++ = 0xff000000 | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_b2g3r3 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint8_t *pixel = (const uint8_t *)bits + x;
+ const uint8_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t r, g, b;
+
+ b = p & 0xc0;
+ b |= b >> 2;
+ b |= b >> 4;
+ b &= 0xff;
+
+ g = (p & 0x38) << 10;
+ g |= g >> 3;
+ g |= g >> 6;
+ g &= 0xff00;
+
+ r = (p & 0x7) << 21;
+ r |= r >> 3;
+ r |= r >> 6;
+ r &= 0xff0000;
+
+ *buffer++ = 0xff000000 | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_a2r2g2b2 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint8_t *pixel = (const uint8_t *)bits + x;
+ const uint8_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t a, r, g, b;
+
+ a = ((p & 0xc0) * 0x55) << 18;
+ r = ((p & 0x30) * 0x55) << 12;
+ g = ((p & 0x0c) * 0x55) << 6;
+ b = ((p & 0x03) * 0x55);
+
+ *buffer++ = a | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_a2b2g2r2 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint8_t *pixel = (const uint8_t *)bits + x;
+ const uint8_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+ uint32_t a, r, g, b;
+
+ a = ((p & 0xc0) * 0x55) << 18;
+ b = ((p & 0x30) * 0x55) >> 4;
+ g = ((p & 0x0c) * 0x55) << 6;
+ r = ((p & 0x03) * 0x55) << 16;
+
+ *buffer++ = a | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_c8 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const pixman_indexed_t * indexed = image->bits.indexed;
+ const uint8_t *pixel = (const uint8_t *)bits + x;
+ const uint8_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint32_t p = READ (image, pixel++);
+
+ *buffer++ = indexed->rgba[p];
+ }
+}
+
+static void
+fetch_scanline_x4a4 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const uint8_t *pixel = (const uint8_t *)bits + x;
+ const uint8_t *end = pixel + width;
+
+ while (pixel < end)
+ {
+ uint8_t p = READ (image, pixel++) & 0xf;
+
+ *buffer++ = (p | (p << 4)) << 24;
+ }
+}
+
+#define FETCH_8(img,l,o) (READ (img, (((uint8_t *)(l)) + ((o) >> 3))))
+#ifdef WORDS_BIGENDIAN
+#define FETCH_4(img,l,o) \
+ (((4 * (o)) & 4) ? (FETCH_8 (img,l, 4 * (o)) & 0xf) : (FETCH_8 (img,l,(4 * (o))) >> 4))
+#else
+#define FETCH_4(img,l,o) \
+ (((4 * (o)) & 4) ? (FETCH_8 (img, l, 4 * (o)) >> 4) : (FETCH_8 (img, l, (4 * (o))) & 0xf))
+#endif
+
+static void
+fetch_scanline_a4 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t p = FETCH_4 (image, bits, i + x);
+
+ p |= p << 4;
+
+ *buffer++ = p << 24;
+ }
+}
+
+static void
+fetch_scanline_r1g2b1 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t p = FETCH_4 (image, bits, i + x);
+ uint32_t r, g, b;
+
+ r = ((p & 0x8) * 0xff) << 13;
+ g = ((p & 0x6) * 0x55) << 7;
+ b = ((p & 0x1) * 0xff);
+
+ *buffer++ = 0xff000000 | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_b1g2r1 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t p = FETCH_4 (image, bits, i + x);
+ uint32_t r, g, b;
+
+ b = ((p & 0x8) * 0xff) >> 3;
+ g = ((p & 0x6) * 0x55) << 7;
+ r = ((p & 0x1) * 0xff) << 16;
+
+ *buffer++ = 0xff000000 | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_a1r1g1b1 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ uint32_t a, r, g, b;
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t p = FETCH_4 (image, bits, i + x);
+
+ a = ((p & 0x8) * 0xff) << 21;
+ r = ((p & 0x4) * 0xff) << 14;
+ g = ((p & 0x2) * 0xff) << 7;
+ b = ((p & 0x1) * 0xff);
+
+ *buffer++ = a | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_a1b1g1r1 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t p = FETCH_4 (image, bits, i + x);
+ uint32_t a, r, g, b;
+
+ a = ((p & 0x8) * 0xff) << 21;
+ b = ((p & 0x4) * 0xff) >> 2;
+ g = ((p & 0x2) * 0xff) << 7;
+ r = ((p & 0x1) * 0xff) << 16;
+
+ *buffer++ = a | r | g | b;
+ }
+}
+
+static void
+fetch_scanline_c4 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const pixman_indexed_t * indexed = image->bits.indexed;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t p = FETCH_4 (image, bits, i + x);
+
+ *buffer++ = indexed->rgba[p];
+ }
+}
+
+static void
+fetch_scanline_a1 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t p = READ (image, bits + ((i + x) >> 5));
+ uint32_t a;
+
+#ifdef WORDS_BIGENDIAN
+ a = p >> (0x1f - ((i + x) & 0x1f));
+#else
+ a = p >> ((i + x) & 0x1f);
+#endif
+ a = a & 1;
+ a |= a << 1;
+ a |= a << 2;
+ a |= a << 4;
+
+ *buffer++ = a << 24;
+ }
+}
+
+static void
+fetch_scanline_g1 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + y * image->bits.rowstride;
+ const pixman_indexed_t * indexed = image->bits.indexed;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t p = READ (image, bits + ((i + x) >> 5));
+ uint32_t a;
+
+#ifdef WORDS_BIGENDIAN
+ a = p >> (0x1f - ((i + x) & 0x1f));
+#else
+ a = p >> ((i + x) & 0x1f);
+#endif
+ a = a & 1;
+
+ *buffer++ = indexed->rgba[a];
+ }
+}
+
+static void
+fetch_scanline_yuy2 (pixman_image_t *image,
+ int x,
+ int line,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ const uint32_t *bits = image->bits.bits + image->bits.rowstride * line;
+ int i;
+
+ for (i = 0; i < width; i++)
+ {
+ int16_t y, u, v;
+ int32_t r, g, b;
+
+ y = ((uint8_t *) bits)[(x + i) << 1] - 16;
+ u = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] - 128;
+ v = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] - 128;
+
+ /* R = 1.164(Y - 16) + 1.596(V - 128) */
+ r = 0x012b27 * y + 0x019a2e * v;
+ /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
+ g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
+ /* B = 1.164(Y - 16) + 2.018(U - 128) */
+ b = 0x012b27 * y + 0x0206a2 * u;
+
+ *buffer++ = 0xff000000 |
+ (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
+ (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
+ (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
+ }
+}
+
+static void
+fetch_scanline_yv12 (pixman_image_t *image,
+ int x,
+ int line,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ YV12_SETUP (image);
+ uint8_t *y_line = YV12_Y (line);
+ uint8_t *u_line = YV12_U (line);
+ uint8_t *v_line = YV12_V (line);
+ int i;
+
+ for (i = 0; i < width; i++)
+ {
+ int16_t y, u, v;
+ int32_t r, g, b;
+
+ y = y_line[x + i] - 16;
+ u = u_line[(x + i) >> 1] - 128;
+ v = v_line[(x + i) >> 1] - 128;
+
+ /* R = 1.164(Y - 16) + 1.596(V - 128) */
+ r = 0x012b27 * y + 0x019a2e * v;
+ /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
+ g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
+ /* B = 1.164(Y - 16) + 2.018(U - 128) */
+ b = 0x012b27 * y + 0x0206a2 * u;
+
+ *buffer++ = 0xff000000 |
+ (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
+ (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
+ (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
+ }
+}
+
+/**************************** Pixel wise fetching *****************************/
+
+/* Despite the type, expects a uint64_t buffer */
+static uint64_t
+fetch_pixel_a2r10g10b10 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t p = READ (image, bits + offset);
+ uint64_t a = p >> 30;
+ uint64_t r = (p >> 20) & 0x3ff;
+ uint64_t g = (p >> 10) & 0x3ff;
+ uint64_t b = p & 0x3ff;
+
+ r = r << 6 | r >> 4;
+ g = g << 6 | g >> 4;
+ b = b << 6 | b >> 4;
+
+ a <<= 14;
+ a |= a >> 2;
+ a |= a >> 4;
+ a |= a >> 8;
+
+ return a << 48 | r << 32 | g << 16 | b;
+}
+
+/* Despite the type, this function expects a uint64_t buffer */
+static uint64_t
+fetch_pixel_x2r10g10b10 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t p = READ (image, bits + offset);
+ uint64_t r = (p >> 20) & 0x3ff;
+ uint64_t g = (p >> 10) & 0x3ff;
+ uint64_t b = p & 0x3ff;
+
+ r = r << 6 | r >> 4;
+ g = g << 6 | g >> 4;
+ b = b << 6 | b >> 4;
+
+ return 0xffffULL << 48 | r << 32 | g << 16 | b;
+}
+
+/* Despite the type, expects a uint64_t buffer */
+static uint64_t
+fetch_pixel_a2b10g10r10 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t p = READ (image, bits + offset);
+ uint64_t a = p >> 30;
+ uint64_t b = (p >> 20) & 0x3ff;
+ uint64_t g = (p >> 10) & 0x3ff;
+ uint64_t r = p & 0x3ff;
+
+ r = r << 6 | r >> 4;
+ g = g << 6 | g >> 4;
+ b = b << 6 | b >> 4;
+
+ a <<= 14;
+ a |= a >> 2;
+ a |= a >> 4;
+ a |= a >> 8;
+
+ return a << 48 | r << 32 | g << 16 | b;
+}
+
+/* Despite the type, this function expects a uint64_t buffer */
+static uint64_t
+fetch_pixel_x2b10g10r10 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t p = READ (image, bits + offset);
+ uint64_t b = (p >> 20) & 0x3ff;
+ uint64_t g = (p >> 10) & 0x3ff;
+ uint64_t r = p & 0x3ff;
+
+ r = r << 6 | r >> 4;
+ g = g << 6 | g >> 4;
+ b = b << 6 | b >> 4;
+
+ return 0xffffULL << 48 | r << 32 | g << 16 | b;
+}
+
+static uint32_t
+fetch_pixel_a8r8g8b8 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ return READ (image, (uint32_t *)bits + offset);
+}
+
+static uint32_t
+fetch_pixel_x8r8g8b8 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+
+ return READ (image, (uint32_t *)bits + offset) | 0xff000000;
+}
+
+static uint32_t
+fetch_pixel_a8b8g8r8 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint32_t *)bits + offset);
+
+ return ((pixel & 0xff000000) |
+ ((pixel >> 16) & 0xff) |
+ (pixel & 0x0000ff00) |
+ ((pixel & 0xff) << 16));
+}
+
+static uint32_t
+fetch_pixel_x8b8g8r8 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint32_t *)bits + offset);
+
+ return ((0xff000000) |
+ ((pixel >> 16) & 0xff) |
+ (pixel & 0x0000ff00) |
+ ((pixel & 0xff) << 16));
+}
+
+static uint32_t
+fetch_pixel_b8g8r8a8 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint32_t *)bits + offset);
+
+ return ((pixel & 0xff000000) >> 24 |
+ (pixel & 0x00ff0000) >> 8 |
+ (pixel & 0x0000ff00) << 8 |
+ (pixel & 0x000000ff) << 24);
+}
+
+static uint32_t
+fetch_pixel_b8g8r8x8 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint32_t *)bits + offset);
+
+ return ((0xff000000) |
+ (pixel & 0xff000000) >> 24 |
+ (pixel & 0x00ff0000) >> 8 |
+ (pixel & 0x0000ff00) << 8);
+}
+
+static uint32_t
+fetch_pixel_r8g8b8a8 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint32_t *)bits + offset);
+
+ return (((pixel & 0x000000ff) << 24) | (pixel >> 8));
+}
+
+static uint32_t
+fetch_pixel_r8g8b8x8 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint32_t *)bits + offset);
+
+ return (0xff000000 | (pixel >> 8));
+}
+
+static uint32_t
+fetch_pixel_x14r6g6b6 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint32_t *) bits + offset);
+ uint32_t r, g, b;
+
+ r = ((pixel & 0x3f000) << 6) | ((pixel & 0x30000));
+ g = ((pixel & 0x00fc0) << 4) | ((pixel & 0x00c00) >> 2);
+ b = ((pixel & 0x0003f) << 2) | ((pixel & 0x00030) >> 4);
+
+ return 0xff000000 | r | g | b;
+}
+
+static uint32_t
+fetch_pixel_r8g8b8 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint8_t *pixel = ((uint8_t *) bits) + (offset * 3);
+
+#ifdef WORDS_BIGENDIAN
+ return (0xff000000 |
+ (READ (image, pixel + 0) << 16) |
+ (READ (image, pixel + 1) << 8) |
+ (READ (image, pixel + 2)));
+#else
+ return (0xff000000 |
+ (READ (image, pixel + 2) << 16) |
+ (READ (image, pixel + 1) << 8) |
+ (READ (image, pixel + 0)));
+#endif
+}
+
+static uint32_t
+fetch_pixel_b8g8r8 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint8_t *pixel = ((uint8_t *) bits) + (offset * 3);
+#ifdef WORDS_BIGENDIAN
+ return (0xff000000 |
+ (READ (image, pixel + 2) << 16) |
+ (READ (image, pixel + 1) << 8) |
+ (READ (image, pixel + 0)));
+#else
+ return (0xff000000 |
+ (READ (image, pixel + 0) << 16) |
+ (READ (image, pixel + 1) << 8) |
+ (READ (image, pixel + 2)));
+#endif
+}
+
+static uint32_t
+fetch_pixel_r5g6b5 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+ uint32_t r, g, b;
+
+ r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
+ g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
+ b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
+
+ return (0xff000000 | r | g | b);
+}
+
+static uint32_t
+fetch_pixel_b5g6r5 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t r, g, b;
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+
+ b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
+ g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
+ r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
+
+ return (0xff000000 | r | g | b);
+}
+
+static uint32_t
+fetch_pixel_a1r5g5b5 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+ uint32_t a, r, g, b;
+
+ a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
+ r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
+ g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
+ b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
+
+ return (a | r | g | b);
+}
+
+static uint32_t
+fetch_pixel_x1r5g5b5 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+ uint32_t r, g, b;
+
+ r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
+ g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
+ b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
+
+ return (0xff000000 | r | g | b);
+}
+
+static uint32_t
+fetch_pixel_a1b5g5r5 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+ uint32_t a, r, g, b;
+
+ a = (uint32_t) ((uint8_t) (0 - ((pixel & 0x8000) >> 15))) << 24;
+ b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
+ g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
+ r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
+
+ return (a | r | g | b);
+}
+
+static uint32_t
+fetch_pixel_x1b5g5r5 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+ uint32_t r, g, b;
+
+ b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
+ g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
+ r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
+
+ return (0xff000000 | r | g | b);
+}
+
+static uint32_t
+fetch_pixel_a4r4g4b4 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+ uint32_t a, r, g, b;
+
+ a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
+ r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
+ g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
+ b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
+
+ return (a | r | g | b);
+}
+
+static uint32_t
+fetch_pixel_x4r4g4b4 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+ uint32_t r, g, b;
+
+ r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
+ g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
+ b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
+
+ return (0xff000000 | r | g | b);
+}
+
+static uint32_t
+fetch_pixel_a4b4g4r4 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+ uint32_t a, r, g, b;
+
+ a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
+ b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
+ g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
+ r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
+
+ return (a | r | g | b);
+}
+
+static uint32_t
+fetch_pixel_x4b4g4r4 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint16_t *) bits + offset);
+ uint32_t r, g, b;
+
+ b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) >> 4;
+ g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
+ r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4)) << 16;
+
+ return (0xff000000 | r | g | b);
+}
+
+static uint32_t
+fetch_pixel_a8 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint8_t *) bits + offset);
+
+ return pixel << 24;
+}
+
+static uint32_t
+fetch_pixel_r3g3b2 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint8_t *) bits + offset);
+ uint32_t r, g, b;
+
+ r = ((pixel & 0xe0) |
+ ((pixel & 0xe0) >> 3) |
+ ((pixel & 0xc0) >> 6)) << 16;
+
+ g = ((pixel & 0x1c) |
+ ((pixel & 0x18) >> 3) |
+ ((pixel & 0x1c) << 3)) << 8;
+
+ b = (((pixel & 0x03) ) |
+ ((pixel & 0x03) << 2) |
+ ((pixel & 0x03) << 4) |
+ ((pixel & 0x03) << 6));
+
+ return (0xff000000 | r | g | b);
+}
+
+static uint32_t
+fetch_pixel_b2g3r3 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t p = READ (image, (uint8_t *) bits + offset);
+ uint32_t r, g, b;
+
+ b = p & 0xc0;
+ b |= b >> 2;
+ b |= b >> 4;
+ b &= 0xff;
+
+ g = (p & 0x38) << 10;
+ g |= g >> 3;
+ g |= g >> 6;
+ g &= 0xff00;
+
+ r = (p & 0x7) << 21;
+ r |= r >> 3;
+ r |= r >> 6;
+ r &= 0xff0000;
+
+ return 0xff000000 | r | g | b;
+}
+
+static uint32_t
+fetch_pixel_a2r2g2b2 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint8_t *) bits + offset);
+ uint32_t a, r, g, b;
+
+ a = ((pixel & 0xc0) * 0x55) << 18;
+ r = ((pixel & 0x30) * 0x55) << 12;
+ g = ((pixel & 0x0c) * 0x55) << 6;
+ b = ((pixel & 0x03) * 0x55);
+
+ return a | r | g | b;
+}
+
+static uint32_t
+fetch_pixel_a2b2g2r2 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint8_t *) bits + offset);
+ uint32_t a, r, g, b;
+
+ a = ((pixel & 0xc0) * 0x55) << 18;
+ b = ((pixel & 0x30) * 0x55) >> 4;
+ g = ((pixel & 0x0c) * 0x55) << 6;
+ r = ((pixel & 0x03) * 0x55) << 16;
+
+ return a | r | g | b;
+}
+
+static uint32_t
+fetch_pixel_c8 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint8_t *) bits + offset);
+ const pixman_indexed_t * indexed = image->indexed;
+
+ return indexed->rgba[pixel];
+}
+
+static uint32_t
+fetch_pixel_x4a4 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, (uint8_t *) bits + offset);
+
+ return ((pixel & 0xf) | ((pixel & 0xf) << 4)) << 24;
+}
+
+static uint32_t
+fetch_pixel_a4 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = FETCH_4 (image, bits, offset);
+
+ pixel |= pixel << 4;
+ return pixel << 24;
+}
+
+static uint32_t
+fetch_pixel_r1g2b1 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = FETCH_4 (image, bits, offset);
+ uint32_t r, g, b;
+
+ r = ((pixel & 0x8) * 0xff) << 13;
+ g = ((pixel & 0x6) * 0x55) << 7;
+ b = ((pixel & 0x1) * 0xff);
+
+ return 0xff000000 | r | g | b;
+}
+
+static uint32_t
+fetch_pixel_b1g2r1 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = FETCH_4 (image, bits, offset);
+ uint32_t r, g, b;
+
+ b = ((pixel & 0x8) * 0xff) >> 3;
+ g = ((pixel & 0x6) * 0x55) << 7;
+ r = ((pixel & 0x1) * 0xff) << 16;
+
+ return 0xff000000 | r | g | b;
+}
+
+static uint32_t
+fetch_pixel_a1r1g1b1 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = FETCH_4 (image, bits, offset);
+ uint32_t a, r, g, b;
+
+ a = ((pixel & 0x8) * 0xff) << 21;
+ r = ((pixel & 0x4) * 0xff) << 14;
+ g = ((pixel & 0x2) * 0xff) << 7;
+ b = ((pixel & 0x1) * 0xff);
+
+ return a | r | g | b;
+}
+
+static uint32_t
+fetch_pixel_a1b1g1r1 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = FETCH_4 (image, bits, offset);
+ uint32_t a, r, g, b;
+
+ a = ((pixel & 0x8) * 0xff) << 21;
+ b = ((pixel & 0x4) * 0xff) >> 2;
+ g = ((pixel & 0x2) * 0xff) << 7;
+ r = ((pixel & 0x1) * 0xff) << 16;
+
+ return a | r | g | b;
+}
+
+static uint32_t
+fetch_pixel_c4 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = FETCH_4 (image, bits, offset);
+ const pixman_indexed_t * indexed = image->indexed;
+
+ return indexed->rgba[pixel];
+}
+
+static uint32_t
+fetch_pixel_a1 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, bits + (offset >> 5));
+ uint32_t a;
+
+#ifdef WORDS_BIGENDIAN
+ a = pixel >> (0x1f - (offset & 0x1f));
+#else
+ a = pixel >> (offset & 0x1f);
+#endif
+ a = a & 1;
+ a |= a << 1;
+ a |= a << 2;
+ a |= a << 4;
+
+ return a << 24;
+}
+
+static uint32_t
+fetch_pixel_g1 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t *bits = image->bits + line * image->rowstride;
+ uint32_t pixel = READ (image, bits + (offset >> 5));
+ const pixman_indexed_t * indexed = image->indexed;
+ uint32_t a;
+
+#ifdef WORDS_BIGENDIAN
+ a = pixel >> (0x1f - (offset & 0x1f));
+#else
+ a = pixel >> (offset & 0x1f);
+#endif
+ a = a & 1;
+
+ return indexed->rgba[a];
+}
+
+static uint32_t
+fetch_pixel_yuy2 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ const uint32_t *bits = image->bits + image->rowstride * line;
+
+ int16_t y, u, v;
+ int32_t r, g, b;
+
+ y = ((uint8_t *) bits)[offset << 1] - 16;
+ u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128;
+ v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128;
+
+ /* R = 1.164(Y - 16) + 1.596(V - 128) */
+ r = 0x012b27 * y + 0x019a2e * v;
+
+ /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
+ g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
+
+ /* B = 1.164(Y - 16) + 2.018(U - 128) */
+ b = 0x012b27 * y + 0x0206a2 * u;
+
+ return 0xff000000 |
+ (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
+ (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
+ (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
+}
+
+static uint32_t
+fetch_pixel_yv12 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ YV12_SETUP (image);
+ int16_t y = YV12_Y (line)[offset] - 16;
+ int16_t u = YV12_U (line)[offset >> 1] - 128;
+ int16_t v = YV12_V (line)[offset >> 1] - 128;
+ int32_t r, g, b;
+
+ /* R = 1.164(Y - 16) + 1.596(V - 128) */
+ r = 0x012b27 * y + 0x019a2e * v;
+
+ /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
+ g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
+
+ /* B = 1.164(Y - 16) + 2.018(U - 128) */
+ b = 0x012b27 * y + 0x0206a2 * u;
+
+ return 0xff000000 |
+ (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
+ (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
+ (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
+}
+
+/*********************************** Store ************************************/
+
+#define SPLIT_A(v) \
+ uint32_t a = ((v) >> 24), \
+ r = ((v) >> 16) & 0xff, \
+ g = ((v) >> 8) & 0xff, \
+ b = (v) & 0xff
+
+#define SPLIT(v) \
+ uint32_t r = ((v) >> 16) & 0xff, \
+ g = ((v) >> 8) & 0xff, \
+ b = (v) & 0xff
+
+static void
+store_scanline_a2r10g10b10 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *v)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint32_t *pixel = bits + x;
+ uint64_t *values = (uint64_t *)v;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ WRITE (image, pixel++,
+ ((values[i] >> 32) & 0xc0000000) |
+ ((values[i] >> 18) & 0x3ff00000) |
+ ((values[i] >> 12) & 0xffc00) |
+ ((values[i] >> 6) & 0x3ff));
+ }
+}
+
+static void
+store_scanline_x2r10g10b10 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *v)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint64_t *values = (uint64_t *)v;
+ uint32_t *pixel = bits + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ WRITE (image, pixel++,
+ ((values[i] >> 18) & 0x3ff00000) |
+ ((values[i] >> 12) & 0xffc00) |
+ ((values[i] >> 6) & 0x3ff));
+ }
+}
+
+static void
+store_scanline_a2b10g10r10 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *v)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint32_t *pixel = bits + x;
+ uint64_t *values = (uint64_t *)v;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ WRITE (image, pixel++,
+ ((values[i] >> 32) & 0xc0000000) |
+ ((values[i] >> 38) & 0x3ff) |
+ ((values[i] >> 12) & 0xffc00) |
+ ((values[i] << 14) & 0x3ff00000));
+ }
+}
+
+static void
+store_scanline_x2b10g10r10 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *v)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint64_t *values = (uint64_t *)v;
+ uint32_t *pixel = bits + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ WRITE (image, pixel++,
+ ((values[i] >> 38) & 0x3ff) |
+ ((values[i] >> 12) & 0xffc00) |
+ ((values[i] << 14) & 0x3ff00000));
+ }
+}
+
+static void
+store_scanline_a8r8g8b8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+
+ MEMCPY_WRAPPED (image, ((uint32_t *)bits) + x, values,
+ width * sizeof(uint32_t));
+}
+
+static void
+store_scanline_x8r8g8b8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint32_t *pixel = (uint32_t *)bits + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ WRITE (image, pixel++, values[i] & 0xffffff);
+}
+
+static void
+store_scanline_a8b8g8r8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint32_t *pixel = (uint32_t *)bits + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ WRITE (image, pixel++,
+ (values[i] & 0xff00ff00) |
+ ((values[i] >> 16) & 0xff) |
+ ((values[i] & 0xff) << 16));
+ }
+}
+
+static void
+store_scanline_x8b8g8r8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint32_t *pixel = (uint32_t *)bits + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ WRITE (image, pixel++,
+ (values[i] & 0x0000ff00) |
+ ((values[i] >> 16) & 0xff) |
+ ((values[i] & 0xff) << 16));
+ }
+}
+
+static void
+store_scanline_b8g8r8a8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint32_t *pixel = (uint32_t *)bits + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ WRITE (image, pixel++,
+ ((values[i] >> 24) & 0x000000ff) |
+ ((values[i] >> 8) & 0x0000ff00) |
+ ((values[i] << 8) & 0x00ff0000) |
+ ((values[i] << 24) & 0xff000000));
+ }
+}
+
+static void
+store_scanline_b8g8r8x8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint32_t *pixel = (uint32_t *)bits + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ WRITE (image, pixel++,
+ ((values[i] >> 8) & 0x0000ff00) |
+ ((values[i] << 8) & 0x00ff0000) |
+ ((values[i] << 24) & 0xff000000));
+ }
+}
+
+static void
+store_scanline_r8g8b8a8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint32_t *pixel = (uint32_t *)bits + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ WRITE (image, pixel++,
+ ((values[i] >> 24) & 0x000000ff) | (values[i] << 8));
+ }
+}
+
+static void
+store_scanline_r8g8b8x8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint32_t *pixel = (uint32_t *)bits + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ WRITE (image, pixel++, (values[i] << 8));
+}
+
+static void
+store_scanline_x14r6g6b6 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint32_t *pixel = ((uint32_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t s = values[i];
+ uint32_t r, g, b;
+
+ r = (s & 0xfc0000) >> 6;
+ g = (s & 0x00fc00) >> 4;
+ b = (s & 0x0000fc) >> 2;
+
+ WRITE (image, pixel++, r | g | b);
+ }
+}
+
+static void
+store_scanline_r8g8b8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint8_t *pixel = ((uint8_t *) bits) + 3 * x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t val = values[i];
+
+#ifdef WORDS_BIGENDIAN
+ WRITE (image, pixel++, (val & 0x00ff0000) >> 16);
+ WRITE (image, pixel++, (val & 0x0000ff00) >> 8);
+ WRITE (image, pixel++, (val & 0x000000ff) >> 0);
+#else
+ WRITE (image, pixel++, (val & 0x000000ff) >> 0);
+ WRITE (image, pixel++, (val & 0x0000ff00) >> 8);
+ WRITE (image, pixel++, (val & 0x00ff0000) >> 16);
+#endif
+ }
+}
+
+static void
+store_scanline_b8g8r8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint8_t *pixel = ((uint8_t *) bits) + 3 * x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t val = values[i];
+
+#ifdef WORDS_BIGENDIAN
+ WRITE (image, pixel++, (val & 0x000000ff) >> 0);
+ WRITE (image, pixel++, (val & 0x0000ff00) >> 8);
+ WRITE (image, pixel++, (val & 0x00ff0000) >> 16);
+#else
+ WRITE (image, pixel++, (val & 0x00ff0000) >> 16);
+ WRITE (image, pixel++, (val & 0x0000ff00) >> 8);
+ WRITE (image, pixel++, (val & 0x000000ff) >> 0);
+#endif
+ }
+}
+
+static void
+store_scanline_r5g6b5 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint16_t *pixel = ((uint16_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t s = values[i];
+
+ WRITE (image, pixel++,
+ ((s >> 3) & 0x001f) |
+ ((s >> 5) & 0x07e0) |
+ ((s >> 8) & 0xf800));
+ }
+}
+
+static void
+store_scanline_b5g6r5 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint16_t *pixel = ((uint16_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT (values[i]);
+
+ WRITE (image, pixel++,
+ ((b << 8) & 0xf800) |
+ ((g << 3) & 0x07e0) |
+ ((r >> 3) ));
+ }
+}
+
+static void
+store_scanline_a1r5g5b5 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint16_t *pixel = ((uint16_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT_A (values[i]);
+
+ WRITE (image, pixel++,
+ ((a << 8) & 0x8000) |
+ ((r << 7) & 0x7c00) |
+ ((g << 2) & 0x03e0) |
+ ((b >> 3) ));
+ }
+}
+
+static void
+store_scanline_x1r5g5b5 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint16_t *pixel = ((uint16_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT (values[i]);
+
+ WRITE (image, pixel++,
+ ((r << 7) & 0x7c00) |
+ ((g << 2) & 0x03e0) |
+ ((b >> 3) ));
+ }
+}
+
+static void
+store_scanline_a1b5g5r5 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint16_t *pixel = ((uint16_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT_A (values[i]);
+
+ WRITE (image, pixel++,
+ ((a << 8) & 0x8000) |
+ ((b << 7) & 0x7c00) |
+ ((g << 2) & 0x03e0) |
+ ((r >> 3) ));
+ }
+}
+
+static void
+store_scanline_x1b5g5r5 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint16_t *pixel = ((uint16_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT (values[i]);
+
+ WRITE (image, pixel++, ((b << 7) & 0x7c00) |
+ ((g << 2) & 0x03e0) |
+ ((r >> 3) ));
+ }
+}
+
+static void
+store_scanline_a4r4g4b4 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint16_t *pixel = ((uint16_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT_A (values[i]);
+
+ WRITE (image, pixel++,
+ ((a << 8) & 0xf000) |
+ ((r << 4) & 0x0f00) |
+ ((g ) & 0x00f0) |
+ ((b >> 4) ));
+ }
+}
+
+static void
+store_scanline_x4r4g4b4 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint16_t *pixel = ((uint16_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT (values[i]);
+
+ WRITE (image, pixel++,
+ ((r << 4) & 0x0f00) |
+ ((g ) & 0x00f0) |
+ ((b >> 4) ));
+ }
+}
+
+static void
+store_scanline_a4b4g4r4 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint16_t *pixel = ((uint16_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT_A (values[i]);
+ WRITE (image, pixel++, ((a << 8) & 0xf000) |
+ ((b << 4) & 0x0f00) |
+ ((g ) & 0x00f0) |
+ ((r >> 4) ));
+ }
+}
+
+static void
+store_scanline_x4b4g4r4 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint16_t *pixel = ((uint16_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT (values[i]);
+
+ WRITE (image, pixel++,
+ ((b << 4) & 0x0f00) |
+ ((g ) & 0x00f0) |
+ ((r >> 4) ));
+ }
+}
+
+static void
+store_scanline_a8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint8_t *pixel = ((uint8_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ WRITE (image, pixel++, values[i] >> 24);
+ }
+}
+
+static void
+store_scanline_r3g3b2 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint8_t *pixel = ((uint8_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT (values[i]);
+
+ WRITE (image, pixel++,
+ ((r ) & 0xe0) |
+ ((g >> 3) & 0x1c) |
+ ((b >> 6) ));
+ }
+}
+
+static void
+store_scanline_b2g3r3 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint8_t *pixel = ((uint8_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT (values[i]);
+
+ WRITE (image, pixel++,
+ ((b ) & 0xc0) |
+ ((g >> 2) & 0x38) |
+ ((r >> 5) ));
+ }
+}
+
+static void
+store_scanline_a2r2g2b2 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint8_t *pixel = ((uint8_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT_A (values[i]);
+
+ WRITE (image, pixel++,
+ ((a ) & 0xc0) |
+ ((r >> 2) & 0x30) |
+ ((g >> 4) & 0x0c) |
+ ((b >> 6) ));
+ }
+}
+
+static void
+store_scanline_a2b2g2r2 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint8_t *pixel = ((uint8_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ SPLIT_A (values[i]);
+
+ WRITE (image, pixel++,
+ ((a ) & 0xc0) |
+ ((b >> 2) & 0x30) |
+ ((g >> 4) & 0x0c) |
+ ((r >> 6) ));
+ }
+}
+
+static void
+store_scanline_c8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint8_t *pixel = ((uint8_t *) bits) + x;
+ const pixman_indexed_t *indexed = image->indexed;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ WRITE (image, pixel++, RGB24_TO_ENTRY (indexed,values[i]));
+}
+
+static void
+store_scanline_g8 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint8_t *pixel = ((uint8_t *) bits) + x;
+ const pixman_indexed_t *indexed = image->indexed;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ WRITE (image, pixel++, RGB24_TO_ENTRY_Y (indexed,values[i]));
+}
+
+static void
+store_scanline_x4a4 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ uint8_t *pixel = ((uint8_t *) bits) + x;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ WRITE (image, pixel++, values[i] >> 28);
+}
+
+#define STORE_8(img,l,o,v) (WRITE (img, (uint8_t *)(l) + ((o) >> 3), (v)))
+#ifdef WORDS_BIGENDIAN
+
+#define STORE_4(img,l,o,v) \
+ do \
+ { \
+ int bo = 4 * (o); \
+ int v4 = (v) & 0x0f; \
+ \
+ STORE_8 (img, l, bo, ( \
+ bo & 4 ? \
+ (FETCH_8 (img, l, bo) & 0xf0) | (v4) : \
+ (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4))); \
+ } while (0)
+#else
+
+#define STORE_4(img,l,o,v) \
+ do \
+ { \
+ int bo = 4 * (o); \
+ int v4 = (v) & 0x0f; \
+ \
+ STORE_8 (img, l, bo, ( \
+ bo & 4 ? \
+ (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4) : \
+ (FETCH_8 (img, l, bo) & 0xf0) | (v4))); \
+ } while (0)
+#endif
+
+static void
+store_scanline_a4 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ STORE_4 (image, bits, i + x, values[i] >> 28);
+}
+
+static void
+store_scanline_r1g2b1 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t pixel;
+
+ SPLIT (values[i]);
+ pixel = (((r >> 4) & 0x8) |
+ ((g >> 5) & 0x6) |
+ ((b >> 7) ));
+ STORE_4 (image, bits, i + x, pixel);
+ }
+}
+
+static void
+store_scanline_b1g2r1 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t pixel;
+
+ SPLIT (values[i]);
+ pixel = (((b >> 4) & 0x8) |
+ ((g >> 5) & 0x6) |
+ ((r >> 7) ));
+ STORE_4 (image, bits, i + x, pixel);
+ }
+}
+
+static void
+store_scanline_a1r1g1b1 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t pixel;
+
+ SPLIT_A (values[i]);
+ pixel = (((a >> 4) & 0x8) |
+ ((r >> 5) & 0x4) |
+ ((g >> 6) & 0x2) |
+ ((b >> 7) ));
+
+ STORE_4 (image, bits, i + x, pixel);
+ }
+}
+
+static void
+store_scanline_a1b1g1r1 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t pixel;
+
+ SPLIT_A (values[i]);
+ pixel = (((a >> 4) & 0x8) |
+ ((b >> 5) & 0x4) |
+ ((g >> 6) & 0x2) |
+ ((r >> 7) ));
+
+ STORE_4 (image, bits, i + x, pixel);
+ }
+}
+
+static void
+store_scanline_c4 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ const pixman_indexed_t *indexed = image->indexed;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t pixel;
+
+ pixel = RGB24_TO_ENTRY (indexed, values[i]);
+ STORE_4 (image, bits, i + x, pixel);
+ }
+}
+
+static void
+store_scanline_g4 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ const pixman_indexed_t *indexed = image->indexed;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t pixel;
+
+ pixel = RGB24_TO_ENTRY_Y (indexed, values[i]);
+ STORE_4 (image, bits, i + x, pixel);
+ }
+}
+
+static void
+store_scanline_a1 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t *pixel = ((uint32_t *) bits) + ((i + x) >> 5);
+ uint32_t mask, v;
+
+#ifdef WORDS_BIGENDIAN
+ mask = 1 << (0x1f - ((i + x) & 0x1f));
+#else
+ mask = 1 << ((i + x) & 0x1f);
+#endif
+ v = values[i] & 0x80000000 ? mask : 0;
+
+ WRITE (image, pixel, (READ (image, pixel) & ~mask) | v);
+ }
+}
+
+static void
+store_scanline_g1 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *bits = image->bits + image->rowstride * y;
+ const pixman_indexed_t *indexed = image->indexed;
+ int i;
+
+ for (i = 0; i < width; ++i)
+ {
+ uint32_t *pixel = ((uint32_t *) bits) + ((i + x) >> 5);
+ uint32_t mask, v;
+
+#ifdef WORDS_BIGENDIAN
+ mask = 1 << (0x1f - ((i + x) & 0x1f));
+#else
+ mask = 1 << ((i + x) & 0x1f);
+#endif
+ v = RGB24_TO_ENTRY_Y (indexed, values[i]) & 0x1 ? mask : 0;
+
+ WRITE (image, pixel, (READ (image, pixel) & ~mask) | v);
+ }
+}
+
+/*
+ * Contracts a 64bpp image to 32bpp and then stores it using a regular 32-bit
+ * store proc. Despite the type, this function expects a uint64_t buffer.
+ */
+static void
+store_scanline_generic_64 (bits_image_t * image,
+ int x,
+ int y,
+ int width,
+ const uint32_t *values)
+{
+ uint32_t *argb8_pixels;
+
+ assert (image->common.type == BITS);
+
+ argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t));
+ if (!argb8_pixels)
+ return;
+
+ /* Contract the scanline. We could do this in place if values weren't
+ * const.
+ */
+ pixman_contract (argb8_pixels, (uint64_t *)values, width);
+
+ image->store_scanline_32 (image, x, y, width, argb8_pixels);
+
+ free (argb8_pixels);
+}
+
+/* Despite the type, this function expects both buffer
+ * and mask to be uint64_t
+ */
+static void
+fetch_scanline_generic_64 (pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ pixman_format_code_t format;
+
+ /* Fetch the pixels into the first half of buffer and then expand them in
+ * place.
+ */
+ image->bits.fetch_scanline_32 (image, x, y, width, buffer, NULL);
+
+ format = image->bits.format;
+ if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR ||
+ PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
+ {
+ /* Indexed formats are mapped to a8r8g8b8 with full
+ * precision, so when expanding we shouldn't correct
+ * for the width of the channels
+ */
+
+ format = PIXMAN_a8r8g8b8;
+ }
+
+ pixman_expand ((uint64_t *)buffer, buffer, format, width);
+}
+
+/* Despite the type, this function expects a uint64_t *buffer */
+static uint64_t
+fetch_pixel_generic_64 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line);
+ uint64_t result;
+ pixman_format_code_t format;
+
+ format = image->format;
+ if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR ||
+ PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
+ {
+ /* Indexed formats are mapped to a8r8g8b8 with full
+ * precision, so when expanding we shouldn't correct
+ * for the width of the channels
+ */
+
+ format = PIXMAN_a8r8g8b8;
+ }
+
+ pixman_expand ((uint64_t *)&result, &pixel32, format, 1);
+
+ return result;
+}
+
+/*
+ * XXX: The transformed fetch path only works at 32-bpp so far. When all
+ * paths have wide versions, this can be removed.
+ *
+ * WARNING: This function loses precision!
+ */
+static uint32_t
+fetch_pixel_generic_lossy_32 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ uint64_t pixel64 = image->fetch_pixel_64 (image, offset, line);
+ uint32_t result;
+
+ pixman_contract (&result, &pixel64, 1);
+
+ return result;
+}
+
+typedef struct
+{
+ pixman_format_code_t format;
+ fetch_scanline_t fetch_scanline_32;
+ fetch_scanline_t fetch_scanline_64;
+ fetch_pixel_32_t fetch_pixel_32;
+ fetch_pixel_64_t fetch_pixel_64;
+ store_scanline_t store_scanline_32;
+ store_scanline_t store_scanline_64;
+} format_info_t;
+
+#define FORMAT_INFO(format) \
+ { \
+ PIXMAN_ ## format, \
+ fetch_scanline_ ## format, \
+ fetch_scanline_generic_64, \
+ fetch_pixel_ ## format, fetch_pixel_generic_64, \
+ store_scanline_ ## format, store_scanline_generic_64 \
+ }
+
+static const format_info_t accessors[] =
+{
+/* 32 bpp formats */
+ FORMAT_INFO (a8r8g8b8),
+ FORMAT_INFO (x8r8g8b8),
+ FORMAT_INFO (a8b8g8r8),
+ FORMAT_INFO (x8b8g8r8),
+ FORMAT_INFO (b8g8r8a8),
+ FORMAT_INFO (b8g8r8x8),
+ FORMAT_INFO (r8g8b8a8),
+ FORMAT_INFO (r8g8b8x8),
+ FORMAT_INFO (x14r6g6b6),
+
+/* 24bpp formats */
+ FORMAT_INFO (r8g8b8),
+ FORMAT_INFO (b8g8r8),
+
+/* 16bpp formats */
+ FORMAT_INFO (r5g6b5),
+ FORMAT_INFO (b5g6r5),
+
+ FORMAT_INFO (a1r5g5b5),
+ FORMAT_INFO (x1r5g5b5),
+ FORMAT_INFO (a1b5g5r5),
+ FORMAT_INFO (x1b5g5r5),
+ FORMAT_INFO (a4r4g4b4),
+ FORMAT_INFO (x4r4g4b4),
+ FORMAT_INFO (a4b4g4r4),
+ FORMAT_INFO (x4b4g4r4),
+
+/* 8bpp formats */
+ FORMAT_INFO (a8),
+ FORMAT_INFO (r3g3b2),
+ FORMAT_INFO (b2g3r3),
+ FORMAT_INFO (a2r2g2b2),
+ FORMAT_INFO (a2b2g2r2),
+
+ FORMAT_INFO (c8),
+
+#define fetch_scanline_g8 fetch_scanline_c8
+#define fetch_pixel_g8 fetch_pixel_c8
+ FORMAT_INFO (g8),
+
+#define fetch_scanline_x4c4 fetch_scanline_c8
+#define fetch_pixel_x4c4 fetch_pixel_c8
+#define store_scanline_x4c4 store_scanline_c8
+ FORMAT_INFO (x4c4),
+
+#define fetch_scanline_x4g4 fetch_scanline_c8
+#define fetch_pixel_x4g4 fetch_pixel_c8
+#define store_scanline_x4g4 store_scanline_g8
+ FORMAT_INFO (x4g4),
+
+ FORMAT_INFO (x4a4),
+
+/* 4bpp formats */
+ FORMAT_INFO (a4),
+ FORMAT_INFO (r1g2b1),
+ FORMAT_INFO (b1g2r1),
+ FORMAT_INFO (a1r1g1b1),
+ FORMAT_INFO (a1b1g1r1),
+
+ FORMAT_INFO (c4),
+
+#define fetch_scanline_g4 fetch_scanline_c4
+#define fetch_pixel_g4 fetch_pixel_c4
+ FORMAT_INFO (g4),
+
+/* 1bpp formats */
+ FORMAT_INFO (a1),
+ FORMAT_INFO (g1),
+
+/* Wide formats */
+
+ { PIXMAN_a2r10g10b10,
+ NULL, fetch_scanline_a2r10g10b10,
+ fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10,
+ NULL, store_scanline_a2r10g10b10 },
+
+ { PIXMAN_x2r10g10b10,
+ NULL, fetch_scanline_x2r10g10b10,
+ fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10,
+ NULL, store_scanline_x2r10g10b10 },
+
+ { PIXMAN_a2b10g10r10,
+ NULL, fetch_scanline_a2b10g10r10,
+ fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10,
+ NULL, store_scanline_a2b10g10r10 },
+
+ { PIXMAN_x2b10g10r10,
+ NULL, fetch_scanline_x2b10g10r10,
+ fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10,
+ NULL, store_scanline_x2b10g10r10 },
+
+/* YUV formats */
+ { PIXMAN_yuy2,
+ fetch_scanline_yuy2, fetch_scanline_generic_64,
+ fetch_pixel_yuy2, fetch_pixel_generic_64,
+ NULL, NULL },
+
+ { PIXMAN_yv12,
+ fetch_scanline_yv12, fetch_scanline_generic_64,
+ fetch_pixel_yv12, fetch_pixel_generic_64,
+ NULL, NULL },
+
+ { PIXMAN_null },
+};
+
+static void
+setup_accessors (bits_image_t *image)
+{
+ const format_info_t *info = accessors;
+
+ while (info->format != PIXMAN_null)
+ {
+ if (info->format == image->format)
+ {
+ image->fetch_scanline_32 = info->fetch_scanline_32;
+ image->fetch_scanline_64 = info->fetch_scanline_64;
+ image->fetch_pixel_32 = info->fetch_pixel_32;
+ image->fetch_pixel_64 = info->fetch_pixel_64;
+ image->store_scanline_32 = info->store_scanline_32;
+ image->store_scanline_64 = info->store_scanline_64;
+
+ return;
+ }
+
+ info++;
+ }
+}
+
+#ifndef PIXMAN_FB_ACCESSORS
+void
+_pixman_bits_image_setup_accessors_accessors (bits_image_t *image);
+
+void
+_pixman_bits_image_setup_accessors (bits_image_t *image)
+{
+ if (image->read_func || image->write_func)
+ _pixman_bits_image_setup_accessors_accessors (image);
+ else
+ setup_accessors (image);
+}
+
+#else
+
+void
+_pixman_bits_image_setup_accessors_accessors (bits_image_t *image)
+{
+ setup_accessors (image);
+}
+
+#endif
diff --git a/pixman/pixman/pixman.c b/pixman/pixman/pixman.c
index 8b24849af..f21af2f36 100644
--- a/pixman/pixman/pixman.c
+++ b/pixman/pixman/pixman.c
@@ -1,1211 +1,1217 @@
-/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
-/*
- * Copyright © 2000 SuSE, Inc.
- * Copyright © 2007 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. SuSE makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Keith Packard, SuSE, Inc.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include "pixman-private.h"
-
-#include <stdlib.h>
-
-static pixman_implementation_t *global_implementation;
-
-#ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
-static void __attribute__((constructor))
-pixman_constructor (void)
-{
- global_implementation = _pixman_choose_implementation ();
-}
-#endif
-
-static force_inline pixman_implementation_t *
-get_implementation (void)
-{
-#ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
- if (!global_implementation)
- global_implementation = _pixman_choose_implementation ();
-#endif
- return global_implementation;
-}
-
-typedef struct operator_info_t operator_info_t;
-
-struct operator_info_t
-{
- uint8_t opaque_info[4];
-};
-
-#define PACK(neither, src, dest, both) \
- {{ (uint8_t)PIXMAN_OP_ ## neither, \
- (uint8_t)PIXMAN_OP_ ## src, \
- (uint8_t)PIXMAN_OP_ ## dest, \
- (uint8_t)PIXMAN_OP_ ## both }}
-
-static const operator_info_t operator_table[] =
-{
- /* Neither Opaque Src Opaque Dst Opaque Both Opaque */
- PACK (CLEAR, CLEAR, CLEAR, CLEAR),
- PACK (SRC, SRC, SRC, SRC),
- PACK (DST, DST, DST, DST),
- PACK (OVER, SRC, OVER, SRC),
- PACK (OVER_REVERSE, OVER_REVERSE, DST, DST),
- PACK (IN, IN, SRC, SRC),
- PACK (IN_REVERSE, DST, IN_REVERSE, DST),
- PACK (OUT, OUT, CLEAR, CLEAR),
- PACK (OUT_REVERSE, CLEAR, OUT_REVERSE, CLEAR),
- PACK (ATOP, IN, OVER, SRC),
- PACK (ATOP_REVERSE, OVER_REVERSE, IN_REVERSE, DST),
- PACK (XOR, OUT, OUT_REVERSE, CLEAR),
- PACK (ADD, ADD, ADD, ADD),
- PACK (SATURATE, OVER_REVERSE, DST, DST),
-
- {{ 0 /* 0x0e */ }},
- {{ 0 /* 0x0f */ }},
-
- PACK (CLEAR, CLEAR, CLEAR, CLEAR),
- PACK (SRC, SRC, SRC, SRC),
- PACK (DST, DST, DST, DST),
- PACK (DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER),
- PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
- PACK (DISJOINT_IN, DISJOINT_IN, DISJOINT_IN, DISJOINT_IN),
- PACK (DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE),
- PACK (DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT),
- PACK (DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE),
- PACK (DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP),
- PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
- PACK (DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR),
-
- {{ 0 /* 0x1c */ }},
- {{ 0 /* 0x1d */ }},
- {{ 0 /* 0x1e */ }},
- {{ 0 /* 0x1f */ }},
-
- PACK (CLEAR, CLEAR, CLEAR, CLEAR),
- PACK (SRC, SRC, SRC, SRC),
- PACK (DST, DST, DST, DST),
- PACK (CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER),
- PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
- PACK (CONJOINT_IN, CONJOINT_IN, CONJOINT_IN, CONJOINT_IN),
- PACK (CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE),
- PACK (CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT),
- PACK (CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE),
- PACK (CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP),
- PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
- PACK (CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR),
-
- {{ 0 /* 0x2c */ }},
- {{ 0 /* 0x2d */ }},
- {{ 0 /* 0x2e */ }},
- {{ 0 /* 0x2f */ }},
-
- PACK (MULTIPLY, MULTIPLY, MULTIPLY, MULTIPLY),
- PACK (SCREEN, SCREEN, SCREEN, SCREEN),
- PACK (OVERLAY, OVERLAY, OVERLAY, OVERLAY),
- PACK (DARKEN, DARKEN, DARKEN, DARKEN),
- PACK (LIGHTEN, LIGHTEN, LIGHTEN, LIGHTEN),
- PACK (COLOR_DODGE, COLOR_DODGE, COLOR_DODGE, COLOR_DODGE),
- PACK (COLOR_BURN, COLOR_BURN, COLOR_BURN, COLOR_BURN),
- PACK (HARD_LIGHT, HARD_LIGHT, HARD_LIGHT, HARD_LIGHT),
- PACK (SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT),
- PACK (DIFFERENCE, DIFFERENCE, DIFFERENCE, DIFFERENCE),
- PACK (EXCLUSION, EXCLUSION, EXCLUSION, EXCLUSION),
- PACK (HSL_HUE, HSL_HUE, HSL_HUE, HSL_HUE),
- PACK (HSL_SATURATION, HSL_SATURATION, HSL_SATURATION, HSL_SATURATION),
- PACK (HSL_COLOR, HSL_COLOR, HSL_COLOR, HSL_COLOR),
- PACK (HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY),
-};
-
-/*
- * Optimize the current operator based on opacity of source or destination
- * The output operator should be mathematically equivalent to the source.
- */
-static pixman_op_t
-optimize_operator (pixman_op_t op,
- uint32_t src_flags,
- uint32_t mask_flags,
- uint32_t dst_flags)
-{
- pixman_bool_t is_source_opaque, is_dest_opaque;
-
-#define OPAQUE_SHIFT 13
-
- COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
-
- is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
- is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
-
- is_dest_opaque >>= OPAQUE_SHIFT - 1;
- is_source_opaque >>= OPAQUE_SHIFT;
-
- return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
-}
-
-/*
- * Computing composite region
- */
-static inline pixman_bool_t
-clip_general_image (pixman_region32_t * region,
- pixman_region32_t * clip,
- int dx,
- int dy)
-{
- if (pixman_region32_n_rects (region) == 1 &&
- pixman_region32_n_rects (clip) == 1)
- {
- pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL);
- pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL);
- int v;
-
- if (rbox->x1 < (v = cbox->x1 + dx))
- rbox->x1 = v;
- if (rbox->x2 > (v = cbox->x2 + dx))
- rbox->x2 = v;
- if (rbox->y1 < (v = cbox->y1 + dy))
- rbox->y1 = v;
- if (rbox->y2 > (v = cbox->y2 + dy))
- rbox->y2 = v;
- if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
- {
- pixman_region32_init (region);
- return FALSE;
- }
- }
- else if (!pixman_region32_not_empty (clip))
- {
- return FALSE;
- }
- else
- {
- if (dx || dy)
- pixman_region32_translate (region, -dx, -dy);
-
- if (!pixman_region32_intersect (region, region, clip))
- return FALSE;
-
- if (dx || dy)
- pixman_region32_translate (region, dx, dy);
- }
-
- return pixman_region32_not_empty (region);
-}
-
-static inline pixman_bool_t
-clip_source_image (pixman_region32_t * region,
- pixman_image_t * image,
- int dx,
- int dy)
-{
- /* Source clips are ignored, unless they are explicitly turned on
- * and the clip in question was set by an X client. (Because if
- * the clip was not set by a client, then it is a hierarchy
- * clip and those should always be ignored for sources).
- */
- if (!image->common.clip_sources || !image->common.client_clip)
- return TRUE;
-
- return clip_general_image (region,
- &image->common.clip_region,
- dx, dy);
-}
-
-/*
- * returns FALSE if the final region is empty. Indistinguishable from
- * an allocation failure, but rendering ignores those anyways.
- */
-static pixman_bool_t
-pixman_compute_composite_region32 (pixman_region32_t * region,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- region->extents.x1 = dest_x;
- region->extents.x2 = dest_x + width;
- region->extents.y1 = dest_y;
- region->extents.y2 = dest_y + height;
-
- region->extents.x1 = MAX (region->extents.x1, 0);
- region->extents.y1 = MAX (region->extents.y1, 0);
- region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
- region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
-
- region->data = 0;
-
- /* Check for empty operation */
- if (region->extents.x1 >= region->extents.x2 ||
- region->extents.y1 >= region->extents.y2)
- {
- region->extents.x1 = 0;
- region->extents.x2 = 0;
- region->extents.y1 = 0;
- region->extents.y2 = 0;
- return FALSE;
- }
-
- if (dst_image->common.have_clip_region)
- {
- if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
- return FALSE;
- }
-
- if (dst_image->common.alpha_map)
- {
- if (!pixman_region32_intersect_rect (region, region,
- dst_image->common.alpha_origin_x,
- dst_image->common.alpha_origin_y,
- dst_image->common.alpha_map->width,
- dst_image->common.alpha_map->height))
- {
- return FALSE;
- }
- if (!pixman_region32_not_empty (region))
- return FALSE;
- if (dst_image->common.alpha_map->common.have_clip_region)
- {
- if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
- -dst_image->common.alpha_origin_x,
- -dst_image->common.alpha_origin_y))
- {
- return FALSE;
- }
- }
- }
-
- /* clip against src */
- if (src_image->common.have_clip_region)
- {
- if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
- return FALSE;
- }
- if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
- {
- if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
- dest_x - (src_x - src_image->common.alpha_origin_x),
- dest_y - (src_y - src_image->common.alpha_origin_y)))
- {
- return FALSE;
- }
- }
- /* clip against mask */
- if (mask_image && mask_image->common.have_clip_region)
- {
- if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
- return FALSE;
-
- if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
- {
- if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
- dest_x - (mask_x - mask_image->common.alpha_origin_x),
- dest_y - (mask_y - mask_image->common.alpha_origin_y)))
- {
- return FALSE;
- }
- }
- }
-
- return TRUE;
-}
-
-#define N_CACHED_FAST_PATHS 8
-
-typedef struct
-{
- struct
- {
- pixman_implementation_t * imp;
- pixman_fast_path_t fast_path;
- } cache [N_CACHED_FAST_PATHS];
-} cache_t;
-
-PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
-
-static force_inline pixman_bool_t
-lookup_composite_function (pixman_op_t op,
- pixman_format_code_t src_format,
- uint32_t src_flags,
- pixman_format_code_t mask_format,
- uint32_t mask_flags,
- pixman_format_code_t dest_format,
- uint32_t dest_flags,
- pixman_implementation_t **out_imp,
- pixman_composite_func_t *out_func)
-{
- pixman_implementation_t *imp;
- cache_t *cache;
- int i;
-
- /* Check cache for fast paths */
- cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
-
- for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
- {
- const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
-
- /* 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)
- {
- *out_imp = cache->cache[i].imp;
- *out_func = cache->cache[i].fast_path.func;
-
- goto update_cache;
- }
- }
-
- for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
- {
- const pixman_fast_path_t *info = imp->fast_paths;
-
- while (info->op != PIXMAN_OP_NONE)
- {
- if ((info->op == op || info->op == PIXMAN_OP_any) &&
- /* Formats */
- ((info->src_format == src_format) ||
- (info->src_format == PIXMAN_any)) &&
- ((info->mask_format == mask_format) ||
- (info->mask_format == PIXMAN_any)) &&
- ((info->dest_format == dest_format) ||
- (info->dest_format == PIXMAN_any)) &&
- /* Flags */
- (info->src_flags & src_flags) == info->src_flags &&
- (info->mask_flags & mask_flags) == info->mask_flags &&
- (info->dest_flags & dest_flags) == info->dest_flags)
- {
- *out_imp = imp;
- *out_func = info->func;
-
- /* Set i to the last spot in the cache so that the
- * move-to-front code below will work
- */
- i = N_CACHED_FAST_PATHS - 1;
-
- goto update_cache;
- }
-
- ++info;
- }
- }
- return FALSE;
-
-update_cache:
- if (i)
- {
- while (i--)
- cache->cache[i + 1] = cache->cache[i];
-
- cache->cache[0].imp = *out_imp;
- cache->cache[0].fast_path.op = op;
- cache->cache[0].fast_path.src_format = src_format;
- cache->cache[0].fast_path.src_flags = src_flags;
- cache->cache[0].fast_path.mask_format = mask_format;
- cache->cache[0].fast_path.mask_flags = mask_flags;
- cache->cache[0].fast_path.dest_format = dest_format;
- cache->cache[0].fast_path.dest_flags = dest_flags;
- cache->cache[0].fast_path.func = *out_func;
- }
-
- return TRUE;
-}
-
-static pixman_bool_t
-compute_sample_extents (pixman_transform_t *transform,
- pixman_box32_t *extents, int x, int y,
- pixman_fixed_t x_off, pixman_fixed_t y_off,
- pixman_fixed_t width, pixman_fixed_t height)
-{
- pixman_fixed_t x1, y1, x2, y2;
- pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
-
- /* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
- x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2;
- y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2;
- x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2;
- y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2;
-
- if (!transform)
- {
- tx1 = (pixman_fixed_48_16_t)x1;
- ty1 = (pixman_fixed_48_16_t)y1;
- tx2 = (pixman_fixed_48_16_t)x2;
- ty2 = (pixman_fixed_48_16_t)y2;
- }
- else
- {
- int i;
-
- /* Silence GCC */
- tx1 = ty1 = tx2 = ty2 = 0;
-
- for (i = 0; i < 4; ++i)
- {
- pixman_fixed_48_16_t tx, ty;
- pixman_vector_t v;
-
- v.vector[0] = (i & 0x01)? x1 : x2;
- v.vector[1] = (i & 0x02)? y1 : y2;
- v.vector[2] = pixman_fixed_1;
-
- if (!pixman_transform_point (transform, &v))
- return FALSE;
-
- tx = (pixman_fixed_48_16_t)v.vector[0];
- ty = (pixman_fixed_48_16_t)v.vector[1];
-
- if (i == 0)
- {
- tx1 = tx;
- ty1 = ty;
- tx2 = tx;
- ty2 = ty;
- }
- else
- {
- if (tx < tx1)
- tx1 = tx;
- if (ty < ty1)
- ty1 = ty;
- if (tx > tx2)
- tx2 = tx;
- if (ty > ty2)
- ty2 = ty;
- }
- }
- }
-
- /* Expand the source area by a tiny bit so account of different rounding that
- * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
- * 0.5 so this won't cause the area computed to be overly pessimistic.
- */
- tx1 += x_off - 8 * pixman_fixed_e;
- ty1 += y_off - 8 * pixman_fixed_e;
- tx2 += x_off + width + 8 * pixman_fixed_e;
- ty2 += y_off + height + 8 * pixman_fixed_e;
-
- if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
- ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
- tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
- ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
- {
- return FALSE;
- }
- else
- {
- extents->x1 = pixman_fixed_to_int (tx1);
- extents->y1 = pixman_fixed_to_int (ty1);
- extents->x2 = pixman_fixed_to_int (tx2) + 1;
- extents->y2 = pixman_fixed_to_int (ty2) + 1;
-
- return TRUE;
- }
-}
-
-#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
-
-static pixman_bool_t
-analyze_extent (pixman_image_t *image, int x, int y,
- const pixman_box32_t *extents, uint32_t *flags)
-{
- pixman_transform_t *transform;
- pixman_fixed_t *params;
- pixman_fixed_t x_off, y_off;
- pixman_fixed_t width, height;
- pixman_box32_t ex;
-
- if (!image)
- return TRUE;
-
- /* Some compositing functions walk one step
- * outside the destination rectangle, so we
- * check here that the expanded-by-one source
- * extents in destination space fits in 16 bits
- */
- if (!IS_16BIT (extents->x1 - x - 1) ||
- !IS_16BIT (extents->y1 - y - 1) ||
- !IS_16BIT (extents->x2 - x + 1) ||
- !IS_16BIT (extents->y2 - y + 1))
- {
- return FALSE;
- }
-
- transform = image->common.transform;
- if (image->common.type == BITS)
- {
- /* During repeat mode calculations we might convert the
- * width/height of an image to fixed 16.16, so we need
- * them to be smaller than 16 bits.
- */
- if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
- return FALSE;
-
-#define ID_AND_NEAREST (FAST_PATH_ID_TRANSFORM | FAST_PATH_NEAREST_FILTER)
-
- if ((image->common.flags & ID_AND_NEAREST) == ID_AND_NEAREST &&
- extents->x1 - x >= 0 &&
- extents->y1 - y >= 0 &&
- extents->x2 - x <= image->bits.width &&
- extents->y2 - y <= image->bits.height)
- {
- *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
- return TRUE;
- }
-
- switch (image->common.filter)
- {
- case PIXMAN_FILTER_CONVOLUTION:
- params = image->common.filter_params;
- x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
- y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
- width = params[0];
- height = params[1];
- break;
-
- case PIXMAN_FILTER_GOOD:
- case PIXMAN_FILTER_BEST:
- case PIXMAN_FILTER_BILINEAR:
- x_off = - pixman_fixed_1 / 2;
- y_off = - pixman_fixed_1 / 2;
- width = pixman_fixed_1;
- height = pixman_fixed_1;
- break;
-
- case PIXMAN_FILTER_FAST:
- case PIXMAN_FILTER_NEAREST:
- x_off = - pixman_fixed_e;
- y_off = - pixman_fixed_e;
- width = 0;
- height = 0;
- break;
-
- default:
- return FALSE;
- }
-
- /* Check whether the non-expanded, transformed extent is entirely within
- * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
- */
- ex = *extents;
- if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height) &&
- ex.x1 >= 0 && ex.y1 >= 0 &&
- ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
- {
- *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
- }
- }
- else
- {
- x_off = 0;
- y_off = 0;
- width = 0;
- height = 0;
- }
-
- /* Check that the extents expanded by one don't overflow. This ensures that
- * compositing functions can simply walk the source space using 16.16
- * variables without worrying about overflow.
- */
- ex.x1 = extents->x1 - 1;
- ex.y1 = extents->y1 - 1;
- ex.x2 = extents->x2 + 1;
- ex.y2 = extents->y2 + 1;
-
- if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
- return FALSE;
-
- return TRUE;
-}
-
-/*
- * Work around GCC bug causing crashes in Mozilla with SSE2
- *
- * When using -msse, gcc generates movdqa instructions assuming that
- * the stack is 16 byte aligned. Unfortunately some applications, such
- * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
- * causes the movdqa instructions to fail.
- *
- * The __force_align_arg_pointer__ makes gcc generate a prologue that
- * realigns the stack pointer to 16 bytes.
- *
- * On x86-64 this is not necessary because the standard ABI already
- * calls for a 16 byte aligned stack.
- *
- * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
- */
-#if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
-__attribute__((__force_align_arg_pointer__))
-#endif
-PIXMAN_EXPORT void
-pixman_image_composite32 (pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height)
-{
- pixman_format_code_t src_format, mask_format, dest_format;
- uint32_t src_flags, mask_flags, dest_flags;
- pixman_region32_t region;
- pixman_box32_t *extents;
- pixman_implementation_t *imp;
- pixman_composite_func_t func;
-
- _pixman_image_validate (src);
- if (mask)
- _pixman_image_validate (mask);
- _pixman_image_validate (dest);
-
- src_format = src->common.extended_format_code;
- src_flags = src->common.flags;
-
- if (mask)
- {
- mask_format = mask->common.extended_format_code;
- mask_flags = mask->common.flags;
- }
- else
- {
- mask_format = PIXMAN_null;
- mask_flags = FAST_PATH_IS_OPAQUE;
- }
-
- dest_format = dest->common.extended_format_code;
- dest_flags = dest->common.flags;
-
- /* Check for pixbufs */
- if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
- (src->type == BITS && src->bits.bits == mask->bits.bits) &&
- (src->common.repeat == mask->common.repeat) &&
- (src_x == mask_x && src_y == mask_y))
- {
- if (src_format == PIXMAN_x8b8g8r8)
- src_format = mask_format = PIXMAN_pixbuf;
- else if (src_format == PIXMAN_x8r8g8b8)
- src_format = mask_format = PIXMAN_rpixbuf;
- }
-
- pixman_region32_init (&region);
-
- if (!pixman_compute_composite_region32 (
- &region, src, mask, dest,
- src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
- {
- goto out;
- }
-
- extents = pixman_region32_extents (&region);
-
- if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
- goto out;
-
- if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
- goto out;
-
- /* If the clip is within the source samples, and the samples are opaque,
- * then the source is effectively opaque.
- */
-#define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
-
- if ((src_flags & BOTH) == BOTH)
- src_flags |= FAST_PATH_IS_OPAQUE;
-
- if ((mask_flags & BOTH) == BOTH)
- mask_flags |= FAST_PATH_IS_OPAQUE;
-
- /*
- * Check if we can replace our operator by a simpler one
- * if the src or dest are opaque. The output operator should be
- * mathematically equivalent to the source.
- */
- op = optimize_operator (op, src_flags, mask_flags, dest_flags);
- if (op == PIXMAN_OP_DST)
- goto out;
-
- if (lookup_composite_function (op,
- src_format, src_flags,
- mask_format, mask_flags,
- dest_format, dest_flags,
- &imp, &func))
- {
- const pixman_box32_t *pbox;
- int n;
-
- pbox = pixman_region32_rectangles (&region, &n);
-
- while (n--)
- {
- func (imp, op,
- src, mask, dest,
- pbox->x1 + src_x - dest_x,
- pbox->y1 + src_y - dest_y,
- pbox->x1 + mask_x - dest_x,
- pbox->y1 + mask_y - dest_y,
- pbox->x1,
- pbox->y1,
- pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
-
- pbox++;
- }
- }
-
-out:
- pixman_region32_fini (&region);
-}
-
-PIXMAN_EXPORT void
-pixman_image_composite (pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * mask,
- pixman_image_t * dest,
- int16_t src_x,
- int16_t src_y,
- int16_t mask_x,
- int16_t mask_y,
- int16_t dest_x,
- int16_t dest_y,
- uint16_t width,
- uint16_t height)
-{
- pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
- mask_x, mask_y, dest_x, dest_y, width, height);
-}
-
-PIXMAN_EXPORT pixman_bool_t
-pixman_blt (uint32_t *src_bits,
- uint32_t *dst_bits,
- int src_stride,
- int dst_stride,
- int src_bpp,
- int dst_bpp,
- int src_x,
- int src_y,
- int dst_x,
- int dst_y,
- int width,
- int height)
-{
- return _pixman_implementation_blt (get_implementation(),
- src_bits, dst_bits, src_stride, dst_stride,
- src_bpp, dst_bpp,
- src_x, src_y,
- dst_x, dst_y,
- width, height);
-}
-
-PIXMAN_EXPORT pixman_bool_t
-pixman_fill (uint32_t *bits,
- int stride,
- int bpp,
- int x,
- int y,
- int width,
- int height,
- uint32_t xor)
-{
- return _pixman_implementation_fill (
- get_implementation(), bits, stride, bpp, x, y, width, height, xor);
-}
-
-static uint32_t
-color_to_uint32 (const pixman_color_t *color)
-{
- return
- (color->alpha >> 8 << 24) |
- (color->red >> 8 << 16) |
- (color->green & 0xff00) |
- (color->blue >> 8);
-}
-
-static pixman_bool_t
-color_to_pixel (pixman_color_t * color,
- uint32_t * pixel,
- pixman_format_code_t format)
-{
- uint32_t c = color_to_uint32 (color);
-
- if (!(format == PIXMAN_a8r8g8b8 ||
- format == PIXMAN_x8r8g8b8 ||
- format == PIXMAN_a8b8g8r8 ||
- format == PIXMAN_x8b8g8r8 ||
- format == PIXMAN_b8g8r8a8 ||
- format == PIXMAN_b8g8r8x8 ||
- format == PIXMAN_r5g6b5 ||
- format == PIXMAN_b5g6r5 ||
- format == PIXMAN_a8 ||
- format == PIXMAN_a1))
- {
- return FALSE;
- }
-
- if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
- {
- c = ((c & 0xff000000) >> 0) |
- ((c & 0x00ff0000) >> 16) |
- ((c & 0x0000ff00) >> 0) |
- ((c & 0x000000ff) << 16);
- }
- if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
- {
- c = ((c & 0xff000000) >> 24) |
- ((c & 0x00ff0000) >> 8) |
- ((c & 0x0000ff00) << 8) |
- ((c & 0x000000ff) << 24);
- }
-
- if (format == PIXMAN_a1)
- c = c >> 31;
- else if (format == PIXMAN_a8)
- c = c >> 24;
- else if (format == PIXMAN_r5g6b5 ||
- format == PIXMAN_b5g6r5)
- c = CONVERT_8888_TO_0565 (c);
-
-#if 0
- printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
- printf ("pixel: %x\n", c);
-#endif
-
- *pixel = c;
- return TRUE;
-}
-
-PIXMAN_EXPORT pixman_bool_t
-pixman_image_fill_rectangles (pixman_op_t op,
- pixman_image_t * dest,
- pixman_color_t * color,
- int n_rects,
- const pixman_rectangle16_t *rects)
-{
- pixman_box32_t stack_boxes[6];
- pixman_box32_t *boxes;
- pixman_bool_t result;
- int i;
-
- if (n_rects > 6)
- {
- boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
- if (boxes == NULL)
- return FALSE;
- }
- else
- {
- boxes = stack_boxes;
- }
-
- for (i = 0; i < n_rects; ++i)
- {
- boxes[i].x1 = rects[i].x;
- boxes[i].y1 = rects[i].y;
- boxes[i].x2 = boxes[i].x1 + rects[i].width;
- boxes[i].y2 = boxes[i].y1 + rects[i].height;
- }
-
- result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
-
- if (boxes != stack_boxes)
- free (boxes);
-
- return result;
-}
-
-PIXMAN_EXPORT pixman_bool_t
-pixman_image_fill_boxes (pixman_op_t op,
- pixman_image_t * dest,
- pixman_color_t * color,
- int n_boxes,
- const pixman_box32_t *boxes)
-{
- pixman_image_t *solid;
- pixman_color_t c;
- int i;
-
- _pixman_image_validate (dest);
-
- if (color->alpha == 0xffff)
- {
- if (op == PIXMAN_OP_OVER)
- op = PIXMAN_OP_SRC;
- }
-
- if (op == PIXMAN_OP_CLEAR)
- {
- c.red = 0;
- c.green = 0;
- c.blue = 0;
- c.alpha = 0;
-
- color = &c;
-
- op = PIXMAN_OP_SRC;
- }
-
- if (op == PIXMAN_OP_SRC)
- {
- uint32_t pixel;
-
- if (color_to_pixel (color, &pixel, dest->bits.format))
- {
- pixman_region32_t fill_region;
- int n_rects, j;
- pixman_box32_t *rects;
-
- if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
- return FALSE;
-
- if (dest->common.have_clip_region)
- {
- if (!pixman_region32_intersect (&fill_region,
- &fill_region,
- &dest->common.clip_region))
- return FALSE;
- }
-
- rects = pixman_region32_rectangles (&fill_region, &n_rects);
- for (j = 0; j < n_rects; ++j)
- {
- const pixman_box32_t *rect = &(rects[j]);
- pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
- rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
- pixel);
- }
-
- pixman_region32_fini (&fill_region);
- return TRUE;
- }
- }
-
- solid = pixman_image_create_solid_fill (color);
- if (!solid)
- return FALSE;
-
- for (i = 0; i < n_boxes; ++i)
- {
- const pixman_box32_t *box = &(boxes[i]);
-
- pixman_image_composite32 (op, solid, NULL, dest,
- 0, 0, 0, 0,
- box->x1, box->y1,
- box->x2 - box->x1, box->y2 - box->y1);
- }
-
- pixman_image_unref (solid);
-
- return TRUE;
-}
-
-/**
- * pixman_version:
- *
- * Returns the version of the pixman library encoded in a single
- * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
- * later versions compare greater than earlier versions.
- *
- * A run-time comparison to check that pixman's version is greater than
- * or equal to version X.Y.Z could be performed as follows:
- *
- * <informalexample><programlisting>
- * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
- * </programlisting></informalexample>
- *
- * See also pixman_version_string() as well as the compile-time
- * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
- *
- * Return value: the encoded version.
- **/
-PIXMAN_EXPORT int
-pixman_version (void)
-{
- return PIXMAN_VERSION;
-}
-
-/**
- * pixman_version_string:
- *
- * Returns the version of the pixman library as a human-readable string
- * of the form "X.Y.Z".
- *
- * See also pixman_version() as well as the compile-time equivalents
- * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
- *
- * Return value: a string containing the version.
- **/
-PIXMAN_EXPORT const char*
-pixman_version_string (void)
-{
- return PIXMAN_VERSION_STRING;
-}
-
-/**
- * pixman_format_supported_source:
- * @format: A pixman_format_code_t format
- *
- * Return value: whether the provided format code is a supported
- * format for a pixman surface used as a source in
- * rendering.
- *
- * Currently, all pixman_format_code_t values are supported.
- **/
-PIXMAN_EXPORT pixman_bool_t
-pixman_format_supported_source (pixman_format_code_t format)
-{
- switch (format)
- {
- /* 32 bpp formats */
- case PIXMAN_a2b10g10r10:
- case PIXMAN_x2b10g10r10:
- case PIXMAN_a2r10g10b10:
- case PIXMAN_x2r10g10b10:
- case PIXMAN_a8r8g8b8:
- case PIXMAN_x8r8g8b8:
- case PIXMAN_a8b8g8r8:
- case PIXMAN_x8b8g8r8:
- case PIXMAN_b8g8r8a8:
- case PIXMAN_b8g8r8x8:
- case PIXMAN_r8g8b8:
- case PIXMAN_b8g8r8:
- case PIXMAN_r5g6b5:
- case PIXMAN_b5g6r5:
- case PIXMAN_x14r6g6b6:
- /* 16 bpp formats */
- case PIXMAN_a1r5g5b5:
- case PIXMAN_x1r5g5b5:
- case PIXMAN_a1b5g5r5:
- case PIXMAN_x1b5g5r5:
- case PIXMAN_a4r4g4b4:
- case PIXMAN_x4r4g4b4:
- case PIXMAN_a4b4g4r4:
- case PIXMAN_x4b4g4r4:
- /* 8bpp formats */
- case PIXMAN_a8:
- case PIXMAN_r3g3b2:
- case PIXMAN_b2g3r3:
- case PIXMAN_a2r2g2b2:
- case PIXMAN_a2b2g2r2:
- case PIXMAN_c8:
- case PIXMAN_g8:
- case PIXMAN_x4a4:
- /* Collides with PIXMAN_c8
- case PIXMAN_x4c4:
- */
- /* Collides with PIXMAN_g8
- case PIXMAN_x4g4:
- */
- /* 4bpp formats */
- case PIXMAN_a4:
- case PIXMAN_r1g2b1:
- case PIXMAN_b1g2r1:
- case PIXMAN_a1r1g1b1:
- case PIXMAN_a1b1g1r1:
- case PIXMAN_c4:
- case PIXMAN_g4:
- /* 1bpp formats */
- case PIXMAN_a1:
- case PIXMAN_g1:
- /* YUV formats */
- case PIXMAN_yuy2:
- case PIXMAN_yv12:
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
-/**
- * pixman_format_supported_destination:
- * @format: A pixman_format_code_t format
- *
- * Return value: whether the provided format code is a supported
- * format for a pixman surface used as a destination in
- * rendering.
- *
- * Currently, all pixman_format_code_t values are supported
- * except for the YUV formats.
- **/
-PIXMAN_EXPORT pixman_bool_t
-pixman_format_supported_destination (pixman_format_code_t format)
-{
- /* YUV formats cannot be written to at the moment */
- if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
- return FALSE;
-
- return pixman_format_supported_source (format);
-}
-
-PIXMAN_EXPORT pixman_bool_t
-pixman_compute_composite_region (pixman_region16_t * region,
- pixman_image_t * src_image,
- pixman_image_t * mask_image,
- pixman_image_t * dst_image,
- int16_t src_x,
- int16_t src_y,
- int16_t mask_x,
- int16_t mask_y,
- int16_t dest_x,
- int16_t dest_y,
- uint16_t width,
- uint16_t height)
-{
- pixman_region32_t r32;
- pixman_bool_t retval;
-
- pixman_region32_init (&r32);
-
- retval = pixman_compute_composite_region32 (
- &r32, src_image, mask_image, dst_image,
- src_x, src_y, mask_x, mask_y, dest_x, dest_y,
- width, height);
-
- if (retval)
- {
- if (!pixman_region16_copy_from_region32 (region, &r32))
- retval = FALSE;
- }
-
- pixman_region32_fini (&r32);
- return retval;
-}
+/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
+/*
+ * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "pixman-private.h"
+
+#include <stdlib.h>
+
+static pixman_implementation_t *global_implementation;
+
+#ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
+static void __attribute__((constructor))
+pixman_constructor (void)
+{
+ global_implementation = _pixman_choose_implementation ();
+}
+#endif
+
+static force_inline pixman_implementation_t *
+get_implementation (void)
+{
+#ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
+ if (!global_implementation)
+ global_implementation = _pixman_choose_implementation ();
+#endif
+ return global_implementation;
+}
+
+typedef struct operator_info_t operator_info_t;
+
+struct operator_info_t
+{
+ uint8_t opaque_info[4];
+};
+
+#define PACK(neither, src, dest, both) \
+ {{ (uint8_t)PIXMAN_OP_ ## neither, \
+ (uint8_t)PIXMAN_OP_ ## src, \
+ (uint8_t)PIXMAN_OP_ ## dest, \
+ (uint8_t)PIXMAN_OP_ ## both }}
+
+static const operator_info_t operator_table[] =
+{
+ /* Neither Opaque Src Opaque Dst Opaque Both Opaque */
+ PACK (CLEAR, CLEAR, CLEAR, CLEAR),
+ PACK (SRC, SRC, SRC, SRC),
+ PACK (DST, DST, DST, DST),
+ PACK (OVER, SRC, OVER, SRC),
+ PACK (OVER_REVERSE, OVER_REVERSE, DST, DST),
+ PACK (IN, IN, SRC, SRC),
+ PACK (IN_REVERSE, DST, IN_REVERSE, DST),
+ PACK (OUT, OUT, CLEAR, CLEAR),
+ PACK (OUT_REVERSE, CLEAR, OUT_REVERSE, CLEAR),
+ PACK (ATOP, IN, OVER, SRC),
+ PACK (ATOP_REVERSE, OVER_REVERSE, IN_REVERSE, DST),
+ PACK (XOR, OUT, OUT_REVERSE, CLEAR),
+ PACK (ADD, ADD, ADD, ADD),
+ PACK (SATURATE, OVER_REVERSE, DST, DST),
+
+ {{ 0 /* 0x0e */ }},
+ {{ 0 /* 0x0f */ }},
+
+ PACK (CLEAR, CLEAR, CLEAR, CLEAR),
+ PACK (SRC, SRC, SRC, SRC),
+ PACK (DST, DST, DST, DST),
+ PACK (DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER),
+ PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE),
+ PACK (DISJOINT_IN, DISJOINT_IN, DISJOINT_IN, DISJOINT_IN),
+ PACK (DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE),
+ PACK (DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT),
+ PACK (DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE),
+ PACK (DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP),
+ PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE),
+ PACK (DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR),
+
+ {{ 0 /* 0x1c */ }},
+ {{ 0 /* 0x1d */ }},
+ {{ 0 /* 0x1e */ }},
+ {{ 0 /* 0x1f */ }},
+
+ PACK (CLEAR, CLEAR, CLEAR, CLEAR),
+ PACK (SRC, SRC, SRC, SRC),
+ PACK (DST, DST, DST, DST),
+ PACK (CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER),
+ PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE),
+ PACK (CONJOINT_IN, CONJOINT_IN, CONJOINT_IN, CONJOINT_IN),
+ PACK (CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE),
+ PACK (CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT),
+ PACK (CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE),
+ PACK (CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP),
+ PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE),
+ PACK (CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR),
+
+ {{ 0 /* 0x2c */ }},
+ {{ 0 /* 0x2d */ }},
+ {{ 0 /* 0x2e */ }},
+ {{ 0 /* 0x2f */ }},
+
+ PACK (MULTIPLY, MULTIPLY, MULTIPLY, MULTIPLY),
+ PACK (SCREEN, SCREEN, SCREEN, SCREEN),
+ PACK (OVERLAY, OVERLAY, OVERLAY, OVERLAY),
+ PACK (DARKEN, DARKEN, DARKEN, DARKEN),
+ PACK (LIGHTEN, LIGHTEN, LIGHTEN, LIGHTEN),
+ PACK (COLOR_DODGE, COLOR_DODGE, COLOR_DODGE, COLOR_DODGE),
+ PACK (COLOR_BURN, COLOR_BURN, COLOR_BURN, COLOR_BURN),
+ PACK (HARD_LIGHT, HARD_LIGHT, HARD_LIGHT, HARD_LIGHT),
+ PACK (SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT),
+ PACK (DIFFERENCE, DIFFERENCE, DIFFERENCE, DIFFERENCE),
+ PACK (EXCLUSION, EXCLUSION, EXCLUSION, EXCLUSION),
+ PACK (HSL_HUE, HSL_HUE, HSL_HUE, HSL_HUE),
+ PACK (HSL_SATURATION, HSL_SATURATION, HSL_SATURATION, HSL_SATURATION),
+ PACK (HSL_COLOR, HSL_COLOR, HSL_COLOR, HSL_COLOR),
+ PACK (HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY),
+};
+
+/*
+ * Optimize the current operator based on opacity of source or destination
+ * The output operator should be mathematically equivalent to the source.
+ */
+static pixman_op_t
+optimize_operator (pixman_op_t op,
+ uint32_t src_flags,
+ uint32_t mask_flags,
+ uint32_t dst_flags)
+{
+ pixman_bool_t is_source_opaque, is_dest_opaque;
+
+#define OPAQUE_SHIFT 13
+
+ COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT));
+
+ is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE);
+ is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE);
+
+ is_dest_opaque >>= OPAQUE_SHIFT - 1;
+ is_source_opaque >>= OPAQUE_SHIFT;
+
+ return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
+}
+
+/*
+ * Computing composite region
+ */
+static inline pixman_bool_t
+clip_general_image (pixman_region32_t * region,
+ pixman_region32_t * clip,
+ int dx,
+ int dy)
+{
+ if (pixman_region32_n_rects (region) == 1 &&
+ pixman_region32_n_rects (clip) == 1)
+ {
+ pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL);
+ pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL);
+ int v;
+
+ if (rbox->x1 < (v = cbox->x1 + dx))
+ rbox->x1 = v;
+ if (rbox->x2 > (v = cbox->x2 + dx))
+ rbox->x2 = v;
+ if (rbox->y1 < (v = cbox->y1 + dy))
+ rbox->y1 = v;
+ if (rbox->y2 > (v = cbox->y2 + dy))
+ rbox->y2 = v;
+ if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2)
+ {
+ pixman_region32_init (region);
+ return FALSE;
+ }
+ }
+ else if (!pixman_region32_not_empty (clip))
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (dx || dy)
+ pixman_region32_translate (region, -dx, -dy);
+
+ if (!pixman_region32_intersect (region, region, clip))
+ return FALSE;
+
+ if (dx || dy)
+ pixman_region32_translate (region, dx, dy);
+ }
+
+ return pixman_region32_not_empty (region);
+}
+
+static inline pixman_bool_t
+clip_source_image (pixman_region32_t * region,
+ pixman_image_t * image,
+ int dx,
+ int dy)
+{
+ /* Source clips are ignored, unless they are explicitly turned on
+ * and the clip in question was set by an X client. (Because if
+ * the clip was not set by a client, then it is a hierarchy
+ * clip and those should always be ignored for sources).
+ */
+ if (!image->common.clip_sources || !image->common.client_clip)
+ return TRUE;
+
+ return clip_general_image (region,
+ &image->common.clip_region,
+ dx, dy);
+}
+
+/*
+ * returns FALSE if the final region is empty. Indistinguishable from
+ * an allocation failure, but rendering ignores those anyways.
+ */
+static pixman_bool_t
+pixman_compute_composite_region32 (pixman_region32_t * region,
+ pixman_image_t * src_image,
+ pixman_image_t * mask_image,
+ pixman_image_t * dst_image,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t mask_x,
+ int32_t mask_y,
+ int32_t dest_x,
+ int32_t dest_y,
+ int32_t width,
+ int32_t height)
+{
+ region->extents.x1 = dest_x;
+ region->extents.x2 = dest_x + width;
+ region->extents.y1 = dest_y;
+ region->extents.y2 = dest_y + height;
+
+ region->extents.x1 = MAX (region->extents.x1, 0);
+ region->extents.y1 = MAX (region->extents.y1, 0);
+ region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
+ region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
+
+ region->data = 0;
+
+ /* Check for empty operation */
+ if (region->extents.x1 >= region->extents.x2 ||
+ region->extents.y1 >= region->extents.y2)
+ {
+ region->extents.x1 = 0;
+ region->extents.x2 = 0;
+ region->extents.y1 = 0;
+ region->extents.y2 = 0;
+ return FALSE;
+ }
+
+ if (dst_image->common.have_clip_region)
+ {
+ if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
+ return FALSE;
+ }
+
+ if (dst_image->common.alpha_map)
+ {
+ if (!pixman_region32_intersect_rect (region, region,
+ dst_image->common.alpha_origin_x,
+ dst_image->common.alpha_origin_y,
+ dst_image->common.alpha_map->width,
+ dst_image->common.alpha_map->height))
+ {
+ return FALSE;
+ }
+ if (!pixman_region32_not_empty (region))
+ return FALSE;
+ if (dst_image->common.alpha_map->common.have_clip_region)
+ {
+ if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
+ -dst_image->common.alpha_origin_x,
+ -dst_image->common.alpha_origin_y))
+ {
+ return FALSE;
+ }
+ }
+ }
+
+ /* clip against src */
+ if (src_image->common.have_clip_region)
+ {
+ if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y))
+ return FALSE;
+ }
+ if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region)
+ {
+ if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map,
+ dest_x - (src_x - src_image->common.alpha_origin_x),
+ dest_y - (src_y - src_image->common.alpha_origin_y)))
+ {
+ return FALSE;
+ }
+ }
+ /* clip against mask */
+ if (mask_image && mask_image->common.have_clip_region)
+ {
+ if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y))
+ return FALSE;
+
+ if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region)
+ {
+ if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map,
+ dest_x - (mask_x - mask_image->common.alpha_origin_x),
+ dest_y - (mask_y - mask_image->common.alpha_origin_y)))
+ {
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+#define N_CACHED_FAST_PATHS 8
+
+typedef struct
+{
+ struct
+ {
+ pixman_implementation_t * imp;
+ pixman_fast_path_t fast_path;
+ } cache [N_CACHED_FAST_PATHS];
+} cache_t;
+
+PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
+
+static force_inline pixman_bool_t
+lookup_composite_function (pixman_op_t op,
+ pixman_format_code_t src_format,
+ uint32_t src_flags,
+ pixman_format_code_t mask_format,
+ uint32_t mask_flags,
+ pixman_format_code_t dest_format,
+ uint32_t dest_flags,
+ pixman_implementation_t **out_imp,
+ pixman_composite_func_t *out_func)
+{
+ pixman_implementation_t *imp;
+ cache_t *cache;
+ int i;
+
+ /* Check cache for fast paths */
+ cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
+
+ for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
+ {
+ const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
+
+ /* 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)
+ {
+ *out_imp = cache->cache[i].imp;
+ *out_func = cache->cache[i].fast_path.func;
+
+ goto update_cache;
+ }
+ }
+
+ for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
+ {
+ const pixman_fast_path_t *info = imp->fast_paths;
+
+ while (info->op != PIXMAN_OP_NONE)
+ {
+ if ((info->op == op || info->op == PIXMAN_OP_any) &&
+ /* Formats */
+ ((info->src_format == src_format) ||
+ (info->src_format == PIXMAN_any)) &&
+ ((info->mask_format == mask_format) ||
+ (info->mask_format == PIXMAN_any)) &&
+ ((info->dest_format == dest_format) ||
+ (info->dest_format == PIXMAN_any)) &&
+ /* Flags */
+ (info->src_flags & src_flags) == info->src_flags &&
+ (info->mask_flags & mask_flags) == info->mask_flags &&
+ (info->dest_flags & dest_flags) == info->dest_flags)
+ {
+ *out_imp = imp;
+ *out_func = info->func;
+
+ /* Set i to the last spot in the cache so that the
+ * move-to-front code below will work
+ */
+ i = N_CACHED_FAST_PATHS - 1;
+
+ goto update_cache;
+ }
+
+ ++info;
+ }
+ }
+ return FALSE;
+
+update_cache:
+ if (i)
+ {
+ while (i--)
+ cache->cache[i + 1] = cache->cache[i];
+
+ cache->cache[0].imp = *out_imp;
+ cache->cache[0].fast_path.op = op;
+ cache->cache[0].fast_path.src_format = src_format;
+ cache->cache[0].fast_path.src_flags = src_flags;
+ cache->cache[0].fast_path.mask_format = mask_format;
+ cache->cache[0].fast_path.mask_flags = mask_flags;
+ cache->cache[0].fast_path.dest_format = dest_format;
+ cache->cache[0].fast_path.dest_flags = dest_flags;
+ cache->cache[0].fast_path.func = *out_func;
+ }
+
+ return TRUE;
+}
+
+static pixman_bool_t
+compute_sample_extents (pixman_transform_t *transform,
+ pixman_box32_t *extents, int x, int y,
+ pixman_fixed_t x_off, pixman_fixed_t y_off,
+ pixman_fixed_t width, pixman_fixed_t height)
+{
+ pixman_fixed_t x1, y1, x2, y2;
+ pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
+
+ /* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
+ x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2;
+ y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2;
+ x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2;
+ y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2;
+
+ if (!transform)
+ {
+ tx1 = (pixman_fixed_48_16_t)x1;
+ ty1 = (pixman_fixed_48_16_t)y1;
+ tx2 = (pixman_fixed_48_16_t)x2;
+ ty2 = (pixman_fixed_48_16_t)y2;
+ }
+ else
+ {
+ int i;
+
+ /* Silence GCC */
+ tx1 = ty1 = tx2 = ty2 = 0;
+
+ for (i = 0; i < 4; ++i)
+ {
+ pixman_fixed_48_16_t tx, ty;
+ pixman_vector_t v;
+
+ v.vector[0] = (i & 0x01)? x1 : x2;
+ v.vector[1] = (i & 0x02)? y1 : y2;
+ v.vector[2] = pixman_fixed_1;
+
+ if (!pixman_transform_point (transform, &v))
+ return FALSE;
+
+ tx = (pixman_fixed_48_16_t)v.vector[0];
+ ty = (pixman_fixed_48_16_t)v.vector[1];
+
+ if (i == 0)
+ {
+ tx1 = tx;
+ ty1 = ty;
+ tx2 = tx;
+ ty2 = ty;
+ }
+ else
+ {
+ if (tx < tx1)
+ tx1 = tx;
+ if (ty < ty1)
+ ty1 = ty;
+ if (tx > tx2)
+ tx2 = tx;
+ if (ty > ty2)
+ ty2 = ty;
+ }
+ }
+ }
+
+ /* Expand the source area by a tiny bit so account of different rounding that
+ * may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
+ * 0.5 so this won't cause the area computed to be overly pessimistic.
+ */
+ tx1 += x_off - 8 * pixman_fixed_e;
+ ty1 += y_off - 8 * pixman_fixed_e;
+ tx2 += x_off + width + 8 * pixman_fixed_e;
+ ty2 += y_off + height + 8 * pixman_fixed_e;
+
+ if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
+ ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
+ tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
+ ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
+ {
+ return FALSE;
+ }
+ else
+ {
+ extents->x1 = pixman_fixed_to_int (tx1);
+ extents->y1 = pixman_fixed_to_int (ty1);
+ extents->x2 = pixman_fixed_to_int (tx2) + 1;
+ extents->y2 = pixman_fixed_to_int (ty2) + 1;
+
+ return TRUE;
+ }
+}
+
+#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
+
+static pixman_bool_t
+analyze_extent (pixman_image_t *image, int x, int y,
+ const pixman_box32_t *extents, uint32_t *flags)
+{
+ pixman_transform_t *transform;
+ pixman_fixed_t *params;
+ pixman_fixed_t x_off, y_off;
+ pixman_fixed_t width, height;
+ pixman_box32_t ex;
+
+ if (!image)
+ return TRUE;
+
+ /* Some compositing functions walk one step
+ * outside the destination rectangle, so we
+ * check here that the expanded-by-one source
+ * extents in destination space fits in 16 bits
+ */
+ if (!IS_16BIT (extents->x1 - x - 1) ||
+ !IS_16BIT (extents->y1 - y - 1) ||
+ !IS_16BIT (extents->x2 - x + 1) ||
+ !IS_16BIT (extents->y2 - y + 1))
+ {
+ return FALSE;
+ }
+
+ transform = image->common.transform;
+ if (image->common.type == BITS)
+ {
+ /* During repeat mode calculations we might convert the
+ * width/height of an image to fixed 16.16, so we need
+ * them to be smaller than 16 bits.
+ */
+ if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
+ return FALSE;
+
+#define ID_AND_NEAREST (FAST_PATH_ID_TRANSFORM | FAST_PATH_NEAREST_FILTER)
+
+ if ((image->common.flags & ID_AND_NEAREST) == ID_AND_NEAREST &&
+ extents->x1 - x >= 0 &&
+ extents->y1 - y >= 0 &&
+ extents->x2 - x <= image->bits.width &&
+ extents->y2 - y <= image->bits.height)
+ {
+ *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
+ return TRUE;
+ }
+
+ switch (image->common.filter)
+ {
+ case PIXMAN_FILTER_CONVOLUTION:
+ params = image->common.filter_params;
+ x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1);
+ y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1);
+ width = params[0];
+ height = params[1];
+ break;
+
+ case PIXMAN_FILTER_GOOD:
+ case PIXMAN_FILTER_BEST:
+ case PIXMAN_FILTER_BILINEAR:
+ x_off = - pixman_fixed_1 / 2;
+ y_off = - pixman_fixed_1 / 2;
+ width = pixman_fixed_1;
+ height = pixman_fixed_1;
+ break;
+
+ case PIXMAN_FILTER_FAST:
+ case PIXMAN_FILTER_NEAREST:
+ x_off = - pixman_fixed_e;
+ y_off = - pixman_fixed_e;
+ width = 0;
+ height = 0;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ /* Check whether the non-expanded, transformed extent is entirely within
+ * the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
+ */
+ ex = *extents;
+ if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height) &&
+ ex.x1 >= 0 && ex.y1 >= 0 &&
+ ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
+ {
+ *flags |= FAST_PATH_SAMPLES_COVER_CLIP;
+ }
+ }
+ else
+ {
+ x_off = 0;
+ y_off = 0;
+ width = 0;
+ height = 0;
+ }
+
+ /* Check that the extents expanded by one don't overflow. This ensures that
+ * compositing functions can simply walk the source space using 16.16
+ * variables without worrying about overflow.
+ */
+ ex.x1 = extents->x1 - 1;
+ ex.y1 = extents->y1 - 1;
+ ex.x2 = extents->x2 + 1;
+ ex.y2 = extents->y2 + 1;
+
+ if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * Work around GCC bug causing crashes in Mozilla with SSE2
+ *
+ * When using -msse, gcc generates movdqa instructions assuming that
+ * the stack is 16 byte aligned. Unfortunately some applications, such
+ * as Mozilla and Mono, end up aligning the stack to 4 bytes, which
+ * causes the movdqa instructions to fail.
+ *
+ * The __force_align_arg_pointer__ makes gcc generate a prologue that
+ * realigns the stack pointer to 16 bytes.
+ *
+ * On x86-64 this is not necessary because the standard ABI already
+ * calls for a 16 byte aligned stack.
+ *
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=15693
+ */
+#if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
+__attribute__((__force_align_arg_pointer__))
+#endif
+PIXMAN_EXPORT void
+pixman_image_composite32 (pixman_op_t op,
+ pixman_image_t * src,
+ pixman_image_t * mask,
+ pixman_image_t * dest,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t mask_x,
+ int32_t mask_y,
+ int32_t dest_x,
+ int32_t dest_y,
+ int32_t width,
+ int32_t height)
+{
+ pixman_format_code_t src_format, mask_format, dest_format;
+ uint32_t src_flags, mask_flags, dest_flags;
+ pixman_region32_t region;
+ pixman_box32_t *extents;
+ pixman_implementation_t *imp;
+ pixman_composite_func_t func;
+
+ _pixman_image_validate (src);
+ if (mask)
+ _pixman_image_validate (mask);
+ _pixman_image_validate (dest);
+
+ src_format = src->common.extended_format_code;
+ src_flags = src->common.flags;
+
+ if (mask)
+ {
+ mask_format = mask->common.extended_format_code;
+ mask_flags = mask->common.flags;
+ }
+ else
+ {
+ mask_format = PIXMAN_null;
+ mask_flags = FAST_PATH_IS_OPAQUE;
+ }
+
+ dest_format = dest->common.extended_format_code;
+ dest_flags = dest->common.flags;
+
+ /* Check for pixbufs */
+ if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) &&
+ (src->type == BITS && src->bits.bits == mask->bits.bits) &&
+ (src->common.repeat == mask->common.repeat) &&
+ (src_x == mask_x && src_y == mask_y))
+ {
+ if (src_format == PIXMAN_x8b8g8r8)
+ src_format = mask_format = PIXMAN_pixbuf;
+ else if (src_format == PIXMAN_x8r8g8b8)
+ src_format = mask_format = PIXMAN_rpixbuf;
+ }
+
+ pixman_region32_init (&region);
+
+ if (!pixman_compute_composite_region32 (
+ &region, src, mask, dest,
+ src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
+ {
+ goto out;
+ }
+
+ extents = pixman_region32_extents (&region);
+
+ if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
+ goto out;
+
+ if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
+ goto out;
+
+ /* If the clip is within the source samples, and the samples are opaque,
+ * then the source is effectively opaque.
+ */
+#define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
+
+ if ((src_flags & BOTH) == BOTH)
+ src_flags |= FAST_PATH_IS_OPAQUE;
+
+ if ((mask_flags & BOTH) == BOTH)
+ mask_flags |= FAST_PATH_IS_OPAQUE;
+
+ /*
+ * Check if we can replace our operator by a simpler one
+ * if the src or dest are opaque. The output operator should be
+ * mathematically equivalent to the source.
+ */
+ op = optimize_operator (op, src_flags, mask_flags, dest_flags);
+ if (op == PIXMAN_OP_DST)
+ goto out;
+
+ if (lookup_composite_function (op,
+ src_format, src_flags,
+ mask_format, mask_flags,
+ dest_format, dest_flags,
+ &imp, &func))
+ {
+ const pixman_box32_t *pbox;
+ int n;
+
+ pbox = pixman_region32_rectangles (&region, &n);
+
+ while (n--)
+ {
+ func (imp, op,
+ src, mask, dest,
+ pbox->x1 + src_x - dest_x,
+ pbox->y1 + src_y - dest_y,
+ pbox->x1 + mask_x - dest_x,
+ pbox->y1 + mask_y - dest_y,
+ pbox->x1,
+ pbox->y1,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+
+ pbox++;
+ }
+ }
+
+out:
+ pixman_region32_fini (&region);
+}
+
+PIXMAN_EXPORT void
+pixman_image_composite (pixman_op_t op,
+ pixman_image_t * src,
+ pixman_image_t * mask,
+ pixman_image_t * dest,
+ int16_t src_x,
+ int16_t src_y,
+ int16_t mask_x,
+ int16_t mask_y,
+ int16_t dest_x,
+ int16_t dest_y,
+ uint16_t width,
+ uint16_t height)
+{
+ pixman_image_composite32 (op, src, mask, dest, src_x, src_y,
+ mask_x, mask_y, dest_x, dest_y, width, height);
+}
+
+PIXMAN_EXPORT pixman_bool_t
+pixman_blt (uint32_t *src_bits,
+ uint32_t *dst_bits,
+ int src_stride,
+ int dst_stride,
+ int src_bpp,
+ int dst_bpp,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ int width,
+ int height)
+{
+ return _pixman_implementation_blt (get_implementation(),
+ src_bits, dst_bits, src_stride, dst_stride,
+ src_bpp, dst_bpp,
+ src_x, src_y,
+ dst_x, dst_y,
+ width, height);
+}
+
+PIXMAN_EXPORT pixman_bool_t
+pixman_fill (uint32_t *bits,
+ int stride,
+ int bpp,
+ int x,
+ int y,
+ int width,
+ int height,
+ uint32_t xor)
+{
+ return _pixman_implementation_fill (
+ get_implementation(), bits, stride, bpp, x, y, width, height, xor);
+}
+
+static uint32_t
+color_to_uint32 (const pixman_color_t *color)
+{
+ return
+ (color->alpha >> 8 << 24) |
+ (color->red >> 8 << 16) |
+ (color->green & 0xff00) |
+ (color->blue >> 8);
+}
+
+static pixman_bool_t
+color_to_pixel (pixman_color_t * color,
+ uint32_t * pixel,
+ pixman_format_code_t format)
+{
+ uint32_t c = color_to_uint32 (color);
+
+ if (!(format == PIXMAN_a8r8g8b8 ||
+ format == PIXMAN_x8r8g8b8 ||
+ format == PIXMAN_a8b8g8r8 ||
+ format == PIXMAN_x8b8g8r8 ||
+ format == PIXMAN_b8g8r8a8 ||
+ format == PIXMAN_b8g8r8x8 ||
+ format == PIXMAN_r8g8b8a8 ||
+ format == PIXMAN_r8g8b8x8 ||
+ format == PIXMAN_r5g6b5 ||
+ format == PIXMAN_b5g6r5 ||
+ format == PIXMAN_a8 ||
+ format == PIXMAN_a1))
+ {
+ return FALSE;
+ }
+
+ if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
+ {
+ c = ((c & 0xff000000) >> 0) |
+ ((c & 0x00ff0000) >> 16) |
+ ((c & 0x0000ff00) >> 0) |
+ ((c & 0x000000ff) << 16);
+ }
+ if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA)
+ {
+ c = ((c & 0xff000000) >> 24) |
+ ((c & 0x00ff0000) >> 8) |
+ ((c & 0x0000ff00) << 8) |
+ ((c & 0x000000ff) << 24);
+ }
+ if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA)
+ c = ((c & 0xff000000) >> 24) | (c << 8);
+
+ if (format == PIXMAN_a1)
+ c = c >> 31;
+ else if (format == PIXMAN_a8)
+ c = c >> 24;
+ else if (format == PIXMAN_r5g6b5 ||
+ format == PIXMAN_b5g6r5)
+ c = CONVERT_8888_TO_0565 (c);
+
+#if 0
+ printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
+ printf ("pixel: %x\n", c);
+#endif
+
+ *pixel = c;
+ return TRUE;
+}
+
+PIXMAN_EXPORT pixman_bool_t
+pixman_image_fill_rectangles (pixman_op_t op,
+ pixman_image_t * dest,
+ pixman_color_t * color,
+ int n_rects,
+ const pixman_rectangle16_t *rects)
+{
+ pixman_box32_t stack_boxes[6];
+ pixman_box32_t *boxes;
+ pixman_bool_t result;
+ int i;
+
+ if (n_rects > 6)
+ {
+ boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects);
+ if (boxes == NULL)
+ return FALSE;
+ }
+ else
+ {
+ boxes = stack_boxes;
+ }
+
+ for (i = 0; i < n_rects; ++i)
+ {
+ boxes[i].x1 = rects[i].x;
+ boxes[i].y1 = rects[i].y;
+ boxes[i].x2 = boxes[i].x1 + rects[i].width;
+ boxes[i].y2 = boxes[i].y1 + rects[i].height;
+ }
+
+ result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes);
+
+ if (boxes != stack_boxes)
+ free (boxes);
+
+ return result;
+}
+
+PIXMAN_EXPORT pixman_bool_t
+pixman_image_fill_boxes (pixman_op_t op,
+ pixman_image_t * dest,
+ pixman_color_t * color,
+ int n_boxes,
+ const pixman_box32_t *boxes)
+{
+ pixman_image_t *solid;
+ pixman_color_t c;
+ int i;
+
+ _pixman_image_validate (dest);
+
+ if (color->alpha == 0xffff)
+ {
+ if (op == PIXMAN_OP_OVER)
+ op = PIXMAN_OP_SRC;
+ }
+
+ if (op == PIXMAN_OP_CLEAR)
+ {
+ c.red = 0;
+ c.green = 0;
+ c.blue = 0;
+ c.alpha = 0;
+
+ color = &c;
+
+ op = PIXMAN_OP_SRC;
+ }
+
+ if (op == PIXMAN_OP_SRC)
+ {
+ uint32_t pixel;
+
+ if (color_to_pixel (color, &pixel, dest->bits.format))
+ {
+ pixman_region32_t fill_region;
+ int n_rects, j;
+ pixman_box32_t *rects;
+
+ if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes))
+ return FALSE;
+
+ if (dest->common.have_clip_region)
+ {
+ if (!pixman_region32_intersect (&fill_region,
+ &fill_region,
+ &dest->common.clip_region))
+ return FALSE;
+ }
+
+ rects = pixman_region32_rectangles (&fill_region, &n_rects);
+ for (j = 0; j < n_rects; ++j)
+ {
+ const pixman_box32_t *rect = &(rects[j]);
+ pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
+ rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1,
+ pixel);
+ }
+
+ pixman_region32_fini (&fill_region);
+ return TRUE;
+ }
+ }
+
+ solid = pixman_image_create_solid_fill (color);
+ if (!solid)
+ return FALSE;
+
+ for (i = 0; i < n_boxes; ++i)
+ {
+ const pixman_box32_t *box = &(boxes[i]);
+
+ pixman_image_composite32 (op, solid, NULL, dest,
+ 0, 0, 0, 0,
+ box->x1, box->y1,
+ box->x2 - box->x1, box->y2 - box->y1);
+ }
+
+ pixman_image_unref (solid);
+
+ return TRUE;
+}
+
+/**
+ * pixman_version:
+ *
+ * Returns the version of the pixman library encoded in a single
+ * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that
+ * later versions compare greater than earlier versions.
+ *
+ * A run-time comparison to check that pixman's version is greater than
+ * or equal to version X.Y.Z could be performed as follows:
+ *
+ * <informalexample><programlisting>
+ * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...}
+ * </programlisting></informalexample>
+ *
+ * See also pixman_version_string() as well as the compile-time
+ * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING.
+ *
+ * Return value: the encoded version.
+ **/
+PIXMAN_EXPORT int
+pixman_version (void)
+{
+ return PIXMAN_VERSION;
+}
+
+/**
+ * pixman_version_string:
+ *
+ * Returns the version of the pixman library as a human-readable string
+ * of the form "X.Y.Z".
+ *
+ * See also pixman_version() as well as the compile-time equivalents
+ * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION.
+ *
+ * Return value: a string containing the version.
+ **/
+PIXMAN_EXPORT const char*
+pixman_version_string (void)
+{
+ return PIXMAN_VERSION_STRING;
+}
+
+/**
+ * pixman_format_supported_source:
+ * @format: A pixman_format_code_t format
+ *
+ * Return value: whether the provided format code is a supported
+ * format for a pixman surface used as a source in
+ * rendering.
+ *
+ * Currently, all pixman_format_code_t values are supported.
+ **/
+PIXMAN_EXPORT pixman_bool_t
+pixman_format_supported_source (pixman_format_code_t format)
+{
+ switch (format)
+ {
+ /* 32 bpp formats */
+ case PIXMAN_a2b10g10r10:
+ case PIXMAN_x2b10g10r10:
+ case PIXMAN_a2r10g10b10:
+ case PIXMAN_x2r10g10b10:
+ case PIXMAN_a8r8g8b8:
+ case PIXMAN_x8r8g8b8:
+ case PIXMAN_a8b8g8r8:
+ case PIXMAN_x8b8g8r8:
+ case PIXMAN_b8g8r8a8:
+ case PIXMAN_b8g8r8x8:
+ case PIXMAN_r8g8b8a8:
+ case PIXMAN_r8g8b8x8:
+ case PIXMAN_r8g8b8:
+ case PIXMAN_b8g8r8:
+ case PIXMAN_r5g6b5:
+ case PIXMAN_b5g6r5:
+ case PIXMAN_x14r6g6b6:
+ /* 16 bpp formats */
+ case PIXMAN_a1r5g5b5:
+ case PIXMAN_x1r5g5b5:
+ case PIXMAN_a1b5g5r5:
+ case PIXMAN_x1b5g5r5:
+ case PIXMAN_a4r4g4b4:
+ case PIXMAN_x4r4g4b4:
+ case PIXMAN_a4b4g4r4:
+ case PIXMAN_x4b4g4r4:
+ /* 8bpp formats */
+ case PIXMAN_a8:
+ case PIXMAN_r3g3b2:
+ case PIXMAN_b2g3r3:
+ case PIXMAN_a2r2g2b2:
+ case PIXMAN_a2b2g2r2:
+ case PIXMAN_c8:
+ case PIXMAN_g8:
+ case PIXMAN_x4a4:
+ /* Collides with PIXMAN_c8
+ case PIXMAN_x4c4:
+ */
+ /* Collides with PIXMAN_g8
+ case PIXMAN_x4g4:
+ */
+ /* 4bpp formats */
+ case PIXMAN_a4:
+ case PIXMAN_r1g2b1:
+ case PIXMAN_b1g2r1:
+ case PIXMAN_a1r1g1b1:
+ case PIXMAN_a1b1g1r1:
+ case PIXMAN_c4:
+ case PIXMAN_g4:
+ /* 1bpp formats */
+ case PIXMAN_a1:
+ case PIXMAN_g1:
+ /* YUV formats */
+ case PIXMAN_yuy2:
+ case PIXMAN_yv12:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+/**
+ * pixman_format_supported_destination:
+ * @format: A pixman_format_code_t format
+ *
+ * Return value: whether the provided format code is a supported
+ * format for a pixman surface used as a destination in
+ * rendering.
+ *
+ * Currently, all pixman_format_code_t values are supported
+ * except for the YUV formats.
+ **/
+PIXMAN_EXPORT pixman_bool_t
+pixman_format_supported_destination (pixman_format_code_t format)
+{
+ /* YUV formats cannot be written to at the moment */
+ if (format == PIXMAN_yuy2 || format == PIXMAN_yv12)
+ return FALSE;
+
+ return pixman_format_supported_source (format);
+}
+
+PIXMAN_EXPORT pixman_bool_t
+pixman_compute_composite_region (pixman_region16_t * region,
+ pixman_image_t * src_image,
+ pixman_image_t * mask_image,
+ pixman_image_t * dst_image,
+ int16_t src_x,
+ int16_t src_y,
+ int16_t mask_x,
+ int16_t mask_y,
+ int16_t dest_x,
+ int16_t dest_y,
+ uint16_t width,
+ uint16_t height)
+{
+ pixman_region32_t r32;
+ pixman_bool_t retval;
+
+ pixman_region32_init (&r32);
+
+ retval = pixman_compute_composite_region32 (
+ &r32, src_image, mask_image, dst_image,
+ src_x, src_y, mask_x, mask_y, dest_x, dest_y,
+ width, height);
+
+ if (retval)
+ {
+ if (!pixman_region16_copy_from_region32 (region, &r32))
+ retval = FALSE;
+ }
+
+ pixman_region32_fini (&r32);
+ return retval;
+}
diff --git a/pixman/pixman/pixman.h b/pixman/pixman/pixman.h
index 855575a30..59d076089 100644
--- a/pixman/pixman/pixman.h
+++ b/pixman/pixman/pixman.h
@@ -1,986 +1,990 @@
-/***********************************************************
-
-Copyright 1987, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-/*
- * Copyright © 1998, 2004 Keith Packard
- * Copyright 2007 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef PIXMAN_H__
-#define PIXMAN_H__
-
-#include <pixman-version.h>
-
-#ifdef __cplusplus
-#define PIXMAN_BEGIN_DECLS extern "C" {
-#define PIXMAN_END_DECLS }
-#else
-#define PIXMAN_BEGIN_DECLS
-#define PIXMAN_END_DECLS
-#endif
-
-PIXMAN_BEGIN_DECLS
-
-/*
- * Standard integers
- */
-
-#if !defined (PIXMAN_DONT_DEFINE_STDINT)
-
-#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined (_sgi) || defined (__sun) || defined (sun) || defined (__digital__) || defined (__HP_cc)
-# include <inttypes.h>
-/* VS 2010 (_MSC_VER 1600) has stdint.h */
-#elif defined (_MSC_VER) && _MSC_VER < 1600
-typedef __int8 int8_t;
-typedef unsigned __int8 uint8_t;
-typedef __int16 int16_t;
-typedef unsigned __int16 uint16_t;
-typedef __int32 int32_t;
-typedef unsigned __int32 uint32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-#elif defined (_AIX)
-# include <sys/inttypes.h>
-#else
-# include <stdint.h>
-#endif
-
-#endif
-
-/*
- * Boolean
- */
-typedef int pixman_bool_t;
-
-/*
- * Fixpoint numbers
- */
-typedef int64_t pixman_fixed_32_32_t;
-typedef pixman_fixed_32_32_t pixman_fixed_48_16_t;
-typedef uint32_t pixman_fixed_1_31_t;
-typedef uint32_t pixman_fixed_1_16_t;
-typedef int32_t pixman_fixed_16_16_t;
-typedef pixman_fixed_16_16_t pixman_fixed_t;
-
-#define pixman_fixed_e ((pixman_fixed_t) 1)
-#define pixman_fixed_1 (pixman_int_to_fixed(1))
-#define pixman_fixed_1_minus_e (pixman_fixed_1 - pixman_fixed_e)
-#define pixman_fixed_minus_1 (pixman_int_to_fixed(-1))
-#define pixman_fixed_to_int(f) ((int) ((f) >> 16))
-#define pixman_int_to_fixed(i) ((pixman_fixed_t) ((i) << 16))
-#define pixman_fixed_to_double(f) (double) ((f) / (double) pixman_fixed_1)
-#define pixman_double_to_fixed(d) ((pixman_fixed_t) ((d) * 65536.0))
-#define pixman_fixed_frac(f) ((f) & pixman_fixed_1_minus_e)
-#define pixman_fixed_floor(f) ((f) & ~pixman_fixed_1_minus_e)
-#define pixman_fixed_ceil(f) pixman_fixed_floor ((f) + pixman_fixed_1_minus_e)
-#define pixman_fixed_fraction(f) ((f) & pixman_fixed_1_minus_e)
-#define pixman_fixed_mod_2(f) ((f) & (pixman_fixed1 | pixman_fixed_1_minus_e))
-#define pixman_max_fixed_48_16 ((pixman_fixed_48_16_t) 0x7fffffff)
-#define pixman_min_fixed_48_16 (-((pixman_fixed_48_16_t) 1 << 31))
-
-/*
- * Misc structs
- */
-typedef struct pixman_color pixman_color_t;
-typedef struct pixman_point_fixed pixman_point_fixed_t;
-typedef struct pixman_line_fixed pixman_line_fixed_t;
-typedef struct pixman_vector pixman_vector_t;
-typedef struct pixman_transform pixman_transform_t;
-
-struct pixman_color
-{
- uint16_t red;
- uint16_t green;
- uint16_t blue;
- uint16_t alpha;
-};
-
-struct pixman_point_fixed
-{
- pixman_fixed_t x;
- pixman_fixed_t y;
-};
-
-struct pixman_line_fixed
-{
- pixman_point_fixed_t p1, p2;
-};
-
-/*
- * Fixed point matrices
- */
-
-struct pixman_vector
-{
- pixman_fixed_t vector[3];
-};
-
-struct pixman_transform
-{
- pixman_fixed_t matrix[3][3];
-};
-
-/* forward declaration (sorry) */
-struct pixman_box16;
-typedef union pixman_image pixman_image_t;
-
-void pixman_transform_init_identity (struct pixman_transform *matrix);
-pixman_bool_t pixman_transform_point_3d (const struct pixman_transform *transform,
- struct pixman_vector *vector);
-pixman_bool_t pixman_transform_point (const struct pixman_transform *transform,
- struct pixman_vector *vector);
-pixman_bool_t pixman_transform_multiply (struct pixman_transform *dst,
- const struct pixman_transform *l,
- const struct pixman_transform *r);
-void pixman_transform_init_scale (struct pixman_transform *t,
- pixman_fixed_t sx,
- pixman_fixed_t sy);
-pixman_bool_t pixman_transform_scale (struct pixman_transform *forward,
- struct pixman_transform *reverse,
- pixman_fixed_t sx,
- pixman_fixed_t sy);
-void pixman_transform_init_rotate (struct pixman_transform *t,
- pixman_fixed_t cos,
- pixman_fixed_t sin);
-pixman_bool_t pixman_transform_rotate (struct pixman_transform *forward,
- struct pixman_transform *reverse,
- pixman_fixed_t c,
- pixman_fixed_t s);
-void pixman_transform_init_translate (struct pixman_transform *t,
- pixman_fixed_t tx,
- pixman_fixed_t ty);
-pixman_bool_t pixman_transform_translate (struct pixman_transform *forward,
- struct pixman_transform *reverse,
- pixman_fixed_t tx,
- pixman_fixed_t ty);
-pixman_bool_t pixman_transform_bounds (const struct pixman_transform *matrix,
- struct pixman_box16 *b);
-pixman_bool_t pixman_transform_invert (struct pixman_transform *dst,
- const struct pixman_transform *src);
-pixman_bool_t pixman_transform_is_identity (const struct pixman_transform *t);
-pixman_bool_t pixman_transform_is_scale (const struct pixman_transform *t);
-pixman_bool_t pixman_transform_is_int_translate (const struct pixman_transform *t);
-pixman_bool_t pixman_transform_is_inverse (const struct pixman_transform *a,
- const struct pixman_transform *b);
-
-/*
- * Floating point matrices
- */
-struct pixman_f_vector
-{
- double v[3];
-};
-
-struct pixman_f_transform
-{
- double m[3][3];
-};
-
-pixman_bool_t pixman_transform_from_pixman_f_transform (struct pixman_transform *t,
- const struct pixman_f_transform *ft);
-void pixman_f_transform_from_pixman_transform (struct pixman_f_transform *ft,
- const struct pixman_transform *t);
-pixman_bool_t pixman_f_transform_invert (struct pixman_f_transform *dst,
- const struct pixman_f_transform *src);
-pixman_bool_t pixman_f_transform_point (const struct pixman_f_transform *t,
- struct pixman_f_vector *v);
-void pixman_f_transform_point_3d (const struct pixman_f_transform *t,
- struct pixman_f_vector *v);
-void pixman_f_transform_multiply (struct pixman_f_transform *dst,
- const struct pixman_f_transform *l,
- const struct pixman_f_transform *r);
-void pixman_f_transform_init_scale (struct pixman_f_transform *t,
- double sx,
- double sy);
-pixman_bool_t pixman_f_transform_scale (struct pixman_f_transform *forward,
- struct pixman_f_transform *reverse,
- double sx,
- double sy);
-void pixman_f_transform_init_rotate (struct pixman_f_transform *t,
- double cos,
- double sin);
-pixman_bool_t pixman_f_transform_rotate (struct pixman_f_transform *forward,
- struct pixman_f_transform *reverse,
- double c,
- double s);
-void pixman_f_transform_init_translate (struct pixman_f_transform *t,
- double tx,
- double ty);
-pixman_bool_t pixman_f_transform_translate (struct pixman_f_transform *forward,
- struct pixman_f_transform *reverse,
- double tx,
- double ty);
-pixman_bool_t pixman_f_transform_bounds (const struct pixman_f_transform *t,
- struct pixman_box16 *b);
-void pixman_f_transform_init_identity (struct pixman_f_transform *t);
-
-typedef enum
-{
- PIXMAN_REPEAT_NONE,
- PIXMAN_REPEAT_NORMAL,
- PIXMAN_REPEAT_PAD,
- PIXMAN_REPEAT_REFLECT
-} pixman_repeat_t;
-
-typedef enum
-{
- PIXMAN_FILTER_FAST,
- PIXMAN_FILTER_GOOD,
- PIXMAN_FILTER_BEST,
- PIXMAN_FILTER_NEAREST,
- PIXMAN_FILTER_BILINEAR,
- PIXMAN_FILTER_CONVOLUTION
-} pixman_filter_t;
-
-typedef enum
-{
- PIXMAN_OP_CLEAR = 0x00,
- PIXMAN_OP_SRC = 0x01,
- PIXMAN_OP_DST = 0x02,
- PIXMAN_OP_OVER = 0x03,
- PIXMAN_OP_OVER_REVERSE = 0x04,
- PIXMAN_OP_IN = 0x05,
- PIXMAN_OP_IN_REVERSE = 0x06,
- PIXMAN_OP_OUT = 0x07,
- PIXMAN_OP_OUT_REVERSE = 0x08,
- PIXMAN_OP_ATOP = 0x09,
- PIXMAN_OP_ATOP_REVERSE = 0x0a,
- PIXMAN_OP_XOR = 0x0b,
- PIXMAN_OP_ADD = 0x0c,
- PIXMAN_OP_SATURATE = 0x0d,
-
- PIXMAN_OP_DISJOINT_CLEAR = 0x10,
- PIXMAN_OP_DISJOINT_SRC = 0x11,
- PIXMAN_OP_DISJOINT_DST = 0x12,
- PIXMAN_OP_DISJOINT_OVER = 0x13,
- PIXMAN_OP_DISJOINT_OVER_REVERSE = 0x14,
- PIXMAN_OP_DISJOINT_IN = 0x15,
- PIXMAN_OP_DISJOINT_IN_REVERSE = 0x16,
- PIXMAN_OP_DISJOINT_OUT = 0x17,
- PIXMAN_OP_DISJOINT_OUT_REVERSE = 0x18,
- PIXMAN_OP_DISJOINT_ATOP = 0x19,
- PIXMAN_OP_DISJOINT_ATOP_REVERSE = 0x1a,
- PIXMAN_OP_DISJOINT_XOR = 0x1b,
-
- PIXMAN_OP_CONJOINT_CLEAR = 0x20,
- PIXMAN_OP_CONJOINT_SRC = 0x21,
- PIXMAN_OP_CONJOINT_DST = 0x22,
- PIXMAN_OP_CONJOINT_OVER = 0x23,
- PIXMAN_OP_CONJOINT_OVER_REVERSE = 0x24,
- PIXMAN_OP_CONJOINT_IN = 0x25,
- PIXMAN_OP_CONJOINT_IN_REVERSE = 0x26,
- PIXMAN_OP_CONJOINT_OUT = 0x27,
- PIXMAN_OP_CONJOINT_OUT_REVERSE = 0x28,
- PIXMAN_OP_CONJOINT_ATOP = 0x29,
- PIXMAN_OP_CONJOINT_ATOP_REVERSE = 0x2a,
- PIXMAN_OP_CONJOINT_XOR = 0x2b,
-
- PIXMAN_OP_MULTIPLY = 0x30,
- PIXMAN_OP_SCREEN = 0x31,
- PIXMAN_OP_OVERLAY = 0x32,
- PIXMAN_OP_DARKEN = 0x33,
- PIXMAN_OP_LIGHTEN = 0x34,
- PIXMAN_OP_COLOR_DODGE = 0x35,
- PIXMAN_OP_COLOR_BURN = 0x36,
- PIXMAN_OP_HARD_LIGHT = 0x37,
- PIXMAN_OP_SOFT_LIGHT = 0x38,
- PIXMAN_OP_DIFFERENCE = 0x39,
- PIXMAN_OP_EXCLUSION = 0x3a,
- PIXMAN_OP_HSL_HUE = 0x3b,
- PIXMAN_OP_HSL_SATURATION = 0x3c,
- PIXMAN_OP_HSL_COLOR = 0x3d,
- PIXMAN_OP_HSL_LUMINOSITY = 0x3e
-
-#ifdef PIXMAN_USE_INTERNAL_API
- ,
- PIXMAN_N_OPERATORS,
- PIXMAN_OP_NONE = PIXMAN_N_OPERATORS
-#endif
-} pixman_op_t;
-
-/*
- * Regions
- */
-typedef struct pixman_region16_data pixman_region16_data_t;
-typedef struct pixman_box16 pixman_box16_t;
-typedef struct pixman_rectangle16 pixman_rectangle16_t;
-typedef struct pixman_region16 pixman_region16_t;
-
-struct pixman_region16_data {
- long size;
- long numRects;
-/* pixman_box16_t rects[size]; in memory but not explicitly declared */
-};
-
-struct pixman_rectangle16
-{
- int16_t x, y;
- uint16_t width, height;
-};
-
-struct pixman_box16
-{
- int16_t x1, y1, x2, y2;
-};
-
-struct pixman_region16
-{
- pixman_box16_t extents;
- pixman_region16_data_t *data;
-};
-
-typedef enum
-{
- PIXMAN_REGION_OUT,
- PIXMAN_REGION_IN,
- PIXMAN_REGION_PART
-} pixman_region_overlap_t;
-
-/* This function exists only to make it possible to preserve
- * the X ABI - it should go away at first opportunity.
- */
-void pixman_region_set_static_pointers (pixman_box16_t *empty_box,
- pixman_region16_data_t *empty_data,
- pixman_region16_data_t *broken_data);
-
-/* creation/destruction */
-void pixman_region_init (pixman_region16_t *region);
-void pixman_region_init_rect (pixman_region16_t *region,
- int x,
- int y,
- unsigned int width,
- unsigned int height);
-pixman_bool_t pixman_region_init_rects (pixman_region16_t *region,
- const pixman_box16_t *boxes,
- int count);
-void pixman_region_init_with_extents (pixman_region16_t *region,
- pixman_box16_t *extents);
-void pixman_region_init_from_image (pixman_region16_t *region,
- pixman_image_t *image);
-void pixman_region_fini (pixman_region16_t *region);
-
-
-/* manipulation */
-void pixman_region_translate (pixman_region16_t *region,
- int x,
- int y);
-pixman_bool_t pixman_region_copy (pixman_region16_t *dest,
- pixman_region16_t *source);
-pixman_bool_t pixman_region_intersect (pixman_region16_t *new_reg,
- pixman_region16_t *reg1,
- pixman_region16_t *reg2);
-pixman_bool_t pixman_region_union (pixman_region16_t *new_reg,
- pixman_region16_t *reg1,
- pixman_region16_t *reg2);
-pixman_bool_t pixman_region_union_rect (pixman_region16_t *dest,
- pixman_region16_t *source,
- int x,
- int y,
- unsigned int width,
- unsigned int height);
-pixman_bool_t pixman_region_intersect_rect (pixman_region16_t *dest,
- pixman_region16_t *source,
- int x,
- int y,
- unsigned int width,
- unsigned int height);
-pixman_bool_t pixman_region_subtract (pixman_region16_t *reg_d,
- pixman_region16_t *reg_m,
- pixman_region16_t *reg_s);
-pixman_bool_t pixman_region_inverse (pixman_region16_t *new_reg,
- pixman_region16_t *reg1,
- pixman_box16_t *inv_rect);
-pixman_bool_t pixman_region_contains_point (pixman_region16_t *region,
- int x,
- int y,
- pixman_box16_t *box);
-pixman_region_overlap_t pixman_region_contains_rectangle (pixman_region16_t *region,
- pixman_box16_t *prect);
-pixman_bool_t pixman_region_not_empty (pixman_region16_t *region);
-pixman_box16_t * pixman_region_extents (pixman_region16_t *region);
-int pixman_region_n_rects (pixman_region16_t *region);
-pixman_box16_t * pixman_region_rectangles (pixman_region16_t *region,
- int *n_rects);
-pixman_bool_t pixman_region_equal (pixman_region16_t *region1,
- pixman_region16_t *region2);
-pixman_bool_t pixman_region_selfcheck (pixman_region16_t *region);
-void pixman_region_reset (pixman_region16_t *region,
- pixman_box16_t *box);
-/*
- * 32 bit regions
- */
-typedef struct pixman_region32_data pixman_region32_data_t;
-typedef struct pixman_box32 pixman_box32_t;
-typedef struct pixman_rectangle32 pixman_rectangle32_t;
-typedef struct pixman_region32 pixman_region32_t;
-
-struct pixman_region32_data {
- long size;
- long numRects;
-/* pixman_box32_t rects[size]; in memory but not explicitly declared */
-};
-
-struct pixman_rectangle32
-{
- int32_t x, y;
- uint32_t width, height;
-};
-
-struct pixman_box32
-{
- int32_t x1, y1, x2, y2;
-};
-
-struct pixman_region32
-{
- pixman_box32_t extents;
- pixman_region32_data_t *data;
-};
-
-/* creation/destruction */
-void pixman_region32_init (pixman_region32_t *region);
-void pixman_region32_init_rect (pixman_region32_t *region,
- int x,
- int y,
- unsigned int width,
- unsigned int height);
-pixman_bool_t pixman_region32_init_rects (pixman_region32_t *region,
- const pixman_box32_t *boxes,
- int count);
-void pixman_region32_init_with_extents (pixman_region32_t *region,
- pixman_box32_t *extents);
-void pixman_region32_init_from_image (pixman_region32_t *region,
- pixman_image_t *image);
-void pixman_region32_fini (pixman_region32_t *region);
-
-
-/* manipulation */
-void pixman_region32_translate (pixman_region32_t *region,
- int x,
- int y);
-pixman_bool_t pixman_region32_copy (pixman_region32_t *dest,
- pixman_region32_t *source);
-pixman_bool_t pixman_region32_intersect (pixman_region32_t *new_reg,
- pixman_region32_t *reg1,
- pixman_region32_t *reg2);
-pixman_bool_t pixman_region32_union (pixman_region32_t *new_reg,
- pixman_region32_t *reg1,
- pixman_region32_t *reg2);
-pixman_bool_t pixman_region32_intersect_rect (pixman_region32_t *dest,
- pixman_region32_t *source,
- int x,
- int y,
- unsigned int width,
- unsigned int height);
-pixman_bool_t pixman_region32_union_rect (pixman_region32_t *dest,
- pixman_region32_t *source,
- int x,
- int y,
- unsigned int width,
- unsigned int height);
-pixman_bool_t pixman_region32_subtract (pixman_region32_t *reg_d,
- pixman_region32_t *reg_m,
- pixman_region32_t *reg_s);
-pixman_bool_t pixman_region32_inverse (pixman_region32_t *new_reg,
- pixman_region32_t *reg1,
- pixman_box32_t *inv_rect);
-pixman_bool_t pixman_region32_contains_point (pixman_region32_t *region,
- int x,
- int y,
- pixman_box32_t *box);
-pixman_region_overlap_t pixman_region32_contains_rectangle (pixman_region32_t *region,
- pixman_box32_t *prect);
-pixman_bool_t pixman_region32_not_empty (pixman_region32_t *region);
-pixman_box32_t * pixman_region32_extents (pixman_region32_t *region);
-int pixman_region32_n_rects (pixman_region32_t *region);
-pixman_box32_t * pixman_region32_rectangles (pixman_region32_t *region,
- int *n_rects);
-pixman_bool_t pixman_region32_equal (pixman_region32_t *region1,
- pixman_region32_t *region2);
-pixman_bool_t pixman_region32_selfcheck (pixman_region32_t *region);
-void pixman_region32_reset (pixman_region32_t *region,
- pixman_box32_t *box);
-
-
-/* Copy / Fill / Misc */
-pixman_bool_t pixman_blt (uint32_t *src_bits,
- uint32_t *dst_bits,
- int src_stride,
- int dst_stride,
- int src_bpp,
- int dst_bpp,
- int src_x,
- int src_y,
- int dst_x,
- int dst_y,
- int width,
- int height);
-pixman_bool_t pixman_fill (uint32_t *bits,
- int stride,
- int bpp,
- int x,
- int y,
- int width,
- int height,
- uint32_t _xor);
-
-int pixman_version (void);
-const char* pixman_version_string (void);
-
-/*
- * Images
- */
-typedef struct pixman_indexed pixman_indexed_t;
-typedef struct pixman_gradient_stop pixman_gradient_stop_t;
-
-typedef uint32_t (* pixman_read_memory_func_t) (const void *src, int size);
-typedef void (* pixman_write_memory_func_t) (void *dst, uint32_t value, int size);
-
-typedef void (* pixman_image_destroy_func_t) (pixman_image_t *image, void *data);
-
-struct pixman_gradient_stop {
- pixman_fixed_t x;
- pixman_color_t color;
-};
-
-#define PIXMAN_MAX_INDEXED 256 /* XXX depth must be <= 8 */
-
-#if PIXMAN_MAX_INDEXED <= 256
-typedef uint8_t pixman_index_type;
-#endif
-
-struct pixman_indexed
-{
- pixman_bool_t color;
- uint32_t rgba[PIXMAN_MAX_INDEXED];
- pixman_index_type ent[32768];
-};
-
-/*
- * While the protocol is generous in format support, the
- * sample implementation allows only packed RGB and GBR
- * representations for data to simplify software rendering,
- */
-#define PIXMAN_FORMAT(bpp,type,a,r,g,b) (((bpp) << 24) | \
- ((type) << 16) | \
- ((a) << 12) | \
- ((r) << 8) | \
- ((g) << 4) | \
- ((b)))
-
-#define PIXMAN_FORMAT_BPP(f) (((f) >> 24) )
-#define PIXMAN_FORMAT_TYPE(f) (((f) >> 16) & 0xff)
-#define PIXMAN_FORMAT_A(f) (((f) >> 12) & 0x0f)
-#define PIXMAN_FORMAT_R(f) (((f) >> 8) & 0x0f)
-#define PIXMAN_FORMAT_G(f) (((f) >> 4) & 0x0f)
-#define PIXMAN_FORMAT_B(f) (((f) ) & 0x0f)
-#define PIXMAN_FORMAT_RGB(f) (((f) ) & 0xfff)
-#define PIXMAN_FORMAT_VIS(f) (((f) ) & 0xffff)
-#define PIXMAN_FORMAT_DEPTH(f) (PIXMAN_FORMAT_A(f) + \
- PIXMAN_FORMAT_R(f) + \
- PIXMAN_FORMAT_G(f) + \
- PIXMAN_FORMAT_B(f))
-
-#define PIXMAN_TYPE_OTHER 0
-#define PIXMAN_TYPE_A 1
-#define PIXMAN_TYPE_ARGB 2
-#define PIXMAN_TYPE_ABGR 3
-#define PIXMAN_TYPE_COLOR 4
-#define PIXMAN_TYPE_GRAY 5
-#define PIXMAN_TYPE_YUY2 6
-#define PIXMAN_TYPE_YV12 7
-#define PIXMAN_TYPE_BGRA 8
-
-#define PIXMAN_FORMAT_COLOR(f) \
- (PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB || \
- PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR || \
- PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_BGRA)
-
-/* 32bpp formats */
-typedef enum {
- PIXMAN_a8r8g8b8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,8,8,8,8),
- PIXMAN_x8r8g8b8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,8,8,8),
- PIXMAN_a8b8g8r8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,8,8,8,8),
- PIXMAN_x8b8g8r8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,0,8,8,8),
- PIXMAN_b8g8r8a8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_BGRA,8,8,8,8),
- PIXMAN_b8g8r8x8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_BGRA,0,8,8,8),
- PIXMAN_x14r6g6b6 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,6,6,6),
- PIXMAN_x2r10g10b10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,10,10,10),
- PIXMAN_a2r10g10b10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,2,10,10,10),
- PIXMAN_x2b10g10r10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,0,10,10,10),
- PIXMAN_a2b10g10r10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,2,10,10,10),
-
-/* 24bpp formats */
- PIXMAN_r8g8b8 = PIXMAN_FORMAT(24,PIXMAN_TYPE_ARGB,0,8,8,8),
- PIXMAN_b8g8r8 = PIXMAN_FORMAT(24,PIXMAN_TYPE_ABGR,0,8,8,8),
-
-/* 16bpp formats */
- PIXMAN_r5g6b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,5,6,5),
- PIXMAN_b5g6r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,5,6,5),
-
- PIXMAN_a1r5g5b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,1,5,5,5),
- PIXMAN_x1r5g5b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,5,5,5),
- PIXMAN_a1b5g5r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,1,5,5,5),
- PIXMAN_x1b5g5r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,5,5,5),
- PIXMAN_a4r4g4b4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,4,4,4,4),
- PIXMAN_x4r4g4b4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,4,4,4),
- PIXMAN_a4b4g4r4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,4,4,4,4),
- PIXMAN_x4b4g4r4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,4,4,4),
-
-/* 8bpp formats */
- PIXMAN_a8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_A,8,0,0,0),
- PIXMAN_r3g3b2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ARGB,0,3,3,2),
- PIXMAN_b2g3r3 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ABGR,0,3,3,2),
- PIXMAN_a2r2g2b2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ARGB,2,2,2,2),
- PIXMAN_a2b2g2r2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ABGR,2,2,2,2),
-
- PIXMAN_c8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_COLOR,0,0,0,0),
- PIXMAN_g8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_GRAY,0,0,0,0),
-
- PIXMAN_x4a4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_A,4,0,0,0),
-
- PIXMAN_x4c4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_COLOR,0,0,0,0),
- PIXMAN_x4g4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_GRAY,0,0,0,0),
-
-/* 4bpp formats */
- PIXMAN_a4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_A,4,0,0,0),
- PIXMAN_r1g2b1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ARGB,0,1,2,1),
- PIXMAN_b1g2r1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ABGR,0,1,2,1),
- PIXMAN_a1r1g1b1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ARGB,1,1,1,1),
- PIXMAN_a1b1g1r1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ABGR,1,1,1,1),
-
- PIXMAN_c4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_COLOR,0,0,0,0),
- PIXMAN_g4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_GRAY,0,0,0,0),
-
-/* 1bpp formats */
- PIXMAN_a1 = PIXMAN_FORMAT(1,PIXMAN_TYPE_A,1,0,0,0),
-
- PIXMAN_g1 = PIXMAN_FORMAT(1,PIXMAN_TYPE_GRAY,0,0,0,0),
-
-/* YUV formats */
- PIXMAN_yuy2 = PIXMAN_FORMAT(16,PIXMAN_TYPE_YUY2,0,0,0,0),
- PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0)
-} pixman_format_code_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);
-
-/* Constructors */
-pixman_image_t *pixman_image_create_solid_fill (pixman_color_t *color);
-pixman_image_t *pixman_image_create_linear_gradient (pixman_point_fixed_t *p1,
- pixman_point_fixed_t *p2,
- const pixman_gradient_stop_t *stops,
- int n_stops);
-pixman_image_t *pixman_image_create_radial_gradient (pixman_point_fixed_t *inner,
- pixman_point_fixed_t *outer,
- pixman_fixed_t inner_radius,
- pixman_fixed_t outer_radius,
- const pixman_gradient_stop_t *stops,
- int n_stops);
-pixman_image_t *pixman_image_create_conical_gradient (pixman_point_fixed_t *center,
- pixman_fixed_t angle,
- const pixman_gradient_stop_t *stops,
- int n_stops);
-pixman_image_t *pixman_image_create_bits (pixman_format_code_t format,
- int width,
- int height,
- uint32_t *bits,
- int rowstride_bytes);
-
-/* Destructor */
-pixman_image_t *pixman_image_ref (pixman_image_t *image);
-pixman_bool_t pixman_image_unref (pixman_image_t *image);
-
-void pixman_image_set_destroy_function (pixman_image_t *image,
- pixman_image_destroy_func_t function,
- void *data);
-void * pixman_image_get_destroy_data (pixman_image_t *image);
-
-/* Set properties */
-pixman_bool_t pixman_image_set_clip_region (pixman_image_t *image,
- pixman_region16_t *region);
-pixman_bool_t pixman_image_set_clip_region32 (pixman_image_t *image,
- pixman_region32_t *region);
-void pixman_image_set_has_client_clip (pixman_image_t *image,
- pixman_bool_t clien_clip);
-pixman_bool_t pixman_image_set_transform (pixman_image_t *image,
- const pixman_transform_t *transform);
-void pixman_image_set_repeat (pixman_image_t *image,
- pixman_repeat_t repeat);
-pixman_bool_t pixman_image_set_filter (pixman_image_t *image,
- pixman_filter_t filter,
- const pixman_fixed_t *filter_params,
- int n_filter_params);
-void pixman_image_set_source_clipping (pixman_image_t *image,
- pixman_bool_t source_clipping);
-void pixman_image_set_alpha_map (pixman_image_t *image,
- pixman_image_t *alpha_map,
- int16_t x,
- int16_t y);
-void pixman_image_set_component_alpha (pixman_image_t *image,
- pixman_bool_t component_alpha);
-pixman_bool_t pixman_image_get_component_alpha (pixman_image_t *image);
-void pixman_image_set_accessors (pixman_image_t *image,
- pixman_read_memory_func_t read_func,
- pixman_write_memory_func_t write_func);
-void pixman_image_set_indexed (pixman_image_t *image,
- const pixman_indexed_t *indexed);
-uint32_t *pixman_image_get_data (pixman_image_t *image);
-int pixman_image_get_width (pixman_image_t *image);
-int pixman_image_get_height (pixman_image_t *image);
-int pixman_image_get_stride (pixman_image_t *image); /* in bytes */
-int pixman_image_get_depth (pixman_image_t *image);
-pixman_format_code_t pixman_image_get_format (pixman_image_t *image);
-pixman_bool_t pixman_image_fill_rectangles (pixman_op_t op,
- pixman_image_t *image,
- pixman_color_t *color,
- int n_rects,
- const pixman_rectangle16_t *rects);
-pixman_bool_t pixman_image_fill_boxes (pixman_op_t op,
- pixman_image_t *dest,
- pixman_color_t *color,
- int n_boxes,
- const pixman_box32_t *boxes);
-
-/* Composite */
-pixman_bool_t pixman_compute_composite_region (pixman_region16_t *region,
- pixman_image_t *src_image,
- pixman_image_t *mask_image,
- pixman_image_t *dst_image,
- int16_t src_x,
- int16_t src_y,
- int16_t mask_x,
- int16_t mask_y,
- int16_t dest_x,
- int16_t dest_y,
- uint16_t width,
- uint16_t height);
-void pixman_image_composite (pixman_op_t op,
- pixman_image_t *src,
- pixman_image_t *mask,
- pixman_image_t *dest,
- int16_t src_x,
- int16_t src_y,
- int16_t mask_x,
- int16_t mask_y,
- int16_t dest_x,
- int16_t dest_y,
- uint16_t width,
- uint16_t height);
-void pixman_image_composite32 (pixman_op_t op,
- pixman_image_t *src,
- pixman_image_t *mask,
- pixman_image_t *dest,
- int32_t src_x,
- int32_t src_y,
- int32_t mask_x,
- int32_t mask_y,
- int32_t dest_x,
- int32_t dest_y,
- int32_t width,
- int32_t height);
-
-/* Executive Summary: This function is a no-op that only exists
- * for historical reasons.
- *
- * There used to be a bug in the X server where it would rely on
- * out-of-bounds accesses when it was asked to composite with a
- * window as the source. It would create a pixman image pointing
- * to some bogus position in memory, but then set a clip region
- * to the position where the actual bits were.
- *
- * Due to a bug in old versions of pixman, where it would not clip
- * against the image bounds when a clip region was set, this would
- * actually work. So when the pixman bug was fixed, a workaround was
- * added to allow certain out-of-bound accesses. This function disabled
- * those workarounds.
- *
- * Since 0.21.2, pixman doesn't do these workarounds anymore, so now this
- * function is a no-op.
- */
-void pixman_disable_out_of_bounds_workaround (void);
-
-/*
- * Trapezoids
- */
-typedef struct pixman_edge pixman_edge_t;
-typedef struct pixman_trapezoid pixman_trapezoid_t;
-typedef struct pixman_trap pixman_trap_t;
-typedef struct pixman_span_fix pixman_span_fix_t;
-typedef struct pixman_triangle pixman_triangle_t;
-
-/*
- * An edge structure. This represents a single polygon edge
- * and can be quickly stepped across small or large gaps in the
- * sample grid
- */
-struct pixman_edge
-{
- pixman_fixed_t x;
- pixman_fixed_t e;
- pixman_fixed_t stepx;
- pixman_fixed_t signdx;
- pixman_fixed_t dy;
- pixman_fixed_t dx;
-
- pixman_fixed_t stepx_small;
- pixman_fixed_t stepx_big;
- pixman_fixed_t dx_small;
- pixman_fixed_t dx_big;
-};
-
-struct pixman_trapezoid
-{
- pixman_fixed_t top, bottom;
- pixman_line_fixed_t left, right;
-};
-
-struct pixman_triangle
-{
- pixman_point_fixed_t p1, p2, p3;
-};
-
-/* whether 't' is a well defined not obviously empty trapezoid */
-#define pixman_trapezoid_valid(t) \
- ((t)->left.p1.y != (t)->left.p2.y && \
- (t)->right.p1.y != (t)->right.p2.y && \
- (int) ((t)->bottom - (t)->top) > 0)
-
-struct pixman_span_fix
-{
- pixman_fixed_t l, r, y;
-};
-
-struct pixman_trap
-{
- pixman_span_fix_t top, bot;
-};
-
-pixman_fixed_t pixman_sample_ceil_y (pixman_fixed_t y,
- int bpp);
-pixman_fixed_t pixman_sample_floor_y (pixman_fixed_t y,
- int bpp);
-void pixman_edge_step (pixman_edge_t *e,
- int n);
-void pixman_edge_init (pixman_edge_t *e,
- int bpp,
- pixman_fixed_t y_start,
- pixman_fixed_t x_top,
- pixman_fixed_t y_top,
- pixman_fixed_t x_bot,
- pixman_fixed_t y_bot);
-void pixman_line_fixed_edge_init (pixman_edge_t *e,
- int bpp,
- pixman_fixed_t y,
- const pixman_line_fixed_t *line,
- int x_off,
- int y_off);
-void pixman_rasterize_edges (pixman_image_t *image,
- pixman_edge_t *l,
- pixman_edge_t *r,
- pixman_fixed_t t,
- pixman_fixed_t b);
-void pixman_add_traps (pixman_image_t *image,
- int16_t x_off,
- int16_t y_off,
- int ntrap,
- pixman_trap_t *traps);
-void pixman_add_trapezoids (pixman_image_t *image,
- int16_t x_off,
- int y_off,
- int ntraps,
- const pixman_trapezoid_t *traps);
-void pixman_rasterize_trapezoid (pixman_image_t *image,
- const pixman_trapezoid_t *trap,
- int x_off,
- int y_off);
-void pixman_composite_trapezoids (pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * dst,
- pixman_format_code_t mask_format,
- int x_src,
- int y_src,
- int x_dst,
- int y_dst,
- int n_traps,
- const pixman_trapezoid_t * traps);
-void pixman_composite_triangles (pixman_op_t op,
- pixman_image_t * src,
- pixman_image_t * dst,
- pixman_format_code_t mask_format,
- int x_src,
- int y_src,
- int x_dst,
- int y_dst,
- int n_tris,
- const pixman_triangle_t * tris);
-void pixman_add_triangles (pixman_image_t *image,
- int32_t x_off,
- int32_t y_off,
- int n_tris,
- const pixman_triangle_t *tris);
-
-PIXMAN_END_DECLS
-
-#endif /* PIXMAN_H__ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/*
+ * Copyright © 1998, 2004 Keith Packard
+ * Copyright 2007 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef PIXMAN_H__
+#define PIXMAN_H__
+
+#include <pixman-version.h>
+
+#ifdef __cplusplus
+#define PIXMAN_BEGIN_DECLS extern "C" {
+#define PIXMAN_END_DECLS }
+#else
+#define PIXMAN_BEGIN_DECLS
+#define PIXMAN_END_DECLS
+#endif
+
+PIXMAN_BEGIN_DECLS
+
+/*
+ * Standard integers
+ */
+
+#if !defined (PIXMAN_DONT_DEFINE_STDINT)
+
+#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined (_sgi) || defined (__sun) || defined (sun) || defined (__digital__) || defined (__HP_cc)
+# include <inttypes.h>
+/* VS 2010 (_MSC_VER 1600) has stdint.h */
+#elif defined (_MSC_VER) && _MSC_VER < 1600
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#elif defined (_AIX)
+# include <sys/inttypes.h>
+#else
+# include <stdint.h>
+#endif
+
+#endif
+
+/*
+ * Boolean
+ */
+typedef int pixman_bool_t;
+
+/*
+ * Fixpoint numbers
+ */
+typedef int64_t pixman_fixed_32_32_t;
+typedef pixman_fixed_32_32_t pixman_fixed_48_16_t;
+typedef uint32_t pixman_fixed_1_31_t;
+typedef uint32_t pixman_fixed_1_16_t;
+typedef int32_t pixman_fixed_16_16_t;
+typedef pixman_fixed_16_16_t pixman_fixed_t;
+
+#define pixman_fixed_e ((pixman_fixed_t) 1)
+#define pixman_fixed_1 (pixman_int_to_fixed(1))
+#define pixman_fixed_1_minus_e (pixman_fixed_1 - pixman_fixed_e)
+#define pixman_fixed_minus_1 (pixman_int_to_fixed(-1))
+#define pixman_fixed_to_int(f) ((int) ((f) >> 16))
+#define pixman_int_to_fixed(i) ((pixman_fixed_t) ((i) << 16))
+#define pixman_fixed_to_double(f) (double) ((f) / (double) pixman_fixed_1)
+#define pixman_double_to_fixed(d) ((pixman_fixed_t) ((d) * 65536.0))
+#define pixman_fixed_frac(f) ((f) & pixman_fixed_1_minus_e)
+#define pixman_fixed_floor(f) ((f) & ~pixman_fixed_1_minus_e)
+#define pixman_fixed_ceil(f) pixman_fixed_floor ((f) + pixman_fixed_1_minus_e)
+#define pixman_fixed_fraction(f) ((f) & pixman_fixed_1_minus_e)
+#define pixman_fixed_mod_2(f) ((f) & (pixman_fixed1 | pixman_fixed_1_minus_e))
+#define pixman_max_fixed_48_16 ((pixman_fixed_48_16_t) 0x7fffffff)
+#define pixman_min_fixed_48_16 (-((pixman_fixed_48_16_t) 1 << 31))
+
+/*
+ * Misc structs
+ */
+typedef struct pixman_color pixman_color_t;
+typedef struct pixman_point_fixed pixman_point_fixed_t;
+typedef struct pixman_line_fixed pixman_line_fixed_t;
+typedef struct pixman_vector pixman_vector_t;
+typedef struct pixman_transform pixman_transform_t;
+
+struct pixman_color
+{
+ uint16_t red;
+ uint16_t green;
+ uint16_t blue;
+ uint16_t alpha;
+};
+
+struct pixman_point_fixed
+{
+ pixman_fixed_t x;
+ pixman_fixed_t y;
+};
+
+struct pixman_line_fixed
+{
+ pixman_point_fixed_t p1, p2;
+};
+
+/*
+ * Fixed point matrices
+ */
+
+struct pixman_vector
+{
+ pixman_fixed_t vector[3];
+};
+
+struct pixman_transform
+{
+ pixman_fixed_t matrix[3][3];
+};
+
+/* forward declaration (sorry) */
+struct pixman_box16;
+typedef union pixman_image pixman_image_t;
+
+void pixman_transform_init_identity (struct pixman_transform *matrix);
+pixman_bool_t pixman_transform_point_3d (const struct pixman_transform *transform,
+ struct pixman_vector *vector);
+pixman_bool_t pixman_transform_point (const struct pixman_transform *transform,
+ struct pixman_vector *vector);
+pixman_bool_t pixman_transform_multiply (struct pixman_transform *dst,
+ const struct pixman_transform *l,
+ const struct pixman_transform *r);
+void pixman_transform_init_scale (struct pixman_transform *t,
+ pixman_fixed_t sx,
+ pixman_fixed_t sy);
+pixman_bool_t pixman_transform_scale (struct pixman_transform *forward,
+ struct pixman_transform *reverse,
+ pixman_fixed_t sx,
+ pixman_fixed_t sy);
+void pixman_transform_init_rotate (struct pixman_transform *t,
+ pixman_fixed_t cos,
+ pixman_fixed_t sin);
+pixman_bool_t pixman_transform_rotate (struct pixman_transform *forward,
+ struct pixman_transform *reverse,
+ pixman_fixed_t c,
+ pixman_fixed_t s);
+void pixman_transform_init_translate (struct pixman_transform *t,
+ pixman_fixed_t tx,
+ pixman_fixed_t ty);
+pixman_bool_t pixman_transform_translate (struct pixman_transform *forward,
+ struct pixman_transform *reverse,
+ pixman_fixed_t tx,
+ pixman_fixed_t ty);
+pixman_bool_t pixman_transform_bounds (const struct pixman_transform *matrix,
+ struct pixman_box16 *b);
+pixman_bool_t pixman_transform_invert (struct pixman_transform *dst,
+ const struct pixman_transform *src);
+pixman_bool_t pixman_transform_is_identity (const struct pixman_transform *t);
+pixman_bool_t pixman_transform_is_scale (const struct pixman_transform *t);
+pixman_bool_t pixman_transform_is_int_translate (const struct pixman_transform *t);
+pixman_bool_t pixman_transform_is_inverse (const struct pixman_transform *a,
+ const struct pixman_transform *b);
+
+/*
+ * Floating point matrices
+ */
+struct pixman_f_vector
+{
+ double v[3];
+};
+
+struct pixman_f_transform
+{
+ double m[3][3];
+};
+
+pixman_bool_t pixman_transform_from_pixman_f_transform (struct pixman_transform *t,
+ const struct pixman_f_transform *ft);
+void pixman_f_transform_from_pixman_transform (struct pixman_f_transform *ft,
+ const struct pixman_transform *t);
+pixman_bool_t pixman_f_transform_invert (struct pixman_f_transform *dst,
+ const struct pixman_f_transform *src);
+pixman_bool_t pixman_f_transform_point (const struct pixman_f_transform *t,
+ struct pixman_f_vector *v);
+void pixman_f_transform_point_3d (const struct pixman_f_transform *t,
+ struct pixman_f_vector *v);
+void pixman_f_transform_multiply (struct pixman_f_transform *dst,
+ const struct pixman_f_transform *l,
+ const struct pixman_f_transform *r);
+void pixman_f_transform_init_scale (struct pixman_f_transform *t,
+ double sx,
+ double sy);
+pixman_bool_t pixman_f_transform_scale (struct pixman_f_transform *forward,
+ struct pixman_f_transform *reverse,
+ double sx,
+ double sy);
+void pixman_f_transform_init_rotate (struct pixman_f_transform *t,
+ double cos,
+ double sin);
+pixman_bool_t pixman_f_transform_rotate (struct pixman_f_transform *forward,
+ struct pixman_f_transform *reverse,
+ double c,
+ double s);
+void pixman_f_transform_init_translate (struct pixman_f_transform *t,
+ double tx,
+ double ty);
+pixman_bool_t pixman_f_transform_translate (struct pixman_f_transform *forward,
+ struct pixman_f_transform *reverse,
+ double tx,
+ double ty);
+pixman_bool_t pixman_f_transform_bounds (const struct pixman_f_transform *t,
+ struct pixman_box16 *b);
+void pixman_f_transform_init_identity (struct pixman_f_transform *t);
+
+typedef enum
+{
+ PIXMAN_REPEAT_NONE,
+ PIXMAN_REPEAT_NORMAL,
+ PIXMAN_REPEAT_PAD,
+ PIXMAN_REPEAT_REFLECT
+} pixman_repeat_t;
+
+typedef enum
+{
+ PIXMAN_FILTER_FAST,
+ PIXMAN_FILTER_GOOD,
+ PIXMAN_FILTER_BEST,
+ PIXMAN_FILTER_NEAREST,
+ PIXMAN_FILTER_BILINEAR,
+ PIXMAN_FILTER_CONVOLUTION
+} pixman_filter_t;
+
+typedef enum
+{
+ PIXMAN_OP_CLEAR = 0x00,
+ PIXMAN_OP_SRC = 0x01,
+ PIXMAN_OP_DST = 0x02,
+ PIXMAN_OP_OVER = 0x03,
+ PIXMAN_OP_OVER_REVERSE = 0x04,
+ PIXMAN_OP_IN = 0x05,
+ PIXMAN_OP_IN_REVERSE = 0x06,
+ PIXMAN_OP_OUT = 0x07,
+ PIXMAN_OP_OUT_REVERSE = 0x08,
+ PIXMAN_OP_ATOP = 0x09,
+ PIXMAN_OP_ATOP_REVERSE = 0x0a,
+ PIXMAN_OP_XOR = 0x0b,
+ PIXMAN_OP_ADD = 0x0c,
+ PIXMAN_OP_SATURATE = 0x0d,
+
+ PIXMAN_OP_DISJOINT_CLEAR = 0x10,
+ PIXMAN_OP_DISJOINT_SRC = 0x11,
+ PIXMAN_OP_DISJOINT_DST = 0x12,
+ PIXMAN_OP_DISJOINT_OVER = 0x13,
+ PIXMAN_OP_DISJOINT_OVER_REVERSE = 0x14,
+ PIXMAN_OP_DISJOINT_IN = 0x15,
+ PIXMAN_OP_DISJOINT_IN_REVERSE = 0x16,
+ PIXMAN_OP_DISJOINT_OUT = 0x17,
+ PIXMAN_OP_DISJOINT_OUT_REVERSE = 0x18,
+ PIXMAN_OP_DISJOINT_ATOP = 0x19,
+ PIXMAN_OP_DISJOINT_ATOP_REVERSE = 0x1a,
+ PIXMAN_OP_DISJOINT_XOR = 0x1b,
+
+ PIXMAN_OP_CONJOINT_CLEAR = 0x20,
+ PIXMAN_OP_CONJOINT_SRC = 0x21,
+ PIXMAN_OP_CONJOINT_DST = 0x22,
+ PIXMAN_OP_CONJOINT_OVER = 0x23,
+ PIXMAN_OP_CONJOINT_OVER_REVERSE = 0x24,
+ PIXMAN_OP_CONJOINT_IN = 0x25,
+ PIXMAN_OP_CONJOINT_IN_REVERSE = 0x26,
+ PIXMAN_OP_CONJOINT_OUT = 0x27,
+ PIXMAN_OP_CONJOINT_OUT_REVERSE = 0x28,
+ PIXMAN_OP_CONJOINT_ATOP = 0x29,
+ PIXMAN_OP_CONJOINT_ATOP_REVERSE = 0x2a,
+ PIXMAN_OP_CONJOINT_XOR = 0x2b,
+
+ PIXMAN_OP_MULTIPLY = 0x30,
+ PIXMAN_OP_SCREEN = 0x31,
+ PIXMAN_OP_OVERLAY = 0x32,
+ PIXMAN_OP_DARKEN = 0x33,
+ PIXMAN_OP_LIGHTEN = 0x34,
+ PIXMAN_OP_COLOR_DODGE = 0x35,
+ PIXMAN_OP_COLOR_BURN = 0x36,
+ PIXMAN_OP_HARD_LIGHT = 0x37,
+ PIXMAN_OP_SOFT_LIGHT = 0x38,
+ PIXMAN_OP_DIFFERENCE = 0x39,
+ PIXMAN_OP_EXCLUSION = 0x3a,
+ PIXMAN_OP_HSL_HUE = 0x3b,
+ PIXMAN_OP_HSL_SATURATION = 0x3c,
+ PIXMAN_OP_HSL_COLOR = 0x3d,
+ PIXMAN_OP_HSL_LUMINOSITY = 0x3e
+
+#ifdef PIXMAN_USE_INTERNAL_API
+ ,
+ PIXMAN_N_OPERATORS,
+ PIXMAN_OP_NONE = PIXMAN_N_OPERATORS
+#endif
+} pixman_op_t;
+
+/*
+ * Regions
+ */
+typedef struct pixman_region16_data pixman_region16_data_t;
+typedef struct pixman_box16 pixman_box16_t;
+typedef struct pixman_rectangle16 pixman_rectangle16_t;
+typedef struct pixman_region16 pixman_region16_t;
+
+struct pixman_region16_data {
+ long size;
+ long numRects;
+/* pixman_box16_t rects[size]; in memory but not explicitly declared */
+};
+
+struct pixman_rectangle16
+{
+ int16_t x, y;
+ uint16_t width, height;
+};
+
+struct pixman_box16
+{
+ int16_t x1, y1, x2, y2;
+};
+
+struct pixman_region16
+{
+ pixman_box16_t extents;
+ pixman_region16_data_t *data;
+};
+
+typedef enum
+{
+ PIXMAN_REGION_OUT,
+ PIXMAN_REGION_IN,
+ PIXMAN_REGION_PART
+} pixman_region_overlap_t;
+
+/* This function exists only to make it possible to preserve
+ * the X ABI - it should go away at first opportunity.
+ */
+void pixman_region_set_static_pointers (pixman_box16_t *empty_box,
+ pixman_region16_data_t *empty_data,
+ pixman_region16_data_t *broken_data);
+
+/* creation/destruction */
+void pixman_region_init (pixman_region16_t *region);
+void pixman_region_init_rect (pixman_region16_t *region,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height);
+pixman_bool_t pixman_region_init_rects (pixman_region16_t *region,
+ const pixman_box16_t *boxes,
+ int count);
+void pixman_region_init_with_extents (pixman_region16_t *region,
+ pixman_box16_t *extents);
+void pixman_region_init_from_image (pixman_region16_t *region,
+ pixman_image_t *image);
+void pixman_region_fini (pixman_region16_t *region);
+
+
+/* manipulation */
+void pixman_region_translate (pixman_region16_t *region,
+ int x,
+ int y);
+pixman_bool_t pixman_region_copy (pixman_region16_t *dest,
+ pixman_region16_t *source);
+pixman_bool_t pixman_region_intersect (pixman_region16_t *new_reg,
+ pixman_region16_t *reg1,
+ pixman_region16_t *reg2);
+pixman_bool_t pixman_region_union (pixman_region16_t *new_reg,
+ pixman_region16_t *reg1,
+ pixman_region16_t *reg2);
+pixman_bool_t pixman_region_union_rect (pixman_region16_t *dest,
+ pixman_region16_t *source,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height);
+pixman_bool_t pixman_region_intersect_rect (pixman_region16_t *dest,
+ pixman_region16_t *source,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height);
+pixman_bool_t pixman_region_subtract (pixman_region16_t *reg_d,
+ pixman_region16_t *reg_m,
+ pixman_region16_t *reg_s);
+pixman_bool_t pixman_region_inverse (pixman_region16_t *new_reg,
+ pixman_region16_t *reg1,
+ pixman_box16_t *inv_rect);
+pixman_bool_t pixman_region_contains_point (pixman_region16_t *region,
+ int x,
+ int y,
+ pixman_box16_t *box);
+pixman_region_overlap_t pixman_region_contains_rectangle (pixman_region16_t *region,
+ pixman_box16_t *prect);
+pixman_bool_t pixman_region_not_empty (pixman_region16_t *region);
+pixman_box16_t * pixman_region_extents (pixman_region16_t *region);
+int pixman_region_n_rects (pixman_region16_t *region);
+pixman_box16_t * pixman_region_rectangles (pixman_region16_t *region,
+ int *n_rects);
+pixman_bool_t pixman_region_equal (pixman_region16_t *region1,
+ pixman_region16_t *region2);
+pixman_bool_t pixman_region_selfcheck (pixman_region16_t *region);
+void pixman_region_reset (pixman_region16_t *region,
+ pixman_box16_t *box);
+/*
+ * 32 bit regions
+ */
+typedef struct pixman_region32_data pixman_region32_data_t;
+typedef struct pixman_box32 pixman_box32_t;
+typedef struct pixman_rectangle32 pixman_rectangle32_t;
+typedef struct pixman_region32 pixman_region32_t;
+
+struct pixman_region32_data {
+ long size;
+ long numRects;
+/* pixman_box32_t rects[size]; in memory but not explicitly declared */
+};
+
+struct pixman_rectangle32
+{
+ int32_t x, y;
+ uint32_t width, height;
+};
+
+struct pixman_box32
+{
+ int32_t x1, y1, x2, y2;
+};
+
+struct pixman_region32
+{
+ pixman_box32_t extents;
+ pixman_region32_data_t *data;
+};
+
+/* creation/destruction */
+void pixman_region32_init (pixman_region32_t *region);
+void pixman_region32_init_rect (pixman_region32_t *region,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height);
+pixman_bool_t pixman_region32_init_rects (pixman_region32_t *region,
+ const pixman_box32_t *boxes,
+ int count);
+void pixman_region32_init_with_extents (pixman_region32_t *region,
+ pixman_box32_t *extents);
+void pixman_region32_init_from_image (pixman_region32_t *region,
+ pixman_image_t *image);
+void pixman_region32_fini (pixman_region32_t *region);
+
+
+/* manipulation */
+void pixman_region32_translate (pixman_region32_t *region,
+ int x,
+ int y);
+pixman_bool_t pixman_region32_copy (pixman_region32_t *dest,
+ pixman_region32_t *source);
+pixman_bool_t pixman_region32_intersect (pixman_region32_t *new_reg,
+ pixman_region32_t *reg1,
+ pixman_region32_t *reg2);
+pixman_bool_t pixman_region32_union (pixman_region32_t *new_reg,
+ pixman_region32_t *reg1,
+ pixman_region32_t *reg2);
+pixman_bool_t pixman_region32_intersect_rect (pixman_region32_t *dest,
+ pixman_region32_t *source,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height);
+pixman_bool_t pixman_region32_union_rect (pixman_region32_t *dest,
+ pixman_region32_t *source,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height);
+pixman_bool_t pixman_region32_subtract (pixman_region32_t *reg_d,
+ pixman_region32_t *reg_m,
+ pixman_region32_t *reg_s);
+pixman_bool_t pixman_region32_inverse (pixman_region32_t *new_reg,
+ pixman_region32_t *reg1,
+ pixman_box32_t *inv_rect);
+pixman_bool_t pixman_region32_contains_point (pixman_region32_t *region,
+ int x,
+ int y,
+ pixman_box32_t *box);
+pixman_region_overlap_t pixman_region32_contains_rectangle (pixman_region32_t *region,
+ pixman_box32_t *prect);
+pixman_bool_t pixman_region32_not_empty (pixman_region32_t *region);
+pixman_box32_t * pixman_region32_extents (pixman_region32_t *region);
+int pixman_region32_n_rects (pixman_region32_t *region);
+pixman_box32_t * pixman_region32_rectangles (pixman_region32_t *region,
+ int *n_rects);
+pixman_bool_t pixman_region32_equal (pixman_region32_t *region1,
+ pixman_region32_t *region2);
+pixman_bool_t pixman_region32_selfcheck (pixman_region32_t *region);
+void pixman_region32_reset (pixman_region32_t *region,
+ pixman_box32_t *box);
+
+
+/* Copy / Fill / Misc */
+pixman_bool_t pixman_blt (uint32_t *src_bits,
+ uint32_t *dst_bits,
+ int src_stride,
+ int dst_stride,
+ int src_bpp,
+ int dst_bpp,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ int width,
+ int height);
+pixman_bool_t pixman_fill (uint32_t *bits,
+ int stride,
+ int bpp,
+ int x,
+ int y,
+ int width,
+ int height,
+ uint32_t _xor);
+
+int pixman_version (void);
+const char* pixman_version_string (void);
+
+/*
+ * Images
+ */
+typedef struct pixman_indexed pixman_indexed_t;
+typedef struct pixman_gradient_stop pixman_gradient_stop_t;
+
+typedef uint32_t (* pixman_read_memory_func_t) (const void *src, int size);
+typedef void (* pixman_write_memory_func_t) (void *dst, uint32_t value, int size);
+
+typedef void (* pixman_image_destroy_func_t) (pixman_image_t *image, void *data);
+
+struct pixman_gradient_stop {
+ pixman_fixed_t x;
+ pixman_color_t color;
+};
+
+#define PIXMAN_MAX_INDEXED 256 /* XXX depth must be <= 8 */
+
+#if PIXMAN_MAX_INDEXED <= 256
+typedef uint8_t pixman_index_type;
+#endif
+
+struct pixman_indexed
+{
+ pixman_bool_t color;
+ uint32_t rgba[PIXMAN_MAX_INDEXED];
+ pixman_index_type ent[32768];
+};
+
+/*
+ * While the protocol is generous in format support, the
+ * sample implementation allows only packed RGB and GBR
+ * representations for data to simplify software rendering,
+ */
+#define PIXMAN_FORMAT(bpp,type,a,r,g,b) (((bpp) << 24) | \
+ ((type) << 16) | \
+ ((a) << 12) | \
+ ((r) << 8) | \
+ ((g) << 4) | \
+ ((b)))
+
+#define PIXMAN_FORMAT_BPP(f) (((f) >> 24) )
+#define PIXMAN_FORMAT_TYPE(f) (((f) >> 16) & 0xff)
+#define PIXMAN_FORMAT_A(f) (((f) >> 12) & 0x0f)
+#define PIXMAN_FORMAT_R(f) (((f) >> 8) & 0x0f)
+#define PIXMAN_FORMAT_G(f) (((f) >> 4) & 0x0f)
+#define PIXMAN_FORMAT_B(f) (((f) ) & 0x0f)
+#define PIXMAN_FORMAT_RGB(f) (((f) ) & 0xfff)
+#define PIXMAN_FORMAT_VIS(f) (((f) ) & 0xffff)
+#define PIXMAN_FORMAT_DEPTH(f) (PIXMAN_FORMAT_A(f) + \
+ PIXMAN_FORMAT_R(f) + \
+ PIXMAN_FORMAT_G(f) + \
+ PIXMAN_FORMAT_B(f))
+
+#define PIXMAN_TYPE_OTHER 0
+#define PIXMAN_TYPE_A 1
+#define PIXMAN_TYPE_ARGB 2
+#define PIXMAN_TYPE_ABGR 3
+#define PIXMAN_TYPE_COLOR 4
+#define PIXMAN_TYPE_GRAY 5
+#define PIXMAN_TYPE_YUY2 6
+#define PIXMAN_TYPE_YV12 7
+#define PIXMAN_TYPE_BGRA 8
+#define PIXMAN_TYPE_RGBA 9
+
+#define PIXMAN_FORMAT_COLOR(f) \
+ (PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB || \
+ PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR || \
+ PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_BGRA || \
+ PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_RGBA)
+
+/* 32bpp formats */
+typedef enum {
+ PIXMAN_a8r8g8b8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,8,8,8,8),
+ PIXMAN_x8r8g8b8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,8,8,8),
+ PIXMAN_a8b8g8r8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,8,8,8,8),
+ PIXMAN_x8b8g8r8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,0,8,8,8),
+ PIXMAN_b8g8r8a8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_BGRA,8,8,8,8),
+ PIXMAN_b8g8r8x8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_BGRA,0,8,8,8),
+ PIXMAN_r8g8b8a8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_RGBA,8,8,8,8),
+ PIXMAN_r8g8b8x8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_RGBA,0,8,8,8),
+ PIXMAN_x14r6g6b6 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,6,6,6),
+ PIXMAN_x2r10g10b10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,10,10,10),
+ PIXMAN_a2r10g10b10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,2,10,10,10),
+ PIXMAN_x2b10g10r10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,0,10,10,10),
+ PIXMAN_a2b10g10r10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,2,10,10,10),
+
+/* 24bpp formats */
+ PIXMAN_r8g8b8 = PIXMAN_FORMAT(24,PIXMAN_TYPE_ARGB,0,8,8,8),
+ PIXMAN_b8g8r8 = PIXMAN_FORMAT(24,PIXMAN_TYPE_ABGR,0,8,8,8),
+
+/* 16bpp formats */
+ PIXMAN_r5g6b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,5,6,5),
+ PIXMAN_b5g6r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,5,6,5),
+
+ PIXMAN_a1r5g5b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,1,5,5,5),
+ PIXMAN_x1r5g5b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,5,5,5),
+ PIXMAN_a1b5g5r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,1,5,5,5),
+ PIXMAN_x1b5g5r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,5,5,5),
+ PIXMAN_a4r4g4b4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,4,4,4,4),
+ PIXMAN_x4r4g4b4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,4,4,4),
+ PIXMAN_a4b4g4r4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,4,4,4,4),
+ PIXMAN_x4b4g4r4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,4,4,4),
+
+/* 8bpp formats */
+ PIXMAN_a8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_A,8,0,0,0),
+ PIXMAN_r3g3b2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ARGB,0,3,3,2),
+ PIXMAN_b2g3r3 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ABGR,0,3,3,2),
+ PIXMAN_a2r2g2b2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ARGB,2,2,2,2),
+ PIXMAN_a2b2g2r2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ABGR,2,2,2,2),
+
+ PIXMAN_c8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_COLOR,0,0,0,0),
+ PIXMAN_g8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_GRAY,0,0,0,0),
+
+ PIXMAN_x4a4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_A,4,0,0,0),
+
+ PIXMAN_x4c4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_COLOR,0,0,0,0),
+ PIXMAN_x4g4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_GRAY,0,0,0,0),
+
+/* 4bpp formats */
+ PIXMAN_a4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_A,4,0,0,0),
+ PIXMAN_r1g2b1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ARGB,0,1,2,1),
+ PIXMAN_b1g2r1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ABGR,0,1,2,1),
+ PIXMAN_a1r1g1b1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ARGB,1,1,1,1),
+ PIXMAN_a1b1g1r1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ABGR,1,1,1,1),
+
+ PIXMAN_c4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_COLOR,0,0,0,0),
+ PIXMAN_g4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_GRAY,0,0,0,0),
+
+/* 1bpp formats */
+ PIXMAN_a1 = PIXMAN_FORMAT(1,PIXMAN_TYPE_A,1,0,0,0),
+
+ PIXMAN_g1 = PIXMAN_FORMAT(1,PIXMAN_TYPE_GRAY,0,0,0,0),
+
+/* YUV formats */
+ PIXMAN_yuy2 = PIXMAN_FORMAT(16,PIXMAN_TYPE_YUY2,0,0,0,0),
+ PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0)
+} pixman_format_code_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);
+
+/* Constructors */
+pixman_image_t *pixman_image_create_solid_fill (pixman_color_t *color);
+pixman_image_t *pixman_image_create_linear_gradient (pixman_point_fixed_t *p1,
+ pixman_point_fixed_t *p2,
+ const pixman_gradient_stop_t *stops,
+ int n_stops);
+pixman_image_t *pixman_image_create_radial_gradient (pixman_point_fixed_t *inner,
+ pixman_point_fixed_t *outer,
+ pixman_fixed_t inner_radius,
+ pixman_fixed_t outer_radius,
+ const pixman_gradient_stop_t *stops,
+ int n_stops);
+pixman_image_t *pixman_image_create_conical_gradient (pixman_point_fixed_t *center,
+ pixman_fixed_t angle,
+ const pixman_gradient_stop_t *stops,
+ int n_stops);
+pixman_image_t *pixman_image_create_bits (pixman_format_code_t format,
+ int width,
+ int height,
+ uint32_t *bits,
+ int rowstride_bytes);
+
+/* Destructor */
+pixman_image_t *pixman_image_ref (pixman_image_t *image);
+pixman_bool_t pixman_image_unref (pixman_image_t *image);
+
+void pixman_image_set_destroy_function (pixman_image_t *image,
+ pixman_image_destroy_func_t function,
+ void *data);
+void * pixman_image_get_destroy_data (pixman_image_t *image);
+
+/* Set properties */
+pixman_bool_t pixman_image_set_clip_region (pixman_image_t *image,
+ pixman_region16_t *region);
+pixman_bool_t pixman_image_set_clip_region32 (pixman_image_t *image,
+ pixman_region32_t *region);
+void pixman_image_set_has_client_clip (pixman_image_t *image,
+ pixman_bool_t clien_clip);
+pixman_bool_t pixman_image_set_transform (pixman_image_t *image,
+ const pixman_transform_t *transform);
+void pixman_image_set_repeat (pixman_image_t *image,
+ pixman_repeat_t repeat);
+pixman_bool_t pixman_image_set_filter (pixman_image_t *image,
+ pixman_filter_t filter,
+ const pixman_fixed_t *filter_params,
+ int n_filter_params);
+void pixman_image_set_source_clipping (pixman_image_t *image,
+ pixman_bool_t source_clipping);
+void pixman_image_set_alpha_map (pixman_image_t *image,
+ pixman_image_t *alpha_map,
+ int16_t x,
+ int16_t y);
+void pixman_image_set_component_alpha (pixman_image_t *image,
+ pixman_bool_t component_alpha);
+pixman_bool_t pixman_image_get_component_alpha (pixman_image_t *image);
+void pixman_image_set_accessors (pixman_image_t *image,
+ pixman_read_memory_func_t read_func,
+ pixman_write_memory_func_t write_func);
+void pixman_image_set_indexed (pixman_image_t *image,
+ const pixman_indexed_t *indexed);
+uint32_t *pixman_image_get_data (pixman_image_t *image);
+int pixman_image_get_width (pixman_image_t *image);
+int pixman_image_get_height (pixman_image_t *image);
+int pixman_image_get_stride (pixman_image_t *image); /* in bytes */
+int pixman_image_get_depth (pixman_image_t *image);
+pixman_format_code_t pixman_image_get_format (pixman_image_t *image);
+pixman_bool_t pixman_image_fill_rectangles (pixman_op_t op,
+ pixman_image_t *image,
+ pixman_color_t *color,
+ int n_rects,
+ const pixman_rectangle16_t *rects);
+pixman_bool_t pixman_image_fill_boxes (pixman_op_t op,
+ pixman_image_t *dest,
+ pixman_color_t *color,
+ int n_boxes,
+ const pixman_box32_t *boxes);
+
+/* Composite */
+pixman_bool_t pixman_compute_composite_region (pixman_region16_t *region,
+ pixman_image_t *src_image,
+ pixman_image_t *mask_image,
+ pixman_image_t *dst_image,
+ int16_t src_x,
+ int16_t src_y,
+ int16_t mask_x,
+ int16_t mask_y,
+ int16_t dest_x,
+ int16_t dest_y,
+ uint16_t width,
+ uint16_t height);
+void pixman_image_composite (pixman_op_t op,
+ pixman_image_t *src,
+ pixman_image_t *mask,
+ pixman_image_t *dest,
+ int16_t src_x,
+ int16_t src_y,
+ int16_t mask_x,
+ int16_t mask_y,
+ int16_t dest_x,
+ int16_t dest_y,
+ uint16_t width,
+ uint16_t height);
+void pixman_image_composite32 (pixman_op_t op,
+ pixman_image_t *src,
+ pixman_image_t *mask,
+ pixman_image_t *dest,
+ int32_t src_x,
+ int32_t src_y,
+ int32_t mask_x,
+ int32_t mask_y,
+ int32_t dest_x,
+ int32_t dest_y,
+ int32_t width,
+ int32_t height);
+
+/* Executive Summary: This function is a no-op that only exists
+ * for historical reasons.
+ *
+ * There used to be a bug in the X server where it would rely on
+ * out-of-bounds accesses when it was asked to composite with a
+ * window as the source. It would create a pixman image pointing
+ * to some bogus position in memory, but then set a clip region
+ * to the position where the actual bits were.
+ *
+ * Due to a bug in old versions of pixman, where it would not clip
+ * against the image bounds when a clip region was set, this would
+ * actually work. So when the pixman bug was fixed, a workaround was
+ * added to allow certain out-of-bound accesses. This function disabled
+ * those workarounds.
+ *
+ * Since 0.21.2, pixman doesn't do these workarounds anymore, so now this
+ * function is a no-op.
+ */
+void pixman_disable_out_of_bounds_workaround (void);
+
+/*
+ * Trapezoids
+ */
+typedef struct pixman_edge pixman_edge_t;
+typedef struct pixman_trapezoid pixman_trapezoid_t;
+typedef struct pixman_trap pixman_trap_t;
+typedef struct pixman_span_fix pixman_span_fix_t;
+typedef struct pixman_triangle pixman_triangle_t;
+
+/*
+ * An edge structure. This represents a single polygon edge
+ * and can be quickly stepped across small or large gaps in the
+ * sample grid
+ */
+struct pixman_edge
+{
+ pixman_fixed_t x;
+ pixman_fixed_t e;
+ pixman_fixed_t stepx;
+ pixman_fixed_t signdx;
+ pixman_fixed_t dy;
+ pixman_fixed_t dx;
+
+ pixman_fixed_t stepx_small;
+ pixman_fixed_t stepx_big;
+ pixman_fixed_t dx_small;
+ pixman_fixed_t dx_big;
+};
+
+struct pixman_trapezoid
+{
+ pixman_fixed_t top, bottom;
+ pixman_line_fixed_t left, right;
+};
+
+struct pixman_triangle
+{
+ pixman_point_fixed_t p1, p2, p3;
+};
+
+/* whether 't' is a well defined not obviously empty trapezoid */
+#define pixman_trapezoid_valid(t) \
+ ((t)->left.p1.y != (t)->left.p2.y && \
+ (t)->right.p1.y != (t)->right.p2.y && \
+ (int) ((t)->bottom - (t)->top) > 0)
+
+struct pixman_span_fix
+{
+ pixman_fixed_t l, r, y;
+};
+
+struct pixman_trap
+{
+ pixman_span_fix_t top, bot;
+};
+
+pixman_fixed_t pixman_sample_ceil_y (pixman_fixed_t y,
+ int bpp);
+pixman_fixed_t pixman_sample_floor_y (pixman_fixed_t y,
+ int bpp);
+void pixman_edge_step (pixman_edge_t *e,
+ int n);
+void pixman_edge_init (pixman_edge_t *e,
+ int bpp,
+ pixman_fixed_t y_start,
+ pixman_fixed_t x_top,
+ pixman_fixed_t y_top,
+ pixman_fixed_t x_bot,
+ pixman_fixed_t y_bot);
+void pixman_line_fixed_edge_init (pixman_edge_t *e,
+ int bpp,
+ pixman_fixed_t y,
+ const pixman_line_fixed_t *line,
+ int x_off,
+ int y_off);
+void pixman_rasterize_edges (pixman_image_t *image,
+ pixman_edge_t *l,
+ pixman_edge_t *r,
+ pixman_fixed_t t,
+ pixman_fixed_t b);
+void pixman_add_traps (pixman_image_t *image,
+ int16_t x_off,
+ int16_t y_off,
+ int ntrap,
+ pixman_trap_t *traps);
+void pixman_add_trapezoids (pixman_image_t *image,
+ int16_t x_off,
+ int y_off,
+ int ntraps,
+ const pixman_trapezoid_t *traps);
+void pixman_rasterize_trapezoid (pixman_image_t *image,
+ const pixman_trapezoid_t *trap,
+ int x_off,
+ int y_off);
+void pixman_composite_trapezoids (pixman_op_t op,
+ pixman_image_t * src,
+ pixman_image_t * dst,
+ pixman_format_code_t mask_format,
+ int x_src,
+ int y_src,
+ int x_dst,
+ int y_dst,
+ int n_traps,
+ const pixman_trapezoid_t * traps);
+void pixman_composite_triangles (pixman_op_t op,
+ pixman_image_t * src,
+ pixman_image_t * dst,
+ pixman_format_code_t mask_format,
+ int x_src,
+ int y_src,
+ int x_dst,
+ int y_dst,
+ int n_tris,
+ const pixman_triangle_t * tris);
+void pixman_add_triangles (pixman_image_t *image,
+ int32_t x_off,
+ int32_t y_off,
+ int n_tris,
+ const pixman_triangle_t *tris);
+
+PIXMAN_END_DECLS
+
+#endif /* PIXMAN_H__ */
diff --git a/pixman/test/blitters-test.c b/pixman/test/blitters-test.c
index 5a867f23a..3ecfb0994 100644
--- a/pixman/test/blitters-test.c
+++ b/pixman/test/blitters-test.c
@@ -1,417 +1,422 @@
-/*
- * Test program, which stresses the use of different color formats and
- * compositing operations.
- *
- * Script 'fuzzer-find-diff.pl' can be used to narrow down the problem in
- * the case of test failure.
- */
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <config.h>
-#include "utils.h"
-
-static pixman_indexed_t rgb_palette[9];
-static pixman_indexed_t y_palette[9];
-
-/* Create random image for testing purposes */
-static pixman_image_t *
-create_random_image (pixman_format_code_t *allowed_formats,
- int max_width,
- int max_height,
- int max_extra_stride,
- pixman_format_code_t *used_fmt)
-{
- int n = 0, i, width, height, stride;
- pixman_format_code_t fmt;
- uint32_t *buf;
- pixman_image_t *img;
-
- while (allowed_formats[n] != PIXMAN_null)
- n++;
- fmt = allowed_formats[lcg_rand_n (n)];
-
- width = lcg_rand_n (max_width) + 1;
- height = lcg_rand_n (max_height) + 1;
- stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 +
- lcg_rand_n (max_extra_stride + 1);
- stride = (stride + 3) & ~3;
-
- /* do the allocation */
- buf = aligned_malloc (64, stride * height);
-
- /* initialize image with random data */
- for (i = 0; i < stride * height; i++)
- {
- /* generation is biased to having more 0 or 255 bytes as
- * they are more likely to be special-cased in code
- */
- *((uint8_t *)buf + i) = lcg_rand_n (4) ? lcg_rand_n (256) :
- (lcg_rand_n (2) ? 0 : 255);
- }
-
- img = pixman_image_create_bits (fmt, width, height, buf, stride);
-
- if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR)
- {
- pixman_image_set_indexed (img, &(rgb_palette[PIXMAN_FORMAT_BPP (fmt)]));
- }
- else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY)
- {
- pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)]));
- }
-
- image_endian_swap (img);
-
- if (used_fmt) *used_fmt = fmt;
- return img;
-}
-
-/* Free random image, and optionally update crc32 based on its data */
-static uint32_t
-free_random_image (uint32_t initcrc,
- pixman_image_t *img,
- pixman_format_code_t fmt)
-{
- uint32_t crc32 = 0;
- int stride = pixman_image_get_stride (img);
- uint32_t *data = pixman_image_get_data (img);
- int height = pixman_image_get_height (img);
-
- if (fmt != PIXMAN_null)
- {
- /* mask unused 'x' part */
- if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) &&
- PIXMAN_FORMAT_DEPTH (fmt) != 0)
- {
- int i;
- uint32_t *data = pixman_image_get_data (img);
- uint32_t mask = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1;
-
- if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA)
- mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
-
- for (i = 0; i < 32; i++)
- mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));
-
- for (i = 0; i < stride * height / 4; i++)
- data[i] &= mask;
- }
-
- /* swap endiannes in order to provide identical results on both big
- * and litte endian systems
- */
- image_endian_swap (img);
- crc32 = compute_crc32 (initcrc, data, stride * height);
- }
-
- pixman_image_unref (img);
- free (data);
-
- return crc32;
-}
-
-static pixman_op_t op_list[] = {
- PIXMAN_OP_SRC,
- PIXMAN_OP_OVER,
- PIXMAN_OP_ADD,
- PIXMAN_OP_CLEAR,
- PIXMAN_OP_SRC,
- PIXMAN_OP_DST,
- PIXMAN_OP_OVER,
- PIXMAN_OP_OVER_REVERSE,
- PIXMAN_OP_IN,
- PIXMAN_OP_IN_REVERSE,
- PIXMAN_OP_OUT,
- PIXMAN_OP_OUT_REVERSE,
- PIXMAN_OP_ATOP,
- PIXMAN_OP_ATOP_REVERSE,
- PIXMAN_OP_XOR,
- PIXMAN_OP_ADD,
- PIXMAN_OP_SATURATE,
- PIXMAN_OP_DISJOINT_CLEAR,
- PIXMAN_OP_DISJOINT_SRC,
- PIXMAN_OP_DISJOINT_DST,
- PIXMAN_OP_DISJOINT_OVER,
- PIXMAN_OP_DISJOINT_OVER_REVERSE,
- PIXMAN_OP_DISJOINT_IN,
- PIXMAN_OP_DISJOINT_IN_REVERSE,
- PIXMAN_OP_DISJOINT_OUT,
- PIXMAN_OP_DISJOINT_OUT_REVERSE,
- PIXMAN_OP_DISJOINT_ATOP,
- PIXMAN_OP_DISJOINT_ATOP_REVERSE,
- PIXMAN_OP_DISJOINT_XOR,
- PIXMAN_OP_CONJOINT_CLEAR,
- PIXMAN_OP_CONJOINT_SRC,
- PIXMAN_OP_CONJOINT_DST,
- PIXMAN_OP_CONJOINT_OVER,
- PIXMAN_OP_CONJOINT_OVER_REVERSE,
- PIXMAN_OP_CONJOINT_IN,
- PIXMAN_OP_CONJOINT_IN_REVERSE,
- PIXMAN_OP_CONJOINT_OUT,
- PIXMAN_OP_CONJOINT_OUT_REVERSE,
- PIXMAN_OP_CONJOINT_ATOP,
- PIXMAN_OP_CONJOINT_ATOP_REVERSE,
- PIXMAN_OP_CONJOINT_XOR,
- PIXMAN_OP_MULTIPLY,
- PIXMAN_OP_SCREEN,
- PIXMAN_OP_OVERLAY,
- PIXMAN_OP_DARKEN,
- PIXMAN_OP_LIGHTEN,
- PIXMAN_OP_COLOR_DODGE,
- PIXMAN_OP_COLOR_BURN,
- PIXMAN_OP_HARD_LIGHT,
- PIXMAN_OP_DIFFERENCE,
- PIXMAN_OP_EXCLUSION,
-#if 0 /* these use floating point math and are not always bitexact on different platforms */
- PIXMAN_OP_SOFT_LIGHT,
- PIXMAN_OP_HSL_HUE,
- PIXMAN_OP_HSL_SATURATION,
- PIXMAN_OP_HSL_COLOR,
- PIXMAN_OP_HSL_LUMINOSITY,
-#endif
-};
-
-static pixman_format_code_t img_fmt_list[] = {
- PIXMAN_a8r8g8b8,
- PIXMAN_x8r8g8b8,
- PIXMAN_r5g6b5,
- PIXMAN_r3g3b2,
- PIXMAN_a8,
- PIXMAN_a8b8g8r8,
- PIXMAN_x8b8g8r8,
- PIXMAN_b8g8r8a8,
- PIXMAN_b8g8r8x8,
- PIXMAN_x14r6g6b6,
- PIXMAN_r8g8b8,
- PIXMAN_b8g8r8,
- PIXMAN_r5g6b5,
- PIXMAN_b5g6r5,
- PIXMAN_x2r10g10b10,
- PIXMAN_a2r10g10b10,
- PIXMAN_x2b10g10r10,
- PIXMAN_a2b10g10r10,
- PIXMAN_a1r5g5b5,
- PIXMAN_x1r5g5b5,
- PIXMAN_a1b5g5r5,
- PIXMAN_x1b5g5r5,
- PIXMAN_a4r4g4b4,
- PIXMAN_x4r4g4b4,
- PIXMAN_a4b4g4r4,
- PIXMAN_x4b4g4r4,
- PIXMAN_a8,
- PIXMAN_r3g3b2,
- PIXMAN_b2g3r3,
- PIXMAN_a2r2g2b2,
- PIXMAN_a2b2g2r2,
- PIXMAN_c8,
- PIXMAN_g8,
- PIXMAN_x4c4,
- PIXMAN_x4g4,
- PIXMAN_c4,
- PIXMAN_g4,
- PIXMAN_g1,
- PIXMAN_x4a4,
- PIXMAN_a4,
- PIXMAN_r1g2b1,
- PIXMAN_b1g2r1,
- PIXMAN_a1r1g1b1,
- PIXMAN_a1b1g1r1,
- PIXMAN_a1,
- PIXMAN_null
-};
-
-static pixman_format_code_t mask_fmt_list[] = {
- PIXMAN_a8r8g8b8,
- PIXMAN_a8,
- PIXMAN_a4,
- PIXMAN_a1,
- PIXMAN_null
-};
-
-
-/*
- * Composite operation with pseudorandom images
- */
-uint32_t
-test_composite (int testnum, int verbose)
-{
- int i;
- pixman_image_t *src_img = NULL;
- pixman_image_t *dst_img = NULL;
- pixman_image_t *mask_img = NULL;
- int src_width, src_height;
- int dst_width, dst_height;
- int src_stride, dst_stride;
- int src_x, src_y;
- int dst_x, dst_y;
- int mask_x, mask_y;
- int w, h;
- pixman_op_t op;
- pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
- uint32_t *dstbuf, *srcbuf, *maskbuf;
- uint32_t crc32;
- int max_width, max_height, max_extra_stride;
- FLOAT_REGS_CORRUPTION_DETECTOR_START ();
-
- max_width = max_height = 24 + testnum / 10000;
- max_extra_stride = 4 + testnum / 1000000;
-
- if (max_width > 256)
- max_width = 256;
-
- if (max_height > 16)
- max_height = 16;
-
- if (max_extra_stride > 8)
- max_extra_stride = 8;
-
- lcg_srand (testnum);
-
- op = op_list[lcg_rand_n (sizeof (op_list) / sizeof (op_list[0]))];
-
- if (lcg_rand_n (8))
- {
- /* normal image */
- src_img = create_random_image (img_fmt_list, max_width, max_height,
- max_extra_stride, &src_fmt);
- }
- else
- {
- /* solid case */
- src_img = create_random_image (img_fmt_list, 1, 1,
- max_extra_stride, &src_fmt);
-
- pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
- }
-
- dst_img = create_random_image (img_fmt_list, max_width, max_height,
- max_extra_stride, &dst_fmt);
-
- src_width = pixman_image_get_width (src_img);
- src_height = pixman_image_get_height (src_img);
- src_stride = pixman_image_get_stride (src_img);
-
- dst_width = pixman_image_get_width (dst_img);
- dst_height = pixman_image_get_height (dst_img);
- dst_stride = pixman_image_get_stride (dst_img);
-
- dstbuf = pixman_image_get_data (dst_img);
- srcbuf = pixman_image_get_data (src_img);
-
- src_x = lcg_rand_n (src_width);
- src_y = lcg_rand_n (src_height);
- dst_x = lcg_rand_n (dst_width);
- dst_y = lcg_rand_n (dst_height);
-
- mask_img = NULL;
- mask_fmt = PIXMAN_null;
- mask_x = 0;
- mask_y = 0;
- maskbuf = NULL;
-
- if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) &&
- (lcg_rand_n (4) == 0))
- {
- /* PIXBUF */
- mask_fmt = lcg_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
- mask_img = pixman_image_create_bits (mask_fmt,
- src_width,
- src_height,
- srcbuf,
- src_stride);
- mask_x = src_x;
- mask_y = src_y;
- maskbuf = srcbuf;
- }
- else if (lcg_rand_n (2))
- {
- if (lcg_rand_n (2))
- {
- mask_img = create_random_image (mask_fmt_list, max_width, max_height,
- max_extra_stride, &mask_fmt);
- }
- else
- {
- /* solid case */
- mask_img = create_random_image (mask_fmt_list, 1, 1,
- max_extra_stride, &mask_fmt);
- pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
- }
-
- if (lcg_rand_n (2))
- pixman_image_set_component_alpha (mask_img, 1);
-
- mask_x = lcg_rand_n (pixman_image_get_width (mask_img));
- mask_y = lcg_rand_n (pixman_image_get_height (mask_img));
- }
-
-
- w = lcg_rand_n (dst_width - dst_x + 1);
- h = lcg_rand_n (dst_height - dst_y + 1);
-
- if (verbose)
- {
- printf ("op=%d, src_fmt=%08X, dst_fmt=%08X, mask_fmt=%08X\n",
- op, src_fmt, dst_fmt, mask_fmt);
- printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
- src_width, src_height, dst_width, dst_height);
- printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
- src_x, src_y, dst_x, dst_y);
- printf ("src_stride=%d, dst_stride=%d\n",
- src_stride, dst_stride);
- printf ("w=%d, h=%d\n", w, h);
- }
-
- pixman_image_composite (op, src_img, mask_img, dst_img,
- src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);
-
- if (verbose)
- {
- int j;
-
- printf ("---\n");
- for (i = 0; i < dst_height; i++)
- {
- for (j = 0; j < dst_stride; j++)
- {
- if (j == (dst_width * PIXMAN_FORMAT_BPP (dst_fmt) + 7) / 8)
- printf ("| ");
-
- printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j));
- }
- printf ("\n");
- }
- printf ("---\n");
- }
-
- free_random_image (0, src_img, PIXMAN_null);
- crc32 = free_random_image (0, dst_img, dst_fmt);
-
- if (mask_img)
- {
- if (srcbuf == maskbuf)
- pixman_image_unref(mask_img);
- else
- free_random_image (0, mask_img, PIXMAN_null);
- }
-
- FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
- return crc32;
-}
-
-int
-main (int argc, const char *argv[])
-{
- int i;
-
- for (i = 1; i <= 8; i++)
- {
- initialize_palette (&(rgb_palette[i]), i, TRUE);
- initialize_palette (&(y_palette[i]), i, FALSE);
- }
-
- return fuzzer_test_main("blitters", 2000000,
- 0x1DB8BDF8,
- test_composite, argc, argv);
-}
+/*
+ * Test program, which stresses the use of different color formats and
+ * compositing operations.
+ *
+ * Script 'fuzzer-find-diff.pl' can be used to narrow down the problem in
+ * the case of test failure.
+ */
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <config.h>
+#include "utils.h"
+
+static pixman_indexed_t rgb_palette[9];
+static pixman_indexed_t y_palette[9];
+
+/* Create random image for testing purposes */
+static pixman_image_t *
+create_random_image (pixman_format_code_t *allowed_formats,
+ int max_width,
+ int max_height,
+ int max_extra_stride,
+ pixman_format_code_t *used_fmt)
+{
+ int n = 0, i, width, height, stride;
+ pixman_format_code_t fmt;
+ uint32_t *buf;
+ pixman_image_t *img;
+
+ while (allowed_formats[n] != PIXMAN_null)
+ n++;
+ fmt = allowed_formats[lcg_rand_n (n)];
+
+ width = lcg_rand_n (max_width) + 1;
+ height = lcg_rand_n (max_height) + 1;
+ stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 +
+ lcg_rand_n (max_extra_stride + 1);
+ stride = (stride + 3) & ~3;
+
+ /* do the allocation */
+ buf = aligned_malloc (64, stride * height);
+
+ /* initialize image with random data */
+ for (i = 0; i < stride * height; i++)
+ {
+ /* generation is biased to having more 0 or 255 bytes as
+ * they are more likely to be special-cased in code
+ */
+ *((uint8_t *)buf + i) = lcg_rand_n (4) ? lcg_rand_n (256) :
+ (lcg_rand_n (2) ? 0 : 255);
+ }
+
+ img = pixman_image_create_bits (fmt, width, height, buf, stride);
+
+ if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR)
+ {
+ pixman_image_set_indexed (img, &(rgb_palette[PIXMAN_FORMAT_BPP (fmt)]));
+ }
+ else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY)
+ {
+ pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)]));
+ }
+
+ image_endian_swap (img);
+
+ if (used_fmt) *used_fmt = fmt;
+ return img;
+}
+
+/* Free random image, and optionally update crc32 based on its data */
+static uint32_t
+free_random_image (uint32_t initcrc,
+ pixman_image_t *img,
+ pixman_format_code_t fmt)
+{
+ uint32_t crc32 = 0;
+ int stride = pixman_image_get_stride (img);
+ uint32_t *data = pixman_image_get_data (img);
+ int height = pixman_image_get_height (img);
+
+ if (fmt != PIXMAN_null)
+ {
+ /* mask unused 'x' part */
+ if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) &&
+ PIXMAN_FORMAT_DEPTH (fmt) != 0)
+ {
+ int i;
+ uint32_t *data = pixman_image_get_data (img);
+ uint32_t mask = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1;
+
+ if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
+ PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA)
+ {
+ mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
+ }
+
+ for (i = 0; i < 32; i++)
+ mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));
+
+ for (i = 0; i < stride * height / 4; i++)
+ data[i] &= mask;
+ }
+
+ /* swap endiannes in order to provide identical results on both big
+ * and litte endian systems
+ */
+ image_endian_swap (img);
+ crc32 = compute_crc32 (initcrc, data, stride * height);
+ }
+
+ pixman_image_unref (img);
+ free (data);
+
+ return crc32;
+}
+
+static pixman_op_t op_list[] = {
+ PIXMAN_OP_SRC,
+ PIXMAN_OP_OVER,
+ PIXMAN_OP_ADD,
+ PIXMAN_OP_CLEAR,
+ PIXMAN_OP_SRC,
+ PIXMAN_OP_DST,
+ PIXMAN_OP_OVER,
+ PIXMAN_OP_OVER_REVERSE,
+ PIXMAN_OP_IN,
+ PIXMAN_OP_IN_REVERSE,
+ PIXMAN_OP_OUT,
+ PIXMAN_OP_OUT_REVERSE,
+ PIXMAN_OP_ATOP,
+ PIXMAN_OP_ATOP_REVERSE,
+ PIXMAN_OP_XOR,
+ PIXMAN_OP_ADD,
+ PIXMAN_OP_SATURATE,
+ PIXMAN_OP_DISJOINT_CLEAR,
+ PIXMAN_OP_DISJOINT_SRC,
+ PIXMAN_OP_DISJOINT_DST,
+ PIXMAN_OP_DISJOINT_OVER,
+ PIXMAN_OP_DISJOINT_OVER_REVERSE,
+ PIXMAN_OP_DISJOINT_IN,
+ PIXMAN_OP_DISJOINT_IN_REVERSE,
+ PIXMAN_OP_DISJOINT_OUT,
+ PIXMAN_OP_DISJOINT_OUT_REVERSE,
+ PIXMAN_OP_DISJOINT_ATOP,
+ PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+ PIXMAN_OP_DISJOINT_XOR,
+ PIXMAN_OP_CONJOINT_CLEAR,
+ PIXMAN_OP_CONJOINT_SRC,
+ PIXMAN_OP_CONJOINT_DST,
+ PIXMAN_OP_CONJOINT_OVER,
+ PIXMAN_OP_CONJOINT_OVER_REVERSE,
+ PIXMAN_OP_CONJOINT_IN,
+ PIXMAN_OP_CONJOINT_IN_REVERSE,
+ PIXMAN_OP_CONJOINT_OUT,
+ PIXMAN_OP_CONJOINT_OUT_REVERSE,
+ PIXMAN_OP_CONJOINT_ATOP,
+ PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+ PIXMAN_OP_CONJOINT_XOR,
+ PIXMAN_OP_MULTIPLY,
+ PIXMAN_OP_SCREEN,
+ PIXMAN_OP_OVERLAY,
+ PIXMAN_OP_DARKEN,
+ PIXMAN_OP_LIGHTEN,
+ PIXMAN_OP_COLOR_DODGE,
+ PIXMAN_OP_COLOR_BURN,
+ PIXMAN_OP_HARD_LIGHT,
+ PIXMAN_OP_DIFFERENCE,
+ PIXMAN_OP_EXCLUSION,
+#if 0 /* these use floating point math and are not always bitexact on different platforms */
+ PIXMAN_OP_SOFT_LIGHT,
+ PIXMAN_OP_HSL_HUE,
+ PIXMAN_OP_HSL_SATURATION,
+ PIXMAN_OP_HSL_COLOR,
+ PIXMAN_OP_HSL_LUMINOSITY,
+#endif
+};
+
+static pixman_format_code_t img_fmt_list[] = {
+ PIXMAN_a8r8g8b8,
+ PIXMAN_x8r8g8b8,
+ PIXMAN_r5g6b5,
+ PIXMAN_r3g3b2,
+ PIXMAN_a8,
+ PIXMAN_a8b8g8r8,
+ PIXMAN_x8b8g8r8,
+ PIXMAN_b8g8r8a8,
+ PIXMAN_b8g8r8x8,
+ PIXMAN_r8g8b8a8,
+ PIXMAN_r8g8b8x8,
+ PIXMAN_x14r6g6b6,
+ PIXMAN_r8g8b8,
+ PIXMAN_b8g8r8,
+ PIXMAN_r5g6b5,
+ PIXMAN_b5g6r5,
+ PIXMAN_x2r10g10b10,
+ PIXMAN_a2r10g10b10,
+ PIXMAN_x2b10g10r10,
+ PIXMAN_a2b10g10r10,
+ PIXMAN_a1r5g5b5,
+ PIXMAN_x1r5g5b5,
+ PIXMAN_a1b5g5r5,
+ PIXMAN_x1b5g5r5,
+ PIXMAN_a4r4g4b4,
+ PIXMAN_x4r4g4b4,
+ PIXMAN_a4b4g4r4,
+ PIXMAN_x4b4g4r4,
+ PIXMAN_a8,
+ PIXMAN_r3g3b2,
+ PIXMAN_b2g3r3,
+ PIXMAN_a2r2g2b2,
+ PIXMAN_a2b2g2r2,
+ PIXMAN_c8,
+ PIXMAN_g8,
+ PIXMAN_x4c4,
+ PIXMAN_x4g4,
+ PIXMAN_c4,
+ PIXMAN_g4,
+ PIXMAN_g1,
+ PIXMAN_x4a4,
+ PIXMAN_a4,
+ PIXMAN_r1g2b1,
+ PIXMAN_b1g2r1,
+ PIXMAN_a1r1g1b1,
+ PIXMAN_a1b1g1r1,
+ PIXMAN_a1,
+ PIXMAN_null
+};
+
+static pixman_format_code_t mask_fmt_list[] = {
+ PIXMAN_a8r8g8b8,
+ PIXMAN_a8,
+ PIXMAN_a4,
+ PIXMAN_a1,
+ PIXMAN_null
+};
+
+
+/*
+ * Composite operation with pseudorandom images
+ */
+uint32_t
+test_composite (int testnum, int verbose)
+{
+ int i;
+ pixman_image_t *src_img = NULL;
+ pixman_image_t *dst_img = NULL;
+ pixman_image_t *mask_img = NULL;
+ int src_width, src_height;
+ int dst_width, dst_height;
+ int src_stride, dst_stride;
+ int src_x, src_y;
+ int dst_x, dst_y;
+ int mask_x, mask_y;
+ int w, h;
+ pixman_op_t op;
+ pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
+ uint32_t *dstbuf, *srcbuf, *maskbuf;
+ uint32_t crc32;
+ int max_width, max_height, max_extra_stride;
+ FLOAT_REGS_CORRUPTION_DETECTOR_START ();
+
+ max_width = max_height = 24 + testnum / 10000;
+ max_extra_stride = 4 + testnum / 1000000;
+
+ if (max_width > 256)
+ max_width = 256;
+
+ if (max_height > 16)
+ max_height = 16;
+
+ if (max_extra_stride > 8)
+ max_extra_stride = 8;
+
+ lcg_srand (testnum);
+
+ op = op_list[lcg_rand_n (sizeof (op_list) / sizeof (op_list[0]))];
+
+ if (lcg_rand_n (8))
+ {
+ /* normal image */
+ src_img = create_random_image (img_fmt_list, max_width, max_height,
+ max_extra_stride, &src_fmt);
+ }
+ else
+ {
+ /* solid case */
+ src_img = create_random_image (img_fmt_list, 1, 1,
+ max_extra_stride, &src_fmt);
+
+ pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
+ }
+
+ dst_img = create_random_image (img_fmt_list, max_width, max_height,
+ max_extra_stride, &dst_fmt);
+
+ src_width = pixman_image_get_width (src_img);
+ src_height = pixman_image_get_height (src_img);
+ src_stride = pixman_image_get_stride (src_img);
+
+ dst_width = pixman_image_get_width (dst_img);
+ dst_height = pixman_image_get_height (dst_img);
+ dst_stride = pixman_image_get_stride (dst_img);
+
+ dstbuf = pixman_image_get_data (dst_img);
+ srcbuf = pixman_image_get_data (src_img);
+
+ src_x = lcg_rand_n (src_width);
+ src_y = lcg_rand_n (src_height);
+ dst_x = lcg_rand_n (dst_width);
+ dst_y = lcg_rand_n (dst_height);
+
+ mask_img = NULL;
+ mask_fmt = PIXMAN_null;
+ mask_x = 0;
+ mask_y = 0;
+ maskbuf = NULL;
+
+ if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) &&
+ (lcg_rand_n (4) == 0))
+ {
+ /* PIXBUF */
+ mask_fmt = lcg_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
+ mask_img = pixman_image_create_bits (mask_fmt,
+ src_width,
+ src_height,
+ srcbuf,
+ src_stride);
+ mask_x = src_x;
+ mask_y = src_y;
+ maskbuf = srcbuf;
+ }
+ else if (lcg_rand_n (2))
+ {
+ if (lcg_rand_n (2))
+ {
+ mask_img = create_random_image (mask_fmt_list, max_width, max_height,
+ max_extra_stride, &mask_fmt);
+ }
+ else
+ {
+ /* solid case */
+ mask_img = create_random_image (mask_fmt_list, 1, 1,
+ max_extra_stride, &mask_fmt);
+ pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
+ }
+
+ if (lcg_rand_n (2))
+ pixman_image_set_component_alpha (mask_img, 1);
+
+ mask_x = lcg_rand_n (pixman_image_get_width (mask_img));
+ mask_y = lcg_rand_n (pixman_image_get_height (mask_img));
+ }
+
+
+ w = lcg_rand_n (dst_width - dst_x + 1);
+ h = lcg_rand_n (dst_height - dst_y + 1);
+
+ if (verbose)
+ {
+ printf ("op=%d, src_fmt=%08X, dst_fmt=%08X, mask_fmt=%08X\n",
+ op, src_fmt, dst_fmt, mask_fmt);
+ printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
+ src_width, src_height, dst_width, dst_height);
+ printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
+ src_x, src_y, dst_x, dst_y);
+ printf ("src_stride=%d, dst_stride=%d\n",
+ src_stride, dst_stride);
+ printf ("w=%d, h=%d\n", w, h);
+ }
+
+ pixman_image_composite (op, src_img, mask_img, dst_img,
+ src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);
+
+ if (verbose)
+ {
+ int j;
+
+ printf ("---\n");
+ for (i = 0; i < dst_height; i++)
+ {
+ for (j = 0; j < dst_stride; j++)
+ {
+ if (j == (dst_width * PIXMAN_FORMAT_BPP (dst_fmt) + 7) / 8)
+ printf ("| ");
+
+ printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j));
+ }
+ printf ("\n");
+ }
+ printf ("---\n");
+ }
+
+ free_random_image (0, src_img, PIXMAN_null);
+ crc32 = free_random_image (0, dst_img, dst_fmt);
+
+ if (mask_img)
+ {
+ if (srcbuf == maskbuf)
+ pixman_image_unref(mask_img);
+ else
+ free_random_image (0, mask_img, PIXMAN_null);
+ }
+
+ FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
+ return crc32;
+}
+
+int
+main (int argc, const char *argv[])
+{
+ int i;
+
+ for (i = 1; i <= 8; i++)
+ {
+ initialize_palette (&(rgb_palette[i]), i, TRUE);
+ initialize_palette (&(y_palette[i]), i, FALSE);
+ }
+
+ return fuzzer_test_main("blitters", 2000000,
+ 0x265CDFEB,
+ test_composite, argc, argv);
+}
diff --git a/pixman/test/composite.c b/pixman/test/composite.c
index e6d52b990..9a001e519 100644
--- a/pixman/test/composite.c
+++ b/pixman/test/composite.c
@@ -102,6 +102,8 @@ static const format_t formats[] =
P(x8b8g8r8),
P(b8g8r8a8),
P(b8g8r8x8),
+ P(r8g8b8a8),
+ P(r8g8b8x8),
P(x2r10g10b10),
P(x2b10g10r10),
P(a2r10g10b10),
@@ -556,6 +558,13 @@ get_pixel (pixman_image_t *image,
bs = g + gs;
break;
+ case PIXMAN_TYPE_RGBA:
+ as = 0;
+ bs = PIXMAN_FORMAT_BPP (format) - (b + g + r);
+ gs = b + bs;
+ rs = g + gs;
+ break;
+
case PIXMAN_TYPE_A:
as = 0;
rs = 0;
@@ -900,13 +909,13 @@ main (int argc, char **argv)
#ifdef USE_OPENMP
# pragma omp parallel for default(none) shared(result, argv, seed)
#endif
- for (i = seed; i <= N_TESTS; ++i)
+ for (i = 0; i <= N_TESTS; ++i)
{
- if (!result && !run_test (i))
+ if (!result && !run_test (i + seed))
{
- printf ("Test 0x%08X failed.\n", i);
+ printf ("Test 0x%08X failed.\n", seed + i);
- result = i;
+ result = seed + i;
}
}
diff --git a/pixman/test/fetch-test.c b/pixman/test/fetch-test.c
index 60bc765f6..feb98d9b7 100644
--- a/pixman/test/fetch-test.c
+++ b/pixman/test/fetch-test.c
@@ -34,6 +34,16 @@ static testcase_t testcases[] =
NULL,
},
{
+ PIXMAN_r8g8b8a8,
+ 2, 2,
+ 8,
+ { 0x11223300, 0x55667744,
+ 0x99aabb88, 0xddeeffcc },
+ { 0x00112233, 0x44556677,
+ 0x8899aabb, 0xccddeeff },
+ NULL,
+ },
+ {
PIXMAN_g1,
8, 2,
4,
diff --git a/pixman/test/stress-test.c b/pixman/test/stress-test.c
index d496f93e2..571420ab0 100644
--- a/pixman/test/stress-test.c
+++ b/pixman/test/stress-test.c
@@ -19,6 +19,8 @@ static const pixman_format_code_t image_formats[] =
PIXMAN_x8b8g8r8,
PIXMAN_b8g8r8a8,
PIXMAN_b8g8r8x8,
+ PIXMAN_r8g8b8a8,
+ PIXMAN_r8g8b8x8,
PIXMAN_x14r6g6b6,
PIXMAN_r8g8b8,
PIXMAN_b8g8r8,