Exemple #1
0
void brush_get_selected (ppm_t *p)
{
  if (brush_from_file)
    brush_reload (pcvals.selected_brush, p);
  else
    ppm_copy (&brushppm, p);
}
static void
update_vector_prev (void)
{
  static gint    ok = 0;
  gint           i, x, y;
  gdouble        dir, xo, yo;
  gdouble        val;
  static gdouble last_val = 0.0;
  guchar         gray[3]  = {120, 120, 120};
  guchar         red[3]   = {255, 0, 0};
  guchar         white[3] = {255, 255, 255};

  if (vector_preview_brightness_adjust)
    val = 1.0 - gtk_adjustment_get_value (GTK_ADJUSTMENT (vector_preview_brightness_adjust)) / 100.0;
  else
    val = 0.5;

  if (!ok || (val != last_val))
    {
      infile_copy_to_ppm (&update_vector_preview_backup);
      ppm_apply_brightness (&update_vector_preview_backup, val, 1,1,1);

      if ((update_vector_preview_backup.width != OMWIDTH) ||
          (update_vector_preview_backup.height != OMHEIGHT))
        resize_fast (&update_vector_preview_backup, OMWIDTH, OMHEIGHT);
      ok = 1;
    }
  ppm_copy (&update_vector_preview_backup, &update_vector_preview_buffer);

  for (i = 0; i < num_vectors; i++)
    {
      gdouble s;

      x = vector[i].x * OMWIDTH;
      y = vector[i].y * OMHEIGHT;
      dir = gimp_deg_to_rad (vector[i].dir);
      s = gimp_deg_to_rad (vector[i].str);
      xo = sin (dir) * (6.0+100*s);
      yo = cos (dir) * (6.0+100*s);

      if (i == selectedvector)
        {
          ppm_drawline (&update_vector_preview_buffer,
                        x - xo, y - yo, x + xo, y + yo, red);
        }
      else
        {
          ppm_drawline (&update_vector_preview_buffer,
                        x - xo, y - yo, x + xo, y + yo, gray);
        }
      ppm_put_rgb (&update_vector_preview_buffer, x - xo, y - yo, white);
  }

  gimp_preview_area_draw (GIMP_PREVIEW_AREA (vector_preview),
                          0, 0, OMWIDTH, OMHEIGHT,
                          GIMP_RGB_IMAGE,
                          (guchar *)update_vector_preview_buffer.col,
                          OMWIDTH * 3);
}
Exemple #3
0
/*
 * This function caches the last result. Call it with fn as NULL, to
 * free the arguments.
 * */
void
brush_reload (const gchar *fn,
              ppm_t       *p)
{
  static char  lastfn[256] = "";
  static ppm_t cache       = {0, 0, NULL};

  if (fn == NULL)
    {
      ppm_kill (&cache);
      lastfn[0] = '\0';
      return;
    }

  if (strcmp (fn, lastfn))
    {
      g_strlcpy (lastfn, fn, sizeof (lastfn));
      ppm_kill (&cache);
      ppm_load (fn, &cache);
    }
  ppm_copy (&cache, p);
  set_colorbrushes (fn);
}
Exemple #4
0
static void
update_brush_preview (const gchar *fn)
{
  gint   i, j;
  guchar *preview_image;

  if (fn)
    brush_from_file = 1;

  preview_image = g_new0 (guchar, 100*100);

  if (!fn && brush_from_file)
    {
      /* preview_image is already initialized to our liking. */
    }
  else
    {
      double sc;
      ppm_t  p = {0, 0, NULL};
      guchar gammatable[256];
      int    newheight;

      if (brush_from_file)
        brush_reload (fn, &p);
      else if (PPM_IS_INITED (&brushppm))
        ppm_copy (&brushppm, &p);

      set_colorbrushes (fn);

      sc = gtk_adjustment_get_value (brush_gamma_adjust);
      if (sc != 1.0)
        for (i = 0; i < 256; i++)
          gammatable[i] = pow (i / 255.0, sc) * 255;
      else
        for (i = 0; i < 256; i++)
          gammatable[i] = i;

      newheight = p.height *
        pow (10, gtk_adjustment_get_value (brush_aspect_adjust));

      sc = p.width > newheight ? p.width : newheight;
      sc = 100.0 / sc;
      resize_fast (&p, p.width*sc,newheight*sc);
      padbrush (&p, 100, 100);
      for (i = 0; i < 100; i++)
        {
          int k = i * p.width * 3;
          if (i < p.height)
            for (j = 0; j < p.width; j++)
              preview_image[i*100+j] = gammatable[p.col[k + j * 3]];
        }
      ppm_kill (&p);
    }
  gimp_preview_area_draw (GIMP_PREVIEW_AREA (brush_preview),
                          0, 0, 100, 100,
                          GIMP_GRAY_IMAGE,
                          preview_image,
                          100);

  g_free (preview_image);
}
Exemple #5
0
void
repaint (ppm_t *p, ppm_t *a)
{
  int         x, y;
  int         tx = 0, ty = 0;
  ppm_t       tmp = {0, 0, NULL};
  ppm_t       atmp = {0, 0, NULL};
  int         r, g, b, h, i, j, on, sn;
  int         num_brushes, maxbrushwidth, maxbrushheight;
  guchar      back[3] = {0, 0, 0};
  ppm_t      *brushes, *shadows;
  ppm_t      *brush, *shadow = NULL;
  double     *brushes_sum;
  int         cx, cy, maxdist;
  double      scale, relief, startangle, anglespan, density, bgamma;
  int         max_progress;
  ppm_t       paper_ppm = {0, 0, NULL};
  ppm_t       dirmap = {0, 0, NULL};
  ppm_t       sizmap = {0, 0, NULL};
  int        *xpos = NULL, *ypos = NULL;
  int         progstep;
  static int  running = 0;

  int dropshadow = pcvals.general_drop_shadow;
  int shadowblur = pcvals.general_shadow_blur;

  if (running)
    return;
  running++;

  runningvals = pcvals;

  /* Shouldn't be necessary, but... */
  if (img_has_alpha)
    if ((p->width != a->width) || (p->height != a->height))
      {
        g_printerr ("Huh? Image size != alpha size?\n");
        return;
      }

  num_brushes = runningvals.orient_num * runningvals.size_num;
  startangle = runningvals.orient_first;
  anglespan = runningvals.orient_last;

  density = runningvals.brush_density;

  if (runningvals.place_type == PLACEMENT_TYPE_EVEN_DIST)
    density /= 3.0;

  bgamma = runningvals.brushgamma;

  brushes = g_malloc (num_brushes * sizeof (ppm_t));
  brushes_sum = g_malloc (num_brushes * sizeof (double));

  if (dropshadow)
    shadows = g_malloc (num_brushes * sizeof (ppm_t));
  else
    shadows = NULL;

  brushes[0].col = NULL;
  brush_get_selected (&brushes[0]);

  resize (&brushes[0],
          brushes[0].width,
          brushes[0].height * pow (10, runningvals.brush_aspect));
  scale = runningvals.size_last / MAX (brushes[0].width, brushes[0].height);

  if (bgamma != 1.0)
    ppm_apply_gamma (&brushes[0], 1.0 / bgamma, 1,1,1);

  resize (&brushes[0], brushes[0].width * scale, brushes[0].height * scale);
  i = 1 + sqrt (brushes[0].width  * brushes[0].width +
                brushes[0].height * brushes[0].height);
  ppm_pad (&brushes[0], i-brushes[0].width, i-brushes[0].width,
           i - brushes[0].height, i - brushes[0].height, back);

  for (i = 1; i < num_brushes; i++)
    {
      brushes[i].col = NULL;
      ppm_copy (&brushes[0], &brushes[i]);
    }

    for (i = 0; i < runningvals.size_num; i++)
      {
      double sv;
      if (runningvals.size_num > 1)
        sv = i / (runningvals.size_num - 1.0);
      else sv = 1.0;
      for (j = 0; j < runningvals.orient_num; j++)
        {
          h = j + i * runningvals.orient_num;
          free_rotate (&brushes[h],
                       startangle + j * anglespan / runningvals.orient_num);
          rescale (&brushes[h],
                   ( sv      * runningvals.size_first +
                    (1.0-sv) * runningvals.size_last    ) / runningvals.size_last);
          autocrop (&brushes[h],1);
        }
    }

  /* Brush-debugging */
#if 0
  for (i = 0; i < num_brushes; i++)
    {
      char tmp[1000];
      g_snprintf (tmp, sizeof (tmp), "/tmp/_brush%03d.ppm", i);
      ppm_save (&brushes[i], tmp);
    }
#endif

  for (i = 0; i < num_brushes; i++)
    {
      if (!runningvals.color_brushes)
        prepare_brush (&brushes[i]);
      brushes_sum[i] = sum_brush (&brushes[i]);
    }

  brush = &brushes[0];

  maxbrushwidth = maxbrushheight = 0;
  for (i = 0; i < num_brushes; i++)
    {
      if (brushes[i].width > maxbrushwidth)
        maxbrushwidth = brushes[i].width;
      if (brushes[i].height > maxbrushheight)
        maxbrushheight = brushes[i].height;
    }

  for (i = 0; i < num_brushes; i++)
    {
      int xp, yp;
      guchar blk[3] = {0, 0, 0};

      xp = maxbrushwidth - brushes[i].width;
      yp = maxbrushheight - brushes[i].height;
      if (xp || yp)
        ppm_pad (&brushes[i], xp / 2, xp - xp / 2, yp / 2, yp - yp / 2, blk);
    }

  if (dropshadow)
    {
      for (i = 0; i < num_brushes; i++)
        {
          shadows[i].col = NULL;
          ppm_copy (&brushes[i], &shadows[i]);
          ppm_apply_gamma (&shadows[i], 0, 1,1,0);
          ppm_pad (&shadows[i], shadowblur*2, shadowblur*2,
                   shadowblur*2, shadowblur*2, back);
          for (j = 0; j < shadowblur; j++)
            blur (&shadows[i], 2, 2);
#if 0
          autocrop (&shadows[i],1);
#endif
        }
#if 0
      maxbrushwidth += shadowdepth*3;
      maxbrushheight += shadowdepth*3;
#endif
    }

  /* For extra annoying debugging :-) */
#if 0
  ppm_save (brushes, "/tmp/__brush.ppm");
  if (shadows) ppm_save (shadows, "/tmp/__shadow.ppm");
  system ("xv /tmp/__brush.ppm & xv /tmp/__shadow.ppm & ");
#endif

  if (runningvals.general_paint_edges)
    {
      edgepad (p, maxbrushwidth, maxbrushwidth,
               maxbrushheight, maxbrushheight);
      if (img_has_alpha)
        edgepad (a, maxbrushwidth, maxbrushwidth,
                 maxbrushheight, maxbrushheight);
    }

  if (img_has_alpha)
    {
    /* Initially fully transparent */
      if (runningvals.general_background_type == BG_TYPE_TRANSPARENT)
        {
          guchar tmpcol[3] = {255, 255, 255};

          ppm_new (&atmp, a->width, a->height);
          fill (&atmp, tmpcol);
        }
      else
        {
          ppm_copy (a, &atmp);
        }
    }

  if (runningvals.general_background_type == BG_TYPE_SOLID)
    {
      guchar tmpcol[3];

      ppm_new (&tmp, p->width, p->height);
      gimp_rgb_get_uchar (&runningvals.color,
                          &tmpcol[0], &tmpcol[1], &tmpcol[2]);
      fill (&tmp, tmpcol);
    }
  else if (runningvals.general_background_type == BG_TYPE_KEEP_ORIGINAL)
    {
      ppm_copy (p, &tmp);
    }
  else
    {
      int dx, dy;

      ppm_new (&tmp, p->width, p->height);
      ppm_load (runningvals.selected_paper, &paper_ppm);

      if (runningvals.paper_scale != 100.0)
        {
          scale = runningvals.paper_scale / 100.0;
          resize (&paper_ppm, paper_ppm.width * scale, paper_ppm.height * scale);
        }

      if (runningvals.paper_invert)
        ppm_apply_gamma (&paper_ppm, -1.0, 1, 1, 1);

      dx = runningvals.general_paint_edges ? paper_ppm.width - maxbrushwidth : 0;
      dy = runningvals.general_paint_edges ? paper_ppm.height - maxbrushheight : 0;

      for (y = 0; y < tmp.height; y++)
        {
          int lx;
          int ry = (y + dy) % paper_ppm.height;

          for (x = 0; x < tmp.width; x+=lx)
            {
              int rx = (x + dx) % paper_ppm.width;

              lx = MIN (tmp.width - x, paper_ppm.width - rx);

              memcpy (&tmp.col[y * tmp.width * 3 + x * 3],
                      &paper_ppm.col[ry * paper_ppm.width * 3 + rx * 3],
                      3 * lx);
            }
        }
    }

  cx = p->width / 2;
  cy = p->height / 2;
  maxdist = sqrt (cx * cx + cy * cy);

  switch (runningvals.orient_type)
    {
    case ORIENTATION_VALUE:
      ppm_new (&dirmap, p->width, p->height);
      for (y = 0; y < dirmap.height; y++)
        {
          guchar *dstrow = &dirmap.col[y * dirmap.width * 3];
          guchar *srcrow = &p->col[y * p->width * 3];
          for (x = 0; x < dirmap.width; x++)
            {
              dstrow[x * 3] =
                (srcrow[x * 3] + srcrow[x * 3 + 1] + srcrow[x * 3 + 2]) / 3;
            }
        }
      break;

    case ORIENTATION_RADIUS:
      ppm_new (&dirmap, p->width, p->height);
      for (y = 0; y < dirmap.height; y++)
        {
          guchar *dstrow = &dirmap.col[y * dirmap.width * 3];
          double ysqr = (cy - y) * (cy - y);

          for (x = 0; x < dirmap.width; x++)
            {
              dstrow[x*3] = sqrt ((cx - x) * (cx - x) + ysqr) * 255 / maxdist;
            }
        }
      break;

    case ORIENTATION_RADIAL:
      ppm_new (&dirmap, p->width, p->height);
      for (y = 0; y < dirmap.height; y++)
        {
          guchar *dstrow = &dirmap.col[y * dirmap.width * 3];

          for (x = 0; x < dirmap.width; x++)
            {
              dstrow[x * 3] = (G_PI + atan2 (cy - y, cx - x)) *
                              255.0 / (G_PI * 2);
            }
        }
      break;

    case ORIENTATION_FLOWING:
      ppm_new (&dirmap, p->width / 6 + 5, p->height / 6 + 5);
      mkgrayplasma (&dirmap, 15);
      blur (&dirmap, 2, 2);
      blur (&dirmap, 2, 2);
      resize (&dirmap, p->width, p->height);
      blur (&dirmap, 2, 2);
      if (runningvals.general_paint_edges)
        edgepad (&dirmap, maxbrushwidth, maxbrushheight,
                 maxbrushwidth, maxbrushheight);
      break;

    case ORIENTATION_HUE:
      ppm_new (&dirmap, p->width, p->height);
      for (y = 0; y < dirmap.height; y++)
        {
          guchar *dstrow = &dirmap.col[y * dirmap.width * 3];
          guchar *srcrow = &p->col[y * p->width * 3];

          for (x = 0; x < dirmap.width; x++)
            {
              dstrow[x * 3] = get_hue (&srcrow[x * 3]);
            }
        }
      break;

    case ORIENTATION_ADAPTIVE:
      {
        guchar tmpcol[3] = {0, 0, 0};

        ppm_new (&dirmap, p->width, p->height);
        fill (&dirmap, tmpcol);
      }
      break;

    case ORIENTATION_MANUAL:
      ppm_new (&dirmap, p->width-maxbrushwidth*2, p->height-maxbrushheight*2);
      for (y = 0; y < dirmap.height; y++)
        {
          guchar *dstrow = &dirmap.col[y * dirmap.width * 3];
          double tmpy = y / (double)dirmap.height;
          for (x = 0; x < dirmap.width; x++)
            {
              dstrow[x * 3] = get_pixel_value(90 -
                                              get_direction(x /
                                                            (double)dirmap.width,
                                                            tmpy, 1));
            }
        }
      edgepad (&dirmap,
               maxbrushwidth, maxbrushwidth,
               maxbrushheight, maxbrushheight);
    break;
  }

  if (runningvals.size_type == SIZE_TYPE_VALUE)
    {
      ppm_new (&sizmap, p->width, p->height);
      for (y = 0; y < sizmap.height; y++)
        {
          guchar *dstrow = &sizmap.col[y * sizmap.width * 3];
          guchar *srcrow = &p->col[y * p->width * 3];

          for (x = 0; x < sizmap.width; x++)
            {
              dstrow[x * 3] =
                (srcrow[x * 3] + srcrow[x * 3 + 1] + srcrow[x * 3 + 2]) / 3;
            }
        }
    }
  else if (runningvals.size_type == SIZE_TYPE_RADIUS)
    {
      ppm_new (&sizmap, p->width, p->height);
      for (y = 0; y < sizmap.height; y++)
        {
          guchar *dstrow = &sizmap.col[y * sizmap.width * 3];
          double ysqr = (cy - y) * (cy - y);

          for (x = 0; x < sizmap.width; x++)
            {
              dstrow[x * 3] =
                sqrt ((cx - x) * (cx - x) + ysqr) * 255 / maxdist;
            }
        }
    }
  else if (runningvals.size_type == SIZE_TYPE_RADIAL)
    {
      ppm_new (&sizmap, p->width, p->height);
      for (y = 0; y < sizmap.height; y++)
        {
          guchar *dstrow = &sizmap.col[y * sizmap.width * 3];

          for (x = 0; x < sizmap.width; x++)
            {
              dstrow[x * 3] = (G_PI + atan2 (cy - y, cx - x)) *
                              255.0 / (G_PI * 2);
            }
        }
    }
  else if (runningvals.size_type == SIZE_TYPE_FLOWING)
    {
      ppm_new (&sizmap, p->width / 6 + 5, p->height / 6 + 5);
      mkgrayplasma (&sizmap, 15);
      blur (&sizmap, 2, 2);
      blur (&sizmap, 2, 2);
      resize (&sizmap, p->width, p->height);
      blur (&sizmap, 2, 2);
      if (runningvals.general_paint_edges)
        edgepad (&sizmap,
                 maxbrushwidth, maxbrushheight,
                 maxbrushwidth, maxbrushheight);
    }
  else if (runningvals.size_type == SIZE_TYPE_HUE)
    {
      ppm_new (&sizmap, p->width, p->height);
      for (y = 0; y < sizmap.height; y++)
        {
          guchar *dstrow = &sizmap.col[y * sizmap.width * 3];
          guchar *srcrow = &p->col[y * p->width * 3];

          for (x = 0; x < sizmap.width; x++)
            {
              dstrow[ x * 3] = get_hue (&srcrow[x * 3]);
            }
        }
    }
  else if (runningvals.size_type == SIZE_TYPE_ADAPTIVE)
    {
      guchar tmpcol[3] = {0, 0, 0};

      ppm_new (&sizmap, p->width, p->height);
      fill (&sizmap, tmpcol);
    }
  else if (runningvals.size_type == SIZE_TYPE_MANUAL)
    {
      ppm_new (&sizmap,
               p->width-maxbrushwidth * 2,
               p->height-maxbrushheight * 2);

      for (y = 0; y < sizmap.height; y++)
        {
          guchar *dstrow = &sizmap.col[y * sizmap.width * 3];
          double tmpy = y / (double)sizmap.height;

          for (x = 0; x < sizmap.width; x++)
            {
              dstrow[x * 3] = 255 * (1.0 - get_siz_from_pcvals (x / (double)sizmap.width, tmpy));
            }
        }
      edgepad (&sizmap,
               maxbrushwidth, maxbrushwidth,
               maxbrushheight, maxbrushheight);
    }
#if 0
  ppm_save(&sizmap, "/tmp/_sizmap.ppm");
#endif
  if (runningvals.place_type == PLACEMENT_TYPE_RANDOM)
    {
      i = tmp.width * tmp.height / (maxbrushwidth * maxbrushheight);
      i *= density;
    }
  else if (runningvals.place_type == PLACEMENT_TYPE_EVEN_DIST)
    {
      i = (int)(tmp.width * density / maxbrushwidth) *
          (int)(tmp.height * density / maxbrushheight);
#if 0
    g_printerr("i=%d\n", i);
#endif
    }

  if (i < 1)
    i = 1;

  max_progress = i;
  progstep = max_progress / 30;
  if (progstep < 10)
    progstep = 10;

  if (runningvals.place_type == PLACEMENT_TYPE_EVEN_DIST)
    {
      int j;

      xpos = g_new (int, i);
      ypos = g_new (int, i);
      for (j = 0; j < i; j++)
        {
          int factor = (int)(tmp.width * density / maxbrushwidth + 0.5);

          if (factor < 1)
            factor = 1;
          xpos[j] = maxbrushwidth/2 + (j % factor) * maxbrushwidth / density;
          ypos[j] = maxbrushheight/2 + (j / factor) * maxbrushheight / density;
        }
      for (j = 0; j < i; j++)
        {
          int a, b;

          a = g_rand_int_range (random_generator, 0, i);
          b = xpos[j]; xpos[j] = xpos[a]; xpos[a] = b;
          b = ypos[j]; ypos[j] = ypos[a]; ypos[a] = b;
        }
    }
Exemple #6
0
static void
updatesmvectorprev (void)
{
  static int     ok = 0;
  gint           i, x, y;
  gdouble        val;
  static gdouble last_val = 0.0;
  guchar         gray[3]  = {120, 120, 120};
  guchar         red[3]   = {255, 0, 0};
  guchar         white[3] = {255, 255, 255};

  if (smvectprevbrightadjust)
    val = 1.0 - gtk_adjustment_get_value (GTK_ADJUSTMENT (smvectprevbrightadjust)) / 100.0;
  else
    val = 0.5;

  if (!ok || (val != last_val))
    {
#if 0
      if (!PPM_IS_INITED (&infile))
         updatepreview (NULL, (void *)2); /* Force grabarea () */
      ppm_copy (&infile, &update_vector_preview_backup);
#else
      infile_copy_to_ppm (&update_vector_preview_backup);
#endif
      ppm_apply_brightness (&update_vector_preview_backup, val, 1,1,1);

      if (update_vector_preview_backup.width != OMWIDTH ||
          update_vector_preview_backup.height != OMHEIGHT)
         resize_fast (&update_vector_preview_backup, OMWIDTH, OMHEIGHT);

      ok = 1;
  }
  ppm_copy (&update_vector_preview_backup, &update_vector_preview_sbuffer);

  for (i = 0; i < numsmvect; i++)
    {
      x = smvector[i].x * OMWIDTH;
      y = smvector[i].y * OMHEIGHT;
      if (i == selectedsmvector)
      {
         ppm_drawline (&update_vector_preview_sbuffer, x-5, y, x+5, y, red);
         ppm_drawline (&update_vector_preview_sbuffer, x, y-5, x, y+5, red);
      }
      else
      {
         ppm_drawline (&update_vector_preview_sbuffer, x-5, y, x+5, y, gray);
         ppm_drawline (&update_vector_preview_sbuffer, x, y-5, x, y+5, gray);
      }
      ppm_put_rgb (&update_vector_preview_sbuffer, x, y, white);
  }

  gimp_preview_area_draw (GIMP_PREVIEW_AREA (smvectorprev),
                          0, 0, OMWIDTH, OMHEIGHT,
                          GIMP_RGB_IMAGE,
                          update_vector_preview_sbuffer.col,
                          OMWIDTH * 3);

  gtk_widget_set_sensitive (prev_button, (numsmvect > 1));
  gtk_widget_set_sensitive (next_button, (numsmvect > 1));
  gtk_widget_set_sensitive (add_button, (numsmvect < MAXORIENTVECT));
  gtk_widget_set_sensitive (kill_button, (numsmvect > 1));
}