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