added glasstile, colorify, papertile, and illusion plugins

updated despeckle, and math map
This commit is contained in:
Adrian Likins 1997-12-09 05:57:33 +00:00
parent 9109dbafd8
commit 9ac0e40758
26 changed files with 4462 additions and 170 deletions

View File

@ -1,3 +1,10 @@
Tue Dec 9 00:52:15 EST 1997 Adrian Likins <adrian@gimp.org>
* added illusion, papertile, colorify, and glasstile
plugins
* updated despeckle, and math map
Mon Dec 8 21:59:03 PST 1997 Manish Singh <yosh@gimp.org>
* updated CML_explorer

View File

@ -42,6 +42,7 @@ SUBDIRS = \
c_astretch \
CEL \
checkerboard \
colorify \
compose \
convmatrix \
coordmap \
@ -68,6 +69,7 @@ SUBDIRS = \
gfli \
gicon \
gif \
glasstile \
gqbist \
gradmap \
grid \
@ -77,6 +79,7 @@ SUBDIRS = \
hot \
hrz \
ifscompose \
illusion \
iwarp \
laplace \
lic \
@ -91,6 +94,7 @@ SUBDIRS = \
normalize \
nova \
oilify \
papertile \
pat \
pcx \
pix \

View File

@ -0,0 +1,42 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = colorify
colorify_SOURCES = \
colorify.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
colorify_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

@ -0,0 +1,473 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* Colorify. Changes the pixel's luminosity to a specified color
* Copyright (C) 1997 Francisco Bustamante
*
* 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.
*/
/* Changes:
1.1
-Corrected small bug when calling color selection dialog
-Added LUTs to speed things a little bit up
1.0
-First release */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
#define PLUG_IN_NAME "Colorify"
#define PLUG_IN_VERSION "1.1"
static void query (void);
static void run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals);
typedef struct {
guchar color[3];
} ColorifyVals;
typedef struct {
gint run;
} ColorifyInterface;
typedef struct {
guchar red;
guchar green;
guchar blue;
GtkWidget *preview;
gint button_num;
} ButtonInformation;
static ColorifyInterface cint =
{
FALSE
};
static ColorifyVals cvals =
{
{255, 255, 255}
};
static ButtonInformation button_info[] =
{
{255, 0, 0, NULL, 0},
{255, 255, 0, NULL, 0},
{0, 255, 0, NULL, 0},
{0, 255, 255, NULL, 0},
{0, 0, 255, NULL, 0},
{255, 0, 255, NULL, 0},
{255, 255, 255, NULL, 0},
};
GPlugInInfo PLUG_IN_INFO =
{
NULL,
NULL,
query,
run,
};
gint lum_red_lookup[256], lum_green_lookup[256], lum_blue_lookup[256];
gint final_red_lookup[256], final_green_lookup[256], final_blue_lookup[256];
MAIN ()
static int colorify_dialog (guchar red, guchar green, guchar blue);
static void colorify (GDrawable *drawable);
static void set_preview_color (GtkWidget *preview, guchar red, guchar green, guchar blue);
static void
query ()
{
static GParamDef args[] =
{
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
{ PARAM_IMAGE, "image", "Input image" },
{ PARAM_DRAWABLE, "drawable", "Input drawable" },
{ PARAM_COLOR, "color", "Color to apply"},
};
static GParamDef *return_vals = NULL;
static int nargs = sizeof(args) / sizeof(args[0]),
nreturn_vals = 0;
gimp_install_procedure ("Colorify",
"Similar to the \"Color\" mode for layers.",
"Makes an average of the RGB channels and uses it to set the color",
"Francisco Bustamante", "Francisco Bustamante",
"0.0.1", "<Image>/Filters/Image/Colorify", "RGB",
PROC_PLUG_IN,
nargs, nreturn_vals,
args, return_vals);
}
gint sel_x1, sel_x2, sel_y1, sel_y2, sel_width, sel_height;
GtkWidget *preview;
GtkWidget *c_dialog;
static void
run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals)
{
GRunModeType run_mode;
GStatusType status;
static GParam values[1];
GDrawable *drawable;
status = STATUS_SUCCESS;
run_mode = param[0].data.d_int32;
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
*nreturn_vals = 1;
*return_vals = values;
drawable = gimp_drawable_get (param[2].data.d_drawable);
gimp_drawable_mask_bounds (drawable->id, &sel_x1, &sel_y1, &sel_x2, &sel_y2);
sel_width = sel_x2 - sel_x1;
sel_height = sel_y2 - sel_y1;
switch (run_mode) {
case RUN_INTERACTIVE :
gimp_get_data(PLUG_IN_NAME, &cvals);
if (!colorify_dialog (cvals.color[0], cvals.color[1], cvals.color[2]))
return;
break;
case RUN_NONINTERACTIVE :
if (nparams != 4)
status = STATUS_CALLING_ERROR;
if (status == STATUS_SUCCESS) {
cvals.color[0] = param[3].data.d_color.red;
cvals.color[1] = param[3].data.d_color.green;
cvals.color[2] = param[3].data.d_color.blue;
}
break;
case RUN_WITH_LAST_VALS :
/* Possibly retrieve data */
gimp_get_data (PLUG_IN_NAME, &cvals);
break;
default :
break;
}
if (status == STATUS_SUCCESS) {
gimp_progress_init("Colorifying...");
colorify (drawable);
if (run_mode == RUN_INTERACTIVE)
gimp_set_data (PLUG_IN_NAME, &cvals, sizeof (ColorifyVals));
if (run_mode != RUN_NONINTERACTIVE) {
gimp_displays_flush ();
}
}
values[0].data.d_status = status;
}
static void colorify_row (guchar *row,
gint width);
static void close_callback (GtkWidget *widget,
gpointer data);
static void colorify_ok_callback (GtkWidget *widget,
gpointer data);
static void custom_color_callback (GtkWidget *widget,
gpointer data);
static void predefined_color_callback (GtkWidget *widget,
gpointer data);
static void color_changed (GtkWidget *widget,
gpointer data);
static void
colorify (GDrawable *drawable)
{
GPixelRgn source_region, dest_region;
guchar *row;
gint y = 0;
gint progress = 0;
gint i = 0;
for (i = 0; i < 256; i ++) {
lum_red_lookup[i] = i * 0.30;
lum_green_lookup[i] = i * 0.59;
lum_blue_lookup[i] = i * 0.11;
final_red_lookup[i] = i * cvals.color[0] / 255;
final_green_lookup[i] = i * cvals.color[1] / 255;
final_blue_lookup[i] = i * cvals.color[2] / 255;
}
row = g_malloc (sel_width * 3 * sizeof(guchar));
gimp_pixel_rgn_init (&source_region, drawable, sel_x1, sel_y1, sel_width, sel_height, FALSE, FALSE);
gimp_pixel_rgn_init (&dest_region, drawable, sel_x1, sel_y1, sel_width, sel_height, TRUE, TRUE);
for (y = sel_y1; y < sel_y2; y++) {
gimp_pixel_rgn_get_row (&source_region, row, sel_x1, y, sel_width);
colorify_row (row, sel_width);
gimp_pixel_rgn_set_row (&dest_region, row, sel_x1, y, sel_width);
gimp_progress_update ((double) ++progress / sel_height);
}
g_free (row);
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, sel_x1, sel_y1, sel_width, sel_height);
}
static void
colorify_row (guchar *row,
gint width)
{
gint cur_x;
gint lum; /* luminosity */
guchar *current = row;
for (cur_x = 0; cur_x < width; cur_x++) {
lum = lum_red_lookup[current[0]] + lum_green_lookup[current[1]] + lum_blue_lookup[current[2]];
current[0] = final_red_lookup[lum];
current[1] = final_green_lookup[lum];
current[2] = final_blue_lookup[lum];
current += 3;
}
}
static int
colorify_dialog (guchar red,
guchar green,
guchar blue)
{
GtkWidget *dialog;
GtkWidget *label;
GtkWidget *button;
GtkWidget *frame;
GtkWidget *table;
gchar **argv;
gint argc;
gint i;
GSList *group = NULL;
argc = 1;
argv = g_new (gchar *, 1);
argv[0] = g_strdup ("colorify");
gtk_init (&argc, &argv);
gtk_rc_parse (gimp_gtkrc());
dialog = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (dialog), "Colorify");
gtk_window_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
(GtkSignalFunc) close_callback,
NULL);
button = gtk_button_new_with_label ("Ok");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) colorify_ok_callback,
dialog);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->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 (dialog));
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button, TRUE, TRUE, 0);
gtk_widget_show (button);
frame = gtk_frame_new ("Color");
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_border_width (GTK_CONTAINER (frame), 10);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
table = gtk_table_new (2, 7, TRUE);
gtk_container_border_width (GTK_CONTAINER (table), 10);
gtk_container_add (GTK_CONTAINER (frame), table);
gtk_table_set_row_spacings (GTK_TABLE (table), 5);
gtk_table_set_col_spacings (GTK_TABLE (table), 5);
gtk_widget_show (table);
label = gtk_label_new ("Custom Color: ");
gtk_table_attach (GTK_TABLE (table), label, 4, 6, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (label);
button = gtk_radio_button_new (group);
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
gtk_widget_set_usize (button, 35, 35);
gtk_signal_connect (GTK_OBJECT (button), "button_press_event",
(GtkSignalFunc) custom_color_callback,
NULL);
gtk_table_attach (GTK_TABLE (table), button, 6, 7, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (button);
preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (preview), 30, 30);
set_preview_color (preview, cvals.color[0], cvals.color[1], cvals.color[2]);
gtk_container_add (GTK_CONTAINER (button), preview);
gtk_widget_show (preview);
for(i = 0; i < 7; i++) {
group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
button = gtk_radio_button_new (group);
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
button_info[i].preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (button_info[i].preview),
30, 30);
gtk_container_add (GTK_CONTAINER (button), button_info[i].preview);
set_preview_color (button_info[i].preview,
button_info[i].red,
button_info[i].green,
button_info[i].blue);
button_info[i].button_num = i;
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) predefined_color_callback,
&button_info[i].button_num);
gtk_widget_show (button_info[i].preview);
gtk_table_attach (GTK_TABLE (table), button, i, i + 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (button);
}
gtk_widget_show (dialog);
gtk_main();
return cint.run;
}
static void
close_callback (GtkWidget *widget,
gpointer data)
{
gtk_main_quit();
}
static void
colorify_ok_callback (GtkWidget *widget,
gpointer data)
{
gtk_widget_destroy (GTK_WIDGET (data));
cint.run = TRUE;
}
static void
set_preview_color (GtkWidget *preview,
guchar red,
guchar green,
guchar blue)
{
gint i;
guchar buf[3 * 30];
for (i = 0; i < 30; i ++) {
buf [3 * i] = red;
buf [3 * i + 1] = green;
buf [3 * i + 2] = blue;
}
for (i = 0; i < 30; i ++)
gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 30);
gtk_widget_draw (preview, NULL);
}
static void
custom_color_callback (GtkWidget *widget,
gpointer data)
{
GtkColorSelectionDialog *csd;
gdouble colour[3];
c_dialog = gtk_color_selection_dialog_new ("Colorify Custom Color");
csd = GTK_COLOR_SELECTION_DIALOG (c_dialog);
gtk_color_selection_set_update_policy (GTK_COLOR_SELECTION(csd->colorsel),
GTK_UPDATE_DISCONTINUOUS);
gtk_widget_destroy (csd->help_button);
gtk_widget_destroy (csd->cancel_button);
gtk_signal_connect (GTK_OBJECT (csd->ok_button), "clicked",
(GtkSignalFunc) color_changed,
NULL);
colour[0] = cvals.color[0] / 255.0;
colour[1] = cvals.color[1] / 255.0;
colour[2] = cvals.color[2] / 255.0;
gtk_color_selection_set_color (GTK_COLOR_SELECTION (csd->colorsel),
colour);
gtk_window_position (GTK_WINDOW(c_dialog), GTK_WIN_POS_MOUSE);
gtk_widget_show (c_dialog);
}
static void
predefined_color_callback (GtkWidget *widget,
gpointer data)
{
gint *num;
num = (gint *) data;
cvals.color[0] = button_info[*num].red;
cvals.color[1] = button_info[*num].green;
cvals.color[2] = button_info[*num].blue;
}
static void
color_changed (GtkWidget *widget,
gpointer data)
{
gdouble colour[3];
gtk_color_selection_get_color (GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (c_dialog)->colorsel),
colour);
cvals.color[0] = (guchar) (colour[0] * 255.0);
cvals.color[1] = (guchar) (colour[1] * 255.0);
cvals.color[2] = (guchar) (colour[2] * 255.0);
set_preview_color (preview, cvals.color[0], cvals.color[1], cvals.color[2]);
gtk_widget_destroy (c_dialog);
}

473
plug-ins/common/colorify.c Normal file
View File

@ -0,0 +1,473 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* Colorify. Changes the pixel's luminosity to a specified color
* Copyright (C) 1997 Francisco Bustamante
*
* 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.
*/
/* Changes:
1.1
-Corrected small bug when calling color selection dialog
-Added LUTs to speed things a little bit up
1.0
-First release */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
#define PLUG_IN_NAME "Colorify"
#define PLUG_IN_VERSION "1.1"
static void query (void);
static void run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals);
typedef struct {
guchar color[3];
} ColorifyVals;
typedef struct {
gint run;
} ColorifyInterface;
typedef struct {
guchar red;
guchar green;
guchar blue;
GtkWidget *preview;
gint button_num;
} ButtonInformation;
static ColorifyInterface cint =
{
FALSE
};
static ColorifyVals cvals =
{
{255, 255, 255}
};
static ButtonInformation button_info[] =
{
{255, 0, 0, NULL, 0},
{255, 255, 0, NULL, 0},
{0, 255, 0, NULL, 0},
{0, 255, 255, NULL, 0},
{0, 0, 255, NULL, 0},
{255, 0, 255, NULL, 0},
{255, 255, 255, NULL, 0},
};
GPlugInInfo PLUG_IN_INFO =
{
NULL,
NULL,
query,
run,
};
gint lum_red_lookup[256], lum_green_lookup[256], lum_blue_lookup[256];
gint final_red_lookup[256], final_green_lookup[256], final_blue_lookup[256];
MAIN ()
static int colorify_dialog (guchar red, guchar green, guchar blue);
static void colorify (GDrawable *drawable);
static void set_preview_color (GtkWidget *preview, guchar red, guchar green, guchar blue);
static void
query ()
{
static GParamDef args[] =
{
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
{ PARAM_IMAGE, "image", "Input image" },
{ PARAM_DRAWABLE, "drawable", "Input drawable" },
{ PARAM_COLOR, "color", "Color to apply"},
};
static GParamDef *return_vals = NULL;
static int nargs = sizeof(args) / sizeof(args[0]),
nreturn_vals = 0;
gimp_install_procedure ("Colorify",
"Similar to the \"Color\" mode for layers.",
"Makes an average of the RGB channels and uses it to set the color",
"Francisco Bustamante", "Francisco Bustamante",
"0.0.1", "<Image>/Filters/Image/Colorify", "RGB",
PROC_PLUG_IN,
nargs, nreturn_vals,
args, return_vals);
}
gint sel_x1, sel_x2, sel_y1, sel_y2, sel_width, sel_height;
GtkWidget *preview;
GtkWidget *c_dialog;
static void
run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals)
{
GRunModeType run_mode;
GStatusType status;
static GParam values[1];
GDrawable *drawable;
status = STATUS_SUCCESS;
run_mode = param[0].data.d_int32;
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
*nreturn_vals = 1;
*return_vals = values;
drawable = gimp_drawable_get (param[2].data.d_drawable);
gimp_drawable_mask_bounds (drawable->id, &sel_x1, &sel_y1, &sel_x2, &sel_y2);
sel_width = sel_x2 - sel_x1;
sel_height = sel_y2 - sel_y1;
switch (run_mode) {
case RUN_INTERACTIVE :
gimp_get_data(PLUG_IN_NAME, &cvals);
if (!colorify_dialog (cvals.color[0], cvals.color[1], cvals.color[2]))
return;
break;
case RUN_NONINTERACTIVE :
if (nparams != 4)
status = STATUS_CALLING_ERROR;
if (status == STATUS_SUCCESS) {
cvals.color[0] = param[3].data.d_color.red;
cvals.color[1] = param[3].data.d_color.green;
cvals.color[2] = param[3].data.d_color.blue;
}
break;
case RUN_WITH_LAST_VALS :
/* Possibly retrieve data */
gimp_get_data (PLUG_IN_NAME, &cvals);
break;
default :
break;
}
if (status == STATUS_SUCCESS) {
gimp_progress_init("Colorifying...");
colorify (drawable);
if (run_mode == RUN_INTERACTIVE)
gimp_set_data (PLUG_IN_NAME, &cvals, sizeof (ColorifyVals));
if (run_mode != RUN_NONINTERACTIVE) {
gimp_displays_flush ();
}
}
values[0].data.d_status = status;
}
static void colorify_row (guchar *row,
gint width);
static void close_callback (GtkWidget *widget,
gpointer data);
static void colorify_ok_callback (GtkWidget *widget,
gpointer data);
static void custom_color_callback (GtkWidget *widget,
gpointer data);
static void predefined_color_callback (GtkWidget *widget,
gpointer data);
static void color_changed (GtkWidget *widget,
gpointer data);
static void
colorify (GDrawable *drawable)
{
GPixelRgn source_region, dest_region;
guchar *row;
gint y = 0;
gint progress = 0;
gint i = 0;
for (i = 0; i < 256; i ++) {
lum_red_lookup[i] = i * 0.30;
lum_green_lookup[i] = i * 0.59;
lum_blue_lookup[i] = i * 0.11;
final_red_lookup[i] = i * cvals.color[0] / 255;
final_green_lookup[i] = i * cvals.color[1] / 255;
final_blue_lookup[i] = i * cvals.color[2] / 255;
}
row = g_malloc (sel_width * 3 * sizeof(guchar));
gimp_pixel_rgn_init (&source_region, drawable, sel_x1, sel_y1, sel_width, sel_height, FALSE, FALSE);
gimp_pixel_rgn_init (&dest_region, drawable, sel_x1, sel_y1, sel_width, sel_height, TRUE, TRUE);
for (y = sel_y1; y < sel_y2; y++) {
gimp_pixel_rgn_get_row (&source_region, row, sel_x1, y, sel_width);
colorify_row (row, sel_width);
gimp_pixel_rgn_set_row (&dest_region, row, sel_x1, y, sel_width);
gimp_progress_update ((double) ++progress / sel_height);
}
g_free (row);
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, sel_x1, sel_y1, sel_width, sel_height);
}
static void
colorify_row (guchar *row,
gint width)
{
gint cur_x;
gint lum; /* luminosity */
guchar *current = row;
for (cur_x = 0; cur_x < width; cur_x++) {
lum = lum_red_lookup[current[0]] + lum_green_lookup[current[1]] + lum_blue_lookup[current[2]];
current[0] = final_red_lookup[lum];
current[1] = final_green_lookup[lum];
current[2] = final_blue_lookup[lum];
current += 3;
}
}
static int
colorify_dialog (guchar red,
guchar green,
guchar blue)
{
GtkWidget *dialog;
GtkWidget *label;
GtkWidget *button;
GtkWidget *frame;
GtkWidget *table;
gchar **argv;
gint argc;
gint i;
GSList *group = NULL;
argc = 1;
argv = g_new (gchar *, 1);
argv[0] = g_strdup ("colorify");
gtk_init (&argc, &argv);
gtk_rc_parse (gimp_gtkrc());
dialog = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (dialog), "Colorify");
gtk_window_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
(GtkSignalFunc) close_callback,
NULL);
button = gtk_button_new_with_label ("Ok");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) colorify_ok_callback,
dialog);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->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 (dialog));
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button, TRUE, TRUE, 0);
gtk_widget_show (button);
frame = gtk_frame_new ("Color");
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_border_width (GTK_CONTAINER (frame), 10);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
table = gtk_table_new (2, 7, TRUE);
gtk_container_border_width (GTK_CONTAINER (table), 10);
gtk_container_add (GTK_CONTAINER (frame), table);
gtk_table_set_row_spacings (GTK_TABLE (table), 5);
gtk_table_set_col_spacings (GTK_TABLE (table), 5);
gtk_widget_show (table);
label = gtk_label_new ("Custom Color: ");
gtk_table_attach (GTK_TABLE (table), label, 4, 6, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (label);
button = gtk_radio_button_new (group);
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
gtk_widget_set_usize (button, 35, 35);
gtk_signal_connect (GTK_OBJECT (button), "button_press_event",
(GtkSignalFunc) custom_color_callback,
NULL);
gtk_table_attach (GTK_TABLE (table), button, 6, 7, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (button);
preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (preview), 30, 30);
set_preview_color (preview, cvals.color[0], cvals.color[1], cvals.color[2]);
gtk_container_add (GTK_CONTAINER (button), preview);
gtk_widget_show (preview);
for(i = 0; i < 7; i++) {
group = gtk_radio_button_group (GTK_RADIO_BUTTON (button));
button = gtk_radio_button_new (group);
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
button_info[i].preview = gtk_preview_new (GTK_PREVIEW_COLOR);
gtk_preview_size (GTK_PREVIEW (button_info[i].preview),
30, 30);
gtk_container_add (GTK_CONTAINER (button), button_info[i].preview);
set_preview_color (button_info[i].preview,
button_info[i].red,
button_info[i].green,
button_info[i].blue);
button_info[i].button_num = i;
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) predefined_color_callback,
&button_info[i].button_num);
gtk_widget_show (button_info[i].preview);
gtk_table_attach (GTK_TABLE (table), button, i, i + 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (button);
}
gtk_widget_show (dialog);
gtk_main();
return cint.run;
}
static void
close_callback (GtkWidget *widget,
gpointer data)
{
gtk_main_quit();
}
static void
colorify_ok_callback (GtkWidget *widget,
gpointer data)
{
gtk_widget_destroy (GTK_WIDGET (data));
cint.run = TRUE;
}
static void
set_preview_color (GtkWidget *preview,
guchar red,
guchar green,
guchar blue)
{
gint i;
guchar buf[3 * 30];
for (i = 0; i < 30; i ++) {
buf [3 * i] = red;
buf [3 * i + 1] = green;
buf [3 * i + 2] = blue;
}
for (i = 0; i < 30; i ++)
gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 30);
gtk_widget_draw (preview, NULL);
}
static void
custom_color_callback (GtkWidget *widget,
gpointer data)
{
GtkColorSelectionDialog *csd;
gdouble colour[3];
c_dialog = gtk_color_selection_dialog_new ("Colorify Custom Color");
csd = GTK_COLOR_SELECTION_DIALOG (c_dialog);
gtk_color_selection_set_update_policy (GTK_COLOR_SELECTION(csd->colorsel),
GTK_UPDATE_DISCONTINUOUS);
gtk_widget_destroy (csd->help_button);
gtk_widget_destroy (csd->cancel_button);
gtk_signal_connect (GTK_OBJECT (csd->ok_button), "clicked",
(GtkSignalFunc) color_changed,
NULL);
colour[0] = cvals.color[0] / 255.0;
colour[1] = cvals.color[1] / 255.0;
colour[2] = cvals.color[2] / 255.0;
gtk_color_selection_set_color (GTK_COLOR_SELECTION (csd->colorsel),
colour);
gtk_window_position (GTK_WINDOW(c_dialog), GTK_WIN_POS_MOUSE);
gtk_widget_show (c_dialog);
}
static void
predefined_color_callback (GtkWidget *widget,
gpointer data)
{
gint *num;
num = (gint *) data;
cvals.color[0] = button_info[*num].red;
cvals.color[1] = button_info[*num].green;
cvals.color[2] = button_info[*num].blue;
}
static void
color_changed (GtkWidget *widget,
gpointer data)
{
gdouble colour[3];
gtk_color_selection_get_color (GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (c_dialog)->colorsel),
colour);
cvals.color[0] = (guchar) (colour[0] * 255.0);
cvals.color[1] = (guchar) (colour[1] * 255.0);
cvals.color[2] = (guchar) (colour[2] * 255.0);
set_preview_color (preview, cvals.color[0], cvals.color[1], cvals.color[2]);
gtk_widget_destroy (c_dialog);
}

View File

@ -44,17 +44,19 @@
* Revision History:
*
* $Log$
* Revision 1.1.1.1 1997/11/24 22:04:12 sopwith
* Let's try this import one last time.
* Revision 1.2 1997/12/09 05:57:27 adrian
* added glasstile, colorify, papertile, and illusion plugins
*
* Revision 1.1 1997/11/14 20:08:37 nobody
* *** empty log message ***
* updated despeckle, and math map
*
* Revision 1.2 1997/09/27 10:30:27 nobody
* Boatload of changes from 0.99.11 to 0.99.12. For details, see the ChangeLog :-)
* Revision 1.14 1997/11/14 17:17:59 mike
* Updated to dynamically allocate return params in the run() function.
*
* (Now that we are all using cvs (right?), this boatload of changes kind
* of commit shouldn't happen...)
* Revision 1.13 1997/11/12 15:53:34 mike
* Added <string.h> header file for Digital UNIX...
*
* Revision 1.12 1997/10/17 13:56:54 mike
* Updated author/contact information.
*
* Revision 1.11 1997/06/12 16:58:11 mike
* Optimized final despeckle - now grab gimp_tile_height() rows at a time
@ -101,18 +103,27 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <gtk/gtk.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
/*
* Macros...
*/
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
/*
* Constants...
*/
#define PLUG_IN_NAME "plug_in_despeckle"
#define PLUG_IN_VERSION "1.1"
#define PLUG_IN_VERSION "1.1.3 - 14 November 1997"
#define PREVIEW_SIZE 128
#define SCALE_WIDTH 64
#define ENTRY_WIDTH 64
@ -219,8 +230,10 @@ query(void)
gimp_install_procedure(PLUG_IN_NAME,
"Despeckle filter, typically used to \'despeckle\' a photographic image.",
"This plug-in selectively performs a median or adaptive box filter on an image.",
"Michael Sweet", "Michael Sweet",
PLUG_IN_VERSION, "<Image>/Filters/Image/Despeckle...", "RGB*, GRAY*",
"Michael Sweet <mike@easysw.com>",
"Michael Sweet <mike@easysw.com>",
PLUG_IN_VERSION,
"<Image>/Filters/Image/Despeckle...", "RGB*, GRAY*",
PROC_PLUG_IN, nargs, nreturn_vals, args, return_vals);
}
@ -238,7 +251,7 @@ run(char *name, /* I - Name of filter program. */
{
GRunModeType run_mode; /* Current run mode */
GStatusType status; /* Return status */
static GParam values[1]; /* Return values */
GParam *values; /* Return values */
/*
@ -248,6 +261,8 @@ run(char *name, /* I - Name of filter program. */
status = STATUS_SUCCESS;
run_mode = param[0].data.d_int32;
values = g_new(GParam, 1);
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
@ -783,7 +798,8 @@ despeckle_dialog(void)
static void
preview_init(void)
{
int size, /* Size of filter box */
int row, /* Current row in preview_srcs */
size, /* Size of filter box */
width; /* Byte width of the image */
@ -1003,7 +1019,8 @@ preview_update(void)
static void
preview_exit(void)
{
int size; /* Size of row buffer */
int row, /* Looping var */
size; /* Size of row buffer */
size = MAX_RADIUS * 2 + 1;

427
plug-ins/common/glasstile.c Normal file
View File

@ -0,0 +1,427 @@
/*
* This is the Glass Tile plug-in for the GIMP 0.99
* Version 1.01
*
* Copyright (C) 1997 Karl-Johan Andersson (t96kja@student.tdb.uu.se)
*
* 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.
*
*/
/*
* This filter divide the image into square "glass"-blocks in which
* the image is refracted.
*
* The alpha-channel is left unchanged.
*
* Please send any comments or suggestions to
* Karl-Johan Andersson (t96kja@student.tdb.uu.se)
*
*/
#include <stdlib.h>
#include "libgimp/gimp.h"
#include "gtk/gtk.h"
/* --- Typedefs --- */
typedef struct {
gint xblock;
gint yblock;
} GlassValues;
typedef struct {
gint run;
} GlassInterface;
/* --- Declare local functions --- */
static void query (void);
static void run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals);
static gint glass_dialog (void);
static void glass_close_callback (GtkWidget *widget, gpointer data);
static void glass_ok_callback (GtkWidget *widget, gpointer data);
static void glass_scale_update (GtkAdjustment *adjustment, gpointer data);
static void glasstile (GDrawable *drawable);
/* --- Variables --- */
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
static GlassValues gtvals =
{
20, /* tile width */
20 /* tile height */
};
static GlassInterface gt_int =
{
FALSE /* run */
};
/* --- Functions --- */
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_INT32, "tilex", "Tile width (10 - 50)" },
{ PARAM_INT32, "tiley", "Tile height (10 - 50)" },
};
static GParamDef *return_vals = NULL;
static int nargs = sizeof (args) / sizeof (args[0]);
static int nreturn_vals = 0;
gimp_install_procedure ("plug_in_glasstile",
"Divide the image into square glassblocks",
"More here later",
"Karl-Johan Andersson", /* Author */
"Karl-Johan Andersson", /* Copyright */
"1997",
"<Image>/Filters/Distorts/Glass Tile",
"RGB*, GRAY*",
PROC_PLUG_IN,
nargs, nreturn_vals,
args, return_vals);
}
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;
run_mode = param[0].data.d_int32;
*nreturn_vals = 1;
*return_vals = values;
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
/* Get the specified drawable */
drawable = gimp_drawable_get (param[2].data.d_drawable);
switch (run_mode)
{
case RUN_INTERACTIVE:
/* Possibly retrieve data */
gimp_get_data ("plug_in_glasstile", &gtvals);
/* First acquire information with a dialog */
if (! glass_dialog ())
{
gimp_drawable_detach (drawable);
return;
}
break;
case RUN_NONINTERACTIVE:
/* Make sure all the arguments are there! */
if (nparams != 5)
status = STATUS_CALLING_ERROR;
if (status == STATUS_SUCCESS)
{
gtvals.xblock = (gint) param[3].data.d_int32;
gtvals.yblock = (gint) param[4].data.d_int32;
}
if (gtvals.xblock < 10 || gtvals.xblock > 50)
status = STATUS_CALLING_ERROR;
if (gtvals.yblock < 10 || gtvals.yblock > 50)
status = STATUS_CALLING_ERROR;
break;
case RUN_WITH_LAST_VALS:
/* Possibly retrieve data */
gimp_get_data ("plug_in_glasstile", &gtvals);
break;
default:
break;
}
if (status == STATUS_SUCCESS)
{
/* Make sure that the drawable is gray or RGB color */
if (gimp_drawable_color (drawable->id) || gimp_drawable_gray (drawable->id))
{
gimp_progress_init ("Glass Tile...");
gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));
glasstile (drawable);
if (run_mode != RUN_NONINTERACTIVE)
gimp_displays_flush ();
/* Store data */
if (run_mode == RUN_INTERACTIVE)
gimp_set_data ("plug_in_glasstile", &gtvals, sizeof (GlassValues));
}
else
{
/* gimp_message ("glasstile: cannot operate on indexed color images"); */
status = STATUS_EXECUTION_ERROR;
}
}
values[0].data.d_status = status;
gimp_drawable_detach (drawable);
}
static gint glass_dialog ()
{
GtkWidget *dlg;
GtkWidget *label;
GtkWidget *button;
GtkWidget *scale;
GtkWidget *frame;
GtkWidget *table;
GtkObject *adjustment;
gchar **argv;
gint argc;
argc = 1;
argv = g_new (gchar *, 1);
argv[0] = g_strdup ("glasstile");
gtk_init (&argc, &argv);
gtk_rc_parse (gimp_gtkrc ());
dlg = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (dlg), "Glass Tile");
gtk_window_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
(GtkSignalFunc) glass_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) glass_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);
/* Parameter settings */
frame = gtk_frame_new ("Parameter Settings");
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_border_width (GTK_CONTAINER (frame), 10);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, TRUE, TRUE, 0);
table = gtk_table_new (2, 2, FALSE); /* table height, width */
gtk_container_border_width (GTK_CONTAINER (table), 10);
gtk_container_add (GTK_CONTAINER (frame), table);
/* Horizontal scale - Width */
label = gtk_label_new ("Tile Width");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, 0, 5, 0);
/* xStart, xEnd, yStart, yEnd */
adjustment = gtk_adjustment_new (gtvals.xblock, 10, 50, 1, 1, 0);
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
(GtkSignalFunc) glass_scale_update,
&(gtvals.xblock));
scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
gtk_widget_set_usize (scale, 150, 30);
gtk_table_attach (GTK_TABLE (table), scale, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_widget_show (label);
gtk_widget_show (scale);
/* Horizontal scale - Height */
label = gtk_label_new ("Tile Height");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, 0, 5, 0);
adjustment = gtk_adjustment_new (gtvals.yblock, 10, 50, 1, 1, 0);
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
(GtkSignalFunc) glass_scale_update,
&(gtvals.yblock));
scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
gtk_widget_set_usize (scale, 150, 30);
gtk_table_attach (GTK_TABLE (table), scale, 1, 2, 1, 2, GTK_FILL, 0, 0, 0);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_widget_show (label);
gtk_widget_show (scale);
gtk_widget_show (frame);
gtk_widget_show (table);
gtk_widget_show (dlg);
gtk_main ();
gdk_flush ();
return gt_int.run;
}
/* - Interface functions - */
static void glass_close_callback (GtkWidget *widget, gpointer data)
{
gtk_main_quit ();
}
static void glass_ok_callback (GtkWidget *widget, gpointer data)
{
gt_int.run = TRUE;
gtk_widget_destroy (GTK_WIDGET (data));
}
static void glass_scale_update (GtkAdjustment *adjustment, gpointer data)
{
gint *dptr = (gint*) data;
*dptr = (gint) adjustment->value;
}
/* - Filter function - */
static void glasstile (GDrawable *drawable)
{
GPixelRgn srcPR, destPR;
gint width, height;
gint bytes;
guchar *dest, *d, *ad;
guchar *cur_row;
gint row, col, i, iwidth;
gint x1, y1, x2, y2;
gint rutbredd, xpixel1, xpixel2;
gint ruthojd , ypixel2;
gint xhalv, xoffs, xmitt, xplus;
gint yhalv, yoffs, ymitt, yplus, cbytes;
/* 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, &x1, &y1, &x2, &y2);
/* 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;
/* allocate row buffers */
cur_row = (guchar *) malloc ((x2 - x1) * bytes);
dest = (guchar *) malloc ((x2 - x1) * bytes);
ad = (guchar *) malloc ((x2 - x1) * bytes);
/* 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);
rutbredd = gtvals.xblock;
ruthojd = gtvals.yblock;
xhalv = rutbredd / 2;
yhalv = ruthojd / 2;
cbytes = bytes;
if (cbytes%2 == 0) cbytes--;
iwidth = width - x1;
xplus = rutbredd % 2;
yplus = ruthojd % 2;
ymitt = y1;
yoffs = 0;
/* Loop through the rows */
for (row = y1; row < y2; row++)
{
d = dest;
ypixel2 = ymitt + yoffs * 2;
if (ypixel2 < height)
gimp_pixel_rgn_get_row (&srcPR, cur_row, x1, ypixel2, iwidth);
else
gimp_pixel_rgn_get_row (&srcPR, cur_row, x1, y2-1, iwidth);
if (cbytes != bytes) /* Alpha check */
gimp_pixel_rgn_get_row (&srcPR, ad, x1, row, (x2-x1));
yoffs++;
if (yoffs == yhalv) {
ymitt += ruthojd;
yoffs =- yhalv;
yoffs -= yplus;
}
xmitt = 0;
xoffs = 0;
for (col = 0; col < (x2 - x1); col++) /* one pixel */
{
xpixel1 = (xmitt + xoffs) * bytes;
xpixel2 = (xmitt + xoffs * 2) * bytes;
if (xpixel2 < ((x2 - x1) * bytes)) {
for (i = 0; i < cbytes; i++)
d[xpixel1 + i] = cur_row[xpixel2 + i];
}
else {
for (i = 0; i < cbytes; i++)
d[xpixel1 + i]=cur_row[xpixel1 + i];
}
if (cbytes != bytes) /* Alpha channel unchanged */
d[xpixel1 + cbytes] = ad[xpixel1 + cbytes];
xoffs++;
if (xoffs == xhalv) {
xmitt += rutbredd;
xoffs =- xhalv;
xoffs -= xplus;
}
}
/* Store the dest */
gimp_pixel_rgn_set_row (&destPR, dest, x1, row, iwidth);
if ((row % 5) == 0)
gimp_progress_update ((double) row / (double) (y2 - y1));
}
/* Update region */
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, x1, y1, (x2 - x1), (y2 - y1));
free (cur_row);
free (dest);
free (ad);
}

368
plug-ins/common/illusion.c Normal file
View File

@ -0,0 +1,368 @@
/*******************************************************************************
illusion.c -- This is a plug-in for the GIMP 1.0
Copyright (C) 1997 Hirotsuna Mizuno
s1041150@u-aizu.ac.jp
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 <gtk/gtk.h>
#include <math.h>
#include "libgimp/gimp.h"
#define PLUG_IN_NAME "plug_in_illusion"
#define PLUG_IN_VERSION "v0.7 (Dec. 25 1997)"
#define DIALOG_CAPTION "Illusion"
#ifndef PI
#define PI 3.141592653589793238462643383279
#endif
#ifndef PI_2
#define PI_2 (PI*2)
#endif
/******************************************************************************/
static void query( void );
static void run( char *, int, GParam *, int *, GParam ** );
static void filter( GDrawable *drawable );
static int dialog( void );
/******************************************************************************/
typedef struct {
gint32 division;
} parameter_t;
/******************************************************************************/
GPlugInInfo PLUG_IN_INFO = {
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
static parameter_t parameters = {
8
};
static gint image_width;
static gint image_height;
static gint image_bpp;
static gint image_has_alpha;
static gint select_x1;
static gint select_y1;
static gint select_x2;
static gint select_y2;
static gint select_width;
static gint select_height;
static gdouble center_x;
static gdouble center_y;
/******************************************************************************/
MAIN();
/******************************************************************************/
static void query( void )
{
static int nargs = 4;
static GParamDef args[] = {
{ PARAM_INT32, "run_mode", "interactive / non-interactive" },
{ PARAM_IMAGE, "image", "input image" },
{ PARAM_DRAWABLE, "drawable", "input drawable" },
{ PARAM_INT32, "division", "the number of divisions" }
};
static int nreturn_vals = 0;
static GParamDef *return_vals = NULL;
gimp_install_procedure(
PLUG_IN_NAME,
"produce illusion",
"produce illusion",
"Hirotsuna Mizuno <s1041150@u-aizu.ac.jp>",
"Hirotsuna Mizuno",
PLUG_IN_VERSION,
"<Image>/Filters/Effects/Illusion",
"RGB*, GRAY*",
PROC_PLUG_IN,
nargs,
nreturn_vals,
args,
return_vals
);
}
/******************************************************************************/
static void run( char *name,
int paramc,
GParam *params,
int *returnc,
GParam **returns )
{
GDrawable *drawable;
GRunModeType run_mode;
static GParam returnv[1];
GStatusType status = STATUS_SUCCESS;
run_mode = params[0].data.d_int32;
drawable = gimp_drawable_get( params[2].data.d_drawable );
*returnc = 1;
*returns = returnv;
/* get the drawable info */
image_width = gimp_drawable_width( drawable->id );
image_height = gimp_drawable_height( drawable->id );
image_bpp = gimp_drawable_bpp( drawable->id );
image_has_alpha = gimp_drawable_has_alpha( drawable->id );
gimp_drawable_mask_bounds( drawable->id,
&select_x1, &select_y1, &select_x2, &select_y2 );
select_width = select_x2 - select_x1;
select_height = select_y2 - select_y1;
center_x = select_x1 + (gdouble)select_width / 2;
center_y = select_y1 + (gdouble)select_height / 2;
/* switch the run mode */
switch( run_mode ){
case RUN_INTERACTIVE:
gimp_get_data( PLUG_IN_NAME, &parameters );
if( ! dialog() ) return;
gimp_set_data( PLUG_IN_NAME, &parameters, sizeof( parameter_t ) );
break;
case RUN_NONINTERACTIVE:
if( paramc != 4 ){
status = STATUS_CALLING_ERROR;
} else {
parameters.division = params[3].data.d_int32;
}
break;
case RUN_WITH_LAST_VALS:
gimp_get_data( PLUG_IN_NAME, &parameters );
break;
}
if( status == STATUS_SUCCESS ){
if( gimp_drawable_color( drawable->id ) ||
gimp_drawable_gray( drawable->id ) ){
gimp_tile_cache_ntiles( 2 * ( drawable->width / gimp_tile_width() + 1 ) );
filter( drawable );
if( run_mode != RUN_NONINTERACTIVE ) gimp_displays_flush ();
} else {
status = STATUS_EXECUTION_ERROR;
}
}
returnv[0].type = PARAM_STATUS;
returnv[0].data.d_status = status;
gimp_drawable_detach( drawable );
}
/******************************************************************************/
static void filter( GDrawable *drawable )
{
GPixelRgn srcPR, destPR;
guchar **pixels;
guchar **destpixels;
gint x, y, b;
gint xx, yy;
gdouble scale, radius, cx, cy, angle, offset;
gimp_pixel_rgn_init( &srcPR, drawable,
0, 0, image_width, image_height, FALSE, FALSE );
gimp_pixel_rgn_init( &destPR, drawable,
0, 0, image_width, image_height, TRUE, TRUE );
pixels = (guchar **)malloc( image_height * sizeof(guchar *) );
destpixels = (guchar **)malloc( image_height * sizeof(guchar *) );
for( y = 0; y < image_height; y++ ){
pixels[y] = (guchar *)malloc( image_width * image_bpp );
destpixels[y] = (guchar *)malloc( image_width * image_bpp );
gimp_pixel_rgn_get_row( &srcPR, pixels[y], 0, y, image_width );
}
/*
for( y = select_y1; y < select_y2; y++ ){
for( x = select_x1; x < select_x2; x++ ){
for( b = 0; b < image_bpp; b++ ){
destpixels[y][x*image_bpp+b] = 0;
}
}
}
*/
gimp_progress_init( PLUG_IN_NAME );
scale = sqrt(select_width*select_width+select_height*select_height) / 2;
offset = (gint)(scale / 2);
for( y = select_y1; y < select_y2; y++ ){
cy = ((gdouble)y - center_y) / scale;
for( x = select_x1; x < select_x2; x++ ){
cx = ((gdouble)x - center_x) / scale;
angle = floor( atan2(cy,cx) * parameters.division / PI_2 )
* PI_2 / parameters.division + ( PI / parameters.division );
radius = sqrt((gdouble)(cx*cx+cy*cy));
xx = x - offset * cos( angle );
yy = y - offset * sin( angle );
if( xx < 0 ) xx = 0;
else if( image_width <= xx ) xx = image_width - 1;
if( yy < 0 ) yy = 0;
else if( image_height <= yy ) yy = image_height - 1;
for( b = 0; b < image_bpp; b++ )
destpixels[y][x*image_bpp+b] =
(1-radius)*pixels[y][x*image_bpp+b]
+ radius*pixels[yy][xx*image_bpp+b];
}
gimp_pixel_rgn_set_row (&destPR, destpixels[y], 0, y, image_width );
gimp_progress_update ( (double)( y - select_y1 ) / (double)select_height );
}
gimp_drawable_flush( drawable );
gimp_drawable_merge_shadow( drawable->id, TRUE );
gimp_drawable_update( drawable->id,
select_x1, select_y1, select_width, select_height );
for( y = select_y1; y < select_y2; y++ ) free( pixels[y-select_y1] );
free( pixels );
for( y = select_y1; y < select_y2; y++ ) free( destpixels[y-select_y1] );
free( destpixels );
}
/******************************************************************************/
static int dialog_status;
static GtkWidget *entry_division;
static void dialog_destroy_handler( GtkWidget *widget, gpointer *data )
{
gtk_main_quit();
}
static void dialog_ok_handler( GtkWidget *widget, gpointer *data )
{
dialog_status = TRUE;
parameters.division =
(gint32)atof(gtk_entry_get_text( GTK_ENTRY( entry_division ) ) );
gtk_widget_destroy( GTK_WIDGET( data ) );
}
static void dialog_cancel_handler( GtkWidget *widget, gpointer *data )
{
dialog_status = FALSE;
gtk_widget_destroy( GTK_WIDGET( data ) );
}
/******************************************************************************/
static int dialog( void )
{
GtkWidget *window;
dialog_status = FALSE;
{
gint argc = 1;
gchar **argv = g_new( gchar *, 1 );
argv[0] = g_strdup( DIALOG_CAPTION );
gtk_init( &argc, &argv );
}
/* dialog window */
window = gtk_dialog_new();
gtk_signal_connect( GTK_OBJECT( window ), "destroy",
GTK_SIGNAL_FUNC( dialog_destroy_handler ), NULL );
gtk_container_border_width( GTK_CONTAINER( window ), 0 );
gtk_container_border_width( GTK_CONTAINER( GTK_DIALOG( window )->vbox ), 5 );
{
/* buttons */
GtkWidget *button;
/* ok button */
button = gtk_button_new_with_label( "OK" );
gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
GTK_SIGNAL_FUNC( dialog_ok_handler ),
GTK_OBJECT( window ) );
GTK_WIDGET_SET_FLAGS( button, GTK_CAN_DEFAULT );
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->action_area ),
button, TRUE, TRUE, 0 );
gtk_widget_grab_default( button );
gtk_widget_show( button );
/* cancel button */
button = gtk_button_new_with_label( "Cancel" );
gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
GTK_SIGNAL_FUNC( dialog_cancel_handler ),
GTK_OBJECT( window )) ;
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->action_area ),
button, TRUE, TRUE, 0 );
gtk_widget_show( button );
}
{
/* text boxes */
GtkWidget *table;
GtkWidget *label;
char buffer[32];
/* table */
table = gtk_table_new( 1, 2, FALSE );
gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->vbox ),
table, TRUE, TRUE, 0 );
gtk_widget_show( table );
/* tile width */
label = gtk_label_new( "division: " );
entry_division = gtk_entry_new();
sprintf( buffer, "%d", parameters.division );
gtk_entry_set_text( GTK_ENTRY( entry_division ), buffer );
gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 0, 1 );
gtk_table_attach_defaults( GTK_TABLE( table ), entry_division, 1, 2, 0, 1 );
gtk_widget_show( label );
gtk_widget_show( entry_division );
}
gtk_widget_show( window );
gtk_main();
return dialog_status;
}
/******************************************************************************/

469
plug-ins/common/papertile.c Normal file
View File

@ -0,0 +1,469 @@
/*******************************************************************************
papertile.c -- This is a plug-in for the GIMP 1.0
Copyright (C) 1997 Hirotsuna Mizuno
s1041150@u-aizu.ac.jp
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 <gtk/gtk.h>
#include <libgimp/gimp.h>
#define PLUG_IN_NAME "plug_in_paper_tile"
#define PLUG_IN_VERSION "v0.7 (Dec. 25 1997)"
#define DIALOG_CAPTION "Paper Tile"
/******************************************************************************/
static void query( void );
static void run( char *, int, GParam *, int *, GParam ** );
static void filter( GDrawable *drawable );
static int dialog( void );
/******************************************************************************/
#define BG_TYPE_TRANSPARENT 0
#define BG_TYPE_BLACK 1
#define BG_TYPE_WHITE 2
typedef struct {
gint32 tile_width;
gint32 tile_height;
gint32 slide_length;
gint32 bg_type;
} parameter_t;
/******************************************************************************/
GPlugInInfo PLUG_IN_INFO = {
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
static parameter_t parameters = {
50,
50,
10,
BG_TYPE_TRANSPARENT
};
static gint image_width;
static gint image_height;
static gint image_bpp;
static gint image_has_alpha;
static gint select_x1;
static gint select_y1;
static gint select_x2;
static gint select_y2;
static gint select_width;
static gint select_height;
/******************************************************************************/
MAIN();
/******************************************************************************/
static void query( void )
{
static int nargs = 7;
static GParamDef args[] = {
{ PARAM_INT32, "run_mode", "interactive / non-interactive" },
{ PARAM_IMAGE, "image", "input image" },
{ PARAM_DRAWABLE, "drawable", "input drawable" },
{ PARAM_INT32, "width", "tile width" },
{ PARAM_INT32, "height", "tile height" },
{ PARAM_INT32, "slide_length", "slide length" },
{ PARAM_INT32, "bg_type", "background color "
"(0=transparent, 1=black, 2=white )" }
};
static int nreturn_vals = 0;
static GParamDef *return_vals = NULL;
gimp_install_procedure(
PLUG_IN_NAME,
"cut and slide image",
"cut and slide image",
"Hirotsuna Mizuno <s1041150@u-aizu.ac.jp>",
"Hirotsuna Mizuno",
PLUG_IN_VERSION,
"<Image>/Filters/Effects/Paper Tile",
"RGB*, GRAY*",
PROC_PLUG_IN,
nargs,
nreturn_vals,
args,
return_vals
);
}
/******************************************************************************/
static void run( char *name,
int paramc,
GParam *params,
int *returnc,
GParam **returns )
{
GDrawable *drawable;
GRunModeType run_mode;
static GParam returnv[1];
GStatusType status = STATUS_SUCCESS;
run_mode = params[0].data.d_int32;
drawable = gimp_drawable_get( params[2].data.d_drawable );
*returnc = 1;
*returns = returnv;
/* get the drawable info */
image_width = gimp_drawable_width( drawable->id );
image_height = gimp_drawable_height( drawable->id );
image_bpp = gimp_drawable_bpp( drawable->id );
image_has_alpha = gimp_drawable_has_alpha( drawable->id );
gimp_drawable_mask_bounds( drawable->id,
&select_x1, &select_y1, &select_x2, &select_y2 );
select_width = select_x2 - select_x1;
select_height = select_y2 - select_y1;
/* switch the run mode */
switch( run_mode ){
case RUN_INTERACTIVE:
gimp_get_data( PLUG_IN_NAME, &parameters );
if( ! dialog() ) return;
gimp_set_data( PLUG_IN_NAME, &parameters, sizeof( parameter_t ) );
break;
case RUN_NONINTERACTIVE:
if( paramc != 7 ){
status = STATUS_CALLING_ERROR;
} else {
parameters.tile_width = params[3].data.d_int32;
parameters.tile_height = params[4].data.d_int32;
parameters.slide_length = params[5].data.d_int32;
parameters.bg_type = params[6].data.d_int32;
}
break;
case RUN_WITH_LAST_VALS:
gimp_get_data( PLUG_IN_NAME, &parameters );
break;
}
if( status == STATUS_SUCCESS ){
if( gimp_drawable_color( drawable->id ) ||
gimp_drawable_gray( drawable->id ) ){
gimp_tile_cache_ntiles( 2 * ( drawable->width / gimp_tile_width() + 1 ) );
filter( drawable );
if( run_mode != RUN_NONINTERACTIVE ) gimp_displays_flush ();
} else {
status = STATUS_EXECUTION_ERROR;
}
}
returnv[0].type = PARAM_STATUS;
returnv[0].data.d_status = status;
gimp_drawable_detach( drawable );
}
/******************************************************************************/
static void filter( GDrawable *drawable )
{
GPixelRgn srcPR, destPR;
guchar **pixels;
guchar **destpixels;
gint x, y, b;
gint vx, vy, xx, yy;
gimp_pixel_rgn_init( &srcPR, drawable,
0, 0, image_width, image_height, FALSE, FALSE );
gimp_pixel_rgn_init( &destPR, drawable,
0, 0, image_width, image_height, TRUE, TRUE );
pixels = (guchar **)malloc( image_height * sizeof(guchar *) );
destpixels = (guchar **)malloc( image_height * sizeof(guchar *) );
for( y = 0; y < image_height; y++ ){
pixels[y] = (guchar *)malloc( image_width * image_bpp );
destpixels[y] = (guchar *)malloc( image_width * image_bpp );
gimp_pixel_rgn_get_row( &srcPR, pixels[y], 0, y, image_width );
}
for( y = select_y1; y < select_y2; y++ ){
for( x = select_x1; x < select_x2; x++ ){
switch( parameters.bg_type ){
case BG_TYPE_TRANSPARENT:
for( b = 0; b < image_bpp; b++ ){
destpixels[y][x*image_bpp+b] = 0;
}
break;
case BG_TYPE_BLACK:
for( b = 0; b < image_bpp; b++ ){
if( b == image_bpp - 1 && image_has_alpha ){
destpixels[y][x*image_bpp+b] = 255;
} else {
destpixels[y][x*image_bpp+b] = 0;
}
}
break;
case BG_TYPE_WHITE:
for( b = 0; b < image_bpp; b++ ){
destpixels[y][x*image_bpp+b] = 255;
}
break;
}
}
}
gimp_progress_init( PLUG_IN_NAME );
for( y = select_y1; y < select_y2; y+=parameters.tile_height )
for( x = select_x1; x < select_x2; x+=parameters.tile_width ){
vx = rand()%parameters.slide_length - parameters.slide_length/2;
vy = rand()%parameters.slide_length - parameters.slide_length/2;
for( xx = 0; xx < parameters.tile_width; xx++ )
if( 0 <= x+xx+vx && x+xx+vx < image_width && x+xx < image_width )
for( yy = 0; yy < parameters.tile_height; yy++ )
if( 0 <= y+yy+vy && y+yy+vy < image_height && y+yy < image_height )
for( b = 0; b < image_bpp; b++ )
destpixels[y+yy+vy][(x+xx+vx)*image_bpp+b]
= pixels[y+yy][(x+xx)*image_bpp+b];
}
for( y = select_y1; y < select_y2; y++ ){
gimp_pixel_rgn_set_row (&destPR, destpixels[y], 0, y, image_width );
gimp_progress_update ( (double)( y - select_y1 ) / select_height );
}
gimp_drawable_flush( drawable );
gimp_drawable_merge_shadow( drawable->id, TRUE );
gimp_drawable_update( drawable->id,
select_x1, select_y1, select_width, select_height );
for( y = select_y1; y < select_y2; y++ ) free( pixels[y-select_y1] );
free( pixels );
for( y = select_y1; y < select_y2; y++ ) free( destpixels[y-select_y1] );
free( destpixels );
}
/******************************************************************************/
static int dialog_status;
static GtkWidget *entry_width;
static GtkWidget *entry_height;
static GtkWidget *entry_slide;
static GtkWidget *button_transparent;
static GtkWidget *button_black;
static GtkWidget *button_white;
static void dialog_destroy_handler( GtkWidget *widget,
gpointer *data )
{
gtk_main_quit();
}
static void dialog_ok_handler( GtkWidget *widget,
gpointer *data )
{
dialog_status = TRUE;
if( GTK_TOGGLE_BUTTON( button_white )->active ) parameters.bg_type = BG_TYPE_WHITE;
if( GTK_TOGGLE_BUTTON( button_black )->active ) parameters.bg_type = BG_TYPE_BLACK;
if( image_has_alpha ){
if( GTK_TOGGLE_BUTTON( button_transparent )->active ){
parameters.bg_type = BG_TYPE_TRANSPARENT;
}
}
parameters.tile_width =
(gint32)atof(gtk_entry_get_text( GTK_ENTRY( entry_width ) ) );
parameters.tile_height =
(gint32)atof(gtk_entry_get_text( GTK_ENTRY( entry_height ) ) );
parameters.slide_length =
(gint32)atof(gtk_entry_get_text( GTK_ENTRY( entry_slide ) ) );
gtk_widget_destroy( GTK_WIDGET( data ) );
}
static void dialog_cancel_handler( GtkWidget *widget,
gpointer *data )
{
dialog_status = FALSE;
gtk_widget_destroy( GTK_WIDGET( data ) );
}
/******************************************************************************/
static int dialog( void )
{
GtkWidget *window;
dialog_status = FALSE;
{
gint argc = 1;
gchar **argv = g_new( gchar *, 1 );
argv[0] = g_strdup( DIALOG_CAPTION );
gtk_init( &argc, &argv );
}
/* dialog window */
window = gtk_dialog_new();
gtk_signal_connect( GTK_OBJECT( window ), "destroy",
GTK_SIGNAL_FUNC( dialog_destroy_handler ), NULL );
gtk_container_border_width( GTK_CONTAINER( window ), 0 );
gtk_container_border_width( GTK_CONTAINER( GTK_DIALOG( window )->vbox ), 5 );
{
/* buttons */
GtkWidget *button;
/* ok button */
button = gtk_button_new_with_label( "OK" );
gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
GTK_SIGNAL_FUNC( dialog_ok_handler ),
GTK_OBJECT( window ) );
GTK_WIDGET_SET_FLAGS( button, GTK_CAN_DEFAULT );
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->action_area ),
button, TRUE, TRUE, 0 );
gtk_widget_grab_default( button );
gtk_widget_show( button );
/* cancel button */
button = gtk_button_new_with_label( "Cancel" );
gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
GTK_SIGNAL_FUNC( dialog_cancel_handler ),
GTK_OBJECT( window ));
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->action_area ),
button, TRUE, TRUE, 0 );
gtk_widget_show( button );
}
{
/* text boxes */
GtkWidget *table;
GtkWidget *label;
char buffer[32];
/* table */
table = gtk_table_new( 3, 2, FALSE );
gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->vbox ),
table, TRUE, TRUE, 0 );
gtk_widget_show( table );
/* tile width */
label = gtk_label_new( "width: " );
entry_width = gtk_entry_new();
sprintf( buffer, "%d", parameters.tile_width );
gtk_entry_set_text( GTK_ENTRY( entry_width ), buffer );
gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 0, 1 );
gtk_table_attach_defaults( GTK_TABLE( table ), entry_width, 1, 2, 0, 1 );
gtk_widget_show( label );
gtk_widget_show( entry_width );
/* tile height */
label = gtk_label_new( "height: " );
entry_height = gtk_entry_new();
sprintf( buffer, "%d", parameters.tile_height );
gtk_entry_set_text( GTK_ENTRY( entry_height ), buffer );
gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 1, 2 );
gtk_table_attach_defaults( GTK_TABLE( table ), entry_height, 1, 2, 1, 2 );
gtk_widget_show( label );
gtk_widget_show( entry_height );
/* slide length */
label = gtk_label_new( "slide: " );
entry_slide = gtk_entry_new();
sprintf( buffer, "%d", parameters.slide_length );
gtk_entry_set_text( GTK_ENTRY( entry_slide ), buffer );
gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 2, 3 );
gtk_table_attach_defaults( GTK_TABLE( table ), entry_slide, 1, 2, 2, 3 );
gtk_widget_show( label );
gtk_widget_show( entry_slide );
}
{
/* radio buttons */
GtkWidget *frame;
GtkWidget *vbox;
GSList *group;
frame = gtk_frame_new( "Background" );
gtk_container_border_width( GTK_CONTAINER( frame ), 0 );
gtk_frame_set_shadow_type( GTK_FRAME( frame ), GTK_SHADOW_ETCHED_IN );
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->vbox ),
frame, TRUE, TRUE, 0 );
gtk_widget_show( frame );
vbox = gtk_vbox_new( FALSE, 0 );
gtk_container_border_width( GTK_CONTAINER( vbox ), 0 );
gtk_container_add( GTK_CONTAINER( frame ), vbox );
gtk_widget_show( vbox );
group = NULL;
if( image_has_alpha ){
/* transparent */
button_transparent =
gtk_radio_button_new_with_label( NULL, "Transparent" );
gtk_box_pack_start( GTK_BOX( vbox ),
button_transparent, TRUE, TRUE, 0 );
if( parameters.bg_type == BG_TYPE_TRANSPARENT )
gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( button_transparent ),
TRUE );
gtk_widget_show( button_transparent );
group = gtk_radio_button_group( GTK_RADIO_BUTTON( button_transparent ) );
}
/* black */
button_black = gtk_radio_button_new_with_label( group, "Black" );
gtk_box_pack_start( GTK_BOX( vbox ), button_black, TRUE, TRUE, 0 );
if( parameters.bg_type == BG_TYPE_BLACK )
gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( button_black ), TRUE );
gtk_widget_show( button_black );
group = gtk_radio_button_group( GTK_RADIO_BUTTON( button_black ) );
/* white */
button_white = gtk_radio_button_new_with_label( group, "White" );
gtk_box_pack_start( GTK_BOX( vbox ), button_white, TRUE, TRUE, 0 );
if( parameters.bg_type == BG_TYPE_WHITE )
gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( button_white ), TRUE );
gtk_widget_show( button_white );
}
gtk_widget_show( window );
gtk_main();
return dialog_status;
}
/******************************************************************************/

View File

@ -44,17 +44,19 @@
* Revision History:
*
* $Log$
* Revision 1.1.1.1 1997/11/24 22:04:12 sopwith
* Let's try this import one last time.
* Revision 1.2 1997/12/09 05:57:27 adrian
* added glasstile, colorify, papertile, and illusion plugins
*
* Revision 1.1 1997/11/14 20:08:37 nobody
* *** empty log message ***
* updated despeckle, and math map
*
* Revision 1.2 1997/09/27 10:30:27 nobody
* Boatload of changes from 0.99.11 to 0.99.12. For details, see the ChangeLog :-)
* Revision 1.14 1997/11/14 17:17:59 mike
* Updated to dynamically allocate return params in the run() function.
*
* (Now that we are all using cvs (right?), this boatload of changes kind
* of commit shouldn't happen...)
* Revision 1.13 1997/11/12 15:53:34 mike
* Added <string.h> header file for Digital UNIX...
*
* Revision 1.12 1997/10/17 13:56:54 mike
* Updated author/contact information.
*
* Revision 1.11 1997/06/12 16:58:11 mike
* Optimized final despeckle - now grab gimp_tile_height() rows at a time
@ -101,18 +103,27 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <gtk/gtk.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
/*
* Macros...
*/
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
/*
* Constants...
*/
#define PLUG_IN_NAME "plug_in_despeckle"
#define PLUG_IN_VERSION "1.1"
#define PLUG_IN_VERSION "1.1.3 - 14 November 1997"
#define PREVIEW_SIZE 128
#define SCALE_WIDTH 64
#define ENTRY_WIDTH 64
@ -219,8 +230,10 @@ query(void)
gimp_install_procedure(PLUG_IN_NAME,
"Despeckle filter, typically used to \'despeckle\' a photographic image.",
"This plug-in selectively performs a median or adaptive box filter on an image.",
"Michael Sweet", "Michael Sweet",
PLUG_IN_VERSION, "<Image>/Filters/Image/Despeckle...", "RGB*, GRAY*",
"Michael Sweet <mike@easysw.com>",
"Michael Sweet <mike@easysw.com>",
PLUG_IN_VERSION,
"<Image>/Filters/Image/Despeckle...", "RGB*, GRAY*",
PROC_PLUG_IN, nargs, nreturn_vals, args, return_vals);
}
@ -238,7 +251,7 @@ run(char *name, /* I - Name of filter program. */
{
GRunModeType run_mode; /* Current run mode */
GStatusType status; /* Return status */
static GParam values[1]; /* Return values */
GParam *values; /* Return values */
/*
@ -248,6 +261,8 @@ run(char *name, /* I - Name of filter program. */
status = STATUS_SUCCESS;
run_mode = param[0].data.d_int32;
values = g_new(GParam, 1);
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
@ -783,7 +798,8 @@ despeckle_dialog(void)
static void
preview_init(void)
{
int size, /* Size of filter box */
int row, /* Current row in preview_srcs */
size, /* Size of filter box */
width; /* Byte width of the image */
@ -1003,7 +1019,8 @@ preview_update(void)
static void
preview_exit(void)
{
int size; /* Size of row buffer */
int row, /* Looping var */
size; /* Size of row buffer */
size = MAX_RADIUS * 2 + 1;

View File

@ -0,0 +1,55 @@
GFIG Version 0.1
Name: First\040gfig
Version: 0.000000
ObjCount: 6
<OPTIONS>
GridSpacing: 30
GridType: RECT_GRID
DrawGrid: FALSE
Snap2Grid: FALSE
LockOnGrid: FALSE
ShowControl: TRUE
</OPTIONS>
<SPIRAL>
71 81
96 103
<EXTRA>
4
</EXTRA>
</SPIRAL>
<SPIRAL>
152 79
179 91
<EXTRA>
-4
</EXTRA>
</SPIRAL>
<BEZIER>
116 94
105 147
73 161
<EXTRA>
4
</EXTRA>
</BEZIER>
<STAR>
206 106
228 123
214 112
<EXTRA>
3
</EXTRA>
</STAR>
<STAR>
26 115
10 133
20 121
<EXTRA>
3
</EXTRA>
</STAR>
<ARC>
38 169
92 218
182 182
</ARC>

View File

@ -0,0 +1,42 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = glasstile
glasstile_SOURCES = \
glasstile.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
glasstile_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

@ -0,0 +1,427 @@
/*
* This is the Glass Tile plug-in for the GIMP 0.99
* Version 1.01
*
* Copyright (C) 1997 Karl-Johan Andersson (t96kja@student.tdb.uu.se)
*
* 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.
*
*/
/*
* This filter divide the image into square "glass"-blocks in which
* the image is refracted.
*
* The alpha-channel is left unchanged.
*
* Please send any comments or suggestions to
* Karl-Johan Andersson (t96kja@student.tdb.uu.se)
*
*/
#include <stdlib.h>
#include "libgimp/gimp.h"
#include "gtk/gtk.h"
/* --- Typedefs --- */
typedef struct {
gint xblock;
gint yblock;
} GlassValues;
typedef struct {
gint run;
} GlassInterface;
/* --- Declare local functions --- */
static void query (void);
static void run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals);
static gint glass_dialog (void);
static void glass_close_callback (GtkWidget *widget, gpointer data);
static void glass_ok_callback (GtkWidget *widget, gpointer data);
static void glass_scale_update (GtkAdjustment *adjustment, gpointer data);
static void glasstile (GDrawable *drawable);
/* --- Variables --- */
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
static GlassValues gtvals =
{
20, /* tile width */
20 /* tile height */
};
static GlassInterface gt_int =
{
FALSE /* run */
};
/* --- Functions --- */
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_INT32, "tilex", "Tile width (10 - 50)" },
{ PARAM_INT32, "tiley", "Tile height (10 - 50)" },
};
static GParamDef *return_vals = NULL;
static int nargs = sizeof (args) / sizeof (args[0]);
static int nreturn_vals = 0;
gimp_install_procedure ("plug_in_glasstile",
"Divide the image into square glassblocks",
"More here later",
"Karl-Johan Andersson", /* Author */
"Karl-Johan Andersson", /* Copyright */
"1997",
"<Image>/Filters/Distorts/Glass Tile",
"RGB*, GRAY*",
PROC_PLUG_IN,
nargs, nreturn_vals,
args, return_vals);
}
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;
run_mode = param[0].data.d_int32;
*nreturn_vals = 1;
*return_vals = values;
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
/* Get the specified drawable */
drawable = gimp_drawable_get (param[2].data.d_drawable);
switch (run_mode)
{
case RUN_INTERACTIVE:
/* Possibly retrieve data */
gimp_get_data ("plug_in_glasstile", &gtvals);
/* First acquire information with a dialog */
if (! glass_dialog ())
{
gimp_drawable_detach (drawable);
return;
}
break;
case RUN_NONINTERACTIVE:
/* Make sure all the arguments are there! */
if (nparams != 5)
status = STATUS_CALLING_ERROR;
if (status == STATUS_SUCCESS)
{
gtvals.xblock = (gint) param[3].data.d_int32;
gtvals.yblock = (gint) param[4].data.d_int32;
}
if (gtvals.xblock < 10 || gtvals.xblock > 50)
status = STATUS_CALLING_ERROR;
if (gtvals.yblock < 10 || gtvals.yblock > 50)
status = STATUS_CALLING_ERROR;
break;
case RUN_WITH_LAST_VALS:
/* Possibly retrieve data */
gimp_get_data ("plug_in_glasstile", &gtvals);
break;
default:
break;
}
if (status == STATUS_SUCCESS)
{
/* Make sure that the drawable is gray or RGB color */
if (gimp_drawable_color (drawable->id) || gimp_drawable_gray (drawable->id))
{
gimp_progress_init ("Glass Tile...");
gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));
glasstile (drawable);
if (run_mode != RUN_NONINTERACTIVE)
gimp_displays_flush ();
/* Store data */
if (run_mode == RUN_INTERACTIVE)
gimp_set_data ("plug_in_glasstile", &gtvals, sizeof (GlassValues));
}
else
{
/* gimp_message ("glasstile: cannot operate on indexed color images"); */
status = STATUS_EXECUTION_ERROR;
}
}
values[0].data.d_status = status;
gimp_drawable_detach (drawable);
}
static gint glass_dialog ()
{
GtkWidget *dlg;
GtkWidget *label;
GtkWidget *button;
GtkWidget *scale;
GtkWidget *frame;
GtkWidget *table;
GtkObject *adjustment;
gchar **argv;
gint argc;
argc = 1;
argv = g_new (gchar *, 1);
argv[0] = g_strdup ("glasstile");
gtk_init (&argc, &argv);
gtk_rc_parse (gimp_gtkrc ());
dlg = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (dlg), "Glass Tile");
gtk_window_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
(GtkSignalFunc) glass_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) glass_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);
/* Parameter settings */
frame = gtk_frame_new ("Parameter Settings");
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_border_width (GTK_CONTAINER (frame), 10);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, TRUE, TRUE, 0);
table = gtk_table_new (2, 2, FALSE); /* table height, width */
gtk_container_border_width (GTK_CONTAINER (table), 10);
gtk_container_add (GTK_CONTAINER (frame), table);
/* Horizontal scale - Width */
label = gtk_label_new ("Tile Width");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, 0, 5, 0);
/* xStart, xEnd, yStart, yEnd */
adjustment = gtk_adjustment_new (gtvals.xblock, 10, 50, 1, 1, 0);
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
(GtkSignalFunc) glass_scale_update,
&(gtvals.xblock));
scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
gtk_widget_set_usize (scale, 150, 30);
gtk_table_attach (GTK_TABLE (table), scale, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_widget_show (label);
gtk_widget_show (scale);
/* Horizontal scale - Height */
label = gtk_label_new ("Tile Height");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, 0, 5, 0);
adjustment = gtk_adjustment_new (gtvals.yblock, 10, 50, 1, 1, 0);
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
(GtkSignalFunc) glass_scale_update,
&(gtvals.yblock));
scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
gtk_widget_set_usize (scale, 150, 30);
gtk_table_attach (GTK_TABLE (table), scale, 1, 2, 1, 2, GTK_FILL, 0, 0, 0);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_widget_show (label);
gtk_widget_show (scale);
gtk_widget_show (frame);
gtk_widget_show (table);
gtk_widget_show (dlg);
gtk_main ();
gdk_flush ();
return gt_int.run;
}
/* - Interface functions - */
static void glass_close_callback (GtkWidget *widget, gpointer data)
{
gtk_main_quit ();
}
static void glass_ok_callback (GtkWidget *widget, gpointer data)
{
gt_int.run = TRUE;
gtk_widget_destroy (GTK_WIDGET (data));
}
static void glass_scale_update (GtkAdjustment *adjustment, gpointer data)
{
gint *dptr = (gint*) data;
*dptr = (gint) adjustment->value;
}
/* - Filter function - */
static void glasstile (GDrawable *drawable)
{
GPixelRgn srcPR, destPR;
gint width, height;
gint bytes;
guchar *dest, *d, *ad;
guchar *cur_row;
gint row, col, i, iwidth;
gint x1, y1, x2, y2;
gint rutbredd, xpixel1, xpixel2;
gint ruthojd , ypixel2;
gint xhalv, xoffs, xmitt, xplus;
gint yhalv, yoffs, ymitt, yplus, cbytes;
/* 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, &x1, &y1, &x2, &y2);
/* 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;
/* allocate row buffers */
cur_row = (guchar *) malloc ((x2 - x1) * bytes);
dest = (guchar *) malloc ((x2 - x1) * bytes);
ad = (guchar *) malloc ((x2 - x1) * bytes);
/* 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);
rutbredd = gtvals.xblock;
ruthojd = gtvals.yblock;
xhalv = rutbredd / 2;
yhalv = ruthojd / 2;
cbytes = bytes;
if (cbytes%2 == 0) cbytes--;
iwidth = width - x1;
xplus = rutbredd % 2;
yplus = ruthojd % 2;
ymitt = y1;
yoffs = 0;
/* Loop through the rows */
for (row = y1; row < y2; row++)
{
d = dest;
ypixel2 = ymitt + yoffs * 2;
if (ypixel2 < height)
gimp_pixel_rgn_get_row (&srcPR, cur_row, x1, ypixel2, iwidth);
else
gimp_pixel_rgn_get_row (&srcPR, cur_row, x1, y2-1, iwidth);
if (cbytes != bytes) /* Alpha check */
gimp_pixel_rgn_get_row (&srcPR, ad, x1, row, (x2-x1));
yoffs++;
if (yoffs == yhalv) {
ymitt += ruthojd;
yoffs =- yhalv;
yoffs -= yplus;
}
xmitt = 0;
xoffs = 0;
for (col = 0; col < (x2 - x1); col++) /* one pixel */
{
xpixel1 = (xmitt + xoffs) * bytes;
xpixel2 = (xmitt + xoffs * 2) * bytes;
if (xpixel2 < ((x2 - x1) * bytes)) {
for (i = 0; i < cbytes; i++)
d[xpixel1 + i] = cur_row[xpixel2 + i];
}
else {
for (i = 0; i < cbytes; i++)
d[xpixel1 + i]=cur_row[xpixel1 + i];
}
if (cbytes != bytes) /* Alpha channel unchanged */
d[xpixel1 + cbytes] = ad[xpixel1 + cbytes];
xoffs++;
if (xoffs == xhalv) {
xmitt += rutbredd;
xoffs =- xhalv;
xoffs -= xplus;
}
}
/* Store the dest */
gimp_pixel_rgn_set_row (&destPR, dest, x1, row, iwidth);
if ((row % 5) == 0)
gimp_progress_update ((double) row / (double) (y2 - y1));
}
/* Update region */
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, x1, y1, (x2 - x1), (y2 - y1));
free (cur_row);
free (dest);
free (ad);
}

View File

@ -0,0 +1,42 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = illusion
illusion_SOURCES = \
illusion.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
illusion_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

@ -0,0 +1,368 @@
/*******************************************************************************
illusion.c -- This is a plug-in for the GIMP 1.0
Copyright (C) 1997 Hirotsuna Mizuno
s1041150@u-aizu.ac.jp
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 <gtk/gtk.h>
#include <math.h>
#include "libgimp/gimp.h"
#define PLUG_IN_NAME "plug_in_illusion"
#define PLUG_IN_VERSION "v0.7 (Dec. 25 1997)"
#define DIALOG_CAPTION "Illusion"
#ifndef PI
#define PI 3.141592653589793238462643383279
#endif
#ifndef PI_2
#define PI_2 (PI*2)
#endif
/******************************************************************************/
static void query( void );
static void run( char *, int, GParam *, int *, GParam ** );
static void filter( GDrawable *drawable );
static int dialog( void );
/******************************************************************************/
typedef struct {
gint32 division;
} parameter_t;
/******************************************************************************/
GPlugInInfo PLUG_IN_INFO = {
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
static parameter_t parameters = {
8
};
static gint image_width;
static gint image_height;
static gint image_bpp;
static gint image_has_alpha;
static gint select_x1;
static gint select_y1;
static gint select_x2;
static gint select_y2;
static gint select_width;
static gint select_height;
static gdouble center_x;
static gdouble center_y;
/******************************************************************************/
MAIN();
/******************************************************************************/
static void query( void )
{
static int nargs = 4;
static GParamDef args[] = {
{ PARAM_INT32, "run_mode", "interactive / non-interactive" },
{ PARAM_IMAGE, "image", "input image" },
{ PARAM_DRAWABLE, "drawable", "input drawable" },
{ PARAM_INT32, "division", "the number of divisions" }
};
static int nreturn_vals = 0;
static GParamDef *return_vals = NULL;
gimp_install_procedure(
PLUG_IN_NAME,
"produce illusion",
"produce illusion",
"Hirotsuna Mizuno <s1041150@u-aizu.ac.jp>",
"Hirotsuna Mizuno",
PLUG_IN_VERSION,
"<Image>/Filters/Effects/Illusion",
"RGB*, GRAY*",
PROC_PLUG_IN,
nargs,
nreturn_vals,
args,
return_vals
);
}
/******************************************************************************/
static void run( char *name,
int paramc,
GParam *params,
int *returnc,
GParam **returns )
{
GDrawable *drawable;
GRunModeType run_mode;
static GParam returnv[1];
GStatusType status = STATUS_SUCCESS;
run_mode = params[0].data.d_int32;
drawable = gimp_drawable_get( params[2].data.d_drawable );
*returnc = 1;
*returns = returnv;
/* get the drawable info */
image_width = gimp_drawable_width( drawable->id );
image_height = gimp_drawable_height( drawable->id );
image_bpp = gimp_drawable_bpp( drawable->id );
image_has_alpha = gimp_drawable_has_alpha( drawable->id );
gimp_drawable_mask_bounds( drawable->id,
&select_x1, &select_y1, &select_x2, &select_y2 );
select_width = select_x2 - select_x1;
select_height = select_y2 - select_y1;
center_x = select_x1 + (gdouble)select_width / 2;
center_y = select_y1 + (gdouble)select_height / 2;
/* switch the run mode */
switch( run_mode ){
case RUN_INTERACTIVE:
gimp_get_data( PLUG_IN_NAME, &parameters );
if( ! dialog() ) return;
gimp_set_data( PLUG_IN_NAME, &parameters, sizeof( parameter_t ) );
break;
case RUN_NONINTERACTIVE:
if( paramc != 4 ){
status = STATUS_CALLING_ERROR;
} else {
parameters.division = params[3].data.d_int32;
}
break;
case RUN_WITH_LAST_VALS:
gimp_get_data( PLUG_IN_NAME, &parameters );
break;
}
if( status == STATUS_SUCCESS ){
if( gimp_drawable_color( drawable->id ) ||
gimp_drawable_gray( drawable->id ) ){
gimp_tile_cache_ntiles( 2 * ( drawable->width / gimp_tile_width() + 1 ) );
filter( drawable );
if( run_mode != RUN_NONINTERACTIVE ) gimp_displays_flush ();
} else {
status = STATUS_EXECUTION_ERROR;
}
}
returnv[0].type = PARAM_STATUS;
returnv[0].data.d_status = status;
gimp_drawable_detach( drawable );
}
/******************************************************************************/
static void filter( GDrawable *drawable )
{
GPixelRgn srcPR, destPR;
guchar **pixels;
guchar **destpixels;
gint x, y, b;
gint xx, yy;
gdouble scale, radius, cx, cy, angle, offset;
gimp_pixel_rgn_init( &srcPR, drawable,
0, 0, image_width, image_height, FALSE, FALSE );
gimp_pixel_rgn_init( &destPR, drawable,
0, 0, image_width, image_height, TRUE, TRUE );
pixels = (guchar **)malloc( image_height * sizeof(guchar *) );
destpixels = (guchar **)malloc( image_height * sizeof(guchar *) );
for( y = 0; y < image_height; y++ ){
pixels[y] = (guchar *)malloc( image_width * image_bpp );
destpixels[y] = (guchar *)malloc( image_width * image_bpp );
gimp_pixel_rgn_get_row( &srcPR, pixels[y], 0, y, image_width );
}
/*
for( y = select_y1; y < select_y2; y++ ){
for( x = select_x1; x < select_x2; x++ ){
for( b = 0; b < image_bpp; b++ ){
destpixels[y][x*image_bpp+b] = 0;
}
}
}
*/
gimp_progress_init( PLUG_IN_NAME );
scale = sqrt(select_width*select_width+select_height*select_height) / 2;
offset = (gint)(scale / 2);
for( y = select_y1; y < select_y2; y++ ){
cy = ((gdouble)y - center_y) / scale;
for( x = select_x1; x < select_x2; x++ ){
cx = ((gdouble)x - center_x) / scale;
angle = floor( atan2(cy,cx) * parameters.division / PI_2 )
* PI_2 / parameters.division + ( PI / parameters.division );
radius = sqrt((gdouble)(cx*cx+cy*cy));
xx = x - offset * cos( angle );
yy = y - offset * sin( angle );
if( xx < 0 ) xx = 0;
else if( image_width <= xx ) xx = image_width - 1;
if( yy < 0 ) yy = 0;
else if( image_height <= yy ) yy = image_height - 1;
for( b = 0; b < image_bpp; b++ )
destpixels[y][x*image_bpp+b] =
(1-radius)*pixels[y][x*image_bpp+b]
+ radius*pixels[yy][xx*image_bpp+b];
}
gimp_pixel_rgn_set_row (&destPR, destpixels[y], 0, y, image_width );
gimp_progress_update ( (double)( y - select_y1 ) / (double)select_height );
}
gimp_drawable_flush( drawable );
gimp_drawable_merge_shadow( drawable->id, TRUE );
gimp_drawable_update( drawable->id,
select_x1, select_y1, select_width, select_height );
for( y = select_y1; y < select_y2; y++ ) free( pixels[y-select_y1] );
free( pixels );
for( y = select_y1; y < select_y2; y++ ) free( destpixels[y-select_y1] );
free( destpixels );
}
/******************************************************************************/
static int dialog_status;
static GtkWidget *entry_division;
static void dialog_destroy_handler( GtkWidget *widget, gpointer *data )
{
gtk_main_quit();
}
static void dialog_ok_handler( GtkWidget *widget, gpointer *data )
{
dialog_status = TRUE;
parameters.division =
(gint32)atof(gtk_entry_get_text( GTK_ENTRY( entry_division ) ) );
gtk_widget_destroy( GTK_WIDGET( data ) );
}
static void dialog_cancel_handler( GtkWidget *widget, gpointer *data )
{
dialog_status = FALSE;
gtk_widget_destroy( GTK_WIDGET( data ) );
}
/******************************************************************************/
static int dialog( void )
{
GtkWidget *window;
dialog_status = FALSE;
{
gint argc = 1;
gchar **argv = g_new( gchar *, 1 );
argv[0] = g_strdup( DIALOG_CAPTION );
gtk_init( &argc, &argv );
}
/* dialog window */
window = gtk_dialog_new();
gtk_signal_connect( GTK_OBJECT( window ), "destroy",
GTK_SIGNAL_FUNC( dialog_destroy_handler ), NULL );
gtk_container_border_width( GTK_CONTAINER( window ), 0 );
gtk_container_border_width( GTK_CONTAINER( GTK_DIALOG( window )->vbox ), 5 );
{
/* buttons */
GtkWidget *button;
/* ok button */
button = gtk_button_new_with_label( "OK" );
gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
GTK_SIGNAL_FUNC( dialog_ok_handler ),
GTK_OBJECT( window ) );
GTK_WIDGET_SET_FLAGS( button, GTK_CAN_DEFAULT );
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->action_area ),
button, TRUE, TRUE, 0 );
gtk_widget_grab_default( button );
gtk_widget_show( button );
/* cancel button */
button = gtk_button_new_with_label( "Cancel" );
gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
GTK_SIGNAL_FUNC( dialog_cancel_handler ),
GTK_OBJECT( window )) ;
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->action_area ),
button, TRUE, TRUE, 0 );
gtk_widget_show( button );
}
{
/* text boxes */
GtkWidget *table;
GtkWidget *label;
char buffer[32];
/* table */
table = gtk_table_new( 1, 2, FALSE );
gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->vbox ),
table, TRUE, TRUE, 0 );
gtk_widget_show( table );
/* tile width */
label = gtk_label_new( "division: " );
entry_division = gtk_entry_new();
sprintf( buffer, "%d", parameters.division );
gtk_entry_set_text( GTK_ENTRY( entry_division ), buffer );
gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 0, 1 );
gtk_table_attach_defaults( GTK_TABLE( table ), entry_division, 1, 2, 0, 1 );
gtk_widget_show( label );
gtk_widget_show( entry_division );
}
gtk_widget_show( window );
gtk_main();
return dialog_status;
}
/******************************************************************************/

View File

@ -18,67 +18,91 @@ extern int stackp;
double
color_to_double (int red, int green, int blue)
{
return (red << 16) | (green << 8) | blue;
double val;
*(int*)&val = (red << 16) | (green << 8) | blue;
return val;
}
void
double_to_color (double val, int *red, int *green, int *blue)
{
int color = val;
int color = *(int*)&val;
*red = color >> 16;
*green = (color >> 8) & 0xff;
*blue = color & 0xff;
}
void
builtin_if (double arg)
int
red_component (double val)
{
if (stack[stackp - 3] != 0.0)
stack[stackp - 3] = stack[stackp - 2];
else
stack[stackp - 3] = stack[stackp - 1];
stackp -= 2;
int color = *(int*)&val;
return color >> 16;
}
int
green_component (double val)
{
int color = *(int*)&val;
return (color >> 8) & 0xff;
}
int
blue_component (double val)
{
int color = *(int*)&val;
return color & 0xff;
}
void
builtin_sin (double arg)
builtin_sin (void *arg)
{
stack[stackp - 1] = sin(stack[stackp - 1] * M_PI / 180.0);
}
void
builtin_cos (double arg)
builtin_cos (void *arg)
{
stack[stackp - 1] = cos(stack[stackp - 1] * M_PI / 180.0);
}
void
builtin_tan (double arg)
builtin_tan (void *arg)
{
stack[stackp - 1] = tan(stack[stackp - 1] * M_PI / 180.0);
}
void
builtin_asin (double arg)
builtin_asin (void *arg)
{
stack[stackp - 1] = asin(stack[stackp - 1]) * 180.0 / M_PI;
}
void
builtin_acos (double arg)
builtin_acos (void *arg)
{
stack[stackp - 1] = acos(stack[stackp - 1]) * 180.0 / M_PI;
}
void
builtin_atan (double arg)
builtin_atan (void *arg)
{
stack[stackp - 1] = atan(stack[stackp - 1]) * 180.0 / M_PI;
}
void
builtin_sign (double arg)
builtin_abs (void *arg)
{
stack[stackp - 1] = fabs(stack[stackp - 1]);
}
void
builtin_sign (void *arg)
{
if (stack[stackp - 1] < 0)
stack[stackp - 1] = -1.0;
@ -89,7 +113,7 @@ builtin_sign (double arg)
}
void
builtin_min (double arg)
builtin_min (void *arg)
{
if (stack[stackp - 2] >= stack[stackp - 1])
stack[stackp - 2] = stack[stackp - 1];
@ -97,7 +121,7 @@ builtin_min (double arg)
}
void
builtin_max (double arg)
builtin_max (void *arg)
{
if (stack[stackp - 2] <= stack[stackp - 1])
stack[stackp - 2] = stack[stackp - 1];
@ -105,7 +129,37 @@ builtin_max (double arg)
}
void
builtin_inintv (double arg)
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_less (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;
@ -115,7 +169,7 @@ builtin_inintv (double arg)
}
void
builtin_rand (double arg)
builtin_rand (void *arg)
{
stack[stackp - 2] = (random() / (double)0x7fffffff)
* (stack[stackp - 1] - stack[stackp - 2]) + stack[stackp - 2];
@ -132,7 +186,7 @@ extern int originX,
wholeImageHeight;
void
builtin_origValXY (double arg)
builtin_origValXY (void *arg)
{
int x = stack[stackp - 2],
y = stack[stackp - 1];
@ -145,7 +199,7 @@ builtin_origValXY (double arg)
}
void
builtin_origValXYIntersample (double arg)
builtin_origValXYIntersample (void *arg)
{
double x = stack[stackp - 2] + middleX + originX,
y = stack[stackp - 1] + middleY + originY;
@ -203,7 +257,7 @@ builtin_origValXYIntersample (double arg)
}
void
builtin_origValRA (double arg)
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;
@ -216,7 +270,7 @@ builtin_origValRA (double arg)
}
void
builtin_origValRAIntersample (double arg)
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;
@ -276,7 +330,7 @@ builtin_origValRAIntersample (double arg)
#else
void
builtin_origValXY (double arg)
builtin_origValXY (void *arg)
{
int x = stack[stackp - 2] + middleX,
y = stack[stackp - 1] + middleY;
@ -296,7 +350,7 @@ builtin_origValXY (double arg)
}
void
builtin_origValXYIntersample (double arg)
builtin_origValXYIntersample (void *arg)
{
double x = stack[stackp - 2] + middleX,
y = stack[stackp - 1] + middleY;
@ -350,7 +404,7 @@ builtin_origValXYIntersample (double arg)
}
void
builtin_origValRA (double arg)
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;
@ -370,7 +424,7 @@ builtin_origValRA (double arg)
}
void
builtin_origValRAIntersample (double arg)
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;
@ -426,7 +480,52 @@ builtin_origValRAIntersample (double arg)
#endif /* _GIMP */
void
builtin_grayColor (double arg)
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_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);
}
void
builtin_grayColor (void *arg)
{
int grayLevel = stack[stackp - 1] * 255;

View File

@ -2,20 +2,27 @@
double color_to_double (int red, int green, int blue);
void double_to_color (double val, int *red, int *green, int *blue);
void builtin_if (double arg);
void builtin_sin (double arg);
void builtin_cos (double arg);
void builtin_tan (double arg);
void builtin_asin (double arg);
void builtin_acos (double arg);
void builtin_atan (double arg);
void builtin_sign (double arg);
void builtin_min (double arg);
void builtin_max (double arg);
void builtin_inintv (double arg);
void builtin_rand (double arg);
void builtin_origValXY (double arg);
void builtin_origValXYIntersample (double arg);
void builtin_origValRA (double arg);
void builtin_origValRAIntersample (double arg);
void builtin_grayColor (double arg);
void builtin_sin (void *arg);
void builtin_cos (void *arg);
void builtin_tan (void *arg);
void builtin_asin (void *arg);
void builtin_acos (void *arg);
void builtin_atan (void *arg);
void builtin_abs (void *arg);
void builtin_sign (void *arg);
void builtin_min (void *arg);
void builtin_max (void *arg);
void builtin_or (void *arg);
void builtin_and (void *arg);
void builtin_less (void *arg);
void builtin_inintv (void *arg);
void builtin_rand (void *arg);
void builtin_origValXY (void *arg);
void builtin_origValXYIntersample (void *arg);
void builtin_origValRA (void *arg);
void builtin_origValRAIntersample (void *arg);
void builtin_red (void *arg);
void builtin_green (void *arg);
void builtin_blue (void *arg);
void builtin_rgbColor (void *arg);
void builtin_grayColor (void *arg);

View File

@ -57,8 +57,8 @@ make_var (char *name)
tree->type = EXPR_VAR_BIG_Y;
else
{
tree->type = EXPR_NUMBER;
tree->val.number = 0.0;
tree->type = EXPR_VARIABLE;
tree->val.var = register_variable(name);
}
tree->next = 0;
@ -85,12 +85,7 @@ make_function (char *name, exprtree *args)
{
exprtree *tree = (exprtree*)malloc(sizeof(exprtree));
if (strcmp(name, "if") == 0)
{
tree->val.func.routine = builtin_if;
tree->val.func.numArgs = 3;
}
else if (strcmp(name, "sin") == 0)
if (strcmp(name, "sin") == 0)
{
tree->val.func.routine = builtin_sin;
tree->val.func.numArgs = 1;
@ -120,6 +115,11 @@ make_function (char *name, exprtree *args)
tree->val.func.routine = builtin_atan;
tree->val.func.numArgs = 1;
}
else if (strcmp(name, "abs") == 0)
{
tree->val.func.routine = builtin_abs;
tree->val.func.numArgs = 1;
}
else if (strcmp(name, "sign") == 0)
{
tree->val.func.routine = builtin_sign;
@ -135,6 +135,21 @@ make_function (char *name, exprtree *args)
tree->val.func.routine = builtin_max;
tree->val.func.numArgs = 2;
}
else if (strcmp(name, "or") == 0)
{
tree->val.func.routine = builtin_or;
tree->val.func.numArgs = 2;
}
else if (strcmp(name, "and") == 0)
{
tree->val.func.routine = builtin_and;
tree->val.func.numArgs = 2;
}
else if (strcmp(name, "less") == 0)
{
tree->val.func.routine = builtin_less;
tree->val.func.numArgs = 2;
}
else if (strcmp(name, "inintv") == 0)
{
tree->val.func.routine = builtin_inintv;
@ -161,6 +176,26 @@ make_function (char *name, exprtree *args)
tree->val.func.routine = builtin_origValRA;
tree->val.func.numArgs = 2;
}
else if (strcmp(name, "red") == 0)
{
tree->val.func.routine = builtin_red;
tree->val.func.numArgs = 1;
}
else if (strcmp(name, "green") == 0)
{
tree->val.func.routine = builtin_green;
tree->val.func.numArgs = 1;
}
else if (strcmp(name, "blue") == 0)
{
tree->val.func.routine = builtin_blue;
tree->val.func.numArgs = 1;
}
else if (strcmp(name, "rgbColor") == 0)
{
tree->val.func.routine = builtin_rgbColor;
tree->val.func.numArgs = 3;
}
else if (strcmp(name, "grayColor") == 0)
{
tree->val.func.routine = builtin_grayColor;
@ -184,6 +219,92 @@ make_function (char *name, exprtree *args)
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)
{

View File

@ -1,10 +1,12 @@
#ifndef __EXPRTREE_H__
#define __EXPRTREE_H__
#include "vars.h"
#ifdef USE_TREE
typedef double (*function) (double*);
#else
typedef void (*function) (double);
typedef void (*function) (void*);
#endif
typedef char ident[64];
@ -16,6 +18,7 @@ typedef struct _exprtree
union
{
double number;
variable *var;
struct
{
int numArgs;
@ -27,6 +30,26 @@ typedef struct _exprtree
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;
@ -49,11 +72,24 @@ typedef struct _exprtree
#define EXPR_VAR_BIG_R 15
#define EXPR_VAR_BIG_X 16
#define EXPR_VAR_BIG_Y 17
#define EXPR_SEQUENCE 18
#define EXPR_ASSIGNMENT 19
#define EXPR_VARIABLE 20
#define EXPR_IF_THEN 21
#define EXPR_IF_THEN_ELSE 22
#define EXPR_WHILE 23
#define EXPR_DO_WHILE 24
exprtree* make_number (double num);
exprtree* make_var (char *name);
exprtree* make_operator (int type, exprtree *left, exprtree *right);
exprtree* make_function (char *name, 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);

View File

@ -10,6 +10,8 @@
* Copyright (C) 1997 Federico Mena Quintero
* federico@nuclecu.unam.mx
*
* Version 0.2
*
* 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
@ -29,6 +31,7 @@
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <gtk/gtk.h>
#include <libgimp/gimp.h>
@ -36,6 +39,7 @@
#include "exprtree.h"
#include "builtins.h"
#include "postfix.h"
#include "scanner.h"
/***** Macros *****/
@ -168,17 +172,37 @@ char *examples[][2] = {
{ "pond", "origValRA(r+sin(r*30)*3,a)" },
{ "enhanced pond", "origValRA(r+(sin(500000/(r+100))*7),a)" },
{ "twirl 90", "origValRA(r,a+(r/R-1)*45)" },
{ "sphere", "origValRA(r*(1-inintv(r/(X*2),-0.5,0.5))+X/90*asin(inintv(r/(X*2),-0.5,0.5)*r/X),a)" },
{ "sphere", "p=r/(X*2);origValRA(r*(1-inintv(p,-0.5,0.5))+X/90*asin(inintv(p,-0.5,0.5)*r/X),a)" },
{ "jitter", "origValRA(r,a+a%8-4)" },
{ "radial mosaic", "origValRA(r-r%5,a-a%5)" },
{ "circular slice", "origValRA(r,a+(r%5)-2)" },
{ "fisheye", "origValRA(r*r/R,a)" },
{ "center shake", "origValXY(x+max(0,cos(x*2))*5*max(0,cos(y*2))*cos(y*10),y+max(0,cos(x*2))*5*max(0,cos(y*2))*cos(x*10))" },
{ "scatter", "origValXY(x+rand(-3,3),y+rand(-3,3))" },
{ "darts", "p=origValXY(x,y);p=if inintv((a-9)%36,0,18) then p else rgbColor(1-red(p),1-green(p),1-blue(p)) end;if inintv(r%80,68,80) then p else rgbColor(1-red(p),1-green(p),1-blue(p)) end" },
{ "?", "origValRA(r,a+sin(a*10)*20)" },
{ "?", "origValRA(r+r%20,a)" },
{ "sine wave", "grayColor(sin(r*10)*0.5+0.5)" },
{ "grid", "grayColor(if((x%20)*(y%20),1,0))" },
{ "grid", "grayColor(if (x%20)*(y%20) then 1 else 0 end)" },
{ "moire1", "rgbColor(abs(sin(15*r)+sin(15*a))*0.5,abs(sin(17*r)+sin(17*a))*0.5,abs(sin(19*r)+sin(19*a))*0.5)" },
{ "moire2", "grayColor(sin(x*y)*0.5+0.5)" },
{ "mandelbrot",
"tx=1.5*x/X-0.5; "
"ty=1.5*y/X-0; "
"iter=0; "
"xr=0; "
"xi=0; "
"xrsq=0; "
"xisq=0; "
"while and(less(xrsq+xisq,4),less(iter,31)) "
"do "
"xrsq=xr*xr; "
"xisq=xi*xi; "
"xi=2*xr*xi+ty; "
"xr=xrsq-xisq+tx; "
"iter=iter+1 "
"end; "
"grayColor(iter/32)" },
{ 0, 0 }
};
@ -428,12 +452,15 @@ mathmap(void)
theExprtree = 0;
yy_scan_string(mmvals.expression);
scanFromString(mmvals.expression);
yyparse();
endScanningFromString();
if (theExprtree == 0)
return;
make_postfix(theExprtree);
/* output_postfix(); */
/* Initialize pixel region */
@ -562,6 +589,11 @@ mathmap(void)
iy = (int) cy;
currentX = col - sel_x1 - middleX; currentY = row - sel_y1 - middleY;
if (!intersamplingEnabled)
{
currentX += 0.5;
currentY += 0.5;
}
calc_ra(); result = eval_postfix();
double_to_color(result, &red, &green, &blue);
@ -623,6 +655,7 @@ mathmap_get_pixel(int x, int y, guchar *pixel)
gimp_tile_unref(the_tile, FALSE);
the_tile = gimp_drawable_get_tile(drawable, FALSE, newrow, newcol);
assert(the_tile != 0);
gimp_tile_ref(the_tile);
col = newcol;
@ -730,8 +763,6 @@ mathmap_dialog(void)
gtk_widget_set_default_visual(gtk_preview_get_visual());
gtk_widget_set_default_colormap(gtk_preview_get_cmap());
fprintf(stderr, "here we are5!\n");
build_preview_source_image();
dialog = gtk_dialog_new();
@ -895,7 +926,6 @@ dialog_update_preview(void)
{
double left, right, bottom, top;
double dx, dy;
double px, py;
double cx, cy;
int ix, iy;
int x, y;
@ -916,15 +946,13 @@ dialog_update_preview(void)
scale_x = (double) (preview_width - 1) / (right - left);
scale_y = (double) (preview_height - 1) / (bottom - top);
py = top;
p_ul = wint.wimage;
p_lr = wint.wimage + 3 * (preview_width * preview_height - 1);
theExprtree = 0;
yy_scan_string(mmvals.expression);
scanFromString(mmvals.expression);
yyparse();
endScanningFromString();
if (theExprtree == 0)
return;
@ -950,10 +978,8 @@ dialog_update_preview(void)
imageR = sqrt(imageX * imageX + imageY * imageY);
for (y = 0; y <= preview_height; y++)
for (y = 0; y < preview_height; y++)
{
px = left;
for (x = 0; x < preview_width; x++)
{
double result;
@ -981,7 +1007,7 @@ dialog_update_preview(void)
gtk_preview_draw_row(GTK_PREVIEW(wint.preview), p, 0, y, preview_width);
p += preview_width * 3;
} /* for */
}
gtk_widget_draw(wint.preview, NULL);
gdk_flush();

View File

@ -12,7 +12,11 @@ extern exprtree *theExprtree;
}
%token T_IDENT T_NUMBER
%token T_IF T_THEN T_ELSE T_END
%token T_WHILE T_DO
%right ';'
%right '='
%left '+' '-'
%left '*' '/' '%'
%left NEG
@ -36,7 +40,20 @@ expr : T_NUMBER { $<exprtree>$ = $<exprtree>1; }
$<exprtree>1, $<exprtree>3); }
| '-' expr %prec NEG { $<exprtree>$ = make_operator(EXPR_NEG, $<exprtree>2, 0); }
| '(' expr ')' { $<exprtree>$ = $<exprtree>2; };
| T_IDENT '(' arglist ')' { $<exprtree>$ = make_function($<ident>1, $<exprtree>3); }
| T_IDENT '(' arglist ')'
{ $<exprtree>$ = make_function($<ident>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; }

View File

@ -1,5 +1,9 @@
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include "builtins.h"
#include "vars.h"
#include "postfix.h"
@ -24,144 +28,184 @@ int exprp,
exprlen;
void
stack_push (double arg)
stack_push (double *arg)
{
stack[stackp++] = arg;
stack[stackp++] = *arg;
}
void
stack_add (double arg)
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_add_i (double *arg)
{
stack[stackp - 1] += arg;
stack[stackp - 1] += *arg;
}
void
stack_sub (double arg)
stack_sub (void *arg)
{
stack[stackp - 2] = stack[stackp - 2] - stack[stackp - 1];
--stackp;
}
void
stack_sub_i (double arg)
stack_sub_i (double *arg)
{
stack[stackp - 1] -= arg;
stack[stackp - 1] -= *arg;
}
void
stack_neg (double arg)
stack_neg (void *arg)
{
stack[stackp - 1] = -stack[stackp - 1];
}
void
stack_mul (double arg)
stack_mul (void *arg)
{
stack[stackp - 2] = stack[stackp - 2] * stack[stackp - 1];
--stackp;
}
void
stack_mul_i (double arg)
stack_mul_i (double *arg)
{
stack[stackp - 1] *= arg;
stack[stackp - 1] *= *arg;
}
void
stack_div (double arg)
stack_div (void *arg)
{
stack[stackp - 2] = stack[stackp - 2] / stack[stackp - 1];
--stackp;
}
void
stack_div_i (double arg)
stack_div_i (double *arg)
{
stack[stackp - 1] /= arg;
stack[stackp - 1] /= *arg;
}
void
stack_mod (double arg)
stack_mod (void *arg)
{
stack[stackp - 2] = fmod(stack[stackp - 2], stack[stackp - 1]);
--stackp;
}
void
stack_mod_i (double arg)
stack_mod_i (double *arg)
{
stack[stackp - 1] = fmod(stack[stackp - 1], arg);
stack[stackp - 1] = fmod(stack[stackp - 1], *arg);
}
void
stack_var_x (double arg)
stack_var_x (void *arg)
{
stack[stackp++] = currentX;
}
void
stack_var_y (double arg)
stack_var_y (void *arg)
{
stack[stackp++] = currentY;
}
void
stack_var_r (double arg)
stack_var_r (void *arg)
{
stack[stackp++] = currentR;
}
void
stack_var_a (double arg)
stack_var_a (void *arg)
{
stack[stackp++] = currentA;
}
void
stack_var_w (double arg)
stack_var_w (void *arg)
{
stack[stackp++] = imageWidth;
}
void
stack_var_h (double arg)
stack_var_h (void *arg)
{
stack[stackp++] = imageHeight;
}
void
stack_var_big_r (double arg)
stack_var_big_r (void *arg)
{
stack[stackp++] = imageR;
}
void
stack_var_big_x (double arg)
stack_var_big_x (void *arg)
{
stack[stackp++] = imageX;
}
void
stack_var_big_y (double arg)
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 = stack_push;
expression[exprp].arg = tree->val.number;
expression[exprp].func = (stackfunc)stack_push;
expression[exprp].arg = &tree->val.number;
++exprp;
break;
@ -169,8 +213,8 @@ make_postfix_recursive (exprtree *tree)
make_postfix_recursive(tree->val.operator.left);
if (tree->val.operator.right->type == EXPR_NUMBER)
{
expression[exprp].func = stack_add_i;
expression[exprp].arg = tree->val.operator.right->val.number;
expression[exprp].func = (stackfunc)stack_add_i;
expression[exprp].arg = &tree->val.operator.right->val.number;
}
else
{
@ -184,8 +228,8 @@ make_postfix_recursive (exprtree *tree)
make_postfix_recursive(tree->val.operator.left);
if (tree->val.operator.right->type == EXPR_NUMBER)
{
expression[exprp].func = stack_sub_i;
expression[exprp].arg = tree->val.operator.right->val.number;
expression[exprp].func = (stackfunc)stack_sub_i;
expression[exprp].arg = &tree->val.operator.right->val.number;
}
else
{
@ -196,16 +240,17 @@ make_postfix_recursive (exprtree *tree)
break;
case EXPR_NEG :
/*
if (tree->val.operator.left->type == EXPR_NUMBER)
{
expression[exprp].func = stack_push;
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;
@ -213,8 +258,8 @@ make_postfix_recursive (exprtree *tree)
make_postfix_recursive(tree->val.operator.left);
if (tree->val.operator.right->type == EXPR_NUMBER)
{
expression[exprp].func = stack_mul_i;
expression[exprp].arg = tree->val.operator.right->val.number;
expression[exprp].func = (stackfunc)stack_mul_i;
expression[exprp].arg = &tree->val.operator.right->val.number;
}
else
{
@ -228,8 +273,8 @@ make_postfix_recursive (exprtree *tree)
make_postfix_recursive(tree->val.operator.left);
if (tree->val.operator.right->type == EXPR_NUMBER)
{
expression[exprp].func = stack_div_i;
expression[exprp].arg = tree->val.operator.right->val.number;
expression[exprp].func = (stackfunc)stack_div_i;
expression[exprp].arg = &tree->val.operator.right->val.number;
}
else
{
@ -243,8 +288,8 @@ make_postfix_recursive (exprtree *tree)
make_postfix_recursive(tree->val.operator.left);
if (tree->val.operator.right->type == EXPR_NUMBER)
{
expression[exprp].func = stack_mod_i;
expression[exprp].arg = tree->val.operator.right->val.number;
expression[exprp].func = (stackfunc)stack_mod_i;
expression[exprp].arg = &tree->val.operator.right->val.number;
}
else
{
@ -304,6 +349,85 @@ make_postfix_recursive (exprtree *tree)
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");
}
@ -317,6 +441,107 @@ make_postfix (exprtree *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_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)
{

View File

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

View File

@ -9,14 +9,32 @@
%%
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_]* { strncpy(yylval.ident, yytext, 63);
yylval.ident[63] = 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 yytext[0];
;.* ;
[-,()+*/%=;] return yytext[0];
#.* ;
[ \t\n] ;
%%
void
scanFromString (char *string)
{
yy_scan_string(string);
}
void
endScanningFromString (void)
{
yy_delete_buffer(YY_CURRENT_BUFFER);
}

View File

@ -0,0 +1,42 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = papertile
papertile_SOURCES = \
papertile.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
papertile_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

@ -0,0 +1,469 @@
/*******************************************************************************
papertile.c -- This is a plug-in for the GIMP 1.0
Copyright (C) 1997 Hirotsuna Mizuno
s1041150@u-aizu.ac.jp
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 <gtk/gtk.h>
#include <libgimp/gimp.h>
#define PLUG_IN_NAME "plug_in_paper_tile"
#define PLUG_IN_VERSION "v0.7 (Dec. 25 1997)"
#define DIALOG_CAPTION "Paper Tile"
/******************************************************************************/
static void query( void );
static void run( char *, int, GParam *, int *, GParam ** );
static void filter( GDrawable *drawable );
static int dialog( void );
/******************************************************************************/
#define BG_TYPE_TRANSPARENT 0
#define BG_TYPE_BLACK 1
#define BG_TYPE_WHITE 2
typedef struct {
gint32 tile_width;
gint32 tile_height;
gint32 slide_length;
gint32 bg_type;
} parameter_t;
/******************************************************************************/
GPlugInInfo PLUG_IN_INFO = {
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
static parameter_t parameters = {
50,
50,
10,
BG_TYPE_TRANSPARENT
};
static gint image_width;
static gint image_height;
static gint image_bpp;
static gint image_has_alpha;
static gint select_x1;
static gint select_y1;
static gint select_x2;
static gint select_y2;
static gint select_width;
static gint select_height;
/******************************************************************************/
MAIN();
/******************************************************************************/
static void query( void )
{
static int nargs = 7;
static GParamDef args[] = {
{ PARAM_INT32, "run_mode", "interactive / non-interactive" },
{ PARAM_IMAGE, "image", "input image" },
{ PARAM_DRAWABLE, "drawable", "input drawable" },
{ PARAM_INT32, "width", "tile width" },
{ PARAM_INT32, "height", "tile height" },
{ PARAM_INT32, "slide_length", "slide length" },
{ PARAM_INT32, "bg_type", "background color "
"(0=transparent, 1=black, 2=white )" }
};
static int nreturn_vals = 0;
static GParamDef *return_vals = NULL;
gimp_install_procedure(
PLUG_IN_NAME,
"cut and slide image",
"cut and slide image",
"Hirotsuna Mizuno <s1041150@u-aizu.ac.jp>",
"Hirotsuna Mizuno",
PLUG_IN_VERSION,
"<Image>/Filters/Effects/Paper Tile",
"RGB*, GRAY*",
PROC_PLUG_IN,
nargs,
nreturn_vals,
args,
return_vals
);
}
/******************************************************************************/
static void run( char *name,
int paramc,
GParam *params,
int *returnc,
GParam **returns )
{
GDrawable *drawable;
GRunModeType run_mode;
static GParam returnv[1];
GStatusType status = STATUS_SUCCESS;
run_mode = params[0].data.d_int32;
drawable = gimp_drawable_get( params[2].data.d_drawable );
*returnc = 1;
*returns = returnv;
/* get the drawable info */
image_width = gimp_drawable_width( drawable->id );
image_height = gimp_drawable_height( drawable->id );
image_bpp = gimp_drawable_bpp( drawable->id );
image_has_alpha = gimp_drawable_has_alpha( drawable->id );
gimp_drawable_mask_bounds( drawable->id,
&select_x1, &select_y1, &select_x2, &select_y2 );
select_width = select_x2 - select_x1;
select_height = select_y2 - select_y1;
/* switch the run mode */
switch( run_mode ){
case RUN_INTERACTIVE:
gimp_get_data( PLUG_IN_NAME, &parameters );
if( ! dialog() ) return;
gimp_set_data( PLUG_IN_NAME, &parameters, sizeof( parameter_t ) );
break;
case RUN_NONINTERACTIVE:
if( paramc != 7 ){
status = STATUS_CALLING_ERROR;
} else {
parameters.tile_width = params[3].data.d_int32;
parameters.tile_height = params[4].data.d_int32;
parameters.slide_length = params[5].data.d_int32;
parameters.bg_type = params[6].data.d_int32;
}
break;
case RUN_WITH_LAST_VALS:
gimp_get_data( PLUG_IN_NAME, &parameters );
break;
}
if( status == STATUS_SUCCESS ){
if( gimp_drawable_color( drawable->id ) ||
gimp_drawable_gray( drawable->id ) ){
gimp_tile_cache_ntiles( 2 * ( drawable->width / gimp_tile_width() + 1 ) );
filter( drawable );
if( run_mode != RUN_NONINTERACTIVE ) gimp_displays_flush ();
} else {
status = STATUS_EXECUTION_ERROR;
}
}
returnv[0].type = PARAM_STATUS;
returnv[0].data.d_status = status;
gimp_drawable_detach( drawable );
}
/******************************************************************************/
static void filter( GDrawable *drawable )
{
GPixelRgn srcPR, destPR;
guchar **pixels;
guchar **destpixels;
gint x, y, b;
gint vx, vy, xx, yy;
gimp_pixel_rgn_init( &srcPR, drawable,
0, 0, image_width, image_height, FALSE, FALSE );
gimp_pixel_rgn_init( &destPR, drawable,
0, 0, image_width, image_height, TRUE, TRUE );
pixels = (guchar **)malloc( image_height * sizeof(guchar *) );
destpixels = (guchar **)malloc( image_height * sizeof(guchar *) );
for( y = 0; y < image_height; y++ ){
pixels[y] = (guchar *)malloc( image_width * image_bpp );
destpixels[y] = (guchar *)malloc( image_width * image_bpp );
gimp_pixel_rgn_get_row( &srcPR, pixels[y], 0, y, image_width );
}
for( y = select_y1; y < select_y2; y++ ){
for( x = select_x1; x < select_x2; x++ ){
switch( parameters.bg_type ){
case BG_TYPE_TRANSPARENT:
for( b = 0; b < image_bpp; b++ ){
destpixels[y][x*image_bpp+b] = 0;
}
break;
case BG_TYPE_BLACK:
for( b = 0; b < image_bpp; b++ ){
if( b == image_bpp - 1 && image_has_alpha ){
destpixels[y][x*image_bpp+b] = 255;
} else {
destpixels[y][x*image_bpp+b] = 0;
}
}
break;
case BG_TYPE_WHITE:
for( b = 0; b < image_bpp; b++ ){
destpixels[y][x*image_bpp+b] = 255;
}
break;
}
}
}
gimp_progress_init( PLUG_IN_NAME );
for( y = select_y1; y < select_y2; y+=parameters.tile_height )
for( x = select_x1; x < select_x2; x+=parameters.tile_width ){
vx = rand()%parameters.slide_length - parameters.slide_length/2;
vy = rand()%parameters.slide_length - parameters.slide_length/2;
for( xx = 0; xx < parameters.tile_width; xx++ )
if( 0 <= x+xx+vx && x+xx+vx < image_width && x+xx < image_width )
for( yy = 0; yy < parameters.tile_height; yy++ )
if( 0 <= y+yy+vy && y+yy+vy < image_height && y+yy < image_height )
for( b = 0; b < image_bpp; b++ )
destpixels[y+yy+vy][(x+xx+vx)*image_bpp+b]
= pixels[y+yy][(x+xx)*image_bpp+b];
}
for( y = select_y1; y < select_y2; y++ ){
gimp_pixel_rgn_set_row (&destPR, destpixels[y], 0, y, image_width );
gimp_progress_update ( (double)( y - select_y1 ) / select_height );
}
gimp_drawable_flush( drawable );
gimp_drawable_merge_shadow( drawable->id, TRUE );
gimp_drawable_update( drawable->id,
select_x1, select_y1, select_width, select_height );
for( y = select_y1; y < select_y2; y++ ) free( pixels[y-select_y1] );
free( pixels );
for( y = select_y1; y < select_y2; y++ ) free( destpixels[y-select_y1] );
free( destpixels );
}
/******************************************************************************/
static int dialog_status;
static GtkWidget *entry_width;
static GtkWidget *entry_height;
static GtkWidget *entry_slide;
static GtkWidget *button_transparent;
static GtkWidget *button_black;
static GtkWidget *button_white;
static void dialog_destroy_handler( GtkWidget *widget,
gpointer *data )
{
gtk_main_quit();
}
static void dialog_ok_handler( GtkWidget *widget,
gpointer *data )
{
dialog_status = TRUE;
if( GTK_TOGGLE_BUTTON( button_white )->active ) parameters.bg_type = BG_TYPE_WHITE;
if( GTK_TOGGLE_BUTTON( button_black )->active ) parameters.bg_type = BG_TYPE_BLACK;
if( image_has_alpha ){
if( GTK_TOGGLE_BUTTON( button_transparent )->active ){
parameters.bg_type = BG_TYPE_TRANSPARENT;
}
}
parameters.tile_width =
(gint32)atof(gtk_entry_get_text( GTK_ENTRY( entry_width ) ) );
parameters.tile_height =
(gint32)atof(gtk_entry_get_text( GTK_ENTRY( entry_height ) ) );
parameters.slide_length =
(gint32)atof(gtk_entry_get_text( GTK_ENTRY( entry_slide ) ) );
gtk_widget_destroy( GTK_WIDGET( data ) );
}
static void dialog_cancel_handler( GtkWidget *widget,
gpointer *data )
{
dialog_status = FALSE;
gtk_widget_destroy( GTK_WIDGET( data ) );
}
/******************************************************************************/
static int dialog( void )
{
GtkWidget *window;
dialog_status = FALSE;
{
gint argc = 1;
gchar **argv = g_new( gchar *, 1 );
argv[0] = g_strdup( DIALOG_CAPTION );
gtk_init( &argc, &argv );
}
/* dialog window */
window = gtk_dialog_new();
gtk_signal_connect( GTK_OBJECT( window ), "destroy",
GTK_SIGNAL_FUNC( dialog_destroy_handler ), NULL );
gtk_container_border_width( GTK_CONTAINER( window ), 0 );
gtk_container_border_width( GTK_CONTAINER( GTK_DIALOG( window )->vbox ), 5 );
{
/* buttons */
GtkWidget *button;
/* ok button */
button = gtk_button_new_with_label( "OK" );
gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
GTK_SIGNAL_FUNC( dialog_ok_handler ),
GTK_OBJECT( window ) );
GTK_WIDGET_SET_FLAGS( button, GTK_CAN_DEFAULT );
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->action_area ),
button, TRUE, TRUE, 0 );
gtk_widget_grab_default( button );
gtk_widget_show( button );
/* cancel button */
button = gtk_button_new_with_label( "Cancel" );
gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
GTK_SIGNAL_FUNC( dialog_cancel_handler ),
GTK_OBJECT( window ));
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->action_area ),
button, TRUE, TRUE, 0 );
gtk_widget_show( button );
}
{
/* text boxes */
GtkWidget *table;
GtkWidget *label;
char buffer[32];
/* table */
table = gtk_table_new( 3, 2, FALSE );
gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->vbox ),
table, TRUE, TRUE, 0 );
gtk_widget_show( table );
/* tile width */
label = gtk_label_new( "width: " );
entry_width = gtk_entry_new();
sprintf( buffer, "%d", parameters.tile_width );
gtk_entry_set_text( GTK_ENTRY( entry_width ), buffer );
gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 0, 1 );
gtk_table_attach_defaults( GTK_TABLE( table ), entry_width, 1, 2, 0, 1 );
gtk_widget_show( label );
gtk_widget_show( entry_width );
/* tile height */
label = gtk_label_new( "height: " );
entry_height = gtk_entry_new();
sprintf( buffer, "%d", parameters.tile_height );
gtk_entry_set_text( GTK_ENTRY( entry_height ), buffer );
gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 1, 2 );
gtk_table_attach_defaults( GTK_TABLE( table ), entry_height, 1, 2, 1, 2 );
gtk_widget_show( label );
gtk_widget_show( entry_height );
/* slide length */
label = gtk_label_new( "slide: " );
entry_slide = gtk_entry_new();
sprintf( buffer, "%d", parameters.slide_length );
gtk_entry_set_text( GTK_ENTRY( entry_slide ), buffer );
gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 2, 3 );
gtk_table_attach_defaults( GTK_TABLE( table ), entry_slide, 1, 2, 2, 3 );
gtk_widget_show( label );
gtk_widget_show( entry_slide );
}
{
/* radio buttons */
GtkWidget *frame;
GtkWidget *vbox;
GSList *group;
frame = gtk_frame_new( "Background" );
gtk_container_border_width( GTK_CONTAINER( frame ), 0 );
gtk_frame_set_shadow_type( GTK_FRAME( frame ), GTK_SHADOW_ETCHED_IN );
gtk_box_pack_start( GTK_BOX( GTK_DIALOG( window )->vbox ),
frame, TRUE, TRUE, 0 );
gtk_widget_show( frame );
vbox = gtk_vbox_new( FALSE, 0 );
gtk_container_border_width( GTK_CONTAINER( vbox ), 0 );
gtk_container_add( GTK_CONTAINER( frame ), vbox );
gtk_widget_show( vbox );
group = NULL;
if( image_has_alpha ){
/* transparent */
button_transparent =
gtk_radio_button_new_with_label( NULL, "Transparent" );
gtk_box_pack_start( GTK_BOX( vbox ),
button_transparent, TRUE, TRUE, 0 );
if( parameters.bg_type == BG_TYPE_TRANSPARENT )
gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( button_transparent ),
TRUE );
gtk_widget_show( button_transparent );
group = gtk_radio_button_group( GTK_RADIO_BUTTON( button_transparent ) );
}
/* black */
button_black = gtk_radio_button_new_with_label( group, "Black" );
gtk_box_pack_start( GTK_BOX( vbox ), button_black, TRUE, TRUE, 0 );
if( parameters.bg_type == BG_TYPE_BLACK )
gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( button_black ), TRUE );
gtk_widget_show( button_black );
group = gtk_radio_button_group( GTK_RADIO_BUTTON( button_black ) );
/* white */
button_white = gtk_radio_button_new_with_label( group, "White" );
gtk_box_pack_start( GTK_BOX( vbox ), button_white, TRUE, TRUE, 0 );
if( parameters.bg_type == BG_TYPE_WHITE )
gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( button_white ), TRUE );
gtk_widget_show( button_white );
}
gtk_widget_show( window );
gtk_main();
return dialog_status;
}
/******************************************************************************/