Browse Source

add image_container.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1251 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 14 years ago
parent
commit
515b337983

+ 1 - 0
components/rtgui/SConscript

@@ -18,6 +18,7 @@ common/image.c
 common/image_xpm.c
 common/image_xpm.c
 common/image_hdc.c
 common/image_hdc.c
 common/image_bmp.c
 common/image_bmp.c
+common/image_container.c
 common/font.c
 common/font.c
 common/font_bmp.c
 common/font_bmp.c
 common/font_hz_file.c
 common/font_hz_file.c

+ 376 - 0
components/rtgui/common/image_container.c

@@ -0,0 +1,376 @@
+#include <rtgui/image_container.h>
+
+typedef unsigned int (*rtgui_hash_func_t) (const void* key);
+typedef struct _rtgui_hash_table  rtgui_hash_table_t;
+typedef rt_bool_t (*rtgui_equal_func_t) (const void* a, const void* b);
+typedef void (*rtgui_user_func_t) (const void* value, const void* data);
+
+/*
+ *Hash tables
+ */
+rtgui_hash_table_t* hash_table_create(rtgui_hash_func_t hash_func, rtgui_equal_func_t key_equal_func);
+void hash_table_destroy (rtgui_hash_table_t* hash_table);
+
+void* hash_table_find (rtgui_hash_table_t* hash_table, void* key);
+void hash_table_insert (rtgui_hash_table_t* hash_table, void* key, void* value);
+rt_bool_t hash_table_remove (rtgui_hash_table_t* hash_table, void* key);
+
+void hash_table_foreach(rtgui_hash_table_t* hash_table, rtgui_user_func_t user_func, void* data);
+unsigned int hash_table_get_size (rtgui_hash_table_t* hash_table);
+
+/* Hash Functions
+ */
+unsigned int direct_hash (void* v);
+
+#define HASH_TABLE_MIN_SIZE 11
+#define HASH_TABLE_MAX_SIZE 6247
+
+typedef struct _gui_hash_node rtgui_hash_node_t;
+struct _gui_hash_node
+{
+	void* key;
+	void* value;
+	rtgui_hash_node_t *next;
+};
+
+struct _rtgui_hash_table
+{
+	rt_uint16_t size;
+	rt_uint16_t nnodes;
+
+	rtgui_hash_node_t **nodes;
+	rtgui_hash_func_t hash_func;
+	rtgui_equal_func_t key_equal_func;
+};
+
+static const unsigned int primes[] =
+{
+	11,
+	19,
+	37,
+	73,
+	109,
+	163,
+	251,
+	367,
+	557,
+	823,
+	1237,
+	1861,
+	2777,
+	4177,
+	6247,
+/*
+	9371,
+	14057,
+	21089,
+	31627,
+	47431,
+	71143,
+	106721,
+	160073,
+	240101,
+	360163,
+	540217,
+	810343,
+	1215497,
+	1823231,
+	2734867,
+	4102283,
+	6153409,
+	9230113,
+	13845163,
+*/
+};
+
+static const unsigned int nprimes = sizeof (primes) / sizeof (primes[0]);
+
+static void hash_table_resize (rtgui_hash_table_t *hash_table);
+static rtgui_hash_node_t** hash_table_find_node (rtgui_hash_table_t *hash_table, void* key);
+static rtgui_hash_node_t* hash_node_create (void* key, void* value);
+static void hash_node_destroy (rtgui_hash_node_t *hash_node);
+static void hash_nodes_destroy (rtgui_hash_node_t *hash_node);
+static unsigned int primes_closest (unsigned int num);
+static void hash_table_needresize(rtgui_hash_table_t *hash_table);
+
+rt_inline unsigned int primes_closest (unsigned int num)
+{
+	int i;
+
+	for (i = 0; i < nprimes; i++)
+		if (primes[i] > num)
+			return primes[i];
+
+	return primes[nprimes - 1];
+}
+
+/* directly hash */
+unsigned int direct_hash (void* v)
+{
+	return (unsigned int)v;
+}
+
+rtgui_hash_table_t* hash_table_create(rtgui_hash_func_t hash_func, rtgui_equal_func_t key_equal_func)
+{
+	rtgui_hash_table_t *hash_table;
+
+	hash_table = (rtgui_hash_table_t*) rt_malloc (sizeof(rtgui_hash_table_t));
+	if (hash_table != RT_NULL)
+	{
+		hash_table->size               = HASH_TABLE_MIN_SIZE;
+		hash_table->nnodes             = 0;
+		hash_table->hash_func          = hash_func ? hash_func : direct_hash;
+		hash_table->key_equal_func     = key_equal_func;
+		hash_table->nodes              = (rtgui_hash_node_t **)rt_malloc ( sizeof(rtgui_hash_node_t*) * hash_table->size);
+		if (hash_table->nodes == RT_NULL)
+		{
+			/* no memory yet */
+			rt_free(hash_table);
+			return RT_NULL;
+		}
+
+		rt_memset(hash_table->nodes, 0, sizeof(rtgui_hash_node_t*) * hash_table->size);
+	}
+
+	return hash_table;
+}
+
+void hash_table_destroy (rtgui_hash_table_t *hash_table)
+{
+	unsigned int i;
+
+	RT_ASSERT(hash_table != RT_NULL);
+
+	for (i = 0; i < hash_table->size; i++)
+		hash_nodes_destroy (hash_table->nodes[i]);
+
+	rt_free (hash_table->nodes);
+	rt_free (hash_table);
+}
+
+static rtgui_hash_node_t** hash_table_find_node (rtgui_hash_table_t *hash_table, void* key)
+{
+	rtgui_hash_node_t **node;
+
+	node = &hash_table->nodes [(* hash_table->hash_func) (key) % hash_table->size];
+
+	if (hash_table->key_equal_func)
+		while (*node && !(*hash_table->key_equal_func) ((*node)->key, key))
+			node = &(*node)->next;
+	else
+		while (*node && (*node)->key != key)
+			node = &(*node)->next;
+
+	return node;
+}
+
+void* hash_table_find (rtgui_hash_table_t* hash_table, void* key)
+{
+	rtgui_hash_node_t *node;
+
+	RT_ASSERT(hash_table != RT_NULL);
+	RT_ASSERT(key != RT_NULL);
+
+	node = *hash_table_find_node (hash_table, key);
+
+	if (node) return node->value;
+	else return RT_NULL;
+}
+
+void hash_table_insert (rtgui_hash_table_t *hash_table, void* key, void* value)
+{
+	rtgui_hash_node_t **node;
+
+	if (hash_table == RT_NULL)return;
+
+	node = hash_table_find_node (hash_table, key);
+	if (*node)
+	{
+		(*node)->value = value;
+	}
+	else
+	{
+		*node = hash_node_create (key, value);
+		hash_table->nnodes++;
+		hash_table_needresize (hash_table);
+	}
+}
+
+rt_bool_t hash_table_remove (rtgui_hash_table_t *hash_table, void*  key)
+{
+	rtgui_hash_node_t **node, *dest;
+
+	if (hash_table == RT_NULL) return RT_FALSE;
+
+	node = hash_table_find_node (hash_table, key);
+	if (*node)
+	{
+		dest = *node;
+		(*node) = dest->next;
+		hash_node_destroy (dest);
+		hash_table->nnodes--;
+
+		hash_table_needresize (hash_table);
+
+		return RT_TRUE;
+	}
+
+	return RT_FALSE;
+}
+
+void hash_table_foreach(rtgui_hash_table_t *hash_table, rtgui_user_func_t user_func, void* data)
+{
+	rtgui_hash_node_t *node;
+	int i;
+
+	RT_ASSERT(hash_table != RT_NULL);
+	RT_ASSERT(user_func != RT_NULL);
+
+	for (i = 0; i < hash_table->size; i++)
+		for (node = hash_table->nodes[i]; node; node = node->next)
+			(* user_func) (node->value, data);
+}
+
+unsigned int hash_table_get_size (rtgui_hash_table_t *hash_table)
+{
+	if ( hash_table ==NULL ) return 0;
+
+	return hash_table->nnodes;
+}
+
+static void hash_table_needresize(rtgui_hash_table_t *hash_table)
+{
+	if ((hash_table->size >= 3*hash_table->nnodes && hash_table->size > HASH_TABLE_MIN_SIZE) ||
+	        (3 * hash_table->size <= hash_table->nnodes && hash_table->size < HASH_TABLE_MAX_SIZE))
+		hash_table_resize (hash_table);
+}
+
+static void hash_table_resize (rtgui_hash_table_t *hash_table)
+{
+	rtgui_hash_node_t **new_nodes;
+	rtgui_hash_node_t *node;
+	rtgui_hash_node_t *next;
+	unsigned int hash_val;
+	int new_size;
+	int i;
+
+	i = primes_closest(hash_table->nnodes);
+	new_size = i > HASH_TABLE_MAX_SIZE ? HASH_TABLE_MAX_SIZE : i < HASH_TABLE_MIN_SIZE ? HASH_TABLE_MIN_SIZE : i ;
+
+	new_nodes = (rtgui_hash_node_t **)rt_malloc ( sizeof(rtgui_hash_node_t*) * new_size);
+	if (new_nodes == RT_NULL) return; /* no memory yet */
+	rt_memset(new_nodes, 0, sizeof(rtgui_hash_node_t*) * new_size);
+
+	for (i = 0; i < hash_table->size; i++)
+	{
+		for (node = hash_table->nodes[i]; node; node = next)
+		{
+			next = node->next;
+
+			hash_val = (* hash_table->hash_func) (node->key) % new_size;
+
+			node->next = new_nodes[hash_val];
+			new_nodes[hash_val] = node;
+		}
+	}
+
+	rt_free (hash_table->nodes);
+	hash_table->nodes = new_nodes;
+	hash_table->size = new_size;
+}
+
+static rtgui_hash_node_t* hash_node_create (void* key, void* value)
+{
+	rtgui_hash_node_t *hash_node;
+
+	hash_node = (rtgui_hash_node_t*) rt_malloc ( sizeof(rtgui_hash_node_t) );
+	if (hash_node != RT_NULL)
+	{
+		/* set value and key */
+		hash_node->key = key;
+		hash_node->value = value;;
+
+		hash_node->next = RT_NULL;
+	}
+
+	return hash_node;
+}
+
+static void hash_node_destroy (rtgui_hash_node_t *hash_node)
+{
+	rt_free(hash_node);
+}
+
+static void hash_nodes_destroy (rtgui_hash_node_t *hash_node)
+{
+	if (hash_node)
+	{
+		rtgui_hash_node_t *node = hash_node;
+		rtgui_hash_node_t *temp;
+
+		while (node->next)
+		{
+			node->key = NULL;
+			node->value = NULL;
+
+			temp = node;
+			node = node->next;
+			rt_free(temp);
+		}
+
+		node->key = NULL;
+		node->value = NULL;
+		rt_free(node);
+	}
+}
+
+unsigned int string_hash_func(const void* self)
+{
+	const char *p;
+	int h=0, g;
+
+	for(p = self; *p != '\0'; p += 1)
+	{
+		h = ( h << 4 ) + *p;
+		if ( ( g = h & 0xf0000000 ) )
+		{
+			h = h ^ (g >> 24);
+			h = h ^ g;
+		}
+	}
+
+	return h ;
+}
+rt_bool_t string_equal_func(const void* a, const void* b)
+{
+	const char *str1, *str2;
+
+	str1 = (const char*)a;
+	str2 = (const char*)b;
+
+	if (strcmp(str1, str2) == 0) return RT_TRUE;
+	return RT_FALSE;
+}
+
+static rtgui_hash_table_t* image_hash_table;
+rt_bool_t load_image = RT_FALSE;
+void image_container_system_init(rt_bool_t is_load)
+{
+	/* create image hash table */
+	image_hash_table = hash_table_create(string_hash_func, string_equal_func);
+	RT_ASSERT(image_hash_table != RT_NULL);
+	load_image = is_load;
+}
+
+rtgui_image_t* image_container_get(const char* filename)
+{
+	/* get image type */
+}
+
+rtgui_image_t* image_container_get_memref(const rt_uint8_t* memory, const char* type)
+{
+}
+
+void image_container_put(rtgui_image_t* image)
+{
+}

+ 12 - 0
components/rtgui/include/rtgui/image_container.h

@@ -0,0 +1,12 @@
+#ifndef __RTGUI_IMAGE_CONTAINER_H__
+#define __RTGUI_IMAGE_CONTAINER_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/image.h>
+
+void image_container_system_init(void);
+
+rtgui_image_t* image_container_get(const char* filename);
+void image_container_put(rtgui_image_t* image);
+
+#endif