Add support for PixelFormat (RGBA, ARGB) in Image, add more CFFI methods
This commit is contained in:
@@ -459,6 +459,42 @@ namespace lime {
|
||||
}
|
||||
|
||||
|
||||
value lime_image_data_util_copy_channel (value *arg, int nargs) {
|
||||
|
||||
enum { image, sourceImage, sourceRect, destPoint, srcChannel, destChannel };
|
||||
|
||||
Image _image = Image (arg[image]);
|
||||
Image _sourceImage = Image (arg[sourceImage]);
|
||||
Rectangle _sourceRect = Rectangle (arg[sourceRect]);
|
||||
Vector2 _destPoint = Vector2 (arg[destPoint]);
|
||||
ImageDataUtil::CopyChannel (&_image, &_sourceImage, &_sourceRect, &_destPoint, val_int (arg[srcChannel]), val_int (arg[destChannel]));
|
||||
return alloc_null ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
value lime_image_data_util_copy_pixels (value image, value sourceImage, value sourceRect, value destPoint, value mergeAlpha) {
|
||||
|
||||
Image _image = Image (image);
|
||||
Image _sourceImage = Image (sourceImage);
|
||||
Rectangle _sourceRect = Rectangle (sourceRect);
|
||||
Vector2 _destPoint = Vector2 (destPoint);
|
||||
ImageDataUtil::CopyPixels (&_image, &_sourceImage, &_sourceRect, &_destPoint, val_bool (mergeAlpha));
|
||||
return alloc_null ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
value lime_image_data_util_fill_rect (value image, value rect, value color) {
|
||||
|
||||
Image _image = Image (image);
|
||||
Rectangle _rect = Rectangle (rect);
|
||||
ImageDataUtil::FillRect (&_image, &_rect, val_number (color));
|
||||
return alloc_null ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
value lime_image_data_util_multiply_alpha (value image) {
|
||||
|
||||
Image _image = Image (image);
|
||||
@@ -869,6 +905,9 @@ namespace lime {
|
||||
DEFINE_PRIM (lime_gamepad_get_device_guid, 1);
|
||||
DEFINE_PRIM (lime_gamepad_get_device_name, 1);
|
||||
DEFINE_PRIM (lime_image_data_util_color_transform, 3);
|
||||
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_multiply_alpha, 1);
|
||||
DEFINE_PRIM (lime_image_data_util_unmultiply_alpha, 1);
|
||||
DEFINE_PRIM (lime_image_encode, 3);
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace lime {
|
||||
static int id_height;
|
||||
static int id_offsetX;
|
||||
static int id_offsetY;
|
||||
static int id_transparent;
|
||||
static int id_width;
|
||||
static bool init = false;
|
||||
|
||||
@@ -18,6 +19,7 @@ namespace lime {
|
||||
height = 0;
|
||||
offsetX = 0;
|
||||
offsetY = 0;
|
||||
transparent = true;
|
||||
width = 0;
|
||||
|
||||
}
|
||||
@@ -31,6 +33,7 @@ namespace lime {
|
||||
id_height = val_id ("height");
|
||||
id_offsetX = val_id ("offsetX");
|
||||
id_offsetY = val_id ("offsetY");
|
||||
id_transparent = val_id ("transparent");
|
||||
id_width = val_id ("width");
|
||||
init = true;
|
||||
|
||||
@@ -41,6 +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));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,149 @@ namespace lime {
|
||||
}
|
||||
|
||||
|
||||
void ImageDataUtil::CopyChannel (Image* image, Image* sourceImage, Rectangle* sourceRect, Vector2* destPoint, int srcChannel, int destChannel) {
|
||||
|
||||
int srcStride = sourceImage->buffer->width * 4;
|
||||
int srcPosition = ((sourceRect->x + sourceImage->offsetX) * 4) + (srcStride * (sourceRect->y + sourceImage->offsetY)) + srcChannel;
|
||||
int srcRowOffset = srcStride - int (4 * (sourceRect->width + sourceImage->offsetX));
|
||||
int srcRowEnd = 4 * (sourceRect->x + sourceImage->offsetX + sourceRect->width);
|
||||
uint8_t* srcData = (uint8_t*)sourceImage->buffer->data->Bytes ();
|
||||
|
||||
int destStride = image->buffer->width * 4;
|
||||
int destPosition = ((destPoint->x + image->offsetX) * 4) + (destStride * (destPoint->y + image->offsetY)) + destChannel;
|
||||
int destRowOffset = destStride - int (4 * (sourceRect->width + image->offsetX));
|
||||
int destRowEnd = 4 * (destPoint->x + image->offsetX + sourceRect->width);
|
||||
uint8_t* destData = (uint8_t*)image->buffer->data->Bytes ();
|
||||
|
||||
int length = sourceRect->width * sourceRect->height;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
destData[destPosition] = srcData[srcPosition];
|
||||
|
||||
srcPosition += 4;
|
||||
destPosition += 4;
|
||||
|
||||
if ((srcPosition % srcStride) > srcRowEnd) {
|
||||
|
||||
srcPosition += srcRowOffset;
|
||||
|
||||
}
|
||||
|
||||
if ((destPosition % destStride) > destRowEnd) {
|
||||
|
||||
destPosition += destRowOffset;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ImageDataUtil::CopyPixels (Image* image, Image* sourceImage, Rectangle* sourceRect, Vector2* destPoint, bool mergeAlpha) {
|
||||
|
||||
int rowOffset = int (destPoint->y + image->offsetY - sourceRect->y - sourceImage->offsetY);
|
||||
int columnOffset = int (destPoint->x + image->offsetX - sourceRect->x - sourceImage->offsetY);
|
||||
|
||||
uint8_t* sourceData = (uint8_t*)sourceImage->buffer->data->Bytes ();
|
||||
int sourceStride = sourceImage->buffer->width * 4;
|
||||
int sourceOffset = 0;
|
||||
|
||||
uint8_t* data = (uint8_t*)image->buffer->data->Bytes ();
|
||||
int stride = image->buffer->width * 4;
|
||||
int offset = 0;
|
||||
|
||||
int rows = sourceRect->y + sourceRect->height + sourceImage->offsetY;
|
||||
int columns = sourceRect->x + sourceRect->width + sourceImage->offsetX;
|
||||
|
||||
if (!mergeAlpha || !sourceImage->transparent) {
|
||||
|
||||
for (int row = sourceRect->y + sourceImage->offsetY; row < rows; row++) {
|
||||
|
||||
for (int column = sourceRect->x + sourceImage->offsetX; column < columns; column++) {
|
||||
|
||||
sourceOffset = (row * sourceStride) + (column * 4);
|
||||
offset = ((row + rowOffset) * stride) + ((column + columnOffset) * 4);
|
||||
|
||||
data[offset] = sourceData[sourceOffset];
|
||||
data[offset + 1] = sourceData[sourceOffset + 1];
|
||||
data[offset + 2] = sourceData[sourceOffset + 2];
|
||||
data[offset + 3] = sourceData[sourceOffset + 3];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
float sourceAlpha;
|
||||
float oneMinusSourceAlpha;
|
||||
|
||||
for (int row = sourceRect->y + sourceImage->offsetY; row < rows; row++) {
|
||||
|
||||
for (int column = sourceRect->x + sourceImage->offsetX; column < columns; column++) {
|
||||
|
||||
sourceOffset = (row * sourceStride) + (column * 4);
|
||||
offset = ((row + rowOffset) * stride) + ((column + columnOffset) * 4);
|
||||
|
||||
sourceAlpha = sourceData[sourceOffset + 3] / 255;
|
||||
oneMinusSourceAlpha = (1 - sourceAlpha);
|
||||
|
||||
data[offset] = __clamp[int (sourceData[sourceOffset] + (data[offset] * oneMinusSourceAlpha))];
|
||||
data[offset + 1] = __clamp[int (sourceData[sourceOffset + 1] + (data[offset + 1] * oneMinusSourceAlpha))];
|
||||
data[offset + 2] = __clamp[int (sourceData[sourceOffset + 2] + (data[offset + 2] * oneMinusSourceAlpha))];
|
||||
data[offset + 3] = __clamp[int (sourceData[sourceOffset + 3] + (data[offset + 3] * oneMinusSourceAlpha))];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ImageDataUtil::FillRect (Image* image, Rectangle* rect, int color) {
|
||||
|
||||
int* data = (int*)image->buffer->data->Bytes ();
|
||||
|
||||
if (rect->width == image->buffer->width && rect->height == image->buffer->height && rect->x == 0 && rect->y == 0 && image->offsetX == 0 && image->offsetY == 0) {
|
||||
|
||||
int length = image->buffer->width * image->buffer->height;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
data[i] = color;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
int stride = image->buffer->width;
|
||||
int offset;
|
||||
|
||||
int rowStart = int (rect->y + image->offsetY);
|
||||
int rowEnd = int (rect->y + rect->height + image->offsetY);
|
||||
int columnStart = int (rect->x + image->offsetX);
|
||||
int columnEnd = int (rect->x + rect->width + image->offsetX);
|
||||
|
||||
for (int row = rowStart; row < rowEnd; row++) {
|
||||
|
||||
for (int column = columnStart; column < columnEnd; column++) {
|
||||
|
||||
offset = (row * stride) + (column);
|
||||
data[offset] = color;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ImageDataUtil::MultiplyAlpha (Image* image) {
|
||||
|
||||
int a16 = 0;
|
||||
|
||||
36
project/src/math/Vector2.cpp
Normal file
36
project/src/math/Vector2.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <math/Vector2.h>
|
||||
|
||||
|
||||
namespace lime {
|
||||
|
||||
|
||||
static int id_x;
|
||||
static int id_y;
|
||||
static bool init = false;
|
||||
|
||||
|
||||
Vector2::Vector2 () {
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Vector2::Vector2 (value vec) {
|
||||
|
||||
if (!init) {
|
||||
|
||||
id_x = val_id ("x");
|
||||
id_y = val_id ("y");
|
||||
init = true;
|
||||
|
||||
}
|
||||
|
||||
x = val_number (val_field (vec, id_x));
|
||||
y = val_number (val_field (vec, id_y));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user