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); } } } }
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); } }
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); } } } }
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); } } } }
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); } } }
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); }
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; }