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 <gegl.h>
#include <glib-object.h>
#include "libgimpmath/gimpmath.h"
@ -156,71 +157,28 @@ gimp_bilinear_32 (gdouble x,
* gimp_bilinear_rgb:
* @x:
* @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
gimp_bilinear_rgb (gdouble x,
gdouble y,
GimpRGB *values)
void
gimp_bilinear_rgb (gdouble x,
gdouble y,
gdouble *values,
gboolean has_alpha,
gdouble *retvalues)
{
gdouble m0, m1;
gdouble ix, iy;
GimpRGB v = { 0, };
gdouble m0;
gdouble m1;
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;
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;
/* Red */
m0 = ix * values[0].r + x * values[1].r;
m1 = ix * values[2].r + x * values[3].r;
v.r = 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);
g_return_if_fail (values != NULL);
x = fmod (x, 1.0);
y = fmod (y, 1.0);
@ -233,41 +191,25 @@ gimp_bilinear_rgba (gdouble x,
ix = 1.0 - x;
iy = 1.0 - y;
a0 = values[0].a;
a1 = values[1].a;
a2 = values[2].a;
a3 = values[3].a;
if (has_alpha)
{
for (gint i = 0; i < 4; i++)
a[i] = values[(i * 4) + 3];
/* Alpha */
m0 = ix * a[0] + x * a[1];
m1 = ix * a[2] + x * a[3];
m0 = ix * a0 + x * a1;
m1 = ix * a2 + x * a3;
alpha = v.a = iy * m0 + y * m1;
alpha = retvalues[3] = iy * m0 + y * m1;
}
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;
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;
retvalues[i] = (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,
gdouble y,
guint32 *values);
GimpRGB gimp_bilinear_rgb (gdouble x,
void gimp_bilinear_rgb (gdouble x,
gdouble y,
GimpRGB *values);
GimpRGB gimp_bilinear_rgba (gdouble x,
gdouble y,
GimpRGB *values);
gdouble *values,
gboolean has_alpha,
gdouble *retvalues);
G_END_DECLS

View File

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

View File

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

View File

@ -239,11 +239,17 @@ pos_to_float (gdouble x,
GimpRGB
get_image_color (gdouble u,
gdouble v,
gint *inside)
gdouble v,
gint *inside)
{
gint x1, y1, x2, y2;
GimpRGB p[4];
gint x1;
gint y1;
gint x2;
gint y2;
GimpRGB p[4];
GimpRGB p_rgba;
gdouble pixel[4];
gdouble pixels[16];
x1 = RINT (u);
y1 = RINT (v);
@ -269,7 +275,19 @@ get_image_color (gdouble u,
p[2] = peek (x1, 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

View File

@ -189,8 +189,14 @@ get_image_color (gdouble u,
gdouble v,
gint *inside)
{
gint x1, y1, x2, y2;
GimpRGB p[4];
gint x1;
gint y1;
gint x2;
gint y2;
GimpRGB p[4];
GimpRGB p_rgba;
gdouble pixel[4];
gdouble pixels[16];
pos_to_int (u, v, &x1, &y1);
@ -212,7 +218,19 @@ get_image_color (gdouble u,
p[2] = peek (x1, 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)
@ -232,14 +250,26 @@ get_image_color (gdouble u,
return peek (x1, y1);
}
*inside=TRUE;
*inside = TRUE;
p[0] = peek (x1, y1);
p[1] = peek (x2, y1);
p[2] = peek (x1, 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
@ -247,9 +277,16 @@ get_box_image_color (gint image,
gdouble u,
gdouble v)
{
gint w, h;
gint x1, y1, x2, y2;
GimpRGB p[4];
gint w;
gint h;
gint x1;
gint y1;
gint x2;
gint y2;
GimpRGB p[4];
GimpRGB p_rgba;
gdouble pixel[4];
gdouble pixels[16];
w = gegl_buffer_get_width (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[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
@ -279,9 +328,16 @@ get_cylinder_image_color (gint image,
gdouble u,
gdouble v)
{
gint w, h;
gint x1, y1, x2, y2;
GimpRGB p[4];
gint w;
gint h;
gint x1;
gint y1;
gint x2;
gint y2;
GimpRGB p[4];
GimpRGB p_rgba;
gdouble pixel[4];
gdouble pixels[16];
w = gegl_buffer_get_width (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[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;
}
/****************************************/