Add expand and contract functions to convert between ARGB8 and ARGB16.
authorAaron Plattner <aplattner@nvidia.com>
Fri, 6 Jun 2008 22:30:52 +0000 (15:30 -0700)
committerSøren Sandmann Pedersen <sandmann@redhat.com>
Fri, 13 Jun 2008 04:11:37 +0000 (00:11 -0400)
The expansion function isn't quite correct, but gives reasonable results.

Signed-off-by: Søren Sandmann Pedersen <sandmann@redhat.com>
pixman/pixman-access.c
pixman/pixman-private.h
pixman/pixman.h

index 29b846c..5609421 100644 (file)
@@ -1678,3 +1678,49 @@ storeProc32 ACCESS(pixman_storeProcForPicture32) (bits_image_t * pict)
         return NULL;
     }
 }
+
+#ifndef PIXMAN_FB_ACCESSORS
+/*
+ * This function expands images from ARGB8 format to ARGB16.  To preserve
+ * precision, it needs to know the original source format.  For example, if the
+ * source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then
+ * the expanded value is 12345123.  To correctly expand this to 16 bits, it
+ * should be 1234512345123451 and not 1234512312345123.
+ *
+ * XXX[AGP]: For now, this just does naïve byte replication.
+ */
+void pixman_expand(uint64_t *dst, const uint32_t *src,
+                   pixman_format_code_t format, int width)
+{
+    /* Start at the end so that we can do the expansion in place when src == dst */
+    for (width--; width >= 0; width--)
+    {
+        const uint8_t a = src[width] >> 24,
+                      r = src[width] >> 16,
+                      g = src[width] >> 8,
+                      b = src[width];
+        dst[width] = (uint64_t)a << 56 | (uint64_t) a << 48 |
+                     (uint64_t)r << 40 | (uint64_t) r << 32 |
+                     (uint64_t)g << 24 | (uint64_t) g << 16 |
+                     (uint64_t)b << 8 | (uint64_t)b;
+    }
+}
+
+/*
+ * Contracting is easier than expanding.  We just need to truncate the
+ * components.
+ */
+void pixman_contract(uint32_t *dst, const uint64_t *src, int width)
+{
+    /* Start at the beginning so that we can do the contraction in place when
+     * src == dst */
+    for (width--; width >= 0; width--, src++, dst++)
+    {
+        const uint8_t a = *src >> 56,
+                      r = *src >> 40,
+                      g = *src >> 24,
+                      b = *src >> 8;
+        *dst = a << 24 | r << 16 | g << 8 | b;
+    }
+}
+#endif // PIXMAN_FB_ACCESSORS
index 0ea0cb3..5a2f89e 100644 (file)
@@ -214,6 +214,9 @@ fetchProc64 pixman_fetchProcForPicture64_accessors (bits_image_t *);
 fetchPixelProc64 pixman_fetchPixelProcForPicture64_accessors (bits_image_t *);
 storeProc64 pixman_storeProcForPicture64_accessors (bits_image_t *);
 
+void pixman_expand(uint64_t *dst, const uint32_t *src, pixman_format_code_t, int width);
+void pixman_contract(uint32_t *dst, const uint64_t *src, int width);
+
 void pixmanFetchSourcePict(source_image_t *, int x, int y, int width,
                            uint32_t *buffer, uint32_t *mask, uint32_t maskBits);
 
index 7f74594..78dee13 100644 (file)
@@ -495,6 +495,10 @@ struct pixman_indexed
                                 PIXMAN_FORMAT_R(f) +   \
                                 PIXMAN_FORMAT_G(f) +   \
                                 PIXMAN_FORMAT_B(f))
+#define PIXMAN_FORMAT_16BPC(f) (PIXMAN_FORMAT_A(f) > 8 || \
+                                PIXMAN_FORMAT_R(f) > 8 || \
+                                PIXMAN_FORMAT_G(f) > 8 || \
+                                PIXMAN_FORMAT_B(f) > 8)
 
 #define PIXMAN_TYPE_OTHER      0
 #define PIXMAN_TYPE_A          1