Пример #1
0
gboolean
gimp_gegl_mask_is_empty (GeglBuffer *buffer)
{
  GeglBufferIterator *iter;
  const Babl         *format;
  gint                bpp;

  g_return_val_if_fail (GEGL_IS_BUFFER (buffer), FALSE);

  format = gegl_buffer_get_format (buffer);
  bpp    = babl_format_get_bytes_per_pixel (format);

  iter = gegl_buffer_iterator_new (buffer, NULL, 0, format,
                                   GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 1);

  while (gegl_buffer_iterator_next (iter))
    {
      if (! gegl_memeq_zero (iter->items[0].data, bpp * iter->length))
        {
          gegl_buffer_iterator_stop (iter);

          return FALSE;
        }
    }

  return TRUE;
}
Пример #2
0
gboolean
gimp_gegl_mask_is_empty (GeglBuffer *buffer)
{
  GeglBufferIterator *iter;

  g_return_val_if_fail (GEGL_IS_BUFFER (buffer), FALSE);

  iter = gegl_buffer_iterator_new (buffer, NULL, 0, babl_format ("Y float"),
                                   GEGL_BUFFER_READ, GEGL_ABYSS_NONE);

  while (gegl_buffer_iterator_next (iter))
    {
      gfloat *data = iter->data[0];
      gint    i;

      for (i = 0; i < iter->length; i++)
        {
          if (data[i])
            {
              gegl_buffer_iterator_stop (iter);

              return FALSE;
            }
        }
    }

  return TRUE;
}
Пример #3
0
gboolean
gegl_buffer_iterator_next (GeglBufferIterator *iter)
{
  GeglBufferIteratorPriv *priv = iter->priv;

  if (priv->state == GeglIteratorState_Start)
    {
      int index;
      GeglBuffer *primary = priv->sub_iter[0].buffer;
      if (primary->tile_width == primary->extent.width 
          && primary->tile_height == primary->extent.height 
          && priv->sub_iter[0].full_rect.width == primary->tile_width 
          && priv->sub_iter[0].full_rect.height == primary->tile_height
          && priv->sub_iter[0].full_rect.x == primary->extent.x
          && priv->sub_iter[0].full_rect.y == primary->extent.y
          && priv->sub_iter[0].buffer->extent.x == iter->roi[0].x
          && priv->sub_iter[0].buffer->extent.y == iter->roi[0].y
          && FALSE) /* XXX: conditions are not strict enough, GIMPs TIFF
                       plug-in fails; but GEGLs buffer test suite passes */
      {
        if (gegl_cl_is_accelerated ())
          for (index = 0; index < priv->num_buffers; index++)
            {
              SubIterState *sub = &priv->sub_iter[index];
              gegl_buffer_cl_cache_flush (sub->buffer, &sub->full_rect);
            }
        linear_shortcut (iter);
        return TRUE;
      }

      prepare_iteration (iter);

      if (gegl_cl_is_accelerated ())
        for (index = 0; index < priv->num_buffers; index++)
          {
            SubIterState *sub = &priv->sub_iter[index];
            gegl_buffer_cl_cache_flush (sub->buffer, &sub->full_rect);
          }

      initialize_rects (iter);

      load_rects (iter);

      return TRUE;
    }
  else if (priv->state == GeglIteratorState_InRows)
    {
      int index;

      for (index = 0; index < priv->num_buffers; index++)
        {
          iter->data[index]   = ((char *)iter->data[index]) + priv->sub_iter[index].row_stride;
          iter->roi[index].y += 1;
        }

      priv->remaining_rows -= 1;

      if (priv->remaining_rows == 0)
        priv->state = GeglIteratorState_InTile;

      return TRUE;
    }
  else if (priv->state == GeglIteratorState_InTile)
    {
      int index;

      for (index = 0; index < priv->num_buffers; index++)
        {
          release_tile (iter, index);
        }

      if (increment_rects (iter) == FALSE)
        {
          gegl_buffer_iterator_stop (iter);
          return FALSE;
        }

      load_rects (iter);

      return TRUE;
    }
  else
    {
      gegl_buffer_iterator_stop (iter);
      return FALSE;
    }
}
Пример #4
0
GeglBuffer *
gimp_drawable_transform_buffer_flip (GimpDrawable         *drawable,
                                     GimpContext          *context,
                                     GeglBuffer           *orig_buffer,
                                     gint                  orig_offset_x,
                                     gint                  orig_offset_y,
                                     GimpOrientationType   flip_type,
                                     gdouble               axis,
                                     gboolean              clip_result,
                                     GimpColorProfile    **buffer_profile,
                                     gint                 *new_offset_x,
                                     gint                 *new_offset_y)
{
  const Babl         *format;
  GeglBuffer         *new_buffer;
  GeglBufferIterator *iter;
  GeglRectangle       src_rect;
  GeglRectangle       dest_rect;
  gint                bpp;
  gint                orig_x, orig_y;
  gint                orig_width, orig_height;
  gint                new_x, new_y;
  gint                new_width, new_height;
  gint                x, y;

  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
  g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
  g_return_val_if_fail (GEGL_IS_BUFFER (orig_buffer), NULL);
  g_return_val_if_fail (buffer_profile != NULL, NULL);
  g_return_val_if_fail (new_offset_x != NULL, NULL);
  g_return_val_if_fail (new_offset_y != NULL, NULL);

  *buffer_profile =
    gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (drawable));

  orig_x      = orig_offset_x;
  orig_y      = orig_offset_y;
  orig_width  = gegl_buffer_get_width (orig_buffer);
  orig_height = gegl_buffer_get_height (orig_buffer);

  new_x      = orig_x;
  new_y      = orig_y;
  new_width  = orig_width;
  new_height = orig_height;

  switch (flip_type)
    {
    case GIMP_ORIENTATION_HORIZONTAL:
      new_x = RINT (-((gdouble) orig_x +
                      (gdouble) orig_width - axis) + axis);
      break;

    case GIMP_ORIENTATION_VERTICAL:
      new_y = RINT (-((gdouble) orig_y +
                      (gdouble) orig_height - axis) + axis);
      break;

    case GIMP_ORIENTATION_UNKNOWN:
      g_return_val_if_reached (NULL);
      break;
    }

  format = gegl_buffer_get_format (orig_buffer);
  bpp    = babl_format_get_bytes_per_pixel (format);

  new_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                                new_width, new_height),
                                format);

  if (clip_result && (new_x != orig_x || new_y != orig_y))
    {
      GimpRGB    bg;
      GeglColor *color;
      gint       clip_x, clip_y;
      gint       clip_width, clip_height;

      *new_offset_x = orig_x;
      *new_offset_y = orig_y;

      /*  Use transparency, rather than the bg color, as the "outside" color of
       *  channels, and drawables with an alpha channel.
       */
      if (GIMP_IS_CHANNEL (drawable) || babl_format_has_alpha (format))
        {
          gimp_rgba_set (&bg, 0.0, 0.0, 0.0, 0.0);
        }
      else
        {
          gimp_context_get_background (context, &bg);
          gimp_pickable_srgb_to_image_color (GIMP_PICKABLE (drawable),
                                             &bg, &bg);
        }

      color = gimp_gegl_color_new (&bg, gimp_drawable_get_space (drawable));
      gegl_buffer_set_color (new_buffer, NULL, color);
      g_object_unref (color);

      if (gimp_rectangle_intersect (orig_x, orig_y, orig_width, orig_height,
                                    new_x, new_y, new_width, new_height,
                                    &clip_x, &clip_y,
                                    &clip_width, &clip_height))
        {
          orig_x = new_x = clip_x - orig_x;
          orig_y = new_y = clip_y - orig_y;
        }

      orig_width  = new_width  = clip_width;
      orig_height = new_height = clip_height;
    }
  else
    {
      *new_offset_x = new_x;
      *new_offset_y = new_y;

      orig_x = 0;
      orig_y = 0;
      new_x  = 0;
      new_y  = 0;
    }

  if (new_width == 0 && new_height == 0)
    return new_buffer;

  dest_rect.x      = new_x;
  dest_rect.y      = new_y;
  dest_rect.width  = new_width;
  dest_rect.height = new_height;

  iter = gegl_buffer_iterator_new (new_buffer, &dest_rect, 0, NULL,
                                   GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE, 1);

  switch (flip_type)
    {
    case GIMP_ORIENTATION_HORIZONTAL:
      while (gegl_buffer_iterator_next (iter))
        {
          gint stride = iter->items[0].roi.width * bpp;

          src_rect = iter->items[0].roi;

          src_rect.x = (orig_x + orig_width)          -
                       (iter->items[0].roi.x - dest_rect.x) -
                       iter->items[0].roi.width;

          gegl_buffer_get (orig_buffer, &src_rect, 1.0, NULL, iter->items[0].data,
                           stride, GEGL_ABYSS_NONE);

          for (y = 0; y < iter->items[0].roi.height; y++)
            {
              guint8 *left  = iter->items[0].data;
              guint8 *right = iter->items[0].data;

              left  += y * stride;
              right += y * stride + (iter->items[0].roi.width - 1) * bpp;

              for (x = 0; x < iter->items[0].roi.width / 2; x++)
                {
                  guint8 temp[bpp];

                  memcpy (temp,  left,  bpp);
                  memcpy (left,  right, bpp);
                  memcpy (right, temp,  bpp);

                  left  += bpp;
                  right -= bpp;
                }
            }
        }
      break;

    case GIMP_ORIENTATION_VERTICAL:
      while (gegl_buffer_iterator_next (iter))
        {
          gint stride = iter->items[0].roi.width * bpp;

          src_rect = iter->items[0].roi;

          src_rect.y = (orig_y + orig_height)         -
                       (iter->items[0].roi.y - dest_rect.y) -
                       iter->items[0].roi.height;

          gegl_buffer_get (orig_buffer, &src_rect, 1.0, NULL, iter->items[0].data,
                           stride, GEGL_ABYSS_NONE);

          for (x = 0; x < iter->items[0].roi.width; x++)
            {
              guint8 *top    = iter->items[0].data;
              guint8 *bottom = iter->items[0].data;

              top    += x * bpp;
              bottom += x * bpp + (iter->items[0].roi.height - 1) * stride;

              for (y = 0; y < iter->items[0].roi.height / 2; y++)
                {
                  guint8 temp[bpp];

                  memcpy (temp,   top,    bpp);
                  memcpy (top,    bottom, bpp);
                  memcpy (bottom, temp,   bpp);

                  top    += stride;
                  bottom -= stride;
                }
            }
        }
      break;

    case GIMP_ORIENTATION_UNKNOWN:
      gegl_buffer_iterator_stop (iter);
      break;
    }

  return new_buffer;
}
Пример #5
0
gboolean
gegl_buffer_iterator_next (GeglBufferIterator *iter)
{
  GeglBufferIteratorPriv *priv = iter->priv;

  if (priv->state == GeglIteratorState_Start)
    {
      int index;

      prepare_iteration (iter);

      if (gegl_cl_is_accelerated ())
        for (index = 0; index < priv->num_buffers; index++)
          {
            SubIterState *sub = &priv->sub_iter[index];
            gegl_buffer_cl_cache_flush (sub->buffer, &sub->full_rect);
          }

      initialize_rects (iter);

      load_rects (iter);

      return TRUE;
    }
  else if (priv->state == GeglIteratorState_InRows)
    {
      int index;

      for (index = 0; index < priv->num_buffers; index++)
        {
          iter->data[index]   = ((char *)iter->data[index]) + priv->sub_iter[index].row_stride;
          iter->roi[index].y += 1;
        }

      priv->remaining_rows -= 1;

      if (priv->remaining_rows == 0)
        priv->state = GeglIteratorState_InTile;

      return TRUE;
    }
  else if (priv->state == GeglIteratorState_InTile)
    {
      int index;

      for (index = 0; index < priv->num_buffers; index++)
        {
          release_tile (iter, index);
        }

      if (increment_rects (iter) == FALSE)
        {
          gegl_buffer_iterator_stop (iter);
          return FALSE;
        }

      load_rects (iter);

      return TRUE;
    }
  else
    {
      gegl_buffer_iterator_stop (iter);
      return FALSE;
    }
}
gboolean
gegl_buffer_iterator_next (GeglBufferIterator *iterator)
{
  GeglBufferIterators *i = (gpointer)iterator;
  gboolean result = FALSE;
  gint no;

  if (i->is_finished)
    g_error ("%s called on finished buffer iterator", G_STRFUNC);
  if (i->iteration_no == 0)
    {
      for (no=0; no<i->iterators;no++)
        {
          gint j;
          gboolean found = FALSE;
          for (j=0; j<no; j++)
            if (i->buffer[no]==i->buffer[j])
              {
                found = TRUE;
                break;
              }
          if (!found)
            gegl_buffer_lock (i->buffer[no]);

          if (gegl_cl_is_accelerated ())
            gegl_buffer_cl_cache_flush (i->buffer[no], &i->rect[no]);
        }
    }
  else
    {
      /* complete pending write work */
      for (no=0; no<i->iterators;no++)
        {
          if (i->flags[no] & GEGL_BUFFER_WRITE)
            {

              if (i->flags[no] & GEGL_BUFFER_SCAN_COMPATIBLE &&
                  i->flags[no] & GEGL_BUFFER_FORMAT_COMPATIBLE &&
                  i->roi[no].width == i->i[no].buffer->tile_storage->tile_width && (i->flags[no] & GEGL_BUFFER_FORMAT_COMPATIBLE))
                { /* direct access, don't need to do anything */
#if DEBUG_DIRECT
                   direct_write += i->roi[no].width * i->roi[no].height;
#endif
                }
              else
                {
#if DEBUG_DIRECT
                  in_direct_write += i->roi[no].width * i->roi[no].height;
#endif

                  ensure_buf (i, no);

  /* XXX: should perhaps use _set_unlocked, and keep the lock in the
   * iterator.
   */
                  gegl_buffer_set (i->buffer[no], &(i->roi[no]), 0, i->format[no], i->buf[no], GEGL_AUTO_ROWSTRIDE); /* XXX: use correct level */
                }
            }
        }
    }

  g_assert (i->iterators > 0);

  /* then we iterate all */
  for (no=0; no<i->iterators;no++)
    {
      if (i->flags[no] & GEGL_BUFFER_SCAN_COMPATIBLE)
        {
          gboolean res;
          res = gegl_buffer_tile_iterator_next (&i->i[no]);
          if (no == 0)
            {
              result = res;
            }
          i->roi[no] = i->i[no].roi2;

          /* since they were scan compatible this should be true */
          if (res != result)
            {
              g_print ("%i==%i != 0==%i\n", no, res, result);
            }
          g_assert (res == result);

          if ((i->flags[no] & GEGL_BUFFER_FORMAT_COMPATIBLE) &&
              i->roi[no].width == i->i[no].buffer->tile_storage->tile_width
           )
            {
              /* direct access */
              i->data[no]=i->i[no].sub_data;
#if DEBUG_DIRECT
              direct_read += i->roi[no].width * i->roi[no].height;
#endif
            }
          else
            {
              ensure_buf (i, no);

              if (i->flags[no] & GEGL_BUFFER_READ)
                {
                  gegl_buffer_get_unlocked (i->buffer[no], 1.0, &(i->roi[no]), i->format[no], i->buf[no], GEGL_AUTO_ROWSTRIDE);
                }

              i->data[no]=i->buf[no];
#if DEBUG_DIRECT
              in_direct_read += i->roi[no].width * i->roi[no].height;
#endif
            }
        }
      else
        {
          /* we copy the roi from iterator 0  */
          i->roi[no] = i->roi[0];
          i->roi[no].x += (i->rect[no].x-i->rect[0].x);
          i->roi[no].y += (i->rect[no].y-i->rect[0].y);

          ensure_buf (i, no);

          if (i->flags[no] & GEGL_BUFFER_READ)
            {
              gegl_buffer_get_unlocked (i->buffer[no], 1.0, &(i->roi[no]), i->format[no], i->buf[no], GEGL_AUTO_ROWSTRIDE);
            }
          i->data[no]=i->buf[no];

#if DEBUG_DIRECT
          in_direct_read += i->roi[no].width * i->roi[no].height;
#endif
        }
      i->length = i->roi[no].width * i->roi[no].height;
    }

  i->iteration_no++;

  if (result == FALSE)
    gegl_buffer_iterator_stop (iterator);

  return result;
}