Previous Next Table of Contents

7. Complete Plug-In-Templates

The following programs represent two templates, one with and one without preview function.

7.1 A Simple Plug-In


#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;
  }
}

7.2 A Plug-In With Preview


#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;
  }
}                                                                                  


Previous Next Table of Contents