예제 #1
0
static void
get_tile (GeglBufferIterator *iter,
          int        index)
{
  GeglBufferIteratorPriv *priv = iter->priv;
  SubIterState           *sub  = &priv->sub_iter[index];

  GeglBuffer *buf = priv->sub_iter[index].buffer;

  if (sub->linear_tile)
    {
      sub->current_tile = sub->linear_tile;

      sub->real_roi = buf->extent;

      sub->current_tile_mode = GeglIteratorTileMode_LinearTile;
    }
  else
    {
      int shift_x = buf->shift_x;
      int shift_y = buf->shift_y;

      int tile_width  = buf->tile_width;
      int tile_height = buf->tile_height;

      int tile_x = gegl_tile_indice (iter->roi[index].x + shift_x, tile_width);
      int tile_y = gegl_tile_indice (iter->roi[index].y + shift_y, tile_height);

      sub->current_tile = gegl_tile_source_get_tile ((GeglTileSource *)(buf),
                                                     tile_x, tile_y, 0);

      if (sub->flags & GEGL_BUFFER_WRITE)
        gegl_tile_lock (sub->current_tile);

      sub->real_roi.x = (tile_x * tile_width)  - shift_x;
      sub->real_roi.y = (tile_y * tile_height) - shift_y;
      sub->real_roi.width  = tile_width;
      sub->real_roi.height = tile_height;

      sub->current_tile_mode = GeglIteratorTileMode_DirectTile;
    }

  sub->row_stride = buf->tile_width * sub->format_bpp;

  iter->data[index] = gegl_tile_get_data (sub->current_tile);
}
예제 #2
0
static void
retile_subs (GeglBufferIterator *iter,
             int                 x,
             int                 y)
{
  GeglBufferIteratorPriv *priv = iter->priv;
  GeglRectangle real_roi;
  int index;

  int shift_x = priv->origin_tile.x;
  int shift_y = priv->origin_tile.y;

  int tile_x = gegl_tile_indice (x + shift_x, priv->origin_tile.width);
  int tile_y = gegl_tile_indice (y + shift_y, priv->origin_tile.height);

  /* Reset tile size */
  real_roi.x = (tile_x * priv->origin_tile.width)  - shift_x;
  real_roi.y = (tile_y * priv->origin_tile.height) - shift_y;
  real_roi.width  = priv->origin_tile.width;
  real_roi.height = priv->origin_tile.height;

  /* Trim tile down to the iteration roi */
  gegl_rectangle_intersect (&iter->roi[0], &real_roi, &priv->sub_iter[0].full_rect);
  priv->sub_iter[0].real_roi = iter->roi[0];

  for (index = 1; index < priv->num_buffers; index++)
    {
      SubIterState *lead_sub = &priv->sub_iter[0];
      SubIterState *sub = &priv->sub_iter[index];

      int roi_offset_x = sub->full_rect.x - lead_sub->full_rect.x;
      int roi_offset_y = sub->full_rect.y - lead_sub->full_rect.y;

      iter->roi[index].x = iter->roi[0].x + roi_offset_x;
      iter->roi[index].y = iter->roi[0].y + roi_offset_y;
      iter->roi[index].width  = iter->roi[0].width;
      iter->roi[index].height = iter->roi[0].height;
      sub->real_roi = iter->roi[index];
    }
}
static gboolean
gegl_buffer_tile_iterator_next (GeglBufferTileIterator *i)
{
  GeglBuffer *buffer   = i->buffer;
  gint  tile_width     = buffer->tile_storage->tile_width;
  gint  tile_height    = buffer->tile_storage->tile_height;
  gint  buffer_shift_x = buffer->shift_x;
  gint  buffer_shift_y = buffer->shift_y;
  gint  buffer_x       = i->roi.x + buffer_shift_x;
  gint  buffer_y       = i->roi.y + buffer_shift_y;

  if (i->roi.width == 0 || i->roi.height == 0)
    return FALSE;

gulp:

  /* unref previously held tile */
  if (i->tile)
    {
      if (i->write && i->subrect.width == tile_width && i->same_format)
        {
          gegl_tile_unlock (i->tile);
        }
      gegl_tile_unref (i->tile);
      i->tile = NULL;
    }

  if (i->next_col < i->roi.width)
    { /* return tile on this row */
      gint tiledx = buffer_x + i->next_col;
      gint tiledy = buffer_y + i->next_row;
      gint offsetx = gegl_tile_offset (tiledx, tile_width);
      gint offsety = gegl_tile_offset (tiledy, tile_height);

        {
         i->subrect.x = offsetx;
         i->subrect.y = offsety;
         if (i->roi.width + offsetx - i->next_col < tile_width)
           i->subrect.width = (i->roi.width + offsetx - i->next_col) - offsetx;
         else
           i->subrect.width = tile_width - offsetx;

         if (i->roi.height + offsety - i->next_row < tile_height)
           i->subrect.height = (i->roi.height + offsety - i->next_row) - offsety;
         else
           i->subrect.height = tile_height - offsety;

         i->tile = gegl_tile_source_get_tile ((GeglTileSource *) (buffer),
                                        gegl_tile_indice (tiledx, tile_width),
                                        gegl_tile_indice (tiledy, tile_height),
                                        0);
         if (i->write && i->subrect.width == tile_width && i->same_format)
           {
             gegl_tile_lock (i->tile);
           }
         i->data = gegl_tile_get_data (i->tile);

         {
         gint bpp = babl_format_get_bytes_per_pixel (i->buffer->soft_format);
         i->rowstride = bpp * tile_width;
         i->sub_data = (guchar*)(i->data) + bpp * 
                        (i->subrect.y * tile_width + i->subrect.x);
         }

         i->col = i->next_col;
         i->row = i->next_row;
         i->next_col += tile_width - offsetx;


         i->roi2.x      = i->roi.x + i->col;
         i->roi2.y      = i->roi.y + i->row;
         i->roi2.width  = i->subrect.width;
         i->roi2.height = i->subrect.height;

         return TRUE;
       }
    }
  else /* move down to next row */
    {
      gint tiledy;
      gint offsety;

      i->row = i->next_row;
      i->col = i->next_col;

      tiledy = buffer_y + i->next_row;
      offsety = gegl_tile_offset (tiledy, tile_height);

      i->next_row += tile_height - offsety;
      i->next_col=0;

      if (i->next_row < i->roi.height)
        {
          goto gulp; /* return the first tile in the next row */
        }
      return FALSE;
    }
  return FALSE;
}
예제 #4
0
static void inline
gegl_sampler_get_pixel (GeglSampler    *sampler,
                        gint            x,
                        gint            y,
                        gpointer        data,
                        GeglAbyssPolicy repeat_mode)
{
  GeglSamplerNearest *nearest_sampler = (GeglSamplerNearest*)(sampler);
  GeglBuffer *buffer = sampler->buffer;
  const GeglRectangle *abyss = &buffer->abyss;
  guchar              *buf   = data;

  if (y <  abyss->y ||
      x <  abyss->x ||
      y >= abyss->y + abyss->height ||
      x >= abyss->x + abyss->width)
    {
      switch (repeat_mode)
      {
        case GEGL_ABYSS_CLAMP:
          x = CLAMP (x, abyss->x, abyss->x+abyss->width-1);
          y = CLAMP (y, abyss->y, abyss->y+abyss->height-1);
          break;

        case GEGL_ABYSS_LOOP:
          x = abyss->x + GEGL_REMAINDER (x - abyss->x, abyss->width);
          y = abyss->y + GEGL_REMAINDER (y - abyss->y, abyss->height);
          break;

        case GEGL_ABYSS_BLACK:
          {
            gfloat color[4] = {0.0, 0.0, 0.0, 1.0};
            babl_process (babl_fish (gegl_babl_rgba_linear_float (), sampler->format),
                          color,
                          buf,
                          1);
            return;
          }

        case GEGL_ABYSS_WHITE:
          {
            gfloat color[4] = {1.0, 1.0, 1.0, 1.0};
            babl_process (babl_fish (gegl_babl_rgba_linear_float (),
                                     sampler->format),
                          color,
                          buf,
                          1);
            return;
          }

        default:
        case GEGL_ABYSS_NONE:
          memset (buf, 0x00, babl_format_get_bytes_per_pixel (sampler->format));
          return;
      }
    }

  gegl_buffer_lock (sampler->buffer);

  {
    gint tile_width  = buffer->tile_width;
    gint tile_height = buffer->tile_height;
    gint tiledy      = y + buffer->shift_y;
    gint tiledx      = x + buffer->shift_x;
    gint indice_x    = gegl_tile_indice (tiledx, tile_width);
    gint indice_y    = gegl_tile_indice (tiledy, tile_height);

    GeglTile *tile = nearest_sampler->hot_tile;

    if (!(tile &&
          tile->x == indice_x &&
          tile->y == indice_y))
      {
        if (gegl_config_threads()>1)
          g_rec_mutex_lock (&buffer->tile_storage->mutex);

        if (tile)
          gegl_tile_unref (tile);

        tile = gegl_tile_source_get_tile ((GeglTileSource *) (buffer),
                                          indice_x, indice_y,
                                          0);
        nearest_sampler->hot_tile = tile;

        if (gegl_config_threads()>1)
          g_rec_mutex_unlock (&buffer->tile_storage->mutex);
      }

    if (tile)
      {
        gint tile_origin_x = indice_x * tile_width;
        gint tile_origin_y = indice_y * tile_height;
        gint       offsetx = tiledx - tile_origin_x;
        gint       offsety = tiledy - tile_origin_y;

        guchar *tp = gegl_tile_get_data (tile) + (offsety * tile_width + offsetx) * nearest_sampler->buffer_bpp;

        babl_process (sampler->fish, tp, buf, 1);
      }
  }

  gegl_buffer_unlock (sampler->buffer);
}