libgimpcolor, plug-ins: Replace gimp_bilinear_rgb/a()...

..with gimp_bilinear_rgb ().
This function takes in a double array of raw pixels,
a boolean to determine if the pixels have an alpha channel,
and a reference to return the final pixel to.
This commit is contained in:
Alx Sa 2024-09-08 15:00:49 +00:00
parent 74c272ce69
commit b54a70af69
6 changed files with 154 additions and 119 deletions

View file

@ -18,6 +18,7 @@
#include "config.h" #include "config.h"
#include <gegl.h>
#include <glib-object.h> #include <glib-object.h>
#include "libgimpmath/gimpmath.h" #include "libgimpmath/gimpmath.h"
@ -156,18 +157,28 @@ gimp_bilinear_32 (gdouble x,
* gimp_bilinear_rgb: * gimp_bilinear_rgb:
* @x: * @x:
* @y: * @y:
* @values: (array fixed-size=4): * @values: (array fixed-size=16): Array of pixels in RGBA double format
* @has_alpha: Whether @values has an alpha channel
* @retvalues: (array fixed-size=4): Resulting pixel
*/ */
GimpRGB void
gimp_bilinear_rgb (gdouble x, gimp_bilinear_rgb (gdouble x,
gdouble y, gdouble y,
GimpRGB *values) gdouble *values,
gboolean has_alpha,
gdouble *retvalues)
{ {
gdouble m0, m1; gdouble m0;
gdouble ix, iy; gdouble m1;
GimpRGB v = { 0, }; gdouble ix;
gdouble iy;
gdouble a[4] = { 1.0, 1.0, 1.0, 1.0 };
gdouble alpha = 1.0;
g_return_val_if_fail (values != NULL, v); for (gint i = 0; i < 4; i++)
retvalues[i] = 0.0;
g_return_if_fail (values != NULL);
x = fmod (x, 1.0); x = fmod (x, 1.0);
y = fmod (y, 1.0); y = fmod (y, 1.0);
@ -180,94 +191,25 @@ gimp_bilinear_rgb (gdouble x,
ix = 1.0 - x; ix = 1.0 - x;
iy = 1.0 - y; iy = 1.0 - y;
/* Red */ if (has_alpha)
{
for (gint i = 0; i < 4; i++)
a[i] = values[(i * 4) + 3];
m0 = ix * values[0].r + x * values[1].r; m0 = ix * a[0] + x * a[1];
m1 = ix * values[2].r + x * values[3].r; m1 = ix * a[2] + x * a[3];
v.r = iy * m0 + y * m1; alpha = retvalues[3] = iy * m0 + y * m1;
/* Green */
m0 = ix * values[0].g + x * values[1].g;
m1 = ix * values[2].g + x * values[3].g;
v.g = iy * m0 + y * m1;
/* Blue */
m0 = ix * values[0].b + x * values[1].b;
m1 = ix * values[2].b + x * values[3].b;
v.b = iy * m0 + y * m1;
return v;
} }
/**
* gimp_bilinear_rgba:
* @x:
* @y:
* @values: (array fixed-size=4):
*/
GimpRGB
gimp_bilinear_rgba (gdouble x,
gdouble y,
GimpRGB *values)
{
gdouble m0, m1;
gdouble ix, iy;
gdouble a0, a1, a2, a3, alpha;
GimpRGB v = { 0, };
g_return_val_if_fail (values != NULL, v);
x = fmod (x, 1.0);
y = fmod (y, 1.0);
if (x < 0)
x += 1.0;
if (y < 0)
y += 1.0;
ix = 1.0 - x;
iy = 1.0 - y;
a0 = values[0].a;
a1 = values[1].a;
a2 = values[2].a;
a3 = values[3].a;
/* Alpha */
m0 = ix * a0 + x * a1;
m1 = ix * a2 + x * a3;
alpha = v.a = iy * m0 + y * m1;
if (alpha > 0) if (alpha > 0)
{ {
/* Red */ for (gint i = 0; i < 3; i++)
{
m0 = ix * a[0] * values[0 + i] + x * a[1] * values[4 + i];
m1 = ix * a[2] * values[8 + 1] + x * a[3] * values[12 + i];
m0 = ix * a0 * values[0].r + x * a1 * values[1].r; retvalues[i] = (iy * m0 + y * m1) / alpha;
m1 = ix * a2 * values[2].r + x * a3 * values[3].r; }
v.r = (iy * m0 + y * m1)/alpha;
/* Green */
m0 = ix * a0 * values[0].g + x * a1 * values[1].g;
m1 = ix * a2 * values[2].g + x * a3 * values[3].g;
v.g = (iy * m0 + y * m1)/alpha;
/* Blue */
m0 = ix * a0 * values[0].b + x * a1 * values[1].b;
m1 = ix * a2 * values[2].b + x * a3 * values[3].b;
v.b = (iy * m0 + y * m1)/alpha;
} }
return v;
} }

View file

@ -43,12 +43,11 @@ guint16 gimp_bilinear_16 (gdouble x,
guint32 gimp_bilinear_32 (gdouble x, guint32 gimp_bilinear_32 (gdouble x,
gdouble y, gdouble y,
guint32 *values); guint32 *values);
GimpRGB gimp_bilinear_rgb (gdouble x, void gimp_bilinear_rgb (gdouble x,
gdouble y, gdouble y,
GimpRGB *values); gdouble *values,
GimpRGB gimp_bilinear_rgba (gdouble x, gboolean has_alpha,
gdouble y, gdouble *retvalues);
GimpRGB *values);
G_END_DECLS G_END_DECLS

View file

@ -5,7 +5,6 @@ EXPORTS
gimp_bilinear_32 gimp_bilinear_32
gimp_bilinear_8 gimp_bilinear_8
gimp_bilinear_rgb gimp_bilinear_rgb
gimp_bilinear_rgba
gimp_cairo_checkerboard_create gimp_cairo_checkerboard_create
gimp_cairo_surface_create_buffer gimp_cairo_surface_create_buffer
gimp_cairo_surface_get_format gimp_cairo_surface_get_format

View file

@ -541,6 +541,8 @@ getpixel (GeglBuffer *buffer,
register gint x1, y1, x2, y2; register gint x1, y1, x2, y2;
gint width, height; gint width, height;
static GimpRGB pp[4]; static GimpRGB pp[4];
gdouble pixel[4];
gdouble pixels[16];
width = border_w; width = border_w;
height = border_h; height = border_h;
@ -566,10 +568,17 @@ getpixel (GeglBuffer *buffer,
peek (buffer, x1, y2, &pp[2]); peek (buffer, x1, y2, &pp[2]);
peek (buffer, x2, y2, &pp[3]); peek (buffer, x2, y2, &pp[3]);
if (source_drw_has_alpha) for (gint i = 0; i < 4; i++)
*p = gimp_bilinear_rgba (u, v, pp); {
else pixels[(i * 4)] = pp[i].r;
*p = gimp_bilinear_rgb (u, v, pp); pixels[(i * 4) + 1] = pp[i].g;
pixels[(i * 4) + 2] = pp[i].b;
pixels[(i * 4) + 3] = pp[i].a;
}
gimp_bilinear_rgb (u, v, pixels, source_drw_has_alpha, pixel);
gimp_rgba_set (p, pixel[0], pixel[1], pixel[2], pixel[3]);
} }
static void static void

View file

@ -242,8 +242,14 @@ get_image_color (gdouble u,
gdouble v, gdouble v,
gint *inside) gint *inside)
{ {
gint x1, y1, x2, y2; gint x1;
gint y1;
gint x2;
gint y2;
GimpRGB p[4]; GimpRGB p[4];
GimpRGB p_rgba;
gdouble pixel[4];
gdouble pixels[16];
x1 = RINT (u); x1 = RINT (u);
y1 = RINT (v); y1 = RINT (v);
@ -269,7 +275,19 @@ get_image_color (gdouble u,
p[2] = peek (x1, y2); p[2] = peek (x1, y2);
p[3] = peek (x2, y2); p[3] = peek (x2, y2);
return gimp_bilinear_rgba (u, v, p); for (gint i = 0; i < 4; i++)
{
pixels[(i * 4)] = p[i].r;
pixels[(i * 4) + 1] = p[i].g;
pixels[(i * 4) + 2] = p[i].b;
pixels[(i * 4) + 3] = p[i].a;
}
gimp_bilinear_rgb (u, v, pixels, TRUE, pixel);
gimp_rgba_set (&p_rgba, pixel[0], pixel[1], pixel[2], pixel[3]);
return p_rgba;
} }
gdouble gdouble

View file

@ -189,8 +189,14 @@ get_image_color (gdouble u,
gdouble v, gdouble v,
gint *inside) gint *inside)
{ {
gint x1, y1, x2, y2; gint x1;
gint y1;
gint x2;
gint y2;
GimpRGB p[4]; GimpRGB p[4];
GimpRGB p_rgba;
gdouble pixel[4];
gdouble pixels[16];
pos_to_int (u, v, &x1, &y1); pos_to_int (u, v, &x1, &y1);
@ -212,7 +218,19 @@ get_image_color (gdouble u,
p[2] = peek (x1, y2); p[2] = peek (x1, y2);
p[3] = peek (x2, y2); p[3] = peek (x2, y2);
return gimp_bilinear_rgba (u * width, v * height, p); for (gint i = 0; i < 4; i++)
{
pixels[(i * 4)] = p[i].r;
pixels[(i * 4) + 1] = p[i].g;
pixels[(i * 4) + 2] = p[i].b;
pixels[(i * 4) + 3] = p[i].a;
}
gimp_bilinear_rgb (u * width, v * height, pixels, TRUE, pixel);
gimp_rgba_set (&p_rgba, pixel[0], pixel[1], pixel[2], pixel[3]);
return p_rgba;
} }
if (checkbounds (x1, y1) == FALSE) if (checkbounds (x1, y1) == FALSE)
@ -239,7 +257,19 @@ get_image_color (gdouble u,
p[2] = peek (x1, y2); p[2] = peek (x1, y2);
p[3] = peek (x2, y2); p[3] = peek (x2, y2);
return gimp_bilinear_rgba (u * width, v * height, p); for (gint i = 0; i < 4; i++)
{
pixels[(i * 4)] = p[i].r;
pixels[(i * 4) + 1] = p[i].g;
pixels[(i * 4) + 2] = p[i].b;
pixels[(i * 4) + 3] = p[i].a;
}
gimp_bilinear_rgb (u * width, v * height, pixels, TRUE, pixel);
gimp_rgba_set (&p_rgba, pixel[0], pixel[1], pixel[2], pixel[3]);
return p_rgba;
} }
GimpRGB GimpRGB
@ -247,9 +277,16 @@ get_box_image_color (gint image,
gdouble u, gdouble u,
gdouble v) gdouble v)
{ {
gint w, h; gint w;
gint x1, y1, x2, y2; gint h;
gint x1;
gint y1;
gint x2;
gint y2;
GimpRGB p[4]; GimpRGB p[4];
GimpRGB p_rgba;
gdouble pixel[4];
gdouble pixels[16];
w = gegl_buffer_get_width (box_buffers[image]); w = gegl_buffer_get_width (box_buffers[image]);
h = gegl_buffer_get_height (box_buffers[image]); h = gegl_buffer_get_height (box_buffers[image]);
@ -271,7 +308,19 @@ get_box_image_color (gint image,
p[2] = peek_box_image (image, x1, y2); p[2] = peek_box_image (image, x1, y2);
p[3] = peek_box_image (image, x2, y2); p[3] = peek_box_image (image, x2, y2);
return gimp_bilinear_rgba (u * w, v * h, p); for (gint i = 0; i < 4; i++)
{
pixels[(i * 4)] = p[i].r;
pixels[(i * 4) + 1] = p[i].g;
pixels[(i * 4) + 2] = p[i].b;
pixels[(i * 4) + 3] = p[i].a;
}
gimp_bilinear_rgb (u * w, v * h, pixels, TRUE, pixel);
gimp_rgba_set (&p_rgba, pixel[0], pixel[1], pixel[2], pixel[3]);
return p_rgba;
} }
GimpRGB GimpRGB
@ -279,9 +328,16 @@ get_cylinder_image_color (gint image,
gdouble u, gdouble u,
gdouble v) gdouble v)
{ {
gint w, h; gint w;
gint x1, y1, x2, y2; gint h;
gint x1;
gint y1;
gint x2;
gint y2;
GimpRGB p[4]; GimpRGB p[4];
GimpRGB p_rgba;
gdouble pixel[4];
gdouble pixels[16];
w = gegl_buffer_get_width (cylinder_buffers[image]); w = gegl_buffer_get_width (cylinder_buffers[image]);
h = gegl_buffer_get_height (cylinder_buffers[image]); h = gegl_buffer_get_height (cylinder_buffers[image]);
@ -303,7 +359,19 @@ get_cylinder_image_color (gint image,
p[2] = peek_cylinder_image (image, x1, y2); p[2] = peek_cylinder_image (image, x1, y2);
p[3] = peek_cylinder_image (image, x2, y2); p[3] = peek_cylinder_image (image, x2, y2);
return gimp_bilinear_rgba (u * w, v * h, p); for (gint i = 0; i < 4; i++)
{
pixels[(i * 4)] = p[i].r;
pixels[(i * 4) + 1] = p[i].g;
pixels[(i * 4) + 2] = p[i].b;
pixels[(i * 4) + 3] = p[i].a;
}
gimp_bilinear_rgb (u * w, v * h, pixels, TRUE, pixel);
gimp_rgba_set (&p_rgba, pixel[0], pixel[1], pixel[2], pixel[3]);
return p_rgba;
} }
/****************************************/ /****************************************/