Exemplo n.º 1
0
static void
preview_update_preview (GimpPreview  *preview,
                        GimpDrawable *drawable)
{
  gint          x1, y1;
  gint          width, height;
  gint          bpp;
  guchar       *buffer;
  GimpPixelRgn  src_rgn;
  GimpPixelRgn  preview_rgn;
  gint32        image_id, src_image_id;
  gint32        preview_id;
  GimpDrawable *preview_drawable;

  bpp = gimp_drawable_bpp (drawable->drawable_id);

  gimp_preview_get_position (preview, &x1, &y1);
  gimp_preview_get_size (preview, &width, &height);

  buffer = g_new (guchar, width * height * bpp);

  gimp_pixel_rgn_init (&src_rgn, drawable,
                       x1, y1, width, height, FALSE, FALSE);
  gimp_pixel_rgn_get_rect (&src_rgn, buffer,
                           x1, y1, width, height);

  /* set up gimp drawable for rendering preview into */
  src_image_id = gimp_drawable_get_image (drawable->drawable_id);
  image_id = gimp_image_new (width, height,
                             gimp_image_base_type (src_image_id));
  preview_id = gimp_layer_new (image_id, "preview", width, height,
                               gimp_drawable_type (drawable->drawable_id),
                               100,
                               GIMP_NORMAL_MODE);
  preview_drawable = gimp_drawable_get (preview_id);
  gimp_image_add_layer (image_id, preview_id, 0);
  gimp_layer_set_offsets (preview_id, 0, 0);
  gimp_pixel_rgn_init (&preview_rgn, preview_drawable,
                       0, 0, width, height, TRUE, TRUE);
  gimp_pixel_rgn_set_rect (&preview_rgn, buffer,
                           0, 0, width, height);
  gimp_drawable_flush (preview_drawable);
  gimp_drawable_merge_shadow (preview_id, TRUE);
  gimp_drawable_update (preview_id, 0, 0, width, height);

  dog (image_id, preview_drawable, dogvals.inner, dogvals.outer, FALSE);

  gimp_pixel_rgn_get_rect (&preview_rgn, buffer,
                           0, 0, width, height);

  gimp_preview_draw_buffer (preview, buffer, width * bpp);

  gimp_image_delete (image_id);
  g_free (buffer);
}
Exemplo n.º 2
0
/* -----------------------
 * p_tri_map_preprocessing
 * -----------------------
 * prepare the tri mask for processing
 * - have bpp == 1
 * - have same size and offset as the input drawable (that is a layer)
 * - pixel values >= 240 are set to value 240 (MATTING_USER_FOREGROUND)
 * - in case the input layer already has an alpha channel
 *   all fully transparent (alpha == 0) pixels are also set 0 (MATTING_USER_BACKGROUND)
 *   in the tri map to keep pixels fully transparent. (such pixels typicall do not
 *   have a useful color information in the RGB channels)
 *
 *
 * in case the user provided the tri map as layer or channel that is NOT the layermask of the input layer
 * we create a new dummy layer with same size and offset as the input layer
 * and add a layermask to this dummy layer.
 * The layermask of the dummy layer is then filled with the intersecting grayscale copy
 * of the user-provided triMap drawable and will be used as tri map in the alpha matting processing.
 *
 * returns the dawable Id of the relevant TRI MAP that fulfills the conditons listed above.
 */
static gint32
p_tri_map_preprocessing (GimpDrawable *drawable, GapFgExtractValues *fgValPtr, gint32 *dummyLayerId)
{
  gint32           prepocessedTriMapLayerId;
  gint32           inputLayerMaskId;
  gint32           imageId;

  *dummyLayerId = -1;
  imageId = gimp_drawable_get_image(drawable->drawable_id);


  inputLayerMaskId = gimp_layer_get_mask(drawable->drawable_id);
  if (fgValPtr->tri_map_drawable_id == inputLayerMaskId)
  {
    prepocessedTriMapLayerId = inputLayerMaskId;
  }
  else
  {
    gint          offset_x;
    gint          offset_y;
    gint32        dummyLayerMaskId;
    gint32        l_fsel_layer_id;

    *dummyLayerId = gimp_layer_new(imageId
            , "DUMMY"
            , drawable->width
            , drawable->height
            , GIMP_RGBA_IMAGE
            , 100.0   /* full opacity */
            , GIMP_NORMAL_MODE       /* normal mode */
            );

    /* get offsets of the input drawable (layer) within the image */
    gimp_drawable_offsets (drawable->drawable_id, &offset_x, &offset_y);

    /* add dummy layer (of same size at same offsets) to the same image */
    gimp_image_add_layer(imageId, *dummyLayerId, -1 /* stackposition */ );
    gimp_layer_set_offsets(*dummyLayerId, offset_x, offset_y);

    /* create a new layermask (black is full transparent */
    dummyLayerMaskId = gimp_layer_create_mask(*dummyLayerId, GIMP_ADD_BLACK_MASK);
    gimp_layer_add_mask(*dummyLayerId, dummyLayerMaskId);

    gimp_edit_copy(fgValPtr->tri_map_drawable_id);
    l_fsel_layer_id = gimp_edit_paste(dummyLayerMaskId, FALSE);
    gimp_floating_sel_anchor(l_fsel_layer_id);

    prepocessedTriMapLayerId = dummyLayerMaskId;
  }

  gap_fg_rgn_tri_map_normalize(drawable, prepocessedTriMapLayerId);

  return(prepocessedTriMapLayerId);

}       /* end p_tri_map_preprocessing */
Exemplo n.º 3
0
/* -----------------------------------
 * p_set_drawable_offsets
 * -----------------------------------
 * simple 2-point align via offsets (without rotate and scale)
 */
static gint32
p_set_drawable_offsets(gint32 activeDrawableId, AlingCoords *alingCoords)
{
  gdouble px1, py1, px2, py2;
  gdouble dx, dy;
  gint    offset_x;
  gint    offset_y;
  

  px1 = alingCoords->startCoords.px;
  py1 = alingCoords->startCoords.py;
  px2 = alingCoords->currCoords.px;
  py2 = alingCoords->currCoords.py;

  dx = px2 - px1;
  dy = py2 - py1;

  /* findout the offsets of the original layer within the source Image */
  gimp_drawable_offsets(activeDrawableId, &offset_x, &offset_y );
  gimp_layer_set_offsets(activeDrawableId, offset_x - dx, offset_y - dy);
  
  return (activeDrawableId);

}  /* end p_set_drawable_offsets */
static gboolean apply_watermark(watermark_settings settings, image_output out) 
{
    gboolean success = TRUE;
    gint32 layerId;
    gdouble posX, posY;
    gint wmwidth, wmheight, wmasc, wmdesc;
    
    if (settings->mode) {
        if (strlen(settings->text) == 0) {
            return TRUE;
        }
        
        GimpRGB old_foreground, new_foreground;
        
        gimp_context_get_foreground(&old_foreground);
        gimp_rgb_parse_hex (&new_foreground, gdk_color_to_string(&(settings->color)), strlen(gdk_color_to_string(&(settings->color))));
        gimp_context_set_foreground(&new_foreground);
        
        gimp_text_get_extents_fontname(
            settings->text,
            pango_font_description_get_size(settings->font) / PANGO_SCALE,
            GIMP_PIXELS,
            pango_font_description_get_family(settings->font),
            &wmwidth,
            &wmheight,
            &wmasc,
            &wmdesc
        );

        if (settings->position == WM_POS_TL) {
            posX = 10;
            posY = 5;
        }
        else if (settings->position == WM_POS_TC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = 5;
        }
        else if (settings->position == WM_POS_TR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = 5;
        }
        else if (settings->position == WM_POS_BL) {
            posX = 10;
            posY = gimp_image_height(out->image_id) - wmheight - 5;
        }
        else if (settings->position == WM_POS_BC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = gimp_image_height(out->image_id) - wmheight - 5;
        }
        else if (settings->position == WM_POS_BR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = gimp_image_height(out->image_id) - wmheight - 5;
        }
        else if (settings->position == WM_POS_CL) {
            posX = 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else if (settings->position == WM_POS_CR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        
        layerId = gimp_text_fontname(
            out->image_id,
            -1,
            posX,
            posY,
            settings->text,
            -1,
            TRUE,
            pango_font_description_get_size(settings->font) / PANGO_SCALE,
            GIMP_PIXELS,
            pango_font_description_get_family(settings->font)
        );
        gimp_context_set_foreground(&old_foreground);
        gimp_layer_set_opacity(layerId, settings->opacity);
    }
    else {
        if (!g_file_test(settings->image_file, G_FILE_TEST_IS_REGULAR)) {//((access(settings->image_file, R_OK) == -1)) {
            // error, can't access image file
            return TRUE;
        }
        
        layerId = gimp_file_load_layer(
            GIMP_RUN_NONINTERACTIVE,
            out->image_id,
            settings->image_file
        );
        
        gimp_layer_set_opacity(layerId, settings->opacity);
        wmwidth = gimp_drawable_width(layerId);
        wmheight = gimp_drawable_height(layerId);
        
        #if USE_API26
        
            gimp_image_add_layer(
                out->image_id,
                layerId,
                0
            );
        
        #else
        
            // starting from 2.8, gimp_image_add_layer is deprecated. 
            // use gimp_image_insert_layer instead
            gimp_image_insert_layer(
                out->image_id,
                layerId,
                0,
                0
            );
            
        #endif
        
        if (settings->position == WM_POS_TL) {
            posX = 10;
            posY = 10;
        }
        else if (settings->position == WM_POS_TC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = 10;
        }
        else if (settings->position == WM_POS_TR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = 10;
        }
        else if (settings->position == WM_POS_BL) {
            posX = 10;
            posY = gimp_image_height(out->image_id) - wmheight - 10;
        }
        else if (settings->position == WM_POS_BC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = gimp_image_height(out->image_id) - wmheight - 10;
        }
        else if (settings->position == WM_POS_BR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = gimp_image_height(out->image_id) - wmheight - 10;
        }
        else if (settings->position == WM_POS_CL) {
            posX = 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else if (settings->position == WM_POS_CR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        
        gimp_layer_set_offsets(
            layerId,
            posX,
            posY
        );   
    }
    
    // refresh all drawables
    g_free(out->drawable_ids);
    out->drawable_ids = gimp_image_get_layers(out->image_id, &out->drawable_count);
    
    return success;
}
Exemplo n.º 5
0
static gint32
do_curl_effect (gint32 drawable_id)
{
  gint          x = 0;
  gint          y = 0;
  gboolean      color_image;
  gint          x1, y1, k;
  guint         alpha_pos, progress, max_progress;
  gdouble       intensity, alpha;
  GimpVector2   v, dl, dr;
  gdouble       dl_mag, dr_mag, angle, factor;
  guchar       *pp, *dest, fore_grayval, back_grayval;
  guchar       *gradsamp;
  GimpPixelRgn  dest_rgn;
  gpointer      pr;
  gint32        curl_layer_id;
  guchar       *grad_samples  = NULL;

  color_image = gimp_drawable_is_rgb (drawable_id);

  curl_layer =
    gimp_drawable_get (gimp_layer_new (image_id,
				       _("Curl Layer"),
				       true_sel_width,
				       true_sel_height,
				       color_image ?
                                       GIMP_RGBA_IMAGE : GIMP_GRAYA_IMAGE,
				       100, GIMP_NORMAL_MODE));

  curl_layer_id = curl_layer->drawable_id;

  gimp_image_insert_layer (image_id, curl_layer->drawable_id,
                           gimp_item_get_parent (drawable_id),
                           drawable_position);
  gimp_drawable_fill (curl_layer->drawable_id, GIMP_FILL_TRANSPARENT);

  gimp_drawable_offsets (drawable_id, &x1, &y1);
  gimp_layer_set_offsets (curl_layer->drawable_id, sel_x + x1, sel_y + y1);
  gimp_tile_cache_ntiles (2 * (curl_layer->width / gimp_tile_width () + 1));

  gimp_pixel_rgn_init (&dest_rgn, curl_layer,
		       0, 0, true_sel_width, true_sel_height, TRUE, TRUE);

  /* Init shade_under */
  gimp_vector2_set (&dl, -sel_width, -sel_height);
  dl_mag = gimp_vector2_length (&dl);
  gimp_vector2_set (&dr,
		    -(sel_width - right_tangent.x),
		    -(sel_height - right_tangent.y));
  dr_mag = gimp_vector2_length (&dr);
  alpha = acos (gimp_vector2_inner_product (&dl, &dr) / (dl_mag * dr_mag));

  /* Init shade_curl */

  fore_grayval = GIMP_RGB_LUMINANCE (fore_color[0],
                                     fore_color[1],
                                     fore_color[2]) + 0.5;
  back_grayval = GIMP_RGB_LUMINANCE (back_color[0],
                                     back_color[1],
                                     back_color[2]) + 0.5;

  /* Gradient Samples */
  switch (curl.colors)
    {
    case CURL_COLORS_FG_BG:
      break;
    case CURL_COLORS_GRADIENT:
      grad_samples = get_gradient_samples (curl_layer->drawable_id, FALSE);
      break;
    case CURL_COLORS_GRADIENT_REVERSE:
      grad_samples = get_gradient_samples (curl_layer->drawable_id, TRUE);
      break;
    }

  max_progress = 2 * sel_width * sel_height;
  progress = 0;

  alpha_pos = dest_rgn.bpp - 1;

  /* Main loop */
  for (pr = gimp_pixel_rgns_register (1, &dest_rgn);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      dest = dest_rgn.data;

      for (y1 = dest_rgn.y; y1 < dest_rgn.y + dest_rgn.h; y1++)
	{
	  pp = dest;
	  for (x1 = dest_rgn.x; x1 < dest_rgn.x + dest_rgn.w; x1++)
	    {
	      /* Map coordinates to get the curl correct... */
              switch (curl.orientation)
                {
                case CURL_ORIENTATION_VERTICAL:
		  x = CURL_EDGE_RIGHT (curl.edge) ? x1 : sel_width  - 1 - x1;
		  y = CURL_EDGE_UPPER (curl.edge) ? y1 : sel_height - 1 - y1;
                  break;

                case CURL_ORIENTATION_HORIZONTAL:
                  x = CURL_EDGE_LOWER (curl.edge) ? y1 : sel_width  - 1 - y1;
		  y = CURL_EDGE_LEFT  (curl.edge) ? x1 : sel_height - 1 - x1;
                  break;
		}

	      if (left_of_diagl (x, y))
		{ /* uncurled region */
		  for (k = 0; k <= alpha_pos; k++)
		    pp[k] = 0;
		}
	      else if (right_of_diagr (x, y) ||
		       (right_of_diagm (x, y) &&
			below_diagb (x, y) &&
			!inside_circle (x, y)))
		{
		  /* curled region */
		  for (k = 0; k <= alpha_pos; k++)
		    pp[k] = 0;
		}
	      else
		{
		  v.x = -(sel_width - x);
		  v.y = -(sel_height - y);
		  angle = acos (gimp_vector2_inner_product (&v, &dl) /
				(gimp_vector2_length (&v) * dl_mag));

		  if (inside_circle (x, y) || below_diagb (x, y))
		    {
		      /* Below the curl. */
		      factor = angle / alpha;
		      for (k = 0; k < alpha_pos; k++)
			pp[k] = 0;

		      pp[alpha_pos] = (curl.shade ?
                                       (guchar) ((float) 255 * (float) factor) :
                                       0);
		    }
		  else
		    {
		      /* On the curl */
                      switch (curl.colors)
                        {
                        case CURL_COLORS_FG_BG:
			  intensity = pow (sin (G_PI * angle / alpha), 1.5);
			  if (color_image)
			    {
			      pp[0] = (intensity * back_color[0] +
                                       (1.0 - intensity) * fore_color[0]);
			      pp[1] = (intensity * back_color[1] +
                                       (1.0 - intensity) * fore_color[1]);
			      pp[2] = (intensity * back_color[2] +
                                       (1.0 - intensity) * fore_color[2]);
			    }
			  else
			    pp[0] = (intensity * back_grayval +
                                     (1 - intensity) * fore_grayval);

			  pp[alpha_pos] = (guchar) ((double) 255.99 *
                                                    (1.0 - intensity *
                                                     (1.0 - curl.opacity)));
                          break;

                        case CURL_COLORS_GRADIENT:
                        case CURL_COLORS_GRADIENT_REVERSE:
			  /* Calculate position in Gradient */
                          intensity =
                            (angle/alpha) + sin (G_PI*2 * angle/alpha) * 0.075;

			  /* Check boundaries */
			  intensity = CLAMP (intensity, 0.0, 1.0);
			  gradsamp  = (grad_samples +
                                       ((guint) (intensity * NGRADSAMPLES)) *
                                       dest_rgn.bpp);

			  if (color_image)
			    {
			      pp[0] = gradsamp[0];
			      pp[1] = gradsamp[1];
			      pp[2] = gradsamp[2];
			    }
			  else
			    pp[0] = gradsamp[0];

			  pp[alpha_pos] =
                            (guchar) ((double) gradsamp[alpha_pos] *
                                      (1.0 - intensity * (1.0 - curl.opacity)));
                          break;
                        }
		    }
		}
	      pp += dest_rgn.bpp;
	    }
	  dest += dest_rgn.rowstride;
	}
      progress += dest_rgn.w * dest_rgn.h;
      gimp_progress_update ((double) progress / (double) max_progress);
    }

  gimp_progress_update (1.0);
  gimp_drawable_flush (curl_layer);
  gimp_drawable_merge_shadow (curl_layer->drawable_id, FALSE);
  gimp_drawable_update (curl_layer->drawable_id,
			0, 0, curl_layer->width, curl_layer->height);
  gimp_drawable_detach (curl_layer);

  g_free (grad_samples);

  return curl_layer_id;
}
Exemplo n.º 6
0
/* Create a layer with the provided image data and add it to the image */
gboolean create_layer(gint32   image_ID,
                      uint8_t *layer_data,
                      gint32   position,
                      gchar   *name,
                      gint     width,
                      gint     height,
                      gint32   offsetx,
                      gint32   offsety)
{
    gint32        layer_ID;
#ifdef GIMP_2_9
    GeglBuffer   *geglbuffer;
    GeglRectangle extent;
#else
    GimpDrawable *drawable;
    GimpPixelRgn  region;
#endif

    layer_ID = gimp_layer_new(image_ID,
                              name,
                              width, height,
	                          GIMP_RGBA_IMAGE,
	                          100,
                              GIMP_NORMAL_MODE);

#ifdef GIMP_2_9
	/* Retrieve the buffer for the layer */
	geglbuffer = gimp_drawable_get_buffer(layer_ID);

	/* Copy the image data to the region */
    gegl_rectangle_set(&extent, 0, 0, width, height);
    gegl_buffer_set(geglbuffer, &extent, 0, NULL, layer_data, GEGL_AUTO_ROWSTRIDE);

	/* Flush the drawable and detach */
    gegl_buffer_flush(geglbuffer);

	g_object_unref(geglbuffer);
#else
    /* Retrieve the drawable for the layer */
    drawable = gimp_drawable_get(layer_ID);

    /* Get a pixel region from the layer */
    gimp_pixel_rgn_init(&region,
                        drawable,
                        0, 0,
                        width, height,
                        FALSE, FALSE);

    /* Copy the image data to the region */
    gimp_pixel_rgn_set_rect(&region,
                            layer_data,
                            0, 0,
                            width, height);

    /* Flush the drawable and detach */
    gimp_drawable_flush(drawable);
    gimp_drawable_detach(drawable);
#endif

    /* Add the new layer to the image */
    gimp_image_insert_layer(image_ID, layer_ID, -1, position);

    /* If layer offsets were provided, use them to position the image */
    if (offsetx || offsety) {
        gimp_layer_set_offsets(layer_ID, offsetx, offsety);
    }

    /* TODO: fix this */
    return TRUE;
}
Exemplo n.º 7
0
/* 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;
}
Exemplo n.º 8
0
static void
rotate_drawable (GimpDrawable *drawable)
{
  GimpPixelRgn  srcPR, destPR;
  gint          width, height;
  gint          longside;
  gint          bytes;
  gint          row, col;
  gint          offsetx, offsety;
  gboolean      was_lock_alpha = FALSE;
  guchar       *buffer;
  guchar       *src_row, *dest_row;

  /* initialize */

  row = 0;

  /* Get the size of the input drawable. */
  width = drawable->width;
  height = drawable->height;
  bytes = drawable->bpp;

  if (gimp_layer_get_lock_alpha (drawable->drawable_id))
    {
      was_lock_alpha = TRUE;
      gimp_layer_set_lock_alpha (drawable->drawable_id, FALSE);
    }

  if (rotvals.angle == 2)  /* we're rotating by 180° */
    {
      gimp_tile_cache_ntiles (2 * (width / gimp_tile_width() + 1));

      gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height,
                           FALSE, FALSE);
      gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height,
                           TRUE, TRUE);

      src_row  = (guchar *) g_malloc (width * bytes);
      dest_row = (guchar *) g_malloc (width * bytes);

      for (row = 0; row < height; row++)
        {
          gimp_pixel_rgn_get_row (&srcPR, src_row, 0, row, width);
          for (col = 0; col < width; col++)
            {
              memcpy (dest_row + col * bytes,
                      src_row + (width - 1 - col) * bytes,
                      bytes);
            }
          gimp_pixel_rgn_set_row (&destPR, dest_row, 0, (height - row - 1),
                                  width);

          if ((row % 5) == 0)
            gimp_progress_update ((double) row / (double) height);
        }

      g_free (src_row);
      g_free (dest_row);

      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, 0, 0, width, height);

    }
  else                     /* we're rotating by 90° or 270° */
    {
      (width > height) ? (longside = width) : (longside = height);

      gimp_layer_resize (drawable->drawable_id, longside, longside, 0, 0);
      drawable = gimp_drawable_get (drawable->drawable_id);
      gimp_drawable_flush (drawable);

      gimp_tile_cache_ntiles ((longside / gimp_tile_width () + 1) +
                              (longside / gimp_tile_height () + 1));

      gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, longside, longside,
                           FALSE, FALSE);
      gimp_pixel_rgn_init (&destPR, drawable, 0, 0, longside, longside,
                           TRUE, TRUE);

      buffer = g_malloc (longside * bytes);

      if (rotvals.angle == 1)     /* we're rotating by 90° */
        {
          for (row = 0; row < height; row++)
            {
              gimp_pixel_rgn_get_row (&srcPR, buffer, 0, row, width);
              gimp_pixel_rgn_set_col (&destPR, buffer, (height - row - 1), 0,
                                      width);

              if ((row % 5) == 0)
                gimp_progress_update ((double) row / (double) height);
            }
        }
      else                        /* we're rotating by 270° */
        {
          for (col = 0; col < width; col++)
            {
              gimp_pixel_rgn_get_col (&srcPR, buffer, col, 0, height);
              gimp_pixel_rgn_set_row (&destPR, buffer, 0, (width - col - 1),
                                      height);

              if ((col % 5) == 0)
                gimp_progress_update ((double) col / (double) width);
            }
        }

      g_free (buffer);

      gimp_progress_update (1.0);

      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, 0, 0, height, width);

      gimp_layer_resize (drawable->drawable_id, height, width, 0, 0);
      drawable = gimp_drawable_get (drawable->drawable_id);
      gimp_drawable_flush (drawable);
      gimp_drawable_update (drawable->drawable_id, 0, 0, height, width);
    }

  gimp_drawable_offsets (drawable->drawable_id, &offsetx, &offsety);
  rotate_compute_offsets (&offsetx, &offsety,
                          gimp_image_width (image_ID),
                          gimp_image_height (image_ID),
                          width, height);
  gimp_layer_set_offsets (drawable->drawable_id, offsetx, offsety);

  if (was_lock_alpha)
    gimp_layer_set_lock_alpha (drawable->drawable_id, TRUE);

  return;
}
Exemplo n.º 9
0
/* -------------------------------
 * gap_drawable_foreground_extract
 * -------------------------------
 * perform foreground extraction.
 * This is done in 3 steps INIT, EXTRACTION, DONE (e.g. cleanup)
 */
static gint32
gap_drawable_foreground_extract (GimpDrawable              *drawable,
                                 GimpDrawable              *maskDrawable,
                                 GapFgExtractValues        *fgValPtr
                                 )
{
  GappMattingState *state;
  gint32            resultLayerId;
  gint              mask_offset_x;
  gint              mask_offset_y;

  resultLayerId = -1;

  /* get mask offsets within the image
   *  - in case mask is a channel offsets are always 0)
   *  - in case mask is a layer retieve its offsets
   */
  gimp_drawable_offsets (drawable->drawable_id, &mask_offset_x, &mask_offset_y);

  state = gap_drawable_foreground_extract_matting_init (drawable,
        mask_offset_x, mask_offset_y,
        maskDrawable->width,
        maskDrawable->height
        );

  if (state)
  {
    gint32 imageId;

    imageId = gimp_drawable_get_image(drawable->drawable_id);
    resultLayerId = gimp_layer_new(imageId
            , "FG"
            , drawable->width
            , drawable->height
            , GIMP_RGBA_IMAGE
            , 100.0   /* full opacity */
            , GIMP_NORMAL_MODE       /* normal mode */
            );
    if (resultLayerId != -1)
    {
      GimpDrawable *resultDrawable;

      resultDrawable = gimp_drawable_get(resultLayerId);
      if (resultDrawable != NULL)
      {
        gint          offset_x;
        gint          offset_y;
        gboolean      resultUpdateRequired;


        resultUpdateRequired = FALSE;

        /* get offsets of the input drawable (layer) within the image */
        gimp_drawable_offsets (drawable->drawable_id, &offset_x, &offset_y);

        /* add resulting layer (of same size at same offsets) to the same image */
        gimp_image_add_layer(imageId, resultLayerId, -1 /* stackposition */ );
        gimp_layer_set_offsets(resultLayerId, offset_x, offset_y);

        /* perform the foreground extraction */
        gap_drawable_foreground_extract_matting (maskDrawable, resultDrawable, state,
            0.0 // start_percentage 0 (non-interactive shall always start rendering immediate
            );

        /* clean up after fg extract is done */
        gap_drawable_foreground_extract_matting_done (state);

        /* postprocessing */
        if (fgValPtr->lock_color)
        {
          if(gap_debug)
          {
            printf("postprocessing: restore resultDrawable:%d RGB channels from original drawable:%d\n"
               ,(int)resultDrawable->drawable_id
               ,(int)drawable->drawable_id
               );
          }
          resultUpdateRequired = TRUE;
          gap_fg_rgn_copy_rgb_channels(drawable, resultDrawable);
        }

        if (fgValPtr->create_layermask)
        {
          gint32 resultLayerMaskId;

          /* create a new layermask (from alpha channel) */
          resultLayerMaskId = gimp_layer_create_mask(resultLayerId, GIMP_ADD_ALPHA_MASK);
          gimp_layer_add_mask(resultLayerId, resultLayerMaskId);
          if (gimp_drawable_has_alpha(drawable->drawable_id))
          {
            if(gap_debug)
            {
              printf("postprocessing: restore resultDrawable:%d ALPHA channel from original drawable:%d\n"
               ,(int)resultDrawable->drawable_id
               ,(int)drawable->drawable_id
               );
            }
            /* copy the original alpha channel to the result layer */
            gap_fg_rgn_copy_alpha_channel(drawable, resultDrawable);
            resultUpdateRequired = TRUE;
          }
        }

        if(resultUpdateRequired)
        {
          gimp_drawable_update (resultDrawable->drawable_id
                               , 0, 0
                               , resultDrawable->width, resultDrawable->height
                               );
        }


        gimp_drawable_detach (resultDrawable);
      }
    }
  }

  return (resultLayerId);

}  /* end gap_drawable_foreground_extract */
Exemplo n.º 10
0
/* ------------------------------------
 * gap_image_merge_group_layer
 * ------------------------------------
 * merge the specified group layer and return the id of the resulting layer.
 *
 * The merge strategy
 *  o) create a temporary image  of same size/type (l_tmp_img_id)
 *  o) copy the specified grouplayer to the temporary image (l_tmp_img_id)
 *  o) call gimp_image_merge_visible_layers on the temporary image (l_tmp_img_id, mode)
 *  o) copy the merged layer back to the original image
 *      to the same group at the position of the original layergroup
 *  o) remove the temporary image
 *  o) remove original layergroup
 *  o) rename the resuling merged layer.
 *
 * returns   0 if all done OK
 *           (or -1 on error)
 */
gint32
gap_image_merge_group_layer(gint32 image_id,
              gint32 group_layer_id,
              gint merge_mode)
{
  gint32   l_tmp_img_id;
  gint32   l_new_layer_id;
  gint32   l_merged_layer_id;
  gint32   l_parent_id;
  gint32   l_position;
  gint     l_src_offset_x;
  gint     l_src_offset_y;
  gboolean l_visible;
  char    *l_name;

  if (!gimp_item_is_group(group_layer_id))
  {
    /* the specified group_layer_id is not a group
     * -- no merge is done, return its id as result --
     */
    return(group_layer_id);
  }
  l_visible = gimp_item_get_visible(group_layer_id);
  l_name = gimp_item_get_name(group_layer_id);

  /* create a temporary image */
  l_tmp_img_id = gap_image_new_of_samesize(image_id);

  /* copy the grouplayer to the temporary image  */
  l_new_layer_id = gap_layer_copy_to_dest_image(l_tmp_img_id,
                                         group_layer_id,
                                         100.0,   /* full opacity */
                                         0,       /* NORMAL paintmode */
                                         &l_src_offset_x,
                                         &l_src_offset_y
                                         );

  gimp_image_insert_layer (l_tmp_img_id, l_new_layer_id, 0, 0);
  gimp_layer_set_offsets(l_new_layer_id, l_src_offset_x, l_src_offset_y);
  gimp_item_set_visible(l_new_layer_id, TRUE);


  /* merge visible layers in the temporary image */
  l_merged_layer_id = gimp_image_merge_visible_layers (l_tmp_img_id, merge_mode);
  l_new_layer_id = gap_layer_copy_to_dest_image(image_id,
                                         l_merged_layer_id,
                                         gimp_layer_get_opacity(group_layer_id),
                                         gimp_layer_get_mode(group_layer_id),
                                         &l_src_offset_x,
                                         &l_src_offset_y
                                         );
  l_position = gimp_image_get_item_position (image_id, group_layer_id);
  l_parent_id = gimp_item_get_parent(group_layer_id);
  if (l_parent_id < 0)
  {
    l_parent_id = 0;
  }
  gimp_image_insert_layer (image_id, l_new_layer_id, l_parent_id, l_position);
  gimp_layer_set_offsets(l_new_layer_id, l_src_offset_x, l_src_offset_y);

  /* remove the original group layer from the original image */
  gimp_image_remove_layer(image_id, group_layer_id);

  /* restore the original layer name */
  if (l_name != NULL)
  {
    gimp_item_set_name(l_new_layer_id, l_name);
    g_free(l_name);
  }
  gimp_item_set_visible(l_new_layer_id, l_visible);

  /* remove the temporary image */
  gap_image_delete_immediate(l_tmp_img_id);
  return(l_new_layer_id);

}  /* end gap_image_merge_group_layer */
Exemplo n.º 11
0
static GimpPDBStatusType
align_layers (gint32 image_id)
{
  gint  layer_num = 0;
  gint  visible_layer_num = 0;
  gint *layers = NULL;
  gint  index;
  gint  vindex;
  gint  step_x   = 0;
  gint  step_y   = 0;
  gint  x        = 0;
  gint  y        = 0;
  gint  orig_x   = 0;
  gint  orig_y   = 0;
  gint  offset_x = 0;
  gint  offset_y = 0;
  gint  base_x   = 0;
  gint  base_y   = 0;
  gint  bg_index = 0;

  layers = gimp_image_get_layers (image_id, &layer_num);
  bg_index = layer_num - 1;

  for (index = 0; index < layer_num; index++)
    {
      if (gimp_item_get_visible (layers[index]))
        visible_layer_num++;
    }

  if (VALS.ignore_bottom)
    {
      layer_num--;
      if (gimp_item_get_visible (layers[bg_index]))
        visible_layer_num--;
    }

  if (0 < visible_layer_num)
    {
      gint      min_x = G_MAXINT;
      gint      min_y = G_MAXINT;
      gint      max_x = G_MININT;
      gint      max_y = G_MININT;

      /* 0 is the top layer */
      for (index = 0; index < layer_num; index++)
        {
          if (gimp_item_get_visible (layers[index]))
            {
              gimp_drawable_offsets (layers[index], &orig_x, &orig_y);
              align_layers_get_align_offsets (layers[index], &offset_x,
                                              &offset_y);
              orig_x += offset_x;
              orig_y += offset_y;

              if ( orig_x < min_x ) min_x = orig_x;
              if ( max_x < orig_x ) max_x = orig_x;
              if ( orig_y < min_y ) min_y = orig_y;
              if ( max_y < orig_y ) max_y = orig_y;
            }
        }

      if (VALS.base_is_bottom_layer)
        {
          gimp_drawable_offsets (layers[bg_index], &orig_x, &orig_y);
          align_layers_get_align_offsets (layers[bg_index], &offset_x,
                                          &offset_y);
          orig_x += offset_x;
          orig_y += offset_y;
          base_x = min_x = orig_x;
          base_y = min_y = orig_y;
        }

      if (visible_layer_num > 1)
        {
          step_x = (max_x - min_x) / (visible_layer_num - 1);
          step_y = (max_y - min_y) / (visible_layer_num - 1);
        }

      if ( (VALS.h_style == LEFT2RIGHT) || (VALS.h_style == RIGHT2LEFT))
        base_x = min_x;

      if ( (VALS.v_style == TOP2BOTTOM) || (VALS.v_style == BOTTOM2TOP))
        base_y = min_y;
    }

  gimp_image_undo_group_start (image_id);

  for (vindex = -1, index = 0; index < layer_num; index++)
    {
      if (gimp_item_get_visible (layers[index]))
        vindex++;
      else
        continue;

      gimp_drawable_offsets (layers[index], &orig_x, &orig_y);
      align_layers_get_align_offsets (layers[index], &offset_x, &offset_y);

      switch (VALS.h_style)
        {
        case H_NONE:
          x = orig_x;
          break;
        case H_COLLECT:
          x = base_x - offset_x;
          break;
        case LEFT2RIGHT:
          x = (base_x + vindex * step_x) - offset_x;
          break;
        case RIGHT2LEFT:
          x = (base_x + (visible_layer_num - vindex - 1) * step_x) - offset_x;
          break;
        case SNAP2HGRID:
          x = VALS.grid_size
            * (int) ((orig_x + offset_x + VALS.grid_size /2) / VALS.grid_size)
            - offset_x;
          break;
        }
      switch (VALS.v_style)
        {
        case V_NONE:
          y = orig_y;
          break;
        case V_COLLECT:
          y = base_y - offset_y;
          break;
        case TOP2BOTTOM:
          y = (base_y + vindex * step_y) - offset_y;
          break;
        case BOTTOM2TOP:
          y = (base_y + (visible_layer_num - vindex - 1) * step_y) - offset_y;
          break;
        case SNAP2VGRID:
          y = VALS.grid_size
            * (int) ((orig_y + offset_y + VALS.grid_size / 2) / VALS.grid_size)
            - offset_y;
          break;
        }
      gimp_layer_set_offsets (layers[index], x, y);
    }

  gimp_image_undo_group_end (image_id);

  return GIMP_PDB_SUCCESS;
}
Exemplo n.º 12
0
/*
 * Modifies position of each visible layers
 * according to data.
 */
static void
align_layers_perform_alignment (gint      *layers,
                                gint       layer_num,
                                AlignData  data)
{
  gint index;

  for (index = 0; index < layer_num; index++)
    {
      gint x = 0;
      gint y = 0;
      gint orig_x;
      gint orig_y;
      gint offset_x;
      gint offset_y;

      gimp_drawable_offsets (layers[index], &orig_x, &orig_y);

      align_layers_get_align_offsets (layers[index],
                                      &offset_x,
                                      &offset_y);
      switch (VALS.h_style)
        {
        case H_NONE:
          x = orig_x;
          break;
        case H_COLLECT:
          x = data.base_x - offset_x;
          break;
        case LEFT2RIGHT:
          x = (data.base_x + index * data.step_x) - offset_x;
          break;
        case RIGHT2LEFT:
          x = (data.base_x + (layer_num - index - 1) * data.step_x) - offset_x;
          break;
        case SNAP2HGRID:
          x = VALS.grid_size
            * (int) ((orig_x + offset_x + VALS.grid_size /2) / VALS.grid_size)
            - offset_x;
          break;
        }

      switch (VALS.v_style)
        {
        case V_NONE:
          y = orig_y;
          break;
        case V_COLLECT:
          y = data.base_y - offset_y;
          break;
        case TOP2BOTTOM:
          y = (data.base_y + index * data.step_y) - offset_y;
          break;
        case BOTTOM2TOP:
          y = (data.base_y + (layer_num - index - 1) * data.step_y) - offset_y;
          break;
        case SNAP2VGRID:
          y = VALS.grid_size
            * (int) ((orig_y + offset_y + VALS.grid_size / 2) / VALS.grid_size)
            - offset_y;
          break;
        }

      gimp_layer_set_offsets (layers[index], x, y);
    }
}