From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/src/core/palette.c | 317 +++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100755 Source/DirectFB/src/core/palette.c (limited to 'Source/DirectFB/src/core/palette.c') diff --git a/Source/DirectFB/src/core/palette.c b/Source/DirectFB/src/core/palette.c new file mode 100755 index 0000000..3d66a54 --- /dev/null +++ b/Source/DirectFB/src/core/palette.c @@ -0,0 +1,317 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + 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. +*/ + +#include + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +D_DEBUG_DOMAIN( Core_Palette, "Core/Palette", "DirectFB Palette Core" ); + +/**********************************************************************************************************************/ + +static const u8 lookup3to8[] = { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff }; +static const u8 lookup2to8[] = { 0x00, 0x55, 0xaa, 0xff }; + +static const ReactionFunc dfb_palette_globals[] = { +/* 0 */ _dfb_surface_palette_listener, + NULL +}; + +/**********************************************************************************************************************/ + +static void palette_destructor( FusionObject *object, bool zombie, void *ctx ) +{ + CorePaletteNotification notification; + CorePalette *palette = (CorePalette*) object; + + D_MAGIC_ASSERT( palette, CorePalette ); + + D_DEBUG_AT( Core_Palette, "destroying %p (%d)%s\n", palette, + palette->num_entries, zombie ? " (ZOMBIE)" : ""); + + D_ASSERT( palette->entries != NULL ); + D_ASSERT( palette->entries_yuv != NULL ); + + notification.flags = CPNF_DESTROY; + notification.palette = palette; + + dfb_palette_dispatch( palette, ¬ification, dfb_palette_globals ); + + if (palette->hash_attached) { + dfb_colorhash_invalidate( NULL, palette ); + dfb_colorhash_detach( NULL, palette ); + } + + SHFREE( palette->shmpool, palette->entries_yuv ); + SHFREE( palette->shmpool, palette->entries ); + + D_MAGIC_CLEAR( palette ); + + fusion_object_destroy( object ); +} + +FusionObjectPool * +dfb_palette_pool_create( const FusionWorld *world ) +{ + FusionObjectPool *pool; + + pool = fusion_object_pool_create( "Palette Pool", + sizeof(CorePalette), + sizeof(CorePaletteNotification), + palette_destructor, NULL, world ); + + return pool; +} + +/**********************************************************************************************************************/ + +DFBResult +dfb_palette_create( CoreDFB *core, + unsigned int size, + CorePalette **ret_palette ) +{ + CorePalette *palette; + + D_DEBUG_AT( Core_Palette, "%s( %d )\n", __FUNCTION__, size ); + + D_ASSERT( ret_palette ); + + palette = dfb_core_create_palette( core ); + if (!palette) + return DFB_FUSION; + + palette->shmpool = dfb_core_shmpool( core ); + + if (size) { + palette->entries = SHCALLOC( palette->shmpool, size, sizeof(DFBColor) ); + if (!palette->entries) { + fusion_object_destroy( &palette->object ); + return D_OOSHM(); + } + + palette->entries_yuv = SHCALLOC( palette->shmpool, size, sizeof(DFBColorYUV) ); + if (!palette->entries_yuv) { + SHFREE( palette->shmpool, palette->entries ); + fusion_object_destroy( &palette->object ); + return D_OOSHM(); + } + } + + palette->num_entries = size; + + /* reset cache */ + palette->search_cache.index = -1; + + D_MAGIC_SET( palette, CorePalette ); + + /* activate object */ + fusion_object_activate( &palette->object ); + + /* return the new palette */ + *ret_palette = palette; + + D_DEBUG_AT( Core_Palette, " -> %p\n", palette ); + + return DFB_OK; +} + +void +dfb_palette_generate_rgb332_map( CorePalette *palette ) +{ + unsigned int i; + + D_DEBUG_AT( Core_Palette, "%s( %p )\n", __FUNCTION__, palette ); + + D_MAGIC_ASSERT( palette, CorePalette ); + + if (!palette->num_entries) + return; + + for (i=0; inum_entries; i++) { + palette->entries[i].a = i ? 0xff : 0x00; + palette->entries[i].r = lookup3to8[ (i & 0xE0) >> 5 ]; + palette->entries[i].g = lookup3to8[ (i & 0x1C) >> 2 ]; + palette->entries[i].b = lookup2to8[ (i & 0x03) ]; + + palette->entries_yuv[i].a = palette->entries[i].a; + + RGB_TO_YCBCR( palette->entries[i].r, palette->entries[i].g, palette->entries[i].b, + palette->entries_yuv[i].y, palette->entries_yuv[i].u, palette->entries_yuv[i].v ); + } + + dfb_palette_update( palette, 0, palette->num_entries - 1 ); +} + +void +dfb_palette_generate_rgb121_map( CorePalette *palette ) +{ + unsigned int i; + + D_DEBUG_AT( Core_Palette, "%s( %p )\n", __FUNCTION__, palette ); + + D_MAGIC_ASSERT( palette, CorePalette ); + + if (!palette->num_entries) + return; + + for (i=0; inum_entries; i++) { + palette->entries[i].a = i ? 0xff : 0x00; + palette->entries[i].r = (i & 0x8) ? 0xff : 0x00; + palette->entries[i].g = lookup2to8[ (i & 0x6) >> 1 ]; + palette->entries[i].b = (i & 0x1) ? 0xff : 0x00; + + palette->entries_yuv[i].a = palette->entries[i].a; + + RGB_TO_YCBCR( palette->entries[i].r, palette->entries[i].g, palette->entries[i].b, + palette->entries_yuv[i].y, palette->entries_yuv[i].u, palette->entries_yuv[i].v ); + } + + dfb_palette_update( palette, 0, palette->num_entries - 1 ); +} + +unsigned int +dfb_palette_search( CorePalette *palette, + u8 r, + u8 g, + u8 b, + u8 a ) +{ + unsigned int index; + + D_MAGIC_ASSERT( palette, CorePalette ); + + /* check local cache first */ + if (palette->search_cache.index != -1 && + palette->search_cache.color.a == a && + palette->search_cache.color.r == r && + palette->search_cache.color.g == g && + palette->search_cache.color.b == b) + return palette->search_cache.index; + + /* check the global color hash table, returns the closest match */ + if (!palette->hash_attached) { + dfb_colorhash_attach( NULL, palette ); + palette->hash_attached = true; + } + + index = dfb_colorhash_lookup( NULL, palette, r, g, b, a ); + + /* write into local cache */ + palette->search_cache.index = index; + palette->search_cache.color.a = a; + palette->search_cache.color.r = r; + palette->search_cache.color.g = g; + palette->search_cache.color.b = b; + + return index; +} + +void +dfb_palette_update( CorePalette *palette, int first, int last ) +{ + CorePaletteNotification notification; + + D_DEBUG_AT( Core_Palette, "%s( %p, %d, %d )\n", __FUNCTION__, palette, first, last ); + + D_MAGIC_ASSERT( palette, CorePalette ); + D_ASSERT( first >= 0 ); + D_ASSERT( first < palette->num_entries ); + D_ASSERT( last >= 0 ); + D_ASSERT( last < palette->num_entries ); + D_ASSERT( first <= last ); + + notification.flags = CPNF_ENTRIES; + notification.palette = palette; + notification.first = first; + notification.last = last; + + /* reset cache */ + if (palette->search_cache.index >= first && + palette->search_cache.index <= last) + palette->search_cache.index = -1; + + /* invalidate entries in colorhash */ + if (palette->hash_attached) + dfb_colorhash_invalidate( NULL, palette ); + + /* post message about palette update */ + dfb_palette_dispatch( palette, ¬ification, dfb_palette_globals ); +} + +bool +dfb_palette_equal( CorePalette *palette1, CorePalette *palette2 ) +{ + u32 *entries1; + u32 *entries2; + int i; + + D_DEBUG_AT( Core_Palette, "%s( %p, %p )\n", __FUNCTION__, palette1, palette2 ); + + D_ASSERT( palette1 != NULL ); + D_ASSERT( palette2 != NULL ); + + if (palette1 == palette2) { + D_DEBUG_AT( Core_Palette, " -> SAME\n" ); + return true; + } + + if (palette1->num_entries != palette2->num_entries) { + D_DEBUG_AT( Core_Palette, " -> NOT EQUAL (%d/%d)\n", palette1->num_entries, palette2->num_entries ); + return false; + } + + entries1 = (u32*)palette1->entries; + entries2 = (u32*)palette2->entries; + + for (i = 0; i < palette1->num_entries; i++) { + if (entries1[i] != entries2[i]) { + D_DEBUG_AT( Core_Palette, " -> NOT EQUAL (%d)\n", i ); + return false; + } + } + + D_DEBUG_AT( Core_Palette, " -> EQUAL\n" ); + + return true; +} + -- cgit