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>
|
||||
|
||||
* app/gdisplay.c
|
||||
|
|
|
@ -167,10 +167,10 @@ typedef void (* TileValidateProc) (TileManager *tm,
|
|||
|
||||
typedef void (* ToolOptionsResetFunc) (void);
|
||||
|
||||
typedef void (* GimpProgressFunc) (gint ymin,
|
||||
gint ymax,
|
||||
gint curr_y,
|
||||
gpointer progress_data);
|
||||
typedef void (* GimpProgressFunc) (gint min,
|
||||
gint max,
|
||||
gint current,
|
||||
gpointer data);
|
||||
|
||||
typedef void (* ImageMapApplyFunc) (PixelRegion *srcPR,
|
||||
PixelRegion *destPR,
|
||||
|
|
106
app/asupsample.c
106
app/asupsample.c
|
@ -20,7 +20,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
/* 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 /
|
||||
|
@ -47,14 +46,14 @@ typedef struct
|
|||
{
|
||||
gchar ready;
|
||||
GimpRGB color;
|
||||
} sample_t;
|
||||
} GimpSampleType;
|
||||
|
||||
|
||||
/***** Local functions *****/
|
||||
|
||||
static gulong render_sub_pixel (gint max_depth,
|
||||
static gulong gimp_render_sub_pixel (gint max_depth,
|
||||
gint depth,
|
||||
sample_t **block,
|
||||
GimpSampleType **block,
|
||||
gint x,
|
||||
gint y,
|
||||
gint x1,
|
||||
|
@ -63,23 +62,23 @@ static gulong render_sub_pixel (gint max_depth,
|
|||
gint y3,
|
||||
gdouble threshold,
|
||||
gint sub_pixel_size,
|
||||
render_func_t render_func,
|
||||
GimpRGB *color,
|
||||
GimpRenderFunc render_func,
|
||||
gpointer render_data);
|
||||
|
||||
|
||||
/***** Functions *****/
|
||||
|
||||
gulong
|
||||
adaptive_supersample_area (gint x1,
|
||||
gimp_adaptive_supersample_area (gint x1,
|
||||
gint y1,
|
||||
gint x2,
|
||||
gint y2,
|
||||
gint max_depth,
|
||||
gdouble threshold,
|
||||
render_func_t render_func,
|
||||
GimpRenderFunc render_func,
|
||||
gpointer render_data,
|
||||
put_pixel_func_t put_pixel_func,
|
||||
GimpPutPixelFunc put_pixel_func,
|
||||
gpointer put_pixel_data,
|
||||
GimpProgressFunc progress_func,
|
||||
gpointer progress_data)
|
||||
|
@ -87,11 +86,10 @@ adaptive_supersample_area (gint x1,
|
|||
gint x, y, width; /* Counters, width of region */
|
||||
gint xt, xtt, yt; /* Temporary counters */
|
||||
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 */
|
||||
sample_t tmp_sample; /* For swapping samples */
|
||||
sample_t *top_row, *bot_row, *tmp_row; /* Sample rows */
|
||||
sample_t **block; /* Sample block matrix */
|
||||
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 */
|
||||
|
@ -100,39 +98,37 @@ adaptive_supersample_area (gint x1,
|
|||
|
||||
/* Calculate sub-pixel size */
|
||||
|
||||
sub_pixel_size = 1 << max_depth; /* 2**max_depth */
|
||||
sub_pixel_size = 1 << max_depth;
|
||||
|
||||
/* Create row arrays */
|
||||
|
||||
width = x2 - x1 + 1;
|
||||
|
||||
row_size = (sub_pixel_size * width + 1) * sizeof (sample_t);
|
||||
|
||||
top_row = g_malloc (row_size);
|
||||
bot_row = g_malloc (row_size);
|
||||
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 = 0;
|
||||
top_row[x].ready = FALSE;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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++)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -147,7 +143,7 @@ adaptive_supersample_area (gint x1,
|
|||
/* Clear the bottom row */
|
||||
|
||||
for (xt = 0; xt < (sub_pixel_size * width + 1); xt++)
|
||||
bot_row[xt].ready = 0;
|
||||
bot_row[xt].ready = FALSE;
|
||||
|
||||
/* Clear first column */
|
||||
|
||||
|
@ -162,7 +158,7 @@ adaptive_supersample_area (gint x1,
|
|||
|
||||
for (yt = 1; yt < (sub_pixel_size + 1); yt++)
|
||||
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 */
|
||||
|
||||
|
@ -173,14 +169,14 @@ adaptive_supersample_area (gint x1,
|
|||
|
||||
/* 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,
|
||||
threshold, sub_pixel_size,
|
||||
render_func, &color,
|
||||
render_data);
|
||||
&color,
|
||||
render_func, render_data);
|
||||
|
||||
if (put_pixel_func)
|
||||
(* put_pixel_func) (x, y, color, put_pixel_data);
|
||||
(* put_pixel_func) (x, y, &color, put_pixel_data);
|
||||
|
||||
/* Copy block information to rows */
|
||||
|
||||
|
@ -226,9 +222,9 @@ adaptive_supersample_area (gint x1,
|
|||
}
|
||||
|
||||
static gulong
|
||||
render_sub_pixel (gint max_depth,
|
||||
gimp_render_sub_pixel (gint max_depth,
|
||||
gint depth,
|
||||
sample_t **block,
|
||||
GimpSampleType **block,
|
||||
gint x,
|
||||
gint y,
|
||||
gint x1,
|
||||
|
@ -237,8 +233,8 @@ render_sub_pixel (gint max_depth,
|
|||
gint y3,
|
||||
gdouble threshold,
|
||||
gint sub_pixel_size,
|
||||
render_func_t render_func,
|
||||
GimpRGB *color,
|
||||
GimpRenderFunc render_func,
|
||||
gpointer render_data)
|
||||
{
|
||||
gint x2, y2; /* Coords of center sample */
|
||||
|
@ -262,9 +258,11 @@ render_sub_pixel (gint max_depth,
|
|||
if (!block[y1][x1].ready)
|
||||
{
|
||||
num_samples++;
|
||||
|
||||
if (render_func)
|
||||
(* render_func) (x + dx1, y + dy1, &c1, render_data);
|
||||
|
||||
block[y1][x1].ready = 1;
|
||||
block[y1][x1].ready = TRUE;
|
||||
block[y1][x1].color = c1;
|
||||
}
|
||||
else
|
||||
|
@ -277,9 +275,11 @@ render_sub_pixel (gint max_depth,
|
|||
if (! block[y1][x3].ready)
|
||||
{
|
||||
num_samples++;
|
||||
|
||||
if (render_func)
|
||||
(* render_func) (x + dx3, y + dy1, &c2, render_data);
|
||||
|
||||
block[y1][x3].ready = 1;
|
||||
block[y1][x3].ready = TRUE;
|
||||
block[y1][x3].color = c2;
|
||||
}
|
||||
else
|
||||
|
@ -292,9 +292,11 @@ render_sub_pixel (gint max_depth,
|
|||
if (! block[y3][x1].ready)
|
||||
{
|
||||
num_samples++;
|
||||
|
||||
if (render_func)
|
||||
(* render_func) (x + dx1, y + dy3, &c3, render_data);
|
||||
|
||||
block[y3][x1].ready = 1;
|
||||
block[y3][x1].ready = TRUE;
|
||||
block[y3][x1].color = c3;
|
||||
}
|
||||
else
|
||||
|
@ -307,9 +309,11 @@ render_sub_pixel (gint max_depth,
|
|||
if (! block[y3][x3].ready)
|
||||
{
|
||||
num_samples++;
|
||||
|
||||
if (render_func)
|
||||
(* render_func) (x + dx3, y + dy3, &c4, render_data);
|
||||
|
||||
block[y3][x3].ready = 1;
|
||||
block[y3][x3].ready = TRUE;
|
||||
block[y3][x3].color = c4;
|
||||
}
|
||||
else
|
||||
|
@ -337,21 +341,29 @@ render_sub_pixel (gint max_depth,
|
|||
|
||||
/* Render sub-blocks */
|
||||
|
||||
num_samples += render_sub_pixel (max_depth, depth + 1, block, x, y, x1, y1, x2, y2,
|
||||
threshold, sub_pixel_size, render_func, &c1,
|
||||
render_data);
|
||||
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
|
||||
x, y, x1, y1, x2, y2,
|
||||
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,
|
||||
threshold, sub_pixel_size, render_func, &c2,
|
||||
render_data);
|
||||
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
|
||||
x, y, x2, y1, x3, y2,
|
||||
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,
|
||||
threshold, sub_pixel_size, render_func, &c3,
|
||||
render_data);
|
||||
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
|
||||
x, y, x1, y2, x2, y3,
|
||||
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,
|
||||
threshold, sub_pixel_size, render_func, &c4,
|
||||
render_data);
|
||||
num_samples += gimp_render_sub_pixel (max_depth, depth + 1, block,
|
||||
x, y, x2, y2, x3, y3,
|
||||
threshold, sub_pixel_size,
|
||||
&c4,
|
||||
render_func, render_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,25 +24,25 @@
|
|||
#define __ASUPSAMPLE_H__
|
||||
|
||||
|
||||
typedef void (* render_func_t) (gdouble x,
|
||||
typedef void (* GimpRenderFunc) (gdouble x,
|
||||
gdouble y,
|
||||
GimpRGB *color,
|
||||
gpointer render_data);
|
||||
typedef void (* put_pixel_func_t) (gint x,
|
||||
gpointer data);
|
||||
typedef void (* GimpPutPixelFunc) (gint x,
|
||||
gint y,
|
||||
GimpRGB color,
|
||||
gpointer put_pixel_data);
|
||||
GimpRGB *color,
|
||||
gpointer data);
|
||||
|
||||
|
||||
gulong adaptive_supersample_area (gint x1,
|
||||
gulong gimp_adaptive_supersample_area (gint x1,
|
||||
gint y1,
|
||||
gint x2,
|
||||
gint y2,
|
||||
gint max_depth,
|
||||
gdouble threshold,
|
||||
render_func_t render_func,
|
||||
GimpRenderFunc render_func,
|
||||
gpointer render_data,
|
||||
put_pixel_func_t put_pixel_func,
|
||||
GimpPutPixelFunc put_pixel_func,
|
||||
gpointer put_pixel_data,
|
||||
GimpProgressFunc progress_func,
|
||||
gpointer progress_data);
|
||||
|
|
|
@ -245,7 +245,7 @@ static void gradient_render_pixel (gdouble x,
|
|||
gpointer render_data);
|
||||
static void gradient_put_pixel (gint x,
|
||||
gint y,
|
||||
GimpRGB color,
|
||||
GimpRGB *color,
|
||||
gpointer put_pixel_data);
|
||||
|
||||
static void gradient_fill_region (GImage *gimage,
|
||||
|
@ -1403,7 +1403,7 @@ gradient_render_pixel (double x,
|
|||
static void
|
||||
gradient_put_pixel (int x,
|
||||
int y,
|
||||
GimpRGB color,
|
||||
GimpRGB *color,
|
||||
void *put_pixel_data)
|
||||
{
|
||||
PutPixelData *ppd;
|
||||
|
@ -1417,17 +1417,17 @@ gradient_put_pixel (int x,
|
|||
|
||||
if (ppd->bytes >= 3)
|
||||
{
|
||||
*data++ = color.r * 255.0;
|
||||
*data++ = color.g * 255.0;
|
||||
*data++ = color.b * 255.0;
|
||||
*data++ = color.a * 255.0;
|
||||
*data++ = color->r * 255.0;
|
||||
*data++ = color->g * 255.0;
|
||||
*data++ = color->b * 255.0;
|
||||
*data++ = color->a * 255.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert to grayscale */
|
||||
|
||||
*data++ = 255.0 * INTENSITY (color.r, color.g, color.b);
|
||||
*data++ = color.a * 255.0;
|
||||
*data++ = 255.0 * INTENSITY (color->r, color->g, color->b);
|
||||
*data++ = color->a * 255.0;
|
||||
}
|
||||
|
||||
/* Paint whole row if we are on the rightmost pixel */
|
||||
|
@ -1588,7 +1588,7 @@ gradient_fill_region (GImage *gimage,
|
|||
|
||||
/* Render! */
|
||||
|
||||
adaptive_supersample_area (0, 0, (width - 1), (height - 1),
|
||||
gimp_adaptive_supersample_area (0, 0, (width - 1), (height - 1),
|
||||
max_depth, threshold,
|
||||
gradient_render_pixel, &rbd,
|
||||
gradient_put_pixel, &ppd,
|
||||
|
|
|
@ -180,10 +180,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
|||
|
||||
/* set up the scrollbar observers */
|
||||
gtk_signal_connect (GTK_OBJECT (gdisp->hsbdata), "value_changed",
|
||||
(GtkSignalFunc) scrollbar_horz_update,
|
||||
GTK_SIGNAL_FUNC(scrollbar_horz_update),
|
||||
gdisp);
|
||||
gtk_signal_connect (GTK_OBJECT (gdisp->vsbdata), "value_changed",
|
||||
(GtkSignalFunc) scrollbar_vert_update,
|
||||
GTK_SIGNAL_FUNC (scrollbar_vert_update),
|
||||
gdisp);
|
||||
|
||||
/* setup scale properly */
|
||||
|
@ -247,12 +247,12 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
|||
gtk_grab_add (canvas);
|
||||
|
||||
/* This is a hack to prevent other stuff being run in the middle of
|
||||
a tool operation (like changing image types.... brrrr). We just
|
||||
block all the keypress event. A better solution is to implement
|
||||
some sort of locking for images.
|
||||
Note that this is dependent on specific GTK behavior, and isn't
|
||||
guaranteed to work in future versions of GTK.
|
||||
-Yosh
|
||||
* a tool operation (like changing image types.... brrrr). We just
|
||||
* block all the keypress event. A better solution is to implement
|
||||
* some sort of locking for images.
|
||||
* Note that this is dependent on specific GTK behavior, and isn't
|
||||
* guaranteed to work in future versions of GTK.
|
||||
* -Yosh
|
||||
*/
|
||||
if (key_signal_id == 0)
|
||||
key_signal_id = gtk_signal_connect (GTK_OBJECT (canvas),
|
||||
|
@ -363,8 +363,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
|||
*
|
||||
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
||||
*/
|
||||
if (gimp_busy &&
|
||||
!(active_tool->type == FUZZY_SELECT &&
|
||||
if (gimp_busy && ! (active_tool->type == FUZZY_SELECT &&
|
||||
active_tool->state == ACTIVE))
|
||||
return TRUE;
|
||||
|
||||
|
@ -437,14 +436,13 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
|||
*
|
||||
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
||||
*/
|
||||
if (gimp_busy &&
|
||||
!(active_tool->type == FUZZY_SELECT &&
|
||||
if (gimp_busy && ! (active_tool->type == FUZZY_SELECT &&
|
||||
active_tool->state == ACTIVE))
|
||||
return TRUE;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
|
||||
|
|
|
@ -180,10 +180,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
|||
|
||||
/* set up the scrollbar observers */
|
||||
gtk_signal_connect (GTK_OBJECT (gdisp->hsbdata), "value_changed",
|
||||
(GtkSignalFunc) scrollbar_horz_update,
|
||||
GTK_SIGNAL_FUNC(scrollbar_horz_update),
|
||||
gdisp);
|
||||
gtk_signal_connect (GTK_OBJECT (gdisp->vsbdata), "value_changed",
|
||||
(GtkSignalFunc) scrollbar_vert_update,
|
||||
GTK_SIGNAL_FUNC (scrollbar_vert_update),
|
||||
gdisp);
|
||||
|
||||
/* setup scale properly */
|
||||
|
@ -247,12 +247,12 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
|||
gtk_grab_add (canvas);
|
||||
|
||||
/* This is a hack to prevent other stuff being run in the middle of
|
||||
a tool operation (like changing image types.... brrrr). We just
|
||||
block all the keypress event. A better solution is to implement
|
||||
some sort of locking for images.
|
||||
Note that this is dependent on specific GTK behavior, and isn't
|
||||
guaranteed to work in future versions of GTK.
|
||||
-Yosh
|
||||
* a tool operation (like changing image types.... brrrr). We just
|
||||
* block all the keypress event. A better solution is to implement
|
||||
* some sort of locking for images.
|
||||
* Note that this is dependent on specific GTK behavior, and isn't
|
||||
* guaranteed to work in future versions of GTK.
|
||||
* -Yosh
|
||||
*/
|
||||
if (key_signal_id == 0)
|
||||
key_signal_id = gtk_signal_connect (GTK_OBJECT (canvas),
|
||||
|
@ -363,8 +363,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
|||
*
|
||||
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
||||
*/
|
||||
if (gimp_busy &&
|
||||
!(active_tool->type == FUZZY_SELECT &&
|
||||
if (gimp_busy && ! (active_tool->type == FUZZY_SELECT &&
|
||||
active_tool->state == ACTIVE))
|
||||
return TRUE;
|
||||
|
||||
|
@ -437,14 +436,13 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
|||
*
|
||||
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
||||
*/
|
||||
if (gimp_busy &&
|
||||
!(active_tool->type == FUZZY_SELECT &&
|
||||
if (gimp_busy && ! (active_tool->type == FUZZY_SELECT &&
|
||||
active_tool->state == ACTIVE))
|
||||
return TRUE;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
|
||||
|
|
|
@ -180,10 +180,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
|||
|
||||
/* set up the scrollbar observers */
|
||||
gtk_signal_connect (GTK_OBJECT (gdisp->hsbdata), "value_changed",
|
||||
(GtkSignalFunc) scrollbar_horz_update,
|
||||
GTK_SIGNAL_FUNC(scrollbar_horz_update),
|
||||
gdisp);
|
||||
gtk_signal_connect (GTK_OBJECT (gdisp->vsbdata), "value_changed",
|
||||
(GtkSignalFunc) scrollbar_vert_update,
|
||||
GTK_SIGNAL_FUNC (scrollbar_vert_update),
|
||||
gdisp);
|
||||
|
||||
/* setup scale properly */
|
||||
|
@ -247,12 +247,12 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
|||
gtk_grab_add (canvas);
|
||||
|
||||
/* This is a hack to prevent other stuff being run in the middle of
|
||||
a tool operation (like changing image types.... brrrr). We just
|
||||
block all the keypress event. A better solution is to implement
|
||||
some sort of locking for images.
|
||||
Note that this is dependent on specific GTK behavior, and isn't
|
||||
guaranteed to work in future versions of GTK.
|
||||
-Yosh
|
||||
* a tool operation (like changing image types.... brrrr). We just
|
||||
* block all the keypress event. A better solution is to implement
|
||||
* some sort of locking for images.
|
||||
* Note that this is dependent on specific GTK behavior, and isn't
|
||||
* guaranteed to work in future versions of GTK.
|
||||
* -Yosh
|
||||
*/
|
||||
if (key_signal_id == 0)
|
||||
key_signal_id = gtk_signal_connect (GTK_OBJECT (canvas),
|
||||
|
@ -363,8 +363,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
|||
*
|
||||
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
||||
*/
|
||||
if (gimp_busy &&
|
||||
!(active_tool->type == FUZZY_SELECT &&
|
||||
if (gimp_busy && ! (active_tool->type == FUZZY_SELECT &&
|
||||
active_tool->state == ACTIVE))
|
||||
return TRUE;
|
||||
|
||||
|
@ -437,14 +436,13 @@ gdisplay_canvas_events (GtkWidget *canvas,
|
|||
*
|
||||
* ugly: fuzzy_select sets busy cursors while ACTIVE.
|
||||
*/
|
||||
if (gimp_busy &&
|
||||
!(active_tool->type == FUZZY_SELECT &&
|
||||
if (gimp_busy && ! (active_tool->type == FUZZY_SELECT &&
|
||||
active_tool->state == ACTIVE))
|
||||
return TRUE;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
|
||||
|
|
|
@ -245,7 +245,7 @@ static void gradient_render_pixel (gdouble x,
|
|||
gpointer render_data);
|
||||
static void gradient_put_pixel (gint x,
|
||||
gint y,
|
||||
GimpRGB color,
|
||||
GimpRGB *color,
|
||||
gpointer put_pixel_data);
|
||||
|
||||
static void gradient_fill_region (GImage *gimage,
|
||||
|
@ -1403,7 +1403,7 @@ gradient_render_pixel (double x,
|
|||
static void
|
||||
gradient_put_pixel (int x,
|
||||
int y,
|
||||
GimpRGB color,
|
||||
GimpRGB *color,
|
||||
void *put_pixel_data)
|
||||
{
|
||||
PutPixelData *ppd;
|
||||
|
@ -1417,17 +1417,17 @@ gradient_put_pixel (int x,
|
|||
|
||||
if (ppd->bytes >= 3)
|
||||
{
|
||||
*data++ = color.r * 255.0;
|
||||
*data++ = color.g * 255.0;
|
||||
*data++ = color.b * 255.0;
|
||||
*data++ = color.a * 255.0;
|
||||
*data++ = color->r * 255.0;
|
||||
*data++ = color->g * 255.0;
|
||||
*data++ = color->b * 255.0;
|
||||
*data++ = color->a * 255.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert to grayscale */
|
||||
|
||||
*data++ = 255.0 * INTENSITY (color.r, color.g, color.b);
|
||||
*data++ = color.a * 255.0;
|
||||
*data++ = 255.0 * INTENSITY (color->r, color->g, color->b);
|
||||
*data++ = color->a * 255.0;
|
||||
}
|
||||
|
||||
/* Paint whole row if we are on the rightmost pixel */
|
||||
|
@ -1588,7 +1588,7 @@ gradient_fill_region (GImage *gimage,
|
|||
|
||||
/* Render! */
|
||||
|
||||
adaptive_supersample_area (0, 0, (width - 1), (height - 1),
|
||||
gimp_adaptive_supersample_area (0, 0, (width - 1), (height - 1),
|
||||
max_depth, threshold,
|
||||
gradient_render_pixel, &rbd,
|
||||
gradient_put_pixel, &ppd,
|
||||
|
|
|
@ -245,7 +245,7 @@ static void gradient_render_pixel (gdouble x,
|
|||
gpointer render_data);
|
||||
static void gradient_put_pixel (gint x,
|
||||
gint y,
|
||||
GimpRGB color,
|
||||
GimpRGB *color,
|
||||
gpointer put_pixel_data);
|
||||
|
||||
static void gradient_fill_region (GImage *gimage,
|
||||
|
@ -1403,7 +1403,7 @@ gradient_render_pixel (double x,
|
|||
static void
|
||||
gradient_put_pixel (int x,
|
||||
int y,
|
||||
GimpRGB color,
|
||||
GimpRGB *color,
|
||||
void *put_pixel_data)
|
||||
{
|
||||
PutPixelData *ppd;
|
||||
|
@ -1417,17 +1417,17 @@ gradient_put_pixel (int x,
|
|||
|
||||
if (ppd->bytes >= 3)
|
||||
{
|
||||
*data++ = color.r * 255.0;
|
||||
*data++ = color.g * 255.0;
|
||||
*data++ = color.b * 255.0;
|
||||
*data++ = color.a * 255.0;
|
||||
*data++ = color->r * 255.0;
|
||||
*data++ = color->g * 255.0;
|
||||
*data++ = color->b * 255.0;
|
||||
*data++ = color->a * 255.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert to grayscale */
|
||||
|
||||
*data++ = 255.0 * INTENSITY (color.r, color.g, color.b);
|
||||
*data++ = color.a * 255.0;
|
||||
*data++ = 255.0 * INTENSITY (color->r, color->g, color->b);
|
||||
*data++ = color->a * 255.0;
|
||||
}
|
||||
|
||||
/* Paint whole row if we are on the rightmost pixel */
|
||||
|
@ -1588,7 +1588,7 @@ gradient_fill_region (GImage *gimage,
|
|||
|
||||
/* Render! */
|
||||
|
||||
adaptive_supersample_area (0, 0, (width - 1), (height - 1),
|
||||
gimp_adaptive_supersample_area (0, 0, (width - 1), (height - 1),
|
||||
max_depth, threshold,
|
||||
gradient_render_pixel, &rbd,
|
||||
gradient_put_pixel, &ppd,
|
||||
|
|
|
@ -159,6 +159,10 @@ libgimp_la_SOURCES = \
|
|||
gimp.h \
|
||||
${PDB_WRAPPERS_C} \
|
||||
${PDB_WRAPPERS_H} \
|
||||
gimpadaptivesupersample.c \
|
||||
gimpadaptivesupersample.h \
|
||||
gimpbilinear.c \
|
||||
gimpbilinear.h \
|
||||
gimpcolor.c \
|
||||
gimpcolor.h \
|
||||
gimpcolorspace.c \
|
||||
|
@ -230,6 +234,8 @@ libgimpui_la_SOURCES = \
|
|||
gimpinclude_HEADERS = \
|
||||
gimp.h \
|
||||
${PDB_WRAPPERS_H} \
|
||||
gimpadaptivesupersample.h \
|
||||
gimpbilinear.h \
|
||||
gimpchainbutton.h \
|
||||
gimpchannel.h \
|
||||
gimpcolor.h \
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include <libgimp/gimpenums.h>
|
||||
#include <libgimp/gimptypes.h>
|
||||
|
||||
#include <libgimp/gimpadaptivesupersample.h>
|
||||
#include <libgimp/gimpbilinear.h>
|
||||
#include <libgimp/gimpchannel.h>
|
||||
#include <libgimp/gimpcolor.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__ */
|
|
@ -267,7 +267,7 @@ get_image_color (gdouble u,
|
|||
p[2] = peek (x1, y2);
|
||||
p[3] = peek (x2, y2);
|
||||
|
||||
return gck_bilinear_rgba (u, v, p);
|
||||
return gimp_bilinear_rgba (u, v, p);
|
||||
}
|
||||
|
||||
gdouble
|
||||
|
@ -297,7 +297,7 @@ get_map_value (GimpPixelRgn *region,
|
|||
p[2] = (gdouble) peek_map (region, x1, y2);
|
||||
p[3] = (gdouble) peek_map (region, x2, y2);
|
||||
|
||||
return gck_bilinear (u, v, p);
|
||||
return gimp_bilinear (u, v, p);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -189,7 +189,8 @@ init_compute (void)
|
|||
void
|
||||
render (gdouble x,
|
||||
gdouble y,
|
||||
GimpRGB *col)
|
||||
GimpRGB *col,
|
||||
gpointer data)
|
||||
{
|
||||
GimpVector3 pos;
|
||||
|
||||
|
@ -203,7 +204,8 @@ render (gdouble x,
|
|||
void
|
||||
show_progress (gint min,
|
||||
gint max,
|
||||
gint curr)
|
||||
gint curr,
|
||||
gpointer data)
|
||||
{
|
||||
gimp_progress_update ((gdouble) curr / (gdouble) max);
|
||||
}
|
||||
|
@ -288,7 +290,7 @@ compute_image (void)
|
|||
{
|
||||
p = int_to_pos (xcount, ycount);
|
||||
color = (* get_ray_color) (&p);
|
||||
poke (xcount, ycount, &color);
|
||||
poke (xcount, ycount, &color, NULL);
|
||||
|
||||
if ((progress_counter++ % width) == 0)
|
||||
gimp_progress_update ((gdouble) progress_counter /
|
||||
|
@ -298,13 +300,16 @@ compute_image (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
gck_adaptive_supersample_area (0, 0,
|
||||
gimp_adaptive_supersample_area (0, 0,
|
||||
width - 1, height - 1,
|
||||
max_depth,
|
||||
mapvals.pixeltreshold,
|
||||
render,
|
||||
NULL,
|
||||
poke,
|
||||
show_progress);
|
||||
NULL,
|
||||
show_progress,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Update the region */
|
||||
|
|
|
@ -136,16 +136,14 @@ peek_cylinder_image (gint image,
|
|||
void
|
||||
poke (gint x,
|
||||
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_rgba_get_uchar (color, &col[0], &col[1], &col[2], &col[3]);
|
||||
|
||||
gimp_pixel_rgn_set_pixel (&dest_region, data, x, y);
|
||||
gimp_pixel_rgn_set_pixel (&dest_region, col, x, y);
|
||||
}
|
||||
|
||||
gint
|
||||
|
@ -246,7 +244,7 @@ get_image_color (gdouble u,
|
|||
p[2] = peek (x1, 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)
|
||||
|
@ -273,7 +271,7 @@ get_image_color (gdouble u,
|
|||
p[2] = peek (x1, 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
|
||||
|
@ -281,7 +279,8 @@ get_box_image_color (gint image,
|
|||
gdouble u,
|
||||
gdouble v)
|
||||
{
|
||||
gint w,h, x1, y1, x2, y2;
|
||||
gint w, h;
|
||||
gint x1, y1, x2, y2;
|
||||
GimpRGB p[4];
|
||||
|
||||
w = box_drawables[image]->width;
|
||||
|
@ -304,7 +303,7 @@ get_box_image_color (gint image,
|
|||
p[2] = peek_box_image (image, x1, 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
|
||||
|
@ -312,7 +311,8 @@ get_cylinder_image_color (gint image,
|
|||
gdouble u,
|
||||
gdouble v)
|
||||
{
|
||||
gint w,h, x1, y1, x2, y2;
|
||||
gint w, h;
|
||||
gint x1, y1, x2, y2;
|
||||
GimpRGB p[4];
|
||||
|
||||
w = cylinder_drawables[image]->width;
|
||||
|
@ -335,7 +335,7 @@ get_cylinder_image_color (gint image,
|
|||
p[2] = peek_cylinder_image (image, x1, 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);
|
||||
extern void poke (gint x,
|
||||
gint y,
|
||||
GimpRGB *color);
|
||||
GimpRGB *color,
|
||||
gpointer data);
|
||||
extern GimpVector3 int_to_pos (gint x,
|
||||
gint y);
|
||||
extern void pos_to_int (gdouble x,
|
||||
|
|
|
@ -56,12 +56,6 @@ typedef struct
|
|||
GckDitherType dithermethod;
|
||||
} 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);
|
||||
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,
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -42,12 +42,6 @@
|
|||
|
||||
#define ROUND_TO_INT(val) ((val) + 0.5)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guchar ready;
|
||||
GimpRGB color;
|
||||
} _GckSampleType;
|
||||
|
||||
|
||||
/* returns a static storage */
|
||||
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);
|
||||
}
|
||||
|
||||
/********************/
|
||||
/* 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