b0887a0d75
cogl-bitmap.c cogl-bitmap-pixbuf.c cogl-bitmap-fallback.c cogl-bitmap-private.h: Add _cogl_bitmap_can_premult(), _cogl_bitmap_premult() and implement a reasonably fast implementation in the "fallback" code. http://bugzilla.openedhand.com/show_bug.cgi?id=1406 Signed-off-by: Robert Bragg <robert@linux.intel.com>
209 lines
5.0 KiB
C
209 lines
5.0 KiB
C
/*
|
|
* Cogl
|
|
*
|
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
|
*
|
|
* Copyright (C) 2007,2008,2009 Intel Corporation.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "cogl.h"
|
|
#include "cogl-internal.h"
|
|
#include "cogl-bitmap-private.h"
|
|
|
|
#include <string.h>
|
|
|
|
static void _cogl_bitmap_free (CoglBitmap *bmp);
|
|
|
|
COGL_HANDLE_DEFINE (Bitmap, bitmap);
|
|
|
|
static void
|
|
_cogl_bitmap_free (CoglBitmap *bmp)
|
|
{
|
|
g_free (bmp->data);
|
|
g_free (bmp);
|
|
}
|
|
|
|
gint
|
|
_cogl_get_format_bpp (CoglPixelFormat format)
|
|
{
|
|
gint bpp_lut[] = {
|
|
0, /* invalid */
|
|
1, /* A_8 */
|
|
3, /* 888 */
|
|
4, /* 8888 */
|
|
2, /* 565 */
|
|
2, /* 4444 */
|
|
2, /* 5551 */
|
|
2, /* YUV */
|
|
1 /* G_8 */
|
|
};
|
|
|
|
return bpp_lut [format & COGL_UNORDERED_MASK];
|
|
}
|
|
|
|
gboolean
|
|
_cogl_bitmap_convert_and_premult (const CoglBitmap *bmp,
|
|
CoglBitmap *dst_bmp,
|
|
CoglPixelFormat dst_format)
|
|
{
|
|
CoglBitmap tmp_bmp = *bmp;
|
|
CoglBitmap new_bmp = *bmp;
|
|
gboolean new_bmp_owner = FALSE;
|
|
|
|
/* Is base format different (not considering premult status)? */
|
|
if ((bmp->format & COGL_UNPREMULT_MASK) !=
|
|
(dst_format & COGL_UNPREMULT_MASK))
|
|
{
|
|
/* Try converting using imaging library */
|
|
if (!_cogl_bitmap_convert (&new_bmp, &tmp_bmp, dst_format))
|
|
{
|
|
/* ... or try fallback */
|
|
if (!_cogl_bitmap_fallback_convert (&new_bmp, &tmp_bmp, dst_format))
|
|
return FALSE;
|
|
}
|
|
|
|
/* Update bitmap with new data */
|
|
new_bmp = tmp_bmp;
|
|
new_bmp_owner = TRUE;
|
|
}
|
|
|
|
/* Do we need to unpremultiply */
|
|
if ((bmp->format & COGL_PREMULT_BIT) > 0 &&
|
|
(dst_format & COGL_PREMULT_BIT) == 0)
|
|
{
|
|
/* Try unpremultiplying using imaging library */
|
|
if (!_cogl_bitmap_unpremult (&new_bmp, &tmp_bmp))
|
|
{
|
|
/* ... or try fallback */
|
|
if (!_cogl_bitmap_fallback_unpremult (&new_bmp, &tmp_bmp))
|
|
{
|
|
if (new_bmp_owner)
|
|
g_free (new_bmp.data);
|
|
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/* Update bitmap with new data */
|
|
if (new_bmp_owner)
|
|
g_free (new_bmp.data);
|
|
|
|
new_bmp = tmp_bmp;
|
|
new_bmp_owner = TRUE;
|
|
}
|
|
|
|
/* Do we need to premultiply */
|
|
if ((bmp->format & COGL_PREMULT_BIT) == 0 &&
|
|
(dst_format & COGL_PREMULT_BIT) > 0)
|
|
{
|
|
/* Try premultiplying using imaging library */
|
|
if (!_cogl_bitmap_premult (&new_bmp, &tmp_bmp))
|
|
{
|
|
/* ... or try fallback */
|
|
if (!_cogl_bitmap_fallback_premult (&new_bmp, &tmp_bmp))
|
|
{
|
|
if (new_bmp_owner)
|
|
g_free (new_bmp.data);
|
|
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/* Update bitmap with new data */
|
|
if (new_bmp_owner)
|
|
g_free (new_bmp.data);
|
|
|
|
new_bmp = tmp_bmp;
|
|
new_bmp_owner = TRUE;
|
|
}
|
|
|
|
/* Output new bitmap info */
|
|
*dst_bmp = new_bmp;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
_cogl_bitmap_copy_subregion (CoglBitmap *src,
|
|
CoglBitmap *dst,
|
|
gint src_x,
|
|
gint src_y,
|
|
gint dst_x,
|
|
gint dst_y,
|
|
gint width,
|
|
gint height)
|
|
{
|
|
guchar *srcdata;
|
|
guchar *dstdata;
|
|
gint bpp;
|
|
gint line;
|
|
|
|
/* Intended only for fast copies when format is equal! */
|
|
g_assert (src->format == dst->format);
|
|
bpp = _cogl_get_format_bpp (src->format);
|
|
|
|
srcdata = src->data + src_y * src->rowstride + src_x * bpp;
|
|
dstdata = dst->data + dst_y * dst->rowstride + dst_x * bpp;
|
|
|
|
for (line=0; line<height; ++line)
|
|
{
|
|
memcpy (dstdata, srcdata, width * bpp);
|
|
srcdata += src->rowstride;
|
|
dstdata += dst->rowstride;
|
|
}
|
|
}
|
|
|
|
gboolean
|
|
cogl_bitmap_get_size_from_file (const gchar *filename,
|
|
gint *width,
|
|
gint *height)
|
|
{
|
|
return _cogl_bitmap_get_size_from_file (filename, width, height);
|
|
}
|
|
|
|
CoglHandle
|
|
cogl_bitmap_new_from_file (const gchar *filename,
|
|
GError **error)
|
|
{
|
|
CoglBitmap bmp;
|
|
CoglBitmap *ret;
|
|
|
|
g_return_val_if_fail (error == NULL || *error == NULL, COGL_INVALID_HANDLE);
|
|
|
|
/* Try loading with imaging backend */
|
|
if (!_cogl_bitmap_from_file (&bmp, filename, error))
|
|
{
|
|
/* Try fallback */
|
|
if (!_cogl_bitmap_fallback_from_file (&bmp, filename))
|
|
return NULL;
|
|
else if (error && *error)
|
|
{
|
|
g_error_free (*error);
|
|
*error = NULL;
|
|
}
|
|
}
|
|
|
|
ret = g_memdup (&bmp, sizeof (CoglBitmap));
|
|
return _cogl_bitmap_handle_new (ret);
|
|
}
|
|
|