babl r304 - in trunk: . babl
- From: ok svn gnome org
- To: svn-commits-list gnome org
- Subject: babl r304 - in trunk: . babl
- Date: Tue, 8 Apr 2008 18:01:23 +0100 (BST)
Author: ok
Date: Tue Apr 8 18:01:23 2008
New Revision: 304
URL: http://svn.gnome.org/viewvc/babl?rev=304&view=rev
Log:
Applied patch from Jan Heller that improves logic of go_fishing code
in babl-fish.c. The current code searches list of all fishes while
looking for suitable preexistent BABL_FISH_PATH instance. The new code
only searches relevant part of database's hash table. Further, the
current code searches for fish path every time such a babl fish is
requested, even though the same fish path has been requested before
and not found. The new code creates dummy BABL_FISH instance with
appropriate source/destination formats and inserts it into the fish
database to indicate that fish path has been searched for and not
found.
* babl/babl-fish.c: (find_fish_path), (find_memcpy_fish),
(babl_fish_get_id), (babl_fish):
* babl/babl-fish-path.c: (babl_fish_path):
* babl/babl-fish-reference.c: (babl_fish_reference):
* babl/babl-fish-simple.c: (babl_fish_simple):
* babl/babl-internal.h:
Modified:
trunk/ChangeLog
trunk/babl/babl-fish-path.c
trunk/babl/babl-fish-reference.c
trunk/babl/babl-fish-simple.c
trunk/babl/babl-fish.c
trunk/babl/babl-internal.h
Modified: trunk/babl/babl-fish-path.c
==============================================================================
--- trunk/babl/babl-fish-path.c (original)
+++ trunk/babl/babl-fish-path.c Tue Apr 8 18:01:23 2008
@@ -193,9 +193,10 @@
babl_fish_path (const Babl *source,
const Babl *destination)
{
- Babl *babl = NULL;
- char *name = create_name (source, destination, 1);
+ Babl *babl = NULL;
+ char *name;
+ name = create_name (source, destination, 1);
babl = babl_db_exist_by_name (babl_fish_db (), name);
if (babl)
{
@@ -205,17 +206,11 @@
return babl;
}
- babl_assert (BABL_IS_BABL (source));
- babl_assert (BABL_IS_BABL (destination));
-
- babl_assert (source->class_type == BABL_FORMAT);
- babl_assert (destination->class_type == BABL_FORMAT);
-
babl = babl_calloc (1, sizeof (BablFishPath) +
strlen (name) + 1);
babl->class_type = BABL_FISH_PATH;
- babl->instance.id = 0;
+ babl->instance.id = babl_fish_get_id (source, destination);
babl->instance.name = ((char *) babl) + sizeof (BablFishPath);
strcpy (babl->instance.name, name);
babl->fish.source = source;
Modified: trunk/babl/babl-fish-reference.c
==============================================================================
--- trunk/babl/babl-fish-reference.c (original)
+++ trunk/babl/babl-fish-reference.c Tue Apr 8 18:01:23 2008
@@ -69,7 +69,7 @@
babl = babl_malloc (sizeof (BablFishReference) +
strlen (name) + 1);
babl->class_type = BABL_FISH_REFERENCE;
- babl->instance.id = 0;
+ babl->instance.id = babl_fish_get_id (source, destination);
babl->instance.name = ((char *) babl) + sizeof (BablFishReference);
strcpy (babl->instance.name, name);
babl->fish.source = source;
Modified: trunk/babl/babl-fish-simple.c
==============================================================================
--- trunk/babl/babl-fish-simple.c (original)
+++ trunk/babl/babl-fish-simple.c Tue Apr 8 18:01:23 2008
@@ -33,7 +33,6 @@
babl_assert (BABL_IS_BABL (conversion));
name = create_name (conversion);
-
babl = babl_db_exist_by_name (babl_fish_db (), name);
if (babl)
{
@@ -46,7 +45,7 @@
babl = babl_malloc (sizeof (BablFishSimple) +
strlen (name) + 1);
babl->class_type = BABL_FISH_SIMPLE;
- babl->instance.id = 0;
+ babl->instance.id = babl_fish_get_id (conversion->source, conversion->destination);
babl->instance.name = ((char *) babl) + sizeof (BablFishSimple);
strcpy (babl->instance.name, name);
babl->fish.source = conversion->source;
Modified: trunk/babl/babl-fish.c
==============================================================================
--- trunk/babl/babl-fish.c (original)
+++ trunk/babl/babl-fish.c Tue Apr 8 18:01:23 2008
@@ -20,6 +20,87 @@
#include <string.h>
#include <stdarg.h>
+typedef struct _BablFindFish BablFindFish;
+
+typedef struct _BablFindFish
+{
+ Babl *fish_path;
+ Babl *fish_ref;
+ Babl *fish_fish;
+ int fishes;
+ const Babl *source;
+ const Babl *destination;
+} _BablFishFish;
+
+
+static int
+match_conversion (Babl *conversion,
+ void *inout);
+
+static int
+find_fish_path (Babl *item,
+ void *data);
+
+static int
+find_memcpy_fish (Babl *item,
+ void *data);
+
+static int
+each_babl_fish_destroy (Babl *babl,
+ void *data);
+
+
+/* ====================================== */
+
+
+static int
+find_fish_path (Babl *item,
+ void *data)
+{
+ BablFindFish *ffish = (BablFindFish *) data;
+ if ((item->fish.source == ffish->source) &&
+ (item->fish.destination == ffish->destination))
+ {
+ if (item->instance.class_type == BABL_FISH_REFERENCE)
+ {
+ ffish->fish_ref = item;
+ ffish->fishes++;
+ }
+ else if (item->instance.class_type == BABL_FISH_PATH)
+ {
+ ffish->fish_path = item;
+ ffish->fishes++;
+ }
+ else if (item->instance.class_type == BABL_FISH)
+ {
+ ffish->fish_fish = item;
+ ffish->fishes++;
+ }
+ if (ffish->fishes == 3)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+find_memcpy_fish (Babl *item,
+ void *data)
+{
+ BablFindFish *ffish = (BablFindFish *) data;
+ if ((item->fish.source == ffish->source) &&
+ (item->fish.destination == ffish->destination))
+ {
+ if ((item->fish.source == item->fish.destination) &&
+ (item->instance.class_type == BABL_FISH_REFERENCE))
+ {
+ ffish->fish_ref = item;
+ return 1;
+ }
+ }
+
+ return 0;
+}
static int
match_conversion (Babl *conversion,
@@ -47,6 +128,20 @@
return data;
}
+int
+babl_fish_get_id (const Babl *source,
+ const Babl *destination)
+{
+ /* value of 'id' will be used as argument for hash function,
+ * substraction serves as simple combination of
+ * source/destination values. */
+ int id = (int) source - (int) destination;
+ /* instances with id 0 won't be inserted into database */
+ if (id == 0)
+ id = 1;
+ return id;
+}
+
BablDb *
babl_fish_db (void)
{
@@ -55,28 +150,6 @@
return db;
}
-static inline Babl *
-go_fishing (const Babl *source,
- const Babl *destination)
-{
- BablDb *db = babl_fish_db ();
- int i;
-
- for (i = 0; i < db->babl_list->count; i++)
- {
- Babl *item = db->babl_list->items[i];
- if ((void *) source == (void *) item->fish.source &&
- (void *) destination == (void *) item->fish.destination &&
- (item->class_type == BABL_FISH_PATH || /* accept only paths */
- source == destination) /* or memcpy */
- )
- {
- return item;
- }
- }
- return NULL;
-}
-
Babl *
babl_fish (const void *source,
const void *destination,
@@ -89,14 +162,10 @@
babl_assert (destination);
if (BABL_IS_BABL (source))
- {
- source_format = source;
- }
+ source_format = source;
if (!source_format)
- {
- source_format = babl_format ((char *) source);
- }
+ source_format = babl_format ((char *) source);
if (!source_format)
{
@@ -105,14 +174,10 @@
}
if (BABL_IS_BABL (destination))
- {
- destination_format = destination;
- }
+ destination_format = destination;
if (!destination_format)
- {
- destination_format = babl_format ((char *) destination);
- }
+ destination_format = babl_format ((char *) destination);
if (!destination_format)
{
@@ -121,41 +186,90 @@
}
{
- Babl *lucky;
- lucky = go_fishing (source_format, destination_format);
- if (lucky)
- return lucky;
- }
-
- if (0) /* do not accept shortcut conversions, since there might be
- a faster path, besides the shortcut conversion might
- have a too large error, let's rely on the paths for
- error checking.
- */
- {
- Babl *shortcut_conversion;
+ int hashval;
+ BablHashTable *id_htable;
+ BablFindFish ffish = {(Babl *) NULL,
+ (Babl *) NULL,
+ (Babl *) NULL,
+ 0,
+ source_format,
+ destination_format};
- shortcut_conversion = babl_conversion_find (
- source_format, destination_format);
+ id_htable = (babl_fish_db ())->id_hash;
+ hashval = babl_hash_by_int (id_htable, babl_fish_get_id (source_format, destination_format));
- if (shortcut_conversion)
- {
- return babl_fish_simple (&(shortcut_conversion->conversion));
- }
- }
+ if (source_format == destination_format)
+ {
+ /* In the case of equal source and destination formats
+ * we will search through the fish database for reference fish
+ * to handle the memcpy */
+ id_htable->find_func = find_memcpy_fish;
+ babl_hash_table_find (id_htable, hashval, (void *) &ffish);
+ }
+ else
+ {
+ /* In the case of different source and destination formats
+ * we will search through the fish database for appropriate fish path
+ * to handle the conversion. In the case that preexistent
+ * fish path is found, we'll return it. In the case BABL_FISH
+ * instance with the same source/destination is found, we'll
+ * return reference fish.
+ * In the case neither fish path nor BABL_FISH path are found,
+ * we'll try to construct new fish path for requested
+ * source/destination. In the case new fish path is found, we'll
+ * return it, otherwise we'll create dummy BABL_FISH instance and
+ * insert it into the fish database to indicate non-existent fish
+ * path.
+ */
+ id_htable->find_func = find_fish_path;
+ babl_hash_table_find (id_htable, hashval, (void *) &ffish);
- {
- Babl *fish_path;
+ if (ffish.fish_path)
+ {
+ /* we have found suitable fish path in the database */
+ return ffish.fish_path;
+ }
+ if (!ffish.fish_fish)
+ {
+ /* we haven't tried to search for suitable path yet */
+ Babl *fish_path = babl_fish_path (source_format, destination_format);
- fish_path = babl_fish_path (source_format, destination_format);
+ if (fish_path)
+ {
+ return fish_path;
+ }
+ else
+ {
+ /* there isn't a suitable path for requested formats,
+ * let's create a dummy BABL_FISH instance and insert
+ * it into the fish database to indicate that such path
+ * does not exist.
+ */
+ char *name = "X"; /* name does not matter */
+ Babl *fish = babl_calloc (1, sizeof (BablFish) + strlen (name) + 1);
+
+ fish->class_type = BABL_FISH;
+ fish->instance.id = babl_fish_get_id (source_format, destination_format);
+ fish->instance.name = ((char *) fish) + sizeof (BablFish);
+ strcpy (fish->instance.name, name);
+ fish->fish.source = source_format;
+ fish->fish.destination = destination_format;
+ babl_db_insert (babl_fish_db (), fish);
+ }
+ }
+ }
- if (fish_path)
+ if (ffish.fish_ref)
+ {
+ /* we have already found suitable reference fish */
+ return ffish.fish_ref;
+ }
+ else
{
- return fish_path;
+ /* we have to create new reference fish */
+ return babl_fish_reference (source_format, destination_format);
}
}
-
- return babl_fish_reference (source_format, destination_format);
}
long
@@ -164,7 +278,7 @@
void *destination,
long n)
{
- long ret = 0;
+ long ret = 0;
switch (babl->class_type)
{
Modified: trunk/babl/babl-internal.h
==============================================================================
--- trunk/babl/babl-internal.h (original)
+++ trunk/babl/babl-internal.h Tue Apr 8 18:01:23 2008
@@ -88,6 +88,8 @@
void *source,
void *destination,
long n);
+int babl_fish_get_id (const Babl *source,
+ const Babl *destination);
double babl_format_loss (Babl *babl);
Babl * babl_image_from_linear (char *buffer,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]