Пример #1
0
static void
gimp_paint_core_copy_valid_tiles (TileManager *src_tiles,
                                  TileManager *dest_tiles,
                                  gint         x,
                                  gint         y,
                                  gint         w,
                                  gint         h)
{
  Tile *src_tile;
  gint  i, j;

  for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
    {
      for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
        {
          src_tile = tile_manager_get_tile (src_tiles,
                                            j, i, FALSE, FALSE);

          if (tile_is_valid (src_tile))
            {
              src_tile = tile_manager_get_tile (src_tiles,
                                                j, i, TRUE, FALSE);

              tile_manager_map_tile (dest_tiles, j, i, src_tile);

              tile_release (src_tile, FALSE);
            }
        }
    }
}
Пример #2
0
static void
gimp_projection_validate_tile (TileManager    *tm,
                               Tile           *tile,
                               GimpProjection *proj)
{
  Tile *additional[7];
  gint  n_additional = 0;
  gint  x, y;
  gint  width, height;
  gint  tile_width, tile_height;
  gint  col, row;
  gint  i;

  /*  Find the coordinates of this tile  */
  tile_manager_get_tile_coordinates (tm, tile, &x, &y);

  width  = tile_width  = tile_ewidth (tile);
  height = tile_height = tile_eheight (tile);

  tile_manager_get_tile_col_row (tm, tile, &col, &row);

  /*  try to validate up to 8 invalid tiles in a row  */
  while (tile_width == TILE_WIDTH && n_additional < 7)
    {
      Tile *t;

      col++;

      /*  get the next tile without any read or write access, so it
       *  won't be locked (and validated)
       */
      t = tile_manager_get_at (tm, col, row, FALSE, FALSE);

      /*  if we hit the right border, or a valid tile, bail out
       */
      if (! t || tile_is_valid (t))
        break;

      /*  HACK: mark the tile as valid, so locking it with r/w access
       *  won't validate it
       */
      t->valid = TRUE;
      t = tile_manager_get_at (tm, col, row, TRUE, TRUE);

      /*  add the tile's width to the chunk to validate  */
      tile_width = tile_ewidth (t);
      width += tile_width;

      additional[n_additional++] = t;
    }

  gimp_projection_construct (proj, x, y, width, height);

  for (i = 0; i < n_additional; i++)
    {
      /*  HACK: mark the tile as valid, because we know it is  */
      additional[i]->valid = TRUE;
      tile_release (additional[i], TRUE);
    }
}
Пример #3
0
void
gimp_paint_core_validate_canvas_tiles (GimpPaintCore *core,
                                       gint           x,
                                       gint           y,
                                       gint           w,
                                       gint           h)
{
  gint i, j;

  g_return_if_fail (GIMP_IS_PAINT_CORE (core));
  g_return_if_fail (core->canvas_tiles != NULL);

  for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
    {
      for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
        {
          Tile *tile = tile_manager_get_tile (core->canvas_tiles, j, i,
                                              FALSE, FALSE);

          if (! tile_is_valid (tile))
            {
              tile = tile_manager_get_tile (core->canvas_tiles, j, i,
                                            TRUE, TRUE);
              memset (tile_data_pointer (tile, 0, 0), 0, tile_size (tile));
              tile_release (tile, TRUE);
            }
        }
    }
}
Пример #4
0
void
gimp_paint_core_validate_saved_proj_tiles (GimpPaintCore *core,
                                           GimpPickable  *pickable,
                                           gint           x,
                                           gint           y,
                                           gint           w,
                                           gint           h)
{
  gint i, j;

  g_return_if_fail (GIMP_IS_PAINT_CORE (core));
  g_return_if_fail (GIMP_IS_PICKABLE (pickable));
  g_return_if_fail (core->saved_proj_tiles != NULL);

  for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
    {
      for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
        {
          Tile *dest_tile = tile_manager_get_tile (core->saved_proj_tiles,
                                                   j, i, FALSE, FALSE);

          if (! tile_is_valid (dest_tile))
            {
              Tile *src_tile =
                tile_manager_get_tile (gimp_pickable_get_tiles (pickable),
                                       j, i, TRUE, FALSE);

              tile_manager_map_tile (core->saved_proj_tiles, j, i, src_tile);
              tile_release (src_tile, FALSE);
            }
        }
    }
}
Пример #5
0
static void
tile_pyramid_validate_tile (TileManager *tm,
                            Tile        *tile,
                            TileManager *tm_below)
{
  gint  tile_col;
  gint  tile_row;
  gint  i, j;

  tile_manager_get_tile_col_row (tm, tile, &tile_col, &tile_row);

  for (i = 0; i < 2; i++)
    for (j = 0; j < 2; j++)
      {
        Tile *source = tile_manager_get_at (tm_below,
                                            tile_col * 2 + i,
                                            tile_row * 2 + j,
                                            TRUE, FALSE);
        if (source)
          {
            tile_pyramid_write_quarter (tile, source, i, j);
            tile_release (source, FALSE);
          }
      }
}
Пример #6
0
static void
find_empty_segs (PixelRegion  *maskPR,
                 gint          scanline,
                 gint          empty_segs[],
                 gint          max_empty,
                 gint         *num_empty,
                 BoundaryType  type,
                 gint          x1,
                 gint          y1,
                 gint          x2,
                 gint          y2,
                 guchar        threshold)
{
    const guchar *data  = NULL;
    Tile         *tile  = NULL;
    gint          start = 0;
    gint          end   = 0;
    gint          endx  = 0;
    gint          bpp   = 0;
    gint          tilex = -1;
    gint          last  = -1;
    gint          l_num_empty;
    gint          x;

    *num_empty = 0;

    if (scanline < maskPR->y || scanline >= (maskPR->y + maskPR->h))
    {
        empty_segs[(*num_empty)++] = 0;
        empty_segs[(*num_empty)++] = G_MAXINT;
        return;
    }

    if (type == BOUNDARY_WITHIN_BOUNDS)
    {
        if (scanline < y1 || scanline >= y2)
        {
            empty_segs[(*num_empty)++] = 0;
            empty_segs[(*num_empty)++] = G_MAXINT;
            return;
        }

        start = x1;
        end   = x2;
    }
    else if (type == BOUNDARY_IGNORE_BOUNDS)
    {
        start = maskPR->x;
        end   = maskPR->x + maskPR->w;
        if (scanline < y1 || scanline >= y2)
            x2 = -1;
    }

    empty_segs[(*num_empty)++] = 0;

    l_num_empty = *num_empty;

    bpp = maskPR->bytes;

    if (! maskPR->tiles)
    {
        data  = maskPR->data + scanline * maskPR->rowstride;
        endx = end;
    }

    for (x = start; x < end;)
    {
        /*  Check to see if we must advance to next tile  */
        if (maskPR->tiles)
        {
            if ((x / TILE_WIDTH) != tilex)
            {
                if (tile)
                    tile_release (tile, FALSE);

                tile = tile_manager_get_tile (maskPR->tiles,
                                              x, scanline, TRUE, FALSE);
                data = ((const guchar *) tile_data_pointer (tile, x, scanline) +
                        bpp - 1);

                tilex = x / TILE_WIDTH;
            }

            endx = x + (TILE_WIDTH - (x % TILE_WIDTH));
            endx = MIN (end, endx);
        }

        if (type == BOUNDARY_IGNORE_BOUNDS && (endx > x1 || x < x2))
        {
            for (; x < endx; x++)
            {
                gint val;

                if (*data > threshold)
                {
                    if (x >= x1 && x < x2)
                        val = -1;
                    else
                        val = 1;
                }
                else
                {
                    val = -1;
                }

                data += bpp;

                if (last != val)
                    empty_segs[l_num_empty++] = x;

                last = val;
            }
        }
        else
        {
            for (; x < endx; x++)
            {
                gint val;

                if (*data > threshold)
                    val = 1;
                else
                    val = -1;

                data += bpp;

                if (last != val)
                    empty_segs[l_num_empty++] = x;

                last = val;
            }
        }
    }

    *num_empty = l_num_empty;

    if (last > 0)
        empty_segs[(*num_empty)++] = x;

    empty_segs[(*num_empty)++] = G_MAXINT;

    if (tile)
        tile_release (tile, FALSE);
}
Пример #7
0
TempBuf *
gimp_paint_core_get_orig_proj (GimpPaintCore *core,
                               GimpPickable  *pickable,
                               gint           x,
                               gint           y,
                               gint           width,
                               gint           height)
{
  TileManager  *src_tiles;
  PixelRegion   srcPR;
  PixelRegion   destPR;
  Tile         *saved_tile;
  gboolean      release_tile;
  gint          h;
  gint          pixelwidth;
  gint          pickable_width;
  gint          pickable_height;
  const guchar *s;
  guchar       *d;
  gpointer      pr;

  g_return_val_if_fail (GIMP_IS_PAINT_CORE (core), NULL);
  g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), NULL);
  g_return_val_if_fail (core->saved_proj_tiles != NULL, NULL);

  core->orig_proj_buf = temp_buf_resize (core->orig_proj_buf,
                                         gimp_pickable_get_bytes (pickable),
                                         x, y, width, height);

  src_tiles = gimp_pickable_get_tiles (pickable);

  pickable_width  = tile_manager_width  (src_tiles);
  pickable_height = tile_manager_height (src_tiles);

  gimp_rectangle_intersect (x, y,
                            width, height,
                            0, 0,
                            pickable_width, pickable_height,
                            &x, &y,
                            &width, &height);

  /*  configure the pixel regions  */
  pixel_region_init (&srcPR, src_tiles,
                     x, y, width, height,
                     FALSE);

  pixel_region_init_temp_buf (&destPR, core->orig_proj_buf,
                              x - core->orig_proj_buf->x,
                              y - core->orig_proj_buf->y,
                              width, height);

  for (pr = pixel_regions_register (2, &srcPR, &destPR);
       pr != NULL;
       pr = pixel_regions_process (pr))
    {
      /*  If the saved tile corresponding to this location is valid, use it  */
      saved_tile = tile_manager_get_tile (core->saved_proj_tiles,
                                          srcPR.x, srcPR.y,
                                          FALSE, FALSE);

      if (tile_is_valid (saved_tile))
        {
          release_tile = TRUE;

          saved_tile = tile_manager_get_tile (core->saved_proj_tiles,
                                              srcPR.x, srcPR.y,
                                              TRUE, FALSE);
          s = tile_data_pointer (saved_tile, srcPR.x, srcPR.y);
        }
      else
        {
          release_tile = FALSE;

          s = srcPR.data;
        }

      d = destPR.data;

      pixelwidth = srcPR.w * srcPR.bytes;

      h = srcPR.h;
      while (h --)
        {
          memcpy (d, s, pixelwidth);

          s += srcPR.rowstride;
          d += destPR.rowstride;
        }

      if (release_tile)
        tile_release (saved_tile, FALSE);
    }

  return core->orig_proj_buf;
}