From: Øyvind Kolås Date: Fri, 31 Aug 2018 09:18:30 +0000 (+0200) Subject: babl-fish-reference: factor out separate function for float/double X-Git-Tag: archive/raspbian/1%0.1.106-3+rpi1^2~15^2~14^2~11 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=da0216ffde2eaebbf3fc80fca806e24dc61d2818;p=babl.git babl-fish-reference: factor out separate function for float/double babl_fish_reference_process now only contains the dispatch tree that tries various fast paths first before ending up in the float or double synthetic references. --- diff --git a/babl/babl-fish-reference.c b/babl/babl-fish-reference.c index 35b9d95..619ceb5 100644 --- a/babl/babl-fish-reference.c +++ b/babl/babl-fish-reference.c @@ -611,15 +611,6 @@ process_same_model (const Babl *babl, { const void *type_float = babl_type_from_id (BABL_FLOAT); #define MAX(a, b) ((a) > (b) ? (a) : (b)) - if (BABL (babl->fish.source) == BABL (babl->fish.destination)) - { - if (source == destination) - { - memcpy (destination, source, n * babl->fish.source->format.bytes_per_pixel); - } - return; - } - @@ -699,45 +690,175 @@ process_same_model (const Babl *babl, } } -void -babl_fish_reference_process (const Babl *babl, - const char *source, - char *destination, - long n, - void *data) + +static void +babl_fish_reference_process_double (const Babl *babl, + const char *source, + char *destination, + long n, + void *data) { - const void *type_float = babl_type_from_id (BABL_FLOAT); - const void *type_double = babl_type_from_id (BABL_DOUBLE); - Babl *source_image = NULL; - Babl *rgba_image = NULL; - Babl *destination_image = NULL; + Babl *source_image = NULL; + Babl *rgba_image = NULL; + Babl *destination_image = NULL; + void *source_double_buf_alloc = NULL; + void *source_double_buf; + void *rgba_double_buf_alloc = NULL; + void *rgba_double_buf; + void *destination_double_buf_alloc = NULL; + void *destination_double_buf; + const void *type_double = babl_type_from_id (BABL_DOUBLE); - static int allow_float_reference = -1; - if (allow_float_reference == -1) - allow_float_reference = getenv ("BABL_REFERENCE_NOFLOAT") ? 0 : 1; + if (babl->fish.source->format.type[0] == type_double && + BABL(babl->fish.source)->format.components == + BABL(babl->fish.source)->format.model->components && 0) + { + source_double_buf = (void*)source; + source_image = babl_image_from_linear ( + source_double_buf, BABL (BABL ((babl->fish.source))->format.model)); + } + else + { + source_double_buf_alloc = babl_malloc (sizeof (double) * n * + BABL (babl->fish.source)->format.model->components); - if ((BABL (babl->fish.source)->format.model == - BABL (babl->fish.destination)->format.model) && - (BABL (babl->fish.source)->format.space == - BABL (babl->fish.destination)->format.space) - ) - { - process_same_model (babl, source, destination, n); - return; - } + source_double_buf = source_double_buf_alloc; + source_image = babl_image_from_linear ( + source_double_buf, BABL (BABL ((babl->fish.source))->format.model)); + convert_to_double ( + (BablFormat *) BABL (babl->fish.source), + source, + source_double_buf, + n + ); + } - if (babl_format_is_format_n (BABL (babl->fish.destination))) - { - process_to_n_component (babl, source, destination, n); - return; - } + if (babl_model_is ((void*)babl->fish.source->format.model, "RGBA")) + { + rgba_double_buf = source_double_buf; + rgba_image = babl_image_from_linear ( + rgba_double_buf, + (void*)babl->fish.source->format.model); + } + else + { + Babl *conv = + assert_conversion_find ( + BABL (babl->fish.source)->format.model, - if (allow_float_reference && - (babl->fish.source->format.type[0]->bits < 32 || - babl->fish.source->format.type[0] == type_float) && - (babl->fish.destination->format.type[0]->bits < 32 || - babl->fish.destination->format.type[0] == type_float)) - { + babl_remodel_with_space (babl_model_from_id (BABL_RGBA), + BABL (BABL ((babl->fish.source))->format.space))); + + rgba_double_buf_alloc = babl_malloc (sizeof (double) * n * 4); + rgba_double_buf = rgba_double_buf_alloc; + + rgba_image = babl_image_from_linear ( + rgba_double_buf, babl_remodel_with_space (babl_model_from_id (BABL_RGBA), + BABL (BABL ((babl->fish.source))->format.space)) ); + + if (conv->class_type == BABL_CONVERSION_PLANAR) + { + babl_conversion_process ( + conv, + (void*)source_image, (void*)rgba_image, + n); + } + else if (conv->class_type == BABL_CONVERSION_LINEAR) + { + babl_conversion_process ( + conv, + source_double_buf, rgba_double_buf, + n); + } + else babl_fatal ("oops"); + } + + if (((babl->fish.source)->format.space != + ((babl->fish.destination)->format.space))) + { + double matrix[9]; + double *rgba = rgba_double_buf; + babl_matrix_mul_matrix ( + (babl->fish.destination)->format.space->space.XYZtoRGB, + (babl->fish.source)->format.space->space.RGBtoXYZ, + matrix); + + babl_matrix_mul_vector_buf4 (matrix, rgba, rgba, n); + } + + { + const Babl *destination_rgba_format = + babl_remodel_with_space (babl_model_from_id (BABL_RGBA), + BABL (BABL ((babl->fish.destination))->format.space)); + + if(BABL (babl->fish.destination)->format.model == (void*)destination_rgba_format) + { + destination_double_buf = rgba_double_buf; + } + else + { + Babl *conv = + assert_conversion_find (destination_rgba_format, + BABL (babl->fish.destination)->format.model); + + destination_double_buf_alloc = babl_malloc (sizeof (double) * n * + BABL (babl->fish.destination)->format.model->components); + destination_double_buf = destination_double_buf_alloc; + + if (conv->class_type == BABL_CONVERSION_PLANAR) + { + destination_image = babl_image_from_linear ( + destination_double_buf, BABL (BABL ((babl->fish.destination))->format.model)); + + + babl_conversion_process ( + conv, + (void*)rgba_image, (void*)destination_image, + n); + } + else if (conv->class_type == BABL_CONVERSION_LINEAR) + { + babl_conversion_process ( + conv, + rgba_double_buf, destination_double_buf, + n); + } + else babl_fatal ("oops"); + } + } + + convert_from_double ( + (BablFormat *) BABL (babl->fish.destination), + destination_double_buf, + destination, + n + ); + + if (destination_double_buf_alloc) + babl_free (destination_double_buf_alloc); + if (rgba_double_buf_alloc) + babl_free (rgba_double_buf_alloc); + if (source_double_buf_alloc) + babl_free (source_double_buf_alloc); + if (source_image) + babl_free (source_image); + if (rgba_image) + babl_free (rgba_image); + if (destination_image) + babl_free (destination_image); +} + +static void +babl_fish_reference_process_float (const Babl *babl, + const char *source, + char *destination, + long n, + void *data) +{ + const void *type_float = babl_type_from_id (BABL_FLOAT); + Babl *source_image = NULL; + Babl *rgba_image = NULL; + Babl *destination_image = NULL; void *source_float_buf_alloc = NULL; void *source_float_buf; void *rgba_float_buf_alloc = NULL; @@ -773,9 +894,11 @@ babl_fish_reference_process (const Babl *babl, } if (!conv_to_rgba || !conv_from_rgba) - goto double_entry; - - + { + /* needed float conversions not found, using double code path instead */ + babl_fish_reference_process_double (babl, source, destination, n, data); + return; + } if (babl->fish.source->format.type[0] == type_float && BABL(babl->fish.source)->format.components == @@ -854,39 +977,35 @@ babl_fish_reference_process (const Babl *babl, { - if( - babl_format_with_space ("RGBA float", + if(babl_format_with_space ("RGBA float", BABL (BABL ((babl->fish.destination))->format.space)) == - babl_format_with_space (dst_name, + babl_format_with_space (dst_name, BABL (BABL ((babl->fish.destination))->format.space))) { - destination_float_buf = rgba_float_buf; + destination_float_buf = rgba_float_buf; } else { - destination_float_buf_alloc = babl_malloc (sizeof (float) * n * - BABL (babl->fish.destination)->format.model->components); - destination_float_buf = destination_float_buf_alloc; + destination_float_buf_alloc = babl_malloc (sizeof (float) * n * + BABL (babl->fish.destination)->format.model->components); + destination_float_buf = destination_float_buf_alloc; - if (conv_from_rgba->class_type == BABL_CONVERSION_PLANAR) + if (conv_from_rgba->class_type == BABL_CONVERSION_PLANAR) { - destination_image = babl_image_from_linear ( - destination_float_buf, destination_float_format); - babl_conversion_process ( - conv_from_rgba, - (void*)rgba_image, (void*)destination_image, - n); - } - else if (conv_from_rgba->class_type == BABL_CONVERSION_LINEAR) - { - babl_conversion_process ( - conv_from_rgba, - rgba_float_buf, destination_float_buf, - n); - } - + destination_image = babl_image_from_linear ( + destination_float_buf, destination_float_format); + babl_conversion_process ( + conv_from_rgba, + (void*)rgba_image, (void*)destination_image, + n); + } + else if (conv_from_rgba->class_type == BABL_CONVERSION_LINEAR) + { + babl_conversion_process (conv_from_rgba, rgba_float_buf, + destination_float_buf, n); + } } - } + } convert_from_float ( (BablFormat *) BABL (babl->fish.destination), @@ -901,154 +1020,79 @@ babl_fish_reference_process (const Babl *babl, babl_free (rgba_float_buf_alloc); if (source_float_buf_alloc) babl_free (source_float_buf_alloc); - } - else /* double */ - { - void *source_double_buf_alloc = NULL; - void *source_double_buf; - void *rgba_double_buf_alloc = NULL; - void *rgba_double_buf; - void *destination_double_buf_alloc = NULL; - void *destination_double_buf; - double_entry: - - if (babl->fish.source->format.type[0] == type_double && - BABL(babl->fish.source)->format.components == - BABL(babl->fish.source)->format.model->components && 0) - { - source_double_buf = (void*)source; - source_image = babl_image_from_linear ( - source_double_buf, BABL (BABL ((babl->fish.source))->format.model)); - } - else - { - source_double_buf_alloc = babl_malloc (sizeof (double) * n * - BABL (babl->fish.source)->format.model->components); - - source_double_buf = source_double_buf_alloc; - source_image = babl_image_from_linear ( - source_double_buf, BABL (BABL ((babl->fish.source))->format.model)); - convert_to_double ( - (BablFormat *) BABL (babl->fish.source), - source, - source_double_buf, - n - ); - } - - if (babl_model_is ((void*)babl->fish.source->format.model, "RGBA")) - { - rgba_double_buf = source_double_buf; - rgba_image = babl_image_from_linear ( - rgba_double_buf, - (void*)babl->fish.source->format.model); - } - else - { - Babl *conv = - assert_conversion_find ( - BABL (babl->fish.source)->format.model, - - babl_remodel_with_space (babl_model_from_id (BABL_RGBA), - BABL (BABL ((babl->fish.source))->format.space))); - - rgba_double_buf_alloc = babl_malloc (sizeof (double) * n * 4); - rgba_double_buf = rgba_double_buf_alloc; + if (source_image) + babl_free (source_image); + if (rgba_image) + babl_free (rgba_image); + if (destination_image) + babl_free (destination_image); +} - rgba_image = babl_image_from_linear ( - rgba_double_buf, babl_remodel_with_space (babl_model_from_id (BABL_RGBA), - BABL (BABL ((babl->fish.source))->format.space)) ); +void +babl_fish_reference_process (const Babl *babl, + const char *source, + char *destination, + long n, + void *data) +{ + static const void *type_float = NULL; + static int allow_float_reference = -1; - if (conv->class_type == BABL_CONVERSION_PLANAR) - { - babl_conversion_process ( - conv, - (void*)source_image, (void*)rgba_image, - n); - } - else if (conv->class_type == BABL_CONVERSION_LINEAR) - { - babl_conversion_process ( - conv, - source_double_buf, rgba_double_buf, - n); - } - else babl_fatal ("oops"); - } + if (!type_float) type_float = babl_type_from_id (BABL_FLOAT); - if (((babl->fish.source)->format.space != - ((babl->fish.destination)->format.space))) + /* same format in source/destination */ + if (BABL (babl->fish.source) == BABL (babl->fish.destination)) + { + if (source == destination) { - double matrix[9]; - double *rgba = rgba_double_buf; - babl_matrix_mul_matrix ( - (babl->fish.destination)->format.space->space.XYZtoRGB, - (babl->fish.source)->format.space->space.RGBtoXYZ, - matrix); - - babl_matrix_mul_vector_buf4 (matrix, rgba, rgba, n); + memcpy (destination, source, n * babl->fish.source->format.bytes_per_pixel); } + return; + } - { - const Babl *destination_rgba_format = - babl_remodel_with_space (babl_model_from_id (BABL_RGBA), - BABL (BABL ((babl->fish.destination))->format.space)); - - if(BABL (babl->fish.destination)->format.model == (void*)destination_rgba_format) - { - destination_double_buf = rgba_double_buf; - } - else - { - Babl *conv = - assert_conversion_find (destination_rgba_format, - BABL (babl->fish.destination)->format.model); - - destination_double_buf_alloc = babl_malloc (sizeof (double) * n * - BABL (babl->fish.destination)->format.model->components); - destination_double_buf = destination_double_buf_alloc; - - if (conv->class_type == BABL_CONVERSION_PLANAR) - { - destination_image = babl_image_from_linear ( - destination_double_buf, BABL (BABL ((babl->fish.destination))->format.model)); - + /* same model and space, only convert type */ + if ((BABL (babl->fish.source)->format.model == + BABL (babl->fish.destination)->format.model) && + (BABL (babl->fish.source)->format.space == + BABL (babl->fish.destination)->format.space) + ) + { + process_same_model (babl, source, destination, n); + return; + } - babl_conversion_process ( - conv, - (void*)rgba_image, (void*)destination_image, - n); - } - else if (conv->class_type == BABL_CONVERSION_LINEAR) - { - babl_conversion_process ( - conv, - rgba_double_buf, destination_double_buf, - n); - } - else babl_fatal ("oops"); - } - } + /* we're converting to a n_component format - special case */ + if (babl_format_is_format_n (BABL (babl->fish.destination))) + { + process_to_n_component (babl, source, destination, n); + return; + } - convert_from_double ( - (BablFormat *) BABL (babl->fish.destination), - destination_double_buf, - destination, - n - ); + if (allow_float_reference == -1) + allow_float_reference = getenv ("BABL_REFERENCE_NOFLOAT") ? 0 : 1; - if (destination_double_buf_alloc) - babl_free (destination_double_buf_alloc); - if (rgba_double_buf_alloc) - babl_free (rgba_double_buf_alloc); - if (source_double_buf_alloc) - babl_free (source_double_buf_alloc); + /* both source and destination are either single precision float or <32bit component, + we then do a similar to the double reference - using the first registered + float conversions - note that this makes the first registered float conversion of + a given type a reference, and we thus rely on the *first* float conversion regsitered + to be correct, this will be the case if the code paths are duplicated and we register + either a planar or linear conversion to and from "RGBA float" at the same time as + registering conversions for double. When needed conversions do not exist, we defer + to the double code paths + */ + if (allow_float_reference && + (babl->fish.source->format.type[0]->bits < 32 || + babl->fish.source->format.type[0] == type_float) && + (babl->fish.destination->format.type[0]->bits < 32 || + babl->fish.destination->format.type[0] == type_float) && + !babl_format_is_palette (babl->fish.source) && + !babl_format_is_palette (babl->fish.destination)) + { + babl_fish_reference_process_float (babl, source, destination, n, data); + } + else /* double */ + { + babl_fish_reference_process_double (babl, source, destination, n, data); } - if (source_image) - babl_free (source_image); - if (rgba_image) - babl_free (rgba_image); - if (destination_image) - babl_free (destination_image); }