[cairo] [PATCH]: pixman: New functions for converting format to/from masks

Carl Worth cworth at redhat.com
Tue Mar 25 10:16:39 PDT 2008


Here is a small (two commit) patch series that adds this little bit of
new API to pixman:

	typedef struct _pixman_format_masks {
	    int bpp;
	    unsigned long alpha_mask;
	    unsigned long red_mask;
	    unsigned long green_mask;
	    unsigned long blue_mask;
	} pixman_format_masks_t;

	/* Format conversion */
	PIXMAN_EXPORT
	pixman_bool_t   pixman_format_code_to_masks (pixman_format_code_t code,
	                                             pixman_format_masks_t *masks);

	PIXMAN_EXPORT
	pixman_bool_t   pixman_format_masks_to_code (pixman_format_masks_t *masks,
	                                             pixman_format_code_t *code_ret);

See the patch itself for complete documentation of these functions.

This functionality currently lives within cairo itself, but really
needs to live in pixman. As can be seen in the patch series, the cairo
versions are already very incomplete with respect to what formats
pixman provides.

The commits here also add a new format-test to test the functions for
all current pixman_format_code_t values.

As before, I'll push unless there are any objections.

-Carl

PS. With these functions in place in pixman, and once cairo moves to
using them, I don't think that cairo needs anything else from pixman,
(other than an actual pixman release), before cairo's 1.6 release. So
thanks to everyone working on pixman!

-------------- next part --------------
From 057d5ac0befeae4ae367c7a935c25066187e341b Mon Sep 17 00:00:00 2001
From: Carl Worth <cworth at cworth.org>
Date: Mon, 24 Mar 2008 16:56:17 -0700
Subject: [PATCH] Add pixman_format_code_to_masks and pixman_format_masks_to_code

These functions were originally created within the cairo library,
but they really do belong here in pixman where they can be properly
maintained, (and support all pixman formats).
---
 pixman/Makefile.am     |    1 +
 pixman/pixman-format.c |  194 ++++++++++++++++++++++++++++++++++++++++++++++++
 pixman/pixman.h        |   17 ++++
 3 files changed, 212 insertions(+), 0 deletions(-)
 create mode 100644 pixman/pixman-format.c

diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index ff3997b..6bb71b4 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -11,6 +11,7 @@ libpixman_1_la_SOURCES =		\
 	pixman-combine.c	\
 	pixman-compose.c	\
 	pixman-compose-accessors.c	\
+	pixman-format.c		\
 	pixman-pict.c		\
 	pixman-source.c		\
 	pixman-transformed.c	\
diff --git a/pixman/pixman-format.c b/pixman/pixman-format.c
new file mode 100644
index 0000000..ba238fb
--- /dev/null
+++ b/pixman/pixman-format.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright ? 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth at cworth.org>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pixman-private.h"
+
+/**
+ * pixman_format_code_to_masks:
+ * @code: A pixman_format_code_t
+ * @masks: Mask-based description of that format
+ * 
+ * Given a pixman_format_code_t return a mask-based description of the
+ * format in @masks if possible. Some formats cannot be described with
+ * alpha, red, green, and blue masks, (such as a palette-based format
+ * like PIXMAN_c8 or a YUV format like PIXMAN_yuy2).
+ *
+ * Return value: TRUE if a unique pixman_format_masks_t value is
+ * returned, FALSE otherwise.
+ **/
+pixman_bool_t
+pixman_format_code_to_masks (pixman_format_code_t    code,
+			     pixman_format_masks_t  *masks)
+{
+    masks->alpha_mask = 0x0;
+    masks->red_mask   = 0x0;
+    masks->green_mask = 0x0;
+    masks->blue_mask  = 0x0;
+
+    switch (code)
+    {
+    case PIXMAN_a8r8g8b8:
+	masks->alpha_mask = 0xff000000;
+	/* fall-through */
+    case PIXMAN_x8r8g8b8:
+	masks->bpp        = 32;
+	masks->red_mask   = 0x00ff0000;
+	masks->green_mask = 0x0000ff00;
+	masks->blue_mask  = 0x000000ff;
+	return TRUE;
+
+    case PIXMAN_a8b8g8r8:
+	masks->alpha_mask = 0xff000000;
+	/* fall-through */
+    case PIXMAN_x8b8g8r8:
+	masks->bpp        = 32;
+	masks->red_mask   = 0x000000ff;
+	masks->green_mask = 0x0000ff00;
+	masks->blue_mask  = 0x00ff0000;
+	return TRUE;
+
+    case PIXMAN_r5g6b5:
+	masks->bpp        = 16;
+	masks->red_mask   = 0xf800;
+	masks->green_mask = 0x07e0;
+	masks->blue_mask  = 0x001f;
+	return TRUE;
+
+    case PIXMAN_x1r5g5b5:
+	masks->bpp        = 16;
+	masks->red_mask   = 0x7c00;
+	masks->green_mask = 0x03e0;
+	masks->blue_mask  = 0x001f;
+	return TRUE;
+
+    case PIXMAN_a8:
+	masks->bpp = 8;
+	masks->alpha_mask = 0xff;
+	return TRUE;
+
+    case PIXMAN_a1:
+	masks->bpp = 1;
+	masks->alpha_mask = 0x1;
+	return TRUE;
+
+    default:
+	return FALSE;
+    }
+}
+
+/**
+ * pixman_format_masks_to_code:
+ * @masks: Mask-based description of desired format
+ * @code_ret: A pixman_format_code_t matching @masks (if possible)
+ *
+ * Returns a pixman_format_code_t in @code_ret corresponding to the
+ * @masks passed in, (if possible). There is a limited set of
+ * supported format codes in pixman---arbitrary masks are not
+ * supported. So the caller must check to see if the conversion is
+ * succesful.
+ * 
+ * Return value: TRUE if a pixman_format_code_t is found, FALSE
+ * otherwise.
+ **/
+pixman_bool_t
+pixman_format_masks_to_code (pixman_format_masks_t  *masks,
+			     pixman_format_code_t   *code_ret)
+{
+    switch (masks->bpp) {
+    case 32:
+	if (masks->alpha_mask == 0xff000000 &&
+	    masks->red_mask   == 0x00ff0000 &&
+	    masks->green_mask == 0x0000ff00 &&
+	    masks->blue_mask  == 0x000000ff)
+	{
+	    *code_ret = PIXMAN_a8r8g8b8;
+	    return TRUE;
+	}
+	if (masks->alpha_mask == 0x00000000 &&
+	    masks->red_mask   == 0x00ff0000 &&
+	    masks->green_mask == 0x0000ff00 &&
+	    masks->blue_mask  == 0x000000ff)
+	{
+	    *code_ret = PIXMAN_x8r8g8b8;
+	    return TRUE;
+	}
+	if (masks->alpha_mask == 0xff000000 &&
+	    masks->red_mask   == 0x000000ff &&
+	    masks->green_mask == 0x0000ff00 &&
+	    masks->blue_mask  == 0x00ff0000)
+	{
+	    *code_ret = PIXMAN_a8b8g8r8;
+	    return TRUE;
+	}
+	if (masks->alpha_mask == 0x00000000 &&
+	    masks->red_mask   == 0x000000ff &&
+	    masks->green_mask == 0x0000ff00 &&
+	    masks->blue_mask  == 0x00ff0000)
+	{
+	    *code_ret = PIXMAN_x8b8g8r8;
+	    return TRUE;
+	}
+	break;
+    case 16:
+	if (masks->alpha_mask == 0x0000 &&
+	    masks->red_mask   == 0xf800 &&
+	    masks->green_mask == 0x07e0 &&
+	    masks->blue_mask  == 0x001f)
+	{
+	    *code_ret = PIXMAN_r5g6b5;
+	    return TRUE;
+	}
+	if (masks->alpha_mask == 0x0000 &&
+	    masks->red_mask   == 0x7c00 &&
+	    masks->green_mask == 0x03e0 &&
+	    masks->blue_mask  == 0x001f)
+	{
+	    *code_ret = PIXMAN_x1r5g5b5;
+	    return TRUE;
+	}
+	break;
+    case 8:
+	if (masks->alpha_mask == 0xff)
+	{
+	    *code_ret = PIXMAN_a8;
+	    return TRUE;
+	}
+	break;
+    case 1:
+	if (masks->alpha_mask == 0x1)
+	{
+	    *code_ret = PIXMAN_a1;
+	    return TRUE;
+	}
+	break;
+    }
+
+    return FALSE;
+}
diff --git a/pixman/pixman.h b/pixman/pixman.h
index c4c5c3b..1eb4e00 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -503,6 +503,23 @@ typedef enum {
     PIXMAN_yv12 =	PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0),
 } pixman_format_code_t;
 
+typedef struct _pixman_format_masks {
+    int bpp;
+    unsigned long alpha_mask;
+    unsigned long red_mask;
+    unsigned long green_mask;
+    unsigned long blue_mask;
+} pixman_format_masks_t;
+
+/* Format conversion */
+PIXMAN_EXPORT
+pixman_bool_t	pixman_format_code_to_masks (pixman_format_code_t    code,
+					     pixman_format_masks_t  *masks);
+
+PIXMAN_EXPORT
+pixman_bool_t	pixman_format_masks_to_code (pixman_format_masks_t  *masks,
+					     pixman_format_code_t   *code_ret);
+
 /* Constructors */
 PIXMAN_EXPORT
 pixman_image_t *pixman_image_create_solid_fill       (pixman_color_t               *color);
-- 
1.5.5.rc0.24.g86c30


From fa2aacffdd257c48ff414271a22b4a9fb2dd99c9 Mon Sep 17 00:00:00 2001
From: Carl Worth <cworth at cworth.org>
Date: Tue, 25 Mar 2008 10:08:45 -0700
Subject: [PATCH] Complete (and test) the new pixman_format conversion functions

The original versions of these functions as they came from cairo
supported only a small, hard-coded set of formats, (those that
cairo directly uses). Now, these functions made more general,
and support all pixman_format_code_t values. This is ensured
with a new format-test test.
---
 .gitignore             |    1 +
 pixman/pixman-format.c |  332 +++++++++++++++++++++++++++++++++++-------------
 test/Makefile.am       |    4 +-
 test/format-test.c     |  136 ++++++++++++++++++++
 4 files changed, 382 insertions(+), 91 deletions(-)
 create mode 100644 test/format-test.c

diff --git a/.gitignore b/.gitignore
index 70b7b64..9a3c43b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,6 +29,7 @@ config.h.in
 pixman/pixman-version.h
 test/composite-test
 test/fetch-test
+test/format-test
 test/gradient-test
 *.pdb
 *.dll
diff --git a/pixman/pixman-format.c b/pixman/pixman-format.c
index ba238fb..435fa1e 100644
--- a/pixman/pixman-format.c
+++ b/pixman/pixman-format.c
@@ -30,6 +30,9 @@
 
 #include "pixman-private.h"
 
+/* A mask consisting of N bits set to 1. */
+#define MASK(N) ((1 << (N))-1)
+
 /**
  * pixman_format_code_to_masks:
  * @code: A pixman_format_code_t
@@ -47,58 +50,44 @@ pixman_bool_t
 pixman_format_code_to_masks (pixman_format_code_t    code,
 			     pixman_format_masks_t  *masks)
 {
-    masks->alpha_mask = 0x0;
-    masks->red_mask   = 0x0;
-    masks->green_mask = 0x0;
-    masks->blue_mask  = 0x0;
+    int a, r, g, b;
 
-    switch (code)
-    {
-    case PIXMAN_a8r8g8b8:
-	masks->alpha_mask = 0xff000000;
-	/* fall-through */
-    case PIXMAN_x8r8g8b8:
-	masks->bpp        = 32;
-	masks->red_mask   = 0x00ff0000;
-	masks->green_mask = 0x0000ff00;
-	masks->blue_mask  = 0x000000ff;
-	return TRUE;
+    masks->bpp = PIXMAN_FORMAT_BPP (code);
 
-    case PIXMAN_a8b8g8r8:
-	masks->alpha_mask = 0xff000000;
-	/* fall-through */
-    case PIXMAN_x8b8g8r8:
-	masks->bpp        = 32;
-	masks->red_mask   = 0x000000ff;
-	masks->green_mask = 0x0000ff00;
-	masks->blue_mask  = 0x00ff0000;
+    /* Number of bits in each channel */
+    a = PIXMAN_FORMAT_A (code);
+    r = PIXMAN_FORMAT_R (code);
+    g = PIXMAN_FORMAT_G (code);
+    b = PIXMAN_FORMAT_B (code);
+    
+    switch (PIXMAN_FORMAT_TYPE (code)) {
+    case PIXMAN_TYPE_ARGB:
+	masks->alpha_mask = MASK (a) << (r + g + b);
+	masks->red_mask   = MASK (r) << (g + b);
+	masks->green_mask = MASK (g) << (b);
+	masks->blue_mask  = MASK (b);
 	return TRUE;
-
-    case PIXMAN_r5g6b5:
-	masks->bpp        = 16;
-	masks->red_mask   = 0xf800;
-	masks->green_mask = 0x07e0;
-	masks->blue_mask  = 0x001f;
+    case PIXMAN_TYPE_ABGR:
+	masks->alpha_mask = MASK (a) << (b + g + r);
+	masks->blue_mask  = MASK (b) << (g +r);
+	masks->green_mask = MASK (g) << (r);
+	masks->red_mask   = MASK (r);
 	return TRUE;
-
-    case PIXMAN_x1r5g5b5:
-	masks->bpp        = 16;
-	masks->red_mask   = 0x7c00;
-	masks->green_mask = 0x03e0;
-	masks->blue_mask  = 0x001f;
+    case PIXMAN_TYPE_A:
+	masks->alpha_mask = MASK (a);
+	masks->red_mask   = 0;
+	masks->green_mask = 0;
+	masks->blue_mask  = 0;
 	return TRUE;
-
-    case PIXMAN_a8:
-	masks->bpp = 8;
-	masks->alpha_mask = 0xff;
-	return TRUE;
-
-    case PIXMAN_a1:
-	masks->bpp = 1;
-	masks->alpha_mask = 0x1;
-	return TRUE;
-
-    default:
+    case PIXMAN_TYPE_OTHER:
+    case PIXMAN_TYPE_COLOR:
+    case PIXMAN_TYPE_GRAY:
+    case PIXMAN_TYPE_YUY2:
+    case PIXMAN_TYPE_YV12:
+	masks->alpha_mask = 0;
+	masks->red_mask   = 0;
+	masks->green_mask = 0;
+	masks->blue_mask  = 0;
 	return FALSE;
     }
 }
@@ -123,62 +112,225 @@ pixman_format_masks_to_code (pixman_format_masks_t  *masks,
 {
     switch (masks->bpp) {
     case 32:
-	if (masks->alpha_mask == 0xff000000 &&
-	    masks->red_mask   == 0x00ff0000 &&
-	    masks->green_mask == 0x0000ff00 &&
-	    masks->blue_mask  == 0x000000ff)
+	if (masks->alpha_mask == 0xff000000)
 	{
-	    *code_ret = PIXMAN_a8r8g8b8;
-	    return TRUE;
+	    if (masks->red_mask   == 0x00ff0000 &&
+		masks->green_mask == 0x0000ff00 &&
+		masks->blue_mask  == 0x000000ff)
+	    {
+		*code_ret = PIXMAN_a8r8g8b8;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x000000ff &&
+		masks->green_mask == 0x0000ff00 &&
+		masks->blue_mask  == 0x00ff0000)
+	    {
+		*code_ret = PIXMAN_a8b8g8r8;
+		return TRUE;
+	    }
 	}
-	if (masks->alpha_mask == 0x00000000 &&
-	    masks->red_mask   == 0x00ff0000 &&
-	    masks->green_mask == 0x0000ff00 &&
-	    masks->blue_mask  == 0x000000ff)
+	else if (masks->alpha_mask == 0)
 	{
-	    *code_ret = PIXMAN_x8r8g8b8;
-	    return TRUE;
+	    if (masks->red_mask   == 0x00ff0000 &&
+		masks->green_mask == 0x0000ff00 &&
+		masks->blue_mask  == 0x000000ff)
+	    {
+		*code_ret = PIXMAN_x8r8g8b8;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x000000ff &&
+		masks->green_mask == 0x0000ff00 &&
+		masks->blue_mask  == 0x00ff0000)
+	    {
+		*code_ret = PIXMAN_x8b8g8r8;
+		return TRUE;
+	    }
 	}
-	if (masks->alpha_mask == 0xff000000 &&
-	    masks->red_mask   == 0x000000ff &&
-	    masks->green_mask == 0x0000ff00 &&
-	    masks->blue_mask  == 0x00ff0000)
-	{
-	    *code_ret = PIXMAN_a8b8g8r8;
-	    return TRUE;
-	}
-	if (masks->alpha_mask == 0x00000000 &&
-	    masks->red_mask   == 0x000000ff &&
-	    masks->green_mask == 0x0000ff00 &&
-	    masks->blue_mask  == 0x00ff0000)
+	break;
+    case 24:
+	if (masks->alpha_mask == 0) 
 	{
-	    *code_ret = PIXMAN_x8b8g8r8;
-	    return TRUE;
+	    if (masks->red_mask   == 0xff0000 &&
+		masks->green_mask == 0x00ff00 &&
+		masks->blue_mask  == 0x0000ff)
+	    {
+		*code_ret = PIXMAN_r8g8b8;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x0000ff &&
+		masks->green_mask == 0x00ff00 &&
+		masks->blue_mask  == 0xff0000)
+	    {
+		*code_ret = PIXMAN_b8g8r8;
+		return TRUE;
+	    }
 	}
 	break;
     case 16:
-	if (masks->alpha_mask == 0x0000 &&
-	    masks->red_mask   == 0xf800 &&
-	    masks->green_mask == 0x07e0 &&
-	    masks->blue_mask  == 0x001f)
-	{
-	    *code_ret = PIXMAN_r5g6b5;
-	    return TRUE;
-	}
-	if (masks->alpha_mask == 0x0000 &&
-	    masks->red_mask   == 0x7c00 &&
-	    masks->green_mask == 0x03e0 &&
-	    masks->blue_mask  == 0x001f)
-	{
-	    *code_ret = PIXMAN_x1r5g5b5;
-	    return TRUE;
+	switch (masks->alpha_mask) {
+	case 0xf000:
+	    if (masks->red_mask   == 0x0f00 &&
+		masks->green_mask == 0x00f0 &&
+		masks->blue_mask  == 0x000f)
+	    {
+		*code_ret = PIXMAN_a4r4g4b4;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x000f &&
+		masks->green_mask == 0x00f0 &&
+		masks->blue_mask  == 0x0f00)
+	    {
+		*code_ret = PIXMAN_a4b4g4r4;
+		return TRUE;
+	    }
+	    break;
+	case 0x8000:
+	    if (masks->red_mask   == 0x7c00 &&
+		masks->green_mask == 0x03e0 &&
+		masks->blue_mask  == 0x001f)
+	    {
+		*code_ret = PIXMAN_a1r5g5b5;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x001f &&
+		masks->green_mask == 0x03e0 &&
+		masks->blue_mask  == 0x7c00)
+	    {
+		*code_ret = PIXMAN_a1b5g5r5;
+		return TRUE;
+	    }
+	    break;
+	case 0x0000:
+	    if (masks->red_mask   == 0xf800 &&
+		masks->green_mask == 0x07e0 &&
+		masks->blue_mask  == 0x001f)
+	    {
+		*code_ret = PIXMAN_r5g6b5;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x001f &&
+		masks->green_mask == 0x07e0 &&
+		masks->blue_mask  == 0xf800)
+	    {
+		*code_ret = PIXMAN_b5g6r5;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x0f00 &&
+		masks->green_mask == 0x00f0 &&
+		masks->blue_mask  == 0x000f)
+	    {
+		*code_ret = PIXMAN_x4r4g4b4;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x000f &&
+		masks->green_mask == 0x00f0 &&
+		masks->blue_mask  == 0x0f00)
+	    {
+		*code_ret = PIXMAN_x4b4g4r4;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x7c00 &&
+		masks->green_mask == 0x03e0 &&
+		masks->blue_mask  == 0x001f)
+	    {
+		*code_ret = PIXMAN_x1r5g5b5;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x001f &&
+		masks->green_mask == 0x03e0 &&
+		masks->blue_mask  == 0x7c00)
+	    {
+		*code_ret = PIXMAN_x1b5g5r5;
+		return TRUE;
+	    }
+	    break;
 	}
 	break;
     case 8:
-	if (masks->alpha_mask == 0xff)
-	{
+	switch (masks->alpha_mask) {
+	case 0xff:
 	    *code_ret = PIXMAN_a8;
 	    return TRUE;
+	    break;
+	case 0xc0:
+	    if (masks->red_mask   == 0x30 &&
+		masks->green_mask == 0x0c &&
+		masks->blue_mask  == 0x03)
+	    {
+		*code_ret = PIXMAN_a2r2g2b2;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x03 &&
+		masks->green_mask == 0x0c &&
+		masks->blue_mask  == 0x30)
+	    {
+		*code_ret = PIXMAN_a2b2g2r2;
+		return TRUE;
+	    }
+	    break;
+	case 0x0f:
+	    if (masks->red_mask   == 0x00 &&
+		masks->green_mask == 0x00 &&
+		masks->blue_mask  == 0x00)
+	    {
+		*code_ret = PIXMAN_x4a4;
+		return TRUE;
+	    }
+	case 0x00:
+	    if (masks->red_mask   == 0xe0 &&
+		masks->green_mask == 0x1c &&
+		masks->blue_mask  == 0x03)
+	    {
+		*code_ret = PIXMAN_r3g3b2;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x07 &&
+		masks->green_mask == 0x38 &&
+		masks->blue_mask  == 0xc0)
+	    {
+		*code_ret = PIXMAN_b2g3r3;
+		return TRUE;
+	    }
+	    break;
+	}
+	break;
+    case 4:
+	switch (masks->alpha_mask) {
+	case 0xf:
+	    *code_ret = PIXMAN_a4;
+	    return TRUE;
+	case 0x8:
+	    if (masks->red_mask   == 0x4 &&
+		masks->green_mask == 0x2 &&
+		masks->blue_mask  == 0x1)
+	    {
+		*code_ret = PIXMAN_a1r1g1b1;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x1 &&
+		masks->green_mask == 0x2 &&
+		masks->blue_mask  == 0x4)
+	    {
+		*code_ret = PIXMAN_a1b1g1r1;
+		return TRUE;
+	    }
+	    break;
+	case 0x0:
+	    if (masks->red_mask   == 0x8 &&
+		masks->green_mask == 0x6 &&
+		masks->blue_mask  == 0x1)
+	    {
+		*code_ret = PIXMAN_r1g2b1;
+		return TRUE;
+	    }
+	    if (masks->red_mask   == 0x1 &&
+		masks->green_mask == 0x6 &&
+		masks->blue_mask  == 0x8)
+	    {
+		*code_ret = PIXMAN_b1g2r1;
+		return TRUE;
+	    }
+	    break;
 	}
 	break;
     case 1:
diff --git a/test/Makefile.am b/test/Makefile.am
index 3db77b3..54a0515 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -2,7 +2,8 @@ if HAVE_GTK
 TESTPROGRAMS = \
 	composite-test		\
 	gradient-test		\
-	fetch-test
+	fetch-test		\
+	format-test
 
 noinst_PROGRAMS = $(TESTPROGRAMS)
 
@@ -11,5 +12,6 @@ INCLUDES = -I$(top_srcdir)/pixman $(GTK_CFLAGS)
 composite_test_LDADD =	$(top_builddir)/pixman/libpixman-1.la $(GTK_LIBS)
 gradient_test_LDADD = $(top_builddir)/pixman/libpixman-1.la $(GTK_LIBS)
 fetch_test_LDADD = $(top_builddir)/pixman/libpixman-1.la
+format_test_LDADD = $(top_builddir)/pixman/libpixman-1.la
 
 endif
diff --git a/test/format-test.c b/test/format-test.c
new file mode 100644
index 0000000..45d44db
--- /dev/null
+++ b/test/format-test.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright ? 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth at cworth.org>
+ */
+
+#include <stdio.h>
+
+#include "pixman.h"
+
+static const pixman_format_code_t mask_formats[] = {
+    /* 32bpp formats */
+    PIXMAN_a8r8g8b8,
+    PIXMAN_x8r8g8b8,
+    PIXMAN_a8b8g8r8,
+    PIXMAN_x8b8g8r8,
+    /* 24bpp formats */
+    PIXMAN_r8g8b8,
+    PIXMAN_b8g8r8,
+    /* 16bpp formats */
+    PIXMAN_r5g6b5,
+    PIXMAN_b5g6r5,
+    PIXMAN_a1r5g5b5,
+    PIXMAN_x1r5g5b5,
+    PIXMAN_a1b5g5r5,
+    PIXMAN_x1b5g5r5,
+    PIXMAN_a4r4g4b4,
+    PIXMAN_x4r4g4b4,
+    PIXMAN_a4b4g4r4,
+    PIXMAN_x4b4g4r4,
+    /* 8bpp formats */
+    PIXMAN_a8,
+    PIXMAN_r3g3b2,
+    PIXMAN_b2g3r3,
+    PIXMAN_a2r2g2b2,
+    PIXMAN_a2b2g2r2,
+    PIXMAN_x4a4,
+    /* 4bpp formats */
+    PIXMAN_a4,
+    PIXMAN_r1g2b1,
+    PIXMAN_b1g2r1,
+    PIXMAN_a1r1g1b1,
+    PIXMAN_a1b1g1r1,
+    /* 1bpp formats */
+    PIXMAN_a1
+};
+
+static const pixman_format_code_t non_mask_formats[] = {
+    /* 8bpp formats */
+    PIXMAN_c8,
+    PIXMAN_g8,
+    PIXMAN_x4c4,
+    PIXMAN_x4g4,
+    /* 4bpp formats */
+    PIXMAN_c4,
+    PIXMAN_g4,
+    /* 1bpp formats */
+    PIXMAN_g1,
+    /* YUV formats */
+    PIXMAN_yuy2,
+    PIXMAN_yv12
+};
+
+#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))
+int
+main (int argc, char *argv[])
+{
+    pixman_format_code_t format, format_from_masks;
+    pixman_format_masks_t masks;
+    pixman_bool_t success;
+    int i, ret = 0;
+
+    /* First check that all mask-describable formats can be
+     * round-tripped through pixman_format_to_masks and
+     * pixman_format_from_masks. */
+    for (i = 0; i < ARRAY_SIZE (mask_formats); i++) {
+	format = mask_formats[i];
+	pixman_format_code_to_masks (format, &masks);
+	success = pixman_format_masks_to_code (&masks, &format_from_masks);
+	if (! success) {
+	    fprintf (stderr,
+		     "%s: Error: Format code 0x%08x (private index %d) resulted in masks:\n"
+		     "\tbits per pixel:\t%d\n"
+		     "\talpha mask:    \t0x%08lx\n"
+		     "\tred mask:      \t0x%08lx\n"
+		     "\tgreen mask:    \t0x%08lx\n"
+		     "\tblue mask:     \t0x%08lx\n"
+		     "But these masks did not result in valid format code when passed to\n"
+		     "pixman_format_form_masks\n",
+		     argv[0], format, i,
+		     masks.bpp, masks.alpha_mask,
+		     masks.red_mask, masks.green_mask, masks.blue_mask);
+	    ret = 1;
+	    continue;
+	}
+	if (format_from_masks != format) {
+	    fprintf (stderr, "%s: Error: Format code 0x%08x (private index %d) failed to roundtrip, (came back as 0x%08x).\n",
+		     argv[0], format, i, format_from_masks);
+	    ret = 1;
+	}
+    }
+
+    /* Then check that all formats that are not describable by masks
+     * fail to roundtrip. */
+    for (i = 0; i < ARRAY_SIZE (non_mask_formats); i++) {
+	format = non_mask_formats[i];
+	success = pixman_format_code_to_masks (format, &masks);
+	if (success) {
+	    fprintf (stderr, "%s: Error: Format code 0x%08x (private index %d) did not fail as expected when attempting roundtrip.\n",
+		     argv[0], format, i);
+	    ret = 1;
+	}
+    }
+
+    return ret;
+}
-- 
1.5.5.rc0.24.g86c30

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.cairographics.org/archives/cairo/attachments/20080325/1ddbfc0b/attachment-0001.pgp 


More information about the cairo mailing list