{
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;
- }
-
}
}
-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;
}
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 ==
{
- 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),
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);
}