mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-19 14:23:33 +00:00
Plugin updates Properly generated aa Makefile (still not built by default)
Plugin updates Properly generated aa Makefile (still not built by default) Sven's no args script patch -Yosh
This commit is contained in:
parent
c56e1b18e7
commit
4cebd76133
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Sun Jan 25 01:25:55 PST 1998 Manish Singh <yosh@gimp.org>
|
||||
|
||||
* plugin updates from the registry (align_layers,
|
||||
despeckle, mathmap, print)
|
||||
|
||||
* plug-ins/script-fu/script-fu-scripts.c
|
||||
* plug-ins/script-fu/scripts/copy-visible.scm:
|
||||
Applied Sven's no arguments script patch and copy-visible
|
||||
fix
|
||||
|
||||
Sun Jan 25 00:12:15 EST 1998 Adrian Likins <adrian@gimp.org>
|
||||
|
||||
* added plug-ins/script-fu-scripts/chip-away.scm
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
pluginlibdir = $(gimpplugindir)/plug-ins
|
||||
|
||||
pluginlib_PROGRAMS = #STD#
|
||||
pluginlib_PROGRAMS = aa
|
||||
|
||||
#STD#_SOURCES = \
|
||||
#STD#.c
|
||||
aa_SOURCES = aa.c
|
||||
|
||||
INCLUDES = \
|
||||
$(X_CFLAGS) \
|
||||
|
@ -16,6 +15,7 @@ LDADD = \
|
|||
$(top_builddir)/libgimp/libgimpui.la \
|
||||
$(top_builddir)/libgimp/libgimp.la \
|
||||
$(X_LIBS) \
|
||||
-laa \
|
||||
-lc
|
||||
|
||||
DEPS = \
|
||||
|
|
|
@ -7,5 +7,4 @@ So dont send us or Tim newsome bug reports about this yet.
|
|||
|
||||
ftp://ftp.ta.jcu.cz/pub/aa
|
||||
|
||||
|
||||
|
||||
NOTE: You need aalib version 1.1.6 for this plugin.
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* align_layers.c -- This is a plug-in for the GIMP (1.0's API)
|
||||
* Author: Shuji Narazaki <narazaki@InetQ.or.jp>
|
||||
* Time-stamp: <1997/10/23 23:44:11 narazaki@InetQ.or.jp>
|
||||
* Version: 0.25
|
||||
* Time-stamp: <1998/01/17 00:32:23 narazaki@InetQ.or.jp>
|
||||
* Version: 0.26
|
||||
*
|
||||
* Copyright (C) 1997 Shuji Narazaki <narazaki@InetQ.or.jp>
|
||||
* Copyright (C) 1997-1998 Shuji Narazaki <narazaki@InetQ.or.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
|
||||
|
@ -220,7 +220,7 @@ query ()
|
|||
gimp_install_procedure (PLUG_IN_NAME,
|
||||
"Align visible layers",
|
||||
"align visible layers",
|
||||
"Shuji Narazaki (narazaki@InetQ.or.jp)",
|
||||
"Shuji Narazaki <narazaki@InetQ.or.jp>",
|
||||
"Shuji Narazaki",
|
||||
"1997",
|
||||
MENU_POSITION,
|
||||
|
@ -285,6 +285,8 @@ run (char *name,
|
|||
static GStatusType
|
||||
align_layers (gint32 image_id)
|
||||
{
|
||||
GParam* return_vals;
|
||||
gint retvals;
|
||||
gint layer_num = 0;
|
||||
gint visible_layer_num = 1;
|
||||
gint *layers = NULL;
|
||||
|
@ -361,6 +363,12 @@ align_layers (gint32 image_id)
|
|||
base_y = min_y;
|
||||
}
|
||||
|
||||
return_vals = gimp_run_procedure ("gimp_undo_push_group_start",
|
||||
&retvals,
|
||||
PARAM_IMAGE, image_id,
|
||||
PARAM_END);
|
||||
gimp_destroy_params (return_vals, retvals);
|
||||
|
||||
for (vindex = -1, index = 0; index < layer_num; index++)
|
||||
{
|
||||
if (gimp_layer_get_visible (layers[index]))
|
||||
|
@ -413,10 +421,14 @@ align_layers (gint32 image_id)
|
|||
}
|
||||
gimp_layer_set_offsets (layers[index], x, y);
|
||||
}
|
||||
return_vals = gimp_run_procedure ("gimp_undo_push_group_end",
|
||||
&retvals,
|
||||
PARAM_IMAGE, image_id,
|
||||
PARAM_END);
|
||||
gimp_destroy_params (return_vals, retvals);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
align_layers_get_align_offsets (gint32 drawable_id,
|
||||
gint *x,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* align_layers.c -- This is a plug-in for the GIMP (1.0's API)
|
||||
* Author: Shuji Narazaki <narazaki@InetQ.or.jp>
|
||||
* Time-stamp: <1997/10/23 23:44:11 narazaki@InetQ.or.jp>
|
||||
* Version: 0.25
|
||||
* Time-stamp: <1998/01/17 00:32:23 narazaki@InetQ.or.jp>
|
||||
* Version: 0.26
|
||||
*
|
||||
* Copyright (C) 1997 Shuji Narazaki <narazaki@InetQ.or.jp>
|
||||
* Copyright (C) 1997-1998 Shuji Narazaki <narazaki@InetQ.or.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
|
||||
|
@ -220,7 +220,7 @@ query ()
|
|||
gimp_install_procedure (PLUG_IN_NAME,
|
||||
"Align visible layers",
|
||||
"align visible layers",
|
||||
"Shuji Narazaki (narazaki@InetQ.or.jp)",
|
||||
"Shuji Narazaki <narazaki@InetQ.or.jp>",
|
||||
"Shuji Narazaki",
|
||||
"1997",
|
||||
MENU_POSITION,
|
||||
|
@ -285,6 +285,8 @@ run (char *name,
|
|||
static GStatusType
|
||||
align_layers (gint32 image_id)
|
||||
{
|
||||
GParam* return_vals;
|
||||
gint retvals;
|
||||
gint layer_num = 0;
|
||||
gint visible_layer_num = 1;
|
||||
gint *layers = NULL;
|
||||
|
@ -361,6 +363,12 @@ align_layers (gint32 image_id)
|
|||
base_y = min_y;
|
||||
}
|
||||
|
||||
return_vals = gimp_run_procedure ("gimp_undo_push_group_start",
|
||||
&retvals,
|
||||
PARAM_IMAGE, image_id,
|
||||
PARAM_END);
|
||||
gimp_destroy_params (return_vals, retvals);
|
||||
|
||||
for (vindex = -1, index = 0; index < layer_num; index++)
|
||||
{
|
||||
if (gimp_layer_get_visible (layers[index]))
|
||||
|
@ -413,10 +421,14 @@ align_layers (gint32 image_id)
|
|||
}
|
||||
gimp_layer_set_offsets (layers[index], x, y);
|
||||
}
|
||||
return_vals = gimp_run_procedure ("gimp_undo_push_group_end",
|
||||
&retvals,
|
||||
PARAM_IMAGE, image_id,
|
||||
PARAM_END);
|
||||
gimp_destroy_params (return_vals, retvals);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
align_layers_get_align_offsets (gint32 drawable_id,
|
||||
gint *x,
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
* Despeckle (adaptive median) filter for The GIMP -- an image manipulation
|
||||
* program
|
||||
*
|
||||
* Copyright 1997 Michael Sweet. This code is based off Quartic's bumpmap
|
||||
* filter and the median filter (described in most image processing books...)
|
||||
* Copyright 1997-1998 Michael Sweet (mike@easysw.com)
|
||||
*
|
||||
* 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
|
||||
|
@ -44,23 +43,20 @@
|
|||
* Revision History:
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.4 1998/01/25 02:18:21 yosh
|
||||
* Applied Sven's menu patch
|
||||
* Revision 1.5 1998/01/25 09:29:23 yosh
|
||||
* Plugin updates
|
||||
* Properly generated aa Makefile (still not built by default)
|
||||
* Sven's no args script patch
|
||||
*
|
||||
* -Yosh
|
||||
*
|
||||
* Revision 1.3 1998/01/04 19:20:55 scott
|
||||
* * plug-ins/despeckle/despeckle.c: realloc buffers when the radius
|
||||
* of effect changes; save all values (not just radius) in plugin
|
||||
* data store; adjusted parameter handling to match PDB registration.
|
||||
* The algorithm still generates artifacts in the top rows of the
|
||||
* image. --sg
|
||||
* #
|
||||
* Revision 1.16 1998/01/22 14:35:03 mike
|
||||
* Added black & white level controls.
|
||||
* Fixed bug in despeckle code that caused the borders to darken.
|
||||
*
|
||||
* Revision 1.2 1997/12/09 05:57:27 adrian
|
||||
* added glasstile, colorify, papertile, and illusion plugins
|
||||
*
|
||||
* updated despeckle, and math map
|
||||
* Revision 1.15 1998/01/21 21:33:47 mike
|
||||
* Fixed malloc buffer overflow bug - wasn't realloc'ing buffers
|
||||
* when the filter radius changed.
|
||||
*
|
||||
* Revision 1.14 1997/11/14 17:17:59 mike
|
||||
* Updated to dynamically allocate return params in the run() function.
|
||||
|
@ -136,7 +132,7 @@
|
|||
*/
|
||||
|
||||
#define PLUG_IN_NAME "plug_in_despeckle"
|
||||
#define PLUG_IN_VERSION "1.1.3 - 14 November 1997"
|
||||
#define PLUG_IN_VERSION "1.2 - 22 January 1998"
|
||||
#define PREVIEW_SIZE 128
|
||||
#define SCALE_WIDTH 64
|
||||
#define ENTRY_WIDTH 64
|
||||
|
@ -145,11 +141,10 @@
|
|||
#define FILTER_ADAPTIVE 0x01
|
||||
#define FILTER_RECURSIVE 0x02
|
||||
|
||||
typedef struct _despeckle_values
|
||||
{
|
||||
int radius;
|
||||
int filter_type;
|
||||
} DespeckleVals;
|
||||
#define despeckle_radius (despeckle_vals[0]) /* Radius of filter */
|
||||
#define filter_type (despeckle_vals[1]) /* Type of filter */
|
||||
#define black_level (despeckle_vals[2]) /* Black level */
|
||||
#define white_level (despeckle_vals[3]) /* White level */
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
|
@ -193,8 +188,7 @@ int preview_width, /* Width of preview widget */
|
|||
preview_y1, /* Upper-left Y of preview */
|
||||
preview_x2, /* Lower-right X of preview */
|
||||
preview_y2; /* Lower-right Y of preview */
|
||||
int preview_buf_size; /* Allocated buffer size */
|
||||
guchar *preview_src, /* Source pixel rows */
|
||||
guchar *preview_src = NULL, /* Source pixel rows */
|
||||
*preview_dst, /* Destination pixel row */
|
||||
*preview_sort; /* Pixel value sort array */
|
||||
GtkObject *hscroll_data, /* Horizontal scrollbar data */
|
||||
|
@ -209,11 +203,8 @@ int sel_width, /* Selection width */
|
|||
sel_height; /* Selection height */
|
||||
int img_bpp; /* Bytes-per-pixel in image */
|
||||
gint run_filter = FALSE; /* True if we should run the filter */
|
||||
DespeckleVals despeckle_vals =
|
||||
{
|
||||
3, /* Radius of median filter box */
|
||||
FILTER_ADAPTIVE /* Type of filter */
|
||||
};
|
||||
int despeckle_vals[4] = { 3, FILTER_ADAPTIVE, 7, 248 };
|
||||
|
||||
|
||||
/*
|
||||
* 'main()' - Main entry - just call gimp_main()...
|
||||
|
@ -240,7 +231,9 @@ query(void)
|
|||
{ PARAM_IMAGE, "image", "Input image" },
|
||||
{ PARAM_DRAWABLE, "drawable", "Input drawable" },
|
||||
{ PARAM_INT32, "radius", "Filter box radius (default = 3)" },
|
||||
{ PARAM_INT32, "type", "Filter type (0 = median, 1 = adaptive, 2 = recursive-median, 3 = recursive-adaptive)" }
|
||||
{ PARAM_INT32, "type", "Filter type (0 = median, 1 = adaptive, 2 = recursive-median, 3 = recursive-adaptive)" },
|
||||
{ PARAM_INT32, "black", "Black level (0 to 255)" },
|
||||
{ PARAM_INT32, "white", "White level (0 to 255)" }
|
||||
};
|
||||
static GParamDef *return_vals = NULL;
|
||||
static int nargs = sizeof(args) / sizeof(args[0]),
|
||||
|
@ -312,7 +305,7 @@ run(char *name, /* I - Name of filter program. */
|
|||
* Possibly retrieve data...
|
||||
*/
|
||||
|
||||
gimp_get_data(PLUG_IN_NAME, &despeckle_vals);
|
||||
gimp_get_data(PLUG_IN_NAME, &despeckle_radius);
|
||||
|
||||
/*
|
||||
* Get information from the dialog...
|
||||
|
@ -327,13 +320,36 @@ run(char *name, /* I - Name of filter program. */
|
|||
* Make sure all the arguments are present...
|
||||
*/
|
||||
|
||||
if (nparams != 5)
|
||||
if (nparams < 4 || nparams > 7)
|
||||
status = STATUS_CALLING_ERROR;
|
||||
else
|
||||
{
|
||||
despeckle_vals.radius = param[3].data.d_int32;
|
||||
despeckle_vals.filter_type = param[4].data.d_int32;
|
||||
}
|
||||
else if (nparams == 4)
|
||||
{
|
||||
despeckle_radius = param[3].data.d_int32;
|
||||
filter_type = FILTER_ADAPTIVE;
|
||||
black_level = 7;
|
||||
white_level = 248;
|
||||
}
|
||||
else if (nparams == 5)
|
||||
{
|
||||
despeckle_radius = param[3].data.d_int32;
|
||||
filter_type = param[4].data.d_int32;
|
||||
black_level = 7;
|
||||
white_level = 248;
|
||||
}
|
||||
else if (nparams == 6)
|
||||
{
|
||||
despeckle_radius = param[3].data.d_int32;
|
||||
filter_type = param[4].data.d_int32;
|
||||
black_level = param[5].data.d_int32;
|
||||
white_level = 248;
|
||||
}
|
||||
else
|
||||
{
|
||||
despeckle_radius = param[3].data.d_int32;
|
||||
filter_type = param[4].data.d_int32;
|
||||
black_level = param[5].data.d_int32;
|
||||
white_level = param[6].data.d_int32;
|
||||
};
|
||||
break;
|
||||
|
||||
case RUN_WITH_LAST_VALS :
|
||||
|
@ -341,7 +357,7 @@ run(char *name, /* I - Name of filter program. */
|
|||
* Possibly retrieve data...
|
||||
*/
|
||||
|
||||
gimp_get_data(PLUG_IN_NAME, &despeckle_vals);
|
||||
gimp_get_data(PLUG_IN_NAME, despeckle_vals);
|
||||
break;
|
||||
|
||||
default :
|
||||
|
@ -383,7 +399,7 @@ run(char *name, /* I - Name of filter program. */
|
|||
*/
|
||||
|
||||
if (run_mode == RUN_INTERACTIVE)
|
||||
gimp_set_data(PLUG_IN_NAME, &despeckle_vals, sizeof(despeckle_vals));
|
||||
gimp_set_data(PLUG_IN_NAME, despeckle_vals, sizeof(despeckle_vals));
|
||||
}
|
||||
else
|
||||
status = STATUS_EXECUTION_ERROR;
|
||||
|
@ -456,7 +472,7 @@ despeckle(void)
|
|||
gimp_pixel_rgn_init(&src_rgn, drawable, sel_x1, sel_y1, sel_width, sel_height, FALSE, FALSE);
|
||||
gimp_pixel_rgn_init(&dst_rgn, drawable, sel_x1, sel_y1, sel_width, sel_height, TRUE, TRUE);
|
||||
|
||||
size = despeckle_vals.radius * 2 + 1;
|
||||
size = despeckle_radius * 2 + 1;
|
||||
max_row = 2 * gimp_tile_height();
|
||||
width = sel_width * img_bpp;
|
||||
|
||||
|
@ -490,7 +506,7 @@ despeckle(void)
|
|||
|
||||
for (y = sel_y1 ; y < sel_y2; y ++)
|
||||
{
|
||||
if ((y + despeckle_vals.radius) >= lasty &&
|
||||
if ((y + despeckle_radius) >= lasty &&
|
||||
lasty < sel_y2)
|
||||
{
|
||||
/*
|
||||
|
@ -512,86 +528,97 @@ despeckle(void)
|
|||
* Now find the median pixels and save the results...
|
||||
*/
|
||||
|
||||
radius = despeckle_vals.radius;
|
||||
radius = despeckle_radius;
|
||||
|
||||
for (x = 0; x < width; x ++)
|
||||
memcpy(dst_row, src_rows[(row + y - lasty + max_row) % max_row], width);
|
||||
|
||||
if (y >= (sel_y1 + radius) && y < (sel_y2 - radius))
|
||||
{
|
||||
hist0 = 0;
|
||||
hist255 = 0;
|
||||
xmin = x - radius * img_bpp;
|
||||
xmax = x + (radius + 1) * img_bpp;
|
||||
for (x = 0; x < width; x ++)
|
||||
{
|
||||
hist0 = 0;
|
||||
hist255 = 0;
|
||||
xmin = x - radius * img_bpp;
|
||||
xmax = x + (radius + 1) * img_bpp;
|
||||
|
||||
if (xmin < 0)
|
||||
xmin = x % img_bpp;
|
||||
if (xmin < 0)
|
||||
xmin = x % img_bpp;
|
||||
|
||||
if (xmax > width)
|
||||
xmax = width;
|
||||
if (xmax > width)
|
||||
xmax = width;
|
||||
|
||||
startrow = (row + y - lasty - radius + max_row) % max_row;
|
||||
endrow = (row + y - lasty + radius + 1 + max_row) % max_row;
|
||||
startrow = (row + y - lasty - radius + max_row) % max_row;
|
||||
endrow = (row + y - lasty + radius + 1 + max_row) % max_row;
|
||||
|
||||
for (sort_ptr = sort, trow = startrow;
|
||||
trow != endrow;
|
||||
trow = (trow + 1) % max_row)
|
||||
for (tx = xmin, src_ptr = src_rows[trow] + xmin;
|
||||
tx < xmax;
|
||||
tx += img_bpp, sort_ptr ++, src_ptr += img_bpp)
|
||||
for (sort_ptr = sort, trow = startrow;
|
||||
trow != endrow;
|
||||
trow = (trow + 1) % max_row)
|
||||
for (tx = xmin, src_ptr = src_rows[trow] + xmin;
|
||||
tx < xmax;
|
||||
tx += img_bpp, src_ptr += img_bpp)
|
||||
{
|
||||
if ((*sort_ptr = *src_ptr) <= black_level)
|
||||
hist0 ++;
|
||||
else if (*sort_ptr >= white_level)
|
||||
hist255 ++;
|
||||
|
||||
if (*sort_ptr < white_level)
|
||||
sort_ptr ++;
|
||||
};
|
||||
|
||||
/*
|
||||
* Shell sort the color values...
|
||||
*/
|
||||
|
||||
sort_count = sort_ptr - sort;
|
||||
|
||||
if (sort_count > 1)
|
||||
{
|
||||
if ((*sort_ptr = *src_ptr) == 0)
|
||||
hist0 ++;
|
||||
else if (*sort_ptr == 255)
|
||||
hist255 ++;
|
||||
for (d = sort_count / 2; d > 0; d = d / 2)
|
||||
for (i = d; i < sort_count; i ++)
|
||||
for (j = i - d, sort_ptr = sort + j;
|
||||
j >= 0 && sort_ptr[0] > sort_ptr[d];
|
||||
j -= d, sort_ptr -= d)
|
||||
{
|
||||
t = sort_ptr[0];
|
||||
sort_ptr[0] = sort_ptr[d];
|
||||
sort_ptr[d] = t;
|
||||
};
|
||||
|
||||
/*
|
||||
* Assign the median value...
|
||||
*/
|
||||
|
||||
t = sort_count / 2;
|
||||
|
||||
if (sort_count & 1)
|
||||
dst_row[x] = (sort[t] + sort[t + 1]) / 2;
|
||||
else
|
||||
dst_row[x] = sort[t];
|
||||
|
||||
/*
|
||||
* Save the change to the source image too if the user wants the
|
||||
* recursive method...
|
||||
*/
|
||||
|
||||
if (filter_type & FILTER_RECURSIVE)
|
||||
src_rows[(row + y - lasty + max_row) % max_row][x] = dst_row[x];
|
||||
};
|
||||
|
||||
/*
|
||||
* Shell sort the color values...
|
||||
*/
|
||||
/*
|
||||
* Check the histogram and adjust the radius accordingly...
|
||||
*/
|
||||
|
||||
sort_count = sort_ptr - sort;
|
||||
|
||||
for (d = sort_count / 2; d > 0; d = d / 2)
|
||||
for (i = d; i < sort_count; i ++)
|
||||
for (j = i - d, sort_ptr = sort + j;
|
||||
j >= 0 && sort_ptr[0] > sort_ptr[d];
|
||||
j -= d, sort_ptr -= d)
|
||||
{
|
||||
t = sort_ptr[0];
|
||||
sort_ptr[0] = sort_ptr[d];
|
||||
sort_ptr[d] = t;
|
||||
};
|
||||
|
||||
/*
|
||||
* Assign the median value...
|
||||
*/
|
||||
|
||||
t = sort_count / 2;
|
||||
|
||||
if (sort_count & 1)
|
||||
dst_row[x] = (sort[t] + sort[t + 1]) / 2;
|
||||
else
|
||||
dst_row[x] = sort[t];
|
||||
|
||||
/*
|
||||
* Save the change to the source image too if the user wants the
|
||||
* recursive method...
|
||||
*/
|
||||
|
||||
if (despeckle_vals.filter_type & FILTER_RECURSIVE)
|
||||
src_rows[(row + y - lasty + max_row) % max_row][x] = dst_row[x];
|
||||
|
||||
/*
|
||||
* Check the histogram and adjust the radius accordingly...
|
||||
*/
|
||||
|
||||
if (despeckle_vals.filter_type & FILTER_ADAPTIVE)
|
||||
{
|
||||
if (hist0 >= radius || hist255 >= radius)
|
||||
if (filter_type & FILTER_ADAPTIVE)
|
||||
{
|
||||
if (radius < despeckle_vals.radius)
|
||||
radius ++;
|
||||
}
|
||||
else if (radius > 1)
|
||||
radius --;
|
||||
if (hist0 >= radius || hist255 >= radius)
|
||||
{
|
||||
if (radius < despeckle_radius)
|
||||
radius ++;
|
||||
}
|
||||
else if (radius > 1)
|
||||
radius --;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -666,7 +693,7 @@ despeckle_dialog(void)
|
|||
*/
|
||||
|
||||
dialog = gtk_dialog_new();
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), "Despeckle");
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), "Despeckle " PLUG_IN_VERSION);
|
||||
gtk_window_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(dialog), 0);
|
||||
gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
|
||||
|
@ -677,7 +704,7 @@ despeckle_dialog(void)
|
|||
* Top-level table for dialog...
|
||||
*/
|
||||
|
||||
table = gtk_table_new(3, 3, FALSE);
|
||||
table = gtk_table_new(5, 3, FALSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(table), 6);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(table), 4);
|
||||
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, FALSE, 0);
|
||||
|
@ -731,11 +758,16 @@ despeckle_dialog(void)
|
|||
|
||||
preview_init();
|
||||
|
||||
preview_x1 = sel_x1;
|
||||
preview_y1 = sel_y1;
|
||||
preview_x2 = preview_x1 + MIN(preview_width, sel_width);
|
||||
preview_y2 = preview_y1 + MIN(preview_height, sel_height);
|
||||
|
||||
/*
|
||||
* Filter type controls...
|
||||
*/
|
||||
|
||||
ftable = gtk_table_new(4, 1, FALSE);
|
||||
ftable = gtk_table_new(6, 1, FALSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(ftable), 4);
|
||||
gtk_table_attach(GTK_TABLE(table), ftable, 2, 3, 0, 1, 0, 0, 0, 0);
|
||||
gtk_widget_show(ftable);
|
||||
|
@ -744,7 +776,7 @@ despeckle_dialog(void)
|
|||
gtk_table_attach(GTK_TABLE(ftable), button, 0, 1, 0, 1,
|
||||
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
|
||||
(despeckle_vals.filter_type & FILTER_ADAPTIVE) ? TRUE : FALSE);
|
||||
(filter_type & FILTER_ADAPTIVE) ? TRUE : FALSE);
|
||||
gtk_signal_connect(GTK_OBJECT(button), "toggled",
|
||||
(GtkSignalFunc)dialog_adaptive_callback,
|
||||
NULL);
|
||||
|
@ -754,7 +786,7 @@ despeckle_dialog(void)
|
|||
gtk_table_attach(GTK_TABLE(ftable), button, 0, 1, 1, 2,
|
||||
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
|
||||
(despeckle_vals.filter_type & FILTER_RECURSIVE) ? TRUE : FALSE);
|
||||
(filter_type & FILTER_RECURSIVE) ? TRUE : FALSE);
|
||||
gtk_signal_connect(GTK_OBJECT(button), "toggled",
|
||||
(GtkSignalFunc)dialog_recursive_callback,
|
||||
NULL);
|
||||
|
@ -764,7 +796,19 @@ despeckle_dialog(void)
|
|||
* Box size (radius) control...
|
||||
*/
|
||||
|
||||
dialog_create_ivalue("Radius", GTK_TABLE(table), 2, &despeckle_vals.radius, 1, MAX_RADIUS);
|
||||
dialog_create_ivalue("Radius", GTK_TABLE(table), 2, &despeckle_radius, 1, MAX_RADIUS);
|
||||
|
||||
/*
|
||||
* Black level control...
|
||||
*/
|
||||
|
||||
dialog_create_ivalue("Black Level", GTK_TABLE(table), 3, &black_level, 0, 256);
|
||||
|
||||
/*
|
||||
* White level control...
|
||||
*/
|
||||
|
||||
dialog_create_ivalue("White Level", GTK_TABLE(table), 4, &white_level, 0, 256);
|
||||
|
||||
/*
|
||||
* OK, cancel buttons...
|
||||
|
@ -821,7 +865,7 @@ despeckle_dialog(void)
|
|||
static void
|
||||
preview_init(void)
|
||||
{
|
||||
int size, /* Size of filter box */
|
||||
int size, /* Size of filter box */
|
||||
width; /* Byte width of the image */
|
||||
|
||||
|
||||
|
@ -829,17 +873,19 @@ preview_init(void)
|
|||
* Setup for preview filter...
|
||||
*/
|
||||
|
||||
preview_buf_size = size = despeckle_vals.radius * 2 + 1;
|
||||
size = despeckle_radius * 2 + 1;
|
||||
width = preview_width * img_bpp;
|
||||
|
||||
if (preview_src != NULL)
|
||||
{
|
||||
g_free(preview_src);
|
||||
g_free(preview_dst);
|
||||
g_free(preview_sort);
|
||||
};
|
||||
|
||||
preview_src = g_malloc(width * preview_height * sizeof(guchar *));
|
||||
preview_dst = g_malloc(width * sizeof(guchar));
|
||||
preview_sort = g_malloc(size * size * sizeof(guchar));
|
||||
|
||||
preview_x1 = sel_x1;
|
||||
preview_y1 = sel_y1;
|
||||
preview_x2 = preview_x1 + MIN(preview_width, sel_width);
|
||||
preview_y2 = preview_y1 + MIN(preview_height, sel_height);
|
||||
}
|
||||
|
||||
|
||||
|
@ -893,19 +939,9 @@ preview_update(void)
|
|||
* Pre-load the preview rectangle...
|
||||
*/
|
||||
|
||||
size = despeckle_vals.radius * 2 + 1;
|
||||
size = despeckle_radius * 2 + 1;
|
||||
width = preview_width * img_bpp;
|
||||
|
||||
if (size != preview_buf_size)
|
||||
{
|
||||
preview_src = g_realloc(preview_src,
|
||||
width * preview_height * sizeof(guchar *));
|
||||
preview_dst = g_realloc(preview_dst,
|
||||
width * sizeof(guchar));
|
||||
preview_sort = g_realloc(preview_sort,
|
||||
size * size * sizeof(guchar));
|
||||
}
|
||||
|
||||
gimp_pixel_rgn_get_rect(&src_rgn, preview_src, preview_x1, preview_y1,
|
||||
preview_width, preview_height);
|
||||
|
||||
|
@ -919,11 +955,11 @@ preview_update(void)
|
|||
* Now find the median pixels and save the results...
|
||||
*/
|
||||
|
||||
radius = despeckle_vals.radius;
|
||||
radius = despeckle_radius;
|
||||
|
||||
if (y < radius || y >= (preview_height - radius))
|
||||
memcpy(preview_dst, preview_src + y * width, width);
|
||||
else
|
||||
memcpy(preview_dst, preview_src + y * width, width);
|
||||
|
||||
if (y >= radius && y < (preview_height - radius))
|
||||
{
|
||||
for (x = 0, dst_ptr = preview_dst; x < width; x ++, dst_ptr ++)
|
||||
{
|
||||
|
@ -942,12 +978,15 @@ preview_update(void)
|
|||
src_ptr = preview_src + width * (y - radius);
|
||||
i <= radius;
|
||||
i ++, src_ptr += width)
|
||||
for (tx = xmin; tx < xmax; tx += img_bpp, sort_ptr ++)
|
||||
for (tx = xmin; tx < xmax; tx += img_bpp)
|
||||
{
|
||||
if ((*sort_ptr = src_ptr[tx]) == 0)
|
||||
if ((*sort_ptr = src_ptr[tx]) <= black_level)
|
||||
hist0 ++;
|
||||
else if (*sort_ptr == 255)
|
||||
else if (*sort_ptr >= white_level)
|
||||
hist255 ++;
|
||||
|
||||
if (*sort_ptr < white_level)
|
||||
sort_ptr ++;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -956,45 +995,48 @@ preview_update(void)
|
|||
|
||||
sort_count = sort_ptr - preview_sort;
|
||||
|
||||
for (d = sort_count / 2; d > 0; d = d / 2)
|
||||
for (i = d; i < sort_count; i ++)
|
||||
for (j = i - d, sort_ptr = preview_sort + j;
|
||||
j >= 0 && sort_ptr[0] > sort_ptr[d];
|
||||
j -= d, sort_ptr -= d)
|
||||
{
|
||||
t = sort_ptr[0];
|
||||
sort_ptr[0] = sort_ptr[d];
|
||||
sort_ptr[d] = t;
|
||||
};
|
||||
if (sort_count > 1)
|
||||
{
|
||||
for (d = sort_count / 2; d > 0; d = d / 2)
|
||||
for (i = d; i < sort_count; i ++)
|
||||
for (j = i - d, sort_ptr = preview_sort + j;
|
||||
j >= 0 && sort_ptr[0] > sort_ptr[d];
|
||||
j -= d, sort_ptr -= d)
|
||||
{
|
||||
t = sort_ptr[0];
|
||||
sort_ptr[0] = sort_ptr[d];
|
||||
sort_ptr[d] = t;
|
||||
};
|
||||
|
||||
/*
|
||||
* Assign the median value...
|
||||
*/
|
||||
/*
|
||||
* Assign the median value...
|
||||
*/
|
||||
|
||||
t = sort_count / 2;
|
||||
t = sort_count / 2;
|
||||
|
||||
if (sort_count & 1)
|
||||
*dst_ptr = (preview_sort[t] + preview_sort[t + 1]) / 2;
|
||||
else
|
||||
*dst_ptr = preview_sort[t];
|
||||
if (sort_count & 1)
|
||||
*dst_ptr = (preview_sort[t] + preview_sort[t + 1]) / 2;
|
||||
else
|
||||
*dst_ptr = preview_sort[t];
|
||||
|
||||
/*
|
||||
* Save the change to the source image too if the user wants the
|
||||
* recursive method...
|
||||
*/
|
||||
/*
|
||||
* Save the change to the source image too if the user wants the
|
||||
* recursive method...
|
||||
*/
|
||||
|
||||
if (despeckle_vals.filter_type & FILTER_RECURSIVE)
|
||||
preview_src[y * width + x] = *dst_ptr;
|
||||
if (filter_type & FILTER_RECURSIVE)
|
||||
preview_src[y * width + x] = *dst_ptr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Check the histogram and adjust the radius accordingly...
|
||||
*/
|
||||
|
||||
if (despeckle_vals.filter_type & FILTER_ADAPTIVE)
|
||||
if (filter_type & FILTER_ADAPTIVE)
|
||||
{
|
||||
if (hist0 >= radius || hist255 >= radius)
|
||||
{
|
||||
if (radius < despeckle_vals.radius)
|
||||
if (radius < despeckle_radius)
|
||||
radius ++;
|
||||
}
|
||||
else if (radius > 1)
|
||||
|
@ -1051,7 +1093,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;
|
||||
|
@ -1148,6 +1191,9 @@ dialog_iscale_update(GtkAdjustment *adjustment, /* I - New value */
|
|||
gtk_entry_set_text(GTK_ENTRY(entry), buf);
|
||||
gtk_signal_handler_unblock_by_data(GTK_OBJECT(entry), value);
|
||||
|
||||
if (value == &despeckle_radius)
|
||||
preview_init();
|
||||
|
||||
preview_update();
|
||||
};
|
||||
}
|
||||
|
@ -1179,6 +1225,9 @@ dialog_ientry_update(GtkWidget *widget, /* I - Entry widget */
|
|||
|
||||
gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
|
||||
|
||||
if (value == &despeckle_radius)
|
||||
preview_init();
|
||||
|
||||
preview_update();
|
||||
};
|
||||
};
|
||||
|
@ -1194,9 +1243,9 @@ dialog_adaptive_callback(GtkWidget *widget, /* I - Toggle button */
|
|||
gpointer data) /* I - Data */
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
despeckle_vals.filter_type |= FILTER_ADAPTIVE;
|
||||
filter_type |= FILTER_ADAPTIVE;
|
||||
else
|
||||
despeckle_vals.filter_type &= ~FILTER_ADAPTIVE;
|
||||
filter_type &= ~FILTER_ADAPTIVE;
|
||||
|
||||
preview_update();
|
||||
}
|
||||
|
@ -1211,9 +1260,9 @@ dialog_recursive_callback(GtkWidget *widget, /* I - Toggle button */
|
|||
gpointer data) /* I - Data */
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
despeckle_vals.filter_type |= FILTER_RECURSIVE;
|
||||
filter_type |= FILTER_RECURSIVE;
|
||||
else
|
||||
despeckle_vals.filter_type &= ~FILTER_RECURSIVE;
|
||||
filter_type &= ~FILTER_RECURSIVE;
|
||||
|
||||
preview_update();
|
||||
}
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
* Despeckle (adaptive median) filter for The GIMP -- an image manipulation
|
||||
* program
|
||||
*
|
||||
* Copyright 1997 Michael Sweet. This code is based off Quartic's bumpmap
|
||||
* filter and the median filter (described in most image processing books...)
|
||||
* Copyright 1997-1998 Michael Sweet (mike@easysw.com)
|
||||
*
|
||||
* 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
|
||||
|
@ -44,23 +43,20 @@
|
|||
* Revision History:
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.4 1998/01/25 02:18:21 yosh
|
||||
* Applied Sven's menu patch
|
||||
* Revision 1.5 1998/01/25 09:29:23 yosh
|
||||
* Plugin updates
|
||||
* Properly generated aa Makefile (still not built by default)
|
||||
* Sven's no args script patch
|
||||
*
|
||||
* -Yosh
|
||||
*
|
||||
* Revision 1.3 1998/01/04 19:20:55 scott
|
||||
* * plug-ins/despeckle/despeckle.c: realloc buffers when the radius
|
||||
* of effect changes; save all values (not just radius) in plugin
|
||||
* data store; adjusted parameter handling to match PDB registration.
|
||||
* The algorithm still generates artifacts in the top rows of the
|
||||
* image. --sg
|
||||
* #
|
||||
* Revision 1.16 1998/01/22 14:35:03 mike
|
||||
* Added black & white level controls.
|
||||
* Fixed bug in despeckle code that caused the borders to darken.
|
||||
*
|
||||
* Revision 1.2 1997/12/09 05:57:27 adrian
|
||||
* added glasstile, colorify, papertile, and illusion plugins
|
||||
*
|
||||
* updated despeckle, and math map
|
||||
* Revision 1.15 1998/01/21 21:33:47 mike
|
||||
* Fixed malloc buffer overflow bug - wasn't realloc'ing buffers
|
||||
* when the filter radius changed.
|
||||
*
|
||||
* Revision 1.14 1997/11/14 17:17:59 mike
|
||||
* Updated to dynamically allocate return params in the run() function.
|
||||
|
@ -136,7 +132,7 @@
|
|||
*/
|
||||
|
||||
#define PLUG_IN_NAME "plug_in_despeckle"
|
||||
#define PLUG_IN_VERSION "1.1.3 - 14 November 1997"
|
||||
#define PLUG_IN_VERSION "1.2 - 22 January 1998"
|
||||
#define PREVIEW_SIZE 128
|
||||
#define SCALE_WIDTH 64
|
||||
#define ENTRY_WIDTH 64
|
||||
|
@ -145,11 +141,10 @@
|
|||
#define FILTER_ADAPTIVE 0x01
|
||||
#define FILTER_RECURSIVE 0x02
|
||||
|
||||
typedef struct _despeckle_values
|
||||
{
|
||||
int radius;
|
||||
int filter_type;
|
||||
} DespeckleVals;
|
||||
#define despeckle_radius (despeckle_vals[0]) /* Radius of filter */
|
||||
#define filter_type (despeckle_vals[1]) /* Type of filter */
|
||||
#define black_level (despeckle_vals[2]) /* Black level */
|
||||
#define white_level (despeckle_vals[3]) /* White level */
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
|
@ -193,8 +188,7 @@ int preview_width, /* Width of preview widget */
|
|||
preview_y1, /* Upper-left Y of preview */
|
||||
preview_x2, /* Lower-right X of preview */
|
||||
preview_y2; /* Lower-right Y of preview */
|
||||
int preview_buf_size; /* Allocated buffer size */
|
||||
guchar *preview_src, /* Source pixel rows */
|
||||
guchar *preview_src = NULL, /* Source pixel rows */
|
||||
*preview_dst, /* Destination pixel row */
|
||||
*preview_sort; /* Pixel value sort array */
|
||||
GtkObject *hscroll_data, /* Horizontal scrollbar data */
|
||||
|
@ -209,11 +203,8 @@ int sel_width, /* Selection width */
|
|||
sel_height; /* Selection height */
|
||||
int img_bpp; /* Bytes-per-pixel in image */
|
||||
gint run_filter = FALSE; /* True if we should run the filter */
|
||||
DespeckleVals despeckle_vals =
|
||||
{
|
||||
3, /* Radius of median filter box */
|
||||
FILTER_ADAPTIVE /* Type of filter */
|
||||
};
|
||||
int despeckle_vals[4] = { 3, FILTER_ADAPTIVE, 7, 248 };
|
||||
|
||||
|
||||
/*
|
||||
* 'main()' - Main entry - just call gimp_main()...
|
||||
|
@ -240,7 +231,9 @@ query(void)
|
|||
{ PARAM_IMAGE, "image", "Input image" },
|
||||
{ PARAM_DRAWABLE, "drawable", "Input drawable" },
|
||||
{ PARAM_INT32, "radius", "Filter box radius (default = 3)" },
|
||||
{ PARAM_INT32, "type", "Filter type (0 = median, 1 = adaptive, 2 = recursive-median, 3 = recursive-adaptive)" }
|
||||
{ PARAM_INT32, "type", "Filter type (0 = median, 1 = adaptive, 2 = recursive-median, 3 = recursive-adaptive)" },
|
||||
{ PARAM_INT32, "black", "Black level (0 to 255)" },
|
||||
{ PARAM_INT32, "white", "White level (0 to 255)" }
|
||||
};
|
||||
static GParamDef *return_vals = NULL;
|
||||
static int nargs = sizeof(args) / sizeof(args[0]),
|
||||
|
@ -312,7 +305,7 @@ run(char *name, /* I - Name of filter program. */
|
|||
* Possibly retrieve data...
|
||||
*/
|
||||
|
||||
gimp_get_data(PLUG_IN_NAME, &despeckle_vals);
|
||||
gimp_get_data(PLUG_IN_NAME, &despeckle_radius);
|
||||
|
||||
/*
|
||||
* Get information from the dialog...
|
||||
|
@ -327,13 +320,36 @@ run(char *name, /* I - Name of filter program. */
|
|||
* Make sure all the arguments are present...
|
||||
*/
|
||||
|
||||
if (nparams != 5)
|
||||
if (nparams < 4 || nparams > 7)
|
||||
status = STATUS_CALLING_ERROR;
|
||||
else
|
||||
{
|
||||
despeckle_vals.radius = param[3].data.d_int32;
|
||||
despeckle_vals.filter_type = param[4].data.d_int32;
|
||||
}
|
||||
else if (nparams == 4)
|
||||
{
|
||||
despeckle_radius = param[3].data.d_int32;
|
||||
filter_type = FILTER_ADAPTIVE;
|
||||
black_level = 7;
|
||||
white_level = 248;
|
||||
}
|
||||
else if (nparams == 5)
|
||||
{
|
||||
despeckle_radius = param[3].data.d_int32;
|
||||
filter_type = param[4].data.d_int32;
|
||||
black_level = 7;
|
||||
white_level = 248;
|
||||
}
|
||||
else if (nparams == 6)
|
||||
{
|
||||
despeckle_radius = param[3].data.d_int32;
|
||||
filter_type = param[4].data.d_int32;
|
||||
black_level = param[5].data.d_int32;
|
||||
white_level = 248;
|
||||
}
|
||||
else
|
||||
{
|
||||
despeckle_radius = param[3].data.d_int32;
|
||||
filter_type = param[4].data.d_int32;
|
||||
black_level = param[5].data.d_int32;
|
||||
white_level = param[6].data.d_int32;
|
||||
};
|
||||
break;
|
||||
|
||||
case RUN_WITH_LAST_VALS :
|
||||
|
@ -341,7 +357,7 @@ run(char *name, /* I - Name of filter program. */
|
|||
* Possibly retrieve data...
|
||||
*/
|
||||
|
||||
gimp_get_data(PLUG_IN_NAME, &despeckle_vals);
|
||||
gimp_get_data(PLUG_IN_NAME, despeckle_vals);
|
||||
break;
|
||||
|
||||
default :
|
||||
|
@ -383,7 +399,7 @@ run(char *name, /* I - Name of filter program. */
|
|||
*/
|
||||
|
||||
if (run_mode == RUN_INTERACTIVE)
|
||||
gimp_set_data(PLUG_IN_NAME, &despeckle_vals, sizeof(despeckle_vals));
|
||||
gimp_set_data(PLUG_IN_NAME, despeckle_vals, sizeof(despeckle_vals));
|
||||
}
|
||||
else
|
||||
status = STATUS_EXECUTION_ERROR;
|
||||
|
@ -456,7 +472,7 @@ despeckle(void)
|
|||
gimp_pixel_rgn_init(&src_rgn, drawable, sel_x1, sel_y1, sel_width, sel_height, FALSE, FALSE);
|
||||
gimp_pixel_rgn_init(&dst_rgn, drawable, sel_x1, sel_y1, sel_width, sel_height, TRUE, TRUE);
|
||||
|
||||
size = despeckle_vals.radius * 2 + 1;
|
||||
size = despeckle_radius * 2 + 1;
|
||||
max_row = 2 * gimp_tile_height();
|
||||
width = sel_width * img_bpp;
|
||||
|
||||
|
@ -490,7 +506,7 @@ despeckle(void)
|
|||
|
||||
for (y = sel_y1 ; y < sel_y2; y ++)
|
||||
{
|
||||
if ((y + despeckle_vals.radius) >= lasty &&
|
||||
if ((y + despeckle_radius) >= lasty &&
|
||||
lasty < sel_y2)
|
||||
{
|
||||
/*
|
||||
|
@ -512,86 +528,97 @@ despeckle(void)
|
|||
* Now find the median pixels and save the results...
|
||||
*/
|
||||
|
||||
radius = despeckle_vals.radius;
|
||||
radius = despeckle_radius;
|
||||
|
||||
for (x = 0; x < width; x ++)
|
||||
memcpy(dst_row, src_rows[(row + y - lasty + max_row) % max_row], width);
|
||||
|
||||
if (y >= (sel_y1 + radius) && y < (sel_y2 - radius))
|
||||
{
|
||||
hist0 = 0;
|
||||
hist255 = 0;
|
||||
xmin = x - radius * img_bpp;
|
||||
xmax = x + (radius + 1) * img_bpp;
|
||||
for (x = 0; x < width; x ++)
|
||||
{
|
||||
hist0 = 0;
|
||||
hist255 = 0;
|
||||
xmin = x - radius * img_bpp;
|
||||
xmax = x + (radius + 1) * img_bpp;
|
||||
|
||||
if (xmin < 0)
|
||||
xmin = x % img_bpp;
|
||||
if (xmin < 0)
|
||||
xmin = x % img_bpp;
|
||||
|
||||
if (xmax > width)
|
||||
xmax = width;
|
||||
if (xmax > width)
|
||||
xmax = width;
|
||||
|
||||
startrow = (row + y - lasty - radius + max_row) % max_row;
|
||||
endrow = (row + y - lasty + radius + 1 + max_row) % max_row;
|
||||
startrow = (row + y - lasty - radius + max_row) % max_row;
|
||||
endrow = (row + y - lasty + radius + 1 + max_row) % max_row;
|
||||
|
||||
for (sort_ptr = sort, trow = startrow;
|
||||
trow != endrow;
|
||||
trow = (trow + 1) % max_row)
|
||||
for (tx = xmin, src_ptr = src_rows[trow] + xmin;
|
||||
tx < xmax;
|
||||
tx += img_bpp, sort_ptr ++, src_ptr += img_bpp)
|
||||
for (sort_ptr = sort, trow = startrow;
|
||||
trow != endrow;
|
||||
trow = (trow + 1) % max_row)
|
||||
for (tx = xmin, src_ptr = src_rows[trow] + xmin;
|
||||
tx < xmax;
|
||||
tx += img_bpp, src_ptr += img_bpp)
|
||||
{
|
||||
if ((*sort_ptr = *src_ptr) <= black_level)
|
||||
hist0 ++;
|
||||
else if (*sort_ptr >= white_level)
|
||||
hist255 ++;
|
||||
|
||||
if (*sort_ptr < white_level)
|
||||
sort_ptr ++;
|
||||
};
|
||||
|
||||
/*
|
||||
* Shell sort the color values...
|
||||
*/
|
||||
|
||||
sort_count = sort_ptr - sort;
|
||||
|
||||
if (sort_count > 1)
|
||||
{
|
||||
if ((*sort_ptr = *src_ptr) == 0)
|
||||
hist0 ++;
|
||||
else if (*sort_ptr == 255)
|
||||
hist255 ++;
|
||||
for (d = sort_count / 2; d > 0; d = d / 2)
|
||||
for (i = d; i < sort_count; i ++)
|
||||
for (j = i - d, sort_ptr = sort + j;
|
||||
j >= 0 && sort_ptr[0] > sort_ptr[d];
|
||||
j -= d, sort_ptr -= d)
|
||||
{
|
||||
t = sort_ptr[0];
|
||||
sort_ptr[0] = sort_ptr[d];
|
||||
sort_ptr[d] = t;
|
||||
};
|
||||
|
||||
/*
|
||||
* Assign the median value...
|
||||
*/
|
||||
|
||||
t = sort_count / 2;
|
||||
|
||||
if (sort_count & 1)
|
||||
dst_row[x] = (sort[t] + sort[t + 1]) / 2;
|
||||
else
|
||||
dst_row[x] = sort[t];
|
||||
|
||||
/*
|
||||
* Save the change to the source image too if the user wants the
|
||||
* recursive method...
|
||||
*/
|
||||
|
||||
if (filter_type & FILTER_RECURSIVE)
|
||||
src_rows[(row + y - lasty + max_row) % max_row][x] = dst_row[x];
|
||||
};
|
||||
|
||||
/*
|
||||
* Shell sort the color values...
|
||||
*/
|
||||
/*
|
||||
* Check the histogram and adjust the radius accordingly...
|
||||
*/
|
||||
|
||||
sort_count = sort_ptr - sort;
|
||||
|
||||
for (d = sort_count / 2; d > 0; d = d / 2)
|
||||
for (i = d; i < sort_count; i ++)
|
||||
for (j = i - d, sort_ptr = sort + j;
|
||||
j >= 0 && sort_ptr[0] > sort_ptr[d];
|
||||
j -= d, sort_ptr -= d)
|
||||
{
|
||||
t = sort_ptr[0];
|
||||
sort_ptr[0] = sort_ptr[d];
|
||||
sort_ptr[d] = t;
|
||||
};
|
||||
|
||||
/*
|
||||
* Assign the median value...
|
||||
*/
|
||||
|
||||
t = sort_count / 2;
|
||||
|
||||
if (sort_count & 1)
|
||||
dst_row[x] = (sort[t] + sort[t + 1]) / 2;
|
||||
else
|
||||
dst_row[x] = sort[t];
|
||||
|
||||
/*
|
||||
* Save the change to the source image too if the user wants the
|
||||
* recursive method...
|
||||
*/
|
||||
|
||||
if (despeckle_vals.filter_type & FILTER_RECURSIVE)
|
||||
src_rows[(row + y - lasty + max_row) % max_row][x] = dst_row[x];
|
||||
|
||||
/*
|
||||
* Check the histogram and adjust the radius accordingly...
|
||||
*/
|
||||
|
||||
if (despeckle_vals.filter_type & FILTER_ADAPTIVE)
|
||||
{
|
||||
if (hist0 >= radius || hist255 >= radius)
|
||||
if (filter_type & FILTER_ADAPTIVE)
|
||||
{
|
||||
if (radius < despeckle_vals.radius)
|
||||
radius ++;
|
||||
}
|
||||
else if (radius > 1)
|
||||
radius --;
|
||||
if (hist0 >= radius || hist255 >= radius)
|
||||
{
|
||||
if (radius < despeckle_radius)
|
||||
radius ++;
|
||||
}
|
||||
else if (radius > 1)
|
||||
radius --;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -666,7 +693,7 @@ despeckle_dialog(void)
|
|||
*/
|
||||
|
||||
dialog = gtk_dialog_new();
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), "Despeckle");
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), "Despeckle " PLUG_IN_VERSION);
|
||||
gtk_window_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(dialog), 0);
|
||||
gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
|
||||
|
@ -677,7 +704,7 @@ despeckle_dialog(void)
|
|||
* Top-level table for dialog...
|
||||
*/
|
||||
|
||||
table = gtk_table_new(3, 3, FALSE);
|
||||
table = gtk_table_new(5, 3, FALSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(table), 6);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(table), 4);
|
||||
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, FALSE, 0);
|
||||
|
@ -731,11 +758,16 @@ despeckle_dialog(void)
|
|||
|
||||
preview_init();
|
||||
|
||||
preview_x1 = sel_x1;
|
||||
preview_y1 = sel_y1;
|
||||
preview_x2 = preview_x1 + MIN(preview_width, sel_width);
|
||||
preview_y2 = preview_y1 + MIN(preview_height, sel_height);
|
||||
|
||||
/*
|
||||
* Filter type controls...
|
||||
*/
|
||||
|
||||
ftable = gtk_table_new(4, 1, FALSE);
|
||||
ftable = gtk_table_new(6, 1, FALSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(ftable), 4);
|
||||
gtk_table_attach(GTK_TABLE(table), ftable, 2, 3, 0, 1, 0, 0, 0, 0);
|
||||
gtk_widget_show(ftable);
|
||||
|
@ -744,7 +776,7 @@ despeckle_dialog(void)
|
|||
gtk_table_attach(GTK_TABLE(ftable), button, 0, 1, 0, 1,
|
||||
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
|
||||
(despeckle_vals.filter_type & FILTER_ADAPTIVE) ? TRUE : FALSE);
|
||||
(filter_type & FILTER_ADAPTIVE) ? TRUE : FALSE);
|
||||
gtk_signal_connect(GTK_OBJECT(button), "toggled",
|
||||
(GtkSignalFunc)dialog_adaptive_callback,
|
||||
NULL);
|
||||
|
@ -754,7 +786,7 @@ despeckle_dialog(void)
|
|||
gtk_table_attach(GTK_TABLE(ftable), button, 0, 1, 1, 2,
|
||||
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
|
||||
(despeckle_vals.filter_type & FILTER_RECURSIVE) ? TRUE : FALSE);
|
||||
(filter_type & FILTER_RECURSIVE) ? TRUE : FALSE);
|
||||
gtk_signal_connect(GTK_OBJECT(button), "toggled",
|
||||
(GtkSignalFunc)dialog_recursive_callback,
|
||||
NULL);
|
||||
|
@ -764,7 +796,19 @@ despeckle_dialog(void)
|
|||
* Box size (radius) control...
|
||||
*/
|
||||
|
||||
dialog_create_ivalue("Radius", GTK_TABLE(table), 2, &despeckle_vals.radius, 1, MAX_RADIUS);
|
||||
dialog_create_ivalue("Radius", GTK_TABLE(table), 2, &despeckle_radius, 1, MAX_RADIUS);
|
||||
|
||||
/*
|
||||
* Black level control...
|
||||
*/
|
||||
|
||||
dialog_create_ivalue("Black Level", GTK_TABLE(table), 3, &black_level, 0, 256);
|
||||
|
||||
/*
|
||||
* White level control...
|
||||
*/
|
||||
|
||||
dialog_create_ivalue("White Level", GTK_TABLE(table), 4, &white_level, 0, 256);
|
||||
|
||||
/*
|
||||
* OK, cancel buttons...
|
||||
|
@ -821,7 +865,7 @@ despeckle_dialog(void)
|
|||
static void
|
||||
preview_init(void)
|
||||
{
|
||||
int size, /* Size of filter box */
|
||||
int size, /* Size of filter box */
|
||||
width; /* Byte width of the image */
|
||||
|
||||
|
||||
|
@ -829,17 +873,19 @@ preview_init(void)
|
|||
* Setup for preview filter...
|
||||
*/
|
||||
|
||||
preview_buf_size = size = despeckle_vals.radius * 2 + 1;
|
||||
size = despeckle_radius * 2 + 1;
|
||||
width = preview_width * img_bpp;
|
||||
|
||||
if (preview_src != NULL)
|
||||
{
|
||||
g_free(preview_src);
|
||||
g_free(preview_dst);
|
||||
g_free(preview_sort);
|
||||
};
|
||||
|
||||
preview_src = g_malloc(width * preview_height * sizeof(guchar *));
|
||||
preview_dst = g_malloc(width * sizeof(guchar));
|
||||
preview_sort = g_malloc(size * size * sizeof(guchar));
|
||||
|
||||
preview_x1 = sel_x1;
|
||||
preview_y1 = sel_y1;
|
||||
preview_x2 = preview_x1 + MIN(preview_width, sel_width);
|
||||
preview_y2 = preview_y1 + MIN(preview_height, sel_height);
|
||||
}
|
||||
|
||||
|
||||
|
@ -893,19 +939,9 @@ preview_update(void)
|
|||
* Pre-load the preview rectangle...
|
||||
*/
|
||||
|
||||
size = despeckle_vals.radius * 2 + 1;
|
||||
size = despeckle_radius * 2 + 1;
|
||||
width = preview_width * img_bpp;
|
||||
|
||||
if (size != preview_buf_size)
|
||||
{
|
||||
preview_src = g_realloc(preview_src,
|
||||
width * preview_height * sizeof(guchar *));
|
||||
preview_dst = g_realloc(preview_dst,
|
||||
width * sizeof(guchar));
|
||||
preview_sort = g_realloc(preview_sort,
|
||||
size * size * sizeof(guchar));
|
||||
}
|
||||
|
||||
gimp_pixel_rgn_get_rect(&src_rgn, preview_src, preview_x1, preview_y1,
|
||||
preview_width, preview_height);
|
||||
|
||||
|
@ -919,11 +955,11 @@ preview_update(void)
|
|||
* Now find the median pixels and save the results...
|
||||
*/
|
||||
|
||||
radius = despeckle_vals.radius;
|
||||
radius = despeckle_radius;
|
||||
|
||||
if (y < radius || y >= (preview_height - radius))
|
||||
memcpy(preview_dst, preview_src + y * width, width);
|
||||
else
|
||||
memcpy(preview_dst, preview_src + y * width, width);
|
||||
|
||||
if (y >= radius && y < (preview_height - radius))
|
||||
{
|
||||
for (x = 0, dst_ptr = preview_dst; x < width; x ++, dst_ptr ++)
|
||||
{
|
||||
|
@ -942,12 +978,15 @@ preview_update(void)
|
|||
src_ptr = preview_src + width * (y - radius);
|
||||
i <= radius;
|
||||
i ++, src_ptr += width)
|
||||
for (tx = xmin; tx < xmax; tx += img_bpp, sort_ptr ++)
|
||||
for (tx = xmin; tx < xmax; tx += img_bpp)
|
||||
{
|
||||
if ((*sort_ptr = src_ptr[tx]) == 0)
|
||||
if ((*sort_ptr = src_ptr[tx]) <= black_level)
|
||||
hist0 ++;
|
||||
else if (*sort_ptr == 255)
|
||||
else if (*sort_ptr >= white_level)
|
||||
hist255 ++;
|
||||
|
||||
if (*sort_ptr < white_level)
|
||||
sort_ptr ++;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -956,45 +995,48 @@ preview_update(void)
|
|||
|
||||
sort_count = sort_ptr - preview_sort;
|
||||
|
||||
for (d = sort_count / 2; d > 0; d = d / 2)
|
||||
for (i = d; i < sort_count; i ++)
|
||||
for (j = i - d, sort_ptr = preview_sort + j;
|
||||
j >= 0 && sort_ptr[0] > sort_ptr[d];
|
||||
j -= d, sort_ptr -= d)
|
||||
{
|
||||
t = sort_ptr[0];
|
||||
sort_ptr[0] = sort_ptr[d];
|
||||
sort_ptr[d] = t;
|
||||
};
|
||||
if (sort_count > 1)
|
||||
{
|
||||
for (d = sort_count / 2; d > 0; d = d / 2)
|
||||
for (i = d; i < sort_count; i ++)
|
||||
for (j = i - d, sort_ptr = preview_sort + j;
|
||||
j >= 0 && sort_ptr[0] > sort_ptr[d];
|
||||
j -= d, sort_ptr -= d)
|
||||
{
|
||||
t = sort_ptr[0];
|
||||
sort_ptr[0] = sort_ptr[d];
|
||||
sort_ptr[d] = t;
|
||||
};
|
||||
|
||||
/*
|
||||
* Assign the median value...
|
||||
*/
|
||||
/*
|
||||
* Assign the median value...
|
||||
*/
|
||||
|
||||
t = sort_count / 2;
|
||||
t = sort_count / 2;
|
||||
|
||||
if (sort_count & 1)
|
||||
*dst_ptr = (preview_sort[t] + preview_sort[t + 1]) / 2;
|
||||
else
|
||||
*dst_ptr = preview_sort[t];
|
||||
if (sort_count & 1)
|
||||
*dst_ptr = (preview_sort[t] + preview_sort[t + 1]) / 2;
|
||||
else
|
||||
*dst_ptr = preview_sort[t];
|
||||
|
||||
/*
|
||||
* Save the change to the source image too if the user wants the
|
||||
* recursive method...
|
||||
*/
|
||||
/*
|
||||
* Save the change to the source image too if the user wants the
|
||||
* recursive method...
|
||||
*/
|
||||
|
||||
if (despeckle_vals.filter_type & FILTER_RECURSIVE)
|
||||
preview_src[y * width + x] = *dst_ptr;
|
||||
if (filter_type & FILTER_RECURSIVE)
|
||||
preview_src[y * width + x] = *dst_ptr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Check the histogram and adjust the radius accordingly...
|
||||
*/
|
||||
|
||||
if (despeckle_vals.filter_type & FILTER_ADAPTIVE)
|
||||
if (filter_type & FILTER_ADAPTIVE)
|
||||
{
|
||||
if (hist0 >= radius || hist255 >= radius)
|
||||
{
|
||||
if (radius < despeckle_vals.radius)
|
||||
if (radius < despeckle_radius)
|
||||
radius ++;
|
||||
}
|
||||
else if (radius > 1)
|
||||
|
@ -1051,7 +1093,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;
|
||||
|
@ -1148,6 +1191,9 @@ dialog_iscale_update(GtkAdjustment *adjustment, /* I - New value */
|
|||
gtk_entry_set_text(GTK_ENTRY(entry), buf);
|
||||
gtk_signal_handler_unblock_by_data(GTK_OBJECT(entry), value);
|
||||
|
||||
if (value == &despeckle_radius)
|
||||
preview_init();
|
||||
|
||||
preview_update();
|
||||
};
|
||||
}
|
||||
|
@ -1179,6 +1225,9 @@ dialog_ientry_update(GtkWidget *widget, /* I - Entry widget */
|
|||
|
||||
gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
|
||||
|
||||
if (value == &despeckle_radius)
|
||||
preview_init();
|
||||
|
||||
preview_update();
|
||||
};
|
||||
};
|
||||
|
@ -1194,9 +1243,9 @@ dialog_adaptive_callback(GtkWidget *widget, /* I - Toggle button */
|
|||
gpointer data) /* I - Data */
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
despeckle_vals.filter_type |= FILTER_ADAPTIVE;
|
||||
filter_type |= FILTER_ADAPTIVE;
|
||||
else
|
||||
despeckle_vals.filter_type &= ~FILTER_ADAPTIVE;
|
||||
filter_type &= ~FILTER_ADAPTIVE;
|
||||
|
||||
preview_update();
|
||||
}
|
||||
|
@ -1211,9 +1260,9 @@ dialog_recursive_callback(GtkWidget *widget, /* I - Toggle button */
|
|||
gpointer data) /* I - Data */
|
||||
{
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
despeckle_vals.filter_type |= FILTER_RECURSIVE;
|
||||
filter_type |= FILTER_RECURSIVE;
|
||||
else
|
||||
despeckle_vals.filter_type &= ~FILTER_RECURSIVE;
|
||||
filter_type &= ~FILTER_RECURSIVE;
|
||||
|
||||
preview_update();
|
||||
}
|
||||
|
|
|
@ -1,36 +1,25 @@
|
|||
CFLAGS=-D_GIMP
|
||||
CFLAGS=-D_GIMP -Wall -O3
|
||||
CC = gcc
|
||||
|
||||
OBJECTS=mathmap.o builtins.o exprtree.o parser.o scanner.o postfix.o
|
||||
OBJECTS=mathmap.o builtins.o exprtree.o parser.o scanner.o postfix.o vars.o
|
||||
|
||||
mathmap : $(OBJECTS)
|
||||
gcc -o mathmap -lglib -lgdk -lgtk -lgimp -lm $(OBJECTS)
|
||||
$(CC) -o mathmap -lglib -lgdk -lgtk -lgimp -lm $(OBJECTS)
|
||||
|
||||
mathmap.o : mathmap.c
|
||||
gcc $(CFLAGS) -c mathmap.c
|
||||
%.o : %.c
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
|
||||
builtins.o : builtins.c
|
||||
gcc $(CFLAGS) -c builtins.c
|
||||
|
||||
exprtree.o : exprtree.c
|
||||
gcc $(CFLAGS) -c exprtree.c
|
||||
|
||||
postfix.o : postfix.c
|
||||
gcc $(CFLAGS) -c postfix.c
|
||||
|
||||
parser.o : parser.tab.c
|
||||
gcc $(CFLAGS) -c -o parser.o parser.tab.c
|
||||
|
||||
scanner.o : lex.yy.c
|
||||
gcc $(CFLAGS) -c -o scanner.o lex.yy.c
|
||||
|
||||
parser.tab.c : parser.y
|
||||
parser.c : parser.y
|
||||
bison -d parser.y
|
||||
mv parser.tab.c parser.c
|
||||
mv parser.tab.h parser.h
|
||||
|
||||
lex.yy.c : scanner.fl
|
||||
scanner.c : scanner.fl
|
||||
flex scanner.fl
|
||||
mv lex.yy.c scanner.c
|
||||
|
||||
install : mathmap
|
||||
cp mathmap $(HOME)/.gimp/plug-ins/
|
||||
|
||||
clean :
|
||||
rm -f *~ *.o mathmap lex.yy.c parser.tab.[ch]
|
||||
rm -f *~ *.o mathmap scanner.c parser.[ch]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <math.h>
|
||||
#include <string.h>
|
||||
#ifdef _GIMP
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
|
@ -8,53 +9,81 @@
|
|||
#include "builtins.h"
|
||||
|
||||
extern int imageWidth,
|
||||
imageHeight;
|
||||
imageHeight,
|
||||
inputBPP;
|
||||
extern double middleX,
|
||||
middleY;
|
||||
extern unsigned char *imageData;
|
||||
extern double stack[];
|
||||
extern int stackp;
|
||||
extern int intersamplingEnabled,
|
||||
oversamplingEnabled;
|
||||
|
||||
builtin *firstBuiltin = 0;
|
||||
|
||||
double
|
||||
color_to_double (int red, int green, int blue)
|
||||
color_to_double (unsigned int red, unsigned int green, unsigned int blue, unsigned int alpha)
|
||||
{
|
||||
double val;
|
||||
|
||||
*(int*)&val = (red << 16) | (green << 8) | blue;
|
||||
*(unsigned int*)&val = (alpha << 24) | (red << 16) | (green << 8) | blue;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
double_to_color (double val, int *red, int *green, int *blue)
|
||||
double
|
||||
pixel_to_double (unsigned char *pixel)
|
||||
{
|
||||
int color = *(int*)&val;
|
||||
if (inputBPP == 1)
|
||||
return color_to_double(pixel[0], pixel[0], pixel[0], 255);
|
||||
else if (inputBPP == 2)
|
||||
return color_to_double(pixel[0], pixel[0], pixel[0], pixel[1]);
|
||||
else if (inputBPP == 3)
|
||||
return color_to_double(pixel[0], pixel[1], pixel[2], 255);
|
||||
else
|
||||
return color_to_double(pixel[0], pixel[1], pixel[2], pixel[3]);
|
||||
}
|
||||
|
||||
*red = color >> 16;
|
||||
void
|
||||
double_to_color (double val, unsigned int *red, unsigned int *green,
|
||||
unsigned int *blue, unsigned int *alpha)
|
||||
{
|
||||
unsigned int color = *(unsigned int*)&val;
|
||||
|
||||
*alpha = color >> 24;
|
||||
*red = (color >> 16) & 0xff;
|
||||
*green = (color >> 8) & 0xff;
|
||||
*blue = color & 0xff;
|
||||
}
|
||||
|
||||
int
|
||||
red_component (double val)
|
||||
unsigned int
|
||||
alpha_component (double val)
|
||||
{
|
||||
int color = *(int*)&val;
|
||||
unsigned int color = *(unsigned int*)&val;
|
||||
|
||||
return color >> 16;
|
||||
return color >> 24;
|
||||
}
|
||||
|
||||
int
|
||||
unsigned int
|
||||
red_component (double val)
|
||||
{
|
||||
unsigned int color = *(unsigned int*)&val;
|
||||
|
||||
return (color >> 16) & 0xff;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
green_component (double val)
|
||||
{
|
||||
int color = *(int*)&val;
|
||||
unsigned int color = *(unsigned int*)&val;
|
||||
|
||||
return (color >> 8) & 0xff;
|
||||
}
|
||||
|
||||
int
|
||||
unsigned int
|
||||
blue_component (double val)
|
||||
{
|
||||
int color = *(int*)&val;
|
||||
unsigned int color = *(unsigned int*)&val;
|
||||
|
||||
return color & 0xff;
|
||||
}
|
||||
|
@ -95,12 +124,25 @@ builtin_atan (void *arg)
|
|||
stack[stackp - 1] = atan(stack[stackp - 1]) * 180.0 / M_PI;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_pow (void *arg)
|
||||
{
|
||||
stack[stackp - 2] = pow(stack[stackp - 2], stack[stackp - 1]);
|
||||
--stackp;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_abs (void *arg)
|
||||
{
|
||||
stack[stackp - 1] = fabs(stack[stackp - 1]);
|
||||
}
|
||||
|
||||
void
|
||||
builtin_floor (void *arg)
|
||||
{
|
||||
stack[stackp - 1] = floor(stack[stackp - 1]);
|
||||
}
|
||||
|
||||
void
|
||||
builtin_sign (void *arg)
|
||||
{
|
||||
|
@ -128,6 +170,15 @@ builtin_max (void *arg)
|
|||
--stackp;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_not (void *arg)
|
||||
{
|
||||
if (stack[stackp - 1] != 0.0)
|
||||
stack[stackp - 1] = 0.0;
|
||||
else
|
||||
stack[stackp - 1] = 1.0;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_or (void *arg)
|
||||
{
|
||||
|
@ -148,6 +199,16 @@ builtin_and (void *arg)
|
|||
--stackp;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_equal (void *arg)
|
||||
{
|
||||
if (stack[stackp - 2] == stack[stackp - 1])
|
||||
stack[stackp - 2] = 1.0;
|
||||
else
|
||||
stack[stackp - 2] = 0.0;
|
||||
--stackp;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_less (void *arg)
|
||||
{
|
||||
|
@ -158,6 +219,46 @@ builtin_less (void *arg)
|
|||
--stackp;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_greater (void *arg)
|
||||
{
|
||||
if (stack[stackp - 2] > stack[stackp - 1])
|
||||
stack[stackp - 2] = 1.0;
|
||||
else
|
||||
stack[stackp - 2] = 0.0;
|
||||
--stackp;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_lessequal (void *arg)
|
||||
{
|
||||
if (stack[stackp - 2] <= stack[stackp - 1])
|
||||
stack[stackp - 2] = 1.0;
|
||||
else
|
||||
stack[stackp - 2] = 0.0;
|
||||
--stackp;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_greaterequal (void *arg)
|
||||
{
|
||||
if (stack[stackp - 2] >= stack[stackp - 1])
|
||||
stack[stackp - 2] = 1.0;
|
||||
else
|
||||
stack[stackp - 2] = 0.0;
|
||||
--stackp;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_notequal (void *arg)
|
||||
{
|
||||
if (stack[stackp - 2] != stack[stackp - 1])
|
||||
stack[stackp - 2] = 1.0;
|
||||
else
|
||||
stack[stackp - 2] = 0.0;
|
||||
--stackp;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_inintv (void *arg)
|
||||
{
|
||||
|
@ -188,13 +289,19 @@ extern int originX,
|
|||
void
|
||||
builtin_origValXY (void *arg)
|
||||
{
|
||||
int x = stack[stackp - 2],
|
||||
double x = stack[stackp - 2],
|
||||
y = stack[stackp - 1];
|
||||
unsigned char pixel[4];
|
||||
|
||||
mathmap_get_pixel(x + originX + middleX, y + originY + middleY, pixel);
|
||||
if (!oversamplingEnabled)
|
||||
{
|
||||
x += 0.5;
|
||||
y += 0.5;
|
||||
}
|
||||
|
||||
stack[stackp - 2] = color_to_double(pixel[0], pixel[1], pixel[2]);
|
||||
mathmap_get_pixel(floor(x + originX + middleX), floor(y + originY + middleY), pixel);
|
||||
|
||||
stack[stackp - 2] = pixel_to_double(pixel);
|
||||
--stackp;
|
||||
}
|
||||
|
||||
|
@ -219,14 +326,13 @@ builtin_origValXYIntersample (void *arg)
|
|||
unsigned char pixel1a[4],
|
||||
pixel2a[4],
|
||||
pixel3a[4],
|
||||
pixel4a[4];
|
||||
pixel4a[4],
|
||||
resultPixel[4];
|
||||
unsigned char *pixel1 = pixel1a,
|
||||
*pixel2 = pixel2a,
|
||||
*pixel3 = pixel3a,
|
||||
*pixel4 = pixel4a;
|
||||
int red,
|
||||
green,
|
||||
blue;
|
||||
int i;
|
||||
|
||||
if (x1 < 0 || x1 >= wholeImageWidth || y1 < 0 || y1 >= wholeImageHeight)
|
||||
pixel1 = blackPixel;
|
||||
|
@ -248,24 +354,32 @@ builtin_origValXYIntersample (void *arg)
|
|||
else
|
||||
mathmap_get_pixel(x2, y2, pixel4);
|
||||
|
||||
red = pixel1[0] * p1fact + pixel2[0] * p2fact + pixel3[0] * p3fact + pixel4[0] * p4fact;
|
||||
green = pixel1[1] * p1fact + pixel2[1] * p2fact + pixel3[1] * p3fact + pixel4[1] * p4fact;
|
||||
blue = pixel1[2] * p1fact + pixel2[2] * p2fact + pixel3[2] * p3fact + pixel4[2] * p4fact;
|
||||
for (i = 0; i < inputBPP; ++i)
|
||||
resultPixel[i] = pixel1[i] * p1fact
|
||||
+ pixel2[i] * p2fact
|
||||
+ pixel3[i] * p3fact
|
||||
+ pixel4[i] * p4fact;
|
||||
|
||||
stack[stackp - 2] = color_to_double(red, green, blue);
|
||||
stack[stackp - 2] = pixel_to_double(resultPixel);
|
||||
--stackp;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_origValRA (void *arg)
|
||||
{
|
||||
int x = cos(stack[stackp - 1] * M_PI / 180) * stack[stackp - 2] + middleX,
|
||||
double x = cos(stack[stackp - 1] * M_PI / 180) * stack[stackp - 2] + middleX,
|
||||
y = sin(stack[stackp - 1] * M_PI / 180) * stack[stackp - 2] + middleY;
|
||||
unsigned char pixel[4];
|
||||
|
||||
if (!oversamplingEnabled)
|
||||
{
|
||||
x += 0.5;
|
||||
y += 0.5;
|
||||
}
|
||||
|
||||
mathmap_get_pixel(x + originX, y + originY, pixel);
|
||||
mathmap_get_pixel(floor(x + originX), floor(y + originY), pixel);
|
||||
|
||||
stack[stackp - 2] = color_to_double(pixel[0], pixel[1], pixel[2]);
|
||||
stack[stackp - 2] = pixel_to_double(pixel);
|
||||
--stackp;
|
||||
}
|
||||
|
||||
|
@ -290,14 +404,13 @@ builtin_origValRAIntersample (void *arg)
|
|||
unsigned char pixel1a[4],
|
||||
pixel2a[4],
|
||||
pixel3a[4],
|
||||
pixel4a[4];
|
||||
pixel4a[4],
|
||||
resultPixel[4];
|
||||
unsigned char *pixel1 = pixel1a,
|
||||
*pixel2 = pixel2a,
|
||||
*pixel3 = pixel3a,
|
||||
*pixel4 = pixel4a;
|
||||
int red,
|
||||
green,
|
||||
blue;
|
||||
int i;
|
||||
|
||||
if (x1 < 0 || x1 >= wholeImageWidth || y1 < 0 || y1 >= wholeImageHeight)
|
||||
pixel1 = blackPixel;
|
||||
|
@ -319,11 +432,13 @@ builtin_origValRAIntersample (void *arg)
|
|||
else
|
||||
mathmap_get_pixel(x2, y2, pixel4);
|
||||
|
||||
red = pixel1[0] * p1fact + pixel2[0] * p2fact + pixel3[0] * p3fact + pixel4[0] * p4fact;
|
||||
green = pixel1[1] * p1fact + pixel2[1] * p2fact + pixel3[1] * p3fact + pixel4[1] * p4fact;
|
||||
blue = pixel1[2] * p1fact + pixel2[2] * p2fact + pixel3[2] * p3fact + pixel4[2] * p4fact;
|
||||
for (i = 0; i < inputBPP; ++i)
|
||||
resultPixel[i] = pixel1[i] * p1fact
|
||||
+ pixel2[i] * p2fact
|
||||
+ pixel3[i] * p3fact
|
||||
+ pixel4[i] * p4fact;
|
||||
|
||||
stack[stackp - 2] = color_to_double(red, green, blue);
|
||||
stack[stackp - 2] = pixel_to_double(resultPixel);
|
||||
--stackp;
|
||||
}
|
||||
|
||||
|
@ -497,6 +612,24 @@ builtin_blue (void *arg)
|
|||
stack[stackp - 1] = blue_component(stack[stackp - 1]) / 255.0;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_gray (void *arg)
|
||||
{
|
||||
int red,
|
||||
green,
|
||||
blue,
|
||||
alpha;
|
||||
|
||||
double_to_color(stack[stackp - 1], &red, &green, &blue, &alpha);
|
||||
stack[stackp - 1] = (0.299 * red + 0.587 * green + 0.114 * blue) / 255.0;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_alpha (void *arg)
|
||||
{
|
||||
stack[stackp - 1] = alpha_component(stack[stackp - 1]) / 255.0;
|
||||
}
|
||||
|
||||
void
|
||||
builtin_rgbColor (void *arg)
|
||||
{
|
||||
|
@ -521,7 +654,41 @@ builtin_rgbColor (void *arg)
|
|||
else if (blueComponent > 255)
|
||||
blueComponent = 255;
|
||||
|
||||
stack[stackp - 1] = color_to_double(redComponent, greenComponent, blueComponent);
|
||||
stack[stackp - 1] = color_to_double(redComponent, greenComponent, blueComponent, 255);
|
||||
}
|
||||
|
||||
void
|
||||
builtin_rgbaColor (void *arg)
|
||||
{
|
||||
int redComponent = stack[stackp - 4] * 255,
|
||||
greenComponent = stack[stackp - 3] * 255,
|
||||
blueComponent = stack[stackp - 2] * 255,
|
||||
alphaComponent = stack[stackp - 1] * 255;
|
||||
|
||||
stackp -= 3;
|
||||
|
||||
if (redComponent < 0)
|
||||
redComponent = 0;
|
||||
else if (redComponent > 255)
|
||||
redComponent = 255;
|
||||
|
||||
if (greenComponent < 0)
|
||||
greenComponent = 0;
|
||||
else if (greenComponent > 255)
|
||||
greenComponent = 255;
|
||||
|
||||
if (blueComponent < 0)
|
||||
blueComponent = 0;
|
||||
else if (blueComponent > 255)
|
||||
blueComponent = 255;
|
||||
|
||||
if (alphaComponent < 0)
|
||||
alphaComponent = 0;
|
||||
else if (alphaComponent > 255)
|
||||
alphaComponent = 255;
|
||||
|
||||
stack[stackp - 1] = color_to_double(redComponent, greenComponent,
|
||||
blueComponent, alphaComponent);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -534,5 +701,101 @@ builtin_grayColor (void *arg)
|
|||
else if (grayLevel > 255)
|
||||
grayLevel = 255;
|
||||
|
||||
stack[stackp - 1] = color_to_double(grayLevel, grayLevel, grayLevel);
|
||||
stack[stackp - 1] = color_to_double(grayLevel, grayLevel, grayLevel, 255);
|
||||
}
|
||||
|
||||
void
|
||||
builtin_grayaColor (void *arg)
|
||||
{
|
||||
int grayLevel = stack[stackp - 2] * 255,
|
||||
alphaComponent = stack[stackp - 1] * 255;
|
||||
|
||||
--stackp;
|
||||
|
||||
if (grayLevel < 0)
|
||||
grayLevel = 0;
|
||||
else if (grayLevel > 255)
|
||||
grayLevel = 255;
|
||||
|
||||
if (alphaComponent < 0)
|
||||
alphaComponent = 0;
|
||||
else if (alphaComponent > 255)
|
||||
alphaComponent = 255;
|
||||
|
||||
stack[stackp - 1] = color_to_double(grayLevel, grayLevel, grayLevel, alphaComponent);
|
||||
}
|
||||
|
||||
builtin*
|
||||
builtin_with_name (const char *name)
|
||||
{
|
||||
builtin *next;
|
||||
|
||||
if (intersamplingEnabled)
|
||||
{
|
||||
if (strcmp(name, "origValXY") == 0)
|
||||
return builtin_with_name("origValXYIntersample");
|
||||
else if (strcmp(name, "origValRA") == 0)
|
||||
return builtin_with_name("origValRAIntersample");
|
||||
}
|
||||
|
||||
for (next = firstBuiltin; next != 0; next = next->next)
|
||||
if (strcmp(name, next->name) == 0)
|
||||
return next;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
register_builtin (const char *name, builtinFunction function, int numParams)
|
||||
{
|
||||
builtin *theBuiltin = (builtin*)malloc(sizeof(builtin));
|
||||
|
||||
strncpy(theBuiltin->name, name, MAX_BUILTIN_LENGTH);
|
||||
theBuiltin->name[MAX_BUILTIN_LENGTH] = '\0';
|
||||
theBuiltin->function = function;
|
||||
theBuiltin->numParams = numParams;
|
||||
theBuiltin->next = firstBuiltin;
|
||||
|
||||
firstBuiltin = theBuiltin;
|
||||
}
|
||||
|
||||
void
|
||||
init_builtins (void)
|
||||
{
|
||||
register_builtin("sin", builtin_sin, 1);
|
||||
register_builtin("cos", builtin_cos, 1);
|
||||
register_builtin("tan", builtin_tan, 1);
|
||||
register_builtin("asin", builtin_asin, 1);
|
||||
register_builtin("acos", builtin_acos, 1);
|
||||
register_builtin("atan", builtin_atan, 1);
|
||||
register_builtin("pow", builtin_pow, 2);
|
||||
register_builtin("abs", builtin_abs, 1);
|
||||
register_builtin("floor", builtin_floor, 1);
|
||||
register_builtin("sign", builtin_sign, 1);
|
||||
register_builtin("min", builtin_min, 2);
|
||||
register_builtin("max", builtin_max, 2);
|
||||
register_builtin("not", builtin_not, 1);
|
||||
register_builtin("or", builtin_or, 2);
|
||||
register_builtin("and", builtin_and, 2);
|
||||
register_builtin("equal", builtin_equal, 2);
|
||||
register_builtin("less", builtin_less, 2);
|
||||
register_builtin("greater", builtin_greater, 2);
|
||||
register_builtin("lessequal", builtin_lessequal, 2);
|
||||
register_builtin("greaterequal", builtin_greaterequal, 2);
|
||||
register_builtin("notequal", builtin_notequal, 2);
|
||||
register_builtin("inintv", builtin_inintv, 3);
|
||||
register_builtin("rand", builtin_rand, 2);
|
||||
register_builtin("origValXY", builtin_origValXY, 2);
|
||||
register_builtin("origValXYIntersample", builtin_origValXYIntersample, 2);
|
||||
register_builtin("origValRA", builtin_origValRA, 2);
|
||||
register_builtin("origValRAIntersample", builtin_origValRAIntersample, 2);
|
||||
register_builtin("red", builtin_red, 1);
|
||||
register_builtin("green", builtin_green, 1);
|
||||
register_builtin("blue", builtin_blue, 1);
|
||||
register_builtin("gray", builtin_gray, 1);
|
||||
register_builtin("alpha", builtin_alpha, 1);
|
||||
register_builtin("rgbColor", builtin_rgbColor, 3);
|
||||
register_builtin("rgbaColor", builtin_rgbaColor, 4);
|
||||
register_builtin("grayColor", builtin_grayColor, 1);
|
||||
register_builtin("grayaColor", builtin_grayaColor, 2);
|
||||
}
|
||||
|
|
|
@ -1,28 +1,27 @@
|
|||
/* -*- c -*- */
|
||||
|
||||
double color_to_double (int red, int green, int blue);
|
||||
void double_to_color (double val, int *red, int *green, int *blue);
|
||||
#ifndef __BUILTINS_H__
|
||||
#define __BUILTINS_H__
|
||||
|
||||
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);
|
||||
#define MAX_BUILTIN_LENGTH 63
|
||||
|
||||
typedef void (*builtinFunction) (void*);
|
||||
|
||||
typedef struct _builtin
|
||||
{
|
||||
char name[MAX_BUILTIN_LENGTH + 1];
|
||||
builtinFunction function;
|
||||
int numParams;
|
||||
struct _builtin *next;
|
||||
} builtin;
|
||||
|
||||
double color_to_double (unsigned int red, unsigned int green,
|
||||
unsigned int blue, unsigned int alpha);
|
||||
void double_to_color (double val, unsigned int *red, unsigned int *green,
|
||||
unsigned int *blue, unsigned int *alpha);
|
||||
|
||||
builtin* builtin_with_name (const char *name);
|
||||
|
||||
void init_builtins (void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,8 @@ make_var (char *name)
|
|||
tree->type = EXPR_VAR_X;
|
||||
else if (strcmp(name, "y") == 0)
|
||||
tree->type = EXPR_VAR_Y;
|
||||
else if (strcmp(name, "t") == 0)
|
||||
tree->type = EXPR_VAR_T;
|
||||
else if (strcmp(name, "r") == 0)
|
||||
{
|
||||
tree->type = EXPR_VAR_R;
|
||||
|
@ -81,137 +83,13 @@ make_operator (int type, exprtree *left, exprtree *right)
|
|||
}
|
||||
|
||||
exprtree*
|
||||
make_function (char *name, exprtree *args)
|
||||
make_function (builtin *theBuiltin, exprtree *args)
|
||||
{
|
||||
exprtree *tree = (exprtree*)malloc(sizeof(exprtree));
|
||||
|
||||
if (strcmp(name, "sin") == 0)
|
||||
{
|
||||
tree->val.func.routine = builtin_sin;
|
||||
tree->val.func.numArgs = 1;
|
||||
}
|
||||
else if (strcmp(name, "cos") == 0)
|
||||
{
|
||||
tree->val.func.routine = builtin_cos;
|
||||
tree->val.func.numArgs = 1;
|
||||
}
|
||||
else if (strcmp(name, "tan") == 0)
|
||||
{
|
||||
tree->val.func.routine = builtin_tan;
|
||||
tree->val.func.numArgs = 1;
|
||||
}
|
||||
else if (strcmp(name, "asin") == 0)
|
||||
{
|
||||
tree->val.func.routine = builtin_asin;
|
||||
tree->val.func.numArgs = 1;
|
||||
}
|
||||
else if (strcmp(name, "acos") == 0)
|
||||
{
|
||||
tree->val.func.routine = builtin_acos;
|
||||
tree->val.func.numArgs = 1;
|
||||
}
|
||||
else if (strcmp(name, "atan") == 0)
|
||||
{
|
||||
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;
|
||||
tree->val.func.numArgs = 1;
|
||||
}
|
||||
else if (strcmp(name, "min") == 0)
|
||||
{
|
||||
tree->val.func.routine = builtin_min;
|
||||
tree->val.func.numArgs = 2;
|
||||
}
|
||||
else if (strcmp(name, "max") == 0)
|
||||
{
|
||||
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;
|
||||
tree->val.func.numArgs = 3;
|
||||
}
|
||||
else if (strcmp(name, "rand") == 0)
|
||||
{
|
||||
tree->val.func.routine = builtin_rand;
|
||||
tree->val.func.numArgs = 2;
|
||||
}
|
||||
else if (strcmp(name, "origValXY") == 0)
|
||||
{
|
||||
if (intersamplingEnabled)
|
||||
tree->val.func.routine = builtin_origValXYIntersample;
|
||||
else
|
||||
tree->val.func.routine = builtin_origValXY;
|
||||
tree->val.func.numArgs = 2;
|
||||
}
|
||||
else if (strcmp(name, "origValRA") == 0)
|
||||
{
|
||||
if (intersamplingEnabled)
|
||||
tree->val.func.routine = builtin_origValRAIntersample;
|
||||
else
|
||||
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;
|
||||
tree->val.func.numArgs = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tree->type = EXPR_NUMBER;
|
||||
tree->val.number = 0.0;
|
||||
|
||||
tree->next = 0;
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
tree->type = EXPR_FUNC;
|
||||
tree->val.func.routine = theBuiltin->function;
|
||||
tree->val.func.numArgs = theBuiltin->numParams;
|
||||
tree->val.func.args = args;
|
||||
|
||||
tree->next = 0;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define __EXPRTREE_H__
|
||||
|
||||
#include "vars.h"
|
||||
#include "builtins.h"
|
||||
|
||||
#ifdef USE_TREE
|
||||
typedef double (*function) (double*);
|
||||
|
@ -9,7 +10,9 @@ typedef double (*function) (double*);
|
|||
typedef void (*function) (void*);
|
||||
#endif
|
||||
|
||||
typedef char ident[64];
|
||||
#define MAX_IDENT_LENGTH 63
|
||||
|
||||
typedef char ident[MAX_IDENT_LENGTH + 1];
|
||||
|
||||
typedef struct _exprtree
|
||||
{
|
||||
|
@ -55,35 +58,36 @@ typedef struct _exprtree
|
|||
struct _exprtree *next;
|
||||
} exprtree;
|
||||
|
||||
#define EXPR_NUMBER 1
|
||||
#define EXPR_ADD 2
|
||||
#define EXPR_SUB 3
|
||||
#define EXPR_MUL 4
|
||||
#define EXPR_DIV 5
|
||||
#define EXPR_MOD 6
|
||||
#define EXPR_NEG 7
|
||||
#define EXPR_FUNC 8
|
||||
#define EXPR_VAR_X 9
|
||||
#define EXPR_VAR_Y 10
|
||||
#define EXPR_VAR_R 11
|
||||
#define EXPR_VAR_A 12
|
||||
#define EXPR_VAR_W 13
|
||||
#define EXPR_VAR_H 14
|
||||
#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
|
||||
#define EXPR_NUMBER 1
|
||||
#define EXPR_ADD 2
|
||||
#define EXPR_SUB 3
|
||||
#define EXPR_MUL 4
|
||||
#define EXPR_DIV 5
|
||||
#define EXPR_MOD 6
|
||||
#define EXPR_NEG 7
|
||||
#define EXPR_FUNC 8
|
||||
#define EXPR_VAR_X 9
|
||||
#define EXPR_VAR_Y 10
|
||||
#define EXPR_VAR_T 11
|
||||
#define EXPR_VAR_R 12
|
||||
#define EXPR_VAR_A 13
|
||||
#define EXPR_VAR_W 14
|
||||
#define EXPR_VAR_H 15
|
||||
#define EXPR_VAR_BIG_R 16
|
||||
#define EXPR_VAR_BIG_X 17
|
||||
#define EXPR_VAR_BIG_Y 18
|
||||
#define EXPR_SEQUENCE 19
|
||||
#define EXPR_ASSIGNMENT 20
|
||||
#define EXPR_VARIABLE 21
|
||||
#define EXPR_IF_THEN 22
|
||||
#define EXPR_IF_THEN_ELSE 23
|
||||
#define EXPR_WHILE 24
|
||||
#define EXPR_DO_WHILE 25
|
||||
|
||||
exprtree* make_number (double num);
|
||||
exprtree* make_var (char *name);
|
||||
exprtree* make_operator (int type, exprtree *left, exprtree *right);
|
||||
exprtree* make_function (char *name, exprtree *args);
|
||||
exprtree* make_function (builtin *theBuiltin, exprtree *args);
|
||||
exprtree* make_sequence (exprtree *left, exprtree *right);
|
||||
exprtree* make_assignment (char *name, exprtree *value);
|
||||
exprtree* make_if_then (exprtree *condition, exprtree *conclusion);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* Copyright (C) 1997 Federico Mena Quintero
|
||||
* federico@nuclecu.unam.mx
|
||||
*
|
||||
* Version 0.2
|
||||
* Version 0.4
|
||||
*
|
||||
* 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
|
||||
|
@ -32,6 +32,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <libgimp/gimp.h>
|
||||
|
@ -54,17 +55,20 @@
|
|||
#define ENTRY_WIDTH 60
|
||||
|
||||
#define DEFAULT_EXPRESSION "origValXY(x+sin(y*10)*3,y+sin(x*10)*3)"
|
||||
#define DEFAULT_NUMBER_FRAMES 10
|
||||
|
||||
#define FLAG_INTERSAMPLING 1
|
||||
#define FLAG_OVERSAMPLING 2
|
||||
#define FLAG_ANIMATION 4
|
||||
|
||||
#define MAX_EXPRESSION_LENGTH 1024
|
||||
#define MAX_EXPRESSION_LENGTH 8192
|
||||
|
||||
/***** Types *****/
|
||||
|
||||
typedef struct {
|
||||
gchar expression[MAX_EXPRESSION_LENGTH];
|
||||
gint flags;
|
||||
gint frames;
|
||||
} mathmap_vals_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -89,17 +93,23 @@ static void expression_copy (gchar *dest, gchar *src);
|
|||
|
||||
static void mathmap (void);
|
||||
void mathmap_get_pixel(int x, int y, guchar *pixel);
|
||||
static gint32 mathmap_layer_copy(gint32 layerID);
|
||||
|
||||
extern int yyparse (void);
|
||||
|
||||
static void build_preview_source_image(void);
|
||||
|
||||
static gint mathmap_dialog(void);
|
||||
static void dialog_update_preview(void);
|
||||
/*
|
||||
static void dialog_create_value(char *title, GtkTable *table, int row, gdouble *value,
|
||||
double left, double right);
|
||||
static void dialog_scale_update(GtkAdjustment *adjustment, gdouble *value);
|
||||
static void dialog_entry_update(GtkWidget *widget, gdouble *value);
|
||||
*/
|
||||
static void dialog_scale_update(GtkAdjustment *adjustment, gint *value);
|
||||
static void dialog_entry_update(GtkWidget *widget, gpointer value);
|
||||
static void dialog_intersampling_update (GtkWidget *widget, gpointer data);
|
||||
static void dialog_oversampling_update (GtkWidget *widget, gpointer data);
|
||||
static void dialog_animation_update (GtkWidget *widget, gpointer data);
|
||||
static void dialog_preview_callback (GtkWidget *widget, gpointer data);
|
||||
static void dialog_example_callback (GtkWidget *widget, char *expression);
|
||||
static void dialog_close_callback(GtkWidget *widget, gpointer data);
|
||||
|
@ -118,7 +128,8 @@ GPlugInInfo PLUG_IN_INFO = {
|
|||
|
||||
static mathmap_vals_t mmvals = {
|
||||
DEFAULT_EXPRESSION, /* expression */
|
||||
FLAG_INTERSAMPLING /* flags */
|
||||
FLAG_INTERSAMPLING, /* flags */
|
||||
DEFAULT_NUMBER_FRAMES /* frames */
|
||||
}; /* mmvals */
|
||||
|
||||
static mathmap_interface_t wint = {
|
||||
|
@ -128,10 +139,13 @@ static mathmap_interface_t wint = {
|
|||
FALSE /* run */
|
||||
}; /* wint */
|
||||
|
||||
static GDrawable *drawable;
|
||||
static gint32 image_id;
|
||||
static gint32 layer_id;
|
||||
static GDrawable *input_drawable;
|
||||
static GDrawable *output_drawable;
|
||||
|
||||
static gint tile_width, tile_height;
|
||||
static gint img_width, img_height, img_bpp;
|
||||
static gint img_width, img_height;
|
||||
static gint sel_x1, sel_y1, sel_x2, sel_y2;
|
||||
static gint sel_width, sel_height;
|
||||
static gint preview_width, preview_height;
|
||||
|
@ -141,7 +155,8 @@ static double cen_x, cen_y;
|
|||
static double scale_x, scale_y;
|
||||
static double radius, radius2;
|
||||
|
||||
GtkWidget *expressionEntry = 0;
|
||||
GtkWidget *expression_entry = 0,
|
||||
*animate_table;
|
||||
|
||||
exprtree *theExprtree = 0;
|
||||
int imageWidth,
|
||||
|
@ -149,43 +164,54 @@ int imageWidth,
|
|||
wholeImageWidth,
|
||||
wholeImageHeight,
|
||||
originX,
|
||||
originY;
|
||||
originY,
|
||||
inputBPP,
|
||||
outputBPP;
|
||||
int usesRA = 0;
|
||||
double currentX,
|
||||
currentY,
|
||||
currentR,
|
||||
currentA,
|
||||
currentT,
|
||||
imageR,
|
||||
imageX,
|
||||
imageY,
|
||||
middleX,
|
||||
middleY;
|
||||
int intersamplingEnabled,
|
||||
oversamplingEnabled;
|
||||
oversamplingEnabled,
|
||||
animationEnabled = 1;
|
||||
|
||||
char *examples[][2] = {
|
||||
{ "wave", "origValXY(x+sin(y*10)*3,y+sin(x*10)*3)" },
|
||||
{ "wave", "origValXY(x+sin(y*10+t*360)*3,y+sin(x*10+t*360)*3)" },
|
||||
{ "square", "origValXY(sign(x)*x*x/50,sign(y)*y*y/50)" },
|
||||
{ "mosaic", "origValXY(x-x%5,y-y%5)" },
|
||||
{ "slice", "origValXY(x+5*sign(cos(9*y)),y+5*sign(cos(9*x)))" },
|
||||
{ "mercator", "origValXY(x*cos(90/Y*y),y)" },
|
||||
{ "pond", "origValRA(r+sin(r*30)*3,a)" },
|
||||
{ "enhanced pond", "origValRA(r+(sin(500000/(r+100))*7),a)" },
|
||||
{ "slice", "q=t*360;origValXY(x+5*sign(cos(9*y+q)),y+5*sign(cos(9*x+q)))" },
|
||||
{ "mercator", "origValXY(x*cos(90/Y*y+t*360),y)" },
|
||||
{ "pond", "origValRA(r+sin(r*20+t*360)*3,a)" },
|
||||
{ "enhanced pond", "origValRA(r+(sin(500000/(r+100)+t*360)*7),a)" },
|
||||
{ "sea 1", "origValXY(x+10*sin(t*360+2000*Y*pow(y+Y+60,-1)),y)" },
|
||||
{ "sea 2", "origValXY(x,y+5*sin(t*360+2000*Y*pow(y+Y+60,-1)))" },
|
||||
{ "sea 3", "s=sin(t*360+2000*Y*pow(y+Y+60,-1));origValXY(x+10*s,y+5*s)" },
|
||||
{ "twirl 90", "origValRA(r,a+(r/R-1)*45)" },
|
||||
{ "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)" },
|
||||
{ "jitter", "origValRA(r,a+(a+t*8)%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)" },
|
||||
{ "circular slice", "origValRA(r,a+(r+t*6)%6-3)" },
|
||||
{ "fisheye", "origValRA(pow(r,2-t)/pow(R,1-t),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))" },
|
||||
{ "spiral", "p=origValXY(x,y);q=sin((r-a*0.1)*10+t*360)*0.5+0.5;rgbColor(q*red(p),q*green(p),q*blue(p))" },
|
||||
{ "alpha spiral", "p=origValXY(x,y);rgbaColor(red(p),green(p),blue(p),sin((r-a*0.1)*10+t*360)*0.5+0.5)" },
|
||||
{ "scatter", "origValXY(x+rand(-3,3),y+rand(-3,3))" },
|
||||
{ "desaturate", "p=origValXY(x,y);grayaColor(gray(p),alpha(p))" },
|
||||
{ "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" },
|
||||
{ "tile", "origValXY((x+X)*2%W-X,(y+Y)*2%H-Y)" },
|
||||
{ "?", "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) 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)" },
|
||||
{ "moire1", "q=t*360;rgbColor(abs(sin(15*r+q)+sin(15*a+q))*0.5,abs(sin(17*r+q)+sin(17*a+q))*0.5,abs(sin(19*r+q)+sin(19*a+q))*0.5)" },
|
||||
{ "moire2", "grayColor(sin(x*y+t*360)*0.5+0.5)" },
|
||||
{ "mandelbrot",
|
||||
"tx=1.5*x/X-0.5; "
|
||||
"ty=1.5*y/X-0; "
|
||||
|
@ -194,7 +220,7 @@ char *examples[][2] = {
|
|||
"xi=0; "
|
||||
"xrsq=0; "
|
||||
"xisq=0; "
|
||||
"while and(less(xrsq+xisq,4),less(iter,31)) "
|
||||
"while xrsq+xisq<4 && iter<31 "
|
||||
"do "
|
||||
"xrsq=xr*xr; "
|
||||
"xisq=xi*xi; "
|
||||
|
@ -234,7 +260,8 @@ query(void)
|
|||
{ PARAM_IMAGE, "image", "Input image" },
|
||||
{ PARAM_DRAWABLE, "drawable", "Input drawable" },
|
||||
{ PARAM_STRING, "expression", "MathMap expression" },
|
||||
{ PARAM_INT32, "flags", "1: Intersampling 2: Oversampling" }
|
||||
{ PARAM_INT32, "flags", "1: Intersampling 2: Oversampling 4: Animate" },
|
||||
{ PARAM_INT32, "frames", "Number of Frames" }
|
||||
}; /* args */
|
||||
|
||||
static GParamDef *return_vals = NULL;
|
||||
|
@ -245,12 +272,12 @@ query(void)
|
|||
"Generate an image using a mathematical expression.",
|
||||
"Generates an image by means of a mathematical expression. The expression "
|
||||
"can also refer to the data of an original image. Thus, arbitrary "
|
||||
"distortions can be constructed.",
|
||||
"distortions can be constructed. Even animations can be generated.",
|
||||
"Mark Probst",
|
||||
"Mark Probst",
|
||||
"October 1997, 0.1",
|
||||
"<Image>/Filters/Generic/MathMap",
|
||||
"RGB",
|
||||
"January 1998, 0.4",
|
||||
"<Image>/Filters/Distorts/MathMap",
|
||||
"RGB*, GRAY*",
|
||||
PROC_PLUG_IN,
|
||||
nargs,
|
||||
nreturn_vals,
|
||||
|
@ -278,6 +305,9 @@ run(char *name,
|
|||
status = STATUS_SUCCESS;
|
||||
run_mode = param[0].data.d_int32;
|
||||
|
||||
image_id = param[1].data.d_int32;
|
||||
layer_id = gimp_image_get_active_layer(image_id);
|
||||
|
||||
values[0].type = PARAM_STATUS;
|
||||
values[0].data.d_status = status;
|
||||
|
||||
|
@ -286,16 +316,16 @@ run(char *name,
|
|||
|
||||
/* Get the active drawable info */
|
||||
|
||||
drawable = gimp_drawable_get(param[2].data.d_drawable);
|
||||
input_drawable = gimp_drawable_get(param[2].data.d_drawable);
|
||||
|
||||
tile_width = gimp_tile_width();
|
||||
tile_height = gimp_tile_height();
|
||||
|
||||
img_width = gimp_drawable_width(drawable->id);
|
||||
img_height = gimp_drawable_height(drawable->id);
|
||||
img_bpp = gimp_drawable_bpp(drawable->id);
|
||||
img_width = gimp_drawable_width(input_drawable->id);
|
||||
img_height = gimp_drawable_height(input_drawable->id);
|
||||
inputBPP = gimp_drawable_bpp(input_drawable->id);
|
||||
|
||||
gimp_drawable_mask_bounds(drawable->id, &sel_x1, &sel_y1, &sel_x2, &sel_y2);
|
||||
gimp_drawable_mask_bounds(input_drawable->id, &sel_x1, &sel_y1, &sel_x2, &sel_y2);
|
||||
|
||||
originX = sel_x1;
|
||||
originY = sel_y1;
|
||||
|
@ -336,6 +366,8 @@ run(char *name,
|
|||
preview_width = MAX(pwidth, 2); /* Min size is 2 */
|
||||
preview_height = MAX(pheight, 2);
|
||||
|
||||
init_builtins();
|
||||
|
||||
/* See how we will run */
|
||||
|
||||
switch (run_mode) {
|
||||
|
@ -377,20 +409,45 @@ run(char *name,
|
|||
|
||||
/* Mathmap the image */
|
||||
|
||||
if ((status == STATUS_SUCCESS) &&
|
||||
(gimp_drawable_color(drawable->id) ||
|
||||
gimp_drawable_gray(drawable->id))) {
|
||||
|
||||
if ((status == STATUS_SUCCESS)
|
||||
&& (gimp_drawable_color(input_drawable->id)
|
||||
|| gimp_drawable_gray(input_drawable->id)))
|
||||
{
|
||||
intersamplingEnabled = mmvals.flags & FLAG_INTERSAMPLING;
|
||||
oversamplingEnabled = mmvals.flags & FLAG_OVERSAMPLING;
|
||||
animationEnabled = mmvals.flags & FLAG_ANIMATION;
|
||||
|
||||
/* Set the tile cache size */
|
||||
|
||||
gimp_tile_cache_ntiles((drawable->width + gimp_tile_width() - 1) / gimp_tile_width());
|
||||
gimp_tile_cache_ntiles((input_drawable->width + gimp_tile_width() - 1)
|
||||
/ gimp_tile_width());
|
||||
|
||||
/* Run! */
|
||||
|
||||
mathmap();
|
||||
if (animationEnabled)
|
||||
{
|
||||
int frameNum;
|
||||
|
||||
for (frameNum = 0; frameNum < mmvals.frames; ++frameNum)
|
||||
{
|
||||
gint32 layer;
|
||||
char layerName[100];
|
||||
|
||||
currentT = (double)frameNum / (double)mmvals.frames;
|
||||
layer = mathmap_layer_copy(layer_id);
|
||||
sprintf(layerName, "kurdenlayer %d", frameNum);
|
||||
gimp_layer_set_name(layer, layerName);
|
||||
output_drawable = gimp_drawable_get(layer);
|
||||
mathmap();
|
||||
gimp_image_add_layer(image_id, layer, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentT = 0.0;
|
||||
output_drawable = input_drawable;
|
||||
mathmap();
|
||||
}
|
||||
|
||||
/* If run mode is interactive, flush displays */
|
||||
|
||||
|
@ -406,7 +463,7 @@ run(char *name,
|
|||
|
||||
values[0].data.d_status = status;
|
||||
|
||||
gimp_drawable_detach(drawable);
|
||||
gimp_drawable_detach(input_drawable);
|
||||
} /* run */
|
||||
|
||||
|
||||
|
@ -431,6 +488,27 @@ calc_ra (void)
|
|||
}
|
||||
}
|
||||
|
||||
static gint32
|
||||
mathmap_layer_copy(gint32 layerID)
|
||||
{
|
||||
GParam *return_vals;
|
||||
int nreturn_vals;
|
||||
gint32 nlayer;
|
||||
|
||||
return_vals = gimp_run_procedure ("gimp_layer_copy",
|
||||
&nreturn_vals,
|
||||
PARAM_LAYER, layerID,
|
||||
PARAM_INT32, TRUE,
|
||||
PARAM_END);
|
||||
|
||||
if (return_vals[0].data.d_status == STATUS_SUCCESS)
|
||||
nlayer = return_vals[1].data.d_layer;
|
||||
else
|
||||
nlayer = -1;
|
||||
gimp_destroy_params(return_vals, nreturn_vals);
|
||||
return nlayer;
|
||||
}
|
||||
|
||||
static void
|
||||
mathmap(void)
|
||||
{
|
||||
|
@ -440,15 +518,15 @@ mathmap(void)
|
|||
guchar *dest_row;
|
||||
guchar *dest;
|
||||
gint row, col;
|
||||
guchar pixel[4][4];
|
||||
guchar values[4];
|
||||
double cx, cy;
|
||||
int ix, iy;
|
||||
int i;
|
||||
double result;
|
||||
int red,
|
||||
green,
|
||||
blue;
|
||||
blue,
|
||||
alpha;
|
||||
|
||||
outputBPP = gimp_drawable_bpp(output_drawable->id);
|
||||
|
||||
theExprtree = 0;
|
||||
|
||||
|
@ -464,7 +542,7 @@ mathmap(void)
|
|||
|
||||
/* Initialize pixel region */
|
||||
|
||||
gimp_pixel_rgn_init(&dest_rgn, drawable, sel_x1, sel_y1, sel_width, sel_height,
|
||||
gimp_pixel_rgn_init(&dest_rgn, output_drawable, sel_x1, sel_y1, sel_width, sel_height,
|
||||
TRUE, TRUE);
|
||||
|
||||
imageWidth = sel_width;
|
||||
|
@ -490,7 +568,7 @@ mathmap(void)
|
|||
progress = 0;
|
||||
max_progress = sel_width * sel_height;
|
||||
|
||||
gimp_progress_init("Mathmaping...");
|
||||
gimp_progress_init("Mathmapping...");
|
||||
|
||||
for (pr = gimp_pixel_rgns_register(1, &dest_rgn);
|
||||
pr != NULL; pr = gimp_pixel_rgns_process(pr))
|
||||
|
@ -512,7 +590,7 @@ mathmap(void)
|
|||
currentX = col + dest_rgn.x - sel_x1 - middleX;
|
||||
currentY = 0.0 + dest_rgn.y - sel_y1 - middleY;
|
||||
calc_ra(); result = eval_postfix();
|
||||
double_to_color(result, &red, &green, &blue);
|
||||
double_to_color(result, &red, &green, &blue, &alpha);
|
||||
|
||||
line1[col * 3 + 0] = red;
|
||||
line1[col * 3 + 1] = green;
|
||||
|
@ -528,7 +606,7 @@ mathmap(void)
|
|||
currentX = col + dest_rgn.x - sel_x1 + 0.5 - middleX;
|
||||
currentY = row + dest_rgn.y - sel_y1 + 0.5 - middleY;
|
||||
calc_ra(); result = eval_postfix();
|
||||
double_to_color(result, &red, &green, &blue);
|
||||
double_to_color(result, &red, &green, &blue, &alpha);
|
||||
|
||||
line2[col * 3 + 0] = red;
|
||||
line2[col * 3 + 1] = green;
|
||||
|
@ -539,7 +617,7 @@ mathmap(void)
|
|||
currentX = col + dest_rgn.x - sel_x1 - middleX;
|
||||
currentY = row + dest_rgn.y - sel_y1 + 1.0 - middleY;
|
||||
calc_ra(); result = eval_postfix();
|
||||
double_to_color(result, &red, &green, &blue);
|
||||
double_to_color(result, &red, &green, &blue, &alpha);
|
||||
|
||||
line3[col * 3 + 0] = red;
|
||||
line3[col * 3 + 1] = green;
|
||||
|
@ -567,7 +645,7 @@ mathmap(void)
|
|||
dest[0] = red / 6;
|
||||
dest[1] = green / 6;
|
||||
dest[2] = blue / 6;
|
||||
dest += img_bpp;
|
||||
dest += outputBPP;
|
||||
}
|
||||
|
||||
memcpy(line1, line3, (imageWidth + 1) * 3);
|
||||
|
@ -589,18 +667,20 @@ 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);
|
||||
double_to_color(result, &red, &green, &blue, &alpha);
|
||||
|
||||
dest[0] = red;
|
||||
dest[1] = green;
|
||||
dest[2] = blue;
|
||||
dest += img_bpp;
|
||||
if (outputBPP == 2)
|
||||
dest[1] = alpha;
|
||||
else if (outputBPP >= 3)
|
||||
{
|
||||
dest[1] = green;
|
||||
dest[2] = blue;
|
||||
if (outputBPP == 4)
|
||||
dest[3] = alpha;
|
||||
}
|
||||
dest += outputBPP;
|
||||
}
|
||||
|
||||
dest_row += dest_rgn.rowstride;
|
||||
|
@ -617,9 +697,9 @@ mathmap(void)
|
|||
the_tile = NULL;
|
||||
} /* if */
|
||||
|
||||
gimp_drawable_flush(drawable);
|
||||
gimp_drawable_merge_shadow(drawable->id, TRUE);
|
||||
gimp_drawable_update(drawable->id, sel_x1, sel_y1, sel_width, sel_height);
|
||||
gimp_drawable_flush(output_drawable);
|
||||
gimp_drawable_merge_shadow(output_drawable->id, TRUE);
|
||||
gimp_drawable_update(output_drawable->id, sel_x1, sel_y1, sel_width, sel_height);
|
||||
} /* mathmap */
|
||||
|
||||
|
||||
|
@ -654,7 +734,7 @@ mathmap_get_pixel(int x, int y, guchar *pixel)
|
|||
if (the_tile != NULL)
|
||||
gimp_tile_unref(the_tile, FALSE);
|
||||
|
||||
the_tile = gimp_drawable_get_tile(drawable, FALSE, newrow, newcol);
|
||||
the_tile = gimp_drawable_get_tile(input_drawable, FALSE, newrow, newcol);
|
||||
assert(the_tile != 0);
|
||||
gimp_tile_ref(the_tile);
|
||||
|
||||
|
@ -664,7 +744,7 @@ mathmap_get_pixel(int x, int y, guchar *pixel)
|
|||
|
||||
p = the_tile->data + the_tile->bpp * (the_tile->ewidth * newrowoff + newcoloff);
|
||||
|
||||
for (i = img_bpp; i; i--)
|
||||
for (i = inputBPP; i; i--)
|
||||
*pixel++ = *p++;
|
||||
}
|
||||
|
||||
|
@ -703,7 +783,7 @@ build_preview_source_image(void)
|
|||
{
|
||||
mathmap_get_pixel((int) px, (int) py, pixel);
|
||||
|
||||
if (img_bpp < 3)
|
||||
if (inputBPP < 3)
|
||||
{
|
||||
pixel[1] = pixel[0];
|
||||
pixel[2] = pixel[0];
|
||||
|
@ -727,12 +807,12 @@ static gint
|
|||
mathmap_dialog(void)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *top_table;
|
||||
GtkWidget *top_table,
|
||||
*middle_table;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *table;
|
||||
GtkWidget *button;
|
||||
GtkWidget *label;
|
||||
GtkWidget *entry;
|
||||
GtkWidget *toggle;
|
||||
GtkWidget *arrow;
|
||||
GtkWidget *alignment;
|
||||
|
@ -741,6 +821,8 @@ mathmap_dialog(void)
|
|||
GtkWidget *menubaritem;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *item;
|
||||
GtkWidget *scale;
|
||||
GtkObject *adjustment;
|
||||
int i;
|
||||
gint argc;
|
||||
gchar **argv;
|
||||
|
@ -773,13 +855,13 @@ mathmap_dialog(void)
|
|||
(GtkSignalFunc) dialog_close_callback,
|
||||
NULL);
|
||||
|
||||
top_table = gtk_table_new(6, 3, FALSE);
|
||||
top_table = gtk_table_new(5, 3, FALSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(top_table), 6);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(top_table), 4);
|
||||
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), top_table, FALSE, FALSE, 0);
|
||||
gtk_widget_show(top_table);
|
||||
|
||||
/* Preview */
|
||||
/* Preview */
|
||||
|
||||
frame = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
|
||||
|
@ -796,25 +878,112 @@ mathmap_dialog(void)
|
|||
gtk_table_attach(GTK_TABLE(top_table), button, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
|
||||
gtk_widget_show(button);
|
||||
|
||||
alignment = gtk_alignment_new(0, 0, 0, 0);
|
||||
toggle = gtk_check_button_new_with_label("Intersampling");
|
||||
gtk_container_add(GTK_CONTAINER(alignment), toggle);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), mmvals.flags & FLAG_INTERSAMPLING);
|
||||
gtk_table_attach(GTK_TABLE(top_table), alignment, 0, 3, 2, 3, GTK_FILL, 0, 0, 0);
|
||||
gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
|
||||
(GtkSignalFunc)dialog_intersampling_update, 0);
|
||||
gtk_widget_show(toggle);
|
||||
gtk_widget_show(alignment);
|
||||
middle_table = gtk_table_new(1, 2, FALSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(middle_table), 6);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(middle_table), 4);
|
||||
gtk_table_attach(GTK_TABLE(top_table), middle_table, 0, 3, 2, 3, GTK_FILL, 0, 0, 0);
|
||||
gtk_widget_show(middle_table);
|
||||
|
||||
alignment = gtk_alignment_new(0, 0, 0, 0);
|
||||
toggle = gtk_check_button_new_with_label("Oversampling");
|
||||
gtk_container_add(GTK_CONTAINER(alignment), toggle);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), mmvals.flags & FLAG_OVERSAMPLING);
|
||||
gtk_table_attach(GTK_TABLE(top_table), alignment, 0, 3, 3, 4, GTK_FILL, 0, 0, 0);
|
||||
gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
|
||||
(GtkSignalFunc)dialog_oversampling_update, 0);
|
||||
gtk_widget_show(toggle);
|
||||
gtk_widget_show(alignment);
|
||||
/* Sampling */
|
||||
|
||||
table = gtk_table_new(2, 1, FALSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(table), 6);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(table), 4);
|
||||
|
||||
frame = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_container_add(GTK_CONTAINER(frame), table);
|
||||
|
||||
alignment = gtk_alignment_new(0, 0, 0, 0);
|
||||
gtk_container_add(GTK_CONTAINER(alignment), frame);
|
||||
gtk_table_attach(GTK_TABLE(middle_table), alignment, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
|
||||
|
||||
gtk_widget_show(table);
|
||||
gtk_widget_show(frame);
|
||||
gtk_widget_show(alignment);
|
||||
|
||||
/* Intersampling */
|
||||
|
||||
alignment = gtk_alignment_new(0, 0, 0, 0);
|
||||
toggle = gtk_check_button_new_with_label("Intersampling");
|
||||
gtk_container_add(GTK_CONTAINER(alignment), toggle);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle),
|
||||
mmvals.flags & FLAG_INTERSAMPLING);
|
||||
gtk_table_attach(GTK_TABLE(table), alignment, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
|
||||
gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
|
||||
(GtkSignalFunc)dialog_intersampling_update, 0);
|
||||
gtk_widget_show(toggle);
|
||||
gtk_widget_show(alignment);
|
||||
|
||||
/* Oversampling */
|
||||
|
||||
alignment = gtk_alignment_new(0, 0, 0, 0);
|
||||
toggle = gtk_check_button_new_with_label("Oversampling");
|
||||
gtk_container_add(GTK_CONTAINER(alignment), toggle);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle),
|
||||
mmvals.flags & FLAG_OVERSAMPLING);
|
||||
gtk_table_attach(GTK_TABLE(table), alignment, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
|
||||
gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
|
||||
(GtkSignalFunc)dialog_oversampling_update, 0);
|
||||
gtk_widget_show(toggle);
|
||||
gtk_widget_show(alignment);
|
||||
|
||||
/* Animation */
|
||||
|
||||
table = gtk_table_new(2, 1, FALSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(table), 6);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(table), 4);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(table), 4);
|
||||
|
||||
frame = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_container_add(GTK_CONTAINER(frame), table);
|
||||
|
||||
alignment = gtk_alignment_new(0, 0, 0, 0);
|
||||
gtk_container_add(GTK_CONTAINER(alignment), frame);
|
||||
gtk_table_attach(GTK_TABLE(middle_table), alignment, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);
|
||||
|
||||
gtk_widget_show(table);
|
||||
gtk_widget_show(frame);
|
||||
gtk_widget_show(alignment);
|
||||
|
||||
/* Animation Toggle */
|
||||
|
||||
alignment = gtk_alignment_new(0, 0, 0, 0);
|
||||
toggle = gtk_check_button_new_with_label("Animate");
|
||||
gtk_container_add(GTK_CONTAINER(alignment), toggle);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle),
|
||||
mmvals.flags & FLAG_ANIMATION);
|
||||
gtk_table_attach(GTK_TABLE(table), alignment, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
|
||||
gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
|
||||
(GtkSignalFunc)dialog_animation_update, 0);
|
||||
gtk_widget_show(toggle);
|
||||
gtk_widget_show(alignment);
|
||||
|
||||
/* Number of Frames */
|
||||
|
||||
animate_table = gtk_table_new(1, 2, FALSE);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(animate_table), 4);
|
||||
gtk_table_attach(GTK_TABLE(table), animate_table, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
|
||||
|
||||
label = gtk_label_new("Frames");
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
|
||||
gtk_table_attach(GTK_TABLE(animate_table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
|
||||
adjustment = gtk_adjustment_new(mmvals.frames, 2, 100, 1.0, 1.0, 0.0);
|
||||
scale = gtk_hscale_new(GTK_ADJUSTMENT(adjustment));
|
||||
gtk_widget_set_usize(scale, 100, 0);
|
||||
gtk_table_attach (GTK_TABLE (animate_table), scale, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);
|
||||
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
|
||||
gtk_scale_set_digits(GTK_SCALE(scale),0);
|
||||
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
|
||||
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
|
||||
(GtkSignalFunc) dialog_scale_update,
|
||||
&mmvals.frames);
|
||||
gtk_widget_show(label);
|
||||
gtk_widget_show(scale);
|
||||
|
||||
gtk_widget_show(animate_table);
|
||||
gtk_widget_set_sensitive(animate_table, mmvals.flags & FLAG_ANIMATION);
|
||||
|
||||
/* Menu */
|
||||
|
||||
|
@ -824,7 +993,8 @@ mathmap_dialog(void)
|
|||
{
|
||||
item = gtk_menu_item_new_with_label(examples[i][0]);
|
||||
gtk_menu_append(GTK_MENU(menu), item);
|
||||
gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc)dialog_example_callback, examples[i][1]);
|
||||
gtk_signal_connect(GTK_OBJECT(item), "activate",
|
||||
(GtkSignalFunc)dialog_example_callback, examples[i][1]);
|
||||
gtk_widget_show(item);
|
||||
}
|
||||
|
||||
|
@ -843,7 +1013,7 @@ mathmap_dialog(void)
|
|||
gtk_container_add(GTK_CONTAINER(menubar), menubaritem);
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menubaritem), menu);
|
||||
|
||||
gtk_table_attach(GTK_TABLE(top_table), alignment, 0, 3, 4, 5, GTK_FILL, 0, 0, 0);
|
||||
gtk_table_attach(GTK_TABLE(top_table), alignment, 0, 3, 3, 4, GTK_FILL, 0, 0, 0);
|
||||
|
||||
gtk_widget_show(arrow);
|
||||
gtk_widget_show(label);
|
||||
|
@ -856,7 +1026,7 @@ mathmap_dialog(void)
|
|||
|
||||
table = gtk_table_new(1, 2, FALSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(table), 0);
|
||||
gtk_table_attach(GTK_TABLE(top_table), table, 0, 3, 5, 6, GTK_EXPAND | GTK_FILL, 0, 0, 0);
|
||||
gtk_table_attach(GTK_TABLE(top_table), table, 0, 3, 4, 5, GTK_EXPAND | GTK_FILL, 0, 0, 0);
|
||||
gtk_widget_show(table);
|
||||
|
||||
label = gtk_label_new("Expression");
|
||||
|
@ -864,19 +1034,19 @@ mathmap_dialog(void)
|
|||
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 4, 0);
|
||||
gtk_widget_show(label);
|
||||
|
||||
expressionEntry = gtk_entry_new();
|
||||
expression_entry = gtk_entry_new();
|
||||
/*
|
||||
gtk_object_set_user_data(GTK_OBJECT(entry), scale_data);
|
||||
gtk_object_set_user_data(scale_data, entry);
|
||||
*/
|
||||
gtk_widget_set_usize(expressionEntry, ENTRY_WIDTH, 0);
|
||||
gtk_entry_set_text(GTK_ENTRY(expressionEntry), mmvals.expression);
|
||||
gtk_signal_connect(GTK_OBJECT(expressionEntry), "changed",
|
||||
gtk_widget_set_usize(expression_entry, ENTRY_WIDTH, 0);
|
||||
gtk_entry_set_text(GTK_ENTRY(expression_entry), mmvals.expression);
|
||||
gtk_signal_connect(GTK_OBJECT(expression_entry), "changed",
|
||||
(GtkSignalFunc) dialog_entry_update,
|
||||
0);
|
||||
gtk_table_attach(GTK_TABLE(table), expressionEntry, 1, 2, 0, 1,
|
||||
gtk_table_attach(GTK_TABLE(table), expression_entry, 1, 2, 0, 1,
|
||||
GTK_EXPAND | GTK_FILL, GTK_FILL, 4, 0);
|
||||
gtk_widget_show(expressionEntry);
|
||||
gtk_widget_show(expression_entry);
|
||||
|
||||
/* Buttons */
|
||||
|
||||
|
@ -926,11 +1096,9 @@ dialog_update_preview(void)
|
|||
{
|
||||
double left, right, bottom, top;
|
||||
double dx, dy;
|
||||
double cx, cy;
|
||||
int ix, iy;
|
||||
int x, y;
|
||||
double scale_x, scale_y;
|
||||
guchar *p_ul, *p_lr, *i, *p;
|
||||
guchar *p_ul, *p_lr, *p;
|
||||
|
||||
intersamplingEnabled = mmvals.flags & FLAG_INTERSAMPLING;
|
||||
oversamplingEnabled = mmvals.flags & FLAG_OVERSAMPLING;
|
||||
|
@ -985,12 +1153,13 @@ dialog_update_preview(void)
|
|||
double result;
|
||||
int red,
|
||||
green,
|
||||
blue;
|
||||
blue,
|
||||
alpha;
|
||||
|
||||
currentX = x * imageWidth / preview_width - middleX;
|
||||
currentY = y * imageHeight / preview_height - middleY;
|
||||
calc_ra(); result = eval_postfix();
|
||||
double_to_color(result, &red, &green, &blue);
|
||||
double_to_color(result, &red, &green, &blue, &alpha);
|
||||
|
||||
p_ul[0] = red;
|
||||
p_ul[1] = green;
|
||||
|
@ -1016,6 +1185,7 @@ dialog_update_preview(void)
|
|||
|
||||
/*****/
|
||||
|
||||
/*
|
||||
static void
|
||||
dialog_create_value(char *title, GtkTable *table, int row, gdouble *value,
|
||||
double left, double right)
|
||||
|
@ -1059,36 +1229,23 @@ dialog_create_value(char *title, GtkTable *table, int row, gdouble *value,
|
|||
value);
|
||||
gtk_table_attach(GTK_TABLE(table), entry, 2, 3, row, row + 1, GTK_FILL, GTK_FILL, 4, 0);
|
||||
gtk_widget_show(entry);
|
||||
} /* dialog_create_value */
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*****/
|
||||
|
||||
static void
|
||||
dialog_scale_update(GtkAdjustment *adjustment, gdouble *value)
|
||||
dialog_scale_update(GtkAdjustment *adjustment, gint *value)
|
||||
{
|
||||
GtkWidget *entry;
|
||||
char buf[256];
|
||||
|
||||
if (*value != adjustment->value) {
|
||||
*value = adjustment->value;
|
||||
|
||||
entry = gtk_object_get_user_data(GTK_OBJECT(adjustment));
|
||||
sprintf(buf, "%0.2f", *value);
|
||||
|
||||
gtk_signal_handler_block_by_data(GTK_OBJECT(entry), value);
|
||||
gtk_entry_set_text(GTK_ENTRY(entry), buf);
|
||||
gtk_signal_handler_unblock_by_data(GTK_OBJECT(entry), value);
|
||||
|
||||
/* dialog_update_preview(); */
|
||||
} /* if */
|
||||
*value = (gint)adjustment->value;
|
||||
} /* dialog_scale_update */
|
||||
|
||||
|
||||
/*****/
|
||||
|
||||
static void
|
||||
dialog_entry_update(GtkWidget *widget, gdouble *value)
|
||||
dialog_entry_update(GtkWidget *widget, gpointer value)
|
||||
{
|
||||
expression_copy(mmvals.expression, gtk_entry_get_text(GTK_ENTRY(widget)));
|
||||
} /* dialog_entry_update */
|
||||
|
@ -1117,10 +1274,23 @@ dialog_intersampling_update (GtkWidget *widget, gpointer data)
|
|||
|
||||
/*****/
|
||||
|
||||
static void
|
||||
dialog_animation_update (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
mmvals.flags &= ~FLAG_ANIMATION;
|
||||
|
||||
if (GTK_TOGGLE_BUTTON(widget)->active)
|
||||
mmvals.flags |= FLAG_ANIMATION;
|
||||
|
||||
gtk_widget_set_sensitive(animate_table, mmvals.flags & FLAG_ANIMATION);
|
||||
}
|
||||
|
||||
/*****/
|
||||
|
||||
static void
|
||||
dialog_example_callback (GtkWidget *widget, char *expression)
|
||||
{
|
||||
gtk_entry_set_text(GTK_ENTRY(expressionEntry), expression);
|
||||
gtk_entry_set_text(GTK_ENTRY(expression_entry), expression);
|
||||
}
|
||||
|
||||
/*****/
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "exprtree.h"
|
||||
#include "builtins.h"
|
||||
|
||||
extern exprtree *theExprtree;
|
||||
%}
|
||||
|
@ -9,17 +10,21 @@ extern exprtree *theExprtree;
|
|||
%union {
|
||||
ident ident;
|
||||
exprtree *exprtree;
|
||||
builtin *builtin;
|
||||
}
|
||||
|
||||
%token T_IDENT T_NUMBER
|
||||
%token T_IF T_THEN T_ELSE T_END
|
||||
%token T_WHILE T_DO
|
||||
%token T_BUILTIN
|
||||
|
||||
%right ';'
|
||||
%right '='
|
||||
%left T_OR T_AND
|
||||
%left T_EQUAL '<' '>' T_LESSEQUAL T_GREATEREQUAL T_NOTEQUAL
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%'
|
||||
%left NEG
|
||||
%left UNARY
|
||||
|
||||
%%
|
||||
|
||||
|
@ -38,10 +43,32 @@ expr : T_NUMBER { $<exprtree>$ = $<exprtree>1; }
|
|||
$<exprtree>1, $<exprtree>3); }
|
||||
| expr '%' expr { $<exprtree>$ = make_operator(EXPR_MOD,
|
||||
$<exprtree>1, $<exprtree>3); }
|
||||
| '-' expr %prec NEG { $<exprtree>$ = make_operator(EXPR_NEG, $<exprtree>2, 0); }
|
||||
| expr T_EQUAL expr { $<exprtree>$ = make_function(builtin_with_name("equal"),
|
||||
arglist_append($<exprtree>1, $<exprtree>3)); }
|
||||
| expr '<' expr { $<exprtree>$ = make_function(builtin_with_name("less"),
|
||||
arglist_append($<exprtree>1, $<exprtree>3)); }
|
||||
| expr '>' expr { $<exprtree>$ = make_function(builtin_with_name("greater"),
|
||||
arglist_append($<exprtree>1, $<exprtree>3)); }
|
||||
| expr T_LESSEQUAL expr
|
||||
{ $<exprtree>$ = make_function(builtin_with_name("lessequal"),
|
||||
arglist_append($<exprtree>1, $<exprtree>3)); }
|
||||
| expr T_GREATEREQUAL expr
|
||||
{ $<exprtree>$ = make_function(builtin_with_name("greaterequal"),
|
||||
arglist_append($<exprtree>1, $<exprtree>3)); }
|
||||
| expr T_NOTEQUAL expr
|
||||
{ $<exprtree>$ = make_function(builtin_with_name("notequal"),
|
||||
arglist_append($<exprtree>1, $<exprtree>3)); }
|
||||
| expr T_OR expr { $<exprtree>$ = make_function(builtin_with_name("or"),
|
||||
arglist_append($<exprtree>1, $<exprtree>3)); }
|
||||
| expr T_AND expr { $<exprtree>$ = make_function(builtin_with_name("and"),
|
||||
arglist_append($<exprtree>1, $<exprtree>3)); }
|
||||
| '-' expr %prec UNARY
|
||||
{ $<exprtree>$ = make_operator(EXPR_NEG, $<exprtree>2, 0); }
|
||||
| '!' expr %prec UNARY
|
||||
{ $<exprtree>$ = make_function(builtin_with_name("not"), $<exprtree>2); }
|
||||
| '(' expr ')' { $<exprtree>$ = $<exprtree>2; };
|
||||
| T_IDENT '(' arglist ')'
|
||||
{ $<exprtree>$ = make_function($<ident>1, $<exprtree>3); }
|
||||
| T_BUILTIN '(' arglist ')'
|
||||
{ $<exprtree>$ = make_function($<builtin>1, $<exprtree>3); }
|
||||
| T_IDENT '=' expr { $<exprtree>$ = make_assignment($<ident>1, $<exprtree>3); }
|
||||
| expr ';' expr { $<exprtree>$ = make_sequence($<exprtree>1, $<exprtree>3); }
|
||||
| T_IF expr T_THEN expr T_END
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
extern double currentX,
|
||||
currentY,
|
||||
currentT,
|
||||
currentR,
|
||||
currentA,
|
||||
imageR,
|
||||
|
@ -142,6 +143,12 @@ stack_var_y (void *arg)
|
|||
stack[stackp++] = currentY;
|
||||
}
|
||||
|
||||
void
|
||||
stack_var_t (void *arg)
|
||||
{
|
||||
stack[stackp++] = currentT;
|
||||
}
|
||||
|
||||
void
|
||||
stack_var_r (void *arg)
|
||||
{
|
||||
|
@ -307,6 +314,10 @@ make_postfix_recursive (exprtree *tree)
|
|||
expression[exprp++].func = stack_var_y;
|
||||
break;
|
||||
|
||||
case EXPR_VAR_T :
|
||||
expression[exprp++].func = stack_var_t;
|
||||
break;
|
||||
|
||||
case EXPR_VAR_R :
|
||||
expression[exprp++].func = stack_var_r;
|
||||
break;
|
||||
|
@ -487,6 +498,8 @@ output_postfix (void)
|
|||
printf("push x\n");
|
||||
else if (expression[i].func == stack_var_y)
|
||||
printf("push y\n");
|
||||
else if (expression[i].func == stack_var_t)
|
||||
printf("push t\n");
|
||||
else if (expression[i].func == stack_var_r)
|
||||
printf("push r\n");
|
||||
else if (expression[i].func == stack_var_a)
|
||||
|
@ -505,6 +518,7 @@ output_postfix (void)
|
|||
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)
|
||||
|
@ -537,6 +551,7 @@ output_postfix (void)
|
|||
printf("origValRA\n");
|
||||
else if (expression[i].func == builtin_grayColor)
|
||||
printf("grayColor\n");
|
||||
*/
|
||||
else
|
||||
printf("unknown opcode\n");
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "exprtree.h"
|
||||
#include "parser.tab.h"
|
||||
#include "builtins.h"
|
||||
#include "parser.h"
|
||||
%}
|
||||
|
||||
%option noyywrap
|
||||
|
@ -15,13 +16,30 @@ 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;
|
||||
[a-zA-Z_][a-zA-Z0-9_]* {
|
||||
builtin *theBuiltin = builtin_with_name(yytext);
|
||||
|
||||
if (theBuiltin != 0)
|
||||
{
|
||||
yylval.builtin = theBuiltin;
|
||||
return T_BUILTIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(yylval.ident, yytext, MAX_IDENT_LENGTH);
|
||||
yylval.ident[MAX_IDENT_LENGTH] = 0;
|
||||
return T_IDENT;
|
||||
}
|
||||
}
|
||||
[0-9]+ { yylval.exprtree = make_number(atof(yytext)); return T_NUMBER; }
|
||||
[0-9]*\.[0-9]+ { yylval.exprtree = make_number(atof(yytext)); return T_NUMBER; }
|
||||
[-,()+*/%=;] return yytext[0];
|
||||
"==" return T_EQUAL;
|
||||
"<=" return T_LESSEQUAL;
|
||||
">=" return T_GREATEREQUAL;
|
||||
"!=" return T_NOTEQUAL;
|
||||
"||" return T_OR;
|
||||
"&&" return T_AND;
|
||||
[-<>!,()+*/%=;] return yytext[0];
|
||||
#.* ;
|
||||
[ \t\n] ;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "vars.h"
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Print plug-in EPSON ESC/P2 driver for the GIMP.
|
||||
*
|
||||
* Copyright 1997 Michael Sweet (mike@easysw.com)
|
||||
* Copyright 1997-1998 Michael Sweet (mike@easysw.com)
|
||||
*
|
||||
* 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
|
||||
|
@ -27,21 +27,15 @@
|
|||
* Revision History:
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.1.1.1 1997/11/24 22:04:34 sopwith
|
||||
* Let's try this import one last time.
|
||||
* Revision 1.2 1998/01/25 09:29:25 yosh
|
||||
* Plugin updates
|
||||
* Properly generated aa Makefile (still not built by default)
|
||||
* Sven's no args script patch
|
||||
*
|
||||
* Revision 1.3 1997/11/18 03:04:25 nobody
|
||||
* fixed ugly comment-bugs introduced by evil darkwing
|
||||
* keep out configuration empty dirs
|
||||
* --darkwing
|
||||
* -Yosh
|
||||
*
|
||||
* Revision 1.2 1997/11/17 05:43:56 nobody
|
||||
* updated ChangeLog
|
||||
* dropped non-working doc/Makefile entries
|
||||
* applied many fixes from the registry as well as the devel ML
|
||||
* applied missing patches by Art Haas
|
||||
*
|
||||
* --darkwing
|
||||
* Revision 1.8 1998/01/21 21:33:47 mike
|
||||
* Updated copyright.
|
||||
*
|
||||
* Revision 1.7 1997/11/12 15:57:48 mike
|
||||
* Minor changes for clean compiles under Digital UNIX.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Print plug-in HP PCL driver for the GIMP.
|
||||
*
|
||||
* Copyright 1997 Michael Sweet (mike@easysw.com)
|
||||
* Copyright 1997-1998 Michael Sweet (mike@easysw.com)
|
||||
*
|
||||
* 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
|
||||
|
@ -28,21 +28,15 @@
|
|||
* Revision History:
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.1.1.1 1997/11/24 22:04:34 sopwith
|
||||
* Let's try this import one last time.
|
||||
* Revision 1.2 1998/01/25 09:29:26 yosh
|
||||
* Plugin updates
|
||||
* Properly generated aa Makefile (still not built by default)
|
||||
* Sven's no args script patch
|
||||
*
|
||||
* Revision 1.3 1997/11/18 03:04:26 nobody
|
||||
* fixed ugly comment-bugs introduced by evil darkwing
|
||||
* keep out configuration empty dirs
|
||||
* --darkwing
|
||||
* -Yosh
|
||||
*
|
||||
* Revision 1.2 1997/11/17 05:43:56 nobody
|
||||
* updated ChangeLog
|
||||
* dropped non-working doc/Makefile entries
|
||||
* applied many fixes from the registry as well as the devel ML
|
||||
* applied missing patches by Art Haas
|
||||
*
|
||||
* --darkwing
|
||||
* Revision 1.8 1998/01/21 21:33:47 mike
|
||||
* Updated copyright.
|
||||
*
|
||||
* Revision 1.7 1997/11/12 15:57:48 mike
|
||||
* Minor changes for clean compiles under Digital UNIX.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Print plug-in Adobe PostScript driver for the GIMP.
|
||||
*
|
||||
* Copyright 1997 Michael Sweet (mike@easysw.com)
|
||||
* Copyright 1997-1998 Michael Sweet (mike@easysw.com)
|
||||
*
|
||||
* 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
|
||||
|
@ -21,27 +21,27 @@
|
|||
*
|
||||
* Contents:
|
||||
*
|
||||
* ps_print() - Print an image to a PostScript printer.
|
||||
* ps_hex() - Print binary data as a series of hexadecimal numbers.
|
||||
* ps_print() - Print an image to a PostScript printer.
|
||||
* ps_hex() - Print binary data as a series of hexadecimal numbers.
|
||||
* ps_ascii85() - Print binary data as a series of base-85 numbers.
|
||||
*
|
||||
* Revision History:
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.1.1.1 1997/11/24 22:04:34 sopwith
|
||||
* Let's try this import one last time.
|
||||
* Revision 1.2 1998/01/25 09:29:27 yosh
|
||||
* Plugin updates
|
||||
* Properly generated aa Makefile (still not built by default)
|
||||
* Sven's no args script patch
|
||||
*
|
||||
* Revision 1.3 1997/11/18 03:04:26 nobody
|
||||
* fixed ugly comment-bugs introduced by evil darkwing
|
||||
* keep out configuration empty dirs
|
||||
* --darkwing
|
||||
* -Yosh
|
||||
*
|
||||
* Revision 1.2 1997/11/17 05:43:57 nobody
|
||||
* updated ChangeLog
|
||||
* dropped non-working doc/Makefile entries
|
||||
* applied many fixes from the registry as well as the devel ML
|
||||
* applied missing patches by Art Haas
|
||||
* Revision 1.10 1998/01/22 15:38:46 mike
|
||||
* Updated copyright notice.
|
||||
* Whoops - wasn't encoding correctly for portrait output to level 2 printers!
|
||||
*
|
||||
* --darkwing
|
||||
* Revision 1.9 1998/01/21 21:33:47 mike
|
||||
* Added support for Level 2 filters; images are now sent in hex or
|
||||
* base-85 ASCII as necessary (faster printing).
|
||||
*
|
||||
* Revision 1.8 1997/11/12 15:57:48 mike
|
||||
* Minor changes for clean compiles under Digital UNIX.
|
||||
|
@ -86,6 +86,7 @@
|
|||
*/
|
||||
|
||||
static void ps_hex(FILE *, guchar *, int);
|
||||
static void ps_ascii85(FILE *, guchar *, int, int);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -117,11 +118,18 @@ ps_print(FILE *prn, /* I - File to print to */
|
|||
out_width, /* Width of image on page */
|
||||
out_height, /* Height of image on page */
|
||||
out_bpp, /* Output bytes per pixel */
|
||||
out_length, /* Output length (Level 2 output) */
|
||||
out_offset, /* Output offset (Level 2 output) */
|
||||
temp_width, /* Temporary width of image on page */
|
||||
temp_height, /* Temporary height of image on page */
|
||||
landscape; /* True if we rotate the output 90 degrees */
|
||||
time_t curtime; /* Current time of day */
|
||||
convert_t colorfunc; /* Color conversion function... */
|
||||
static char *filters[2] = /* PostScript image filters... */
|
||||
{
|
||||
"{currentfile picture readhexstring pop}", /* Level 1 */
|
||||
"currentfile /ASCII85Decode filter" /* Level 2 */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
|
@ -226,12 +234,12 @@ ps_print(FILE *prn, /* I - File to print to */
|
|||
fputs("%!PS-Adobe-3.0\n", prn);
|
||||
fputs("%%Creator: " PLUG_IN_NAME " plug-in V" PLUG_IN_VERSION " for GIMP.\n", prn);
|
||||
fprintf(prn, "%%%%CreationDate: %s", ctime(&curtime));
|
||||
fputs("%%Copyright: 1997 by Michael Sweet (mike@easysw.com)\n", prn);
|
||||
fputs("%%Copyright: 1997-1998 by Michael Sweet (mike@easysw.com)\n", prn);
|
||||
fprintf(prn, "%%%%BoundingBox: %d %d %d %d\n",
|
||||
(page_width - out_width) / 2 + 18, (page_height - out_height) / 2 + 36,
|
||||
(page_width + out_width) / 2 + 18, (page_height + out_height) / 2 + 36);
|
||||
fputs("%%DocumentData: Clean7Bit\n", prn);
|
||||
fprintf(prn, "%%%%LanguageLevel: %d\n", output_type + 1);
|
||||
fprintf(prn, "%%%%LanguageLevel: %d\n", model + 1);
|
||||
fputs("%%Pages: 1\n", prn);
|
||||
fputs("%%Orientation: Portrait\n", prn);
|
||||
fputs("%%EndComments\n", prn);
|
||||
|
@ -260,55 +268,99 @@ ps_print(FILE *prn, /* I - File to print to */
|
|||
if (landscape)
|
||||
{
|
||||
in = g_malloc(drawable->height * drawable->bpp);
|
||||
out = g_malloc(drawable->height * out_bpp);
|
||||
out = g_malloc(drawable->height * out_bpp + 3);
|
||||
|
||||
fprintf(prn, "/picture %d string def\n", drawable->height * out_bpp);
|
||||
if (model == 0)
|
||||
fprintf(prn, "/picture %d string def\n", drawable->height * out_bpp);
|
||||
|
||||
if (output_type == OUTPUT_GRAY)
|
||||
fprintf(prn, "%d %d 8 [%d 0 0 %d 0 %d] {currentfile picture readhexstring pop} image\n",
|
||||
fprintf(prn, "%d %d 8 [%d 0 0 %d 0 %d] %s image\n",
|
||||
drawable->height, drawable->width,
|
||||
drawable->height, drawable->width, 0);
|
||||
drawable->height, drawable->width, 0,
|
||||
filters[model]);
|
||||
else
|
||||
fprintf(prn, "%d %d 8 [%d 0 0 %d 0 %d] {currentfile picture readhexstring pop} false 3 colorimage\n",
|
||||
fprintf(prn, "%d %d 8 [%d 0 0 %d 0 %d] %s false 3 colorimage\n",
|
||||
drawable->height, drawable->width,
|
||||
drawable->height, drawable->width, 0);
|
||||
drawable->height, drawable->width, 0,
|
||||
filters[model]);
|
||||
|
||||
for (x = 0; x < drawable->width; x ++)
|
||||
for (x = 0, out_offset = 0; x < drawable->width; x ++)
|
||||
{
|
||||
if ((x & 15) == 0)
|
||||
gimp_progress_update((double)x / (double)drawable->width);
|
||||
|
||||
gimp_pixel_rgn_get_col(&rgn, in, x, 0, drawable->height);
|
||||
(*colorfunc)(in, out, drawable->height, drawable->bpp, lut, cmap);
|
||||
(*colorfunc)(in, out + out_offset, drawable->height, drawable->bpp, lut, cmap);
|
||||
|
||||
ps_hex(prn, out, drawable->height * out_bpp);
|
||||
if (model)
|
||||
{
|
||||
out_length = out_offset + drawable->height * out_bpp;
|
||||
|
||||
if (x < (drawable->width - 1))
|
||||
{
|
||||
ps_ascii85(prn, out, out_length & ~3, 0);
|
||||
out_offset = out_length & 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
ps_ascii85(prn, out, out_length, 1);
|
||||
out_offset = 0;
|
||||
};
|
||||
|
||||
if (out_offset > 0)
|
||||
memcpy(out, out + out_length - out_offset, out_offset);
|
||||
}
|
||||
else
|
||||
ps_hex(prn, out, drawable->height * out_bpp);
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
in = g_malloc(drawable->width * drawable->bpp);
|
||||
out = g_malloc(drawable->width * out_bpp);
|
||||
out = g_malloc(drawable->width * out_bpp + 3);
|
||||
|
||||
fprintf(prn, "/picture %d string def\n", drawable->width * out_bpp);
|
||||
if (model == 0)
|
||||
fprintf(prn, "/picture %d string def\n", drawable->width * out_bpp);
|
||||
|
||||
if (output_type == OUTPUT_GRAY)
|
||||
fprintf(prn, "%d %d 8 [%d 0 0 %d 0 %d] {currentfile picture readhexstring pop} image\n",
|
||||
fprintf(prn, "%d %d 8 [%d 0 0 %d 0 %d] %s image\n",
|
||||
drawable->width, drawable->height,
|
||||
drawable->width, -drawable->height, drawable->height);
|
||||
drawable->width, -drawable->height, drawable->height,
|
||||
filters[model]);
|
||||
else
|
||||
fprintf(prn, "%d %d 8 [%d 0 0 %d 0 %d] {currentfile picture readhexstring pop} false 3 colorimage\n",
|
||||
fprintf(prn, "%d %d 8 [%d 0 0 %d 0 %d] %s false 3 colorimage\n",
|
||||
drawable->width, drawable->height,
|
||||
drawable->width, -drawable->height, drawable->height);
|
||||
drawable->width, -drawable->height, drawable->height,
|
||||
filters[model]);
|
||||
|
||||
for (y = 0; y < drawable->height; y ++)
|
||||
for (y = 0, out_offset = 0; y < drawable->height; y ++)
|
||||
{
|
||||
if ((y & 15) == 0)
|
||||
gimp_progress_update((double)y / (double)drawable->height);
|
||||
|
||||
gimp_pixel_rgn_get_row(&rgn, in, 0, y, drawable->width);
|
||||
(*colorfunc)(in, out, drawable->width, drawable->bpp, lut, cmap);
|
||||
(*colorfunc)(in, out + out_offset, drawable->width, drawable->bpp, lut, cmap);
|
||||
|
||||
ps_hex(prn, out, drawable->width * out_bpp);
|
||||
if (model)
|
||||
{
|
||||
out_length = out_offset + drawable->width * out_bpp;
|
||||
|
||||
if (y < (drawable->height - 1))
|
||||
{
|
||||
ps_ascii85(prn, out, out_length & ~3, 0);
|
||||
out_offset = out_length & 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
ps_ascii85(prn, out, out_length, 1);
|
||||
out_offset = 0;
|
||||
};
|
||||
|
||||
if (out_offset > 0)
|
||||
memcpy(out, out + out_length - out_offset, out_offset);
|
||||
}
|
||||
else
|
||||
ps_hex(prn, out, drawable->width * out_bpp);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -352,6 +404,77 @@ ps_hex(FILE *prn, /* I - File to print to */
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'ps_ascii85()' - Print binary data as a series of base-85 numbers.
|
||||
*/
|
||||
|
||||
static void
|
||||
ps_ascii85(FILE *prn, /* I - File to print to */
|
||||
guchar *data, /* I - Data to print */
|
||||
int length, /* I - Number of bytes to print */
|
||||
int last_line) /* I - Last line of raster data? */
|
||||
{
|
||||
unsigned b; /* Binary data word */
|
||||
unsigned char c[5]; /* ASCII85 encoded chars */
|
||||
int col; /* Current column */
|
||||
|
||||
|
||||
col = 0;
|
||||
while (length > 3)
|
||||
{
|
||||
b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3];
|
||||
|
||||
if (b == 0)
|
||||
putc('z', prn);
|
||||
else
|
||||
{
|
||||
c[4] = (b % 85) + '!';
|
||||
b /= 85;
|
||||
c[3] = (b % 85) + '!';
|
||||
b /= 85;
|
||||
c[2] = (b % 85) + '!';
|
||||
b /= 85;
|
||||
c[1] = (b % 85) + '!';
|
||||
b /= 85;
|
||||
c[0] = b + '!';
|
||||
|
||||
fwrite(c, 5, 1, prn);
|
||||
};
|
||||
|
||||
data += 4;
|
||||
length -= 4;
|
||||
|
||||
col = (col + 1) & 15;
|
||||
if (col == 0 && length > 0)
|
||||
putc('\n', prn);
|
||||
};
|
||||
|
||||
if (last_line)
|
||||
{
|
||||
if (length > 0)
|
||||
{
|
||||
for (b = 0, col = length; col > 0; b = (b << 8) | data[0], data ++, col --);
|
||||
|
||||
c[4] = (b % 85) + '!';
|
||||
b /= 85;
|
||||
c[3] = (b % 85) + '!';
|
||||
b /= 85;
|
||||
c[2] = (b % 85) + '!';
|
||||
b /= 85;
|
||||
c[1] = (b % 85) + '!';
|
||||
b /= 85;
|
||||
c[0] = b + '!';
|
||||
|
||||
fwrite(c, length + 1, 1, prn);
|
||||
};
|
||||
|
||||
fputs("~>\n", prn);
|
||||
}
|
||||
else
|
||||
putc('\n', prn);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id$".
|
||||
*/
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Print plug-in driver utility functions for the GIMP.
|
||||
*
|
||||
* Copyright 1997 Michael Sweet (mike@easysw.com)
|
||||
* Copyright 1997-1998 Michael Sweet (mike@easysw.com)
|
||||
*
|
||||
* 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
|
||||
|
@ -35,21 +35,15 @@
|
|||
* Revision History:
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.1.1.1 1997/11/24 22:04:34 sopwith
|
||||
* Let's try this import one last time.
|
||||
* Revision 1.2 1998/01/25 09:29:27 yosh
|
||||
* Plugin updates
|
||||
* Properly generated aa Makefile (still not built by default)
|
||||
* Sven's no args script patch
|
||||
*
|
||||
* Revision 1.3 1997/11/18 03:04:26 nobody
|
||||
* fixed ugly comment-bugs introduced by evil darkwing
|
||||
* keep out configuration empty dirs
|
||||
* --darkwing
|
||||
* -Yosh
|
||||
*
|
||||
* Revision 1.2 1997/11/17 05:43:57 nobody
|
||||
* updated ChangeLog
|
||||
* dropped non-working doc/Makefile entries
|
||||
* applied many fixes from the registry as well as the devel ML
|
||||
* applied missing patches by Art Haas
|
||||
*
|
||||
* --darkwing
|
||||
* Revision 1.8 1998/01/21 21:33:47 mike
|
||||
* Replaced Burkes dither with stochastic (random) dither.
|
||||
*
|
||||
* Revision 1.7 1997/10/02 17:57:26 mike
|
||||
* Replaced ordered dither with Burkes dither (error-diffusion).
|
||||
|
@ -127,44 +121,51 @@ dither_black(guchar *gray, /* I - Grayscale pixels */
|
|||
unsigned char bit, /* Current bit */
|
||||
*kptr; /* Current black pixel */
|
||||
int k, /* Current black error */
|
||||
ditherk, /* Next error value in buffer */
|
||||
*kerror0, /* Pointer to current error row */
|
||||
*kerror1; /* Pointer to next error row */
|
||||
int ditherbit; /* Random dithering bitmask */
|
||||
|
||||
|
||||
xstep = src_width / dst_width;
|
||||
xmod = src_width % dst_width;
|
||||
length = (dst_width + 7) / 8;
|
||||
|
||||
kerror0 = error[row & 1][3] + 2;
|
||||
kerror1 = error[1 - (row & 1)][3] + 2;
|
||||
kerror0 = error[row & 1][3] + 1;
|
||||
kerror1 = error[1 - (row & 1)][3] + 1;
|
||||
kerror1[0] = 0;
|
||||
kerror1[1] = 0;
|
||||
|
||||
memset(black, 0, length);
|
||||
|
||||
for (x = 0, bit = 128, kptr = black, xerror = 0;
|
||||
for (x = 0, bit = 128, kptr = black, xerror = 0,
|
||||
ditherbit = rand(), ditherk = *kerror0;
|
||||
x < dst_width;
|
||||
x ++, kerror0 ++, kerror1 ++)
|
||||
{
|
||||
k = 255 - *gray + *kerror0;
|
||||
k = 255 - *gray + ditherk / 4;
|
||||
if (k > 127)
|
||||
{
|
||||
*kptr |= bit;
|
||||
k -= 255;
|
||||
};
|
||||
|
||||
kerror0[1] += k / 4;
|
||||
kerror0[2] += k / 8;
|
||||
kerror1[-2] += k / 16;
|
||||
kerror1[-1] += k / 8;
|
||||
kerror1[0] += k / 4;
|
||||
kerror1[1] += k / 8;
|
||||
kerror1[2] = k / 16;
|
||||
if (ditherbit & bit)
|
||||
{
|
||||
kerror1[0] = 3 * k;
|
||||
ditherk = kerror0[1] + k;
|
||||
}
|
||||
else
|
||||
{
|
||||
kerror1[0] = k;
|
||||
ditherk = kerror0[1] + 3 * k;
|
||||
};
|
||||
|
||||
if (bit == 1)
|
||||
{
|
||||
kptr ++;
|
||||
bit = 128;
|
||||
bit = 128;
|
||||
ditherbit = rand();
|
||||
}
|
||||
else
|
||||
bit >>= 1;
|
||||
|
@ -205,18 +206,19 @@ dither_cmyk(guchar *rgb, /* I - RGB pixels */
|
|||
*mptr, /* Current magenta pixel */
|
||||
*yptr, /* Current yellow pixel */
|
||||
*kptr; /* Current black pixel */
|
||||
int cerror, /* Current cyan error */
|
||||
int ditherc, /* Next error value in buffer */
|
||||
*cerror0, /* Pointer to current error row */
|
||||
*cerror1; /* Pointer to next error row */
|
||||
int yerror, /* Current yellow error */
|
||||
int dithery, /* Next error value in buffer */
|
||||
*yerror0, /* Pointer to current error row */
|
||||
*yerror1; /* Pointer to next error row */
|
||||
int merror, /* Current magenta error */
|
||||
int ditherm, /* Next error value in buffer */
|
||||
*merror0, /* Pointer to current error row */
|
||||
*merror1; /* Pointer to next error row */
|
||||
int kerror, /* Current black error */
|
||||
int ditherk, /* Next error value in buffer */
|
||||
*kerror0, /* Pointer to current error row */
|
||||
*kerror1; /* Pointer to next error row */
|
||||
int ditherbit; /* Random dither bitmask */
|
||||
|
||||
|
||||
xstep = 3 * (src_width / dst_width);
|
||||
|
@ -250,7 +252,8 @@ dither_cmyk(guchar *rgb, /* I - RGB pixels */
|
|||
memset(black, 0, length);
|
||||
|
||||
for (x = 0, bit = 128, cptr = cyan, mptr = magenta, yptr = yellow, kptr=black,
|
||||
xerror = 0;
|
||||
xerror = 0, ditherbit = rand(), ditherc = cerror0[0],
|
||||
ditherm = merror0[0], dithery = yerror0[0], ditherk = kerror0[0];
|
||||
x < dst_width;
|
||||
x ++, cerror0 ++, cerror1 ++, merror0 ++, merror1 ++, yerror0 ++,
|
||||
yerror1 ++, kerror0 ++, kerror1 ++)
|
||||
|
@ -272,76 +275,89 @@ dither_cmyk(guchar *rgb, /* I - RGB pixels */
|
|||
y = 255 * (y - k) / ik;
|
||||
};
|
||||
|
||||
k += *kerror0;
|
||||
k += ditherk / 4;
|
||||
if (k > 127)
|
||||
{
|
||||
*kptr |= bit;
|
||||
k -= 255;
|
||||
};
|
||||
|
||||
kerror0[1] += k / 4;
|
||||
kerror0[2] += k / 8;
|
||||
kerror1[-2] += k / 16;
|
||||
kerror1[-1] += k / 8;
|
||||
kerror1[0] += k / 4;
|
||||
kerror1[1] += k / 8;
|
||||
kerror1[2] = k / 16;
|
||||
if (ditherbit & bit)
|
||||
{
|
||||
kerror1[0] = 3 * k;
|
||||
ditherk = kerror0[1] + k;
|
||||
}
|
||||
else
|
||||
{
|
||||
kerror1[0] = k;
|
||||
ditherk = kerror0[1] + 3 * k;
|
||||
};
|
||||
|
||||
if (bit == 1)
|
||||
kptr ++;
|
||||
};
|
||||
|
||||
c += *cerror0;
|
||||
c += ditherc / 4;
|
||||
if (c > 127)
|
||||
{
|
||||
*cptr |= bit;
|
||||
c -= 255;
|
||||
};
|
||||
|
||||
cerror0[1] += c / 4;
|
||||
cerror0[2] += c / 8;
|
||||
cerror1[-2] += c / 16;
|
||||
cerror1[-1] += c / 8;
|
||||
cerror1[0] += c / 4;
|
||||
cerror1[1] += c / 8;
|
||||
cerror1[2] = c / 16;
|
||||
if (ditherbit & bit)
|
||||
{
|
||||
cerror1[0] = 3 * c;
|
||||
ditherc = cerror0[1] + c;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerror1[0] = c;
|
||||
ditherc = cerror0[1] + 3 * c;
|
||||
};
|
||||
|
||||
m += *merror0;
|
||||
m += ditherm / 4;
|
||||
if (m > 127)
|
||||
{
|
||||
*mptr |= bit;
|
||||
m -= 255;
|
||||
};
|
||||
|
||||
merror0[1] += m / 4;
|
||||
merror0[2] += m / 8;
|
||||
merror1[-2] += m / 16;
|
||||
merror1[-1] += m / 8;
|
||||
merror1[0] += m / 4;
|
||||
merror1[1] += m / 8;
|
||||
merror1[2] = m / 16;
|
||||
if (ditherbit & bit)
|
||||
{
|
||||
merror1[0] = 3 * m;
|
||||
ditherm = merror0[1] + m;
|
||||
}
|
||||
else
|
||||
{
|
||||
merror1[0] = m;
|
||||
ditherm = merror0[1] + 3 * m;
|
||||
};
|
||||
|
||||
y += *yerror0;
|
||||
y += dithery / 4;
|
||||
if (y > 127)
|
||||
{
|
||||
*yptr |= bit;
|
||||
y -= 255;
|
||||
};
|
||||
|
||||
yerror0[1] += y / 4;
|
||||
yerror0[2] += y / 8;
|
||||
yerror1[-2] += y / 16;
|
||||
yerror1[-1] += y / 8;
|
||||
yerror1[0] += y / 4;
|
||||
yerror1[1] += y / 8;
|
||||
yerror1[2] = y / 16;
|
||||
if (ditherbit & bit)
|
||||
{
|
||||
yerror1[0] = 3 * y;
|
||||
dithery = yerror0[1] + y;
|
||||
}
|
||||
else
|
||||
{
|
||||
yerror1[0] = y;
|
||||
dithery = yerror0[1] + 3 * y;
|
||||
};
|
||||
|
||||
if (bit == 1)
|
||||
{
|
||||
cptr ++;
|
||||
mptr ++;
|
||||
yptr ++;
|
||||
bit = 128;
|
||||
bit = 128;
|
||||
ditherbit = rand();
|
||||
}
|
||||
else
|
||||
bit >>= 1;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Print plug-in for the GIMP.
|
||||
*
|
||||
* Copyright 1997 Michael Sweet (mike@easysw.com)
|
||||
* Copyright 1997-1998 Michael Sweet (mike@easysw.com)
|
||||
*
|
||||
* 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
|
||||
|
@ -39,21 +39,22 @@
|
|||
* Revision History:
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.1.1.1 1997/11/24 22:04:34 sopwith
|
||||
* Let's try this import one last time.
|
||||
* Revision 1.2 1998/01/25 09:29:27 yosh
|
||||
* Plugin updates
|
||||
* Properly generated aa Makefile (still not built by default)
|
||||
* Sven's no args script patch
|
||||
*
|
||||
* Revision 1.3 1997/11/18 03:04:27 nobody
|
||||
* fixed ugly comment-bugs introduced by evil darkwing
|
||||
* keep out configuration empty dirs
|
||||
* --darkwing
|
||||
* -Yosh
|
||||
*
|
||||
* Revision 1.2 1997/11/17 05:43:57 nobody
|
||||
* updated ChangeLog
|
||||
* dropped non-working doc/Makefile entries
|
||||
* applied many fixes from the registry as well as the devel ML
|
||||
* applied missing patches by Art Haas
|
||||
* Revision 1.13 1998/01/22 15:06:31 mike
|
||||
* Added "file" printer for printing to file.
|
||||
* Now you don't need the "|" in front of print commands.
|
||||
* Now "remembers" last selected printer.
|
||||
*
|
||||
* --darkwing
|
||||
* Revision 1.12 1998/01/21 21:33:47 mike
|
||||
* Added Level 2 PostScript driver.
|
||||
* Fixed bug in dialog - didn't display correct output file/command
|
||||
* and driver for the default printer.
|
||||
*
|
||||
* Revision 1.11 1997/11/14 17:17:59 mike
|
||||
* Updated to dynamically allocate return params in the run() function.
|
||||
|
@ -180,8 +181,8 @@ struct /* Plug-in variables */
|
|||
top; /* ... */
|
||||
} vars =
|
||||
{
|
||||
"|lp", /* Name of file or command to print to */
|
||||
"ps", /* Name of printer "driver" */
|
||||
"", /* Name of file or command to print to */
|
||||
"ps2", /* Name of printer "driver" */
|
||||
MEDIA_LETTER, /* Size of output media */
|
||||
OUTPUT_COLOR, /* Color or grayscale output */
|
||||
100, /* Output brightness */
|
||||
|
@ -218,6 +219,7 @@ int runme = FALSE, /* True if print should proceed */
|
|||
printer_t printers[] = /* List of supported printer types */
|
||||
{
|
||||
{ "PostScript Printer", "ps", 72, 72, 1, 1, 0, 1.000, 1.000, ps_print },
|
||||
{ "PostScript Printer (Level 2)", "ps2", 72, 72, 1, 1, 1, 1.000, 1.000, ps_print },
|
||||
{ "HP DeskJet 500, 520", "pcl-500", 300, 300, 0, 0, 500, 0.541, 0.548, pcl_print },
|
||||
{ "HP DeskJet 500C, 540C", "pcl-501", 300, 300, 0, 1, 501, 0.541, 0.548, pcl_print },
|
||||
{ "HP DeskJet 550C, 560C", "pcl-550", 300, 300, 0, 1, 550, 0.541, 0.548, pcl_print },
|
||||
|
@ -445,8 +447,8 @@ run(char *name, /* I - Name of print program. */
|
|||
* Open the file/execute the print command...
|
||||
*/
|
||||
|
||||
if (vars.output_to[0] == '|')
|
||||
prn = popen(vars.output_to + 1, "w");
|
||||
if (plist_current > 0)
|
||||
prn = popen(vars.output_to, "w");
|
||||
else
|
||||
prn = fopen(vars.output_to, "w");
|
||||
|
||||
|
@ -491,7 +493,7 @@ run(char *name, /* I - Name of print program. */
|
|||
vars.output_type, printer->model, lut, cmap,
|
||||
vars.orientation, vars.scaling, vars.left, vars.top);
|
||||
|
||||
if (vars.output_to[0] == '|')
|
||||
if (plist_current > 0)
|
||||
pclose(prn);
|
||||
else
|
||||
fclose(prn);
|
||||
|
@ -573,7 +575,7 @@ print_dialog(void)
|
|||
*/
|
||||
|
||||
dialog = gtk_dialog_new();
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), "Print");
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), "Print " PLUG_IN_VERSION);
|
||||
gtk_window_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
|
||||
gtk_container_border_width(GTK_CONTAINER(dialog), 0);
|
||||
gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
|
||||
|
@ -627,9 +629,6 @@ print_dialog(void)
|
|||
menu = gtk_menu_new();
|
||||
for (i = 0; i < plist_count; i ++)
|
||||
{
|
||||
if (strcmp(plist[i].command, vars.output_to) == 0)
|
||||
plist_current = i;
|
||||
|
||||
item = gtk_menu_item_new_with_label(plist[i].name);
|
||||
gtk_menu_append(GTK_MENU(menu), item);
|
||||
gtk_signal_connect(GTK_OBJECT(item), "activate",
|
||||
|
@ -770,7 +769,7 @@ print_dialog(void)
|
|||
* Print file/command...
|
||||
*/
|
||||
|
||||
label = gtk_label_new("File/|Command:");
|
||||
label = gtk_label_new("File/Command:");
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
|
||||
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 11, 12, GTK_FILL, GTK_FILL, 4, 0);
|
||||
gtk_widget_show(label);
|
||||
|
@ -809,6 +808,8 @@ print_dialog(void)
|
|||
* Show it and wait for the user to do something...
|
||||
*/
|
||||
|
||||
plist_callback(NULL, plist_current);
|
||||
|
||||
gtk_widget_show(dialog);
|
||||
|
||||
gtk_main();
|
||||
|
@ -1269,9 +1270,18 @@ printrc_load(void)
|
|||
|
||||
if (sscanf(line, "%s%s%d%*[ \t]%[^\n]", key.name, key.driver,
|
||||
&(key.output_type), key.command) == 4)
|
||||
if ((p = bsearch(&key, plist, plist_count, sizeof(plist_t),
|
||||
{
|
||||
/*
|
||||
* Check to see if this is an old printrc file...
|
||||
*/
|
||||
|
||||
if (key.command[0] == '|')
|
||||
strcpy(key.command, key.command + 1);
|
||||
|
||||
if ((p = bsearch(&key, plist + 1, plist_count - 1, sizeof(plist_t),
|
||||
(int (*)(const void *, const void *))compare_printers)) != NULL)
|
||||
memcpy(p, &key, sizeof(plist_t));
|
||||
};
|
||||
};
|
||||
|
||||
fclose(fp);
|
||||
|
@ -1309,7 +1319,7 @@ printrc_save(void)
|
|||
|
||||
fputs("#PRINTRC " PLUG_IN_VERSION "\n", fp);
|
||||
|
||||
for (i = 0, p = plist; i < plist_count; i ++, p ++)
|
||||
for (i = 1, p = plist + 1; i < plist_count; i ++, p ++)
|
||||
fprintf(fp, "%s %s %d %s\n", p->name, p->driver, p->output_type, p->command);
|
||||
|
||||
fclose(fp);
|
||||
|
@ -1346,10 +1356,14 @@ get_printers(void)
|
|||
defname[0] = '\0';
|
||||
|
||||
memset(plist, 0, sizeof(plist));
|
||||
plist_count = 1;
|
||||
strcpy(plist[0].name, "File");
|
||||
sprintf(plist[0].command, "file.ps", line);
|
||||
strcpy(plist[0].driver, "ps2");
|
||||
plist[0].output_type = OUTPUT_COLOR;
|
||||
|
||||
#ifndef sun /* Sun Solaris merges LPR and LP queues */
|
||||
if (access("/usr/etc/lpc", 0) == 0 &&
|
||||
(pfile = popen("/usr/etc/lpc status", "r")) != NULL)
|
||||
if ((pfile = popen("lpc status", "r")) != NULL)
|
||||
{
|
||||
while (fgets(line, sizeof(line), pfile) != NULL &&
|
||||
plist_count < MAX_PLIST)
|
||||
|
@ -1357,8 +1371,8 @@ get_printers(void)
|
|||
{
|
||||
*strchr(line, ':') = '\0';
|
||||
strcpy(plist[plist_count].name, line);
|
||||
sprintf(plist[plist_count].command, "|lpr -P%s -l", line);
|
||||
strcpy(plist[plist_count].driver, "ps");
|
||||
sprintf(plist[plist_count].command, "lpr -P%s -l", line);
|
||||
strcpy(plist[plist_count].driver, "ps2");
|
||||
plist[plist_count].output_type = OUTPUT_COLOR;
|
||||
plist_count ++;
|
||||
};
|
||||
|
@ -1367,8 +1381,7 @@ get_printers(void)
|
|||
};
|
||||
#endif /* !sun */
|
||||
|
||||
if (access("/usr/bin/lpstat", 0) == 0 &&
|
||||
(pfile = popen("/usr/bin/lpstat -d -p", "r")) != NULL)
|
||||
if ((pfile = popen("lpstat -d -p", "r")) != NULL)
|
||||
{
|
||||
while (fgets(line, sizeof(line), pfile) != NULL &&
|
||||
plist_count < MAX_PLIST)
|
||||
|
@ -1377,11 +1390,11 @@ get_printers(void)
|
|||
{
|
||||
strcpy(plist[plist_count].name, name);
|
||||
#ifdef __sgi /* SGI still uses the SVR3 spooler */
|
||||
sprintf(plist[plist_count].command, "|lp -s -oraw -d%s", name);
|
||||
sprintf(plist[plist_count].command, "lp -s -d%s", name);
|
||||
#else
|
||||
sprintf(plist[plist_count].command, "|lp -s -oraw -d %s", name);
|
||||
sprintf(plist[plist_count].command, "lp -s -d %s", name);
|
||||
#endif /* __sgi */
|
||||
strcpy(plist[plist_count].driver, "ps");
|
||||
strcpy(plist[plist_count].driver, "ps2");
|
||||
plist[plist_count].output_type = OUTPUT_COLOR;
|
||||
plist_count ++;
|
||||
}
|
||||
|
@ -1392,16 +1405,25 @@ get_printers(void)
|
|||
pclose(pfile);
|
||||
};
|
||||
|
||||
if (plist_count > 1)
|
||||
qsort(plist, plist_count, sizeof(plist_t),
|
||||
if (plist_count > 2)
|
||||
qsort(plist + 1, plist_count - 1, sizeof(plist_t),
|
||||
(int (*)(const void *, const void *))compare_printers);
|
||||
|
||||
if (defname[0] != '\0')
|
||||
if (defname[0] != '\0' && vars.output_to[0] == '\0')
|
||||
{
|
||||
for (i = 0; i < plist_count; i ++)
|
||||
if (strcmp(defname, plist[i].name) == 0)
|
||||
break;
|
||||
|
||||
if (i < plist_count)
|
||||
plist_current = i;
|
||||
}
|
||||
else if (vars.output_to[0] != '\0')
|
||||
{
|
||||
for (i = 0; i < plist_count; i ++)
|
||||
if (strcmp(vars.output_to, plist[i].command) == 0)
|
||||
break;
|
||||
|
||||
if (i < plist_count)
|
||||
plist_current = i;
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Print plug-in header file for the GIMP.
|
||||
*
|
||||
* Copyright 1997 Michael Sweet (mike@easysw.com)
|
||||
* Copyright 1997-1998 Michael Sweet (mike@easysw.com)
|
||||
*
|
||||
* 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
|
||||
|
@ -22,21 +22,17 @@
|
|||
* Revision History:
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.1.1.1 1997/11/24 22:04:34 sopwith
|
||||
* Let's try this import one last time.
|
||||
* Revision 1.2 1998/01/25 09:29:28 yosh
|
||||
* Plugin updates
|
||||
* Properly generated aa Makefile (still not built by default)
|
||||
* Sven's no args script patch
|
||||
*
|
||||
* Revision 1.3 1997/11/18 03:04:27 nobody
|
||||
* fixed ugly comment-bugs introduced by evil darkwing
|
||||
* keep out configuration empty dirs
|
||||
* --darkwing
|
||||
* -Yosh
|
||||
*
|
||||
* Revision 1.2 1997/11/17 05:43:57 nobody
|
||||
* updated ChangeLog
|
||||
* dropped non-working doc/Makefile entries
|
||||
* applied many fixes from the registry as well as the devel ML
|
||||
* applied missing patches by Art Haas
|
||||
*
|
||||
* --darkwing
|
||||
* Revision 1.9 1998/01/21 21:33:47 mike
|
||||
* Added Level 2 PostScript driver.
|
||||
* Replaced Burkes dither with stochastic (random) dither.
|
||||
* Now use Level 2 ASCII85 filter for Level 2 printers.
|
||||
*
|
||||
* Revision 1.8 1997/11/14 17:17:59 mike
|
||||
* Updated to dynamically allocate return params in the run() function.
|
||||
|
@ -89,7 +85,7 @@
|
|||
* Constants...
|
||||
*/
|
||||
|
||||
#define PLUG_IN_VERSION "1.2.2 - 14 November 1997"
|
||||
#define PLUG_IN_VERSION "1.3 - 22 January 1998"
|
||||
#define PLUG_IN_NAME "Print"
|
||||
|
||||
#define MEDIA_LETTER 0 /* 8.5x11" a.k.a. "A" size */
|
||||
|
|
|
@ -508,6 +508,7 @@ script_fu_script_proc (char *name,
|
|||
GStatusType status = STATUS_SUCCESS;
|
||||
GRunModeType run_mode;
|
||||
SFScript *script;
|
||||
int min_args;
|
||||
|
||||
run_mode = params[0].data.d_int32;
|
||||
|
||||
|
@ -530,8 +531,12 @@ script_fu_script_proc (char *name,
|
|||
script->image_based = FALSE;
|
||||
|
||||
/* First acquire information with a dialog */
|
||||
script_fu_interface (script);
|
||||
break;
|
||||
/* Skip this part if the script takes no parameters */
|
||||
min_args = (script->image_based) ? 2 : 0;
|
||||
if (script->num_args > min_args) {
|
||||
script_fu_interface (script);
|
||||
break;
|
||||
}
|
||||
|
||||
case RUN_NONINTERACTIVE:
|
||||
/* Make sure all the arguments are there! */
|
||||
|
|
|
@ -508,6 +508,7 @@ script_fu_script_proc (char *name,
|
|||
GStatusType status = STATUS_SUCCESS;
|
||||
GRunModeType run_mode;
|
||||
SFScript *script;
|
||||
int min_args;
|
||||
|
||||
run_mode = params[0].data.d_int32;
|
||||
|
||||
|
@ -530,8 +531,12 @@ script_fu_script_proc (char *name,
|
|||
script->image_based = FALSE;
|
||||
|
||||
/* First acquire information with a dialog */
|
||||
script_fu_interface (script);
|
||||
break;
|
||||
/* Skip this part if the script takes no parameters */
|
||||
min_args = (script->image_based) ? 2 : 0;
|
||||
if (script->num_args > min_args) {
|
||||
script_fu_interface (script);
|
||||
break;
|
||||
}
|
||||
|
||||
case RUN_NONINTERACTIVE:
|
||||
/* Make sure all the arguments are there! */
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
; along with this program; if not, write to the Free Software
|
||||
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
;
|
||||
; "Copy Visible" version 0.05 10/19/97
|
||||
; "Copy Visible" version 0.11 01/24/98
|
||||
; by Adrian Likins <adrian@gimp.org>
|
||||
; _heavily_ based on:
|
||||
; cyn-merge.scm version 0.02 10/10/97
|
||||
|
@ -26,9 +26,10 @@
|
|||
drawable)
|
||||
(let* ((layers (gimp-image-get-layers image))
|
||||
(num-layers (car layers))
|
||||
(num-visi-layers 0)
|
||||
(layer-array (cadr layers)))
|
||||
|
||||
(gimp-image-disable-undo image)
|
||||
(gimp-undo-push-group-start image)
|
||||
|
||||
; copy all visible layers and make them invisible
|
||||
(set! layer-count 1)
|
||||
|
@ -42,35 +43,39 @@
|
|||
(set! copy (car (gimp-layer-copy layer TRUE)))
|
||||
(gimp-image-add-layer image copy -1)
|
||||
(gimp-layer-set-visible copy TRUE)
|
||||
(gimp-layer-set-visible layer FALSE)))
|
||||
(gimp-layer-set-visible layer FALSE)
|
||||
(set! num-visi-layers (+ num-visi-layers 1))))
|
||||
(set! layer-count (+ layer-count 1)))
|
||||
|
||||
; merge all visible layers
|
||||
;changed
|
||||
(set! merged-layer (car (gimp-image-merge-visible-layers image EXPAND-AS-NECESSARY)))
|
||||
|
||||
(if (> num-visi-layers 1)
|
||||
(set! merged-layer (car (gimp-image-merge-visible-layers image EXPAND-AS-NECESSARY)))
|
||||
(if (> num-visi-layers 0)
|
||||
(set! merged-layer copy)))
|
||||
|
||||
(if (> num-visi-layers 0)
|
||||
(begin
|
||||
(gimp-edit-copy image merged-layer)
|
||||
(gimp-image-remove-layer image merged-layer)))
|
||||
|
||||
; restore the layers visibilty
|
||||
(set! layer-count 0)
|
||||
(while (< layer-count num-layers)
|
||||
(set! layer (aref layer-array layer-count))
|
||||
(gimp-layer-set-visible layer (aref visi-array layer-count))
|
||||
(set! layer-count (+ layer-count 1)))
|
||||
;changed
|
||||
(gimp-edit-copy image merged-layer)
|
||||
|
||||
(gimp-image-set-active-layer image drawable)
|
||||
(gimp-image-remove-layer image merged-layer)
|
||||
|
||||
(gimp-image-enable-undo image)
|
||||
(gimp-undo-push-group-end image)
|
||||
(gimp-displays-flush)))
|
||||
|
||||
(script-fu-register "script-fu-copy-visible"
|
||||
; I use the script under the edit menu, but probabaly bad style for a dist version.
|
||||
; "<Image>/Edit/Copy Visible"
|
||||
"<Image>/Script-Fu/Selection/Copy Visible"
|
||||
"<Image>/Edit/Copy Visible"
|
||||
"Copy the visible selction"
|
||||
"Sven Neumann (neumanns@uni-duesseldorf.de), Adrian Likins <adrian@gimp.org>"
|
||||
"Sven Neumann, Adrian Likins"
|
||||
"10/19/1997"
|
||||
"01/24/1998"
|
||||
"RGB* INDEXED* GRAY*"
|
||||
SF-IMAGE "Image" 0
|
||||
SF-DRAWABLE "Drawable" 0)
|
||||
|
|
Loading…
Reference in a new issue