示例#1
0
Image* NewImageFromMask(const DocumentLocation& location)
{
  const Sprite* srcSprite = location.sprite();
  const Mask* srcMask = location.document()->getMask();
  const Image* srcBitmap = srcMask->getBitmap();
  const gfx::Rect& srcBounds = srcMask->getBounds();
  const uint8_t* address;
  int x, y, u, v, getx, gety;
  Image *dst;
  const Image *src = location.image(&x, &y);
  div_t d;

  ASSERT(srcSprite);
  ASSERT(srcMask);
  ASSERT(srcBitmap);
  ASSERT(src);

  dst = Image::create(srcSprite->getPixelFormat(), srcBounds.w, srcBounds.h);
  if (!dst)
    return NULL;

  // Clear the new image
  image_clear(dst, 0);

  // Copy the masked zones
  for (v=0; v<srcBounds.h; v++) {
    d = div(0, 8);
    address = ((const uint8_t**)srcBitmap->line)[v]+d.quot;

    for (u=0; u<srcBounds.w; u++) {
      if ((*address & (1<<d.rem))) {
        getx = u+srcBounds.x-x;
        gety = v+srcBounds.y-y;

        if ((getx >= 0) && (getx < src->w) &&
            (gety >= 0) && (gety < src->h))
          dst->putpixel(u, v, src->getpixel(getx, gety));
      }

      _image_bitmap_next_bit(d, address);
    }
  }

  return dst;
}
示例#2
0
文件: misc.cpp 项目: Skiles/aseprite
Image* NewImageFromMask(const Document* srcDocument)
{
    const Sprite* srcSprite = srcDocument->getSprite();
    const Mask* srcMask = srcDocument->getMask();
    const uint8_t* address;
    int x, y, u, v, getx, gety;
    Image *dst;
    const Image *src = srcSprite->getCurrentImage(&x, &y);
    div_t d;

    ASSERT(srcSprite);
    ASSERT(srcMask);
    ASSERT(srcMask->bitmap);
    ASSERT(src);

    dst = image_new(srcSprite->getImgType(), srcMask->w, srcMask->h);
    if (!dst)
        return NULL;

    // Clear the new image
    image_clear(dst, 0);

    // Copy the masked zones
    for (v=0; v<srcMask->h; v++) {
        d = div(0, 8);
        address = ((const uint8_t**)srcMask->bitmap->line)[v]+d.quot;

        for (u=0; u<srcMask->w; u++) {
            if ((*address & (1<<d.rem))) {
                getx = u+srcMask->x-x;
                gety = v+srcMask->y-y;

                if ((getx >= 0) && (getx < src->w) &&
                        (gety >= 0) && (gety < src->h))
                    dst->putpixel(u, v, src->getpixel(getx, gety));
            }

            _image_bitmap_next_bit(d, address);
        }
    }

    return dst;
}
示例#3
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)
{
  uint8_t* data;
  int x;
  int start, end;
  int val, last;
  int endx, l_num_empty;
  div_t d;

  data  = NULL;
  start = 0;
  end   = 0;

  *num_empty = 0;

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

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

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

  /*   tilex = -1; */
  empty_segs[(*num_empty)++] = 0;
  last = -1;

  l_num_empty = *num_empty;

  d = div (start, 8);
  data = ((uint8_t*)maskPR->line[scanline])+d.quot;

  for (x = start; x < end;)
    {
      endx = end;
      if (type == IgnoreBounds && (endx > x1 || x < x2))
	{
	  for (; x < endx; x++)
	    {
	      if (*data & (1<<d.rem))
		if (x >= x1 && x < x2)
		  val = -1;
		else
		  val = 1;
	      else
		val = -1;
	      
	      _image_bitmap_next_bit(d, data);

	      if (last != val)
		empty_segs[l_num_empty++] = x;
	      
	      last = val;
	    }
	}
      else
	{
	  for (; x < endx; x++)
	    {
	      if (*data & (1<<d.rem))
		val = 1;
	      else
		val = -1;
	      
	      _image_bitmap_next_bit(d, data);

	      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;
}
示例#4
0
int image_count_diff(const Image* i1, const Image* i2)
{
  int c, size, diff = 0;

  if ((i1->getPixelFormat() != i2->getPixelFormat()) ||
      (i1->w != i2->w) || (i1->h != i2->h))
    return -1;

  size = i1->w * i1->h;

  switch (i1->getPixelFormat()) {

    case IMAGE_RGB:
      {
        uint32_t* address1 = (uint32_t*)i1->dat;
        uint32_t* address2 = (uint32_t*)i2->dat;
        for (c=0; c<size; c++)
          if (*(address1++) != *(address2++))
            diff++;
      }
      break;

    case IMAGE_GRAYSCALE:
      {
        uint16_t* address1 = (uint16_t*)i1->dat;
        uint16_t* address2 = (uint16_t*)i2->dat;
        for (c=0; c<size; c++)
          if (*(address1++) != *(address2++))
            diff++;
      }
      break;

    case IMAGE_INDEXED:
      {
        uint8_t* address1 = (uint8_t*)i1->dat;
        uint8_t* address2 = (uint8_t*)i2->dat;
        for (c=0; c<size; c++)
          if (*(address1++) != *(address2++))
            diff++;
      }
      break;

    case IMAGE_BITMAP:
      /* TODO test it */
      {
        uint8_t* address1 = (uint8_t*)i1->dat;
        uint8_t* address2 = (uint8_t*)i2->dat;
        div_t d1 = div (0, 8);
        div_t d2 = div (0, 8);
        for (c=0; c<size; c++) {
          if (((*address1) & (1<<d1.rem)) !=
              ((*address2) & (1<<d2.rem)))
            diff++;
          _image_bitmap_next_bit(d1, address1);
          _image_bitmap_next_bit(d2, address2);
        }
      }
      break;
  }

  return diff;
}
示例#5
0
// clears the mask region in the current sprite with the specified background color
void UndoTransaction::clearMask(int bgcolor)
{
  Cel* cel = getCurrentCel();
  if (!cel)
    return;

  Image* image = getCelImage(cel);
  if (!image)
    return;

  Mask* mask = m_document->getMask();

  // If the mask is empty or is not visible then we have to clear the
  // entire image in the cel.
  if (!m_document->isMaskVisible()) {
    // If the layer is the background then we clear the image.
    if (m_sprite->getCurrentLayer()->is_background()) {
      if (isEnabled())
        m_undoHistory->pushUndoer(new undoers::ImageArea(m_undoHistory->getObjects(),
            image, 0, 0, image->w, image->h));

      // clear all
      image_clear(image, bgcolor);
    }
    // If the layer is transparent we can remove the cel (and its
    // associated image).
    else {
      removeCel(static_cast<LayerImage*>(m_sprite->getCurrentLayer()), cel);
    }
  }
  else {
    int offset_x = mask->getBounds().x-cel->getX();
    int offset_y = mask->getBounds().y-cel->getY();
    int u, v, putx, puty;
    int x1 = MAX(0, offset_x);
    int y1 = MAX(0, offset_y);
    int x2 = MIN(image->w-1, offset_x+mask->getBounds().w-1);
    int y2 = MIN(image->h-1, offset_y+mask->getBounds().h-1);

    // do nothing
    if (x1 > x2 || y1 > y2)
      return;

    if (isEnabled())
      m_undoHistory->pushUndoer(new undoers::ImageArea(m_undoHistory->getObjects(),
          image, x1, y1, x2-x1+1, y2-y1+1));

    // clear the masked zones
    for (v=0; v<mask->getBounds().h; v++) {
      div_t d = div(0, 8);
      uint8_t* address = ((uint8_t**)mask->getBitmap()->line)[v]+d.quot;

      for (u=0; u<mask->getBounds().w; u++) {
        if ((*address & (1<<d.rem))) {
          putx = u + offset_x;
          puty = v + offset_y;
          image_putpixel(image, putx, puty, bgcolor);
        }

        _image_bitmap_next_bit(d, address);
      }
    }
  }
}