/* * 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 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; linerowstride; 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); }