Add floodFill in CFFI

This commit is contained in:
Joshua Granick
2015-04-14 14:26:57 -07:00
parent 560a78db62
commit e2c2359726
5 changed files with 94 additions and 5 deletions

View File

@@ -22,6 +22,7 @@ namespace lime {
static void CopyChannel (Image* image, Image* sourceImage, Rectangle* sourceRect, Vector2* destPoint, int srcChannel, int destChannel);
static void CopyPixels (Image* image, Image* sourceImage, Rectangle* sourceRect, Vector2* destPoint, bool mergeAlpha);
static void FillRect (Image* image, Rectangle* rect, int color);
static void FloodFill (Image* image, int x, int y, int color);
static void MultiplyAlpha (Image *image);
static void UnmultiplyAlpha (Image *image);

View File

@@ -495,6 +495,15 @@ namespace lime {
}
value lime_image_data_util_flood_fill (value image, value x, value y, value color) {
Image _image = Image (image);
ImageDataUtil::FloodFill (&_image, val_number (x), val_number (y), val_number (color));
return alloc_null ();
}
value lime_image_data_util_multiply_alpha (value image) {
Image _image = Image (image);
@@ -908,6 +917,7 @@ namespace lime {
DEFINE_PRIM_MULT (lime_image_data_util_copy_channel);
DEFINE_PRIM (lime_image_data_util_copy_pixels, 5);
DEFINE_PRIM (lime_image_data_util_fill_rect, 3);
DEFINE_PRIM (lime_image_data_util_flood_fill, 4);
DEFINE_PRIM (lime_image_data_util_multiply_alpha, 1);
DEFINE_PRIM (lime_image_data_util_unmultiply_alpha, 1);
DEFINE_PRIM (lime_image_encode, 3);

View File

@@ -44,7 +44,7 @@ namespace lime {
buffer = new ImageBuffer (val_field (image, id_buffer));
offsetX = val_int (val_field (image, id_offsetX));
offsetY = val_int (val_field (image, id_offsetY));
transparent = val_bool (val_field (image, id_transparent));
transparent = val_int (val_field (image, id_transparent));
}

View File

@@ -1,5 +1,6 @@
#include <graphics/utils/ImageDataUtil.h>
#include <system/System.h>
#include <utils/QuickVec.h>
namespace lime {
@@ -227,6 +228,74 @@ namespace lime {
}
void ImageDataUtil::FloodFill (Image* image, int x, int y, int color) {
uint8_t* data = (uint8_t*)image->buffer->data->Bytes ();
int offset = (((y + image->offsetY) * (image->buffer->width * 4)) + ((x + image->offsetX) * 4));
uint8_t hitColorR = data[offset + 0];
uint8_t hitColorG = data[offset + 1];
uint8_t hitColorB = data[offset + 2];
uint8_t hitColorA = image->transparent ? data[offset + 3] : 0xFF;
uint8_t r = (color >> 24) & 0xFF;
uint8_t g = (color >> 16) & 0xFF;
uint8_t b = (color >> 8) & 0xFF;
uint8_t a = image->transparent ? color & 0xFF : 0xFF;
if (hitColorR == r && hitColorG == g && hitColorB == b && hitColorA == a) return;
int dx[4] = { 0, -1, 1, 0 };
int dy[4] = { -1, 0, 0, 1 };
int minX = -image->offsetX;
int minY = -image->offsetY;
int maxX = minX + image->width;
int maxY = minY + image->height;
QuickVec<int> queue = QuickVec<int> ();
queue.push_back (x);
queue.push_back (y);
int curPointX, curPointY, i, nextPointX, nextPointY, nextPointOffset;
while (queue.size () > 0) {
curPointY = queue.qpop ();
curPointX = queue.qpop ();
for (i = 0; i < 4; i++) {
nextPointX = curPointX + dx[i];
nextPointY = curPointY + dy[i];
if (nextPointX < minX || nextPointY < minY || nextPointX >= maxX || nextPointY >= maxY) {
continue;
}
nextPointOffset = (nextPointY * image->width + nextPointX) * 4;
if (data[nextPointOffset + 0] == hitColorR && data[nextPointOffset + 1] == hitColorG && data[nextPointOffset + 2] == hitColorB && data[nextPointOffset + 3] == hitColorA) {
data[nextPointOffset + 0] = r;
data[nextPointOffset + 1] = g;
data[nextPointOffset + 2] = b;
data[nextPointOffset + 3] = a;
queue.push_back (nextPointX);
queue.push_back (nextPointY);
}
}
}
}
void ImageDataUtil::MultiplyAlpha (Image* image) {
int a16 = 0;