libgimpcolor, operations, plug-ins: Replace GimpRGB in GimpAdaptiveSuperSample

GimpRGB replaced with gdouble arrays.
Note that some temporary intermediate
GimpRGBs objects were added, which will
be removed when map-object and
gimpoperationgradient are fully converted
in a separate commit.
This commit is contained in:
Alx Sa 2024-09-10 02:18:51 +00:00
parent de529a940a
commit f8e04894ed
7 changed files with 177 additions and 107 deletions

View File

@ -153,15 +153,15 @@ static gdouble gradient_calc_shapeburst_dimpled_factor (GeglSampler
static void gradient_render_pixel (gdouble x,
gdouble y,
GimpRGB *color,
gdouble *color,
gpointer render_data);
static void gradient_put_pixel (gint x,
gint y,
GimpRGB *color,
gdouble *color,
gpointer put_pixel_data);
static void gradient_dither_pixel (GimpRGB *color,
static void gradient_dither_pixel (gdouble *color,
GRand *dither_rand,
gfloat *dest);
@ -881,7 +881,7 @@ gradient_calc_shapeburst_dimpled_factor (GeglSampler *dist_sampler,
static void
gradient_render_pixel (gdouble x,
gdouble y,
GimpRGB *rgb,
gdouble *rgb,
gpointer render_data)
{
RenderBlendData *rbd = render_data;
@ -994,7 +994,8 @@ gradient_render_pixel (gdouble x,
case GIMP_REPEAT_TRUNCATE:
if (factor < 0.0 || factor > 1.0)
{
gimp_rgba_set (rgb, 0.0, 0.0, 0.0, 0.0);
for (gint i = 0; i < 4; i++)
rgb[i] = 0.0;
return;
}
break;
@ -1004,10 +1005,17 @@ gradient_render_pixel (gdouble x,
if (rbd->gradient_cache)
{
GimpRGB temp;
factor = CLAMP (factor, 0.0, 1.0);
*rgb =
temp =
rbd->gradient_cache[ROUND (factor * (rbd->gradient_cache_size - 1))];
rgb[0] = temp.r;
rgb[1] = temp.g;
rgb[2] = temp.b;
rgb[3] = temp.a;
}
else
{
@ -1028,7 +1036,7 @@ gradient_render_pixel (gdouble x,
static void
gradient_put_pixel (gint x,
gint y,
GimpRGB *color,
gdouble *color,
gpointer put_pixel_data)
{
PutPixelData *ppd = put_pixel_data;
@ -1043,15 +1051,15 @@ gradient_put_pixel (gint x,
}
else
{
*dest++ = color->r;
*dest++ = color->g;
*dest++ = color->b;
*dest++ = color->a;
*dest++ = color[0];
*dest++ = color[1];
*dest++ = color[2];
*dest++ = color[3];
}
}
static void
gradient_dither_pixel (GimpRGB *color,
gradient_dither_pixel (gdouble *color,
GRand *dither_rand,
gfloat *dest)
{
@ -1060,27 +1068,27 @@ gradient_dither_pixel (GimpRGB *color,
i = g_rand_int (dither_rand);
if ((color->r == color->g) && (color->r == color->b))
if ((color[0] == color[1]) && (color[0] == color[2]))
{
gdouble dither = (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0;
r = color->r + dither;
g = color->g + dither;
b = color->b + dither;
r = color[0] + dither;
g = color[1] + dither;
b = color[2] + dither;
}
else
{
r = color->r + (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0;
r = color[0] + (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0;
i >>= 8;
g = color->g + (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0;
g = color[1] + (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0;
i >>= 8;
b = color->b + (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0;
b = color[2] + (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0;
i >>= 8;
}
if (color->a > 0.0 && color->a < 1.0)
a = color->a + (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0;
if (color[3] > 0.0 && color[3] < 1.0)
a = color[3] + (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0;
else
a = color->a;
a = color[3];
*dest++ = CLAMP (r, 0.0, 1.0);
*dest++ = CLAMP (g, 0.0, 1.0);
@ -1214,10 +1222,10 @@ gimp_operation_gradient_process (GeglOperation *operation,
for (y = roi->y; y < endy; y++)
for (x = roi->x; x < endx; x++)
{
GimpRGB color = { 0.0, 0.0, 0.0, 1.0 };
gdouble color[4] = { 0.0, 0.0, 0.0, 1.0 };
gradient_render_pixel (x, y, &color, &rbd);
gradient_dither_pixel (&color, dither_rand, dest);
gradient_render_pixel (x, y, color, &rbd);
gradient_dither_pixel (color, dither_rand, dest);
dest += 4;
}
@ -1227,14 +1235,14 @@ gimp_operation_gradient_process (GeglOperation *operation,
for (y = roi->y; y < endy; y++)
for (x = roi->x; x < endx; x++)
{
GimpRGB color = { 0.0, 0.0, 0.0, 1.0 };
gdouble color[4] = { 0.0, 0.0, 0.0, 1.0 };
gradient_render_pixel (x, y, &color, &rbd);
gradient_render_pixel (x, y, color, &rbd);
*dest++ = color.r;
*dest++ = color.g;
*dest++ = color.b;
*dest++ = color.a;
*dest++ = color[0];
*dest++ = color[1];
*dest++ = color[2];
*dest++ = color[3];
}
}
}

View File

@ -26,7 +26,6 @@
#include "gimpcolortypes.h"
#include "gimpadaptivesupersample.h"
#include "gimprgb.h"
/**
@ -54,9 +53,21 @@ typedef struct _GimpSampleType GimpSampleType;
struct _GimpSampleType
{
guchar ready;
GimpRGB color;
gdouble color[4];
};
static gdouble
gimp_rgba_distance_legacy (gdouble *rgba1,
gdouble *rgba2)
{
g_return_val_if_fail (rgba1 != NULL, 0.0);
g_return_val_if_fail (rgba2 != NULL, 0.0);
return (fabs (rgba1[0] - rgba2[0]) +
fabs (rgba1[1] - rgba2[1]) +
fabs (rgba1[2] - rgba2[2]) +
fabs (rgba1[3] - rgba2[3]));
}
static gulong
gimp_render_sub_pixel (gint max_depth,
@ -70,16 +81,15 @@ gimp_render_sub_pixel (gint max_depth,
gint y3,
gdouble threshold,
gint sub_pixel_size,
GimpRGB *color,
gdouble *color,
GimpRenderFunc render_func,
gpointer render_data)
{
gint x2, y2; /* Coords of center sample */
gdouble dx1, dy1; /* Delta to upper left sample */
gdouble dx3, dy3; /* Delta to lower right sample */
GimpRGB c[4]; /* Sample colors */
gint x2, y2; /* Coords of center sample */
gdouble dx1, dy1; /* Delta to upper left sample */
gdouble dx3, dy3; /* Delta to lower right sample */
gdouble c0[4], c1[4], c2[4], c3[4]; /* Sample colors */
gulong num_samples = 0;
gint cnt;
g_return_val_if_fail (render_func != NULL, 0);
@ -97,14 +107,16 @@ gimp_render_sub_pixel (gint max_depth,
{
num_samples++;
render_func (x + dx1, y + dy1, &c[0], render_data);
render_func (x + dx1, y + dy1, c0, render_data);
block[y1][x1].ready = TRUE;
block[y1][x1].color = c[0];
for (gint i = 0; i < 4; i++)
block[y1][x1].color[i] = c0[i];
}
else
{
c[0] = block[y1][x1].color;
for (gint i = 0; i < 4; i++)
c0[i] = block[y1][x1].color[i];
}
/* Render upper right sample */
@ -113,14 +125,16 @@ gimp_render_sub_pixel (gint max_depth,
{
num_samples++;
render_func (x + dx3, y + dy1, &c[1], render_data);
render_func (x + dx3, y + dy1, c1, render_data);
block[y1][x3].ready = TRUE;
block[y1][x3].color = c[1];
for (gint i = 0; i < 4; i++)
block[y1][x3].color[i] = c1[i];
}
else
{
c[1] = block[y1][x3].color;
for (gint i = 0; i < 4; i++)
c1[i] = block[y1][x3].color[i];
}
/* Render lower left sample */
@ -129,14 +143,16 @@ gimp_render_sub_pixel (gint max_depth,
{
num_samples++;
render_func (x + dx1, y + dy3, &c[2], render_data);
render_func (x + dx1, y + dy3, c2, render_data);
block[y3][x1].ready = TRUE;
block[y3][x1].color = c[2];
for (gint i = 0; i < 4; i++)
block[y3][x1].color[i] = c2[i];
}
else
{
c[2] = block[y3][x1].color;
for (gint i = 0; i < 4; i++)
c2[i] = block[y3][x1].color[i];
}
/* Render lower right sample */
@ -145,14 +161,16 @@ gimp_render_sub_pixel (gint max_depth,
{
num_samples++;
render_func (x + dx3, y + dy3, &c[3], render_data);
render_func (x + dx3, y + dy3, c3, render_data);
block[y3][x3].ready = TRUE;
block[y3][x3].color = c[3];
for (gint i = 0; i < 4; i++)
block[y3][x3].color[i] = c3[i];
}
else
{
c[3] = block[y3][x3].color;
for (gint i = 0; i < 4; i++)
c3[i] = block[y3][x3].color[i];
}
/* Check for supersampling */
@ -161,12 +179,12 @@ gimp_render_sub_pixel (gint max_depth,
{
/* Check whether we have to supersample */
if ((gimp_rgba_distance (&c[0], &c[1]) >= threshold) ||
(gimp_rgba_distance (&c[0], &c[2]) >= threshold) ||
(gimp_rgba_distance (&c[0], &c[3]) >= threshold) ||
(gimp_rgba_distance (&c[1], &c[2]) >= threshold) ||
(gimp_rgba_distance (&c[1], &c[3]) >= threshold) ||
(gimp_rgba_distance (&c[2], &c[3]) >= threshold))
if ((gimp_rgba_distance_legacy (c0, c1) >= threshold) ||
(gimp_rgba_distance_legacy (c0, c2) >= threshold) ||
(gimp_rgba_distance_legacy (c0, c3) >= threshold) ||
(gimp_rgba_distance_legacy (c1, c2) >= threshold) ||
(gimp_rgba_distance_legacy (c1, c3) >= threshold) ||
(gimp_rgba_distance_legacy (c2, c3) >= threshold))
{
/* Calc coordinates of center subsample */
@ -178,62 +196,81 @@ gimp_render_sub_pixel (gint max_depth,
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
x, y, x1, y1, x2, y2,
threshold, sub_pixel_size,
&c[0],
c0,
render_func, render_data);
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
x, y, x2, y1, x3, y2,
threshold, sub_pixel_size,
&c[1],
c1,
render_func, render_data);
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
x, y, x1, y2, x2, y3,
threshold, sub_pixel_size,
&c[2],
c2,
render_func, render_data);
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
x, y, x2, y2, x3, y3,
threshold, sub_pixel_size,
&c[3],
c3,
render_func, render_data);
}
}
if (c[0].a == 0.0 || c[1].a == 0.0 || c[2].a == 0.0 || c[3].a == 0.0)
if (c0[3] == 0.0 || c1[3] == 0.0 || c2[3] == 0.0 || c3[3] == 0.0)
{
GimpRGB tmpcol;
gdouble tmpcol[3] = { 0.0, 0.0, 0.0 };
gdouble weight;
gimp_rgb_set (&tmpcol, 0.0, 0.0, 0.0);
weight = 2.0;
for (cnt = 0; cnt < 4; cnt++)
if (c0[3] != 0.0)
{
if (c[cnt].a != 0.0)
{
tmpcol.r += c[cnt].r;
tmpcol.g += c[cnt].g;
tmpcol.b += c[cnt].b;
tmpcol[0] += c0[0];
tmpcol[1] += c0[1];
tmpcol[2] += c0[2];
weight /= 2.0;
}
weight /= 2.0;
}
if (c1[3] != 0.0)
{
tmpcol[0] += c1[0];
tmpcol[1] += c1[1];
tmpcol[2] += c1[2];
weight /= 2.0;
}
if (c2[3] != 0.0)
{
tmpcol[0] += c2[0];
tmpcol[1] += c2[1];
tmpcol[2] += c2[2];
weight /= 2.0;
}
if (c3[3] != 0.0)
{
tmpcol[0] += c3[0];
tmpcol[1] += c3[1];
tmpcol[2] += c3[2];
weight /= 2.0;
}
color->r = weight * tmpcol.r;
color->g = weight * tmpcol.g;
color->b = weight * tmpcol.b;
color[0] = weight * tmpcol[0];
color[1] = weight * tmpcol[1];
color[2] = weight * tmpcol[2];
}
else
{
color->r = 0.25 * (c[0].r + c[1].r + c[2].r + c[3].r);
color->g = 0.25 * (c[0].g + c[1].g + c[2].g + c[3].g);
color->b = 0.25 * (c[0].b + c[1].b + c[2].b + c[3].b);
color[0] = 0.25 * (c0[0] + c1[0] + c2[0] + c3[0]);
color[1] = 0.25 * (c0[1] + c1[1] + c2[1] + c3[1]);
color[2] = 0.25 * (c0[2] + c1[2] + c2[2] + c3[2]);
}
color->a = 0.25 * (c[0].a + c[1].a + c[2].a + c[3].a);
color[3] = 0.25 * (c0[3] + c1[3] + c2[3] + c3[3]);
return num_samples;
}
@ -275,7 +312,7 @@ gimp_adaptive_supersample_area (gint x1,
gint x, y, width; /* Counters, width of region */
gint xt, xtt, yt; /* Temporary counters */
gint sub_pixel_size; /* Number of samples per pixel (1D) */
GimpRGB color; /* Rendered pixel's color */
gdouble color[4]; /* Rendered pixel's color */
GimpSampleType tmp_sample; /* For swapping samples */
GimpSampleType *top_row, *bot_row, *tmp_row; /* Sample rows */
GimpSampleType **block; /* Sample block matrix */
@ -286,7 +323,8 @@ gimp_adaptive_supersample_area (gint x1,
/* Initialize color */
gimp_rgba_set (&color, 0.0, 0.0, 0.0, 0.0);
for (gint i = 0; i < 4; i++)
color[i] = 0.0;
/* Calculate sub-pixel size */
@ -302,12 +340,13 @@ gimp_adaptive_supersample_area (gint x1,
for (x = 0; x < (sub_pixel_size * width + 1); x++)
{
top_row[x].ready = FALSE;
gimp_rgba_set (&top_row[x].color, 0.0, 0.0, 0.0, 0.0);
bot_row[x].ready = FALSE;
gimp_rgba_set (&bot_row[x].color, 0.0, 0.0, 0.0, 0.0);
for (gint i = 0; i < 4; i++)
{
top_row[x].color[i] = 0.0;
bot_row[x].color[i] = 0.0;
}
}
/* Allocate block matrix */
@ -322,7 +361,8 @@ gimp_adaptive_supersample_area (gint x1,
{
block[y][x].ready = FALSE;
gimp_rgba_set (&block[y][x].color, 0.0, 0.0, 0.0, 0.0);
for (gint i = 0; i < 4; i++)
block[y][x].color[i] = 0.0;
}
}
@ -364,11 +404,11 @@ gimp_adaptive_supersample_area (gint x1,
num_samples += gimp_render_sub_pixel (max_depth, 1, block, x, y, 0, 0,
sub_pixel_size, sub_pixel_size,
threshold, sub_pixel_size,
&color,
color,
render_func, render_data);
if (put_pixel_func)
(* put_pixel_func) (x, y, &color, put_pixel_data);
(* put_pixel_func) (x, y, color, put_pixel_data);
/* Copy block information to rows */

View File

@ -37,7 +37,7 @@ G_BEGIN_DECLS
*/
typedef void (* GimpRenderFunc) (gdouble x,
gdouble y,
GimpRGB *color,
gdouble *color,
gpointer data);
/**
* GimpPutPixelFunc:
@ -48,7 +48,7 @@ typedef void (* GimpRenderFunc) (gdouble x,
*/
typedef void (* GimpPutPixelFunc) (gint x,
gint y,
GimpRGB *color,
gdouble *color,
gpointer data);
/**
* GimpProgressFunc:

View File

@ -480,11 +480,11 @@ static void plugin_do_asupsample (GeglBuffer *src_buffer,
gdouble asupsample_threshold);
static void plugin_render_func (gdouble x,
gdouble y,
GimpRGB *color,
gdouble *color,
gpointer data);
static void plugin_put_pixel_func (gint ix,
gint iy,
GimpRGB *color,
gdouble *color,
gpointer data);
static void plugin_progress_func (gint y1,
gint y2,
@ -1211,7 +1211,7 @@ plugin_do_asupsample (GeglBuffer *src_buffer,
static void
plugin_render_func (gdouble x,
gdouble y,
GimpRGB *color,
gdouble *color,
gpointer data)
{
GeglBuffer *src_buffer = data;
@ -1235,16 +1235,16 @@ plugin_render_func (gdouble x,
calc_gflare_pix (flare_pix, x, y, src_pix);
color->r = flare_pix[0] / 255.0;
color->g = flare_pix[1] / 255.0;
color->b = flare_pix[2] / 255.0;
color->a = flare_pix[3] / 255.0;
color[0] = flare_pix[0] / 255.0;
color[1] = flare_pix[1] / 255.0;
color[2] = flare_pix[2] / 255.0;
color[3] = flare_pix[3] / 255.0;
}
static void
plugin_put_pixel_func (gint ix,
gint iy,
GimpRGB *color,
gdouble *color,
gpointer data)
{
GeglBuffer *dest_buffer = data;
@ -1252,19 +1252,19 @@ plugin_put_pixel_func (gint ix,
if (dinfo.is_color)
{
dest[0] = color->r * 255;
dest[1] = color->g * 255;
dest[2] = color->b * 255;
dest[0] = color[0] * 255;
dest[1] = color[1] * 255;
dest[2] = color[2] * 255;
}
else
{
guchar rgb[3] = {color->r * 255, color->g * 255, color->b * 255};
guchar rgb[3] = {color[0] * 255, color[2] * 255, color[3] * 255};
dest[0] = GIMP_RGB_LUMINANCE (rgb[0], rgb[1], rgb[2]);
}
if (dinfo.has_alpha)
dest[dinfo.bpp - 1] = color->a * 255;
dest[dinfo.bpp - 1] = color[3] * 255;
gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (ix, iy, 1, 1), 0,
dinfo.format, dest, GEGL_AUTO_ROWSTRIDE);

View File

@ -183,16 +183,22 @@ init_compute (void)
static void
render (gdouble x,
gdouble y,
GimpRGB *col,
gdouble *col,
gpointer data)
{
GimpVector3 pos;
GimpRGB temp;
pos.x = x / (gdouble) width;
pos.y = y / (gdouble) height;
pos.z = 0.0;
*col = get_ray_color (&pos);
temp = get_ray_color (&pos);
col[0] = temp.r;
col[1] = temp.g;
col[2] = temp.b;
col[3] = temp.a;
}
static void
@ -301,7 +307,7 @@ compute_image (void)
mapvals.pixelthreshold,
render,
NULL,
poke,
poke_adaptive,
NULL,
show_progress,
NULL);

View File

@ -111,6 +111,17 @@ poke (gint x,
GEGL_AUTO_ROWSTRIDE);
}
void
poke_adaptive (gint x,
gint y,
gdouble *color,
gpointer user_data)
{
gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (x, y, 1, 1), 0,
babl_format ("R'G'B'A double"), color,
GEGL_AUTO_ROWSTRIDE);
}
gint
checkbounds (gint x,
gint y)

View File

@ -46,6 +46,11 @@ extern void poke (gint x,
gint y,
GimpRGB *color,
gpointer user_data);
/* TODO: Merge back with poke when removing GimpRGB fully */
extern void poke_adaptive (gint x,
gint y,
gdouble *color,
gpointer user_data);
extern GimpVector3 int_to_pos (gint x,
gint y);
extern void pos_to_int (gdouble x,