[cogl/wip/pbo-read-pixels: 10/18] bitmap: Support pre/unpre-multiplying any format
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/pbo-read-pixels: 10/18] bitmap: Support pre/unpre-multiplying any format
- Date: Fri, 2 Mar 2012 18:11:51 +0000 (UTC)
commit df6efe28c6459d0632f7ec5fa214172badbd5b01
Author: Neil Roberts <neil linux intel com>
Date: Fri Mar 2 18:03:02 2012 +0000
bitmap: Support pre/unpre-multiplying any format
If the fast-path inplace premult conversion can't be used then it will
now fallback to unpacking the buffer into a row of guint16s and use
the generic conversion.
cogl/cogl-bitmap-conversion.c | 81 ++++++++++++++++++++++++++++-------------
1 files changed, 56 insertions(+), 25 deletions(-)
---
diff --git a/cogl/cogl-bitmap-conversion.c b/cogl/cogl-bitmap-conversion.c
index 9732059..467459f 100644
--- a/cogl/cogl-bitmap-conversion.c
+++ b/cogl/cogl-bitmap-conversion.c
@@ -267,7 +267,7 @@ _cogl_bitmap_premult_unpacked_span_guint16 (guint16 *data,
}
static gboolean
-_cogl_bitmap_can_premult (CoglPixelFormat format)
+_cogl_bitmap_can_fast_premult (CoglPixelFormat format)
{
switch (format & ~COGL_PREMULT_BIT)
{
@@ -319,7 +319,7 @@ _cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp,
/* If the base format is the same then we can just copy the bitmap
instead */
if ((src_format & ~COGL_PREMULT_BIT) == (dst_format & ~COGL_PREMULT_BIT) &&
- (!need_premult || _cogl_bitmap_can_premult (dst_format)))
+ (!need_premult || _cogl_bitmap_can_fast_premult (dst_format)))
{
if (!_cogl_bitmap_copy_subregion (src_bmp, dst_bmp,
0, 0, /* src_x / src_y */
@@ -450,6 +450,7 @@ gboolean
_cogl_bitmap_unpremult (CoglBitmap *bmp)
{
guint8 *p, *data;
+ guint16 *tmp_row;
int x,y;
CoglPixelFormat format;
int width, height;
@@ -460,35 +461,50 @@ _cogl_bitmap_unpremult (CoglBitmap *bmp)
height = _cogl_bitmap_get_height (bmp);
rowstride = _cogl_bitmap_get_rowstride (bmp);
- /* If we can premult that implies we can un-premult too... */
- if (!_cogl_bitmap_can_premult (format))
- return FALSE;
-
if ((data = _cogl_bitmap_map (bmp,
COGL_BUFFER_ACCESS_READ |
COGL_BUFFER_ACCESS_WRITE,
0)) == NULL)
return FALSE;
+ /* If we can't directly unpremult the data inline then we'll
+ allocate a temporary row and unpack the data. This assumes if we
+ can fast premult then we can also fast unpremult */
+ if (_cogl_bitmap_can_fast_premult (format))
+ tmp_row = NULL;
+ else
+ tmp_row = g_malloc (sizeof (guint16) * 4 * width);
+
for (y = 0; y < height; y++)
{
p = (guint8*) data + y * rowstride;
- if (format & COGL_AFIRST_BIT)
+ if (tmp_row)
+ {
+ _cogl_unpack_guint16 (format, p, tmp_row, width);
+ _cogl_bitmap_unpremult_unpacked_span_guint16 (tmp_row, width);
+ _cogl_pack_guint16 (format, tmp_row, p, width);
+ }
+ else
{
- for (x = 0; x < width; x++)
+ if (format & COGL_AFIRST_BIT)
{
- if (p[0] == 0)
- _cogl_unpremult_alpha_0 (p);
- else
- _cogl_unpremult_alpha_first (p);
- p += 4;
+ for (x = 0; x < width; x++)
+ {
+ if (p[0] == 0)
+ _cogl_unpremult_alpha_0 (p);
+ else
+ _cogl_unpremult_alpha_first (p);
+ p += 4;
+ }
}
+ else
+ _cogl_bitmap_unpremult_unpacked_span_guint8 (p, width);
}
- else
- _cogl_bitmap_unpremult_unpacked_span_guint8 (p, width);
}
+ g_free (tmp_row);
+
_cogl_bitmap_unmap (bmp);
_cogl_bitmap_set_format (bmp, format & ~COGL_PREMULT_BIT);
@@ -500,6 +516,7 @@ gboolean
_cogl_bitmap_premult (CoglBitmap *bmp)
{
guint8 *p, *data;
+ guint16 *tmp_row;
int x,y;
CoglPixelFormat format;
int width, height;
@@ -510,32 +527,46 @@ _cogl_bitmap_premult (CoglBitmap *bmp)
height = _cogl_bitmap_get_height (bmp);
rowstride = _cogl_bitmap_get_rowstride (bmp);
- /* Make sure format supported for un-premultiplication */
- if (!_cogl_bitmap_can_premult (format))
- return FALSE;
-
if ((data = _cogl_bitmap_map (bmp,
COGL_BUFFER_ACCESS_READ |
COGL_BUFFER_ACCESS_WRITE,
0)) == NULL)
return FALSE;
+ /* If we can't directly premult the data inline then we'll allocate
+ a temporary row and unpack the data. */
+ if (_cogl_bitmap_can_fast_premult (format))
+ tmp_row = NULL;
+ else
+ tmp_row = g_malloc (sizeof (guint16) * 4 * width);
+
for (y = 0; y < height; y++)
{
p = (guint8*) data + y * rowstride;
- if (format & COGL_AFIRST_BIT)
+ if (tmp_row)
+ {
+ _cogl_unpack_guint16 (format, p, tmp_row, width);
+ _cogl_bitmap_premult_unpacked_span_guint16 (tmp_row, width);
+ _cogl_pack_guint16 (format, tmp_row, p, width);
+ }
+ else
{
- for (x = 0; x < width; x++)
+ if (format & COGL_AFIRST_BIT)
{
- _cogl_premult_alpha_first (p);
- p += 4;
+ for (x = 0; x < width; x++)
+ {
+ _cogl_premult_alpha_first (p);
+ p += 4;
+ }
}
+ else
+ _cogl_bitmap_premult_unpacked_span_guint8 (p, width);
}
- else
- _cogl_bitmap_premult_unpacked_span_guint8 (p, width);
}
+ g_free (tmp_row);
+
_cogl_bitmap_unmap (bmp);
_cogl_bitmap_set_format (bmp, format | COGL_PREMULT_BIT);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]