operations: make generated point composers handle more pixel formats

Make the innerloops able to work with any number of components with or without
alpha, a possible performance enhancement would be to implement separate code
paths for formats with and without alpha, while still keeping the number of
components dynamic.

This makes the math and generated operations have code paths dealing with
grayscale and grayscale with alpha versions - reducing the needed memory
bandwidth, while also preparing for spectral or other multi-channel uses with
or without alpha channels.
parent 0f56f883
......@@ -46,14 +46,56 @@ property_double (value, _("Value"), 0.0)
static void prepare (GeglOperation *operation)
{
const Babl *space = gegl_operation_get_source_space (operation, "input");
const Babl *format;
if (!space)
space = gegl_operation_get_source_space (operation, "aux");
format = babl_format_with_space ("RGBA float", space);
const Babl *format = gegl_operation_get_source_format (operation, "input");
const Babl *space = NULL;
const Babl *model = NULL;
if (!format)
format = gegl_operation_get_source_format (operation, "aux");
if (format)
{
model = babl_format_get_model (format);
}
if (babl_model_is (model, "Y") ||
babl_model_is (model, "Y'") ||
babl_model_is (model, "Y~"))
{
format = babl_format_with_space ("Y float", space);
}
else if (babl_model_is (model, "YA") ||
babl_model_is (model, "Y'A") ||
babl_model_is (model, "Y~A") ||
babl_model_is (model, "YaA") ||
babl_model_is (model, "Y'aA"))
{
format = babl_format_with_space ("YA float", space);
}
else if (babl_model_is (model, "RGB") ||
babl_model_is (model, "R'G'B'") ||
babl_model_is (model, "R~G~B~"))
{
format = babl_format_with_space ("RGB float", space);
}
#if 0
else if (babl_model_is (model, "RGBA") ||
babl_model_is (model, "RGB") ||
babl_model_is (model, "R'G'B'A") ||
babl_model_is (model, "R'G'B'") ||
babl_model_is (model, "R~G~B~A") ||
babl_model_is (model, "R~G~B~") ||
babl_model_is (model, "RaGaBaA") ||
babl_model_is (model, "R'aG'aB'aA"))
{
format = babl_format_with_space ("RGBA float", space);
}
#endif
else
{
format = babl_format_with_space ("RGBA float", space);
}
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", babl_format_with_space ("RGB float", space));
gegl_operation_set_format (operation, "aux", format);
gegl_operation_set_format (operation, "output", format);
}
......@@ -69,6 +111,9 @@ process (GeglOperation *op,
gfloat * GEGL_ALIGNED in = in_buf;
gfloat * GEGL_ALIGNED out = out_buf;
gfloat * GEGL_ALIGNED aux = aux_buf;
const Babl *format = gegl_operation_get_format (op, "output");
gint components = babl_format_get_n_components (format);
gint alpha = babl_format_has_alpha (format);
gint i;
if (aux == NULL)
......@@ -77,16 +122,17 @@ process (GeglOperation *op,
for (i=0; i<n_pixels; i++)
{
gint j;
for (j=0; j<3; j++)
for (j=0; j<components-alpha; j++)
{
gfloat result;
gfloat input=in[j];
result = input + value;
out[j]=result;
}
out[3]=in[3];
in += 4;
out+= 4;
if (alpha)
out[components-1]=in[components-1];
in += components;
out+= components;
}
}
else
......@@ -95,7 +141,7 @@ process (GeglOperation *op,
{
gint j;
gfloat value;
for (j=0; j<3; j++)
for (j=0; j<components-alpha; j++)
{
gfloat input =in[j];
gfloat result;
......@@ -103,13 +149,14 @@ process (GeglOperation *op,
result = input + value;
out[j]=result;
}
out[3]=in[3];
in += 4;
aux += 3;
out+= 4;
if (alpha)
out[components-1]=in[components-1];
in += components;
aux += components;
out += components;
}
}
return TRUE;
}
......
......@@ -48,18 +48,55 @@ property_boolean (srgb, _("sRGB"), FALSE)
static void prepare (GeglOperation *operation)
{
const Babl *space = gegl_operation_get_source_space (operation, "input");
const Babl *format;
if (!space)
space = gegl_operation_get_source_space (operation, "aux");
if (GEGL_PROPERTIES (operation)->srgb)
format = babl_format_with_space ("R~aG~aB~aA float", space);
int use_srgb = GEGL_PROPERTIES (operation)->srgb?1:0;
const Babl *format = gegl_operation_get_source_format (operation, "input");
const Babl *space = NULL;
const Babl *model = NULL;
if (!format)
format = gegl_operation_get_source_format (operation, "aux");
if (format)
{
model = babl_format_get_model (format);
}
if (babl_model_is (model, "Y") ||
babl_model_is (model, "Y'") ||
babl_model_is (model, "Y~"))
{
format = babl_format_with_space (use_srgb?"Y~ float":"Y float", space);
}
else if (babl_model_is (model, "YA") ||
babl_model_is (model, "Y'A") ||
babl_model_is (model, "Y~A") ||
babl_model_is (model, "YaA") ||
babl_model_is (model, "Y'aA"))
{
format = babl_format_with_space (use_srgb?"Y~aA float":"YaA float", space);
}
else if (babl_model_is (model, "RGB") ||
babl_model_is (model, "R'G'B'") ||
babl_model_is (model, "R~G~B~"))
{
format = babl_format_with_space (use_srgb?"R~G~B~ float":"RGB float", space);
}
else if (babl_model_is (model, "RGBA") ||
babl_model_is (model, "RGB") ||
babl_model_is (model, "R'G'B'A") ||
babl_model_is (model, "R'G'B'") ||
babl_model_is (model, "R~G~B~A") ||
babl_model_is (model, "R~G~B~") ||
babl_model_is (model, "RaGaBaA") ||
babl_model_is (model, "R'aG'aB'aA"))
{
format = babl_format_with_space (use_srgb?"R~aG~aB~a float":"RaGaBaA float", space);
}
else
format = babl_format_with_space ("RaGaBaA float", space);
{
format = babl_format_with_space (use_srgb?"R~aG~aB~a float":"RaGaBaA float", space);
}
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
gegl_operation_set_format (operation, "output", format);
}
......@@ -76,6 +113,9 @@ process (GeglOperation *op,
gfloat * GEGL_ALIGNED in = in_buf;
gfloat * GEGL_ALIGNED aux = aux_buf;
gfloat * GEGL_ALIGNED out = out_buf;
const Babl *format = gegl_operation_get_format (op, "output");
gint components = babl_format_get_n_components (format);
gint alpha = babl_format_has_alpha (format);
if (!aux)
return TRUE;
......@@ -86,11 +126,18 @@ process (GeglOperation *op,
gint j;
gfloat aA G_GNUC_UNUSED, aB G_GNUC_UNUSED, aD G_GNUC_UNUSED;
aB = in[3];
aA = aux[3];
if (alpha)
{
aB = in[components-1];
aA = aux[components-1];
}
else
{
aB = aA = 1.0f;
}
aD = 0.0f;
for (j = 0; j < 3; j++)
for (j = 0; j < components-alpha; j++)
{
gfloat cA G_GNUC_UNUSED, cB G_GNUC_UNUSED;
......@@ -98,10 +145,11 @@ process (GeglOperation *op,
cA = aux[j];
out[j] = 0.0f;
}
out[3] = aD;
in += 4;
aux += 4;
out += 4;
if (alpha)
out[components-alpha] = aD;
in += components;
aux += components;
out += components;
}
}
return TRUE;
......
......@@ -48,18 +48,55 @@ property_boolean (srgb, _("sRGB"), FALSE)
static void prepare (GeglOperation *operation)
{
const Babl *space = gegl_operation_get_source_space (operation, "input");
const Babl *format;
if (!space)
space = gegl_operation_get_source_space (operation, "aux");
int use_srgb = GEGL_PROPERTIES (operation)->srgb?1:0;
const Babl *format = gegl_operation_get_source_format (operation, "input");
const Babl *space = NULL;
const Babl *model = NULL;
if (!format)
format = gegl_operation_get_source_format (operation, "aux");
if (format)
{
model = babl_format_get_model (format);
}
if (GEGL_PROPERTIES (operation)->srgb)
format = babl_format_with_space ("R~aG~aB~aA float", space);
if (babl_model_is (model, "Y") ||
babl_model_is (model, "Y'") ||
babl_model_is (model, "Y~"))
{
format = babl_format_with_space (use_srgb?"Y~ float":"Y float", space);
}
else if (babl_model_is (model, "YA") ||
babl_model_is (model, "Y'A") ||
babl_model_is (model, "Y~A") ||
babl_model_is (model, "YaA") ||
babl_model_is (model, "Y'aA"))
{
format = babl_format_with_space (use_srgb?"Y~aA float":"YaA float", space);
}
else if (babl_model_is (model, "RGB") ||
babl_model_is (model, "R'G'B'") ||
babl_model_is (model, "R~G~B~"))
{
format = babl_format_with_space (use_srgb?"R~G~B~ float":"RGB float", space);
}
else if (babl_model_is (model, "RGBA") ||
babl_model_is (model, "RGB") ||
babl_model_is (model, "R'G'B'A") ||
babl_model_is (model, "R'G'B'") ||
babl_model_is (model, "R~G~B~A") ||
babl_model_is (model, "R~G~B~") ||
babl_model_is (model, "RaGaBaA") ||
babl_model_is (model, "R'aG'aB'aA"))
{
format = babl_format_with_space (use_srgb?"R~aG~aB~a float":"RaGaBaA float", space);
}
else
format = babl_format_with_space ("RaGaBaA float", space);
{
format = babl_format_with_space (use_srgb?"R~aG~aB~a float":"RaGaBaA float", space);
}
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
gegl_operation_set_format (operation, "output", format);
}
......@@ -119,6 +156,9 @@ process (GeglOperation *op,
const GeglRectangle *roi,
gint level)
{
const Babl *format = gegl_operation_get_format (op, "output");
gint components = babl_format_get_n_components (format);
gint alpha = babl_format_has_alpha (format);
gfloat * GEGL_ALIGNED in = in_buf;
gfloat * GEGL_ALIGNED aux = aux_buf;
gfloat * GEGL_ALIGNED out = out_buf;
......@@ -132,11 +172,18 @@ process (GeglOperation *op,
gfloat aA, aB, aD;
gint j;
aB = in[3];
aA = aux[3];
if (alpha)
{
aB = in[components-1];
aA = aux[components-1];
}
else
{
aB = aA = 1.0f;
}
aD = aA + aB - aA * aB;
for (j = 0; j < 3; j++)
for (j = 0; j < components-alpha; j++)
{
gfloat cA, cB;
......@@ -147,10 +194,11 @@ process (GeglOperation *op,
else
out[j] = CLAMP ((cA == 0 ? 1 : (aA * (cA * aB + cB * aA - aA * aB) / cA) + cA * (1 - aB) + cB * (1 - aA)), 0, aD);
}
out[3] = aD;
in += 4;
aux += 4;
out += 4;
if (alpha)
out[components-1] = aD;
in += components;
aux += components;
out += components;
}
return TRUE;
......
......@@ -48,18 +48,55 @@ property_boolean (srgb, _("sRGB"), FALSE)
static void prepare (GeglOperation *operation)
{
const Babl *space = gegl_operation_get_source_space (operation, "input");
const Babl *format;
if (!space)
space = gegl_operation_get_source_space (operation, "aux");
int use_srgb = GEGL_PROPERTIES (operation)->srgb?1:0;
const Babl *format = gegl_operation_get_source_format (operation, "input");
const Babl *space = NULL;
const Babl *model = NULL;
if (!format)
format = gegl_operation_get_source_format (operation, "aux");
if (format)
{
model = babl_format_get_model (format);
}
if (GEGL_PROPERTIES (operation)->srgb)
format = babl_format_with_space ("R~aG~aB~aA float", space);
if (babl_model_is (model, "Y") ||
babl_model_is (model, "Y'") ||
babl_model_is (model, "Y~"))
{
format = babl_format_with_space (use_srgb?"Y~ float":"Y float", space);
}
else if (babl_model_is (model, "YA") ||
babl_model_is (model, "Y'A") ||
babl_model_is (model, "Y~A") ||
babl_model_is (model, "YaA") ||
babl_model_is (model, "Y'aA"))
{
format = babl_format_with_space (use_srgb?"Y~aA float":"YaA float", space);
}
else if (babl_model_is (model, "RGB") ||
babl_model_is (model, "R'G'B'") ||
babl_model_is (model, "R~G~B~"))
{
format = babl_format_with_space (use_srgb?"R~G~B~ float":"RGB float", space);
}
else if (babl_model_is (model, "RGBA") ||
babl_model_is (model, "RGB") ||
babl_model_is (model, "R'G'B'A") ||
babl_model_is (model, "R'G'B'") ||
babl_model_is (model, "R~G~B~A") ||
babl_model_is (model, "R~G~B~") ||
babl_model_is (model, "RaGaBaA") ||
babl_model_is (model, "R'aG'aB'aA"))
{
format = babl_format_with_space (use_srgb?"R~aG~aB~a float":"RaGaBaA float", space);
}
else
format = babl_format_with_space ("RaGaBaA float", space);
{
format = babl_format_with_space (use_srgb?"R~aG~aB~a float":"RaGaBaA float", space);
}
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
gegl_operation_set_format (operation, "output", format);
}
......@@ -119,6 +156,9 @@ process (GeglOperation *op,
const GeglRectangle *roi,
gint level)
{
const Babl *format = gegl_operation_get_format (op, "output");
gint components = babl_format_get_n_components (format);
gint alpha = babl_format_has_alpha (format);
gfloat * GEGL_ALIGNED in = in_buf;
gfloat * GEGL_ALIGNED aux = aux_buf;
gfloat * GEGL_ALIGNED out = out_buf;
......@@ -132,11 +172,18 @@ process (GeglOperation *op,
gfloat aA, aB, aD;
gint j;
aB = in[3];
aA = aux[3];
if (alpha)
{
aB = in[components-1];
aA = aux[components-1];
}
else
{
aB = aA = 1.0f;
}
aD = aA + aB - aA * aB;
for (j = 0; j < 3; j++)
for (j = 0; j < components-alpha; j++)
{
gfloat cA, cB;
......@@ -147,10 +194,11 @@ process (GeglOperation *op,
else
out[j] = CLAMP ((cA == aA ? 1 : cB * aA / (aA == 0 ? 1 : 1 - cA / aA)) + cA * (1 - aB) + cB * (1 - aA), 0, aD);
}
out[3] = aD;
in += 4;
aux += 4;
out += 4;
if (alpha)
out[components-1] = aD;
in += components;
aux += components;
out += components;
}
return TRUE;
......
......@@ -48,18 +48,55 @@ property_boolean (srgb, _("sRGB"), FALSE)
static void prepare (GeglOperation *operation)
{
const Babl *space = gegl_operation_get_source_space (operation, "input");
const Babl *format;
if (!space)
space = gegl_operation_get_source_space (operation, "aux");
int use_srgb = GEGL_PROPERTIES (operation)->srgb?1:0;
const Babl *format = gegl_operation_get_source_format (operation, "input");
const Babl *space = NULL;
const Babl *model = NULL;
if (!format)
format = gegl_operation_get_source_format (operation, "aux");
if (format)
{
model = babl_format_get_model (format);
}
if (GEGL_PROPERTIES (operation)->srgb)
format = babl_format_with_space ("R~aG~aB~aA float", space);
if (babl_model_is (model, "Y") ||
babl_model_is (model, "Y'") ||
babl_model_is (model, "Y~"))
{
format = babl_format_with_space (use_srgb?"Y~ float":"Y float", space);
}
else if (babl_model_is (model, "YA") ||
babl_model_is (model, "Y'A") ||
babl_model_is (model, "Y~A") ||
babl_model_is (model, "YaA") ||
babl_model_is (model, "Y'aA"))
{
format = babl_format_with_space (use_srgb?"Y~aA float":"YaA float", space);
}
else if (babl_model_is (model, "RGB") ||
babl_model_is (model, "R'G'B'") ||
babl_model_is (model, "R~G~B~"))
{
format = babl_format_with_space (use_srgb?"R~G~B~ float":"RGB float", space);
}
else if (babl_model_is (model, "RGBA") ||
babl_model_is (model, "RGB") ||
babl_model_is (model, "R'G'B'A") ||
babl_model_is (model, "R'G'B'") ||
babl_model_is (model, "R~G~B~A") ||
babl_model_is (model, "R~G~B~") ||
babl_model_is (model, "RaGaBaA") ||
babl_model_is (model, "R'aG'aB'aA"))
{
format = babl_format_with_space (use_srgb?"R~aG~aB~a float":"RaGaBaA float", space);
}
else
format = babl_format_with_space ("RaGaBaA float", space);
{
format = babl_format_with_space (use_srgb?"R~aG~aB~a float":"RaGaBaA float", space);
}
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
gegl_operation_set_format (operation, "output", format);
}
......@@ -119,6 +156,9 @@ process (GeglOperation *op,
const GeglRectangle *roi,
gint level)
{
const Babl *format = gegl_operation_get_format (op, "output");
gint components = babl_format_get_n_components (format);
gint alpha = babl_format_has_alpha (format);
gfloat * GEGL_ALIGNED in = in_buf;
gfloat * GEGL_ALIGNED aux = aux_buf;
gfloat * GEGL_ALIGNED out = out_buf;
......@@ -132,11 +172,18 @@ process (GeglOperation *op,
gfloat aA, aB, aD;
gint j;
aB = in[3];
aA = aux[3];
if (alpha)
{
aB = in[components-1];
aA = aux[components-1];
}
else
{
aB = aA = 1.0f;
}
aD = aA + aB - aA * aB;
for (j = 0; j < 3; j++)
for (j = 0; j < components-alpha; j++)
{
gfloat cA, cB;
......@@ -144,10 +191,11 @@ process (GeglOperation *op,
cA = aux[j];
out[j] = CLAMP (MIN (cA * aB, cB * aA) + cA * (1 - aB) + cB * (1 - aA), 0, aD);
}
out[3] = aD;
in += 4;
aux += 4;
out += 4;
if (alpha)
out[components-1] = aD;
in += components;
aux += components;
out += components;
}
return TRUE;
......
......@@ -48,18 +48,55 @@ property_boolean (srgb, _("sRGB"), FALSE)
static void prepare (GeglOperation *operation)
{
const Babl *space = gegl_operation_get_source_space (operation, "input");
const Babl *format;
if (!space)
space = gegl_operation_get_source_space (operation, "aux");
int use_srgb = GEGL_PROPERTIES (operation)->srgb?1:0;
const Babl *format = gegl_operation_get_source_format (operation, "input");
const Babl *space = NULL;
const Babl *model = NULL;
if (!format)
format = gegl_operation_get_source_format (operation, "aux");
if (format)
{
model = babl_format_get_model (format);
}
if (GEGL_PROPERTIES (operation)->srgb)
format = babl_format_with_space ("R~aG~aB~aA float", space);
if (babl_model_is (model, "Y") ||
babl_model_is (model, "Y'") ||
babl_model_is (model, "Y~"))
{
format = babl_format_with_space (use_srgb?"Y~ float":"Y float", space);
}
else if (babl_model_is (model, "YA") ||
babl_model_is (model, "Y'A") ||
babl_model_is (model, "Y~A") ||
babl_model_is (model, "YaA") ||
babl_model_is (model, "Y'aA"))
{
format = babl_format_with_space (use_srgb?"Y~aA float":"YaA float", space);
}
else if (babl_model_is (model, "RGB") ||
babl_model_is (model, "R'G'B'") ||
babl_model_is (model, "R~G~B~"))
{
format = babl_format_with_space (use_srgb?"R~G~B~ float":"RGB float", space);
}
else if (babl_model_is (model, "RGBA") ||
babl_model_is (model, "RGB") ||
babl_model_is (model, "R'G'B'A") ||
babl_model_is (model, "R'G'B'") ||
babl_model_is (model, "R~G~B~A") ||
babl_model_is (model, "R~G~B~") ||
babl_model_is (model, "RaGaBaA") ||
babl_model_is (model, "R'aG'aB'aA"))
{
format = babl_format_with_space (use_srgb?"R~aG~aB~a float":"RaGaBaA float", space);
}
else
format = babl_format_with_space ("RaGaBaA float", space);
{
format = babl_format_with_space (use_srgb?"R~aG~aB~a float":"RaGaBaA float", space);
}
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "aux", format);
gegl_operation_set_format (operation, "output", format);
}
......@@ -119,6 +156,9 @@ process (GeglOperation *op,
const GeglRectangle *roi,
gint level)
{
const Babl *format = gegl_operation_get_format (op, "output");
gint components = babl_format_get_n_components (format);
gint alpha = babl_format_has_alpha (format);
gfloat * GEGL_ALIGNED in = in_buf;
gfloat * GEGL_ALIGNED aux = aux_buf;
gfloat * GEGL_ALIGNED out = out_buf;
......@@ -132,11 +172,18 @@ process (GeglOperation *op,
gfloat aA, aB, aD;
gint j;
aB = in[3];
aA = aux[3];
if (alpha)
{
aB = in[components-1];
aA = aux[components-1];
}
else
{
aB = aA = 1.0f;
}
aD = aA + aB - aA * aB;
for (j = 0; j < 3; j++)
for (j = 0; j < components-alpha; j++)
{
gfloat cA, cB;
......@@ -144,10 +191,11 @@ process (GeglOperation *op,
cA = aux[j];
out[j] = CLAMP (cA + cB - 2 * (MIN (cA * aB, cB * aA)), 0, aD);
}
out[3] = aD;
in += 4;
aux += 4;
out += 4;
if (alpha)
out[components-1] = aD;
in += components;
aux += components;
out += components;
}
return TRUE;
......
......@@ -46,14 +46,56 @@ property_double (value, _("Value"), 1.0)
static void prepare (GeglOperation *operation)
{
const Babl *space = gegl_operation_get_source_space (operation, "input");
const Babl *format;
if (!space)
space = gegl_operation_get_source_space (operation, "aux");
format = babl_format_with_space ("RGBA float", space);
const Babl *format = gegl_operation_get_source_format (operation, "input");
const Babl *space = NULL;
const Babl *model = NULL;
if (!format)
format = gegl_operation_get_source_format (operation, "aux");
if (format)
{
model = babl_format_get_model (format);
}
if (babl_model_is (model, "Y") ||
babl_model_is (model, "Y'") ||
babl_model_is (model, "Y~"))
{
format = babl_format_with_space ("Y float", space);
}
else if (babl_model_is (model, "YA") ||
babl_model_is (