mirror of https://github.com/GNOME/gimp.git
libgimp/Makefile.am libgimp/gimp.h libgimp/gimpadaptivesupersample.[ch]
2001-01-23 Michael Natterer <mitch@gimp.org> * libgimp/Makefile.am * libgimp/gimp.h * libgimp/gimpadaptivesupersample.[ch] * libgimp/gimpbilinear.[ch]: new files cut out of LibGCK. * plug-ins/libgck/gck/gck.h * plug-ins/libgck/gck/gckcolor.c: removed the bilinear and supersample code. * app/apptypes.h * app/asupsample.[ch] * app/tools/blend.c: made the adaptive_supersample interface the same as in libgimp but don't use the libgimp function yet. The libgimp function takes total transparancy into account when weighting the 4 resulting RGBA values, the app function always weights them equally. Please have a look at the code. * plug-ins/Lighting/lighting_image.c * plug-ins/MapObject/mapobject_apply.c * plug-ins/MapObject/mapobject_image.[ch]: changed accordingly. * app/disp_callbacks.c: paranoia cleanups.
This commit is contained in:
parent
5591b7cd2d
commit
75760de9d1
26
ChangeLog
26
ChangeLog
|
@ -1,3 +1,29 @@
|
||||||
|
2001-01-23 Michael Natterer <mitch@gimp.org>
|
||||||
|
|
||||||
|
* libgimp/Makefile.am
|
||||||
|
* libgimp/gimp.h
|
||||||
|
* libgimp/gimpadaptivesupersample.[ch]
|
||||||
|
* libgimp/gimpbilinear.[ch]: new files cut out of LibGCK.
|
||||||
|
|
||||||
|
* plug-ins/libgck/gck/gck.h
|
||||||
|
* plug-ins/libgck/gck/gckcolor.c: removed the bilinear and
|
||||||
|
supersample code.
|
||||||
|
|
||||||
|
* app/apptypes.h
|
||||||
|
* app/asupsample.[ch]
|
||||||
|
* app/tools/blend.c: made the adaptive_supersample interface the
|
||||||
|
same as in libgimp but don't use the libgimp function yet.
|
||||||
|
|
||||||
|
The libgimp function takes total transparancy into account when
|
||||||
|
weighting the 4 resulting RGBA values, the app function always
|
||||||
|
weights them equally. Please have a look at the code.
|
||||||
|
|
||||||
|
* plug-ins/Lighting/lighting_image.c
|
||||||
|
* plug-ins/MapObject/mapobject_apply.c
|
||||||
|
* plug-ins/MapObject/mapobject_image.[ch]: changed accordingly.
|
||||||
|
|
||||||
|
* app/disp_callbacks.c: paranoia cleanups.
|
||||||
|
|
||||||
2001-01-22 Sven Neumann <sven@gimp.org>
|
2001-01-22 Sven Neumann <sven@gimp.org>
|
||||||
|
|
||||||
* app/gdisplay.c
|
* app/gdisplay.c
|
||||||
|
|
|
@ -167,10 +167,10 @@ typedef void (* TileValidateProc) (TileManager *tm,
|
||||||
|
|
||||||
typedef void (* ToolOptionsResetFunc) (void);
|
typedef void (* ToolOptionsResetFunc) (void);
|
||||||
|
|
||||||
typedef void (* GimpProgressFunc) (gint ymin,
|
typedef void (* GimpProgressFunc) (gint min,
|
||||||
gint ymax,
|
gint max,
|
||||||
gint curr_y,
|
gint current,
|
||||||
gpointer progress_data);
|
gpointer data);
|
||||||
|
|
||||||
typedef void (* ImageMapApplyFunc) (PixelRegion *srcPR,
|
typedef void (* ImageMapApplyFunc) (PixelRegion *srcPR,
|
||||||
PixelRegion *destPR,
|
PixelRegion *destPR,
|
||||||
|
|
200
app/asupsample.c
200
app/asupsample.c
|
@ -20,7 +20,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* This code is *largely* based on the sources for POV-Ray 3.0. I am
|
/* This code is *largely* based on the sources for POV-Ray 3.0. I am
|
||||||
* grateful to the POV-Team for such a great program and for making
|
* grateful to the POV-Team for such a great program and for making
|
||||||
* their sources available. All comments / bug reports /
|
* their sources available. All comments / bug reports /
|
||||||
|
@ -47,52 +46,51 @@ typedef struct
|
||||||
{
|
{
|
||||||
gchar ready;
|
gchar ready;
|
||||||
GimpRGB color;
|
GimpRGB color;
|
||||||
} sample_t;
|
} GimpSampleType;
|
||||||
|
|
||||||
|
|
||||||
/***** Local functions *****/
|
/***** Local functions *****/
|
||||||
|
|
||||||
static gulong render_sub_pixel (gint max_depth,
|
static gulong gimp_render_sub_pixel (gint max_depth,
|
||||||
gint depth,
|
gint depth,
|
||||||
sample_t **block,
|
GimpSampleType **block,
|
||||||
gint x,
|
gint x,
|
||||||
gint y,
|
gint y,
|
||||||
gint x1,
|
gint x1,
|
||||||
gint y1,
|
gint y1,
|
||||||
gint x3,
|
gint x3,
|
||||||
gint y3,
|
gint y3,
|
||||||
gdouble threshold,
|
gdouble threshold,
|
||||||
gint sub_pixel_size,
|
gint sub_pixel_size,
|
||||||
render_func_t render_func,
|
GimpRGB *color,
|
||||||
GimpRGB *color,
|
GimpRenderFunc render_func,
|
||||||
gpointer render_data);
|
gpointer render_data);
|
||||||
|
|
||||||
|
|
||||||
/***** Functions *****/
|
/***** Functions *****/
|
||||||
|
|
||||||
gulong
|
gulong
|
||||||
adaptive_supersample_area (gint x1,
|
gimp_adaptive_supersample_area (gint x1,
|
||||||
gint y1,
|
gint y1,
|
||||||
gint x2,
|
gint x2,
|
||||||
gint y2,
|
gint y2,
|
||||||
gint max_depth,
|
gint max_depth,
|
||||||
gdouble threshold,
|
gdouble threshold,
|
||||||
render_func_t render_func,
|
GimpRenderFunc render_func,
|
||||||
gpointer render_data,
|
gpointer render_data,
|
||||||
put_pixel_func_t put_pixel_func,
|
GimpPutPixelFunc put_pixel_func,
|
||||||
gpointer put_pixel_data,
|
gpointer put_pixel_data,
|
||||||
GimpProgressFunc progress_func,
|
GimpProgressFunc progress_func,
|
||||||
gpointer progress_data)
|
gpointer progress_data)
|
||||||
{
|
{
|
||||||
gint x, y, width; /* Counters, width of region */
|
gint x, y, width; /* Counters, width of region */
|
||||||
gint xt, xtt, yt; /* Temporary counters */
|
gint xt, xtt, yt; /* Temporary counters */
|
||||||
gint sub_pixel_size; /* Numbe of samples per pixel (1D) */
|
gint sub_pixel_size; /* Numbe of samples per pixel (1D) */
|
||||||
size_t row_size; /* Memory needed for one row */
|
GimpRGB color; /* Rendered pixel's color */
|
||||||
GimpRGB color; /* Rendered pixel's color */
|
GimpSampleType tmp_sample; /* For swapping samples */
|
||||||
sample_t tmp_sample; /* For swapping samples */
|
GimpSampleType *top_row, *bot_row, *tmp_row; /* Sample rows */
|
||||||
sample_t *top_row, *bot_row, *tmp_row; /* Sample rows */
|
GimpSampleType **block; /* Sample block matrix */
|
||||||
sample_t **block; /* Sample block matrix */
|
gulong num_samples;
|
||||||
gulong num_samples;
|
|
||||||
|
|
||||||
/* Initialize color */
|
/* Initialize color */
|
||||||
|
|
||||||
|
@ -100,39 +98,37 @@ adaptive_supersample_area (gint x1,
|
||||||
|
|
||||||
/* Calculate sub-pixel size */
|
/* Calculate sub-pixel size */
|
||||||
|
|
||||||
sub_pixel_size = 1 << max_depth; /* 2**max_depth */
|
sub_pixel_size = 1 << max_depth;
|
||||||
|
|
||||||
/* Create row arrays */
|
/* Create row arrays */
|
||||||
|
|
||||||
width = x2 - x1 + 1;
|
width = x2 - x1 + 1;
|
||||||
|
|
||||||
row_size = (sub_pixel_size * width + 1) * sizeof (sample_t);
|
top_row = g_new (GimpSampleType, sub_pixel_size * width + 1);
|
||||||
|
bot_row = g_new (GimpSampleType, sub_pixel_size * width + 1);
|
||||||
top_row = g_malloc (row_size);
|
|
||||||
bot_row = g_malloc (row_size);
|
|
||||||
|
|
||||||
for (x = 0; x < (sub_pixel_size * width + 1); x++)
|
for (x = 0; x < (sub_pixel_size * width + 1); x++)
|
||||||
{
|
{
|
||||||
top_row[x].ready = 0;
|
top_row[x].ready = FALSE;
|
||||||
|
|
||||||
gimp_rgba_set (&top_row[x].color, 0.0, 0.0, 0.0, 0.0);
|
gimp_rgba_set (&top_row[x].color, 0.0, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
bot_row[x].ready = 0;
|
bot_row[x].ready = FALSE;
|
||||||
|
|
||||||
gimp_rgba_set (&bot_row[x].color, 0.0, 0.0, 0.0, 0.0);
|
gimp_rgba_set (&bot_row[x].color, 0.0, 0.0, 0.0, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate block matrix */
|
/* Allocate block matrix */
|
||||||
|
|
||||||
block = g_malloc((sub_pixel_size + 1) * sizeof(sample_t *)); /* Rows */
|
block = g_new (GimpSampleType *, sub_pixel_size + 1); /* Rows */
|
||||||
|
|
||||||
for (y = 0; y < (sub_pixel_size + 1); y++)
|
for (y = 0; y < (sub_pixel_size + 1); y++)
|
||||||
{
|
{
|
||||||
block[y] = g_malloc((sub_pixel_size + 1) * sizeof(sample_t)); /* Columns */
|
block[y] = g_new (GimpSampleType, sub_pixel_size + 1); /* Columns */
|
||||||
|
|
||||||
for (x = 0; x < (sub_pixel_size + 1); x++)
|
for (x = 0; x < (sub_pixel_size + 1); x++)
|
||||||
{
|
{
|
||||||
block[y][x].ready = 0;
|
block[y][x].ready = FALSE;
|
||||||
|
|
||||||
gimp_rgba_set (&block[y][x].color, 0.0, 0.0, 0.0, 0.0);
|
gimp_rgba_set (&block[y][x].color, 0.0, 0.0, 0.0, 0.0);
|
||||||
}
|
}
|
||||||
|
@ -147,7 +143,7 @@ adaptive_supersample_area (gint x1,
|
||||||
/* Clear the bottom row */
|
/* Clear the bottom row */
|
||||||
|
|
||||||
for (xt = 0; xt < (sub_pixel_size * width + 1); xt++)
|
for (xt = 0; xt < (sub_pixel_size * width + 1); xt++)
|
||||||
bot_row[xt].ready = 0;
|
bot_row[xt].ready = FALSE;
|
||||||
|
|
||||||
/* Clear first column */
|
/* Clear first column */
|
||||||
|
|
||||||
|
@ -162,7 +158,7 @@ adaptive_supersample_area (gint x1,
|
||||||
|
|
||||||
for (yt = 1; yt < (sub_pixel_size + 1); yt++)
|
for (yt = 1; yt < (sub_pixel_size + 1); yt++)
|
||||||
for (xt = 1; xt < (sub_pixel_size + 1); xt++)
|
for (xt = 1; xt < (sub_pixel_size + 1); xt++)
|
||||||
block[yt][xt].ready = 0;
|
block[yt][xt].ready = FALSE;
|
||||||
|
|
||||||
/* Copy samples from top row to block */
|
/* Copy samples from top row to block */
|
||||||
|
|
||||||
|
@ -173,14 +169,14 @@ adaptive_supersample_area (gint x1,
|
||||||
|
|
||||||
/* Render pixel on (x, y) */
|
/* Render pixel on (x, y) */
|
||||||
|
|
||||||
num_samples += render_sub_pixel (max_depth, 1, block, x, y, 0, 0,
|
num_samples += gimp_render_sub_pixel (max_depth, 1, block, x, y, 0, 0,
|
||||||
sub_pixel_size, sub_pixel_size,
|
sub_pixel_size, sub_pixel_size,
|
||||||
threshold, sub_pixel_size,
|
threshold, sub_pixel_size,
|
||||||
render_func, &color,
|
&color,
|
||||||
render_data);
|
render_func, render_data);
|
||||||
|
|
||||||
if (put_pixel_func)
|
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 */
|
/* Copy block information to rows */
|
||||||
|
|
||||||
|
@ -195,8 +191,8 @@ adaptive_supersample_area (gint x1,
|
||||||
|
|
||||||
for (yt = 0; yt < (sub_pixel_size + 1); yt++)
|
for (yt = 0; yt < (sub_pixel_size + 1); yt++)
|
||||||
{
|
{
|
||||||
tmp_sample = block[yt][0];
|
tmp_sample = block[yt][0];
|
||||||
block[yt][0] = block[yt][sub_pixel_size];
|
block[yt][0] = block[yt][sub_pixel_size];
|
||||||
block[yt][sub_pixel_size] = tmp_sample;
|
block[yt][sub_pixel_size] = tmp_sample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,20 +222,20 @@ adaptive_supersample_area (gint x1,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gulong
|
static gulong
|
||||||
render_sub_pixel (gint max_depth,
|
gimp_render_sub_pixel (gint max_depth,
|
||||||
gint depth,
|
gint depth,
|
||||||
sample_t **block,
|
GimpSampleType **block,
|
||||||
gint x,
|
gint x,
|
||||||
gint y,
|
gint y,
|
||||||
gint x1,
|
gint x1,
|
||||||
gint y1,
|
gint y1,
|
||||||
gint x3,
|
gint x3,
|
||||||
gint y3,
|
gint y3,
|
||||||
gdouble threshold,
|
gdouble threshold,
|
||||||
gint sub_pixel_size,
|
gint sub_pixel_size,
|
||||||
render_func_t render_func,
|
GimpRGB *color,
|
||||||
GimpRGB *color,
|
GimpRenderFunc render_func,
|
||||||
gpointer render_data)
|
gpointer render_data)
|
||||||
{
|
{
|
||||||
gint x2, y2; /* Coords of center sample */
|
gint x2, y2; /* Coords of center sample */
|
||||||
gdouble dx1, dy1; /* Delta to upper left sample */
|
gdouble dx1, dy1; /* Delta to upper left sample */
|
||||||
|
@ -262,9 +258,11 @@ render_sub_pixel (gint max_depth,
|
||||||
if (!block[y1][x1].ready)
|
if (!block[y1][x1].ready)
|
||||||
{
|
{
|
||||||
num_samples++;
|
num_samples++;
|
||||||
(* render_func) (x + dx1, y + dy1, &c1, render_data);
|
|
||||||
|
|
||||||
block[y1][x1].ready = 1;
|
if (render_func)
|
||||||
|
(* render_func) (x + dx1, y + dy1, &c1, render_data);
|
||||||
|
|
||||||
|
block[y1][x1].ready = TRUE;
|
||||||
block[y1][x1].color = c1;
|
block[y1][x1].color = c1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -274,12 +272,14 @@ render_sub_pixel (gint max_depth,
|
||||||
|
|
||||||
/* Render upper right sample */
|
/* Render upper right sample */
|
||||||
|
|
||||||
if (!block[y1][x3].ready)
|
if (! block[y1][x3].ready)
|
||||||
{
|
{
|
||||||
num_samples++;
|
num_samples++;
|
||||||
(* render_func) (x + dx3, y + dy1, &c2, render_data);
|
|
||||||
|
|
||||||
block[y1][x3].ready = 1;
|
if (render_func)
|
||||||
|
(* render_func) (x + dx3, y + dy1, &c2, render_data);
|
||||||
|
|
||||||
|
block[y1][x3].ready = TRUE;
|
||||||
block[y1][x3].color = c2;
|
block[y1][x3].color = c2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -289,12 +289,14 @@ render_sub_pixel (gint max_depth,
|
||||||
|
|
||||||
/* Render lower left sample */
|
/* Render lower left sample */
|
||||||
|
|
||||||
if (!block[y3][x1].ready)
|
if (! block[y3][x1].ready)
|
||||||
{
|
{
|
||||||
num_samples++;
|
num_samples++;
|
||||||
(* render_func) (x + dx1, y + dy3, &c3, render_data);
|
|
||||||
|
|
||||||
block[y3][x1].ready = 1;
|
if (render_func)
|
||||||
|
(* render_func) (x + dx1, y + dy3, &c3, render_data);
|
||||||
|
|
||||||
|
block[y3][x1].ready = TRUE;
|
||||||
block[y3][x1].color = c3;
|
block[y3][x1].color = c3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -304,12 +306,14 @@ render_sub_pixel (gint max_depth,
|
||||||
|
|
||||||
/* Render lower right sample */
|
/* Render lower right sample */
|
||||||
|
|
||||||
if (!block[y3][x3].ready)
|
if (! block[y3][x3].ready)
|
||||||
{
|
{
|
||||||
num_samples++;
|
num_samples++;
|
||||||
(* render_func) (x + dx3, y + dy3, &c4, render_data);
|
|
||||||
|
|
||||||
block[y3][x3].ready = 1;
|
if (render_func)
|
||||||
|
(* render_func) (x + dx3, y + dy3, &c4, render_data);
|
||||||
|
|
||||||
|
block[y3][x3].ready = TRUE;
|
||||||
block[y3][x3].color = c4;
|
block[y3][x3].color = c4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -337,21 +341,29 @@ render_sub_pixel (gint max_depth,
|
||||||
|
|
||||||
/* Render sub-blocks */
|
/* Render sub-blocks */
|
||||||
|
|
||||||
num_samples += render_sub_pixel (max_depth, depth + 1, block, x, y, x1, y1, x2, y2,
|
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
|
||||||
threshold, sub_pixel_size, render_func, &c1,
|
x, y, x1, y1, x2, y2,
|
||||||
render_data);
|
threshold, sub_pixel_size,
|
||||||
|
&c1,
|
||||||
|
render_func, render_data);
|
||||||
|
|
||||||
num_samples += render_sub_pixel(max_depth, depth + 1, block, x, y, x2, y1, x3, y2,
|
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
|
||||||
threshold, sub_pixel_size, render_func, &c2,
|
x, y, x2, y1, x3, y2,
|
||||||
render_data);
|
threshold, sub_pixel_size,
|
||||||
|
&c2,
|
||||||
|
render_func, render_data);
|
||||||
|
|
||||||
num_samples += render_sub_pixel(max_depth, depth + 1, block, x, y, x1, y2, x2, y3,
|
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
|
||||||
threshold, sub_pixel_size, render_func, &c3,
|
x, y, x1, y2, x2, y3,
|
||||||
render_data);
|
threshold, sub_pixel_size,
|
||||||
|
&c3,
|
||||||
|
render_func, render_data);
|
||||||
|
|
||||||
num_samples += render_sub_pixel(max_depth, depth + 1, block, x, y, x2, y2, x3, y3,
|
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
|
||||||
threshold, sub_pixel_size, render_func, &c4,
|
x, y, x2, y2, x3, y3,
|
||||||
render_data);
|
threshold, sub_pixel_size,
|
||||||
|
&c4,
|
||||||
|
render_func, render_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,28 +24,28 @@
|
||||||
#define __ASUPSAMPLE_H__
|
#define __ASUPSAMPLE_H__
|
||||||
|
|
||||||
|
|
||||||
typedef void (* render_func_t) (gdouble x,
|
typedef void (* GimpRenderFunc) (gdouble x,
|
||||||
gdouble y,
|
gdouble y,
|
||||||
GimpRGB *color,
|
GimpRGB *color,
|
||||||
gpointer render_data);
|
gpointer data);
|
||||||
typedef void (* put_pixel_func_t) (gint x,
|
typedef void (* GimpPutPixelFunc) (gint x,
|
||||||
gint y,
|
gint y,
|
||||||
GimpRGB color,
|
GimpRGB *color,
|
||||||
gpointer put_pixel_data);
|
gpointer data);
|
||||||
|
|
||||||
|
|
||||||
gulong adaptive_supersample_area (gint x1,
|
gulong gimp_adaptive_supersample_area (gint x1,
|
||||||
gint y1,
|
gint y1,
|
||||||
gint x2,
|
gint x2,
|
||||||
gint y2,
|
gint y2,
|
||||||
gint max_depth,
|
gint max_depth,
|
||||||
gdouble threshold,
|
gdouble threshold,
|
||||||
render_func_t render_func,
|
GimpRenderFunc render_func,
|
||||||
gpointer render_data,
|
gpointer render_data,
|
||||||
put_pixel_func_t put_pixel_func,
|
GimpPutPixelFunc put_pixel_func,
|
||||||
gpointer put_pixel_data,
|
gpointer put_pixel_data,
|
||||||
GimpProgressFunc progress_func,
|
GimpProgressFunc progress_func,
|
||||||
gpointer progress_data);
|
gpointer progress_data);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __ASUPSAMPLE_H__ */
|
#endif /* __ASUPSAMPLE_H__ */
|
||||||
|
|
|
@ -245,7 +245,7 @@ static void gradient_render_pixel (gdouble x,
|
||||||
gpointer render_data);
|
gpointer render_data);
|
||||||
static void gradient_put_pixel (gint x,
|
static void gradient_put_pixel (gint x,
|
||||||
gint y,
|
gint y,
|
||||||
GimpRGB color,
|
GimpRGB *color,
|
||||||
gpointer put_pixel_data);
|
gpointer put_pixel_data);
|
||||||
|
|
||||||
static void gradient_fill_region (GImage *gimage,
|
static void gradient_fill_region (GImage *gimage,
|
||||||
|
@ -1403,7 +1403,7 @@ gradient_render_pixel (double x,
|
||||||
static void
|
static void
|
||||||
gradient_put_pixel (int x,
|
gradient_put_pixel (int x,
|
||||||
int y,
|
int y,
|
||||||
GimpRGB color,
|
GimpRGB *color,
|
||||||
void *put_pixel_data)
|
void *put_pixel_data)
|
||||||
{
|
{
|
||||||
PutPixelData *ppd;
|
PutPixelData *ppd;
|
||||||
|
@ -1417,17 +1417,17 @@ gradient_put_pixel (int x,
|
||||||
|
|
||||||
if (ppd->bytes >= 3)
|
if (ppd->bytes >= 3)
|
||||||
{
|
{
|
||||||
*data++ = color.r * 255.0;
|
*data++ = color->r * 255.0;
|
||||||
*data++ = color.g * 255.0;
|
*data++ = color->g * 255.0;
|
||||||
*data++ = color.b * 255.0;
|
*data++ = color->b * 255.0;
|
||||||
*data++ = color.a * 255.0;
|
*data++ = color->a * 255.0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Convert to grayscale */
|
/* Convert to grayscale */
|
||||||
|
|
||||||
*data++ = 255.0 * INTENSITY (color.r, color.g, color.b);
|
*data++ = 255.0 * INTENSITY (color->r, color->g, color->b);
|
||||||
*data++ = color.a * 255.0;
|
*data++ = color->a * 255.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paint whole row if we are on the rightmost pixel */
|
/* Paint whole row if we are on the rightmost pixel */
|
||||||
|
@ -1588,11 +1588,11 @@ gradient_fill_region (GImage *gimage,
|
||||||
|
|
||||||
/* Render! */
|
/* Render! */
|
||||||
|
|
||||||
adaptive_supersample_area (0, 0, (width - 1), (height - 1),
|
gimp_adaptive_supersample_area (0, 0, (width - 1), (height - 1),
|
||||||
max_depth, threshold,
|
max_depth, threshold,
|
||||||
gradient_render_pixel, &rbd,
|
gradient_render_pixel, &rbd,
|
||||||
gradient_put_pixel, &ppd,
|
gradient_put_pixel, &ppd,
|
||||||
progress_callback, progress_data);
|
progress_callback, progress_data);
|
||||||
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
|
|
||||||
gdisp = (GDisplay *) gtk_object_get_user_data (GTK_OBJECT (canvas));
|
gdisp = (GDisplay *) gtk_object_get_user_data (GTK_OBJECT (canvas));
|
||||||
|
|
||||||
if (!canvas->window)
|
if (!canvas->window)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* If this is the first event... */
|
/* If this is the first event... */
|
||||||
|
@ -180,10 +180,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
|
|
||||||
/* set up the scrollbar observers */
|
/* set up the scrollbar observers */
|
||||||
gtk_signal_connect (GTK_OBJECT (gdisp->hsbdata), "value_changed",
|
gtk_signal_connect (GTK_OBJECT (gdisp->hsbdata), "value_changed",
|
||||||
(GtkSignalFunc) scrollbar_horz_update,
|
GTK_SIGNAL_FUNC(scrollbar_horz_update),
|
||||||
gdisp);
|
gdisp);
|
||||||
gtk_signal_connect (GTK_OBJECT (gdisp->vsbdata), "value_changed",
|
gtk_signal_connect (GTK_OBJECT (gdisp->vsbdata), "value_changed",
|
||||||
(GtkSignalFunc) scrollbar_vert_update,
|
GTK_SIGNAL_FUNC (scrollbar_vert_update),
|
||||||
gdisp);
|
gdisp);
|
||||||
|
|
||||||
/* setup scale properly */
|
/* setup scale properly */
|
||||||
|
@ -191,7 +191,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find out what device the event occurred upon */
|
/* Find out what device the event occurred upon */
|
||||||
if (!gimp_busy && devices_check_change (event))
|
if (! gimp_busy && devices_check_change (event))
|
||||||
gdisplay_check_device_cursor (gdisp);
|
gdisplay_check_device_cursor (gdisp);
|
||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
|
@ -216,7 +216,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_LEAVE_NOTIFY:
|
case GDK_LEAVE_NOTIFY:
|
||||||
if (((GdkEventCrossing*) event)->mode != GDK_CROSSING_NORMAL)
|
if (((GdkEventCrossing *) event)->mode != GDK_CROSSING_NORMAL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
gdisplay_update_cursor (gdisp, 0, 0);
|
gdisplay_update_cursor (gdisp, 0, 0);
|
||||||
gtk_label_set_text (GTK_LABEL (gdisp->cursor_label), "");
|
gtk_label_set_text (GTK_LABEL (gdisp->cursor_label), "");
|
||||||
|
@ -227,7 +227,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_ENTER_NOTIFY:
|
case GDK_ENTER_NOTIFY:
|
||||||
if (((GdkEventCrossing*) event)->mode != GDK_CROSSING_NORMAL)
|
if (((GdkEventCrossing *) event)->mode != GDK_CROSSING_NORMAL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
/* Actually, should figure out tx,ty here */
|
/* Actually, should figure out tx,ty here */
|
||||||
break;
|
break;
|
||||||
|
@ -247,12 +247,12 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
gtk_grab_add (canvas);
|
gtk_grab_add (canvas);
|
||||||
|
|
||||||
/* This is a hack to prevent other stuff being run in the middle of
|
/* This is a hack to prevent other stuff being run in the middle of
|
||||||
a tool operation (like changing image types.... brrrr). We just
|
* a tool operation (like changing image types.... brrrr). We just
|
||||||
block all the keypress event. A better solution is to implement
|
* block all the keypress event. A better solution is to implement
|
||||||
some sort of locking for images.
|
* some sort of locking for images.
|
||||||
Note that this is dependent on specific GTK behavior, and isn't
|
* Note that this is dependent on specific GTK behavior, and isn't
|
||||||
guaranteed to work in future versions of GTK.
|
* guaranteed to work in future versions of GTK.
|
||||||
-Yosh
|
* -Yosh
|
||||||
*/
|
*/
|
||||||
if (key_signal_id == 0)
|
if (key_signal_id == 0)
|
||||||
key_signal_id = gtk_signal_connect (GTK_OBJECT (canvas),
|
key_signal_id = gtk_signal_connect (GTK_OBJECT (canvas),
|
||||||
|
@ -261,7 +261,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (active_tool && ((active_tool->type == MOVE) ||
|
if (active_tool && ((active_tool->type == MOVE) ||
|
||||||
!gimp_image_is_empty (gdisp->gimage)))
|
! gimp_image_is_empty (gdisp->gimage)))
|
||||||
{
|
{
|
||||||
if (active_tool->auto_snap_to)
|
if (active_tool->auto_snap_to)
|
||||||
{
|
{
|
||||||
|
@ -363,9 +363,8 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
*
|
*
|
||||||
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
||||||
*/
|
*/
|
||||||
if (gimp_busy &&
|
if (gimp_busy && ! (active_tool->type == FUZZY_SELECT &&
|
||||||
!(active_tool->type == FUZZY_SELECT &&
|
active_tool->state == ACTIVE))
|
||||||
active_tool->state == ACTIVE))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
switch (bevent->button)
|
switch (bevent->button)
|
||||||
|
@ -394,7 +393,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
bevent->y = ty;
|
bevent->y = ty;
|
||||||
update_cursor = TRUE;
|
update_cursor = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
(* active_tool->button_release_func) (active_tool, bevent,
|
(* active_tool->button_release_func) (active_tool, bevent,
|
||||||
gdisp);
|
gdisp);
|
||||||
}
|
}
|
||||||
|
@ -437,14 +436,13 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
*
|
*
|
||||||
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
||||||
*/
|
*/
|
||||||
if (gimp_busy &&
|
if (gimp_busy && ! (active_tool->type == FUZZY_SELECT &&
|
||||||
!(active_tool->type == FUZZY_SELECT &&
|
active_tool->state == ACTIVE))
|
||||||
active_tool->state == ACTIVE))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* Ask for the pointer position, but ignore it except for cursor
|
/* Ask for the pointer position, but ignore it except for cursor
|
||||||
* handling, so motion events sync with the button press/release events */
|
* handling, so motion events sync with the button press/release events
|
||||||
|
*/
|
||||||
if (mevent->is_hint)
|
if (mevent->is_hint)
|
||||||
{
|
{
|
||||||
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
|
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
|
||||||
|
@ -469,7 +467,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (active_tool && ((active_tool->type == MOVE) ||
|
if (active_tool && ((active_tool->type == MOVE) ||
|
||||||
!gimp_image_is_empty (gdisp->gimage)) &&
|
! gimp_image_is_empty (gdisp->gimage)) &&
|
||||||
(mevent->state & GDK_BUTTON1_MASK))
|
(mevent->state & GDK_BUTTON1_MASK))
|
||||||
{
|
{
|
||||||
if (active_tool->state == ACTIVE)
|
if (active_tool->state == ACTIVE)
|
||||||
|
|
|
@ -160,7 +160,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
|
|
||||||
gdisp = (GDisplay *) gtk_object_get_user_data (GTK_OBJECT (canvas));
|
gdisp = (GDisplay *) gtk_object_get_user_data (GTK_OBJECT (canvas));
|
||||||
|
|
||||||
if (!canvas->window)
|
if (!canvas->window)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* If this is the first event... */
|
/* If this is the first event... */
|
||||||
|
@ -180,10 +180,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
|
|
||||||
/* set up the scrollbar observers */
|
/* set up the scrollbar observers */
|
||||||
gtk_signal_connect (GTK_OBJECT (gdisp->hsbdata), "value_changed",
|
gtk_signal_connect (GTK_OBJECT (gdisp->hsbdata), "value_changed",
|
||||||
(GtkSignalFunc) scrollbar_horz_update,
|
GTK_SIGNAL_FUNC(scrollbar_horz_update),
|
||||||
gdisp);
|
gdisp);
|
||||||
gtk_signal_connect (GTK_OBJECT (gdisp->vsbdata), "value_changed",
|
gtk_signal_connect (GTK_OBJECT (gdisp->vsbdata), "value_changed",
|
||||||
(GtkSignalFunc) scrollbar_vert_update,
|
GTK_SIGNAL_FUNC (scrollbar_vert_update),
|
||||||
gdisp);
|
gdisp);
|
||||||
|
|
||||||
/* setup scale properly */
|
/* setup scale properly */
|
||||||
|
@ -191,7 +191,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find out what device the event occurred upon */
|
/* Find out what device the event occurred upon */
|
||||||
if (!gimp_busy && devices_check_change (event))
|
if (! gimp_busy && devices_check_change (event))
|
||||||
gdisplay_check_device_cursor (gdisp);
|
gdisplay_check_device_cursor (gdisp);
|
||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
|
@ -216,7 +216,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_LEAVE_NOTIFY:
|
case GDK_LEAVE_NOTIFY:
|
||||||
if (((GdkEventCrossing*) event)->mode != GDK_CROSSING_NORMAL)
|
if (((GdkEventCrossing *) event)->mode != GDK_CROSSING_NORMAL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
gdisplay_update_cursor (gdisp, 0, 0);
|
gdisplay_update_cursor (gdisp, 0, 0);
|
||||||
gtk_label_set_text (GTK_LABEL (gdisp->cursor_label), "");
|
gtk_label_set_text (GTK_LABEL (gdisp->cursor_label), "");
|
||||||
|
@ -227,7 +227,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_ENTER_NOTIFY:
|
case GDK_ENTER_NOTIFY:
|
||||||
if (((GdkEventCrossing*) event)->mode != GDK_CROSSING_NORMAL)
|
if (((GdkEventCrossing *) event)->mode != GDK_CROSSING_NORMAL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
/* Actually, should figure out tx,ty here */
|
/* Actually, should figure out tx,ty here */
|
||||||
break;
|
break;
|
||||||
|
@ -247,12 +247,12 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
gtk_grab_add (canvas);
|
gtk_grab_add (canvas);
|
||||||
|
|
||||||
/* This is a hack to prevent other stuff being run in the middle of
|
/* This is a hack to prevent other stuff being run in the middle of
|
||||||
a tool operation (like changing image types.... brrrr). We just
|
* a tool operation (like changing image types.... brrrr). We just
|
||||||
block all the keypress event. A better solution is to implement
|
* block all the keypress event. A better solution is to implement
|
||||||
some sort of locking for images.
|
* some sort of locking for images.
|
||||||
Note that this is dependent on specific GTK behavior, and isn't
|
* Note that this is dependent on specific GTK behavior, and isn't
|
||||||
guaranteed to work in future versions of GTK.
|
* guaranteed to work in future versions of GTK.
|
||||||
-Yosh
|
* -Yosh
|
||||||
*/
|
*/
|
||||||
if (key_signal_id == 0)
|
if (key_signal_id == 0)
|
||||||
key_signal_id = gtk_signal_connect (GTK_OBJECT (canvas),
|
key_signal_id = gtk_signal_connect (GTK_OBJECT (canvas),
|
||||||
|
@ -261,7 +261,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (active_tool && ((active_tool->type == MOVE) ||
|
if (active_tool && ((active_tool->type == MOVE) ||
|
||||||
!gimp_image_is_empty (gdisp->gimage)))
|
! gimp_image_is_empty (gdisp->gimage)))
|
||||||
{
|
{
|
||||||
if (active_tool->auto_snap_to)
|
if (active_tool->auto_snap_to)
|
||||||
{
|
{
|
||||||
|
@ -363,9 +363,8 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
*
|
*
|
||||||
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
||||||
*/
|
*/
|
||||||
if (gimp_busy &&
|
if (gimp_busy && ! (active_tool->type == FUZZY_SELECT &&
|
||||||
!(active_tool->type == FUZZY_SELECT &&
|
active_tool->state == ACTIVE))
|
||||||
active_tool->state == ACTIVE))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
switch (bevent->button)
|
switch (bevent->button)
|
||||||
|
@ -394,7 +393,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
bevent->y = ty;
|
bevent->y = ty;
|
||||||
update_cursor = TRUE;
|
update_cursor = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
(* active_tool->button_release_func) (active_tool, bevent,
|
(* active_tool->button_release_func) (active_tool, bevent,
|
||||||
gdisp);
|
gdisp);
|
||||||
}
|
}
|
||||||
|
@ -437,14 +436,13 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
*
|
*
|
||||||
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
||||||
*/
|
*/
|
||||||
if (gimp_busy &&
|
if (gimp_busy && ! (active_tool->type == FUZZY_SELECT &&
|
||||||
!(active_tool->type == FUZZY_SELECT &&
|
active_tool->state == ACTIVE))
|
||||||
active_tool->state == ACTIVE))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* Ask for the pointer position, but ignore it except for cursor
|
/* Ask for the pointer position, but ignore it except for cursor
|
||||||
* handling, so motion events sync with the button press/release events */
|
* handling, so motion events sync with the button press/release events
|
||||||
|
*/
|
||||||
if (mevent->is_hint)
|
if (mevent->is_hint)
|
||||||
{
|
{
|
||||||
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
|
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
|
||||||
|
@ -469,7 +467,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (active_tool && ((active_tool->type == MOVE) ||
|
if (active_tool && ((active_tool->type == MOVE) ||
|
||||||
!gimp_image_is_empty (gdisp->gimage)) &&
|
! gimp_image_is_empty (gdisp->gimage)) &&
|
||||||
(mevent->state & GDK_BUTTON1_MASK))
|
(mevent->state & GDK_BUTTON1_MASK))
|
||||||
{
|
{
|
||||||
if (active_tool->state == ACTIVE)
|
if (active_tool->state == ACTIVE)
|
||||||
|
|
|
@ -160,7 +160,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
|
|
||||||
gdisp = (GDisplay *) gtk_object_get_user_data (GTK_OBJECT (canvas));
|
gdisp = (GDisplay *) gtk_object_get_user_data (GTK_OBJECT (canvas));
|
||||||
|
|
||||||
if (!canvas->window)
|
if (!canvas->window)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* If this is the first event... */
|
/* If this is the first event... */
|
||||||
|
@ -180,10 +180,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
|
|
||||||
/* set up the scrollbar observers */
|
/* set up the scrollbar observers */
|
||||||
gtk_signal_connect (GTK_OBJECT (gdisp->hsbdata), "value_changed",
|
gtk_signal_connect (GTK_OBJECT (gdisp->hsbdata), "value_changed",
|
||||||
(GtkSignalFunc) scrollbar_horz_update,
|
GTK_SIGNAL_FUNC(scrollbar_horz_update),
|
||||||
gdisp);
|
gdisp);
|
||||||
gtk_signal_connect (GTK_OBJECT (gdisp->vsbdata), "value_changed",
|
gtk_signal_connect (GTK_OBJECT (gdisp->vsbdata), "value_changed",
|
||||||
(GtkSignalFunc) scrollbar_vert_update,
|
GTK_SIGNAL_FUNC (scrollbar_vert_update),
|
||||||
gdisp);
|
gdisp);
|
||||||
|
|
||||||
/* setup scale properly */
|
/* setup scale properly */
|
||||||
|
@ -191,7 +191,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find out what device the event occurred upon */
|
/* Find out what device the event occurred upon */
|
||||||
if (!gimp_busy && devices_check_change (event))
|
if (! gimp_busy && devices_check_change (event))
|
||||||
gdisplay_check_device_cursor (gdisp);
|
gdisplay_check_device_cursor (gdisp);
|
||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
|
@ -216,7 +216,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_LEAVE_NOTIFY:
|
case GDK_LEAVE_NOTIFY:
|
||||||
if (((GdkEventCrossing*) event)->mode != GDK_CROSSING_NORMAL)
|
if (((GdkEventCrossing *) event)->mode != GDK_CROSSING_NORMAL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
gdisplay_update_cursor (gdisp, 0, 0);
|
gdisplay_update_cursor (gdisp, 0, 0);
|
||||||
gtk_label_set_text (GTK_LABEL (gdisp->cursor_label), "");
|
gtk_label_set_text (GTK_LABEL (gdisp->cursor_label), "");
|
||||||
|
@ -227,7 +227,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_ENTER_NOTIFY:
|
case GDK_ENTER_NOTIFY:
|
||||||
if (((GdkEventCrossing*) event)->mode != GDK_CROSSING_NORMAL)
|
if (((GdkEventCrossing *) event)->mode != GDK_CROSSING_NORMAL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
/* Actually, should figure out tx,ty here */
|
/* Actually, should figure out tx,ty here */
|
||||||
break;
|
break;
|
||||||
|
@ -247,12 +247,12 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
gtk_grab_add (canvas);
|
gtk_grab_add (canvas);
|
||||||
|
|
||||||
/* This is a hack to prevent other stuff being run in the middle of
|
/* This is a hack to prevent other stuff being run in the middle of
|
||||||
a tool operation (like changing image types.... brrrr). We just
|
* a tool operation (like changing image types.... brrrr). We just
|
||||||
block all the keypress event. A better solution is to implement
|
* block all the keypress event. A better solution is to implement
|
||||||
some sort of locking for images.
|
* some sort of locking for images.
|
||||||
Note that this is dependent on specific GTK behavior, and isn't
|
* Note that this is dependent on specific GTK behavior, and isn't
|
||||||
guaranteed to work in future versions of GTK.
|
* guaranteed to work in future versions of GTK.
|
||||||
-Yosh
|
* -Yosh
|
||||||
*/
|
*/
|
||||||
if (key_signal_id == 0)
|
if (key_signal_id == 0)
|
||||||
key_signal_id = gtk_signal_connect (GTK_OBJECT (canvas),
|
key_signal_id = gtk_signal_connect (GTK_OBJECT (canvas),
|
||||||
|
@ -261,7 +261,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (active_tool && ((active_tool->type == MOVE) ||
|
if (active_tool && ((active_tool->type == MOVE) ||
|
||||||
!gimp_image_is_empty (gdisp->gimage)))
|
! gimp_image_is_empty (gdisp->gimage)))
|
||||||
{
|
{
|
||||||
if (active_tool->auto_snap_to)
|
if (active_tool->auto_snap_to)
|
||||||
{
|
{
|
||||||
|
@ -363,9 +363,8 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
*
|
*
|
||||||
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
||||||
*/
|
*/
|
||||||
if (gimp_busy &&
|
if (gimp_busy && ! (active_tool->type == FUZZY_SELECT &&
|
||||||
!(active_tool->type == FUZZY_SELECT &&
|
active_tool->state == ACTIVE))
|
||||||
active_tool->state == ACTIVE))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
switch (bevent->button)
|
switch (bevent->button)
|
||||||
|
@ -394,7 +393,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
bevent->y = ty;
|
bevent->y = ty;
|
||||||
update_cursor = TRUE;
|
update_cursor = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
(* active_tool->button_release_func) (active_tool, bevent,
|
(* active_tool->button_release_func) (active_tool, bevent,
|
||||||
gdisp);
|
gdisp);
|
||||||
}
|
}
|
||||||
|
@ -437,14 +436,13 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
*
|
*
|
||||||
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
||||||
*/
|
*/
|
||||||
if (gimp_busy &&
|
if (gimp_busy && ! (active_tool->type == FUZZY_SELECT &&
|
||||||
!(active_tool->type == FUZZY_SELECT &&
|
active_tool->state == ACTIVE))
|
||||||
active_tool->state == ACTIVE))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* Ask for the pointer position, but ignore it except for cursor
|
/* Ask for the pointer position, but ignore it except for cursor
|
||||||
* handling, so motion events sync with the button press/release events */
|
* handling, so motion events sync with the button press/release events
|
||||||
|
*/
|
||||||
if (mevent->is_hint)
|
if (mevent->is_hint)
|
||||||
{
|
{
|
||||||
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
|
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
|
||||||
|
@ -469,7 +467,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (active_tool && ((active_tool->type == MOVE) ||
|
if (active_tool && ((active_tool->type == MOVE) ||
|
||||||
!gimp_image_is_empty (gdisp->gimage)) &&
|
! gimp_image_is_empty (gdisp->gimage)) &&
|
||||||
(mevent->state & GDK_BUTTON1_MASK))
|
(mevent->state & GDK_BUTTON1_MASK))
|
||||||
{
|
{
|
||||||
if (active_tool->state == ACTIVE)
|
if (active_tool->state == ACTIVE)
|
||||||
|
|
|
@ -245,7 +245,7 @@ static void gradient_render_pixel (gdouble x,
|
||||||
gpointer render_data);
|
gpointer render_data);
|
||||||
static void gradient_put_pixel (gint x,
|
static void gradient_put_pixel (gint x,
|
||||||
gint y,
|
gint y,
|
||||||
GimpRGB color,
|
GimpRGB *color,
|
||||||
gpointer put_pixel_data);
|
gpointer put_pixel_data);
|
||||||
|
|
||||||
static void gradient_fill_region (GImage *gimage,
|
static void gradient_fill_region (GImage *gimage,
|
||||||
|
@ -1403,7 +1403,7 @@ gradient_render_pixel (double x,
|
||||||
static void
|
static void
|
||||||
gradient_put_pixel (int x,
|
gradient_put_pixel (int x,
|
||||||
int y,
|
int y,
|
||||||
GimpRGB color,
|
GimpRGB *color,
|
||||||
void *put_pixel_data)
|
void *put_pixel_data)
|
||||||
{
|
{
|
||||||
PutPixelData *ppd;
|
PutPixelData *ppd;
|
||||||
|
@ -1417,17 +1417,17 @@ gradient_put_pixel (int x,
|
||||||
|
|
||||||
if (ppd->bytes >= 3)
|
if (ppd->bytes >= 3)
|
||||||
{
|
{
|
||||||
*data++ = color.r * 255.0;
|
*data++ = color->r * 255.0;
|
||||||
*data++ = color.g * 255.0;
|
*data++ = color->g * 255.0;
|
||||||
*data++ = color.b * 255.0;
|
*data++ = color->b * 255.0;
|
||||||
*data++ = color.a * 255.0;
|
*data++ = color->a * 255.0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Convert to grayscale */
|
/* Convert to grayscale */
|
||||||
|
|
||||||
*data++ = 255.0 * INTENSITY (color.r, color.g, color.b);
|
*data++ = 255.0 * INTENSITY (color->r, color->g, color->b);
|
||||||
*data++ = color.a * 255.0;
|
*data++ = color->a * 255.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paint whole row if we are on the rightmost pixel */
|
/* Paint whole row if we are on the rightmost pixel */
|
||||||
|
@ -1588,11 +1588,11 @@ gradient_fill_region (GImage *gimage,
|
||||||
|
|
||||||
/* Render! */
|
/* Render! */
|
||||||
|
|
||||||
adaptive_supersample_area (0, 0, (width - 1), (height - 1),
|
gimp_adaptive_supersample_area (0, 0, (width - 1), (height - 1),
|
||||||
max_depth, threshold,
|
max_depth, threshold,
|
||||||
gradient_render_pixel, &rbd,
|
gradient_render_pixel, &rbd,
|
||||||
gradient_put_pixel, &ppd,
|
gradient_put_pixel, &ppd,
|
||||||
progress_callback, progress_data);
|
progress_callback, progress_data);
|
||||||
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,7 @@ static void gradient_render_pixel (gdouble x,
|
||||||
gpointer render_data);
|
gpointer render_data);
|
||||||
static void gradient_put_pixel (gint x,
|
static void gradient_put_pixel (gint x,
|
||||||
gint y,
|
gint y,
|
||||||
GimpRGB color,
|
GimpRGB *color,
|
||||||
gpointer put_pixel_data);
|
gpointer put_pixel_data);
|
||||||
|
|
||||||
static void gradient_fill_region (GImage *gimage,
|
static void gradient_fill_region (GImage *gimage,
|
||||||
|
@ -1403,7 +1403,7 @@ gradient_render_pixel (double x,
|
||||||
static void
|
static void
|
||||||
gradient_put_pixel (int x,
|
gradient_put_pixel (int x,
|
||||||
int y,
|
int y,
|
||||||
GimpRGB color,
|
GimpRGB *color,
|
||||||
void *put_pixel_data)
|
void *put_pixel_data)
|
||||||
{
|
{
|
||||||
PutPixelData *ppd;
|
PutPixelData *ppd;
|
||||||
|
@ -1417,17 +1417,17 @@ gradient_put_pixel (int x,
|
||||||
|
|
||||||
if (ppd->bytes >= 3)
|
if (ppd->bytes >= 3)
|
||||||
{
|
{
|
||||||
*data++ = color.r * 255.0;
|
*data++ = color->r * 255.0;
|
||||||
*data++ = color.g * 255.0;
|
*data++ = color->g * 255.0;
|
||||||
*data++ = color.b * 255.0;
|
*data++ = color->b * 255.0;
|
||||||
*data++ = color.a * 255.0;
|
*data++ = color->a * 255.0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Convert to grayscale */
|
/* Convert to grayscale */
|
||||||
|
|
||||||
*data++ = 255.0 * INTENSITY (color.r, color.g, color.b);
|
*data++ = 255.0 * INTENSITY (color->r, color->g, color->b);
|
||||||
*data++ = color.a * 255.0;
|
*data++ = color->a * 255.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paint whole row if we are on the rightmost pixel */
|
/* Paint whole row if we are on the rightmost pixel */
|
||||||
|
@ -1588,11 +1588,11 @@ gradient_fill_region (GImage *gimage,
|
||||||
|
|
||||||
/* Render! */
|
/* Render! */
|
||||||
|
|
||||||
adaptive_supersample_area (0, 0, (width - 1), (height - 1),
|
gimp_adaptive_supersample_area (0, 0, (width - 1), (height - 1),
|
||||||
max_depth, threshold,
|
max_depth, threshold,
|
||||||
gradient_render_pixel, &rbd,
|
gradient_render_pixel, &rbd,
|
||||||
gradient_put_pixel, &ppd,
|
gradient_put_pixel, &ppd,
|
||||||
progress_callback, progress_data);
|
progress_callback, progress_data);
|
||||||
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
|
|
||||||
|
|
|
@ -155,55 +155,59 @@ endif
|
||||||
@:
|
@:
|
||||||
|
|
||||||
libgimp_la_SOURCES = \
|
libgimp_la_SOURCES = \
|
||||||
gimp.c \
|
gimp.c \
|
||||||
gimp.h \
|
gimp.h \
|
||||||
${PDB_WRAPPERS_C} \
|
${PDB_WRAPPERS_C} \
|
||||||
${PDB_WRAPPERS_H} \
|
${PDB_WRAPPERS_H} \
|
||||||
gimpcolor.c \
|
gimpadaptivesupersample.c \
|
||||||
gimpcolor.h \
|
gimpadaptivesupersample.h \
|
||||||
gimpcolorspace.c \
|
gimpbilinear.c \
|
||||||
gimpcolorspace.h \
|
gimpbilinear.h \
|
||||||
gimpchannel.c \
|
gimpcolor.c \
|
||||||
gimpchannel.h \
|
gimpcolor.h \
|
||||||
gimpdrawable.c \
|
gimpcolorspace.c \
|
||||||
gimpdrawable.h \
|
gimpcolorspace.h \
|
||||||
gimpenv.c \
|
gimpchannel.c \
|
||||||
gimpenv.h \
|
gimpchannel.h \
|
||||||
gimpgradientselect.c \
|
gimpdrawable.c \
|
||||||
gimpgradientselect.h \
|
gimpdrawable.h \
|
||||||
gimphelp.c \
|
gimpenv.c \
|
||||||
gimpimage.c \
|
gimpenv.h \
|
||||||
gimpimage.h \
|
gimpgradientselect.c \
|
||||||
gimplayer.c \
|
gimpgradientselect.h \
|
||||||
gimplayer.h \
|
gimphelp.c \
|
||||||
gimplimits.h \
|
gimpimage.c \
|
||||||
gimpmatrix.c \
|
gimpimage.h \
|
||||||
gimpmatrix.h \
|
gimplayer.c \
|
||||||
gimpparasite.c \
|
gimplayer.h \
|
||||||
gimpparasite.h \
|
gimplimits.h \
|
||||||
gimpparasiteio.c \
|
gimpmatrix.c \
|
||||||
gimpparasiteio.h \
|
gimpmatrix.h \
|
||||||
gimppixelrgn.c \
|
gimpparasite.c \
|
||||||
gimppixelrgn.h \
|
gimpparasite.h \
|
||||||
gimpproceduraldb.c \
|
gimpparasiteio.c \
|
||||||
gimpproceduraldb.h \
|
gimpparasiteio.h \
|
||||||
gimpprotocol.c \
|
gimppixelrgn.c \
|
||||||
gimpprotocol.h \
|
gimppixelrgn.h \
|
||||||
gimpselection.c \
|
gimpproceduraldb.c \
|
||||||
gimpselection.h \
|
gimpproceduraldb.h \
|
||||||
gimpsignal.c \
|
gimpprotocol.c \
|
||||||
gimpsignal.h \
|
gimpprotocol.h \
|
||||||
gimptile.c \
|
gimpselection.c \
|
||||||
gimptile.h \
|
gimpselection.h \
|
||||||
gimpunit.c \
|
gimpsignal.c \
|
||||||
gimpunit.h \
|
gimpsignal.h \
|
||||||
gimputils.c \
|
gimptile.c \
|
||||||
gimputils.h \
|
gimptile.h \
|
||||||
gimpvector.c \
|
gimpunit.c \
|
||||||
gimpvector.h \
|
gimpunit.h \
|
||||||
gimpwire.c \
|
gimputils.c \
|
||||||
gimpwire.h \
|
gimputils.h \
|
||||||
stdplugins-intl.h \
|
gimpvector.c \
|
||||||
|
gimpvector.h \
|
||||||
|
gimpwire.c \
|
||||||
|
gimpwire.h \
|
||||||
|
stdplugins-intl.h \
|
||||||
libgimp-intl.h
|
libgimp-intl.h
|
||||||
|
|
||||||
libgimpui_la_SOURCES = \
|
libgimpui_la_SOURCES = \
|
||||||
|
@ -228,52 +232,54 @@ libgimpui_la_SOURCES = \
|
||||||
gimpwidgets.c
|
gimpwidgets.c
|
||||||
|
|
||||||
gimpinclude_HEADERS = \
|
gimpinclude_HEADERS = \
|
||||||
gimp.h \
|
gimp.h \
|
||||||
${PDB_WRAPPERS_H} \
|
${PDB_WRAPPERS_H} \
|
||||||
gimpchainbutton.h \
|
gimpadaptivesupersample.h \
|
||||||
gimpchannel.h \
|
gimpbilinear.h \
|
||||||
gimpcolor.h \
|
gimpchainbutton.h \
|
||||||
gimpcolorarea.h \
|
gimpchannel.h \
|
||||||
gimpcolorbutton.h \
|
gimpcolor.h \
|
||||||
gimpcolordisplay.h \
|
gimpcolorarea.h \
|
||||||
gimpcolorselector.h \
|
gimpcolorbutton.h \
|
||||||
gimpcolorspace.h \
|
gimpcolordisplay.h \
|
||||||
gimpcompat.h \
|
gimpcolorselector.h \
|
||||||
gimpdrawable.h \
|
gimpcolorspace.h \
|
||||||
gimpdialog.h \
|
gimpcompat.h \
|
||||||
gimpenums.h \
|
gimpdrawable.h \
|
||||||
gimpenv.h \
|
gimpdialog.h \
|
||||||
gimpexport.h \
|
gimpenums.h \
|
||||||
gimpfeatures.h \
|
gimpenv.h \
|
||||||
gimpfileselection.h \
|
gimpexport.h \
|
||||||
gimpgradientselect.h \
|
gimpfeatures.h \
|
||||||
gimphelpui.h \
|
gimpfileselection.h \
|
||||||
gimpimage.h \
|
gimpgradientselect.h \
|
||||||
gimplayer.h \
|
gimphelpui.h \
|
||||||
gimplimits.h \
|
gimpimage.h \
|
||||||
gimpmath.h \
|
gimplayer.h \
|
||||||
gimpmatrix.h \
|
gimplimits.h \
|
||||||
gimpmenu.h \
|
gimpmath.h \
|
||||||
gimpmodule.h \
|
gimpmatrix.h \
|
||||||
gimpparasite.h \
|
gimpmenu.h \
|
||||||
gimpparasiteio.h \
|
gimpmodule.h \
|
||||||
gimppatheditor.h \
|
gimpparasite.h \
|
||||||
gimppixelrgn.h \
|
gimpparasiteio.h \
|
||||||
gimppixmap.h \
|
gimppatheditor.h \
|
||||||
gimpproceduraldb.h \
|
gimppixelrgn.h \
|
||||||
gimpquerybox.h \
|
gimppixmap.h \
|
||||||
gimpselection.h \
|
gimpproceduraldb.h \
|
||||||
gimpsignal.h \
|
gimpquerybox.h \
|
||||||
gimpsizeentry.h \
|
gimpselection.h \
|
||||||
gimptile.h \
|
gimpsignal.h \
|
||||||
gimptypes.h \
|
gimpsizeentry.h \
|
||||||
gimpui.h \
|
gimptile.h \
|
||||||
gimpuitypes.h \
|
gimptypes.h \
|
||||||
gimpunit.h \
|
gimpui.h \
|
||||||
gimpunitmenu.h \
|
gimpuitypes.h \
|
||||||
gimputils.h \
|
gimpunit.h \
|
||||||
gimpvector.h \
|
gimpunitmenu.h \
|
||||||
gimpwidgets.h \
|
gimputils.h \
|
||||||
|
gimpvector.h \
|
||||||
|
gimpwidgets.h \
|
||||||
gimpintl.h
|
gimpintl.h
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <libgimp/gimpenums.h>
|
#include <libgimp/gimpenums.h>
|
||||||
#include <libgimp/gimptypes.h>
|
#include <libgimp/gimptypes.h>
|
||||||
|
|
||||||
|
#include <libgimp/gimpadaptivesupersample.h>
|
||||||
|
#include <libgimp/gimpbilinear.h>
|
||||||
#include <libgimp/gimpchannel.h>
|
#include <libgimp/gimpchannel.h>
|
||||||
#include <libgimp/gimpcolor.h>
|
#include <libgimp/gimpcolor.h>
|
||||||
#include <libgimp/gimpcolorspace.h>
|
#include <libgimp/gimpcolorspace.h>
|
||||||
|
|
|
@ -0,0 +1,380 @@
|
||||||
|
/* LIBGIMP - The GIMP Library
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "gimpcolor.h"
|
||||||
|
#include "gimpadaptivesupersample.h"
|
||||||
|
#include "gimpmath.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Sumpersampling code (Quartic) */
|
||||||
|
/* This code is *largely* based on the sources for POV-Ray 3.0. I am */
|
||||||
|
/* grateful to the POV-Team for such a great program and for making */
|
||||||
|
/* their sources available. All comments / bug reports / */
|
||||||
|
/* etc. regarding this code should be addressed to me, not to the */
|
||||||
|
/* POV-Ray team. Any bugs are my responsibility, not theirs. */
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _GimpSampleType GimpSampleType;
|
||||||
|
|
||||||
|
struct _GimpSampleType
|
||||||
|
{
|
||||||
|
guchar ready;
|
||||||
|
GimpRGB color;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static gulong
|
||||||
|
gimp_render_sub_pixel (gint max_depth,
|
||||||
|
gint depth,
|
||||||
|
GimpSampleType **block,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint x1,
|
||||||
|
gint y1,
|
||||||
|
gint x3,
|
||||||
|
gint y3,
|
||||||
|
gdouble threshold,
|
||||||
|
gint sub_pixel_size,
|
||||||
|
GimpRGB *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 */
|
||||||
|
gulong num_samples = 0;
|
||||||
|
gint cnt;
|
||||||
|
|
||||||
|
/* Get offsets for corners */
|
||||||
|
|
||||||
|
dx1 = (gdouble) (x1 - sub_pixel_size / 2) / sub_pixel_size;
|
||||||
|
dx3 = (gdouble) (x3 - sub_pixel_size / 2) / sub_pixel_size;
|
||||||
|
|
||||||
|
dy1 = (gdouble) (y1 - sub_pixel_size / 2) / sub_pixel_size;
|
||||||
|
dy3 = (gdouble) (y3 - sub_pixel_size / 2) / sub_pixel_size;
|
||||||
|
|
||||||
|
/* Render upper left sample */
|
||||||
|
|
||||||
|
if (! block[y1][x1].ready)
|
||||||
|
{
|
||||||
|
num_samples++;
|
||||||
|
|
||||||
|
if (render_func)
|
||||||
|
(* render_func) (x + dx1, y + dy1, &c[0], render_data);
|
||||||
|
|
||||||
|
block[y1][x1].ready = TRUE;
|
||||||
|
block[y1][x1].color = c[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c[0] = block[y1][x1].color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render upper right sample */
|
||||||
|
|
||||||
|
if (! block[y1][x3].ready)
|
||||||
|
{
|
||||||
|
num_samples++;
|
||||||
|
|
||||||
|
if (render_func)
|
||||||
|
(* render_func) (x + dx3, y + dy1, &c[1], render_data);
|
||||||
|
|
||||||
|
block[y1][x3].ready = TRUE;
|
||||||
|
block[y1][x3].color = c[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c[1] = block[y1][x3].color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render lower left sample */
|
||||||
|
|
||||||
|
if (! block[y3][x1].ready)
|
||||||
|
{
|
||||||
|
num_samples++;
|
||||||
|
|
||||||
|
if (render_func)
|
||||||
|
(* render_func) (x + dx1, y + dy3, &c[2], render_data);
|
||||||
|
|
||||||
|
block[y3][x1].ready = TRUE;
|
||||||
|
block[y3][x1].color = c[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c[2] = block[y3][x1].color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render lower right sample */
|
||||||
|
|
||||||
|
if (! block[y3][x3].ready)
|
||||||
|
{
|
||||||
|
num_samples++;
|
||||||
|
|
||||||
|
if (render_func)
|
||||||
|
(* render_func) (x + dx3, y + dy3, &c[3], render_data);
|
||||||
|
|
||||||
|
block[y3][x3].ready = TRUE;
|
||||||
|
block[y3][x3].color = c[3];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c[3] = block[y3][x3].color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for supersampling */
|
||||||
|
|
||||||
|
if (depth <= 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))
|
||||||
|
{
|
||||||
|
/* Calc coordinates of center subsample */
|
||||||
|
|
||||||
|
x2 = (x1 + x3) / 2;
|
||||||
|
y2 = (y1 + y3) / 2;
|
||||||
|
|
||||||
|
/* Render sub-blocks */
|
||||||
|
|
||||||
|
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
|
||||||
|
x, y, x1, y1, x2, y2,
|
||||||
|
threshold, sub_pixel_size,
|
||||||
|
&c[0],
|
||||||
|
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],
|
||||||
|
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],
|
||||||
|
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],
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
GimpRGB tmpcol;
|
||||||
|
gdouble weight;
|
||||||
|
|
||||||
|
gimp_rgb_set (&tmpcol, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
weight = 2.0;
|
||||||
|
|
||||||
|
for (cnt = 0; cnt < 4; cnt++)
|
||||||
|
{
|
||||||
|
if (c[cnt].a != 0.0)
|
||||||
|
{
|
||||||
|
tmpcol.r += c[cnt].r;
|
||||||
|
tmpcol.g += c[cnt].g;
|
||||||
|
tmpcol.b += c[cnt].b;
|
||||||
|
|
||||||
|
weight /= 2.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
color->r = weight * tmpcol.r;
|
||||||
|
color->g = weight * tmpcol.g;
|
||||||
|
color->b = weight * tmpcol.b;
|
||||||
|
}
|
||||||
|
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->a = 0.25 * (c[0].a + c[1].a + c[2].a + c[3].a);
|
||||||
|
|
||||||
|
return num_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
gulong
|
||||||
|
gimp_adaptive_supersample_area (gint x1,
|
||||||
|
gint y1,
|
||||||
|
gint x2,
|
||||||
|
gint y2,
|
||||||
|
gint max_depth,
|
||||||
|
gdouble threshold,
|
||||||
|
GimpRenderFunc render_func,
|
||||||
|
gpointer render_data,
|
||||||
|
GimpPutPixelFunc put_pixel_func,
|
||||||
|
gpointer put_pixel_data,
|
||||||
|
GimpProgressFunc progress_func,
|
||||||
|
gpointer progress_data)
|
||||||
|
{
|
||||||
|
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 */
|
||||||
|
GimpSampleType tmp_sample; /* For swapping samples */
|
||||||
|
GimpSampleType *top_row, *bot_row, *tmp_row; /* Sample rows */
|
||||||
|
GimpSampleType **block; /* Sample block matrix */
|
||||||
|
gulong num_samples;
|
||||||
|
|
||||||
|
/* Initialize color */
|
||||||
|
|
||||||
|
gimp_rgba_set (&color, 0.0, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
/* Calculate sub-pixel size */
|
||||||
|
|
||||||
|
sub_pixel_size = 1 << max_depth;
|
||||||
|
|
||||||
|
/* Create row arrays */
|
||||||
|
|
||||||
|
width = x2 - x1 + 1;
|
||||||
|
|
||||||
|
top_row = g_new (GimpSampleType, sub_pixel_size * width + 1);
|
||||||
|
bot_row = g_new (GimpSampleType, sub_pixel_size * width + 1);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate block matrix */
|
||||||
|
|
||||||
|
block = g_new (GimpSampleType *, sub_pixel_size + 1); /* Rows */
|
||||||
|
|
||||||
|
for (y = 0; y < (sub_pixel_size + 1); y++)
|
||||||
|
{
|
||||||
|
block[y] = g_new (GimpSampleType, sub_pixel_size + 1); /* Columns */
|
||||||
|
|
||||||
|
for (x = 0; x < (sub_pixel_size + 1); x++)
|
||||||
|
{
|
||||||
|
block[y][x].ready = FALSE;
|
||||||
|
|
||||||
|
gimp_rgba_set (&block[y][x].color, 0.0, 0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render region */
|
||||||
|
|
||||||
|
num_samples = 0;
|
||||||
|
|
||||||
|
for (y = y1; y <= y2; y++)
|
||||||
|
{
|
||||||
|
/* Clear the bottom row */
|
||||||
|
|
||||||
|
for (xt = 0; xt < (sub_pixel_size * width + 1); xt++)
|
||||||
|
bot_row[xt].ready = FALSE;
|
||||||
|
|
||||||
|
/* Clear first column */
|
||||||
|
|
||||||
|
for (yt = 0; yt < (sub_pixel_size + 1); yt++)
|
||||||
|
block[yt][0].ready = FALSE;
|
||||||
|
|
||||||
|
/* Render row */
|
||||||
|
|
||||||
|
for (x = x1; x <= x2; x++)
|
||||||
|
{
|
||||||
|
/* Initialize block by clearing all but first row/column */
|
||||||
|
|
||||||
|
for (yt = 1; yt < (sub_pixel_size + 1); yt++)
|
||||||
|
for (xt = 1; xt < (sub_pixel_size + 1); xt++)
|
||||||
|
block[yt][xt].ready = FALSE;
|
||||||
|
|
||||||
|
/* Copy samples from top row to block */
|
||||||
|
|
||||||
|
for (xtt = 0, xt = (x - x1) * sub_pixel_size;
|
||||||
|
xtt < (sub_pixel_size + 1);
|
||||||
|
xtt++, xt++)
|
||||||
|
block[0][xtt] = top_row[xt];
|
||||||
|
|
||||||
|
/* Render pixel on (x, y) */
|
||||||
|
|
||||||
|
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,
|
||||||
|
render_func, render_data);
|
||||||
|
|
||||||
|
if (put_pixel_func)
|
||||||
|
(* put_pixel_func) (x, y, &color, put_pixel_data);
|
||||||
|
|
||||||
|
/* Copy block information to rows */
|
||||||
|
|
||||||
|
top_row[(x - x1 + 1) * sub_pixel_size] = block[0][sub_pixel_size];
|
||||||
|
|
||||||
|
for (xtt = 0, xt = (x - x1) * sub_pixel_size;
|
||||||
|
xtt < (sub_pixel_size + 1);
|
||||||
|
xtt++, xt++)
|
||||||
|
bot_row[xt] = block[sub_pixel_size][xtt];
|
||||||
|
|
||||||
|
/* Swap first and last columns */
|
||||||
|
|
||||||
|
for (yt = 0; yt < (sub_pixel_size + 1); yt++)
|
||||||
|
{
|
||||||
|
tmp_sample = block[yt][0];
|
||||||
|
block[yt][0] = block[yt][sub_pixel_size];
|
||||||
|
block[yt][sub_pixel_size] = tmp_sample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Swap rows */
|
||||||
|
|
||||||
|
tmp_row = top_row;
|
||||||
|
top_row = bot_row;
|
||||||
|
bot_row = tmp_row;
|
||||||
|
|
||||||
|
/* Call progress display function (if any) */
|
||||||
|
|
||||||
|
if (progress_func != NULL)
|
||||||
|
(* progress_func) (y1, y2, y, progress_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free memory */
|
||||||
|
|
||||||
|
for (y = 0; y < (sub_pixel_size + 1); y++)
|
||||||
|
g_free (block[y]);
|
||||||
|
|
||||||
|
g_free (block);
|
||||||
|
g_free (top_row);
|
||||||
|
g_free (bot_row);
|
||||||
|
|
||||||
|
return num_samples;
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/* LIBGIMP - The GIMP Library
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GIMP_ADAPTIVE_SUPERSAMPLE_H__
|
||||||
|
#define __GIMP_ADAPTIVE_SUPERSAMPLE_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/* For information look into the C source or the html documentation */
|
||||||
|
|
||||||
|
|
||||||
|
/* adaptive supersampling function taken from LibGCK */
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (* GimpRenderFunc) (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
GimpRGB *color,
|
||||||
|
gpointer data);
|
||||||
|
typedef void (* GimpPutPixelFunc) (gint x,
|
||||||
|
gint y,
|
||||||
|
GimpRGB *color,
|
||||||
|
gpointer data);
|
||||||
|
typedef void (* GimpProgressFunc) (gint min,
|
||||||
|
gint max,
|
||||||
|
gint current,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
|
|
||||||
|
gulong gimp_adaptive_supersample_area (gint x1,
|
||||||
|
gint y1,
|
||||||
|
gint x2,
|
||||||
|
gint y2,
|
||||||
|
gint max_depth,
|
||||||
|
gdouble threshold,
|
||||||
|
GimpRenderFunc render_func,
|
||||||
|
gpointer render_data,
|
||||||
|
GimpPutPixelFunc put_pixel_func,
|
||||||
|
gpointer put_pixel_data,
|
||||||
|
GimpProgressFunc progress_func,
|
||||||
|
gpointer progress_data);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* __GIMP_ADAPTIVE_SUPERSAMPLE_H__ */
|
|
@ -0,0 +1,222 @@
|
||||||
|
/* LIBGIMP - The GIMP Library
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "gimpcolor.h"
|
||||||
|
#include "gimpbilinear.h"
|
||||||
|
#include "gimpmath.h"
|
||||||
|
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
gimp_bilinear (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
gdouble *values)
|
||||||
|
{
|
||||||
|
gdouble xx, yy;
|
||||||
|
gdouble m0, m1;
|
||||||
|
|
||||||
|
g_assert (values != NULL);
|
||||||
|
|
||||||
|
xx = fmod (x, 1.0);
|
||||||
|
yy = fmod (y, 1.0);
|
||||||
|
|
||||||
|
if (x < 0.0)
|
||||||
|
x += 1.0;
|
||||||
|
if (y < 0.0)
|
||||||
|
y += 1.0;
|
||||||
|
|
||||||
|
m0 = (1.0 - xx) * values[0] + xx * values[1];
|
||||||
|
m1 = (1.0 - xx) * values[2] + xx * values[3];
|
||||||
|
|
||||||
|
return (1.0 - yy) * m0 + yy * m1;
|
||||||
|
}
|
||||||
|
|
||||||
|
guchar
|
||||||
|
gimp_bilinear_8 (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
guchar *values)
|
||||||
|
{
|
||||||
|
gdouble xx, yy;
|
||||||
|
gdouble m0, m1;
|
||||||
|
|
||||||
|
g_assert (values != NULL);
|
||||||
|
|
||||||
|
xx = fmod (x, 1.0);
|
||||||
|
yy = fmod (y, 1.0);
|
||||||
|
|
||||||
|
if (x < 0.0)
|
||||||
|
x += 1.0;
|
||||||
|
if (y < 0.0)
|
||||||
|
y += 1.0;
|
||||||
|
|
||||||
|
m0 = (1.0 - xx) * values[0] + xx * values[1];
|
||||||
|
m1 = (1.0 - xx) * values[2] + xx * values[3];
|
||||||
|
|
||||||
|
return (guchar) ((1.0 - yy) * m0 + yy * m1);
|
||||||
|
}
|
||||||
|
|
||||||
|
guint16
|
||||||
|
gimp_bilinear_16 (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
guint16 *values)
|
||||||
|
{
|
||||||
|
gdouble xx, yy;
|
||||||
|
gdouble m0, m1;
|
||||||
|
|
||||||
|
g_assert (values != NULL);
|
||||||
|
|
||||||
|
xx = fmod (x, 1.0);
|
||||||
|
yy = fmod (y, 1.0);
|
||||||
|
|
||||||
|
if (x < 0.0)
|
||||||
|
x += 1.0;
|
||||||
|
if (y < 0.0)
|
||||||
|
y += 1.0;
|
||||||
|
|
||||||
|
m0 = (1.0 - xx) * values[0] + xx * values[1];
|
||||||
|
m1 = (1.0 - xx) * values[2] + xx * values[3];
|
||||||
|
|
||||||
|
return (guint16) ((1.0 - yy) * m0 + yy * m1);
|
||||||
|
}
|
||||||
|
|
||||||
|
guint32
|
||||||
|
gimp_bilinear_32 (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
guint32 *values)
|
||||||
|
{
|
||||||
|
gdouble xx, yy;
|
||||||
|
gdouble m0, m1;
|
||||||
|
|
||||||
|
g_assert (values != NULL);
|
||||||
|
|
||||||
|
xx = fmod (x, 1.0);
|
||||||
|
yy = fmod (y, 1.0);
|
||||||
|
|
||||||
|
if (x < 0.0)
|
||||||
|
x += 1.0;
|
||||||
|
if (y < 0.0)
|
||||||
|
y += 1.0;
|
||||||
|
|
||||||
|
m0 = (1.0 - xx) * values[0] + xx * values[1];
|
||||||
|
m1 = (1.0 - xx) * values[2] + xx * values[3];
|
||||||
|
|
||||||
|
return (guint32) ((1.0 - yy) * m0 + yy * m1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GimpRGB
|
||||||
|
gimp_bilinear_rgb (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
GimpRGB *values)
|
||||||
|
{
|
||||||
|
gdouble m0, m1;
|
||||||
|
gdouble ix, iy;
|
||||||
|
GimpRGB v;
|
||||||
|
|
||||||
|
g_assert (values != NULL);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
GimpRGB
|
||||||
|
gimp_bilinear_rgba (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
GimpRGB *values)
|
||||||
|
{
|
||||||
|
gdouble m0, m1;
|
||||||
|
gdouble ix, iy;
|
||||||
|
GimpRGB v;
|
||||||
|
|
||||||
|
g_assert (values != NULL);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* Alpha */
|
||||||
|
|
||||||
|
m0 = ix * values[0].a + x * values[1].a;
|
||||||
|
m1 = ix * values[2].a + x * values[3].a;
|
||||||
|
|
||||||
|
v.a = iy * m0 + y * m1;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* LIBGIMP - The GIMP Library
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GIMP_BILINEAR_H__
|
||||||
|
#define __GIMP_BILINEAR_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/* For information look into the C source or the html documentation */
|
||||||
|
|
||||||
|
|
||||||
|
/* bilinear interpolation functions taken from LibGCK */
|
||||||
|
|
||||||
|
|
||||||
|
gdouble gimp_bilinear (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
gdouble *values);
|
||||||
|
guchar gimp_bilinear_8 (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
guchar *values);
|
||||||
|
guint16 gimp_bilinear_16 (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
guint16 *values);
|
||||||
|
guint32 gimp_bilinear_32 (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
guint32 *values);
|
||||||
|
GimpRGB gimp_bilinear_rgb (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
GimpRGB *values);
|
||||||
|
GimpRGB gimp_bilinear_rgba (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
GimpRGB *values);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* __GIMP_BILINEAR_H__ */
|
|
@ -0,0 +1,380 @@
|
||||||
|
/* LIBGIMP - The GIMP Library
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "gimpcolor.h"
|
||||||
|
#include "gimpadaptivesupersample.h"
|
||||||
|
#include "gimpmath.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* Sumpersampling code (Quartic) */
|
||||||
|
/* This code is *largely* based on the sources for POV-Ray 3.0. I am */
|
||||||
|
/* grateful to the POV-Team for such a great program and for making */
|
||||||
|
/* their sources available. All comments / bug reports / */
|
||||||
|
/* etc. regarding this code should be addressed to me, not to the */
|
||||||
|
/* POV-Ray team. Any bugs are my responsibility, not theirs. */
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _GimpSampleType GimpSampleType;
|
||||||
|
|
||||||
|
struct _GimpSampleType
|
||||||
|
{
|
||||||
|
guchar ready;
|
||||||
|
GimpRGB color;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static gulong
|
||||||
|
gimp_render_sub_pixel (gint max_depth,
|
||||||
|
gint depth,
|
||||||
|
GimpSampleType **block,
|
||||||
|
gint x,
|
||||||
|
gint y,
|
||||||
|
gint x1,
|
||||||
|
gint y1,
|
||||||
|
gint x3,
|
||||||
|
gint y3,
|
||||||
|
gdouble threshold,
|
||||||
|
gint sub_pixel_size,
|
||||||
|
GimpRGB *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 */
|
||||||
|
gulong num_samples = 0;
|
||||||
|
gint cnt;
|
||||||
|
|
||||||
|
/* Get offsets for corners */
|
||||||
|
|
||||||
|
dx1 = (gdouble) (x1 - sub_pixel_size / 2) / sub_pixel_size;
|
||||||
|
dx3 = (gdouble) (x3 - sub_pixel_size / 2) / sub_pixel_size;
|
||||||
|
|
||||||
|
dy1 = (gdouble) (y1 - sub_pixel_size / 2) / sub_pixel_size;
|
||||||
|
dy3 = (gdouble) (y3 - sub_pixel_size / 2) / sub_pixel_size;
|
||||||
|
|
||||||
|
/* Render upper left sample */
|
||||||
|
|
||||||
|
if (! block[y1][x1].ready)
|
||||||
|
{
|
||||||
|
num_samples++;
|
||||||
|
|
||||||
|
if (render_func)
|
||||||
|
(* render_func) (x + dx1, y + dy1, &c[0], render_data);
|
||||||
|
|
||||||
|
block[y1][x1].ready = TRUE;
|
||||||
|
block[y1][x1].color = c[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c[0] = block[y1][x1].color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render upper right sample */
|
||||||
|
|
||||||
|
if (! block[y1][x3].ready)
|
||||||
|
{
|
||||||
|
num_samples++;
|
||||||
|
|
||||||
|
if (render_func)
|
||||||
|
(* render_func) (x + dx3, y + dy1, &c[1], render_data);
|
||||||
|
|
||||||
|
block[y1][x3].ready = TRUE;
|
||||||
|
block[y1][x3].color = c[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c[1] = block[y1][x3].color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render lower left sample */
|
||||||
|
|
||||||
|
if (! block[y3][x1].ready)
|
||||||
|
{
|
||||||
|
num_samples++;
|
||||||
|
|
||||||
|
if (render_func)
|
||||||
|
(* render_func) (x + dx1, y + dy3, &c[2], render_data);
|
||||||
|
|
||||||
|
block[y3][x1].ready = TRUE;
|
||||||
|
block[y3][x1].color = c[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c[2] = block[y3][x1].color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render lower right sample */
|
||||||
|
|
||||||
|
if (! block[y3][x3].ready)
|
||||||
|
{
|
||||||
|
num_samples++;
|
||||||
|
|
||||||
|
if (render_func)
|
||||||
|
(* render_func) (x + dx3, y + dy3, &c[3], render_data);
|
||||||
|
|
||||||
|
block[y3][x3].ready = TRUE;
|
||||||
|
block[y3][x3].color = c[3];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c[3] = block[y3][x3].color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for supersampling */
|
||||||
|
|
||||||
|
if (depth <= 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))
|
||||||
|
{
|
||||||
|
/* Calc coordinates of center subsample */
|
||||||
|
|
||||||
|
x2 = (x1 + x3) / 2;
|
||||||
|
y2 = (y1 + y3) / 2;
|
||||||
|
|
||||||
|
/* Render sub-blocks */
|
||||||
|
|
||||||
|
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
|
||||||
|
x, y, x1, y1, x2, y2,
|
||||||
|
threshold, sub_pixel_size,
|
||||||
|
&c[0],
|
||||||
|
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],
|
||||||
|
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],
|
||||||
|
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],
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
GimpRGB tmpcol;
|
||||||
|
gdouble weight;
|
||||||
|
|
||||||
|
gimp_rgb_set (&tmpcol, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
weight = 2.0;
|
||||||
|
|
||||||
|
for (cnt = 0; cnt < 4; cnt++)
|
||||||
|
{
|
||||||
|
if (c[cnt].a != 0.0)
|
||||||
|
{
|
||||||
|
tmpcol.r += c[cnt].r;
|
||||||
|
tmpcol.g += c[cnt].g;
|
||||||
|
tmpcol.b += c[cnt].b;
|
||||||
|
|
||||||
|
weight /= 2.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
color->r = weight * tmpcol.r;
|
||||||
|
color->g = weight * tmpcol.g;
|
||||||
|
color->b = weight * tmpcol.b;
|
||||||
|
}
|
||||||
|
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->a = 0.25 * (c[0].a + c[1].a + c[2].a + c[3].a);
|
||||||
|
|
||||||
|
return num_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
gulong
|
||||||
|
gimp_adaptive_supersample_area (gint x1,
|
||||||
|
gint y1,
|
||||||
|
gint x2,
|
||||||
|
gint y2,
|
||||||
|
gint max_depth,
|
||||||
|
gdouble threshold,
|
||||||
|
GimpRenderFunc render_func,
|
||||||
|
gpointer render_data,
|
||||||
|
GimpPutPixelFunc put_pixel_func,
|
||||||
|
gpointer put_pixel_data,
|
||||||
|
GimpProgressFunc progress_func,
|
||||||
|
gpointer progress_data)
|
||||||
|
{
|
||||||
|
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 */
|
||||||
|
GimpSampleType tmp_sample; /* For swapping samples */
|
||||||
|
GimpSampleType *top_row, *bot_row, *tmp_row; /* Sample rows */
|
||||||
|
GimpSampleType **block; /* Sample block matrix */
|
||||||
|
gulong num_samples;
|
||||||
|
|
||||||
|
/* Initialize color */
|
||||||
|
|
||||||
|
gimp_rgba_set (&color, 0.0, 0.0, 0.0, 0.0);
|
||||||
|
|
||||||
|
/* Calculate sub-pixel size */
|
||||||
|
|
||||||
|
sub_pixel_size = 1 << max_depth;
|
||||||
|
|
||||||
|
/* Create row arrays */
|
||||||
|
|
||||||
|
width = x2 - x1 + 1;
|
||||||
|
|
||||||
|
top_row = g_new (GimpSampleType, sub_pixel_size * width + 1);
|
||||||
|
bot_row = g_new (GimpSampleType, sub_pixel_size * width + 1);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate block matrix */
|
||||||
|
|
||||||
|
block = g_new (GimpSampleType *, sub_pixel_size + 1); /* Rows */
|
||||||
|
|
||||||
|
for (y = 0; y < (sub_pixel_size + 1); y++)
|
||||||
|
{
|
||||||
|
block[y] = g_new (GimpSampleType, sub_pixel_size + 1); /* Columns */
|
||||||
|
|
||||||
|
for (x = 0; x < (sub_pixel_size + 1); x++)
|
||||||
|
{
|
||||||
|
block[y][x].ready = FALSE;
|
||||||
|
|
||||||
|
gimp_rgba_set (&block[y][x].color, 0.0, 0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render region */
|
||||||
|
|
||||||
|
num_samples = 0;
|
||||||
|
|
||||||
|
for (y = y1; y <= y2; y++)
|
||||||
|
{
|
||||||
|
/* Clear the bottom row */
|
||||||
|
|
||||||
|
for (xt = 0; xt < (sub_pixel_size * width + 1); xt++)
|
||||||
|
bot_row[xt].ready = FALSE;
|
||||||
|
|
||||||
|
/* Clear first column */
|
||||||
|
|
||||||
|
for (yt = 0; yt < (sub_pixel_size + 1); yt++)
|
||||||
|
block[yt][0].ready = FALSE;
|
||||||
|
|
||||||
|
/* Render row */
|
||||||
|
|
||||||
|
for (x = x1; x <= x2; x++)
|
||||||
|
{
|
||||||
|
/* Initialize block by clearing all but first row/column */
|
||||||
|
|
||||||
|
for (yt = 1; yt < (sub_pixel_size + 1); yt++)
|
||||||
|
for (xt = 1; xt < (sub_pixel_size + 1); xt++)
|
||||||
|
block[yt][xt].ready = FALSE;
|
||||||
|
|
||||||
|
/* Copy samples from top row to block */
|
||||||
|
|
||||||
|
for (xtt = 0, xt = (x - x1) * sub_pixel_size;
|
||||||
|
xtt < (sub_pixel_size + 1);
|
||||||
|
xtt++, xt++)
|
||||||
|
block[0][xtt] = top_row[xt];
|
||||||
|
|
||||||
|
/* Render pixel on (x, y) */
|
||||||
|
|
||||||
|
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,
|
||||||
|
render_func, render_data);
|
||||||
|
|
||||||
|
if (put_pixel_func)
|
||||||
|
(* put_pixel_func) (x, y, &color, put_pixel_data);
|
||||||
|
|
||||||
|
/* Copy block information to rows */
|
||||||
|
|
||||||
|
top_row[(x - x1 + 1) * sub_pixel_size] = block[0][sub_pixel_size];
|
||||||
|
|
||||||
|
for (xtt = 0, xt = (x - x1) * sub_pixel_size;
|
||||||
|
xtt < (sub_pixel_size + 1);
|
||||||
|
xtt++, xt++)
|
||||||
|
bot_row[xt] = block[sub_pixel_size][xtt];
|
||||||
|
|
||||||
|
/* Swap first and last columns */
|
||||||
|
|
||||||
|
for (yt = 0; yt < (sub_pixel_size + 1); yt++)
|
||||||
|
{
|
||||||
|
tmp_sample = block[yt][0];
|
||||||
|
block[yt][0] = block[yt][sub_pixel_size];
|
||||||
|
block[yt][sub_pixel_size] = tmp_sample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Swap rows */
|
||||||
|
|
||||||
|
tmp_row = top_row;
|
||||||
|
top_row = bot_row;
|
||||||
|
bot_row = tmp_row;
|
||||||
|
|
||||||
|
/* Call progress display function (if any) */
|
||||||
|
|
||||||
|
if (progress_func != NULL)
|
||||||
|
(* progress_func) (y1, y2, y, progress_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free memory */
|
||||||
|
|
||||||
|
for (y = 0; y < (sub_pixel_size + 1); y++)
|
||||||
|
g_free (block[y]);
|
||||||
|
|
||||||
|
g_free (block);
|
||||||
|
g_free (top_row);
|
||||||
|
g_free (bot_row);
|
||||||
|
|
||||||
|
return num_samples;
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/* LIBGIMP - The GIMP Library
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GIMP_ADAPTIVE_SUPERSAMPLE_H__
|
||||||
|
#define __GIMP_ADAPTIVE_SUPERSAMPLE_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/* For information look into the C source or the html documentation */
|
||||||
|
|
||||||
|
|
||||||
|
/* adaptive supersampling function taken from LibGCK */
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (* GimpRenderFunc) (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
GimpRGB *color,
|
||||||
|
gpointer data);
|
||||||
|
typedef void (* GimpPutPixelFunc) (gint x,
|
||||||
|
gint y,
|
||||||
|
GimpRGB *color,
|
||||||
|
gpointer data);
|
||||||
|
typedef void (* GimpProgressFunc) (gint min,
|
||||||
|
gint max,
|
||||||
|
gint current,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
|
|
||||||
|
gulong gimp_adaptive_supersample_area (gint x1,
|
||||||
|
gint y1,
|
||||||
|
gint x2,
|
||||||
|
gint y2,
|
||||||
|
gint max_depth,
|
||||||
|
gdouble threshold,
|
||||||
|
GimpRenderFunc render_func,
|
||||||
|
gpointer render_data,
|
||||||
|
GimpPutPixelFunc put_pixel_func,
|
||||||
|
gpointer put_pixel_data,
|
||||||
|
GimpProgressFunc progress_func,
|
||||||
|
gpointer progress_data);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* __GIMP_ADAPTIVE_SUPERSAMPLE_H__ */
|
|
@ -0,0 +1,222 @@
|
||||||
|
/* LIBGIMP - The GIMP Library
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "gimpcolor.h"
|
||||||
|
#include "gimpbilinear.h"
|
||||||
|
#include "gimpmath.h"
|
||||||
|
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
gimp_bilinear (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
gdouble *values)
|
||||||
|
{
|
||||||
|
gdouble xx, yy;
|
||||||
|
gdouble m0, m1;
|
||||||
|
|
||||||
|
g_assert (values != NULL);
|
||||||
|
|
||||||
|
xx = fmod (x, 1.0);
|
||||||
|
yy = fmod (y, 1.0);
|
||||||
|
|
||||||
|
if (x < 0.0)
|
||||||
|
x += 1.0;
|
||||||
|
if (y < 0.0)
|
||||||
|
y += 1.0;
|
||||||
|
|
||||||
|
m0 = (1.0 - xx) * values[0] + xx * values[1];
|
||||||
|
m1 = (1.0 - xx) * values[2] + xx * values[3];
|
||||||
|
|
||||||
|
return (1.0 - yy) * m0 + yy * m1;
|
||||||
|
}
|
||||||
|
|
||||||
|
guchar
|
||||||
|
gimp_bilinear_8 (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
guchar *values)
|
||||||
|
{
|
||||||
|
gdouble xx, yy;
|
||||||
|
gdouble m0, m1;
|
||||||
|
|
||||||
|
g_assert (values != NULL);
|
||||||
|
|
||||||
|
xx = fmod (x, 1.0);
|
||||||
|
yy = fmod (y, 1.0);
|
||||||
|
|
||||||
|
if (x < 0.0)
|
||||||
|
x += 1.0;
|
||||||
|
if (y < 0.0)
|
||||||
|
y += 1.0;
|
||||||
|
|
||||||
|
m0 = (1.0 - xx) * values[0] + xx * values[1];
|
||||||
|
m1 = (1.0 - xx) * values[2] + xx * values[3];
|
||||||
|
|
||||||
|
return (guchar) ((1.0 - yy) * m0 + yy * m1);
|
||||||
|
}
|
||||||
|
|
||||||
|
guint16
|
||||||
|
gimp_bilinear_16 (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
guint16 *values)
|
||||||
|
{
|
||||||
|
gdouble xx, yy;
|
||||||
|
gdouble m0, m1;
|
||||||
|
|
||||||
|
g_assert (values != NULL);
|
||||||
|
|
||||||
|
xx = fmod (x, 1.0);
|
||||||
|
yy = fmod (y, 1.0);
|
||||||
|
|
||||||
|
if (x < 0.0)
|
||||||
|
x += 1.0;
|
||||||
|
if (y < 0.0)
|
||||||
|
y += 1.0;
|
||||||
|
|
||||||
|
m0 = (1.0 - xx) * values[0] + xx * values[1];
|
||||||
|
m1 = (1.0 - xx) * values[2] + xx * values[3];
|
||||||
|
|
||||||
|
return (guint16) ((1.0 - yy) * m0 + yy * m1);
|
||||||
|
}
|
||||||
|
|
||||||
|
guint32
|
||||||
|
gimp_bilinear_32 (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
guint32 *values)
|
||||||
|
{
|
||||||
|
gdouble xx, yy;
|
||||||
|
gdouble m0, m1;
|
||||||
|
|
||||||
|
g_assert (values != NULL);
|
||||||
|
|
||||||
|
xx = fmod (x, 1.0);
|
||||||
|
yy = fmod (y, 1.0);
|
||||||
|
|
||||||
|
if (x < 0.0)
|
||||||
|
x += 1.0;
|
||||||
|
if (y < 0.0)
|
||||||
|
y += 1.0;
|
||||||
|
|
||||||
|
m0 = (1.0 - xx) * values[0] + xx * values[1];
|
||||||
|
m1 = (1.0 - xx) * values[2] + xx * values[3];
|
||||||
|
|
||||||
|
return (guint32) ((1.0 - yy) * m0 + yy * m1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GimpRGB
|
||||||
|
gimp_bilinear_rgb (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
GimpRGB *values)
|
||||||
|
{
|
||||||
|
gdouble m0, m1;
|
||||||
|
gdouble ix, iy;
|
||||||
|
GimpRGB v;
|
||||||
|
|
||||||
|
g_assert (values != NULL);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
GimpRGB
|
||||||
|
gimp_bilinear_rgba (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
GimpRGB *values)
|
||||||
|
{
|
||||||
|
gdouble m0, m1;
|
||||||
|
gdouble ix, iy;
|
||||||
|
GimpRGB v;
|
||||||
|
|
||||||
|
g_assert (values != NULL);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* Alpha */
|
||||||
|
|
||||||
|
m0 = ix * values[0].a + x * values[1].a;
|
||||||
|
m1 = ix * values[2].a + x * values[3].a;
|
||||||
|
|
||||||
|
v.a = iy * m0 + y * m1;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* LIBGIMP - The GIMP Library
|
||||||
|
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GIMP_BILINEAR_H__
|
||||||
|
#define __GIMP_BILINEAR_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/* For information look into the C source or the html documentation */
|
||||||
|
|
||||||
|
|
||||||
|
/* bilinear interpolation functions taken from LibGCK */
|
||||||
|
|
||||||
|
|
||||||
|
gdouble gimp_bilinear (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
gdouble *values);
|
||||||
|
guchar gimp_bilinear_8 (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
guchar *values);
|
||||||
|
guint16 gimp_bilinear_16 (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
guint16 *values);
|
||||||
|
guint32 gimp_bilinear_32 (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
guint32 *values);
|
||||||
|
GimpRGB gimp_bilinear_rgb (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
GimpRGB *values);
|
||||||
|
GimpRGB gimp_bilinear_rgba (gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
GimpRGB *values);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* __GIMP_BILINEAR_H__ */
|
|
@ -240,7 +240,7 @@ get_image_color (gdouble u,
|
||||||
gdouble v,
|
gdouble v,
|
||||||
gint *inside)
|
gint *inside)
|
||||||
{
|
{
|
||||||
gint x1, y1, x2, y2;
|
gint x1, y1, x2, y2;
|
||||||
GimpRGB p[4];
|
GimpRGB p[4];
|
||||||
|
|
||||||
x1 = RINT (u);
|
x1 = RINT (u);
|
||||||
|
@ -267,7 +267,7 @@ 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 gck_bilinear_rgba (u, v, p);
|
return gimp_bilinear_rgba (u, v, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
gdouble
|
gdouble
|
||||||
|
@ -297,7 +297,7 @@ get_map_value (GimpPixelRgn *region,
|
||||||
p[2] = (gdouble) peek_map (region, x1, y2);
|
p[2] = (gdouble) peek_map (region, x1, y2);
|
||||||
p[3] = (gdouble) peek_map (region, x2, y2);
|
p[3] = (gdouble) peek_map (region, x2, y2);
|
||||||
|
|
||||||
return gck_bilinear (u, v, p);
|
return gimp_bilinear (u, v, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -187,9 +187,10 @@ init_compute (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
render (gdouble x,
|
render (gdouble x,
|
||||||
gdouble y,
|
gdouble y,
|
||||||
GimpRGB *col)
|
GimpRGB *col,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
GimpVector3 pos;
|
GimpVector3 pos;
|
||||||
|
|
||||||
|
@ -201,9 +202,10 @@ render (gdouble x,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
show_progress (gint min,
|
show_progress (gint min,
|
||||||
gint max,
|
gint max,
|
||||||
gint curr)
|
gint curr,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
gimp_progress_update ((gdouble) curr / (gdouble) max);
|
gimp_progress_update ((gdouble) curr / (gdouble) max);
|
||||||
}
|
}
|
||||||
|
@ -288,7 +290,7 @@ compute_image (void)
|
||||||
{
|
{
|
||||||
p = int_to_pos (xcount, ycount);
|
p = int_to_pos (xcount, ycount);
|
||||||
color = (* get_ray_color) (&p);
|
color = (* get_ray_color) (&p);
|
||||||
poke (xcount, ycount, &color);
|
poke (xcount, ycount, &color, NULL);
|
||||||
|
|
||||||
if ((progress_counter++ % width) == 0)
|
if ((progress_counter++ % width) == 0)
|
||||||
gimp_progress_update ((gdouble) progress_counter /
|
gimp_progress_update ((gdouble) progress_counter /
|
||||||
|
@ -298,13 +300,16 @@ compute_image (void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gck_adaptive_supersample_area (0, 0,
|
gimp_adaptive_supersample_area (0, 0,
|
||||||
width - 1, height - 1,
|
width - 1, height - 1,
|
||||||
max_depth,
|
max_depth,
|
||||||
mapvals.pixeltreshold,
|
mapvals.pixeltreshold,
|
||||||
render,
|
render,
|
||||||
poke,
|
NULL,
|
||||||
show_progress);
|
poke,
|
||||||
|
NULL,
|
||||||
|
show_progress,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the region */
|
/* Update the region */
|
||||||
|
|
|
@ -134,18 +134,16 @@ peek_cylinder_image (gint image,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
poke (gint x,
|
poke (gint x,
|
||||||
gint y,
|
gint y,
|
||||||
GimpRGB *color)
|
GimpRGB *color,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
static guchar data[4];
|
static guchar col[4];
|
||||||
|
|
||||||
data[0] = (guchar) (color->r * 255.0);
|
|
||||||
data[1] = (guchar) (color->g * 255.0);
|
|
||||||
data[2] = (guchar) (color->b * 255.0);
|
|
||||||
data[3] = (guchar) (color->a * 255.0);
|
|
||||||
|
|
||||||
gimp_pixel_rgn_set_pixel (&dest_region, data, x, y);
|
gimp_rgba_get_uchar (color, &col[0], &col[1], &col[2], &col[3]);
|
||||||
|
|
||||||
|
gimp_pixel_rgn_set_pixel (&dest_region, col, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
gint
|
gint
|
||||||
|
@ -223,7 +221,7 @@ get_image_color (gdouble u,
|
||||||
gdouble v,
|
gdouble v,
|
||||||
gint *inside)
|
gint *inside)
|
||||||
{
|
{
|
||||||
gint x1, y1, x2, y2;
|
gint x1, y1, x2, y2;
|
||||||
GimpRGB p[4];
|
GimpRGB p[4];
|
||||||
|
|
||||||
pos_to_int (u, v, &x1, &y1);
|
pos_to_int (u, v, &x1, &y1);
|
||||||
|
@ -246,7 +244,7 @@ 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 gck_bilinear_rgba (u * width, v * height, p);
|
return gimp_bilinear_rgba (u * width, v * height, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkbounds (x1, y1) == FALSE)
|
if (checkbounds (x1, y1) == FALSE)
|
||||||
|
@ -273,7 +271,7 @@ 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 gck_bilinear_rgba (u * width, v * height, p);
|
return gimp_bilinear_rgba (u * width, v * height, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
GimpRGB
|
GimpRGB
|
||||||
|
@ -281,7 +279,8 @@ get_box_image_color (gint image,
|
||||||
gdouble u,
|
gdouble u,
|
||||||
gdouble v)
|
gdouble v)
|
||||||
{
|
{
|
||||||
gint w,h, x1, y1, x2, y2;
|
gint w, h;
|
||||||
|
gint x1, y1, x2, y2;
|
||||||
GimpRGB p[4];
|
GimpRGB p[4];
|
||||||
|
|
||||||
w = box_drawables[image]->width;
|
w = box_drawables[image]->width;
|
||||||
|
@ -304,7 +303,7 @@ 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 gck_bilinear_rgba (u * w, v * h, p);
|
return gimp_bilinear_rgba (u * w, v * h, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
GimpRGB
|
GimpRGB
|
||||||
|
@ -312,7 +311,8 @@ get_cylinder_image_color (gint image,
|
||||||
gdouble u,
|
gdouble u,
|
||||||
gdouble v)
|
gdouble v)
|
||||||
{
|
{
|
||||||
gint w,h, x1, y1, x2, y2;
|
gint w, h;
|
||||||
|
gint x1, y1, x2, y2;
|
||||||
GimpRGB p[4];
|
GimpRGB p[4];
|
||||||
|
|
||||||
w = cylinder_drawables[image]->width;
|
w = cylinder_drawables[image]->width;
|
||||||
|
@ -335,7 +335,7 @@ 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 gck_bilinear_rgba (u * w, v * h, p);
|
return gimp_bilinear_rgba (u * w, v * h, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************/
|
/****************************************/
|
||||||
|
|
|
@ -40,7 +40,8 @@ extern GimpRGB peek (gint x,
|
||||||
gint y);
|
gint y);
|
||||||
extern void poke (gint x,
|
extern void poke (gint x,
|
||||||
gint y,
|
gint y,
|
||||||
GimpRGB *color);
|
GimpRGB *color,
|
||||||
|
gpointer data);
|
||||||
extern GimpVector3 int_to_pos (gint x,
|
extern GimpVector3 int_to_pos (gint x,
|
||||||
gint y);
|
gint y);
|
||||||
extern void pos_to_int (gdouble x,
|
extern void pos_to_int (gdouble x,
|
||||||
|
@ -48,14 +49,14 @@ extern void pos_to_int (gdouble x,
|
||||||
gint *scr_x,
|
gint *scr_x,
|
||||||
gint *scr_y);
|
gint *scr_y);
|
||||||
|
|
||||||
extern GimpRGB get_image_color (gdouble u,
|
extern GimpRGB get_image_color (gdouble u,
|
||||||
gdouble v,
|
gdouble v,
|
||||||
gint *inside);
|
gint *inside);
|
||||||
extern GimpRGB get_box_image_color (gint image,
|
extern GimpRGB get_box_image_color (gint image,
|
||||||
gdouble u,
|
gdouble u,
|
||||||
gdouble v);
|
gdouble v);
|
||||||
extern GimpRGB get_cylinder_image_color (gint image,
|
extern GimpRGB get_cylinder_image_color (gint image,
|
||||||
gdouble u,
|
gdouble u,
|
||||||
gdouble v);
|
gdouble v);
|
||||||
|
|
||||||
#endif /* __MAPOBJECT_IMAGE_H__ */
|
#endif /* __MAPOBJECT_IMAGE_H__ */
|
||||||
|
|
|
@ -56,12 +56,6 @@ typedef struct
|
||||||
GckDitherType dithermethod;
|
GckDitherType dithermethod;
|
||||||
} GckVisualInfo;
|
} GckVisualInfo;
|
||||||
|
|
||||||
typedef void (* GckRenderFunction) (gdouble, gdouble, GimpRGB *);
|
|
||||||
typedef void (* GckPutPixelFunction) (gint, gint, GimpRGB *);
|
|
||||||
typedef void (* GckProgressFunction) (gint, gint, gint);
|
|
||||||
typedef void (* GckColorUpdateFunction) (GimpRGB *);
|
|
||||||
|
|
||||||
|
|
||||||
GckVisualInfo *gck_visualinfo_new (void);
|
GckVisualInfo *gck_visualinfo_new (void);
|
||||||
void gck_visualinfo_destroy (GckVisualInfo *visinfo);
|
void gck_visualinfo_destroy (GckVisualInfo *visinfo);
|
||||||
|
|
||||||
|
@ -80,27 +74,6 @@ void gck_gc_set_foreground (GckVisualInfo *visinfo,GdkGC *gc,
|
||||||
void gck_gc_set_background (GckVisualInfo *visinfo,GdkGC *gc,
|
void gck_gc_set_background (GckVisualInfo *visinfo,GdkGC *gc,
|
||||||
guchar r, guchar g, guchar b);
|
guchar r, guchar g, guchar b);
|
||||||
|
|
||||||
/********************/
|
|
||||||
/* Color operations */
|
|
||||||
/********************/
|
|
||||||
|
|
||||||
double gck_bilinear (double x,double y, double *values);
|
|
||||||
guchar gck_bilinear_8 (double x,double y, guchar *values);
|
|
||||||
guint16 gck_bilinear_16 (double x,double y, guint16 *values);
|
|
||||||
guint32 gck_bilinear_32 (double x,double y, guint32 *values);
|
|
||||||
GimpRGB gck_bilinear_rgb (double x,double y, GimpRGB *values);
|
|
||||||
GimpRGB gck_bilinear_rgba (double x,double y, GimpRGB *values);
|
|
||||||
|
|
||||||
/* Supersampling */
|
|
||||||
/* ============= */
|
|
||||||
|
|
||||||
gulong gck_adaptive_supersample_area (int x1,int y1,int x2,int y2,
|
|
||||||
int max_depth,
|
|
||||||
double threshold,
|
|
||||||
GckRenderFunction render_func,
|
|
||||||
GckPutPixelFunction put_pixel_func,
|
|
||||||
GckProgressFunction progress_func);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,12 +42,6 @@
|
||||||
|
|
||||||
#define ROUND_TO_INT(val) ((val) + 0.5)
|
#define ROUND_TO_INT(val) ((val) + 0.5)
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
guchar ready;
|
|
||||||
GimpRGB color;
|
|
||||||
} _GckSampleType;
|
|
||||||
|
|
||||||
|
|
||||||
/* returns a static storage */
|
/* returns a static storage */
|
||||||
static GdkColor *gck_rgb_to_gdkcolor (GckVisualInfo *visinfo,
|
static GdkColor *gck_rgb_to_gdkcolor (GckVisualInfo *visinfo,
|
||||||
|
@ -1278,505 +1272,3 @@ gck_rgb_to_gdkcolor_r(GckVisualInfo * visinfo, guchar r, guchar g, guchar b)
|
||||||
|
|
||||||
return (color);
|
return (color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************/
|
|
||||||
/* Color operations */
|
|
||||||
/********************/
|
|
||||||
|
|
||||||
/******************************************/
|
|
||||||
/* Bilinear interpolation stuff (Quartic) */
|
|
||||||
/******************************************/
|
|
||||||
|
|
||||||
double gck_bilinear(double x, double y, double *values)
|
|
||||||
{
|
|
||||||
double xx, yy, m0, m1;
|
|
||||||
|
|
||||||
g_assert(values!=NULL);
|
|
||||||
|
|
||||||
xx = fmod(x, 1.0);
|
|
||||||
yy = fmod(y, 1.0);
|
|
||||||
|
|
||||||
if (x < 0.0)
|
|
||||||
x += 1.0;
|
|
||||||
if (y < 0.0)
|
|
||||||
y += 1.0;
|
|
||||||
|
|
||||||
m0 = (1.0 - xx) * values[0] + xx * values[1];
|
|
||||||
m1 = (1.0 - xx) * values[2] + xx * values[3];
|
|
||||||
|
|
||||||
return ((1.0 - yy) * m0 + yy * m1);
|
|
||||||
}
|
|
||||||
|
|
||||||
guchar gck_bilinear_8(double x, double y, guchar * values)
|
|
||||||
{
|
|
||||||
double xx, yy, m0, m1;
|
|
||||||
|
|
||||||
g_assert(values!=NULL);
|
|
||||||
|
|
||||||
xx = fmod(x, 1.0);
|
|
||||||
yy = fmod(y, 1.0);
|
|
||||||
|
|
||||||
if (x < 0.0)
|
|
||||||
x += 1.0;
|
|
||||||
if (y < 0.0)
|
|
||||||
y += 1.0;
|
|
||||||
|
|
||||||
m0 = (1.0 - xx) * values[0] + xx * values[1];
|
|
||||||
m1 = (1.0 - xx) * values[2] + xx * values[3];
|
|
||||||
|
|
||||||
return ((guchar) ((1.0 - yy) * m0 + yy * m1));
|
|
||||||
}
|
|
||||||
|
|
||||||
guint16 gck_bilinear_16(double x, double y, guint16 * values)
|
|
||||||
{
|
|
||||||
double xx, yy, m0, m1;
|
|
||||||
|
|
||||||
g_assert(values!=NULL);
|
|
||||||
|
|
||||||
xx = fmod(x, 1.0);
|
|
||||||
yy = fmod(y, 1.0);
|
|
||||||
|
|
||||||
if (x < 0.0)
|
|
||||||
x += 1.0;
|
|
||||||
if (y < 0.0)
|
|
||||||
y += 1.0;
|
|
||||||
|
|
||||||
m0 = (1.0 - xx) * values[0] + xx * values[1];
|
|
||||||
m1 = (1.0 - xx) * values[2] + xx * values[3];
|
|
||||||
|
|
||||||
return ((guint16) ((1.0 - yy) * m0 + yy * m1));
|
|
||||||
}
|
|
||||||
|
|
||||||
guint32 gck_bilinear_32(double x, double y, guint32 * values)
|
|
||||||
{
|
|
||||||
double xx, yy, m0, m1;
|
|
||||||
|
|
||||||
g_assert(values!=NULL);
|
|
||||||
|
|
||||||
xx = fmod(x, 1.0);
|
|
||||||
yy = fmod(y, 1.0);
|
|
||||||
|
|
||||||
if (x < 0.0)
|
|
||||||
x += 1.0;
|
|
||||||
if (y < 0.0)
|
|
||||||
y += 1.0;
|
|
||||||
|
|
||||||
m0 = (1.0 - xx) * values[0] + xx * values[1];
|
|
||||||
m1 = (1.0 - xx) * values[2] + xx * values[3];
|
|
||||||
|
|
||||||
return ((guint32) ((1.0 - yy) * m0 + yy * m1));
|
|
||||||
}
|
|
||||||
|
|
||||||
GimpRGB gck_bilinear_rgb(double x, double y, GimpRGB *values)
|
|
||||||
{
|
|
||||||
double m0, m1;
|
|
||||||
double ix, iy;
|
|
||||||
GimpRGB v;
|
|
||||||
|
|
||||||
g_assert(values!=NULL);
|
|
||||||
|
|
||||||
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);
|
|
||||||
} /* bilinear */
|
|
||||||
|
|
||||||
GimpRGB gck_bilinear_rgba(double x, double y, GimpRGB *values)
|
|
||||||
{
|
|
||||||
double m0, m1;
|
|
||||||
double ix, iy;
|
|
||||||
GimpRGB v;
|
|
||||||
|
|
||||||
g_assert(values!=NULL);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* Alpha */
|
|
||||||
/* ===== */
|
|
||||||
|
|
||||||
m0 = ix * values[0].a + x * values[1].a;
|
|
||||||
m1 = ix * values[2].a + x * values[3].a;
|
|
||||||
|
|
||||||
v.a = iy * m0 + y * m1;
|
|
||||||
|
|
||||||
return (v);
|
|
||||||
} /* bilinear */
|
|
||||||
|
|
||||||
/*********************************************************************/
|
|
||||||
/* Sumpersampling code (Quartic) */
|
|
||||||
/* This code is *largely* based on the sources for POV-Ray 3.0. I am */
|
|
||||||
/* grateful to the POV-Team for such a great program and for making */
|
|
||||||
/* their sources available. All comments / bug reports / */
|
|
||||||
/* etc. regarding this code should be addressed to me, not to the */
|
|
||||||
/* POV-Ray team. Any bugs are my responsibility, not theirs. */
|
|
||||||
/*********************************************************************/
|
|
||||||
|
|
||||||
gulong gck_render_sub_pixel(int max_depth, int depth, _GckSampleType ** block,
|
|
||||||
int x, int y, int x1, int y1, int x3, int y3, double threshold,
|
|
||||||
int sub_pixel_size, GckRenderFunction render_func, GimpRGB * color)
|
|
||||||
{
|
|
||||||
int x2, y2, cnt; /* Coords of center sample */
|
|
||||||
double dx1, dy1; /* Delta to upper left sample */
|
|
||||||
double dx3, dy3, weight; /* Delta to lower right sample */
|
|
||||||
GimpRGB c[4],tmpcol;
|
|
||||||
unsigned long num_samples = 0;
|
|
||||||
|
|
||||||
/* Get offsets for corners */
|
|
||||||
/* ======================= */
|
|
||||||
|
|
||||||
dx1 = (double)(x1 - sub_pixel_size / 2) / sub_pixel_size;
|
|
||||||
dx3 = (double)(x3 - sub_pixel_size / 2) / sub_pixel_size;
|
|
||||||
|
|
||||||
dy1 = (double)(y1 - sub_pixel_size / 2) / sub_pixel_size;
|
|
||||||
dy3 = (double)(y3 - sub_pixel_size / 2) / sub_pixel_size;
|
|
||||||
|
|
||||||
/* Render upper left sample */
|
|
||||||
/* ======================== */
|
|
||||||
|
|
||||||
if (!block[y1][x1].ready)
|
|
||||||
{
|
|
||||||
num_samples++;
|
|
||||||
(*render_func) (x + dx1, y + dy1, &c[0]);
|
|
||||||
block[y1][x1].ready = 1;
|
|
||||||
block[y1][x1].color = c[0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c[0] = block[y1][x1].color;
|
|
||||||
|
|
||||||
/* Render upper right sample */
|
|
||||||
/* ========================= */
|
|
||||||
|
|
||||||
if (!block[y1][x3].ready)
|
|
||||||
{
|
|
||||||
num_samples++;
|
|
||||||
(*render_func) (x + dx3, y + dy1, &c[1]);
|
|
||||||
block[y1][x3].ready = 1;
|
|
||||||
block[y1][x3].color = c[1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c[1] = block[y1][x3].color;
|
|
||||||
|
|
||||||
/* Render lower left sample */
|
|
||||||
/* ======================== */
|
|
||||||
|
|
||||||
if (!block[y3][x1].ready)
|
|
||||||
{
|
|
||||||
num_samples++;
|
|
||||||
(*render_func) (x + dx1, y + dy3, &c[2]);
|
|
||||||
block[y3][x1].ready = 1;
|
|
||||||
block[y3][x1].color = c[2];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c[2] = block[y3][x1].color;
|
|
||||||
|
|
||||||
/* Render lower right sample */
|
|
||||||
/* ========================= */
|
|
||||||
|
|
||||||
if (!block[y3][x3].ready)
|
|
||||||
{
|
|
||||||
num_samples++;
|
|
||||||
(*render_func) (x + dx3, y + dy3, &c[3]);
|
|
||||||
block[y3][x3].ready = 1;
|
|
||||||
block[y3][x3].color = c[3];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c[3] = block[y3][x3].color;
|
|
||||||
|
|
||||||
/* Check for supersampling */
|
|
||||||
/* ======================= */
|
|
||||||
|
|
||||||
if (depth <= 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))
|
|
||||||
{
|
|
||||||
/* Calc coordinates of center subsample */
|
|
||||||
/* ==================================== */
|
|
||||||
|
|
||||||
x2 = (x1 + x3) / 2;
|
|
||||||
y2 = (y1 + y3) / 2;
|
|
||||||
|
|
||||||
/* Render sub-blocks */
|
|
||||||
/* ================= */
|
|
||||||
|
|
||||||
num_samples += gck_render_sub_pixel(max_depth, depth + 1, block, x, y, x1, y1, x2, y2,
|
|
||||||
threshold, sub_pixel_size, render_func, &c[0]);
|
|
||||||
|
|
||||||
num_samples += gck_render_sub_pixel(max_depth, depth + 1, block, x, y, x2, y1, x3, y2,
|
|
||||||
threshold, sub_pixel_size, render_func, &c[1]);
|
|
||||||
|
|
||||||
num_samples += gck_render_sub_pixel(max_depth, depth + 1, block, x, y, x1, y2, x2, y3,
|
|
||||||
threshold, sub_pixel_size, render_func, &c[2]);
|
|
||||||
|
|
||||||
num_samples += gck_render_sub_pixel(max_depth, depth + 1, block, x, y, x2, y2, x3, y3,
|
|
||||||
threshold, sub_pixel_size, render_func, &c[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c[0].a==0.0 || c[1].a==0.0 || c[2].a==0.0 || c[3].a==0.0)
|
|
||||||
{
|
|
||||||
tmpcol.r=0.0;
|
|
||||||
tmpcol.g=0.0;
|
|
||||||
tmpcol.b=0.0;
|
|
||||||
weight=2.0;
|
|
||||||
|
|
||||||
for (cnt=0;cnt<4;cnt++)
|
|
||||||
{
|
|
||||||
if (c[cnt].a!=0.0)
|
|
||||||
{
|
|
||||||
tmpcol.r+=c[cnt].r;
|
|
||||||
tmpcol.g+=c[cnt].g;
|
|
||||||
tmpcol.b+=c[cnt].b;
|
|
||||||
weight/=2.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
color->r=weight*tmpcol.r;
|
|
||||||
color->g=weight*tmpcol.g;
|
|
||||||
color->b=weight*tmpcol.b;
|
|
||||||
}
|
|
||||||
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->a = 0.25 * (c[0].a + c[1].a + c[2].a + c[3].a);
|
|
||||||
|
|
||||||
return (num_samples);
|
|
||||||
} /* Render_Sub_Pixel */
|
|
||||||
|
|
||||||
gulong gck_adaptive_supersample_area(int x1, int y1, int x2, int y2, int max_depth,
|
|
||||||
double threshold,
|
|
||||||
GckRenderFunction render_func,
|
|
||||||
GckPutPixelFunction put_pixel_func,
|
|
||||||
GckProgressFunction progress_func)
|
|
||||||
{
|
|
||||||
int x, y, width; /* Counters, width of region */
|
|
||||||
int xt, xtt, yt; /* Temporary counters */
|
|
||||||
int sub_pixel_size; /* Numbe of samples per pixel (1D) */
|
|
||||||
size_t row_size; /* Memory needed for one row */
|
|
||||||
GimpRGB color; /* Rendered pixel's color */
|
|
||||||
_GckSampleType tmp_sample; /* For swapping samples */
|
|
||||||
_GckSampleType *top_row, *bot_row, *tmp_row; /* Sample rows */
|
|
||||||
_GckSampleType **block; /* Sample block matrix */
|
|
||||||
unsigned long num_samples;
|
|
||||||
|
|
||||||
/* Initialize color */
|
|
||||||
/* ================ */
|
|
||||||
|
|
||||||
color.r = color.b = color.g = color.a = 0.0;
|
|
||||||
|
|
||||||
/* Calculate sub-pixel size */
|
|
||||||
/* ======================== */
|
|
||||||
|
|
||||||
sub_pixel_size = 1 << max_depth;
|
|
||||||
|
|
||||||
/* Create row arrays */
|
|
||||||
/* ================= */
|
|
||||||
|
|
||||||
width = x2 - x1 + 1;
|
|
||||||
|
|
||||||
row_size = (sub_pixel_size * width + 1) * sizeof(_GckSampleType);
|
|
||||||
|
|
||||||
top_row = (_GckSampleType *) g_malloc(row_size);
|
|
||||||
bot_row = (_GckSampleType *) g_malloc(row_size);
|
|
||||||
|
|
||||||
for (x = 0; x < (sub_pixel_size * width + 1); x++)
|
|
||||||
{
|
|
||||||
top_row[x].ready = 0;
|
|
||||||
|
|
||||||
top_row[x].color.r = 0.0;
|
|
||||||
top_row[x].color.g = 0.0;
|
|
||||||
top_row[x].color.b = 0.0;
|
|
||||||
top_row[x].color.a = 0.0;
|
|
||||||
|
|
||||||
bot_row[x].ready = 0;
|
|
||||||
|
|
||||||
bot_row[x].color.r = 0.0;
|
|
||||||
bot_row[x].color.g = 0.0;
|
|
||||||
bot_row[x].color.b = 0.0;
|
|
||||||
bot_row[x].color.a = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate block matrix */
|
|
||||||
/* ===================== */
|
|
||||||
|
|
||||||
block = g_malloc((sub_pixel_size + 1) * sizeof(_GckSampleType *)); /* Rows */
|
|
||||||
|
|
||||||
for (y = 0; y < (sub_pixel_size + 1); y++)
|
|
||||||
block[y] = g_malloc((sub_pixel_size + 1) * sizeof(_GckSampleType));
|
|
||||||
|
|
||||||
for (y = 0; y < (sub_pixel_size + 1); y++)
|
|
||||||
for (x = 0; x < (sub_pixel_size + 1); x++)
|
|
||||||
{
|
|
||||||
block[y][x].ready = 0;
|
|
||||||
block[y][x].color.r = 0.0;
|
|
||||||
block[y][x].color.g = 0.0;
|
|
||||||
block[y][x].color.b = 0.0;
|
|
||||||
block[y][x].color.a = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Render region */
|
|
||||||
/* ============= */
|
|
||||||
|
|
||||||
num_samples = 0;
|
|
||||||
|
|
||||||
for (y = y1; y <= y2; y++)
|
|
||||||
{
|
|
||||||
/* Clear the bottom row */
|
|
||||||
/* ==================== */
|
|
||||||
|
|
||||||
for (xt = 0; xt < (sub_pixel_size * width + 1); xt++)
|
|
||||||
bot_row[xt].ready = 0;
|
|
||||||
|
|
||||||
/* Clear first column */
|
|
||||||
/* ================== */
|
|
||||||
|
|
||||||
for (yt = 0; yt < (sub_pixel_size + 1); yt++)
|
|
||||||
block[yt][0].ready = 0;
|
|
||||||
|
|
||||||
/* Render row */
|
|
||||||
/* ========== */
|
|
||||||
|
|
||||||
for (x = x1; x <= x2; x++)
|
|
||||||
{
|
|
||||||
/* Initialize block by clearing all but first row/column */
|
|
||||||
/* ===================================================== */
|
|
||||||
|
|
||||||
for (yt = 1; yt < (sub_pixel_size + 1); yt++)
|
|
||||||
for (xt = 1; xt < (sub_pixel_size + 1); xt++)
|
|
||||||
block[yt][xt].ready = 0;
|
|
||||||
|
|
||||||
/* Copy samples from top row to block */
|
|
||||||
/* ================================== */
|
|
||||||
|
|
||||||
for (xtt = 0, xt = (x - x1) * sub_pixel_size; xtt < (sub_pixel_size + 1); xtt++, xt++)
|
|
||||||
block[0][xtt] = top_row[xt];
|
|
||||||
|
|
||||||
/* Render pixel on (x, y) */
|
|
||||||
/* ====================== */
|
|
||||||
|
|
||||||
num_samples += gck_render_sub_pixel(max_depth, 1, block, x, y, 0, 0, sub_pixel_size,
|
|
||||||
sub_pixel_size, threshold, sub_pixel_size, render_func, &color);
|
|
||||||
|
|
||||||
(*put_pixel_func) (x, y, &color);
|
|
||||||
|
|
||||||
/* Copy block information to rows */
|
|
||||||
/* ============================== */
|
|
||||||
|
|
||||||
top_row[(x - x1 + 1) * sub_pixel_size] = block[0][sub_pixel_size];
|
|
||||||
|
|
||||||
for (xtt = 0, xt = (x - x1) * sub_pixel_size; xtt < (sub_pixel_size + 1); xtt++, xt++)
|
|
||||||
bot_row[xt] = block[sub_pixel_size][xtt];
|
|
||||||
|
|
||||||
/* Swap first and last columns */
|
|
||||||
/* =========================== */
|
|
||||||
|
|
||||||
for (yt = 0; yt < (sub_pixel_size + 1); yt++)
|
|
||||||
{
|
|
||||||
tmp_sample = block[yt][0];
|
|
||||||
block[yt][0] = block[yt][sub_pixel_size];
|
|
||||||
block[yt][sub_pixel_size] = tmp_sample;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Swap rows */
|
|
||||||
/* ========= */
|
|
||||||
|
|
||||||
tmp_row = top_row;
|
|
||||||
top_row = bot_row;
|
|
||||||
bot_row = tmp_row;
|
|
||||||
|
|
||||||
/* Call progress display function (if any) */
|
|
||||||
/* ======================================= */
|
|
||||||
|
|
||||||
if (progress_func != NULL)
|
|
||||||
(*progress_func) (y1, y2, y);
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
/* Free memory */
|
|
||||||
/* =========== */
|
|
||||||
|
|
||||||
for (y = 0; y < (sub_pixel_size + 1); y++)
|
|
||||||
g_free(block[y]);
|
|
||||||
|
|
||||||
g_free(block);
|
|
||||||
g_free(top_row);
|
|
||||||
g_free(bot_row);
|
|
||||||
|
|
||||||
return (num_samples);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue