Gimp/plug-ins/common/aa.c
Michael Natterer c55bbde079 app/gimpui.[ch] removed & renamed some functions from gimpui.[ch] (see
2000-01-13  Michael Natterer  <mitch@gimp.org>

	* app/gimpui.[ch]
	* app/preferences_dialog.c: removed & renamed some functions from
	gimpui.[ch] (see below).

	* libgimp/Makefile.am
	* libgimp/gimpwidgets.[ch]; new files. Functions moved from
	app/gimpui.[ch]. Added a constructor for the label + hscale +
	entry combination used in many plugins (now hscale + spinbutton).

	* libgimp/gimpui.h: include gimpwidgets.h

	* plug-ins/megawidget/megawidget.[ch]: removed all functions
	except the preview stuff (I'm not yet sure how to implement this
	in libgimp because the libgimp preview should be general enough to
	replace all the other plugin previews, too).

	* plug-ins/borderaverage/Makefile.am
	* plug-ins/borderaverage/borderaverage.c
	* plug-ins/common/plugin-defs.pl
	* plug-ins/common/Makefile.am
	* plug-ins/common/aa.c
	* plug-ins/common/align_layers.c
	* plug-ins/common/animationplay.c
	* plug-ins/common/apply_lens.c
	* plug-ins/common/blinds.c
	* plug-ins/common/bumpmap.c
	* plug-ins/common/checkerboard.c
	* plug-ins/common/colorify.c
	* plug-ins/common/convmatrix.c
	* plug-ins/common/cubism.c
	* plug-ins/common/curve_bend.c
	* plug-ins/common/deinterlace.c
	* plug-ins/common/despeckle.c
	* plug-ins/common/destripe.c
	* plug-ins/common/displace.c
	* plug-ins/common/edge.c
	* plug-ins/common/emboss.c
	* plug-ins/common/hot.c
	* plug-ins/common/nlfilt.c
	* plug-ins/common/pixelize.c
	* plug-ins/common/waves.c
	* plug-ins/sgi/sgi.c
	* plug-ins/sinus/sinus.c: ui updates like removing megawidget,
	using the dialog constructor, I18N fixes, indentation, ...
2000-01-13 15:39:26 +00:00

423 lines
9.7 KiB
C

/**
* aa.c version 1.0
* A plugin that uses libaa (ftp://ftp.ta.jcu.cz/pub/aa) to save images as
* ASCII.
* NOTE: This plugin *requires* aalib 1.2 or later. Earlier versions will
* not work.
* Code copied from all over the GIMP source.
* Tim Newsome <nuisance@cmu.edu>
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <aalib.h>
#include <gtk/gtk.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "libgimp/stdplugins-intl.h"
/*
* Declare some local functions.
*/
static void query (void);
static void run (gchar *name,
gint nparams,
GParam *param,
gint *nreturn_vals,
GParam **return_vals);
static void init_gtk (void);
static gboolean aa_savable (gint32 drawable_ID);
static gboolean save_aa (gint output_type,
gchar *filename,
gint32 image,
gint32 drawable);
static void gimp2aa (gint32 image,
gint32 drawable_ID,
aa_context *context);
static gint type_dialog (int selected);
static void type_dialog_ok_callback (GtkWidget *widget,
gpointer data);
static void type_dialog_toggle_update (GtkWidget *widget,
gpointer data);
static void type_dialog_cancel_callback (GtkWidget *widget,
gpointer data);
/*
* Some global variables.
*/
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
/**
* Type the user selected. (Global for easier UI coding.)
*/
static gint selected_type = 0;
MAIN ()
static void
query (void)
{
static GParamDef save_args[] =
{
{PARAM_INT32, "run_mode", "Interactive, non-interactive"},
{PARAM_IMAGE, "image", "Input image"},
{PARAM_DRAWABLE, "drawable", "Drawable to save"},
{PARAM_STRING, "filename", "The name of the file to save the image in"},
{PARAM_STRING, "raw_filename", "The name entered"},
{PARAM_STRING, "file_type", "File type to use"}
};
static int nsave_args = sizeof(save_args) / sizeof(save_args[0]);
INIT_I18N();
gimp_install_procedure ("file_aa_save",
_("Saves files in various text formats"),
_("Saves files in various text formats"),
"Tim Newsome <nuisance@cmu.edu>",
"Tim Newsome <nuisance@cmu.edu>",
"1997",
"<Save>/AA",
"GRAY*", /* support grayscales */
PROC_PLUG_IN,
nsave_args, 0,
save_args, NULL);
gimp_register_save_handler ("file_aa_save", "ansi,txt,text,html", "");
}
/**
* Searches aa_formats defined by aalib to find the index of the type
* specified by string.
* -1 means it wasn't found.
*/
static int
get_type_from_string (char *string)
{
int type = 0;
aa_format **p = aa_formats;
while (*p && strcmp ((*p)->formatname, string))
{
p++;
type++;
}
if (*p == NULL)
return -1;
return type;
}
static void
run (gchar *name,
gint nparams,
GParam *param,
gint *nreturn_vals,
GParam **return_vals)
{
static GParam values[2];
GStatusType status = STATUS_SUCCESS;
GRunModeType run_mode;
gint output_type = 0;
static int last_type = 0;
gint32 image_ID;
gint32 drawable_ID;
GimpExportReturnType export = EXPORT_CANCEL;
/* Set us up to return a status. */
*nreturn_vals = 1;
*return_vals = values;
values[0].type = PARAM_STATUS;
values[0].data.d_status = STATUS_CALLING_ERROR;
run_mode = param[0].data.d_int32;
image_ID = param[1].data.d_int32;
drawable_ID = param[2].data.d_int32;
/* eventually export the image */
switch (run_mode)
{
case RUN_INTERACTIVE:
case RUN_WITH_LAST_VALS:
INIT_I18N_UI();
init_gtk ();
export = gimp_export_image (&image_ID, &drawable_ID, "AA",
(CAN_HANDLE_GRAY | CAN_HANDLE_ALPHA));
if (export == EXPORT_CANCEL)
{
values[0].data.d_status = STATUS_EXECUTION_ERROR;
return;
}
break;
default:
INIT_I18N();
break;
}
if (!aa_savable (drawable_ID))
{
values[0].data.d_status = STATUS_CALLING_ERROR;
goto finish;
}
switch (run_mode)
{
case RUN_INTERACTIVE:
gimp_get_data ("file_aa_save", &last_type);
output_type = type_dialog (last_type);
break;
case RUN_NONINTERACTIVE:
/* Make sure all the arguments are there! */
if (nparams != 6)
status = STATUS_CALLING_ERROR;
else
output_type = get_type_from_string (param[5].data.d_string);
break;
case RUN_WITH_LAST_VALS:
gimp_get_data ("file_aa_save", &last_type);
output_type = last_type;
break;
default:
break;
}
if (output_type < 0)
{
status = STATUS_CALLING_ERROR;
goto finish;
}
if (save_aa (output_type, param[3].data.d_string, image_ID, drawable_ID))
{
values[0].data.d_status = STATUS_EXECUTION_ERROR;
last_type = output_type;
gimp_set_data ("file_aa_save", &last_type, sizeof(last_type));
}
else
values[0].data.d_status = STATUS_SUCCESS;
finish:
if (export == EXPORT_EXPORT)
gimp_image_delete (image_ID);
}
/**
* The actual save function. What it's all about.
* The image type has to be GRAY.
*/
static gboolean
save_aa (gint output_type,
gchar *filename,
gint32 image_ID,
gint32 drawable_ID)
{
aa_savedata savedata = {NULL, NULL};
aa_context *context = NULL;
GDrawable *drawable = NULL;
aa_format format;
/*fprintf(stderr, "save %s\n", filename); */
drawable = gimp_drawable_get (drawable_ID);
memcpy (&format, aa_formats[output_type], sizeof (format));
format.width = drawable->width / 2;
format.height = drawable->height / 2;
/*fprintf(stderr, "save_aa %i x %i\n", format.width, format.height); */
/* Get a libaa context which will save its output to filename. */
savedata.name = filename;
savedata.format = &format;
context = aa_init (&save_d, &aa_defparams, &savedata);
if (context == NULL)
return TRUE;
gimp2aa (image_ID, drawable_ID, context);
aa_flush (context);
aa_close (context);
/*fprintf(stderr, "Success!\n"); */
return FALSE;
}
static void
gimp2aa (gint32 image,
gint32 drawable_ID,
aa_context *context)
{
gint width, height, x, y;
guchar *buffer;
GDrawable *drawable = NULL;
GPixelRgn pixel_rgn;
aa_renderparams *renderparams = NULL;
gint bpp;
width = aa_imgwidth (context);
height = aa_imgheight (context);
/*fprintf(stderr, "gimp2aa %i x %i\n", width, height); */
drawable = gimp_drawable_get (drawable_ID);
bpp = drawable->bpp;
buffer = g_new (guchar, width * bpp);
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width,
drawable->height, FALSE, FALSE);
for (y = 0; y < height; y++)
{
gimp_pixel_rgn_get_row (&pixel_rgn, buffer, 0, y, width);
for (x = 0; x < width; x++)
{
/* Just copy one byte. If it's indexed that's all we need. Otherwise
* it'll be the most significant one. */
aa_putpixel (context, x, y, buffer[x * bpp]);
}
}
renderparams = aa_getrenderparams ();
renderparams->dither = AA_FLOYD_S;
aa_render (context, renderparams, 0, 0,
aa_scrwidth (context), aa_scrheight (context));
}
static gboolean
aa_savable (gint32 drawable_ID)
{
GDrawableType drawable_type;
drawable_type = gimp_drawable_type (drawable_ID);
if (drawable_type != GRAY_IMAGE && drawable_type != GRAYA_IMAGE)
return FALSE;
return TRUE;
}
/*
* User Interface dialog thingie.
*/
static void
init_gtk (void)
{
gchar **argv;
gint argc;
argc = 1;
argv = g_new (gchar *, 1);
argv[0] = g_strdup ("aa");
gtk_init (&argc, &argv);
gtk_rc_parse (gimp_gtkrc ());
}
static gint
type_dialog (int selected)
{
GtkWidget *dlg;
GtkWidget *toggle;
GtkWidget *frame;
GtkWidget *toggle_vbox;
GSList *group;
/* Create the actual window. */
dlg = gimp_dialog_new (_("Save as Text"), "aa",
gimp_plugin_help_func, "filters/aa.html",
GTK_WIN_POS_MOUSE,
FALSE, TRUE, FALSE,
_("OK"), gtk_widget_destroy,
NULL, 1, NULL, TRUE, FALSE,
_("Cancel"), type_dialog_cancel_callback,
NULL, NULL, NULL, FALSE, TRUE,
NULL);
gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
GTK_SIGNAL_FUNC (gtk_main_quit),
NULL);
/* file save type */
frame = gtk_frame_new (_("Data Formatting"));
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dlg)->vbox), frame, TRUE, TRUE, 0);
toggle_vbox = gtk_vbox_new (FALSE, 2);
gtk_container_set_border_width (GTK_CONTAINER(toggle_vbox), 4);
gtk_container_add (GTK_CONTAINER (frame), toggle_vbox);
group = NULL;
{
aa_format **p = aa_formats;
gint current = 0;
while (*p != NULL)
{
toggle = gtk_radio_button_new_with_label (group, (*p)->formatname);
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
gtk_box_pack_start (GTK_BOX (toggle_vbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
GTK_SIGNAL_FUNC (type_dialog_toggle_update),
(*p)->formatname);
if (current == selected)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), TRUE);
gtk_widget_show (toggle);
p++;
current++;
}
}
gtk_widget_show (toggle_vbox);
gtk_widget_show (frame);
gtk_widget_show (dlg);
gtk_main ();
gdk_flush ();
return selected_type;
}
/*
* Callbacks for the dialog.
*/
static void
type_dialog_cancel_callback (GtkWidget *widget,
gpointer data)
{
selected_type = -1;
gtk_widget_destroy (GTK_WIDGET (data));
}
static void
type_dialog_toggle_update (GtkWidget *widget,
gpointer data)
{
selected_type = get_type_from_string ((char *)data);
}