Start of a stable/unstable plug-in split (these are going into

gimp-plugins-unstable)

-Yosh
This commit is contained in:
Manish Singh 1998-02-19 23:26:15 +00:00
parent 0e9f9891f6
commit 4607c5e5e5
47 changed files with 0 additions and 12661 deletions

View File

@ -289,7 +289,6 @@ plug-ins/maze/Makefile
plug-ins/max_rgb/Makefile
plug-ins/mail/Makefile
plug-ins/magiceye/Makefile
plug-ins/lic/Makefile
plug-ins/laplace/Makefile
plug-ins/ifscompose/Makefile
plug-ins/iwarp/Makefile
@ -307,10 +306,8 @@ plug-ins/gfli/Makefile
plug-ins/gbr/Makefile
plug-ins/gauss_iir/Makefile
plug-ins/gauss_rle/Makefile
plug-ins/fp/Makefile
plug-ins/fits/Makefile
plug-ins/film/Makefile
plug-ins/figures/Makefile
plug-ins/faxg3/Makefile
plug-ins/exchange/Makefile
plug-ins/engrave/Makefile
@ -358,13 +355,10 @@ plug-ins/flame/Makefile
plug-ins/gimptcl/Makefile
plug-ins/gimptcl/scripts/Makefile
plug-ins/fuse/Makefile
plug-ins/mathmap/Makefile
plug-ins/rcm/Makefile
plug-ins/refract/Makefile
plug-ins/struc/Makefile
plug-ins/twist/Makefile
plug-ins/user_filter/Makefile
plug-ins/warp/Makefile
plug-ins/zealouscrop/Makefile
plug-ins/xwd/Makefile
plug-ins/whirlpinch/Makefile

View File

@ -14,11 +14,9 @@ SUBDIRS = \
fuse \
gflare \
@GIMPTCL@ \
refract \
script-fu \
struc \
twist \
warp \
@TIFF@ \
@JPEG@ \
@PNG@ \
@ -57,12 +55,10 @@ SUBDIRS = \
engrave \
exchange \
faxg3 \
figures \
film \
fits \
flame \
flarefx \
fp \
fractaltrace \
gauss_iir \
gauss_rle \
@ -83,7 +79,6 @@ SUBDIRS = \
illusion \
iwarp \
laplace \
lic \
magiceye \
mail \
max_rgb \

View File

@ -1,287 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
#include "fp.h"
#include "fp_hsv.h"
FP_Params Current =
{
1,
.25, /* Initial Roughness */
NULL,
.6, /* Initial Degree of Aliasing */
NULL,
60,
NULL,
MIDTONES, /* Initial Range */
BY_VAL, /* Initial God knows what */
TRUE, /* Selection Only */
TRUE, /* Real Time */
0, /* Offset */
HUE|VALUE,
{32,224,255},
{0,0,0}
};
GDrawable *drawable, *mask;
void query (void);
void run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals);
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
MAIN()
void
query ()
{
GParamDef args[] =
{
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
{ PARAM_IMAGE, "image", "Input image (used for indexed images)" },
{ PARAM_DRAWABLE, "drawable", "Input drawable" },
};
GParamDef *return_vals = NULL;
int nargs = sizeof (args) / sizeof (args[0]);
int nreturn_vals = 0;
gimp_install_procedure ("plug_in_filter_pack",
"Allows the user to change H, S, or C with many previews",
"Then something else here",
"Pavel Grinfeld (pavel@ml.com)",
"Pavel Grinfeld (pavel@ml.com)",
"27th March 1997",
"<Image>/Filters/Colors/Filter Pack",
"RGB*,INDEXED*,GRAY*",
PROC_PLUG_IN,
nargs, nreturn_vals,
args, return_vals);
}
/********************************STANDARD RUN*************************/
void
run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals)
{
GParam values[1];
GStatusType status = STATUS_SUCCESS;
*nreturn_vals = 1;
*return_vals = values;
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
initializeFilterPacks();
drawable = gimp_drawable_get (param[2].data.d_drawable);
mask=gimp_drawable_get(gimp_image_get_selection(param[1].data.d_image));
if (gimp_drawable_indexed (drawable->id) ||gimp_drawable_gray (drawable->id) ) {
ErrorMessage("Convert the image to RGB first!");
status = STATUS_EXECUTION_ERROR;
}
else if (gimp_drawable_color (drawable->id) && fp_dialog())
{
gimp_progress_init ("Applying the Filter Pack...");
gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));
fp (drawable);
gimp_displays_flush ();
}
else status = STATUS_EXECUTION_ERROR;
values[0].data.d_status = status;
if (status==STATUS_SUCCESS)
gimp_drawable_detach (drawable);
}
void
fp_row (const guchar *src_row,
guchar *dest_row,
gint row,
gint row_width,
gint bytes)
{
gint col, bytenum, k;
int JudgeBy, Intensity, P[3], backupP[3];
hsv H,S,V;
gint M, m, middle;
/* initialize */
Intensity = 0;
for (col = 0; col < row_width ; col++)
{
backupP[0] = P[0] = src_row[col*bytes+0];
backupP[0] = P[1] = src_row[col*bytes+1];
backupP[0] = P[2] = src_row[col*bytes+2];
rgb_to_hsv(P[0]/255.0, P[1]/255.0, P[2]/255.0, &H, &S, &V);
for (JudgeBy=BY_HUE; JudgeBy<JUDGE_BY; JudgeBy++) {
if (!Current.Touched[JudgeBy]) continue;
switch (JudgeBy) {
case BY_HUE:
Intensity=255*H;
break;
case BY_SAT:
Intensity=255*S;
break;
case BY_VAL:
Intensity=255*V;
break;
}
/* It's important to take care of Saturation first!!! */
m = MIN(MIN(P[0],P[1]),P[2]);
M = MAX(MAX(P[0],P[1]),P[2]);
middle=(M+m)/2;
for (k=0; k<3; k++)
if (P[k]!=m && P[k]!=M) middle=P[k];
for (k=0; k<3; k++)
if (M!=m)
if (P[k] == M)
P[k] = MAX(P[k]+Current.satAdj[JudgeBy][Intensity],middle);
else if (P[k] == m)
P[k] = MIN(P[k]-Current.satAdj[JudgeBy][Intensity],middle);
P[0] += Current.redAdj[JudgeBy][Intensity];
P[1] += Current.greenAdj[JudgeBy][Intensity];
P[2] += Current.blueAdj[JudgeBy][Intensity];
P[0] = MAX(0,MIN(255, P[0]));
P[1] = MAX(0,MIN(255, P[1]));
P[2] = MAX(0,MIN(255, P[2]));
}
dest_row[col*bytes + 0] = P[0];
dest_row[col*bytes + 1] = P[1];
dest_row[col*bytes + 2] = P[2];
if (bytes>3)
for (bytenum = 3; bytenum<bytes; bytenum++)
dest_row[col*bytes+bytenum] = src_row[col*bytes+bytenum];
}
}
void fp (GDrawable *drawable)
{
GPixelRgn srcPR, destPR;
gint width, height;
gint bytes;
guchar *src_row, *dest_row;
gint row;
gint x1, y1, x2, y2;
gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
width = drawable->width;
height = drawable->height;
bytes = drawable->bpp;
src_row = (guchar *) malloc ((x2 - x1) * bytes);
dest_row = (guchar *) malloc ((x2 - x1) * bytes);
gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE);
for (row = y1; row < y2; row++)
{
gimp_pixel_rgn_get_row (&srcPR, src_row, x1, row, (x2 - x1));
fp_row (src_row,
dest_row,
row,
(x2 - x1),
bytes
);
gimp_pixel_rgn_set_row (&destPR, dest_row, x1, row, (x2 - x1));
if ((row % 10) == 0)
gimp_progress_update ((double) row / (double) (y2 - y1));
}
/* update the processed region */
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, x1, y1, (x2 - x1), (y2 - y1));
free (src_row);
free (dest_row);
}
void
ErrorMessage(guchar *message)
{
GtkWidget *window, *label, *button,*table;
gchar **argv=g_new (gchar *, 1);
gint argc=1;
argv[0] = g_strdup ("fp");
gtk_init (&argc, &argv);
gtk_rc_parse (gimp_gtkrc ());
window=gtk_dialog_new();
gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
gtk_window_set_title(GTK_WINDOW(window),"Filter Pack Simulation Message");
gtk_signal_connect (GTK_OBJECT (window), "destroy",
(GtkSignalFunc) fp_close_callback,
NULL);
button = gtk_button_new_with_label ("Got It!");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) fp_ok_callback,
window);
gtk_widget_grab_default (button);
gtk_widget_show (button);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);
table=gtk_table_new(2,2,FALSE);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox),table,TRUE,TRUE,0);
gtk_widget_show(table);
label=gtk_label_new("");
gtk_label_set(GTK_LABEL(label),message);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table),label,0,1,0,1,
GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,15,15);
gtk_widget_show(window);
gtk_main ();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
figures

View File

@ -1,39 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = figures
figures_SOURCES = \
figures.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
\
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
figures_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

View File

@ -1,442 +0,0 @@
/* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer
* Kimball and Peter Mattis * * This program is free software; you can
* redistribute it and/or modify * it under the terms of the GNU General
* Public License as published by * the Free Software Foundation; either
* version 2 of the License, or * (at your option) any later version. * *
* This program 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
* General Public License for more details. * * You should have received a
* copy of the GNU General Public License * along with this program; if not,
* write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA
* 02139, USA. */
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "libgimp/gimp.h"
#include "gtk/gtk.h"
/* Declare local functions. */
static void query(void);
static void run(char *name,
int nparams,
GParam * param,
int *nreturn_vals,
GParam ** return_vals);
static gint dialog();
static void doit(GDrawable * drawable);
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
gint bytes;
gint sx1, sy1, sx2, sy2;
int run_flag = 0;
typedef struct {
gint min_width, max_width;
gint min_height, max_height;
float density;
} config;
config my_config =
{
10, 30, /* min_width, max_width */
10, 30, /* min_height, max_height */
4 /* density */
};
MAIN()
static void query()
{
static GParamDef args[] =
{
{PARAM_INT32, "run_mode", "Interactive, non-interactive"},
{PARAM_IMAGE, "image", "Input image (unused)"},
{PARAM_DRAWABLE, "drawable", "Input drawable"},
{PARAM_FLOAT, "density", "Density"},
{PARAM_INT32, "min_width", "Min. width"},
{PARAM_INT32, "max_width", "Max. width"},
{PARAM_INT32, "min_height", "Min. height"},
{PARAM_INT32, "max_height", "Max. height"},
};
static GParamDef *return_vals = NULL;
static int nargs = sizeof(args) / sizeof(args[0]);
static int nreturn_vals = 0;
gimp_install_procedure("plug_in_figures",
"Draws lots of rectangles.",
"Can be nice to use as \"textures\".",
"Tim Newsome",
"Tim Newsome",
"1997",
"<Image>/Filters/Render/Figures",
"RGB*, GRAY*",
PROC_PLUG_IN,
nargs, nreturn_vals,
args, return_vals);
}
static void run(char *name, int n_params, GParam * param, int *nreturn_vals,
GParam ** return_vals)
{
static GParam values[1];
GDrawable *drawable;
GRunModeType run_mode;
GStatusType status = STATUS_SUCCESS;
*nreturn_vals = 1;
*return_vals = values;
run_mode = param[0].data.d_int32;
if (run_mode == RUN_NONINTERACTIVE) {
if (n_params != 8) {
status = STATUS_CALLING_ERROR;
} else {
my_config.density = param[3].data.d_float;
my_config.min_width = param[4].data.d_int32;
my_config.max_width = param[5].data.d_int32;
my_config.min_height = param[6].data.d_int32;
my_config.max_height = param[7].data.d_int32;
}
} else {
/* Possibly retrieve data */
gimp_get_data("plug_in_figures", &my_config);
if (run_mode == RUN_INTERACTIVE) {
/* Oh boy. We get to do a dialog box, because we can't really expect the
* user to set us up with the right values using gdb.
*/
if (!dialog()) {
/* The dialog was closed, or something similarly evil happened. */
status = STATUS_EXECUTION_ERROR;
}
}
}
if (status == STATUS_SUCCESS) {
/* Get the specified drawable */
drawable = gimp_drawable_get(param[2].data.d_drawable);
/* Make sure that the drawable is gray or RGB color */
if (gimp_drawable_color(drawable->id) || gimp_drawable_gray(drawable->id)) {
gimp_progress_init("Drawing Figures...");
gimp_tile_cache_ntiles(2 * (drawable->width / gimp_tile_width() + 1));
srand(time(NULL));
doit(drawable);
if (run_mode != RUN_NONINTERACTIVE)
gimp_displays_flush();
if (run_mode == RUN_INTERACTIVE)
gimp_set_data("plug_in_figures", &my_config, sizeof(my_config));
} else {
status = STATUS_EXECUTION_ERROR;
}
gimp_drawable_detach(drawable);
}
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
}
/*
* Draws a rectangle in region, using tmp as tempspace, with center x, y,
* width w, height h, with color color, and opaqueness a.
*/
static void draw_rectangle(guchar * tmp, GPixelRgn * region, int x, int y,
int w, int h, guchar color[], float a)
{
int i, j, k;
int rx1, rx2, ry1, ry2;
rx1 = x - w / 2;
rx2 = rx1 + w;
ry1 = y - h / 2;
ry2 = ry1 + h;
rx1 = rx1 < sx1 ? sx1 : rx1;
ry1 = ry1 < sy1 ? sy1 : ry1;
rx2 = rx2 > sx2 ? sx2 : rx2;
ry2 = ry2 > sy2 ? sy2 : ry2;
gimp_pixel_rgn_get_rect(region, tmp, rx1, ry1, rx2 - rx1, ry2 - ry1);
for (j = 0; j < (rx2 - rx1); j++) {
for (k = 0; k < (ry2 - ry1); k++) {
for (i = 0; i < bytes; i++) {
tmp[(j + (rx2 - rx1) * k) * bytes + i] =
(float) tmp[(j + (rx2 - rx1) * k) * bytes + i] * (1 - a) +
(float) color[i] * a;
}
}
}
gimp_pixel_rgn_set_rect(region, tmp, rx1, ry1, rx2 - rx1, ry2 - ry1);
}
static void doit(GDrawable * drawable)
{
GPixelRgn srcPR, destPR;
gint width, height;
int x, y, w, h;
int i, j;
guchar *tmp, *copybuf;
guchar color[4];
int objects;
/* Get the input area. This is the bounding box of the selection in
* the image (or the entire image if there is no selection). Only
* operating on the input area is simply an optimization. It doesn't
* need to be done for correct operation. (It simply makes it go
* faster, since fewer pixels need to be operated on).
*/
gimp_drawable_mask_bounds(drawable->id, &sx1, &sy1, &sx2, &sy2);
/* Get the size of the input image. (This will/must be the same
* as the size of the output image.
*/
width = drawable->width;
height = drawable->height;
bytes = drawable->bpp;
tmp = (guchar *) malloc(my_config.max_width * my_config.max_height * bytes);
if (tmp == NULL) {
return;
}
/* initialize the pixel regions */
gimp_pixel_rgn_init(&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
gimp_pixel_rgn_init(&destPR, drawable, 0, 0, width, height, TRUE, TRUE);
/* First off, copy the old one to the new one. */
copybuf = malloc(width * bytes);
for (i = sy1; i < sy2; i++) {
gimp_pixel_rgn_get_row(&srcPR, copybuf, sx1, i, width);
gimp_pixel_rgn_set_row(&destPR, copybuf, sx1, i, width);
}
free(copybuf);
objects = my_config.density * (float) (width * height) /
(float) (((my_config.min_width + my_config.max_width) / 2) *
((my_config.min_height + my_config.max_height)) / 2);
for (i = 0; i < objects; i++) {
w = my_config.min_width + rand() * (double) (my_config.max_width -
my_config.min_width) / (double) RAND_MAX;
h = my_config.min_height + rand() * (double) (my_config.max_height -
my_config.min_height) / (double) RAND_MAX;
x = sx1 + rand() * (double) width / (double) RAND_MAX;
y = sy1 + rand() * (double) height / (double) RAND_MAX;
for (j = 0; j < bytes; j++) {
color[j] = rand() * 255. / (double) RAND_MAX;
}
draw_rectangle(tmp, &destPR, x, y, w, h, color,
rand() / (double) RAND_MAX);
if (!(i % 64)) {
gimp_progress_update((double) i / (double) objects);
}
}
/* update the timred region */
gimp_drawable_flush(drawable);
gimp_drawable_merge_shadow(drawable->id, TRUE);
gimp_drawable_update(drawable->id, sx1, sy1, sx2 - sx1, sy2 - sy1);
}
/***************************************************
* GUI stuff
*/
static void close_callback(GtkWidget * widget, gpointer data)
{
gtk_main_quit();
}
static void ok_callback(GtkWidget * widget, gpointer data)
{
run_flag = 1;
gtk_widget_destroy(GTK_WIDGET(data));
}
static void entry_callback(GtkWidget * widget, gpointer data)
{
if (data == &my_config.density)
my_config.density = atof(gtk_entry_get_text(GTK_ENTRY(widget)));
else if (data == &my_config.min_width)
my_config.min_width = atoi(gtk_entry_get_text(GTK_ENTRY(widget)));
else if (data == &my_config.max_width)
my_config.max_width = atoi(gtk_entry_get_text(GTK_ENTRY(widget)));
else if (data == &my_config.min_height)
my_config.min_height = atoi(gtk_entry_get_text(GTK_ENTRY(widget)));
else if (data == &my_config.max_height)
my_config.max_height = atoi(gtk_entry_get_text(GTK_ENTRY(widget)));
}
static gint dialog()
{
GtkWidget *dlg;
GtkWidget *button;
GtkWidget *label;
GtkWidget *entry;
GtkWidget *table;
gchar buffer[12];
gchar **argv;
gint argc;
argc = 1;
argv = g_new(gchar *, 1);
argv[0] = g_strdup("plasma");
gtk_init(&argc, &argv);
gtk_rc_parse (gimp_gtkrc ());
dlg = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dlg), "Figures");
gtk_window_position(GTK_WINDOW(dlg), GTK_WIN_POS_MOUSE);
gtk_signal_connect(GTK_OBJECT(dlg), "destroy",
(GtkSignalFunc) close_callback, NULL);
/* Action area */
button = gtk_button_new_with_label("OK");
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
gtk_signal_connect(GTK_OBJECT(button), "clicked",
(GtkSignalFunc) ok_callback,
dlg);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area), button, TRUE, TRUE, 0);
gtk_widget_grab_default(button);
gtk_widget_show(button);
button = gtk_button_new_with_label("Cancel");
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
(GtkSignalFunc) gtk_widget_destroy,
GTK_OBJECT(dlg));
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area), button, TRUE, TRUE, 0);
gtk_widget_show(button);
/* The main table */
/* Set its size (y, x) */
table = gtk_table_new(5, 3, FALSE);
gtk_container_border_width(GTK_CONTAINER(table), 10);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), table, TRUE, TRUE, 0);
gtk_widget_show(table);
gtk_table_set_row_spacings(GTK_TABLE(table), 10);
gtk_table_set_col_spacings(GTK_TABLE(table), 10);
/*********************
* The density entry *
*********************/
label = gtk_label_new("Density:");
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0,
0);
gtk_widget_show(label);
entry = gtk_entry_new();
gtk_table_attach(GTK_TABLE(table), entry, 1, 3, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_set_usize(entry, 50, 0);
sprintf(buffer, "%0.2f", my_config.density);
gtk_entry_set_text(GTK_ENTRY(entry), buffer);
gtk_signal_connect(GTK_OBJECT(entry), "changed",
(GtkSignalFunc) entry_callback,
&my_config.density);
gtk_widget_show(entry);
/**********************
* The min/max labels *
**********************/
label = gtk_label_new("Min.");
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 0,
0);
gtk_widget_show(label);
label = gtk_label_new("Max.");
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 2, 3, 2, 3, GTK_FILL, GTK_FILL, 0,
0);
gtk_widget_show(label);
/************************
* The min_width entry: *
************************/
label = gtk_label_new("Width:");
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 0,
0);
gtk_widget_show(label);
entry = gtk_entry_new();
gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 3, 4, GTK_EXPAND | GTK_FILL,
GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_set_usize(entry, 50, 0);
sprintf(buffer, "%i", my_config.min_width);
gtk_entry_set_text(GTK_ENTRY(entry), buffer);
gtk_signal_connect(GTK_OBJECT(entry), "changed",
(GtkSignalFunc) entry_callback, &my_config.min_width);
gtk_widget_show(entry);
/************************
* The max_width entry: *
************************/
entry = gtk_entry_new();
gtk_table_attach(GTK_TABLE(table), entry, 2, 3, 3, 4, GTK_EXPAND | GTK_FILL,
GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_set_usize(entry, 50, 0);
sprintf(buffer, "%i", my_config.max_width);
gtk_entry_set_text(GTK_ENTRY(entry), buffer);
gtk_signal_connect(GTK_OBJECT(entry), "changed",
(GtkSignalFunc) entry_callback, &my_config.max_width);
gtk_widget_show(entry);
gtk_widget_show(dlg);
/************************
* The min_height entry: *
************************/
label = gtk_label_new("Height:");
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 0,
0);
gtk_widget_show(label);
entry = gtk_entry_new();
gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 4, 5, GTK_EXPAND | GTK_FILL,
GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_set_usize(entry, 50, 0);
sprintf(buffer, "%i", my_config.min_height);
gtk_entry_set_text(GTK_ENTRY(entry), buffer);
gtk_signal_connect(GTK_OBJECT(entry), "changed",
(GtkSignalFunc) entry_callback, &my_config.min_height);
gtk_widget_show(entry);
/************************
* The max_height entry: *
************************/
entry = gtk_entry_new();
gtk_table_attach(GTK_TABLE(table), entry, 2, 3, 4, 5, GTK_EXPAND | GTK_FILL,
GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_set_usize(entry, 50, 0);
sprintf(buffer, "%i", my_config.max_height);
gtk_entry_set_text(GTK_ENTRY(entry), buffer);
gtk_signal_connect(GTK_OBJECT(entry), "changed",
(GtkSignalFunc) entry_callback, &my_config.max_height);
gtk_widget_show(entry);
gtk_widget_show(dlg);
gtk_main();
gdk_flush();
return run_flag;
}

View File

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
fp

View File

@ -1,39 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = fp
fp_SOURCES = \
fp.c fp.h fp_gdk.c fp_gtk.c fp_hsv.c fp_hsv.h fp_misc.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
\
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
fp_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

View File

@ -1,287 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
#include "fp.h"
#include "fp_hsv.h"
FP_Params Current =
{
1,
.25, /* Initial Roughness */
NULL,
.6, /* Initial Degree of Aliasing */
NULL,
60,
NULL,
MIDTONES, /* Initial Range */
BY_VAL, /* Initial God knows what */
TRUE, /* Selection Only */
TRUE, /* Real Time */
0, /* Offset */
HUE|VALUE,
{32,224,255},
{0,0,0}
};
GDrawable *drawable, *mask;
void query (void);
void run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals);
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
MAIN()
void
query ()
{
GParamDef args[] =
{
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
{ PARAM_IMAGE, "image", "Input image (used for indexed images)" },
{ PARAM_DRAWABLE, "drawable", "Input drawable" },
};
GParamDef *return_vals = NULL;
int nargs = sizeof (args) / sizeof (args[0]);
int nreturn_vals = 0;
gimp_install_procedure ("plug_in_filter_pack",
"Allows the user to change H, S, or C with many previews",
"Then something else here",
"Pavel Grinfeld (pavel@ml.com)",
"Pavel Grinfeld (pavel@ml.com)",
"27th March 1997",
"<Image>/Filters/Colors/Filter Pack",
"RGB*,INDEXED*,GRAY*",
PROC_PLUG_IN,
nargs, nreturn_vals,
args, return_vals);
}
/********************************STANDARD RUN*************************/
void
run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals)
{
GParam values[1];
GStatusType status = STATUS_SUCCESS;
*nreturn_vals = 1;
*return_vals = values;
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
initializeFilterPacks();
drawable = gimp_drawable_get (param[2].data.d_drawable);
mask=gimp_drawable_get(gimp_image_get_selection(param[1].data.d_image));
if (gimp_drawable_indexed (drawable->id) ||gimp_drawable_gray (drawable->id) ) {
ErrorMessage("Convert the image to RGB first!");
status = STATUS_EXECUTION_ERROR;
}
else if (gimp_drawable_color (drawable->id) && fp_dialog())
{
gimp_progress_init ("Applying the Filter Pack...");
gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));
fp (drawable);
gimp_displays_flush ();
}
else status = STATUS_EXECUTION_ERROR;
values[0].data.d_status = status;
if (status==STATUS_SUCCESS)
gimp_drawable_detach (drawable);
}
void
fp_row (const guchar *src_row,
guchar *dest_row,
gint row,
gint row_width,
gint bytes)
{
gint col, bytenum, k;
int JudgeBy, Intensity, P[3], backupP[3];
hsv H,S,V;
gint M, m, middle;
/* initialize */
Intensity = 0;
for (col = 0; col < row_width ; col++)
{
backupP[0] = P[0] = src_row[col*bytes+0];
backupP[0] = P[1] = src_row[col*bytes+1];
backupP[0] = P[2] = src_row[col*bytes+2];
rgb_to_hsv(P[0]/255.0, P[1]/255.0, P[2]/255.0, &H, &S, &V);
for (JudgeBy=BY_HUE; JudgeBy<JUDGE_BY; JudgeBy++) {
if (!Current.Touched[JudgeBy]) continue;
switch (JudgeBy) {
case BY_HUE:
Intensity=255*H;
break;
case BY_SAT:
Intensity=255*S;
break;
case BY_VAL:
Intensity=255*V;
break;
}
/* It's important to take care of Saturation first!!! */
m = MIN(MIN(P[0],P[1]),P[2]);
M = MAX(MAX(P[0],P[1]),P[2]);
middle=(M+m)/2;
for (k=0; k<3; k++)
if (P[k]!=m && P[k]!=M) middle=P[k];
for (k=0; k<3; k++)
if (M!=m)
if (P[k] == M)
P[k] = MAX(P[k]+Current.satAdj[JudgeBy][Intensity],middle);
else if (P[k] == m)
P[k] = MIN(P[k]-Current.satAdj[JudgeBy][Intensity],middle);
P[0] += Current.redAdj[JudgeBy][Intensity];
P[1] += Current.greenAdj[JudgeBy][Intensity];
P[2] += Current.blueAdj[JudgeBy][Intensity];
P[0] = MAX(0,MIN(255, P[0]));
P[1] = MAX(0,MIN(255, P[1]));
P[2] = MAX(0,MIN(255, P[2]));
}
dest_row[col*bytes + 0] = P[0];
dest_row[col*bytes + 1] = P[1];
dest_row[col*bytes + 2] = P[2];
if (bytes>3)
for (bytenum = 3; bytenum<bytes; bytenum++)
dest_row[col*bytes+bytenum] = src_row[col*bytes+bytenum];
}
}
void fp (GDrawable *drawable)
{
GPixelRgn srcPR, destPR;
gint width, height;
gint bytes;
guchar *src_row, *dest_row;
gint row;
gint x1, y1, x2, y2;
gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
width = drawable->width;
height = drawable->height;
bytes = drawable->bpp;
src_row = (guchar *) malloc ((x2 - x1) * bytes);
dest_row = (guchar *) malloc ((x2 - x1) * bytes);
gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE);
for (row = y1; row < y2; row++)
{
gimp_pixel_rgn_get_row (&srcPR, src_row, x1, row, (x2 - x1));
fp_row (src_row,
dest_row,
row,
(x2 - x1),
bytes
);
gimp_pixel_rgn_set_row (&destPR, dest_row, x1, row, (x2 - x1));
if ((row % 10) == 0)
gimp_progress_update ((double) row / (double) (y2 - y1));
}
/* update the processed region */
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, x1, y1, (x2 - x1), (y2 - y1));
free (src_row);
free (dest_row);
}
void
ErrorMessage(guchar *message)
{
GtkWidget *window, *label, *button,*table;
gchar **argv=g_new (gchar *, 1);
gint argc=1;
argv[0] = g_strdup ("fp");
gtk_init (&argc, &argv);
gtk_rc_parse (gimp_gtkrc ());
window=gtk_dialog_new();
gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
gtk_window_set_title(GTK_WINDOW(window),"Filter Pack Simulation Message");
gtk_signal_connect (GTK_OBJECT (window), "destroy",
(GtkSignalFunc) fp_close_callback,
NULL);
button = gtk_button_new_with_label ("Got It!");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) fp_ok_callback,
window);
gtk_widget_grab_default (button);
gtk_widget_show (button);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);
table=gtk_table_new(2,2,FALSE);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox),table,TRUE,TRUE,0);
gtk_widget_show(table);
label=gtk_label_new("");
gtk_label_set(GTK_LABEL(label),message);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table),label,0,1,0,1,
GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,15,15);
gtk_widget_show(window);
gtk_main ();
}

View File

@ -1,212 +0,0 @@
#define MAX_PREVIEW_SIZE 125
#define MAX_ROUGHNESS 128
#define RANGE_HEIGHT 15
#define PR_BX_BRDR 10
#define ALL 255
#define RANGE_ADJUST_MASK GDK_EXPOSURE_MASK | \
GDK_ENTER_NOTIFY_MASK | \
GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_BUTTON1_MOTION_MASK | \
GDK_POINTER_MOTION_HINT_MASK
typedef struct {
gint run;
} fpInterface;
typedef double hsv;
typedef struct {
gint width;
gint height;
guchar *rgb;
hsv *hsv;
guchar *mask;
} ReducedImage;
typedef enum {
SHADOWS,
MIDTONES,
HIGHLIGHTS,
INTENSITIES
}FP_Intensity;
enum {
NONEATALL =0,
CURRENT =1,
HUE =2,
SATURATION =4,
VALUE =8
};
enum {
RED,
GREEN,
BLUE,
CYAN,
YELLOW,
MAGENTA,
ALL_PRIMARY
};
enum {
DOWN = -1,
UP = 1
};
enum {
BY_HUE,
BY_SAT,
BY_VAL,
JUDGE_BY
};
typedef struct {
GtkWidget *window;
GtkWidget *shadowsEntry;
GtkWidget *midtonesEntry;
GtkWidget *rangePreview;
GtkWidget *aliasingPreview;
GtkObject *aliasingData;
GtkWidget *aliasingGraph;
} AdvancedWindow;
typedef struct {
int Color;
float Rough;
GtkWidget *roughnessScale;
float Alias;
GtkWidget *aliasingScale;
float PreviewSize;
GtkWidget *previewSizeScale;
FP_Intensity Range;
gint ValueBy;
gint SlctnOnly;
gint RealTime;
guchar Offset;
guchar VisibleFrames;
guchar Cutoffs[INTENSITIES];
gint Touched[JUDGE_BY];
gint redAdj[JUDGE_BY][256];
gint blueAdj[JUDGE_BY][256];
gint greenAdj[JUDGE_BY][256];
gint satAdj[JUDGE_BY][256];
GtkWidget *rangeLabels[12];
}FP_Params;
GtkWidget *fp_create_bna(void);
GtkWidget *fp_create_rough(void);
GtkWidget *fp_create_range(void);
GtkWidget *fp_create_circle_palette(void);
GtkWidget *fp_create_lnd(void);
GtkWidget *fp_create_show(void);
GtkWidget *fp_create_msnls();
GtkWidget *fp_create_frame_select();
GtkWidget *fp_create_pixels_select_by();
void fp_show_hide_frame(GtkWidget *button,
GtkWidget *frame);
ReducedImage *Reduce_The_Image (GDrawable *,
GDrawable *,
gint,
gint);
void fp_render_preview (GtkWidget *,
gint,
gint );
void Update_Current_FP (gint,
gint );
void fp_Create_Nudge (gint* );
gint fp_dialog (void);
gint fp_advanced_dialog (void);
void fp_advanced_call (void);
void fp_entire_image (GtkWidget *,
gpointer );
void fp_selection_only (GtkWidget *,
gpointer );
void fp_selection_in_context (GtkWidget *,
gpointer );
void selectionMade (GtkWidget *,
gpointer );
void fp_close_callback (GtkWidget *,
gpointer );
void fp_ok_callback (GtkWidget *,
gpointer );
void fp_scale_update (GtkAdjustment *,
float* );
void fp_change_current_range (GtkAdjustment*,
gint* );
void fp_change_current_pixels_by (GtkWidget *,
gint *);
void resetFilterPacks (void);
void update_range_labels (void);
void fp_create_smoothness_graph (GtkWidget* );
void fp_range_preview_spill (GtkWidget*,
gint );
void Create_A_Preview (GtkWidget **,
GtkWidget **,
int,
int );
void Create_A_Table_Entry (GtkWidget **,
GtkWidget *,
char *);
GSList* Button_In_A_Box (GtkWidget *,
GSList *,
guchar *,
GtkSignalFunc,
gpointer,
int );
void Check_Button_In_A_Box (GtkWidget *,
guchar *label,
GtkSignalFunc func,
gpointer data,
int clicked);
void Adjust_Preview_Sizes (int width,
int height );
void refreshPreviews (int);
void initializeFilterPacks (void);
void fp (GDrawable *drawable);
void fp_row (const guchar *src_row,
guchar *dest_row,
gint row,
gint row_width,
gint bytes);
void draw_slider (GdkWindow *window,
GdkGC *border_gc,
GdkGC *fill_gc,
int xpos);
gint FP_Range_Change_Events (GtkWidget *,
GdkEvent *,
FP_Params *);
void As_You_Drag (GtkWidget *button);
void preview_size_scale_update (GtkAdjustment *adjustment,
float *scale_val);
void ErrorMessage (guchar *);
void fp_advanced_ok();

View File

@ -1,160 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
#include "fp.h"
#include "fp_hsv.h"
extern AdvancedWindow AW;
extern FP_Params Current;
extern gint nudgeArray[256];
void
draw_slider(GdkWindow *window,
GdkGC *border_gc,
GdkGC *fill_gc,
int xpos)
{
int i;
for (i = 0; i < RANGE_HEIGHT; i++)
gdk_draw_line(window, fill_gc,xpos-i/2, i,xpos+i/2,i);
gdk_draw_line(window, border_gc, xpos, 0,
xpos - (RANGE_HEIGHT - 1) / 2, RANGE_HEIGHT - 1);
gdk_draw_line(window, border_gc, xpos, 0,
xpos + (RANGE_HEIGHT - 1) / 2, RANGE_HEIGHT - 1);
gdk_draw_line(window, border_gc,xpos-(RANGE_HEIGHT-1)/2,RANGE_HEIGHT-1,
xpos + (RANGE_HEIGHT-1)/2, RANGE_HEIGHT-1);
}
void
draw_it(GtkWidget *widget)
{
draw_slider(AW.aliasingGraph->window,
AW.aliasingGraph->style->black_gc,
AW.aliasingGraph->style->dark_gc[GTK_STATE_NORMAL],
Current.Cutoffs[SHADOWS]);
draw_slider(AW.aliasingGraph->window,
AW.aliasingGraph->style->black_gc,
AW.aliasingGraph->style->dark_gc[GTK_STATE_NORMAL],
Current.Cutoffs[MIDTONES]);
draw_slider(AW.aliasingGraph->window,
AW.aliasingGraph->style->black_gc,
AW.aliasingGraph->style->dark_gc[GTK_STATE_NORMAL],
Current.Offset);
}
void
slider_erase (GdkWindow *window,
int xpos)
{
gdk_window_clear_area (window, xpos - (RANGE_HEIGHT - 1) / 2, 0,
RANGE_HEIGHT, RANGE_HEIGHT);
}
gint
FP_Range_Change_Events (GtkWidget *widget,
GdkEvent *event,
FP_Params *current)
{
GdkEventButton *bevent;
GdkEventMotion *mevent;
gint shad, mid, offset, min;
static guchar *new;
gint x;
switch(event->type) {
case GDK_EXPOSE:
draw_it(NULL);
case GDK_BUTTON_PRESS:
bevent=(GdkEventButton *) event;
shad = abs(bevent->x - Current.Cutoffs[SHADOWS]);
mid = abs(bevent->x - Current.Cutoffs[MIDTONES]);
offset = abs(bevent->x - Current.Offset);
min= MIN(MIN(shad,mid),offset);
if (bevent->x >0 && bevent->x<256) {
if (min==shad)
new = &Current.Cutoffs[SHADOWS];
else if (min==mid)
new = &Current.Cutoffs[MIDTONES];
else
new = &Current.Offset;
slider_erase(AW.aliasingGraph->window,*new);
*new=bevent->x;
}
draw_it(NULL);
if (Current.RealTime) {
fp_range_preview_spill(AW.rangePreview,Current.ValueBy);
update_range_labels();
fp_create_smoothness_graph(AW.aliasingPreview);
refreshPreviews(Current.VisibleFrames);
}
break;
case GDK_BUTTON_RELEASE:
if (!Current.RealTime) {
fp_range_preview_spill(AW.rangePreview,Current.ValueBy);
update_range_labels();
fp_create_smoothness_graph(AW.aliasingPreview);
refreshPreviews(Current.VisibleFrames);
}
break;
case GDK_MOTION_NOTIFY:
mevent= (GdkEventMotion *) event;
gdk_window_get_pointer(widget->window, &x,NULL, NULL);
if (x>=0 && x<256) {
slider_erase(AW.aliasingGraph->window,*new);
*new=x;
draw_it(NULL);
if (Current.RealTime) {
fp_range_preview_spill(AW.rangePreview,Current.ValueBy);
update_range_labels();
fp_create_smoothness_graph(AW.aliasingPreview);
refreshPreviews(Current.VisibleFrames);
}
}
break;
default:
break;
}
return 0;
}
void
update_range_labels()
{
guchar buffer[3];
gtk_label_set(GTK_LABEL(Current.rangeLabels[1]),"0");
sprintf(buffer,"%d",Current.Cutoffs[SHADOWS]);
gtk_label_set(GTK_LABEL(Current.rangeLabels[3]),buffer);
gtk_label_set(GTK_LABEL(Current.rangeLabels[5]),buffer);
sprintf(buffer,"%d",Current.Cutoffs[MIDTONES]);
gtk_label_set(GTK_LABEL(Current.rangeLabels[7]),buffer);
gtk_label_set(GTK_LABEL(Current.rangeLabels[9]),buffer);
gtk_label_set(GTK_LABEL(Current.rangeLabels[11]),"255");
}

File diff suppressed because it is too large Load Diff

View File

@ -1,93 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "libgimp/gimp.h"
typedef double hsv;
void rgb_to_hsv (hsv r,
hsv g,
hsv b,
hsv *h,
hsv *s,
hsv *l)
{
hsv v;
hsv m;
hsv vm;
hsv r2, g2, b2;
v = MAX(r,g);
v = MAX(v,b);
m = MIN(r,g);
m = MIN(m,b);
if ((*l = (m + v) / 2.0) <= 0.0)
{
*s=*h=0;
return;
}
if ((*s = vm = v - m) > 0.0)
{
*s /= (*l <= 0.5) ? (v + m ) :
(2.0 - v - m) ;
}
else
{
*h=0;
return;
}
r2 = (v - r) / vm;
g2 = (v - g) / vm;
b2 = (v - b) / vm;
if (r == v)
*h = (g == m ? 5.0 + b2 : 1.0 - g2);
else if (g == v)
*h = (b == m ? 1.0 + r2 : 3.0 - b2);
else
*h = (r == m ? 3.0 + g2 : 5.0 - r2);
*h /= 6;
}
void hsv_to_rgb (hsv h,
hsv sl,
hsv l,
hsv *r,
hsv *g,
hsv *b)
{
hsv v;
v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
if (v <= 0)
{
*r = *g = *b = 0.0;
}
else
{
hsv m;
hsv sv;
gint sextant;
hsv fract, vsf, mid1, mid2;
m = l + l - v;
sv = (v - m ) / v;
h *= 6.0;
sextant = h;
fract = h - sextant;
vsf = v * sv * fract;
mid1 = m + vsf;
mid2 = v - vsf;
switch (sextant)
{
case 0: *r = v; *g = mid1; *b = m; break;
case 1: *r = mid2; *g = v; *b = m; break;
case 2: *r = m; *g = v; *b = mid1; break;
case 3: *r = m; *g = mid2; *b = v; break;
case 4: *r = mid1; *g = m; *b = v; break;
case 5: *r = v; *g = m; *b = mid2; break;
}
}
}

View File

@ -1,13 +0,0 @@
void rgb_to_hsv (hsv r,
hsv g,
hsv b,
hsv *h,
hsv *s,
hsv *l);
void hsv_to_rgb (hsv h,
hsv sl,
hsv l,
hsv *r,
hsv *g,
hsv *b);

View File

@ -1,394 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
#include "fp.h"
#include "fp_hsv.h"
extern FP_Params Current;
extern GDrawable *drawable, *mask;
extern ReducedImage *reduced;
extern gint nudgeArray[256];
gint colorSign[3][ALL_PRIMARY]=
{{1,-1,-1,-1,1,1},{-1,1,-1,1,1,-1},{-1,-1,1,1,-1,1}};
void initializeFilterPacks()
{
gint i, j;
for (i=0; i<256; i++)
for (j=BY_HUE; j<JUDGE_BY; j++) {
Current.redAdj [j][i]=0;
Current.greenAdj [j][i]=0;
Current.blueAdj [j][i]=0;
Current.satAdj [j][i]=0;
}
}
void resetFilterPacks()
{
initializeFilterPacks();
refreshPreviews(Current.VisibleFrames);
}
ReducedImage *Reduce_The_Image(GDrawable *drawable,
GDrawable *mask,
gint LongerSize,
gint Slctn)
{
gint width;
gint height;
gint bytes=drawable->bpp;
gint RH, RW;
ReducedImage *temp=(ReducedImage *)malloc(sizeof(ReducedImage));
guchar *tempRGB, *src_row, *tempmask, *src_mask_row,R,G,B;
gint i, j, whichcol, whichrow, x1, x2, y1, y2;
GPixelRgn srcPR, srcMask;
gint NoSelectionMade=TRUE;
hsv *tempHSV, H, S, V;
gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
width = x2-x1;
height = y2-y1;
if (width != drawable->width && height != drawable->height)
NoSelectionMade=FALSE;
if (Slctn==0) {
x1=0;
x2=drawable->width;
y1=0;
y2=drawable->height;
}
if (Slctn==2) {
x1=MAX(0, x1-width/2.0);
x2=MIN(drawable->width, x2+width/2.0);
y1=MAX(0, y1-height/2.0);
y2=MIN(drawable->height, y2+height/2.0);
}
width = x2-x1;
height = y2-y1;
if (width>height) {
RW=LongerSize;
RH=(float) height * (float) LongerSize/ (float) width;
}
else {
RH=LongerSize;
RW=(float)width * (float) LongerSize/ (float) height;
}
tempRGB = (guchar *) malloc(RW*RH*bytes);
tempHSV = (hsv *) malloc(RW*RH*bytes*sizeof(hsv));
tempmask = (guchar *) malloc(RW*RH);
gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, width, height, FALSE, FALSE);
gimp_pixel_rgn_init (&srcMask, mask, x1, y1, width, height, FALSE, FALSE);
src_row = (guchar *) malloc (width*bytes);
src_mask_row = (guchar *) malloc (width*bytes);
for (i=0; i<RH; i++) {
whichrow=(float)i*(float)height/(float)RH;
gimp_pixel_rgn_get_row (&srcPR, src_row, x1, y1+whichrow, width);
gimp_pixel_rgn_get_row (&srcMask, src_mask_row, x1, y1+whichrow, width);
for (j=0; j<RW; j++) {
whichcol=(float)j*(float)width/(float)RW;
if (NoSelectionMade)
tempmask[i*RW+j]=255;
else
tempmask[i*RW+j]=src_mask_row[whichcol];
R=src_row[whichcol*bytes+0];
G=src_row[whichcol*bytes+1];
B=src_row[whichcol*bytes+2];
rgb_to_hsv(R/255.0,G/255.0,B/255.0,&H,&S,&V);
tempRGB[i*RW*bytes+j*bytes+0]=R;
tempRGB[i*RW*bytes+j*bytes+1]=G;
tempRGB[i*RW*bytes+j*bytes+2]=B;
tempHSV[i*RW*bytes+j*bytes+0]=H;
tempHSV[i*RW*bytes+j*bytes+1]=S;
tempHSV[i*RW*bytes+j*bytes+2]=V;
if (bytes==4)
tempRGB[i*RW*bytes+j*bytes+3]=src_row[whichcol*bytes+3];
}
}
temp->width=RW;
temp->height=RH;
temp->rgb=tempRGB;
temp->hsv=tempHSV;
temp->mask=tempmask;
return temp;
}
/*************************************************************/
/************** The Preview Function *************************/
void
fp_render_preview(GtkWidget *preview,
gint changewhat,
gint changewhich)
{
guchar *a;
gint Inten, bytes=drawable->bpp;
gint i, j, k, nudge, M, m, middle,JudgeBy;
float partial;
gint RW=reduced->width;
gint RH=reduced->height;
gint backupP[3], P[3], tempSat[JUDGE_BY][256];
a =(guchar *) malloc(bytes*RW);
if (changewhat==SATURATION)
for (k=0; k<256; k++) {
for (JudgeBy=BY_HUE; JudgeBy<JUDGE_BY; JudgeBy++)
tempSat[JudgeBy][k]=0;
tempSat[Current.ValueBy][k] += changewhich*nudgeArray[(k+Current.Offset)%256];
}
for (i=0; i<RH; i++) {
for (j=0; j<RW; j++) {
backupP[0] = P[0] = (int) reduced->rgb[i*RW*bytes + j*bytes + 0];
backupP[1] = P[1] = (int) reduced->rgb[i*RW*bytes + j*bytes + 1];
backupP[2] = P[2] = (int) reduced->rgb[i*RW*bytes + j*bytes + 2];
m = MIN(MIN(P[0],P[1]),P[2]);
M = MAX(MAX(P[0],P[1]),P[2]);
middle=(M+m)/2;
for (k=0; k<3; k++)
if (P[k]!=m && P[k]!=M) middle=P[k];
partial = reduced->mask[i*RW+j]/255.0;
for (JudgeBy=BY_HUE; JudgeBy<JUDGE_BY; JudgeBy++) {
if (!Current.Touched[JudgeBy]) continue;
Inten = reduced->hsv[i*RW*bytes + j*bytes + JudgeBy]*255.0;
/*DO SATURATION FIRST*/
if (changewhat != NONEATALL) {
if (M!=m)
for (k=0; k<3; k++)
if (backupP[k] == M)
P[k] = MAX(P[k]+partial*Current.satAdj[JudgeBy][Inten],middle);
else if (backupP[k] == m)
P[k] = MIN(P[k]-partial*Current.satAdj[JudgeBy][Inten],middle);
P[0] += partial*Current.redAdj[JudgeBy][Inten];
P[1] += partial*Current.greenAdj[JudgeBy][Inten];
P[2] += partial*Current.blueAdj[JudgeBy][Inten];
}
}
Inten = reduced->hsv[i*RW*bytes + j*bytes + Current.ValueBy]*255.0;
nudge = partial*nudgeArray[(Inten+Current.Offset)%256];
switch (changewhat) {
case HUE:
P[0] += colorSign[RED][changewhich] * nudge;
P[1] += colorSign[GREEN][changewhich] * nudge;
P[2] += colorSign[BLUE][changewhich] * nudge;
break;
case SATURATION:
for (JudgeBy=BY_HUE; JudgeBy<JUDGE_BY; JudgeBy++)
for (k=0; k<3; k++)
if (M!=m)
if (backupP[k] == M)
P[k] = MAX(P[k]+
partial*tempSat[JudgeBy][Inten],middle);
else if (backupP[k] == m)
P[k] = MIN(P[k]-
partial*tempSat[JudgeBy][Inten],middle);
break;
case VALUE:
P[0] += changewhich * nudge;
P[1] += changewhich * nudge;
P[2] += changewhich * nudge;
break;
default:
break;
}
a[j*3+0] = MAX(0,MIN(P[0], 255));
a[j*3+1] = MAX(0,MIN(P[1], 255));
a[j*3+2] = MAX(0,MIN(P[2], 255));
}
gtk_preview_draw_row( GTK_PREVIEW(preview),a,0,i,RW);
}
free(a);
gtk_widget_draw(preview,NULL);
gdk_flush();
}
void
Update_Current_FP (gint changewhat,
gint changewhich)
{
int i, nudge;
for (i=0; i<256; i++) {
fp_Create_Nudge(nudgeArray);
nudge=nudgeArray[(i+Current.Offset)%256];
switch (changewhat) {
case HUE:
Current.redAdj[Current.ValueBy][i] +=
colorSign[RED][changewhich] * nudge;
Current.greenAdj[Current.ValueBy][i] +=
colorSign[GREEN][changewhich] * nudge;
Current.blueAdj[Current.ValueBy][i] +=
colorSign[BLUE][changewhich] * nudge;
break;
case SATURATION:
Current.satAdj[Current.ValueBy][i] += changewhich*nudge;
break;
case VALUE:
Current.redAdj[Current.ValueBy][i] += changewhich * nudge;
Current.greenAdj[Current.ValueBy][i] += changewhich * nudge;
Current.blueAdj[Current.ValueBy][i] += changewhich * nudge;
break;
default:
break;
} /* switch */
} /* for */
}
void
fp_create_smoothness_graph (GtkWidget *preview)
{
guchar data[256*3];
gint nArray[256];
int i, j, toBeBlack;
fp_Create_Nudge(nArray);
for (i=0; i<MAX_ROUGHNESS; i++)
{
int coor=MAX_ROUGHNESS-i;
for (j=0; j<256; j++) {
data[3*j+0]=255;
data[3*j+1]=255;
data[3*j+2]=255;
if (!(i%(MAX_ROUGHNESS/4))) {
data[3*j+0]=255;
data[3*j+1]=128;
data[3*j+2]=128;
}
if (!((j+1)%32)) {
data[3*j+0]=255;
data[3*j+1]=128;
data[3*j+2]=128;
}
toBeBlack=0;
if (nArray[j]==coor) toBeBlack=1;
if (j<255) {
int jump=abs(nArray[j]-nArray[j+1]);
if ( abs(coor-nArray[j]) < jump
&& abs(coor-nArray[j+1]) < jump)
toBeBlack=1;
}
if (toBeBlack) {
data[3*j+0]=0;
data[3*j+1]=0;
data[3*j+2]=0;
}
}
gtk_preview_draw_row( GTK_PREVIEW(preview),data,0,i,256);
}
gtk_widget_draw(preview,NULL);
gdk_flush();
}
void
fp_range_preview_spill(GtkWidget *preview, int type)
{
guchar data[256*3];
int i, j;
hsv R,G,B;
for (i=0; i<RANGE_HEIGHT; i++) {
for (j=0; j<256; j++)
if (!((j+1)%32)) {
data[3*j+0]=255;
data[3*j+1]=128;
data[3*j+2]=128;
}
else
switch (type) {
case BY_VAL:
data[3*j+0]=j-Current.Offset;
data[3*j+1]=j-Current.Offset;
data[3*j+2]=j-Current.Offset;
break;
case BY_HUE:
hsv_to_rgb((hsv)((j-Current.Offset+256)%256)/255.0, 1.0, .5, &R, &G, &B);
data[3*j+0]=R*255;
data[3*j+1]=G*255;
data[3*j+2]=B*255;
break;
case BY_SAT:
hsv_to_rgb(.5,(hsv)((j-(gint)Current.Offset+256)%256)/255.0,.5,&R,&G,&B);
data[3*j+0]=R*255;
data[3*j+1]=G*255;
data[3*j+2]=B*255;
break;
}
gtk_preview_draw_row( GTK_PREVIEW(preview),data,0,i,256);
}
gtk_widget_draw(preview,NULL);
gdk_flush();
}
void fp_Create_Nudge(gint *adjArray)
{
int left, right, middle,i;
/* The following function was determined by trial and error */
double Steepness=pow(1-Current.Alias,4)*.8;
left = (Current.Range == SHADOWS) ? 0 : Current.Cutoffs[Current.Range-1];
right = Current.Cutoffs[Current.Range];
middle = (left + right)/2;
if (Current.Alias!=0)
for (i=0; i<256; i++)
if (i<=middle)
adjArray[i] = MAX_ROUGHNESS *
Current.Rough*(1+tanh(Steepness*(i-left)))/2;
else
adjArray[i] = MAX_ROUGHNESS *
Current.Rough*(1+tanh(Steepness*(right-i)))/2;
else
for (i=0; i<256; i++)
if (left<=i && i<=right)
adjArray[i] = MAX_ROUGHNESS * Current.Rough;
else
adjArray[i] = 0;
}

View File

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
lic

View File

@ -1,39 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = lic
lic_SOURCES = \
lic.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
\
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
lic_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
mathmap

View File

@ -1,38 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = #STD#
#STD#_SOURCES = \
#STD#.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
#STD#_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

View File

@ -1,25 +0,0 @@
CFLAGS=-D_GIMP -Wall -O3
CC = gcc
OBJECTS=mathmap.o builtins.o exprtree.o parser.o scanner.o postfix.o vars.o
mathmap : $(OBJECTS)
$(CC) -o mathmap -lglib -lgdk -lgtk -lgimp -lm $(OBJECTS)
%.o : %.c
$(CC) $(CFLAGS) -c $<
parser.c : parser.y
bison -d parser.y
mv parser.tab.c parser.c
mv parser.tab.h parser.h
scanner.c : scanner.fl
flex scanner.fl
mv lex.yy.c scanner.c
install : mathmap
cp mathmap $(HOME)/.gimp/plug-ins/
clean :
rm -f *~ *.o mathmap scanner.c parser.[ch]

View File

@ -1,801 +0,0 @@
#include <math.h>
#include <string.h>
#ifdef _GIMP
#include <stdlib.h>
#else
#include <libc.h>
#endif
#include "builtins.h"
extern int imageWidth,
imageHeight,
inputBPP;
extern double middleX,
middleY;
extern unsigned char *imageData;
extern double stack[];
extern int stackp;
extern int intersamplingEnabled,
oversamplingEnabled;
builtin *firstBuiltin = 0;
double
color_to_double (unsigned int red, unsigned int green, unsigned int blue, unsigned int alpha)
{
double val;
*(unsigned int*)&val = (alpha << 24) | (red << 16) | (green << 8) | blue;
return val;
}
double
pixel_to_double (unsigned char *pixel)
{
if (inputBPP == 1)
return color_to_double(pixel[0], pixel[0], pixel[0], 255);
else if (inputBPP == 2)
return color_to_double(pixel[0], pixel[0], pixel[0], pixel[1]);
else if (inputBPP == 3)
return color_to_double(pixel[0], pixel[1], pixel[2], 255);
else
return color_to_double(pixel[0], pixel[1], pixel[2], pixel[3]);
}
void
double_to_color (double val, unsigned int *red, unsigned int *green,
unsigned int *blue, unsigned int *alpha)
{
unsigned int color = *(unsigned int*)&val;
*alpha = color >> 24;
*red = (color >> 16) & 0xff;
*green = (color >> 8) & 0xff;
*blue = color & 0xff;
}
unsigned int
alpha_component (double val)
{
unsigned int color = *(unsigned int*)&val;
return color >> 24;
}
unsigned int
red_component (double val)
{
unsigned int color = *(unsigned int*)&val;
return (color >> 16) & 0xff;
}
unsigned int
green_component (double val)
{
unsigned int color = *(unsigned int*)&val;
return (color >> 8) & 0xff;
}
unsigned int
blue_component (double val)
{
unsigned int color = *(unsigned int*)&val;
return color & 0xff;
}
void
builtin_sin (void *arg)
{
stack[stackp - 1] = sin(stack[stackp - 1] * M_PI / 180.0);
}
void
builtin_cos (void *arg)
{
stack[stackp - 1] = cos(stack[stackp - 1] * M_PI / 180.0);
}
void
builtin_tan (void *arg)
{
stack[stackp - 1] = tan(stack[stackp - 1] * M_PI / 180.0);
}
void
builtin_asin (void *arg)
{
stack[stackp - 1] = asin(stack[stackp - 1]) * 180.0 / M_PI;
}
void
builtin_acos (void *arg)
{
stack[stackp - 1] = acos(stack[stackp - 1]) * 180.0 / M_PI;
}
void
builtin_atan (void *arg)
{
stack[stackp - 1] = atan(stack[stackp - 1]) * 180.0 / M_PI;
}
void
builtin_pow (void *arg)
{
stack[stackp - 2] = pow(stack[stackp - 2], stack[stackp - 1]);
--stackp;
}
void
builtin_abs (void *arg)
{
stack[stackp - 1] = fabs(stack[stackp - 1]);
}
void
builtin_floor (void *arg)
{
stack[stackp - 1] = floor(stack[stackp - 1]);
}
void
builtin_sign (void *arg)
{
if (stack[stackp - 1] < 0)
stack[stackp - 1] = -1.0;
else if (stack[stackp - 1] > 0)
stack[stackp - 1] = 1.0;
else
stack[stackp - 1] = 0.0;
}
void
builtin_min (void *arg)
{
if (stack[stackp - 2] >= stack[stackp - 1])
stack[stackp - 2] = stack[stackp - 1];
--stackp;
}
void
builtin_max (void *arg)
{
if (stack[stackp - 2] <= stack[stackp - 1])
stack[stackp - 2] = stack[stackp - 1];
--stackp;
}
void
builtin_not (void *arg)
{
if (stack[stackp - 1] != 0.0)
stack[stackp - 1] = 0.0;
else
stack[stackp - 1] = 1.0;
}
void
builtin_or (void *arg)
{
if (stack[stackp - 2] || stack[stackp - 1])
stack[stackp - 2] = 1.0;
else
stack[stackp - 2] = 0.0;
--stackp;
}
void
builtin_and (void *arg)
{
if (stack[stackp - 2] && stack[stackp - 1])
stack[stackp - 2] = 1.0;
else
stack[stackp - 2] = 0.0;
--stackp;
}
void
builtin_equal (void *arg)
{
if (stack[stackp - 2] == stack[stackp - 1])
stack[stackp - 2] = 1.0;
else
stack[stackp - 2] = 0.0;
--stackp;
}
void
builtin_less (void *arg)
{
if (stack[stackp - 2] < stack[stackp - 1])
stack[stackp - 2] = 1.0;
else
stack[stackp - 2] = 0.0;
--stackp;
}
void
builtin_greater (void *arg)
{
if (stack[stackp - 2] > stack[stackp - 1])
stack[stackp - 2] = 1.0;
else
stack[stackp - 2] = 0.0;
--stackp;
}
void
builtin_lessequal (void *arg)
{
if (stack[stackp - 2] <= stack[stackp - 1])
stack[stackp - 2] = 1.0;
else
stack[stackp - 2] = 0.0;
--stackp;
}
void
builtin_greaterequal (void *arg)
{
if (stack[stackp - 2] >= stack[stackp - 1])
stack[stackp - 2] = 1.0;
else
stack[stackp - 2] = 0.0;
--stackp;
}
void
builtin_notequal (void *arg)
{
if (stack[stackp - 2] != stack[stackp - 1])
stack[stackp - 2] = 1.0;
else
stack[stackp - 2] = 0.0;
--stackp;
}
void
builtin_inintv (void *arg)
{
if (stack[stackp - 3] >= stack[stackp - 2] && stack[stackp - 3] <= stack[stackp - 1])
stack[stackp - 3] = 1.0;
else
stack[stackp - 3] = 0.0;
stackp -= 2;
}
void
builtin_rand (void *arg)
{
stack[stackp - 2] = (random() / (double)0x7fffffff)
* (stack[stackp - 1] - stack[stackp - 2]) + stack[stackp - 2];
--stackp;
}
#ifdef _GIMP
void mathmap_get_pixel (int x, int y, unsigned char *pixel);
extern int originX,
originY,
wholeImageWidth,
wholeImageHeight;
void
builtin_origValXY (void *arg)
{
double x = stack[stackp - 2],
y = stack[stackp - 1];
unsigned char pixel[4];
if (!oversamplingEnabled)
{
x += 0.5;
y += 0.5;
}
mathmap_get_pixel(floor(x + originX + middleX), floor(y + originY + middleY), pixel);
stack[stackp - 2] = pixel_to_double(pixel);
--stackp;
}
void
builtin_origValXYIntersample (void *arg)
{
double x = stack[stackp - 2] + middleX + originX,
y = stack[stackp - 1] + middleY + originY;
int x1 = floor(x),
x2 = x1 + 1,
y1 = floor(y),
y2 = y1 + 1;
double x2fact = (x - x1),
y2fact = (y - y1),
x1fact = 1.0 - x2fact,
y1fact = 1.0 - y2fact,
p1fact = x1fact * y1fact,
p2fact = x1fact * y2fact,
p3fact = x2fact * y1fact,
p4fact = x2fact * y2fact;
static unsigned char blackPixel[4] = { 0, 0, 0, 0 };
unsigned char pixel1a[4],
pixel2a[4],
pixel3a[4],
pixel4a[4],
resultPixel[4];
unsigned char *pixel1 = pixel1a,
*pixel2 = pixel2a,
*pixel3 = pixel3a,
*pixel4 = pixel4a;
int i;
if (x1 < 0 || x1 >= wholeImageWidth || y1 < 0 || y1 >= wholeImageHeight)
pixel1 = blackPixel;
else
mathmap_get_pixel(x1, y1, pixel1);
if (x1 < 0 || x1 >= wholeImageWidth || y2 < 0 || y2 >= wholeImageHeight)
pixel2 = blackPixel;
else
mathmap_get_pixel(x1, y2, pixel2);
if (x2 < 0 || x2 >= wholeImageWidth || y1 < 0 || y1 >= wholeImageHeight)
pixel3 = blackPixel;
else
mathmap_get_pixel(x2, y1, pixel3);
if (x2 < 0 || x2 >= wholeImageWidth || y2 < 0 || y2 >= wholeImageHeight)
pixel4 = blackPixel;
else
mathmap_get_pixel(x2, y2, pixel4);
for (i = 0; i < inputBPP; ++i)
resultPixel[i] = pixel1[i] * p1fact
+ pixel2[i] * p2fact
+ pixel3[i] * p3fact
+ pixel4[i] * p4fact;
stack[stackp - 2] = pixel_to_double(resultPixel);
--stackp;
}
void
builtin_origValRA (void *arg)
{
double x = cos(stack[stackp - 1] * M_PI / 180) * stack[stackp - 2] + middleX,
y = sin(stack[stackp - 1] * M_PI / 180) * stack[stackp - 2] + middleY;
unsigned char pixel[4];
if (!oversamplingEnabled)
{
x += 0.5;
y += 0.5;
}
mathmap_get_pixel(floor(x + originX), floor(y + originY), pixel);
stack[stackp - 2] = pixel_to_double(pixel);
--stackp;
}
void
builtin_origValRAIntersample (void *arg)
{
double x = cos(stack[stackp - 1] * M_PI / 180) * stack[stackp - 2] + middleX + originX,
y = sin(stack[stackp - 1] * M_PI / 180) * stack[stackp - 2] + middleY + originY;
int x1 = floor(x),
x2 = x1 + 1,
y1 = floor(y),
y2 = y1 + 1;
double x2fact = (x - x1),
y2fact = (y - y1),
x1fact = 1.0 - x2fact,
y1fact = 1.0 - y2fact,
p1fact = x1fact * y1fact,
p2fact = x1fact * y2fact,
p3fact = x2fact * y1fact,
p4fact = x2fact * y2fact;
static unsigned char blackPixel[4] = { 0, 0, 0, 0 };
unsigned char pixel1a[4],
pixel2a[4],
pixel3a[4],
pixel4a[4],
resultPixel[4];
unsigned char *pixel1 = pixel1a,
*pixel2 = pixel2a,
*pixel3 = pixel3a,
*pixel4 = pixel4a;
int i;
if (x1 < 0 || x1 >= wholeImageWidth || y1 < 0 || y1 >= wholeImageHeight)
pixel1 = blackPixel;
else
mathmap_get_pixel(x1, y1, pixel1);
if (x1 < 0 || x1 >= wholeImageWidth || y2 < 0 || y2 >= wholeImageHeight)
pixel2 = blackPixel;
else
mathmap_get_pixel(x1, y2, pixel2);
if (x2 < 0 || x2 >= wholeImageWidth || y1 < 0 || y1 >= wholeImageHeight)
pixel3 = blackPixel;
else
mathmap_get_pixel(x2, y1, pixel3);
if (x2 < 0 || x2 >= wholeImageWidth || y2 < 0 || y2 >= wholeImageHeight)
pixel4 = blackPixel;
else
mathmap_get_pixel(x2, y2, pixel4);
for (i = 0; i < inputBPP; ++i)
resultPixel[i] = pixel1[i] * p1fact
+ pixel2[i] * p2fact
+ pixel3[i] * p3fact
+ pixel4[i] * p4fact;
stack[stackp - 2] = pixel_to_double(resultPixel);
--stackp;
}
#else
void
builtin_origValXY (void *arg)
{
int x = stack[stackp - 2] + middleX,
y = stack[stackp - 1] + middleY;
unsigned char *pixel;
if (x < 0 || y < 0 || x >= imageWidth || y >= imageHeight)
{
stack[stackp - 2] = 0.0;
--stackp;
return;
}
pixel = imageData + (y * imageWidth + x) * 3;
stack[stackp - 2] = color_to_double(pixel[0], pixel[1], pixel[2]);
--stackp;
}
void
builtin_origValXYIntersample (void *arg)
{
double x = stack[stackp - 2] + middleX,
y = stack[stackp - 1] + middleY;
int x1 = floor(x),
x2 = x1 + 1,
y1 = floor(y),
y2 = y1 + 1;
double x2fact = (x - x1),
y2fact = (y - y1),
x1fact = 1.0 - x2fact,
y1fact = 1.0 - y2fact,
p1fact = x1fact * y1fact,
p2fact = x1fact * y2fact,
p3fact = x2fact * y1fact,
p4fact = x2fact * y2fact;
static unsigned char blackPixel[] = { 0, 0, 0 };
unsigned char *pixel1,
*pixel2,
*pixel3,
*pixel4;
int red,
green,
blue;
if (x1 < 0 || x1 >= imageWidth || y1 < 0 || y1 >= imageHeight)
pixel1 = blackPixel;
else
pixel1 = imageData + (y1 * imageWidth + x1) * 3;
if (x1 < 0 || x1 >= imageWidth || y2 < 0 || y2 >= imageHeight)
pixel2 = blackPixel;
else
pixel2 = imageData + (y2 * imageWidth + x1) * 3;
if (x2 < 0 || x2 >= imageWidth || y1 < 0 || y1 >= imageHeight)
pixel3 = blackPixel;
else
pixel3 = imageData + (y1 * imageWidth + x2) * 3;
if (x2 < 0 || x2 >= imageWidth || y2 < 0 || y2 >= imageHeight)
pixel4 = blackPixel;
else
pixel4 = imageData + (y2 * imageWidth + x2) * 3;
red = pixel1[0] * p1fact + pixel2[0] * p2fact + pixel3[0] * p3fact + pixel4[0] * p4fact;
green = pixel1[1] * p1fact + pixel2[1] * p2fact + pixel3[1] * p3fact + pixel4[1] * p4fact;
blue = pixel1[2] * p1fact + pixel2[2] * p2fact + pixel3[2] * p3fact + pixel4[2] * p4fact;
stack[stackp - 2] = color_to_double(red, green, blue);
--stackp;
}
void
builtin_origValRA (void *arg)
{
int x = cos(stack[stackp - 1] * M_PI / 180) * stack[stackp - 2] + middleX,
y = sin(stack[stackp - 1] * M_PI / 180) * stack[stackp - 2] + middleY;
unsigned char *pixel;
if (x < 0 || y < 0 || x >= imageWidth || y >= imageHeight)
{
stack[stackp - 2] = 0.0;
--stackp;
return;
}
pixel = imageData + (y * imageWidth + x) * 3;
stack[stackp - 2] = color_to_double(pixel[0], pixel[1], pixel[2]);
--stackp;
}
void
builtin_origValRAIntersample (void *arg)
{
double x = cos(stack[stackp - 1] * M_PI / 180) * stack[stackp - 2] + middleX,
y = sin(stack[stackp - 1] * M_PI / 180) * stack[stackp - 2] + middleY;
int x1 = floor(x),
x2 = x1 + 1,
y1 = floor(y),
y2 = y1 + 1;
double x2fact = (x - x1),
y2fact = (y - y1),
x1fact = 1.0 - x2fact,
y1fact = 1.0 - y2fact,
p1fact = x1fact * y1fact,
p2fact = x1fact * y2fact,
p3fact = x2fact * y1fact,
p4fact = x2fact * y2fact;
static unsigned char blackPixel[] = { 0, 0, 0 };
unsigned char *pixel1,
*pixel2,
*pixel3,
*pixel4;
int red,
green,
blue;
if (x1 < 0 || x1 >= imageWidth || y1 < 0 || y1 >= imageHeight)
pixel1 = blackPixel;
else
pixel1 = imageData + (y1 * imageWidth + x1) * 3;
if (x1 < 0 || x1 >= imageWidth || y2 < 0 || y2 >= imageHeight)
pixel2 = blackPixel;
else
pixel2 = imageData + (y2 * imageWidth + x1) * 3;
if (x2 < 0 || x2 >= imageWidth || y1 < 0 || y1 >= imageHeight)
pixel3 = blackPixel;
else
pixel3 = imageData + (y1 * imageWidth + x2) * 3;
if (x2 < 0 || x2 >= imageWidth || y2 < 0 || y2 >= imageHeight)
pixel4 = blackPixel;
else
pixel4 = imageData + (y2 * imageWidth + x2) * 3;
red = pixel1[0] * p1fact + pixel2[0] * p2fact + pixel3[0] * p3fact + pixel4[0] * p4fact;
green = pixel1[1] * p1fact + pixel2[1] * p2fact + pixel3[1] * p3fact + pixel4[1] * p4fact;
blue = pixel1[2] * p1fact + pixel2[2] * p2fact + pixel3[2] * p3fact + pixel4[2] * p4fact;
stack[stackp - 2] = color_to_double(red, green, blue);
--stackp;
}
#endif /* _GIMP */
void
builtin_red (void *arg)
{
stack[stackp - 1] = red_component(stack[stackp - 1]) / 255.0;
}
void
builtin_green (void *arg)
{
stack[stackp - 1] = green_component(stack[stackp - 1]) / 255.0;
}
void
builtin_blue (void *arg)
{
stack[stackp - 1] = blue_component(stack[stackp - 1]) / 255.0;
}
void
builtin_gray (void *arg)
{
int red,
green,
blue,
alpha;
double_to_color(stack[stackp - 1], &red, &green, &blue, &alpha);
stack[stackp - 1] = (0.299 * red + 0.587 * green + 0.114 * blue) / 255.0;
}
void
builtin_alpha (void *arg)
{
stack[stackp - 1] = alpha_component(stack[stackp - 1]) / 255.0;
}
void
builtin_rgbColor (void *arg)
{
int redComponent = stack[stackp - 3] * 255,
greenComponent = stack[stackp - 2] * 255,
blueComponent = stack[stackp - 1] * 255;
stackp -= 2;
if (redComponent < 0)
redComponent = 0;
else if (redComponent > 255)
redComponent = 255;
if (greenComponent < 0)
greenComponent = 0;
else if (greenComponent > 255)
greenComponent = 255;
if (blueComponent < 0)
blueComponent = 0;
else if (blueComponent > 255)
blueComponent = 255;
stack[stackp - 1] = color_to_double(redComponent, greenComponent, blueComponent, 255);
}
void
builtin_rgbaColor (void *arg)
{
int redComponent = stack[stackp - 4] * 255,
greenComponent = stack[stackp - 3] * 255,
blueComponent = stack[stackp - 2] * 255,
alphaComponent = stack[stackp - 1] * 255;
stackp -= 3;
if (redComponent < 0)
redComponent = 0;
else if (redComponent > 255)
redComponent = 255;
if (greenComponent < 0)
greenComponent = 0;
else if (greenComponent > 255)
greenComponent = 255;
if (blueComponent < 0)
blueComponent = 0;
else if (blueComponent > 255)
blueComponent = 255;
if (alphaComponent < 0)
alphaComponent = 0;
else if (alphaComponent > 255)
alphaComponent = 255;
stack[stackp - 1] = color_to_double(redComponent, greenComponent,
blueComponent, alphaComponent);
}
void
builtin_grayColor (void *arg)
{
int grayLevel = stack[stackp - 1] * 255;
if (grayLevel < 0)
grayLevel = 0;
else if (grayLevel > 255)
grayLevel = 255;
stack[stackp - 1] = color_to_double(grayLevel, grayLevel, grayLevel, 255);
}
void
builtin_grayaColor (void *arg)
{
int grayLevel = stack[stackp - 2] * 255,
alphaComponent = stack[stackp - 1] * 255;
--stackp;
if (grayLevel < 0)
grayLevel = 0;
else if (grayLevel > 255)
grayLevel = 255;
if (alphaComponent < 0)
alphaComponent = 0;
else if (alphaComponent > 255)
alphaComponent = 255;
stack[stackp - 1] = color_to_double(grayLevel, grayLevel, grayLevel, alphaComponent);
}
builtin*
builtin_with_name (const char *name)
{
builtin *next;
if (intersamplingEnabled)
{
if (strcmp(name, "origValXY") == 0)
return builtin_with_name("origValXYIntersample");
else if (strcmp(name, "origValRA") == 0)
return builtin_with_name("origValRAIntersample");
}
for (next = firstBuiltin; next != 0; next = next->next)
if (strcmp(name, next->name) == 0)
return next;
return 0;
}
void
register_builtin (const char *name, builtinFunction function, int numParams)
{
builtin *theBuiltin = (builtin*)malloc(sizeof(builtin));
strncpy(theBuiltin->name, name, MAX_BUILTIN_LENGTH);
theBuiltin->name[MAX_BUILTIN_LENGTH] = '\0';
theBuiltin->function = function;
theBuiltin->numParams = numParams;
theBuiltin->next = firstBuiltin;
firstBuiltin = theBuiltin;
}
void
init_builtins (void)
{
register_builtin("sin", builtin_sin, 1);
register_builtin("cos", builtin_cos, 1);
register_builtin("tan", builtin_tan, 1);
register_builtin("asin", builtin_asin, 1);
register_builtin("acos", builtin_acos, 1);
register_builtin("atan", builtin_atan, 1);
register_builtin("pow", builtin_pow, 2);
register_builtin("abs", builtin_abs, 1);
register_builtin("floor", builtin_floor, 1);
register_builtin("sign", builtin_sign, 1);
register_builtin("min", builtin_min, 2);
register_builtin("max", builtin_max, 2);
register_builtin("not", builtin_not, 1);
register_builtin("or", builtin_or, 2);
register_builtin("and", builtin_and, 2);
register_builtin("equal", builtin_equal, 2);
register_builtin("less", builtin_less, 2);
register_builtin("greater", builtin_greater, 2);
register_builtin("lessequal", builtin_lessequal, 2);
register_builtin("greaterequal", builtin_greaterequal, 2);
register_builtin("notequal", builtin_notequal, 2);
register_builtin("inintv", builtin_inintv, 3);
register_builtin("rand", builtin_rand, 2);
register_builtin("origValXY", builtin_origValXY, 2);
register_builtin("origValXYIntersample", builtin_origValXYIntersample, 2);
register_builtin("origValRA", builtin_origValRA, 2);
register_builtin("origValRAIntersample", builtin_origValRAIntersample, 2);
register_builtin("red", builtin_red, 1);
register_builtin("green", builtin_green, 1);
register_builtin("blue", builtin_blue, 1);
register_builtin("gray", builtin_gray, 1);
register_builtin("alpha", builtin_alpha, 1);
register_builtin("rgbColor", builtin_rgbColor, 3);
register_builtin("rgbaColor", builtin_rgbaColor, 4);
register_builtin("grayColor", builtin_grayColor, 1);
register_builtin("grayaColor", builtin_grayaColor, 2);
}

View File

@ -1,27 +0,0 @@
/* -*- c -*- */
#ifndef __BUILTINS_H__
#define __BUILTINS_H__
#define MAX_BUILTIN_LENGTH 63
typedef void (*builtinFunction) (void*);
typedef struct _builtin
{
char name[MAX_BUILTIN_LENGTH + 1];
builtinFunction function;
int numParams;
struct _builtin *next;
} builtin;
double color_to_double (unsigned int red, unsigned int green,
unsigned int blue, unsigned int alpha);
void double_to_color (double val, unsigned int *red, unsigned int *green,
unsigned int *blue, unsigned int *alpha);
builtin* builtin_with_name (const char *name);
void init_builtins (void);
#endif

View File

@ -1,197 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "exprtree.h"
#include "builtins.h"
extern double currentX,
currentY,
currentR,
currentA;
extern int imageWidth,
imageHeight;
extern int usesRA;
extern int intersamplingEnabled;
exprtree*
make_number (double num)
{
exprtree *tree = (exprtree*)malloc(sizeof(exprtree));
tree->type = EXPR_NUMBER;
tree->val.number = num;
tree->next = 0;
return tree;
}
exprtree*
make_var (char *name)
{
exprtree *tree = (exprtree*)malloc(sizeof(exprtree));
if (strcmp(name, "x") == 0)
tree->type = EXPR_VAR_X;
else if (strcmp(name, "y") == 0)
tree->type = EXPR_VAR_Y;
else if (strcmp(name, "t") == 0)
tree->type = EXPR_VAR_T;
else if (strcmp(name, "r") == 0)
{
tree->type = EXPR_VAR_R;
usesRA = 1;
}
else if (strcmp(name, "a") == 0)
{
tree->type = EXPR_VAR_A;
usesRA = 1;
}
else if (strcmp(name, "W") == 0)
tree->type = EXPR_VAR_W;
else if (strcmp(name, "H") == 0)
tree->type = EXPR_VAR_H;
else if (strcmp(name, "R") == 0)
tree->type = EXPR_VAR_BIG_R;
else if (strcmp(name, "X") == 0)
tree->type = EXPR_VAR_BIG_X;
else if (strcmp(name, "Y") == 0)
tree->type = EXPR_VAR_BIG_Y;
else
{
tree->type = EXPR_VARIABLE;
tree->val.var = register_variable(name);
}
tree->next = 0;
return tree;
}
exprtree*
make_operator (int type, exprtree *left, exprtree *right)
{
exprtree *tree = (exprtree*)malloc(sizeof(exprtree));
tree->type = type;
tree->val.operator.left = left;
tree->val.operator.right = right;
tree->next = 0;
return tree;
}
exprtree*
make_function (builtin *theBuiltin, exprtree *args)
{
exprtree *tree = (exprtree*)malloc(sizeof(exprtree));
tree->type = EXPR_FUNC;
tree->val.func.routine = theBuiltin->function;
tree->val.func.numArgs = theBuiltin->numParams;
tree->val.func.args = args;
tree->next = 0;
return tree;
}
exprtree*
make_sequence (exprtree *left, exprtree *right)
{
exprtree *tree = (exprtree*)malloc(sizeof(exprtree));
tree->type = EXPR_SEQUENCE;
tree->val.operator.left = left;
tree->val.operator.right = right;
tree->next = 0;
return tree;
}
exprtree*
make_assignment (char *name, exprtree *value)
{
exprtree *tree = (exprtree*)malloc(sizeof(exprtree));
variable *var = register_variable(name);
tree->type = EXPR_ASSIGNMENT;
tree->val.assignment.var = var;
tree->val.assignment.value = value;
tree->next = 0;
return tree;
}
exprtree*
make_if_then (exprtree *condition, exprtree *consequence)
{
exprtree *tree = (exprtree*)malloc(sizeof(exprtree));
tree->type = EXPR_IF_THEN;
tree->val.ifExpr.condition = condition;
tree->val.ifExpr.consequence = consequence;
tree->next = 0;
return tree;
}
exprtree*
make_if_then_else (exprtree *condition, exprtree *consequence, exprtree *alternative)
{
exprtree *tree = (exprtree*)malloc(sizeof(exprtree));
tree->type = EXPR_IF_THEN_ELSE;
tree->val.ifExpr.condition = condition;
tree->val.ifExpr.consequence = consequence;
tree->val.ifExpr.alternative = alternative;
tree->next = 0;
return tree;
}
exprtree*
make_while (exprtree *invariant, exprtree *body)
{
exprtree *tree = (exprtree*)malloc(sizeof(exprtree));
tree->type = EXPR_WHILE;
tree->val.whileExpr.invariant = invariant;
tree->val.whileExpr.body = body;
tree->next = 0;
return tree;
}
exprtree*
make_do_while (exprtree *body, exprtree *invariant)
{
exprtree *tree = (exprtree*)malloc(sizeof(exprtree));
tree->type = EXPR_DO_WHILE;
tree->val.whileExpr.invariant = invariant;
tree->val.whileExpr.body = body;
tree->next = 0;
return tree;
}
exprtree*
arglist_append (exprtree *list1, exprtree *list2)
{
exprtree *tree = list1;
while (tree->next != 0)
tree = tree->next;
tree->next = list2;
return list1;
}

View File

@ -1,102 +0,0 @@
#ifndef __EXPRTREE_H__
#define __EXPRTREE_H__
#include "vars.h"
#include "builtins.h"
#ifdef USE_TREE
typedef double (*function) (double*);
#else
typedef void (*function) (void*);
#endif
#define MAX_IDENT_LENGTH 63
typedef char ident[MAX_IDENT_LENGTH + 1];
typedef struct _exprtree
{
int type;
union
{
double number;
variable *var;
struct
{
int numArgs;
function routine;
struct _exprtree *args;
} func;
struct
{
struct _exprtree *left;
struct _exprtree *right;
} operator;
struct
{
variable *var;
struct _exprtree *value;
} assignment;
struct
{
struct _exprtree *condition;
struct _exprtree *consequence;
struct _exprtree *alternative;
int label1;
int label2;
} ifExpr;
struct
{
struct _exprtree *invariant;
struct _exprtree *body;
int label1;
int label2;
} whileExpr;
} val;
struct _exprtree *next;
} exprtree;
#define EXPR_NUMBER 1
#define EXPR_ADD 2
#define EXPR_SUB 3
#define EXPR_MUL 4
#define EXPR_DIV 5
#define EXPR_MOD 6
#define EXPR_NEG 7
#define EXPR_FUNC 8
#define EXPR_VAR_X 9
#define EXPR_VAR_Y 10
#define EXPR_VAR_T 11
#define EXPR_VAR_R 12
#define EXPR_VAR_A 13
#define EXPR_VAR_W 14
#define EXPR_VAR_H 15
#define EXPR_VAR_BIG_R 16
#define EXPR_VAR_BIG_X 17
#define EXPR_VAR_BIG_Y 18
#define EXPR_SEQUENCE 19
#define EXPR_ASSIGNMENT 20
#define EXPR_VARIABLE 21
#define EXPR_IF_THEN 22
#define EXPR_IF_THEN_ELSE 23
#define EXPR_WHILE 24
#define EXPR_DO_WHILE 25
exprtree* make_number (double num);
exprtree* make_var (char *name);
exprtree* make_operator (int type, exprtree *left, exprtree *right);
exprtree* make_function (builtin *theBuiltin, exprtree *args);
exprtree* make_sequence (exprtree *left, exprtree *right);
exprtree* make_assignment (char *name, exprtree *value);
exprtree* make_if_then (exprtree *condition, exprtree *conclusion);
exprtree* make_if_then_else (exprtree *condition, exprtree *conclusion, exprtree *alternative);
exprtree* make_while (exprtree *invariant, exprtree *body);
exprtree* make_do_while (exprtree *body, exprtree *invariant);
exprtree* arglist_append (exprtree *list1, exprtree *list2);
double eval_exprtree (exprtree *tree);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,102 +0,0 @@
%{
#include <stdio.h>
#include "exprtree.h"
#include "builtins.h"
extern exprtree *theExprtree;
%}
%union {
ident ident;
exprtree *exprtree;
builtin *builtin;
}
%token T_IDENT T_NUMBER
%token T_IF T_THEN T_ELSE T_END
%token T_WHILE T_DO
%token T_BUILTIN
%right ';'
%right '='
%left T_OR T_AND
%left T_EQUAL '<' '>' T_LESSEQUAL T_GREATEREQUAL T_NOTEQUAL
%left '+' '-'
%left '*' '/' '%'
%left UNARY
%%
start : expr { theExprtree = $<exprtree>1; }
;
expr : T_NUMBER { $<exprtree>$ = $<exprtree>1; }
| T_IDENT { $<exprtree>$ = make_var($<ident>1); }
| expr '+' expr { $<exprtree>$ = make_operator(EXPR_ADD,
$<exprtree>1, $<exprtree>3); }
| expr '-' expr { $<exprtree>$ = make_operator(EXPR_SUB,
$<exprtree>1, $<exprtree>3); }
| expr '*' expr { $<exprtree>$ = make_operator(EXPR_MUL,
$<exprtree>1, $<exprtree>3); }
| expr '/' expr { $<exprtree>$ = make_operator(EXPR_DIV,
$<exprtree>1, $<exprtree>3); }
| expr '%' expr { $<exprtree>$ = make_operator(EXPR_MOD,
$<exprtree>1, $<exprtree>3); }
| expr T_EQUAL expr { $<exprtree>$ = make_function(builtin_with_name("equal"),
arglist_append($<exprtree>1, $<exprtree>3)); }
| expr '<' expr { $<exprtree>$ = make_function(builtin_with_name("less"),
arglist_append($<exprtree>1, $<exprtree>3)); }
| expr '>' expr { $<exprtree>$ = make_function(builtin_with_name("greater"),
arglist_append($<exprtree>1, $<exprtree>3)); }
| expr T_LESSEQUAL expr
{ $<exprtree>$ = make_function(builtin_with_name("lessequal"),
arglist_append($<exprtree>1, $<exprtree>3)); }
| expr T_GREATEREQUAL expr
{ $<exprtree>$ = make_function(builtin_with_name("greaterequal"),
arglist_append($<exprtree>1, $<exprtree>3)); }
| expr T_NOTEQUAL expr
{ $<exprtree>$ = make_function(builtin_with_name("notequal"),
arglist_append($<exprtree>1, $<exprtree>3)); }
| expr T_OR expr { $<exprtree>$ = make_function(builtin_with_name("or"),
arglist_append($<exprtree>1, $<exprtree>3)); }
| expr T_AND expr { $<exprtree>$ = make_function(builtin_with_name("and"),
arglist_append($<exprtree>1, $<exprtree>3)); }
| '-' expr %prec UNARY
{ $<exprtree>$ = make_operator(EXPR_NEG, $<exprtree>2, 0); }
| '!' expr %prec UNARY
{ $<exprtree>$ = make_function(builtin_with_name("not"), $<exprtree>2); }
| '(' expr ')' { $<exprtree>$ = $<exprtree>2; };
| T_BUILTIN '(' arglist ')'
{ $<exprtree>$ = make_function($<builtin>1, $<exprtree>3); }
| T_IDENT '=' expr { $<exprtree>$ = make_assignment($<ident>1, $<exprtree>3); }
| expr ';' expr { $<exprtree>$ = make_sequence($<exprtree>1, $<exprtree>3); }
| T_IF expr T_THEN expr T_END
{ $<exprtree>$ = make_if_then($<exprtree>2, $<exprtree>4); }
| T_IF expr T_THEN expr T_ELSE expr T_END
{ $<exprtree>$ = make_if_then_else($<exprtree>2,
$<exprtree>4,
$<exprtree>6); }
| T_WHILE expr T_DO expr T_END
{ $<exprtree>$ = make_while($<exprtree>2, $<exprtree>4); }
| T_DO expr T_WHILE expr T_END
{ $<exprtree>$ = make_do_while($<exprtree>2, $<exprtree>4); }
;
arglist : { $<exprtree>$ = 0; }
| args { $<exprtree>$ = $<exprtree>1; }
;
args : expr { $<exprtree>$ = $<exprtree>1; }
| args ',' expr { $<exprtree>$ = arglist_append($<exprtree>1, $<exprtree>3); }
;
%%
int
yyerror (char *s)
{
fprintf(stderr, "%s\n", s);
return 0;
}

View File

@ -1,567 +0,0 @@
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include "builtins.h"
#include "vars.h"
#include "postfix.h"
extern double currentX,
currentY,
currentT,
currentR,
currentA,
imageR,
imageX,
imageY;
extern int imageWidth,
imageHeight;
#define STACKSIZE 128
#define EXPRSIZE 256
double stack[STACKSIZE];
int stackp;
postfix expression[EXPRSIZE];
int exprp,
exprlen;
void
stack_push (double *arg)
{
stack[stackp++] = *arg;
}
void
stack_pop (void *arg)
{
--stackp;
}
void
stack_jmp (int *arg)
{
exprp = *arg - 1;
}
void
stack_jez (int *arg)
{
if (stack[--stackp] == 0.0)
exprp = *arg - 1;
}
void
stack_jnez (int *arg)
{
if (stack[--stackp] != 0.0)
exprp = *arg - 1;
}
void
stack_add (void *arg)
{
stack[stackp - 2] = stack[stackp - 2] + stack[stackp - 1];
--stackp;
}
void
stack_add_i (double *arg)
{
stack[stackp - 1] += *arg;
}
void
stack_sub (void *arg)
{
stack[stackp - 2] = stack[stackp - 2] - stack[stackp - 1];
--stackp;
}
void
stack_sub_i (double *arg)
{
stack[stackp - 1] -= *arg;
}
void
stack_neg (void *arg)
{
stack[stackp - 1] = -stack[stackp - 1];
}
void
stack_mul (void *arg)
{
stack[stackp - 2] = stack[stackp - 2] * stack[stackp - 1];
--stackp;
}
void
stack_mul_i (double *arg)
{
stack[stackp - 1] *= *arg;
}
void
stack_div (void *arg)
{
stack[stackp - 2] = stack[stackp - 2] / stack[stackp - 1];
--stackp;
}
void
stack_div_i (double *arg)
{
stack[stackp - 1] /= *arg;
}
void
stack_mod (void *arg)
{
stack[stackp - 2] = fmod(stack[stackp - 2], stack[stackp - 1]);
--stackp;
}
void
stack_mod_i (double *arg)
{
stack[stackp - 1] = fmod(stack[stackp - 1], *arg);
}
void
stack_var_x (void *arg)
{
stack[stackp++] = currentX;
}
void
stack_var_y (void *arg)
{
stack[stackp++] = currentY;
}
void
stack_var_t (void *arg)
{
stack[stackp++] = currentT;
}
void
stack_var_r (void *arg)
{
stack[stackp++] = currentR;
}
void
stack_var_a (void *arg)
{
stack[stackp++] = currentA;
}
void
stack_var_w (void *arg)
{
stack[stackp++] = imageWidth;
}
void
stack_var_h (void *arg)
{
stack[stackp++] = imageHeight;
}
void
stack_var_big_r (void *arg)
{
stack[stackp++] = imageR;
}
void
stack_var_big_x (void *arg)
{
stack[stackp++] = imageX;
}
void
stack_var_big_y (void *arg)
{
stack[stackp++] = imageY;
}
void
stack_variable (variable *var)
{
stack[stackp++] = var->value;
}
void
stack_assign (variable *var)
{
var->value = stack[stackp - 1];
}
void
make_postfix_recursive (exprtree *tree)
{
static double theZeroValue = 0.0;
switch (tree->type)
{
case EXPR_NUMBER :
expression[exprp].func = (stackfunc)stack_push;
expression[exprp].arg = &tree->val.number;
++exprp;
break;
case EXPR_ADD :
make_postfix_recursive(tree->val.operator.left);
if (tree->val.operator.right->type == EXPR_NUMBER)
{
expression[exprp].func = (stackfunc)stack_add_i;
expression[exprp].arg = &tree->val.operator.right->val.number;
}
else
{
make_postfix_recursive(tree->val.operator.right);
expression[exprp].func = stack_add;
}
++exprp;
break;
case EXPR_SUB :
make_postfix_recursive(tree->val.operator.left);
if (tree->val.operator.right->type == EXPR_NUMBER)
{
expression[exprp].func = (stackfunc)stack_sub_i;
expression[exprp].arg = &tree->val.operator.right->val.number;
}
else
{
make_postfix_recursive(tree->val.operator.right);
expression[exprp].func = stack_sub;
}
++exprp;
break;
case EXPR_NEG :
/*
if (tree->val.operator.left->type == EXPR_NUMBER)
{
expression[exprp].func = (stackfunc)stack_push;
expression[exprp].arg = -tree->val.operator.left->val.number;
}
else
{ */
make_postfix_recursive(tree->val.operator.left);
expression[exprp].func = stack_neg;
/* } */
++exprp;
break;
case EXPR_MUL :
make_postfix_recursive(tree->val.operator.left);
if (tree->val.operator.right->type == EXPR_NUMBER)
{
expression[exprp].func = (stackfunc)stack_mul_i;
expression[exprp].arg = &tree->val.operator.right->val.number;
}
else
{
make_postfix_recursive(tree->val.operator.right);
expression[exprp].func = stack_mul;
}
++exprp;
break;
case EXPR_DIV :
make_postfix_recursive(tree->val.operator.left);
if (tree->val.operator.right->type == EXPR_NUMBER)
{
expression[exprp].func = (stackfunc)stack_div_i;
expression[exprp].arg = &tree->val.operator.right->val.number;
}
else
{
make_postfix_recursive(tree->val.operator.right);
expression[exprp].func = stack_div;
}
++exprp;
break;
case EXPR_MOD :
make_postfix_recursive(tree->val.operator.left);
if (tree->val.operator.right->type == EXPR_NUMBER)
{
expression[exprp].func = (stackfunc)stack_mod_i;
expression[exprp].arg = &tree->val.operator.right->val.number;
}
else
{
make_postfix_recursive(tree->val.operator.right);
expression[exprp].func = stack_mod;
}
++exprp;
break;
case EXPR_VAR_X :
expression[exprp++].func = stack_var_x;
break;
case EXPR_VAR_Y :
expression[exprp++].func = stack_var_y;
break;
case EXPR_VAR_T :
expression[exprp++].func = stack_var_t;
break;
case EXPR_VAR_R :
expression[exprp++].func = stack_var_r;
break;
case EXPR_VAR_A :
expression[exprp++].func = stack_var_a;
break;
case EXPR_VAR_W :
expression[exprp++].func = stack_var_w;
break;
case EXPR_VAR_H :
expression[exprp++].func = stack_var_h;
break;
case EXPR_VAR_BIG_R :
expression[exprp++].func = stack_var_big_r;
break;
case EXPR_VAR_BIG_X :
expression[exprp++].func = stack_var_big_x;
break;
case EXPR_VAR_BIG_Y :
expression[exprp++].func = stack_var_big_y;
break;
case EXPR_FUNC :
{
exprtree *arg = tree->val.func.args;
while (arg != 0)
{
make_postfix_recursive(arg);
arg = arg->next;
}
expression[exprp++].func = tree->val.func.routine;
break;
}
case EXPR_VARIABLE :
expression[exprp].func = (stackfunc)stack_variable;
expression[exprp].arg = tree->val.var;
++exprp;
break;
case EXPR_ASSIGNMENT :
make_postfix_recursive(tree->val.assignment.value);
expression[exprp].func = (stackfunc)stack_assign;
expression[exprp].arg = tree->val.assignment.var;
++exprp;
break;
case EXPR_SEQUENCE :
make_postfix_recursive(tree->val.operator.left);
expression[exprp++].func = stack_pop;
make_postfix_recursive(tree->val.operator.right);
break;
case EXPR_IF_THEN :
make_postfix_recursive(tree->val.ifExpr.condition);
expression[exprp].func = (stackfunc)stack_jez;
expression[exprp].arg = &tree->val.ifExpr.label1;
++exprp;
make_postfix_recursive(tree->val.ifExpr.consequence);
expression[exprp].func = (stackfunc)stack_jmp;
expression[exprp].arg = &tree->val.ifExpr.label2;
++exprp;
tree->val.ifExpr.label1 = exprp;
expression[exprp].func = (stackfunc)stack_push;
expression[exprp].arg = &theZeroValue;
++exprp;
tree->val.ifExpr.label2 = exprp;
break;
case EXPR_IF_THEN_ELSE :
make_postfix_recursive(tree->val.ifExpr.condition);
expression[exprp].func = (stackfunc)stack_jez;
expression[exprp].arg = &tree->val.ifExpr.label1;
++exprp;
make_postfix_recursive(tree->val.ifExpr.consequence);
expression[exprp].func = (stackfunc)stack_jmp;
expression[exprp].arg = &tree->val.ifExpr.label2;
++exprp;
tree->val.ifExpr.label1 = exprp;
make_postfix_recursive(tree->val.ifExpr.alternative);
tree->val.ifExpr.label2 = exprp;
break;
case EXPR_WHILE :
tree->val.whileExpr.label1 = exprp;
make_postfix_recursive(tree->val.whileExpr.invariant);
expression[exprp].func = (stackfunc)stack_jez;
expression[exprp].arg = &tree->val.whileExpr.label2;
++exprp;
make_postfix_recursive(tree->val.whileExpr.body);
expression[exprp++].func = stack_pop;
expression[exprp].func = (stackfunc)stack_jmp;
expression[exprp].arg = &tree->val.whileExpr.label1;
++exprp;
tree->val.whileExpr.label2 = exprp;
expression[exprp].func = (stackfunc)stack_push;
expression[exprp].arg = &theZeroValue;
++exprp;
break;
case EXPR_DO_WHILE :
tree->val.whileExpr.label1 = exprp;
make_postfix_recursive(tree->val.whileExpr.body);
expression[exprp++].func = stack_pop;
make_postfix_recursive(tree->val.whileExpr.invariant);
expression[exprp].func = (stackfunc)stack_jnez;
expression[exprp].arg = &tree->val.whileExpr.label1;
++exprp;
expression[exprp].func = (stackfunc)stack_push;
expression[exprp].arg = &theZeroValue;
++exprp;
break;
default :
fprintf(stderr, "illegal expr\n");
}
}
void
make_postfix (exprtree *tree)
{
exprp = 0;
make_postfix_recursive(tree);
exprlen = exprp;
}
void
output_postfix (void)
{
int i;
printf("-------------------------\n");
for (i = 0; i < exprlen; ++i)
{
printf("%d ", i);
if (expression[i].func == (stackfunc)stack_push)
printf("push %f\n", *(double*)expression[i].arg);
else if (expression[i].func == stack_pop)
printf("pop\n");
else if (expression[i].func == (stackfunc)stack_jmp)
printf("jmp %d\n", *(int*)expression[i].arg);
else if (expression[i].func == (stackfunc)stack_jez)
printf("jez %d\n", *(int*)expression[i].arg);
else if (expression[i].func == (stackfunc)stack_jnez)
printf("jnez %d\n", *(int*)expression[i].arg);
else if (expression[i].func == stack_add)
printf("add\n");
else if (expression[i].func == (stackfunc)stack_add_i)
printf("addi %f\n", *(double*)expression[i].arg);
else if (expression[i].func == stack_sub)
printf("sub\n");
else if (expression[i].func == (stackfunc)stack_sub_i)
printf("subi %f\n", *(double*)expression[i].arg);
else if (expression[i].func == stack_neg)
printf("neg\n");
else if (expression[i].func == stack_mul)
printf("mul\n");
else if (expression[i].func == (stackfunc)stack_mul_i)
printf("muli %f\n", *(double*)expression[i].arg);
else if (expression[i].func == stack_div)
printf("div\n");
else if (expression[i].func == (stackfunc)stack_div_i)
printf("divi %f\n", *(double*)expression[i].arg);
else if (expression[i].func == stack_mod)
printf("mod\n");
else if (expression[i].func == (stackfunc)stack_mod_i)
printf("modi %f\n", *(double*)expression[i].arg);
else if (expression[i].func == stack_var_x)
printf("push x\n");
else if (expression[i].func == stack_var_y)
printf("push y\n");
else if (expression[i].func == stack_var_t)
printf("push t\n");
else if (expression[i].func == stack_var_r)
printf("push r\n");
else if (expression[i].func == stack_var_a)
printf("push a\n");
else if (expression[i].func == stack_var_w)
printf("push w\n");
else if (expression[i].func == stack_var_h)
printf("push h\n");
else if (expression[i].func == stack_var_big_r)
printf("push R\n");
else if (expression[i].func == stack_var_big_x)
printf("push X\n");
else if (expression[i].func == stack_var_big_y)
printf("push Y\n");
else if (expression[i].func == (stackfunc)stack_variable)
printf("push %s\n", ((variable*)expression[i].arg)->name);
else if (expression[i].func == (stackfunc)stack_assign)
printf("sto %s\n", ((variable*)expression[i].arg)->name);
/*
else if (expression[i].func == builtin_sin)
printf("sin\n");
else if (expression[i].func == builtin_cos)
printf("cos\n");
else if (expression[i].func == builtin_tan)
printf("tan\n");
else if (expression[i].func == builtin_asin)
printf("asin\n");
else if (expression[i].func == builtin_acos)
printf("acos\n");
else if (expression[i].func == builtin_atan)
printf("atan\n");
else if (expression[i].func == builtin_sign)
printf("sign\n");
else if (expression[i].func == builtin_min)
printf("min\n");
else if (expression[i].func == builtin_max)
printf("max\n");
else if (expression[i].func == builtin_inintv)
printf("inintv\n");
else if (expression[i].func == builtin_rand)
printf("rand\n");
else if (expression[i].func == builtin_origValXY)
printf("origValXY\n");
else if (expression[i].func == builtin_origValXYIntersample)
printf("origValXY\n");
else if (expression[i].func == builtin_origValRA)
printf("origValRA\n");
else if (expression[i].func == builtin_origValRAIntersample)
printf("origValRA\n");
else if (expression[i].func == builtin_grayColor)
printf("grayColor\n");
*/
else
printf("unknown opcode\n");
}
}
double
eval_postfix (void)
{
stackp = 0;
for (exprp = 0; exprp < exprlen; ++exprp)
expression[exprp].func(expression[exprp].arg);
return stack[0];
}

View File

@ -1,13 +0,0 @@
#include "exprtree.h"
typedef void (*stackfunc) (void*);
typedef struct _postfix
{
stackfunc func;
void *arg;
} postfix;
void make_postfix (exprtree *tree);
void output_postfix (void);
double eval_postfix (void);

View File

@ -1,58 +0,0 @@
%{
#include <string.h>
#include "exprtree.h"
#include "builtins.h"
#include "parser.h"
%}
%option noyywrap
%%
if return T_IF;
then return T_THEN;
else return T_ELSE;
end return T_END;
while return T_WHILE;
do return T_DO;
[a-zA-Z_][a-zA-Z0-9_]* {
builtin *theBuiltin = builtin_with_name(yytext);
if (theBuiltin != 0)
{
yylval.builtin = theBuiltin;
return T_BUILTIN;
}
else
{
strncpy(yylval.ident, yytext, MAX_IDENT_LENGTH);
yylval.ident[MAX_IDENT_LENGTH] = 0;
return T_IDENT;
}
}
[0-9]+ { yylval.exprtree = make_number(atof(yytext)); return T_NUMBER; }
[0-9]*\.[0-9]+ { yylval.exprtree = make_number(atof(yytext)); return T_NUMBER; }
"==" return T_EQUAL;
"<=" return T_LESSEQUAL;
">=" return T_GREATEREQUAL;
"!=" return T_NOTEQUAL;
"||" return T_OR;
"&&" return T_AND;
[-<>!,()+*/%=;] return yytext[0];
#.* ;
[ \t\n] ;
%%
void
scanFromString (char *string)
{
yy_scan_string(string);
}
void
endScanningFromString (void)
{
yy_delete_buffer(YY_CURRENT_BUFFER);
}

View File

@ -1,7 +0,0 @@
#ifndef __SCANNER_H__
#define __SCANNER_H__
void scanFromString (char *string);
void endScanningFromString (void);
#endif

View File

@ -1,42 +0,0 @@
#include <assert.h>
#include <stdlib.h>
#include "vars.h"
variable *firstVariable = 0;
variable*
register_variable (char *name)
{
variable *var;
assert(strlen(name) < VAR_MAX_LENGTH);
for (var = firstVariable; var != 0; var = var->next)
if (strcmp(name, var->name) == 0)
return var;
var = (variable*)malloc(sizeof(variable));
strcpy(var->name, name);
var->value = 0.0;
var->next = firstVariable;
firstVariable = var;
return var;
}
void
clear_all_variables (void)
{
variable *var = firstVariable;
while (var != 0)
{
variable *next = var->next;
free(var);
var = next;
}
firstVariable = 0;
}

View File

@ -1,18 +0,0 @@
#ifndef __VARS_H__
#define __VARS_H__
#define VAR_MAX_LENGTH 32
typedef struct _variable
{
char name[VAR_MAX_LENGTH];
double value;
struct _variable *next;
} variable;
variable* register_variable (char *name);
void clear_all_variables (void);
#endif

View File

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
refract

View File

@ -1,21 +0,0 @@
1/10/98:
Simultaniously changed the name of the menu entry to "Refract" instead
of "Refract&Reflect" and made changes preparing to add Reflect
functionality. Note that this changed the PDB interface.
Discovered that the GParam thing didn't need to be "fixed", so I put
it back.
1/2/98: refract-Beta
Refract is back, and better than ever! That's right... The New Layer
checkbox now works properly from layers with and without alpha.
Fixed so small or goofily placed lenses don't crash. Lo and behold,
lens offsets also seem to be working. How that happened is beyond me.
Fixed some bad GParam values thing in run().
Changed the name of the parameter that determines the lens thickness
to "thick" instead of "depth".

View File

@ -1,12 +0,0 @@
Files that should be in refract distributions:
FILES - this file
INSTALL - Installation instructions (if not part of GIMP distrib)
Makefile
README
TODO
refguts.c - source file containing the actual distort refract code
refmain.c - source file containing query, run, and dialog things
refract.h - common header file, contains configurable settings
Additional file included in refract-bin distributions:
refract - the compiled plug-in executable for linux-ELF-i386

View File

@ -1,31 +0,0 @@
If this file came as part of a GIMP distribution, no special
installation instructions are required. Refract will get built and
installed when all the other plug-ins do.
However, if you wish to install this plug-in seperately, perhaps
because it's a newer version than the one in your distribution...
First, try typing
make install
If that worked, stop reading and go play with GIMP. If it didn't,
read on...
At this point in time, refract needs the files megawidget.h and
megawidget.o to compile. Since I've found megawidgets don't fully
suffice my needs, this will probably change in the near future. But
for now, stick those files (or links to them) somewhere where your
compiler can find them when compiling refract... They should be
included somewhere in the plug-ins directory of your GIMP source
distribution.
You may also wish to dink with the compiler options in the Makefile.
At the moment, as refract is still Not Quite There Yet, it comes
shipped with all sorts of debugging flags turned on and optimizations
turned OFF. If you don't care why refract crashes if and when it
does, go ahead and comment out the debug flags and uncomment the
optimizations. Hopefully it will pick up some speed that way.
There are also a few options available for dinking in refract.h, but
none too interesting at the moment.

View File

@ -1,43 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = refract
refract_SOURCES = \
refmain.c \
refguts.c \
refract.h \
$(top_srcdir)/plug-ins/megawidget/megawidget.h
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/plug-ins/megawidget/libmegawidget.a \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/plug-ins/megawidget/libmegawidget.a \
$(top_builddir)/libgimp/libgimp.la
refract_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

View File

@ -1,48 +0,0 @@
refract: A plug-in for the GIMP 0.99
by Kevin Turner <kevint@poboxes.com>
http://www.poboxes.com/kevint/gimp/refract.html
Refract distorts an image by passing it through the lens. The side of
the lens towards the image is flat, the shape the other side is
determined by a height map; a grayscale image where white pixels are
high, black pixels are low, and anything between is somewhere
inbetween. (Refract will accept an RGB image as a lens map, but will
only use the first channel.)
The thickness of the lens is determined by the "Thickness"
paramater. The "Distance" parameter is the distance between the
bottom of the lens and the image. (The distance between the observer
and the image is fixed at somewhere around infinity minus one.
Fortunately, there are no perspective effects.)
The two indicies of refraction describe what substances you're
looking through. Index A is for the substance between you and the
lens, index B is that of the material the lens is crafted from. So
when looking from air in to water, index A would be about 1 and index
B is 1.333. These indicies are physical constants and can be obtained
by looking in your copy of the CRC, or using the samples provided.
The X and Y offsets move the position of the lens. Sorry,
a preview image is on the TO DO list, but it ain't here yet. The
resulting image can be placed on a new layer by checking the "New
layer" checkbox.
Read the code and the aformentioned web page for more
information. Questions, comments, reservations, and bug reports are
always welcome.
* * *
I'm not a very expirenced C programmer, so questions, comments, and
reservations on code and style are more than welcome. This plug-in
was developed on Linux and I will be the first to admit that I'm
rather inexpirenced (okay, ignorant) with other operating systems.
If I do wrong, educate me.
Credits:
Pixel fetcher routines are from Quartic's whirlpinch plug-in. Thanks,
Quartic[1]!
1: Quartic, AKA Federico Mena-Quintero
federico@nuclecu.unam.mx
http://www.nuclecu.unam.mx/~federico

View File

@ -1,27 +0,0 @@
TO DO:
code:
Do The Right Thing with respect to row buffers, macros, and inline functions.
Have the plug-in return the ID of the new layer, if it created one.
UI:
megawidgets are insufficient. (No way to integrate entry_scale
with tooltips or option_menu). Replace them.
necessary luxuries:
Add radio buttons for edge wrapping options.
nicities:
Find why two undo steps are required to undo.
Find a way to reduce the speckling.
excess luxuries:
Variable IOR information in some [alpha?] channel.
for version 1.1:
THIS PLUGIN NEEDS A PREVIEW THING!
Reflections
for version > 1.1:
Diffraction or whatever that thing that makes rainbows is called.
Lighting

View File

@ -1,539 +0,0 @@
/* refguts.c, 1/2/98 - this file contains the icky stuff.
* refract: a plug-in for the GIMP 0.99
* By Kevin Turner <kevint@poboxes.com>
* http://www.poboxes.com/kevint/gimp/refract.html
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/* Refresher course in optics:
Incident ray is the light ray hitting the surface.
Angles are measured from the perpendicular to the surface.
Angle of reflection is equal to angle of incidence.
Angle of refraction is determined by
Snell's law: index[a] * sin(a) = index[b] * sin(b)
If second index is smaller than first, light is bent toward normal.
Otherwise, away.
*/
#include "refract.h"
#include "libgimp/gimp.h"
typedef struct { /* Quartic's pixelfetcher thing */
gint col, row;
gint img_width, img_height, img_bpp, img_has_alpha;
gint tile_width, tile_height;
guchar bg_color[4];
GDrawable *drawable;
GTile *tile;
} pixel_fetcher_t;
extern RefractValues refractvals;
void go_refract(GDrawable *drawable,
gint32 image_id);
static void do_refract(GPixelRgn *dest_rgn,
GPixelRgn *lens_rgn,
pixel_fetcher_t *pf);
static gint delta (gdouble *offset, gdouble slope, gint height);
#ifndef OLD_SLOPE_MACROS
static gdouble slope(gint h, /* FIXME: I should probably be inlined. */
HEIGHT_TYPE p1,
HEIGHT_TYPE p2,
HEIGHT_TYPE p3,
HEIGHT_TYPE p4);
#endif
/* More pixelfetcher things */
static pixel_fetcher_t *pixel_fetcher_new(GDrawable *drawable);
static void pixel_fetcher_set_bg_color(pixel_fetcher_t *pf, guchar r, guchar g, guchar b, guchar a);
static void pixel_fetcher_get_pixel(pixel_fetcher_t *pf, int x, int y, guchar *pixel);
static void pixel_fetcher_destroy(pixel_fetcher_t *pf);
/* This bilinear interpolation function also borrowed. */
static guchar bilinear_new (double x,
double y,
guchar v[4][4],
guint8 i);
static gint sel_x1=-1,sel_x2=-1,sel_y1=-1,sel_y2=-1;
static gint sel_w, sel_h;
static guchar fg_color[4];
void
go_refract( GDrawable * drawable, gint32 image_id)
{
/* For Initialize pixel fetcher. */
pixel_fetcher_t *pf;
guchar bg_color[4];
/* For Initialize lens region. */
GDrawable *lensmap;
GPixelRgn lens_rgn;
gint lxoff, lyoff;
#if 0
gint use_x1,use_x2,use_y1,use_y2, use_w, use_h;
#endif
/* For Initialize dest region. */
GPixelRgn dest_rgn;
GDrawable *output_drawable;
gint32 new_layer_id;
char buf[256];
/*****************************/
/* Initialize pixel fetcher. */
gimp_drawable_mask_bounds (drawable->id, &sel_x1, &sel_y1, &sel_x2, &sel_y2);
sel_w=sel_x2-sel_x1; sel_h=sel_y2-sel_y1;
pf = pixel_fetcher_new(drawable);
gimp_palette_get_background(&bg_color[0], &bg_color[1], &bg_color[2]);
pixel_fetcher_set_bg_color(pf,
bg_color[0],
bg_color[1],
bg_color[2],
0);
/***************************/
/* Initialize lens region: */
lensmap = gimp_drawable_get (refractvals.lens_id);
/* Fortunately, this isn't really run repeatedly, so it's OK if
it's not all that compact, right? */
#ifdef __PSYCHIC_COMPILER__ /* If your compiler can read my mind better than I can. */
/* Crap. We need a smegging lens-wrap toggle. */
if (lens wrap) {
if (no lens offsets) {
/* no problems. */
lens_rgn = foo(sel_x1, sel_x2, sel_w, sel_h);
/* To conserve resources, we might want to change that
to take less if the lens stops before the image
does. */
} else { /* offsets. Uhoh. */
if (lens_size >= drawable_size) { /* Do this for each dimension. */
/* Oh, it'll be okay. We'll just add offset and take absmod. */
if (split) {
lens_rgn = wholething; /* Oh well, we'll take the whole thing. */
} else { /* not split */
lens_rgn = foo(sel_x1-xoff, sel_y1-yoff, sel_w, sel_h);
} /* endif not split */
} else { /* lens is smaller */
if (split) { g_warning("refract: refguts.c: Go to hell.\n"); }
else { lens_rgn= foo(sel_x1-xoff, sel_y1-yoff, sel_w, sel_h); }
} /* lens is smaller */
} /* endif offsets */
} else { /* no lens wrap */
/* If there's no lens wrapping, I have no problem. It's yo
own dang fault if your lens doesn't land on your drawable
any more. */
/* Let's rub it in... */
if (((xoff > 0) ? (xoff >= sel_w) : (-xoff <= lens_w)) ||
((yoff > 0) ? (yoff >= sel_h) : (-yoff <= lens_h))) {
g_warning("refract: refguts.c: loose nut detected between chair and keyboard.\n");
g_error("refract: refguts.c: Offsets move lens off image.\n");
} else {
lens_rgn = foo(sel_x1-xoff, sel_y1-yoff, sel_w, sel_h);
/* To conserve resources, we might want to change that
to take less if the lens stops before the image
does. */
}
} /* endif no lens wrap */
#else /* Compiler requires actual code. */
gimp_drawable_offsets(lensmap->id,&lxoff, &lyoff);
#ifdef REFRACT_DEBUG
g_print("x: %d\ty: %d\tw: %d\th: %d\n",
lxoff, lyoff,
lensmap->width,lensmap->height);
#endif /* REFRACT_DEBUG */
#if 0 /* If we *didn't* wrap the lens... */
if( (sel_x1 > (lxoff + lensmap->width)) ||
(lxoff > sel_x2) ||
(sel_y1 > (lyoff + lensmap->height)) ||
(lyoff > sel_y2)) {
g_error("refract:refguts.c:Selection and lens don't overlap. You lose.\n");
} else {
use_x1=MAX(sel_x1,lxoff);
use_x2=MIN(sel_x2,lxoff + lensmap->width);
use_y1=MAX(sel_y1,lyoff);
use_y2=MIN(sel_y2,lyoff + lensmap->height);
use_w=use_x2-use_x1;
use_h=use_y2-use_y1;
}
#endif /* if we didn't wrap lenses */
gimp_pixel_rgn_init (&lens_rgn, lensmap,
lxoff, lyoff, lensmap->width, lensmap->height,
FALSE, FALSE);
#endif /* Compiler requires actual code. */
/**********************************/
/* Initialize destination region: */
sprintf(buf,"Refracted %s",gimp_drawable_name(drawable->id));
if (refractvals.newl) { /* New layer? Yes... */
new_layer_id=gimp_layer_new(image_id, buf, sel_w, sel_h,
gimp_drawable_gray(drawable->id)
? GRAYA_IMAGE : RGBA_IMAGE,
100.0, NORMAL_MODE);
/* For layer position (currently 0), how would I say
"one above current layer"? */
gimp_image_add_layer(image_id,new_layer_id,0);
gimp_layer_set_offsets(new_layer_id, sel_x1, sel_y1);
output_drawable=gimp_drawable_get(new_layer_id);
} else { /* New layer No. */
output_drawable=drawable;
} /* New layer No. */
gimp_pixel_rgn_init (&dest_rgn, output_drawable,
sel_x1, sel_y1, sel_w, sel_h,
TRUE, TRUE);
#ifdef REFRACT_DEBUG
g_print("drawable-id: %d\toutput-id: %d:\tlens_rgn-id: %d\n",
drawable->id,output_drawable->id,lens_rgn.drawable->id);
#endif
/********/
/* Misc */
gimp_palette_get_foreground(&fg_color[0], &fg_color[1], &fg_color[2]);
fg_color[3] = 255;
/**********/
/* Do it! */
do_refract(&dest_rgn,&lens_rgn,pf);
/*************/
/* Clean up. */
/* FIXME: If we are cancelled, make sure there's none of that
unsightly new layer residue. */
pixel_fetcher_destroy(pf);
/* I hope this works... */
gimp_drawable_flush(output_drawable);
gimp_drawable_merge_shadow(output_drawable->id,!refractvals.newl);
gimp_drawable_update(output_drawable->id,sel_x1,sel_y1,sel_w,sel_h);
gimp_drawable_detach(drawable);
if (drawable != output_drawable) gimp_drawable_detach(output_drawable);
gimp_drawable_detach(lensmap);
/* return (refractvals.newl ? new_layer_id : NULL); */
} /* go_refract */
#define ABSMOD(A,B) ( ((A) < 0) ? (((B) + (A)) % (B)) : ((A) % (B)) )
#define X(F) ( ABSMOD((F)+refractvals.xofs,lens_rgn->w) )
#define Y(F) ( ABSMOD((F)+refractvals.yofs,lens_rgn->h) )
#define ROWM2 (lm_rowm2[ X(x) * lens_rgn->bpp ])
#define ROWM1 (lm_rowm1[ X(x) * lens_rgn->bpp ])
#define ROW0(F) (lm_row0[ X(x+(F)) * lens_rgn->bpp ])
#define ROWP1 (lm_rowp1[ X(x) * lens_rgn->bpp ])
#define ROWP2 (lm_rowp2[ X(x) * lens_rgn->bpp ])
#ifdef OLD_SLOPE_MACROS
#define SLOPE_X ((gdouble) 1.0 / (12 * h) * ( ROW0(-2*h) - 8 * ROW0(-1*h) + 8 * ROW0(1*h) - ROW0(2*h) ) * depths )
#define SLOPE_Y ((gdouble) 1.0 / (12 * h) * ( ROWM2 - 8 * ROWM1 + 8 * ROWP1 - ROWP2 ) * depths )
#else /* Macros calling the slope function. Functionally equivillant. */
#define SLOPE_X (slope(h,ROW0(-2*h), ROW0(-1*h), ROW0(1*h), ROW0(2*h)))
#define SLOPE_Y (slope(h,ROWM2, ROWM1, ROWP1, ROWP2))
#endif /* OLD_SLOPE_MACROS */
static void
do_refract(GPixelRgn *dest_rgn, GPixelRgn *lens_rgn,
pixel_fetcher_t *pf)
{
HEIGHT_TYPE *lm_rowm2, *lm_rowm1, *lm_row0, *lm_rowp1, *lm_rowp2;
HEIGHT_TYPE *lm_rowfoo;
guchar pixel[4][4];
guint8 i, j;
gint8 diff_bpp;
guchar *dest, *dest_row;
gdouble dx, dy;
gint x, y, xf, yf;
gdouble depths=(gdouble) refractvals.thick/ (gdouble) 256.0; /* Depth scalar */
const gint h=1; /* The delta value for the slope interpolation equation. */
/* FIXME: Give option of changing h? */
/* See if dest_rgn and pf have different bpp */
diff_bpp = dest_rgn->bpp - pf->img_bpp;
/***************/
/* Allocations */
lm_rowm2 = g_malloc(lens_rgn->w * lens_rgn->bpp * sizeof(HEIGHT_TYPE));
lm_rowm1 = g_malloc(lens_rgn->w * lens_rgn->bpp * sizeof(HEIGHT_TYPE));
lm_row0 = g_malloc(lens_rgn->w * lens_rgn->bpp * sizeof(HEIGHT_TYPE));
lm_rowp1 = g_malloc(lens_rgn->w * lens_rgn->bpp * sizeof(HEIGHT_TYPE));
lm_rowp2 = g_malloc(lens_rgn->w * lens_rgn->bpp * sizeof(HEIGHT_TYPE));
dest_row = g_malloc(dest_rgn->w * dest_rgn->bpp * sizeof(guchar));
/************************/
/* Grab some lens rows. */
gimp_pixel_rgn_get_row(lens_rgn, lm_rowm2, 0, Y(sel_y1 - 2*h), lens_rgn->w);
gimp_pixel_rgn_get_row(lens_rgn, lm_rowm1, 0, Y(sel_y1 - 1*h), lens_rgn->w);
gimp_pixel_rgn_get_row(lens_rgn, lm_row0, 0, Y(sel_y1), lens_rgn->w);
gimp_pixel_rgn_get_row(lens_rgn, lm_rowp1, 0, Y(sel_y1 + 1*h), lens_rgn->w);
gimp_pixel_rgn_get_row(lens_rgn, lm_rowp2, 0, Y(sel_y1 + 2*h), lens_rgn->w);
/***********************/
/* Let's begin work... */
for (y=sel_y1; y < sel_y2; y++) {
gimp_pixel_rgn_get_row(dest_rgn, dest_row, sel_x1, y, sel_w);
dest = dest_row;
for (x=sel_x1; x < sel_x2; x++) {
/* If offsets in both X and Y direction exist... */
/* (meaning no internal refraction) */
if (delta(&dx, SLOPE_X, ROW0(0) * depths) &&
delta(&dy, SLOPE_Y, ROW0(0) * depths)) {
switch (refractvals.edge) {
case WRAP:
xf = ABSMOD(x + (gint) dx, dest_rgn->drawable->width);
yf = ABSMOD(y + (gint) dy, dest_rgn->drawable->height);
break;
case BACKGROUND:
case OUTSIDE:
xf = x + (gint) dx;
yf = y + (gint) dy;
break;
default:
g_error("refract: refract.c: Unanticipated value for edge in do_refract\n");
} /* switch refractvals.edge */
pixel_fetcher_get_pixel(pf, xf, yf, pixel[0]);
pixel_fetcher_get_pixel(pf, xf + 1, yf, pixel[1]);
pixel_fetcher_get_pixel(pf, xf, yf + 1, pixel[2]);
pixel_fetcher_get_pixel(pf, xf + 1, yf + 1, pixel[3]);
for (i = 0; i < pf->img_bpp; i++) {
*dest++ = bilinear_new(dx, dy, pixel, i);
} /* next i */
/* If dest_rgn has more bpp than pf's source,
then fill in the rest with 255's... This helps
when making a new layer from a non-alpha layer. */
for (j = 0; j < diff_bpp; j++) {
*dest++ = 255;
}
} else { /* if a delta() call returns false. */
for (i = 0; i < dest_rgn->bpp; i++) {
*dest++ = fg_color[i];
} /* next i */
} /* endif delta() */
} /* next x */
gimp_pixel_rgn_set_row(dest_rgn, dest_row, sel_x1, y, sel_w);
if (!(y % PROGRESS_ROWS))
gimp_progress_update((double) (y-sel_y1) / (double) (sel_y2-sel_y1));
/* move lensmap pointers */
lm_rowfoo=lm_rowm2;
lm_rowm2=lm_rowm1;
lm_rowm1=lm_row0;
lm_row0= lm_rowp1;
lm_rowp1=lm_rowp2;
lm_rowp2=lm_rowfoo;
/* get new lensmap row */
gimp_pixel_rgn_get_row(lens_rgn, lm_rowp2, 0, Y(y+3*h), lens_rgn->w);
} /* next y */
} /* do_refract */
#ifndef OLD_SLOPE_MACROS
static gdouble /* FIXME: I should probably be inlined. */
slope(gint h, HEIGHT_TYPE p1, HEIGHT_TYPE p2, HEIGHT_TYPE p3, HEIGHT_TYPE p4)
{
/* p1 = f(x-2h), p2 = f(x-1h), p3 = f(x+1h), p4=f(x+2h) */
return 1.0 / (12 * h) * ( p1 - 8 * p2 + 8 * p3 - p4 );
}
#endif /* OLD_SLOPE_MACROS */
static gint
delta(gdouble *offset, gdouble slope, gint height)
{
gdouble alpha, beta;
alpha = atan(slope);
if( alpha > asin( refractvals.nb / refractvals.na )) {
return FALSE; /* Total Internal Refraction. Aiee! */
}
beta = asin(refractvals.na * sin(alpha)/refractvals.nb);
*offset = -(refractvals.refr_dist + height) * tan(beta - alpha);
return TRUE;
}
/* A "borrowed" bilinear interpolation function, modified to select from a
two dimensional array instead of a linear one. */
static guchar
bilinear_new(double x, double y, guchar values[4][4], guint8 i)
{
double m0, m1;
x = fmod(x, 1.0);
y = fmod(y, 1.0);
if (x < 0.0)
x += 1.0;
if (y < 0.0)
y += 1.0;
m0 = (double) values[0][i] + x * ((double) values[1][i] - values[0][i]);
m1 = (double) values[2][i] + x * ((double) values[3][i] - values[2][i]);
return (guchar) (m0 + y * (m1 - m0));
} /* bilinear_new */
/************************************************************************
*
* Fun pixel fetching stuff... Quartic's code from whirlpinch.c
* Uses the globals sel_x1,sel_x2,sel_y1,sel_y2.
*/
static pixel_fetcher_t *
pixel_fetcher_new(GDrawable *drawable)
{
pixel_fetcher_t *pf;
pf = g_malloc(sizeof(pixel_fetcher_t));
pf->col = -1;
pf->row = -1;
pf->img_width = drawable->width;
pf->img_height = drawable->height;
pf->img_bpp = drawable->bpp;
pf->img_has_alpha = gimp_drawable_has_alpha(drawable->id);
pf->tile_width = gimp_tile_width();
pf->tile_height = gimp_tile_height();
pf->bg_color[0] = 0;
pf->bg_color[1] = 0;
pf->bg_color[2] = 0;
pf->bg_color[3] = 0;
pf->drawable = drawable;
pf->tile = NULL;
return pf;
} /* pixel_fetcher_new */
/*****/
static void
pixel_fetcher_set_bg_color(pixel_fetcher_t *pf, guchar r, guchar g, guchar b, guchar a)
{
pf->bg_color[0] = r;
pf->bg_color[1] = g;
pf->bg_color[2] = b;
if (pf->img_has_alpha)
pf->bg_color[pf->img_bpp - 1] = a;
} /* pixel_fetcher_set_bg_color */
/*****/
static void
pixel_fetcher_get_pixel(pixel_fetcher_t *pf, int x, int y, guchar *pixel)
{
gint col, row;
gint coloff, rowoff;
guchar *p;
int i;
if ((x < sel_x1) || (x >= sel_x2) ||
(y < sel_y1) || (y >= sel_y2)) {
for (i = 0; i < pf->img_bpp; i++)
pixel[i] = pf->bg_color[i];
return;
} /* if */
col = x / pf->tile_width;
coloff = x % pf->tile_width;
row = y / pf->tile_height;
rowoff = y % pf->tile_height;
if ((col != pf->col) ||
(row != pf->row) ||
(pf->tile == NULL)) {
if (pf->tile != NULL)
gimp_tile_unref(pf->tile, FALSE);
pf->tile = gimp_drawable_get_tile(pf->drawable, FALSE, row, col);
gimp_tile_ref(pf->tile);
pf->col = col;
pf->row = row;
} /* if */
p = pf->tile->data + pf->img_bpp * (pf->tile->ewidth * rowoff + coloff);
for (i = pf->img_bpp; i; i--)
*pixel++ = *p++;
} /* pixel_fetcher_get_pixel */
/*****/
static void
pixel_fetcher_destroy(pixel_fetcher_t *pf)
{
if (pf->tile != NULL)
gimp_tile_unref(pf->tile, FALSE);
g_free(pf);
} /* pixel_fetcher_destroy */

View File

@ -1,536 +0,0 @@
/* refmain.c, 1/2/98 - this file contains startup routine and dialogs.
* refract: A plug-in for the GIMP 0.99.
* Uses a height field as a lens of specified refraction index.
*
* by Kevin Turner <kevint@poboxes.com>
* http://www.poboxes.com/kevint/gimp/refract.html
*/
/* I require megawidgets to compile! A copy was probably compiled in
the plug-ins directory of your GIMP source distribution, it will
work nicely. Just move me or it somewhere I can see it... */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifdef REFRACT_DEBUG
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#endif /* DEBUG */
#include <stdlib.h>
#include <math.h> /* It's not clear to me if this needs be here or no... */
#include "refract.h"
#include "libgimp/gimp.h"
#include "libgimp/gimpui.h"
/* megawidget.h could be in any of several places relative to us... */
/* should this be an autoconf thing? */
#ifdef HAVE_CONFIG_H /* We're part of the GIMP distribution. */
#include <plug-ins/megawidget/megawidget.h>
#else
#include "megawidget.h"
/* #include <megawidget.h> */
#endif
typedef struct {
gint run;
} RefractInterface;
/* go_refract is in refguts.c */
extern void go_refract(GDrawable *drawable,
gint32 image_id);
static void query (void);
static void run (gchar *name,
gint nparams,
GParam *param,
gint *nreturn_vals,
GParam **return_vals);
static gint refract_dialog();
static gint map_constrain(gint32 image_id,
gint32 drawable_id,
gpointer data);
static void newl_toggle_callback (GtkWidget *widget,
gpointer data);
static void tooltips_toggle_callback (GtkWidget *widget,
gpointer data);
static void refract_close_callback(GtkWidget *widget,
gpointer data);
static void refract_ok_callback(GtkWidget *widget,
gpointer data);
static void map_menu_callback (gint32 id,
gpointer data);
static GtkWidget* ior_menu_new(GtkWidget *tieto);
static void ior_menu_callback (GtkWidget *widget,
gfloat *data);
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
/* refractvals defined in refract.h */
/* not static, used in refguts.c */
RefractValues refractvals =
{
-1, /* Lens map ID */
-1, /* Reflection source ID */
32, /* lens thickness */
0, /* lens to image distance */
64, /* lens to reflection source distance */
1.0003, /* index a */
1.333, /* index b */
WRAP, /* wrap behaviour */
FALSE, /* new layer? */
0, /* offset x */
0, /* offset y */
};
static RefractInterface refractint =
{
FALSE /* run */
};
MAIN ()
static void
query ()
{
static GParamDef args[] =
{
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
{ PARAM_IMAGE, "image", "Input image" },
{ PARAM_DRAWABLE, "drawable", "Input drawable" },
/* If we did have parameters, these be them: */
{ PARAM_DRAWABLE, "lens_id", "Lens map drawable" },
{ PARAM_DRAWABLE, "refl_id", "Reflection source drawable." },
{ PARAM_INT32, "thick", "Lens thickness" },
{ PARAM_INT32, "refr_dist", "Lens distance from image" },
{ PARAM_INT32, "refl_dist", "Lens distance from reflection source" },
{ PARAM_FLOAT, "na", "Index of Refraction A" },
{ PARAM_FLOAT, "nb", "Index of Refraction B" },
{ PARAM_INT32, "edge", "Background (0), Outside (1), Wrap (2)" },
{ PARAM_INT32, "newl", "New layer?" },
{ PARAM_INT32, "xofs", "X offset" },
{ PARAM_INT32, "yofs", "Y offset" }
};
static GParamDef *return_vals = NULL;
static int nargs = sizeof (args) / sizeof (args[0]);
static int nreturn_vals = 0;
gimp_install_procedure ("plug_in_refract",
"Uses a height field as a lens.",
"Distorts the image by refracting it through a height field 'lens' with a specified index of refraction.",
"Kevin Turner <kevint@poboxes.com>",
"Kevin Turner",
"1997",
"<Image>/Filters/Glass Effects/Refract",
"RGB*, GRAY*, INDEXED*",
PROC_PLUG_IN,
nargs, nreturn_vals,
args, return_vals);
} /* query */
static void
run (gchar *name,
gint nparams,
GParam *param,
gint *nreturn_vals,
GParam **return_vals)
{
static GParam values[1];
GDrawable *drawable;
GRunModeType run_mode;
GStatusType status = STATUS_SUCCESS;
#ifdef REFRACT_DEBUG
printf("refract: pid %d\n", getpid());
#endif
/* values=g_new(GParam,1); */
run_mode = param[0].data.d_int32;
*nreturn_vals = 1;
*return_vals = values;
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
drawable = gimp_drawable_get (param[2].data.d_drawable);
switch (run_mode) {
case RUN_INTERACTIVE:
/* Possibly retrieve data */
gimp_get_data ("plug_in_refract", &refractvals);
/* Acquire info with a dialog */
if (! refract_dialog ()) {
gimp_drawable_detach (drawable);
return;
}
break;
case RUN_NONINTERACTIVE:
if (status == STATUS_SUCCESS) {
refractvals.lens_id = param[3].data.d_drawable;
refractvals.refl_id = param[4].data.d_int32;
refractvals.thick = param[5].data.d_int32;
refractvals.refr_dist = param[6].data.d_float;
refractvals.refl_dist = param[7].data.d_float;
refractvals.na = param[8].data.d_int32;
refractvals.nb = param[9].data.d_int32;
refractvals.edge = param[10].data.d_int32;
refractvals.newl = param[11].data.d_int32;
refractvals.xofs = param[12].data.d_int32;
refractvals.yofs = param[13].data.d_int32;
} /* if */
break;
case RUN_WITH_LAST_VALS:
/* Possibly retrieve data */
gimp_get_data ("plug_in_refract", &refractvals);
break;
default:
break;
} /* switch run_mode */
if (gimp_drawable_color (drawable->id) || gimp_drawable_gray (drawable->id)) {
gimp_progress_init ("Doing optics homework...");
/* What's this do? */
gimp_tile_cache_ntiles(2 * (drawable->width + gimp_tile_width() - 1)
/ gimp_tile_width());
go_refract (drawable, param[1].data.d_image);
if (run_mode != RUN_NONINTERACTIVE)
gimp_displays_flush ();
if (run_mode == RUN_INTERACTIVE /*|| run_mode == RUN_WITH_LAST_VALS*/)
gimp_set_data ("plug_in_refract", &refractvals, sizeof (RefractValues));
} else {
status = STATUS_EXECUTION_ERROR;
}
values[0].data.d_status = status;
} /* run */
static gint
refract_dialog()
{
gint argc;
gchar **argv;
GtkTooltips *tooltips;
GtkWidget *menu, *option_menu, *ior_a_menu, *ior_b_menu;
GtkWidget *ok_button, *cancel_button;
GtkWidget *layercheck, *toolcheck;
GtkWidget *dlg;
GtkWidget *table;
GtkWidget *label;
#ifdef REFRACT_DEBUG
#if 0
printf("refract: waiting... (pid %d)\n", getpid());
kill(getpid(), SIGSTOP);
#endif
#endif
/* Standard GTK startup sequence */
argc = 1;
argv = g_new (gchar *, 1);
argv[0] = g_strdup ("refract");
gtk_init (&argc, &argv);
gdk_set_use_xshm(gimp_use_xshm());
/* FIXME: Can we use the GIMP colormap when in 8-bit to reduce flashing? */
/* end standard GTK startup */
/* I guess we need a window... */
dlg = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dlg), REFRACT_TITLE);
gtk_signal_connect(GTK_OBJECT(dlg), "destroy",
(GtkSignalFunc) refract_close_callback,
NULL);
tooltips = gtk_tooltips_new ();
/* Action area: */
/* OK */
ok_button = gtk_button_new_with_label ("OK");
GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (ok_button), "clicked",
(GtkSignalFunc) refract_ok_callback, dlg);
gtk_widget_grab_default (ok_button);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), ok_button,
TRUE, TRUE, 0);
gtk_widget_show (ok_button);
/* Cancel */
cancel_button = gtk_button_new_with_label ("Cancel");
GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT);
gtk_signal_connect_object (GTK_OBJECT (cancel_button), "clicked",
(GtkSignalFunc) refract_close_callback,
NULL);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), cancel_button,
TRUE, TRUE, 0);
gtk_widget_show (cancel_button);
/* Paramater settings: */
table = gtk_table_new(7, 3, FALSE);
gtk_container_add(GTK_CONTAINER (GTK_DIALOG (dlg)->vbox),table);
gtk_widget_show (table);
/* FIXME: add preview box */
/* drop box for lens map */
label = gtk_label_new("Lens map");
option_menu = gtk_option_menu_new();
menu = gimp_drawable_menu_new(map_constrain, map_menu_callback,
NULL, refractvals.lens_id);
gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu),menu);
gtk_tooltips_set_tips (tooltips, option_menu,
"The drawable to use as the lens.");
gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,0,1);
gtk_table_attach_defaults(GTK_TABLE(table),option_menu,1,3,0,1);
gtk_widget_show(label);
gtk_widget_show(option_menu);
/* TODO? Add "Invert lens map" Not anytime soon... */
/* Would require adding all sorts of conditional subtracting stuff
in the main loop... Let them invert it first! :) */
/* Eek. Megawidgets don't return a value I can tie tooltips to.
Maybe I should look in to libgck. */
/* entry/scale for lens thickness */
mw_iscale_entry_new(table, "Thickness",
0, 256,
1, 10, 0,
0, 2, 1, 2,
&refractvals.thick);
/* entry/scale pair for distance */
mw_iscale_entry_new(table, "Distance",
0, 1000,
1, 10, 0/*what's this do?*/,
0, 2, 2, 3,
&refractvals.refr_dist);
/* a entry/scale/drop-menu for each index */
mw_fscale_entry_new(table, "Index A",
INDEX_SCALE_MIN, INDEX_SCALE_MAX,
1.0, 0.1, 0,
0,1, 3, 4,
&refractvals.na);
ior_a_menu = ior_menu_new(NULL/*FIXME*/);
gtk_table_attach_defaults(GTK_TABLE(table),ior_a_menu,2,3,3,4);
gtk_widget_show (ior_a_menu);
gtk_tooltips_set_tips (tooltips, ior_a_menu,
"FIXME (No, it doesn't work.)");
mw_fscale_entry_new(table, "Index B",
INDEX_SCALE_MIN, INDEX_SCALE_MAX,
1.0, 0.1, 0,
0, 1, 4, 5,
&refractvals.nb);
ior_b_menu = ior_menu_new(NULL/*FIXME*/);
gtk_table_attach_defaults(GTK_TABLE(table),ior_b_menu,2,3,4,5);
gtk_widget_show (ior_b_menu);
gtk_tooltips_set_tips (tooltips, ior_b_menu,
"FIXME (No, it doesn't work.)");
/* entry/scale pairs for x and y offsets */
mw_iscale_entry_new(table, "X Offset",
-1000, 1000,
1, 20, 0,
0,2, 5, 6,
&refractvals.xofs);
mw_iscale_entry_new(table, "Y Offset",
-1000, 1000,
1, 20, 0,
0,2, 6, 7,
&refractvals.yofs);
/* radio buttons for wrap/transparent (or bg, if image isn't layered) */
/* button = gtk_check_button_new_with_label ("Wrap?");
toggle_button_callback (button, gpointer data);
gtk_toggle_button_set_state (GtkToggleButton button, refractvals.edge); */
/* Make new layer(s) or dirty the old? */
layercheck = gtk_check_button_new_with_label ("New layer?");
gtk_container_add(GTK_CONTAINER (GTK_DIALOG (dlg)->vbox),layercheck);
gtk_signal_connect (GTK_OBJECT (layercheck), "clicked",
GTK_SIGNAL_FUNC (newl_toggle_callback), NULL);
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (layercheck), refractvals.newl);
gtk_tooltips_set_tips (tooltips, layercheck,
"Put the refracted image on a new layer or dirty this one?");
gtk_widget_show (layercheck);
toolcheck = gtk_check_button_new_with_label ("Tooltips?");
gtk_container_add(GTK_CONTAINER (GTK_DIALOG (dlg)->vbox),toolcheck);
gtk_signal_connect (GTK_OBJECT (toolcheck), "clicked",
GTK_SIGNAL_FUNC (tooltips_toggle_callback), (gpointer) tooltips);
gtk_tooltips_set_tips (tooltips, toolcheck,
"Turn off these dumb tooltips.");
gtk_widget_show (toolcheck);
/* Tooltips OFF by default. */
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (toolcheck), FALSE);
gtk_tooltips_disable (tooltips);
gtk_widget_show (dlg);
gtk_main ();
gtk_object_unref (GTK_OBJECT (tooltips));
gdk_flush ();
return refractint.run;
} /* refract_dialog */
static GtkWidget*
ior_menu_new(GtkWidget *tieto)
{
GtkWidget *chooser;
GtkWidget *menu, *menuitem;
guint i;
struct foo
{
const gfloat index;
const gchar *name;
};
/* If you change stuff, don't forget to change this. */
#define NUMSTUFF 9
static const struct foo material[NUMSTUFF] =
{
/* Common indicies of refraction (for yellow sodium light, 589 nm) */
/* From my Sears, Zemansky, Young physics book. */
/* For more, check your copy of the CRC or your favorite pov-ray
include file. */
{ 1.0003, "Air" },
{ 1.309, "Ice" },
{ 1.333, "Water"},
{ 1.36, "Alcohol"},
{ 1.473, "Glycerine"},
{ 1.52, "Glass"},
{ 1.544, "Quartz"},
{ 1.923, "Zircon"},
{ 2.417, "Diamond"},
};
chooser = gtk_option_menu_new();
menu = gtk_menu_new();
for (i=0; i < NUMSTUFF; i++) {
menuitem = gtk_menu_item_new_with_label(material[i].name);
gtk_menu_append(GTK_MENU(menu), menuitem);
gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
(GtkSignalFunc)ior_menu_callback,(gfloat *)&material[i].index);
gtk_widget_show(menuitem);
}; /* next i */
gtk_option_menu_set_menu(GTK_OPTION_MENU(chooser), menu);
return chooser;
}
static void
ior_menu_callback (GtkWidget *widget, gfloat *data)
{
#ifdef REFRACT_DEBUG
printf("%f\n",*data);
#endif
}
static gint
map_constrain(gint32 image_id, gint32 drawable_id, gpointer data)
{
if (drawable_id == -1)
return TRUE;
return (gimp_drawable_color(drawable_id) || gimp_drawable_gray(drawable_id));
} /* map_constrain */
/* Callbacks */
static void
newl_toggle_callback (GtkWidget *widget, gpointer data)
{
refractvals.newl = GTK_TOGGLE_BUTTON (widget)->active;
}
static void
tooltips_toggle_callback (GtkWidget *widget, gpointer data)
{
GtkTooltips *tooltips;
tooltips= (GtkTooltips *) data;
if (GTK_TOGGLE_BUTTON (widget)->active)
gtk_tooltips_enable (tooltips);
else
gtk_tooltips_disable (tooltips);
}
static void
refract_close_callback (GtkWidget *widget,
gpointer data)
{
gtk_main_quit ();
}
static void
refract_ok_callback (GtkWidget *widget, gpointer data)
{
refractint.run = TRUE;
gtk_widget_destroy (GTK_WIDGET (data));
}
static void
map_menu_callback (gint32 id, gpointer data)
{
refractvals.lens_id = id;
}

View File

@ -1,82 +0,0 @@
/* refract.h, 1/2/98
* refract: a plug-in for the GIMP 0.99
* By Kevin Turner <kevint@poboxes.com>
* http://www.poboxes.com/kevint/gimp/refract.html
*/
#ifndef REFRACT_DEBUG
#define REFRACT_TITLE "Refract 1/2/98-Beta"
#else
#define REFRACT_TITLE "Refract 1/2/98 (debug)"
#endif
/* Update the progress bar every this-many rows... */
#ifndef PROGRESS_ROWS
#define PROGRESS_ROWS 8
#endif
/* Realistically, this number should be 1.0. An index of refraction
of less than 1 means the speed of light in that substance is
*faster* than in a vacuum! But hey, it's GIMP, when was the last
time we payed any attention to reality? Go ahead... Add
"subspace" to the list of materials... */
#ifndef INDEX_SCALE_MIN
#define INDEX_SCALE_MIN 0.0
#endif
/* This can be whatever is convient. However, I don't know of any
substances (even artifically generated ones) that have an index of
refraction higher than 4.7 or so...*/
#ifndef INDEX_SCALE_MAX
#define INDEX_SCALE_MAX 5.0
#endif
/* For now, our height maps only have one byte per pixel, so guchar
should be sufficient. May need to change in future versions of
GIMP when it supports greater pixel depth. */
#ifndef HEIGHT_TYPE
#define HEIGHT_TYPE guchar
#endif
/* Should we rely more on macros or functions? */
/* #define OLD_SLOPE_MACROS */
#include "gtk/gtk.h"
typedef struct {
gint32 lens_id; /* lens map id */
gint32 refl_id; /* Reflection source ID */
gint32 thick; /* lens thickness */
gint32 refr_dist; /* distance from lens to image. */
gint32 refl_dist; /* Distance from lens/mirror to reflection source. */
gdouble na; /* index a */
gdouble nb; /* index b */
gint32 edge; /* wrap/transparent */
gint32 newl; /* new layer? */
gint32 xofs; /* offset x */
gint32 yofs; /* offset y */
} RefractValues;
/* for refractvals.edge */
/* If a point is outside the selection, then */
#define BACKGROUND 0 /* use background color (or leave transparent, if alpha) */
#define OUTSIDE 1 /* look outside the selection for the point. If the point is
beyond the edge of the layer, use background or alpha.
Only makes sense if the drawable is a selection of only part
of the layer. */
#define WRAP 2 /* like OUTSIDE, but if the point is over the edge of the layer,
get the point by wrapping around. Probably most useful on
images which are tileable. */
/* TO DO: provide a "smear" option? Would take whatever pixel was on
the edge of the selection or layer (depending if IN_ONLY or
OUTSIDE) where we went over. Then BACKGROUND/SMEAR would be a
choice independant of IN_ONLY/OUTSIDE/WRAP. BACKGROUND/SMEAR would
be ignored in the case of WRAP. */
/* One can also imagine a WRAP_WITHIN_SELECTION option, but I don't
think I would use it too often. Would you? Well, if you're
enthusiastic enough, either write a patch to implement it or
convince me to. For now, take the selection and float it, make it
a new layer, merge it back when you're done, or whatever. */

View File

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
warp

View File

@ -1,43 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = warp
warp_SOURCES = \
warp.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
warp_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

File diff suppressed because it is too large Load Diff