예제 #1
0
파일: gap_image.c 프로젝트: GNOME/gimp-gap
/* ============================================================================
 * gap_image_delete_immediate
 *    delete image (with workaround to ensure that most of the
 *    allocatd memory is freed)
 * ============================================================================
 * The workaround disables undo and scales the image down to miniumum size
 * before calling the gimp_image_delete procedure.
 * this way memory resources for big layers will be freed up immediate.
 */
void
gap_image_delete_immediate (gint32 image_id)
{
  gboolean imageDeleteWorkaroundDefault = TRUE;
  if(gap_base_get_gimprc_gboolean_value("gap-image-delete-workaround"
         , imageDeleteWorkaroundDefault))
  {
    if(gap_debug)
    {
      printf("gap_image_delete_immediate: SCALED down to 2x2 id = %d (workaround for gimp_image-delete problem)\n"
              , (int)image_id
              );
    }

    gimp_image_undo_disable(image_id);
    
    //gimp_image_scale_full(image_id, 2, 2, 0 /*INTERPOLATION_NONE*/);

    gimp_context_push();
    gimp_context_set_interpolation(0);
    gimp_image_scale(image_id, 2, 2);
    gimp_context_pop();


    gimp_image_undo_enable(image_id); /* clear undo stack */
  }

  gimp_image_delete(image_id);
}       /* end  gap_image_delete_immediate */
예제 #2
0
static PyObject *
vectors_to_selection(PyGimpVectors *self, PyObject *args, PyObject *kwargs)
{
    GimpChannelOps operation = GIMP_CHANNEL_OP_REPLACE;
    gboolean antialias = TRUE, feather = FALSE;
    double feather_radius_x = 0.0, feather_radius_y = 0.0;

    static char *kwlist[] = { "operation", "antialias", "feather",
                              "feather_radius_x", "feather_radius_y", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "|iiidd:to_selection", kwlist,
                                     &operation, &antialias, &feather,
                                     &feather_radius_x, &feather_radius_y))
        return NULL;

    gimp_context_push();
    gimp_context_set_antialias(antialias);
    gimp_context_set_feather(feather);
    gimp_context_set_feather_radius(feather_radius_x, feather_radius_y);
    gimp_image_select_item(gimp_item_get_image(self->ID), operation, self->ID);
    gimp_context_pop();

    Py_INCREF(Py_None);
    return Py_None;
}
예제 #3
0
void
render (gint32              image_ID,
	GimpDrawable       *drawable,
	PlugInVals         *vals,
	PlugInImageVals    *image_vals,
	PlugInDrawableVals *drawable_vals)
{
    double angle = gimp_find_skew(drawable); // in radians

    DEBUGPRINT("deskew: angle=%.2f\n",
               57.295779513082320876798154814105*angle);

    if (fabs(angle) < deskew_threshold) {
        // nothing to do; already straightened.
        return;
    }
    gimp_context_push ();
    gimp_context_set_interpolation (GIMP_INTERPOLATION_CUBIC);
    gimp_context_set_transform_resize (GIMP_TRANSFORM_RESIZE_ADJUST);

    drawable->drawable_id =
        gimp_item_transform_rotate(drawable->drawable_id,
                                               angle,
                                               TRUE,    // auto_center
                                               -1, -1  // center_x, center_y
            );
    gimp_context_pop ();
}
예제 #4
0
static void
d_paint_rectangle (GfigObject *obj)
{
  DobjPoints *first_pnt;
  DobjPoints *second_pnt;
  gdouble     dpnts[4];

  g_assert (obj != NULL);

  /* Drawing rectangles is hard .
   * 1) select rectangle
   * 2) stroke it
   */
  first_pnt = obj->points;

  if (!first_pnt)
    return; /* End-of-line */

  second_pnt = first_pnt->next;

  if (!second_pnt)
    {
      g_error ("Internal error - rectangle no second pnt");
    }

  dpnts[0] = (gdouble) MIN (first_pnt->pnt.x, second_pnt->pnt.x);
  dpnts[1] = (gdouble) MIN (first_pnt->pnt.y, second_pnt->pnt.y);
  dpnts[2] = (gdouble) MAX (first_pnt->pnt.x, second_pnt->pnt.x);
  dpnts[3] = (gdouble) MAX (first_pnt->pnt.y, second_pnt->pnt.y);

  /* Scale before drawing */
  if (selvals.scaletoimage)
    scale_to_original_xy (&dpnts[0], 2);
  else
    scale_to_xy (&dpnts[0], 2);

  gimp_context_push ();
  gimp_context_set_feather (selopt.feather);
  gimp_context_set_feather_radius (selopt.feather_radius, selopt.feather_radius);
  gimp_image_select_rectangle (gfig_context->image_id,
                               selopt.type,
                               dpnts[0], dpnts[1],
                               dpnts[2] - dpnts[0],
                               dpnts[3] - dpnts[1]);
  gimp_context_pop ();

  paint_layer_fill (dpnts[0], dpnts[1], dpnts[2], dpnts[3]);

  if (obj->style.paint_type == PAINT_BRUSH_TYPE)
    gimp_edit_stroke (gfig_context->drawable_id);
}
예제 #5
0
파일: gfig.c 프로젝트: ChristianBusch/gimp
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam   values[1];
  gint32             drawable_id;
  GimpRunMode        run_mode;
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
  gint               pwidth, pheight;

  INIT_I18N ();

  gfig_context = g_new0 (GFigContext, 1);
  gfig_context->show_background = TRUE;
  gfig_context->selected_obj = NULL;

  drawable_id = param[2].data.d_drawable;

  run_mode = param[0].data.d_int32;

  gfig_context->image_id = param[1].data.d_image;
  gfig_context->drawable_id = drawable_id;

  *nreturn_vals = 1;
  *return_vals = values;

  values[0].type = GIMP_PDB_STATUS;
  values[0].data.d_status = status;

  gimp_image_undo_group_start (gfig_context->image_id);

  gimp_context_push ();

  /* TMP Hack - clear any selections */
  if (! gimp_selection_is_empty (gfig_context->image_id))
    gimp_selection_none (gfig_context->image_id);

  gimp_drawable_mask_bounds (drawable_id,
                             &sel_x1, &sel_y1, &sel_x2, &sel_y2);

  sel_width  = sel_x2 - sel_x1;
  sel_height = sel_y2 - sel_y1;


  /* Calculate preview size */

  if (sel_width > sel_height)
    {
      pwidth  = MIN (sel_width, PREVIEW_SIZE);
      pheight = sel_height * pwidth / sel_width;
    }
  else
    {
      pheight = MIN (sel_height, PREVIEW_SIZE);
      pwidth  = sel_width * pheight / sel_height;
    }


  preview_width  = MAX (pwidth, 2);  /* Min size is 2 */
  preview_height = MAX (pheight, 2);

  org_scale_x_factor = scale_x_factor =
    (gdouble) sel_width / (gdouble) preview_width;
  org_scale_y_factor = scale_y_factor =
    (gdouble) sel_height / (gdouble) preview_height;

  /* initialize */
  gfig_init_object_classes ();

  switch (run_mode)
    {
    case GIMP_RUN_INTERACTIVE:
    case GIMP_RUN_WITH_LAST_VALS:
      /*gimp_get_data (PLUG_IN_PROC, &selvals);*/
      if (! gfig_dialog ())
        {
          gimp_image_undo_group_end (gfig_context->image_id);

          return;
        }
      break;

    case GIMP_RUN_NONINTERACTIVE:
      status = GIMP_PDB_CALLING_ERROR;
      break;

    default:
      break;
    }

  gimp_context_pop ();

  gimp_image_undo_group_end (gfig_context->image_id);

  if (run_mode != GIMP_RUN_NONINTERACTIVE)
    gimp_displays_flush ();
  else
#if 0
  if (run_mode == GIMP_RUN_INTERACTIVE)
    gimp_set_data (PLUG_IN_PROC, &selvals, sizeof (SelectItVals));
  else
#endif /* 0 */
    {
      status = GIMP_PDB_EXECUTION_ERROR;
    }

  values[0].data.d_status = status;
}
예제 #6
0
static void run ( const gchar *name, gint nparams, const GimpParam *param,
                  gint *nreturn_vals, GimpParam **return_vals)
{
  static GimpParam values[3];
  GimpRunMode run_mode;
  GimpPDBStatusType status = GIMP_PDB_SUCCESS;
  SeparateContext mysc;
  //enum separate_function func = SEP_NONE;
  run_mode = param[0].data.d_int32;


  /* setup for localization */
  INIT_I18N ();

  cmsErrorAction( LCMS_ERROR_IGNORE );

  mysc.filename = NULL;
  if( nparams != ( run_mode == GIMP_RUN_NONINTERACTIVE ? 2 : 1 ) )
    status = GIMP_PDB_CALLING_ERROR;
  else if( run_mode == GIMP_RUN_NONINTERACTIVE ) {
    if( param[1].type != GIMP_PDB_STRING || strlen( param[1].data.d_string ) == 0 )
      status = GIMP_PDB_CALLING_ERROR;
    else
      mysc.filename = g_strdup( param[1].data.d_string );
  } else {
    gint size = gimp_get_data_size( "plug-in-separate-import/lastpath" );
    if( size ) {
      mysc.filename = g_malloc( size );
      gimp_get_data( "plug-in-separate-import/lastpath", mysc.filename );
    }
  }

  if( status == GIMP_PDB_SUCCESS && ( run_mode == GIMP_RUN_NONINTERACTIVE || separate_import_dialog( &mysc ) ) ) {
    gint i, j, x, y;
    TIFF *in;
    guint32 width, height, stripSize, stripCount, stripHeight;
    gint16 bps, spp, step, planerConfig, photometric, inkset, resolutionUnit;
    float xres, yres;
    const gchar *layerNames[] = { "C", "M", "Y", "K" };
    guchar *buf, *maskbuf[4], *srcbuf, *destbuf[4], *iccProfile;
    gint32 layers[5], masks[4];
    GimpDrawable *drw[4];
    GimpPixelRgn rgn[4];
    GimpRGB primaries[4] = { { .180, .541, .870, 1.0 },
                             { .925, .149, .388, 1.0 },
                             { .929, .862, .129, 1.0 },
                             { 0, 0, 0, 1.0 }  };

    gchar *str = NULL;
    gchar *baseName = g_path_get_basename( gimp_filename_to_utf8( mysc.filename ) );

#ifdef G_OS_WIN32
    {
      gchar *_filename = NULL; // win32 filename encoding(not UTF-8)
      _filename = g_win32_locale_filename_from_utf8( mysc.filename );
      in = TIFFOpen( _filename ? _filename : mysc.filename, "r" );
      g_free( _filename );
    }
#else
    in = TIFFOpen( mysc.filename, "r" );
#endif

    if( !in ) {
      str = g_strdup_printf( _( "Cannot open : \"%s\"" ), baseName );
      gimp_message( str );
      g_free( str );
      status = GIMP_PDB_EXECUTION_ERROR;
    } else {
      if( ( TIFFGetField( in, TIFFTAG_BITSPERSAMPLE, &bps ) == FALSE || ( bps != 8 && bps != 16 ) ) ||
          ( TIFFGetField( in, TIFFTAG_SAMPLESPERPIXEL, &spp ) == FALSE || spp != 4 ) ||
          ( TIFFGetField( in, TIFFTAG_PHOTOMETRIC, &photometric ) == FALSE || photometric != PHOTOMETRIC_SEPARATED ) ||
          ( TIFFGetField( in, TIFFTAG_PLANARCONFIG, &planerConfig ) == FALSE || planerConfig != PLANARCONFIG_CONTIG ) ||
          ( TIFFGetField( in, TIFFTAG_INKSET, &inkset ) == TRUE && inkset != INKSET_CMYK ) ) {
        str = g_strdup_printf( _( "\"%s\" is unsupported." ), baseName );
        gimp_message( str );
        g_free( str );
        status = GIMP_PDB_EXECUTION_ERROR;
      } else {
        stripCount = TIFFNumberOfStrips( in );
        stripSize = TIFFStripSize( in );
        TIFFGetField( in, TIFFTAG_IMAGEWIDTH, &width );
        TIFFGetField( in, TIFFTAG_IMAGELENGTH, &height );
        TIFFGetField( in, TIFFTAG_ROWSPERSTRIP, &stripHeight );
        TIFFGetField( in, TIFFTAG_RESOLUTIONUNIT, &resolutionUnit );
        TIFFGetField( in, TIFFTAG_XRESOLUTION, &xres );
        TIFFGetField( in, TIFFTAG_YRESOLUTION, &yres );

#if 0
        str = g_strdup_printf( "Photometric : %d  BPS : %d  SPP : %d\nInkset : %d  StripCount : %d", photometric, bps, spp, inkset, stripCount );
        gimp_message( str );
        g_free( str );
#endif

        step = ( bps == 16 ) ? 2 : 1;

        buf = g_malloc( stripSize );

        values[1].data.d_image = gimp_image_new( width, height, GIMP_RGB );
        gimp_image_set_resolution( values[1].data.d_image, xres, yres );
        gimp_context_push();
        for( i = 0; i < 4; i++ ) {
          layers[i] = gimp_layer_new( values[1].data.d_image, layerNames[i], width, height, GIMP_RGBA_IMAGE, 100.0, GIMP_DARKEN_ONLY_MODE );
          gimp_context_set_foreground( &primaries[i] );
          gimp_drawable_fill( layers[i], GIMP_FOREGROUND_FILL );
          gimp_image_add_layer( values[1].data.d_image, layers[i], i );
          masks[i] = gimp_layer_create_mask( layers[i], GIMP_ADD_BLACK_MASK );
          gimp_layer_add_mask( layers[i], masks[i] );
          drw[i] = gimp_drawable_get( masks[i] );
          maskbuf[i] = g_malloc( width * stripHeight );
        }
        gimp_context_pop();
        layers[4] = gimp_layer_new( values[1].data.d_image, _( "Background" ), width, height, GIMP_RGB_IMAGE, 100.0, GIMP_NORMAL_MODE );
        gimp_drawable_fill( layers[4], GIMP_WHITE_FILL );
        gimp_image_add_layer( values[1].data.d_image, layers[4], 4 );

        str = g_strdup_printf( _( "Reading \"%s\"..." ), baseName );
        gimp_progress_init( str );
        g_free( str );

        for( i = 0; i < stripCount; i++ ) {
          guint32 size = TIFFReadEncodedStrip( in, i, buf, stripSize );
          guint32 rowCount = ( size < stripSize ? height % stripHeight : stripHeight );
          srcbuf = buf;
          if( bps == 16 )
            srcbuf++;
          for( j = 0; j < 4; j++ ) {
            gimp_pixel_rgn_init( &( rgn[j] ), drw[j],
                                 0, stripHeight * i, width, rowCount,
                                 FALSE, FALSE );
            destbuf[j] = maskbuf[j];
          }
          for( y = 0; y < rowCount; y++ ) {
            for( x = 0; x < width; x++ ) {
              *destbuf[0]++ = *srcbuf;
              srcbuf += step;
              *destbuf[1]++ = *srcbuf;
              srcbuf += step;
              *destbuf[2]++ = *srcbuf;
              srcbuf += step;
              *destbuf[3]++ = *srcbuf;
              srcbuf += step;
              //srcbuf += spp > 4 ? spp - 4 : 0;
            }
          }
          gimp_pixel_rgn_set_rect( &( rgn[0] ), maskbuf[0], 0, stripHeight * i, width, rowCount );
          gimp_pixel_rgn_set_rect( &( rgn[1] ), maskbuf[1], 0, stripHeight * i, width, rowCount );
          gimp_pixel_rgn_set_rect( &( rgn[2] ), maskbuf[2], 0, stripHeight * i, width, rowCount );
          gimp_pixel_rgn_set_rect( &( rgn[3] ), maskbuf[3], 0, stripHeight * i, width, rowCount );
          gimp_progress_update( (gdouble)i / stripCount );
        }
        g_free( buf );
        for( i = 0; i < 4; i++ ) {
          g_free( maskbuf[i] );
          gimp_drawable_detach( drw[i] );
        }

#ifdef ENABLE_COLOR_MANAGEMENT
        if ( TIFFGetField( in, TIFFTAG_ICCPROFILE, &width, &iccProfile ) ) {
          GimpParasite *parasite;

          parasite = gimp_parasite_new( CMYKPROFILE, 0, width, iccProfile );
          gimp_image_parasite_attach( values[1].data.d_image, parasite );
          gimp_parasite_free( parasite );

          //g_free( iccProfile ); // This causes clash on TIFFClose( in ).
        }
#endif
      }
      TIFFClose( in );
    }
    g_free( baseName );
  } else
    status = GIMP_PDB_CANCEL;

  *return_vals = values;
  values[0].type = GIMP_PDB_STATUS;
  values[0].data.d_status = status;
  if( status == GIMP_PDB_SUCCESS ) {
    *nreturn_vals = 2;
    values[1].type = GIMP_PDB_IMAGE;
    if( run_mode != GIMP_RUN_NONINTERACTIVE ) {
      gimp_image_undo_enable( values[1].data.d_image );
      gimp_display_new( values[1].data.d_image );
      gimp_displays_flush();
    }
    gimp_set_data( "plug-in-separate-import/lastpath", mysc.filename, strlen( mysc.filename ) + 1 );
  } else
    *nreturn_vals = 1;

  g_free( mysc.filename );
}
예제 #7
0
파일: film.c 프로젝트: LebedevRI/gimp
/* Compose a roll film image from several images */
static gint32
film (void)
{
  gint          width, height;
  guchar       *hole;
  gint          film_height, film_width;
  gint          picture_width, picture_height;
  gint          picture_space, picture_x0, picture_y0;
  gint          hole_offset, hole_width, hole_height, hole_space, hole_x;
  gint          number_height, num_images, num_pictures;
  gint          j, k, picture_count;
  gdouble       f;
  gint          num_layers;
  gint32       *image_ID_src, image_ID_dst, layer_ID_src, layer_ID_dst;
  gint          image_ID_tmp;
  gint32       *layers;
  GimpDrawable *drawable_dst;
  GimpPixelRgn  pixel_rgn_dst;
  gint          new_layer;
  gint          floating_sel;

  /* initialize */

  layers = NULL;

  num_images = filmvals.num_images;
  image_ID_src = filmvals.image;

  if (num_images <= 0)
    return (-1);

  gimp_context_push ();
  gimp_context_set_foreground (&filmvals.number_color);
  gimp_context_set_background (&filmvals.film_color);

  if (filmvals.keep_height) /* Search maximum picture height */
    {
      picture_height = 0;
      for (j = 0; j < num_images; j++)
        {
          height = gimp_image_height (image_ID_src[j]);
          if (height > picture_height) picture_height = height;
        }
      film_height = (int)(picture_height / filmvals.picture_height + 0.5);
      filmvals.film_height = film_height;
    }
  else
    {
      film_height = filmvals.film_height;
      picture_height = (int)(film_height * filmvals.picture_height + 0.5);
    }

  picture_space = (int)(film_height * filmvals.picture_space + 0.5);
  picture_y0 = (film_height - picture_height)/2;

  number_height = film_height * filmvals.number_height;

  /* Calculate total film width */
  film_width = 0;
  num_pictures = 0;
  for (j = 0; j < num_images; j++)
    {
      layers = gimp_image_get_layers (image_ID_src[j], &num_layers);
      /* Get scaled image size */
      width = gimp_image_width (image_ID_src[j]);
      height = gimp_image_height (image_ID_src[j]);
      f = ((double)picture_height) / (double)height;
      picture_width = width * f;

      for (k = 0; k < num_layers; k++)
        {
          if (gimp_layer_is_floating_sel (layers[k]))
            continue;

          film_width += (picture_space/2);  /* Leading space */
          film_width += picture_width;      /* Scaled image width */
          film_width += (picture_space/2);  /* Trailing space */
          num_pictures++;
        }

      g_free (layers);
    }

#ifdef FILM_DEBUG
  g_printerr ("film_height = %d, film_width = %d\n", film_height, film_width);
  g_printerr ("picture_height = %d, picture_space = %d, picture_y0 = %d\n",
              picture_height, picture_space, picture_y0);
  g_printerr ("Number of pictures = %d\n", num_pictures);
#endif

  image_ID_dst = create_new_image (_("Untitled"),
                                   (guint) film_width, (guint) film_height,
                                   GIMP_RGB_IMAGE, &layer_ID_dst,
                                   &drawable_dst, &pixel_rgn_dst);

  /* Fill film background */
  gimp_drawable_fill (layer_ID_dst, GIMP_FILL_BACKGROUND);

  /* Draw all the holes */
  hole_offset = film_height * filmvals.hole_offset;
  hole_width = film_height * filmvals.hole_width;
  hole_height = film_height * filmvals.hole_height;
  hole_space = film_height * filmvals.hole_space;
  hole_x = hole_space / 2;

#ifdef FILM_DEBUG
  g_printerr ("hole_x %d hole_offset %d hole_width %d hole_height %d hole_space %d\n",
              hole_x, hole_offset, hole_width, hole_height, hole_space );
#endif

  hole = create_hole_rgb (hole_width, hole_height);
  if (hole)
    {
      while (hole_x < film_width)
        {
          draw_hole_rgb (drawable_dst, hole_x,
                         hole_offset,
                         hole_width, hole_height, hole);
          draw_hole_rgb (drawable_dst, hole_x,
                         film_height-hole_offset-hole_height,
                         hole_width, hole_height, hole);

          hole_x += hole_width + hole_space;
        }
      g_free (hole);
    }
  gimp_drawable_detach (drawable_dst);


  /* Compose all images and layers */
  picture_x0 = 0;
  picture_count = 0;
  for (j = 0; j < num_images; j++)
    {
      image_ID_tmp = gimp_image_duplicate (image_ID_src[j]);
      width = gimp_image_width (image_ID_tmp);
      height = gimp_image_height (image_ID_tmp);
      f = ((gdouble) picture_height) / (gdouble) height;
      picture_width = width * f;
      if (gimp_image_base_type (image_ID_tmp) != GIMP_RGB)
        gimp_image_convert_rgb (image_ID_tmp);
      gimp_image_scale (image_ID_tmp, picture_width, picture_height);

      layers = gimp_image_get_layers (image_ID_tmp, &num_layers);
      for (k = 0; k < num_layers; k++)
        {
          if (gimp_layer_is_floating_sel (layers[k]))
            continue;

          picture_x0 += picture_space / 2;

          layer_ID_src = layers[k];
          gimp_layer_resize_to_image_size (layer_ID_src);
          new_layer = gimp_layer_new_from_drawable (layer_ID_src,
                                                    image_ID_dst);
          gimp_image_insert_layer (image_ID_dst, new_layer, -1, -1);
          gimp_layer_set_offsets (new_layer, picture_x0, picture_y0);

          /* Draw picture numbers */
          if ((number_height > 0) &&
              (filmvals.number_pos[0] || filmvals.number_pos[1]))
            {
              if (filmvals.number_pos[0])
                draw_number (layer_ID_dst,
                             filmvals.number_start + picture_count,
                             picture_x0 + picture_width/2,
                             (hole_offset-number_height)/2, number_height);
              if (filmvals.number_pos[1])
                draw_number (layer_ID_dst,
                             filmvals.number_start + picture_count,
                             picture_x0 + picture_width/2,
                             film_height - (hole_offset + number_height)/2,
                             number_height);
            }

          picture_x0 += picture_width + (picture_space/2);

          gimp_progress_update (((gdouble) (picture_count + 1)) /
                                (gdouble) num_pictures);

          picture_count++;
        }

      g_free (layers);
      gimp_image_delete (image_ID_tmp);
    }
  gimp_progress_update (1.0);

  gimp_image_flatten (image_ID_dst);

  /* Drawing text/numbers leaves us with a floating selection. Stop it */
  floating_sel = gimp_image_get_floating_sel (image_ID_dst);
  if (floating_sel != -1)
    gimp_floating_sel_anchor (floating_sel);

  gimp_context_pop ();

  return image_ID_dst;
}
예제 #8
0
/* --------------------------------------------
 * gap_fg_from_selection_exec_apply_run
 * --------------------------------------------
 * generate a tri map from the current selection by filling the shrinked
 * shape with white, the expanded shape with black and the borderline
 * between shrinked and expanded selection with medium gray.
 * the trimap is attached as layermask to the input drawable,
 * and used as input for the foreground selection via alpha matting algorithm,
 * that creates a resulting layer with trimmed selection.
 *
 */
gint
gap_fg_from_selection_exec_apply_run (gint32 image_id, gint32 drawable_id
                             , gboolean doProgress, gboolean doFlush
                             , GapFgSelectValues *fsValPtr)
{
  GimpRGB   color;
  gint32    activeSelection;
  gint32    shrinkedSelection;
  gint32    trimap;
  gboolean  hadSelection;
  gint      rc;

  rc = 0;
  trimap = -1;
  activeSelection = -1;
  shrinkedSelection = -1;
  hadSelection = FALSE;
  
  gimp_context_push();
  gimp_image_undo_group_start(image_id);
  

  if (gimp_selection_is_empty(image_id) == TRUE)
  {
     if (gimp_drawable_has_alpha(drawable_id) == FALSE)
     {
       /* if the layer has no alpha select all */
       gimp_selection_all(image_id);
     }
     else
     {
       gimp_selection_layer_alpha(drawable_id);
     }
     activeSelection = gimp_selection_save(image_id);
  }
  else
  {
    activeSelection = gimp_selection_save(image_id);
    hadSelection = TRUE;
  }


  trimap = gimp_layer_get_mask(drawable_id);
  if (trimap < 0)
  {
    /* create trimap as new layermask */
    trimap = gimp_layer_create_mask(drawable_id, GIMP_ADD_BLACK_MASK);
    gimp_layer_add_mask(drawable_id, trimap);
  }
  else
  {
    /* use BLACK color to fill the already existing layermask
     * (note that gimp_drawable_fill is used to fill the entire mask
     * regardless to the current selection)
     */
    color.r = 0.0;
    color.g = 0.0;
    color.b = 0.0;
    color.a = 1.0;
    gimp_context_set_background (&color);
    gimp_drawable_fill(trimap, GIMP_BACKGROUND_FILL);
  }
  
  gimp_selection_sharpen(image_id);
  if (fsValPtr->innerRadius > 0)
  {
    gimp_selection_shrink(image_id, fsValPtr->innerRadius);
  }
  shrinkedSelection = gimp_selection_save(image_id);
  
  
  /* use WHITE color to mark foreground regions
   */
  color.r = 1.0;
  color.g = 1.0;
  color.b = 1.0;
  color.a = 1.0;
  gimp_context_set_background (&color);
  gimp_edit_fill(trimap, GIMP_BACKGROUND_FILL);
  
  gimp_selection_load(activeSelection);
  gimp_selection_sharpen(image_id);
  if (fsValPtr->outerRadius > 0)
  {
    gimp_selection_grow(image_id, fsValPtr->outerRadius);
  }
  gimp_selection_combine(shrinkedSelection, GIMP_CHANNEL_OP_SUBTRACT);

  /* use medium GRAY to mark undefined regions
   */
  color.r = 0.5;
  color.g = 0.5;
  color.b = 0.5;
  color.a = 1.0;
  gimp_context_set_background (&color);
  gimp_edit_fill(trimap, GIMP_BACKGROUND_FILL);

  gimp_selection_none(image_id);

  /* perform the foreground selection (that creates the resulting layer) */
  {
    GapFgExtractValues fgExtractValues;
    GapFgExtractValues *fgValPtr;
    
    fgValPtr = &fgExtractValues;
    fgValPtr->input_drawable_id = drawable_id;
    fgValPtr->tri_map_drawable_id = trimap;
    fgValPtr->create_result = TRUE;
    fgValPtr->create_layermask = fsValPtr->create_layermask;
    fgValPtr->lock_color = fsValPtr->lock_color;
    fgValPtr->colordiff_threshold = fsValPtr->colordiff_threshold;

    rc = gap_fg_matting_exec_apply_run (image_id, drawable_id
                                 , doProgress, doFlush
                                 , fgValPtr
                                 );
  }
  
  
  /* restore original selection */
  if (hadSelection == TRUE)
  {
    gimp_selection_load(activeSelection);
  }

  gimp_image_undo_group_end(image_id);
  gimp_context_pop();
  
  return (rc);

}  /* end gap_fg_from_selection_exec_apply_run */
예제 #9
0
static void
d_paint_star (GfigObject *obj)
{
  /* first point center */
  /* Next point is radius */
  gdouble    *line_pnts;
  gint        seg_count = 0;
  gint        i = 0;
  DobjPoints *center_pnt;
  DobjPoints *outer_radius_pnt;
  DobjPoints *inner_radius_pnt;
  gint16      shift_x;
  gint16      shift_y;
  gdouble     ang_grid;
  gdouble     ang_loop;
  gdouble     outer_radius;
  gdouble     inner_radius;
  gdouble     offset_angle;
  gint        loop;
  GdkPoint    first_pnt = { 0, 0 };
  GdkPoint    last_pnt  = { 0, 0 };
  gboolean    first = TRUE;
  gdouble    *min_max;

  g_assert (obj != NULL);

  /* count - add one to close polygon */
  seg_count = 2 * obj->type_data + 1;

  center_pnt = obj->points;

  if (!center_pnt || !seg_count)
    return; /* no-line */

  line_pnts = g_new0 (gdouble, 2 * seg_count + 1);
  min_max = g_new (gdouble, 4);

  /* Go around all the points drawing a line from one to the next */
  /* Next point defines the radius */
  outer_radius_pnt = center_pnt->next; /* this defines the vetices */

  if (!outer_radius_pnt)
    {
#ifdef DEBUG
      g_warning ("Internal error in star - no outer vertice point \n");
#endif /* DEBUG */
      g_free (line_pnts);
      g_free (min_max);
      return;
    }

  inner_radius_pnt = outer_radius_pnt->next; /* this defines the vetices */

  if (!inner_radius_pnt)
    {
#ifdef DEBUG
      g_warning ("Internal error in star - no inner vertice point \n");
#endif /* DEBUG */
      g_free (line_pnts);
      g_free (min_max);
      return;
    }

  shift_x = outer_radius_pnt->pnt.x - center_pnt->pnt.x;
  shift_y = outer_radius_pnt->pnt.y - center_pnt->pnt.y;

  outer_radius = sqrt ((shift_x*shift_x) + (shift_y*shift_y));

  /* Lines */
  ang_grid = 2.0 * G_PI / (2.0 * (gdouble) obj->type_data);
  offset_angle = atan2 (shift_y, shift_x);

  shift_x = inner_radius_pnt->pnt.x - center_pnt->pnt.x;
  shift_y = inner_radius_pnt->pnt.y - center_pnt->pnt.y;

  inner_radius = sqrt ((shift_x*shift_x) + (shift_y*shift_y));

  for (loop = 0 ; loop < 2 * obj->type_data ; loop++)
    {
      gdouble  lx, ly;
      GdkPoint calc_pnt;

      ang_loop = (gdouble)loop * ang_grid + offset_angle;

      if (loop % 2)
        {
          lx = inner_radius * cos (ang_loop);
          ly = inner_radius * sin (ang_loop);
        }
      else
        {
          lx = outer_radius * cos (ang_loop);
          ly = outer_radius * sin (ang_loop);
        }

      calc_pnt.x = RINT (lx + center_pnt->pnt.x);
      calc_pnt.y = RINT (ly + center_pnt->pnt.y);

      /* Miss out duped pnts */
      if (!first)
        {
          if (calc_pnt.x == last_pnt.x && calc_pnt.y == last_pnt.y)
            {
              continue;
            }
        }

      line_pnts[i++] = calc_pnt.x;
      line_pnts[i++] = calc_pnt.y;
      last_pnt = calc_pnt;

      if (first)
        {
          first_pnt = calc_pnt;
          first = FALSE;
          min_max[0] = min_max[2] = calc_pnt.x;
          min_max[1] = min_max[3] = calc_pnt.y;
        }
      else
        {
          min_max[0] = MIN (min_max[0], calc_pnt.x);
          min_max[1] = MIN (min_max[1], calc_pnt.y);
          min_max[2] = MAX (min_max[2], calc_pnt.x);
          min_max[3] = MAX (min_max[3], calc_pnt.y);
        }
    }

  line_pnts[i++] = first_pnt.x;
  line_pnts[i++] = first_pnt.y;

  /* Scale before drawing */
  if (selvals.scaletoimage)
    {
      scale_to_original_xy (&line_pnts[0], i / 2);
      scale_to_original_xy (min_max, 2);
    }
  else
    {
      scale_to_xy (&line_pnts[0], i / 2);
      scale_to_xy (min_max, 2);
    }

  if (gfig_context_get_current_style ()->fill_type != FILL_NONE)
    {
      gimp_context_push ();
      gimp_context_set_antialias (selopt.antia);
      gimp_context_set_feather (selopt.feather);
      gimp_context_set_feather_radius (selopt.feather_radius, selopt.feather_radius);
      gimp_image_select_polygon (gfig_context->image_id,
                                 selopt.type,
                                 i, line_pnts);
      gimp_context_pop ();

      paint_layer_fill (min_max[0], min_max[1], min_max[2], min_max[3]);
      gimp_selection_none (gfig_context->image_id);
    }

  if (obj->style.paint_type == PAINT_BRUSH_TYPE)
    gfig_paint (selvals.brshtype, gfig_context->drawable_id, i, line_pnts);

  g_free (line_pnts);
  g_free (min_max);
}
예제 #10
0
static void
d_paint_circle (GfigObject *obj)
{
  DobjPoints *center_pnt;
  DobjPoints *edge_pnt;
  gint        radius;
  gdouble     dpnts[4];

  g_assert (obj != NULL);

  center_pnt = obj->points;

  if (!center_pnt)
    return; /* End-of-line */

  edge_pnt = center_pnt->next;

  if (!edge_pnt)
    {
      g_error ("Internal error - circle no edge pnt");
    }

  radius = calc_radius (&center_pnt->pnt, &edge_pnt->pnt);

  dpnts[0] = (gdouble) center_pnt->pnt.x - radius;
  dpnts[1] = (gdouble) center_pnt->pnt.y - radius;
  dpnts[3] = dpnts[2] = (gdouble) radius * 2;

  /* Scale before drawing */
  if (selvals.scaletoimage)
    scale_to_original_xy (&dpnts[0], 2);
  else
    scale_to_xy (&dpnts[0], 2);

  if (gfig_context_get_current_style ()->fill_type != FILL_NONE)
    {
      gimp_context_push ();
      gimp_context_set_antialias (selopt.antia);
      gimp_context_set_feather (selopt.feather);
      gimp_context_set_feather_radius (selopt.feather_radius, selopt.feather_radius);
      gimp_image_select_ellipse (gfig_context->image_id,
                                 selopt.type,
                                 dpnts[0], dpnts[1],
                                 dpnts[2], dpnts[3]);
      gimp_context_pop ();

      paint_layer_fill (center_pnt->pnt.x - radius,
                        center_pnt->pnt.y - radius,
                        center_pnt->pnt.x + radius,
                        center_pnt->pnt.y + radius);
      gimp_selection_none (gfig_context->image_id);
    }

  /* Drawing a circle may be harder than stroking a circular selection,
   * but we have to do it or we will not be able to draw outside of the
   * layer. */
  if (obj->style.paint_type == PAINT_BRUSH_TYPE)
    {
      const gdouble r = dpnts[2] / 2;
      const gdouble cx = dpnts[0] + r, cy = dpnts[1] + r;
      gdouble       line_pnts[362];
      gdouble       angle = 0;
      gint          i = 0;

      while (i < 362)
        {
          static const gdouble step = 2 * G_PI / 180;

          line_pnts[i++] = cx + r * cos (angle);
          line_pnts[i++] = cy + r * sin (angle);
          angle += step;
        }

      gfig_paint (selvals.brshtype, gfig_context->drawable_id, i, line_pnts);
    }
}