From: Øyvind Kolås Date: Wed, 29 Aug 2018 13:28:41 +0000 (+0200) Subject: babl-fish-reference: implement floating point version of reference path X-Git-Tag: archive/raspbian/1%0.1.106-3+rpi1^2~15^2~14^2~27 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=e3832662ea7d593720f100d222e85e4c20a00547;p=babl.git babl-fish-reference: implement floating point version of reference path This relies on conversions, linear or planar, being registered to and from RGBA float, similar to the already existing reference conversions in double. To enable use of it set the environment variable BABL_REFERENCE_FLOAT to any value, babl will crash if the above requirement is not met for a requested conversion - permitting adding it - fallback code could be added that implements it using the double versions when missing - but not having a full coverage at least for the commonly used formats defeats the purpose. --- diff --git a/babl/babl-fish-reference.c b/babl/babl-fish-reference.c index 3eff1ca..7ae5455 100644 --- a/babl/babl-fish-reference.c +++ b/babl/babl-fish-reference.c @@ -97,6 +97,9 @@ create_name (const Babl *source, #endif +/* need an internal version that only ever does double, + * for use in path evaluation? and perhaps even self evaluation of float code path? + */ Babl * babl_fish_reference (const Babl *source, const Babl *destination) @@ -606,7 +609,6 @@ process_same_model (const Babl *babl, char *destination, long n) { - void *double_buf; 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)) @@ -619,67 +621,68 @@ process_same_model (const Babl *babl, } - double_buf = babl_malloc (sizeof (double) * n * + + + if ((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)) + { + void *float_buf = babl_malloc (sizeof (float) * n * MAX (BABL (babl->fish.source)->format.model->components, BABL (babl->fish.source)->format.components)); -#undef MAX - - if (compatible_components ((void*)babl->fish.source, - (void*)babl->fish.destination)) + if (compatible_components ((void*)babl->fish.source, + (void*)babl->fish.destination)) { - - if ((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)) - { ncomponent_convert_to_float ( (BablFormat *) BABL (babl->fish.source), (char *) source, - double_buf, + float_buf, n); ncomponent_convert_from_float ( (BablFormat *) BABL (babl->fish.destination), - double_buf, + float_buf, (char *) destination, n); - } - else - { - ncomponent_convert_to_double ( + } + else + { + convert_to_float ( (BablFormat *) BABL (babl->fish.source), (char *) source, - double_buf, + float_buf, n); - ncomponent_convert_from_double ( + + convert_from_float ( (BablFormat *) BABL (babl->fish.destination), - double_buf, + float_buf, (char *) destination, n); - } } + babl_free (float_buf); + } else + { + void *double_buf = babl_malloc (sizeof (double) * n * + MAX (BABL (babl->fish.source)->format.model->components, + BABL (babl->fish.source)->format.components)); +#undef MAX + if (compatible_components ((void*)babl->fish.source, + (void*)babl->fish.destination)) { - - if ((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)) - { - convert_to_float ( + ncomponent_convert_to_double ( (BablFormat *) BABL (babl->fish.source), (char *) source, double_buf, n); - - convert_from_float ( + ncomponent_convert_from_double ( (BablFormat *) BABL (babl->fish.destination), double_buf, (char *) destination, n); - } - else - { + } + else + { convert_to_double ( (BablFormat *) BABL (babl->fish.source), (char *) source, @@ -691,9 +694,9 @@ process_same_model (const Babl *babl, double_buf, (char *) destination, n); - } } - babl_free (double_buf); + babl_free (double_buf); + } } void @@ -709,6 +712,10 @@ babl_fish_reference_process (const Babl *babl, Babl *rgba_image = NULL; Babl *destination_image = NULL; + static int allow_float_reference = -1; + if (allow_float_reference == -1) + allow_float_reference = getenv ("BABL_REFERENCE_FLOAT") ? 1 : 0; + if ((BABL (babl->fish.source)->format.model == BABL (babl->fish.destination)->format.model) && (BABL (babl->fish.source)->format.space == @@ -725,57 +732,75 @@ babl_fish_reference_process (const Babl *babl, return; } - if (0 && (babl->fish.source->format.type[0]->bits < 32 || + 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)) { -/* this code path is wip - not quite working yet, and needs resyncing - with double code that has gotten unneeded buffer allocation/copying - improvements */ - void *source_float_buf; - void *rgba_float_buf; - void *destination_float_buf; - - source_float_buf = babl_malloc (sizeof (float) * n * - BABL (babl->fish.source)->format.model->components); - rgba_float_buf = babl_malloc (sizeof (float) * n * 4); - destination_float_buf = babl_malloc (sizeof (float) * n * - BABL (babl->fish.destination)->format.model->components); - - source_image = babl_image_from_linear ( - source_float_buf, BABL (BABL ((babl->fish.source))->format.model)); - rgba_image = babl_image_from_linear ( - rgba_float_buf, babl_format_with_space ("RGBA float", - BABL (BABL ((babl->fish.source))->format.space))); - destination_image = babl_image_from_linear ( - destination_float_buf, babl_format_with_space ("RGBA float", - BABL (BABL ((babl->fish.destination))->format.space))); - - convert_to_float ( - (BablFormat *) BABL (babl->fish.source), - source, - source_float_buf, - n - ); + void *source_float_buf_alloc = NULL; + void *source_float_buf; + void *rgba_float_buf_alloc = NULL; + void *rgba_float_buf; + void *destination_float_buf_alloc = NULL; + void *destination_float_buf; + + if (babl->fish.source->format.type[0] == type_float && + BABL(babl->fish.source)->format.components == + BABL(babl->fish.source)->format.model->components && 0) + { + source_float_buf = (void*)source; + source_image = babl_image_from_linear ( + source_float_buf, + babl_format_with_model_as_type ((void*)((babl->fish.source))->format.model, + type_float)); + } + else + { + source_float_buf_alloc = babl_malloc (sizeof (float) * n * + BABL (babl->fish.source)->format.model->components); - { - char src_name[256]; - Babl *conv; - if (babl->fish.source->class_type == BABL_FORMAT) - sprintf (src_name, "%s float", - babl_get_name (BABL (babl->fish.source->format.model))); - else if (babl->fish.source->class_type == BABL_MODEL) - sprintf (src_name, "%s float", - babl_get_name (BABL (babl->fish.source))); - - conv = - assert_conversion_find ( - babl_format_with_space (src_name, - BABL (babl->fish.source)), - babl_format_with_space ("RGBA float", - BABL (BABL ((babl->fish.source))->format.space)) + source_float_buf = source_float_buf_alloc; + source_image = babl_image_from_linear ( + source_float_buf, + babl_format_with_model_as_type (BABL(BABL ((babl->fish.source))->format.model), + type_float)); + convert_to_float ( + (BablFormat *) BABL (babl->fish.source), + source, + source_float_buf, + n ); + } + + if (babl_model_is ((void*)babl->fish.source->format.model, "RGBA")) + { + rgba_float_buf = source_float_buf; + rgba_image = babl_image_from_linear ( + rgba_float_buf, + (void*)babl->fish.source->format.model); + } + else + { + char src_name[256]; + Babl *conv; + + sprintf (src_name, "%s float", babl_get_name((void*)babl->fish.source->format.model)); + conv = + assert_conversion_find ( + babl_format_with_space (src_name, + BABL (BABL ((babl->fish.source))->format.space)), + babl_format_with_space ("RGBA float", + BABL (BABL ((babl->fish.source))->format.space))); + + rgba_float_buf_alloc = babl_malloc (sizeof (float) * n * 4); + rgba_float_buf = rgba_float_buf_alloc; + + rgba_image = babl_image_from_linear ( + rgba_float_buf, + babl_format_with_space ("RGBA float", + BABL (BABL ((babl->fish.source))->format.space))); + if (conv->class_type == BABL_CONVERSION_PLANAR) { @@ -791,40 +816,56 @@ babl_fish_reference_process (const Babl *babl, source_float_buf, rgba_float_buf, n); } - else babl_fatal ("oops"); - } - if (((babl->fish.source)->format.space != - ((babl->fish.destination)->format.space))) - { - float matrix[9]; - float *rgba = rgba_float_buf; - babl_matrix_mul_matrixf ( - (babl->fish.destination)->format.space->space.XYZtoRGBf, - (babl->fish.source)->format.space->space.RGBtoXYZf, - matrix); - - babl_matrix_mul_vectorff_buf4 (matrix, rgba, rgba, n); - } - { - char dst_name[256]; - Babl *conv; - if (babl->fish.destination->class_type == BABL_FORMAT) - sprintf (dst_name, "%s float", - babl_get_name (BABL (babl->fish.destination->format.model))); - else if (babl->fish.destination->class_type == BABL_MODEL) - sprintf (dst_name, "%s float", - babl_get_name (BABL (babl->fish.destination))); - conv = - assert_conversion_find ( - babl_format_with_space ("RGBA float", - BABL (BABL ((babl->fish.destination))->format.space)), - babl_format_with_space (dst_name, - BABL (babl->fish.destination))); + } - if (conv->class_type == BABL_CONVERSION_PLANAR) + if (((babl->fish.source)->format.space != + ((babl->fish.destination)->format.space))) + { + float matrix[9]; + float *rgba = rgba_float_buf; + babl_matrix_mul_matrixf ( + (babl->fish.destination)->format.space->space.XYZtoRGBf, + (babl->fish.source)->format.space->space.RGBtoXYZf, + matrix); + + babl_matrix_mul_vectorff_buf4 (matrix, rgba, rgba, n); + } + + { + char dst_name[256]; + Babl *conv; + const Babl *destination_float_format; + sprintf (dst_name, "%s float", babl_get_name((void*)babl->fish.destination->format.model)); + destination_float_format = + babl_format_with_space (dst_name, + BABL (BABL ((babl->fish.destination))->format.space)); + + if( + babl_format_with_space ("RGBA float", + BABL (BABL ((babl->fish.destination))->format.space)) == + babl_format_with_space (dst_name, + BABL (BABL ((babl->fish.destination))->format.space))) + { + 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; + conv = + assert_conversion_find ( + babl_format_with_space ("RGBA float", + BABL (BABL ((babl->fish.destination))->format.space)), + babl_format_with_space (dst_name, + BABL (BABL ((babl->fish.destination))->format.space))); + + if (conv->class_type == BABL_CONVERSION_PLANAR) + { + destination_image = babl_image_from_linear ( + destination_float_buf, destination_float_format); babl_conversion_process ( conv, (void*)rgba_image, (void*)destination_image, @@ -837,19 +878,23 @@ babl_fish_reference_process (const Babl *babl, rgba_float_buf, destination_float_buf, n); } - else babl_fatal ("oops"); - } - convert_from_float ( - (BablFormat *) BABL (babl->fish.destination), - destination_float_buf, - destination, - n - ); + } + } - babl_free (destination_float_buf); - babl_free (rgba_float_buf); - babl_free (source_float_buf); + convert_from_float ( + (BablFormat *) BABL (babl->fish.destination), + destination_float_buf, + destination, + n + ); + + if (destination_float_buf_alloc) + babl_free (destination_float_buf_alloc); + if (rgba_float_buf_alloc) + babl_free (rgba_float_buf_alloc); + if (source_float_buf_alloc) + babl_free (source_float_buf_alloc); } else /* double */ { @@ -859,12 +904,11 @@ babl_fish_reference_process (const Babl *babl, void *rgba_double_buf; void *destination_double_buf_alloc = NULL; void *destination_double_buf; - + if (babl->fish.source->format.type[0] == type_double && - BABL(babl->fish.source)->format.components == + BABL(babl->fish.source)->format.components == BABL(babl->fish.source)->format.model->components && 0) { - fprintf (stderr, "hita\n"); source_double_buf = (void*)source; source_image = babl_image_from_linear ( source_double_buf, BABL (BABL ((babl->fish.source))->format.model)); @@ -873,7 +917,7 @@ babl_fish_reference_process (const Babl *babl, { 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)); @@ -949,7 +993,6 @@ babl_fish_reference_process (const Babl *babl, } else { - /* XXX : do this with format instead of model - more generic */ Babl *conv = assert_conversion_find (destination_rgba_format, BABL (babl->fish.destination)->format.model);