Exemple #1
0
static inline void
randomize_prepare_row (GimpPixelRgn *pixel_rgn,
                       guchar    *data,
                       int        x,
                       int        y,
                       int        w)
{
  gint b;

  if (y <= 0)
    {
      gimp_pixel_rgn_get_row(pixel_rgn, data, x, (y + 1), w);
    }
  else if (y >= pixel_rgn->h)
    {
      gimp_pixel_rgn_get_row(pixel_rgn, data, x, (y - 1), w);
    }
  else
    {
      gimp_pixel_rgn_get_row(pixel_rgn, data, x, y, w);
    }
  /*
   *  Fill in edge pixels
   */
  for (b = 0; b < pixel_rgn->bpp; b++)
    {
      data[-(gint)pixel_rgn->bpp + b] = data[b];
      data[w * pixel_rgn->bpp + b] = data[(w - 1) * pixel_rgn->bpp + b];
    }
}
Exemple #2
0
static void getrange  (GimpDrawable     *drawable, guchar *mintab, guchar *maxtab,  gint x1, gint y1, gint x2, gint y2)
{
    gint         i, j, k, channels;
    GimpPixelRgn rgn_in;
    guchar      *inrow;

  channels = gimp_drawable_bpp (drawable->drawable_id);

  gimp_pixel_rgn_init (&rgn_in,   drawable,   x1, y1,   x2 - x1, y2 - y1,  FALSE, FALSE);  

   inrow = g_new (guchar, channels * (x2 - x1));
 
  for (j = 0; j < 4; j++){
	mintab[j]=255;
	maxtab[j]=0;
  }
  for (i = y1; i < y2; i++)
     {
         /* Get row i */
         gimp_pixel_rgn_get_row (&rgn_in, inrow, x1, i, x2 - x1);
         for (j = x1; j < x2; j++)
           {
              for (k = 0; k < channels; k++){
                  mintab[k]=MIN ( inrow[channels * (j - x1) + k], mintab[k] ) ;
                  maxtab[k]=MAX ( inrow[channels * (j - x1) + k], maxtab[k] ) ;
              }
	   }
     }
  g_free (inrow);
}
Exemple #3
0
static void
color_rotate (GimpDrawable *drawable)
{
  GimpPixelRgn srcPR, destPR;
  gint         width, height;
  gint         bytes;
  guchar      *src_row, *dest_row;
  gint         row;
  gint         x, y;

  if (! gimp_drawable_mask_intersect (drawable->drawable_id,
                                      &x, &y, &width, &height))
    {
      return;
    }

  bytes = drawable->bpp;

  src_row  = g_new (guchar, width * bytes);
  dest_row = g_new (guchar, width * bytes);

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

  for (row = y; row < (y + height); row++)
    {
      gimp_pixel_rgn_get_row (&srcPR, src_row, x, row, width);

      color_rotate_row (src_row, dest_row, row, width, bytes);

      gimp_pixel_rgn_set_row (&destPR, dest_row, x, row, width);

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

  /*  update the processed region  */

  gimp_progress_update (1.0);
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id, x, y, width, height);

  g_free (src_row);
  g_free (dest_row);
}
Exemple #4
0
static void
prepare_row (GimpPixelRgn *pixel_rgn,
             guchar       *data,
             gint          x,
             gint          y,
             gint          w)
{
  gint b;

  if (y <= 0)
    gimp_pixel_rgn_get_row (pixel_rgn, data, x, (y + 1), w);
  else if (y >= pixel_rgn->h)
    gimp_pixel_rgn_get_row (pixel_rgn, data, x, (y - 1), w);
  else
    gimp_pixel_rgn_get_row (pixel_rgn, data, x, y, w);

  /*  Fill in edge pixels  */
  for (b = 0; b < pixel_rgn->bpp; b++)
    {
      data[-(gint)pixel_rgn->bpp + b] = data[b];
      data[w * pixel_rgn->bpp + b] = data[(w - 1) * pixel_rgn->bpp + b];
    }
}
Exemple #5
0
static void
render_gray_image(Preview_t *preview_base, GimpPixelRgn *srcrgn)
{
    guchar        *src_row, *dest_buffer, *src, *dest;
    gint          row, col;
    gint          bpp, dwidth, dheight, pwidth, pheight;
    gint          *src_col;
    GtkWidget     *preview = preview_base->preview;

    dwidth  = srcrgn->w;
    dheight = srcrgn->h;
    pwidth = preview_base->widget_width;
    pheight = preview_base->widget_height;
    bpp = srcrgn->bpp;

    src_row = g_new(guchar, dwidth * bpp);
    dest_buffer = g_new(guchar, pwidth * pheight);
    src_col = g_new(gint, pwidth);

    for (col = 0; col < pwidth; col++)
        src_col[col] = (col * dwidth / pwidth) * bpp;

    dest = dest_buffer;

    for (row = 0; row < pheight; row++) {
        gimp_pixel_rgn_get_row(srcrgn, src_row, 0, row * dheight / pheight,
                               dwidth);

        src = src_row;

        for (col = 0; col < pwidth; col++) {
            src = &src_row[src_col[col]];
            *dest++ = *src;
        }
    }
    gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview),
                            0, 0, pwidth, pheight,
                            GIMP_GRAY_IMAGE,
                            dest_buffer,
                            pwidth);
    g_free(src_col);
    g_free(src_row);
    g_free(dest_buffer);

}
Exemple #6
0
static void blur (GimpDrawable *drawable) {
	gint i, j, k, channels;
	gint x1, y1, x2, y2;
	GimpPixelRgn rgn_in, rgn_out;
	guchar *row1, *row2, *row3;
	guchar *outrow;

	gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
	channels = gimp_drawable_bpp (drawable->drawable_id);

	gimp_pixel_rgn_init (&rgn_in, drawable, x1, y1, x2 - x1, y2 - y1, FALSE, FALSE);
	gimp_pixel_rgn_init (&rgn_out, drawable, x1, y1, x2 - x1, y2 - y1, TRUE, TRUE);

	/* Initialise enough memory for row1, row2, row3, outrow */
	row1 = g_new (guchar, channels * (x2 - x1));
	outrow = g_new (guchar, channels * (x2 - x1));

	for (i = y1; i < y2; i++) {
		/* Get row i-1, i, i+1 */
		gimp_pixel_rgn_get_row (&rgn_in, row1, x1, MAX (y1, i - 1), x2 - x1);

		for (j = x1; j < x2; j++) {
			/* For each layer, compute the average of the nine pixels */
			for (k = 0; k < channels; k++) {
				int in = row1[channels * (j - x1) + k];
				int a = (1.0 - (in / 255.0)) * 100.0;
				int r = rand() % 100;
				outrow[channels * (j - x1) + k] = r < a ? 0 : 255;
			}
		}

		gimp_pixel_rgn_set_row (&rgn_out, outrow, x1, i, x2 - x1);

		if (i % 10 == 0)
			gimp_progress_update ((gdouble) (i - y1) / (gdouble) (y2 - y1));
	}

	g_free (row1);
	g_free (outrow);

	gimp_drawable_flush (drawable);
	gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
	gimp_drawable_update (drawable->drawable_id, x1, y1, x2 - x1, y2 - y1);
}
Exemple #7
0
static void
sobel_prepare_row (GimpPixelRgn *pixel_rgn,
                   guchar       *data,
                   gint          x,
                   gint          y,
                   gint          w)
{
  gint b;

  y = CLAMP (y, 0, pixel_rgn->h - 1);
  gimp_pixel_rgn_get_row (pixel_rgn, data, x, y, w);

  /*  Fill in edge pixels  */
  for (b = 0; b < pixel_rgn->bpp; b++)
    {
      data[-(int)pixel_rgn->bpp + b] = data[b];
      data[w * pixel_rgn->bpp + b] = data[(w - 1) * pixel_rgn->bpp + b];
    }
}
Exemple #8
0
static void
shuffle (GimpPixelRgn *rgn_in,
         guchar      **row,
         gint          x1,
         gint          y1,
         gint          width,
         gint          height,
         gint          ypos)
{
  gint    i;
  guchar *tmp_row;

  /* Get tile row (i + radius + 1) into row[0] */
  gimp_pixel_rgn_get_row (rgn_in,
                          row[0],
                          x1, MIN (ypos + radius + y1, y1 + height - 1),
                          width);

  /* Permute row[i] with row[i-1] and row[0] with row[2r] */
  tmp_row = row[0];
  for (i = 1; i < 2 * radius + 1; i++)
    row[i - 1] = row[i];
  row[2 * radius] = tmp_row;
}
/* do the analyzing */
static void
analyze (GimpDrawable *drawable)
{
  GimpPixelRgn  srcPR;
  guchar       *src_row, *cmap;
  gint          x, y, numcol;
  gint          x1, y1, x2, y2, w, h;
  guchar        r, g, b;
  gint          a;
  guchar        idx;
  gboolean      gray;
  gboolean      has_alpha;
  gboolean      has_sel;
  guchar       *sel;
  GimpPixelRgn  selPR;
  gint          ofsx, ofsy;
  GimpDrawable *selDrawable;

  gimp_progress_init (_("Colorcube Analysis"));

  if (! gimp_drawable_mask_intersect (drawable->drawable_id, &x1, &y1, &w, &h))
    return;

  x2 = x1 + w;
  y2 = y1 + h;

  /*
   * Get the size of the input image (this will/must be the same
   * as the size of the output image).
   */
  width = drawable->width;
  height = drawable->height;
  bpp = drawable->bpp;

  has_sel = !gimp_selection_is_empty (imageID);
  gimp_drawable_offsets (drawable->drawable_id, &ofsx, &ofsy);

  /* initialize the pixel region */
  gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);

  cmap = gimp_image_get_colormap (imageID, &numcol);
  gray = (gimp_drawable_is_gray (drawable->drawable_id) ||
          gimp_item_is_channel (drawable->drawable_id));
  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);

  selDrawable = gimp_drawable_get (gimp_image_get_selection (imageID));
  gimp_pixel_rgn_init (&selPR,
                       selDrawable,
                       0, 0, width, height, FALSE, FALSE);

  /* allocate row buffer */
  src_row = g_new (guchar, (x2 - x1) * bpp);
  sel = g_new (guchar, x2 - x1);

  for (y = y1; y < y2; y++)
    {
      gimp_pixel_rgn_get_row (&srcPR, src_row, x1, y, (x2 - x1));
      if (has_sel)
        gimp_pixel_rgn_get_row (&selPR, sel, x1 + ofsx, y + ofsy, (x2 - x1));

      for (x = 0; x < w; x++)
        {
          /* Start with full opacity.  */
          a = 255;

          /*
           * If the image is indexed, fetch RGB values
           * from colormap.
           */
          if (cmap)
            {
              idx = src_row[x * bpp];

              r = cmap[idx * 3];
              g = cmap[idx * 3 + 1];
              b = cmap[idx * 3 + 2];
              if (has_alpha)
                a = src_row[x * bpp + 1];
            }
          else if (gray)
            {
              r = g = b = src_row[x * bpp];
              if (has_alpha)
                a = src_row[x * bpp + 1];
            }
          else
            {
              r = src_row[x * bpp];
              g = src_row[x * bpp + 1];
              b = src_row[x * bpp + 2];
              if (has_alpha)
                a = src_row[x * bpp + 3];
            }

          if (has_sel)
            a *= sel[x];
          else
            a *= 255;

          if (a != 0)
            insertcolor (r, g, b, (gdouble) a * (1.0 / (255.0 * 255.0)));
        }

      /* tell the user what we're doing */
      if ((y % 10) == 0)
        gimp_progress_update ((gdouble) y / (gdouble) (y2 - y1));
    }

  gimp_progress_update (1.0);

  /* clean up */
  gimp_drawable_detach (selDrawable);
  g_free (src_row);
  g_free (sel);
}
Exemple #10
0
static void
brushdmenuselect (GtkWidget *widget,
                  gpointer   data)
{
  GimpPixelRgn  src_rgn;
  guchar       *src_row;
  guchar       *src;
  gint          id;
  gint          bpp;
  gint          x, y;
  ppm_t        *p;
  gint          x1, y1, x2, y2;
  gint          row;
  GimpDrawable *drawable;
  gint          rowstride;

  gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &id);

  if (id == -1)
    return;

  if (brush_from_file == 2)
    return; /* Not finished GUI-building yet */

  if (brush_from_file)
    {
#if 0
      unselectall (brush_list);
#endif
      preset_save_button_set_sensitive (FALSE);
    }

  gtk_adjustment_set_value (brush_gamma_adjust, 1.0);
  gtk_adjustment_set_value (brush_aspect_adjust, 0.0);

  drawable = gimp_drawable_get (id);

  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);

  bpp = gimp_drawable_bpp (drawable->drawable_id);

  ppm_kill (&brushppm);
  ppm_new (&brushppm, x2 - x1, y2 - y1);
  p = &brushppm;

  rowstride = p->width * 3;

  src_row = g_new (guchar, (x2 - x1) * bpp);

  gimp_pixel_rgn_init (&src_rgn, drawable,
                       0, 0, x2 - x1, y2 - y1,
                       FALSE, FALSE);

  if (bpp == 3)
    { /* RGB */
      int bpr = (x2 - x1) * 3;

      for (row = 0, y = y1; y < y2; row++, y++)
        {
          gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1));
          memcpy (p->col + row*rowstride, src_row, bpr);
        }
    }
  else
    { /* RGBA (bpp > 3) GrayA (bpp == 2) or Gray */
      gboolean is_gray = ((bpp > 3) ? TRUE : FALSE);

      for (row = 0, y = y1; y < y2; row++, y++)
        {
          guchar *tmprow = p->col + row * rowstride;
          guchar *tmprow_ptr;

          gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1));
          src = src_row;
          tmprow_ptr = tmprow;
          /* Possible micro-optimization here:
           * src_end = src + src_rgn.bpp * (x2-x1);
           * for ( ; src < src_end ; src += src_rgn.bpp)
           */
          for (x = x1; x < x2; x++)
            {
              *(tmprow_ptr++) = src[0];
              *(tmprow_ptr++) = src[is_gray ? 1 : 0];
              *(tmprow_ptr++) = src[is_gray ? 2 : 0];
              src += src_rgn.bpp;
            }
        }
    }
  g_free (src_row);

  if (bpp >= 3)
    pcvals.color_brushes = 1;
  else
    pcvals.color_brushes = 0;

  brush_from_file = 0;
  update_brush_preview (NULL);
}
Exemple #11
0
static void
c2g_region (GimpPixelRgn *srcPR,
                GimpPixelRgn *destPR,
                gint          bytes, /* Bytes per pixel */
                gdouble       radius,
                gdouble       amount_p,
                gdouble       gamma_p,
                gint          x1,    /* Corners of subregion */
                gint          x2,
                gint          y1,
                gint          y2,
                gboolean      show_progress)
{
  guchar  *src;
  guchar  *dest;
  guchar *bigsrc;
  guchar *bigdest;
  guchar *tmpdest;
 
  gint     width   = x2 - x1;
  gint     height  = y2 - y1;
  gdouble *cmatrix = NULL;
  gint     cmatrix_length;
  gdouble *ctable;
  gint     row, col, idx;
  gint w = c2g_params.radius+10;

  gdouble amount = c2g_params.amount;
  gdouble gamma = c2g_params.gamma;
    
  if (show_progress)
    gimp_progress_init (_("Blurring..."));
  
  iir_init(c2g_params.radius);

  /* allocate buffers */
  src  = g_new (guchar, MAX (width, height) * bytes);
  dest = g_new (guchar, MAX (width, height) * bytes);
  iir.p = g_new(gdouble, MAX (width, height)+2*w);

 
  bigsrc = g_new(guchar, width * height * bytes);
  bigdest = g_new(guchar, width * height * bytes);
  tmpdest = g_new(guchar, width * height * bytes);

  if (show_progress)
    gimp_progress_init (_("Colour converting..."));
  
  // 1. Calculate Nayatani Grey and Blur in LAB
  gimp_pixel_rgn_get_rect (srcPR, bigsrc, x1, y1, width, height);
  extract_lab(bigsrc, bytes, width * height, bigdest);
  nayatani(bigdest,bytes,width * height, bigdest);
  gimp_pixel_rgn_set_rect (destPR, bigdest, x1, y1, width, height);

  // 2. Make a blur of Grey LAB
  for (row = 0, idx=0; row < height; row++, idx+=width)
    {
      gimp_pixel_rgn_get_row (destPR, src, x1, y1 + row, width);
      blur_line (ctable, cmatrix, cmatrix_length, src, dest, width, bytes);   
      gimp_pixel_rgn_set_row (destPR, dest, x1, y1 + row, width);
    }

  for (col = 0; col < width; col++)
    {
      gimp_pixel_rgn_get_col (destPR, src, x1 + col, y1, height);
      blur_line (ctable, cmatrix, cmatrix_length, src, dest, height, bytes);
      gimp_pixel_rgn_set_col (destPR, dest, x1 + col, y1, height);

      if (show_progress && col % 8 == 0)
        gimp_progress_update ((gdouble) col / (3 * width) + 0.33);
    }

  // 3. Convert grey and blur back to RGB.
  compose_lab(bigdest, width * height, bytes, bigdest); // bigdest=greyRGB
  gimp_pixel_rgn_get_rect (destPR, bigsrc, x1, y1, width, height);
  compose_lab(bigsrc, width * height, bytes, bigsrc); // bigsrc= blurgreyRGB

  // 4. Blur Colour RGB and write into destPR
  gimp_pixel_rgn_get_rect (srcPR, tmpdest, x1, y1, width, height);
  gimp_pixel_rgn_set_rect (destPR, tmpdest, x1, y1, width, height);

  for (row = 0, idx=0; row < height; row++, idx+=width)
    {
      gimp_pixel_rgn_get_row (destPR, src, x1, y1 + row, width);
      blur_line (ctable, cmatrix, cmatrix_length, src, dest, width, bytes);   
      gimp_pixel_rgn_set_row (destPR, dest, x1, y1 + row, width);
    }

  for (col = 0; col < width; col++)
    {
      gimp_pixel_rgn_get_col (destPR, src, x1 + col, y1, height);
      blur_line (ctable, cmatrix, cmatrix_length, src, dest, height, bytes);
      gimp_pixel_rgn_set_col (destPR, dest, x1 + col, y1, height);

      if (show_progress && col % 8 == 0)
        gimp_progress_update ((gdouble) col / (3 * width) + 0.33);
    }

  // destPR = blur colour RGB
  chromaunsharp( srcPR, destPR, bigdest, bigsrc, bytes, x1, y1, width, height, amount, gamma, tmpdest );
  compose_lab(tmpdest, width * height, bytes, tmpdest); // tmpdest has unsharp
  gimp_pixel_rgn_set_rect (destPR, tmpdest, x1, y1, width, height);
  

  if (show_progress)
    gimp_progress_update (0.0);

  g_free (bigsrc);
  g_free (bigdest);
  g_free (tmpdest);
  g_free (iir.p);
  g_free (dest);
  g_free (src);
  
}
Exemple #12
0
void
precompute_normals (gint x1,
                    gint x2,
                    gint y)
{
  GimpVector3 *tmpv, p1, p2, p3, normal;
  gdouble     *tmpd;
  gint         n, i, nv;
  guchar      *map = NULL;
  gint bpp = 1;
  guchar mapval;


  /* First, compute the heights */
  /* ========================== */

  tmpv                = triangle_normals[0];
  triangle_normals[0] = triangle_normals[1];
  triangle_normals[1] = tmpv;

  tmpv              = vertex_normals[0];
  vertex_normals[0] = vertex_normals[1];
  vertex_normals[1] = vertex_normals[2];
  vertex_normals[2] = tmpv;

  tmpd       = heights[0];
  heights[0] = heights[1];
  heights[1] = heights[2];
  heights[2] = tmpd;

  if (mapvals.bumpmap_id != -1)
    {
      bpp = gimp_drawable_bpp(mapvals.bumpmap_id);
    }

  gimp_pixel_rgn_get_row (&bump_region, bumprow, x1, y, x2 - x1);

  if (mapvals.bumpmaptype > 0)
    {
      switch (mapvals.bumpmaptype)
        {
          case 1:
            map = logmap;
            break;
          case 2:
            map = sinemap;
            break;
          default:
            map = spheremap;
            break;
        }

      for (n = 0; n < (x2 - x1); n++)
        {
          if (bpp>1)
            {
              mapval = (guchar)((float)((bumprow[n * bpp] +bumprow[n * bpp +1] + bumprow[n * bpp + 2])/3.0 )) ;
            }
          else
            {
              mapval = bumprow[n * bpp];
            }

          heights[2][n] = (gdouble) mapvals.bumpmax * (gdouble) map[mapval] / 255.0;
        }
    }
  else
    {
      for (n = 0; n < (x2 - x1); n++)
        {
          if (bpp>1)
            {
              mapval = (guchar)((float)((bumprow[n * bpp] +bumprow[n * bpp +1] + bumprow[n * bpp + 2])/3.0 )) ;
            }
          else
            {
              mapval = bumprow[n * bpp];
            }
          heights[2][n] = (gdouble) mapvals.bumpmax * (gdouble) mapval / 255.0;
        }
    }

  /* Compute triangle normals */
  /* ======================== */

  i = 0;
  for (n = 0; n < (x2 - x1 - 1); n++)
    {
      p1.x = 0.0;
      p1.y = ystep;
      p1.z = heights[2][n] - heights[1][n];

      p2.x = xstep;
      p2.y = ystep;
      p2.z = heights[2][n+1] - heights[1][n];

      p3.x = xstep;
      p3.y = 0.0;
      p3.z = heights[1][n+1] - heights[1][n];

      triangle_normals[1][i] = gimp_vector3_cross_product (&p2, &p1);
      triangle_normals[1][i+1] = gimp_vector3_cross_product (&p3, &p2);

      gimp_vector3_normalize (&triangle_normals[1][i]);
      gimp_vector3_normalize (&triangle_normals[1][i+1]);

      i += 2;
    }

  /* Compute vertex normals */
  /* ====================== */

  i = 0;
  gimp_vector3_set (&normal, 0.0, 0.0, 0.0);

  for (n = 0; n < (x2 - x1 - 1); n++)
    {
      nv = 0;

      if (n > 0)
        {
          if (y > 0)
            {
              gimp_vector3_add (&normal, &normal, &triangle_normals[0][i-1]);
              gimp_vector3_add (&normal, &normal, &triangle_normals[0][i-2]);
              nv += 2;
            }

          if (y < pre_h)
            {
              gimp_vector3_add (&normal, &normal, &triangle_normals[1][i-1]);
              nv++;
            }
        }

      if (n <pre_w)
        {
          if (y > 0)
            {
              gimp_vector3_add (&normal, &normal, &triangle_normals[0][i]);
              gimp_vector3_add (&normal, &normal, &triangle_normals[0][i+1]);
              nv += 2;
            }

          if (y < pre_h)
            {
              gimp_vector3_add (&normal, &normal, &triangle_normals[1][i]);
              gimp_vector3_add (&normal, &normal, &triangle_normals[1][i+1]);
              nv += 2;
            }
        }

      gimp_vector3_mul (&normal, 1.0 / (gdouble) nv);
      gimp_vector3_normalize (&normal);
      vertex_normals[1][n] = normal;

      i += 2;
    }
}
Exemple #13
0
gboolean
draw_page_cairo (GtkPrintContext *context,
                 PrintData       *data)
{
  GimpDrawable    *drawable = gimp_drawable_get (data->drawable_id);
  GimpPixelRgn     region;
  cairo_t         *cr;
  cairo_surface_t *surface;
  guchar          *pixels;
  gdouble          cr_width;
  gdouble          cr_height;
  gdouble          cr_dpi_x;
  gdouble          cr_dpi_y;
  gint             width;
  gint             height;
  gint             stride;
  gint             y;
  gdouble          scale_x;
  gdouble          scale_y;

  width  = drawable->width;
  height = drawable->height;

  gimp_tile_cache_ntiles (width / gimp_tile_width () + 1);

  cr = gtk_print_context_get_cairo_context (context);

  cr_width  = gtk_print_context_get_width  (context);
  cr_height = gtk_print_context_get_height (context);
  cr_dpi_x  = gtk_print_context_get_dpi_x  (context);
  cr_dpi_y  = gtk_print_context_get_dpi_y  (context);

  scale_x = cr_dpi_x / data->xres;
  scale_y = cr_dpi_y / data->yres;

#if 0
  /* print header if it is requested */
  if (data->show_info_header)
    {
      draw_info_header (context, cr, data);

/* In points */
#define HEADER_HEIGHT (20 * 72.0 / 25.4)
      cairo_translate (cr, 0, HEADER_HEIGHT);
      cr_height -= HEADER_HEIGHT;
    }
#endif

  cairo_translate (cr,
                   data->offset_x / cr_dpi_x * 72.0,
                   data->offset_y / cr_dpi_y * 72.0);
  cairo_scale (cr, scale_x, scale_y);

  gimp_pixel_rgn_init (&region, drawable, 0, 0, width, height, FALSE, FALSE);

  surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);

  pixels = cairo_image_surface_get_data (surface);
  stride = cairo_image_surface_get_stride (surface);

  for (y = 0; y < height; y++, pixels += stride)
    {
      gimp_pixel_rgn_get_row (&region, pixels, 0, y, width);

      switch (drawable->bpp)
        {
        case 3:
          convert_from_rgb (pixels, width);
          break;
        case 4:
          convert_from_rgba (pixels, width);
          break;
        }

      if (y % 16 == 0)
        gimp_progress_update ((gdouble) y / (gdouble) height);
    }

  cairo_set_source_surface (cr, surface, 0, 0);
  cairo_rectangle (cr, 0, 0, width, height);
  cairo_fill (cr);
  cairo_surface_destroy (surface);

  gimp_progress_update (1.0);

  gimp_drawable_detach (drawable);

  return TRUE;
}
/* Interpol linearly height[2] and triangle_normals[1]
 * using the next row
 */
void
interpol_row (gint x1,
              gint x2,
              gint y)
{
  GimpVector3   p1, p2, p3;
  gint          n, i;
  guchar        *map = NULL;
  gint          bpp = 1;
  guchar* bumprow1 = NULL;
  guchar* bumprow2 = NULL;

  if (mapvals.bumpmap_id != -1)
    {
      bpp = gimp_drawable_bpp(mapvals.bumpmap_id);
    }

  bumprow1 = g_new (guchar, pre_w * bpp);
  bumprow2 = g_new (guchar, pre_w * bpp);

  gimp_pixel_rgn_get_row (&bump_region, bumprow1, x1, y, x2 - x1);
  gimp_pixel_rgn_get_row (&bump_region, bumprow2, x1, y+1, x2 - x1);

  if (mapvals.bumpmaptype > 0)
    {
      switch (mapvals.bumpmaptype)
        {
        case 1:
          map = logmap;
          break;
        case 2:
          map = sinemap;
          break;
        default:
          map = spheremap;
          break;
        }
    }

  for (n = 0; n < (x2 - x1); n++)
    {
      gdouble diff;
      guchar mapval;
      guchar mapval1, mapval2;

      if (bpp>1)
        {
          mapval1 = (guchar)((float)((bumprow1[n * bpp] +bumprow1[n * bpp +1] + bumprow1[n * bpp + 2])/3.0 )) ;
          mapval2 = (guchar)((float)((bumprow2[n * bpp] +bumprow2[n * bpp +1] + bumprow2[n * bpp + 2])/3.0 )) ;
        }
      else
        {
          mapval1 = bumprow1[n * bpp];
          mapval2 = bumprow2[n * bpp];
        }

      diff =  mapval1 - mapval2;
      mapval = (guchar) CLAMP (mapval1 + diff, 0.0, 255.0);

      if (mapvals.bumpmaptype > 0)
        {
          heights[1][n] = (gdouble) mapvals.bumpmax * (gdouble) map[mapval1] / 255.0;
          heights[2][n] = (gdouble) mapvals.bumpmax * (gdouble) map[mapval] / 255.0;
        }
      else
        {
          heights[1][n] = (gdouble) mapvals.bumpmax * (gdouble) mapval1 / 255.0;
          heights[2][n] = (gdouble) mapvals.bumpmax * (gdouble) mapval / 255.0;
        }
    }

  i = 0;
  for (n = 0; n < (x2 - x1 - 1); n++)
    {
      /* heights rows 1 and 2 are inverted */
      p1.x = 0.0;
      p1.y = ystep;
      p1.z = heights[1][n] - heights[2][n];

      p2.x = xstep;
      p2.y = ystep;
      p2.z = heights[1][n+1] - heights[2][n];

      p3.x = xstep;
      p3.y = 0.0;
      p3.z = heights[2][n+1] - heights[2][n];

      triangle_normals[1][i] = gimp_vector3_cross_product (&p2, &p1);
      triangle_normals[1][i+1] = gimp_vector3_cross_product (&p3, &p2);

      gimp_vector3_normalize (&triangle_normals[1][i]);
      gimp_vector3_normalize (&triangle_normals[1][i+1]);

      i += 2;
    }

  g_free (bumprow1);
  g_free (bumprow2);
}
Exemple #15
0
static void
render_rgb_image(Preview_t *preview_base, GimpPixelRgn *srcrgn)
{
   guchar        *src_row, *dest_buffer, *src, *dest;
   gint          row, col;
   gint          dwidth, dheight, pwidth, pheight;
   gint          *src_col;
   gint          bpp, alpha, has_alpha, b;
   guchar        check;
   gboolean      gray = get_map_info()->show_gray;
   GtkWidget    *preview = preview_base->preview;

   dwidth  = srcrgn->w;
   dheight = srcrgn->h;
   pwidth = preview_base->widget_width;
   pheight = preview_base->widget_height;
   bpp = srcrgn->bpp;
   alpha = bpp;
   has_alpha = gimp_drawable_has_alpha(srcrgn->drawable->drawable_id);
   if (has_alpha)
      alpha--;

   src_row = g_new(guchar, dwidth * bpp);
   dest_buffer = g_new(guchar, pwidth * pheight * bpp);
   src_col = g_new(gint, pwidth);

   for (col = 0; col < pwidth; col++)
      src_col[col] = (col * dwidth / pwidth) * bpp;

   dest = dest_buffer;
   for (row = 0; row < pheight; row++) {
      gimp_pixel_rgn_get_row(srcrgn, src_row, 0, row * dheight / pheight,
                             dwidth);
      for (col = 0; col < pwidth; col++) {
         src = &src_row[src_col[col]];
         if(!has_alpha || src[alpha] == OPAQUE) {
            /* no alpha channel or opaque -- simple way */
            for (b = 0; b < alpha; b++)
               dest[b] = src[b];
         } else {
            /* more or less transparent */
            if( ( col % (CHECKWIDTH*2) < CHECKWIDTH ) ^
                ( row % (CHECKWIDTH*2) < CHECKWIDTH ) )
               check = LIGHTCHECK;
            else
               check = DARKCHECK;

            if (src[alpha] == 0) {
               /* full transparent -- check */
               for (b = 0; b < alpha; b++)
                  dest[b] = check;
            } else {
               /* middlemost transparent -- mix check and src */
               for (b = 0; b < alpha; b++)
                  dest[b] = (src[b] * src[alpha] +
                             check * (OPAQUE - src[alpha])) / OPAQUE;
            }
         }
         if (gray) {
            guchar avg;
            avg = (299 * dest[0] + 587 * dest[1] + 114 * dest[2]) / 1000;
            for (b = 0; b < alpha; b++)
               dest[b] = avg;
         }
         dest += alpha;
      }
   }
   gimp_preview_area_draw (GIMP_PREVIEW_AREA (preview),
                           0, 0, pwidth, pheight,
                           GIMP_RGB_IMAGE,
                           dest_buffer,
                           pwidth * 3);
   g_free(src_col);
   g_free(src_row);
   g_free(dest_buffer);
}
Exemple #16
0
static void
do_acrop (GimpDrawable *drawable,
          gint32        image_id)
{
  GimpPixelRgn  srcPR;
  gint          iwidth, iheight;
  gint          x, y, l;
  guchar       *buffer;
  gint          xmin, xmax, ymin, ymax;
  gint         *layers = NULL;
  gint          numlayers;

  iwidth = gimp_image_width(image_id);
  iheight = gimp_image_height(image_id);

  /* Set each edge to the opposite side -- i.e. xmin (the left edge
   * of the final cropped image) starts at the right edge.
   */
  xmin = iwidth - 1;
  xmax = 1;
  ymin = iheight - 1;
  ymax = 1;

  buffer = g_malloc ((iwidth > iheight ? iwidth : iheight) * drawable->bpp);

  layers = gimp_image_get_layers (image_id, &numlayers);

  for (l=0; l<numlayers; ++l)
    {
      gint dwidth, dheight;
      gint layerOffsetX, layerOffsetY;
      gint bytes;
      gint start;

      drawable = gimp_drawable_get(layers[l]);
      dwidth  = drawable->width;
      dheight = drawable->height;
      bytes = drawable->bpp;

      /* Relate the layer coordinates to the image coordinates */
      gimp_drawable_offsets (layers[l], &layerOffsetX, &layerOffsetY);

      /*  initialize the pixel region to this layer */
      gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, dwidth, dheight,
                           FALSE, FALSE);

      /* Update ymin. If the layer offset is greater than ymin,
       * then the region to be cropped already contains the whole layer
       * and we don't have to look any farther.
       */
      start = 0;
      if (layerOffsetY < 0)
          start = -layerOffsetY;
      for (y = start; y < dheight && layerOffsetY + y < ymin; y++)
        {
          gimp_pixel_rgn_get_row (&srcPR, buffer, 0, y, dwidth);

          for (x = 0; x < dwidth * bytes; x += bytes)
            {
              if (!colours_equal (buffer, &buffer[x], bytes))
                {
                  /* convert this layer coordinate back to image coord */
                  ymin = y + layerOffsetY;
                  break;
                }
            }
        }

      /* Update ymax. If the layer's offset plus height is less than
       * ymax, then the region to be cropped already contains the
       * whole layer and we don't have to look any farther.
       */
      start = dheight - 1;
      if (layerOffsetY + dheight > iheight)
          start = iheight - layerOffsetY - 1;
      for (y = start; y > 0 && layerOffsetY + y > ymax; y--)
        {
          gimp_pixel_rgn_get_row (&srcPR, buffer, 0, y, dwidth);

          for (x = 0; x < dwidth * bytes; x += bytes)
            {
              if (!colours_equal (buffer, &buffer[x], bytes))
                {
                  /* convert this layer coordinate back to image coord */
                  ymax = y + layerOffsetY + 1;
                  break;
                }
            }
        }

      /* Update xmin. If the layer offset is greater than ymin,
       * then the region to be cropped already contains the whole layer
       * and we don't have to look any farther.
       */
      start = 0;
      if (layerOffsetX < 0)
          start = -layerOffsetX;
      for (x = start; x < dwidth && layerOffsetX + x < xmin; x++)
        {
          gimp_pixel_rgn_get_col (&srcPR, buffer, x, 0, dheight);

          for (y = 0; y < dheight * bytes; y += bytes)
            {
              if (!colours_equal (buffer, &buffer[y], bytes))
                {
                  /* convert this layer coordinate back to image coord */
                  xmin = x + layerOffsetX;
                  break;
                }
            }
        }

      /* Update xmax. If the layer's offset plus width is less than
       * xmax, then the region to be cropped already contains the
       * whole layer and we don't have to look any farther.
       */
      start = dwidth - 1;
      if (layerOffsetX + dwidth > iwidth)
          start = iwidth - layerOffsetX - 1;
      for (x = start; x > 0 && layerOffsetX + x > xmax; x--)
        {
          gimp_pixel_rgn_get_col (&srcPR, buffer, x, 0, dheight);

          for (y = 0; y < dheight * bytes; y += bytes)
            {
              if (!colours_equal (buffer, &buffer[y], bytes))
                {
                  /* convert this layer coordinate back to image coord */
                  xmax = x + layerOffsetX + 1;
                  break;
                }
            }
        }

      gimp_progress_update ((gdouble)l / numlayers);
    }

  if (xmin == 0 && xmax == iwidth &&
      ymin == 0 && ymax == iheight)
    {
      g_message ("Nothing to crop.");
      return;
    }

  gimp_image_undo_group_start (image_id);

  gimp_image_crop(image_id,
                  xmax - xmin, ymax - ymin,
                  xmin, ymin);

  g_free (layers);
  g_free (buffer);

  gimp_progress_update (1.00);
  gimp_image_undo_group_end (image_id);
}
Exemple #17
0
static void
grid (gint32        image_ID,
      GimpDrawable *drawable,
      GimpPreview  *preview)
{
  GimpPixelRgn  srcPR, destPR;
  gint          bytes;
  gint          x_offset, y_offset;
  guchar       *dest, *buffer = NULL;
  gint          x, y;
  gboolean      alpha;
  gboolean      blend;
  guchar        hcolor[4];
  guchar        vcolor[4];
  guchar        icolor[4];
  guchar       *cmap;
  gint          ncolors;

  gimp_rgba_get_uchar (&grid_cfg.hcolor,
                       hcolor, hcolor + 1, hcolor + 2, hcolor + 3);
  gimp_rgba_get_uchar (&grid_cfg.vcolor,
                       vcolor, vcolor + 1, vcolor + 2, vcolor + 3);
  gimp_rgba_get_uchar (&grid_cfg.icolor,
                       icolor, icolor + 1, icolor + 2, icolor + 3);

  switch (gimp_image_base_type (image_ID))
    {
    case GIMP_RGB:
      blend = TRUE;
      break;

    case GIMP_GRAY:
      hcolor[0] = gimp_rgb_luminance_uchar (&grid_cfg.hcolor);
      vcolor[0] = gimp_rgb_luminance_uchar (&grid_cfg.vcolor);
      icolor[0] = gimp_rgb_luminance_uchar (&grid_cfg.icolor);
      blend = TRUE;
      break;

    case GIMP_INDEXED:
      cmap = gimp_image_get_colormap (image_ID, &ncolors);

      hcolor[0] = best_cmap_match (cmap, ncolors, &grid_cfg.hcolor);
      vcolor[0] = best_cmap_match (cmap, ncolors, &grid_cfg.vcolor);
      icolor[0] = best_cmap_match (cmap, ncolors, &grid_cfg.icolor);

      g_free (cmap);
      blend = FALSE;
      break;

    default:
      g_assert_not_reached ();
      blend = FALSE;
    }

  bytes = drawable->bpp;
  alpha = gimp_drawable_has_alpha (drawable->drawable_id);

  if (preview)
    {
      gimp_preview_get_position (preview, &sx1, &sy1);
      gimp_preview_get_size (preview, &sx2, &sy2);

      buffer = g_new (guchar, bytes * sx2 * sy2);

      sx2 += sx1;
      sy2 += sy1;
    }
  else
    {
      gimp_drawable_mask_bounds (drawable->drawable_id, &sx1, &sy1, &sx2, &sy2);

      gimp_pixel_rgn_init (&destPR,
                           drawable, 0, 0, sx2 - sx1, sy2 - sy1, TRUE, TRUE);
    }

  gimp_pixel_rgn_init (&srcPR,
                       drawable, 0, 0, sx2 - sx1, sy2 - sy1, FALSE, FALSE);

  dest = g_new (guchar, (sx2 - sx1) * bytes);

  for (y = sy1; y < sy2; y++)
    {
      gimp_pixel_rgn_get_row (&srcPR, dest, sx1, y, (sx2 - sx1));

      y_offset = y - grid_cfg.hoffset;
      while (y_offset < 0)
        y_offset += grid_cfg.hspace;

      if ((y_offset +
           (grid_cfg.hwidth / 2)) % grid_cfg.hspace < grid_cfg.hwidth)
        {
          for (x = sx1; x < sx2; x++)
            {
              pix_composite (&dest[(x-sx1) * bytes],
                             hcolor, bytes, blend, alpha);
            }
        }

      for (x = sx1; x < sx2; x++)
        {
          x_offset = grid_cfg.vspace + x - grid_cfg.voffset;
          while (x_offset < 0)
            x_offset += grid_cfg.vspace;

          if ((x_offset +
               (grid_cfg.vwidth / 2)) % grid_cfg.vspace < grid_cfg.vwidth)
            {
              pix_composite (&dest[(x-sx1) * bytes],
                             vcolor, bytes, blend, alpha);
            }

          if ((x_offset +
               (grid_cfg.iwidth / 2)) % grid_cfg.vspace < grid_cfg.iwidth
              &&
              ((y_offset % grid_cfg.hspace >= grid_cfg.ispace
                &&
                y_offset % grid_cfg.hspace < grid_cfg.ioffset)
               ||
               (grid_cfg.hspace -
                (y_offset % grid_cfg.hspace) >= grid_cfg.ispace
                &&
                grid_cfg.hspace -
                (y_offset % grid_cfg.hspace) < grid_cfg.ioffset)))
            {
              pix_composite (&dest[(x-sx1) * bytes],
                             icolor, bytes, blend, alpha);
            }
        }

      if ((y_offset +
           (grid_cfg.iwidth / 2)) % grid_cfg.hspace < grid_cfg.iwidth)
        {
          for (x = sx1; x < sx2; x++)
            {
              x_offset = grid_cfg.vspace + x - grid_cfg.voffset;
              while (x_offset < 0)
                x_offset += grid_cfg.vspace;

              if ((x_offset % grid_cfg.vspace >= grid_cfg.ispace
                   &&
                   x_offset % grid_cfg.vspace < grid_cfg.ioffset)
                  ||
                  (grid_cfg.vspace -
                   (x_offset % grid_cfg.vspace) >= grid_cfg.ispace
                   &&
                   grid_cfg.vspace -
                   (x_offset % grid_cfg.vspace) < grid_cfg.ioffset))
                {
                  pix_composite (&dest[(x-sx1) * bytes],
                                 icolor, bytes, blend, alpha);
                }
            }
        }

      if (preview)
        {
          memcpy (buffer + (y - sy1) * (sx2 - sx1) * bytes,
                  dest,
                  (sx2 - sx1) * bytes);
        }
      else
        {
          gimp_pixel_rgn_set_row (&destPR, dest, sx1, y, (sx2 - sx1));

          if (y % 16 == 0)
            gimp_progress_update ((gdouble) y / (gdouble) (sy2 - sy1));
        }
    }

  g_free (dest);

  if (preview)
    {
      gimp_preview_draw_buffer (preview, buffer, bytes * (sx2 - sx1));
      g_free (buffer);
    }
  else
    {
      gimp_progress_update (1.0);
      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id,
                            sx1, sy1, sx2 - sx1, sy2 - sy1);
    }
}
gint
guess_new_size (GtkWidget * button, PreviewData * p_data, GuessDir direction)
{
  gint32 disc_layer_ID;
  GimpDrawable *drawable;
  gint z1, z2, k;
  gint z1min, z1max, z2max;
  gint width, height;
  gint lw, lh;
  gint x_off, y_off;
  gint bpp, c_bpp;
  GimpPixelRgn rgn_in;
  guchar *line;
  gboolean has_alpha;
  gdouble sum;
  gint mask_size;
  gint max_mask_size = 0;
  gint old_size;
  gint new_size;

  disc_layer_ID = p_data->vals->disc_layer_ID;
  switch (direction)
    {
      case GUESS_DIR_HOR:
        old_size = p_data->old_width;
        break;
      case GUESS_DIR_VERT:
        old_size = p_data->old_height;
        break;
      default:
        g_message("You just found a bug");
        return 0;
    }

  LAYER_CHECK_ACTION(disc_layer_ID, gtk_dialog_response (GTK_DIALOG (dlg), RESPONSE_REFRESH), old_size);

  width = gimp_drawable_width (disc_layer_ID);
  height = gimp_drawable_height (disc_layer_ID);
  has_alpha = gimp_drawable_has_alpha (disc_layer_ID);
  bpp = gimp_drawable_bpp (disc_layer_ID);
  c_bpp = bpp - (has_alpha ? 1 : 0);

  drawable = gimp_drawable_get (disc_layer_ID);
  gimp_pixel_rgn_init (&rgn_in, drawable, 0, 0, width, height, FALSE, FALSE);


  gimp_drawable_offsets (disc_layer_ID, &x_off, &y_off);

  x_off -= p_data->x_off;
  y_off -= p_data->y_off;

  lw = (MIN (p_data->old_width, width + x_off) - MAX (0, x_off));
  lh = (MIN (p_data->old_height, height + y_off) - MAX (0, y_off));

  switch (direction)
    {
      case GUESS_DIR_HOR:
        z1min = MAX (0, y_off);
        z1max = MIN (p_data->old_height, height + y_off);
        z2max = lw;
        break;
      case GUESS_DIR_VERT:
        z1min = MAX (0, x_off);
        z1max = MIN (p_data->old_width, width + x_off);
        z2max = lh;
        break;
      default:
        g_message("You just found a bug");
        return 0;
    }

  line = g_try_new (guchar, bpp * z2max);

  for (z1 = z1min; z1 < z1max; z1++)
    {
      switch (direction)
        {
          case GUESS_DIR_HOR:
            gimp_pixel_rgn_get_row (&rgn_in, line, MAX (0, -x_off), z1 - y_off, z2max);
            break;
          case GUESS_DIR_VERT:
            gimp_pixel_rgn_get_col (&rgn_in, line, z1 - x_off, MAX (0, -y_off), z2max);
            break;
        }

      mask_size = 0;
      for (z2 = 0; z2 < z2max; z2++)
	{
	  sum = 0;
	  for (k = 0; k < c_bpp; k++)
	    {
	      sum += line[bpp * z2 + k];
	    }

	  sum /= (255 * c_bpp);
	  if (has_alpha)
	    {
	      sum *= (gdouble) line[bpp * (z2 + 1) - 1] / 255;
	    }

	  if (sum >= (0.5 / c_bpp))
	    {
	      mask_size++;
	    }
	}
      if (mask_size > max_mask_size)
	{
	  max_mask_size = mask_size;
	}

    }

  new_size = old_size - max_mask_size;

  g_free (line);
  gimp_drawable_detach (drawable);

  return new_size;
}
Exemple #19
0
static void
blur (GimpDrawable *drawable)
{
  gint         i, ii, channels;
  gint         x1, y1, x2, y2;
  GimpPixelRgn rgn_in, rgn_out;
  guchar     **row;
  guchar      *outrow;
  gint         width, height;

  gimp_progress_init ("My Blur...");

  /* Gets upper left and lower right coordinates,
   * and layers number in the image */
  gimp_drawable_mask_bounds (drawable->drawable_id,
                             &x1, &y1,
                             &x2, &y2);
  width  = x2 - x1;
  height = y2 - y1;

  channels = gimp_drawable_bpp (drawable->drawable_id);

  /* Allocate a big enough tile cache */
  gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));

  /* Initialises two PixelRgns, one to read original data,
   * and the other to write output data. That second one will
   * be merged at the end by the call to
   * gimp_drawable_merge_shadow() */
  gimp_pixel_rgn_init (&rgn_in,
                       drawable,
                       x1, y1,
                       width, height,
                       FALSE, FALSE);
  gimp_pixel_rgn_init (&rgn_out,
                       drawable,
                       x1, y1,
                       width, height,
                       TRUE, TRUE);

  /* Allocate memory for input and output tile rows */
  init_mem (&row, &outrow, width * channels);

  for (ii = -radius; ii <= radius; ii++)
    {
      gimp_pixel_rgn_get_row (&rgn_in,
                              row[radius + ii],
                              x1, y1 + CLAMP (ii, 0, height - 1),
                              width);
    }

  for (i = 0; i < height; i++)
    {
      /* To be done for each tile row */
      process_row (row,
                   outrow,
                   x1, y1,
                   width, height,
                   channels,
                   i);
      gimp_pixel_rgn_set_row (&rgn_out,
                              outrow,
                              x1, i + y1,
                              width);
      /* shift tile rows to insert the new one at the end */
      shuffle (&rgn_in,
               row,
               x1, y1,
               width, height,
               i);
      if (i % 10 == 0)
        gimp_progress_update ((gdouble) i / (gdouble) height);
    }

  /* We could also put that in a separate function but it's
   * rather simple */
  for (ii = 0; ii < 2 * radius + 1; ii++)
    g_free (row[ii]);

  g_free (row);
  g_free (outrow);

  /*  Update the modified region */
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id,
                        x1, y1,
                        width, height);
}
Exemple #20
0
static void sinusrow (GimpDrawable *drawable)
{
  gint         i, j, k, channels;
  gint         x1, y1, x2, y2;
  GimpPixelRgn rgn_in, rgn_out;

   guchar      *inrow;
   guchar      *outrow;
 /* guchar       output[4];  */

  /* Gets upper left and lower right coordinates,
   * and layers number in the image */
  gimp_drawable_mask_bounds (drawable->drawable_id,
                             &x1, &y1,
                             &x2, &y2);
  channels = gimp_drawable_bpp (drawable->drawable_id);

  /* Initialises two PixelRgns, one to read original data,
   * and the other to write output data. That second one will
   * be merged at the end by the call to
   * gimp_drawable_merge_shadow() */
  gimp_pixel_rgn_init (&rgn_in,
                       drawable,
                       x1, y1,
                       x2 - x1, y2 - y1,
                       FALSE, FALSE);
  gimp_pixel_rgn_init (&rgn_out,
                       drawable,
                       x1, y1,
                       x2 - x1, y2 - y1,
                       TRUE, TRUE);

 /* Initialise enough memory for inrow, outrow */
        inrow = g_new (guchar, channels * (x2 - x1));
        outrow = g_new (guchar, channels * (x2 - x1));

  guchar minp[4],maxp[4];
  getrange(drawable, minp, maxp, x1, x2, y1, y2);
  
  for (i = y1; i < y2; i++)
     {
         /* Get row i */
         gimp_pixel_rgn_get_row (&rgn_in, inrow, x1, i, x2 - x1);

         for (j = x1; j < x2; j++)
              {
                /* For each layer, compute the average of the nine
                 * pixels */
                for (k = 0; k < channels; k++) 
            {
                double angle = inrow[channels * (j - x1) + k], max=255;
                angle = M_2_PI * (angle / max ) ;
                outrow[channels * (j - x1) + k] = (guchar)(255*(1+sin(angle))/2);
            }

        } /*end for j each pixel of the row*/

      gimp_pixel_rgn_set_row (&rgn_out, outrow, x1, i, x2 - x1);

      if (i % 10 == 0)
        gimp_progress_update ((gdouble) (i - x1) / (gdouble) (x2 - x1));

    } /*end for i each row*/

  g_free (inrow);
  g_free (outrow);

  /* Update the modified region */
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id,
                        x1, y1,
                        x2 - x1, y2 - y1);
}
Exemple #21
0
static void
sharpen (GimpDrawable *drawable)
{
  GimpPixelRgn  src_rgn;        /* Source image region */
  GimpPixelRgn  dst_rgn;        /* Destination image region */
  guchar       *src_rows[4];    /* Source pixel rows */
  guchar       *src_ptr;        /* Current source pixel */
  guchar       *dst_row;        /* Destination pixel row */
  intneg       *neg_rows[4];    /* Negative coefficient rows */
  intneg       *neg_ptr;        /* Current negative coefficient */
  gint          i;              /* Looping vars */
  gint          y;              /* Current location in image */
  gint          row;            /* Current row in src_rows */
  gint          count;          /* Current number of filled src_rows */
  gint          width;          /* Byte width of the image */
  gint          x1;             /* Selection bounds */
  gint          y1;
  gint          y2;
  gint          sel_width;      /* Selection width */
  gint          sel_height;     /* Selection height */
  gint          img_bpp;        /* Bytes-per-pixel in image */
  void          (*filter)(int, guchar *, guchar *, intneg *, intneg *, intneg *);

  filter = NULL;

  if (! gimp_drawable_mask_intersect (drawable->drawable_id,
                                      &x1, &y1, &sel_width, &sel_height))
    return;

  y2 = y1 + sel_height;

  img_bpp = gimp_drawable_bpp (drawable->drawable_id);

  /*
   * Let the user know what we're doing...
   */
  gimp_progress_init (_("Sharpening"));

  /*
   * Setup for filter...
   */

  gimp_pixel_rgn_init (&src_rgn, drawable,
                       x1, y1, sel_width, sel_height, FALSE, FALSE);
  gimp_pixel_rgn_init (&dst_rgn, drawable,
                       x1, y1, sel_width, sel_height, TRUE, TRUE);

  compute_luts ();

  width = sel_width * img_bpp;

  for (row = 0; row < 4; row ++)
    {
      src_rows[row] = g_new (guchar, width);
      neg_rows[row] = g_new (intneg, width);
    }

  dst_row = g_new (guchar, width);

  /*
   * Pre-load the first row for the filter...
   */

  gimp_pixel_rgn_get_row (&src_rgn, src_rows[0], x1, y1, sel_width);

  for (i = width, src_ptr = src_rows[0], neg_ptr = neg_rows[0];
       i > 0;
       i --, src_ptr ++, neg_ptr ++)
    *neg_ptr = neg_lut[*src_ptr];

  row   = 1;
  count = 1;

  /*
   * Select the filter...
   */

  switch (img_bpp)
    {
    case 1 :
      filter = gray_filter;
      break;
    case 2 :
      filter = graya_filter;
      break;
    case 3 :
      filter = rgb_filter;
      break;
    case 4 :
      filter = rgba_filter;
      break;
    };

  /*
   * Sharpen...
   */

  for (y = y1; y < y2; y ++)
    {
      /*
       * Load the next pixel row...
       */

      if ((y + 1) < y2)
        {
          /*
           * Check to see if our src_rows[] array is overflowing yet...
           */

          if (count >= 3)
            count --;

          /*
           * Grab the next row...
           */

          gimp_pixel_rgn_get_row (&src_rgn, src_rows[row],
                                  x1, y + 1, sel_width);
          for (i = width, src_ptr = src_rows[row], neg_ptr = neg_rows[row];
               i > 0;
               i --, src_ptr ++, neg_ptr ++)
            *neg_ptr = neg_lut[*src_ptr];

          count ++;
          row = (row + 1) & 3;
        }
      else
        {
          /*
           * No more pixels at the bottom...  Drop the oldest samples...
           */

          count --;
        }

      /*
       * Now sharpen pixels and save the results...
       */

      if (count == 3)
        {
          (* filter) (sel_width, src_rows[(row + 2) & 3], dst_row,
                      neg_rows[(row + 1) & 3] + img_bpp,
                      neg_rows[(row + 2) & 3] + img_bpp,
                      neg_rows[(row + 3) & 3] + img_bpp);

          /*
           * Set the row...
           */

          gimp_pixel_rgn_set_row (&dst_rgn, dst_row, x1, y, sel_width);
        }
      else if (count == 2)
        {
          if (y == y1)      /* first row */
            gimp_pixel_rgn_set_row (&dst_rgn, src_rows[0],
                                    x1, y, sel_width);
          else                  /* last row  */
            gimp_pixel_rgn_set_row (&dst_rgn, src_rows[(sel_height - 1) & 3],
                                    x1, y, sel_width);
        }

      if ((y & 15) == 0)
        gimp_progress_update ((gdouble) (y - y1) / (gdouble) sel_height);
    }

  /*
   * OK, we're done.  Free all memory used...
   */

  for (row = 0; row < 4; row ++)
    {
      g_free (src_rows[row]);
      g_free (neg_rows[row]);
    }

  g_free (dst_row);

  /*
   * Update the screen...
   */

  gimp_progress_update (1.0);
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id,
                        x1, y1, sel_width, sel_height);
}
Exemple #22
0
static void dofilter (GimpDrawable *drawable)
{
  gint         i, j, k, channels;
  gint         x1, y1, x2, y2;
  GimpPixelRgn rgn_in, rgn_out;

   guchar      *inrow;
   guchar      *outrow;

  /* Gets upper left and lower right coordinates,
   * and layers number in the image */
  gimp_drawable_mask_bounds (drawable->drawable_id,
                             &x1, &y1,                             &x2, &y2);
  channels = gimp_drawable_bpp (drawable->drawable_id);

  /* Initialises two PixelRgns, one to read original data,
   * and the other to write output data. That second one will
   * be merged at the end by the call to
   * gimp_drawable_merge_shadow() */
  gimp_pixel_rgn_init (&rgn_in,        drawable,
                       x1, y1,        x2 - x1, y2 - y1,         FALSE, FALSE);
  gimp_pixel_rgn_init (&rgn_out,    drawable,
                       x1, y1,        x2 - x1, y2 - y1,         TRUE, TRUE);

 /* Initialise enough memory for inrow, outrow */
        inrow = g_new (guchar, channels * (x2 - x1));
        outrow = g_new (guchar, channels * (x2 - x1));




/* EXAMPLE USAGE of the functions to get the range */
//  guchar minp[4],maxp[4];
// getrange(drawable, minp, maxp, x1, x2, y1, y2);



  
  for (i = y1; i < y2; i++)
     {
         /* Get row i  into inrow array*/
         gimp_pixel_rgn_get_row (&rgn_in, inrow, x1, i, x2 - x1);

         for (j = x1; j < x2; j++)
              {
                /* For each layer get the color
                 * pixels */
            guchar rgb[4];
            for (k = 0; k < 4; k++) 
            {
                if (k<channels)
			rgb[k] = inrow[channels * (j - x1) + k];
		else	rgb[k] = 0;
	    }





/* YOUR MAIN CODE HERE : should modify the values inside the rgb array*/

/* EXAMPLE OF CODE : */
            float h,s,b;
            RGBtoHSB (rgb,&h,&s,&b);
	    h=180.0f*(1.0f + cos(h * M_2_PI / 360.0f));
	    HSBtoRGB(h,s,b,rgb);

/* END OF YOUR MAIN CODE HERE */





/* write the new rgb values to the pixels of the outrow */
            for (k = 0; k < channels; k++){ 
                outrow[channels * (j - x1) + k] = rgb[k];
            }

        } /*end for j each pixel of the row*/

      gimp_pixel_rgn_set_row (&rgn_out, outrow, x1, i, x2 - x1);

      if (i % 10 == 0)
        gimp_progress_update ((gdouble) (i - x1) / (gdouble) (x2 - x1));

    } /*end for i each row*/



  g_free (inrow);
  g_free (outrow);


  /* Update the modified region */
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id,                  x1, y1,              x2 - x1, y2 - y1);

}
Exemple #23
0
static void
render_indexed_image(Preview_t *preview_base, GimpPixelRgn *srcrgn)
{
   guchar        *src_row, *dest_buffer, *src, *dest;
   gint          row, col;
   gint          dwidth, dheight, pwidth, pheight;
   gint          *src_col;
   gint          bpp, alpha, has_alpha;
   guchar        *cmap, *colour;
   gint          ncols;
   gboolean      gray = get_map_info()->show_gray;
   GtkWidget    *preview = preview_base->preview;

   dwidth  = srcrgn->w;
   dheight = srcrgn->h;
   pwidth = preview_base->widget_width;
   pheight = preview_base->widget_height;
   bpp = srcrgn->bpp;
   alpha = bpp;
   has_alpha = gimp_drawable_has_alpha(srcrgn->drawable->drawable_id);
   if (has_alpha)
      alpha--;

   cmap = gimp_image_get_colormap (gimp_item_get_image (srcrgn->drawable->drawable_id),
                                   &ncols);

   src_row = g_new(guchar, dwidth * bpp);
   dest_buffer = g_new(guchar, pwidth * pheight * 3);
   src_col = g_new(gint, pwidth);

   for (col = 0; col < pwidth; col++)
      src_col[col] = (col * dwidth / pwidth) * bpp;

   dest = dest_buffer;
   for (row = 0; row < pheight; row++) {
      gimp_pixel_rgn_get_row(srcrgn, src_row, 0, row * dheight / pheight,
                             dwidth);

      for (col = 0; col < pwidth; col++) {
         src = &src_row[src_col[col]];
         colour = cmap + 3 * (int)(*src);

         if (gray) {
            guchar avg = (299 * colour[0] + 587 * colour[1] +
                          114 * colour[2]) / 1000;
            *dest++ = avg;
            *dest++ = avg;
            *dest++ = avg;
         } else {
            *dest++ = colour[0];
            *dest++ = colour[1];
            *dest++ = colour[2];
         }
      }
   }
   gimp_preview_area_draw(GIMP_PREVIEW_AREA(preview),
                          0, 0, pwidth, pheight,
                          GIMP_RGB_IMAGE,
                          dest_buffer,
                          pwidth * 3);
   g_free(src_col);
   g_free(src_row);
   g_free(dest_buffer);
}
Exemple #24
0
static void
neon (GimpDrawable *drawable,
      gdouble       radius,
      gdouble       amount,
      GimpPreview  *preview)
{
    GimpPixelRgn  src_rgn, dest_rgn;
    gint          width, height;
    gint          bytes, bpp;
    gboolean      has_alpha;
    guchar       *dest;
    guchar       *src, *src2, *sp_p, *sp_m;
    gdouble       n_p[5], n_m[5];
    gdouble       d_p[5], d_m[5];
    gdouble       bd_p[5], bd_m[5];
    gdouble      *val_p, *val_m, *vp, *vm;
    gint          x1, y1, x2, y2;
    gint          i, j;
    gint          row, col, b;
    gint          terms;
    gint          progress = 0, max_progress = 1;
    gint          initial_p[4];
    gint          initial_m[4];
    gdouble       std_dev;
    guchar       *preview_buffer1 = NULL;
    guchar       *preview_buffer2 = NULL;

    if (preview)
    {
        gimp_preview_get_position (preview, &x1, &y1);
        gimp_preview_get_size (preview, &width, &height);
        x2 = x1 + width;
        y2 = y1 + height;
    }
    else
    {
        gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
        width  = (x2 - x1);
        height = (y2 - y1);
    }

    if (radius < 1.0)
        return;

    bytes     = drawable->bpp;
    bpp       = bytes;
    has_alpha = gimp_drawable_has_alpha(drawable->drawable_id);
    if (has_alpha)
        bpp--;

    val_p = g_new (gdouble, MAX (width, height) * bytes);
    val_m = g_new (gdouble, MAX (width, height) * bytes);

    src  = g_new (guchar, MAX (width, height) * bytes);
    src2 = g_new (guchar, MAX (width, height) * bytes);
    dest = g_new (guchar, MAX (width, height) * bytes);

    gimp_pixel_rgn_init (&src_rgn, drawable,
                         0, 0, drawable->width, drawable->height, FALSE, FALSE);

    if (preview)
    {
        preview_buffer1 = g_new (guchar, width * height * bytes);
        preview_buffer2 = g_new (guchar, width * height * bytes);
    }
    else
    {
        gimp_pixel_rgn_init (&dest_rgn, drawable,
                             0, 0, drawable->width, drawable->height, TRUE, TRUE);

        progress = 0;
        max_progress = (radius < 1.0 ) ? 0 : width * height * radius * 2;
    }

    /*  First the vertical pass  */
    radius  = fabs (radius) + 1.0;
    std_dev = sqrt (-(radius * radius) / (2 * log (1.0 / 255.0)));

    /*  derive the constants for calculating the gaussian from the std dev  */
    find_constants (n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev);

    for (col = 0; col < width; col++)
    {
        memset (val_p, 0, height * bytes * sizeof (gdouble));
        memset (val_m, 0, height * bytes * sizeof (gdouble));

        gimp_pixel_rgn_get_col (&src_rgn, src, col + x1, y1, (y2 - y1));

        sp_p = src;
        sp_m = src + (height - 1) * bytes;
        vp = val_p;
        vm = val_m + (height - 1) * bytes;

        /*  Set up the first vals  */
        for (i = 0; i < bytes; i++)
        {
            initial_p[i] = sp_p[i];
            initial_m[i] = sp_m[i];
        }

        for (row = 0; row < height; row++)
        {
            gdouble *vpptr, *vmptr;

            terms = (row < 4) ? row : 4;

            for (b = 0; b < bpp; b++)
            {
                vpptr = vp + b;
                vmptr = vm + b;

                for (i = 0; i <= terms; i++)
                {
                    *vpptr += n_p[i] * sp_p[(-i * bytes) + b] -
                              d_p[i] * vp[(-i * bytes) + b];
                    *vmptr += n_m[i] * sp_m[(i * bytes) + b] -
                              d_m[i] * vm[(i * bytes) + b];
                }

                for (j = i; j <= 4; j++)
                {
                    *vpptr += (n_p[j] - bd_p[j]) * initial_p[b];
                    *vmptr += (n_m[j] - bd_m[j]) * initial_m[b];
                }
            }
            if (has_alpha)
            {
                vp[bpp] = sp_p[bpp];
                vm[bpp] = sp_m[bpp];
            }

            sp_p += bytes;
            sp_m -= bytes;
            vp   += bytes;
            vm   -= bytes;
        }

        transfer_pixels (val_p, val_m, dest, bytes, height);

        if (preview)
        {
            for (row = 0 ; row < height ; row++)
                memcpy (preview_buffer1 + (row * width + col) * bytes,
                        dest + bytes * row,
                        bytes);
        }
        else
        {
            gimp_pixel_rgn_set_col (&dest_rgn, dest, col + x1, y1, (y2 - y1));

            progress += height * radius;

            if ((col % 20) == 0)
                gimp_progress_update ((double) progress / (double) max_progress);
        }
    }

    /*  Now the horizontal pass  */
    gimp_pixel_rgn_init (&src_rgn, drawable,
                         0, 0, drawable->width, drawable->height, FALSE, FALSE);

    for (row = 0; row < height; row++)
    {
        memset (val_p, 0, width * bytes * sizeof (gdouble));
        memset (val_m, 0, width * bytes * sizeof (gdouble));

        gimp_pixel_rgn_get_row (&src_rgn, src, x1, row + y1, (x2 - x1));
        if (preview)
        {
            memcpy (src2,
                    preview_buffer1 + row * width * bytes,
                    width * bytes);
        }
        else
        {
            gimp_pixel_rgn_get_row (&dest_rgn, src2, x1, row + y1, (x2 - x1));
        }

        sp_p = src;
        sp_m = src + (width - 1) * bytes;
        vp = val_p;
        vm = val_m + (width - 1) * bytes;

        /*  Set up the first vals  */
        for (i = 0; i < bytes; i++)
        {
            initial_p[i] = sp_p[i];
            initial_m[i] = sp_m[i];
        }

        for (col = 0; col < width; col++)
        {
            gdouble *vpptr, *vmptr;

            terms = (col < 4) ? col : 4;

            for (b = 0; b < bpp; b++)
            {
                vpptr = vp + b;
                vmptr = vm + b;

                for (i = 0; i <= terms; i++)
                {
                    *vpptr += n_p[i] * sp_p[(-i * bytes) + b] -
                              d_p[i] * vp[(-i * bytes) + b];
                    *vmptr += n_m[i] * sp_m[(i * bytes) + b] -
                              d_m[i] * vm[(i * bytes) + b];
                }

                for (j = i; j <= 4; j++)
                {
                    *vpptr += (n_p[j] - bd_p[j]) * initial_p[b];
                    *vmptr += (n_m[j] - bd_m[j]) * initial_m[b];
                }
            }
            if (has_alpha)
            {
                vp[bpp] = sp_p[bpp];
                vm[bpp] = sp_m[bpp];
            }

            sp_p += bytes;
            sp_m -= bytes;
            vp   += bytes;
            vm   -= bytes;
        }

        transfer_pixels (val_p, val_m, dest, bytes, width);

        combine_to_gradient (dest, src2, bytes, width, amount);

        if (preview)
        {
            memcpy (preview_buffer2 + row * width * bytes,
                    dest,
                    width * bytes);
        }
        else
        {
            gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, row + y1, (x2 - x1));

            progress += width * radius;
            if ((row % 20) == 0)
                gimp_progress_update ((double) progress / (double) max_progress);
        }
    }

    if (preview)
    {
        gimp_preview_draw_buffer (preview, preview_buffer2, width * bytes);
        g_free (preview_buffer1);
        g_free (preview_buffer2);
    }
    else
    {
        gimp_progress_update (1.0);
        /*  now, merge horizontal and vertical into a magnitude  */
        gimp_pixel_rgn_init (&src_rgn, drawable,
                             0, 0, drawable->width, drawable->height,
                             FALSE, TRUE);

        /*  merge the shadow, update the drawable  */
        gimp_drawable_flush (drawable);
        gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
        gimp_drawable_update (drawable->drawable_id,
                              x1, y1, (x2 - x1), (y2 - y1));
    }
    /*  free up buffers  */
    g_free (val_p);
    g_free (val_m);
    g_free (src);
    g_free (src2);
    g_free (dest);
}
static void
explorer (GimpDrawable * drawable)
{
  GimpPixelRgn  srcPR;
  GimpPixelRgn  destPR;
  gint          width;
  gint          height;
  gint          bpp;
  gint          row;
  gint          x1;
  gint          y1;
  gint          x2;
  gint          y2;
  guchar       *src_row;
  guchar       *dest_row;

  /* Get the input area. This is the bounding box of the selection in
   *  the image (or the entire image if there is no selection). Only
   *  operating on the input area is simply an optimization. It doesn't
   *  need to be done for correct operation. (It simply makes it go
   *  faster, since fewer pixels need to be operated on).
   */
  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);

  /* Get the size of the input image. (This will/must be the same
   *  as the size of the output image.
   */
  width  = drawable->width;
  height = drawable->height;
  bpp  = drawable->bpp;

  /*  allocate row buffers  */
  src_row  = g_new (guchar, bpp * (x2 - x1));
  dest_row = g_new (guchar, bpp * (x2 - x1));

  /*  initialize the pixel regions  */
  gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
  gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE);

  xbild = width;
  ybild = height;
  xdiff = (xmax - xmin) / xbild;
  ydiff = (ymax - ymin) / ybild;

  /* for grayscale drawables */
  if (bpp < 3)
    {
      gint     i;
      for (i = 0; i < MAXNCOLORS; i++)
          valuemap[i] = GIMP_RGB_LUMINANCE (colormap[i].r,
                                            colormap[i].g,
                                            colormap[i].b);
    }

  for (row = y1; row < y2; row++)
    {
      gimp_pixel_rgn_get_row (&srcPR, src_row, x1, row, (x2 - x1));

      explorer_render_row (src_row,
                           dest_row,
                           row,
                           (x2 - x1),
                           bpp);

      /*  store the dest  */
      gimp_pixel_rgn_set_row (&destPR, dest_row, x1, row, (x2 - x1));

      if ((row % 10) == 0)
        gimp_progress_update ((double) row / (double) (y2 - y1));
    }

  /*  update the processed region  */
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1));

  g_free (src_row);
  g_free (dest_row);
}
Exemple #26
0
/* do the exchanging */
static void
exchange (GimpDrawable *drawable,
          GimpPreview  *preview)
{
  GimpPixelRgn  srcPR, destPR;
  guchar        min_red,  min_green,  min_blue;
  guchar        max_red,  max_green,  max_blue;
  guchar        from_red, from_green, from_blue;
  guchar        to_red,   to_green,   to_blue;
  guchar       *src_row, *dest_row;
  gint          x, y, bpp = drawable->bpp;
  gboolean      has_alpha;
  gint          x1, y1, y2;
  gint          width, height;
  GimpRGB       min;
  GimpRGB       max;

  if (preview)
    {
      gimp_preview_get_position (preview, &x1, &y1);
      gimp_preview_get_size (preview, &width, &height);
    }
  else if (! gimp_drawable_mask_intersect (drawable->drawable_id,
                                           &x1, &y1, &width, &height))
    {
      return;
    }

  y2 = y1 + height;

  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
  /* allocate memory */
  src_row = g_new (guchar, drawable->width * bpp);

  gimp_rgb_get_uchar (&xargs.from, &from_red, &from_green, &from_blue);
  gimp_rgb_get_uchar (&xargs.to,   &to_red,   &to_green,   &to_blue);

  /* get boundary values */
  min = xargs.from;
  gimp_rgb_subtract (&min, &xargs.threshold);
  gimp_rgb_clamp (&min);
  gimp_rgb_get_uchar (&min, &min_red, &min_green, &min_blue);

  max = xargs.from;
  gimp_rgb_add (&max, &xargs.threshold);
  gimp_rgb_clamp (&max);
  gimp_rgb_get_uchar (&max, &max_red, &max_green, &max_blue);

  dest_row = g_new (guchar, drawable->width * bpp);

  gimp_pixel_rgn_init (&srcPR, drawable,
                       x1, y1, width, height, FALSE, FALSE);
  gimp_pixel_rgn_init (&destPR, drawable,
                       x1, y1, width, height, (preview == NULL), TRUE);

  for (y = y1; y < y2; y++)
    {
      gimp_pixel_rgn_get_row (&srcPR, src_row, x1, y, width);

      for (x = 0; x < width; x++)
        {
          guchar pixel_red, pixel_green, pixel_blue;
          guchar new_red, new_green, new_blue;
          guint  idx;

          /* get current pixel-values */
          pixel_red   = src_row[x * bpp];
          pixel_green = src_row[x * bpp + 1];
          pixel_blue  = src_row[x * bpp + 2];

          idx = x * bpp;

          /* want this pixel? */
          if (pixel_red >= min_red &&
              pixel_red <= max_red &&
              pixel_green >= min_green &&
              pixel_green <= max_green &&
              pixel_blue >= min_blue &&
              pixel_blue <= max_blue)
            {
              guchar red_delta, green_delta, blue_delta;

              red_delta   = pixel_red > from_red ?
                pixel_red - from_red : from_red - pixel_red;
              green_delta = pixel_green > from_green ?
                pixel_green - from_green : from_green - pixel_green;
              blue_delta  = pixel_blue > from_blue ?
                pixel_blue - from_blue : from_blue - pixel_blue;

              new_red   = CLAMP (to_red   + red_delta,   0, 255);
              new_green = CLAMP (to_green + green_delta, 0, 255);
              new_blue  = CLAMP (to_blue  + blue_delta,  0, 255);
            }
          else
            {
              new_red   = pixel_red;
              new_green = pixel_green;
              new_blue  = pixel_blue;
            }

          /* fill buffer */
          dest_row[idx + 0] = new_red;
          dest_row[idx + 1] = new_green;
          dest_row[idx + 2] = new_blue;

          /* copy alpha-channel */
          if (has_alpha)
            dest_row[idx + 3] = src_row[x * bpp + 3];
        }
      /* store the dest */
      gimp_pixel_rgn_set_row (&destPR, dest_row, x1, y, width);

      /* and tell the user what we're doing */
      if (!preview && (y % 10) == 0)
        gimp_progress_update ((gdouble) y / (gdouble) height);
    }

  g_free (src_row);
  g_free (dest_row);

  if (preview)
    {
      gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                         &destPR);
    }
  else
    {
      gimp_progress_update (1.0);
      /* update the processed region */
      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, x1, y1, width, height);
    }
}
Exemple #27
0
/*  -  Filter function  -  I wish all filter functions had a pmode :) */
static void
glasstile (GimpDrawable *drawable,
           GimpPreview  *preview)
{
  GimpPixelRgn  srcPR, destPR;
  gint          width, height;
  gint          bytes;
  guchar       *dest, *d;
  guchar       *cur_row;
  gint          row, col, i;
  gint          x1, y1, x2, y2;

  /* Translations of variable names from Maswan
   * rutbredd = grid width
   * ruthojd = grid height
   * ymitt = y middle
   * xmitt = x middle
   */

  gint rutbredd, xpixel1, xpixel2;
  gint ruthojd , ypixel2;
  gint xhalv, xoffs, xmitt, xplus;
  gint yhalv, yoffs, ymitt, yplus;

  if (preview)
    {
      gimp_preview_get_position (preview, &x1, &y1);
      gimp_preview_get_size (preview, &width, &height);
      x2 = x1 + width;
      y2 = y1 + height;
    }
  else
    {
      gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
      width  = x2 - x1;
      height = y2 - y1;
    }
  bytes  = drawable->bpp;

  cur_row = g_new (guchar, width * bytes);
  dest    = g_new (guchar, width * bytes);

  /* initialize the pixel regions, set grid height/width */
  gimp_pixel_rgn_init (&srcPR, drawable,
                        x1, y1, width, height,
                        FALSE, FALSE);
  gimp_pixel_rgn_init (&destPR, drawable,
                       x1, y1, width, height,
                       preview == NULL, TRUE);

  rutbredd = gtvals.xblock;
  ruthojd  = gtvals.yblock;

  xhalv = rutbredd / 2;
  yhalv = ruthojd  / 2;

  xplus = rutbredd % 2;
  yplus = ruthojd  % 2;

  ymitt = y1;
  yoffs = 0;

  /*  Loop through the rows */
  for (row = y1; row < y2; row++)
    {
      d = dest;

      ypixel2 = ymitt + yoffs * 2;
      ypixel2 = CLAMP (ypixel2, 0, y2 - 1);

      gimp_pixel_rgn_get_row (&srcPR, cur_row, x1, ypixel2, width);
      yoffs++;

      /* if current offset = half, do a displacement next time around */
      if (yoffs == yhalv)
        {
          ymitt += ruthojd;
          yoffs = - (yhalv + yplus);
        }

      xmitt = 0;
      xoffs = 0;

      for (col = 0; col < x2 - x1; col++) /* one pixel */
        {
          xpixel1 = (xmitt + xoffs) * bytes;
          xpixel2 = (xmitt + xoffs * 2) * bytes;

          if (xpixel2 < (x2 - x1) * bytes)
            {
              if (xpixel2 < 0)
                xpixel2 = 0;
              for (i = 0; i < bytes; i++)
                d[xpixel1 + i] = cur_row[xpixel2 + i];
            }
          else
            {
              for (i = 0; i < bytes; i++)
                d[xpixel1 + i] = cur_row[xpixel1 + i];
            }

          xoffs++;

          if (xoffs == xhalv)
            {
              xmitt += rutbredd;
              xoffs = - (xhalv + xplus);
            }
        }

      /*  Store the dest  */
      gimp_pixel_rgn_set_row (&destPR, dest, x1, row, width);

      if (!preview && ((row % 5) == 0))
        {
          gimp_progress_update ((gdouble) row / (gdouble) height);
        }
    }

  /*  Update region  */
  if (preview)
    {
      gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                         &destPR);
    }
  else
    {
      gimp_progress_update (1.0);
      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id,
                            x1, y1, width, height);
    }

  g_free (cur_row);
  g_free (dest);
}
Exemple #28
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;
}
Exemple #29
0
static void
gauss_rle (GimpDrawable *drawable,
           gdouble       radius,
           gint          pass,
           gboolean      show_progress)
{
  GimpPixelRgn src_rgn, dest_rgn;
  gint     width, height;
  gint     bytes;
  gint     has_alpha;
  guchar  *dest, *dp;
  guchar  *src, *sp;
  gint    *buf, *bb;
  gint     pixels;
  gint     total = 1;
  gint     x1, y1, x2, y2;
  gint     i, row, col, b;
  gint     start, end;
  gdouble  progress, max_progress;
  gint    *curve;
  gint    *sum = NULL;
  gint     val;
  gint     length;
  gint     initial_p, initial_m;
  gdouble  std_dev;

  if (radius <= 0.0)
    return;

  gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);

  width  = (x2 - x1);
  height = (y2 - y1);

  if (width < 1 || height < 1)
    return;

  bytes = drawable->bpp;
  has_alpha = gimp_drawable_has_alpha(drawable->drawable_id);

  buf = g_new (gint, MAX (width, height) * 2);

  /*  allocate buffers for source and destination pixels  */
  src = g_new (guchar, MAX (width, height) * bytes);
  dest = g_new (guchar, MAX (width, height) * bytes);

  gimp_pixel_rgn_init (&src_rgn,
                       drawable, 0, 0, drawable->width, drawable->height,
                       FALSE, FALSE);
  gimp_pixel_rgn_init (&dest_rgn,
                       drawable, 0, 0, drawable->width, drawable->height,
                       TRUE, TRUE);

  progress = 0.0;
  max_progress  = 2 * width * height;

  /*  First the vertical pass  */
  radius = fabs (radius) + 1.0;
  std_dev = sqrt (-(radius * radius) / (2 * log (1.0 / 255.0)));

  curve = make_curve (std_dev, &length);
  sum = g_new (gint, 2 * length + 1);

  sum[0] = 0;

  for (i = 1; i <= length*2; i++)
    sum[i] = curve[i-length-1] + sum[i-1];
  sum += length;

  total = sum[length] - sum[-length];

  for (col = 0; col < width; col++)
    {
      gimp_pixel_rgn_get_col (&src_rgn, src, col + x1, y1, (y2 - y1));

      if (has_alpha)
        multiply_alpha (src, height, bytes);

      sp = src;
      dp = dest;

      for (b = 0; b < bytes; b++)
        {
          initial_p = sp[b];
          initial_m = sp[(height-1) * bytes + b];

          /*  Determine a run-length encoded version of the row  */
          run_length_encode (sp + b, buf, bytes, height);

          for (row = 0; row < height; row++)
            {
              start = (row < length) ? -row : -length;
              end = (height <= (row + length) ?
                     (height - row - 1) : length);

              val = 0;
              i = start;
              bb = buf + (row + i) * 2;

              if (start != -length)
                val += initial_p * (sum[start] - sum[-length]);

              while (i < end)
                {
                  pixels = bb[0];
                  i += pixels;

                  if (i > end)
                    i = end;

                  val += bb[1] * (sum[i] - sum[start]);
                  bb += (pixels * 2);
                  start = i;
                }

              if (end != length)
                val += initial_m * (sum[length] - sum[end]);

              dp[row * bytes + b] = val / total;
            }
        }

      if (has_alpha)
        separate_alpha (dest, height, bytes);

      gimp_pixel_rgn_set_col (&dest_rgn, dest, col + x1, y1, (y2 - y1));

      if (show_progress)
        {
          progress += height;

          if ((col % 32) == 0)
            gimp_progress_update (0.5 * (pass + (progress / max_progress)));
        }
    }

  /*  prepare for the horizontal pass  */
  gimp_pixel_rgn_init (&src_rgn,
                       drawable, 0, 0, drawable->width, drawable->height,
                       FALSE, TRUE);

  /*  Now the horizontal pass  */
  for (row = 0; row < height; row++)
    {
      gimp_pixel_rgn_get_row (&src_rgn, src, x1, row + y1, (x2 - x1));
      if (has_alpha)
        multiply_alpha (src, width, bytes);

      sp = src;
      dp = dest;

      for (b = 0; b < bytes; b++)
        {
          initial_p = sp[b];
          initial_m = sp[(width-1) * bytes + b];

          /*  Determine a run-length encoded version of the row  */
          run_length_encode (sp + b, buf, bytes, width);

          for (col = 0; col < width; col++)
            {
              start = (col < length) ? -col : -length;
              end = (width <= (col + length)) ? (width - col - 1) : length;

              val = 0;
              i = start;
              bb = buf + (col + i) * 2;

              if (start != -length)
                val += initial_p * (sum[start] - sum[-length]);

              while (i < end)
                {
                  pixels = bb[0];
                  i += pixels;

                  if (i > end)
                    i = end;

                  val += bb[1] * (sum[i] - sum[start]);
                  bb += (pixels * 2);
                  start = i;
                }

              if (end != length)
                val += initial_m * (sum[length] - sum[end]);

              dp[col * bytes + b] = val / total;
            }
        }

      if (has_alpha)
        separate_alpha (dest, width, bytes);

      gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, row + y1, (x2 - x1));

      if (show_progress)
        {
          progress += width;

          if ((row % 32) == 0)
            gimp_progress_update (0.5 * (pass + (progress / max_progress)));
        }
    }

  /*  merge the shadow, update the drawable  */
  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1));

  /*  free buffers  */
  g_free (buf);
  g_free (src);
  g_free (dest);
}
Exemple #30
0
static void
do_zcrop (GimpDrawable *drawable,
          gint32        image_id)
{
  GimpPixelRgn  srcPR, destPR;
  gint          width, height, x, y;
  gint          bytes;
  guchar       *buffer;
  gint8        *killrows;
  gint8        *killcols;
  gint32        livingrows, livingcols, destrow, destcol;
  gint          total_area, area;
  gboolean      has_alpha;

  width  = drawable->width;
  height = drawable->height;
  bytes  = drawable->bpp;

  total_area = width * height * 4;
  area = 0;

  killrows = g_new (gint8, height);
  killcols = g_new (gint8, width);

  buffer = g_malloc ((width > height ? width : height) * bytes);

  /*  initialize the pixel regions  */
  gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
  gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE);

  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);

  livingrows = 0;
  for (y = 0; y < height; y++)
    {
      gimp_pixel_rgn_get_row (&srcPR, buffer, 0, y, width);

      killrows[y] = TRUE;

      for (x = 0; x < width * bytes; x += bytes)
        {
          if (! colors_equal (buffer, &buffer[x], bytes, has_alpha))
            {
              livingrows++;
              killrows[y] = FALSE;
              break;
            }
        }

      area += width;
      if (y % 20 == 0)
        gimp_progress_update ((double) area / (double) total_area);
    }


  livingcols = 0;
  for (x = 0; x < width; x++)
    {
      gimp_pixel_rgn_get_col (&srcPR, buffer, x, 0, height);

      killcols[x] = TRUE;

      for (y = 0; y < height * bytes; y += bytes)
        {
          if (! colors_equal (buffer, &buffer[y], bytes, has_alpha))
            {
              livingcols++;
              killcols[x] = FALSE;
              break;
            }
        }

      area += height;
      if (x % 20 == 0)
        gimp_progress_update ((double) area / (double) total_area);
    }


  if ((livingcols == 0 || livingrows==0) ||
      (livingcols == width && livingrows == height))
    {
      g_message (_("Nothing to crop."));
      g_free (killrows);
      g_free (killcols);
      return;
    }

  destrow = 0;

  for (y = 0; y < height; y++)
    {
      if (!killrows[y])
        {
          gimp_pixel_rgn_get_row (&srcPR, buffer, 0, y, width);
          gimp_pixel_rgn_set_row (&destPR, buffer, 0, destrow, width);
          destrow++;
        }

      area += width;
      if (y % 20 == 0)
        gimp_progress_update ((double) area / (double) total_area);
    }


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

  for (x = 0; x < width; x++)
    {
      if (!killcols[x])
        {
          gimp_pixel_rgn_get_col (&srcPR, buffer, x, 0, height);
          gimp_pixel_rgn_set_col (&destPR, buffer, destcol, 0, height);
          destcol++;
        }

      area += height;
      if (x % 20 == 0)
        gimp_progress_update ((double) area / (double) total_area);
    }

  g_free (buffer);

  g_free (killrows);
  g_free (killcols);

  gimp_progress_update (1.00);

  gimp_image_undo_group_start (image_id);

  gimp_drawable_flush (drawable);
  gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
  gimp_image_crop (image_id, livingcols, livingrows, 0, 0);

  gimp_image_undo_group_end (image_id);
}