long babl_process (const Babl *cbabl, const void *source, void *destination, long n) { Babl *babl = (Babl*)cbabl; babl_assert (babl); babl_assert (source); babl_assert (destination); babl_assert (BABL_IS_BABL (babl)); if (n == 0) return 0; babl_assert (n > 0); /* first check if it is a fish since that is our fast path */ if (babl->class_type >= BABL_FISH && babl->class_type <= BABL_FISH_PATH) { babl->fish.processings++; babl->fish.pixels += babl_fish_process (babl, source, destination, n); return n; } /* matches all conversion classes */ if (babl->class_type >= BABL_CONVERSION && babl->class_type <= BABL_CONVERSION_PLANAR) return babl_conversion_process (babl, source, destination, n); babl_fatal ("eek"); return -1; }
const Babl * babl_type_new (void *first_arg, ...) { va_list varg; Babl *babl; int id = 0; int is_integer = 0; int bits = 0; long min = 0; long max = 255; double min_val = 0.0; double max_val = 0.0; const char *name = first_arg; const char *arg; va_start (varg, first_arg); while (1) { arg = va_arg (varg, char *); if (!arg) break; if (BABL_IS_BABL (arg)) { #ifdef BABL_LOG Babl *babl = (Babl *) arg; babl_log ("%s unexpected", babl_class_name (babl->class_type)); #endif } /* if we didn't point to a babl, we assume arguments to be strings */ else if (!strcmp (arg, "id")) { id = va_arg (varg, int); } else if (!strcmp (arg, "bits"))
const Babl * babl_fish (const void *source, const void *destination) { const Babl *source_format = NULL; const Babl *destination_format = NULL; babl_assert (source); babl_assert (destination); if (BABL_IS_BABL (source)) source_format = source; if (!source_format) source_format = babl_format ((char *) source); if (!source_format) { babl_log ("args=(%p, %p) source format invalid", source, destination); return NULL; } if (BABL_IS_BABL (destination)) destination_format = destination; if (!destination_format) destination_format = babl_format ((char *) destination); if (!destination_format) { babl_log ("args=(%p, %p) destination format invalid", source, destination); return NULL; } { int hashval; BablHashTable *id_htable; BablFindFish ffish = {(Babl *) NULL, (Babl *) NULL, (Babl *) NULL, 0, (Babl *) NULL, (Babl *) NULL}; /* some vendor compilers can't compile non-constant elements of * compound struct initializers */ ffish.source = source_format; ffish.destination = 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 (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 */ babl_hash_table_find (id_htable, hashval, find_memcpy_fish, (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. */ babl_hash_table_find (id_htable, hashval, find_fish_path, (void *) &ffish); 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); 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 (ffish.fish_ref) { /* we have already found suitable reference fish */ return ffish.fish_ref; } else { /* we have to create new reference fish */ return babl_fish_reference (source_format, destination_format); } } }