Ejemplo n.º 1
0
static void
do_zcrop (gint32  drawable_id,
          gint32  image_id)
{
  GeglBuffer  *drawable_buffer;
  GeglBuffer  *shadow_buffer;
  gfloat      *linear_buf;
  const Babl  *format;

  gint         x, y, width, height;
  gint         components;
  gint8       *killrows;
  gint8       *killcols;
  gint32       livingrows, livingcols, destrow, destcol;
  gint32       selection_copy_id;
  gboolean     has_alpha;

  drawable_buffer = gimp_drawable_get_buffer (drawable_id);
  shadow_buffer   = gimp_drawable_get_shadow_buffer (drawable_id);

  width  = gegl_buffer_get_width (drawable_buffer);
  height = gegl_buffer_get_height (drawable_buffer);
  has_alpha = gimp_drawable_has_alpha (drawable_id);

  if (has_alpha)
    format = babl_format ("R'G'B'A float");
  else
    format = babl_format ("R'G'B' float");

  components = babl_format_get_n_components (format);

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

  linear_buf = g_new (gfloat, (width > height ? width : height) * components);

  /* search which rows to remove */

  livingrows = 0;
  for (y = 0; y < height; y++)
    {
      gegl_buffer_get (drawable_buffer, GEGL_RECTANGLE (0, y, width, 1),
                       1.0, format, linear_buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

      killrows[y] = TRUE;

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

  gimp_progress_update (0.25);

  /* search which columns to remove */

  livingcols = 0;
  for (x = 0; x < width; x++)
    {
      gegl_buffer_get (drawable_buffer, GEGL_RECTANGLE (x, 0, 1, height),
                       1.0, format, linear_buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

      killcols[x] = TRUE;

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

  gimp_progress_update (0.5);

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

  /* restitute living rows */

  destrow = 0;
  for (y = 0; y < height; y++)
    {
      if (!killrows[y])
        {
          gegl_buffer_copy (drawable_buffer,
                            GEGL_RECTANGLE (0, y, width, 1),
                            GEGL_ABYSS_NONE,
                            shadow_buffer,
                            GEGL_RECTANGLE (0, destrow, width, 1));

          destrow++;
        }
    }

  gimp_progress_update (0.75);

  /* restitute living columns */

  destcol = 0;
  for (x = 0; x < width; x++)
    {
      if (!killcols[x])
        {
          gegl_buffer_copy (shadow_buffer,
                            GEGL_RECTANGLE (x, 0, 1, height),
                            GEGL_ABYSS_NONE,
                            shadow_buffer,
                            GEGL_RECTANGLE (destcol, 0, 1, height));

          destcol++;
        }
    }

  gimp_progress_update (1.00);

  gimp_image_undo_group_start (image_id);

  selection_copy_id = gimp_selection_save (image_id);
  gimp_selection_none (image_id);

  gegl_buffer_flush (shadow_buffer);
  gimp_drawable_merge_shadow (drawable_id, TRUE);
  gegl_buffer_flush (drawable_buffer);

  gimp_image_select_item (image_id, GIMP_CHANNEL_OP_REPLACE, selection_copy_id);
  gimp_image_remove_channel (image_id, selection_copy_id);

  gimp_image_crop (image_id, livingcols, livingrows, 0, 0);

  gimp_image_undo_group_end (image_id);

  g_object_unref (shadow_buffer);
  g_object_unref (drawable_buffer);

  g_free (linear_buf);
  g_free (killrows);
  g_free (killcols);
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
void cmd_color(const char* cmd, size_t cmdlen, char* args, size_t argslen)
{
    const char* usage = "Usage: /color R G B (R G B must be between 0 and 255)";

    Color color = Color(0,0,0);
    bool valid = true;

    // split lines up
    int i = 0;
    int n = 1;
    const char delim = ' ';
    char c = '\0';
    while ((c = args[i++]) != '\0')
    {
        if (!isdigit(c) && c != delim)
            break;
        if (c == delim)
        {
            args[i-1] = '\0';
            n++;
        }
    }
    i = 0;

    if (c != '\0') valid = false;    // encountered invalid char
    if (n != 3) valid = false;       // invalid arg count

    if (!valid)
    {
        chat_client->send_system_message(usage);
        return;
    }

    char buf[3+1] = {'\0'};

    int j = 0;  // copy red
    while ((c = args[i++]) != '\0' && j < 3)
        buf[j++] = c;
    buf[j] = '\0';
    if (args[i-1] != '\0') valid = false;
    else
    {
        int r = atoi(buf);
        if (r > 0xFF) valid = false;
        else color.r = r;
    }
    printf("r: %s\n", buf);

    j = 0;      // copy green
    while ((c = args[i++]) != '\0' && j < 3)
        buf[j++] = c;
    buf[j] = '\0';
    if (args[i-1] != '\0') valid = false;
    else
    {
        int g = atoi(buf);
        if (g > 0xFF) valid = false;
        else color.g = g;
    }
    printf("g: %s\n", buf);

    j = 0;      // copy blue
    while ((c = args[i++]) != '\0' && j < 3)
        buf[j++] = c;
    buf[j] = '\0';
    if (args[i-1] != '\0') valid = false;
    else
    {
        int b = atoi(buf);
        if (b > 0xFF) valid = false;
        else color.b = b;
    }
    printf("b: %s\n", buf);

    if (!valid)
    {
        chat_client->send_system_message(usage);
        return;
    }

    class Agents::Agent* you = ClientState::player_agent.you();
    if (you != NULL && colors_equal(you->status.color, color))
    {
        static const char msgfmt[] = "Your color is already %d %d %d";
        static const size_t msg_len = sizeof(msgfmt) + 3*3 - 3*2;
        static char msg[msg_len+1] = {'\0'};

        snprintf(msg, msg_len+1, msgfmt, color.r, color.g, color.b);
        chat_client->send_system_message(msg);
    }

    colorme_CtoS msg;
    msg.color = color;
    msg.send();
}