function getBinaryShape(x, y, base) {
  const layer = this.getCurrentLayer();
  const bounds = layer.bounds;
  const bx = layer.x + bounds.x; const by = layer.y + bounds.y;
  const bw = bounds.w; const bh = bounds.h;
  const isEmpty = base[3] === 0;
  const gridl = bw * bh;
  // allocate and do a basic fill onto the grid
  let grid = new Uint8Array(bw * bh);
  for (let ii = 0; ii < gridl; ++ii) {
    const xx = ii % bw;
    const yy = (ii / bw) | 0;
    const color = layer.getPixelAt(bx + xx, by + yy);
    // empty tile based
    if (isEmpty) { if (color !== null) continue; }
    // color based
    else {
      if (color === null) continue;
      if (!(
        base[0] === color[0] &&
        base[1] === color[1] &&
        base[2] === color[2] &&
        base[3] === color[3]
      )) continue;
    }
    // fill tiles with 1's if we got a color match
    grid[yy * bw + xx] = 1;
  };
  // trace connected tiles by [x,y]=2
  let queue = [{x: x - bx, y: y - by}];
  while (queue.length > 0) {
    const point = queue.pop();
    const x = point.x; const y = point.y;
    const idx = y * bw + x;
    // set this grid tile to 2, if it got traced earlier as a color match
    if (grid[idx] === 1) grid[idx] = 2;
    const nn = (y-1) * bw + x;
    const ee = y * bw + (x+1);
    const ss = (y+1) * bw + x;
    const ww = y * bw + (x-1);
    if (grid[nn] === 1) queue.push({x, y:y-1});
    if (grid[ee] === 1) queue.push({x:x+1, y});
    if (grid[ss] === 1) queue.push({x, y:y+1});
    if (grid[ww] === 1) queue.push({x:x-1, y});
  };
  return (grid);
}
Uses preallocated binary grid with the size of the absolute boundings
of our working area. In the next step we trace "alive cells" in the grid,
then we take the boundings of the used area of our grid and crop out
the relevant part. Next we can process each tile=^2 traced as inside shape
@param {Number} x
@param {Number} y
@param {Array} base
@return {Uint8Array}