The following programs represent two templates, one with and one without preview function.
#include <stdlib.h> #include "gimp.h" #define INVALID_IMAGE_TYPE "newfilter: cannot operate on indexed or unknown image type" static void newfilter (Image, Image); static char *prog_name; Image input, output; int main (int argc, char **argv) { prog_name = argv[0]; if (!gimp_init (argc, argv)) exit (0); input = 0; output = 0; if (!(input = gimp_get_input_image (0)) { gimp_quit (); exit (0); } if (!(output = gimp_get_output_image (0)) { gimp_free_image (input); gimp_quit (); exit (); } switch (gimp_image_type (input)) { case RGB_IMAGE: case GRAY_IMAGE: newfilter (input, output); gimp_update_image (output); break; case INDEXED_IMAGE: gimp_message (INVALID_IMAGE_TYPE); break; default: gimp_message (INVALID_IMAGE_TYPE); break; } gimp_free_image (input); gimp_free_image (output); gimp_quit (); return 0; } static void newfilter (Image linput, Image loutput) { long width, height, channels, rowstride; unsigned char *src_row, *dest_row, *src, *dest; short row, col; int x1, y1, x2, y2, i; gimp_image_area (linput, &x1, &y1, &x2, &y2); width = gimp_image_width (linput); height = gimp_image_height (linput); channels = gimp_image_channels (linput); rowstride = width * channels; src_row = gimp_image_data (linput); dest_row = gimp_image_data (loutput); x1 *= channels; x2 *= channels; src_row += rowstride * y1 + x1; dest_row += rowstride * y1 + x1; for (row = y1; row < y2; row++) { src = src_row; dest = dest_row; for (col = x1; col < x2; col++) { for (i = 0; i < channels; i++) *dest++ = *src++; } src_row += rowstride; dest_row += rowstride; } }
#include <stdlib.h> #include "gimp.h" #define INVALID_IMAGE_TYPE "newfilter: cannot operate on indexed or unknown image type" #define DIALOG_TITLE "newfilter" static void newfilter (Image, Image); static void cb_ok (int, void *, void *); static void cb_cancel (int, void *, void *); static void cb_toggle (int, void *, void *); static void saveimage (void); static void freshen (void); static void init_dialog (void); static char *prog_name; static int dialog_ID; static long aapply; static int aapply_ID; Image input, output; static unsigned char *saved; int main (int argc, char **argv) { int text_ID, frame_ID, main_ID, grp_ID; prog_name = argv[0]; if (!gimp_init (argc, argv)) exit (0); input = 0; output = 0; if (!(input = gimp_get_input_image (0))) { gimp_quit (); exit (0); } if (!(output = gimp_get_output_image (0))) { gimp_free_image (input); gimp_quit (); exit (0); } switch (gimp_image_type (input)) { case RGB_IMAGE: case GRAY_IMAGE: saveimage (); init_dialog (); newfilter (input, output); gimp_update_image (output); if (!gimp_show_dialog (dialog_ID)) freshen (); else newfilter (input, output); gimp_update_image (output); free (saved); break; case INDEXED_IMAGE: gimp_message (INVALID_IMAGE_TYPE); break; default: gimp_message (INVALID_IMAGE_TYPE); break; } gimp_free_image (input); gimp_free_image (output); gimp_quit (); return 0; } static void init_dialog (void) { dialog_ID = gimp_new_dialog (DIALOG_TITLE); main_ID = gimp_new_row_group (dialog_ID, DEFAULT, NORMAL, ""); aapply_ID = gimp_new_check_button (dialog_ID, main_ID, "Auto Apply"); aapply = 1; gimp_change_item (dialog_ID, aapply_ID, sizeof (aapply), &aapply); gimp_add_callback (dialog_ID, aapply_ID, cb_toggle, &aapply); gimp_add_callback (dialog_ID, gimp_ok_item_id (dialog_ID), cb_ok, 0); gimp_add_callback (dialog_ID, gimp_cancel_item_id (dialog_ID), cb_cancel, 0); } static void cb_toggle (int item_ID, void *client_data, void *call_data) { *((long*) client_data) = *((long*) call_data); if (aapply) { newfilter (input, output); gimp_update_image (output); } else { freshen (); gimp_update_image (output); } } static void saveimage (void) { saved = (unsigned char *) malloc (gimp_image_width (input) * gimp_image_height (input) * gimp_image_channels (input)); memcpy (saved, gimp_image_data (input), gimp_image_width(input) * gimp_image_height (input) * gimp_image_channels (input)); } static void freshen (void) { memcpy (gimp_image_data (output), saved, gimp_image_width (input) * gimp_image_height (input) * gimp_image_channels (input)); } static void cb_ok (int item_ID, void *client_data, void *call_data) { gimp_close_dialog (dialog_ID, 1); } static void cb_cancel (int item_ID, void *client_data, void *call_data) { gimp_close_dialog (dialog_ID, 0); } static void newfilter (Image linput, Image loutput) { long width, height, channels, rowstride; unsigned char *src_row, *dest_row, *src, *dest; short row, col; int x1, y1, x2, y2, i; gimp_image_area (linput, &x1, &y1, &x2, &y2); width = gimp_image_width (linput); height = gimp_image_height (linput); channels = gimp_image_channels (linput); rowstride = width * channels; src_row = saved; dest_row = gimp_image_data (loutput); x1 *= channels; x2 *= channels; src_row += rowstride * y1 + x1; dest_row += rowstride * y1 + x1; for (row = y1; row < y2; row++) { src = src_row; dest = dest_row; for (col = x1; col < x2; col++) { for (i = 0; i < channels; i++) *dest++ = *src++; } src_row += rowstride; dest_row += rowstride; } }